Automatisierung mit praktischem Pebble, stabilem Noolite und erschwinglichem esp8266

Seit dem letzten Artikel (der Link ging fast ein Jahr. Und in diesem Jahr habe ich einige Dinge überdacht, das Internet und es hat sich so etwas wie IoT herausgestellt :) → das Internet der Dinge).

Ich werde versuchen, einen neuen Teil des gesammelten Wissens zusammenzufassen, zu beschreiben, wo ich mich bemühe und was ich erreichen möchte → Ich bitte Sie, es zu lesen.

Noolite F v2.0


In der Überschrift habe ich die Worte: Kiesel & Noolith. Gehen wir weiter zu ihnen!
Ich schaffe es immer noch mit Kieselsteinen, meinem Noolithlicht, meiner Garage und meinem Tor. Es wurden bereits viele nützliche Informationen über Noolite geschrieben, die Suche zeigt neue Artikel.

Zusätzlich zu den Einheiten der ersten Generation des Noolite-Systems habe ich neue: ein Netzteil SLF-1-200 (nooLite-F) mit Feedback ( und Verschlüsselung der neuen Generation ).

Bild

Leistungsblock SB-1-150

Bild

und aktualisierter USB-Adapter MTRF-64 USB.

Bild

Das ganze Licht in meinem Haus auf dem Noolithsystem.

Bis vor kurzem hatte ich einen USB-Adapter der ersten Generation für 16 Geräte und jetzt 64 Kanäle (MTRF-64 USB) im „System Home Cramp“ sowie für Geräte der neuen Generation mit Feedback (Noolite F). Die Technologie bewegt sich jedoch in die richtige Richtung und schafft neue, moderne Geräte.

Es gibt zwei wichtige Optionen für neue Geräte: Feedback und das Prinzip der Identifizierung von Geräten anhand von Adressen: ID. Jetzt müssen Sie keine Geräte mehr auf Kanal 1 schreiben und den Kanal steuern. Jetzt können Sie über seine ID auf ein bestimmtes Gerät in einem Kanal zugreifen und ihm einen Ausführungsbefehl senden.

Die Dokumentation für die Blöcke der neuen Generation ist auf der Website des Herstellers verfügbar.

Alles funktioniert über die serielle Schnittstelle mit Python-Code.
# -*- coding: utf-8 -*- #!/usr/bin/env python import serial import time class NooLiteCommand: def __init__(self, ch, cmd, mode=0, ctr=0, res=0, fmt=0, d0=0, d1=0, d2=0, d3=0, id0=0, id1=0, id2=0, id3=0): self.st = 171 self.mode = mode self.ctr = ctr self.res = res self.ch = ch self.cmd = cmd self.fmt = fmt self.d0 = d0 self.d1 = d1 self.d2 = d2 self.d3 = d3 self.id0 = id0 self.id1 = id1 self.id2 = id2 self.id3 = id3 self.sp = 172 @property def crc(self): crc = sum([ self.st, self.mode, self.ctr, self.res, self.ch, self.cmd, self.fmt, self.d0, self.d1, self.d2, self.d3, self.id0, self.id1, self.id2, self.id3, ]) return crc if crc < 256 else divmod(crc, 256)[1] def to_bytes(self): return bytearray([ self.st, self.mode, self.ctr, self.res, self.ch, self.cmd, self.fmt, self.d0, self.d1, self.d2, self.d3, self.id0, self.id1, self.id2, self.id3, self.crc, self.sp ]) class NooliteSerial: def __init__(self, tty_name): self.tty = self._get_tty(tty_name) def on(self, ch): self.send_command(ch, 2, 2, 0) pass def off(self, ch): self.send_command(ch, 0, 2, 0) pass def status(self, ch): m = self.send_command(ch, 128, 2, 0) pass def send_command(self, ch, cmd, mode=0, ctr=0, res=0, fmt=0, d0=0, d1=0, d2=0, d3=0, id0=0, id1=0, id2=0, id3=0): command = NooLiteCommand(ch, cmd, mode, ctr, res, fmt, d0, d1, d2, d3, id0, id1, id2, id3) self.tty.write(command.to_bytes()) while True: bytes_response = list(self.tty.read(117)) if bytes_response: all_responses.append(bytes_response) if bytes_response[3] == 0: break else: break return all_responses @staticmethod def _get_tty(tty_name): serial_port = serial.Serial(tty_name, timeout=0.1) if not serial_port.is_open: serial_port.open() serial_port.flushInput() serial_port.flushOutput() return serial_port noo_serial = NooliteSerial('/dev/ttyUSB0') #ch, cmd, mode, ctr #noo_serial.send_command(1, 15, 2, 0) #    1 #noo_serial.send_command(0, 4, 2, 0) #switch #noo_serial.send_command(0, 2, 2, 0) #turn on #noo_serial.send_command(0, 3, 2, 0) #   #noo_serial.send_command(0, 0, 2, 0) #turn off #noo_serial.send_command(0, 15, 2, 0) #  #noo_serial.send_command(0, 128, 2, 0,0,1) #CMD_Read_State + fmt = 1 #noo_serial.on(0) #noo_serial.status(0) #noo_serial.off(0) #noo_serial.off(0) #noo_serial.status(0) #noo_serial.send_command(ch=0,ctr=8, cmd=4, id0=0,id1=0,id2=48,id3=114) #switch noolite ID 0.0.48.114 


Mit den erforderlichen Funktionen zum richtigen Zeitpunkt können wir Noolithblöcke steuern und den Status von neuen erhalten. Da ich 99% dieser alten Blöcke habe, bleibt es für mich, das alte Schema der Aufzeichnung von 1 Block in 1 Kanal zu verwenden, wobei zu berücksichtigen ist, dass der USB-Adapter sowohl alte als auch neue Blöcke unterstützt (danke an die Entwickler für die Kompatibilität ohne Tamburintanz). Im laufenden Betrieb können Sie den Status neuer und alter Blöcke verwalten und empfangen.

Bis vor kurzem gab es im Haus keinen einzigen Druckknopfschalter. Ich musste Licht in die Garage bringen (ich bin gerade dort angekommen, um die Dinge in Ordnung zu bringen: D), und auch ein Schalter erschien in der Hintergrundbeleuchtung des Kosmetikspiegels. Da ich weiß, dass es ein SB-1-150-Netzteil gibt , habe ich den normalen Schalter eingestellt und das Gerät angeschlossen. Die Hintergrundbeleuchtung des Spiegels bestand aus einer weißen Platte, 3-W-Glühbirnen 4000 K und weißem Licht. SB-1-150 ist insofern einzigartig, als es im Kontext des vorhandenen Stromkreises und durch Anschließen eines Druckschalters an das Gerät selbst in der Box des Wandschalters (Schalters) platziert werden kann.

Genau das, was meine Mädchen zum Schminken brauchen :)
Bild

Kiesel


Als ich anfing, mich mit Automatisierung zu beschäftigen, war einer der Hauptfaktoren: kompetentes und bequemes Management.

Es scheint bequem zu sein, von einem Smartphone aus zu steuern, aber ... und es ist nicht bequem, die Anwendung jedes Mal zu laden, wenn kleine unbequeme Tasten, Werbung für Linkshänder oder bis zum Drücken der Taste ... alle Wünsche verschwinden. Die Sprachsteuerung verschwindet, da sie auch unpraktisch und seltsam ist :) - lassen Sie sie in den Handlungen von Science-Fiction-Filmen bleiben.

Bild

Und ich habe das Problem auf andere Weise gelöst - durch eine Armbanduhr, die STÄNDIG bei mir Platz beansprucht und alle Annehmlichkeiten, Mobilität und Geschwindigkeit der Kontrolle vereint. Im Allgemeinen - Pebble lebt! Das Wichtigste ist jedoch, dass Sie für die Uhr weiterhin Anwendungen schreiben können - Ihre eigenen Anwendungen für die Verwaltung Ihrer Automatisierungssysteme. Es ist eigentlich eine Bombe.

Pebble lebt!

Die Tragödie der Schließung des Unternehmens pebble.com (Fitbit kaufte alle pebble.com für Patente) hatte keinen Einfluss auf deren Leistung und Leistung. Vor kurzem gab es ein Update von ios, android - die Uhr wurde von den Pebble Cloud-Diensten (im Falle der Beendigung des Supports) und der Autorisierung getrennt.

Optisch hat sich nichts geändert, aber der Service bleibt : cloudpebble.net - WTF? Dies ist eine sehr nützliche Sache. Wenn Sie Code in JS schreiben können (und nicht viel Zeit mit C ++ verbringen möchten) - bitte willkommen an Bord :) - Mit Cloud Pebble können Sie die Anwendung schnell "werfen". Nun, so habe ich es gemacht. Natürlich sollte die Leistung von JS nicht mit C ++ verglichen werden (dies ist heilig), sondern festgefahren sein. ja!

Pebble Cloud JS-Code für die Arbeit mit API
 var UI = require('ui'); var ajax = require('ajax'); var noolite = [ ['','http://your-home-server-ip-address:1183/mqtt/gate/slidegate', 'images/gate.png'], ['','http://your-home-server-ip-address:1183/mqtt/gate/garage', 'images/door.png'], ['!','http://your-home-server-ip-address:1183/noolite/switch/103', 'images/light.png'], [' ','http://your-home-server-ip-address:1183/noolite/switch/100', 'images/system2.png'], ['1  ','', 'images/light.png'], ['2  ','', 'images/light.png'], [' 1','http://your-home-server-ip-address:1183/noolite/switch/101', 'images/light.png'], [' 2','http://your-home-server-ip-address:1183/noolite/switch/102', 'images/light.png'], ['','', 'images/water.png'], ['','http://your-home-server-ip-address:1183/admin/system/1', 'images/system1.png'], ]; var water = [ [' ','http://your-home-server-ip-address:1183/admin/poliv/1', 'images/water.png'], [' ','http://your-home-server-ip-address:1183/admin/poliv/2', 'images/water.png'], [' 1 ','http://your-home-server-ip-address:1183/noolite/switch/20', 'images/water.png'], [' 2 ','http://your-home-server-ip-address:1183/noolite/switch/21', 'images/water.png'], [' 3 ','http://your-home-server-ip-address:1183/noolite/switch/22', 'images/water.png'], [' 4 ','http://your-home-server-ip-address:1183/noolite/switch/23', 'images/water.png'], [' 5 ','http://your-home-server-ip-address:1183/admin/poliv/switch/5', 'images/water.png'], [' 6 ','http://your-home-server-ip-address:1183/admin/poliv/switch/6', 'images/water.png'], [' 7 ','http://your-home-server-ip-address:1183/admin/poliv/switch/7', 'images/water.png'], [' 8 ','http://your-home-server-ip-address:1183/admin/poliv/switch/8', 'images/water.png'], [' 9 ','http://your-home-server-ip-address:1183/admin/poliv/switch/9', 'images/water.png'], ]; var light1 = [ [' ','http://your-home-server-ip-address:1183/noolite/switch/6', 'images/light.png'], [' ','http://your-home-server-ip-address:1183/noolite/switch/0', 'images/light.png'], ['  ','http://your-home-server-ip-address:1183/noolite/switch/1', 'images/light.png'], ['  ','http://your-home-server-ip-address:1183/noolite/switch/7', 'images/light.png'], ['  ','http://your-home-server-ip-address:1183/noolite/switch/8', 'images/light.png'], [' 1 ','http://your-home-server-ip-address:1183/noolite/switch/2', 'images/light.png'], [' 1 ','http://your-home-server-ip-address:1183/noolite/switch/3', 'images/light.png'], [' 1 ','http://your-home-server-ip-address:1183/noolite/switch/4', 'images/light.png'], [' ','http://your-home-server-ip-address:1183/noolite/switch/5', 'images/light.png'], [' ','http://your-home-server-ip-address:1183/noolite/switch/9', 'images/light.png'], ]; var light2 = [ [' ','http://your-home-server-ip-address:1183/noolite/switch/15', 'images/light.png'], [' ','http://your-home-server-ip-address:1183/noolite/switch/16', 'images/light.png'], [' 2 ','http://your-home-server-ip-address:1183/noolite/switch/10', 'images/light.png'], [' 2 ','http://your-home-server-ip-address:1183/noolite/switch/11', 'images/light.png'], [' 2 ','http://your-home-server-ip-address:1183/noolite/switch/12', 'images/light.png'], [' ','http://your-home-server-ip-address:1183/noolite/switch/13', 'images/light.png'], ['  ','http://your-home-server-ip-address:1183/noolite/switch/14', 'images/light.png'], ]; var menu = new UI.Menu({ sections: [{ items: [{ title: '', subtitle: '' }] }] }); var menu1 = new UI.Menu({ sections: [{ items: [{ title: '', subtitle: '' }] }] }); var menu2 = new UI.Menu({ sections: [{ items: [{ title: '', subtitle: '' }] }] }); var menu3 = new UI.Menu({ sections: [{ items: [{ title: '', subtitle: '' }] }] }); var items = []; for (var i=0; i<noolite.length; i++) { items[i] = { title: noolite[i][0], subtitle: '', icon: noolite[i][2] }; } var items1 = []; for (var i=0; i<light1.length; i++) { items1[i] = { title: light1[i][0], subtitle: '', icon: light1[i][2] }; } var items2 = []; for (var i=0; i<light2.length; i++) { items2[i] = { title: light2[i][0], subtitle: '', icon: light2[i][2] }; } var items3 = []; for (var i=0; i<water.length; i++) { items3[i] = { title: water[i][0], subtitle: '', icon: water[i][2] }; } menu.items(0, items); menu1.items(0, items1); menu2.items(0, items2); menu3.items(0, items3); menu.show(); menu.on('select', function(e) { if (e.itemIndex == 4) { menu1.show(); } else if (e.itemIndex == 5) { menu2.show(); } else if (e.itemIndex ==8) { menu3.show(); } else { var url = noolite[e.itemIndex][1]; console.log(url); ajax({ url: url, method: 'get' }, function(data) { console.log('switched OK'); }, function(error) { // Failure! console.log('error'); } ); } }); menu1.on('select', function(e) { var url = light1[e.itemIndex][1]; console.log(url); ajax({ url: url, method: 'get' }, function(data) { console.log('switched OK'); }, function(error) { // Failure! console.log('error'); } ); }); menu2.on('select', function(e) { var url = light2[e.itemIndex][1]; console.log(url); ajax({ url: url, method: 'get' }, function(data) { console.log('switched OK'); }, function(error) { // Failure! console.log('error'); } ); }); menu3.on('select', function(e) { var url = water[e.itemIndex][1]; ajax({ url: url, method: 'get' }, function(data) { console.log('switched OK'); }, function(error) { // Failure! console.log('error'); } ); }); 


Der Code wird geschrieben, direkt auf der Cloud-Pebble-Website kompiliert und kann über das Telefon, das Herunterladen der kompilierten Anwendung, in Sekundenschnelle auf der Uhr installiert werden. Alles ist so einfach, dass jeder junge Automatisierungstechniker damit umgehen kann;)

Es ist schade ... es ist schade, dass Pebble aufgehört hat zu existieren und im Moment sehe ich keine Alternative. Pebble Time wird immer in unseren Herzen sein!

MQTT


Letztes Jahr traf ich ein so wunderbares Protokoll wie MQTT (History: Die erste Version des Protokolls wurde 1999 von Dr. Andy Stanford-Clark (IBM) und Arlene Nipper (Arcom) entwickelt und unter einer lizenzgebührenfreien Lizenz veröffentlicht. Die MQTT 3.1.1-Spezifikation war 2014 vom OASIS-Konsortium standardisiert. Link ).

Es gibt viele Informationen darüber, wie das Protokoll funktioniert und welche Clients es sind ... und ich war sehr enttäuscht, dass es keine echten Clients für mobile Anwendungen gibt, nur für Android.

Zu verstehen, dass das Fehlen einer guten mobilen Anwendung ein sehr großes Problem (Loch) im Bereich IoT ist (viele Leute sagen, aber sie tun sehr wenig ...) - Ich und mein Team haben bei der Arbeit beschlossen, einen Client für Android, iOS, WP zu erstellen damit es alle Kriterien erfüllt und bequem ist. Ich werde etwas später über den Client schreiben und darüber, wie wir uns mit ESP8266 + MTRF64 (Noolite) angefreundet und die Nodemcu-Firmware vorbereitet haben. Es wird großartig, bequem, billig und schön sein! Folgen Sie den Anwendungsnachrichten hier .

Bild

Jetzt können Sie die Noolite-Beleuchtung ohne Heimserver und USB-Adapter für 50-100 US-Dollar steuern!

Allgemeines Schema der Hausautomation


Das folgende Schema existiert noch:

Videoüberwachung: xeoma Videoüberwachung [IP-Kamera]
Server auf der Systemeinheit: Nginx + Gunicorn + Python + MQTT Broker
Verwaltung: Pebble Watch + MQTT-Client
Steuermodule (Systemknoten): ESP8266 + Optokoppler \ ds18b20, dht11 Sensoren [22]

Aufgrund der Tatsache, dass ich im MQTT-Protokoll viele Annehmlichkeiten gesehen habe, angefangen von der Abonnementarchitektur und der sofortigen Kommunikation mit End-IoT-Geräten bis hin zur Tatsache, dass MQTT-Nachrichten über den Router fliegen können, ohne dort Ports weiterzuleiten und mit einem Tamburin zu tanzen. Bequem! Viel Spaß! Inbrünstig :)

All dies führte mich dazu, das System zu dezentralisieren, dh einen „Home Korchvagen“ zu vermeiden, zu vielen sogenannten Knoten zu wechseln und einen Cloud-MQTT-Broker zu verwenden (es gibt kostenlose MQTT-Broker, zum Beispiel: mqtt.ximxim.com (auf der Website anmelden und für den Zugriff weitergeben) )) - da esp8266 alle Probleme löst und es wiederum über WLAN mit dem MQTT-Protokoll funktioniert.

Angesichts der Tatsache, dass MQTT Buddy einen Skriptservice bereitstellt, werde ich nicht daran denken, Home-Skripte zu schreiben. Ich werde sie nur in einer Cloud-Lösung erstellen. Dies wird ein echtes IoT sein und es wird funktionieren! Von Worten zu Taten!

ESP8266


Als ich dieses Entwicklungsboard kennenlernte, war ich sofort beeindruckt von der Tatsache, dass das Board klein ist und die LUA-Programmiersprache auf der Nodemcu-Firmware unterstützt wird. Was Sie brauchen + MQTT-Modul ist. In der Automatisierung bilden einfache und zuverlässige Lösungen die Grundlage. Mit Kosten von 2 bis 5 US-Dollar gegen eine Gebühr (für das fünfte Modell sofort mit einem USB-Adapter an Bord) können Sie Subsysteme schnell bereitstellen.

WiFi-Verbindung ist schnell, viele Möglichkeiten. Zum Beispiel: Tor / Garage \ Bewässerung \ Lichtsteuerung. Ich habe 30% der Rasenbewässerung mit dem Noolite-System (Trockenkontaktblöcke) betrieben, die restlichen 70% des esp8266-Entwicklungsboards werden über die LUA-Sprache mithilfe des MQTT-Protokolls gesteuert.

Beispiel für einen LUA-Code für esp8266, Abrufen von IP und Aufrufen der Arbeitsdatei mit MQTT
 --load credentials dofile("credentials.lua") function init(name, pass) wifi.setmode(wifi.STATION) wifi.sta.config(name, pass) wifi.sta.connect() tmr.alarm(0, 1000, 1, function() if wifi.sta.getip()== nil then print("IP unavaiable, Waiting...") else tmr.stop(0) print("Config done, IP is "..wifi.sta.getip()) print("mac : "..wifi.sta.getmac()) dofile("mqtt.lua") end end) end print("START!") init(SSID,PASSWORD) 


- mqtt.lua Datei

 local door = 7 -- gpio13 local window = 6 -- gpio12 local cooler = 5 --gpio14 local led = 4 --GPIO2 board led! LOW == turn ON local light1 = 8 --gpio 15 local light2 = 1 --gpio 5 local light3 = 2 -- gpio 4 function register_myself() m:subscribe("mqtt_buddy/#",0,function(conn) print ("subscribed to Xim mqtt.ximxim.com server") end) end m = mqtt.Client("MQTT_BUDDY_SHOW_ROOM", 120, MQTT_USER, MQTT_PASS) m:on("connect", function(client) print ("connected to Xim mqtt.ximxim.com server") end) m:on("offline", function(client) reconnect_mqtt() end) m:on("message", function(client, topic, data) --print(topic.." data:"..data) if topic == "mqtt_buddy/window" and data == "1" then print "open-close window..." gpio.write(window, gpio.HIGH) gpio.write(led, gpio.LOW) tmr.alarm(1, 1000, tmr.ALARM_SINGLE, function() gpio.write(window, gpio.LOW) gpio.write(led, gpio.HIGH) print "command to close\open window is sent!" end) elseif topic == "mqtt_buddy/door" and data == "1" then print "open-close door..." gpio.write(door, gpio.HIGH) gpio.write(led, gpio.LOW) tmr.alarm(2, 1000, tmr.ALARM_SINGLE, function() gpio.write(door, gpio.LOW) gpio.write(led, gpio.HIGH) print "command to close\open door is sent!" end) elseif topic == "mqtt_buddy/cooler" then if data == "1" then print "switch on fan..." gpio.write(cooler, gpio.HIGH) gpio.write(led, gpio.LOW) else print "switch off fan..." gpio.write(cooler, gpio.LOW) gpio.write(led, gpio.HIGH) end elseif topic == "mqtt_buddy/light1" then if data == "1" then print "switch light1 ON..." gpio.write(light1, gpio.HIGH) gpio.write(led, gpio.LOW) else print "switch light1 off..." gpio.write(light1, gpio.LOW) gpio.write(led, gpio.HIGH) end elseif topic == "mqtt_buddy/light2" then if data == "1" then print "switch light2 ON..." gpio.write(light2, gpio.HIGH) gpio.write(led, gpio.LOW) else print "switch light2 off..." gpio.write(light2, gpio.LOW) gpio.write(led, gpio.HIGH) end elseif topic == "mqtt_buddy/light3" then if data == "1" then print "switch light3 ON..." gpio.write(light3, gpio.HIGH) gpio.write(led, gpio.LOW) else print "switch light3 off..." gpio.write(light3, gpio.LOW) gpio.write(led, gpio.HIGH) end end end) m:connect(MQTT_SERVER, MQTT_SERVER_PORT, 0, function(conn) register_myself() end) 


Das Problem


Ich wandte mich an eine große Gemeinschaft denkender Menschen und wollte ein äußerst wichtiges Thema ansprechen, oder vielmehr das Problem, das ich lösen möchte, aber es bleibt nicht genügend Zeit für eingehendere Forschung / Kenntnisse.

Fazit: Bei der Dezentralisierung bleibt die Videoüberwachung bestehen, für die auf die eine oder andere Weise ein Host-Computer erforderlich ist, um Quellbilder (mindestens) auf einen Videoüberwachungsserver (z. B. ivideon) zu übertragen oder sogar Videos auf einem Heimcomputer wie xeoma zu verarbeiten (obwohl sie auch eine Cloud haben). Auf die eine oder andere Weise müssen Sie Videostreams, Bilder für die endgültige Rechenleistung (Cloud-Lösungen) „weiterleiten“ - oder umgekehrt -, um das Streaming zu vereinfachen.

Es wird darüber nachgedacht, Quellbilder von der Kamera abzurufen (es gibt auch hier ein Problem, nicht jede Kamera hat eine URL zum Empfangen eines Bildes von der Kamera und es ist im Allgemeinen unklar, wie andere diese URL erkennen ...) und an den MQTT-Kanal weiterzuleiten, auf dem Binärdaten unterstützt werden (das Es gibt ein Bild, das leicht über das mqtt-Protokoll in binärer Form übertragen werden kann.

Vielleicht hat schon jemand versucht solche Dinge zu implementieren = ESP8266 + IP Web Cam?
Antworte bitte (bogdanovich.alex [@] gmail.com). Ich werde sehr dankbar sein!

Bei der Implementierung von Probros verschwindet die Frage nach dem Heimserver. Warum? Weil er Strom isst und meinen Ofen heizt :)

Bild

Alles ein positiver Tag und gute Laune!

Source: https://habr.com/ru/post/de403273/


All Articles