add unit tests for AsyncStream class

This commit is contained in:
Stefan Allius
2024-10-06 17:43:40 +02:00
parent 9852f44dfa
commit e074a39f5a
8 changed files with 407 additions and 221 deletions

View File

@@ -4,45 +4,45 @@
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
-->
<!-- Title: G Pages: 1 -->
<svg width="446pt" height="1820pt"
viewBox="0.00 0.00 446.35 1820.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 1816)">
<svg width="446pt" height="1796pt"
viewBox="0.00 0.00 446.35 1796.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 1792)">
<title>G</title>
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-1816 442.348,-1816 442.348,4 -4,4"/>
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-1792 442.348,-1792 442.348,4 -4,4"/>
<!-- A0 -->
<g id="node1" class="node">
<title>A0</title>
<polygon fill="#fff8dc" stroke="#000000" points="108.5444,-1788 .1516,-1788 .1516,-1752 114.5444,-1752 114.5444,-1782 108.5444,-1788"/>
<polyline fill="none" stroke="#000000" points="108.5444,-1788 108.5444,-1782 "/>
<polyline fill="none" stroke="#000000" points="114.5444,-1782 108.5444,-1782 "/>
<text text-anchor="middle" x="57.348" y="-1773" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">You can stick notes</text>
<text text-anchor="middle" x="57.348" y="-1761" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">on diagrams too!</text>
<polygon fill="#fff8dc" stroke="#000000" points="108.5444,-1764 .1516,-1764 .1516,-1728 114.5444,-1728 114.5444,-1758 108.5444,-1764"/>
<polyline fill="none" stroke="#000000" points="108.5444,-1764 108.5444,-1758 "/>
<polyline fill="none" stroke="#000000" points="114.5444,-1758 108.5444,-1758 "/>
<text text-anchor="middle" x="57.348" y="-1749" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">You can stick notes</text>
<text text-anchor="middle" x="57.348" y="-1737" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">on diagrams too!</text>
</g>
<!-- A1 -->
<g id="node2" class="node">
<title>A1</title>
<polygon fill="none" stroke="#000000" points="133.348,-1780 133.348,-1812 204.348,-1812 204.348,-1780 133.348,-1780"/>
<text text-anchor="start" x="143.293" y="-1793" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">IterRegistry</text>
<polygon fill="none" stroke="#000000" points="133.348,-1760 133.348,-1780 204.348,-1780 204.348,-1760 133.348,-1760"/>
<polygon fill="none" stroke="#000000" points="133.348,-1728 133.348,-1760 204.348,-1760 204.348,-1728 133.348,-1728"/>
<text text-anchor="start" x="150.787" y="-1741" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">__iter__</text>
<polygon fill="none" stroke="#000000" points="133.348,-1756 133.348,-1788 204.348,-1788 204.348,-1756 133.348,-1756"/>
<text text-anchor="start" x="143.293" y="-1769" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">IterRegistry</text>
<polygon fill="none" stroke="#000000" points="133.348,-1736 133.348,-1756 204.348,-1756 204.348,-1736 133.348,-1736"/>
<polygon fill="none" stroke="#000000" points="133.348,-1704 133.348,-1736 204.348,-1736 204.348,-1704 133.348,-1704"/>
<text text-anchor="start" x="150.787" y="-1717" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">__iter__</text>
</g>
<!-- A14 -->
<g id="node15" class="node">
<title>A14</title>
<polygon fill="none" stroke="#000000" points="128.348,-1574 128.348,-1606 209.348,-1606 209.348,-1574 128.348,-1574"/>
<text text-anchor="start" x="148.5655" y="-1587" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">Message</text>
<polygon fill="none" stroke="#000000" points="128.348,-1542 128.348,-1574 209.348,-1574 209.348,-1542 128.348,-1542"/>
<text text-anchor="start" x="151.0615" y="-1555" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">node_id</text>
<polygon fill="none" stroke="#000000" points="128.348,-1498 128.348,-1542 209.348,-1542 209.348,-1498 128.348,-1498"/>
<text text-anchor="start" x="139.6785" y="-1523" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">inc_counter()</text>
<text text-anchor="start" x="138.0085" y="-1511" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">dec_counter()</text>
<polygon fill="none" stroke="#000000" points="128.348,-1550 128.348,-1582 209.348,-1582 209.348,-1550 128.348,-1550"/>
<text text-anchor="start" x="148.5655" y="-1563" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">Message</text>
<polygon fill="none" stroke="#000000" points="128.348,-1518 128.348,-1550 209.348,-1550 209.348,-1518 128.348,-1518"/>
<text text-anchor="start" x="151.0615" y="-1531" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">node_id</text>
<polygon fill="none" stroke="#000000" points="128.348,-1474 128.348,-1518 209.348,-1518 209.348,-1474 128.348,-1474"/>
<text text-anchor="start" x="139.6785" y="-1499" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">inc_counter()</text>
<text text-anchor="start" x="138.0085" y="-1487" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">dec_counter()</text>
</g>
<!-- A1&#45;&gt;A14 -->
<g id="edge19" class="edge">
<title>A1&#45;&gt;A14</title>
<path fill="none" stroke="#000000" d="M168.348,-1717.8572C168.348,-1684.1684 168.348,-1640.4162 168.348,-1606.3079"/>
<polygon fill="none" stroke="#000000" points="164.8481,-1717.9674 168.348,-1727.9674 171.8481,-1717.9674 164.8481,-1717.9674"/>
<path fill="none" stroke="#000000" d="M168.348,-1693.8572C168.348,-1660.1684 168.348,-1616.4162 168.348,-1582.3079"/>
<polygon fill="none" stroke="#000000" points="164.8481,-1693.9674 168.348,-1703.9674 171.8481,-1693.9674 164.8481,-1693.9674"/>
</g>
<!-- A2 -->
<g id="node3" class="node">
@@ -126,23 +126,21 @@
<!-- A4 -->
<g id="node5" class="node">
<title>A4</title>
<polygon fill="none" stroke="#000000" points="158.348,-982 158.348,-1014 275.348,-1014 275.348,-982 158.348,-982"/>
<text text-anchor="start" x="186.277" y="-995" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">&lt;&lt;AsyncIfc&gt;&gt;</text>
<polygon fill="none" stroke="#000000" points="158.348,-962 158.348,-982 275.348,-982 275.348,-962 158.348,-962"/>
<polygon fill="none" stroke="#000000" points="158.348,-666 158.348,-962 275.348,-962 275.348,-666 158.348,-666"/>
<text text-anchor="start" x="186.284" y="-943" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">set_node_id()</text>
<text text-anchor="start" x="184.614" y="-931" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">get_conn_no()</text>
<text text-anchor="start" x="198.5115" y="-907" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">tx_add()</text>
<text text-anchor="start" x="196.292" y="-895" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">tx_flush()</text>
<text text-anchor="start" x="199.9015" y="-883" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">tx_get()</text>
<text text-anchor="start" x="196.0115" y="-871" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">tx_peek()</text>
<text text-anchor="start" x="200.1815" y="-859" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">tx_log()</text>
<text text-anchor="start" x="196.017" y="-847" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">tx_clear()</text>
<text text-anchor="start" x="200.1815" y="-835" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">tx_len()</text>
<text text-anchor="start" x="194.6225" y="-811" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">fwd_add()</text>
<text text-anchor="start" x="192.403" y="-799" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">fwd_flush()</text>
<text text-anchor="start" x="196.2925" y="-787" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">fwd_log()</text>
<text text-anchor="start" x="192.128" y="-775" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">fwd_clear()</text>
<polygon fill="none" stroke="#000000" points="158.348,-958 158.348,-990 275.348,-990 275.348,-958 158.348,-958"/>
<text text-anchor="start" x="186.277" y="-971" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">&lt;&lt;AsyncIfc&gt;&gt;</text>
<polygon fill="none" stroke="#000000" points="158.348,-938 158.348,-958 275.348,-958 275.348,-938 158.348,-938"/>
<polygon fill="none" stroke="#000000" points="158.348,-666 158.348,-938 275.348,-938 275.348,-666 158.348,-666"/>
<text text-anchor="start" x="186.284" y="-919" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">set_node_id()</text>
<text text-anchor="start" x="184.614" y="-907" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">get_conn_no()</text>
<text text-anchor="start" x="198.5115" y="-883" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">tx_add()</text>
<text text-anchor="start" x="196.292" y="-871" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">tx_flush()</text>
<text text-anchor="start" x="199.9015" y="-859" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">tx_get()</text>
<text text-anchor="start" x="196.0115" y="-847" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">tx_peek()</text>
<text text-anchor="start" x="200.1815" y="-835" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">tx_log()</text>
<text text-anchor="start" x="196.017" y="-823" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">tx_clear()</text>
<text text-anchor="start" x="200.1815" y="-811" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">tx_len()</text>
<text text-anchor="start" x="194.6225" y="-787" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">fwd_add()</text>
<text text-anchor="start" x="196.2925" y="-775" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">fwd_log()</text>
<text text-anchor="start" x="199.6265" y="-763" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">rx_get()</text>
<text text-anchor="start" x="195.7365" y="-751" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">rx_peek()</text>
<text text-anchor="start" x="199.9065" y="-739" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">rx_log()</text>
@@ -167,8 +165,8 @@
<!-- A4&#45;&gt;A5 -->
<g id="edge1" class="edge">
<title>A4&#45;&gt;A5</title>
<path fill="none" stroke="#000000" stroke-dasharray="5,2" d="M216.348,-655.3047C216.348,-637.8196 216.348,-621.0638 216.348,-606.0999"/>
<polygon fill="none" stroke="#000000" points="212.8481,-655.6759 216.348,-665.6759 219.8481,-655.676 212.8481,-655.6759"/>
<path fill="none" stroke="#000000" stroke-dasharray="5,2" d="M216.348,-655.339C216.348,-637.8929 216.348,-621.0952 216.348,-606.0686"/>
<polygon fill="none" stroke="#000000" points="212.8481,-655.6774 216.348,-665.6775 219.8481,-655.6775 212.8481,-655.6774"/>
</g>
<!-- A6 -->
<g id="node7" class="node">
@@ -211,208 +209,208 @@
<!-- A9 -->
<g id="node10" class="node">
<title>A9</title>
<polygon fill="none" stroke="#000000" points="280.348,-1344 280.348,-1376 394.348,-1376 394.348,-1344 280.348,-1344"/>
<text text-anchor="start" x="323.456" y="-1357" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">Talent</text>
<polygon fill="none" stroke="#000000" points="280.348,-1192 280.348,-1344 394.348,-1344 394.348,-1192 280.348,-1192"/>
<text text-anchor="start" x="312.0665" y="-1325" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ifc:AsyncIfc</text>
<text text-anchor="start" x="318.171" y="-1313" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">conn_no</text>
<text text-anchor="start" x="327.345" y="-1301" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">addr</text>
<text text-anchor="start" x="290.111" y="-1277" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">await_conn_resp_cnt</text>
<text text-anchor="start" x="325.1255" y="-1265" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">id_str</text>
<text text-anchor="start" x="305.948" y="-1253" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">contact_name</text>
<text text-anchor="start" x="309.288" y="-1241" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">contact_mail</text>
<text text-anchor="start" x="312.8925" y="-1229" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">db:InfosG3</text>
<text text-anchor="start" x="311.232" y="-1217" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">mb:Modbus</text>
<text text-anchor="start" x="323.46" y="-1205" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">switch</text>
<polygon fill="none" stroke="#000000" points="280.348,-1064 280.348,-1192 394.348,-1192 394.348,-1064 280.348,-1064"/>
<text text-anchor="start" x="294.8405" y="-1173" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">msg_contact_info()</text>
<text text-anchor="start" x="296.7805" y="-1161" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">msg_ota_update()</text>
<text text-anchor="start" x="302.6245" y="-1149" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">msg_get_time()</text>
<text text-anchor="start" x="290.6765" y="-1137" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">msg_collector_data()</text>
<text text-anchor="start" x="292.6215" y="-1125" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">msg_inverter_data()</text>
<text text-anchor="start" x="301.7885" y="-1113" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">msg_unknown()</text>
<text text-anchor="start" x="317.902" y="-1089" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">healthy()</text>
<text text-anchor="start" x="322.3505" y="-1077" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">close()</text>
<polygon fill="none" stroke="#000000" points="280.348,-1320 280.348,-1352 394.348,-1352 394.348,-1320 280.348,-1320"/>
<text text-anchor="start" x="323.456" y="-1333" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">Talent</text>
<polygon fill="none" stroke="#000000" points="280.348,-1168 280.348,-1320 394.348,-1320 394.348,-1168 280.348,-1168"/>
<text text-anchor="start" x="312.0665" y="-1301" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ifc:AsyncIfc</text>
<text text-anchor="start" x="318.171" y="-1289" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">conn_no</text>
<text text-anchor="start" x="327.345" y="-1277" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">addr</text>
<text text-anchor="start" x="290.111" y="-1253" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">await_conn_resp_cnt</text>
<text text-anchor="start" x="325.1255" y="-1241" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">id_str</text>
<text text-anchor="start" x="305.948" y="-1229" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">contact_name</text>
<text text-anchor="start" x="309.288" y="-1217" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">contact_mail</text>
<text text-anchor="start" x="312.8925" y="-1205" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">db:InfosG3</text>
<text text-anchor="start" x="311.232" y="-1193" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">mb:Modbus</text>
<text text-anchor="start" x="323.46" y="-1181" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">switch</text>
<polygon fill="none" stroke="#000000" points="280.348,-1040 280.348,-1168 394.348,-1168 394.348,-1040 280.348,-1040"/>
<text text-anchor="start" x="294.8405" y="-1149" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">msg_contact_info()</text>
<text text-anchor="start" x="296.7805" y="-1137" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">msg_ota_update()</text>
<text text-anchor="start" x="302.6245" y="-1125" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">msg_get_time()</text>
<text text-anchor="start" x="290.6765" y="-1113" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">msg_collector_data()</text>
<text text-anchor="start" x="292.6215" y="-1101" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">msg_inverter_data()</text>
<text text-anchor="start" x="301.7885" y="-1089" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">msg_unknown()</text>
<text text-anchor="start" x="317.902" y="-1065" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">healthy()</text>
<text text-anchor="start" x="322.3505" y="-1053" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">close()</text>
</g>
<!-- A9&#45;&gt;A2 -->
<g id="edge5" class="edge">
<title>A9&#45;&gt;A2</title>
<path fill="none" stroke="#000000" d="M355.8388,-1053.6462C357.5291,-1040.2553 359.074,-1026.9158 360.348,-1014 374.197,-873.5946 378.4625,-708.6618 382.5377,-616.2392"/>
<polygon fill="#000000" stroke="#000000" points="354.52,-1063.8901 351.3338,-1053.3974 355.1585,-1058.9311 355.797,-1053.972 355.797,-1053.972 355.797,-1053.972 355.1585,-1058.9311 360.2601,-1054.5466 354.52,-1063.8901 354.52,-1063.8901"/>
<text text-anchor="middle" x="348.4513" y="-1041.8331" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">remote</text>
<path fill="none" stroke="#000000" d="M355.8061,-1029.6429C357.5037,-1016.2527 359.0593,-1002.9144 360.348,-990 373.4702,-858.5013 377.9848,-704.3277 382.1955,-616.0127"/>
<polygon fill="#000000" stroke="#000000" points="354.4823,-1039.8864 351.3012,-1029.3921 355.1232,-1034.9276 355.764,-1029.9689 355.764,-1029.9689 355.764,-1029.9689 355.1232,-1034.9276 360.2269,-1030.5457 354.4823,-1039.8864 354.4823,-1039.8864"/>
<text text-anchor="middle" x="348.4228" y="-1017.8264" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">remote</text>
</g>
<!-- A9&#45;&gt;A2 -->
<g id="edge7" class="edge">
<title>A9&#45;&gt;A2</title>
<path fill="none" stroke="#000000" d="M373.7894,-1053.6462C375.5291,-1040.2553 377.074,-1026.9158 378.348,-1014 391.6155,-879.4905 396.0874,-722.4703 395.1595,-628.2587"/>
<polygon fill="#000000" stroke="#000000" points="372.4223,-1063.8901 369.2847,-1053.3827 373.0837,-1058.9341 373.7452,-1053.978 373.7452,-1053.978 373.7452,-1053.978 373.0837,-1058.9341 378.2056,-1054.5733 372.4223,-1063.8901 372.4223,-1063.8901"/>
<polygon fill="#000000" stroke="#000000" points="395.1593,-628.2382 391.0833,-622.2896 395.0066,-616.2392 399.0827,-622.1878 395.1593,-628.2382"/>
<text text-anchor="middle" x="403.6888" y="-631.2564" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">local</text>
<path fill="none" stroke="#000000" d="M373.7566,-1029.6429C375.5037,-1016.2527 377.0593,-1002.9144 378.348,-990 390.8936,-864.2801 395.5714,-717.8344 394.9909,-628.0298"/>
<polygon fill="#000000" stroke="#000000" points="372.3845,-1039.8864 369.2521,-1029.3774 373.0484,-1034.9307 373.7122,-1029.9749 373.7122,-1029.9749 373.7122,-1029.9749 373.0484,-1034.9307 378.1724,-1030.5724 372.3845,-1039.8864 372.3845,-1039.8864"/>
<polygon fill="#000000" stroke="#000000" points="394.9908,-628.0122 390.9345,-622.0501 394.8778,-616.0127 398.9341,-621.9747 394.9908,-628.0122"/>
<text text-anchor="middle" x="403.5004" y="-631.0585" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">local</text>
</g>
<!-- A9&#45;&gt;A4 -->
<g id="edge15" class="edge">
<title>A9&#45;&gt;A4</title>
<path fill="none" stroke="#000000" d="M287.6089,-1063.7944C283.4127,-1050.6165 279.1452,-1037.2145 274.8907,-1023.853"/>
<polygon fill="#000000" stroke="#000000" points="271.7962,-1014.1348 279.1182,-1022.298 273.3133,-1018.8991 274.8304,-1023.6634 274.8304,-1023.6634 274.8304,-1023.6634 273.3133,-1018.8991 270.5425,-1025.0288 271.7962,-1014.1348 271.7962,-1014.1348"/>
<text text-anchor="middle" x="274.0553" y="-1046.0873" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">use</text>
<path fill="none" stroke="#000000" d="M286.0331,-1039.9349C281.6793,-1026.6936 277.2605,-1013.2547 272.8698,-999.9011"/>
<polygon fill="#000000" stroke="#000000" points="269.679,-990.1968 277.0774,-998.2908 271.2408,-994.9466 272.8026,-999.6964 272.8026,-999.6964 272.8026,-999.6964 271.2408,-994.9466 268.5277,-1001.102 269.679,-990.1968 269.679,-990.1968"/>
<text text-anchor="middle" x="272.3419" y="-1022.3558" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">use</text>
</g>
<!-- A12 -->
<g id="node13" class="node">
<title>A12</title>
<polygon fill="none" stroke="#000000" points="293.348,-856 293.348,-888 360.348,-888 360.348,-856 293.348,-856"/>
<text text-anchor="start" x="309.341" y="-869" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">InfosG3</text>
<polygon fill="none" stroke="#000000" points="293.348,-836 293.348,-856 360.348,-856 360.348,-836 293.348,-836"/>
<polygon fill="none" stroke="#000000" points="293.348,-792 293.348,-836 360.348,-836 360.348,-792 293.348,-792"/>
<text text-anchor="start" x="303.232" y="-817" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ha_confs()</text>
<text text-anchor="start" x="311.016" y="-805" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">parse()</text>
<polygon fill="none" stroke="#000000" points="293.348,-844 293.348,-876 360.348,-876 360.348,-844 293.348,-844"/>
<text text-anchor="start" x="309.341" y="-857" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">InfosG3</text>
<polygon fill="none" stroke="#000000" points="293.348,-824 293.348,-844 360.348,-844 360.348,-824 293.348,-824"/>
<polygon fill="none" stroke="#000000" points="293.348,-780 293.348,-824 360.348,-824 360.348,-780 293.348,-780"/>
<text text-anchor="start" x="303.232" y="-805" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ha_confs()</text>
<text text-anchor="start" x="311.016" y="-793" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">parse()</text>
</g>
<!-- A9&#45;&gt;A12 -->
<g id="edge16" class="edge">
<title>A9&#45;&gt;A12</title>
<path fill="none" stroke="#000000" d="M332.8263,-1063.7944C331.1366,-1005.4246 329.3197,-942.658 328.0413,-898.4955"/>
<polygon fill="#000000" stroke="#000000" points="327.7446,-888.2447 332.5321,-898.1103 327.8893,-893.2426 328.034,-898.2406 328.034,-898.2406 328.034,-898.2406 327.8893,-893.2426 323.5359,-898.3708 327.7446,-888.2447 327.7446,-888.2447"/>
<path fill="none" stroke="#000000" d="M332.683,-1039.9349C331.0582,-985.577 329.3338,-927.8888 328.095,-886.4463"/>
<polygon fill="#000000" stroke="#000000" points="327.7909,-876.272 332.5878,-886.1331 327.9404,-881.2698 328.0898,-886.2676 328.0898,-886.2676 328.0898,-886.2676 327.9404,-881.2698 323.5918,-886.4021 327.7909,-876.272 327.7909,-876.272"/>
</g>
<!-- A10 -->
<g id="node11" class="node">
<title>A10</title>
<polygon fill="none" stroke="#000000" points="50.348,-1308 50.348,-1340 141.348,-1340 141.348,-1308 50.348,-1308"/>
<text text-anchor="start" x="68.343" y="-1321" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">SolarmanV5</text>
<polygon fill="none" stroke="#000000" points="50.348,-1168 50.348,-1308 141.348,-1308 141.348,-1168 50.348,-1168"/>
<text text-anchor="start" x="70.5665" y="-1289" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ifc:AsyncIfc</text>
<text text-anchor="start" x="76.671" y="-1277" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">conn_no</text>
<text text-anchor="start" x="85.845" y="-1265" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">addr</text>
<text text-anchor="start" x="80.846" y="-1241" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">control</text>
<text text-anchor="start" x="83.9055" y="-1229" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">serial</text>
<text text-anchor="start" x="88.904" y="-1217" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">snr</text>
<text text-anchor="start" x="68.058" y="-1205" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">db:InfosG3P</text>
<text text-anchor="start" x="69.732" y="-1193" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">mb:Modbus</text>
<text text-anchor="start" x="81.96" y="-1181" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">switch</text>
<polygon fill="none" stroke="#000000" points="50.348,-1100 50.348,-1168 141.348,-1168 141.348,-1100 50.348,-1100"/>
<text text-anchor="start" x="60.2885" y="-1149" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">msg_unknown()</text>
<text text-anchor="start" x="76.402" y="-1125" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">healthy()</text>
<text text-anchor="start" x="80.8505" y="-1113" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">close()</text>
<polygon fill="none" stroke="#000000" points="50.348,-1284 50.348,-1316 141.348,-1316 141.348,-1284 50.348,-1284"/>
<text text-anchor="start" x="68.343" y="-1297" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">SolarmanV5</text>
<polygon fill="none" stroke="#000000" points="50.348,-1144 50.348,-1284 141.348,-1284 141.348,-1144 50.348,-1144"/>
<text text-anchor="start" x="70.5665" y="-1265" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ifc:AsyncIfc</text>
<text text-anchor="start" x="76.671" y="-1253" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">conn_no</text>
<text text-anchor="start" x="85.845" y="-1241" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">addr</text>
<text text-anchor="start" x="80.846" y="-1217" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">control</text>
<text text-anchor="start" x="83.9055" y="-1205" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">serial</text>
<text text-anchor="start" x="88.904" y="-1193" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">snr</text>
<text text-anchor="start" x="68.058" y="-1181" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">db:InfosG3P</text>
<text text-anchor="start" x="69.732" y="-1169" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">mb:Modbus</text>
<text text-anchor="start" x="81.96" y="-1157" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">switch</text>
<polygon fill="none" stroke="#000000" points="50.348,-1076 50.348,-1144 141.348,-1144 141.348,-1076 50.348,-1076"/>
<text text-anchor="start" x="60.2885" y="-1125" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">msg_unknown()</text>
<text text-anchor="start" x="76.402" y="-1101" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">healthy()</text>
<text text-anchor="start" x="80.8505" y="-1089" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">close()</text>
</g>
<!-- A10&#45;&gt;A3 -->
<g id="edge9" class="edge">
<title>A10&#45;&gt;A3</title>
<path fill="none" stroke="#000000" d="M63.2254,-1090.0442C59.4271,-1064.8951 56.2542,-1038.6889 54.348,-1014 36.3281,-780.6024 47.1574,-502.891 57.6579,-374.1486"/>
<polygon fill="#000000" stroke="#000000" points="64.7695,-1099.9973 58.7895,-1090.8055 64.0029,-1095.0565 63.2364,-1090.1156 63.2364,-1090.1156 63.2364,-1090.1156 64.0029,-1095.0565 67.6832,-1089.4256 64.7695,-1099.9973 64.7695,-1099.9973"/>
<text text-anchor="middle" x="53.6382" y="-1080.3813" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">remote</text>
<path fill="none" stroke="#000000" d="M63.2254,-1066.0442C59.4271,-1040.8951 56.2542,-1014.6889 54.348,-990 37.0619,-766.107 47.322,-500.0139 57.5568,-374.449"/>
<polygon fill="#000000" stroke="#000000" points="64.7695,-1075.9973 58.7895,-1066.8055 64.0029,-1071.0565 63.2364,-1066.1156 63.2364,-1066.1156 63.2364,-1066.1156 64.0029,-1071.0565 67.6832,-1065.4256 64.7695,-1075.9973 64.7695,-1075.9973"/>
<text text-anchor="middle" x="53.6382" y="-1056.3813" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">remote</text>
</g>
<!-- A10&#45;&gt;A3 -->
<g id="edge11" class="edge">
<title>A10&#45;&gt;A3</title>
<path fill="none" stroke="#000000" d="M80.8817,-1090.0442C77.4271,-1064.8951 74.2542,-1038.6889 72.348,-1014 54.8736,-787.6681 64.5282,-519.665 68.0596,-386.2452"/>
<polygon fill="#000000" stroke="#000000" points="82.2701,-1099.9973 76.4317,-1090.7149 81.5793,-1095.0453 80.8885,-1090.0932 80.8885,-1090.0932 80.8885,-1090.0932 81.5793,-1095.0453 85.3454,-1089.4715 82.2701,-1099.9973 82.2701,-1099.9973"/>
<polygon fill="#000000" stroke="#000000" points="68.0621,-386.1446 64.2181,-380.0435 68.3714,-374.1486 72.2154,-380.2497 68.0621,-386.1446"/>
<text text-anchor="middle" x="76.3539" y="-389.4865" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">local</text>
<path fill="none" stroke="#000000" d="M80.8817,-1066.0442C77.4271,-1040.8951 74.2542,-1014.6889 72.348,-990 55.6021,-773.1036 64.7076,-516.6035 68.1168,-386.6269"/>
<polygon fill="#000000" stroke="#000000" points="82.2701,-1075.9973 76.4317,-1066.7149 81.5793,-1071.0453 80.8885,-1066.0932 80.8885,-1066.0932 80.8885,-1066.0932 81.5793,-1071.0453 85.3454,-1065.4715 82.2701,-1075.9973 82.2701,-1075.9973"/>
<polygon fill="#000000" stroke="#000000" points="68.1213,-386.4451 64.2759,-380.3449 68.4278,-374.449 72.2733,-380.5493 68.1213,-386.4451"/>
<text text-anchor="middle" x="76.4146" y="-389.7851" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">local</text>
</g>
<!-- A10&#45;&gt;A4 -->
<g id="edge17" class="edge">
<title>A10&#45;&gt;A4</title>
<path fill="none" stroke="#000000" d="M133.6332,-1099.7656C141.3073,-1075.6649 149.5353,-1049.8249 157.7176,-1024.1284"/>
<polygon fill="#000000" stroke="#000000" points="160.8501,-1014.2909 162.1038,-1025.1848 159.333,-1019.0552 157.8159,-1023.8195 157.8159,-1023.8195 157.8159,-1023.8195 159.333,-1019.0552 153.5281,-1022.4541 160.8501,-1014.2909 160.8501,-1014.2909"/>
<text text-anchor="middle" x="131.0789" y="-1076.9294" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">use</text>
<path fill="none" stroke="#000000" d="M134.8842,-1075.7577C142.8622,-1051.494 151.3952,-1025.5424 159.8248,-999.9053"/>
<polygon fill="#000000" stroke="#000000" points="163.0491,-990.0992 164.2003,-1001.0045 161.4873,-994.849 159.9255,-999.5989 159.9255,-999.5989 159.9255,-999.5989 161.4873,-994.849 155.6506,-998.1932 163.0491,-990.0992 163.0491,-990.0992"/>
<text text-anchor="middle" x="132.5165" y="-1052.8983" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">use</text>
</g>
<!-- A13 -->
<g id="node14" class="node">
<title>A13</title>
<polygon fill="none" stroke="#000000" points="73.348,-856 73.348,-888 140.348,-888 140.348,-856 73.348,-856"/>
<text text-anchor="start" x="86.0065" y="-869" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">InfosG3P</text>
<polygon fill="none" stroke="#000000" points="73.348,-836 73.348,-856 140.348,-856 140.348,-836 73.348,-836"/>
<polygon fill="none" stroke="#000000" points="73.348,-792 73.348,-836 140.348,-836 140.348,-792 73.348,-792"/>
<text text-anchor="start" x="83.232" y="-817" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ha_confs()</text>
<text text-anchor="start" x="91.016" y="-805" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">parse()</text>
<polygon fill="none" stroke="#000000" points="73.348,-844 73.348,-876 140.348,-876 140.348,-844 73.348,-844"/>
<text text-anchor="start" x="86.0065" y="-857" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">InfosG3P</text>
<polygon fill="none" stroke="#000000" points="73.348,-824 73.348,-844 140.348,-844 140.348,-824 73.348,-824"/>
<polygon fill="none" stroke="#000000" points="73.348,-780 73.348,-824 140.348,-824 140.348,-780 73.348,-780"/>
<text text-anchor="start" x="83.232" y="-805" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ha_confs()</text>
<text text-anchor="start" x="91.016" y="-793" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">parse()</text>
</g>
<!-- A10&#45;&gt;A13 -->
<g id="edge18" class="edge">
<title>A10&#45;&gt;A13</title>
<path fill="none" stroke="#000000" d="M98.8285,-1099.7656C100.7699,-1032.6997 103.1011,-952.1665 104.6479,-898.7305"/>
<polygon fill="#000000" stroke="#000000" points="104.9465,-888.4166 109.1551,-898.5427 104.8017,-893.4145 104.657,-898.4124 104.657,-898.4124 104.657,-898.4124 104.8017,-893.4145 100.1589,-898.2822 104.9465,-888.4166 104.9465,-888.4166"/>
<path fill="none" stroke="#000000" d="M98.9422,-1075.7577C100.842,-1012.1995 103.0881,-937.0598 104.6045,-886.3285"/>
<polygon fill="#000000" stroke="#000000" points="104.9072,-876.2026 109.1063,-886.3326 104.7577,-881.2004 104.6083,-886.1981 104.6083,-886.1981 104.6083,-886.1981 104.7577,-881.2004 100.1103,-886.0636 104.9072,-876.2026 104.9072,-876.2026"/>
</g>
<!-- A11 -->
<g id="node12" class="node">
<title>A11</title>
<polygon fill="none" stroke="#000000" points="159.348,-1308 159.348,-1340 262.348,-1340 262.348,-1308 159.348,-1308"/>
<text text-anchor="start" x="200.01" y="-1321" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">Infos</text>
<polygon fill="none" stroke="#000000" points="159.348,-1252 159.348,-1308 262.348,-1308 262.348,-1252 159.348,-1252"/>
<text text-anchor="start" x="202.7895" y="-1289" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">stat</text>
<text text-anchor="start" x="178.334" y="-1277" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">new_stat_data</text>
<text text-anchor="start" x="191.9515" y="-1265" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">info_dev</text>
<polygon fill="none" stroke="#000000" points="159.348,-1100 159.348,-1252 262.348,-1252 262.348,-1100 159.348,-1100"/>
<text text-anchor="start" x="186.6835" y="-1233" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">static_init()</text>
<text text-anchor="start" x="184.7325" y="-1221" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">dev_value()</text>
<text text-anchor="start" x="181.6785" y="-1209" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">inc_counter()</text>
<text text-anchor="start" x="180.0085" y="-1197" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">dec_counter()</text>
<text text-anchor="start" x="178.058" y="-1185" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ha_proxy_conf</text>
<text text-anchor="start" x="193.061" y="-1173" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ha_conf</text>
<text text-anchor="start" x="185.842" y="-1161" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ha_remove</text>
<text text-anchor="start" x="187.2225" y="-1149" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">update_db</text>
<text text-anchor="start" x="171.385" y="-1137" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">set_db_def_value</text>
<text text-anchor="start" x="180.8335" y="-1125" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">get_db_value</text>
<text text-anchor="start" x="169.1705" y="-1113" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ignore_this_device</text>
<polygon fill="none" stroke="#000000" points="159.348,-1284 159.348,-1316 262.348,-1316 262.348,-1284 159.348,-1284"/>
<text text-anchor="start" x="200.01" y="-1297" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">Infos</text>
<polygon fill="none" stroke="#000000" points="159.348,-1228 159.348,-1284 262.348,-1284 262.348,-1228 159.348,-1228"/>
<text text-anchor="start" x="202.7895" y="-1265" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">stat</text>
<text text-anchor="start" x="178.334" y="-1253" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">new_stat_data</text>
<text text-anchor="start" x="191.9515" y="-1241" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">info_dev</text>
<polygon fill="none" stroke="#000000" points="159.348,-1076 159.348,-1228 262.348,-1228 262.348,-1076 159.348,-1076"/>
<text text-anchor="start" x="186.6835" y="-1209" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">static_init()</text>
<text text-anchor="start" x="184.7325" y="-1197" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">dev_value()</text>
<text text-anchor="start" x="181.6785" y="-1185" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">inc_counter()</text>
<text text-anchor="start" x="180.0085" y="-1173" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">dec_counter()</text>
<text text-anchor="start" x="178.058" y="-1161" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ha_proxy_conf</text>
<text text-anchor="start" x="193.061" y="-1149" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ha_conf</text>
<text text-anchor="start" x="185.842" y="-1137" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ha_remove</text>
<text text-anchor="start" x="187.2225" y="-1125" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">update_db</text>
<text text-anchor="start" x="171.385" y="-1113" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">set_db_def_value</text>
<text text-anchor="start" x="180.8335" y="-1101" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">get_db_value</text>
<text text-anchor="start" x="169.1705" y="-1089" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">ignore_this_device</text>
</g>
<!-- A11&#45;&gt;A12 -->
<g id="edge13" class="edge">
<title>A11&#45;&gt;A12</title>
<path fill="none" stroke="#000000" d="M259.3612,-1090.2414C268.1716,-1065.1077 276.9072,-1038.8566 284.348,-1014 296.9582,-971.8745 308.4598,-923.1578 316.2258,-888.0062"/>
<polygon fill="none" stroke="#000000" points="256.0104,-1089.2193 255.9834,-1099.8141 262.6115,-1091.5486 256.0104,-1089.2193"/>
<path fill="none" stroke="#000000" d="M258.9382,-1066.3836C267.808,-1041.1849 276.6736,-1014.8736 284.348,-990 296.0407,-952.103 307.205,-908.562 315.0802,-876.1703"/>
<polygon fill="none" stroke="#000000" points="255.5783,-1065.3868 255.541,-1075.9815 262.1771,-1067.7225 255.5783,-1065.3868"/>
</g>
<!-- A11&#45;&gt;A13 -->
<g id="edge14" class="edge">
<title>A11&#45;&gt;A13</title>
<path fill="none" stroke="#000000" d="M170.1294,-1090.3375C162.6366,-1065.0902 155.0603,-1038.773 148.348,-1014 136.8889,-971.7079 125.3116,-923.2186 117.2225,-888.1884"/>
<polygon fill="none" stroke="#000000" points="166.7853,-1091.3716 172.995,-1099.9559 173.4939,-1089.3728 166.7853,-1091.3716"/>
<path fill="none" stroke="#000000" d="M170.4636,-1066.2454C162.9411,-1041.0063 155.2684,-1014.7156 148.348,-990 137.6936,-951.9489 126.506,-908.6064 118.3587,-876.3336"/>
<polygon fill="none" stroke="#000000" points="167.1205,-1067.2825 173.3374,-1075.8616 173.8274,-1065.2781 167.1205,-1067.2825"/>
</g>
<!-- A14&#45;&gt;A9 -->
<g id="edge20" class="edge">
<title>A14&#45;&gt;A9</title>
<path fill="none" stroke="#000000" d="M207.7336,-1489.2507C227.8317,-1456.1375 252.0435,-1414.492 271.348,-1376 274.3143,-1370.0855 277.269,-1364.0055 280.1912,-1357.8349"/>
<polygon fill="none" stroke="#000000" points="204.6683,-1487.555 202.4506,-1497.9151 210.6449,-1491.1992 204.6683,-1487.555"/>
<path fill="none" stroke="#000000" d="M207.7336,-1465.2507C227.8317,-1432.1375 252.0435,-1390.492 271.348,-1352 274.3143,-1346.0855 277.269,-1340.0055 280.1912,-1333.8349"/>
<polygon fill="none" stroke="#000000" points="204.6683,-1463.555 202.4506,-1473.9151 210.6449,-1467.1992 204.6683,-1463.555"/>
</g>
<!-- A14&#45;&gt;A10 -->
<g id="edge21" class="edge">
<title>A14&#45;&gt;A10</title>
<path fill="none" stroke="#000000" d="M154.3052,-1488.1339C145.0994,-1446.2665 132.7762,-1390.2214 121.7769,-1340.197"/>
<polygon fill="none" stroke="#000000" points="150.8909,-1488.9045 156.4568,-1497.9196 157.7276,-1487.4012 150.8909,-1488.9045"/>
<path fill="none" stroke="#000000" d="M154.3052,-1464.1339C145.0994,-1422.2665 132.7762,-1366.2214 121.7769,-1316.197"/>
<polygon fill="none" stroke="#000000" points="150.8909,-1464.9045 156.4568,-1473.9196 157.7276,-1463.4012 150.8909,-1464.9045"/>
</g>
<!-- A15 -->
<g id="node16" class="node">
<title>A15</title>
<polygon fill="none" stroke="#000000" points="263.348,-1646 263.348,-1678 338.348,-1678 338.348,-1646 263.348,-1646"/>
<text text-anchor="start" x="283.0655" y="-1659" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">Modbus</text>
<polygon fill="none" stroke="#000000" points="263.348,-1494 263.348,-1646 338.348,-1646 338.348,-1494 263.348,-1494"/>
<text text-anchor="start" x="292.5095" y="-1627" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">que</text>
<text text-anchor="start" x="273.338" y="-1603" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">snd_handler</text>
<text text-anchor="start" x="274.453" y="-1591" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">rsp_handler</text>
<text text-anchor="start" x="284.4565" y="-1579" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">timeout</text>
<text text-anchor="start" x="274.7375" y="-1567" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">max_retires</text>
<text text-anchor="start" x="282.79" y="-1555" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">last_xxx</text>
<text text-anchor="start" x="294.7395" y="-1543" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">err</text>
<text text-anchor="start" x="281.4015" y="-1531" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">retry_cnt</text>
<text text-anchor="start" x="279.727" y="-1519" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">req_pend</text>
<text text-anchor="start" x="294.1845" y="-1507" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">tim</text>
<polygon fill="none" stroke="#000000" points="263.348,-1426 263.348,-1494 338.348,-1494 338.348,-1426 263.348,-1426"/>
<text text-anchor="start" x="274.738" y="-1475" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">build_msg()</text>
<text text-anchor="start" x="278.072" y="-1463" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">recv_req()</text>
<text text-anchor="start" x="275.572" y="-1451" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">recv_resp()</text>
<text text-anchor="start" x="285.8505" y="-1439" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">close()</text>
<polygon fill="none" stroke="#000000" points="263.348,-1622 263.348,-1654 338.348,-1654 338.348,-1622 263.348,-1622"/>
<text text-anchor="start" x="283.0655" y="-1635" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">Modbus</text>
<polygon fill="none" stroke="#000000" points="263.348,-1470 263.348,-1622 338.348,-1622 338.348,-1470 263.348,-1470"/>
<text text-anchor="start" x="292.5095" y="-1603" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">que</text>
<text text-anchor="start" x="273.338" y="-1579" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">snd_handler</text>
<text text-anchor="start" x="274.453" y="-1567" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">rsp_handler</text>
<text text-anchor="start" x="284.4565" y="-1555" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">timeout</text>
<text text-anchor="start" x="274.7375" y="-1543" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">max_retires</text>
<text text-anchor="start" x="282.79" y="-1531" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">last_xxx</text>
<text text-anchor="start" x="294.7395" y="-1519" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">err</text>
<text text-anchor="start" x="281.4015" y="-1507" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">retry_cnt</text>
<text text-anchor="start" x="279.727" y="-1495" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">req_pend</text>
<text text-anchor="start" x="294.1845" y="-1483" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">tim</text>
<polygon fill="none" stroke="#000000" points="263.348,-1402 263.348,-1470 338.348,-1470 338.348,-1402 263.348,-1402"/>
<text text-anchor="start" x="274.738" y="-1451" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">build_msg()</text>
<text text-anchor="start" x="278.072" y="-1439" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">recv_req()</text>
<text text-anchor="start" x="275.572" y="-1427" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">recv_resp()</text>
<text text-anchor="start" x="285.8505" y="-1415" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">close()</text>
</g>
<!-- A15&#45;&gt;A9 -->
<g id="edge23" class="edge">
<title>A15&#45;&gt;A9</title>
<path fill="none" stroke="#000000" d="M315.5861,-1415.2689C317.0212,-1402.3918 318.4833,-1389.272 319.9365,-1376.2329"/>
<polygon fill="#000000" stroke="#000000" points="314.4417,-1425.5379 311.077,-1415.101 314.9955,-1420.5687 315.5493,-1415.5995 315.5493,-1415.5995 315.5493,-1415.5995 314.9955,-1420.5687 320.0217,-1416.0979 314.4417,-1425.5379 314.4417,-1425.5379"/>
<text text-anchor="middle" x="326.3292" y="-1392.1837" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">has</text>
<text text-anchor="middle" x="308.049" y="-1403.5871" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">1</text>
<path fill="none" stroke="#000000" d="M315.5861,-1391.2689C317.0212,-1378.3918 318.4833,-1365.272 319.9365,-1352.2329"/>
<polygon fill="#000000" stroke="#000000" points="314.4417,-1401.5379 311.077,-1391.101 314.9955,-1396.5687 315.5493,-1391.5995 315.5493,-1391.5995 315.5493,-1391.5995 314.9955,-1396.5687 320.0217,-1392.0979 314.4417,-1401.5379 314.4417,-1401.5379"/>
<text text-anchor="middle" x="326.3292" y="-1368.1837" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">has</text>
<text text-anchor="middle" x="308.049" y="-1379.5871" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">1</text>
</g>
<!-- A15&#45;&gt;A10 -->
<g id="edge22" class="edge">
<title>A15&#45;&gt;A10</title>
<path fill="none" stroke="#000000" d="M257.1725,-1475.7757C245.6828,-1458.4941 232.4915,-1440.871 218.348,-1426 192.2483,-1398.5578 171.9188,-1406.411 149.348,-1376 141.2346,-1365.0684 134.273,-1352.8227 128.315,-1340.1269"/>
<polygon fill="#000000" stroke="#000000" points="262.6729,-1484.2184 253.4437,-1478.2962 259.9435,-1480.0291 257.2141,-1475.8397 257.2141,-1475.8397 257.2141,-1475.8397 259.9435,-1480.0291 260.9845,-1473.3833 262.6729,-1484.2184 262.6729,-1484.2184"/>
<text text-anchor="middle" x="143.7688" y="-1349.8225" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">has</text>
<text text-anchor="middle" x="245.6964" y="-1470.645" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">1</text>
<path fill="none" stroke="#000000" d="M257.1725,-1451.7757C245.6828,-1434.4941 232.4915,-1416.871 218.348,-1402 192.2483,-1374.5578 171.9188,-1382.411 149.348,-1352 141.2346,-1341.0684 134.273,-1328.8227 128.315,-1316.1269"/>
<polygon fill="#000000" stroke="#000000" points="262.6729,-1460.2184 253.4437,-1454.2962 259.9435,-1456.0291 257.2141,-1451.8397 257.2141,-1451.8397 257.2141,-1451.8397 259.9435,-1456.0291 260.9845,-1449.3833 262.6729,-1460.2184 262.6729,-1460.2184"/>
<text text-anchor="middle" x="143.7688" y="-1325.8225" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">has</text>
<text text-anchor="middle" x="245.6964" y="-1446.645" font-family="Helvetica,sans-Serif" font-size="10.00" fill="#000000">1</text>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

View File

@@ -8,7 +8,7 @@
[InverterG3|addr;remote:StreamPtr;local:StreamPtr|create_remote();;close()]
[InverterG3P|addr;remote:StreamPtr;local:StreamPtr|create_remote();;close()]
[<<AsyncIfc>>||set_node_id();get_conn_no();;tx_add();tx_flush();tx_get();tx_peek();tx_log();tx_clear();tx_len();;fwd_add();fwd_flush();fwd_log();fwd_clear();rx_get();rx_peek();rx_log();rx_clear();rx_len();rx_set_cb();;prot_set_timeout_cb()]
[<<AsyncIfc>>||set_node_id();get_conn_no();;tx_add();tx_flush();tx_get();tx_peek();tx_log();tx_clear();tx_len();;fwd_add();fwd_log();rx_get();rx_peek();rx_log();rx_clear();rx_len();rx_set_cb();;prot_set_timeout_cb()]
[AsyncIfcImpl|fwd_fifo:ByteFifo;tx_fifo:ByteFifo;rx_fifo:ByteFifo;conn_no:Count;node_id;timeout_cb]
[AsyncStream|reader;writer;addr;r_addr;l_addr|;<async>loop;disc();close();healthy();;__async_read();__async_write();__async_forward()]
[AsyncStreamServer|create_remote|<async>server_loop();<async>_async_forward();<async>publish_outstanding_mqtt();close()]

View File

@@ -56,21 +56,11 @@ class AsyncIfc(ABC):
''' add data to forward queue'''
pass # pragma: no cover
@abstractmethod
def fwd_flush(self):
''' send forward queue and clears it'''
pass # pragma: no cover
@abstractmethod
def fwd_log(self, level, info):
''' log the forward queue'''
pass # pragma: no cover
@abstractmethod
def fwd_clear(self):
''' clear forward queue'''
pass # pragma: no cover
#
# RX - QUEUE
#

View File

@@ -80,18 +80,10 @@ class AsyncIfcImpl(AsyncIfc):
''' add data to forward queue'''
self.fwd_fifo += data
def fwd_flush(self):
''' send forward queue and clears it'''
self.fwd_fifo()
def fwd_log(self, level, info):
''' log the forward queue'''
self.fwd_fifo.logging(level, info)
def fwd_clear(self):
''' clear forward queue'''
self.fwd_fifo.clear()
def rx_get(self, size: int = None) -> bytearray:
'''removes size numbers of bytes and return them'''
return self.rx_fifo.get(size)
@@ -131,9 +123,6 @@ class StreamPtr():
self.stream = _stream
self.ifc = _ifc
def __str__(self) -> str:
return f'ifc:{self._ifc}, stream: {self._stream}'
@property
def ifc(self):
return self._ifc
@@ -181,8 +170,8 @@ class AsyncStream(AsyncIfcImpl):
self._writer.write(self.tx_fifo.get())
def __timeout(self) -> int:
if self.timeout_cb is callable:
return self.timeout_cb
if self.timeout_cb:
return self.timeout_cb()
return 360
async def loop(self) -> Self:
@@ -273,7 +262,7 @@ class AsyncStream(AsyncIfcImpl):
self.proc_start = time.time()
self.rx_fifo += data
wait = self.rx_fifo() # call read in parent class
if wait > 0:
if wait and wait > 0:
await asyncio.sleep(wait)
else:
raise RuntimeError("Peer closed.")

View File

@@ -18,10 +18,11 @@ class ByteFifo:
self.__buf.extend(data)
return self
def __call__(self) -> None:
def __call__(self):
'''triggers the observer'''
if callable(self.__trigger_cb):
return self.__trigger_cb()
return None
def get(self, size: int = None) -> bytearray:
'''removes size numbers of byte and return them'''

View File

@@ -0,0 +1,207 @@
# test_with_pytest.py
import pytest
import asyncio
import gc
from app.src.infos import Infos
from app.src.inverter_base import InverterBase
from app.src.async_stream import AsyncStreamServer, AsyncStreamClient
from app.tests.test_modbus_tcp import FakeReader, FakeWriter
from app.tests.test_inverter_base import config_conn, patch_open_connection
pytest_plugins = ('pytest_asyncio',)
# initialize the proxy statistics
Infos.static_init()
def test_timeout_cb():
reader = FakeReader()
writer = FakeWriter()
def timeout():
return 13
ifc = AsyncStreamClient(reader, writer, None, None)
assert 360 == ifc._AsyncStream__timeout()
ifc.prot_set_timeout_cb(timeout)
assert 13 == ifc._AsyncStream__timeout()
ifc.prot_set_timeout_cb(None)
assert 360 == ifc._AsyncStream__timeout()
# call healthy outside the contexter manager (__exit__() was called)
assert ifc.healthy()
del ifc
cnt = 0
for inv in InverterBase:
print(f'InverterBase refs:{gc.get_referrers(inv)}')
cnt += 1
assert cnt == 0
@pytest.mark.asyncio
async def test_close_cb():
assert asyncio.get_running_loop()
reader = FakeReader()
writer = FakeWriter()
cnt = 0
def timeout():
return 0.1
def closed():
nonlocal cnt
nonlocal ifc
ifc.close() # clears the closed callback
cnt += 1
cnt = 0
ifc = AsyncStreamClient(reader, writer, None, closed)
ifc.prot_set_timeout_cb(timeout)
await ifc.client_loop('')
assert cnt == 1
ifc.prot_set_timeout_cb(timeout)
await ifc.client_loop('')
assert cnt == 1 # check that the closed method would not be called
del ifc
cnt = 0
ifc = AsyncStreamClient(reader, writer, None, None)
ifc.prot_set_timeout_cb(timeout)
await ifc.client_loop('')
assert cnt == 0
del ifc
cnt = 0
for inv in InverterBase:
print(f'InverterBase refs:{gc.get_referrers(inv)}')
cnt += 1
assert cnt == 0
@pytest.mark.asyncio
async def test_read():
global test
assert asyncio.get_running_loop()
reader = FakeReader()
reader.test = FakeReader.RD_TEST_13_BYTES
reader.on_recv.set()
writer = FakeWriter()
cnt = 0
def timeout():
return 1
def closed():
nonlocal cnt
nonlocal ifc
ifc.close() # clears the closed callback
cnt += 1
def app_read():
return 0.01 # async wait of 0.01
cnt = 0
ifc = AsyncStreamClient(reader, writer, None, closed)
ifc.prot_set_timeout_cb(timeout)
ifc.rx_set_cb(app_read)
await ifc.client_loop('')
print('End loop')
assert 13 == ifc.rx_len()
assert cnt == 1
del ifc
cnt = 0
for inv in InverterBase:
print(f'InverterBase refs:{gc.get_referrers(inv)}')
cnt += 1
assert cnt == 0
@pytest.mark.asyncio
async def test_write():
global test
assert asyncio.get_running_loop()
reader = FakeReader()
reader.test = FakeReader.RD_TEST_13_BYTES
reader.on_recv.set()
writer = FakeWriter()
cnt = 0
def timeout():
return 1
def closed():
nonlocal cnt
nonlocal ifc
ifc.close() # clears the closed callback
cnt += 1
cnt = 0
ifc = AsyncStreamClient(reader, writer, None, closed)
ifc.prot_set_timeout_cb(timeout)
ifc.tx_add(b'test-data-resp')
assert 14 == ifc.tx_len()
await ifc.client_loop('')
print('End loop')
assert 13 == ifc.rx_len()
assert 0 == ifc.tx_len()
assert cnt == 1
del ifc
cnt = 0
for inv in InverterBase:
print(f'InverterBase refs:{gc.get_referrers(inv)}')
cnt += 1
assert cnt == 0
@pytest.mark.asyncio
async def test_publ_mqtt_cb():
assert asyncio.get_running_loop()
reader = FakeReader()
reader.test = FakeReader.RD_TEST_13_BYTES
reader.on_recv.set()
writer = FakeWriter()
cnt = 0
def timeout():
return 0.1
async def publ_mqtt():
nonlocal cnt
nonlocal ifc
cnt += 1
cnt = 0
ifc = AsyncStreamServer(reader, writer, publ_mqtt, None, None)
assert ifc.async_publ_mqtt
ifc.prot_set_timeout_cb(timeout)
await ifc.server_loop()
assert cnt == 3 # 2 calls in server_loop() and 1 in loop()
assert ifc.async_publ_mqtt
ifc.close() # clears the closed callback
assert not ifc.async_publ_mqtt
del ifc
cnt = 0
for inv in InverterBase:
print(f'InverterBase refs:{gc.get_referrers(inv)}')
cnt += 1
assert cnt == 0
@pytest.mark.asyncio
async def test_create_remote_cb():
assert asyncio.get_running_loop()
reader = FakeReader()
writer = FakeWriter()
cnt = 0
def timeout():
return 0.1
async def create_remote():
nonlocal cnt
nonlocal ifc
ifc.close() # clears the closed callback
cnt += 1
cnt = 0
ifc = AsyncStreamServer(reader, writer, None, create_remote, None)
assert ifc.create_remote
await ifc.create_remote()
assert cnt == 1
ifc.prot_set_timeout_cb(timeout)
await ifc.server_loop()
assert not ifc.create_remote
del ifc
cnt = 0
for inv in InverterBase:
print(f'InverterBase refs:{gc.get_referrers(inv)}')
cnt += 1
assert cnt == 0

View File

@@ -1,7 +1,7 @@
# test_with_pytest.py
import pytest
import asyncio
import sys,gc
import gc
from mock import patch
from enum import Enum

View File

@@ -71,22 +71,25 @@ def config_conn(test_hostname, test_port):
}
class TestType(Enum):
class FakeReader():
RD_TEST_0_BYTES = 1
RD_TEST_TIMEOUT = 2
RD_TEST_13_BYTES = 3
test = TestType.RD_TEST_0_BYTES
class FakeReader():
def __init__(self):
self.on_recv = asyncio.Event()
self.test = self.RD_TEST_0_BYTES
async def read(self, max_len: int):
print(f'fakeReader test: {self.test}')
await self.on_recv.wait()
if test == TestType.RD_TEST_0_BYTES:
if self.test == self.RD_TEST_0_BYTES:
return b''
elif test == TestType.RD_TEST_TIMEOUT:
elif self.test == self.RD_TEST_13_BYTES:
print('fakeReader return 13 bytes')
self.test = self.RD_TEST_0_BYTES
return b'test-data-req'
elif self.test == self.RD_TEST_TIMEOUT:
raise TimeoutError
def feed_eof(self):
return
@@ -95,8 +98,11 @@ class FakeReader():
class FakeWriter():
def __init__(self, conn='remote.intern'):
self.conn = conn
self.closing = False
def write(self, buf: bytes):
return
async def drain(self):
await asyncio.sleep(0)
def get_extra_info(self, sel: str):
if sel == 'peername':
return self.conn
@@ -104,11 +110,11 @@ class FakeWriter():
return 'sock:1234'
assert False
def is_closing(self):
return False
return self.closing
def close(self):
return
self.closing = True
async def wait_closed(self):
return
await asyncio.sleep(0)
@pytest.fixture
@@ -118,14 +124,19 @@ def patch_open():
return FakeReader(), FakeWriter(conn)
def new_open(host: str, port: int):
global test
if test == TestType.RD_TEST_TIMEOUT:
raise TimeoutError
return new_conn(f'{host}:{port}')
with patch.object(asyncio, 'open_connection', new_open) as conn:
yield conn
@pytest.fixture
def patch_open_timeout():
def new_open(host: str, port: int):
raise TimeoutError
with patch.object(asyncio, 'open_connection', new_open) as conn:
yield conn
@pytest.fixture
def patch_no_mqtt():
with patch.object(Mqtt, 'publish') as conn:
@@ -170,13 +181,11 @@ async def test_modbus_no_cnf():
assert Infos.stat['proxy']['Inverter_Cnt'] == 0
@pytest.mark.asyncio
async def test_modbus_cnf1(config_conn, patch_open):
async def test_modbus_cnf1(config_conn, patch_open_timeout):
_ = config_conn
_ = patch_open
global test
_ = patch_open_timeout
assert asyncio.get_running_loop()
Proxy.class_init()
test = TestType.RD_TEST_TIMEOUT
assert Infos.stat['proxy']['Inverter_Cnt'] == 0
loop = asyncio.get_event_loop()
@@ -194,10 +203,8 @@ async def test_modbus_cnf2(config_conn, patch_no_mqtt, patch_open):
_ = config_conn
_ = patch_open
_ = patch_no_mqtt
global test
assert asyncio.get_running_loop()
Proxy.class_init()
test = TestType.RD_TEST_0_BYTES
assert Infos.stat['proxy']['Inverter_Cnt'] == 0
ModbusTcp(asyncio.get_event_loop())
@@ -220,10 +227,8 @@ async def test_modbus_cnf3(config_conn, patch_no_mqtt, patch_open):
_ = config_conn
_ = patch_open
_ = patch_no_mqtt
global test
assert asyncio.get_running_loop()
Proxy.class_init()
test = TestType.RD_TEST_0_BYTES
assert Infos.stat['proxy']['Inverter_Cnt'] == 0
ModbusTcp(asyncio.get_event_loop(), tim_restart= 0)
@@ -253,10 +258,8 @@ async def test_mqtt_err(config_conn, patch_mqtt_err, patch_open):
_ = config_conn
_ = patch_open
_ = patch_mqtt_err
global test
assert asyncio.get_running_loop()
Proxy.class_init()
test = TestType.RD_TEST_0_BYTES
assert Infos.stat['proxy']['Inverter_Cnt'] == 0
ModbusTcp(asyncio.get_event_loop(), tim_restart= 0)
@@ -286,10 +289,8 @@ async def test_mqtt_except(config_conn, patch_mqtt_except, patch_open):
_ = config_conn
_ = patch_open
_ = patch_mqtt_except
global test
assert asyncio.get_running_loop()
Proxy.class_init()
test = TestType.RD_TEST_0_BYTES
assert Infos.stat['proxy']['Inverter_Cnt'] == 0
ModbusTcp(asyncio.get_event_loop(), tim_restart= 0)