use inverter class to share values between

the two protocol instances of a proxy
- move forward_at_cmd_resp into class InverterG3P
- store inverter ptr in Solarman_V5 instances
- add inverter ptr to all constructurs of protocols
- adapt doku and unit tests-
- add integration tests for AT+ commands which
  check the forwarding from and to the TSUN cloud
-
This commit is contained in:
Stefan Allius
2025-04-05 13:51:46 +02:00
parent 391f55bd26
commit 17811e6ce3
13 changed files with 284 additions and 168 deletions

View File

@@ -4,11 +4,11 @@
<!-- Generated by graphviz version 2.40.1 (20161225.0304) <!-- Generated by graphviz version 2.40.1 (20161225.0304)
--> -->
<!-- Title: G Pages: 1 --> <!-- Title: G Pages: 1 -->
<svg width="541pt" height="1940pt" <svg width="559pt" height="1940pt"
viewBox="0.00 0.00 540.62 1940.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> viewBox="0.00 0.00 558.62 1940.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 1936)"> <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 1936)">
<title>G</title> <title>G</title>
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-1936 536.6165,-1936 536.6165,4 -4,4"/> <polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-1936 554.6165,-1936 554.6165,4 -4,4"/>
<!-- A0 --> <!-- A0 -->
<g id="node1" class="node"> <g id="node1" class="node">
<title>A0</title> <title>A0</title>
@@ -47,78 +47,79 @@
<!-- A2 --> <!-- A2 -->
<g id="node3" class="node"> <g id="node3" class="node">
<title>A2</title> <title>A2</title>
<polygon fill="none" stroke="#000000" points="199.1165,-632 199.1165,-664 297.1165,-664 297.1165,-632 199.1165,-632"/> <polygon fill="none" stroke="#000000" points="185.1165,-638 185.1165,-670 301.1165,-670 301.1165,-638 185.1165,-638"/>
<text text-anchor="start" x="221.1665" y="-645" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">InverterG3P</text> <text text-anchor="start" x="216.1665" y="-651" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">InverterG3P</text>
<polygon fill="none" stroke="#000000" points="199.1165,-576 199.1165,-632 297.1165,-632 297.1165,-576 199.1165,-576"/> <polygon fill="none" stroke="#000000" points="185.1165,-570 185.1165,-638 301.1165,-638 301.1165,-570 185.1165,-570"/>
<text text-anchor="start" x="238.1135" y="-613" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">addr</text> <text text-anchor="start" x="233.1135" y="-619" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">addr</text>
<text text-anchor="start" x="208.6695" y="-601" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">remote:StreamPtr</text> <text text-anchor="start" x="194.775" y="-607" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">forward_at_cmd_resp</text>
<text text-anchor="start" x="213.9485" y="-589" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">local:StreamPtr</text> <text text-anchor="start" x="203.6695" y="-595" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">remote:StreamPtr</text>
<polygon fill="none" stroke="#000000" points="199.1165,-520 199.1165,-576 297.1165,-576 297.1165,-520 199.1165,-520"/> <text text-anchor="start" x="208.9485" y="-583" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">local:StreamPtr</text>
<text text-anchor="start" x="212.5585" y="-557" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">create_remote()</text> <polygon fill="none" stroke="#000000" points="185.1165,-514 185.1165,-570 301.1165,-570 301.1165,-514 185.1165,-514"/>
<text text-anchor="start" x="233.119" y="-533" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">close()</text> <text text-anchor="start" x="207.5585" y="-551" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">create_remote()</text>
<text text-anchor="start" x="228.119" y="-527" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">close()</text>
</g> </g>
<!-- A3 --> <!-- A3 -->
<g id="node4" class="node"> <g id="node4" class="node">
<title>A3</title> <title>A3</title>
<polygon fill="none" stroke="#000000" points="415.4531,-320 318.7799,-320 318.7799,-284 415.4531,-284 415.4531,-320"/> <polygon fill="none" stroke="#000000" points="411.4531,-320 314.7799,-320 314.7799,-284 411.4531,-284 411.4531,-320"/>
<text text-anchor="middle" x="367.1165" y="-299" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">local:StreamPtr</text> <text text-anchor="middle" x="363.1165" y="-299" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">local:StreamPtr</text>
</g> </g>
<!-- A2&#45;&gt;A3 --> <!-- A2&#45;&gt;A3 -->
<g id="edge1" class="edge"> <g id="edge1" class="edge">
<title>A2&#45;&gt;A3</title> <title>A2&#45;&gt;A3</title>
<path fill="none" stroke="#000000" d="M282.2534,-508.8093C307.0525,-448.3743 339.0836,-370.3156 355.8099,-329.5539"/> <path fill="none" stroke="#000000" d="M280.1686,-502.4575C304.7833,-442.972 335.4648,-368.8249 351.7401,-329.4931"/>
<polygon fill="#000000" stroke="#000000" points="282.2407,-508.8403 283.6635,-515.9097 277.6851,-519.942 276.2624,-512.8726 282.2407,-508.8403"/> <polygon fill="#000000" stroke="#000000" points="280.0204,-502.8156 281.4224,-509.8892 275.4322,-513.9038 274.0302,-506.8303 280.0204,-502.8156"/>
<polygon fill="#000000" stroke="#000000" points="359.6225,-320.2627 359.9893,-331.2224 357.7243,-324.8884 355.8262,-329.5141 355.8262,-329.5141 355.8262,-329.5141 357.7243,-324.8884 351.663,-327.8058 359.6225,-320.2627 359.6225,-320.2627"/> <polygon fill="#000000" stroke="#000000" points="355.6493,-320.0458 355.9838,-331.0066 353.7375,-324.6659 351.8257,-329.2859 351.8257,-329.2859 351.8257,-329.2859 353.7375,-324.6659 347.6676,-327.5653 355.6493,-320.0458 355.6493,-320.0458"/>
</g> </g>
<!-- A4 --> <!-- A4 -->
<g id="node5" class="node"> <g id="node5" class="node">
<title>A4</title> <title>A4</title>
<polygon fill="none" stroke="#000000" points="300.5106,-320 193.7224,-320 193.7224,-284 300.5106,-284 300.5106,-320"/> <polygon fill="none" stroke="#000000" points="296.5106,-320 189.7224,-320 189.7224,-284 296.5106,-284 296.5106,-320"/>
<text text-anchor="middle" x="247.1165" y="-299" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">remote:StreamPtr</text> <text text-anchor="middle" x="243.1165" y="-299" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">remote:StreamPtr</text>
</g> </g>
<!-- A2&#45;&gt;A4 --> <!-- A2&#45;&gt;A4 -->
<g id="edge2" class="edge"> <g id="edge2" class="edge">
<title>A2&#45;&gt;A4</title> <title>A2&#45;&gt;A4</title>
<path fill="none" stroke="#000000" d="M247.8254,-507.5905C247.6188,-447.68 247.3542,-370.9429 247.214,-330.266"/> <path fill="none" stroke="#000000" d="M243.1165,-501.6533C243.1165,-442.6619 243.1165,-369.5327 243.1165,-330.2027"/>
<polygon fill="#000000" stroke="#000000" points="247.8265,-507.9421 251.8473,-513.9282 247.868,-519.942 243.8473,-513.9559 247.8265,-507.9421"/> <polygon fill="#000000" stroke="#000000" points="243.1166,-501.9038 247.1165,-507.9039 243.1165,-513.9038 239.1165,-507.9038 243.1166,-501.9038"/>
<polygon fill="#000000" stroke="#000000" points="247.1795,-320.2627 251.714,-330.2471 247.1968,-325.2627 247.2141,-330.2626 247.2141,-330.2626 247.2141,-330.2626 247.1968,-325.2627 242.7141,-330.2782 247.1795,-320.2627 247.1795,-320.2627"/> <polygon fill="#000000" stroke="#000000" points="243.1165,-320.0458 247.6166,-330.0457 243.1165,-325.0458 243.1166,-330.0458 243.1166,-330.0458 243.1166,-330.0458 243.1165,-325.0458 238.6166,-330.0458 243.1165,-320.0458 243.1165,-320.0458"/>
</g> </g>
<!-- A8 --> <!-- A8 -->
<g id="node9" class="node"> <g id="node9" class="node">
<title>A8</title> <title>A8</title>
<polygon fill="none" stroke="#000000" points="261.1165,-100 261.1165,-132 439.1165,-132 439.1165,-100 261.1165,-100"/> <polygon fill="none" stroke="#000000" points="257.1165,-100 257.1165,-132 435.1165,-132 435.1165,-100 257.1165,-100"/>
<text text-anchor="start" x="305.668" y="-113" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">AsyncStreamServer</text> <text text-anchor="start" x="301.668" y="-113" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">AsyncStreamServer</text>
<polygon fill="none" stroke="#000000" points="261.1165,-68 261.1165,-100 439.1165,-100 439.1165,-68 261.1165,-68"/> <polygon fill="none" stroke="#000000" points="257.1165,-68 257.1165,-100 435.1165,-100 435.1165,-68 257.1165,-68"/>
<text text-anchor="start" x="317.8875" y="-81" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">create_remote</text> <text text-anchor="start" x="313.8875" y="-81" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">create_remote</text>
<polygon fill="none" stroke="#000000" points="261.1165,0 261.1165,-68 439.1165,-68 439.1165,0 261.1165,0"/> <polygon fill="none" stroke="#000000" points="257.1165,0 257.1165,-68 435.1165,-68 435.1165,0 257.1165,0"/>
<text text-anchor="start" x="301.774" y="-49" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">&lt;async&gt;server_loop()</text> <text text-anchor="start" x="297.774" y="-49" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">&lt;async&gt;server_loop()</text>
<text text-anchor="start" x="292.605" y="-37" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">&lt;async&gt;_async_forward()</text> <text text-anchor="start" x="288.605" y="-37" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">&lt;async&gt;_async_forward()</text>
<text text-anchor="start" x="270.9255" y="-25" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">&lt;async&gt;publish_outstanding_mqtt()</text> <text text-anchor="start" x="266.9255" y="-25" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">&lt;async&gt;publish_outstanding_mqtt()</text>
<text text-anchor="start" x="335.119" y="-13" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">close()</text> <text text-anchor="start" x="331.119" y="-13" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">close()</text>
</g> </g>
<!-- A3&#45;&gt;A8 --> <!-- A3&#45;&gt;A8 -->
<g id="edge8" class="edge"> <g id="edge8" class="edge">
<title>A3&#45;&gt;A8</title> <title>A3&#45;&gt;A8</title>
<path fill="none" stroke="#000000" d="M364.9314,-271.6651C362.5869,-239.1181 358.7725,-186.1658 355.6014,-142.1431"/> <path fill="none" stroke="#000000" d="M360.9314,-271.6651C358.5869,-239.1181 354.7725,-186.1658 351.6014,-142.1431"/>
<polygon fill="#000000" stroke="#000000" points="364.9485,-271.9044 369.3693,-277.6014 365.8108,-283.8733 361.39,-278.1763 364.9485,-271.9044"/> <polygon fill="#000000" stroke="#000000" points="360.9485,-271.9044 365.3693,-277.6014 361.8108,-283.8733 357.39,-278.1763 360.9485,-271.9044"/>
<polygon fill="#000000" stroke="#000000" points="354.8731,-132.0321 360.08,-141.6829 355.2323,-137.0192 355.5916,-142.0063 355.5916,-142.0063 355.5916,-142.0063 355.2323,-137.0192 351.1032,-142.3296 354.8731,-132.0321 354.8731,-132.0321"/> <polygon fill="#000000" stroke="#000000" points="350.8731,-132.0321 356.08,-141.6829 351.2323,-137.0192 351.5916,-142.0063 351.5916,-142.0063 351.5916,-142.0063 351.2323,-137.0192 347.1032,-142.3296 350.8731,-132.0321 350.8731,-132.0321"/>
</g> </g>
<!-- A9 --> <!-- A9 -->
<g id="node10" class="node"> <g id="node10" class="node">
<title>A9</title> <title>A9</title>
<polygon fill="none" stroke="#000000" points="89.1165,-82 89.1165,-114 227.1165,-114 227.1165,-82 89.1165,-82"/> <polygon fill="none" stroke="#000000" points="85.1165,-82 85.1165,-114 223.1165,-114 223.1165,-82 85.1165,-82"/>
<text text-anchor="start" x="115.6135" y="-95" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">AsyncStreamClient</text> <text text-anchor="start" x="111.6135" y="-95" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">AsyncStreamClient</text>
<polygon fill="none" stroke="#000000" points="89.1165,-62 89.1165,-82 227.1165,-82 227.1165,-62 89.1165,-62"/> <polygon fill="none" stroke="#000000" points="85.1165,-62 85.1165,-82 223.1165,-82 223.1165,-62 85.1165,-62"/>
<polygon fill="none" stroke="#000000" points="89.1165,-18 89.1165,-62 227.1165,-62 227.1165,-18 89.1165,-18"/> <polygon fill="none" stroke="#000000" points="85.1165,-18 85.1165,-62 223.1165,-62 223.1165,-18 85.1165,-18"/>
<text text-anchor="start" x="111.9945" y="-43" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">&lt;async&gt;client_loop()</text> <text text-anchor="start" x="107.9945" y="-43" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">&lt;async&gt;client_loop()</text>
<text text-anchor="start" x="98.9405" y="-31" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">&lt;async&gt;_async_forward())</text> <text text-anchor="start" x="94.9405" y="-31" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">&lt;async&gt;_async_forward())</text>
</g> </g>
<!-- A4&#45;&gt;A9 --> <!-- A4&#45;&gt;A9 -->
<g id="edge10" class="edge"> <g id="edge10" class="edge">
<title>A4&#45;&gt;A9</title> <title>A4&#45;&gt;A9</title>
<path fill="none" stroke="#000000" d="M240.2806,-283.8733C227.5204,-250.0372 199.5834,-175.9573 179.8383,-123.5994"/> <path fill="none" stroke="#000000" d="M236.2806,-283.8733C223.5204,-250.0372 195.5834,-175.9573 175.8383,-123.5994"/>
<polygon fill="#000000" stroke="#000000" points="176.2523,-114.0904 183.9915,-121.8593 178.0166,-118.7688 179.781,-123.4472 179.781,-123.4472 179.781,-123.4472 178.0166,-118.7688 175.5704,-125.0351 176.2523,-114.0904 176.2523,-114.0904"/> <polygon fill="#000000" stroke="#000000" points="172.2523,-114.0904 179.9915,-121.8593 174.0166,-118.7688 175.781,-123.4472 175.781,-123.4472 175.781,-123.4472 174.0166,-118.7688 171.5704,-125.0351 172.2523,-114.0904 172.2523,-114.0904"/>
<text text-anchor="middle" x="225.9759" y="-266.8956" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">0..1</text> <text text-anchor="middle" x="221.9759" y="-266.8956" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">0..1</text>
</g> </g>
<!-- A5 --> <!-- A5 -->
<g id="node6" class="node"> <g id="node6" class="node">
@@ -149,138 +150,139 @@
<!-- A6 --> <!-- A6 -->
<g id="node7" class="node"> <g id="node7" class="node">
<title>A6</title> <title>A6</title>
<polygon fill="none" stroke="#000000" points="84.1165,-622 84.1165,-654 177.1165,-654 177.1165,-622 84.1165,-622"/> <polygon fill="none" stroke="#000000" points="74.1165,-622 74.1165,-654 167.1165,-654 167.1165,-622 74.1165,-622"/>
<text text-anchor="start" x="102.2805" y="-635" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">AsyncIfcImpl</text> <text text-anchor="start" x="92.2805" y="-635" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">AsyncIfcImpl</text>
<polygon fill="none" stroke="#000000" points="84.1165,-530 84.1165,-622 177.1165,-622 177.1165,-530 84.1165,-530"/> <polygon fill="none" stroke="#000000" points="74.1165,-530 74.1165,-622 167.1165,-622 167.1165,-530 74.1165,-530"/>
<text text-anchor="start" x="93.6645" y="-603" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">fwd_fifo:ByteFifo</text> <text text-anchor="start" x="83.6645" y="-603" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">fwd_fifo:ByteFifo</text>
<text text-anchor="start" x="97.5535" y="-591" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">tx_fifo:ByteFifo</text> <text text-anchor="start" x="87.5535" y="-591" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">tx_fifo:ByteFifo</text>
<text text-anchor="start" x="97.2785" y="-579" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">rx_fifo:ByteFifo</text> <text text-anchor="start" x="87.2785" y="-579" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">rx_fifo:ByteFifo</text>
<text text-anchor="start" x="96.7125" y="-567" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">conn_no:Count</text> <text text-anchor="start" x="86.7125" y="-567" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">conn_no:Count</text>
<text text-anchor="start" x="112.83" y="-555" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">node_id</text> <text text-anchor="start" x="102.83" y="-555" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">node_id</text>
<text text-anchor="start" x="106.166" y="-543" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">timeout_cb</text> <text text-anchor="start" x="96.166" y="-543" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">timeout_cb</text>
</g> </g>
<!-- A5&#45;&gt;A6 --> <!-- A5&#45;&gt;A6 -->
<g id="edge3" class="edge"> <g id="edge3" class="edge">
<title>A5&#45;&gt;A6</title> <title>A5&#45;&gt;A6</title>
<path fill="none" stroke="#000000" stroke-dasharray="5,2" d="M165.2976,-752.0017C157.592,-716.9571 149.9649,-682.2694 143.7924,-654.1971"/> <path fill="none" stroke="#000000" stroke-dasharray="5,2" d="M160.1169,-752.0017C151.3558,-716.9571 142.6838,-682.2694 135.6658,-654.1971"/>
<polygon fill="none" stroke="#000000" points="161.906,-752.8753 167.4719,-761.8903 168.7427,-751.372 161.906,-752.8753"/> <polygon fill="none" stroke="#000000" points="156.7681,-753.0378 162.5891,-761.8903 163.5591,-751.34 156.7681,-753.0378"/>
</g> </g>
<!-- A7 --> <!-- A7 -->
<g id="node8" class="node"> <g id="node8" class="node">
<title>A7</title> <title>A7</title>
<polygon fill="none" stroke="#000000" points="74.1165,-390 74.1165,-422 176.1165,-422 176.1165,-390 74.1165,-390"/> <polygon fill="none" stroke="#000000" points="70.1165,-390 70.1165,-422 172.1165,-422 172.1165,-390 70.1165,-390"/>
<text text-anchor="start" x="95.3905" y="-403" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">AsyncStream</text> <text text-anchor="start" x="91.3905" y="-403" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">AsyncStream</text>
<polygon fill="none" stroke="#000000" points="74.1165,-310 74.1165,-390 176.1165,-390 176.1165,-310 74.1165,-310"/> <polygon fill="none" stroke="#000000" points="70.1165,-310 70.1165,-390 172.1165,-390 172.1165,-310 70.1165,-310"/>
<text text-anchor="start" x="110.6695" y="-371" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">reader</text> <text text-anchor="start" x="106.6695" y="-371" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">reader</text>
<text text-anchor="start" x="112.8995" y="-359" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">writer</text> <text text-anchor="start" x="108.8995" y="-359" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">writer</text>
<text text-anchor="start" x="115.1135" y="-347" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">addr</text> <text text-anchor="start" x="111.1135" y="-347" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">addr</text>
<text text-anchor="start" x="110.6695" y="-335" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">r_addr</text> <text text-anchor="start" x="106.6695" y="-335" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">r_addr</text>
<text text-anchor="start" x="111.2245" y="-323" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">l_addr</text> <text text-anchor="start" x="107.2245" y="-323" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">l_addr</text>
<polygon fill="none" stroke="#000000" points="74.1165,-182 74.1165,-310 176.1165,-310 176.1165,-182 74.1165,-182"/> <polygon fill="none" stroke="#000000" points="70.1165,-182 70.1165,-310 172.1165,-310 172.1165,-182 70.1165,-182"/>
<text text-anchor="start" x="96.7705" y="-279" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">&lt;async&gt;loop</text> <text text-anchor="start" x="92.7705" y="-279" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">&lt;async&gt;loop</text>
<text text-anchor="start" x="112.8985" y="-267" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">disc()</text> <text text-anchor="start" x="108.8985" y="-267" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">disc()</text>
<text text-anchor="start" x="110.119" y="-255" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">close()</text> <text text-anchor="start" x="106.119" y="-255" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">close()</text>
<text text-anchor="start" x="105.6705" y="-243" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">healthy()</text> <text text-anchor="start" x="101.6705" y="-243" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">healthy()</text>
<text text-anchor="start" x="90.387" y="-219" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">__async_read()</text> <text text-anchor="start" x="86.387" y="-219" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">__async_read()</text>
<text text-anchor="start" x="89.8375" y="-207" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">__async_write()</text> <text text-anchor="start" x="85.8375" y="-207" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">__async_write()</text>
<text text-anchor="start" x="83.7235" y="-195" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">__async_forward()</text> <text text-anchor="start" x="79.7235" y="-195" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">__async_forward()</text>
</g> </g>
<!-- A6&#45;&gt;A7 --> <!-- A6&#45;&gt;A7 -->
<g id="edge4" class="edge"> <g id="edge4" class="edge">
<title>A6&#45;&gt;A7</title> <title>A6&#45;&gt;A7</title>
<path fill="none" stroke="#000000" d="M128.868,-519.5861C128.3592,-490.0737 127.7571,-455.1552 127.186,-422.0295"/> <path fill="none" stroke="#000000" d="M120.3662,-519.5861C120.468,-490.0737 120.5884,-455.1552 120.7026,-422.0295"/>
<polygon fill="none" stroke="#000000" points="125.3719,-519.8496 129.0439,-529.7877 132.3709,-519.7288 125.3719,-519.8496"/> <polygon fill="none" stroke="#000000" points="116.8656,-519.7757 120.331,-529.7877 123.8656,-519.7999 116.8656,-519.7757"/>
</g> </g>
<!-- A7&#45;&gt;A8 --> <!-- A7&#45;&gt;A8 -->
<g id="edge5" class="edge"> <g id="edge5" class="edge">
<title>A7&#45;&gt;A8</title> <title>A7&#45;&gt;A8</title>
<path fill="none" stroke="#000000" d="M182.5777,-185.0204C183.4154,-184.0001 184.2616,-182.9929 185.1165,-182 206.4788,-157.1889 234.2469,-135.0276 260.8921,-116.8901"/> <path fill="none" stroke="#000000" d="M178.5777,-185.0204C179.4154,-184.0001 180.2616,-182.9929 181.1165,-182 202.4788,-157.1889 230.2469,-135.0276 256.8921,-116.8901"/>
<polygon fill="none" stroke="#000000" points="179.6875,-183.0361 176.3256,-193.0834 185.2193,-187.3255 179.6875,-183.0361"/> <polygon fill="none" stroke="#000000" points="175.6875,-183.0361 172.3256,-193.0834 181.2193,-187.3255 175.6875,-183.0361"/>
</g> </g>
<!-- A7&#45;&gt;A9 --> <!-- A7&#45;&gt;A9 -->
<g id="edge6" class="edge"> <g id="edge6" class="edge">
<title>A7&#45;&gt;A9</title> <title>A7&#45;&gt;A9</title>
<path fill="none" stroke="#000000" d="M143.3214,-171.8077C146.1952,-151.2556 148.9992,-131.2022 151.3799,-114.1772"/> <path fill="none" stroke="#000000" d="M139.3214,-171.8077C142.1952,-151.2556 144.9992,-131.2022 147.3799,-114.1772"/>
<polygon fill="none" stroke="#000000" points="139.8252,-171.5375 141.9065,-181.9259 146.7577,-172.5069 139.8252,-171.5375"/> <polygon fill="none" stroke="#000000" points="135.8252,-171.5375 137.9065,-181.9259 142.7577,-172.5069 135.8252,-171.5375"/>
</g> </g>
<!-- A10 --> <!-- A10 -->
<g id="node11" class="node"> <g id="node11" class="node">
<title>A10</title> <title>A10</title>
<polygon fill="none" stroke="#000000" points="318.1165,-668 318.1165,-700 409.1165,-700 409.1165,-668 318.1165,-668"/> <polygon fill="none" stroke="#000000" points="319.1165,-668 319.1165,-700 429.1165,-700 429.1165,-668 319.1165,-668"/>
<text text-anchor="start" x="336.1115" y="-681" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">SolarmanV5</text> <text text-anchor="start" x="346.6115" y="-681" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">SolarmanV5</text>
<polygon fill="none" stroke="#000000" points="318.1165,-552 318.1165,-668 409.1165,-668 409.1165,-552 318.1165,-552"/> <polygon fill="none" stroke="#000000" points="319.1165,-552 319.1165,-668 429.1165,-668 429.1165,-552 319.1165,-552"/>
<text text-anchor="start" x="344.4395" y="-649" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">conn_no</text> <text text-anchor="start" x="354.9395" y="-649" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">conn_no</text>
<text text-anchor="start" x="353.6135" y="-637" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">addr</text> <text text-anchor="start" x="364.1135" y="-637" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">addr</text>
<text text-anchor="start" x="348.6145" y="-613" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">control</text> <text text-anchor="start" x="329.1105" y="-625" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">inverter:InverterG3P</text>
<text text-anchor="start" x="351.674" y="-601" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">serial</text> <text text-anchor="start" x="359.1145" y="-613" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">control</text>
<text text-anchor="start" x="356.6725" y="-589" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">snr</text> <text text-anchor="start" x="362.174" y="-601" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">serial</text>
<text text-anchor="start" x="335.8265" y="-577" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">db:InfosG3P</text> <text text-anchor="start" x="367.1725" y="-589" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">snr</text>
<text text-anchor="start" x="349.7285" y="-565" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">switch</text> <text text-anchor="start" x="346.3265" y="-577" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">db:InfosG3P</text>
<polygon fill="none" stroke="#000000" points="318.1165,-484 318.1165,-552 409.1165,-552 409.1165,-484 318.1165,-484"/> <text text-anchor="start" x="360.2285" y="-565" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">switch</text>
<text text-anchor="start" x="328.057" y="-533" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">msg_unknown()</text> <polygon fill="none" stroke="#000000" points="319.1165,-484 319.1165,-552 429.1165,-552 429.1165,-484 319.1165,-484"/>
<text text-anchor="start" x="344.1705" y="-509" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">healthy()</text> <text text-anchor="start" x="338.557" y="-533" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">msg_unknown()</text>
<text text-anchor="start" x="348.619" y="-497" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">close()</text> <text text-anchor="start" x="354.6705" y="-509" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">healthy()</text>
<text text-anchor="start" x="359.119" y="-497" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">close()</text>
</g> </g>
<!-- A10&#45;&gt;A3 --> <!-- A10&#45;&gt;A3 -->
<g id="edge7" class="edge"> <g id="edge7" class="edge">
<title>A10&#45;&gt;A3</title> <title>A10&#45;&gt;A3</title>
<path fill="none" stroke="#000000" d="M364.7507,-473.5237C365.4625,-421.9136 366.2384,-365.6622 366.7008,-332.138"/> <path fill="none" stroke="#000000" d="M369.6226,-473.5237C367.6649,-421.9136 365.5313,-365.6622 364.2597,-332.138"/>
<polygon fill="#000000" stroke="#000000" points="364.6116,-483.6023 360.2501,-473.5412 364.6806,-478.6028 364.7497,-473.6033 364.7497,-473.6033 364.7497,-473.6033 364.6806,-478.6028 369.2492,-473.6654 364.6116,-483.6023 364.6116,-483.6023"/> <polygon fill="#000000" stroke="#000000" points="370.0049,-483.6023 365.129,-473.7801 369.8153,-478.6059 369.6257,-473.6095 369.6257,-473.6095 369.6257,-473.6095 369.8153,-478.6059 374.1225,-473.4389 370.0049,-483.6023 370.0049,-483.6023"/>
<polygon fill="#000000" stroke="#000000" points="366.7019,-332.0519 362.7851,-325.9973 366.8675,-320.053 370.7843,-326.1077 366.7019,-332.0519"/> <polygon fill="#000000" stroke="#000000" points="364.2562,-332.0444 360.0316,-326.2004 363.8013,-320.053 368.0259,-325.8971 364.2562,-332.0444"/>
</g> </g>
<!-- A10&#45;&gt;A4 --> <!-- A10&#45;&gt;A4 -->
<g id="edge9" class="edge"> <g id="edge9" class="edge">
<title>A10&#45;&gt;A4</title> <title>A10&#45;&gt;A4</title>
<path fill="none" stroke="#000000" d="M316.0157,-474.2481C292.5547,-415.5956 266.6257,-350.7729 254.3377,-320.053"/> <path fill="none" stroke="#000000" d="M320.9251,-474.2481C294.4304,-415.5956 265.1484,-350.7729 251.2715,-320.053"/>
<polygon fill="#000000" stroke="#000000" points="319.7574,-483.6023 311.8653,-475.9888 317.9004,-478.9599 316.0435,-474.3175 316.0435,-474.3175 316.0435,-474.3175 317.9004,-478.9599 320.2216,-472.6462 319.7574,-483.6023 319.7574,-483.6023"/> <polygon fill="#000000" stroke="#000000" points="325.1506,-483.6023 316.9329,-476.3415 323.0923,-479.0456 321.0339,-474.489 321.0339,-474.489 321.0339,-474.489 323.0923,-479.0456 325.1349,-472.6364 325.1506,-483.6023 325.1506,-483.6023"/>
<text text-anchor="middle" x="268.9174" y="-330.7436" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">0..1</text> <text text-anchor="middle" x="266.4364" y="-330.0924" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">0..1</text>
</g> </g>
<!-- A12 --> <!-- A12 -->
<g id="node13" class="node"> <g id="node13" class="node">
<title>A12</title> <title>A12</title>
<polygon fill="none" stroke="#000000" points="434.1165,-336 434.1165,-368 529.1165,-368 529.1165,-336 434.1165,-336"/> <polygon fill="none" stroke="#000000" points="441.1165,-336 441.1165,-368 536.1165,-368 536.1165,-336 441.1165,-336"/>
<text text-anchor="start" x="460.775" y="-349" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">InfosG3P</text> <text text-anchor="start" x="467.775" y="-349" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">InfosG3P</text>
<polygon fill="none" stroke="#000000" points="434.1165,-304 434.1165,-336 529.1165,-336 529.1165,-304 434.1165,-304"/> <polygon fill="none" stroke="#000000" points="441.1165,-304 441.1165,-336 536.1165,-336 536.1165,-304 441.1165,-304"/>
<text text-anchor="start" x="443.829" y="-317" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">client_mode:bool</text> <text text-anchor="start" x="450.829" y="-317" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">client_mode:bool</text>
<polygon fill="none" stroke="#000000" points="434.1165,-236 434.1165,-304 529.1165,-304 529.1165,-236 434.1165,-236"/> <polygon fill="none" stroke="#000000" points="441.1165,-236 441.1165,-304 536.1165,-304 536.1165,-236 441.1165,-236"/>
<text text-anchor="start" x="458.0005" y="-285" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ha_confs()</text> <text text-anchor="start" x="465.0005" y="-285" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ha_confs()</text>
<text text-anchor="start" x="465.7845" y="-273" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">parse()</text> <text text-anchor="start" x="472.7845" y="-273" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">parse()</text>
<text text-anchor="start" x="469.3985" y="-261" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">calc()</text> <text text-anchor="start" x="476.3985" y="-261" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">calc()</text>
<text text-anchor="start" x="467.73" y="-249" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">build()</text> <text text-anchor="start" x="474.73" y="-249" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">build()</text>
</g> </g>
<!-- A10&#45;&gt;A12 --> <!-- A10&#45;&gt;A12 -->
<g id="edge12" class="edge"> <g id="edge12" class="edge">
<title>A10&#45;&gt;A12</title> <title>A10&#45;&gt;A12</title>
<path fill="none" stroke="#000000" d="M407.2231,-483.6023C421.5819,-448.3138 437.2,-409.9305 450.3629,-377.5809"/> <path fill="none" stroke="#000000" d="M416.728,-483.6023C430.6001,-448.3138 445.6887,-409.9305 458.4054,-377.5809"/>
<polygon fill="#000000" stroke="#000000" points="454.1856,-368.1861 454.5848,-379.1447 452.3011,-372.8174 450.4166,-377.4487 450.4166,-377.4487 450.4166,-377.4487 452.3011,-372.8174 446.2485,-375.7526 454.1856,-368.1861 454.1856,-368.1861"/> <polygon fill="#000000" stroke="#000000" points="462.0985,-368.1861 462.628,-379.1392 460.2692,-372.8395 458.4399,-377.4928 458.4399,-377.4928 458.4399,-377.4928 460.2692,-372.8395 454.2519,-375.8465 462.0985,-368.1861 462.0985,-368.1861"/>
</g> </g>
<!-- A11 --> <!-- A11 -->
<g id="node12" class="node"> <g id="node12" class="node">
<title>A11</title> <title>A11</title>
<polygon fill="none" stroke="#000000" points="430.1165,-680 430.1165,-712 533.1165,-712 533.1165,-680 430.1165,-680"/> <polygon fill="none" stroke="#000000" points="448.1165,-680 448.1165,-712 551.1165,-712 551.1165,-680 448.1165,-680"/>
<text text-anchor="start" x="470.7785" y="-693" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">Infos</text> <text text-anchor="start" x="488.7785" y="-693" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">Infos</text>
<polygon fill="none" stroke="#000000" points="430.1165,-624 430.1165,-680 533.1165,-680 533.1165,-624 430.1165,-624"/> <polygon fill="none" stroke="#000000" points="448.1165,-624 448.1165,-680 551.1165,-680 551.1165,-624 448.1165,-624"/>
<text text-anchor="start" x="473.558" y="-661" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">stat</text> <text text-anchor="start" x="491.558" y="-661" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">stat</text>
<text text-anchor="start" x="449.1025" y="-649" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">new_stat_data</text> <text text-anchor="start" x="467.1025" y="-649" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">new_stat_data</text>
<text text-anchor="start" x="462.72" y="-637" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">info_dev</text> <text text-anchor="start" x="480.72" y="-637" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">info_dev</text>
<polygon fill="none" stroke="#000000" points="430.1165,-472 430.1165,-624 533.1165,-624 533.1165,-472 430.1165,-472"/> <polygon fill="none" stroke="#000000" points="448.1165,-472 448.1165,-624 551.1165,-624 551.1165,-472 448.1165,-472"/>
<text text-anchor="start" x="457.452" y="-605" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">static_init()</text> <text text-anchor="start" x="475.452" y="-605" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">static_init()</text>
<text text-anchor="start" x="455.501" y="-593" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">dev_value()</text> <text text-anchor="start" x="473.501" y="-593" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">dev_value()</text>
<text text-anchor="start" x="452.447" y="-581" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">inc_counter()</text> <text text-anchor="start" x="470.447" y="-581" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">inc_counter()</text>
<text text-anchor="start" x="450.777" y="-569" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">dec_counter()</text> <text text-anchor="start" x="468.777" y="-569" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">dec_counter()</text>
<text text-anchor="start" x="448.8265" y="-557" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ha_proxy_conf</text> <text text-anchor="start" x="466.8265" y="-557" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ha_proxy_conf</text>
<text text-anchor="start" x="463.8295" y="-545" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ha_conf</text> <text text-anchor="start" x="481.8295" y="-545" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ha_conf</text>
<text text-anchor="start" x="456.6105" y="-533" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ha_remove</text> <text text-anchor="start" x="474.6105" y="-533" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ha_remove</text>
<text text-anchor="start" x="457.991" y="-521" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">update_db</text> <text text-anchor="start" x="475.991" y="-521" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">update_db</text>
<text text-anchor="start" x="442.1535" y="-509" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">set_db_def_value</text> <text text-anchor="start" x="460.1535" y="-509" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">set_db_def_value</text>
<text text-anchor="start" x="451.602" y="-497" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">get_db_value</text> <text text-anchor="start" x="469.602" y="-497" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">get_db_value</text>
<text text-anchor="start" x="439.939" y="-485" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ignore_this_device</text> <text text-anchor="start" x="457.939" y="-485" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ignore_this_device</text>
</g> </g>
<!-- A11&#45;&gt;A12 --> <!-- A11&#45;&gt;A12 -->
<g id="edge11" class="edge"> <g id="edge11" class="edge">
<title>A11&#45;&gt;A12</title> <title>A11&#45;&gt;A12</title>
<path fill="none" stroke="#000000" d="M481.1165,-461.9134C481.1165,-429.4373 481.1165,-395.9527 481.1165,-368.0691"/> <path fill="none" stroke="#000000" d="M494.1822,-461.9134C492.9503,-429.4373 491.6802,-395.9527 490.6226,-368.0691"/>
<polygon fill="none" stroke="#000000" points="477.6166,-461.9525 481.1165,-471.9525 484.6166,-461.9526 477.6166,-461.9525"/> <polygon fill="none" stroke="#000000" points="490.6864,-462.0924 494.563,-471.9525 497.6813,-461.827 490.6864,-462.0924"/>
</g> </g>
<!-- A13 --> <!-- A13 -->
<g id="node14" class="node"> <g id="node14" class="node">
@@ -324,8 +326,8 @@
<!-- A13&#45;&gt;A10 --> <!-- A13&#45;&gt;A10 -->
<g id="edge16" class="edge"> <g id="edge16" class="edge">
<title>A13&#45;&gt;A10</title> <title>A13&#45;&gt;A10</title>
<path fill="none" stroke="#000000" d="M276.8964,-1125.5329C298.8204,-989.8666 327.5006,-812.3923 345.6214,-700.2604"/> <path fill="none" stroke="#000000" d="M279.7902,-1125.5329C303.7754,-989.8666 335.1521,-812.3923 354.9765,-700.2604"/>
<polygon fill="none" stroke="#000000" points="273.4037,-1125.2075 275.2634,-1135.6378 280.314,-1126.3243 273.4037,-1125.2075"/> <polygon fill="none" stroke="#000000" points="276.2982,-1125.1812 278.0037,-1135.6378 283.1913,-1126.3999 276.2982,-1125.1812"/>
</g> </g>
<!-- A14&#45;&gt;A13 --> <!-- A14&#45;&gt;A13 -->
<g id="edge15" class="edge"> <g id="edge15" class="edge">

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

@@ -5,7 +5,7 @@
[note: Example of instantiation for a GEN3PLUS inverter!{bg:cornsilk}] [note: Example of instantiation for a GEN3PLUS inverter!{bg:cornsilk}]
[<<AbstractIterMeta>>||__iter__()] [<<AbstractIterMeta>>||__iter__()]
[InverterG3P|addr;remote:StreamPtr;local:StreamPtr|create_remote();;close()] [InverterG3P|addr;forward_at_cmd_resp;remote:StreamPtr;local:StreamPtr|create_remote();;close()]
[InverterG3P]++->[local:StreamPtr] [InverterG3P]++->[local:StreamPtr]
[InverterG3P]++->[remote:StreamPtr] [InverterG3P]++->[remote:StreamPtr]
@@ -19,7 +19,7 @@
[AsyncStream]^[AsyncStreamServer] [AsyncStream]^[AsyncStreamServer]
[AsyncStream]^[AsyncStreamClient] [AsyncStream]^[AsyncStreamClient]
[SolarmanV5|conn_no;addr;;control;serial;snr;db:InfosG3P;switch|msg_unknown();;healthy();close()] [SolarmanV5|conn_no;addr;inverter:InverterG3P;control;serial;snr;db:InfosG3P;switch|msg_unknown();;healthy();close()]
[SolarmanV5]<-++[local:StreamPtr] [SolarmanV5]<-++[local:StreamPtr]
[local:StreamPtr]++->[AsyncStreamServer] [local:StreamPtr]++->[AsyncStreamServer]
[SolarmanV5]<-0..1[remote:StreamPtr] [SolarmanV5]<-0..1[remote:StreamPtr]

View File

@@ -34,10 +34,11 @@ class Control:
class Talent(Message): class Talent(Message):
TXT_UNKNOWN_CTRL = 'Unknown Ctrl' TXT_UNKNOWN_CTRL = 'Unknown Ctrl'
def __init__(self, addr, ifc: "AsyncIfc", server_side: bool, def __init__(self, inverter, addr, ifc: "AsyncIfc", server_side: bool,
client_mode: bool = False, id_str=b''): client_mode: bool = False, id_str=b''):
super().__init__('G3', ifc, server_side, self.send_modbus_cb, super().__init__('G3', ifc, server_side, self.send_modbus_cb,
mb_timeout=15) mb_timeout=15)
_ = inverter
ifc.rx_set_cb(self.read) ifc.rx_set_cb(self.read)
ifc.prot_set_timeout_cb(self._timeout) ifc.prot_set_timeout_cb(self._timeout)
ifc.prot_set_init_new_client_conn_cb(self._init_new_client_conn) ifc.prot_set_init_new_client_conn_cb(self._init_new_client_conn)

View File

@@ -193,13 +193,12 @@ class RegisterSel:
class InfosG3P(Infos): class InfosG3P(Infos):
__slots__ = ('client_mode', 'forward_at_cmd_resp') __slots__ = ('client_mode')
def __init__(self, client_mode: bool): def __init__(self, client_mode: bool):
super().__init__() super().__init__()
self.client_mode = client_mode self.client_mode = client_mode
# shared value between both inverter connections # shared value between both inverter connections
self.forward_at_cmd_resp = False
'''Flag if response for the last at command must be send to the cloud. '''Flag if response for the last at command must be send to the cloud.
False: send result only to the MQTT broker, cause the AT+ command False: send result only to the MQTT broker, cause the AT+ command

View File

@@ -9,6 +9,7 @@ class InverterG3P(InverterBase):
def __init__(self, reader: StreamReader, writer: StreamWriter, def __init__(self, reader: StreamReader, writer: StreamWriter,
client_mode: bool = False): client_mode: bool = False):
remote_prot = None remote_prot = None
self.forward_at_cmd_resp = False
if client_mode: if client_mode:
remote_prot = SolarmanEmu remote_prot = SolarmanEmu
super().__init__(reader, writer, 'solarman', super().__init__(reader, writer, 'solarman',

View File

@@ -10,11 +10,12 @@ logger = logging.getLogger('msg')
class SolarmanEmu(SolarmanBase): class SolarmanEmu(SolarmanBase):
def __init__(self, addr, ifc: "AsyncIfc", def __init__(self, inverter, addr, ifc: "AsyncIfc",
server_side: bool, client_mode: bool): server_side: bool, client_mode: bool):
super().__init__(addr, ifc, server_side=False, super().__init__(addr, ifc, server_side=False,
_send_modbus_cb=None, _send_modbus_cb=None,
mb_timeout=8) mb_timeout=8)
_ = inverter
logging.debug('SolarmanEmu.init()') logging.debug('SolarmanEmu.init()')
self.db = ifc.remote.stream.db self.db = ifc.remote.stream.db
self.snr = ifc.remote.stream.snr self.snr = ifc.remote.stream.snr

View File

@@ -253,11 +253,12 @@ class SolarmanV5(SolarmanBase):
HDR_FMT = '<BLLL' HDR_FMT = '<BLLL'
'''format string for packing of the header''' '''format string for packing of the header'''
def __init__(self, addr, ifc: "AsyncIfc", def __init__(self, inverter, addr, ifc: "AsyncIfc",
server_side: bool, client_mode: bool): server_side: bool, client_mode: bool):
super().__init__(addr, ifc, server_side, self.send_modbus_cb, super().__init__(addr, ifc, server_side, self.send_modbus_cb,
mb_timeout=8) mb_timeout=8)
self.inverter = inverter
self.db = InfosG3P(client_mode) self.db = InfosG3P(client_mode)
self.no_forwarding = False self.no_forwarding = False
'''not allowed to connect to TSUN cloud by connection type''' '''not allowed to connect to TSUN cloud by connection type'''
@@ -334,6 +335,7 @@ class SolarmanV5(SolarmanBase):
# we have references to methods of this class in self.switch # we have references to methods of this class in self.switch
# so we have to erase self.switch, otherwise this instance can't be # so we have to erase self.switch, otherwise this instance can't be
# deallocated by the garbage collector ==> we get a memory leak # deallocated by the garbage collector ==> we get a memory leak
self.inverter = None
self.switch.clear() self.switch.clear()
self.log_lvl.clear() self.log_lvl.clear()
super().close() super().close()
@@ -518,7 +520,7 @@ class SolarmanV5(SolarmanBase):
await Proxy.mqtt.publish(f'{Proxy.entity_prfx}{node_id}{key}', data_json) # noqa: E501 await Proxy.mqtt.publish(f'{Proxy.entity_prfx}{node_id}{key}', data_json) # noqa: E501
return return
self.db.forward_at_cmd_resp = False self.inverter.forward_at_cmd_resp = False
self._build_header(0x4510) self._build_header(0x4510)
self.ifc.tx_add(struct.pack(f'<BHLLL{len(at_cmd)}sc', self.AT_CMD, self.ifc.tx_add(struct.pack(f'<BHLLL{len(at_cmd)}sc', self.AT_CMD,
0x0002, 0, 0, 0, 0x0002, 0, 0, 0,
@@ -643,7 +645,7 @@ class SolarmanV5(SolarmanBase):
self.inc_counter('AT_Command_Blocked') self.inc_counter('AT_Command_Blocked')
return return
self.inc_counter('AT_Command') self.inc_counter('AT_Command')
self.db.forward_at_cmd_resp = True self.inverter.forward_at_cmd_resp = True
elif ftype == self.MB_RTU_CMD: elif ftype == self.MB_RTU_CMD:
rstream = self.ifc.remote.stream rstream = self.ifc.remote.stream
@@ -665,7 +667,7 @@ class SolarmanV5(SolarmanBase):
ftype = self.ifc.rx_peek()[self.header_len] ftype = self.ifc.rx_peek()[self.header_len]
if ftype == self.AT_CMD or \ if ftype == self.AT_CMD or \
ftype == self.AT_CMD_RSP: ftype == self.AT_CMD_RSP:
if self.db.forward_at_cmd_resp: if self.inverter.forward_at_cmd_resp:
return logging.INFO return logging.INFO
return logging.DEBUG return logging.DEBUG
elif ftype == self.MB_RTU_CMD \ elif ftype == self.MB_RTU_CMD \
@@ -680,7 +682,7 @@ class SolarmanV5(SolarmanBase):
ftype = data[0] ftype = data[0]
if ftype == self.AT_CMD or \ if ftype == self.AT_CMD or \
ftype == self.AT_CMD_RSP: ftype == self.AT_CMD_RSP:
if not self.db.forward_at_cmd_resp: if not self.inverter.forward_at_cmd_resp:
data_json = data[14:].decode("utf-8") data_json = data[14:].decode("utf-8")
node_id = self.node_id node_id = self.node_id
key = 'at_resp' key = 'at_resp'

View File

@@ -41,7 +41,7 @@ class InverterBase(InverterIfc, Proxy):
self.remote) self.remote)
self.local = StreamPtr( self.local = StreamPtr(
prot_class(self.addr, ifc, True, client_mode), ifc prot_class(self, self.addr, ifc, True, client_mode), ifc
) )
def __enter__(self): def __enter__(self):
@@ -122,11 +122,11 @@ class InverterBase(InverterIfc, Proxy):
self.remote.ifc = ifc self.remote.ifc = ifc
if hasattr(stream, 'id_str'): if hasattr(stream, 'id_str'):
self.remote.stream = self.prot_class( self.remote.stream = self.prot_class(
addr, ifc, server_side=False, self, addr, ifc, server_side=False,
client_mode=False, id_str=stream.id_str) client_mode=False, id_str=stream.id_str)
else: else:
self.remote.stream = self.prot_class( self.remote.stream = self.prot_class(
addr, ifc, server_side=False, self, addr, ifc, server_side=False,
client_mode=False) client_mode=False)
logging.info(f'[{self.remote.stream.node_id}:' logging.info(f'[{self.remote.stream.node_id}:'

View File

@@ -190,7 +190,8 @@ def patch_mqtt_except():
yield conn yield conn
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_modbus_conn(patch_open): async def test_modbus_conn(config_conn, patch_open):
_ = config_conn
_ = patch_open _ = patch_open
assert Infos.stat['proxy']['Inverter_Cnt'] == 0 assert Infos.stat['proxy']['Inverter_Cnt'] == 0
@@ -210,6 +211,7 @@ async def test_modbus_conn(patch_open):
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_modbus_no_cnf(): async def test_modbus_no_cnf():
_ = config_conn
assert Infos.stat['proxy']['Inverter_Cnt'] == 0 assert Infos.stat['proxy']['Inverter_Cnt'] == 0
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
ModbusTcp(loop) ModbusTcp(loop)

View File

@@ -47,7 +47,7 @@ def config_no_conn(test_port):
@pytest.fixture @pytest.fixture
def spy_at_cmd(): def spy_at_cmd():
conn = SolarmanV5(('test.local', 1234), server_side=True, client_mode= False, ifc=AsyncIfcImpl()) conn = SolarmanV5(None, ('test.local', 1234), server_side=True, client_mode= False, ifc=AsyncIfcImpl())
conn.node_id = 'inv_2/' conn.node_id = 'inv_2/'
with patch.object(conn, 'send_at_cmd', wraps=conn.send_at_cmd) as wrapped_conn: with patch.object(conn, 'send_at_cmd', wraps=conn.send_at_cmd) as wrapped_conn:
yield wrapped_conn yield wrapped_conn
@@ -55,7 +55,7 @@ def spy_at_cmd():
@pytest.fixture @pytest.fixture
def spy_modbus_cmd(): def spy_modbus_cmd():
conn = SolarmanV5(('test.local', 1234), server_side=True, client_mode= False, ifc=AsyncIfcImpl()) conn = SolarmanV5(None, ('test.local', 1234), server_side=True, client_mode= False, ifc=AsyncIfcImpl())
conn.node_id = 'inv_1/' conn.node_id = 'inv_1/'
with patch.object(conn, 'send_modbus_cmd', wraps=conn.send_modbus_cmd) as wrapped_conn: with patch.object(conn, 'send_modbus_cmd', wraps=conn.send_modbus_cmd) as wrapped_conn:
yield wrapped_conn yield wrapped_conn
@@ -63,7 +63,7 @@ def spy_modbus_cmd():
@pytest.fixture @pytest.fixture
def spy_modbus_cmd_client(): def spy_modbus_cmd_client():
conn = SolarmanV5(('test.local', 1234), server_side=False, client_mode= False, ifc=AsyncIfcImpl()) conn = SolarmanV5(None, ('test.local', 1234), server_side=False, client_mode= False, ifc=AsyncIfcImpl())
conn.node_id = 'inv_1/' conn.node_id = 'inv_1/'
with patch.object(conn, 'send_modbus_cmd', wraps=conn.send_modbus_cmd) as wrapped_conn: with patch.object(conn, 'send_modbus_cmd', wraps=conn.send_modbus_cmd) as wrapped_conn:
yield wrapped_conn yield wrapped_conn

View File

@@ -4,7 +4,9 @@ import time
import asyncio import asyncio
import logging import logging
import random import random
from asyncio import StreamReader, StreamWriter
from math import isclose from math import isclose
from async_stream import AsyncIfcImpl, StreamPtr from async_stream import AsyncIfcImpl, StreamPtr
from gen3plus.solarman_v5 import SolarmanV5, SolarmanBase from gen3plus.solarman_v5 import SolarmanV5, SolarmanBase
from cnf.config import Config from cnf.config import Config
@@ -12,6 +14,11 @@ from infos import Infos, Register
from modbus import Modbus from modbus import Modbus
from messages import State, Message from messages import State, Message
from proxy import Proxy from proxy import Proxy
from test_inverter_g3p import FakeReader, FakeWriter, patch_open_connection
from inverter_base import InverterBase
from test_modbus_tcp import test_port, test_hostname
pytest_plugins = ('pytest_asyncio',) pytest_plugins = ('pytest_asyncio',)
@@ -43,10 +50,14 @@ class FakeIfc(AsyncIfcImpl):
async def create_remote(self): async def create_remote(self):
await asyncio.sleep(0) await asyncio.sleep(0)
class FakeInverter():
def __init__(self):
self.forward_at_cmd_resp = False
class MemoryStream(SolarmanV5): class MemoryStream(SolarmanV5):
def __init__(self, msg, chunks = (0,), server_side: bool = True): def __init__(self, msg, chunks = (0,), server_side: bool = True, inverter=FakeInverter()):
_ifc = FakeIfc() _ifc = FakeIfc()
super().__init__(('test.local', 1234), _ifc, server_side, client_mode=False) super().__init__(inverter, ('test.local', 1234), _ifc, server_side, client_mode=False)
if server_side: if server_side:
self.mb.timeout = 0.4 # overwrite for faster testing self.mb.timeout = 0.4 # overwrite for faster testing
self.mb_first_timeout = 0.5 self.mb_first_timeout = 0.5
@@ -828,7 +839,7 @@ def config_tsun_inv1():
'proxy_node_id': 'test_1', 'proxy_node_id': 'test_1',
'proxy_unique_id': '' 'proxy_unique_id': ''
}, },
'solarman':{'enabled': True},'inverters':{'Y170000000000001':{'monitor_sn': 2070233889, 'node_id':'inv1/', 'modbus_polling': True, 'suggested_area':'roof', 'sensor_list': 0}}} 'solarman':{'enabled': True, 'host': 'test_cloud.local', 'port': 1234},'inverters':{'Y170000000000001':{'monitor_sn': 2070233889, 'node_id':'inv1/', 'modbus_polling': True, 'suggested_area':'roof', 'sensor_list': 0}}}
Proxy.class_init() Proxy.class_init()
Proxy.mqtt = Mqtt() Proxy.mqtt = Mqtt()
@@ -1432,9 +1443,9 @@ def test_build_logger_modell(config_tsun_allow_all, device_ind_msg):
def test_msg_iterator(): def test_msg_iterator():
Message._registry.clear() Message._registry.clear()
m1 = SolarmanV5(('test1.local', 1234), ifc=AsyncIfcImpl(), server_side=True, client_mode=False) m1 = SolarmanV5(None, ('test1.local', 1234), ifc=AsyncIfcImpl(), server_side=True, client_mode=False)
m2 = SolarmanV5(('test2.local', 1234), ifc=AsyncIfcImpl(), server_side=True, client_mode=False) m2 = SolarmanV5(None, ('test2.local', 1234), ifc=AsyncIfcImpl(), server_side=True, client_mode=False)
m3 = SolarmanV5(('test3.local', 1234), ifc=AsyncIfcImpl(), server_side=True, client_mode=False) m3 = SolarmanV5(None, ('test3.local', 1234), ifc=AsyncIfcImpl(), server_side=True, client_mode=False)
m3.close() m3.close()
del m3 del m3
test1 = 0 test1 = 0
@@ -1452,7 +1463,7 @@ def test_msg_iterator():
assert test2 == 1 assert test2 == 1
def test_proxy_counter(): def test_proxy_counter():
m = SolarmanV5(('test.local', 1234), ifc=AsyncIfcImpl(), server_side=True, client_mode=False) m = SolarmanV5(None, ('test.local', 1234), ifc=AsyncIfcImpl(), server_side=True, client_mode=False)
assert m.new_data == {} assert m.new_data == {}
m.db.stat['proxy']['Unknown_Msg'] = 0 m.db.stat['proxy']['Unknown_Msg'] = 0
Infos.new_stat_data['proxy'] = False Infos.new_stat_data['proxy'] = False
@@ -1559,7 +1570,7 @@ async def test_at_cmd(config_tsun_allow_all, device_ind_msg, device_rsp_msg, inv
assert m.ifc.fwd_fifo.get()==b'' assert m.ifc.fwd_fifo.get()==b''
assert m.sent_pdu == b'' assert m.sent_pdu == b''
assert str(m.seq) == '03:04' assert str(m.seq) == '03:04'
assert m.db.forward_at_cmd_resp == False assert m.inverter.forward_at_cmd_resp == False
assert Proxy.mqtt.key == '' assert Proxy.mqtt.key == ''
assert Proxy.mqtt.data == "" assert Proxy.mqtt.data == ""
m.close() m.close()
@@ -1594,7 +1605,7 @@ async def test_at_cmd_blocked(config_tsun_allow_all, device_ind_msg, device_rsp_
assert m.ifc.tx_fifo.get()==b'' assert m.ifc.tx_fifo.get()==b''
assert m.ifc.fwd_fifo.get()==b'' assert m.ifc.fwd_fifo.get()==b''
assert str(m.seq) == '02:02' assert str(m.seq) == '02:02'
assert m.db.forward_at_cmd_resp == False assert m.inverter.forward_at_cmd_resp == False
assert Proxy.mqtt.key == 'tsun/at_resp' assert Proxy.mqtt.key == 'tsun/at_resp'
assert Proxy.mqtt.data == "'AT+WEBU' is forbidden" assert Proxy.mqtt.data == "'AT+WEBU' is forbidden"
m.close() m.close()
@@ -1641,6 +1652,7 @@ def test_at_cmd_ind_block(config_tsun_inv1, at_command_ind_msg_block):
m.db.stat['proxy']['AT_Command'] = 0 m.db.stat['proxy']['AT_Command'] = 0
m.db.stat['proxy']['AT_Command_Blocked'] = 0 m.db.stat['proxy']['AT_Command_Blocked'] = 0
m.db.stat['proxy']['Modbus_Command'] = 0 m.db.stat['proxy']['Modbus_Command'] = 0
m.inverter.forward_at_cmd_resp = False
m.read() # read complete msg, and dispatch msg m.read() # read complete msg, and dispatch msg
assert not m.header_valid # must be invalid, since msg was handled and buffer flushed assert not m.header_valid # must be invalid, since msg was handled and buffer flushed
assert m.msg_count == 1 assert m.msg_count == 1
@@ -1656,7 +1668,7 @@ def test_at_cmd_ind_block(config_tsun_inv1, at_command_ind_msg_block):
assert m.db.stat['proxy']['AT_Command'] == 0 assert m.db.stat['proxy']['AT_Command'] == 0
assert m.db.stat['proxy']['AT_Command_Blocked'] == 1 assert m.db.stat['proxy']['AT_Command_Blocked'] == 1
assert m.db.stat['proxy']['Modbus_Command'] == 0 assert m.db.stat['proxy']['Modbus_Command'] == 0
assert m.db.forward_at_cmd_resp == False assert m.inverter.forward_at_cmd_resp == False
assert Proxy.mqtt.key == '' assert Proxy.mqtt.key == ''
assert Proxy.mqtt.data == "" assert Proxy.mqtt.data == ""
m.close() m.close()
@@ -1666,7 +1678,7 @@ def test_msg_at_command_rsp1(config_tsun_inv1, at_command_rsp_msg):
m = MemoryStream(at_command_rsp_msg) m = MemoryStream(at_command_rsp_msg)
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.db.stat['proxy']['Modbus_Command'] = 0 m.db.stat['proxy']['Modbus_Command'] = 0
m.db.forward_at_cmd_resp = True m.inverter.forward_at_cmd_resp = True
m.read() # read complete msg, and dispatch msg m.read() # read complete msg, and dispatch msg
assert not m.header_valid # must be invalid, since msg was handled and buffer flushed assert not m.header_valid # must be invalid, since msg was handled and buffer flushed
assert m.msg_count == 1 assert m.msg_count == 1
@@ -1685,7 +1697,7 @@ def test_msg_at_command_rsp2(config_tsun_inv1, at_command_rsp_msg):
m = MemoryStream(at_command_rsp_msg) m = MemoryStream(at_command_rsp_msg)
m.db.stat['proxy']['Unknown_Ctrl'] = 0 m.db.stat['proxy']['Unknown_Ctrl'] = 0
m.db.stat['proxy']['Modbus_Command'] = 0 m.db.stat['proxy']['Modbus_Command'] = 0
m.db.forward_at_cmd_resp = False m.inverter.forward_at_cmd_resp = False
m.read() # read complete msg, and dispatch msg m.read() # read complete msg, and dispatch msg
assert not m.header_valid # must be invalid, since msg was handled and buffer flushed assert not m.header_valid # must be invalid, since msg was handled and buffer flushed
assert m.msg_count == 1 assert m.msg_count == 1
@@ -1708,7 +1720,7 @@ def test_msg_at_command_rsp3(config_tsun_inv1, at_command_interim_rsp_msg):
m.db.stat['proxy']['Modbus_Command'] = 0 m.db.stat['proxy']['Modbus_Command'] = 0
m.db.stat['proxy']['Invalid_Msg_Format'] = 0 m.db.stat['proxy']['Invalid_Msg_Format'] = 0
m.db.stat['proxy']['Unknown_Msg'] = 0 m.db.stat['proxy']['Unknown_Msg'] = 0
m.db.forward_at_cmd_resp = True m.inverter.forward_at_cmd_resp = True
m.read() # read complete msg, and dispatch msg m.read() # read complete msg, and dispatch msg
assert not m.header_valid # must be invalid, since msg was handled and buffer flushed assert not m.header_valid # must be invalid, since msg was handled and buffer flushed
assert m.msg_count == 1 assert m.msg_count == 1
@@ -2236,4 +2248,100 @@ def test_timestamp():
m = MemoryStream(b'') m = MemoryStream(b'')
ts = m._timestamp() ts = m._timestamp()
ts_emu = m._emu_timestamp() ts_emu = m._emu_timestamp()
assert ts == ts_emu + 24*60*60 assert ts == ts_emu + 24*60*60
class MemoryStream2(MemoryStream):
def __init__(self, inverter, addr, ifc,
server_side: bool, client_mode: bool):
super().__init__(b'', inverter=inverter)
class InverterTest(InverterBase):
def __init__(self, reader: StreamReader, writer: StreamWriter,
client_mode: bool = False):
remote_prot = None
super().__init__(reader, writer, 'solarman',
MemoryStream2, client_mode, remote_prot)
def forward(self, src, dst) -> None:
"""forward handler transmits data over the remote connection"""
# dst.ifc.update_header_cb(src.fwd_fifo.peek())
dst.ifc.tx_add(src.ifc.fwd_fifo.get())
@pytest.mark.asyncio
async def test_proxy_at_cmd(config_tsun_inv1, patch_open_connection, at_command_ind_msg, at_command_rsp_msg):
_ = config_tsun_inv1
_ = patch_open_connection
assert asyncio.get_running_loop()
with InverterTest(FakeReader(), FakeWriter(), client_mode=False) as inverter:
await inverter.create_remote()
await asyncio.sleep(0)
r = inverter.remote.stream
l = inverter.local.stream
l.db.stat['proxy']['AT_Command'] = 0
l.db.stat['proxy']['Unknown_Ctrl'] = 0
l.db.stat['proxy']['AT_Command_Blocked'] = 0
l.db.stat['proxy']['Modbus_Command'] = 0
inverter.forward_at_cmd_resp = False
r.append_msg(at_command_ind_msg)
r.read() # read complete msg, and dispatch msg
assert inverter.forward_at_cmd_resp
inverter.forward(r,l)
assert l.ifc.tx_fifo.get()==at_command_ind_msg
assert l.db.stat['proxy']['Invalid_Msg_Format'] == 0
assert l.db.stat['proxy']['AT_Command'] == 1
assert l.db.stat['proxy']['AT_Command_Blocked'] == 0
assert l.db.stat['proxy']['Modbus_Command'] == 0
l.append_msg(at_command_rsp_msg)
l.read() # read at resp
assert l.ifc.fwd_fifo.peek()==at_command_rsp_msg
inverter.forward(l,r)
assert r.ifc.tx_fifo.get()==at_command_rsp_msg
assert Proxy.mqtt.key == ''
assert Proxy.mqtt.data == ""
@pytest.mark.asyncio
async def test_proxy_at_blocked(config_tsun_inv1, patch_open_connection, at_command_ind_msg_block, at_command_rsp_msg):
_ = config_tsun_inv1
_ = patch_open_connection
assert asyncio.get_running_loop()
with InverterTest(FakeReader(), FakeWriter(), client_mode=False) as inverter:
await inverter.create_remote()
await asyncio.sleep(0)
r = inverter.remote.stream
l = inverter.local.stream
l.db.stat['proxy']['AT_Command'] = 0
l.db.stat['proxy']['Unknown_Ctrl'] = 0
l.db.stat['proxy']['AT_Command_Blocked'] = 0
l.db.stat['proxy']['Modbus_Command'] = 0
inverter.forward_at_cmd_resp = False
r.append_msg(at_command_ind_msg_block)
r.read() # read complete msg, and dispatch msg
assert not inverter.forward_at_cmd_resp
inverter.forward(r,l)
assert l.ifc.tx_fifo.get()==b''
assert l.db.stat['proxy']['Invalid_Msg_Format'] == 0
assert l.db.stat['proxy']['AT_Command'] == 0
assert l.db.stat['proxy']['AT_Command_Blocked'] == 1
assert l.db.stat['proxy']['Modbus_Command'] == 0
l.append_msg(at_command_rsp_msg)
l.read() # read at resp
assert l.ifc.fwd_fifo.peek()==b''
inverter.forward(l,r)
assert r.ifc.tx_fifo.get()==b''
assert Proxy.mqtt.key == 'tsun/inv1/at_resp'
assert Proxy.mqtt.data == "+ok"

View File

@@ -6,7 +6,7 @@ from gen3plus.solarman_v5 import SolarmanV5, SolarmanBase
from gen3plus.solarman_emu import SolarmanEmu from gen3plus.solarman_emu import SolarmanEmu
from infos import Infos, Register from infos import Infos, Register
from test_solarman import FakeIfc, MemoryStream, get_sn_int, get_sn, correct_checksum, config_tsun_inv1, msg_modbus_rsp from test_solarman import FakeIfc, FakeInverter, MemoryStream, get_sn_int, get_sn, correct_checksum, config_tsun_inv1, msg_modbus_rsp
from test_infos_g3p import str_test_ip, bytes_test_ip from test_infos_g3p import str_test_ip, bytes_test_ip
timestamp = 0x3224c8bc timestamp = 0x3224c8bc
@@ -19,10 +19,10 @@ class InvStream(MemoryStream):
return timestamp return timestamp
class CldStream(SolarmanEmu): class CldStream(SolarmanEmu):
def __init__(self, inv: InvStream): def __init__(self, inv: InvStream, inverter=FakeInverter()):
_ifc = FakeIfc() _ifc = FakeIfc()
_ifc.remote.stream = inv _ifc.remote.stream = inv
super().__init__(('test.local', 1234), _ifc, server_side=False, client_mode=False) super().__init__(inverter, ('test.local', 1234), _ifc, server_side=False, client_mode=False)
self.__msg = b'' self.__msg = b''
self.__msg_len = 0 self.__msg_len = 0
self.__offs = 0 self.__offs = 0

View File

@@ -25,7 +25,7 @@ class FakeIfc(AsyncIfcImpl):
class MemoryStream(Talent): class MemoryStream(Talent):
def __init__(self, msg, chunks = (0,), server_side: bool = True): def __init__(self, msg, chunks = (0,), server_side: bool = True):
self.ifc = FakeIfc() self.ifc = FakeIfc()
super().__init__(('test.local', 1234), self.ifc, server_side) super().__init__(None, ('test.local', 1234), self.ifc, server_side)
if server_side: if server_side:
self.mb.timeout = 0.4 # overwrite for faster testing self.mb.timeout = 0.4 # overwrite for faster testing
self.mb_first_timeout = 0.5 self.mb_first_timeout = 0.5
@@ -2026,9 +2026,9 @@ def test_ctrl_byte():
def test_msg_iterator(): def test_msg_iterator():
m1 = Talent(('test1.local', 1234), ifc=AsyncIfcImpl(), server_side=True) m1 = Talent(None, ('test1.local', 1234), ifc=AsyncIfcImpl(), server_side=True)
m2 = Talent(('test2.local', 1234), ifc=AsyncIfcImpl(), server_side=True) m2 = Talent(None, ('test2.local', 1234), ifc=AsyncIfcImpl(), server_side=True)
m3 = Talent(('test3.local', 1234), ifc=AsyncIfcImpl(), server_side=True) m3 = Talent(None, ('test3.local', 1234), ifc=AsyncIfcImpl(), server_side=True)
m3.close() m3.close()
del m3 del m3
test1 = 0 test1 = 0