Decloudifying the pusherApp based Melnor Wifi Aquatimer

Watering your garden

Zu Hause habe ich den regelmässigen Bedarf, im Sommer meinen Rasen und meine Beete zu bewässern. Beides macht sich am besten früh am morgen bevor die Sonne aufgeht und um Mehltau zu vermeiden habe ich das Abends giessen mittlerweile ausgeschlossen, aber früh am morgen schlafe ich meist noch …

Zwei Sommer hab ich das nun von Hand gemacht, aber letztes Jahr kam wiederholt der Gedanke, es einfach mit einem simplen Magnetventil und einem ESP8266 an mein OpenHAB2 System anzubinden und steuerbar zu machen.

Da ich nun schon mehrere solcher Eigenbauprojekte hinter mir hatte und Aufwand kombiniert mit einem halbgaren Stück Technik an der Wand scheute, habe ich auch nach günstigen “professionellen” Alternativen auf Amazon geschaut.
Preislich interessant war für mich dabei der Melnor WiFi AQUATIMER mit vier Ventilen, preislich recht erträglich und auf den ersten Blick ganz solide gebaut.

Meine Hoffnung war auch, dass in dem System irgend ein “hackbarer” Chip in der Art eines ESP8266 stecken würde und ich evtl. per Serial da dran käme. Ich bin dann aber bei der Recherche schnell auf zwei Projekte gestossen

https://hackaday.io/project/159915-hacking-the-melnor-53280-into-an-iot-timer sowie
https://hackaday.io/project/160193-raincloud-de-cloudifier

Zweiteres war genau das was ich suchte, eine “möglichst” einfach Art, ein Wifi gesteuertes Gerät lokal zu betreiben. 18 Monate später (!!) sollte der Prototyp fertig sein 😉

Dank der Vorarbeit von Jean-Philippe waren die ersten einfachen Schritte klar, nämlich mit Hilfe von Wireshark

  • [x] das propertiäre base64 encodierte Protokoll besser verstehen
  • [x] das System was aussen herum gezimmert wurde verstehen (es ist eine Anbindung an das PusherApp Portal)

sobald das klar war, müsste dann “nur” schnell

  • [x] ein DNS Spoofer
  • [x] ein REST Server
  • [x] ein Cloud Simulator für den PusherApp Mechanismus

gebaut werden um dann abschliessend

  • [ ] einen OpenHab2 Konnektor
  • [ ] schönen Code auf GitHub
  • [ ] einen Blog Eintrag und Doku

zu releasen. Die ersten Schritte waren schnell gemacht (s.u.) aber einen funktionalen Code hatte ich am Ende des Sommers leider immer noch nicht. Dann kam der Winter und das Gerät wurde erstmal eingemottet.
Im Frühjahr kamen eine Anfrage eines Interessierten Lesers und die Corona-Krise zusammen und ich beschloss vor dem Sommer das Projekt soweit abzuschliessen, dass ich mich nicht mehr auf
die krautige Cloud von Melnor verlassen müsste, denn auch wenn sie funktioniert hat, die Optik erinnerte an das letzte Jahrtausend und das ganze System (sprich meine Wasserhahn) hing von unverschlüsseltem HTTP und WS ab (Yuck!).

Zwei weitere Nächte Arbeit und das System war endlich lokal via REST API schaltbar!

Die Grundidee

Wie unter https://hackaday.io/project/160193-raincloud-de-cloudifier beschrieben, handelt es sich beim Melnor um zwei Teile, das 4-fach Magnetventil sowie eine WLAN Brücke die remote mit diesem Ventil spricht und selber die Cloudanbindung macht.
Die WLAN Brücke kommuniziert mit dem Ventil via 900 Mhz RF und basiert selbst auf einem Texas Instrument CC3100MOD Base Board und wurde, wie der Rest vom Produkt sehr lieblos mit einem minimal-effort Code bestückt (effektiv befindet sich die SimpleLink App vom Hersteller mit 2 Modifikationen darauf).

  • Melnor (W)LAN Bridge wird durch Sniffing untersucht (siehe Funktionsweise)
  • Gerät wird umkonfiguriert, so dass wir sein DNS Server werden
  • DNS Requests gegen ws.pusherapp.com und wifiaquatimer.com werden von uns beantwortet und entsprechen unserer IP
  • wir nehmen alle HTTP Requests für PusherApp und Melnor WifiCloud entgegen und antworten adäquat
  • wir exportieren eine REST API, mittel derer im lokalen Netz die einzelnen Ventile geschaltet werden können

Die Funktionsweise des Gerätes ausspähen

Im ersten Schritt, sobald man das Gerät ins lokale Netz gebracht hat (nein, das Web-Interface hat kein User/PW), die IP und DNS Einstellungen so anpassen, dass wir im ersten Schritt den Netzwerkverkehr zw. die WLAN Bridge und der Cloud mitsniffen können.

Note : um das Gerät ins lokale Netz zu bringen wird ein Handy und die Melnor Start App (90er Jahre Look) benötigt. Diese konnte unser Gerät nur auf einem IPhone 4 oder SE, nicht aber 6 oder neuer provisionieren!

[]!(melnor01.png)

Der Grundlegende Ablauf ist dabei wie folgt (WLAN Bridge ist der Client)

1.) Client registriert sich als melnor client bei PusherApp via HTTP Request
2.) PusherApp Upgraded die Verbindung zu einer WebSocke4t (plain) Verbindung
3.) Via WebSocket werden eine Socket ID festgelegt und der Client registriert sich auf einem PusherChannel der der MAC Adresse der Bridge entspricht
4.) Client fragt bei der Melnor Cloud via HTTP an und registriert sich auch dort mit seiner MAC Adresse
5.) Nun beginnt die Melnor Cloud mittels der PusherApp Events an den Client zu senden, dieser Ack’ed diese indem er wiederum einen HTTP Request an die Cloud sendet
6.) Als Beispiel : Nun wird ein hash_key Event via WS getriggert, der Client sendet daraufhin einen HTTP Request mit http://wifiaquatimer.com/submit/?idhash=&message=ascii–hashkeyevnt–ack–null
7.) Day0 - Day6 Schedule wird als Event emmitiert und vom Client Ack’ed
8.) manualctrl event setzt die Ventile auf AUS
9.) timestamp event teilt die relative zu nutzende Systemzeit mit (wird für die Schaltung wichtig)
10.) Alle warten und mittels WS Ping/Pong wird die Verbindung offen gehalten

Der Code

Der Code ist in NodeJS geschrieben und teilt sich in den die dnsTools zum spoofen auf, Code für DNS Spoofing gibt es zum Glück wie Sand am Meer.
Der Zweite Teil ist der web.js Part. Dieser registriert einen WEB und REST Server (siehe unten) und wartet auf HTTP Input. Dieser wird, sofern ein /app request kommt direkt zu einer WebSocket Verbindung
geupgraded und ist ab dann der Event-Kanal für die PusherApp Strecke. Ein simpler Automat stellt nunfest an welcher Stelle im Ablauf wir sind und antwortet entsprechend bzw. wartet auf das HTTP Ack vom Client.

Ein Watchdog zählt die Zeit mit und sendet ggf. einen WS Ping. Via der REST API kann der globale State der Ventile verändert werden, was automatisch auch ein manualsched event an den Client generiert und ihn updated.

REST API

Das Binär Protokoll von Melnor

OpenHAB2

Test Client + Code schöner machen