This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
public:it:homeassistant [2021/10/10 16:52] – phil | public:it:homeassistant [Unknown date] (current) – removed - external edit (Unknown date) 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Home Assistant ====== | ||
- | Self hosted server that allows you to control many different types of IOT devices. | ||
- | |||
- | [[https:// | ||
- | |||
- | ===== HestiaPi ===== | ||
- | Open source thermostat. | ||
- | |||
- | https:// | ||
- | |||
- | =====Espurna===== | ||
- | https:// | ||
- | |||
- | ===== Tasmota ====== | ||
- | Integration with Home Assistant [[https:// | ||
- | |||
- | * [[https:// | ||
- | * [[ https:// | ||
- | * [[https:// | ||
- | |||
- | |||
- | ==== Sonoff S31 Commands ==== | ||
- | * [[https:// | ||
- | |||
- | < | ||
- | $ curl -s http:// | ||
- | { | ||
- | " | ||
- | } | ||
- | </ | ||
- | < | ||
- | $ curl -s http:// | ||
- | { | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | ], | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | 0, | ||
- | 0, | ||
- | 0, | ||
- | 0, | ||
- | 0, | ||
- | 0, | ||
- | 0, | ||
- | 0 | ||
- | ], | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | } | ||
- | } | ||
- | </ | ||
- | < | ||
- | $ curl -s http:// | ||
- | {" | ||
- | </ | ||
- | < | ||
- | $ curl -s http:// | ||
- | {" | ||
- | </ | ||
- | < | ||
- | $ curl -s http:// | ||
- | {" | ||
- | </ | ||
- | < | ||
- | $ curl -s http:// | ||
- | { | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | ], | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | 0, | ||
- | 0, | ||
- | 0, | ||
- | 0, | ||
- | 0, | ||
- | 0, | ||
- | 0, | ||
- | 0 | ||
- | ], | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | }, | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | }, | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | }, | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | "" | ||
- | ], | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | ] | ||
- | }, | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | ], | ||
- | " | ||
- | " | ||
- | }, | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | }, | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | }, | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | }, | ||
- | " | ||
- | " | ||
- | 0, | ||
- | 0, | ||
- | 0 | ||
- | ], | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | }, | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | } | ||
- | }, | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | } | ||
- | } | ||
- | } | ||
- | </ | ||
- | < | ||
- | $ curl -s http:// | ||
- | { | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | } | ||
- | } | ||
- | } | ||
- | </ | ||
- | |||
- | |||
- | Just in case I'm saving this. | ||
- | < | ||
- | import requests | ||
- | import json | ||
- | |||
- | class s31powerplug: | ||
- | |||
- | def __init__(self, | ||
- | self.target = target | ||
- | |||
- | def cmd(self, cmd): | ||
- | r = requests.get(' | ||
- | if r.status_code == 200: | ||
- | return r.json() | ||
- | else: | ||
- | return False | ||
- | |||
- | |||
- | def energy(self): | ||
- | r = self.cmd(' | ||
- | return r[' | ||
- | |||
- | |||
- | def network(self): | ||
- | r = self.cmd(' | ||
- | return r[' | ||
- | |||
- | |||
- | def power(self, toggle=None): | ||
- | if toggle is None: | ||
- | return self.cmd(' | ||
- | |||
- | elif toggle: | ||
- | return self.cmd(' | ||
- | |||
- | else: | ||
- | return self.cmd(' | ||
- | |||
- | </ | ||
- | |||
- | ===== MQTT ===== | ||
- | |||
- | ==== Notes from Tom ==== | ||
- | if you enable websocket interface on mosquitto, you can also talk to it from a browser using javascript, which is kinda handy. | ||
- | (basically it just encapsulates the normal MQTT protocol inside a websocket connection so that it can be used directly in a browser -- it's handy for things like dashboards that update in real-time) | ||
- | |||
- | |||
- | I've just used curl with the API so far | ||
- | (from shell scripts) | ||
- | well, plus the MQTT interface via. a python library | ||
- | this one -> https:// | ||
- | |||
- | |||
- | |||
- | that's an example of a simple MQTT frontend -- I kinda cheated by doing some server-side stuff in PHP, so I provided both the PHP source as well as the final HTML it generates | ||
- | I wrote that back in 2016, but I think it should still work with modern servers/ | ||
- | lol some of this code is kinda gross, but at least it gives you the general idea | ||
- | |||
- | === relay_control.html === | ||
- | < | ||
- | < | ||
- | < | ||
- | < | ||
- | < | ||
- | <link rel=" | ||
- | <meta name=" | ||
- | <style type=" | ||
- | </ | ||
- | < | ||
- | <script src=" | ||
- | <script type=" | ||
- | mqtt_topic = " | ||
- | |||
- | function mqtt_connect() { | ||
- | console.log(" | ||
- | client = new Paho.MQTT.Client(' | ||
- | client.onConnectionLost = on_mqtt_connection_lost; | ||
- | client.onMessageArrived = on_mqtt_message; | ||
- | client.connect({onSuccess: | ||
- | } | ||
- | |||
- | mqtt_connect(); | ||
- | |||
- | function on_mqtt_connect() { | ||
- | console.log(" | ||
- | client.subscribe(mqtt_topic + "/#" | ||
- | }; | ||
- | function on_mqtt_connection_lost(response) { | ||
- | if (response.errorCode !== 0) { | ||
- | console.log(" | ||
- | } | ||
- | update_online(false); | ||
- | console.log(" | ||
- | mqtt_connect(); | ||
- | }; | ||
- | function on_mqtt_message(msg) { | ||
- | console.log(" | ||
- | if (msg.destinationName.indexOf(mqtt_topic) == 0) { | ||
- | var short_topic = msg.destinationName.substr(mqtt_topic.length + 1); | ||
- | if (short_topic == " | ||
- | switch (msg.payloadString) { | ||
- | case " | ||
- | update_online(true); | ||
- | break; | ||
- | case " | ||
- | update_online(false); | ||
- | break; | ||
- | default: | ||
- | console.log(" | ||
- | } | ||
- | } else { | ||
- | var element = document.getElementById(short_topic); | ||
- | if (element) { | ||
- | update_element(short_topic, | ||
- | } else { | ||
- | console.log(" | ||
- | } | ||
- | } | ||
- | } else { | ||
- | console.log(" | ||
- | } | ||
- | // | ||
- | }; | ||
- | function send_mqtt(device, | ||
- | if (document.getElementById(" | ||
- | if (state == " | ||
- | return; | ||
- | } | ||
- | if (state == " | ||
- | return; | ||
- | } | ||
- | console.log(" | ||
- | var msg = new Paho.MQTT.Message(String(state)); | ||
- | msg.destinationName = mqtt_topic + "/" | ||
- | msg.qos = 1; | ||
- | msg.retained = true; | ||
- | client.send(msg); | ||
- | } else { | ||
- | console.log(" | ||
- | } | ||
- | }; | ||
- | function update_online(is_online) { | ||
- | if (is_online) { | ||
- | console.log(" | ||
- | document.getElementById(" | ||
- | } else { | ||
- | console.log(" | ||
- | document.getElementById(" | ||
- | } | ||
- | }; | ||
- | function update_element(device, | ||
- | console.log(" | ||
- | switch (status) { | ||
- | case " | ||
- | element.className = " | ||
- | break; | ||
- | case " | ||
- | element.className = " | ||
- | break; | ||
- | case " | ||
- | case " | ||
- | element.className = " | ||
- | break; | ||
- | default: | ||
- | element.className = ""; | ||
- | } | ||
- | }; | ||
- | function toggle_device(device) { | ||
- | state = document.getElementById(device).className; | ||
- | switch (state) { | ||
- | case " | ||
- | return send_mqtt(device, | ||
- | case " | ||
- | return send_mqtt(device, | ||
- | default: | ||
- | console.log(" | ||
- | } | ||
- | } | ||
- | </ | ||
- | < | ||
- | <div id=" | ||
- | <div class=" |