All posts by Mosibi

Control a StorkAir/Zehnder WHR 930 ventilation unit using mqtt

Our house is equipped with a WHR 930 ventilation system, in Dutch a ‘warmte terugwin systeem (wtw)’ and since we have the ‘basic’ version, we have to control it using switch in the bathroom. There is a RF module available for the WHR 930, but that’s a pretty expensive option and i could not figure out how open it was. Since i want to control it from Home Assistant, it must be open or should have some sort of API.

Searching the internet for possibilities i learned that the WHR 930 has a serial interface on it’s mainboard and that the protocol is fully reverse engineered! The picture below is one of the mainboard, the red arrow points at the serial interface (RJ45)

I modified a UTP cable to get the right pin layout for a Serial<>USB converter and attached it to a Raspberry Pi and wrote some python code to interface with the WHR 930 via the serial connection. The code reads the various temperature values and fan status and publishes the results on a mqtt topic. The python code subscribes to a specific mqtt topic (house/2/attic/wtw/set_ventilation_level) for messages (0, 1, 2 or 3) to set the ventilation level. Level 0 stops the ventilation, i did not even know that the WHR 930 could do that 🙂

For now i am happy, but the serial protocol description shows that there is much more possible. Maybe i will look into that later, but do not hesitate to contact me (see my Github page for contact info) if you found out nice additions!

For integration with Home Assistant, see the README file on my Github channel.

Push Hue switch status on a MQTT topic

Since a few weeks we have a Hue switch which can be used to set the Hue lights on and off and also dim or brighten them. Of course the Hue switch only triggers Hue devices and nothing else. But i wanted to trigger other devices also, like a wifi tp-link switch that’s connected to a normal light  when someone pushes the ‘on’ button. And when the ‘off’ button is pressed, all lights in the livingroom should go off, but also that light that’s connected to the tp-link switch and even the TV, radio and the tp-link switch that switches a few devices behind the tv-set that’s not needed at night.

Sadly the switch does not have a webhook or something like that, but it is possible to get the state of the switch from the Hue bridge. With a simple curl command. we can get the state of our switch (our’s has id 2): curl -s -XGET http://<ip address>/api/<user>/sensors/2

 "state": {
 "buttonevent": 1002,
 "lastupdated": "2017-01-22T11:34:05"
 "config": {
 "on": true,
 "battery": 100,
 "reachable": true,
 "pending": []
 "name": "Hue switch",
 "type": "ZLLSwitch",
 "modelid": "RWL021",
 "manufacturername": "Philips",
 "swversion": "",
 "uniqueid": "00:aa:bb:cc:00:ff:00:ff-00-ff00"

Now it is pretty simple to poll the Hue bridge and when someone pushes a button, send the id of the button on a MQTT topic. I use Home Assistant to catch that event and trigger an action depending on the button pressed. Btw, button 1 is ‘on’, button 2 is ‘brighten, button 3 is dim and button 4 is off.

# -*- coding: utf-8 -*-

import time
import json
import requests
import mosquitto

######## CONFIG ########
urlhuebase = "http://<ip address>/api/<user>"
port = 8123
use_ssl = True
sensorid = '2'
pollingtime = 1

def publish_message(msg, mqtt_path):
  mqttc.publish(mqtt_path, msg, 1)

def SensorState(sensorid):
  urlhue = urlhuebase + "/sensors/" + sensorid
  hueresponse = requests.get(urlhue)
  state = hueresponse.json().get('state')
  data = [ state['buttonevent'], state['lastupdated'] ]
  return data

# Connect to the MQTT broker
mqttc = mosquitto.Mosquitto("publish_hue_switch")

sensordata = SensorState(sensorid)
lastupdated = sensordata[1]
print "lastupdated: {0}".format(lastupdated)

while True:
    sensordata = SensorState(sensorid)

    if (sensordata[1] != lastupdated):
      button = str(sensordata[0])[0:1]
      publish_message(msg=button, mqtt_path='house/0/hallway/hueswitch/button_pressed')
      print 'Button pressed: {0}'.format(button)
  except KeyboardInterrupt:
    print 'Exiting on request'

Creating persistent USB device names on a Raspberry Pi

If you use multiple USB devices that for example create device names like /dev/ttyUSB0, /dev/ttyUSB1 and so on, you probably want to assign device names that are more descriptive. On Linux (and thus on an Raspberry Pi) you can do this by writing an udev rule. Udev is a device event handler, so when you plugin your USB device it will be seen by udev and will create device names according the ruleset.

I have two devices that I like to have a device name that are persistent. A Xbee/Zigbee Xstick from and an USB FTDI serial cable. Normally on a Linux system, you use the command ‘udevadm info’ to get the information you need to specify in the config file, but on the RPi ‘udevadm info’ results in a kernel panic, so use the commands ‘lsusb -v’ and ‘usb-devices’ to get the information you need.

Create a file /etc/udev/rules.d/99-usbdevices.rules with the following content:

ATTRS{idVendor}==”0403″, ATTRS{idProduct}==”6001″, ATTRS{product}==”XStick”, SYMLINK+=”zigbee”
ATTRS{idVendor}==”0403″, ATTRS{idProduct}==”6001″, ATTRS{serial}==”A6WGT0NS”, SYMLINK+=”smartmeter”

And restart udev and trigger pulling the devices:

sudo /etc/init.d/udev reload
sudo udevadm trigger

After that you should have links with the names you specified pointing to the real devices

$ ls -l /dev/zigbee /dev/smartmeter
lrwxrwxrwx 1 root root 7 Jul 30 21:02 /dev/smartmeter -> ttyUSB0
lrwxrwxrwx 1 root root 7 Jul 30 21:02 /dev/zigbee -> ttyUSB1

From now you can reference /dev/smartmeter instead of /dev/ttyUSB0 or some other number.

Gas meter update

Yesterday I blogged about getting information from our gas meter with an Arduino that reads the reed switch. After using this setup for many hours, we noticed that our counter was not accurate. My first suspect was the IN-Z31 reed switch, it looked like the switch sometimes stayed closed for a very long time. To get more information, I changed the code so that when the sensor port changes to HIGH (1), I start an other function that checks for how long (in milliseconds) the switch stays closed.

Luckily, soon after changing the code and monitoring the serial (debugging) output, the gas meter stopped exactly at the digit 9 and the CountStateDuration() function showed me that the switch stayed closed. Yesterday we already noticed that we got a pulse every time when the digit 9 was shown, so that the switch stayed closed at 9, was not a very big surprise.

Now we learned that, I modified the code. In the loop() it calls the function CheckSwitch() which returns a 0 if the switch is open (not making contact). If the switch is closed, thus making contact, the function CountStateDuration() is called to check how long the switch is closed. This function returns when the switch is open again, resulting in a counter update.

The LCD screen now shows the real counter, but to get that right, you need to set the current reading before starting the Arduino. The new code can be downloaded here.


Reading our gasmeter with an Arduino

In our temporary home(*), we have a gas meter with a IN-Z31 pulse transmitter.I had never seen one before, so after some Googling, I found out that it is a reed switch, generating pulses when an event happens. This model have 2 switches, one for an alarm event, that is triggered when someone tries to tamper the meter and the other one that will be triggered when an amount off gas is used, the ‘Totalizing contact’.

A cable with 4 wires coming from the IN-Z31 was not attached to anything, so we would not brake or interrupt something when we are trying to read information from it. The datasheet (IN-Z61 is a newer version, but working the same) showed me that the inner 2 wires of the 4 are used for the ‘Totalizing contact’, the one we need.




Two months ago I bought an Arduino Uno, because in our new home we want to do some domotica. Since we have the Arduino, our son Sven (14) had a lot off air time with it, so he helped me a lot to attach the IN-Z31 to the Arduino. Mostly, he build the board and I did the logic.

Board setup

The setup on the board started simple, connect the 5v from the Arduino to one wire and connect the minus of the Arduino to the other wire. Between the wire from the IN-Z31 and the minus, we put a 10K resistor and behind the resistor we attach a wire to port 6 on the Arduino. Port 6 is a digital port, that means we are going to get a 0 (LOW) or a 1 (HIGH) from it. The part of the switch we are reading is normally open and will be close (making contact) when generating the pulse.

The datasheet mentioned that it will be 250ms closed. After connecting the IN-Z31 to the Arduino, we noticed that it triggered an event at every 0,001 m3. But after a lot of fiddling with the timing, we could not get a counter that was exact keeping up with the counters on the meter self. Eventually we decided not to measure the 0,001 m3, but 1 step further, so we count every 0,010 m3. What we did is the following, when we see an event from the reed switch, we append 1 to our counter and wait for 3500 ms (3.5 seconds). Why 3500?, 2500 (10 times 250 ms) was to low (the Arduino is so fast that we sometimes counted 2 extra loops in that 2500 ms ) and 3500 turned out to be a very good number 🙂


The code

After getting stable counters, Sven attached and LCD screen to the Arduino. That way we can leave it in the cabinet where the meter is, without a laptop attached to it, and still read out the information we want. When that worked, Sven did not liked it that the LCD was always on, so he also put a button switch between the LCD screen and the 5v, so that you need to press the button to read the screen, very nice!. The LCD part added some code and cables, but the base is very simple… You can download the code here

The future

Soon a Raspberry PI will arrive, then we will try to get the counters somewhere on the internet

*)  We sold our home and are building a new one, so we now are renting a house on a holiday park in the neighbourhood of our new house

CentOS remote headless install

Soms is het nodig om een systeem op afstand te herinstalleren zonder dat je toegang hebt tot het console, bijvoorbeeld als jouw systeem in een datacenter hangt aan de andere kant van het land. Ik verwacht dit binnenkort nodig te gaan hebben bij een hoster die gebruik maakt van een eigen kernel, waar ik geen gebruik van wil maken en dus een schone installatie wil doen.

CentOS en dus Red Hat, Fedora, Scientific Linux, e.d., gebruiken Anaconda als installatie programma en deze kan gebruik maken van VNC, dus het principe is simpel. Boot met de installatie kernel en geef aan dat je gebruik wilt maken van VNC, zodat je vanaf een remote locatie contact kunt maken met de VNC server die door Anaconda is gestart, om de installatie af te maken.

Uiteraard is het ook mogelijk om gebruik te maken van een kickstart file, zodat de hele installatie ‘unattended’ zal, maar dat gaat voor dit doel een beetje te ver.

Download installatie kernel

Log in op het systeem die je opnieuw wilt installeren en voorzie deze van de installatie kernel

mkdir /boot/netimage
wget -P /boot/netimage
wget -P /boot/netimage

Pas de bootloader aan

Nu moet de installatie kernel toegevoegd worden aan de (Grub) bootloader. Dit kun je het beste met het commando grubby doen, die zorgt voor de juiste formattering en zal ook de padnamen aanpassen aan de lokale situatie. Gebruik je grubby niet, let er dan in ieder geval op dat indien je /boot op een aparte partitie hebt, je de kernel-bestanden aanwijst als /netimage/vmlinuz en /netimage/initrd.img, dus zonder /boot er voor.

grubby --add-kernel=/boot/netimage/vmlinuz --initrd=/boot/netimage/initrd.img --args="ip= netmask= gateway= dns= ksdevice=eth0 repo= headless lang=en_US keymap=us vnc vncpassword=foobar" --title="CentOS 6.2 VNC install"

Het ip adres, netmask en de gateway dien je uiteraard aan te passen aan je eigen situatie. Voor de duidelijkheid, deze gegevens neem je over van het draaiende systeem!

De dns server is de Google publieke DNS server, deze kun je aanpassen naar eigen wens, maar is dus niet nodig.

Het VNC wachtwoord is niet nodig maar ik raad je wel aan om deze te gebruiken. Er zal maar een of andere grapjas je installatie overnemen en de boel vernaggelen.

Bereid volgende boot voor

Grub kent een leuk grapje waarbij je eenmalig de default kernel aan kunt passen. Dat houdt dus in dat indien er onverhoopt iets mis gaan bij het booten van de installatie kernel, je met een reboot (powercycle) het systeem weer laat booten van de normale kernel.

De volgende commando’s regelen dit voor je. GRUBINDEX levert dus de positie op van de installatie kernel in de grub config.

GRUBINDEX=$(grubby --info=/boot/netimage/vmlinuz|awk -F\= '$1 ~ /^index/ {print $2}')
echo "savedefault --stage2=/boot/grub/stage2 --default=${GRUBINDEX} --once" | grub --batch


Na de reboot zal je systeem booten van de installatie kernel en via de installatie image (install.img = 129MB) ophalen. Zodra deze binnen is zal de grafische installatie gestart worden en pas van dit moment kun je met VNC connecten op (:1 is gelijk aan poort 5901) om de installatie af te maken.

Voor dat je dit remote gaat doen, is het trouwens verstandig om dit een paar keer te testen op een (lokaal) systeem waar je wel het scherm van kunt zien tijdens de boot. Zo kun je een en ander finetunen en ervaring krijgen met dit bootproces. Deze handleiding heb ik geschreven door gebruik te maken van virtuele (KVM) hosts.


Virtual hosting met Postfix en Dovecot

Mijn mailserver is nodig aan vervanging toe en zoals ook voor mijn andere machines geldt, wordt ook deze voorzien van Centos in verband mijn aanloop naar het RHCA zijn.

In de nieuwe setup wilde ik geen gebruik meer maken van LDAP, dat heb ik jaren gedaan, maar gewoon simpel van configuratie bestanden, daar heb ik met mijn paar domeintjes ruim voldoende aan. De uiteindelijke aflevering van de email in de juiste box, laat ik over aan het ‘deliver’ programma van Dovecot, zodat ik in de toekomst ook de filtering daarvan kan gaan gebruiken.


De wijzigingen (toevoegingen in dit geval) aan /etc/postfix/ zijn minimaal:

1 virtual_minimum_uid = 500
2 virtual_uid_maps = static:500
3 virtual_gid_maps = static:500
4 virtual_mailbox_domains = hash:/etc/postfix/vdomains
5 virtual_transport = dovecot:
6 transport_maps = hash:/etc/postfix/transport
7 virtual_mailbox_maps = hash:/etc/postfix/vmailbox
8 virtual_alias_maps = hash:/etc/postfix/virtual

Op regel 1 zie je virtual_minimum_uid staan. Dit is fallback methode van Postfix, mocht er ergens een fout gemaakt zijn, dan zal er nooit een lager UID dan 500 gebruikt worden.

Regel 2 en 3 (virtual_uid_maps, virtual_gid_maps) geven aan hoe de mapping van de UID en GID informatie moet geschieden. Omdat ik gebruik maak van virtual hosting en dus de gebruikers geen entry in /etc/passwd hebben, dienen we postfix te vertellen welk UID en GID we willen gebruiken. Ik maak gebruik van UID en GID 500, welke ik koppel aan de gebruiker vmail. Deze gebruiker dient ook aangemaakt te worden:

groupadd -g 500 vmail
adduser -c 'Virtual Mail User' -d /var/vmail -M -g 500 -u 500 -s /sbin/nologin vmail

Met regel 4 (virtual_mailbox_domains) geef ik aan welke domeinen ik als virtueel beschouw. Ik neem hier alle domeinen in op, ook degene waarvoor ik alleen maar backup MX ben en via virtual_transport (regel 5) vertel ik Postfix welke manier van aflevering (transport) ik voor deze domeinen wil. Met transport_maps (regel 6) kan in de default waarde die gezet is met virtual_transport overrulen, dat gebruik ik voor de domeinen waarvoor ik MX backup ben.

De optie virtual_mailbox_maps op regel 7 koppelt een email adres aan een mailbox (directory of bestand) op het systeem. Normaal gesproken vertel je Postfix hiermee in welke directory er geschreven dient te worden, maar aangezien ik het programma deliver van Dovecot gebruik, hoef ik hierin alleen maar de email adressen te specificeren. Het tweede veld verwacht Postfix wel, dus daar kunnen we dummy info plaatsen.

Met virtual_alias_maps ( regel 8 ) koppel je een email adres aan een andere. Postfix geeft aan dat je hier nooit een wildcard domein in op moet nemen, uiteraard vanwege spam redenen, ik gebruik dat voor 1 van mijn domeinen wel, maar daar heb ik dan ook goede redenen voor.

De hash tables die aangemaakt dienen te worden, zie je hieronder staan. Waar ‘dummy’ staat, verwacht Postfix informatie die in deze situatie niet nodig is. Vergeet niet om na iedere wijziging een ‘postmap $bestandsnaam’ te doen.

domain1 dummy
domain2 dummy

/etc/postfix/transport relay relay

/etc/postfix/vmailbox dummy dummy


Verschillende keren heb ik in bovenstaande tekst het programma deliver genoemd van Dovecot. Postfix kent deze standaard niet als LDA (local delivery agent), daarvoor moet aan /etc/postfix/ het volgende worden toegevoegd:

dovecot unix – n n – – pipe
flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${recipient}


De Dovecot configuratie zoals ik hem op dit moment gebruik is alleen voor het afleveren van de email in de juiste mailbox, vandaar dat /etc/dovecot/dovecot.conf er nog minimaal uitziet. In een later stadium ga ik hier onder andere nog SSL aan toevoegen, zoals gezegd, dat heb ik nu nog niet nodig.

ssl = no
protocols = imap
mail_location = maildir:/var/vmail/domains/%d/%n
service auth {
unix_listener auth-userdb {
mode = 0600
user = vmail
group = vmail
passdb {
driver = passwd-file
args = /etc/dovecot/imapusers
userdb {
driver = static
args = uid=vmail gid=vmail home=/var/vmail/domains/%d/%n

In het bestand /etc/dovecot/imapusers staan de gebruikers met hun wachtwoord. Het is mogelijk om daarin mee informatie zoals GECOS en dergelijk op te nemen, maar ook hier geldt weer dat ik dat in mijn situatie niet nodig heb.



Om Dovecot’s deliver te mogen laten schrijven in /var/vmail/, moet de Selinux verteld worden wat de juiste context is voor /var/vmail.

/usr/sbin/semanage fcontext -a -t mail_spool_t '/var/vmail(/.*)?'

Hierna is een restorecon -R /var/vmail nodig om een en ander juist te zetten. Mocht je ooit zelf in deze directory iets aanpassen, herhaal dan het restorecon commando.

Transip VPS pilot

Transip wil binnenkort als dienst VPS’en gaan aanbieden, maar voordat deze dienst wordt aangeboden, willen ze eerst een pilot draaien waarin deelnemers een maand gratis gebruik kunnen maken van een VPS. In die maand kan Transip kijken wat de invloed is van de VPS omgeving op hun bestaande infrastructuur.

Nu komt deze pilot voor mij op precies het juiste moment. Mijn eigen server is inmiddels ouder dan 4 jaar en staat op de nominatie om uitgefaseerd te gaan worden. Deze server draait bij mij thuis en ook dat is een situatie waar ik eigenlijk wel van af wil. Ook al ik de machine zo stil mogelijk en zo heb ik destijds al nagedacht over de energieconsumptie, toch is hij nog hoorbaar in sommige delen van het huis en uiteraard heb ik ook liever het energieverbruik van het huishouden een stukje lager. Tevens staat het idee van het niet meer druk hoeven maken om (mogelijk) uitvallende hardware mij ook wel aan 🙂

Via Twitter account van Transip hoorde ik dat er extra VPS beschikbaar kwamen in de pilot. Ik had al eerder aangeven graag gebruik te willen maken van de pilot, maar hoorde helaas niets. Nu nogmaals gemaild naar Transip en jawel hoor, ik kreeg mail dat er een VPS voor mij beschikbaar zou komen. Yes!

In de portal van Transip (pilot is alleen beschikbaar voor bestaande klanten), was voor mij nu de optie VPS er bij gekomen. Ik kon kiezen uit een installatie van verschillende Linux’en, FreeBSD en OpenBSD. Ik heb gekozen voor Centos 6 en via het console (webbased java applet), zag ik dat het systeem geboot was en in het normale Centos installatie scherm stond te wachten op input van mij.

Het werken via webgui console ging goed, ik merkte echter wel een duidelijke vertraging in de muis bewegingen. Toen het systeem eenmaal geïnstalleerd (minimal) was, werkte het text console uitstekend via de webgui. Via het console heb ik uiteraard meteen SSH aangezet, zodat ik het systeem verder via SSH kon afconfigureren.

Tot nu toe gaat het werken met de VPS erg goed. Het systeem is lekker ‘responsive’ en eigenlijk merk ik geen verschil in het werken met deze VPS bij Transip, of mijn eigen (net als Transip, gebruik ik ook KVM voor virtualisatie) virtuele systemen die op mijn LAN gehost worden.

De VPS zoals deze door Transip is opgeleverd, is voorzien van een 50 GB harddisk. Hopelijk is straks na de pilot het mogelijk om meer storage te krijgen, bijvoorbeeld via NFS of iSCSI.

Conclusie: dit zou wel eens een blijvertje kunnen zijn, als de prijsstelling mij een ‘beetje’ aanstaat 🙂

Nieuwe achterband :: Michelin Pilot Power 2CT

Gisteren heb ik bij Motorsport Klazienaveen de Z1000 laten voorzien van een nieuwe Michelin Pilot Power 2CT achterband. De kilometerstand stond bij het omleggen op 22617, dus heb ik ruim 8500 kilometer met deze band gedaan. Voor een MPP 2CT op een 128 pk sterk apparaat die gebruikt wordt zoals het hoort, is dat helemaal geen gekke waarde.

Het achterwiel heeft nu meteen een haaks ventiel gekregen, dat waren we bij aanschaf vergeten. Bij de volgende bandenwissel zal het voorwiel ook een haaks ventiel krijgen. De volgende bandenwissel zal zeer waarschijnlijk een complete set gaan worden.

winterstalling 2010-2011

Gisteren was het weer zover, eindelijk weer een temperatuur waarbij ik die kleine stukjes rubber wel durf toe te vertrouwen aan het asfalt. De motor stond bij Motorsport Klazienaveen in de winterstalling en was netjes voor mij klaargezet, zodat ik meteen op kon stappen en wegrijden.

‘s Middags heb ik samen met een andere (zwarte) Z1000 rijder een stuk gereden, we zijn binnendoor naar Assen gereden, maar met 12 graden was het nog goed fris!. Vandaag het textiel pak aangedaan. Ook al is die te groot, met wat aansnoeren draagt deze met de huidige temperaturen toch iets fijner 🙂

Na het ritje van vanmiddag staat de kilometerstand op 21405 en zag ik dat de achterband zijn langste tijd heeft gehad. Die zal voor de trip van de Eifel nog vervangen moeten worden. Er ligt nu een Michelin Pilot Power 2CT onder die mij erg goed is bevallen, alleen zou hij wel iets langer mee mogen gaan. Toch kijken naar een Michelin Pilot Road?? We zullen zien…