Home Control

De opzet

Er is natuurlijk al van alles te krijgen om je huis te automatiseren (Home Control, ofwel 'Domotica'). Maar, vaak duur, lastig op te zetten, en niet altijd energiezuinig (bij 20 cent/kWh kost 1 Watt continue ongeveer €1,75, een 100 Watt laptop in de gangkast kost dus zo'n €175 per jaar aan stroom). En, zelf doen is veel leuker... Vandaar dat ik zelf wat aan het hobbyen ben geslagen, gebaseerd op een energiezuinige Raspberry Pi.

Er is ondertussen een echt home control netwerkje te ontstaan, voor de meer nuttige taken. Hierbij wordt niet alles direct door het centrale brein (de Raspberry) bestuurd, maar heb ik veel 'lokale intelligentie'; bijvoorbeeld slimme kleine nodes gebaseerd op de AVR ATtiny. Deze hangen dan via een 4-draads seriële bus aan de Raspberry (Ethernet is veel te 'zwaar' voor dit doel). Je kan het het best vergelijken met hoe een lichaam werkt: de Raspberry is het centrale brein, maar een heleboel taken worden lokaal door reflexen afgehandeld, en de zintuigen zijn daarmee verbonden. Voordeel is dat deze reflexen doorlopen ook als het brein tijdelijk met iets anders bezig is, of om wat voor reden dan ook plat ligt...

Een voorbeeld hiervan is de afzuiging in de douche: een ATtiny is een lokale node, met daarop als zintuig een I2C temperatuursensor aan de warmwatertoevoer (logischer dan via de lamp). Als er gedoucht wordt wordt de leiding warm, en schakelt de ATtiny zelfstandig de afzuiger aan via een solid state schakelaar: de reflexreactie van de ATtiny. De ATtiny regelt ook de nalooptijd: hoe lang moet de ventilator doorlopen als er gestopt is met douchen. Maar, dit alles wordt ook doorgegeven aan het brein, en dat kan bijvoorbeeld besluiten de reflex te onderdrukken, of de nalooptijd aan te passen afhankelijk van de tijd of het seizoen. Ook is het geheugen in het centrale brein: de temperatuur wordt hier gelogd en via een lokale webserver leesbaar gemaakt.

Daarnaast heb ik ook enkele WiFi nodes, bijvoorbeeld gebaseerd op de ESP8266 processor, als te vinden in de 220V-schakelaars van Sonoff en in veel kleine hobby-printjes. Deze hangen in het draadloze netwerk van mijn huis. Nadeel is dat dit wel minder energie-zuinig is, voordeel is dat er geen netwerkkabeltje naar toe hoeft te lopen. Ideaal bijvoorbeeld voor de tijdschakelaar van de kerstboom.

De 'brains'

De intelligentie van het systeem wordt geregeld door een Raspberry Pi 3. Deze zit via Ethernetook aan het internet, en vormt zo ook de (beveiligde) link naar de buitenwereld. Bovendien staat deze toch al aan, omdat er ook allerlei andere services op draaien, zoals de file server en de SSH toegang. De Raspberry zorgt voor gedetaileerde besturing, data logging, het maken van grafiekjes, en zovoort.
Home Control: MQTT data uitwisseling
MQTT op de Raspberry, als hart van de besturing en data-uitwisseling

Hoe komen alle gegevens bij elkaar (en dan bedoel ik niet 'via de draadjes')? Dit kan het handigst via een 'data broker', waar sensoren de gegevens kunnen publiceren, en toepassingen zich op gegevens kunnen abonneren. De distributie wordt dan automatisch via de broker gedaan. Ik gebruik hiervoor MQTT, en wel de mosquitto (open source MQTT message broker) MQTT server. mosquitto implementeerd het standaard "Message Queuing Telemetry Transport" protocol, dat door veel systemen ondersteund wordt. Zie voor installatie bijvoorbeeld de Youtube MQTT basics video.

MQTT zit als een spin in het web, zie hiernaast. Alle gepubliceerde gegevens worden hier opgevangen, en weer doorgestuurd naar de abonnees. Bijvoorbeeld het 'timedate' process publiceert de tijd (verkregen van het internet via 'ntp'), dit wordt dan onder andere opgevangen door het Timer process (en andere processen die zich geabonbeerd hebben). Timer houd de 'tijdschakelklokken' bij, en publiceert het aan/uitschakelen naar de 'Timer' onderwerpen, waarop bijvoorbeeld de Sonoff's zich weer geabonneerd hebben. Zo schakelen lampen op de juiste tijd aan en uit.

Er zijn ook bijvoorbeeld Android app's om de data te bekijken/te wijzigen (bijvoorbeeld MQTT Dash), zodat ik ook een makkelijke user interface heb (in plaats van mijn oude en simpele lighttpd web interface). Het geheel is alleen vanaf mijn lokale netwerk te benaderen (tenzij ik op afstand inlog op mijn VPN), dus minder risico voor 'inbraak'. Meer info: zie mijn MQTT op de Raspberry pagina.

Ik heb een tijd geleden een lezing gehouden over de opbouw van het systeem en het netwerk, op 20 augustus 2013 bij EmSE (Embedded Systems Eindhoven, een lokale hobby-club); hier de (nu verouderd, want alleen over het bedrade gedeelte, en zonder CAN-bus) Home Control presentatie (pdf).

De 'ruggengraat' (netwerk)

CJMCU-TJA1051 CAN module
CJMCU-1051 CAN-serieel interface
Pas op: 5 Volt, niet 3.3V compatibel!

Het lage-snelheidsnetwerk wordt gevormd door een seriële bus op 38400 bits per seconde. Ooit opgezet met een 1-draads 'multi-drop serial hardware' op 9600 bits/seconde, maar ik ben overgegaan op de CAN-bus als fysieke interface. Niet echt snel, maar robust en kan grote afstanden overbruggen. Bovendien zijn bordjes hiervoor tegenwoordig goedkoop verkrijgbaar (had ze per 10 onder de Euro/stuk), bijvoorbeeld de CJMCU-1051 met de NXP TJA1051, met goede documentatie (datasheet, application note). Aan de kant van de Raspberry is deze optisch gekoppeld, zodat een stoorpiek (b.v. door blikseminslag in de buurt) niet ook gelijk de Raspberry opblaast. In principe kan de bus (en mijn optische koppeling) hogere snelheden aan, maar dat is tot nu toe niet nodig.

De bus bestaat uit vier draden; een voor 'aarde', een voor de voeding, en twee voor de communicatie (differential signalling). Alle nodes hangen voor zowel lezen als schrijven aan dezelfde lijn(en). Er zijn geen routers of switches nodig, wat de zaak weer simpel en energie-vriendelijk houdt.

Ik gebruik niet het officiële CAN-bus protocol, omdat de simpele ATtiny processors dit niet ondersteunen: over de CAN bus gaat een simpel serieel protocol, zoals ondersteund door haast alle processoren (start-bit, 8 data bits, stop bit). De Raspberry stuurt hier als controller de commando's, en de geaddresseerde nodes geven antwoord, beiden volgens het onderstaande formaat:

<1:type,len><1:address><N:message><1:checkbyte>

Er zijn ook 'broadcast' commando's die naar alle nodes tegelijk gaan, zoals eens per dag een tijdscommando dat alle klokken weer gelijk laat lopen (via de Raspberry met ntpd gekoppeld aan externe tijds-referenties).

Omdat de seriele bus een gedeelde resource is moet je opletten dat niet meerdere processen tegelijk aan de slag willen. Hierom heb ik de processen niet direct toegang gegeven, maar praten ze via UDP met een UDP-->serieel 'server' process (zie in eerdere figuur het oranje rondje rechtsonder in de Raspberry), dat de verzoeken opvangt en netjes na elkaar afwerkt. Voordeel: dit process is vanaf meerdere systemen op mijn interne netwerk bereikbaar, handig bij bijvoorbeeld foutzoeken.

De reflexen

Minimum netwerk-node met Arduino Nano
Arduino Nano als mijn 'minimale' netwerk-node (voor tests)

Naast de centrale intelligentie zijn er de 'slimme' nodes gebaseerd op de AVR ATtiny of de Arduino Nano, aan het hierboven beschreven netwerk (ook voor voeding). Zou ook via een optische koppeling kunnen, maar ach, ze zijn goedkoop. De nodes hebben een beetje gevoel voor tijd, en doen simpele klusjes. Wel zijn dit vaak essentiële taken, dus op de ATtiny is ook veel foutcontrole toegepast, zoals een 'watchdog timer' die de zaak automatisch reset als de processor door een stoorpiek op tilt gaat. Dat gebeurt nu en dan, en je wilt niet dat dan bijvoorbeeld de afzuiger maar door blijft gaan (of niet aan gaat). Gebeurt uiteraard niet heel vaak, maar als iets 24 uur per dag aanstaat, en er wordt een 220V motor in de buurt geschakeld... Eens in de zoveel maanden gaat het fout.

Maar, daarnaast ook WiFi nodes, zie hier onderaan bij implementatie. Handig voor verplaatsbare apparaten, of als er geen home control bus in de buurt is. Wel meer stroomgebruik vergeleken met de ATtiny modules. Misschien ook eens een keer naar Bluetooth Low Energy (BLE), Zigbee of zo kijken.

De zintuigen

Aan de nodes zitten de 'zintuigen', meestal via I²C. Dit zijn bijvoorbeeld LM75 I²C temperatuursensoren zoals al beschreven op mijn Raspberry hardware pagina. Ook zitten hier de 'spieren' (actuatoren) aan die het resultaat weer naar de buitenwereld teruggeven. Een voorbeeld is het solid state relais (SSR) om de afzuiging aan te schakelen. SSR is optisch gescheiden met goede isolatie, je wilt geen kans op 220 Volt op je netwerk!!!

De User Interface

Hoe komen alle gegevens bij elkaar? Dit kan het handigst via een 'data broker', waar sensoren de gegevens kunnen publiceren en toepassingen zich op gegevens kunnen abonneren. De distributie wordt dan automatisch via die broker gedaan. Ik gebruik hiervoor de mosquitto open source MQTT message broker. mosquitto implementeerd het standaard "Message Queuing Telemetry Transport" (MQTT) protocol, dat door veel systemen ondersteund wordt. Zie voor installatie bijvoorbeeld de Youtube MQTT basics video.

Maar, MQTT is/heeft zelf geen user interface. Hiervoor zijn er bijvoorbeeld Android app's als MQTT Dash, waarmee je de data kunt bekijken/wijzigen. Op de Ubuntu PC/laptop gebruik ik MQTT Explorer. Het netwerk is bewust alleen vanaf mijn lokale netwerk (of via mijn VPN) te benaderen, dus weinig risico voor 'inbraak'. Via MQTT en bijvoorbeeld MQTT Dash kan ik ook de diverse modules besturen, zoals ook mijn Sonoff wifi-gestuurde switch met eigen software (zie mijn Arduino pagina), en mijn 'IoT Energieverklikker'-lamp, waarvan de kleur zich aanpast aan het energiegebruik op dat moment.

MQTT Dashboard
Android MQTT Dash, met de kerstboom op de Sonoff1 module
Het leuke van MQTT is dat je zo makkelijk allerlei losse componenten/programma's aan elkaar kan knopen. Ik heb bijvoorbeeld de Sonoff WiFi 220V schakelaar: op de Raspberry heb ik een 'timer' script gemaakt (als in een digitale tijdschakelklok) in Python. Dit script publiceert de aan/uitstand van de timer naar onderwerp 'Timer1'. De Sonoff1 (met de kerstboom) luistert naar dit onderwerp, en schakelt dus aan en uit op basis van deze timer. Via Android MQTT Dash kan ik een string naar de MQTT server sturen, die deze naar het Python script doorstuurt: zie plaatje rechts 'Sonoff1Timer'. Een andere lamp schakel ik bijvoorbeeld uit op zonsondergangs (tijd wordt dagelijks van het internet opgehaald). Op beide modules zit ook een drukknop, hiermee kan ik de lampen ook met de hand bedienen: ze publiceren dit ook naar de timer-kanalen en MQTT luistert zo mee (kan zo dus ook meerdere lampen naar een knop laten luisteren).

Toepassingen

Als voorbeeld van enkele toepassingen die draaien:

Gas Water Elektra 2017
Geel is elektra
groen is gas
  • Badkamerafzuiging: via een I2C temperatuursensor op de warmwaterleiding wordt gezien dat er gedoucht wordt, en wordt de afzuiger aangezet. Via een timer in software draait deze nog een instelbare tijd door na het douchen. Loopt volledig autonoom, maar de Raspberry kan wel de uitlooptijd instellen en de temperatuur bijhouden.
  • C.V. pomp van de vloerverwarming: hier heb ik de 'domme' pomp (draaide altijd) vervangen door een slimme node, met temperatuursensoren op de aan- en afvoer-leidingen. Een slim algoritme zet aan de hand van de temperaturen de pomp aan (via een optisch gekoppeld solid state relais). Ook zorgt deze er voor dat de pomp elke dag in ieder geval minimaal 10 minuten draait zodat deze niet vast gaat zitten, ook als er die dag geen warmtevraag was. Ook weer autonoom, maar de Raspberry kan de zaak in de gaten houden en bijregelen.
  • Logging van de 'slimme' elektriciteitsmeter (zie verderop), kan ik mooi het verband zien tussen bijvoorbeeld temperatuur en energiegebruik.
  • Luchtkwaliteitsmeting, met een CO2 sensor, luchtvochtigheidssensor, en display
  • WiFi nodes, zoals de kerstboom-timer en mijn IoT-lampje.

De toepassingen op de slimme nodes zijn vrij autonoom: als de Raspberry om wat voor reden zou stoppen, gaat de pomp van de vloerverwarming gewoon door, hoogstens wat minder slim (en de logging op de Raspberry stopt).

De implementatie

De nodes - ATtiny en Nano

Op de nodes loopt een simpele lus, die de binnenkomende taken afhandelt en de resultaten weer terugstuurt, en ook de verdere administratie doet (zoals het gerust stellen van de watchdog). De berichten worden onafhankelijk van de lus met interrupt-routines opgevangen en verstuurd. Onderstaande tekst moet nog verder worden uitgewerkt, maar in het kort: de belangrijkste 3 interrupts (watchdog doet geen interrupt, maar een echte reset):

  • Serial Rx interrupt
    • Wake-up processor bij compleet bericht
    • Filtering op adres al in interrupt (state machine)
    • Bericht in de wacht-rij opslaan voor verwerking in het hoofdprogramma
  • Serial Tx interrupt
    • Verstuurt reply-message
  • Timer interrupt (1 kHz)
    • Real-time clock (½ Hz), time-outs

En dan in het hoofdprogramma een continue lus (loop) waarin de eigenlijke taken worden afgehandeld, als dat nodig is (als er bijvoorbeeld een nieuw bericht is):

  • Taakafhandeling uit binnenkomende berichten
  • I²C afhandeling, bijvoorbeeld elke seconde een temperatuurmeting
  • Foutcontrole en nood-acties (b.v. bij kapotte sensor: motor laten draaien)
  • LEDje knipperen op 1 Hz (zie ik dat de node het nog doet)
  • Slapen als er niets te doen is (wake-up @ irq)

Complete framework in 'C' (seriële routines en zo, maar zonder taken) past in ~ 1 kByte Flash; maar een typisch systeem met echte taken heeft het 2 kByte programmageheugen haast helemaal vol...

De nodes - Sonoff en Wimos

Voor het slimmere werk, of als er geen kabeltje in de buurt is, gebruik ik de WiFi-gebaseerde WEMOS D1 mini en Sonoff modules, beiden gebaseerd op de ESP8266 WiFi chips. Gekoppeld aan de MQTT server op de Raspberry is hiermee ook van alles te besturen en te meten. De Sonoff is vergelijkbaar met de Wimos, maar zit in een mooi doosje met voeding en 220V relais, dus als het ware een slimme schakelaar.

Meten is Weten

Gasgebruik als functie van de buitentemperatuur
Rode lijnen met de hand er in gezet: daalt de temperatuur
buiten overdag onder de 18° dan gaat de kachel blijkbaar aan...

Een voorbeeld daarvan is het uitlezen van de 'slimme energiemeter', zodat je je energiegebruik goed in de gaten kunt houden. Je kan dit natuurlijk 'uitbesteden', maar ik wil eigenlijk niet dat anderen mij in de gaten kunnen houden. Bovendien is zelf doen leuker en leerzamer.

Ik heb mijn slimme energiemeter met zijn P1-poort via een serieel-naar-USB kabeltje aangesloten op de Raspberry. Daar komt nu elke 10 seconden een datagram volgens de DSMR (Dutch Smart Meter Requirements) 4.2 standaard met de gebruiksgegevens van elektra en gas binnen [hier een overzicht voor diverse smart meters, onderaan pagina]. Op de Raspberry loopt een klein 'servertje', die deze gegevens opvangt. Via UDP kan nu elke computer op mijn netwerk dit weer opvragen. Op dezelfde Raspberry loopt ook mijn logging, zodat ik 'mooie' overzichten krijg, geeft best inzicht in waar je elektriciteit en gas blijft.

Gas Water Elektra 2017
Energiegebruik 2017

Zo is op het grafiekje links het energiegebruik van 2017 per maand te zien.

  • De groene lijn is het gasgebruik, in de winter duidelijk hoger dan in de zomer. Maar, in de zomer toch niet helemaal 0: we koken op gas, en voor de douche is warm water nodig: ook gas. Toch, het is duidelijk dat het meeste op gaat aan de verwarming, dit is waar werkelijk het gasgebruik zit.
  • De gele lijn is de elektra, en deze gaat in de zomer onder de nul door: we hebben zonnepanelen, en in die periode leveren we terug aan het net, 'de meter loopt de andere kant op' (al hebben wij geen mechanische meter meer). Het meergebruik in de winter is ongeveer gelijk aan de overproductie in de zomer: eind van het jaar staat de meter ongeveer op nul.

Zo kan je goed je energiegebruik zien, en aanpassen. In de grafiek per dag is te zien dat het huis al vrij zuinig is qua elektra: nachtgebruik is duidelijk onder de 100 Watt per uur, mooi laag. In de jaargrafieken (niet op deze pagina) is te zien dat de energiebesparende stappen van de laatste 6 jaar (sinds we in het huis zijn getrokken) helpen, elk jaar is het gasgebruik een beetje lager. Of ligt dat gewoon aan de globale opwarming, de winters steeds minder koud?

Ping

Een van de taken van mijn home server is ook home control en automation (domotica). Maar, voor je wilt controleren: meten is weten... Vandaar mijn interesse om ook bijvoorbeeld I²C sensoren (als een temperatuursensor in de huiskamer) aan te kunnen sluiten, zie mijn Raspberry Pi hardware pagina. Een simpel voorbeeld van meten: hoe vaak en lang staat mijn PC eigenlijk aan? En mijn TV (met internet)? Geen sensoren voor nodig; je kan dit gewoon met het ping-commando: als je een antwoord terug krijgt (in $?, 0=OK) staat het apparaat aan. Ik test dit een keer per 10 minuten in een script, en schrijf de resultaten naar file. Een simpele variant van dat script, dat ik start met sudo nice bash -c '/home/kees/scripts/TraceTV.sh > /tmp/TraceTV.log' & (let op: '0' is aan):

#!/bin/bash
while true; do
    # Only try once, with a one-second timeout; approx every 10 minutes
    ping -c 1 -W 1 192.168.1.143 >/dev/null
    echo "$?"
    sleep 600
done