first automation steps functioning

This commit is contained in:
rawhide kobayashi 2025-03-23 17:55:12 -05:00
parent 2d8a698e7b
commit 4e2036b1cc
No known key found for this signature in database
GPG Key ID: 7789B80FB28A85D4
10 changed files with 380 additions and 212 deletions

View File

@ -4,265 +4,272 @@
<!-- Generated by graphviz version 12.2.1 (0)
-->
<!-- Pages: 1 -->
<svg width="1745pt" height="637pt"
viewBox="0.00 0.00 1744.50 636.50" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg width="1746pt" height="637pt"
viewBox="0.00 0.00 1745.50 636.50" 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 632.5)">
<polygon fill="white" stroke="none" points="-4,4 -4,-632.5 1740.5,-632.5 1740.5,4 -4,4"/>
<text text-anchor="middle" x="868.25" y="-4.95" font-family="Times,serif" font-size="14.00">State Machine</text>
<polygon fill="white" stroke="none" points="-4,4 -4,-632.5 1741.5,-632.5 1741.5,4 -4,4"/>
<text text-anchor="middle" x="868.75" y="-4.95" font-family="Times,serif" font-size="14.00">State Machine</text>
<!-- PoweredOff -->
<g id="node1" class="node">
<title>PoweredOff</title>
<path fill="white" stroke="black" d="M69.25,-258.25C69.25,-258.25 12,-258.25 12,-258.25 6,-258.25 0,-252.25 0,-246.25 0,-246.25 0,-234.25 0,-234.25 0,-228.25 6,-222.25 12,-222.25 12,-222.25 69.25,-222.25 69.25,-222.25 75.25,-222.25 81.25,-228.25 81.25,-234.25 81.25,-234.25 81.25,-246.25 81.25,-246.25 81.25,-252.25 75.25,-258.25 69.25,-258.25"/>
<text text-anchor="start" x="8" y="-234.07" font-family="Times,serif" font-size="14.00">PoweredOff</text>
<path fill="white" stroke="black" d="M70.25,-258.25C70.25,-258.25 13,-258.25 13,-258.25 7,-258.25 1,-252.25 1,-246.25 1,-246.25 1,-234.25 1,-234.25 1,-228.25 7,-222.25 13,-222.25 13,-222.25 70.25,-222.25 70.25,-222.25 76.25,-222.25 82.25,-228.25 82.25,-234.25 82.25,-234.25 82.25,-246.25 82.25,-246.25 82.25,-252.25 76.25,-258.25 70.25,-258.25"/>
<text text-anchor="start" x="9" y="-234.07" font-family="Times,serif" font-size="14.00">PoweredOff</text>
</g>
<!-- PoweredOff&#45;&gt;PoweredOff -->
<g id="edge1" class="edge">
<title>PoweredOff&#45;&gt;PoweredOff</title>
<path fill="none" stroke="black" d="M23.49,-258.4C20.7,-267.79 26.74,-276.25 41.62,-276.25 50,-276.25 55.57,-273.57 58.35,-269.56"/>
<polygon fill="black" stroke="black" points="61.79,-270.26 59.57,-259.9 54.84,-269.39 61.79,-270.26"/>
<text text-anchor="middle" x="41.62" y="-277.2" font-family="Times,serif" font-size="14.00">hard_shutdown</text>
</g>
<!-- POST -->
<g id="node2" class="node">
<title>POST</title>
<path fill="white" stroke="black" d="M268,-295.25C268,-295.25 238,-295.25 238,-295.25 232,-295.25 226,-289.25 226,-283.25 226,-283.25 226,-271.25 226,-271.25 226,-265.25 232,-259.25 238,-259.25 238,-259.25 268,-259.25 268,-259.25 274,-259.25 280,-265.25 280,-271.25 280,-271.25 280,-283.25 280,-283.25 280,-289.25 274,-295.25 268,-295.25"/>
<text text-anchor="start" x="234" y="-271.07" font-family="Times,serif" font-size="14.00">POST</text>
<path fill="white" stroke="black" d="M269,-295.25C269,-295.25 239,-295.25 239,-295.25 233,-295.25 227,-289.25 227,-283.25 227,-283.25 227,-271.25 227,-271.25 227,-265.25 233,-259.25 239,-259.25 239,-259.25 269,-259.25 269,-259.25 275,-259.25 281,-265.25 281,-271.25 281,-271.25 281,-283.25 281,-283.25 281,-289.25 275,-295.25 269,-295.25"/>
<text text-anchor="start" x="235" y="-271.07" font-family="Times,serif" font-size="14.00">POST</text>
</g>
<!-- PoweredOff&#45;&gt;POST -->
<g id="edge1" class="edge">
<g id="edge2" class="edge">
<title>PoweredOff&#45;&gt;POST</title>
<path fill="none" stroke="black" d="M81.48,-251.24C87.41,-252.7 93.47,-254.09 99.25,-255.25 138.26,-263.11 183.42,-269.26 214.46,-273.03"/>
<polygon fill="black" stroke="black" points="213.78,-276.47 224.13,-274.18 214.61,-269.52 213.78,-276.47"/>
<text text-anchor="middle" x="140.88" y="-269.8" font-family="Times,serif" font-size="14.00">power_on</text>
<path fill="none" stroke="black" d="M82.48,-251.24C88.41,-252.7 94.47,-254.09 100.25,-255.25 139.26,-263.11 184.42,-269.26 215.46,-273.03"/>
<polygon fill="black" stroke="black" points="214.78,-276.47 225.13,-274.18 215.61,-269.52 214.78,-276.47"/>
<text text-anchor="middle" x="141.88" y="-269.8" font-family="Times,serif" font-size="14.00">power_on</text>
</g>
<!-- POST&#45;&gt;PoweredOff -->
<g id="edge15" class="edge">
<g id="edge16" class="edge">
<title>POST&#45;&gt;PoweredOff</title>
<path fill="none" stroke="black" d="M227.68,-258.92C214.94,-250.46 198.66,-241.34 182.5,-237 153.45,-229.2 119.82,-229.64 92.7,-232.2"/>
<polygon fill="black" stroke="black" points="92.58,-228.7 83.01,-233.25 93.33,-235.66 92.58,-228.7"/>
<text text-anchor="middle" x="140.88" y="-237.95" font-family="Times,serif" font-size="14.00">hard_shutdown</text>
<path fill="none" stroke="black" d="M228.68,-258.92C215.94,-250.46 199.66,-241.34 183.5,-237 154.45,-229.2 120.82,-229.64 93.7,-232.2"/>
<polygon fill="black" stroke="black" points="93.58,-228.7 84.01,-233.25 94.33,-235.66 93.58,-228.7"/>
<text text-anchor="middle" x="141.88" y="-237.95" font-family="Times,serif" font-size="14.00">hard_shutdown</text>
</g>
<!-- EnterBIOS -->
<g id="node3" class="node">
<title>EnterBIOS</title>
<path fill="white" stroke="black" d="M594.38,-408.25C594.38,-408.25 542.38,-408.25 542.38,-408.25 536.38,-408.25 530.38,-402.25 530.38,-396.25 530.38,-396.25 530.38,-384.25 530.38,-384.25 530.38,-378.25 536.38,-372.25 542.38,-372.25 542.38,-372.25 594.38,-372.25 594.38,-372.25 600.38,-372.25 606.38,-378.25 606.38,-384.25 606.38,-384.25 606.38,-396.25 606.38,-396.25 606.38,-402.25 600.38,-408.25 594.38,-408.25"/>
<text text-anchor="start" x="538.38" y="-384.07" font-family="Times,serif" font-size="14.00">EnterBIOS</text>
<path fill="white" stroke="black" d="M595.38,-408.25C595.38,-408.25 543.38,-408.25 543.38,-408.25 537.38,-408.25 531.38,-402.25 531.38,-396.25 531.38,-396.25 531.38,-384.25 531.38,-384.25 531.38,-378.25 537.38,-372.25 543.38,-372.25 543.38,-372.25 595.38,-372.25 595.38,-372.25 601.38,-372.25 607.38,-378.25 607.38,-384.25 607.38,-384.25 607.38,-396.25 607.38,-396.25 607.38,-402.25 601.38,-408.25 595.38,-408.25"/>
<text text-anchor="start" x="539.38" y="-384.07" font-family="Times,serif" font-size="14.00">EnterBIOS</text>
</g>
<!-- POST&#45;&gt;EnterBIOS -->
<g id="edge16" class="edge">
<g id="edge17" class="edge">
<title>POST&#45;&gt;EnterBIOS</title>
<path fill="none" stroke="black" d="M264.12,-295.51C275.77,-314.61 296.77,-343.79 323.5,-358.25 384.82,-391.44 467.13,-395.31 518.71,-393.76"/>
<polygon fill="black" stroke="black" points="518.81,-397.26 528.66,-393.37 518.53,-390.26 518.81,-397.26"/>
<text text-anchor="middle" x="410.12" y="-394.95" font-family="Times,serif" font-size="14.00">enter_bios</text>
<path fill="none" stroke="black" d="M265.12,-295.51C276.77,-314.61 297.77,-343.79 324.5,-358.25 385.82,-391.44 468.13,-395.31 519.71,-393.76"/>
<polygon fill="black" stroke="black" points="519.81,-397.26 529.66,-393.37 519.53,-390.26 519.81,-397.26"/>
<text text-anchor="middle" x="411.12" y="-394.95" font-family="Times,serif" font-size="14.00">enter_bios</text>
</g>
<!-- IdleWaitingForInput -->
<g id="node5" class="node">
<title>IdleWaitingForInput</title>
<path fill="darksalmon" stroke="red" d="M865.5,-304.25C865.5,-304.25 762.5,-304.25 762.5,-304.25 756.5,-304.25 750.5,-298.25 750.5,-292.25 750.5,-292.25 750.5,-280.25 750.5,-280.25 750.5,-274.25 756.5,-268.25 762.5,-268.25 762.5,-268.25 865.5,-268.25 865.5,-268.25 871.5,-268.25 877.5,-274.25 877.5,-280.25 877.5,-280.25 877.5,-292.25 877.5,-292.25 877.5,-298.25 871.5,-304.25 865.5,-304.25"/>
<path fill="none" stroke="red" d="M869.5,-308.25C869.5,-308.25 758.5,-308.25 758.5,-308.25 752.5,-308.25 746.5,-302.25 746.5,-296.25 746.5,-296.25 746.5,-276.25 746.5,-276.25 746.5,-270.25 752.5,-264.25 758.5,-264.25 758.5,-264.25 869.5,-264.25 869.5,-264.25 875.5,-264.25 881.5,-270.25 881.5,-276.25 881.5,-276.25 881.5,-296.25 881.5,-296.25 881.5,-302.25 875.5,-308.25 869.5,-308.25"/>
<text text-anchor="start" x="758.5" y="-280.07" font-family="Times,serif" font-size="14.00">IdleWaitingForInput</text>
<path fill="darksalmon" stroke="red" d="M866.5,-304.25C866.5,-304.25 763.5,-304.25 763.5,-304.25 757.5,-304.25 751.5,-298.25 751.5,-292.25 751.5,-292.25 751.5,-280.25 751.5,-280.25 751.5,-274.25 757.5,-268.25 763.5,-268.25 763.5,-268.25 866.5,-268.25 866.5,-268.25 872.5,-268.25 878.5,-274.25 878.5,-280.25 878.5,-280.25 878.5,-292.25 878.5,-292.25 878.5,-298.25 872.5,-304.25 866.5,-304.25"/>
<path fill="none" stroke="red" d="M870.5,-308.25C870.5,-308.25 759.5,-308.25 759.5,-308.25 753.5,-308.25 747.5,-302.25 747.5,-296.25 747.5,-296.25 747.5,-276.25 747.5,-276.25 747.5,-270.25 753.5,-264.25 759.5,-264.25 759.5,-264.25 870.5,-264.25 870.5,-264.25 876.5,-264.25 882.5,-270.25 882.5,-276.25 882.5,-276.25 882.5,-296.25 882.5,-296.25 882.5,-302.25 876.5,-308.25 870.5,-308.25"/>
<text text-anchor="start" x="759.5" y="-280.07" font-family="Times,serif" font-size="14.00">IdleWaitingForInput</text>
</g>
<!-- POST&#45;&gt;IdleWaitingForInput -->
<g id="edge19" class="edge">
<g id="edge20" class="edge">
<title>POST&#45;&gt;IdleWaitingForInput</title>
<path fill="none" stroke="black" d="M280.21,-277.67C360.88,-278.97 607.65,-282.94 735.06,-285"/>
<polygon fill="black" stroke="black" points="734.69,-288.49 744.75,-285.15 734.8,-281.49 734.69,-288.49"/>
<text text-anchor="middle" x="568.38" y="-284.03" font-family="Times,serif" font-size="14.00">go_idle</text>
<path fill="none" stroke="black" d="M281.21,-277.67C361.88,-278.97 608.65,-282.94 736.06,-285"/>
<polygon fill="black" stroke="black" points="735.69,-288.49 745.75,-285.15 735.8,-281.49 735.69,-288.49"/>
<text text-anchor="middle" x="569.38" y="-284.03" font-family="Times,serif" font-size="14.00">go_idle</text>
</g>
<!-- WaitingForOS -->
<g id="node6" class="node">
<title>WaitingForOS</title>
<path fill="white" stroke="black" d="M603.75,-124.25C603.75,-124.25 533,-124.25 533,-124.25 527,-124.25 521,-118.25 521,-112.25 521,-112.25 521,-100.25 521,-100.25 521,-94.25 527,-88.25 533,-88.25 533,-88.25 603.75,-88.25 603.75,-88.25 609.75,-88.25 615.75,-94.25 615.75,-100.25 615.75,-100.25 615.75,-112.25 615.75,-112.25 615.75,-118.25 609.75,-124.25 603.75,-124.25"/>
<text text-anchor="start" x="529" y="-100.08" font-family="Times,serif" font-size="14.00">WaitingForOS</text>
<path fill="white" stroke="black" d="M604.75,-124.25C604.75,-124.25 534,-124.25 534,-124.25 528,-124.25 522,-118.25 522,-112.25 522,-112.25 522,-100.25 522,-100.25 522,-94.25 528,-88.25 534,-88.25 534,-88.25 604.75,-88.25 604.75,-88.25 610.75,-88.25 616.75,-94.25 616.75,-100.25 616.75,-100.25 616.75,-112.25 616.75,-112.25 616.75,-118.25 610.75,-124.25 604.75,-124.25"/>
<text text-anchor="start" x="530" y="-100.08" font-family="Times,serif" font-size="14.00">WaitingForOS</text>
</g>
<!-- POST&#45;&gt;WaitingForOS -->
<g id="edge17" class="edge">
<g id="edge18" class="edge">
<title>POST&#45;&gt;WaitingForOS</title>
<path fill="none" stroke="black" d="M263.64,-258.89C280.46,-227.13 314.28,-164.67 323.5,-158 352.68,-136.9 446.96,-121.37 509.38,-113.08"/>
<polygon fill="black" stroke="black" points="509.68,-116.57 519.14,-111.81 508.77,-109.63 509.68,-116.57"/>
<text text-anchor="middle" x="410.12" y="-158.95" font-family="Times,serif" font-size="14.00">wait_os</text>
<path fill="none" stroke="black" d="M264.64,-258.89C281.46,-227.13 315.28,-164.67 324.5,-158 353.68,-136.9 447.96,-121.37 510.38,-113.08"/>
<polygon fill="black" stroke="black" points="510.68,-116.57 520.14,-111.81 509.77,-109.63 510.68,-116.57"/>
<text text-anchor="middle" x="411.12" y="-158.95" font-family="Times,serif" font-size="14.00">wait_os</text>
</g>
<!-- BootLoop -->
<g id="node12" class="node">
<title>BootLoop</title>
<path fill="white" stroke="black" d="M592.12,-178.25C592.12,-178.25 544.62,-178.25 544.62,-178.25 538.62,-178.25 532.62,-172.25 532.62,-166.25 532.62,-166.25 532.62,-154.25 532.62,-154.25 532.62,-148.25 538.62,-142.25 544.62,-142.25 544.62,-142.25 592.12,-142.25 592.12,-142.25 598.12,-142.25 604.12,-148.25 604.12,-154.25 604.12,-154.25 604.12,-166.25 604.12,-166.25 604.12,-172.25 598.12,-178.25 592.12,-178.25"/>
<text text-anchor="start" x="540.62" y="-154.07" font-family="Times,serif" font-size="14.00">BootLoop</text>
<path fill="white" stroke="black" d="M593.12,-178.25C593.12,-178.25 545.62,-178.25 545.62,-178.25 539.62,-178.25 533.62,-172.25 533.62,-166.25 533.62,-166.25 533.62,-154.25 533.62,-154.25 533.62,-148.25 539.62,-142.25 545.62,-142.25 545.62,-142.25 593.12,-142.25 593.12,-142.25 599.12,-142.25 605.12,-148.25 605.12,-154.25 605.12,-154.25 605.12,-166.25 605.12,-166.25 605.12,-172.25 599.12,-178.25 593.12,-178.25"/>
<text text-anchor="start" x="541.62" y="-154.07" font-family="Times,serif" font-size="14.00">BootLoop</text>
</g>
<!-- POST&#45;&gt;BootLoop -->
<g id="edge18" class="edge">
<g id="edge19" class="edge">
<title>POST&#45;&gt;BootLoop</title>
<path fill="none" stroke="black" d="M264.71,-258.92C276.57,-240.46 297.49,-212.79 323.5,-199 392.11,-162.62 420.3,-189.9 496.75,-176.25 504.66,-174.84 513.02,-173.13 521.11,-171.37"/>
<polygon fill="black" stroke="black" points="521.83,-174.8 530.82,-169.2 520.3,-167.97 521.83,-174.8"/>
<text text-anchor="middle" x="410.12" y="-199.95" font-family="Times,serif" font-size="14.00">unsuccessful_post</text>
<path fill="none" stroke="black" d="M265.71,-258.92C277.57,-240.46 298.49,-212.79 324.5,-199 393.11,-162.62 421.3,-189.9 497.75,-176.25 505.66,-174.84 514.02,-173.13 522.11,-171.37"/>
<polygon fill="black" stroke="black" points="522.83,-174.8 531.82,-169.2 521.3,-167.97 522.83,-174.8"/>
<text text-anchor="middle" x="411.12" y="-199.95" font-family="Times,serif" font-size="14.00">unsuccessful_post</text>
</g>
<!-- BIOSSetup -->
<g id="node4" class="node">
<title>BIOSSetup</title>
<path fill="white" stroke="black" d="M840.75,-462.25C840.75,-462.25 787.25,-462.25 787.25,-462.25 781.25,-462.25 775.25,-456.25 775.25,-450.25 775.25,-450.25 775.25,-438.25 775.25,-438.25 775.25,-432.25 781.25,-426.25 787.25,-426.25 787.25,-426.25 840.75,-426.25 840.75,-426.25 846.75,-426.25 852.75,-432.25 852.75,-438.25 852.75,-438.25 852.75,-450.25 852.75,-450.25 852.75,-456.25 846.75,-462.25 840.75,-462.25"/>
<text text-anchor="start" x="783.25" y="-438.07" font-family="Times,serif" font-size="14.00">BIOSSetup</text>
<path fill="white" stroke="black" d="M841.75,-462.25C841.75,-462.25 788.25,-462.25 788.25,-462.25 782.25,-462.25 776.25,-456.25 776.25,-450.25 776.25,-450.25 776.25,-438.25 776.25,-438.25 776.25,-432.25 782.25,-426.25 788.25,-426.25 788.25,-426.25 841.75,-426.25 841.75,-426.25 847.75,-426.25 853.75,-432.25 853.75,-438.25 853.75,-438.25 853.75,-450.25 853.75,-450.25 853.75,-456.25 847.75,-462.25 841.75,-462.25"/>
<text text-anchor="start" x="784.25" y="-438.07" font-family="Times,serif" font-size="14.00">BIOSSetup</text>
</g>
<!-- EnterBIOS&#45;&gt;BIOSSetup -->
<g id="edge2" class="edge">
<g id="edge3" class="edge">
<title>EnterBIOS&#45;&gt;BIOSSetup</title>
<path fill="none" stroke="black" d="M606.69,-394.55C639.16,-398.7 687.33,-405.86 728.5,-416 740.22,-418.89 752.65,-422.64 764.27,-426.46"/>
<polygon fill="black" stroke="black" points="763.08,-429.76 773.67,-429.64 765.32,-423.12 763.08,-429.76"/>
<text text-anchor="middle" x="684.25" y="-416.95" font-family="Times,serif" font-size="14.00">start_bios_setup</text>
<path fill="none" stroke="black" d="M607.69,-394.55C640.16,-398.7 688.33,-405.86 729.5,-416 741.22,-418.89 753.65,-422.64 765.27,-426.46"/>
<polygon fill="black" stroke="black" points="764.08,-429.76 774.67,-429.64 766.32,-423.12 764.08,-429.76"/>
<text text-anchor="middle" x="685.25" y="-416.95" font-family="Times,serif" font-size="14.00">start_bios_setup</text>
</g>
<!-- EnterBIOS&#45;&gt;IdleWaitingForInput -->
<g id="edge3" class="edge">
<g id="edge4" class="edge">
<title>EnterBIOS&#45;&gt;IdleWaitingForInput</title>
<path fill="none" stroke="black" d="M606.64,-374.34C644.73,-358.08 704.58,-332.53 750.03,-313.13"/>
<polygon fill="black" stroke="black" points="751.16,-316.45 758.99,-309.31 748.42,-310.01 751.16,-316.45"/>
<text text-anchor="middle" x="684.25" y="-360.47" font-family="Times,serif" font-size="14.00">go_idle</text>
<path fill="none" stroke="black" d="M607.64,-374.34C645.73,-358.08 705.58,-332.53 751.03,-313.13"/>
<polygon fill="black" stroke="black" points="752.16,-316.45 759.99,-309.31 749.42,-310.01 752.16,-316.45"/>
<text text-anchor="middle" x="685.25" y="-360.47" font-family="Times,serif" font-size="14.00">go_idle</text>
</g>
<!-- BIOSSetup&#45;&gt;PoweredOff -->
<g id="edge4" class="edge">
<g id="edge5" class="edge">
<title>BIOSSetup&#45;&gt;PoweredOff</title>
<path fill="none" stroke="black" d="M774.97,-454.2C760.51,-457.61 743.84,-461.11 728.5,-463.25 550.01,-488.17 491.43,-508.67 323.5,-443.25 217.43,-401.93 114.54,-311.19 67.8,-266.36"/>
<polygon fill="black" stroke="black" points="70.44,-264.05 60.83,-259.6 65.57,-269.07 70.44,-264.05"/>
<text text-anchor="middle" x="410.12" y="-487.27" font-family="Times,serif" font-size="14.00">hard_shutdown</text>
<path fill="none" stroke="black" d="M775.97,-454.2C761.51,-457.61 744.84,-461.11 729.5,-463.25 551.01,-488.17 492.43,-508.67 324.5,-443.25 218.43,-401.93 115.54,-311.19 68.8,-266.36"/>
<polygon fill="black" stroke="black" points="71.44,-264.05 61.83,-259.6 66.57,-269.07 71.44,-264.05"/>
<text text-anchor="middle" x="411.12" y="-487.27" font-family="Times,serif" font-size="14.00">hard_shutdown</text>
</g>
<!-- BIOSSetup&#45;&gt;POST -->
<g id="edge5" class="edge">
<g id="edge6" class="edge">
<title>BIOSSetup&#45;&gt;POST</title>
<path fill="none" stroke="black" d="M774.91,-446.46C673.09,-451.63 397.39,-460.7 323.5,-412.25 286.78,-388.18 268.43,-338.29 260.08,-306.36"/>
<polygon fill="black" stroke="black" points="263.56,-305.86 257.8,-296.97 256.75,-307.51 263.56,-305.86"/>
<text text-anchor="middle" x="568.38" y="-451.64" font-family="Times,serif" font-size="14.00">finished_bios_setup</text>
<path fill="none" stroke="black" d="M775.91,-446.46C674.09,-451.63 398.39,-460.7 324.5,-412.25 287.78,-388.18 269.43,-338.29 261.08,-306.36"/>
<polygon fill="black" stroke="black" points="264.56,-305.86 258.8,-296.97 257.75,-307.51 264.56,-305.86"/>
<text text-anchor="middle" x="569.38" y="-451.64" font-family="Times,serif" font-size="14.00">finished_bios_setup</text>
</g>
<!-- IdleWaitingForInput&#45;&gt;PoweredOff -->
<g id="edge22" class="edge">
<g id="edge23" class="edge">
<title>IdleWaitingForInput&#45;&gt;PoweredOff</title>
<path fill="none" stroke="black" d="M782.75,-263.83C770.97,-254.56 757.65,-243.39 746.5,-232.25 684.48,-170.29 701.17,-116.9 622,-79.25 452.13,1.52 376.7,-51.42 200.5,-117.25 153.49,-134.82 138.25,-135.67 99.25,-167.25 83.5,-180 69.34,-197.8 59,-212.62"/>
<polygon fill="black" stroke="black" points="56.31,-210.35 53.63,-220.6 62.12,-214.27 56.31,-210.35"/>
<text text-anchor="middle" x="410.12" y="-70.19" font-family="Times,serif" font-size="14.00">hard_shutdown | soft_shutdown</text>
<path fill="none" stroke="black" d="M783.75,-263.83C771.97,-254.56 758.65,-243.39 747.5,-232.25 685.48,-170.29 702.17,-116.9 623,-79.25 453.13,1.52 377.7,-51.42 201.5,-117.25 154.49,-134.82 139.25,-135.67 100.25,-167.25 84.5,-180 70.34,-197.8 60,-212.62"/>
<polygon fill="black" stroke="black" points="57.31,-210.35 54.63,-220.6 63.12,-214.27 57.31,-210.35"/>
<text text-anchor="middle" x="411.12" y="-70.19" font-family="Times,serif" font-size="14.00">hard_shutdown | soft_shutdown</text>
</g>
<!-- IdleWaitingForInput&#45;&gt;POST -->
<g id="edge23" class="edge">
<g id="edge24" class="edge">
<title>IdleWaitingForInput&#45;&gt;POST</title>
<path fill="none" stroke="black" d="M746,-276.08C709.45,-271.04 663.35,-265.51 622,-263 501.29,-255.68 358.06,-266.96 291.49,-273.34"/>
<polygon fill="black" stroke="black" points="291.46,-269.83 281.85,-274.29 292.15,-276.8 291.46,-269.83"/>
<text text-anchor="middle" x="568.38" y="-263.95" font-family="Times,serif" font-size="14.00">reboot</text>
<path fill="none" stroke="black" d="M747,-276.08C710.45,-271.04 664.35,-265.51 623,-263 502.29,-255.68 359.06,-266.96 292.49,-273.34"/>
<polygon fill="black" stroke="black" points="292.46,-269.83 282.85,-274.29 293.15,-276.8 292.46,-269.83"/>
<text text-anchor="middle" x="569.38" y="-263.95" font-family="Times,serif" font-size="14.00">reboot</text>
</g>
<!-- WaitingForHWInfo -->
<g id="node7" class="node">
<title>WaitingForHWInfo</title>
<path fill="white" stroke="black" d="M1127,-304.25C1127,-304.25 1027.75,-304.25 1027.75,-304.25 1021.75,-304.25 1015.75,-298.25 1015.75,-292.25 1015.75,-292.25 1015.75,-280.25 1015.75,-280.25 1015.75,-274.25 1021.75,-268.25 1027.75,-268.25 1027.75,-268.25 1127,-268.25 1127,-268.25 1133,-268.25 1139,-274.25 1139,-280.25 1139,-280.25 1139,-292.25 1139,-292.25 1139,-298.25 1133,-304.25 1127,-304.25"/>
<text text-anchor="start" x="1023.75" y="-280.07" font-family="Times,serif" font-size="14.00">WaitingForHWInfo</text>
<path fill="white" stroke="black" d="M1128,-304.25C1128,-304.25 1028.75,-304.25 1028.75,-304.25 1022.75,-304.25 1016.75,-298.25 1016.75,-292.25 1016.75,-292.25 1016.75,-280.25 1016.75,-280.25 1016.75,-274.25 1022.75,-268.25 1028.75,-268.25 1028.75,-268.25 1128,-268.25 1128,-268.25 1134,-268.25 1140,-274.25 1140,-280.25 1140,-280.25 1140,-292.25 1140,-292.25 1140,-298.25 1134,-304.25 1128,-304.25"/>
<text text-anchor="start" x="1024.75" y="-280.07" font-family="Times,serif" font-size="14.00">WaitingForHWInfo</text>
</g>
<!-- IdleWaitingForInput&#45;&gt;WaitingForHWInfo -->
<g id="edge24" class="edge">
<g id="edge25" class="edge">
<title>IdleWaitingForInput&#45;&gt;WaitingForHWInfo</title>
<path fill="none" stroke="black" d="M881.97,-286.25C919.42,-286.25 966.1,-286.25 1004.33,-286.25"/>
<polygon fill="black" stroke="black" points="1003.88,-289.75 1013.88,-286.25 1003.88,-282.75 1003.88,-289.75"/>
<text text-anchor="middle" x="948.62" y="-287.2" font-family="Times,serif" font-size="14.00">begin_automation</text>
<path fill="none" stroke="black" d="M882.97,-286.25C920.42,-286.25 967.1,-286.25 1005.33,-286.25"/>
<polygon fill="black" stroke="black" points="1004.88,-289.75 1014.88,-286.25 1004.88,-282.75 1004.88,-289.75"/>
<text text-anchor="middle" x="949.62" y="-287.2" font-family="Times,serif" font-size="14.00">begin_automation</text>
</g>
<!-- WaitingForOS&#45;&gt;PoweredOff -->
<g id="edge6" class="edge">
<g id="edge7" class="edge">
<title>WaitingForOS&#45;&gt;PoweredOff</title>
<path fill="none" stroke="black" d="M520.53,-103.99C471.03,-102.62 390.94,-103.29 323.5,-117.25 266.23,-129.11 255.1,-143.04 200.5,-164 155.44,-181.3 142.27,-181.38 99.25,-203.25 91.96,-206.95 84.43,-211.34 77.32,-215.77"/>
<polygon fill="black" stroke="black" points="75.74,-212.62 69.21,-220.96 79.52,-218.52 75.74,-212.62"/>
<text text-anchor="middle" x="253" y="-164.95" font-family="Times,serif" font-size="14.00">hard_shutdown</text>
<path fill="none" stroke="black" d="M521.53,-103.99C472.03,-102.62 391.94,-103.29 324.5,-117.25 267.23,-129.11 256.1,-143.04 201.5,-164 156.44,-181.3 143.27,-181.38 100.25,-203.25 92.96,-206.95 85.43,-211.34 78.32,-215.77"/>
<polygon fill="black" stroke="black" points="76.74,-212.62 70.21,-220.96 80.52,-218.52 76.74,-212.62"/>
<text text-anchor="middle" x="254" y="-164.95" font-family="Times,serif" font-size="14.00">hard_shutdown</text>
</g>
<!-- WaitingForOS&#45;&gt;WaitingForHWInfo -->
<g id="edge7" class="edge">
<g id="edge8" class="edge">
<title>WaitingForOS&#45;&gt;WaitingForHWInfo</title>
<path fill="none" stroke="black" d="M616.16,-122.86C707.79,-155.39 910.9,-227.5 1013.89,-264.07"/>
<polygon fill="black" stroke="black" points="1012.42,-267.26 1023.01,-267.31 1014.76,-260.66 1012.42,-267.26"/>
<text text-anchor="middle" x="814" y="-215.09" font-family="Times,serif" font-size="14.00">os_booted</text>
<path fill="none" stroke="black" d="M617.16,-122.86C708.79,-155.39 911.9,-227.5 1014.89,-264.07"/>
<polygon fill="black" stroke="black" points="1013.42,-267.26 1024.01,-267.31 1015.76,-260.66 1013.42,-267.26"/>
<text text-anchor="middle" x="815" y="-215.09" font-family="Times,serif" font-size="14.00">os_booted</text>
</g>
<!-- OCTypeDecision -->
<g id="node8" class="node">
<title>OCTypeDecision</title>
<path fill="white" stroke="black" d="M1367.25,-307.25C1367.25,-307.25 1280.75,-307.25 1280.75,-307.25 1274.75,-307.25 1268.75,-301.25 1268.75,-295.25 1268.75,-295.25 1268.75,-283.25 1268.75,-283.25 1268.75,-277.25 1274.75,-271.25 1280.75,-271.25 1280.75,-271.25 1367.25,-271.25 1367.25,-271.25 1373.25,-271.25 1379.25,-277.25 1379.25,-283.25 1379.25,-283.25 1379.25,-295.25 1379.25,-295.25 1379.25,-301.25 1373.25,-307.25 1367.25,-307.25"/>
<text text-anchor="start" x="1276.75" y="-283.07" font-family="Times,serif" font-size="14.00">OCTypeDecision</text>
<path fill="white" stroke="black" d="M1368.25,-307.25C1368.25,-307.25 1281.75,-307.25 1281.75,-307.25 1275.75,-307.25 1269.75,-301.25 1269.75,-295.25 1269.75,-295.25 1269.75,-283.25 1269.75,-283.25 1269.75,-277.25 1275.75,-271.25 1281.75,-271.25 1281.75,-271.25 1368.25,-271.25 1368.25,-271.25 1374.25,-271.25 1380.25,-277.25 1380.25,-283.25 1380.25,-283.25 1380.25,-295.25 1380.25,-295.25 1380.25,-301.25 1374.25,-307.25 1368.25,-307.25"/>
<text text-anchor="start" x="1277.75" y="-283.07" font-family="Times,serif" font-size="14.00">OCTypeDecision</text>
</g>
<!-- WaitingForHWInfo&#45;&gt;OCTypeDecision -->
<g id="edge20" class="edge">
<g id="edge21" class="edge">
<title>WaitingForHWInfo&#45;&gt;OCTypeDecision</title>
<path fill="none" stroke="black" d="M1139.47,-287C1175.38,-287.44 1220.78,-288 1257.43,-288.45"/>
<polygon fill="black" stroke="black" points="1256.95,-291.94 1267,-288.56 1257.04,-284.94 1256.95,-291.94"/>
<text text-anchor="middle" x="1203.88" y="-289.31" font-family="Times,serif" font-size="14.00">hwinfo_available</text>
<path fill="none" stroke="black" d="M1140.47,-287C1176.38,-287.44 1221.78,-288 1258.43,-288.45"/>
<polygon fill="black" stroke="black" points="1257.95,-291.94 1268,-288.56 1258.04,-284.94 1257.95,-291.94"/>
<text text-anchor="middle" x="1204.88" y="-289.31" font-family="Times,serif" font-size="14.00">hwinfo_available</text>
</g>
<!-- RoughMulticoreUndervolt -->
<!-- SynchronizeMulticoreVID -->
<g id="node9" class="node">
<title>RoughMulticoreUndervolt</title>
<path fill="white" stroke="black" d="M1723,-536.25C1723,-536.25 1585.5,-536.25 1585.5,-536.25 1579.5,-536.25 1573.5,-530.25 1573.5,-524.25 1573.5,-524.25 1573.5,-512.25 1573.5,-512.25 1573.5,-506.25 1579.5,-500.25 1585.5,-500.25 1585.5,-500.25 1723,-500.25 1723,-500.25 1729,-500.25 1735,-506.25 1735,-512.25 1735,-512.25 1735,-524.25 1735,-524.25 1735,-530.25 1729,-536.25 1723,-536.25"/>
<text text-anchor="start" x="1581.5" y="-512.08" font-family="Times,serif" font-size="14.00">RoughMulticoreUndervolt</text>
<title>SynchronizeMulticoreVID</title>
<path fill="white" stroke="black" d="M1724.38,-536.25C1724.38,-536.25 1586.12,-536.25 1586.12,-536.25 1580.12,-536.25 1574.12,-530.25 1574.12,-524.25 1574.12,-524.25 1574.12,-512.25 1574.12,-512.25 1574.12,-506.25 1580.12,-500.25 1586.12,-500.25 1586.12,-500.25 1724.38,-500.25 1724.38,-500.25 1730.38,-500.25 1736.38,-506.25 1736.38,-512.25 1736.38,-512.25 1736.38,-524.25 1736.38,-524.25 1736.38,-530.25 1730.38,-536.25 1724.38,-536.25"/>
<text text-anchor="start" x="1582.12" y="-512.08" font-family="Times,serif" font-size="14.00">SynchronizeMulticoreVID</text>
</g>
<!-- OCTypeDecision&#45;&gt;RoughMulticoreUndervolt -->
<g id="edge8" class="edge">
<title>OCTypeDecision&#45;&gt;RoughMulticoreUndervolt</title>
<path fill="none" stroke="black" d="M1351.31,-307.6C1409.89,-348.47 1551.14,-447.01 1617.58,-493.36"/>
<polygon fill="black" stroke="black" points="1615.37,-496.09 1625.58,-498.94 1619.38,-490.35 1615.37,-496.09"/>
<text text-anchor="middle" x="1475.62" y="-445.13" font-family="Times,serif" font-size="14.00">rough_multicore_undervolt</text>
<!-- OCTypeDecision&#45;&gt;SynchronizeMulticoreVID -->
<g id="edge9" class="edge">
<title>OCTypeDecision&#45;&gt;SynchronizeMulticoreVID</title>
<path fill="none" stroke="black" d="M1352.31,-307.6C1410.89,-348.47 1552.14,-447.01 1618.58,-493.36"/>
<polygon fill="black" stroke="black" points="1616.37,-496.09 1626.58,-498.94 1620.38,-490.35 1616.37,-496.09"/>
<text text-anchor="middle" x="1476.62" y="-445.13" font-family="Times,serif" font-size="14.00">synchronize_vid</text>
</g>
<!-- PreciseMulticoreUndervolt -->
<g id="node10" class="node">
<title>PreciseMulticoreUndervolt</title>
<path fill="white" stroke="black" d="M1724.5,-362.25C1724.5,-362.25 1584,-362.25 1584,-362.25 1578,-362.25 1572,-356.25 1572,-350.25 1572,-350.25 1572,-338.25 1572,-338.25 1572,-332.25 1578,-326.25 1584,-326.25 1584,-326.25 1724.5,-326.25 1724.5,-326.25 1730.5,-326.25 1736.5,-332.25 1736.5,-338.25 1736.5,-338.25 1736.5,-350.25 1736.5,-350.25 1736.5,-356.25 1730.5,-362.25 1724.5,-362.25"/>
<text text-anchor="start" x="1580" y="-338.07" font-family="Times,serif" font-size="14.00">PreciseMulticoreUndervolt</text>
<path fill="white" stroke="black" d="M1725.5,-362.25C1725.5,-362.25 1585,-362.25 1585,-362.25 1579,-362.25 1573,-356.25 1573,-350.25 1573,-350.25 1573,-338.25 1573,-338.25 1573,-332.25 1579,-326.25 1585,-326.25 1585,-326.25 1725.5,-326.25 1725.5,-326.25 1731.5,-326.25 1737.5,-332.25 1737.5,-338.25 1737.5,-338.25 1737.5,-350.25 1737.5,-350.25 1737.5,-356.25 1731.5,-362.25 1725.5,-362.25"/>
<text text-anchor="start" x="1581" y="-338.07" font-family="Times,serif" font-size="14.00">PreciseMulticoreUndervolt</text>
</g>
<!-- OCTypeDecision&#45;&gt;PreciseMulticoreUndervolt -->
<g id="edge9" class="edge">
<g id="edge10" class="edge">
<title>OCTypeDecision&#45;&gt;PreciseMulticoreUndervolt</title>
<path fill="none" stroke="black" d="M1379.52,-293.13C1426.16,-297.05 1494.92,-304.22 1554,-316 1563.57,-317.91 1573.57,-320.28 1583.37,-322.84"/>
<polygon fill="black" stroke="black" points="1582.3,-326.18 1592.86,-325.4 1584.12,-319.42 1582.3,-326.18"/>
<text text-anchor="middle" x="1475.62" y="-316.95" font-family="Times,serif" font-size="14.00">precise_multicore_undervolt</text>
<path fill="none" stroke="black" d="M1380.52,-293.13C1427.16,-297.05 1495.92,-304.22 1555,-316 1564.57,-317.91 1574.57,-320.28 1584.37,-322.84"/>
<polygon fill="black" stroke="black" points="1583.3,-326.18 1593.86,-325.4 1585.12,-319.42 1583.3,-326.18"/>
<text text-anchor="middle" x="1476.62" y="-316.95" font-family="Times,serif" font-size="14.00">precise_multicore_undervolt</text>
</g>
<!-- SingleCoreTuning -->
<g id="node11" class="node">
<title>SingleCoreTuning</title>
<path fill="white" stroke="black" d="M1699.75,-195.25C1699.75,-195.25 1608.75,-195.25 1608.75,-195.25 1602.75,-195.25 1596.75,-189.25 1596.75,-183.25 1596.75,-183.25 1596.75,-171.25 1596.75,-171.25 1596.75,-165.25 1602.75,-159.25 1608.75,-159.25 1608.75,-159.25 1699.75,-159.25 1699.75,-159.25 1705.75,-159.25 1711.75,-165.25 1711.75,-171.25 1711.75,-171.25 1711.75,-183.25 1711.75,-183.25 1711.75,-189.25 1705.75,-195.25 1699.75,-195.25"/>
<text text-anchor="start" x="1604.75" y="-171.07" font-family="Times,serif" font-size="14.00">SingleCoreTuning</text>
<path fill="white" stroke="black" d="M1700.75,-195.25C1700.75,-195.25 1609.75,-195.25 1609.75,-195.25 1603.75,-195.25 1597.75,-189.25 1597.75,-183.25 1597.75,-183.25 1597.75,-171.25 1597.75,-171.25 1597.75,-165.25 1603.75,-159.25 1609.75,-159.25 1609.75,-159.25 1700.75,-159.25 1700.75,-159.25 1706.75,-159.25 1712.75,-165.25 1712.75,-171.25 1712.75,-171.25 1712.75,-183.25 1712.75,-183.25 1712.75,-189.25 1706.75,-195.25 1700.75,-195.25"/>
<text text-anchor="start" x="1605.75" y="-171.07" font-family="Times,serif" font-size="14.00">SingleCoreTuning</text>
</g>
<!-- OCTypeDecision&#45;&gt;SingleCoreTuning -->
<g id="edge10" class="edge">
<title>OCTypeDecision&#45;&gt;SingleCoreTuning</title>
<path fill="none" stroke="black" d="M1379.2,-270.76C1436.66,-251.15 1527.39,-220.19 1588.56,-199.32"/>
<polygon fill="black" stroke="black" points="1589.47,-202.71 1597.81,-196.17 1587.21,-196.08 1589.47,-202.71"/>
<text text-anchor="middle" x="1475.62" y="-263.13" font-family="Times,serif" font-size="14.00">single_core_tuning</text>
</g>
<!-- RoughMulticoreUndervolt&#45;&gt;PoweredOff -->
<g id="edge11" class="edge">
<title>RoughMulticoreUndervolt&#45;&gt;PoweredOff</title>
<path fill="none" stroke="black" d="M1616.37,-536.53C1556.69,-564.39 1434.55,-614.25 1325,-614.25 252,-614.25 252,-614.25 252,-614.25 169.87,-614.25 145.06,-578.42 99.25,-510.25 48.41,-434.59 41.3,-322.33 41.01,-269.61"/>
<polygon fill="black" stroke="black" points="44.51,-269.94 41.04,-259.93 37.51,-269.92 44.51,-269.94"/>
<text text-anchor="middle" x="814" y="-615.2" font-family="Times,serif" font-size="14.00">hard_shutdown</text>
<title>OCTypeDecision&#45;&gt;SingleCoreTuning</title>
<path fill="none" stroke="black" d="M1380.2,-270.76C1437.66,-251.15 1528.39,-220.19 1589.56,-199.32"/>
<polygon fill="black" stroke="black" points="1590.47,-202.71 1598.81,-196.17 1588.21,-196.08 1590.47,-202.71"/>
<text text-anchor="middle" x="1476.62" y="-263.13" font-family="Times,serif" font-size="14.00">single_core_tuning</text>
</g>
<!-- RoughMulticoreUndervolt&#45;&gt;POST -->
<!-- SynchronizeMulticoreVID&#45;&gt;PoweredOff -->
<g id="edge12" class="edge">
<title>RoughMulticoreUndervolt&#45;&gt;POST</title>
<path fill="none" stroke="black" d="M1573.32,-518.25C1506.85,-518.25 1409.77,-518.25 1325,-518.25 947.62,-518.25 947.62,-518.25 947.62,-518.25 808.9,-518.25 434.1,-587.99 323.5,-504.25 261.72,-457.48 253.2,-356.98 253.03,-306.89"/>
<polygon fill="black" stroke="black" points="256.53,-307.13 253.12,-297.1 249.53,-307.07 256.53,-307.13"/>
<text text-anchor="middle" x="948.62" y="-520.76" font-family="Times,serif" font-size="14.00">reboot</text>
<title>SynchronizeMulticoreVID&#45;&gt;PoweredOff</title>
<path fill="none" stroke="black" d="M1617.37,-536.53C1557.69,-564.39 1435.55,-614.25 1326,-614.25 253,-614.25 253,-614.25 253,-614.25 170.87,-614.25 146.06,-578.42 100.25,-510.25 49.41,-434.59 42.3,-322.33 42.01,-269.61"/>
<polygon fill="black" stroke="black" points="45.51,-269.94 42.04,-259.93 38.51,-269.92 45.51,-269.94"/>
<text text-anchor="middle" x="815" y="-615.2" font-family="Times,serif" font-size="14.00">hard_shutdown</text>
</g>
<!-- SynchronizeMulticoreVID&#45;&gt;POST -->
<g id="edge13" class="edge">
<title>SynchronizeMulticoreVID&#45;&gt;POST</title>
<path fill="none" stroke="black" d="M1573.65,-518.25C1507.2,-518.25 1410.48,-518.25 1326,-518.25 948.62,-518.25 948.62,-518.25 948.62,-518.25 809.9,-518.25 435.1,-587.99 324.5,-504.25 262.72,-457.48 254.2,-356.98 254.03,-306.89"/>
<polygon fill="black" stroke="black" points="257.53,-307.13 254.12,-297.1 250.53,-307.07 257.53,-307.13"/>
<text text-anchor="middle" x="949.62" y="-520.76" font-family="Times,serif" font-size="14.00">reboot</text>
</g>
<!-- PreciseMulticoreUndervolt&#45;&gt;PoweredOff -->
<g id="edge13" class="edge">
<g id="edge14" class="edge">
<title>PreciseMulticoreUndervolt&#45;&gt;PoweredOff</title>
<path fill="none" stroke="black" d="M1643.61,-362.68C1628.48,-389.56 1596.44,-438.87 1554,-462.25 1540.34,-469.78 1013.25,-536.55 997.75,-538.25 859.21,-553.47 824.62,-564.25 685.25,-564.25 252,-564.25 252,-564.25 252,-564.25 112.29,-564.25 60.65,-349.73 46.26,-269.8"/>
<polygon fill="black" stroke="black" points="49.74,-269.35 44.59,-260.09 42.84,-270.54 49.74,-269.35"/>
<text text-anchor="middle" x="814" y="-564.33" font-family="Times,serif" font-size="14.00">hard_shutdown</text>
<path fill="none" stroke="black" d="M1644.61,-362.68C1629.48,-389.56 1597.44,-438.87 1555,-462.25 1541.34,-469.78 1014.25,-536.55 998.75,-538.25 860.21,-553.47 825.62,-564.25 686.25,-564.25 253,-564.25 253,-564.25 253,-564.25 113.29,-564.25 61.65,-349.73 47.26,-269.8"/>
<polygon fill="black" stroke="black" points="50.74,-269.35 45.59,-260.09 43.84,-270.54 50.74,-269.35"/>
<text text-anchor="middle" x="815" y="-564.33" font-family="Times,serif" font-size="14.00">hard_shutdown</text>
</g>
<!-- PreciseMulticoreUndervolt&#45;&gt;POST -->
<g id="edge14" class="edge">
<g id="edge15" class="edge">
<title>PreciseMulticoreUndervolt&#45;&gt;POST</title>
<path fill="none" stroke="black" d="M1571.64,-344.25C1505.22,-344.25 1409.06,-344.25 1325,-344.25 567.38,-344.25 567.38,-344.25 567.38,-344.25 465.67,-344.25 349.41,-310.08 291.26,-290.55"/>
<polygon fill="black" stroke="black" points="292.45,-287.26 281.85,-287.34 290.19,-293.88 292.45,-287.26"/>
<text text-anchor="middle" x="948.62" y="-345.2" font-family="Times,serif" font-size="14.00">reboot</text>
<path fill="none" stroke="black" d="M1572.64,-344.25C1506.22,-344.25 1410.06,-344.25 1326,-344.25 568.38,-344.25 568.38,-344.25 568.38,-344.25 466.67,-344.25 350.41,-310.08 292.26,-290.55"/>
<polygon fill="black" stroke="black" points="293.45,-287.26 282.85,-287.34 291.19,-293.88 293.45,-287.26"/>
<text text-anchor="middle" x="949.62" y="-345.2" font-family="Times,serif" font-size="14.00">reboot</text>
</g>
<!-- SingleCoreTuning&#45;&gt;PoweredOff -->
<g id="edge25" class="edge">
<g id="edge26" class="edge">
<title>SingleCoreTuning&#45;&gt;PoweredOff</title>
<path fill="none" stroke="black" d="M1631.85,-158.86C1581.79,-117.8 1451.67,-22.25 1325,-22.25 252,-22.25 252,-22.25 252,-22.25 171.34,-22.25 152.68,-59.82 99.25,-120.25 75.65,-146.94 59.57,-185.01 50.52,-211.07"/>
<polygon fill="black" stroke="black" points="47.27,-209.75 47.44,-220.34 53.91,-211.95 47.27,-209.75"/>
<text text-anchor="middle" x="814" y="-23.2" font-family="Times,serif" font-size="14.00">hard_shutdown</text>
<path fill="none" stroke="black" d="M1632.85,-158.86C1582.79,-117.8 1452.67,-22.25 1326,-22.25 253,-22.25 253,-22.25 253,-22.25 172.34,-22.25 153.68,-59.82 100.25,-120.25 76.65,-146.94 60.57,-185.01 51.52,-211.07"/>
<polygon fill="black" stroke="black" points="48.27,-209.75 48.44,-220.34 54.91,-211.95 48.27,-209.75"/>
<text text-anchor="middle" x="815" y="-23.2" font-family="Times,serif" font-size="14.00">hard_shutdown</text>
</g>
<!-- SingleCoreTuning&#45;&gt;POST -->
<g id="edge26" class="edge">
<g id="edge27" class="edge">
<title>SingleCoreTuning&#45;&gt;POST</title>
<path fill="none" stroke="black" d="M1596.32,-177.25C1530.86,-177.25 1420.17,-177.25 1325,-177.25 813,-177.25 813,-177.25 813,-177.25 613.71,-177.25 380.62,-239.6 291.36,-265.83"/>
<polygon fill="black" stroke="black" points="290.5,-262.44 281.91,-268.64 292.5,-269.15 290.5,-262.44"/>
<text text-anchor="middle" x="948.62" y="-178.2" font-family="Times,serif" font-size="14.00">reboot</text>
<path fill="none" stroke="black" d="M1597.32,-177.25C1531.86,-177.25 1421.17,-177.25 1326,-177.25 814,-177.25 814,-177.25 814,-177.25 614.71,-177.25 381.62,-239.6 292.36,-265.83"/>
<polygon fill="black" stroke="black" points="291.5,-262.44 282.91,-268.64 293.5,-269.15 291.5,-262.44"/>
<text text-anchor="middle" x="949.62" y="-178.2" font-family="Times,serif" font-size="14.00">reboot</text>
</g>
<!-- BootLoop&#45;&gt;PoweredOff -->
<g id="edge21" class="edge">
<g id="edge22" class="edge">
<title>BootLoop&#45;&gt;PoweredOff</title>
<path fill="none" stroke="black" d="M532.49,-161.55C485.01,-163.65 397.49,-168.66 323.5,-179.25 222.7,-193.68 198.57,-203.78 99.25,-226.25 97.1,-226.74 94.91,-227.24 92.7,-227.75"/>
<polygon fill="black" stroke="black" points="91.98,-224.32 83.05,-230.02 93.59,-231.14 91.98,-224.32"/>
<text text-anchor="middle" x="253" y="-202.61" font-family="Times,serif" font-size="14.00">trigger_cmos_reset</text>
<path fill="none" stroke="black" d="M533.49,-161.55C486.01,-163.65 398.49,-168.66 324.5,-179.25 223.7,-193.68 199.57,-203.78 100.25,-226.25 98.1,-226.74 95.91,-227.24 93.7,-227.75"/>
<polygon fill="black" stroke="black" points="92.98,-224.32 84.05,-230.02 94.59,-231.14 92.98,-224.32"/>
<text text-anchor="middle" x="254" y="-202.61" font-family="Times,serif" font-size="14.00">trigger_cmos_reset</text>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -10,9 +10,11 @@ fps = "60.000"
[client]
hostname = "10.20.30.90"
hwinfo_port = "60000" # Unless you've changed it!
ssh_username = "rawhide"
# MAKE SURE YOU USE SINGLE QUOTES, THIS HAS TO BE A LITERAL
ryzen_smu_cli_path = 'C:\Users\rawhide\Downloads\win-x64\ryzen-smu-cli.exe'
ycruncher_path = 'C:\Users\rawhide\Downloads\y-cruncher v0.8.6.9545b\y-cruncher v0.8.6.9545\y-cruncher.exe'
# Alternatively, just make sure ycruncher and ryzen-smu-cli are in your PATH and leave it as it is
ryzen_smu_cli_path = 'C:\Users\rawhide\Downloads\ryzen-smu-cli-0.0.2\ryzen-smu-cli.exe'
ycruncher_path = 'C:\Users\rawhide\Downloads\y-cruncher v0.8.6.9545\y-cruncher v0.8.6.9545\y-cruncher.exe'
bios_map_path = 'bios-maps/asus/x870-gaming-plus-wifi.gv'
[client.overclocking.common] # Just some ideas of how the settings may work for your system

View File

@ -5,4 +5,5 @@ import logging
app = Flask(__name__)
ui = SocketIO(app)
logger = app.logger
logger.setLevel(logging.INFO)
logger.setLevel(logging.INFO)
logger.propagate = False

View File

@ -45,3 +45,7 @@ def handle_clear_cmos():
"pwr": GPIO.LOW.value
}
esp32_serial.mkb_queue.put(msg)
@ui.on("begin_automation")
def handle_begin_automation():
model.begin_automation()

69
webui/ipkvm/states/ssh.py Normal file
View File

@ -0,0 +1,69 @@
import paramiko
from paramiko import Channel
class ssh_conn():
def __init__(self, hostname: str, ssh_username: str, ycruncher_path: str, ryzen_smu_cli_path: str):
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# Yuck!
self.ycruncher_cmd = f"& \"{ycruncher_path.replace("\\", "\\\\")}\"\r"
# MEGA YUCK!
self.smu_cmd = f"Start-Process -FilePath \"{ryzen_smu_cli_path.replace("\\", "\\\\")}\" -Verb RunAs -ArgumentList "
client.connect(hostname=hostname, username=ssh_username, key_filename=f"/home/{ssh_username}/.ssh/id_rsa.pub")
self.channel_ycruncher = client.invoke_shell()
self.channel_smu = client.invoke_shell()
def ez_send_line(self, channel: Channel, cmd: str | int, wait: bool = False, wait_string: str = ""):
channel.send(f"{cmd}\r".encode())
if wait:
self.read_channel_line_until(channel, wait_string)
def read_channel_line_until(self, channel: Channel, desired_line: str):
line = ""
for byte in iter(lambda: channel.recv(1), b""):
line += byte.decode()
if desired_line.lower() in line.lower():
return
elif byte == b'\n' or byte == b'\r':
line = ""
def start_ycruncher(self, core_list: list[int], test_list: list[int], test_length: int = 120):
self.ez_send_line(self.channel_ycruncher, self.ycruncher_cmd, True, "option:")
self.ez_send_line(self.channel_ycruncher, 2, True, "option:")
self.ez_send_line(self.channel_ycruncher, 1, True, "option:")
self.ez_send_line(self.channel_ycruncher, "d", True, "option:")
for core in core_list:
self.ez_send_line(self.channel_ycruncher, core, True, "option:")
self.ez_send_line(self.channel_ycruncher, "", True, "option:")
self.ez_send_line(self.channel_ycruncher, 8, True, "option:")
for test in test_list:
self.ez_send_line(self.channel_ycruncher, test, True, "option:")
self.ez_send_line(self.channel_ycruncher, 4, True, "(seconds) =")
self.ez_send_line(self.channel_ycruncher, test_length, True, "option:")
self.ez_send_line(self.channel_ycruncher, 0, False)
def run_smu_cmd(self, args: str):
self.ez_send_line(self.channel_smu, f"{self.smu_cmd}\"{args}\"")
#start_ycruncher(channel,
# "& \"C:\\Users\\rawhide\\Downloads\\y-cruncher v0.8.6.9545\\y-cruncher v0.8.6.9545\\y-cruncher.exe\"\r",
# [0,1,6,9,19,25,31], [11,12], 5)
#
#while True:
# line = b''
# for byte in iter(lambda: channel.recv(1), b""):
# line += byte
# if byte == b'\n' or byte == b'\r':
# line = f"{line.decode('utf-8', errors='replace').rstrip()}"
# print(line)
# line = b''

View File

@ -5,7 +5,10 @@ from transitions.extensions import GraphMachine
from ipkvm.util.mkb import esp32_serial
from ipkvm.util.mkb.mkb import GPIO
from ipkvm.util.mkb.scancodes import HIDKeyCode
from ipkvm.app import logging, ui
from ipkvm.app import logging, ui, logger
from ipkvm.util.hwinfo import hw_monitor
from ipkvm.states import ssh
from ipkvm.util.profiles import profile_manager
logging.basicConfig(level=logging.INFO)
@ -15,7 +18,7 @@ class State(Enum):
BIOSSetup = "bios setup"
WaitingForOS = "waiting for os"
OCTypeDecision = "next process decision"
RoughMulticoreUndervolt = "rough multicore undervolting"
SynchronizeMulticoreVID = "sync multicore vid"
PreciseMulticoreUndervolt = "precise multicore undervolting"
POST = "power on self test"
WaitingForHWInfo = "waiting for hwinfo"
@ -37,6 +40,8 @@ class Overclocking:
_current_BIOS_location = "EZ Mode"
_PBO_offsets: list[int] = []
# TRANSITION DEFINITIONS
@add_transitions(transition(State.PoweredOff, State.POST, unless="client_powered"))
def power_on(self): ...
@ -68,21 +73,20 @@ class Overclocking:
@add_transitions(transition(State.BootLoop, State.PoweredOff))
def trigger_cmos_reset(self): ...
@add_transitions(transition([State.IdleWaitingForInput, State.RoughMulticoreUndervolt,
@add_transitions(transition([State.IdleWaitingForInput, State.SynchronizeMulticoreVID,
State.PreciseMulticoreUndervolt, State.SingleCoreTuning], State.POST))
def reboot(self): ...
@add_transitions(transition([State.BIOSSetup, State.IdleWaitingForInput, State.POST, State.WaitingForOS,
State.RoughMulticoreUndervolt, State.PreciseMulticoreUndervolt,
State.SingleCoreTuning], State.PoweredOff, after="_hard_shutdown"))
State.SynchronizeMulticoreVID, State.PreciseMulticoreUndervolt,
State.SingleCoreTuning, State.PoweredOff], State.PoweredOff, after="_hard_shutdown"))
def hard_shutdown(self): ...
@add_transitions(transition(State.IdleWaitingForInput, State.PoweredOff,
after="_soft_shutdown"))
@add_transitions(transition(State.IdleWaitingForInput, State.PoweredOff, after="_soft_shutdown"))
def soft_shutdown(self): ...
@add_transitions(transition(State.OCTypeDecision, State.RoughMulticoreUndervolt))
def rough_multicore_undervolt(self): ...
@add_transitions(transition(State.OCTypeDecision, State.SynchronizeMulticoreVID))
def synchronize_vid(self): ...
@add_transitions(transition(State.OCTypeDecision, State.PreciseMulticoreUndervolt))
def precise_multicore_undervolt(self): ...
@ -93,6 +97,13 @@ class Overclocking:
@add_transitions(transition([State.POST, State.EnterBIOS], State.IdleWaitingForInput))
def go_idle(self): ...
# I WANTED THESE TO BE FUNCTION REFERENCES BUT IT DOESN'T WORK
_OC_steps = {
"synchronize_vid": False,
"precise_multicore_undervolt": False,
"single_core_tuning": False
}
# PROPERTIES GO HERE
@property
@ -133,20 +144,9 @@ class Overclocking:
self.go_idle()
def on_enter_EnterBIOS(self):
# # Wait until the POST has progressed far enough for USB devices to be loaded and options to be imminent
# esp32_serial.notify_code = "45"
# esp32_serial.active_notification_request.set()
# esp32_serial.post_code_notify.wait()
# esp32_serial.post_code_notify.clear()
#
# # Spam delete until the BIOS is loaded
# esp32_serial.notify_code = "Ab"
# esp32_serial.active_notification_request.set()
# while not esp32_serial.post_code_notify.is_set():
spam_timer = time.time()
# Crushed by my lack of consistent access to BIOS post codes, we simply take our time...
# Crushed by my lack of consistent access to BIOS post codes, we simply spam once USB is available...
while time.time() - spam_timer <= 10:
msg = {
"key_down": HIDKeyCode.Delete.value
@ -159,9 +159,7 @@ class Overclocking:
esp32_serial.mkb_queue.put(msg)
time.sleep(0.1)
# esp32_serial.post_code_notify.clear()
# Wait a few seconds for the BIOS to become responsive
# Wait a few seconds for the BIOS to become responsive...
time.sleep(5)
self._enter_bios_flag = False
@ -172,9 +170,77 @@ class Overclocking:
else:
self.go_idle()
def on_enter_WaitingForHWInfo(self):
self._running_automatic = True
while not hw_monitor.is_hwinfo_alive:
pass
self.hwinfo_available()
def on_enter_OCTypeDecision(self):
# I WANTED THESE TO BE FUNCTION REFERENCES BUT IT DOESN'T WORK
if not self._OC_steps["synchronize_vid"]:
self.synchronize_vid()
elif not self._OC_steps["precise_multicore_undervolt"]:
self.precise_multicore_undervolt()
elif not self._OC_steps["single_core_tuning"]:
self.single_core_tuning()
def on_enter_SynchronizeMulticoreVID(self):
ssh_conn = ssh.ssh_conn(profile_manager.profile["client"]["hostname"],
profile_manager.profile["client"]["ssh_username"],
profile_manager.profile["client"]["ycruncher_path"],
profile_manager.profile["client"]["ryzen_smu_cli_path"])
self._PBO_offsets = [0] * hw_monitor.core_dataframe.shape[0]
ssh_conn.start_ycruncher([x for x in range(hw_monitor.core_dataframe.shape[0] * 2)], [11])
conditions_met = False
while not conditions_met:
avg_vid: dict[str, float] = {f"Core {x}": 0 for x in range(hw_monitor.core_dataframe.shape[0])}
# Short wait to allow values to settle. This could be expanded to wait until the PPT does not change
# within a certain envelope for worse cooling systems...
time.sleep(5)
data = hw_monitor.collect_data(10)
for frame in data:
for row in frame.itertuples():
avg_vid[row.Index] = avg_vid[row.Index] + row.VID
data_len = len(data)
for core in avg_vid:
avg_vid[core] = avg_vid[core] / data_len
highest_vid_index = self.get_highest_vid_index(avg_vid)
self._PBO_offsets[highest_vid_index] -= 1
ssh_conn.run_smu_cmd(f"--offset {highest_vid_index}:{self._PBO_offsets[highest_vid_index]}")
logger.info(f"Highest core was core {highest_vid_index} at {avg_vid[f"Core {highest_vid_index}"]}, changed offset to {self._PBO_offsets[highest_vid_index]}!")
print(self._PBO_offsets)
def get_highest_vid_index(self, vid_list: dict[str, float]):
highest_index = 0
for index in range(len(vid_list) - 1):
if vid_list[f"Core {index + 1}"] > vid_list[f"Core {highest_index}"]:
highest_index = index + 1
return highest_index
# STATE EXIT FUNCTIONS
def on_exit_PoweredOff(self):
self._power_switch(0.2)
self._power_switch(0.2)
# UTILITY FUNCTIONS GO HERE
def _power_switch(self, delay: float):

View File

@ -42,6 +42,7 @@
</select>
<button type="button" onclick="socket.emit('save_profile', code_mirror.getValue());">Save</button>
<button type="button" onclick="save_new_profile();">Save as</button>
<button type="button" onclick="socket.emit(`begin_automation`);">Begin automation...</button>
</div>
<div class="cm-editor">
<div id="codemirror" class="cm-scroller"></div>

View File

@ -10,7 +10,9 @@ class HWInfoMonitor(threading.Thread):
def __init__(self):
super().__init__()
self.request_url = f"http://{profile_manager.profile["client"]["hostname"]}:{profile_manager.profile["client"]["hwinfo_port"]}/json.json"
self.dataframe: pd.DataFrame
self.core_dataframe: pd.DataFrame
self._is_hwinfo_alive = False
self._new_data = threading.Event()
self.start()
def run(self):
@ -21,62 +23,77 @@ class HWInfoMonitor(threading.Thread):
def do_work(self):
self.create_dataframe()
time.sleep(0.25)
while not profile_manager.restart_hwinfo.is_set():
self.create_dataframe()
time.sleep(0.25)
def create_dataframe(self):
try:
request = requests.get(self.request_url, timeout=1)
data = request.json()
if request.status_code == 200 and len(request.json()) > 0:
self._is_hwinfo_alive = True
data = request.json()
cpu_list: list[str] = []
vid_list: list[str] = []
mhz_list: list[str] = []
ccd_list: list[str] = []
temp_list: list[str] = []
power_list: list[str] = []
cpu_list: list[str] = []
vid_list: list[str] = []
mhz_list: list[str] = []
ccd_list: list[str] = []
temp_list: list[str] = []
power_list: list[str] = []
for reading in data["hwinfo"]["readings"]:
label = reading["labelOriginal"]
for reading in data["hwinfo"]["readings"]:
label = reading["labelOriginal"]
match = re.match(r"(?P<core_ccd>Core[0-9]* \(CCD[0-9]\))|(?P<core_vid>Core [0-9]* VID)|(?P<core_mhz>Core [0-9]* T0 Effective Clock)|(?P<core_power>Core [0-9]* Power)", label)
match = re.match(r"(?P<core_ccd>Core[0-9]* \(CCD[0-9]\))|(?P<core_vid>Core [0-9]* VID)|(?P<core_mhz>Core [0-9]* T0 Effective Clock)|(?P<core_power>Core [0-9]* Power)", label)
if match:
if match.group("core_ccd"):
core_ccd = match.group("core_ccd").split(' ')
core_ccd[0] = core_ccd[0][:4] + ' ' + core_ccd[0][4:]
cpu_list.append(core_ccd[0])
ccd_list.append(core_ccd[1].strip('()'))
temp_list.append(round(reading["value"], 2))
if match:
if match.group("core_ccd"):
core_ccd = match.group("core_ccd").split(' ')
core_ccd[0] = core_ccd[0][:4] + ' ' + core_ccd[0][4:]
cpu_list.append(core_ccd[0])
ccd_list.append(core_ccd[1].strip('()'))
temp_list.append(round(reading["value"], 2))
elif match.group("core_vid"):
vid_list.append(round(reading["value"], 3))
elif match.group("core_vid"):
vid_list.append(round(reading["value"], 3))
elif match.group("core_mhz"):
mhz_list.append(round(reading["value"], 2))
elif match.group("core_mhz"):
mhz_list.append(round(reading["value"], 2))
elif match.group("core_power"):
power_list.append(round(reading["value"], 2))
elif match.group("core_power"):
power_list.append(round(reading["value"], 2))
core_dataframe = pd.DataFrame({
"CCD": ccd_list,
"Clk": mhz_list,
"VID": vid_list,
"Power": power_list,
"Temp": temp_list
}, index=cpu_list)
self.core_dataframe = pd.DataFrame({
"CCD": ccd_list,
"Clk": mhz_list,
"VID": vid_list,
"Power": power_list,
"Temp": temp_list
}, index=cpu_list)
ui.emit("update_core_info_table", core_dataframe.to_dict("index"))
ui.emit("update_core_info_table", self.core_dataframe.to_dict("index"))
self._new_data.set()
else:
self._is_hwinfo_alive = False
except Exception as e:
#print(e)
#logger.info(e)
pass
def collect_data(self, time_to_collect: int):
start_time = time.time()
dataframe_list: list[pd.DataFrame] = []
while time.time() - start_time <= time_to_collect:
self._new_data.wait()
self._new_data.clear()
dataframe_list.append(self.core_dataframe)
return dataframe_list
@property
def is_hwinfo_alive(self):
request = requests.get(self.request_url, timeout=1)
if request.status_code == 200 and len(request.json()) > 0:
return True
return False
return self._is_hwinfo_alive

View File

@ -21,6 +21,7 @@ class OverclockingDict(TypedDict):
class ClientDict(TypedDict):
hostname: str
hwinfo_port: str
ssh_username: str
ryzen_smu_cli_path: str
ycruncher_path: str
bios_map_path: str

View File

@ -3,8 +3,8 @@ import dataclasses
import re
import subprocess
import threading
import av
import av.container
#import av
#import av.container
import cv2
from ipkvm.app import logger, ui
from ipkvm.util.profiles import profile_manager