In octoprint UI there are options for shutdown system, restart system, restart octoprint.
I would love to have these option available in HA.
While this is an old post I recently tackled it and thought I’d share the solution in case you, or others, would find it useful.
First, if you haven’t added the Home Assistant Octoprint integration you will want to do that, instructions are here: OctoPrint - Home Assistant
Next, you need to know your Octoprint API key for Home Assistant, which you can find this from Octopi - Settings - Application Keys - Registered application keys.
With it you should add a single line in your Home Assistant’s secrets.yaml file that looks like this (where the XXXs is your API key):
octoprint_api_key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
I did this with the help of the following add on:
Next, you will want to add the Node Red add on, instructions are here: Home Assistant Community Add-on: Node-RED
Finally, here is my overall solution for what I needed to do - you should be able to use it as a starting point to do whatever you need to do.
Here too is the Octoprint API guide that will show you the format of the API calls: REST API — OctoPrint master documentation and more specifically here is where you see shutdown command (used in the example below): System — OctoPrint master documentation
Of note, in the example below I have my 3d printer, raspberry pi running octoprint, and a lamp all on individual Home Assistant controlled outlets. The magic that you are after is shown in the middle of this screenshot - this is where the REST API call is built and sent from:
Also, the flow is triggered by an MQTT event, but you could trigger it by something else - however that’s not really too relevant to this posting, which is more about the REST API call.
Here is the Node Red exported code for the above:
[{"id":"21ed7e7ed04b34a8","type":"tab","label":"control the 3D Printer","disabled":false,"info":"","env":[]},{"id":"2c3cf3e1965d9efd","type":"mqtt in","z":"21ed7e7ed04b34a8","name":"MQTT Trigger","topic":"Push2Run/3DPrinter","qos":"2","datatype":"auto-detect","broker":"09367f6ed870beea","nl":false,"rap":true,"rh":0,"inputs":0,"x":150,"y":200,"wires":[["af99d047f2fa18d0"]]},{"id":"af99d047f2fa18d0","type":"switch","z":"21ed7e7ed04b34a8","name":"turn on or off?","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"},{"t":"eq","v":"off","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":400,"y":200,"wires":[["9812e0998bed9d10","6d25c934182bd06f"],["59d97afd5ceca11a"]]},{"id":"6ee9e8bc93128351","type":"api-call-service","z":"21ed7e7ed04b34a8","name":"Turn on the Raspberry with Octoprint","server":"fa166dc4.9eb19","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.power_strip_socket_1"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1210,"y":60,"wires":[[]]},{"id":"5612ef2c2aff5ee6","type":"inject","z":"21ed7e7ed04b34a8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"on","payloadType":"str","x":150,"y":80,"wires":[["af99d047f2fa18d0"]]},{"id":"26d0ae6f702f9fd6","type":"inject","z":"21ed7e7ed04b34a8","name":"off","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"off","payloadType":"str","x":150,"y":320,"wires":[["af99d047f2fa18d0"]]},{"id":"7e5d609176af5107","type":"api-current-state","z":"21ed7e7ed04b34a8","name":"Octoprint printing state","server":"fa166dc4.9eb19","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"binary_sensor.octoprint_printing","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":720,"y":340,"wires":[["dc284bf76c38cb25"]]},{"id":"59d97afd5ceca11a","type":"delay","z":"21ed7e7ed04b34a8","name":"required wait to enable Octoprint printing state check","pauseType":"delay","timeout":"10","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":720,"y":240,"wires":[["7e5d609176af5107"]]},{"id":"dc284bf76c38cb25","type":"switch","z":"21ed7e7ed04b34a8","name":"is currently printing?","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"unavailable","vt":"str"},{"t":"eq","v":"off","vt":"str"},{"t":"eq","v":"on","vt":"str"}],"checkall":"true","repair":false,"outputs":3,"x":940,"y":340,"wires":[[],["3c90e17c71a02f00"],["8c7158e27cc0f566"]]},{"id":"8c7158e27cc0f566","type":"delay","z":"21ed7e7ed04b34a8","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"minutes","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":860,"y":460,"wires":[["7e5d609176af5107"]]},{"id":"43fda19f17b13aaa","type":"function","z":"21ed7e7ed04b34a8","name":"set authorization header","func":"msg.headers = {};\nmsg.headers['Authorization'] = \"Bearer \" + msg.payload;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1250,"y":580,"wires":[["a4e38d19b1aaf64f"]]},{"id":"a49152f104e38e83","type":"switch","z":"21ed7e7ed04b34a8","name":"confirm shut worked","property":"payload","propertyType":"msg","rules":[{"t":"empty"},{"t":"nempty"}],"checkall":"true","repair":false,"outputs":2,"x":1240,"y":740,"wires":[["2d05f64b3f8b8984","378fe1925043d3f1","8c049cb077c90d24"],[]]},{"id":"a4e38d19b1aaf64f","type":"http request","z":"21ed7e7ed04b34a8","name":"Send Octoprint shutdown host request","method":"POST","ret":"txt","paytoqs":"body","url":"http://octopi.local/api/system/commands/core/shutdown","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":1250,"y":660,"wires":[["a49152f104e38e83"]]},{"id":"2d05f64b3f8b8984","type":"delay","z":"21ed7e7ed04b34a8","name":"","pauseType":"delay","timeout":"30","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1240,"y":820,"wires":[["f27960336afb0de7"]]},{"id":"378fe1925043d3f1","type":"api-call-service","z":"21ed7e7ed04b34a8","name":"Turn off the 3D printer","server":"fa166dc4.9eb19","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.power_strip_socket_2"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1520,"y":840,"wires":[[]]},{"id":"3c90e17c71a02f00","type":"file in","z":"21ed7e7ed04b34a8","name":"","filename":"/config/secrets.yaml","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1240,"y":340,"wires":[["453354fe2a1b5f08"]]},{"id":"453354fe2a1b5f08","type":"yaml","z":"21ed7e7ed04b34a8","property":"payload","name":"","x":1230,"y":420,"wires":[["a66e36221bb2661d"]]},{"id":"a66e36221bb2661d","type":"function","z":"21ed7e7ed04b34a8","name":"parse out api key","func":"msg.payload = msg.payload.octoprint_api_key;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1250,"y":500,"wires":[["43fda19f17b13aaa"]]},{"id":"9812e0998bed9d10","type":"api-call-service","z":"21ed7e7ed04b34a8","name":"Turn on the 3D printer","server":"fa166dc4.9eb19","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.power_strip_socket_2"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":680,"y":60,"wires":[["65c205d2491d6a89"]]},{"id":"65c205d2491d6a89","type":"delay","z":"21ed7e7ed04b34a8","name":"","pauseType":"delay","timeout":"15","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":960,"y":60,"wires":[["6ee9e8bc93128351"]]},{"id":"f27960336afb0de7","type":"api-call-service","z":"21ed7e7ed04b34a8","name":"Turn off the Raspberry with Octoprint","server":"fa166dc4.9eb19","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.power_strip_socket_1"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1230,"y":920,"wires":[[]]},{"id":"6d25c934182bd06f","type":"api-call-service","z":"21ed7e7ed04b34a8","name":"Turn on the 3D printer lamp","server":"fa166dc4.9eb19","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.3d_printer_lamp"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":700,"y":140,"wires":[["65c205d2491d6a89"]]},{"id":"8c049cb077c90d24","type":"api-call-service","z":"21ed7e7ed04b34a8","name":"Turn off the 3D printer lamp","server":"fa166dc4.9eb19","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.3d_printer_lamp"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1540,"y":920,"wires":[[]]},{"id":"09367f6ed870beea","type":"mqtt-broker","name":"MQTT","broker":"localhost","port":"1883","clientid":"","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""},{"id":"fa166dc4.9eb19","type":"server","name":"Home Assistant","version":4,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30,"areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m"}]
Again, the above requires you to update your secrets.yaml file with your Octoprint API key. Because it is stored in the secrets file, the above is sharable without any tweaking.
Hope this is of help.
Great to see i am not the only one. Great to see the api supports it, also nice to see it is possible in node red, but it would be even greater to see a option like pause or resume to also shutdown.
I don’t want to leave the raspberry pi on all the time only when i am printing (occasionally) so now i am cutting power from with a zigbee powersocket to the printer and pi, but the pi does not like power cuts so would be great to first shut it down and then cut power all from home-assistant.
I might look in to the code and see if i can do a pull request, but that depends on the complexity of the code.
Yes, actually it’s pretty easy, just create a RESTful command:
octopi_api_halt:
url: 'http://octopi/api/system/commands/core/shutdown'
method: POST
headers:
x-api-key: C1F5D3B4CE83BEE469C0BDA26611495A
(Api key to be replaced with a valid one)