Power Control/Switching
Hi,
Using the TinyPilot but wanted some power control for one of my servers (it doesnt have IPMI unfortunately, its a consumer motherboard) so I thought I would have a dabble and I didnt really want to go all out and start wiring up relays to GPIOs etc so I went with what I had laying around and went wireless:
Server plugged into a TP-Link HS110 (you could use a HS100 or other similar wifi power switch)
https://www.tp-link.com/au/home-networking/smart-plug/hs110/
And a little python magic to switch it off and on based on this repo:
https://github.com/ajay10000/TP-Link-HS110
Maybe it might be of interest to someone someday, so I thought I would post it here
Jeremy
Linked from:
- @fft2021-12-29 04:48:41.919Z
Hi,
I use the shelly plugs https://shop.shelly.cloud/shelly-plug-s-wifi-smart-home-automation#62 instead of the tp-link ones. It takes less space in a german (european) wall socket. The user interface is really easy and they provide a rest api: https://shelly-api-docs.shelly.cloud/gen1/#shelly-plug-plugs-relay-0 they also have US plugs. So a simply curl call does in my home office all my needed magic on a fingertips.
I am not related to shelly in any way, just a happy client, and I liked the idea you had remotely switching on/off a machine.
Jürgen - In reply tojezzab⬆:Michael Lynch @michael2021-12-29 17:38:00.710Z
That's really cool, @jezzab. Thanks for sharing this!
How difficult was it to code this up? I'm interested in making it easier for users to extend TinyPilot's functionality, so any feedback about your experience modifying the code would be helpful.
- JIn reply tojezzab⬆:Jeremy Beall @jezzab
There is probably an easier way to do it but this is the path I took. Hardest part was working out how everything ties together and because I wanted a dialog box with options.
It would be nice to even just have a menu option:Run External Script
or something like thatI created two new PHP files that would call the scripts with different parameters (you could no doubt just do it with one file as well if you just wanted to call a single script and bypass the dialog box all together):
/opt/tinypilot/app/static/rempowoff.php:
<?php echo exec('python3 /opt/tinypilot/app/hs110.py -c off'); $loc = "http://" . $_SERVER['SERVER_ADDR']; echo "<script>window.location.href = '$loc';</script>" ?>
/opt/tinypilot/app/static/rempowon.php:
<?php echo exec('python3 /opt/tinypilot/app/hs110.py -c on'); $loc = "http://" . $_SERVER['SERVER_ADDR']; echo "<script>window.location.href = '$loc';</script>" ?>
Created a new dialog box which I just based on the TinyPilot control one:
/opt/tinypilot/app/templates/custom-elements/rem-power-dialog.html:
<template id="rem-power-dialog-template"> <style> @import "css/style.css"; @import "css/button.css"; #prompt, #restarting, #shutting-down, #shutdown-complete { display: none; } :host([state="prompt"]) #prompt { display: block; } </style> <div id="rem-power-confirmation-panel" class="overlay"> <div> <h3>Control Power on Remote Device?</h3> <p> Note that this will power up or down <strong>The Remote Device</strong>, not the Tiny Pilot Pi to which it is attached. </p> <a href = "rempowon.php"> <button id="rem-power-on" class="btn-danger" type="button"> Power On </button></a> <a href = "rempowoff.php"> <button id="rem-power-off" class="btn-danger" type="button"> Power Off </button></a> <button id="cancel-rem-power" type="button">Cancel</button> </div> </div> </template> <script type="module"> import { DialogClosedEvent, DialogFailedEvent } from "/js/events.js"; import { shutdown } from "/js/controllers.js"; (function () { const template = document.querySelector("#rem-power-dialog-template"); customElements.define( "rem-power-dialog", class extends HTMLElement { constructor() { super(); } connectedCallback() { this.attachShadow({ mode: "open" }).appendChild( template.content.cloneNode(true) ); this.state = "prompt"; this.shadowRoot .getElementById("cancel-rem-power") .addEventListener("click", () => { this.dispatchEvent(new DialogClosedEvent()); }); } get state() { return this.getAttribute("state"); } set state(newValue) { this.setAttribute("state", newValue); } } ); })(); </script>
Then edited the menu bar for another option and to call the dialog box by adding another
rem-power-btn
"button" and item:
/opt/tinypilot/app/templates/custom-elements/menu-bar.html:
Here after theKeyboard Shortcuts
button:... <a>Keyboard Shortcuts</a> <ul class="items"> <li class="item"> <a id="ctrl-alt-del-btn">Ctrl + Alt + Del</a> </li> </ul> </li> <li class="item"> <a id="rem-power-btn">Remote Power Control</a> </li> </ul> </li> ...
And here after the
ctrl-alt-del-btn
request:... "ctrl-alt-del-btn": "ctrl-alt-del-requested", "rem-power-btn": "rem-power-dialog-requested" }; ...
Then added the
rem-power-dialog
overlay to the main index file after the shutdown overlay:
/opt/tinypilot/app/templates/index.html:
... <overlay-panel id="shutdown-overlay"> <shutdown-dialog id="shutdown-dialog"></shutdown-dialog> </overlay-panel> <overlay-panel id="rem-power-overlay"> <rem-power-dialog id="rem-power-dialog"></rem-power-dialog> </overlay-panel> ...
And lastly I had to edit the main app Javascript file to add another event listener after the
shutdown-dialog-requested
one:
/opt/tinypilot/app/static/js/app.js:
menuBar.addEventListener("shutdown-dialog-requested", () => { document.getElementById("shutdown-overlay").show(); }); menuBar.addEventListener("rem-power-dialog-requested", () => { document.getElementById("rem-power-overlay").show(); });
- Michael Lynch @michael2021-12-30 18:28:44.494Z
Cool, thanks for sharing!
You could simplify a bit by dropping PHP from the mix. The backend is Python and your
hs110.py
script is Python, so you should be able to add a route to api.py and then just imporths110
as a module instead of shelling out to its CLI.- JJeremy Beall @jezzab
Ok cool. I'll look into it
- EIn reply tojezzab⬆:@ezekielnewren
There is an expansion board with 4 relay switches for the raspberry pi. I think it would be great to have a tiny pilot version that had this expansion board built in. In fact you can stack up to 4 of these board to control 16 relay switches. This is the solution that I'm going with.
- Diego @diego
Hello @ezekielnewren - Thank you for you feedback, very much appreciated! I understand this would be an amazing feature but unfortunately, this has not been requested by many users, and there are no plans to incorporate extra hardware into the TinyPilot Voyager 2 line, at least not in the near future. It is worthwile noting however, that TinyPilot supports Wake On Lan.
- Progress