Onze “Domotica”

Ik heb de afgelopen jaren al aardig wat geschreven over onze sensoren, logging en “domotica” in huis. Ik heb al diverse vragen gehad om al die informatie eens samen te voegen in een groot artikel. En aangezien dat niet eens zo’n heel slecht idee is heb ik de afgelopen weken gewerkt aan een artikel waarin werkelijk alles aan logging, monitoring, sensoren en domotica samenkomt.

Als u interesse heeft klik dan verder; Haal dan eerst wel een kop koffie want dit artikel groot!

Inleiding

Ik heb lang na moeten denken over de opzet van dit artikel. In de loop der tijd is er nogal wat hardware en software bij gekomen in huis en daar zit nogal wat overlap tussen.  Zo wordt ons servertje gebruikt voor zowel de logging van de zonnepanelen, het verwerken tot grafieken, als opslag van de sensoren en voor nog veel meer zaken.

Daarom heb ik besloten om eerst te beginnen met welke hardware we in huis hebben. Daarna komen de zonnepanelen, de zonneboiler, alle temperatuursensoren etc aan bod. Ik wil proberen om ook een klein deel van de techniek zelf te laten zien en de software die er op draait. Mocht er naar aanleiding van dit artikel behoefte zijn aan nog meer diepgang laat me dat dan weten.

1. Hardware

schema

Dit is een schematisch overzicht van de gebruikte hardware in huis.

  • Donkerblauw: zonnepanelen
  • Lichtblauw: servers en “infrastructuur”
  • Oranje: sensornetwerk
  • Rood: zonneboiler

Het meeste van deze hardware staat op zolder, vlakbij de zonnepanelen. Ik heb hiervoor een apart bureau gemaakt. Deze ligt wel vrij vol 🙂

hardware

Hieronder word alles verder besproken.

Trinity

trinity

Een Thinkpad Edge E145. Dit is een zeer energiezuinige laptop met toch nog redelijk wat rekenkracht. De kabels rondom de laptop verraden al dat Trinity een belangrijke schakel is in het geheel. En waarom de naam Trinity? Ik ben fan van de filmserie “The Matrix”.

Trinity doet dienst als:

  • Opslag voor alle omvormers;
  • Opslag voor alle temperatuursensoren;
  • Opslag van de zonneboilerdata;
  • Crashplan backup
  • Webserver voor jSunnyreports;
  • Webserver voor de domotica / intranet website;
  • En nog wat andere zaken die nu ( niet ) ter zake doen.

Apoc

Apoc is een standaard Synology NAS. Naast opslag voor data gebruik ik hem ook als backup met Crashplan.

Arduino

arduino

Zoals op het schema is te zien dat er 4 S0 kWh meters zijn aangesloten op deze Arduino Mega. Op de bovenstaande foto is nog net een netwerk, RJ45, stekker te zien; Deze gaat richting een klein meterkastje die op de vliering hangt. Bovenop de Arduino zit een prototype board die ik zelf heb voorzien van wat elektronica. Hierover later in dit artikel meer uiteraard.

De Arduino zit via een USB HUB aangesloten op Trinity.

USB RS485 – OK4E

rs485_zonneboiler

Dit is een standaard USB naar RS485 converter. Deze is aangesloten op de OK4E omvormer die in de meterkast hangt. Vanaf de zolder heb ik dus een kabel helemaal rondom liggen naar de koof. Via de koof naar beneden naar de meterkast naar de omvormer toe. Ondanks de leeftijd werkt de OK4E prima samen met deze converter.

USB RS485 – Zonneboiler

rs485_zonneboiler2

Een vergelijkbare RS485 USB converter. Hierop is de controller van de zonneboiler aangesloten.

Het aparte is dat ik met deze converter de OK4E NIET kan uitlezen, de software loopt dan na een paar minuten vast en zelfs de server wordt dan deels onbruikbaar. Voor de zonneboiler echter werkt deze wel stabiel.

Raspberry PI’s

raspi

In totaal op dit moment drie vergelijkbare Raspberry PI’s in ons netwerk. Die op de foto staat wordt gebruikt voor het uitlezen van de temperatuursensoren op zolder. De zwarte, rode en gele draad gaan naar de DS18B20 sensoren toe. Alle Raspberry PI’s zijn via een draadloze adapter aangesloten op ons netwerk. Dit geeft wat meer flexibiliteit waar ik de PI’s kan plaatsen. En overal in huis hebben we gelukkig toch goede WIFI ontvangst.

Samengevat

Het ziet er intimiderend en complex uit maar zoals uit dit artikel zal blijken valt het eigenlijk wel mee.

2. De zonnepanelen

We hebben op dit moment 8 omvormers. Te weten:

  1. Solarmax 2000S
  2. Steca 500
  3. Steca 500
  4. Steca 300
  5. Steca 300
  6. Steca 300
  7. Gridfit 250LV
  8. OK4E

Daar blijft het niet bij. 4,5,6 zijn samengevoegd tot 1 grote omvormer, Steca300x3.

S0 meters

De vetgedrukte omvormers worden bemeten door een viertal DIN kWh meters die voor elke 0.5Wh een korte puls afgeven.

omvormerbord

Hoe gaat dit nu in zijn werk? De zonnepanelen wekken stroom op. Op het moment dat een van de meters merkt dat er 0.5Wh ( dus 1/2000e! Wh ) is opgewekt dan wordt kleine schakeling verbonden waardoor er een stroompje gaat lopen. Op bovenstaande foto zijn allemaal losse draadjes te zien. Deze draden zijn op de 4 meters aangesloten. Aan de andere kant zit de eerder genoemde Arduino.

Arduino

Deze puls komt aan bij de Arduino op het prototype bordje die ik zelf in elkaar heb gezet. Dit printje zit er tussen voor de veiligheid, het z.g.n galvanisch scheiden van de systemen. De chip in het midden is een optocoupler chip. Wanneer er aan de ene kant een stroompje loopt gaat er in de chip een ledje branden. Dit wordt opgemerkt door een gevoelige sensor die ook weer een schakeling sluit.

Dit voorkomt ook ruis op de lijn. In mijn eerste setup had ik deze optocoupler er niet tussen zitten. Toen meette ik een heleboel rotzooi op de lijn. De kabels van de Arduino naar de S0 meters werkt namelijk als een soort antenne.

Op de Arduino komt de puls binnen op 1 van de pins waar de Arduino een z.g.n interrupt controller op heeft zitten. Dit houdt heel kort in dat wanneer er op 1 van deze pins een signaal binnenkomt de processor meteen aandacht daaraan gaat besteden. Het lijkt wel wat op een deurbel waar op gedrukt wordt.

Op de Arduino draait software die ik deels heb gecopieerd en deels zelf heb geschreven. Hieronder staan een aantal korte stukjes van de code:

// STECA1, Steca500 set 3 panels east. backside of the house.
#define STECA1_INTERRUPT 0
#define STECA1_PIN 2        
unsigned long steca1FallTime;  //Time of front raising
unsigned long steca1RiseTime;  //Time of front falling
String steca1String = "S";

Per omvormer geef ik aan op welke interrupt die aangesloten zit. In dit geval op interrupt 0, welke weer zit op PIN 2. Verder een tweetal variabelen waarmee ik precies kan meten straks wanneer een puls begint en wanneer die eindigt. En ik geef aan wat de waarde is die ik weer door wil geven. Daarover later meer.

// SCHELLCOUNT INFO
unsigned long MIN_PULSE_WIDTH_SCHC = 20;        // minimal pulse width SCHELLCOUNT;
unsigned long MAX_PULSE_WIDTH_SCHC = 55;        // maximal pulse width SCHELLCOUNT;

Vanaf de fabrikant is aangegeven hoe lang een puls duurt. In het geval van een Schellcount meter duurt een puls dus minimaal 20ms en maximaal 55ms. Als we straks een puls meten die te kort of te lang is dan weten we zeker dat deze niet goed was. Dit maakt alles weer een stukje stabieler.

 attachInterrupt( STECA1_INTERRUPT, Steca1InterruptHandler, CHANGE );

Deze regel code laat de Arduino weten dat interupt 0 moet worden afgevangen wanneer de pin veranderd van waarde ( van laag naar hoog of van hoog naar laag ). En wanneer dit gebeurd dat de “Steca1InterruptHandler” moet worden gestart. Dit is een apart stukje code die hieronder wordt besproken.

void Steca1InterruptHandler()
{

   unsigned long interruptTime; // Total time of interupt pulse.
 
   if ( digitalRead( STECA1_PIN ) == LOW ) 
   {
      steca1FallTime = millis(); //get time of pulse going down
   }
   else
   {
      steca1RiseTime = millis();                              //get time of pulse going up
      interruptTime = steca1RiseTime - steca1FallTime;      //measure time between down and up

      if ( interruptTime >= MIN_PULSE_WIDTH_SCHC && interruptTime <= MAX_PULSE_WIDTH_SCHC ) 
      {
         Serial.print(steca1String);  
         ChangeLedStatus();
      } else {
        if ( DEBUG ) { 
           // pulse was too short or too long.
           Serial.println( interruptTime );
        }  
        
      }
   } 
}

Ik controleer eerst of een puls begint of eindigd. Als de puls eindigd kan ik bepalen wat de lengte van de puls is geweest. Wanneer de pulslengte goed is wordt de LED op de Arduino veranderd en wordt er via de seriele kabel verstuurd dat we een correcte puls hebben gevonden. In dit geval wordt er over de seriele kabel een “S” teken verstuurd.

Samengevat

Er wordt 0.5Wh opgewekt door de zonnepanelen. De S0 meter geeft een korte puls af. Deze wordt door de Arduino ontvangen, controleert deze en geeft een signaal door aan de computer waar die op zit aangesloten. Maar we zijn er nog niet. De computer moet ook nog wat doen!

Software

Op Trinity heb ik een stuk software geschreven in Java. Deze software luistert de hele tijd naar de USB poort waar de Arduino op zit aangesloten. De Arduino geeft afhankelijk van de omvormer een andere letter door:

  • “S”, Steca500 1
  • “G”, De Gridfit
  • “A”, Steca500 2
  • “B”, 3xSteca300

Wat er in het kort gebeurd is dat er de hele tijd tekens binnenkomen via de kabel. Bijvoorbeeld “SASABG”. Twee pulsen voor beide Steca500 omvormers, een puls voor de Steca300x3 en een voor de Gridfit 250LV.

Elke keer als er een letter wordt ontvangen dan is dit voor de software een “gebeurtenis” oftewel een event in het Engels. En daar zit hem de hele functionaliteit in. Afhankelijk van dit event kan ik precies bepalen WAT er moet gebeuren. Een event afvangen is simpel:

event

Er kan in 1 event meer data binnenkomen, per onderdeel van deze string controleer ik wat voor karakter het is. Wanneer het dus een “S” is start ik de steca1Logger om iets te doen.

Wat nu gebeurd is eenvoudig. Ik bepaal de tijd tussen twee pulsen. Gesteld er zit 10 seconden tussen twee pulsen dan is dus bekend dat in de afgelopen 10 seconden 0.5Wh is opgewekt. Dat is om te rekenen naar het vermogen in W. Dat sla ik uiteindelijk op in een bestand op de server Trinity. Dit alles wordt ook op het scherm getoond zodat ik kan zien wat er gebeurd.

Untitled

Solarmax 2000S

Hier hoef ik weinig voor te doen. Ik heb een stukje software draaien op Trinity die via het netwerk de omvormer kan uitlezen.  Deze schrijft automatisch op een plek op Trinity per dag een bestand weg.

OK4E

De OK4E is net zo saai. Hiervoor draait een oud programma die ooit door IQUE software is geschreven. Dit pakket werkt nog steeds prima onder Windows 7.

1000

Ook dit programma schrijft logbestanden weg op Trinity.

Log bestanden

Alle logbestanden komen binnen op 1 centrale plek op Trinity. Namelijk op c:\omvormerdata

logbestanden

jSunnyreports

jSunnyreports is zo geconfigureerd dat hij bij alle bestanden kan onder deze map en vanuit daar maakt hij alle grafieken en JSON files. Over die laatste straks meer, die komen bij de domoticasectie weer terug.

2. De zonneboiler

Onze SR1168C controller is via een kabel en een RS485 converter aangesloten op de server. Het uitlezen van de zonneboiler is ontzettend eenvoudig. Door een goede set met tekst richting de controller te sturen krijg je antwoord waaruit je alle informatie van de zonneboiler kan halen. De software lijkt heel erg op die van het uitlezen van de Arduino, echter wordt er niet alleen geluisterd maar ook informatie verzonden.

Het verzenden

initcommand

Wanneer bovenstaande string wordt verstuurd naar de controller dan antwoord de controller met een hele rits aan data. Het verzenden gaat als volgt:

sendcommand

Eerst, voor de zekerheid, zorgen dat er nergens meer informatie in een buffer zit. En daarna door middel van een outputStream de string versturen naar de controller

Het ontvangen en verwerken

Het ontvangen van de data is ook een event, vergelijkbaar met dat van de Arduino. Sterker nog, de code is nagenoeg identiek. Daarom laat ik hier ook alleen het verwerken van de data zien.

receiveData

 

Alle data komt in een joekel van een string binnen. Elke deel van die string heeft een betekenis. Dankzij een Excelsheet van iemand weet ik exact wat wat is. Vanuit die lijst kan ik dus alle belangrijke data halen zoals T0 tot en met T6, hoe hard de pomp draait, hoeveel er is opgewekt etc.

Het bepalen van die waarden is een ding. Die data ergens opslaan is een andere zaak. Alle data wordt opgeslagen in een database. Door middel van een standaard HTTP aanroep wordt de data verzonden naar mijn database. De database heeft een aparte ingang zodat ik via HTTP de database kan benaderen. Het versturen naar de database gaat zo:

http_save

Maak een URL aan, maak een HTTP connectie, en lees in wat de response is. Alle informatie staat al in de URL vermeld die ik in de database weer uit elkaar kan halen en kan opslaan.

3. De database

Ik maak gebruik van een Oracle 11G XE database.Dit is een gratis database versie van Oracle maar bevat wel alles wat ik nodig heb. Ik heb een Oracle achtergrond en dat maakt dus ook een groot deel uit bij de beslissing om ook hier voor Oracle te kiezen.

dedatabase

Dit zijn alle tabellen die ik op dit moment in gebruik heb.

  • DTS_LOGGING, hier komt alle logging in te staan, vooral wanneer er wat fout gaat. Geeft mij meer inzicht in wat er fout gaat en waarom.
  • DTS_SENSORBASE, elke sensor heeft een bepaalde locatie, of PI waar die op aangesloten zit. Deze zitten allemaal in deze tabel opgeslagen
  • DTS_SENSORCACHE, de meest recente waarde van elke sensor zit in deze tabel opgeslagen, dit geeft een behoorlijke performancewinst
  • DTS_SENSORDATA, dit is de grootste tabel, hier staan alle sensorwaarden in van alle sensoren in de tijd
  • DTS_SENSORS, dit zijn de aangesloten sensoren in het systeem
  • DTS_UNKNOWNSENSORS, alle data die binnenkomt maar die ik nog niet herken wordt hierin opgeslagen. Ik kan dan op een later stadium deze data alsnog inlezen

Ik kan nu door middel van queries live de database bevragen.

query

Dit geeft een overzicht wanneer welke sensor voor het laatst data heeft ontvangen.

Zonneboiler

Het verwerken van de zonneboiler URL die ik eerder noemde gaat als volgt:

verwerken_zonneboiler_plsql

Voor welke losse sensor wordt een aparte procedure gestart die de data verwerkt.

4. Temperatuursensoren

Zoals iedereen denk ik wel weet ben ik stapsgewijs het huis aan het vol hangen met temperatuursensoren. Op termijn wil ik uit deze bak data kunnen leren hoe ons huis werkt op temperatuurgebied. En, niet onbelangrijk, kijken of ik nog meer geld kan besparen door nog efficiënter te stoken.

Op dit moment heb ik 3 Raspberry PI’s hiervoor in gebruik.

  1. SN-WTW, Raspberry die de doucheWTW en wat andere temperaturen daar in de buurt controleert;
  2. SN-ZOLDER, Raspberry op zolder die de zonneboiler deels logt, maar ook de CV ketel en de temperatuur van het washok en mijn kantoor
  3. SN-ELGA, Raspberry die de ELGA en temperaturen daar rondom gaat controleren *

Nummer 3 wordt op dit moment geïnstalleerd.

Hiervoor gebruik ik temperatuursensoren van het type DS18B20. Deze zijn met een Raspberry PI ontzettend eenvoudig uit te lezen. Hierover schreef ik al eens een kort artikel. De sensoren zijn vanaf het bestandssysteem simpel te benaderen. in /sys/bus/w1/devices/<id> staat een file w1_slave. Door deze te bekijken ( cat w1_slave ) is de inhoud te zien en de temperatuur.

Dat kan uiteraard ook geautomatiseerd worden. En dat is precies wat ik heb  gedaan.

In het kort werkt de software als volgt:

  1. Controleer welke sensoren aangesloten zitten
  2. Lees stuk voor stuk deze sensoren uit
  3. Verstuur de data via HTTP naar de server
  4. Ga 20 seconden slapen.

Het uitlezen van de sensoren gaat als volgt:

getTemperature

Ziet er lastig uit maar is het absoluut niet. Hij pakt voor een specifieke sensor een aantal keer ( MAXPROBES ) de inhoud van de file ( w1_slave ) van die sensor. Daarna wordt gekeken of de inhoud valide is en wordt de temperatuur opgeslagen.

Daarna wordt de laagste en hoogste temperatuur verwijderd en worden de overgebleven temperaturen uitgemiddeld. Dan is de kans op een leesfout minimaal.

Het versturen van de data gaat, net zoals de zonneboiler, over HTTP naar dezelfde database.

5. Plugwise

We hebben al een aantal jaar een plugwise netwerk draaien. Dit doe ik handmatig op mijn laptop, deze data wordt nog niet geautomatiseerd verwerkt in mijn database. Dit staat wel op mijn wensenlijst, ik wil namelijk live weten wat de ELGA verbruikt. Die data heb ik nodig voor het bepalen van de COP van de installatie.

6. Domotica website

Intussen 25 sensoren die worden opgeslagen in een database. Intussen een kleine 950.000 individuele sensorwaarden in diezelfde database. Met andere woorden een beginnende goudmijn. Maar zonder een manier om die data te interpreteren heb je nog niets. Ik ben daarom al een tijd bezig om al die data te ontsluiten in een strak dashboard. Niet alleen wil ik alle informatie van de sensoren daarin hebben maar ook de informatie van Plugwise en de goudmijn die jSunnyreports heet.

Stapje bij beetje ben ik deze website aan het uitbreiden met nieuwe grafieken en tabellen. Hieronder een plaatje hoe de frontend er nu uit ziet.

domotica

De informatie van de zonneboiler, alle temperaturen en de opbrengst van de zonnepanelen staat hier al. Verder heb ik al een hele vracht aan grafieken die ik al eerder op de website plaatste. Maar hoe doe ik dit nu?

Bootstrap

Als eerste; Deze frontend heb ik zelf niet bedacht. Ik heb hiervoor een Bootstrap thema gebruikt. Dit is een mooie website met diverse thema’s. Iemand met een scherp oog zal meteen ontdekken welke ik heb gebruikt als basis. Bootstrap maakt het leven een stuk makkelijker. Ik hoef me ineens niet meer bezig te houden met hoe het eruit ziet. Alleen de content moet ik nog toevoegen.

Highcharts

De template was al voorzien van een stuk code waarmee ik grafieken kon maken. Ik heb echter besloten deze niet te gaan gebruiken. Ik heb al behoorlijk wat ervaring op gedaan met de gratis bibliotheek Highcharts. Dit is een bibliotheek geschreven in javascript waarmee je praktisch alle soorten grafieken kan maken die je wilt. En omdat er ontzettend veel voorbeelden te vinden zijn is het ook nog eens ontzettend makkelijk om Highcharts om te bouwen naar je eigen smaak.

highcharts

Dit is een mooi voorbeeld van hoe data inzichtelijk kan worden gemaakt in een grafiek.

Alleen dan de hamvraag. HOE krijg ik al die data in tabellen en grafieken? De oplossing? Javascript en JSON

JSON

JSON staat voor JavaScript Object Notation. En het is eigenlijk niets anders dan een bepaalde representatie van informatie. Een voorbeeld van een JSON file:

json

In deze file staan al mijn omvormers vermeld. Per omvormer weet ik de naam, Wp, kwh/kWp, ligging op het dak, orientatie en of de installatie actief is. Deze file wordt in dit geval door jSunnyreports gemaakt.

Deze JSON files zijn makkelijk met javascript in te lezen en te verwerken. En met een javascript library genaamd JQuery wordt het wel heel erg makkelijk gemaakt.

Javascript

Bijvoorbeeld de temperatuur van een willekeurige sensor op de hoofdpagina tonen. Deze informatie moet dus uit mijn database komen. Hiervoor heb ik code geschreven die JSON object aanmaakt. het object in dit geval is die van de WTW_IN sensor

json_temp

En het stukje javascript voor het ophalen en tonen:

setgettemperature

de functie getTemperature bepaald wat de URL is die moet worden uitgelezen. Met $.getJSON wordt die data opgehaald. En met de notatie data.temperature haal ik de waarde uit het JSON object.

NB: Voor de Jquery puristen onder ons; Ten tijde van het in elkaar zetten van deze pagina was ik nog niet bekend met de notatie: $( “” ).html(); 🙂 De code kan dus nog korter,bondiger en robuster. Nu nog tijd vinden om naast nieuwbouw ook alles te onderhouden 🙂

jSunnyreports

Ik ben dus nu ook zo langzamerhand jSunnyreports aan het aanpassen. jSunnyreports moet op termijn ook alles in JSON formaat gaan genereren. Dan kan ik met Highcharts een compleet nieuwe frontend bouwen met interactieve grafieken en alle toeters en bellen er op en er aan. Ik ben nu in elk geval bezig om langzaam aan alle files te genereren en daarop grafieken en tabellen te bouwen. Straks komt de uitdaging om een mooi en overzichtelijk dashboard voor te ontwikkelen.

Voelt u zich geroepen?

7. BACKUP!

Ook niet onbelangrijk. De backup! Ik heb twee machines 24/7 draaien, dat zijn Apoc en Trinity. Mijn backup strategie is simpel. De belangrijke data van Apoc wordt op Trinity opgeslagen en andersom. En daarnaast gaat alle data naar de cloudbackup van Crashplan. Met andere woorden; Gaat er een server stuk? Dan staat de data in huis op de andere server. Komen we onder water te staan slaat bijvoorbeeld de bliksem in? Dan staat alle data centraal bij Crashplan.

En daarnaast maak ik elk jaar een backup op DVD van de belangrijkste bestanden. Ik hoop daarmee elk risico tot een minimum te hebben beperkt.

Tot slot

Ik hoop dat nu voor iedereen iets duidelijker is hoe alles in ons huis nu werkt. Het zijn meestal kleine losse overzichtelijke projecten die semi onafhankelijk van elkaar kunnen werken. Centraal staat nog wel mijn server Trinity waar alle data op wordt bewaard.

Vragen? Laat het me weten!