Merge remote-tracking branch 'origin/main'
# Conflicts: # typescript/Frontend/src/config/axiosConfig.tsx
This commit is contained in:
commit
107a439e44
|
@ -267,7 +267,7 @@ public class Controller : ControllerBase
|
||||||
if (! await session.Create(installation))
|
if (! await session.Create(installation))
|
||||||
return Unauthorized();
|
return Unauthorized();
|
||||||
|
|
||||||
return installation.FillOrderNumbers().HideParentIfUserHasNoAccessToParent(session!.User);
|
return installation;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost(nameof(CreateFolder))]
|
[HttpPost(nameof(CreateFolder))]
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
"dotnetRunMessages": true,
|
"dotnetRunMessages": true,
|
||||||
|
|
||||||
"launchUrl": "swagger",
|
"launchUrl": "swagger",
|
||||||
"applicationUrl": "https://localhost:7087;http://localhost:5031",
|
"applicationUrl": "https://localhost:8000",
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,7 +137,7 @@ K3 ✓<y:LabelModel><y:ErdAttributesNodeLabelModel/></y:LabelModel><y:ModelParam
|
||||||
<data key="d5"/>
|
<data key="d5"/>
|
||||||
<data key="d6">
|
<data key="d6">
|
||||||
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
||||||
<y:Geometry height="90.0" width="70.0" x="582.0523615909593" y="160.75568014793453"/>
|
<y:Geometry height="90.0" width="70.0" x="393.7937432135768" y="243.91085524521077"/>
|
||||||
<y:Fill color="#B4B4FF" transparent="false"/>
|
<y:Fill color="#B4B4FF" transparent="false"/>
|
||||||
<y:BorderStyle color="#000068" type="dashed" width="1.0"/>
|
<y:BorderStyle color="#000068" type="dashed" width="1.0"/>
|
||||||
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#B4B4FF" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000068" verticalTextPosition="bottom" visible="true" width="10.864044189453125" x="29.567977905273438" xml:space="preserve" y="4.0">5</y:NodeLabel>
|
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#B4B4FF" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000068" verticalTextPosition="bottom" visible="true" width="10.864044189453125" x="29.567977905273438" xml:space="preserve" y="4.0">5</y:NodeLabel>
|
||||||
|
@ -154,7 +154,7 @@ K3 ✓<y:LabelModel><y:ErdAttributesNodeLabelModel/></y:LabelModel><y:ModelParam
|
||||||
<data key="d5"/>
|
<data key="d5"/>
|
||||||
<data key="d6">
|
<data key="d6">
|
||||||
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
||||||
<y:Geometry height="90.0" width="70.0" x="175.8255534152188" y="188.59145941969348"/>
|
<y:Geometry height="90.0" width="70.0" x="241.37121964689652" y="243.91085524521077"/>
|
||||||
<y:Fill color="#B4B4FF" transparent="false"/>
|
<y:Fill color="#B4B4FF" transparent="false"/>
|
||||||
<y:BorderStyle color="#000068" type="dashed" width="1.0"/>
|
<y:BorderStyle color="#000068" type="dashed" width="1.0"/>
|
||||||
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#B4B4FF" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000068" verticalTextPosition="bottom" visible="true" width="10.864044189453125" x="29.567977905273438" xml:space="preserve" y="4.0">7</y:NodeLabel>
|
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#B4B4FF" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000068" verticalTextPosition="bottom" visible="true" width="10.864044189453125" x="29.567977905273438" xml:space="preserve" y="4.0">7</y:NodeLabel>
|
||||||
|
@ -172,7 +172,7 @@ K3 ✓<y:LabelModel><y:ErdAttributesNodeLabelModel/></y:LabelModel><y:ModelParam
|
||||||
<data key="d5"/>
|
<data key="d5"/>
|
||||||
<data key="d6">
|
<data key="d6">
|
||||||
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
||||||
<y:Geometry height="90.0" width="70.0" x="779.8955241254705" y="229.98399686669086"/>
|
<y:Geometry height="90.0" width="70.0" x="913.7233840476495" y="390.20661887776083"/>
|
||||||
<y:Fill color="#FFEB9C" transparent="false"/>
|
<y:Fill color="#FFEB9C" transparent="false"/>
|
||||||
<y:BorderStyle color="#683A00" type="dashed" width="1.0"/>
|
<y:BorderStyle color="#683A00" type="dashed" width="1.0"/>
|
||||||
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#FFEB9C" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#683A00" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">11</y:NodeLabel>
|
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#FFEB9C" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#683A00" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">11</y:NodeLabel>
|
||||||
|
@ -190,11 +190,11 @@ K3 ✘<y:LabelModel><y:ErdAttributesNodeLabelModel/></y:LabelModel><y:ModelParam
|
||||||
<data key="d5"/>
|
<data key="d5"/>
|
||||||
<data key="d6">
|
<data key="d6">
|
||||||
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
||||||
<y:Geometry height="90.0" width="70.0" x="1080.1411072770327" y="505.0251575795813"/>
|
<y:Geometry height="90.0" width="70.0" x="1032.06702167392" y="683.7966785548988"/>
|
||||||
<y:Fill color="#FFEB9C" transparent="false"/>
|
<y:Fill color="#FFEB9C" transparent="false"/>
|
||||||
<y:BorderStyle color="#683A00" type="dashed" width="1.0"/>
|
<y:BorderStyle color="#683A00" type="dashed" width="1.0"/>
|
||||||
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#FFEB9C" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#683A00" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="3.999999999999943">15</y:NodeLabel>
|
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#FFEB9C" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#683A00" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="3.999999999999943">15</y:NodeLabel>
|
||||||
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasBackgroundColor="false" hasLineColor="false" height="53.0323429107666" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#683A00" verticalTextPosition="top" visible="true" width="30.628189086914062" x="2.0" xml:space="preserve" y="32.34411430358881">K1 ✓
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasBackgroundColor="false" hasLineColor="false" height="53.0323429107666" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#683A00" verticalTextPosition="top" visible="true" width="30.628189086914062" x="2.0" xml:space="preserve" y="32.34411430358887">K1 ✓
|
||||||
K2 ✓
|
K2 ✓
|
||||||
K3 ✓<y:LabelModel><y:ErdAttributesNodeLabelModel/></y:LabelModel><y:ModelParameter><y:ErdAttributesNodeLabelModelParameter/></y:ModelParameter></y:NodeLabel>
|
K3 ✓<y:LabelModel><y:ErdAttributesNodeLabelModel/></y:LabelModel><y:ModelParameter><y:ErdAttributesNodeLabelModelParameter/></y:ModelParameter></y:NodeLabel>
|
||||||
<y:StyleProperties>
|
<y:StyleProperties>
|
||||||
|
@ -207,7 +207,7 @@ K3 ✓<y:LabelModel><y:ErdAttributesNodeLabelModel/></y:LabelModel><y:ModelParam
|
||||||
<data key="d5"/>
|
<data key="d5"/>
|
||||||
<data key="d6">
|
<data key="d6">
|
||||||
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
||||||
<y:Geometry height="90.0" width="70.0" x="614.6002578542565" y="0.0"/>
|
<y:Geometry height="90.0" width="70.0" x="393.7937432135768" y="32.482490272373525"/>
|
||||||
<y:Fill color="#B4B4FF" transparent="false"/>
|
<y:Fill color="#B4B4FF" transparent="false"/>
|
||||||
<y:BorderStyle color="#000068" type="line" width="1.0"/>
|
<y:BorderStyle color="#000068" type="line" width="1.0"/>
|
||||||
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#B4B4FF" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000068" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">21</y:NodeLabel>
|
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#B4B4FF" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000068" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">21</y:NodeLabel>
|
||||||
|
@ -224,7 +224,7 @@ K3 ✓<y:LabelModel><y:ErdAttributesNodeLabelModel/></y:LabelModel><y:ModelParam
|
||||||
<data key="d5"/>
|
<data key="d5"/>
|
||||||
<data key="d6">
|
<data key="d6">
|
||||||
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
||||||
<y:Geometry height="90.0" width="70.0" x="448.50893604095756" y="145.7089497868842"/>
|
<y:Geometry height="90.0" width="70.0" x="546.2162667802571" y="243.91085524521077"/>
|
||||||
<y:Fill color="#B4B4FF" transparent="false"/>
|
<y:Fill color="#B4B4FF" transparent="false"/>
|
||||||
<y:BorderStyle color="#000068" type="line" width="1.0"/>
|
<y:BorderStyle color="#000068" type="line" width="1.0"/>
|
||||||
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#B4B4FF" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000068" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">17</y:NodeLabel>
|
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#B4B4FF" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000068" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">17</y:NodeLabel>
|
||||||
|
@ -242,7 +242,7 @@ K3 ✘<y:LabelModel><y:ErdAttributesNodeLabelModel/></y:LabelModel><y:ModelParam
|
||||||
<data key="d5"/>
|
<data key="d5"/>
|
||||||
<data key="d6">
|
<data key="d6">
|
||||||
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
||||||
<y:Geometry height="90.0" width="70.0" x="893.6854614285201" y="301.4829532979212"/>
|
<y:Geometry height="90.0" width="70.0" x="913.7233840476495" y="243.91085524521077"/>
|
||||||
<y:Fill color="#FFEB9C" transparent="false"/>
|
<y:Fill color="#FFEB9C" transparent="false"/>
|
||||||
<y:BorderStyle color="#683A00" type="line" width="1.0"/>
|
<y:BorderStyle color="#683A00" type="line" width="1.0"/>
|
||||||
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#FFEB9C" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#683A00" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">25</y:NodeLabel>
|
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#FFEB9C" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#683A00" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">25</y:NodeLabel>
|
||||||
|
@ -260,7 +260,7 @@ K3 ✘<y:LabelModel><y:ErdAttributesNodeLabelModel/></y:LabelModel><y:ModelParam
|
||||||
<data key="d5"/>
|
<data key="d5"/>
|
||||||
<data key="d6">
|
<data key="d6">
|
||||||
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
||||||
<y:Geometry height="90.0" width="70.0" x="854.6780813018231" y="84.0068637493531"/>
|
<y:Geometry height="90.0" width="70.0" x="1110.6401046481265" y="390.20661887776083"/>
|
||||||
<y:Fill color="#FFEB9C" transparent="false"/>
|
<y:Fill color="#FFEB9C" transparent="false"/>
|
||||||
<y:BorderStyle color="#683A00" type="line" width="1.0"/>
|
<y:BorderStyle color="#683A00" type="line" width="1.0"/>
|
||||||
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#FFEB9C" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#683A00" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">27</y:NodeLabel>
|
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#FFEB9C" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#683A00" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">27</y:NodeLabel>
|
||||||
|
@ -278,7 +278,7 @@ K3 ✘<y:LabelModel><y:ErdAttributesNodeLabelModel/></y:LabelModel><y:ModelParam
|
||||||
<data key="d5"/>
|
<data key="d5"/>
|
||||||
<data key="d6">
|
<data key="d6">
|
||||||
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
||||||
<y:Geometry height="90.0" width="70.0" x="1219.0187296181307" y="417.76256385308943"/>
|
<y:Geometry height="90.0" width="70.0" x="1268.5061818399" y="683.7966785548988"/>
|
||||||
<y:Fill color="#FFEB9C" color2="#FF0000" transparent="false"/>
|
<y:Fill color="#FFEB9C" color2="#FF0000" transparent="false"/>
|
||||||
<y:BorderStyle color="#683A00" type="line" width="1.0"/>
|
<y:BorderStyle color="#683A00" type="line" width="1.0"/>
|
||||||
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#FFEB9C" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#683A00" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">31</y:NodeLabel>
|
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#FFEB9C" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#683A00" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">31</y:NodeLabel>
|
||||||
|
@ -414,7 +414,7 @@ K3 ✓<y:LabelModel><y:ErdAttributesNodeLabelModel/></y:LabelModel><y:ModelParam
|
||||||
<data key="d5"/>
|
<data key="d5"/>
|
||||||
<data key="d6">
|
<data key="d6">
|
||||||
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
||||||
<y:Geometry height="90.0" width="70.0" x="410.66241765886343" y="1681.8835044865843"/>
|
<y:Geometry height="90.0" width="70.0" x="381.1829957002519" y="1666.836774125534"/>
|
||||||
<y:Fill color="#B4B4FF" transparent="false"/>
|
<y:Fill color="#B4B4FF" transparent="false"/>
|
||||||
<y:BorderStyle color="#000068" type="line" width="1.0"/>
|
<y:BorderStyle color="#000068" type="line" width="1.0"/>
|
||||||
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#B4B4FF" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000068" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">16</y:NodeLabel>
|
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#B4B4FF" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000068" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">16</y:NodeLabel>
|
||||||
|
@ -448,7 +448,7 @@ K3 ✓<y:LabelModel><y:ErdAttributesNodeLabelModel/></y:LabelModel><y:ModelParam
|
||||||
<data key="d5"/>
|
<data key="d5"/>
|
||||||
<data key="d6">
|
<data key="d6">
|
||||||
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
||||||
<y:Geometry height="90.0" width="70.0" x="244.57109584556457" y="1827.5924542734685"/>
|
<y:Geometry height="90.0" width="70.0" x="247.63957015025017" y="1827.5924542734685"/>
|
||||||
<y:Fill color="#B4B4FF" transparent="false"/>
|
<y:Fill color="#B4B4FF" transparent="false"/>
|
||||||
<y:BorderStyle color="#000068" type="line" width="1.0"/>
|
<y:BorderStyle color="#000068" type="line" width="1.0"/>
|
||||||
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#B4B4FF" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000068" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">18</y:NodeLabel>
|
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#B4B4FF" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000068" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">18</y:NodeLabel>
|
||||||
|
@ -465,7 +465,7 @@ K3 ✘<y:LabelModel><y:ErdAttributesNodeLabelModel/></y:LabelModel><y:ModelParam
|
||||||
<data key="d5"/>
|
<data key="d5"/>
|
||||||
<data key="d6">
|
<data key="d6">
|
||||||
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
||||||
<y:Geometry height="90.0" width="70.0" x="277.1189921088617" y="1666.836774125534"/>
|
<y:Geometry height="90.0" width="70.0" x="247.63957015025017" y="1666.836774125534"/>
|
||||||
<y:Fill color="#B4B4FF" transparent="false"/>
|
<y:Fill color="#B4B4FF" transparent="false"/>
|
||||||
<y:BorderStyle color="#000068" type="dashed" width="1.0"/>
|
<y:BorderStyle color="#000068" type="dashed" width="1.0"/>
|
||||||
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#B4B4FF" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000068" verticalTextPosition="bottom" visible="true" width="10.864044189453125" x="29.567977905273438" xml:space="preserve" y="4.0">2</y:NodeLabel>
|
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#B4B4FF" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000068" verticalTextPosition="bottom" visible="true" width="10.864044189453125" x="29.567977905273438" xml:space="preserve" y="4.0">2</y:NodeLabel>
|
||||||
|
@ -482,7 +482,7 @@ K3 ✘<y:LabelModel><y:ErdAttributesNodeLabelModel/></y:LabelModel><y:ModelParam
|
||||||
<data key="d5"/>
|
<data key="d5"/>
|
||||||
<data key="d6">
|
<data key="d6">
|
||||||
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
||||||
<y:Geometry height="90.0" width="70.0" x="745.7969893047066" y="1614.0294463149824"/>
|
<y:Geometry height="90.0" width="70.0" x="735.2707053490758" y="1666.836774125534"/>
|
||||||
<y:Fill color="#FFEB9C" transparent="false"/>
|
<y:Fill color="#FFEB9C" transparent="false"/>
|
||||||
<y:BorderStyle color="#683A00" type="dashed" width="1.0"/>
|
<y:BorderStyle color="#683A00" type="dashed" width="1.0"/>
|
||||||
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#FFEB9C" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#683A00" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">10</y:NodeLabel>
|
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#FFEB9C" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#683A00" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">10</y:NodeLabel>
|
||||||
|
@ -499,7 +499,7 @@ K3 ✘<y:LabelModel><y:ErdAttributesNodeLabelModel/></y:LabelModel><y:ModelParam
|
||||||
<data key="d5"/>
|
<data key="d5"/>
|
||||||
<data key="d6">
|
<data key="d6">
|
||||||
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
||||||
<y:Geometry height="90.0" width="70.0" x="618.9499887405645" y="1658.4151315081558"/>
|
<y:Geometry height="90.0" width="70.0" x="572.3666077540471" y="1666.836774125534"/>
|
||||||
<y:Fill color="#FFEB9C" transparent="false"/>
|
<y:Fill color="#FFEB9C" transparent="false"/>
|
||||||
<y:BorderStyle color="#683A00" type="dashed" width="1.0"/>
|
<y:BorderStyle color="#683A00" type="dashed" width="1.0"/>
|
||||||
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#FFEB9C" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#683A00" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">12</y:NodeLabel>
|
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#FFEB9C" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#683A00" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">12</y:NodeLabel>
|
||||||
|
@ -516,7 +516,7 @@ K3 ✓<y:LabelModel><y:ErdAttributesNodeLabelModel/></y:LabelModel><y:ModelParam
|
||||||
<data key="d5"/>
|
<data key="d5"/>
|
||||||
<data key="d6">
|
<data key="d6">
|
||||||
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
||||||
<y:Geometry height="90.0" width="70.0" x="659.3746230785885" y="1817.3729975910535"/>
|
<y:Geometry height="90.0" width="70.0" x="572.3666077540471" y="1827.5924542734685"/>
|
||||||
<y:Fill color="#FFEB9C" transparent="false"/>
|
<y:Fill color="#FFEB9C" transparent="false"/>
|
||||||
<y:BorderStyle color="#683A00" type="dashed" width="1.0"/>
|
<y:BorderStyle color="#683A00" type="dashed" width="1.0"/>
|
||||||
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#FFEB9C" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#683A00" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">14</y:NodeLabel>
|
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#FFEB9C" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#683A00" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">14</y:NodeLabel>
|
||||||
|
@ -533,7 +533,7 @@ K3 ✓<y:LabelModel><y:ErdAttributesNodeLabelModel/></y:LabelModel><y:ModelParam
|
||||||
<data key="d5"/>
|
<data key="d5"/>
|
||||||
<data key="d6">
|
<data key="d6">
|
||||||
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
||||||
<y:Geometry height="90.0" width="70.0" x="813.3003459398944" y="1763.512057658155"/>
|
<y:Geometry height="90.0" width="70.0" x="735.2707053490758" y="1827.5924542734685"/>
|
||||||
<y:Fill color="#FFEB9C" transparent="false"/>
|
<y:Fill color="#FFEB9C" transparent="false"/>
|
||||||
<y:BorderStyle color="#683A00" type="line" width="1.0"/>
|
<y:BorderStyle color="#683A00" type="line" width="1.0"/>
|
||||||
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#FFEB9C" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#683A00" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">26</y:NodeLabel>
|
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#FFEB9C" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#683A00" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">26</y:NodeLabel>
|
||||||
|
@ -550,7 +550,7 @@ K3 ✘<y:LabelModel><y:ErdAttributesNodeLabelModel/></y:LabelModel><y:ModelParam
|
||||||
<data key="d5"/>
|
<data key="d5"/>
|
||||||
<data key="d6">
|
<data key="d6">
|
||||||
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
<y:GenericNode configuration="com.yworks.entityRelationship.big_entity">
|
||||||
<y:Geometry height="90.0" width="70.0" x="699.7992574166124" y="1976.3308636739512"/>
|
<y:Geometry height="90.0" width="70.0" x="572.3666077540471" y="1988.348134421403"/>
|
||||||
<y:Fill color="#FFEB9C" transparent="false"/>
|
<y:Fill color="#FFEB9C" transparent="false"/>
|
||||||
<y:BorderStyle color="#683A00" type="line" width="1.0"/>
|
<y:BorderStyle color="#683A00" type="line" width="1.0"/>
|
||||||
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#FFEB9C" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#683A00" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">30</y:NodeLabel>
|
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#FFEB9C" configuration="com.yworks.entityRelationship.label.name" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#683A00" verticalTextPosition="bottom" visible="true" width="17.72808837890625" x="26.135955810546875" xml:space="preserve" y="4.0">30</y:NodeLabel>
|
||||||
|
@ -582,8 +582,8 @@ Inverters<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0"
|
||||||
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
<y:Arrows source="none" target="standard"/>
|
<y:Arrows source="none" target="standard"/>
|
||||||
<y:EdgeLabel alignment="center" anchorX="-22.56775183821742" anchorY="-48.88515038132459" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="36.688228607177734" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="center" ratio="0.5" textColor="#000000" upX="-0.33027906195516804" upY="0.9438833303083672" verticalTextPosition="bottom" visible="true" width="57.61639404296875" x="-89.06825945702936" xml:space="preserve" y="-67.91463895907565">switch to
|
<y:EdgeLabel alignment="center" anchorX="-22.56775183821742" anchorY="-5.777885637190593" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="36.688228607177734" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="center" ratio="0.5" textColor="#000000" upX="-0.33027906195516804" upY="0.9438833303083672" verticalTextPosition="bottom" visible="true" width="57.61639404296875" x="-89.06825945702936" xml:space="preserve" y="-24.807374214941643">switch to
|
||||||
grid tie<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.5" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
grid tie<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="true" ratio="0.5" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
<y:BendStyle smoothed="false"/>
|
<y:BendStyle smoothed="false"/>
|
||||||
</y:PolyLineEdge>
|
</y:PolyLineEdge>
|
||||||
</data>
|
</data>
|
||||||
|
@ -641,10 +641,13 @@ Inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEn
|
||||||
<data key="d9"/>
|
<data key="d9"/>
|
||||||
<data key="d10">
|
<data key="d10">
|
||||||
<y:PolyLineEdge>
|
<y:PolyLineEdge>
|
||||||
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
<y:Path sx="0.0" sy="0.0" tx="21.046829314938122" ty="-45.01680098318991">
|
||||||
|
<y:Point x="874.0493776621389" y="435.20661887776083"/>
|
||||||
|
<y:Point x="715.6320547466846" y="519.7002048682145"/>
|
||||||
|
</y:Path>
|
||||||
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
<y:Arrows source="none" target="standard"/>
|
<y:Arrows source="none" target="standard"/>
|
||||||
<y:EdgeLabel alignment="center" anchorX="-30.708326355243116" anchorY="86.75687917585009" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" upX="0.935215143023455" upY="0.3540799856806631" verticalTextPosition="bottom" visible="true" width="50.236328125" x="-48.49600469839221" xml:space="preserve" y="86.75687917585009">open K2<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="true" ratio="0.5" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
<y:EdgeLabel alignment="center" anchorX="-95.81164490935862" anchorY="32.19070766070081" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" upX="0.47060708552926384" upY="0.8823428874590944" verticalTextPosition="bottom" visible="true" width="50.236328125" x="-140.13731172251363" xml:space="preserve" y="32.19070766070081">open K2<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="true" ratio="0.5000000000000019" segment="1"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
<y:BendStyle smoothed="false"/>
|
<y:BendStyle smoothed="false"/>
|
||||||
</y:PolyLineEdge>
|
</y:PolyLineEdge>
|
||||||
</data>
|
</data>
|
||||||
|
@ -656,7 +659,7 @@ Inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEn
|
||||||
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
<y:Arrows source="none" target="standard"/>
|
<y:Arrows source="none" target="standard"/>
|
||||||
<y:EdgeLabel alignment="center" anchorX="-91.4265773429479" anchorY="31.058243169626735" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="center" ratio="0.5" textColor="#000000" upX="0.5320320765153349" upY="0.8467241992282852" verticalTextPosition="bottom" visible="true" width="50.236328125" x="-133.9628920467579" xml:space="preserve" y="31.058243169626735">open K2<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.5" segment="1"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
<y:EdgeLabel alignment="center" anchorX="-58.091523252820025" anchorY="-22.344127643221327" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="center" ratio="0.5" textColor="#000000" upX="-1.2246467991473532E-16" upY="1.0" verticalTextPosition="bottom" visible="true" width="50.236328125" x="-108.32785137782002" xml:space="preserve" y="-22.344127643221334">open K2<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.5" segment="1"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
<y:BendStyle smoothed="false"/>
|
<y:BendStyle smoothed="false"/>
|
||||||
</y:PolyLineEdge>
|
</y:PolyLineEdge>
|
||||||
</data>
|
</data>
|
||||||
|
@ -665,11 +668,14 @@ Inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEn
|
||||||
<data key="d9"/>
|
<data key="d9"/>
|
||||||
<data key="d10">
|
<data key="d10">
|
||||||
<y:PolyLineEdge>
|
<y:PolyLineEdge>
|
||||||
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
<y:Path sx="0.0" sy="0.0" tx="15.152106842485068" ty="-45.029446684529034">
|
||||||
|
<y:Point x="581.2162667802571" y="365.51788910504735"/>
|
||||||
|
<y:Point x="528.1404648420541" y="447.09481487826343"/>
|
||||||
|
</y:Path>
|
||||||
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
<y:Arrows source="none" target="standard"/>
|
<y:Arrows source="none" target="standard"/>
|
||||||
<y:EdgeLabel alignment="center" anchorX="-29.97425394733284" anchorY="101.74082753289088" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="36.688228607177734" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="center" ratio="0.5" textColor="#000000" upX="0.9962292767888588" upY="-0.0867595992887667" verticalTextPosition="bottom" visible="true" width="48.38832092285156" x="-29.97425394733284" xml:space="preserve" y="98.55777152031747">turn off
|
<y:EdgeLabel alignment="center" anchorX="-11.667059533747079" anchorY="53.20739194515636" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="36.688228607177734" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="center" ratio="0.5" textColor="#000000" upX="0.8382050245156525" upY="0.5453552391576654" verticalTextPosition="bottom" visible="true" width="48.38832092285156" x="-38.055883863066654" xml:space="preserve" y="53.20739194515636">turn off
|
||||||
inverter<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.5" segment="1"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
inverter<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="true" ratio="0.5000000000000003" segment="1"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
<y:BendStyle smoothed="false"/>
|
<y:BendStyle smoothed="false"/>
|
||||||
</y:PolyLineEdge>
|
</y:PolyLineEdge>
|
||||||
</data>
|
</data>
|
||||||
|
@ -681,7 +687,7 @@ inverter<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEna
|
||||||
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
<y:Arrows source="none" target="standard"/>
|
<y:Arrows source="none" target="standard"/>
|
||||||
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="36.688228607177734" horizontalTextPosition="center" iconTextGap="4" modelName="side_slider" preferredPlacement="center" ratio="0.0" textColor="#000000" verticalTextPosition="bottom" visible="true" width="54.13636779785156" x="-61.48240607634398" xml:space="preserve" y="-30.072393595089466">turn off
|
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="36.688228607177734" horizontalTextPosition="center" iconTextGap="4" modelName="side_slider" preferredPlacement="center" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="54.13636779785156" x="-110.27792003264085" xml:space="preserve" y="-34.688241946810194">turn off
|
||||||
inverters<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
inverters<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
<y:BendStyle smoothed="false"/>
|
<y:BendStyle smoothed="false"/>
|
||||||
</y:PolyLineEdge>
|
</y:PolyLineEdge>
|
||||||
|
@ -694,7 +700,7 @@ inverters<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0"
|
||||||
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
<y:Arrows source="none" target="standard"/>
|
<y:Arrows source="none" target="standard"/>
|
||||||
<y:EdgeLabel alignment="center" anchorX="-40.1366872375786" anchorY="3.276745889159926" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="36.688228607177734" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="center" ratio="0.5" textColor="#000000" upX="0.9801127226267146" upY="0.19844155548989476" verticalTextPosition="bottom" visible="true" width="54.13636779785156" x="-50.87959227195731" xml:space="preserve" y="3.276745889159926">turn off
|
<y:EdgeLabel alignment="center" anchorX="-38.68821708305404" anchorY="33.66069253418277" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="36.688228607177734" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="center" ratio="0.5" textColor="#000000" upX="1.0" upY="1.8369701987210297E-16" verticalTextPosition="bottom" visible="true" width="54.13636779785156" x="-38.68821708305405" xml:space="preserve" y="33.66069253418277">turn off
|
||||||
inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.5" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.5" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
<y:BendStyle smoothed="false"/>
|
<y:BendStyle smoothed="false"/>
|
||||||
</y:PolyLineEdge>
|
</y:PolyLineEdge>
|
||||||
|
@ -707,7 +713,7 @@ inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEn
|
||||||
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
<y:Arrows source="none" target="standard"/>
|
<y:Arrows source="none" target="standard"/>
|
||||||
<y:EdgeLabel alignment="center" anchorX="-36.42344224440467" anchorY="-13.753969151122476" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="36.688228607177734" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="center" ratio="0.5" textColor="#000000" upX="0.8900092690299531" upY="0.45594243171783055" verticalTextPosition="bottom" visible="true" width="54.13636779785156" x="-61.106509422527964" xml:space="preserve" y="-13.753969151122476">turn off
|
<y:EdgeLabel alignment="center" anchorX="-36.34321140162365" anchorY="-38.68821373332315" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="36.688228607177734" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="center" ratio="0.5" textColor="#000000" upX="-1.2246467991473532E-16" upY="1.0" verticalTextPosition="bottom" visible="true" width="54.13636779785156" x="-90.47957919947521" xml:space="preserve" y="-38.68821373332316">turn off
|
||||||
inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.5" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.5" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
<y:BendStyle smoothed="false"/>
|
<y:BendStyle smoothed="false"/>
|
||||||
</y:PolyLineEdge>
|
</y:PolyLineEdge>
|
||||||
|
@ -717,11 +723,14 @@ inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEn
|
||||||
<data key="d9"/>
|
<data key="d9"/>
|
||||||
<data key="d10">
|
<data key="d10">
|
||||||
<y:PolyLineEdge>
|
<y:PolyLineEdge>
|
||||||
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
|
||||||
|
<y:Point x="875.759476311287" y="288.91085524521077"/>
|
||||||
|
<y:Point x="694.5852254317465" y="500.95688054473624"/>
|
||||||
|
</y:Path>
|
||||||
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
<y:Arrows source="none" target="standard"/>
|
<y:Arrows source="none" target="standard"/>
|
||||||
<y:EdgeLabel alignment="center" anchorX="-87.60097524632454" anchorY="36.001631487133864" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="36.688228607177734" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="center" ratio="0.5" textColor="#000000" upX="0.7247896869799892" upY="0.6889701805212248" verticalTextPosition="bottom" visible="true" width="54.13636779785156" x="-124.89931834077376" xml:space="preserve" y="36.001631487133864">turn off
|
<y:EdgeLabel alignment="center" anchorX="-140.36047493803812" anchorY="60.311953252495755" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="36.688228607177734" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="center" ratio="0.5" textColor="#000000" upX="0.7602822957199457" upY="0.6495928192451093" verticalTextPosition="bottom" visible="true" width="54.13636779785156" x="-175.52707071953466" xml:space="preserve" y="60.311953252495755">turn off
|
||||||
inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.5" segment="1"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.5000000000000003" segment="1"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
<y:BendStyle smoothed="false"/>
|
<y:BendStyle smoothed="false"/>
|
||||||
</y:PolyLineEdge>
|
</y:PolyLineEdge>
|
||||||
</data>
|
</data>
|
||||||
|
@ -743,8 +752,8 @@ inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEn
|
||||||
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
<y:Arrows source="none" target="standard"/>
|
<y:Arrows source="none" target="standard"/>
|
||||||
<y:EdgeLabel alignment="center" anchorX="-2.720348770062401" anchorY="-8.184439221301773" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="36.688228607177734" horizontalTextPosition="center" iconTextGap="4" modelName="custom" ratio="0.5" textColor="#000000" upX="-0.9962292767888588" upY="0.08675959928876727" verticalTextPosition="bottom" visible="true" width="55.108367919921875" x="-44.05141614024578" xml:space="preserve" y="-63.085008739179884">turn off
|
<y:EdgeLabel alignment="center" anchorX="38.68824090899216" anchorY="-89.20073479644952" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="36.688228607177734" horizontalTextPosition="center" iconTextGap="4" modelName="custom" ratio="0.5" textColor="#000000" upX="-1.0" upY="-6.123233995736766E-17" verticalTextPosition="bottom" visible="true" width="55.108367919921875" x="2.0000123018144222" xml:space="preserve" y="-144.3091027163714">turn off
|
||||||
Inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="true" ratio="0.0" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="left|right" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
Inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.4999999999999987" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="left|right" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
<y:BendStyle smoothed="false"/>
|
<y:BendStyle smoothed="false"/>
|
||||||
</y:PolyLineEdge>
|
</y:PolyLineEdge>
|
||||||
</data>
|
</data>
|
||||||
|
@ -817,7 +826,7 @@ Inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEn
|
||||||
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
<y:Arrows source="none" target="standard"/>
|
<y:Arrows source="none" target="standard"/>
|
||||||
<y:EdgeLabel alignment="center" anchorX="-0.601812832179121" anchorY="-7.106143485136727" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="36.688228607177734" horizontalTextPosition="center" iconTextGap="4" modelName="custom" ratio="0.5" textColor="#000000" upX="-0.9801127226267147" upY="-0.19844155548989376" verticalTextPosition="bottom" visible="true" width="54.13636779785156" x="-36.56041246071141" xml:space="preserve" y="-67.4463554735874">turn off
|
<y:EdgeLabel alignment="center" anchorX="-1.9999867345154598" anchorY="-8.293373776572935" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="36.688228607177734" horizontalTextPosition="center" iconTextGap="4" modelName="custom" ratio="0.5" textColor="#000000" upX="-1.0" upY="-6.123233995736766E-17" verticalTextPosition="bottom" visible="true" width="54.13636779785156" x="-38.688215341693194" xml:space="preserve" y="-62.4297415744245">turn off
|
||||||
inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="true" ratio="0.5" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="left|right" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="true" ratio="0.5" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="left|right" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
<y:BendStyle smoothed="false"/>
|
<y:BendStyle smoothed="false"/>
|
||||||
</y:PolyLineEdge>
|
</y:PolyLineEdge>
|
||||||
|
@ -827,10 +836,13 @@ inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEn
|
||||||
<data key="d9"/>
|
<data key="d9"/>
|
||||||
<data key="d10">
|
<data key="d10">
|
||||||
<y:PolyLineEdge>
|
<y:PolyLineEdge>
|
||||||
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
<y:Path sx="0.0" sy="0.0" tx="-13.677119243026084" ty="44.9895375252479">
|
||||||
|
<y:Point x="282.63957015025017" y="1624.6814853696424"/>
|
||||||
|
<y:Point x="402.50587645722584" y="1481.6545842023272"/>
|
||||||
|
</y:Path>
|
||||||
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
<y:Arrows source="none" target="standard"/>
|
<y:Arrows source="none" target="standard"/>
|
||||||
<y:EdgeLabel alignment="center" anchorX="26.767035729346617" anchorY="-89.72842788087337" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="custom" ratio="0.5" textColor="#000000" upX="-0.9519459018107578" upY="-0.30626622410201093" verticalTextPosition="bottom" visible="true" width="50.236328125" x="7.400539492075577" xml:space="preserve" y="-143.7814096319475">open K2<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="true" ratio="0.5" segment="1"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="left|right" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
<y:EdgeLabel alignment="center" anchorX="42.26630925296365" anchorY="-95.71994547025815" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="custom" ratio="0.5" textColor="#000000" upX="-0.7664335365409145" upY="-0.6423236209772972" verticalTextPosition="bottom" visible="true" width="50.236328125" x="26.67389777947143" xml:space="preserve" y="-147.29025726298894">open K2<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="true" ratio="0.4999999999999997" segment="1"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="left|right" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
<y:BendStyle smoothed="false"/>
|
<y:BendStyle smoothed="false"/>
|
||||||
</y:PolyLineEdge>
|
</y:PolyLineEdge>
|
||||||
</data>
|
</data>
|
||||||
|
@ -839,10 +851,13 @@ inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEn
|
||||||
<data key="d9"/>
|
<data key="d9"/>
|
||||||
<data key="d10">
|
<data key="d10">
|
||||||
<y:PolyLineEdge>
|
<y:PolyLineEdge>
|
||||||
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
<y:Path sx="0.0" sy="0.0" tx="19.39352371895791" ty="45.01703178967159">
|
||||||
|
<y:Point x="770.2707053490758" y="1624.8477957198368"/>
|
||||||
|
<y:Point x="626.760131473005" y="1451.0534797665293"/>
|
||||||
|
</y:Path>
|
||||||
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
<y:Arrows source="none" target="standard"/>
|
<y:Arrows source="none" target="standard"/>
|
||||||
<y:EdgeLabel alignment="center" anchorX="-24.296235447239155" anchorY="-84.70970920941136" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="custom" ratio="0.5" textColor="#000000" upX="-0.8599279843359526" upY="0.5104153815823985" verticalTextPosition="bottom" visible="true" width="50.236328125" x="-67.43210324264501" xml:space="preserve" y="-127.90933359438213">open K2<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.5" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="left|right" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
<y:EdgeLabel alignment="center" anchorX="-38.53255297975011" anchorY="-123.76381877365907" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="custom" ratio="0.5" textColor="#000000" upX="-0.7710894922153189" upY="0.6367267820620722" verticalTextPosition="bottom" visible="true" width="50.236328125" x="-86.20650129732047" xml:space="preserve" y="-162.50052351832747">open K2<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.500000000000001" segment="1"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="left|right" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
<y:BendStyle smoothed="false"/>
|
<y:BendStyle smoothed="false"/>
|
||||||
</y:PolyLineEdge>
|
</y:PolyLineEdge>
|
||||||
</data>
|
</data>
|
||||||
|
@ -854,7 +869,7 @@ inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEn
|
||||||
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
<y:LineStyle color="#000000" type="dashed" width="1.0"/>
|
<y:LineStyle color="#000000" type="dashed" width="1.0"/>
|
||||||
<y:Arrows source="none" target="standard"/>
|
<y:Arrows source="none" target="standard"/>
|
||||||
<y:EdgeLabel alignment="center" anchorX="-15.439448720854557" anchorY="-96.96505251280405" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="custom" ratio="0.5" textColor="#000000" upX="-0.9905575559375823" upY="0.13709751410935023" verticalTextPosition="bottom" visible="true" width="55.984375" x="-43.26678350459801" xml:space="preserve" y="-152.42079818349714">K3 opens<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="true" ratio="0.5" segment="1"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="left|right" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
<y:EdgeLabel alignment="center" anchorX="-2.000030429546655" anchorY="-99.48622193119718" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="custom" ratio="0.5" textColor="#000000" upX="-1.0" upY="-6.123233995736766E-17" verticalTextPosition="bottom" visible="true" width="55.984375" x="-22.344144733135522" xml:space="preserve" y="-155.47059693119718">K3 opens<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="true" ratio="0.5" segment="1"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="left|right" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
<y:BendStyle smoothed="false"/>
|
<y:BendStyle smoothed="false"/>
|
||||||
</y:PolyLineEdge>
|
</y:PolyLineEdge>
|
||||||
</data>
|
</data>
|
||||||
|
@ -866,7 +881,7 @@ inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEn
|
||||||
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
<y:Arrows source="none" target="standard"/>
|
<y:Arrows source="none" target="standard"/>
|
||||||
<y:EdgeLabel alignment="center" anchorX="19.787500125521547" anchorY="-12.849807218343813" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="custom" ratio="0.5" textColor="#000000" upX="-0.9691516142140085" upY="0.24646530925544397" verticalTextPosition="bottom" visible="true" width="50.236328125" x="-12.310543238741985" xml:space="preserve" y="-61.53642571287216">open K2<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.5" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="left|right" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
<y:EdgeLabel alignment="center" anchorX="22.344083874042212" anchorY="-10.243393612998716" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="custom" ratio="0.5" textColor="#000000" upX="-1.0" upY="-6.123233995736766E-17" verticalTextPosition="bottom" visible="true" width="50.236328125" x="1.9999695704533451" xml:space="preserve" y="-60.479721737998716">open K2<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.5" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="left|right" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
<y:BendStyle smoothed="false"/>
|
<y:BendStyle smoothed="false"/>
|
||||||
</y:PolyLineEdge>
|
</y:PolyLineEdge>
|
||||||
</data>
|
</data>
|
||||||
|
@ -878,7 +893,7 @@ inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEn
|
||||||
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
<y:Arrows source="none" target="standard"/>
|
<y:Arrows source="none" target="standard"/>
|
||||||
<y:EdgeLabel alignment="center" anchorX="33.170622230079175" anchorY="-20.54894307703944" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="36.688228607177734" horizontalTextPosition="center" iconTextGap="4" modelName="custom" ratio="0.5" textColor="#000000" upX="-0.9113818501099502" upY="0.4115618098052396" verticalTextPosition="bottom" visible="true" width="54.13636779785156" x="-22.546824942353155" xml:space="preserve" y="-69.88784611887813">turn off
|
<y:EdgeLabel alignment="center" anchorX="38.68824303828478" anchorY="-8.293373776572935" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="36.688228607177734" horizontalTextPosition="center" iconTextGap="4" modelName="custom" ratio="0.5" textColor="#000000" upX="-1.0" upY="-6.123233995736766E-17" verticalTextPosition="bottom" visible="true" width="54.13636779785156" x="2.000014431107047" xml:space="preserve" y="-62.4297415744245">turn off
|
||||||
inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.5" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="left|right" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.5" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="left|right" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
<y:BendStyle smoothed="false"/>
|
<y:BendStyle smoothed="false"/>
|
||||||
</y:PolyLineEdge>
|
</y:PolyLineEdge>
|
||||||
|
@ -891,7 +906,7 @@ inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEn
|
||||||
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
<y:Arrows source="none" target="standard"/>
|
<y:Arrows source="none" target="standard"/>
|
||||||
<y:EdgeLabel alignment="center" anchorX="35.867743762755254" anchorY="-15.93315162786348" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="36.688228607177734" horizontalTextPosition="center" iconTextGap="4" modelName="custom" ratio="0.5" textColor="#000000" upX="-0.9691516142140085" upY="0.24646530925544397" verticalTextPosition="bottom" visible="true" width="54.13636779785156" x="-13.031448845807557" xml:space="preserve" y="-68.39949986683459">turn off
|
<y:EdgeLabel alignment="center" anchorX="38.68819817763108" anchorY="-8.293308863013408" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="36.688228607177734" horizontalTextPosition="center" iconTextGap="4" modelName="custom" ratio="0.5" textColor="#000000" upX="-1.0" upY="-6.123233995736766E-17" verticalTextPosition="bottom" visible="true" width="54.13636779785156" x="1.9999695704533451" xml:space="preserve" y="-62.42967666086497">turn off
|
||||||
inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.5" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="left|right" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.5" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="left|right" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
<y:BendStyle smoothed="false"/>
|
<y:BendStyle smoothed="false"/>
|
||||||
</y:PolyLineEdge>
|
</y:PolyLineEdge>
|
||||||
|
@ -914,7 +929,7 @@ inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEn
|
||||||
<data key="d10">
|
<data key="d10">
|
||||||
<y:PolyLineEdge>
|
<y:PolyLineEdge>
|
||||||
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||||
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
<y:LineStyle color="#000000" type="dashed" width="1.0"/>
|
||||||
<y:Arrows source="none" target="standard"/>
|
<y:Arrows source="none" target="standard"/>
|
||||||
<y:EdgeLabel alignment="center" anchorX="-24.918635525422495" anchorY="21.594702697511707" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="custom" ratio="0.5" textColor="#000000" upX="0.9937122098932426" upY="0.11196447610330804" verticalTextPosition="bottom" visible="true" width="55.984375" x="-31.18689674226863" xml:space="preserve" y="21.594702697511707">K1 opens<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.4999999999999979" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="left|right" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
<y:EdgeLabel alignment="center" anchorX="-24.918635525422495" anchorY="21.594702697511707" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="custom" ratio="0.5" textColor="#000000" upX="0.9937122098932426" upY="0.11196447610330804" verticalTextPosition="bottom" visible="true" width="55.984375" x="-31.18689674226863" xml:space="preserve" y="21.594702697511707">K1 opens<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.4999999999999979" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="left|right" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
<y:BendStyle smoothed="false"/>
|
<y:BendStyle smoothed="false"/>
|
||||||
|
@ -925,11 +940,14 @@ inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEn
|
||||||
<data key="d9"/>
|
<data key="d9"/>
|
||||||
<data key="d10">
|
<data key="d10">
|
||||||
<y:PolyLineEdge>
|
<y:PolyLineEdge>
|
||||||
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
|
||||||
|
<y:Point x="55.81460729275682" y="1523.820754474699"/>
|
||||||
|
<y:Point x="234.58612826807462" y="1404.8536338521308"/>
|
||||||
|
</y:Path>
|
||||||
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
<y:Arrows source="none" target="standard"/>
|
<y:Arrows source="none" target="standard"/>
|
||||||
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="36.688228607177734" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="54.13636779785156" x="67.5676531310973" xml:space="preserve" y="-100.68725537689579">turn off
|
<y:EdgeLabel alignment="center" anchorX="88.28491738649134" anchorY="-52.831225794193415" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="36.688228607177734" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" upX="-0.5540104212935304" upY="-0.832509731533611" verticalTextPosition="bottom" visible="true" width="54.13636779785156" x="67.95925639931545" xml:space="preserve" y="-113.36664507338794">turn off
|
||||||
inverters<y:LabelModel><y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/></y:LabelModel><y:ModelParameter><y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="36.32125205930789" distanceToCenter="true" position="right" ratio="0.5" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
inverters<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.5000000000000027" segment="1"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
<y:BendStyle smoothed="false"/>
|
<y:BendStyle smoothed="false"/>
|
||||||
</y:PolyLineEdge>
|
</y:PolyLineEdge>
|
||||||
</data>
|
</data>
|
||||||
|
@ -938,10 +956,13 @@ inverters<y:LabelModel><y:SmartEdgeLabelModel autoRotationEnabled="false" defaul
|
||||||
<data key="d9"/>
|
<data key="d9"/>
|
||||||
<data key="d10">
|
<data key="d10">
|
||||||
<y:PolyLineEdge>
|
<y:PolyLineEdge>
|
||||||
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
<y:Path sx="0.0" sy="0.0" tx="-12.103675434707498" ty="-0.8973455153978875">
|
||||||
|
<y:Point x="428.7937432135768" y="368.2394927091691"/>
|
||||||
|
<y:Point x="500.8846825648616" y="448.27634874029746"/>
|
||||||
|
</y:Path>
|
||||||
<y:LineStyle color="#000000" type="dashed" width="1.0"/>
|
<y:LineStyle color="#000000" type="dashed" width="1.0"/>
|
||||||
<y:Arrows source="none" target="standard"/>
|
<y:Arrows source="none" target="standard"/>
|
||||||
<y:EdgeLabel alignment="center" anchorX="-51.04636249792975" anchorY="85.707351023137" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="custom" ratio="0.5" textColor="#000000" upX="0.9519459018107576" upY="0.3062662241020115" verticalTextPosition="bottom" visible="true" width="58.68438720703125" x="-69.0194081815676" xml:space="preserve" y="85.707351023137">K3's open<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.5000000000000006" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="left|right" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
<y:EdgeLabel alignment="center" anchorX="-0.19439353507226542" anchorY="67.52807422348087" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="custom" ratio="0.5" textColor="#000000" upX="0.7430274178867984" upY="-0.669260977697398" verticalTextPosition="bottom" visible="true" width="58.68438720703125" x="-0.19439353507226542" xml:space="preserve" y="53.91255239427337">K3's open<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.5" segment="1"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="left|right" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
<y:BendStyle smoothed="false"/>
|
<y:BendStyle smoothed="false"/>
|
||||||
</y:PolyLineEdge>
|
</y:PolyLineEdge>
|
||||||
</data>
|
</data>
|
||||||
|
@ -949,10 +970,13 @@ inverters<y:LabelModel><y:SmartEdgeLabelModel autoRotationEnabled="false" defaul
|
||||||
<edge id="e31" source="n8" target="n2">
|
<edge id="e31" source="n8" target="n2">
|
||||||
<data key="d10">
|
<data key="d10">
|
||||||
<y:PolyLineEdge>
|
<y:PolyLineEdge>
|
||||||
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
|
||||||
|
<y:Point x="276.3712196468965" y="371.2720580009981"/>
|
||||||
|
<y:Point x="321.80474594577396" y="464.4058541099475"/>
|
||||||
|
</y:Path>
|
||||||
<y:LineStyle color="#000000" type="dashed" width="1.0"/>
|
<y:LineStyle color="#000000" type="dashed" width="1.0"/>
|
||||||
<y:Arrows source="none" target="delta"/>
|
<y:Arrows source="none" target="delta"/>
|
||||||
<y:EdgeLabel alignment="center" anchorX="7.546056019917529" anchorY="89.21761327127075" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="custom" ratio="0.5" textColor="#000000" upX="0.9438833303083674" upY="-0.3302790619551677" verticalTextPosition="bottom" visible="true" width="58.68438720703125" x="7.546056019917529" xml:space="preserve" y="82.4983782827727">K3's open<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.5" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="left|right" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
<y:EdgeLabel alignment="center" anchorX="-10.230074924814858" anchorY="67.35206739565979" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="20.344114303588867" horizontalTextPosition="center" iconTextGap="4" modelName="custom" ratio="0.5" textColor="#000000" upX="0.8987592955167517" upY="-0.43844238928533374" verticalTextPosition="bottom" visible="true" width="58.68438720703125" x="-10.230074924814858" xml:space="preserve" y="58.43234531250035">K3's open<y:LabelModel><y:RotatedSliderEdgeLabelModel angle="0.0" autoRotationEnabled="true" distance="2.0" distanceRelativeToEdge="true" mode="side_slider"/></y:LabelModel><y:ModelParameter><y:RotatedSliderEdgeLabelModelParameter invertingSign="false" ratio="0.5" segment="1"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" placement="center" side="left|right" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
<y:BendStyle smoothed="false"/>
|
<y:BendStyle smoothed="false"/>
|
||||||
</y:PolyLineEdge>
|
</y:PolyLineEdge>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
@ -4,3 +4,5 @@ Salimax001 ie-entwicklung@10.2.3.104
|
||||||
Salimax002 ie-entwicklung@10.2.4.29
|
Salimax002 ie-entwicklung@10.2.4.29
|
||||||
Salimax003 ie-entwicklung@10.2.4.33
|
Salimax003 ie-entwicklung@10.2.4.33
|
||||||
Salimax004 ie-entwicklung@10.2.4.32
|
Salimax004 ie-entwicklung@10.2.4.32
|
||||||
|
Salimax005 ie-entwicklung@10.2.4.36
|
||||||
|
Salimax006 ie-entwicklung@10.2.4.35
|
|
@ -18,5 +18,5 @@ echo -e "\n============================ Deploy ============================\n"
|
||||||
|
|
||||||
rsync -v \
|
rsync -v \
|
||||||
./bin/Release/$dotnet_version/linux-x64/publish/* \
|
./bin/Release/$dotnet_version/linux-x64/publish/* \
|
||||||
$username@$salimax_ip:~/salimax
|
$username@"$salimax_ip":~/salimax
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ using InnovEnergy.Lib.Devices.Battery48TL.DataTypes;
|
||||||
using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc;
|
using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc;
|
||||||
using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes;
|
using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes;
|
||||||
using InnovEnergy.Lib.Time.Unix;
|
using InnovEnergy.Lib.Time.Unix;
|
||||||
|
using InnovEnergy.Lib.Units;
|
||||||
using InnovEnergy.Lib.Utils;
|
using InnovEnergy.Lib.Utils;
|
||||||
|
|
||||||
namespace InnovEnergy.App.SaliMax.Ess;
|
namespace InnovEnergy.App.SaliMax.Ess;
|
||||||
|
@ -9,12 +10,13 @@ namespace InnovEnergy.App.SaliMax.Ess;
|
||||||
public static class Controller
|
public static class Controller
|
||||||
{
|
{
|
||||||
private static readonly UnixTimeSpan MaxTimeWithoutEoc = UnixTimeSpan.FromDays(7); // TODO: move to config
|
private static readonly UnixTimeSpan MaxTimeWithoutEoc = UnixTimeSpan.FromDays(7); // TODO: move to config
|
||||||
|
private static readonly Double BatteryHeatingPower = 200.0; // TODO: move to config
|
||||||
|
|
||||||
public static EssMode SelectControlMode(this StatusRecord s)
|
public static EssMode SelectControlMode(this StatusRecord s)
|
||||||
{
|
{
|
||||||
//return EssMode.OptimizeSelfConsumption;
|
//return EssMode.OptimizeSelfConsumption;
|
||||||
|
|
||||||
return s.StateMachine.State != 16 ? EssMode.Off
|
return s.StateMachine.State != 23 ? EssMode.Off
|
||||||
: s.MustHeatBatteries() ? EssMode.HeatBatteries
|
: s.MustHeatBatteries() ? EssMode.HeatBatteries
|
||||||
: s.MustDoCalibrationCharge() ? EssMode.CalibrationCharge
|
: s.MustDoCalibrationCharge() ? EssMode.CalibrationCharge
|
||||||
: s.MustReachMinSoc() ? EssMode.ReachMinSoc
|
: s.MustReachMinSoc() ? EssMode.ReachMinSoc
|
||||||
|
@ -25,9 +27,7 @@ public static class Controller
|
||||||
|
|
||||||
public static EssControl ControlEss(this StatusRecord s)
|
public static EssControl ControlEss(this StatusRecord s)
|
||||||
{
|
{
|
||||||
var mode = s.SelectControlMode();
|
var mode = s.SelectControlMode().WriteLine();
|
||||||
|
|
||||||
mode.WriteLine();
|
|
||||||
|
|
||||||
if (mode is EssMode.Off or EssMode.NoGridMeter)
|
if (mode is EssMode.Off or EssMode.NoGridMeter)
|
||||||
return EssControl.Default;
|
return EssControl.Default;
|
||||||
|
@ -85,7 +85,7 @@ public static class Controller
|
||||||
|
|
||||||
|
|
||||||
// find out if we reach the lower or upper Dc limit by comparing the current Dc voltage to the reference voltage
|
// find out if we reach the lower or upper Dc limit by comparing the current Dc voltage to the reference voltage
|
||||||
return s.AcDc.Dc.Voltage > s.Config.ReferenceDcBusVoltage
|
return s.AcDc.Dc.Voltage > s.Config.ReferenceDcLinkVoltageFromAcDc
|
||||||
? control with { PowerCorrection = clampedPowerDelta.ClampMax(-correction), LimitedBy = EssLimit.ChargeLimitedByMaxDcBusVoltage }
|
? control with { PowerCorrection = clampedPowerDelta.ClampMax(-correction), LimitedBy = EssLimit.ChargeLimitedByMaxDcBusVoltage }
|
||||||
: control with { PowerCorrection = clampedPowerDelta.ClampMin(correction), LimitedBy = EssLimit.DischargeLimitedByMinDcBusVoltage };
|
: control with { PowerCorrection = clampedPowerDelta.ClampMin(correction), LimitedBy = EssLimit.DischargeLimitedByMinDcBusVoltage };
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,19 @@ public static class Controller
|
||||||
|
|
||||||
private static Double MaxBatteryChargePower(this StatusRecord s)
|
private static Double MaxBatteryChargePower(this StatusRecord s)
|
||||||
{
|
{
|
||||||
return s.Battery.Devices.Sum(b => b.MaxChargePower);
|
// This introduce a limit when we don't have communication with batteries
|
||||||
|
// Otherwise the limit will be 0 and the batteries will be not heated
|
||||||
|
|
||||||
|
var maxChargePower = s.Config.Devices.BatteryNodes.Length * BatteryHeatingPower;
|
||||||
|
|
||||||
|
if (s.Battery.Devices.Count != 0)
|
||||||
|
{
|
||||||
|
maxChargePower = s.Battery.Devices.Sum(b => b.MaxChargePower);
|
||||||
|
}
|
||||||
|
|
||||||
|
maxChargePower.W().ToDisplayString().WriteLine(" Max Charge Power");
|
||||||
|
|
||||||
|
return maxChargePower;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Double CurrentPowerSetPoint(this StatusRecord s)
|
private static Double CurrentPowerSetPoint(this StatusRecord s)
|
||||||
|
|
|
@ -12,7 +12,9 @@ public static class Flow
|
||||||
private static readonly String DownArrowChar = "V";
|
private static readonly String DownArrowChar = "V";
|
||||||
private static readonly String UpArrowChar = "^";
|
private static readonly String UpArrowChar = "^";
|
||||||
|
|
||||||
public static TextBlock Horizontal(Unit amount, Int32 width = 10)
|
public static TextBlock Horizontal(Unit amount) => Horizontal(amount, 10);
|
||||||
|
|
||||||
|
public static TextBlock Horizontal(Unit amount, Int32 width)
|
||||||
{
|
{
|
||||||
var label = amount.ToDisplayString();
|
var label = amount.ToDisplayString();
|
||||||
var arrowChar = amount.Value < 0 ? LeftArrowChar : RightArrowChar;
|
var arrowChar = amount.Value < 0 ? LeftArrowChar : RightArrowChar;
|
||||||
|
@ -22,9 +24,11 @@ public static class Flow
|
||||||
return TextBlock.AlignCenterHorizontal(label, arrow, "");
|
return TextBlock.AlignCenterHorizontal(label, arrow, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static TextBlock Vertical(Unit amount) => Vertical(amount, 4);
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "PossibleMultipleEnumeration")]
|
[SuppressMessage("ReSharper", "PossibleMultipleEnumeration")]
|
||||||
[SuppressMessage("ReSharper", "CoVariantArrayConversion")]
|
[SuppressMessage("ReSharper", "CoVariantArrayConversion")]
|
||||||
public static TextBlock Vertical(Unit amount, Int32 height = 4)
|
public static TextBlock Vertical(Unit amount, Int32 height)
|
||||||
{
|
{
|
||||||
var label = amount.ToDisplayString();
|
var label = amount.ToDisplayString();
|
||||||
var arrowChar = amount.Value < 0 ? UpArrowChar : DownArrowChar;
|
var arrowChar = amount.Value < 0 ? UpArrowChar : DownArrowChar;
|
||||||
|
|
|
@ -18,15 +18,9 @@ public class CustomLogger : ILogger
|
||||||
_CurrentFileSizeBytes = File.Exists(logFilePath) ? new FileInfo(logFilePath).Length : 0;
|
_CurrentFileSizeBytes = File.Exists(logFilePath) ? new FileInfo(logFilePath).Length : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IDisposable? BeginScope<TState>(TState state) where TState : notnull
|
public IDisposable? BeginScope<TState>(TState state) where TState : notnull => throw new NotImplementedException();
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean IsEnabled(LogLevel logLevel)
|
public Boolean IsEnabled(LogLevel logLevel) => true; // Enable logging for all levels
|
||||||
{
|
|
||||||
return true; // Enable logging for all levels
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception, String> formatter)
|
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception, String> formatter)
|
||||||
{
|
{
|
||||||
|
@ -43,7 +37,7 @@ public class CustomLogger : ILogger
|
||||||
File.AppendAllText(_LogFilePath, logMessage + Environment.NewLine);
|
File.AppendAllText(_LogFilePath, logMessage + Environment.NewLine);
|
||||||
_CurrentFileSizeBytes += logMessage.Length;
|
_CurrentFileSizeBytes += logMessage.Length;
|
||||||
|
|
||||||
Console.WriteLine( logMessage + Environment.NewLine);
|
Console.WriteLine(logMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RotateLogFile()
|
private void RotateLogFile()
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Runtime.InteropServices;
|
using System.Reactive.Linq;
|
||||||
|
using System.Reactive.Threading.Tasks;
|
||||||
using Flurl.Http;
|
using Flurl.Http;
|
||||||
using InnovEnergy.App.SaliMax.Ess;
|
using InnovEnergy.App.SaliMax.Ess;
|
||||||
using InnovEnergy.App.SaliMax.SaliMaxRelays;
|
using InnovEnergy.App.SaliMax.SaliMaxRelays;
|
||||||
|
@ -13,10 +14,10 @@ using InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes;
|
||||||
using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc;
|
using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc;
|
||||||
using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes;
|
using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes;
|
||||||
using InnovEnergy.Lib.Devices.Trumpf.TruConvertDc;
|
using InnovEnergy.Lib.Devices.Trumpf.TruConvertDc;
|
||||||
|
using InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Control;
|
||||||
using InnovEnergy.Lib.Protocols.Modbus.Channels;
|
using InnovEnergy.Lib.Protocols.Modbus.Channels;
|
||||||
using InnovEnergy.Lib.Time.Unix;
|
using InnovEnergy.Lib.Time.Unix;
|
||||||
using InnovEnergy.Lib.Units;
|
using InnovEnergy.Lib.Units;
|
||||||
using InnovEnergy.Lib.Units.Power;
|
|
||||||
using InnovEnergy.Lib.Utils;
|
using InnovEnergy.Lib.Utils;
|
||||||
using static InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes.SystemConfig;
|
using static InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes.SystemConfig;
|
||||||
using AcPower = InnovEnergy.Lib.Units.Composite.AcPower;
|
using AcPower = InnovEnergy.Lib.Units.Composite.AcPower;
|
||||||
|
@ -28,10 +29,7 @@ namespace InnovEnergy.App.SaliMax;
|
||||||
|
|
||||||
internal static class Program
|
internal static class Program
|
||||||
{
|
{
|
||||||
[DllImport("libsystemd.so.0")]
|
private static readonly UnixTimeSpan UpdateInterval = UnixTimeSpan.FromSeconds(2);
|
||||||
private static extern Int32 sd_notify(Int32 unsetEnvironment, String state);
|
|
||||||
|
|
||||||
private const UInt32 UpdateIntervalSeconds = 2;
|
|
||||||
|
|
||||||
private static readonly IReadOnlyList<Byte> BatteryNodes;
|
private static readonly IReadOnlyList<Byte> BatteryNodes;
|
||||||
|
|
||||||
|
@ -82,8 +80,7 @@ internal static class Program
|
||||||
{
|
{
|
||||||
"Starting SaliMax".LogInfo();
|
"Starting SaliMax".LogInfo();
|
||||||
|
|
||||||
// Send the initial "service started" message to systemd
|
Watchdog.Ready();
|
||||||
var sdNotifyReturn = sd_notify(0, "READY=1");
|
|
||||||
|
|
||||||
var battery48TlDevices = BatteryNodes
|
var battery48TlDevices = BatteryNodes
|
||||||
.Select(n => new Battery48TlDevice(BatteriesChannel, n))
|
.Select(n => new Battery48TlDevice(BatteriesChannel, n))
|
||||||
|
@ -99,25 +96,12 @@ internal static class Program
|
||||||
|
|
||||||
StatusRecord ReadStatus()
|
StatusRecord ReadStatus()
|
||||||
{
|
{
|
||||||
"Reading AcDC".LogInfo();
|
|
||||||
var acDc = acDcDevices.Read();
|
|
||||||
|
|
||||||
"Reading dcDc".LogInfo();
|
|
||||||
var dcDc = dcDcDevices.Read();
|
|
||||||
|
|
||||||
"Reading battery".LogInfo();
|
|
||||||
var battery = batteryDevices.Read();
|
var battery = batteryDevices.Read();
|
||||||
|
var acDc = acDcDevices.Read();
|
||||||
"Reading relays".LogInfo();
|
var dcDc = dcDcDevices.Read();
|
||||||
var relays = saliMaxRelaysDevice.Read();
|
var relays = saliMaxRelaysDevice.Read();
|
||||||
|
|
||||||
"Reading loadOnAcIsland".LogInfo();
|
|
||||||
var loadOnAcIsland = acIslandLoadMeter.Read();
|
var loadOnAcIsland = acIslandLoadMeter.Read();
|
||||||
|
|
||||||
"Reading gridMeter".LogInfo();
|
|
||||||
var gridMeter = gridMeterDevice.Read();
|
var gridMeter = gridMeterDevice.Read();
|
||||||
|
|
||||||
"Reading pvOnDc".LogInfo();
|
|
||||||
var pvOnDc = amptDevice.Read();
|
var pvOnDc = amptDevice.Read();
|
||||||
|
|
||||||
var pvOnAcGrid = AcPowerDevice.Null;
|
var pvOnAcGrid = AcPowerDevice.Null;
|
||||||
|
@ -144,7 +128,6 @@ internal static class Program
|
||||||
|
|
||||||
var loadOnDc = new DcPowerDevice { Power = dcPower} ;
|
var loadOnDc = new DcPowerDevice { Power = dcPower} ;
|
||||||
|
|
||||||
|
|
||||||
return new StatusRecord
|
return new StatusRecord
|
||||||
{
|
{
|
||||||
AcDc = acDc ?? AcDcDevicesRecord.Null,
|
AcDc = acDc ?? AcDcDevicesRecord.Null,
|
||||||
|
@ -177,34 +160,40 @@ internal static class Program
|
||||||
dcDcDevices.Write(r.DcDc);
|
dcDcDevices.Write(r.DcDc);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Int32 delayTime = 10;
|
Console.WriteLine("press ctrl-c to stop");
|
||||||
|
|
||||||
Console.WriteLine("press ctrl-C to stop");
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
sd_notify(0, "WATCHDOG=1");
|
await Observable
|
||||||
|
.Interval(UpdateInterval.ToTimeSpan())
|
||||||
var t = UnixTime.Now;
|
.Select(_ => RunIteration())
|
||||||
while (t.Ticks % UpdateIntervalSeconds != 0)
|
.SelectMany(r => UploadCsv(r, UnixTime.Now.RoundTo(UpdateInterval)))
|
||||||
{
|
.SelectError()
|
||||||
await Task.Delay(delayTime);
|
.ToTask();
|
||||||
t = UnixTime.Now;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// var iterations = from _ in Observable.Interval(UpdateInterval.ToTimeSpan())
|
||||||
|
// let t = UnixTime.Now.RoundTo(UpdateInterval)
|
||||||
|
// let record = RunIteration()
|
||||||
|
// from uploaded in UploadCsv(record, t)
|
||||||
|
// select uploaded;
|
||||||
|
//
|
||||||
|
// using var running = iterations.Subscribe();
|
||||||
|
|
||||||
|
|
||||||
|
StatusRecord RunIteration()
|
||||||
|
{
|
||||||
|
Watchdog.Alive();
|
||||||
|
|
||||||
|
var t = UnixTime.Now;
|
||||||
var record = ReadStatus();
|
var record = ReadStatus();
|
||||||
|
|
||||||
if (record.Relays is not null)
|
|
||||||
record.Relays.ToCsv().LogInfo();
|
|
||||||
|
|
||||||
record.ControlConstants();
|
record.ControlConstants();
|
||||||
|
|
||||||
record.ControlSystemState();
|
record.ControlSystemState();
|
||||||
|
|
||||||
(t + "\n").LogInfo();
|
|
||||||
$"{record.StateMachine.State}: {record.StateMachine.Message}".LogInfo();
|
$"{record.StateMachine.State}: {record.StateMachine.Message}".LogInfo();
|
||||||
$"Batteries SOC: {record.Battery.Soc}".LogInfo();
|
|
||||||
var essControl = record.ControlEss().LogInfo();
|
var essControl = record.ControlEss().LogInfo();
|
||||||
|
|
||||||
record.EssControl = essControl;
|
record.EssControl = essControl;
|
||||||
|
@ -216,183 +205,23 @@ internal static class Program
|
||||||
|
|
||||||
WriteControl(record);
|
WriteControl(record);
|
||||||
|
|
||||||
PrintTopology(record);
|
Topology.From(record).WriteLine();
|
||||||
|
|
||||||
await UploadCsv(record, t);
|
//record.ToCsv().WriteLine();
|
||||||
|
|
||||||
|
//await UploadCsv(record, t);
|
||||||
|
|
||||||
record.Config.Save();
|
record.Config.Save();
|
||||||
|
|
||||||
"===========================================".LogInfo();
|
"===========================================".LogInfo();
|
||||||
|
|
||||||
|
return record;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReSharper disable once FunctionNeverReturns
|
// ReSharper disable once FunctionNeverReturns
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void PrintTopology(StatusRecord s)
|
|
||||||
{
|
|
||||||
// Power Measurement Values
|
|
||||||
var gridPower = s.GridMeter is not null ? s.GridMeter!.Ac.Power.Active : 0;
|
|
||||||
var inverterPower = s.AcDc.Ac.Power.Active;
|
|
||||||
var islandLoadPower = s.LoadOnAcIsland is not null ? s.LoadOnAcIsland.Ac.Power.Active : 0;
|
|
||||||
var dcBatteryPower = s.DcDc.Dc.Battery.Power;
|
|
||||||
var dcdcPower = s.DcDc.Dc.Link.Power;
|
|
||||||
var pvOnDcPower = s.PvOnDc.Dc!.Power.Value;
|
|
||||||
|
|
||||||
// Power Calculated Values
|
|
||||||
var islandToGridBusPower = inverterPower + islandLoadPower;
|
|
||||||
var gridLoadPower = s.LoadOnAcGrid is null ? 0: s.LoadOnAcGrid.Power.Active;
|
|
||||||
|
|
||||||
TextBlock gridBusColumn;
|
|
||||||
TextBlock gridBox;
|
|
||||||
TextBlock totalBoxes;
|
|
||||||
|
|
||||||
|
|
||||||
if (s.GridMeter is not null)
|
|
||||||
{
|
|
||||||
var gridPowerByPhase = TextBlock.AlignLeft(s.GridMeter.Ac.L1.Power.Active.ToDisplayString(),
|
|
||||||
s.GridMeter.Ac.L2.Power.Active.ToDisplayString(),
|
|
||||||
s.GridMeter.Ac.L3.Power.Active.ToDisplayString());
|
|
||||||
|
|
||||||
var gridVoltageByPhase = TextBlock.AlignLeft(s.GridMeter.Ac.L1.Voltage.ToDisplayString(),
|
|
||||||
s.GridMeter.Ac.L2.Voltage.ToDisplayString(),
|
|
||||||
s.GridMeter.Ac.L3.Voltage.ToDisplayString());
|
|
||||||
|
|
||||||
gridBusColumn = ColumnBox("Pv", "Grid Bus", "Load" , gridVoltageByPhase , gridLoadPower);
|
|
||||||
gridBox = TextBlock.AlignLeft(gridPowerByPhase).TitleBox("Grid");
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gridBusColumn = TextBlock.Spacer(0);
|
|
||||||
gridBox = TextBlock.Spacer(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var inverterPowerByPhase = TextBlock.AlignLeft(s.AcDc.Ac.L1.Power.Active.ToDisplayString(),
|
|
||||||
s.AcDc.Ac.L2.Power.Active.ToDisplayString(),
|
|
||||||
s.AcDc.Ac.L3.Power.Active.ToDisplayString());
|
|
||||||
|
|
||||||
// ReSharper disable once CoVariantArrayConversion
|
|
||||||
var inverterPowerByAcDc = TextBlock.AlignLeft(s.AcDc.Devices
|
|
||||||
.Select(s1 => s1.Status.Ac.Power)
|
|
||||||
.ToArray());
|
|
||||||
|
|
||||||
var dcLinkVoltage = TextBlock.AlignCenterHorizontal("",
|
|
||||||
s.DcDc.Dc.Link.Voltage.ToDisplayString(),
|
|
||||||
"");
|
|
||||||
|
|
||||||
var dc48Voltage = s.DcDc.Dc.Battery.Voltage.ToDisplayString();
|
|
||||||
var batteryVoltage = s.Battery.Dc.Voltage.Value.RoundToSignificantDigits(3);
|
|
||||||
var batterySoc = s.Battery.Devices.Any()? s.Battery.Devices.Average(b=>b.Soc).Percent().ToDisplayString() : "0";
|
|
||||||
var batteryCurrent = s.Battery.Dc.Current.ToDisplayString();
|
|
||||||
var batteryTemp = s.Battery.Temperature.ToDisplayString();
|
|
||||||
var batteryHeatingCurrent = s.Battery.HeatingCurrent.ToDisplayString();
|
|
||||||
var anyBatteryAlarm = s.Battery.Alarms.Any();
|
|
||||||
var anyBatteryWarning = s.Battery.Warnings.Any();
|
|
||||||
|
|
||||||
var islandBusColumn = ColumnBox("Pv", "Island Bus", "Load" , inverterPowerByPhase, islandLoadPower);
|
|
||||||
var dcBusColumn = ColumnBox("Pv", "Dc Bus", "Load" , dcLinkVoltage, 0, pvOnDcPower);
|
|
||||||
var gridBusFlow = Flow.Horizontal(gridPower);
|
|
||||||
var flowGridBusToIslandBus = Flow.Horizontal((ActivePower)islandToGridBusPower);
|
|
||||||
var flowIslandBusToInverter = Flow.Horizontal(inverterPower);
|
|
||||||
var flowInverterToDcBus = Flow.Horizontal(inverterPower);
|
|
||||||
var flowDcBusToDcDc = Flow.Horizontal(dcdcPower);
|
|
||||||
var flowDcDcToBattery = Flow.Horizontal(dcBatteryPower);
|
|
||||||
|
|
||||||
var inverterBox = TextBlock.AlignLeft(inverterPowerByAcDc).TitleBox("AC/DC");
|
|
||||||
var dcDcBox = TextBlock.AlignLeft(dc48Voltage).TitleBox("DC/DC");
|
|
||||||
var batteryAvgBox = TextBlock.AlignLeft(batteryVoltage,
|
|
||||||
batterySoc,
|
|
||||||
batteryCurrent,
|
|
||||||
batteryTemp,
|
|
||||||
batteryHeatingCurrent,
|
|
||||||
anyBatteryWarning,
|
|
||||||
anyBatteryAlarm)
|
|
||||||
.TitleBox("Battery");
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////// Batteries /////////////////////////
|
|
||||||
|
|
||||||
IReadOnlyList<TextBlock> batteryBoxes = s.Battery
|
|
||||||
.Devices
|
|
||||||
.Select(CreateIndividualBattery)
|
|
||||||
.ToArray(s.Battery.Devices.Count);
|
|
||||||
|
|
||||||
var individualBatteries = batteryBoxes.Any()
|
|
||||||
? TextBlock.AlignLeft(batteryBoxes)
|
|
||||||
: TextBlock.Spacer(1);
|
|
||||||
|
|
||||||
if (s.GridMeter is not null)
|
|
||||||
{
|
|
||||||
totalBoxes = TextBlock.AlignCenterVertical(gridBox,
|
|
||||||
gridBusFlow,
|
|
||||||
gridBusColumn,
|
|
||||||
flowGridBusToIslandBus,
|
|
||||||
islandBusColumn,
|
|
||||||
flowIslandBusToInverter,
|
|
||||||
inverterBox,
|
|
||||||
flowInverterToDcBus,
|
|
||||||
dcBusColumn,
|
|
||||||
flowDcBusToDcDc,
|
|
||||||
dcDcBox,
|
|
||||||
flowDcDcToBattery,
|
|
||||||
batteryAvgBox,
|
|
||||||
individualBatteries);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
totalBoxes = TextBlock.AlignCenterVertical(
|
|
||||||
islandBusColumn,
|
|
||||||
flowIslandBusToInverter,
|
|
||||||
inverterBox,
|
|
||||||
flowInverterToDcBus,
|
|
||||||
dcBusColumn,
|
|
||||||
flowDcBusToDcDc,
|
|
||||||
dcDcBox,
|
|
||||||
flowDcDcToBattery,
|
|
||||||
batteryAvgBox,
|
|
||||||
individualBatteries);
|
|
||||||
}
|
|
||||||
|
|
||||||
totalBoxes.WriteLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static TextBlock CreateIndividualBattery(Battery48TlRecord battery, Int32 i)
|
|
||||||
{
|
|
||||||
var batteryWarnings = battery.Warnings.Any();
|
|
||||||
var batteryAlarms = battery.Alarms.Any();
|
|
||||||
|
|
||||||
var content = TextBlock.AlignLeft(battery.Dc.Voltage.ToDisplayString(),
|
|
||||||
battery.Soc.ToDisplayString(),
|
|
||||||
battery.Dc.Current.ToDisplayString(),
|
|
||||||
battery.Temperatures.Cells.Average.ToDisplayString(),
|
|
||||||
// battery.BusCurrent.ToDisplayString(),
|
|
||||||
battery.HeatingCurrent.ToDisplayString(),
|
|
||||||
batteryWarnings,
|
|
||||||
batteryAlarms);
|
|
||||||
|
|
||||||
var box = content.TitleBox($"Battery {i + 1}");
|
|
||||||
|
|
||||||
var flow = Flow.Horizontal(battery.Dc.Power);
|
|
||||||
|
|
||||||
return TextBlock.AlignCenterVertical(flow, box);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static TextBlock ColumnBox(String pvTitle, String busTitle, String loadTitle, TextBlock dataBox, ActivePower loadPower)
|
|
||||||
{
|
|
||||||
return ColumnBox(pvTitle, busTitle, loadTitle, dataBox, loadPower, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static TextBlock ColumnBox(String pvTitle, String busTitle, String loadTitle, TextBlock dataBox, ActivePower loadPower, ActivePower pvPower)
|
|
||||||
{
|
|
||||||
var pvBox = TextBlock.FromString(pvTitle).Box();
|
|
||||||
var pvToBus = Flow.Vertical(pvPower);
|
|
||||||
var busBox = TextBlock.AlignLeft(dataBox).TitleBox(busTitle);
|
|
||||||
var busToLoad = Flow.Vertical(loadPower);
|
|
||||||
var loadBox = TextBlock.FromString(loadTitle).Box();
|
|
||||||
|
|
||||||
return TextBlock.AlignCenterHorizontal(pvBox, pvToBus, busBox, busToLoad, loadBox);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async Task<T?> ResultOrNull<T>(this Task<T> task)
|
private static async Task<T?> ResultOrNull<T>(this Task<T> task)
|
||||||
{
|
{
|
||||||
|
@ -407,13 +236,19 @@ internal static class Program
|
||||||
var inverters = r.AcDc.Devices;
|
var inverters = r.AcDc.Devices;
|
||||||
var dcDevices = r.DcDc.Devices;
|
var dcDevices = r.DcDc.Devices;
|
||||||
|
|
||||||
inverters.ForEach(d => d.Control.Dc.MaxVoltage = r.Config.MaxDcBusVoltage);
|
inverters.ForEach(d => d.Control.Dc.MaxVoltage = r.Config.MaxDcLinkVoltageFromAcDc);
|
||||||
inverters.ForEach(d => d.Control.Dc.MinVoltage = r.Config.MinDcBusVoltage);
|
inverters.ForEach(d => d.Control.Dc.MinVoltage = r.Config.MinDcLinkVoltageFromAcDc);
|
||||||
inverters.ForEach(d => d.Control.Dc.ReferenceVoltage = r.Config.ReferenceDcBusVoltage);
|
inverters.ForEach(d => d.Control.Dc.ReferenceVoltage = r.Config.ReferenceDcLinkVoltageFromAcDc);
|
||||||
|
inverters.ForEach(d => d.Control.Dc.PrechargeConfig = DcPrechargeConfig.PrechargeDcWithInternal);
|
||||||
|
|
||||||
// dcDevices.ForEach(d => d.Control. Dc.MaxVoltage = r.Config.MaxDcBusVoltage);
|
dcDevices.ForEach(d => d.Control.DroopControl.UpperVoltage = r.Config.UpperDcLinkVoltageFromDc);
|
||||||
// dcDevices.ForEach(d => d.Control. Dc.MinVoltage = r.Config.MinDcBusVoltage);
|
dcDevices.ForEach(d => d.Control.DroopControl.LowerVoltage = r.Config.LowerDcLinkVoltageFromDc);
|
||||||
// dcDevices.ForEach(d => d.Control. Dc.ReferenceVoltage = r.Config.ReferenceDcBusVoltage);
|
dcDevices.ForEach(d => d.Control.DroopControl.ReferenceVoltage = r.Config.ReferenceDcLinkVoltageFromDc);
|
||||||
|
dcDevices.ForEach(d => d.Control.CurrentControl.MaxBatteryChargingCurrent = r.Config.MaxBatteryChargingCurrent);
|
||||||
|
dcDevices.ForEach(d => d.Control.CurrentControl.MaxBatteryDischargingCurrent = r.Config.MaxBatteryDischargingCurrent);
|
||||||
|
dcDevices.ForEach(d => d.Control.VoltageLimits.MaxBatteryVoltage = r.Config.MaxChargeBatteryVoltage);
|
||||||
|
dcDevices.ForEach(d => d.Control.VoltageLimits.MinBatteryVoltage = r.Config.MinDischargeBatteryVoltage);
|
||||||
|
dcDevices.ForEach(d => d.Control.ControlMode = DcControlMode.VoltageDroop);
|
||||||
|
|
||||||
r.DcDc.ResetAlarms();
|
r.DcDc.ResetAlarms();
|
||||||
r.AcDc.ResetAlarms();
|
r.AcDc.ResetAlarms();
|
||||||
|
@ -483,11 +318,11 @@ internal static class Program
|
||||||
sc.ResetAlarmsAndWarnings = true;
|
sc.ResetAlarmsAndWarnings = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task UploadCsv(StatusRecord status, UnixTime timeStamp)
|
private static async Task<Boolean> UploadCsv(StatusRecord status, UnixTime timeStamp)
|
||||||
{
|
{
|
||||||
var s3Config = status.Config.S3;
|
var s3Config = status.Config.S3;
|
||||||
if (s3Config is null)
|
if (s3Config is null)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
var csv = status.ToCsv();
|
var csv = status.ToCsv();
|
||||||
var s3Path = timeStamp + ".csv";
|
var s3Path = timeStamp + ".csv";
|
||||||
|
@ -500,6 +335,7 @@ internal static class Program
|
||||||
var error = response.GetStringAsync();
|
var error = response.GetStringAsync();
|
||||||
Console.WriteLine(error);
|
Console.WriteLine(error);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
using InnovEnergy.App.SaliMax.Ess;
|
using InnovEnergy.App.SaliMax.Ess;
|
||||||
using InnovEnergy.App.SaliMax.SaliMaxRelays;
|
using InnovEnergy.App.SaliMax.SaliMaxRelays;
|
||||||
using InnovEnergy.Lib.Devices.Battery48TL;
|
|
||||||
using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc;
|
using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc;
|
||||||
using InnovEnergy.Lib.Devices.Trumpf.TruConvertDc;
|
using InnovEnergy.Lib.Devices.Trumpf.TruConvertDc;
|
||||||
using static InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes.GridType;
|
using static InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes.GridType;
|
||||||
|
@ -21,13 +20,17 @@ public static class Controller
|
||||||
if (acDcs.NotAvailable())
|
if (acDcs.NotAvailable())
|
||||||
return 102;
|
return 102;
|
||||||
|
|
||||||
var k4 = acDcs.AllDisabled() ? 0
|
|
||||||
: acDcs.AllGridTied() ? 1
|
var k4 = acDcs.AllGridTied() ? 0
|
||||||
: acDcs.AllIsland() ? 2
|
: acDcs.AllIsland() ? 1
|
||||||
: 4;
|
: 4;
|
||||||
|
|
||||||
if (k4 == 4)
|
var k5 = acDcs.AllDisabled() ? 0
|
||||||
return 103; //Message = "Panic: ACDCs have unequal grid types",
|
: acDcs.AllEnabled() ? 1
|
||||||
|
: 4;
|
||||||
|
|
||||||
|
if (k4 == 4 || k5 == 4)
|
||||||
|
return 103; //Message = "Panic: ACDCs have unequal grid types or power stage",
|
||||||
|
|
||||||
var nInverters = r.AcDc.Devices.Count;
|
var nInverters = r.AcDc.Devices.Count;
|
||||||
|
|
||||||
|
@ -36,11 +39,11 @@ public static class Controller
|
||||||
var k3 = relays.K3InverterIsConnectedToIslandBus.Take(nInverters).Any(c => c) ? 1 : 0;
|
var k3 = relays.K3InverterIsConnectedToIslandBus.Take(nInverters).Any(c => c) ? 1 : 0;
|
||||||
|
|
||||||
// states as defined in states excel sheet
|
// states as defined in states excel sheet
|
||||||
return 1
|
return 1 * k1
|
||||||
+ 1*k1
|
|
||||||
+ 2 * k2
|
+ 2 * k2
|
||||||
+ 4 * k3
|
+ 4 * k3
|
||||||
+ 8*k4;
|
+ 8 * k4
|
||||||
|
+ 16 * k5;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean ControlSystemState(this StatusRecord s)
|
public static Boolean ControlSystemState(this StatusRecord s)
|
||||||
|
@ -49,19 +52,21 @@ public static class Controller
|
||||||
|
|
||||||
return s.StateMachine.State switch
|
return s.StateMachine.State switch
|
||||||
{
|
{
|
||||||
|
0 => State0(s),
|
||||||
1 => State1(s),
|
1 => State1(s),
|
||||||
2 => State2(s),
|
3 => State3(s),
|
||||||
4 => State4(s),
|
4 => State4(s),
|
||||||
6 => State6(s),
|
6 => State6(s),
|
||||||
|
8 => State8(s),
|
||||||
9 => State9(s),
|
9 => State9(s),
|
||||||
//10 => State10(s),
|
|
||||||
12 => State12(s),
|
|
||||||
13 => State13(s),
|
13 => State13(s),
|
||||||
15 => State15(s),
|
19 => State19(s),
|
||||||
16 => State16(s),
|
22 => State22(s),
|
||||||
17 => State17(s),
|
23 => State23(s),
|
||||||
18 => State18(s),
|
24 => State24(s),
|
||||||
21 => State21(s),
|
28 => State28(s),
|
||||||
|
29 => State29(s),
|
||||||
|
|
||||||
|
|
||||||
101 => State101(s),
|
101 => State101(s),
|
||||||
102 => State102(s),
|
102 => State102(s),
|
||||||
|
@ -76,130 +81,69 @@ public static class Controller
|
||||||
return acDcs.SystemControl == null || acDcs.Devices.Count == 0;
|
return acDcs.SystemControl == null || acDcs.Devices.Count == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Boolean NotAvailable(this DcDcDevicesRecord dcDcs)
|
private static Boolean State0(StatusRecord s)
|
||||||
{
|
{
|
||||||
return dcDcs.SystemControl == null || dcDcs.Devices.Count == 0;
|
s.StateMachine.Message = "Ac/Dc are off. Switching to Island Mode.";
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static Boolean NotAvailable(this Battery48TlRecords batteries)
|
|
||||||
{
|
|
||||||
return batteries.Devices.Count <= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Boolean State1(StatusRecord s)
|
|
||||||
{
|
|
||||||
s.StateMachine.Message = "Inverters are off. Switching to Island Mode.";
|
|
||||||
|
|
||||||
s.DcDc.Enable();
|
|
||||||
s.AcDc.Enable();
|
|
||||||
s.AcDc.EnableIslandMode();
|
|
||||||
s.Relays.DisconnectIslandBusFromGrid();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// => 17
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Boolean State2(StatusRecord s)
|
|
||||||
{
|
|
||||||
s.StateMachine.Message = "Inverters are disconnected from Island Bus. Switching to GridTie Mode. C";
|
|
||||||
|
|
||||||
s.DcDc.Disable();
|
|
||||||
s.AcDc.Disable();
|
|
||||||
s.AcDc.EnableGridTieMode();
|
|
||||||
s.Relays.ConnectIslandBusToGrid();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// => 10
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Boolean State4(StatusRecord s)
|
|
||||||
{
|
|
||||||
s.StateMachine.Message = "Turning on Inverters";
|
|
||||||
|
|
||||||
s.DcDc.Enable();
|
|
||||||
s.AcDc.Enable();
|
|
||||||
s.AcDc.EnableGridTieMode();
|
|
||||||
s.Relays.ConnectIslandBusToGrid();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// => 12
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static Boolean State6(StatusRecord s)
|
|
||||||
{
|
|
||||||
s.StateMachine.Message = "Inverters are off. Waiting for them to disconnect from Island Bus.";
|
|
||||||
|
|
||||||
s.DcDc.Disable();
|
s.DcDc.Disable();
|
||||||
s.AcDc.Disable();
|
s.AcDc.Disable();
|
||||||
s.AcDc.EnableIslandMode();
|
s.AcDc.EnableIslandMode();
|
||||||
s.Relays.DisconnectIslandBusFromGrid();
|
s.Relays.DisconnectIslandBusFromGrid();
|
||||||
|
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
// => 2
|
// => 8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static Boolean State9(StatusRecord s)
|
private static Boolean State9(StatusRecord s)
|
||||||
{
|
{
|
||||||
|
s.StateMachine.Message = "Ac/Dc are disconnected from Island Bus. Switching to GridTie Mode.";
|
||||||
|
|
||||||
s.StateMachine.Message = "Inverters have disconnected from Island Bus. Turning them off.";
|
s.DcDc.Disable();
|
||||||
|
|
||||||
s.DcDc.Disable(); // TODO: leave enabled?
|
|
||||||
s.AcDc.Disable();
|
s.AcDc.Disable();
|
||||||
s.AcDc.EnableGridTieMode();
|
s.AcDc.EnableGridTieMode();
|
||||||
s.Relays.DisconnectIslandBusFromGrid();
|
s.Relays.DisconnectIslandBusFromGrid();
|
||||||
|
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
// => 1
|
// => 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Boolean State1(StatusRecord s)
|
||||||
//
|
|
||||||
// private static Boolean State10(StatusRecord s)
|
|
||||||
// {
|
|
||||||
//
|
|
||||||
// s.SystemState.Message = "Inverters have disconnected from AcOut. Turning them off.";
|
|
||||||
//
|
|
||||||
// s.DcDc.Disable(); // TODO: leave enabled?
|
|
||||||
// s.AcDc.Disable();
|
|
||||||
// s.AcDc.EnableGridTieMode();
|
|
||||||
// s.Relays.DisconnectIslandBusFromGrid();
|
|
||||||
//
|
|
||||||
// return true;
|
|
||||||
//
|
|
||||||
// // => 12
|
|
||||||
// }
|
|
||||||
|
|
||||||
private static Boolean State12(StatusRecord s)
|
|
||||||
{
|
{
|
||||||
s.StateMachine.Message = "Waiting for Inverters to connect to Island Bus";
|
s.StateMachine.Message = "Grid Tied mode active, closing k2";
|
||||||
|
|
||||||
|
s.DcDc.Disable();
|
||||||
|
s.AcDc.Disable();
|
||||||
|
s.AcDc.EnableGridTieMode();
|
||||||
|
s.Relays.ConnectIslandBusToGrid();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// => 3
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Boolean State3(StatusRecord s)
|
||||||
|
{
|
||||||
|
s.StateMachine.Message = "K2 closed, Turning on Ac/Dc";
|
||||||
|
|
||||||
s.DcDc.Enable();
|
s.DcDc.Enable();
|
||||||
s.AcDc.Enable();
|
s.AcDc.Enable();
|
||||||
s.AcDc.EnableGridTieMode();
|
s.AcDc.EnableGridTieMode();
|
||||||
s.Relays.ConnectIslandBusToGrid();
|
s.Relays.ConnectIslandBusToGrid();
|
||||||
|
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
// => 16
|
// => 19
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static Boolean State13(StatusRecord s)
|
private static Boolean State13(StatusRecord s)
|
||||||
{
|
{
|
||||||
s.StateMachine.Message = "Disconnected from AcIn (K2), awaiting inverters to disconnect from AcOut (K3)";
|
s.StateMachine.Message = "Ac/Dc are off. Waiting for them to disconnect from Island Bus.";
|
||||||
|
|
||||||
s.DcDc.Enable();
|
s.DcDc.Disable();
|
||||||
s.AcDc.Enable();
|
s.AcDc.Disable();
|
||||||
s.AcDc.EnableGridTieMode();
|
s.AcDc.EnableIslandMode();
|
||||||
s.Relays.DisconnectIslandBusFromGrid();
|
s.Relays.DisconnectIslandBusFromGrid();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -207,32 +151,11 @@ public static class Controller
|
||||||
// => 9
|
// => 9
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Boolean State15(StatusRecord s)
|
|
||||||
|
|
||||||
|
private static Boolean State19(StatusRecord s)
|
||||||
{
|
{
|
||||||
s.StateMachine.Message = "Grid has been lost, disconnecting AcIn from AcOut (K2)";
|
s.StateMachine.Message = "Waiting for Ac/Dc to connect to Island Bus";
|
||||||
|
|
||||||
s.DcDc.Enable();
|
|
||||||
s.AcDc.Enable();
|
|
||||||
s.AcDc.EnableGridTieMode();
|
|
||||||
s.Relays.DisconnectIslandBusFromGrid();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// => 13
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Boolean State16(StatusRecord s)
|
|
||||||
{
|
|
||||||
// return new
|
|
||||||
// (
|
|
||||||
// " Inverter is in grid-tie\n Waiting for K1AcInIsConnectedToGrid to open to leave it",
|
|
||||||
// AcPowerStageEnable: true,
|
|
||||||
// DcPowerStageEnable: true,
|
|
||||||
// GridType.GridTied400V50Hz,
|
|
||||||
// HighActivePinState.Closed
|
|
||||||
// );
|
|
||||||
|
|
||||||
s.StateMachine.Message = "ESS";
|
|
||||||
|
|
||||||
s.DcDc.Enable();
|
s.DcDc.Enable();
|
||||||
s.AcDc.Enable();
|
s.AcDc.Enable();
|
||||||
|
@ -241,62 +164,99 @@ public static class Controller
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// => 15
|
// => 23
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static Boolean State17(StatusRecord s)
|
private static Boolean State23(StatusRecord s)
|
||||||
{
|
{
|
||||||
s.StateMachine.Message = "Inverters are in Island Mode. Waiting for them to connect to AcIn.";
|
s.StateMachine.Message = "ESS";
|
||||||
|
|
||||||
s.DcDc.Enable();
|
s.DcDc.Enable();
|
||||||
s.AcDc.Enable();
|
s.AcDc.Enable();
|
||||||
s.AcDc.EnableIslandMode();
|
s.AcDc.EnableGridTieMode();
|
||||||
s.Relays.DisconnectIslandBusFromGrid();
|
s.EnableDcLinkGridTie();
|
||||||
|
s.Relays.ConnectIslandBusToGrid();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// => 21
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static Boolean State18(StatusRecord s)
|
|
||||||
{
|
|
||||||
// return new
|
|
||||||
// (
|
|
||||||
// " Didn't succeed to go to Island mode and K1AcInIsConnectedToGrid close\n Turning off power stage of inverter\n Moving to Grid Tie",
|
|
||||||
// AcPowerStageEnable: false,
|
|
||||||
// DcPowerStageEnable: false,
|
|
||||||
// GridType.GridTied400V50Hz,
|
|
||||||
// HighActivePinState.Open
|
|
||||||
// );
|
|
||||||
|
|
||||||
s.DcDc.Disable();
|
|
||||||
s.AcDc.Disable();
|
|
||||||
s.AcDc.EnableIslandMode();
|
|
||||||
s.Relays.DisconnectIslandBusFromGrid();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Boolean State21(StatusRecord s)
|
|
||||||
{
|
|
||||||
s.StateMachine.Message = "Island Mode";
|
|
||||||
|
|
||||||
s.DcDc.Enable();
|
|
||||||
s.AcDc.Enable();
|
|
||||||
s.AcDc.EnableIslandMode();
|
|
||||||
s.Relays.DisconnectIslandBusFromGrid();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// => 22
|
// => 22
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Boolean State22(StatusRecord s)
|
private static Boolean State22(StatusRecord s)
|
||||||
{
|
{
|
||||||
s.StateMachine.Message = "Grid became available (K1). Turning off inverters.";
|
s.StateMachine.Message = "K1 opened, switching inverters off";
|
||||||
|
|
||||||
|
s.DcDc.Disable();
|
||||||
|
s.AcDc.Disable();
|
||||||
|
s.AcDc.EnableGridTieMode();
|
||||||
|
s.Relays.ConnectIslandBusToGrid();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// => 6
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static Boolean State6(StatusRecord s)
|
||||||
|
{
|
||||||
|
s.StateMachine.Message = "Inverters are off, opening K2";
|
||||||
|
|
||||||
|
s.DcDc.Disable();
|
||||||
|
s.AcDc.Disable();
|
||||||
|
s.AcDc.EnableGridTieMode();
|
||||||
|
s.Relays.DisconnectIslandBusFromGrid();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// => 4
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Boolean State4(StatusRecord s)
|
||||||
|
{
|
||||||
|
s.StateMachine.Message = "K2 is open, waiting K3 to open";
|
||||||
|
|
||||||
|
s.DcDc.Disable();
|
||||||
|
s.AcDc.Disable();
|
||||||
|
s.AcDc.EnableGridTieMode();
|
||||||
|
s.Relays.DisconnectIslandBusFromGrid();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// => 0
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Boolean State8(StatusRecord s)
|
||||||
|
{
|
||||||
|
s.StateMachine.Message = "Ac/Dc are off and in Island Mode.";
|
||||||
|
|
||||||
|
s.DcDc.Enable();
|
||||||
|
s.AcDc.Enable();
|
||||||
|
s.AcDc.EnableIslandMode();
|
||||||
|
s.Relays.DisconnectIslandBusFromGrid();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
// => 24
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Boolean State28(StatusRecord s)
|
||||||
|
{
|
||||||
|
s.StateMachine.Message = "Island Mode";
|
||||||
|
|
||||||
|
s.DcDc.Enable();
|
||||||
|
s.AcDc.Enable();
|
||||||
|
s.AcDc.EnableIslandMode();
|
||||||
|
s.EnableDcLinkIslandMode();
|
||||||
|
s.Relays.DisconnectIslandBusFromGrid();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// => 29
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Boolean State29(StatusRecord s)
|
||||||
|
{
|
||||||
|
s.StateMachine.Message = "K1 closed, Switching off Inverters and moving to grid tie";
|
||||||
|
|
||||||
s.DcDc.Disable();
|
s.DcDc.Disable();
|
||||||
s.AcDc.Disable();
|
s.AcDc.Disable();
|
||||||
|
@ -305,12 +265,22 @@ public static class Controller
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// => 6
|
// => 13
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Boolean State24(StatusRecord s)
|
||||||
|
{
|
||||||
|
s.StateMachine.Message = "Inverter are on waiting for k3 to close";
|
||||||
|
|
||||||
|
s.DcDc.Enable();
|
||||||
|
s.AcDc.Enable();
|
||||||
|
s.AcDc.EnableIslandMode();
|
||||||
|
s.Relays.DisconnectIslandBusFromGrid();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// => 28
|
||||||
|
}
|
||||||
|
|
||||||
private static Boolean State101(StatusRecord s)
|
private static Boolean State101(StatusRecord s)
|
||||||
{
|
{
|
||||||
|
@ -324,24 +294,22 @@ public static class Controller
|
||||||
return s.EnableSafeDefaults();
|
return s.EnableSafeDefaults();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static Boolean State103(StatusRecord s)
|
private static Boolean State103(StatusRecord s)
|
||||||
{
|
{
|
||||||
s.StateMachine.Message = "Panic: ACDCs have unequal grid types";
|
s.StateMachine.Message = "Panic: ACDCs have unequal grid types or PowerStage";
|
||||||
return s.EnableSafeDefaults();
|
return s.EnableSafeDefaults();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Boolean State104(StatusRecord s)
|
// private static Boolean State104(StatusRecord s)
|
||||||
{
|
// {
|
||||||
s.StateMachine.Message = "Panic: DCDCs not available";
|
// s.StateMachine.Message = "Panic: DCDCs not available";
|
||||||
return s.EnableSafeDefaults();
|
// return s.EnableSafeDefaults();
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
private static Boolean UnknownState(StatusRecord s)
|
private static Boolean UnknownState(StatusRecord s)
|
||||||
{
|
{
|
||||||
// "Unknown System State"
|
// "Unknown System State"
|
||||||
|
|
||||||
return s.EnableSafeDefaults();
|
return s.EnableSafeDefaults();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,6 +320,20 @@ public static class Controller
|
||||||
return acDcs.Devices.All(d => !d.Control.PowerStageEnable);
|
return acDcs.Devices.All(d => !d.Control.PowerStageEnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Boolean AllEnabled(this AcDcDevicesRecord acDcs)
|
||||||
|
{
|
||||||
|
return acDcs.Devices.All(d => d.Control.PowerStageEnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static Boolean AllTheSame(this AcDcDevicesRecord acDcs)
|
||||||
|
{
|
||||||
|
return acDcs.Devices
|
||||||
|
.Select(d => d.Control.PowerStageEnable)
|
||||||
|
.Distinct()
|
||||||
|
.Count() == 1;
|
||||||
|
}
|
||||||
|
|
||||||
private static Boolean AllGridTied(this AcDcDevicesRecord acDcs)
|
private static Boolean AllGridTied(this AcDcDevicesRecord acDcs)
|
||||||
{
|
{
|
||||||
return acDcs.Devices.All(d => d.Status.ActiveGridType is GridTied380V60Hz)
|
return acDcs.Devices.All(d => d.Status.ActiveGridType is GridTied380V60Hz)
|
||||||
|
@ -381,9 +363,12 @@ public static class Controller
|
||||||
|
|
||||||
private static void Disable(this DcDcDevicesRecord dcDc)
|
private static void Disable(this DcDcDevicesRecord dcDc)
|
||||||
{
|
{
|
||||||
dcDc.Devices
|
// For Test purpose, The transition from island mode to grid tier and vis versa , may not need to disable Dc/Dc.
|
||||||
.Select(d => d.Control)
|
// This will keep the Dc link powered.
|
||||||
.ForAll(c => c.PowerStageEnable = false);
|
|
||||||
|
// dcDc.Devices
|
||||||
|
// .Select(d => d.Control)
|
||||||
|
// .ForAll(c => c.PowerStageEnable = false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Enable(this AcDcDevicesRecord acDc)
|
private static void Enable(this AcDcDevicesRecord acDc)
|
||||||
|
@ -393,7 +378,6 @@ public static class Controller
|
||||||
.ForAll(c => c.PowerStageEnable = true);
|
.ForAll(c => c.PowerStageEnable = true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void Enable(this DcDcDevicesRecord dcDc)
|
private static void Enable(this DcDcDevicesRecord dcDc)
|
||||||
{
|
{
|
||||||
dcDc.Devices
|
dcDc.Devices
|
||||||
|
@ -402,7 +386,6 @@ public static class Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static void EnableGridTieMode(this AcDcDevicesRecord acDc)
|
private static void EnableGridTieMode(this AcDcDevicesRecord acDc)
|
||||||
{
|
{
|
||||||
acDc.Devices
|
acDc.Devices
|
||||||
|
@ -418,6 +401,33 @@ public static class Controller
|
||||||
.ForAll(c => c.Ac.GridType = Island400V50Hz); // TODO: config grid type
|
.ForAll(c => c.Ac.GridType = Island400V50Hz); // TODO: config grid type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void EnableDcLinkIslandMode(this StatusRecord s)
|
||||||
|
{
|
||||||
|
// Dc Link Windows on AcDc +- 60
|
||||||
|
s.Config.ReferenceDcLinkVoltageFromAcDc = 750;
|
||||||
|
s.Config.MinDcLinkVoltageFromAcDc = 690;
|
||||||
|
s.Config.MaxDcLinkVoltageFromAcDc = 810;
|
||||||
|
|
||||||
|
// Dc Link Windows on DcDc +-55
|
||||||
|
s.Config.ReferenceDcLinkVoltageFromDc = 750;
|
||||||
|
s.Config.UpperDcLinkVoltageFromDc = 55;
|
||||||
|
s.Config.LowerDcLinkVoltageFromDc = 55;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EnableDcLinkGridTie(this StatusRecord s)
|
||||||
|
{
|
||||||
|
// Dc Link Windows on DcDc +-30
|
||||||
|
|
||||||
|
s.Config.ReferenceDcLinkVoltageFromAcDc = 750;
|
||||||
|
s.Config.MinDcLinkVoltageFromAcDc = 720;
|
||||||
|
s.Config.MaxDcLinkVoltageFromAcDc = 780;
|
||||||
|
|
||||||
|
// Dc Link Windows on DcDc +-20
|
||||||
|
s.Config.ReferenceDcLinkVoltageFromDc = 750;
|
||||||
|
s.Config.UpperDcLinkVoltageFromDc = 20;
|
||||||
|
s.Config.LowerDcLinkVoltageFromDc = 20;
|
||||||
|
}
|
||||||
|
|
||||||
private static void DisconnectIslandBusFromGrid(this RelaysRecord? relays)
|
private static void DisconnectIslandBusFromGrid(this RelaysRecord? relays)
|
||||||
{
|
{
|
||||||
if (relays is not null)
|
if (relays is not null)
|
||||||
|
@ -433,15 +443,16 @@ public static class Controller
|
||||||
|
|
||||||
private static Boolean EnableSafeDefaults(this StatusRecord s)
|
private static Boolean EnableSafeDefaults(this StatusRecord s)
|
||||||
{
|
{
|
||||||
s.DcDc.Disable();
|
// After some tests, the safe state is switch off inverter and keep the last state of K2 , Dc/Dc and Grid type to avoid conflict.
|
||||||
s.AcDc.Disable();
|
|
||||||
s.AcDc.EnableGridTieMode();
|
|
||||||
s.Relays.DisconnectIslandBusFromGrid();
|
|
||||||
|
|
||||||
|
// s.DcDc.Disable();
|
||||||
|
s.AcDc.Disable();
|
||||||
|
// s.AcDc.EnableGridTieMode();
|
||||||
|
// s.Relays.DisconnectIslandBusFromGrid();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DcDcDevicesRecord ResetAlarms(this DcDcDevicesRecord dcDcStatus)
|
public static DcDcDevicesRecord ResetAlarms(this DcDcDevicesRecord dcDcStatus)
|
||||||
{
|
{
|
||||||
var sc = dcDcStatus.SystemControl;
|
var sc = dcDcStatus.SystemControl;
|
||||||
|
|
||||||
|
@ -454,7 +465,7 @@ public static class Controller
|
||||||
return dcDcStatus;
|
return dcDcStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AcDcDevicesRecord ResetAlarms(this AcDcDevicesRecord acDcStatus)
|
public static AcDcDevicesRecord ResetAlarms(this AcDcDevicesRecord acDcStatus)
|
||||||
{
|
{
|
||||||
var sc = acDcStatus.SystemControl;
|
var sc = acDcStatus.SystemControl;
|
||||||
|
|
||||||
|
|
|
@ -49,12 +49,16 @@ public class Config //TODO: let IE choose from config files (Json) and connect t
|
||||||
GridSetPoint = 0,
|
GridSetPoint = 0,
|
||||||
BatterySelfDischargePower = 200,
|
BatterySelfDischargePower = 200,
|
||||||
HoldSocZone = 1, // TODO: find better name,
|
HoldSocZone = 1, // TODO: find better name,
|
||||||
MinDcBusVoltage = 690,
|
MinDcLinkVoltageFromAcDc = 690,
|
||||||
ReferenceDcBusVoltage = 750,
|
ReferenceDcLinkVoltageFromAcDc = 750,
|
||||||
MaxDcBusVoltage = 810,
|
MaxDcLinkVoltageFromAcDc = 810,
|
||||||
LowerDcBusVoltageWindow = 50,
|
LowerDcLinkVoltageFromDc = 50,
|
||||||
ReferenceDcBusVoltageWindow = 750,
|
ReferenceDcLinkVoltageFromDc = 750,
|
||||||
UpperDcBusVoltageWindow = 50,
|
UpperDcLinkVoltageFromDc = 50,
|
||||||
|
MaxBatteryChargingCurrent = 210,
|
||||||
|
MaxBatteryDischargingCurrent = 210,
|
||||||
|
MaxChargeBatteryVoltage = 57,
|
||||||
|
MinDischargeBatteryVoltage = 0,
|
||||||
Devices = new ()
|
Devices = new ()
|
||||||
{
|
{
|
||||||
TruConvertAcIp = new() { Host = "localhost", Port = 5001},
|
TruConvertAcIp = new() { Host = "localhost", Port = 5001},
|
||||||
|
|
|
@ -0,0 +1,254 @@
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using InnovEnergy.App.SaliMax.Ess;
|
||||||
|
using InnovEnergy.Lib.Devices.Battery48TL;
|
||||||
|
using InnovEnergy.Lib.Units;
|
||||||
|
using InnovEnergy.Lib.Units.Power;
|
||||||
|
using InnovEnergy.Lib.Utils;
|
||||||
|
using Ac3Bus = InnovEnergy.Lib.Units.Composite.Ac3Bus;
|
||||||
|
|
||||||
|
namespace InnovEnergy.App.SaliMax;
|
||||||
|
|
||||||
|
public static class Topology
|
||||||
|
{
|
||||||
|
public static TextBlock From(this StatusRecord s)
|
||||||
|
{
|
||||||
|
// Topology is built up from right to left
|
||||||
|
|
||||||
|
// Power Measurement Values
|
||||||
|
|
||||||
|
var inverterPower = s.AcDc.Ac.Power.Active;
|
||||||
|
var islandLoadPower = s.LoadOnAcIsland is not null
|
||||||
|
? s.LoadOnAcIsland.Ac.Power.Active
|
||||||
|
: 0; // TODO
|
||||||
|
|
||||||
|
var islandTopology = CreateIslandTopology(s, islandLoadPower, inverterPower);
|
||||||
|
|
||||||
|
if (s.GridMeter is null) // no grid meter?
|
||||||
|
return islandTopology; // we're done
|
||||||
|
|
||||||
|
var gridBusColumn = GridBusColumn(s);
|
||||||
|
var gridBox = CreateGridBox(s);
|
||||||
|
|
||||||
|
ActivePower islandToGridBusPower = inverterPower + islandLoadPower;
|
||||||
|
|
||||||
|
// return TextBlock
|
||||||
|
// .AlignCenterVertical
|
||||||
|
// (
|
||||||
|
// gridBox , Flow.Horizontal(s.GridMeter.Ac.Power.Active),
|
||||||
|
// gridBusColumn, Flow.Horizontal(islandToGridBusPower),
|
||||||
|
// islandTopology
|
||||||
|
// );
|
||||||
|
|
||||||
|
var gridTopology = TextBlock
|
||||||
|
.AlignCenterVertical
|
||||||
|
(
|
||||||
|
gridBox,
|
||||||
|
Flow.Horizontal(s.GridMeter.Ac.Power.Active),
|
||||||
|
gridBusColumn
|
||||||
|
);
|
||||||
|
|
||||||
|
return TextBlock.AlignCenterVertical
|
||||||
|
(
|
||||||
|
gridTopology,
|
||||||
|
Flow.Horizontal(islandToGridBusPower),
|
||||||
|
islandTopology
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TextBlock CreateIslandTopology(StatusRecord s, ActivePower islandLoadPower, ActivePower inverterPower)
|
||||||
|
{
|
||||||
|
var dcBatteryPower = s.DcDc.Dc.Battery.Power;
|
||||||
|
var dcdcPower = s.DcDc.Dc.Link.Power;
|
||||||
|
|
||||||
|
var batteries = CreateBatteryColumn(s);
|
||||||
|
var dcBusColumn = CreateDcBusColumn(s);
|
||||||
|
var islandBusColumn = CreateIslandBusColumn(s, islandLoadPower);
|
||||||
|
var inverterBox = CreateInverterBox(s);
|
||||||
|
var dcDcBox = CreateDcDcBox(s);
|
||||||
|
|
||||||
|
return TextBlock
|
||||||
|
.AlignCenterVertical
|
||||||
|
(
|
||||||
|
islandBusColumn, Flow.Horizontal(inverterPower),
|
||||||
|
inverterBox , Flow.Horizontal(inverterPower),
|
||||||
|
dcBusColumn , Flow.Horizontal(dcdcPower),
|
||||||
|
dcDcBox , Flow.Horizontal(dcBatteryPower),
|
||||||
|
batteries
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TextBlock CreateGridBox(StatusRecord statusRecord)
|
||||||
|
{
|
||||||
|
return statusRecord
|
||||||
|
.GridMeter!
|
||||||
|
.Ac
|
||||||
|
.PhasePowersActive()
|
||||||
|
.TitleBox("Grid");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TextBlock CreateDcDcBox(StatusRecord s)
|
||||||
|
{
|
||||||
|
var dc48Voltage = s.DcDc.Dc.Battery.Voltage.ToDisplayString();
|
||||||
|
|
||||||
|
return TextBlock
|
||||||
|
.AlignLeft(dc48Voltage)
|
||||||
|
.TitleBox("DC/DC");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TextBlock CreateInverterBox(StatusRecord s)
|
||||||
|
{
|
||||||
|
var inverterAcPhases = s
|
||||||
|
.AcDc
|
||||||
|
.Devices
|
||||||
|
.Select(d => d.Status.Ac.Power)
|
||||||
|
.ToReadOnlyList();
|
||||||
|
|
||||||
|
return TextBlock
|
||||||
|
.AlignLeft(inverterAcPhases)
|
||||||
|
.TitleBox("AC/DC");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TextBlock CreateIslandBusColumn(StatusRecord s, ActivePower islandLoadPower)
|
||||||
|
{
|
||||||
|
var islandBusPv = 0.W(); // TODO
|
||||||
|
|
||||||
|
return ColumnBox
|
||||||
|
(
|
||||||
|
"Pv", islandBusPv,
|
||||||
|
"Island Bus", s.AcDc.Ac.PhasePowersActive(),
|
||||||
|
"Load", islandLoadPower
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TextBlock CreateDcBusColumn(StatusRecord s)
|
||||||
|
{
|
||||||
|
var dcBusLoad = 0.W(); // TODO
|
||||||
|
var pvOnDcPower = s.PvOnDc.Dc!.Power; // TODO !
|
||||||
|
var dcLinkVoltage = s.DcDc.Dc.Link.Voltage.ToDisplayString();
|
||||||
|
|
||||||
|
return ColumnBox
|
||||||
|
(
|
||||||
|
"Pv" , pvOnDcPower,
|
||||||
|
"Dc Bus", dcLinkVoltage,
|
||||||
|
"Load" , dcBusLoad
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TextBlock CreateBatteryColumn(StatusRecord s)
|
||||||
|
{
|
||||||
|
var bat = s.Battery;
|
||||||
|
var batteryAvgBox = CreateAveragedBatteryBox(bat);
|
||||||
|
|
||||||
|
var batteryBoxes = bat
|
||||||
|
.Devices
|
||||||
|
.Select(CreateIndividualBattery)
|
||||||
|
.ToReadOnlyList();
|
||||||
|
|
||||||
|
var individualBatteries = batteryBoxes.Any()
|
||||||
|
? TextBlock.AlignLeft(batteryBoxes)
|
||||||
|
: TextBlock.Empty;
|
||||||
|
|
||||||
|
return TextBlock
|
||||||
|
.AlignCenterVertical
|
||||||
|
(
|
||||||
|
batteryAvgBox //,
|
||||||
|
//individualBatteries // TODO
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TextBlock CreateAveragedBatteryBox(Battery48TlRecords bat)
|
||||||
|
{
|
||||||
|
var batteryVoltage = bat.Dc.Voltage.ToDisplayString();
|
||||||
|
var batterySoc = bat.Devices.Any() ? bat.Devices.Average(b => b.Soc).Percent().ToDisplayString() : "0";
|
||||||
|
var batteryCurrent = bat.Dc.Current.ToDisplayString();
|
||||||
|
var batteryTemp = bat.Temperature.ToDisplayString();
|
||||||
|
var batteryHeatingCurrent = bat.HeatingCurrent.ToDisplayString();
|
||||||
|
var alarms = bat.Alarms.Count + " Alarms";
|
||||||
|
var warnings = bat.Warnings.Count + " Warnings";
|
||||||
|
|
||||||
|
return TextBlock
|
||||||
|
.AlignLeft
|
||||||
|
(
|
||||||
|
batteryVoltage,
|
||||||
|
batterySoc,
|
||||||
|
batteryCurrent,
|
||||||
|
batteryTemp,
|
||||||
|
batteryHeatingCurrent,
|
||||||
|
warnings,
|
||||||
|
alarms
|
||||||
|
)
|
||||||
|
.TitleBox("Battery");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TextBlock GridBusColumn(StatusRecord s)
|
||||||
|
{
|
||||||
|
var gridLoadPower = s.LoadOnAcGrid is not null
|
||||||
|
? s.LoadOnAcGrid.Power.Active
|
||||||
|
: 0; // TODO: show that LoadOnAcGrid is actually not available and not 0
|
||||||
|
|
||||||
|
return ColumnBox
|
||||||
|
(
|
||||||
|
"Pv", 0,
|
||||||
|
"Grid Bus", s.GridMeter!.Ac.PhaseVoltages(),
|
||||||
|
"Load", gridLoadPower
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TextBlock PhaseVoltages(this Ac3Bus ac)
|
||||||
|
{
|
||||||
|
return TextBlock.AlignLeft
|
||||||
|
(
|
||||||
|
ac.L1.Voltage.ToDisplayString(),
|
||||||
|
ac.L2.Voltage.ToDisplayString(),
|
||||||
|
ac.L3.Voltage.ToDisplayString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TextBlock PhasePowersActive(this Ac3Bus ac)
|
||||||
|
{
|
||||||
|
return TextBlock.AlignLeft
|
||||||
|
(
|
||||||
|
ac.L1.Power.Active.ToDisplayString(),
|
||||||
|
ac.L2.Power.Active.ToDisplayString(),
|
||||||
|
ac.L3.Power.Active.ToDisplayString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TextBlock CreateIndividualBattery(Battery48TlRecord battery, Int32 i)
|
||||||
|
{
|
||||||
|
var batteryWarnings = battery.Warnings.Any();
|
||||||
|
var batteryAlarms = battery.Alarms.Any();
|
||||||
|
|
||||||
|
var content = TextBlock.AlignLeft
|
||||||
|
(
|
||||||
|
battery.Dc.Voltage.ToDisplayString(),
|
||||||
|
battery.Soc.ToDisplayString(),
|
||||||
|
battery.Dc.Current.ToDisplayString() + " C/D",
|
||||||
|
battery.Temperatures.Cells.Average.ToDisplayString(),
|
||||||
|
battery.BusCurrent.ToDisplayString() + " T",
|
||||||
|
batteryWarnings,
|
||||||
|
batteryAlarms,
|
||||||
|
battery.HeatingCurrent.ToDisplayString() + " H"
|
||||||
|
);
|
||||||
|
|
||||||
|
var box = content.TitleBox($"Battery {i + 1}");
|
||||||
|
var flow = Flow.Horizontal(battery.Dc.Power);
|
||||||
|
|
||||||
|
return TextBlock.AlignCenterVertical(flow, box);
|
||||||
|
}
|
||||||
|
|
||||||
|
[SuppressMessage("ReSharper", "SuggestBaseTypeForParameter")]
|
||||||
|
|
||||||
|
private static TextBlock ColumnBox(String pvTitle , ActivePower pvPower,
|
||||||
|
String busTitle , Object busData,
|
||||||
|
String loadTitle, ActivePower loadPower)
|
||||||
|
{
|
||||||
|
var pvBox = TextBlock.FromString(pvTitle).Box();
|
||||||
|
var pvToBus = Flow.Vertical(pvPower);
|
||||||
|
var busBox = TextBlock.AlignLeft(busData).TitleBox(busTitle);
|
||||||
|
var busToLoad = Flow.Vertical(loadPower);
|
||||||
|
var loadBox = TextBlock.FromString(loadTitle).Box();
|
||||||
|
|
||||||
|
return TextBlock.AlignCenterHorizontal(pvBox, pvToBus, busBox, busToLoad, loadBox);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace InnovEnergy.App.SaliMax;
|
||||||
|
|
||||||
|
// https://www.freedesktop.org/software/systemd/man/sd_notify.html
|
||||||
|
|
||||||
|
public static class Watchdog
|
||||||
|
{
|
||||||
|
// "it is generally recommended to ignore the return value of this call. "
|
||||||
|
[DllImport("libsystemd.so.0")]
|
||||||
|
private static extern Int32 sd_notify(Int32 unsetEnvironment, String state);
|
||||||
|
|
||||||
|
public static void Ready() => _ = sd_notify(0, "READY=1");
|
||||||
|
public static void Alive() => _ = sd_notify(0, "WATCHDOG=1");
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ tunnel() {
|
||||||
rPort=$3
|
rPort=$3
|
||||||
lPort=$4
|
lPort=$4
|
||||||
|
|
||||||
echo -n "localhost:$lPort $name "
|
echo -n "$name @ $ip mapped to localhost:$lPort "
|
||||||
ssh -nNTL "$lPort:$ip:$rPort" "$host" 2> /dev/null &
|
ssh -nNTL "$lPort:$ip:$rPort" "$host" 2> /dev/null &
|
||||||
|
|
||||||
until nc -vz 127.0.0.1 $lPort 2> /dev/null
|
until nc -vz 127.0.0.1 $lPort 2> /dev/null
|
||||||
|
@ -22,23 +22,23 @@ tunnel() {
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
tunnel "Trumpf Inverter (http) " 10.0.2.1 80 7001
|
tunnel "Trumpf Inverter (http) " 10.0.2.1 80 8001
|
||||||
tunnel "Trumpf DCDC (http) " 10.0.3.1 80 7002
|
tunnel "Trumpf DCDC (http) " 10.0.3.1 80 8002
|
||||||
tunnel "Ext Emu Meter (http) " 10.0.4.1 80 7003
|
tunnel "Ext Emu Meter (http) " 10.0.4.1 80 8003
|
||||||
tunnel "Int Emu Meter (http) " 10.0.4.2 80 7004
|
tunnel "Int Emu Meter (http) " 10.0.4.2 80 8004
|
||||||
tunnel "AMPT (http) " 10.0.5.1 8080 7005
|
tunnel "AMPT (http) " 10.0.5.1 8080 8005
|
||||||
tunnel "Doepke (http) " 10.0.6.1 80 7006
|
|
||||||
|
|
||||||
tunnel "Trumpf Inverter (modbus)" 10.0.2.1 502 5001
|
tunnel "Trumpf Inverter (modbus)" 10.0.2.1 502 5001
|
||||||
tunnel "Trumpf DCDC (modbus) " 10.0.3.1 502 5002
|
tunnel "Trumpf DCDC (modbus) " 10.0.3.1 502 5002
|
||||||
tunnel "Ext Emu Meter (modbus) " 10.0.4.1 502 5003
|
tunnel "Ext Emu Meter (modbus) " 10.0.4.1 502 5003
|
||||||
tunnel "Int Emu Meter " 10.0.4.2 502 5004
|
tunnel "Int Emu Meter " 10.0.4.2 502 5004
|
||||||
tunnel "AMPT (modbus) " 10.0.5.1 502 5005
|
tunnel "AMPT (modbus) " 10.0.5.1 502 5005
|
||||||
|
tunnel "Adam " 10.0.1.1 502 5006
|
||||||
tunnel "Batteries " 127.0.0.1 6855 5007
|
tunnel "Batteries " 127.0.0.1 6855 5007
|
||||||
|
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "press any key to close the tunnels ..."
|
echo "press any key to close the tunnels ..."
|
||||||
read -r -n 1 -s
|
read -r -n 1 -s
|
||||||
kill $(jobs -p)
|
kill $(jobs -p)
|
||||||
echo "done"
|
echo "done"
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ public static class Program
|
||||||
app.MapControllers();
|
app.MapControllers();
|
||||||
// app.MapGet("/", () => Controller.Index());
|
// app.MapGet("/", () => Controller.Index());
|
||||||
var webTask = app.RunAsync();
|
var webTask = app.RunAsync();
|
||||||
await Task.WhenAll(webTask);
|
await Task.WhenAll(webTask, updateTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OpenApiInfo OpenApiInfo { get; } = new OpenApiInfo
|
private static OpenApiInfo OpenApiInfo { get; } = new OpenApiInfo
|
||||||
|
|
|
@ -19,7 +19,6 @@ public class AmptDevices
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public AmptDevices(ModbusClient modbusClient)
|
public AmptDevices(ModbusClient modbusClient)
|
||||||
{
|
{
|
||||||
_CommunicationUnit = new ModbusDevice<CommunicationUnitRegisters>(modbusClient);
|
_CommunicationUnit = new ModbusDevice<CommunicationUnitRegisters>(modbusClient);
|
||||||
|
|
|
@ -94,24 +94,23 @@ public partial class Battery48TlRecord
|
||||||
if (HasBit(14)) yield return "FUSE : Main fuse blown";
|
if (HasBit(14)) yield return "FUSE : Main fuse blown";
|
||||||
if (HasBit(15)) yield return "HTRE : Battery failed to warm up";
|
if (HasBit(15)) yield return "HTRE : Battery failed to warm up";
|
||||||
if (HasBit(16)) yield return "TCPE : Temperature sensor failure";
|
if (HasBit(16)) yield return "TCPE : Temperature sensor failure";
|
||||||
if (HasBit(17)) yield return "STRE :";
|
if (HasBit(17)) yield return "STRE : Voltage measurement circuit fails";
|
||||||
if (HasBit(18)) yield return "CME : Current sensor failure";
|
if (HasBit(18)) yield return "CME : Current sensor failure";
|
||||||
if (HasBit(19)) yield return "HWFL : BMS hardware failure";
|
if (HasBit(19)) yield return "HWFL : BMS hardware failure";
|
||||||
if (HasBit(20)) yield return "HWEM : Hardware protection tripped";
|
if (HasBit(20)) yield return "HWEM : Hardware protection tripped";
|
||||||
if (HasBit(21)) yield return "ThM : Heatsink temperature too high";
|
if (HasBit(21)) yield return "ThM : Heatsink temperature too high";
|
||||||
if (HasBit(22)) yield return "vsm1 : String voltage too low";
|
|
||||||
if (HasBit(23)) yield return "vsm2 : Low string voltage failure";
|
if (HasBit(23)) yield return "vsm2 : Low string voltage failure";
|
||||||
if (HasBit(25)) yield return "vsM2 : String voltage too high";
|
if (HasBit(25)) yield return "vsM2 : String voltage too high";
|
||||||
if (HasBit(27)) yield return "iCM2 : Charge current too high";
|
if (HasBit(27)) yield return "iCM2 : Charge current too high";
|
||||||
if (HasBit(29)) yield return "iDM2 : Discharge current too high";
|
if (HasBit(29)) yield return "iDM2 : Discharge current too high";
|
||||||
if (HasBit(31)) yield return "MID2 : String voltage unbalance too high";
|
if (HasBit(31)) yield return "MID2 : String voltage unbalance too high";
|
||||||
if (HasBit(33)) yield return "CCBF : Internal charger hardware failure";
|
// if (HasBit(34)) yield return "AhFL :"; // This is doesn't exist in the manual
|
||||||
if (HasBit(34)) yield return "AhFL :";
|
// if (HasBit(36)) yield return "TbCM :"; // This is doesn't exist in the manual
|
||||||
if (HasBit(36)) yield return "TbCM :";
|
// if (HasBit(37)) yield return "BRNF :"; // This is doesn't exist in the manual
|
||||||
if (HasBit(37)) yield return "BRNF :";
|
|
||||||
if (HasBit(42)) yield return "HTFS : Heater Fuse Blown";
|
if (HasBit(42)) yield return "HTFS : Heater Fuse Blown";
|
||||||
if (HasBit(43)) yield return "DATA : Parameters out of range";
|
if (HasBit(43)) yield return "DATA : Parameters out of range";
|
||||||
if (HasBit(45)) yield return "CELL2:";
|
if (HasBit(45)) yield return "CELL2: Unbalance string voltages";
|
||||||
|
if (HasBit(46)) yield return "HEBT : Loss of heartbeat";
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "StringLiteralTypo")]
|
[SuppressMessage("ReSharper", "StringLiteralTypo")]
|
||||||
|
@ -124,18 +123,20 @@ public partial class Battery48TlRecord
|
||||||
if (HasBit(6) ) yield return "VBm1: Bus voltage low";
|
if (HasBit(6) ) yield return "VBm1: Bus voltage low";
|
||||||
if (HasBit(8) ) yield return "VBM1: Bus voltage high";
|
if (HasBit(8) ) yield return "VBM1: Bus voltage high";
|
||||||
if (HasBit(10)) yield return "IDM1: Discharge current high";
|
if (HasBit(10)) yield return "IDM1: Discharge current high";
|
||||||
|
if (HasBit(22)) yield return "vsm1: String voltage too low";
|
||||||
if (HasBit(24)) yield return "vsM1: String voltage high";
|
if (HasBit(24)) yield return "vsM1: String voltage high";
|
||||||
if (HasBit(26)) yield return "iCM1: Charge current high";
|
if (HasBit(26)) yield return "iCM1: Charge current high";
|
||||||
if (HasBit(28)) yield return "iDM1: Discharge current high";
|
if (HasBit(28)) yield return "iDM1: Discharge current high";
|
||||||
if (HasBit(30)) yield return "MID1: String voltages unbalanced";
|
if (HasBit(30)) yield return "MID1: String voltages unbalanced";
|
||||||
if (HasBit(32)) yield return "BLPW: Not enough charging power on bus";
|
if (HasBit(32)) yield return "BLPW: Not enough charging power on bus";
|
||||||
|
if (HasBit(33)) yield return "CCBF : Internal charger hardware failure";
|
||||||
if (HasBit(35)) yield return "Ah_W: String SOC low";
|
if (HasBit(35)) yield return "Ah_W: String SOC low";
|
||||||
if (HasBit(38)) yield return "MPMM: Midpoint wiring problem";
|
if (HasBit(38)) yield return "MPMM: Midpoint wiring problem";
|
||||||
if (HasBit(39)) yield return "TCMM:";
|
// if (HasBit(39)) yield return "TCMM:"; // This is doesn't exist in the manual
|
||||||
if (HasBit(40)) yield return "TCdi: Temperature difference between strings high";
|
if (HasBit(40)) yield return "TCdi: Temperature difference between strings high";
|
||||||
if (HasBit(41)) yield return "WMTO:";
|
// if (HasBit(41)) yield return "WMTO:"; // This is doesn't exist in the manual
|
||||||
if (HasBit(44)) yield return "bit44:";
|
if (HasBit(44)) yield return "LMPW : String voltages unbalance warning";
|
||||||
if (HasBit(46)) yield return "CELL1:";
|
if (HasBit(47)) yield return "TOCW : ";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,16 @@ public partial class Battery48TlRecord
|
||||||
[InputRegister(1017, Scale = 0.1, Offset = -400)] private Double _TemperaturesCellsRight;
|
[InputRegister(1017, Scale = 0.1, Offset = -400)] private Double _TemperaturesCellsRight;
|
||||||
[InputRegister(1003, Scale = 0.1, Offset = -400)] private Double _TemperaturesCellsAverage;
|
[InputRegister(1003, Scale = 0.1, Offset = -400)] private Double _TemperaturesCellsAverage;
|
||||||
|
|
||||||
|
|
||||||
|
[InputRegister(1054)] private Double _FwVersion;
|
||||||
|
[InputRegister(1055)] private Double _SerialNum1;
|
||||||
|
[InputRegister(1056)] private Double _SerialNum2;
|
||||||
|
[InputRegister(1057)] private Double _SerialNum3;
|
||||||
|
[InputRegister(1058)] private Double _SerialNum4;
|
||||||
|
[InputRegister(1059)] private Double _LimpBitMap;
|
||||||
|
[InputRegister(1060)] private Double _BatteryState1;
|
||||||
|
[InputRegister(1061)] private Double _BatteryState2;
|
||||||
|
|
||||||
private LedState ParseLed(LedColor led) => (LedState)((_LedStates >> (Int32)led) & 3);
|
private LedState ParseLed(LedColor led) => (LedState)((_LedStates >> (Int32)led) & 3);
|
||||||
|
|
||||||
// public Decimal CellsVoltage { get; init; }
|
// public Decimal CellsVoltage { get; init; }
|
||||||
|
|
|
@ -19,7 +19,7 @@ public class Battery48TlRecords
|
||||||
HeatingCurrent = records.Any() ? records.Sum(b => b.HeatingCurrent) : 0;
|
HeatingCurrent = records.Any() ? records.Sum(b => b.HeatingCurrent) : 0;
|
||||||
|
|
||||||
Dc = empty
|
Dc = empty
|
||||||
? DcBus.FromVoltageCurrent(0, 0)
|
? DcBus.Null
|
||||||
: DcBus.FromVoltageCurrent
|
: DcBus.FromVoltageCurrent
|
||||||
(
|
(
|
||||||
records.Average(r => r.Dc.Voltage),
|
records.Average(r => r.Dc.Voltage),
|
||||||
|
|
|
@ -36,7 +36,11 @@ public class DcControl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public DcPrechargeConfig PrechargeConfig => _Self.DcPrechargeConfig;
|
public DcPrechargeConfig PrechargeConfig
|
||||||
|
{
|
||||||
|
get { return _Self.DcPrechargeConfig; }
|
||||||
|
set { _Self.DcPrechargeConfig = value; }
|
||||||
|
}
|
||||||
|
|
||||||
private Boolean Is480V => _Self.GridType is GridType.GridTied480V60Hz or GridType.Island480V60Hz;
|
private Boolean Is480V => _Self.GridType is GridType.GridTied480V60Hz or GridType.Island480V60Hz;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ namespace InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes;
|
||||||
public enum DcPrechargeConfig : UInt16
|
public enum DcPrechargeConfig : UInt16
|
||||||
{
|
{
|
||||||
WaitForExternalPrecharge = 0,
|
WaitForExternalPrecharge = 0,
|
||||||
PrechargeDcWithSystemCtl = 1,
|
PrechargeDcWithInternal = 1,
|
||||||
PrechargeDcWithDcDcs = 2,
|
PrechargeDcWithDcDcs = 2,
|
||||||
PrechargeDcWithSystemCtlAndWait = 3,
|
PrechargeDcWithSystemCtlAndWait = 3,
|
||||||
}
|
}
|
|
@ -16,6 +16,19 @@ public class CurrentControl
|
||||||
set => _Self.MaxCurrentChangePerMs = value.Value;
|
set => _Self.MaxCurrentChangePerMs = value.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Current MaxBatteryChargingCurrent
|
||||||
|
{
|
||||||
|
get => _Self.MaxBatteryChargingCurrent;
|
||||||
|
set => _Self.MaxBatteryChargingCurrent = value.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Current MaxBatteryDischargingCurrent
|
||||||
|
{
|
||||||
|
get => _Self.MaxBatteryDischargingCurrent;
|
||||||
|
set => _Self.MaxBatteryDischargingCurrent = value.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private readonly DcDcRecord _Self;
|
private readonly DcDcRecord _Self;
|
||||||
internal CurrentControl(DcDcRecord self) => _Self = self;
|
internal CurrentControl(DcDcRecord self) => _Self = self;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,14 @@ public partial class DcDcRecord
|
||||||
[HoldingRegister(4100, Scale = .01)] internal Double MaxBatteryVoltage ;
|
[HoldingRegister(4100, Scale = .01)] internal Double MaxBatteryVoltage ;
|
||||||
[HoldingRegister(4101, Scale = .01)] internal Double MinBatteryVoltage ;
|
[HoldingRegister(4101, Scale = .01)] internal Double MinBatteryVoltage ;
|
||||||
|
|
||||||
|
[HoldingRegister(4106, Scale = .1)] internal Double MaxBatteryChargingCurrent ;
|
||||||
|
[HoldingRegister(4109, Scale = .1)] internal Double MaxBatteryDischargingCurrent ;
|
||||||
|
|
||||||
[HoldingRegister(4112, Scale = .1)] internal Double VccEndPointVoltage ;
|
[HoldingRegister(4112, Scale = .1)] internal Double VccEndPointVoltage ;
|
||||||
[HoldingRegister(4115)] internal Double VccEndPointCurrent ;
|
[HoldingRegister(4115)] internal Double VccEndPointCurrent ;
|
||||||
[HoldingRegister(4118)] internal Double VccStartPointCurrent ;
|
[HoldingRegister(4118)] internal Double VccStartPointCurrent ;
|
||||||
|
|
||||||
[HoldingRegister(4118)] internal Double MaxDcPower ;
|
[HoldingRegister(4121)] internal Double MaxDcPower ;
|
||||||
|
|
||||||
[HoldingRegister(4124, Scale = .1)] internal Double MaxVoltageAlarm ;
|
[HoldingRegister(4124, Scale = .1)] internal Double MaxVoltageAlarm ;
|
||||||
[HoldingRegister(4127, Scale = .1)] internal Double MinVoltageAlarm ;
|
[HoldingRegister(4127, Scale = .1)] internal Double MinVoltageAlarm ;
|
||||||
|
|
|
@ -9,8 +9,8 @@ public static class UnixTimeSpanExtensions
|
||||||
public static UnixTimeSpan Weeks (this Int32 w) => UnixTimeSpan.FromWeeks (w);
|
public static UnixTimeSpan Weeks (this Int32 w) => UnixTimeSpan.FromWeeks (w);
|
||||||
|
|
||||||
public static UnixTimeSpan Seconds(this UInt32 s) => UnixTimeSpan.FromSeconds(s);
|
public static UnixTimeSpan Seconds(this UInt32 s) => UnixTimeSpan.FromSeconds(s);
|
||||||
public static UnixTimeSpan Minutes(this UInt32 m) => UnixTimeSpan.FromSeconds(m);
|
public static UnixTimeSpan Minutes(this UInt32 m) => UnixTimeSpan.FromMinutes(m);
|
||||||
public static UnixTimeSpan Hours (this UInt32 h) => UnixTimeSpan.FromMinutes(h);
|
public static UnixTimeSpan Hours (this UInt32 h) => UnixTimeSpan.FromHours (h);
|
||||||
public static UnixTimeSpan Days (this UInt32 d) => UnixTimeSpan.FromHours (d);
|
public static UnixTimeSpan Days (this UInt32 d) => UnixTimeSpan.FromDays (d);
|
||||||
public static UnixTimeSpan Weeks (this UInt32 w) => UnixTimeSpan.FromDays (w);
|
public static UnixTimeSpan Weeks (this UInt32 w) => UnixTimeSpan.FromWeeks (w);
|
||||||
}
|
}
|
|
@ -9,6 +9,11 @@ public abstract class Unit
|
||||||
|
|
||||||
public override String ToString() => $"{Value} {Symbol}";
|
public override String ToString() => $"{Value} {Symbol}";
|
||||||
|
|
||||||
|
private static readonly IReadOnlyList<String> Prefix = new[] { "y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Y" };
|
||||||
|
|
||||||
|
private static Int32 MaxPrefix { get; } = Prefix.Count - 1;
|
||||||
|
private static Int32 DefaultIndex { get; } = Prefix.TakeWhile(e => e != "").Count();
|
||||||
|
|
||||||
public String ToDisplayString()
|
public String ToDisplayString()
|
||||||
{
|
{
|
||||||
if (Value == 0)
|
if (Value == 0)
|
||||||
|
@ -17,14 +22,14 @@ public abstract class Unit
|
||||||
var a = Math.Abs(Value);
|
var a = Math.Abs(Value);
|
||||||
var s = Math.Sign(Value);
|
var s = Math.Sign(Value);
|
||||||
|
|
||||||
var i = 8;
|
var i = DefaultIndex;
|
||||||
|
|
||||||
while (a >= 10000)
|
while (a >= 10000 && i < MaxPrefix)
|
||||||
{
|
{
|
||||||
a /= 1000;
|
a /= 1000;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
while (a < 10)
|
while (a < 10 && i > 0)
|
||||||
{
|
{
|
||||||
a *= 1000;
|
a *= 1000;
|
||||||
i--;
|
i--;
|
||||||
|
@ -37,6 +42,6 @@ public abstract class Unit
|
||||||
return $"{r * s} {Prefix[i]}{Symbol}";
|
return $"{r * s} {Prefix[i]}{Symbol}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly IReadOnlyList<String> Prefix = new[] { "y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Y" };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,19 @@ public static class Units
|
||||||
public static Energy Wh (this Double value) => value;
|
public static Energy Wh (this Double value) => value;
|
||||||
public static Percent Percent(this Double value) => value;
|
public static Percent Percent(this Double value) => value;
|
||||||
|
|
||||||
|
public static Current A (this Int32 value) => value;
|
||||||
|
public static Voltage V (this Int32 value) => value;
|
||||||
|
public static ActivePower W (this Int32 value) => value;
|
||||||
|
public static ReactivePower Var (this Int32 value) => value;
|
||||||
|
public static ApparentPower Va (this Int32 value) => value;
|
||||||
|
public static Resistance Ohm (this Int32 value) => value;
|
||||||
|
public static Frequency Hz (this Int32 value) => value;
|
||||||
|
public static Angle Rad (this Int32 value) => value;
|
||||||
|
public static Temperature Celsius(this Int32 value) => value;
|
||||||
|
public static Energy KWh (this Int32 value) => value * 1000;
|
||||||
|
public static Energy Wh (this Int32 value) => value;
|
||||||
|
public static Percent Percent(this Int32 value) => value;
|
||||||
|
|
||||||
public static String ToCsv(this Object thing)
|
public static String ToCsv(this Object thing)
|
||||||
{
|
{
|
||||||
var csvLines = new List<String>();
|
var csvLines = new List<String>();
|
||||||
|
|
|
@ -13,4 +13,6 @@ public static class ArrayExtensions
|
||||||
Array.Fill(ts, element);
|
Array.Fill(ts, element);
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IReadOnlyList<T> AsReadOnlyList<T>(this T[] ts) => ts;
|
||||||
}
|
}
|
|
@ -38,7 +38,6 @@ public static class ConsoleUtils
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static T Write<T>(this T t, ConsoleColor color)
|
public static T Write<T>(this T t, ConsoleColor color)
|
||||||
{
|
{
|
||||||
var c = Console.ForegroundColor;
|
var c = Console.ForegroundColor;
|
||||||
|
|
|
@ -277,6 +277,9 @@ public static class EnumerableUtils
|
||||||
|
|
||||||
public static T[] ToArray<T>(this IEnumerable<T> ts, Int32 n)
|
public static T[] ToArray<T>(this IEnumerable<T> ts, Int32 n)
|
||||||
{
|
{
|
||||||
|
if (ts is T[] ta)
|
||||||
|
return ta;
|
||||||
|
|
||||||
var array = new T[n];
|
var array = new T[n];
|
||||||
var i = 0;
|
var i = 0;
|
||||||
|
|
||||||
|
@ -296,6 +299,8 @@ public static class EnumerableUtils
|
||||||
return ts as T[] ?? ts.ToArray(ts.Count);
|
return ts as T[] ?? ts.ToArray(ts.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static IEnumerable<T> Concat<T>(this IEnumerable<T> ts, T last)
|
public static IEnumerable<T> Concat<T>(this IEnumerable<T> ts, T last)
|
||||||
{
|
{
|
||||||
foreach (var t in ts)
|
foreach (var t in ts)
|
||||||
|
|
|
@ -132,9 +132,11 @@ public static class StringUtils
|
||||||
.SideBySideWith(text, "");
|
.SideBySideWith(text, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IReadOnlyList<String> SplitLines(this String s)
|
public static IReadOnlyList<String> SplitLines(this String? s)
|
||||||
{
|
{
|
||||||
return s.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
|
return s is null
|
||||||
|
? Array.Empty<String>()
|
||||||
|
: s.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,12 +8,18 @@ public class TextBlock
|
||||||
|
|
||||||
public override String ToString() => _Lines.JoinLines();
|
public override String ToString() => _Lines.JoinLines();
|
||||||
|
|
||||||
public static TextBlock AlignLeft(IReadOnlyList<Object> things)
|
public static TextBlock Empty { get; } = new TextBlock();
|
||||||
|
|
||||||
|
public static TextBlock AlignLeft(IEnumerable<Object> things)
|
||||||
{
|
{
|
||||||
var lines = things
|
var lines = things
|
||||||
.SelectMany(GetLines)
|
.SelectMany(GetLines)
|
||||||
|
.Unless(String.IsNullOrEmpty)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
if (!lines.Any())
|
||||||
|
return Empty;
|
||||||
|
|
||||||
var width = lines.Max(l => l.Length);
|
var width = lines.Max(l => l.Length);
|
||||||
|
|
||||||
var alignedLines = lines
|
var alignedLines = lines
|
||||||
|
@ -27,8 +33,12 @@ public class TextBlock
|
||||||
{
|
{
|
||||||
var lines = things
|
var lines = things
|
||||||
.SelectMany(GetLines)
|
.SelectMany(GetLines)
|
||||||
|
.Unless(String.IsNullOrEmpty)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
if (!lines.Any())
|
||||||
|
return Empty;
|
||||||
|
|
||||||
var width = lines.Max(l => l.Length);
|
var width = lines.Max(l => l.Length);
|
||||||
|
|
||||||
var alignedLines = lines
|
var alignedLines = lines
|
||||||
|
@ -42,8 +52,12 @@ public class TextBlock
|
||||||
{
|
{
|
||||||
var lines = things
|
var lines = things
|
||||||
.SelectMany(GetLines)
|
.SelectMany(GetLines)
|
||||||
|
.Where(l => !String.IsNullOrEmpty(l))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
if (!lines.Any())
|
||||||
|
return Empty;
|
||||||
|
|
||||||
var width = lines.Max(l => l.Length);
|
var width = lines.Max(l => l.Length);
|
||||||
|
|
||||||
var alignedLines = lines
|
var alignedLines = lines
|
||||||
|
@ -53,14 +67,16 @@ public class TextBlock
|
||||||
return new TextBlock(alignedLines);
|
return new TextBlock(alignedLines);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static TextBlock AlignTop(IReadOnlyList<Object> things)
|
public static TextBlock AlignTop(IReadOnlyList<Object> things)
|
||||||
{
|
{
|
||||||
var columns = things
|
var columns = things
|
||||||
.Select(GetLines)
|
.Select(GetLines)
|
||||||
|
.Where(c => c.Count > 0)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
if (!columns.Any())
|
||||||
|
return Empty;
|
||||||
|
|
||||||
var height = columns.Max(l => l.Count);
|
var height = columns.Max(l => l.Count);
|
||||||
|
|
||||||
var alignedLines = Enumerable
|
var alignedLines = Enumerable
|
||||||
|
@ -76,8 +92,12 @@ public class TextBlock
|
||||||
{
|
{
|
||||||
var columns = things
|
var columns = things
|
||||||
.Select(GetLines)
|
.Select(GetLines)
|
||||||
|
.Where(c => c.Count > 0)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
if (!columns.Any())
|
||||||
|
return Empty;
|
||||||
|
|
||||||
var height = columns.Max(l => l.Count);
|
var height = columns.Max(l => l.Count);
|
||||||
|
|
||||||
var alignedLines = Enumerable
|
var alignedLines = Enumerable
|
||||||
|
@ -93,8 +113,12 @@ public class TextBlock
|
||||||
{
|
{
|
||||||
var columns = things
|
var columns = things
|
||||||
.Select(GetLines)
|
.Select(GetLines)
|
||||||
|
.Where(c => c.Count > 0)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
if (!columns.Any())
|
||||||
|
return Empty;
|
||||||
|
|
||||||
var height = columns.Max(l => l.Count);
|
var height = columns.Max(l => l.Count);
|
||||||
|
|
||||||
var alignedLines = Enumerable
|
var alignedLines = Enumerable
|
||||||
|
@ -105,18 +129,18 @@ public class TextBlock
|
||||||
return new TextBlock(alignedLines);
|
return new TextBlock(alignedLines);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TextBlock AlignLeft (params Object[] things) => AlignLeft ((IReadOnlyList<Object>) things);
|
public static TextBlock AlignLeft (params Object?[] things) => AlignLeft ((IReadOnlyList<Object>) things);
|
||||||
public static TextBlock AlignRight (params Object[] things) => AlignRight ((IReadOnlyList<Object>) things);
|
public static TextBlock AlignRight (params Object?[] things) => AlignRight ((IReadOnlyList<Object>) things);
|
||||||
public static TextBlock AlignTop (params Object[] things) => AlignTop ((IReadOnlyList<Object>) things);
|
public static TextBlock AlignTop (params Object?[] things) => AlignTop ((IReadOnlyList<Object>) things);
|
||||||
public static TextBlock AlignBottom (params Object[] things) => AlignBottom ((IReadOnlyList<Object>) things);
|
public static TextBlock AlignBottom (params Object?[] things) => AlignBottom ((IReadOnlyList<Object>) things);
|
||||||
public static TextBlock AlignCenterVertical (params Object[] things) => AlignCenterVertical ((IReadOnlyList<Object>) things);
|
public static TextBlock AlignCenterVertical (params Object?[] things) => AlignCenterVertical ((IReadOnlyList<Object>) things);
|
||||||
public static TextBlock AlignCenterHorizontal(params Object[] things) => AlignCenterHorizontal((IReadOnlyList<Object>) things);
|
public static TextBlock AlignCenterHorizontal(params Object?[] things) => AlignCenterHorizontal((IReadOnlyList<Object>) things);
|
||||||
|
|
||||||
public static TextBlock FromString(String thing) => AlignLeft(thing);
|
public static TextBlock FromString(String thing) => AlignLeft(thing);
|
||||||
|
|
||||||
public TextBlock Box()
|
public TextBlock Box()
|
||||||
{
|
{
|
||||||
var width = _Lines.Max(l => l.Length);
|
var width = _Lines.Any() ? _Lines.Max(l => l.Length) : 0;
|
||||||
|
|
||||||
var hLine = "".PadRight(width + 2, '─');
|
var hLine = "".PadRight(width + 2, '─');
|
||||||
var top = "┌" + hLine + "┐";
|
var top = "┌" + hLine + "┐";
|
||||||
|
@ -134,7 +158,7 @@ public class TextBlock
|
||||||
|
|
||||||
public TextBlock TitleBox(String title)
|
public TextBlock TitleBox(String title)
|
||||||
{
|
{
|
||||||
var linesWidth = _Lines.Max(l => l.Length);
|
var linesWidth = _Lines.Any() ? _Lines.Max(l => l.Length) : 0;
|
||||||
var titleWidth = title.Length;
|
var titleWidth = title.Length;
|
||||||
|
|
||||||
var width = Math.Max(linesWidth, titleWidth);
|
var width = Math.Max(linesWidth, titleWidth);
|
||||||
|
@ -175,11 +199,14 @@ public class TextBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static IReadOnlyList<String> GetLines(Object t)
|
private static IReadOnlyList<String> GetLines(Object? t)
|
||||||
{
|
{
|
||||||
return t is TextBlock tb
|
return t switch
|
||||||
? tb._Lines
|
{
|
||||||
: t.ToString()!.SplitLines();
|
TextBlock tb => tb._Lines,
|
||||||
|
null => Array.Empty<String>(),
|
||||||
|
_ => t.ToString()!.SplitLines()
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String Space(Int32 totalWidth)
|
private static String Space(Int32 totalWidth)
|
||||||
|
|
|
@ -60,10 +60,16 @@ public static class Utils
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Below does not work ;(
|
||||||
|
// [DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)]
|
||||||
|
// public static R Apply<T, S, R>(this T t, Func<S, R> f) where T : S
|
||||||
|
// {
|
||||||
|
// return f(t);
|
||||||
|
// }
|
||||||
|
|
||||||
[DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)]
|
[DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)]
|
||||||
public static R Apply<T, R>(this T t, Func<T, R> f) => f(t);
|
public static R Apply<T, R>(this T t, Func<T, R> f) => f(t);
|
||||||
|
|
||||||
|
|
||||||
[DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)]
|
[DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)]
|
||||||
public static R Apply<T1, T2, R>(this (T1 p1, T2 p2) t, Func<T1, T2, R> f) => f(t.p1, t.p2);
|
public static R Apply<T1, T2, R>(this (T1 p1, T2 p2) t, Func<T1, T2, R> f) => f(t.p1, t.p2);
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,15 @@
|
||||||
|
[package]
|
||||||
|
name = "VrmGrabberOxidised"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rocket = "=0.5.0-rc.3"
|
||||||
|
reqwest = "0.11.18"
|
||||||
|
openssl = { version = "0.10", features = ["vendored"]}
|
||||||
|
serde = {version = "1.0.173", features = ["derive"]}
|
||||||
|
serde_json = "1.0.103"
|
||||||
|
handlebars = "5.0.0-beta.1"
|
||||||
|
urlencoding = "2.1.2"
|
|
@ -0,0 +1,11 @@
|
||||||
|
pub struct Installation {
|
||||||
|
name: String,
|
||||||
|
vrm: i64,
|
||||||
|
ip: String,
|
||||||
|
identifier: String,
|
||||||
|
serial: String,
|
||||||
|
online: String,
|
||||||
|
last_seen: String,
|
||||||
|
number_of_batteries: String,
|
||||||
|
batter_firmware_version: String
|
||||||
|
}
|
|
@ -0,0 +1,168 @@
|
||||||
|
use rocket::serde;
|
||||||
|
use handlebars::Handlebars;
|
||||||
|
// use rocket::serde::__private::de::TagContentOtherField::Content;
|
||||||
|
|
||||||
|
use urlencoding::encode;
|
||||||
|
|
||||||
|
mod installation;
|
||||||
|
mod vrm_account;
|
||||||
|
|
||||||
|
|
||||||
|
struct InstallationToHtmlInterface<'a> {
|
||||||
|
Name: &'a str,
|
||||||
|
Ip: i64,
|
||||||
|
Vrm: &'a str,
|
||||||
|
Identifier: &'a str,
|
||||||
|
Serial: &'a str,
|
||||||
|
EscapedName: &'a str,
|
||||||
|
Online: &'a str,
|
||||||
|
LastSeen: &'a str,
|
||||||
|
NumBatteries: &'a str,
|
||||||
|
BatteryVersion: &'a str,
|
||||||
|
ServerIp : &'a str,
|
||||||
|
FirmwareVersion: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
// impl Default for InstallationToHtmlInterface{
|
||||||
|
// fn default() -> Self {
|
||||||
|
// Self{
|
||||||
|
// Name: "",
|
||||||
|
// Ip: 0,
|
||||||
|
// Vrm: "",
|
||||||
|
// Identifier: "",
|
||||||
|
// Serial: "",
|
||||||
|
// EscapedName: "",
|
||||||
|
// Online: "",
|
||||||
|
// LastSeen: "",
|
||||||
|
// NumBatteries: "",
|
||||||
|
// BatteryVersion: "",
|
||||||
|
// ServerIp : "10.2.0.1",
|
||||||
|
// FirmwareVersion: "AF09",
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
#[macro_use] extern crate rocket;
|
||||||
|
|
||||||
|
#[get("/")]
|
||||||
|
async fn index() -> String{
|
||||||
|
let res = vrm_account::all_installations_request().await;
|
||||||
|
let json = rocket::serde::Deserialize(res.unwrap().text().await.unwrap());
|
||||||
|
let source = "<head>
|
||||||
|
<style>
|
||||||
|
tbody {
|
||||||
|
background-color: #e4f0f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tbody tr:nth-child(odd) {
|
||||||
|
background-color: #ECE9E9;
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td { /* cell */
|
||||||
|
padding: 0.75rem;
|
||||||
|
font-size: 0.9375rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
th { /* header cell */
|
||||||
|
font-weight: 700;
|
||||||
|
text-align: left;
|
||||||
|
color: #272838;
|
||||||
|
border-bottom: 2px solid #EB9486;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
background-color: #F9F8F8;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
width: 100%;
|
||||||
|
border: 2px solid rgb(200, 200, 200);
|
||||||
|
letter-spacing: 1px;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
position: absolute; top: 0; bottom: 0; left: 0; right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead th {
|
||||||
|
border: 1px solid rgb(190, 190, 190);
|
||||||
|
padding: 5px 10px;
|
||||||
|
position: sticky;
|
||||||
|
position: -webkit-sticky;
|
||||||
|
top: 0px;
|
||||||
|
background: white;
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
#managerTable {
|
||||||
|
overflow: hidden;
|
||||||
|
}</style></head>
|
||||||
|
|
||||||
|
<div id='managerTable'>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Gui</th>
|
||||||
|
<th>VRM</th>
|
||||||
|
<th>Grafana</th>
|
||||||
|
<th>Identifier</th>
|
||||||
|
<th>Last Seen</th>
|
||||||
|
<th>Serial</th>
|
||||||
|
<th>#Batteries</th>
|
||||||
|
<th>Firmware-Version</th>
|
||||||
|
<th>Update</th>
|
||||||
|
</tr>
|
||||||
|
{{#inst}}
|
||||||
|
{{> installations}}
|
||||||
|
{{/inst}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div id='managerTable'>";
|
||||||
|
|
||||||
|
let partialSource= "<tr><td>{{Name}}</td>
|
||||||
|
<td><a target='_blank' href=http://{{Ip}}>{{online}} {{Ip}}</a></td>
|
||||||
|
<td><a target='_blank' href=https://vrm.victronenergy.com/installation/{{Vrm}}/dashboard>VRM</a></td>
|
||||||
|
<td><a target='_blank' href='https://salidomo.innovenergy.ch/d/ENkNRQXmk/installation?refresh=5s&orgId=1&var-Installation={{EscapedName}}&kiosk=tv'>Grafana</a></td>
|
||||||
|
<td>{{Identifier}}</td>
|
||||||
|
<td>{{LastSeen}}</td>
|
||||||
|
<td>{{Serial}}</td>
|
||||||
|
<td>{{NumBatteries}}</td>
|
||||||
|
<td>{{BatteryVersion}}</td>
|
||||||
|
<td><a target='_blank' href=https://{{ServerIp}}/UpdateBatteryFirmware/{{Ip}}/{{NumBatteries}}>⬆️{{FirmwareVersion}}</a></td>
|
||||||
|
</tr>";
|
||||||
|
|
||||||
|
let mut handlebars = Handlebars::new();
|
||||||
|
handlebars.register_template_string("installations", partialSource);
|
||||||
|
|
||||||
|
let mut installsForHtml = Vec::<InstallationToHtmlInterface>::new();
|
||||||
|
for inst in json["records"] {
|
||||||
|
let mut installation = InstallationToHtmlInterface {
|
||||||
|
Name: inst["name"],
|
||||||
|
Ip: 0, // TODO
|
||||||
|
Vrm: inst["idSite"].parse::<i64>(),
|
||||||
|
Identifier: inst["identifier"],
|
||||||
|
Serial: "", //Todo Grab and parse Details
|
||||||
|
EscapedName: &encode(inst["name"]).to_string(),
|
||||||
|
Online: "",
|
||||||
|
LastSeen: "",
|
||||||
|
NumBatteries: "",
|
||||||
|
BatteryVersion: "",
|
||||||
|
ServerIp : "10.2.0.1",
|
||||||
|
FirmwareVersion: "AF09",
|
||||||
|
};
|
||||||
|
installsForHtml.push(installation)
|
||||||
|
}
|
||||||
|
let mut data = installsForHtml;
|
||||||
|
|
||||||
|
let result = handlebars.render(source, &data);
|
||||||
|
return result.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[launch]
|
||||||
|
fn rocket() -> _ {
|
||||||
|
rocket::build().mount("/", routes![index])
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
use std::ops::Add;
|
||||||
|
use reqwest::{Error, Response};
|
||||||
|
// use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
|
||||||
|
const API_ROOT:&str ="https://vrmapi.victronenergy.com/v2";
|
||||||
|
const USER_ID:&str = "55450";
|
||||||
|
const TOKEN:&str = "88b36e7226ff7fa7bf231d0f9f98e916f661923c84e494cd27b6bc795ec0074b";
|
||||||
|
|
||||||
|
pub async fn all_installations_request() -> Result<Response, Error> {
|
||||||
|
// use reqwest::header::AUTHORIZATION;
|
||||||
|
let client = reqwest::Client::new();
|
||||||
|
let res = client
|
||||||
|
.get(API_ROOT.to_owned().add("/users/").add(USER_ID).add("/installations"))
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.header("x-authorization","Token ".to_owned()+TOKEN)
|
||||||
|
.send()
|
||||||
|
.await;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
export const axiosConfigWithoutToken = axios.create({
|
export const axiosConfigWithoutToken = axios.create({
|
||||||
baseURL: "http://localhost:5000/api",
|
baseURL: "https://localhost:7087",
|
||||||
});
|
});
|
||||||
|
|
||||||
const axiosConfig = axios.create({
|
const axiosConfig = axios.create({
|
||||||
baseURL: "http://localhost:5000/api",
|
baseURL: "https://localhost:7087",
|
||||||
});
|
});
|
||||||
|
|
||||||
axiosConfig.defaults.params = {};
|
axiosConfig.defaults.params = {};
|
||||||
|
|
Loading…
Reference in New Issue