Meter readings from Kamstrup Omnimeter with Pow-K+

Today I finally received my Pow-K+ HAN port reader which I ordered before Christmas as a gift to myself. Also before Christmas, I prepared for this project by sending an e-mail to N1 (my power grid company) requesting the needed encryption keys. Shortly after, I received my GPK 60 and GPK 61 keys and information that they had activated the HAN port on my power meter.

The waiting time was hard, but worth it. I have been very excited about this product, and now I need to share why.

Inside the envelope I found my board:

Front
Back

I immediately realized that I must have made a mistake when I placed my order, since I didn’t have anything to hold or cover this board. Luckily, the STL file for the 3D model is freely available. So I asked a friend for help, who happens to be quite proficient and well-equipped when it comes to 3D printing. So a few hours later I could pick up a nice holder for the board.

Installation

In the meantime I had also received confirmation that this board doesn’t need power from an external source, so can simply be plugged in. Like this (the cable on the picture is not related to this module):

HAN module installed

Configuration

And now the impressive part – the configuration. Through the big hole seen on the picture a small button is accessible. After holding it for a few seconds, the module created its own access point, and I could connect to it and make the initial Wi-Fi configuration from my phone (remembering 192.168.4.1 which I had read in the documentation earlier). So I configured my IoT SSID and nothing more, since I planned to assign a static IP from my DHCP server later when knowing its MAC address.

After restarting from this initial configuration, it connected to my Wi-Fi and I could now go to my PC and finish the configuration (and also restart it after configuring a fixed IP address on my router). This required only very few steps, like entering the GPK 60 key as “Encryption key” and the GPK 61 key as “Authentication key”. I also had to select parity, which for Denmark is 8N1. Already at this point I was able to see some useful live data on the main webpage. Literally it was fully working and showing data within a few minutes from plugging it in for the first time.

Now it was time to configure MQTT so I could integrate the meter with my home automation and start logging values in my database. So I went to the MQTT configuration page and entered the hostname of my MQTT broker, a publish topic (I chose “omnimeter”) and “Raw values (minimal)” as payload. That’s it. On my openHAB server, which is also hosting mosquitto, I could then have a peek at the published data:

mosquitto_sub -h localhost -t omnipower/# -d

So with a few more minutes of configuration in openHAB, I started to receive the data I have been so eager to get access to. Like this – from log perspective:

2022-12-29 22:59:52.667 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Omnipower_RSSI' changed from -61 dBm to -62 dBm
2022-12-29 23:00:02.716 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Omnipower_Phase3_Voltage' changed from 238 V to 237 V
2022-12-29 23:00:02.730 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Omnipower_Active' changed from 540 W to 563 W
2022-12-29 23:00:07.901 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Omnipower_Accumulated' changed from 14510.99 kWh to 14511.57 kWh
2022-12-29 23:00:07.928 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Omnipower_Active' changed from 563 W to 499 W
2022-12-29 23:00:14.096 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Omnipower_Active' changed from 499 W to 569 W
2022-12-29 23:00:22.610 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Omnipower_Active' changed from 569 W to 520 W

For now, no graphs, just integration. And a sitemap as seen from the openHAB Android app:

Sitemap

Conclusion

I’m very impressed by this product because it just works, and without any issues when installing and configuring it. Meter configuration, Wi-Fi configuration and even MQTT just worked without any hassle or problems. Thank you Egil Opsahl and Gunnar Skjold for making this possible, and I can only give my warm recommendation of this product.

Oh, I forgot to mention that Pow-K+ will receive data every 10 seconds and can be purchased for approximately a third of the price of a SmartMe HAN module which has a cloud dependency (basically making it an inferior product). And it’s Open Source!

Hunter Douglas PowerView API documentation

Take a GitHub issue comment. Add some stubbornness. And months later be ready to publish a 28 page document. I didn’t see that coming. But here we are. Please enjoy, in case you are interested in integrating with the Hunter Douglas PowerView Hub, and find the original document PowerView-Hub-REST-API-v2.pdf lacking in terms of what you can do with the PowerView app vs. your options after reading that document. A few examples for quick inspiration:

  • Enable/disable automations.
  • Create scene groups, which can no longer be created from the app. After creating them by using the API, they can still be maintained within the app.
  • Use your repeater LED’s with your motion sensor to create night light.
  • Or maybe use it to catch up with openHAB in the Home Assistant integration. 🙂

Connected mousetrap

Bothered by mice living in our attic, we have set up simple mousetraps and caught multiple mice every winter. This has spawned two problems based on mousetraps not being checked systematically or frequently:

  1. In some cases a mouse has been caught and left for weeks or even months unnoticed. This is a quite undesired discovery when finally checking.
  2. In other cases a mouse has successfully eaten the bait without having been caught. This has (also) left the mousetrap out of function for longer periods.

To accommodate both problems and optimize the “mousetrap operational uptime” I wanted/needed a connected mousetrap. I researched online, but was not able to find any attractive solutions. After complaining about this at a Christmas party, a friend of mine, Thomas Jørgensen, came to the rescue with a custom-made hardware solution.

Hardware and configuration

It is based on a microcontroller connected to a HAT on a Raspberry Pi Zero WH which acts as a gateway for this custom long-range RF communication:

The sensor will register any movement. So I just let it touch my old-fashioned mousetrap, and when the trap is moving, the sensor will be triggered and send a small packet to the Raspberry Pi Zero WH.

The Pi will listen to serial communication with a small Python script and receive a small JSON payload from the microcontroller:

{
	"sensortype": "mousetrap",
	"messageid": "10",
	"guid": "0x00000001",
	"seq": "27",
	"status": "0x01",
	"mousecount": "134",
	"batteryvoltage": "304",
	"temperature": "20",
	"rssi": "-57",
	"snr": "11",
	"freq": "868900",
	"freq_error": "-1246",
	"sf": "10",
	"bw": "125"
}

The script will parse this and use MQTT to inform openHAB about any state changes for mousetrap triggered, temperature and battery voltage (converted to approximate level in percent). Every seven hours a payload will be sent even if sensor wasn’t triggered. This is quite battery-optimized and also makes it possible to monitor if it’s operating correctly, temperature and remaining battery life.

Notifications

Rules implemented in openHAB makes sure I get notifications when:

  • The mousetrap has been triggered (on cellphone and TV).
    • On cellphone a picture will be included (from a Hikvision surveillance camera).
  • It has been more than sevens hours since last payload was received.
  • When payload has been received again after previously missing.
  • When battery is low.

A notification could look like this:

Power consumption

The Raspberry Pi Zero WH with HAT uses ~0.6 W in this configuration. It’s connected through Wi-Fi, not Ethernet.

Statistics

I started using this setup in October 2020. Since then caught 3-4 mice and quickly reloaded traps at least as many times without a successful hit. The last part is important as this increases the chance of actually catching the small rodents when traps are always operational and loaded with bait.

LK Fuga Wiser Wireless Dimmer hands-on

Lauritz Knudsen by Schneider Electric just released a range of new ZigBee-based products for the Danish market, and today I got my hands on the LK Fuga Wiser Wireless Dimmer:

LK Fuga Wiser Wireless Dimmer as shown everywhere.

This dimmer is ZigBee-certified and should work with any ZigBee-gateway (like Philips Hue or IKEA Trådfri) as well as their own Wiser Gateway, which was also introduced in Denmark this week. And which, by the way, seems to be replaced soon by this Wiser Basic Hub.

My expectation is that this dimmer should identify itself as a dimmable light and work the same way as a Sunricher dimmer or any Philips Hue, IKEA TrÃ¥dfri, Osram Smart+ or other dimmable ZigBee bulb. In other words, I would not expect any problems adding this dimmer to my Philips Hue bridge. So let’s see if my expectations will be fulfilled…

Experimental set-up

Pairing the device with Philips Hue bridge was painless. After three fast clicks on upper left button, it was found by the bridge as a dimmable bulb. Perfect. Now tried to control the connected LED bulb through the Philips Hue app and experienced some weird behavior: Light cannot be switched off! It can be switched on and dimmed up and down without much delay, but it can’t be switched off. When using the buttons on the dimmer to control the light, there is some delay until reflected in Philips Hue, but this is somewhat expected. Within a minute it will be there.

Compatibility/integration

Now decided to investigate this switching off issue a bit more, so added the dimmer to openHAB through the Hue API to monitor exact values with timestamps etc. and try to control it with specific values. It turns out that using openHAB I was able to switch it off by simply setting brightness to 0 like any dimmable light.

So without openHAB, I thought, will I be able to somehow switch it off from within Hue itself? I configured one of my Friends of Hue switches to control the dimmer, and without any problems was able to turn it on as well as off.

Last, I tried configuring a Philips Hue motion sensor for controlling the room where I added the dimmer. This doesn’t work either. Just before it’s about to switch it off, Hue dims a tiny bit as a warning. This part works, but it stays like that and doesn’t switch off.

So it seems that the problem is a very specific compatibility issue with the Philips Hue app and accessories – perhaps some slight difference in the way it turns off lights and dims to 0%. I have ruled out my bridge/configuration since the same problem has been reported by others. LK Dimmer FW version: 001.002.021.R.

Digging deeper

In openHAB the dimmer is represented by a single item, Brightness. However, this kind of item can be used as a dimmer/slider as well as a switch. So in a sitemap I tried to create both types to be able to compare the difference, since dimming to 0% actually works. Here is the result:

Switch it on:

2021-03-07 15:37:26.109 [INFO ] [openhab.event.ItemCommandEvent ] – Item ‘Wiser_Brightness’ received command ON
2021-03-07 15:37:26.129 [INFO ] [penhab.event.ItemStatePredictedEvent] – Item ‘Wiser_Brightness’ predicted to become ON
2021-03-07 15:37:26.136 [INFO ] [openhab.event.ItemStateChangedEvent ] – Item ‘Wiser_Brightness’ changed from 0.0 to 100

Swith it off – this didn’t work:

2021-03-07 15:37:35.408 [INFO ] [openhab.event.ItemCommandEvent ] – Item ‘Wiser_Brightness’ received command OFF
2021-03-07 15:37:35.427 [INFO ] [penhab.event.ItemStatePredictedEvent] – Item ‘Wiser_Brightness’ predicted to become OFF
2021-03-07 15:37:35.434 [INFO ] [openhab.event.ItemStateChangedEvent ] – Item ‘Wiser_Brightness’ changed from 100 to 0

Dim it to 0%, effectively switching it off (this worked):

2021-03-07 15:37:43.178 [INFO ] [openhab.event.ItemCommandEvent ] – Item ‘Wiser_Brightness’ received command 0.0
2021-03-07 15:37:43.194 [INFO ] [penhab.event.ItemStatePredictedEvent] – Item ‘Wiser_Brightness’ predicted to become 0.0
2021-03-07 15:37:43.217 [INFO ] [openhab.event.ItemStateChangedEvent ] – Item ‘Wiser_Brightness’ changed from 100 to 0.0

Did you notice the difference? When setting brightness to “0”, nothing happened. When setting it to “0.0” it works. This should give some indication of the type of bug/incompatibility. Until Lauritz Knudsen hopefully fixes this issue, this can be used as temporary work-around in openHAB:

rule "Wiser work-around"
when
    Item Wiser_Brightness changed to 0
then
    Wiser_Brightness.sendCommand("0.0")
end

This will detect all attempts to switch off the dimmer, also attempts made by accessories like a motion sensor.

Update, March 16th 2021: Although the description above might give some indication about the problem, it’s still only that – an indication. Today I decided to investigate a little deeper to be able to understand the problem without distraction from openHAB. So I created a Hue Developer account to access the Hue documentation and tested directly using the Hue API. Here’s my new finding – this doesn’t work:

URL: /api/<username>/lights/<id>/state
Method: PUT
Body: {"on":false}

But with this body, it works:

{"on":false, "transitiontime":0}

It seems to work with any transitiontime value. As documented:

The duration of the transition from the light’s current state to the new state. This is given as a multiple of 100ms and defaults to 4 (400ms). For example, setting transitiontime:10 will make the transition last 1 second.

To be very specific: It turns off almost immediately with 0, and in 400 ms with the value 4. This is supposed to be the default value, but without it, it doesn’t work. So the Hue app most likely doesn’t include transition time when using the on/off switch, and the same seems to be the case for openHAB. I believe I found the explanation in the binding source code:

           case CHANNEL_BRIGHTNESS:
                if (command instanceof PercentType) {
                    newState = LightStateConverter.toBrightnessLightState((PercentType) command);
                    newState.setTransitionTime(fadeTime);
                } else if (command instanceof OnOffType) {
                    newState = LightStateConverter.toOnOffLightState((OnOffType) command);
                } else if (command instanceof IncreaseDecreaseType) {
                    newState = convertBrightnessChangeToStateUpdate((IncreaseDecreaseType) command, group);
                    if (newState != null) {
                        newState.setTransitionTime(fadeTime);
                    }
                }

So when brightness is set from a switch (OnOffType), the transitionTime attribute is not set, thus it will not work.

With this knowledge work-arounds are possible, although no generic work-around that would fix all integrations. For example for a Hue motion sensor, transitiontime can be added through the Rules API (this has been tested and works):

URL: /api/<username>/rules
Method: POST
Body:
{
     "name": "Wiser motion sensor work-around",
     "conditions": [
         {
             "address": "/sensors/1/state/presence",
             "operator": "eq",
             "value": "false"
         }
     ],
     "actions": [
         {
             "address": "/lights/1/state",
             "method": "PUT",
             "body": {
                 "on": false,
                 "transitiontime": 0
             }
         }
     ]
 }

Update, November 23rd 2021: I’ve created a workaround in the Hue binding in openHAB: https://github.com/openhab/openhab-addons/pull/11572 – it will be included in release 3.2, but a JAR file is also available, and it can be used with 3.1 installations. With this fix, everything works from openHAB, but of course each integration (including the Philips Hue app) will need to provide own workarounds until the LK Wiser bug is fixed.

Power consumption

No post without some mentioning of power consumption. Measured switched off over 24 hours with SparOmeter it used 0.009 kWh, so just below 0.4 W in average. This is exactly as specified in the manual with 0.4 W as max. power consumption. Sunricher dimmer box in comparison uses 0.015.kWh in 24 hours, i.e. roughly 0.6 W.

Dimming characteristics

This is probably a difficult topic with a lot of compatibility concerns, but it’s important to know how well this dimmer can actually dim. I don’t have the equipment or knowledge to measure this. I used an IKEA 1000 Lumen LED bulb for testing, and it went from ~15 W to 3.4 W when fully dimmed. In comparison, a Sunricher dimmer was able to dim below 1 W. The bulb used in my test can only be dimmed to ~2.6 W, after that it starts flickering and eventually it will turn off. However, to be able to dim this much, the minimum level should be configurable. This does not seem to be the case with this LK Dimmer, at least not by using the buttons (when not using their own Wiser gateway).

For the same bulb the LK Touch LED 180 IR will dim this bulb to 4.0 W, so here Wiser is a slight improvement.

Price

This dimmer is the most expensive dimmer I have ever seen. LK LED Touch is cheap in comparison, so is IHC Wireless in general. I really hope prices will drop sooner than later in order to sell more. I bought one after waiting for a product like this for years, but won’t be buying more until prices will drop. The same goes for the double relay switch. At the time of writing, the cheapest I have been able to find has a price tag of 899,- DKK.

Functionality

Unfortunately, and this is also the reason for the price tag, almost no competition exists. This is only because of the small Danish market for LK Fuga design. Currently, this is the best solution on the market for LK Fuga, if:

  • You don’t have anywhere to put a Sunricher (or similar) dimmer.
  • You want to be able to control your light through ZigBee and using a wall switch (without the wall switch taking your light offline).
  • You want to be able to control your light always, even when your gateway is down or wireless signal is disturbed.
  • You want to be able to control your light without any concern about batteries running low.
  • Until switching off bug is fixed: Replace “ZigBee” by “Wiser app”.

Conclusion

I have wanted this product for years. Now that it’s here, I wish it would work better with Philips Hue, and I wish I could use it everywhere in my house. Unfortunately I can’t/won’t because of the price tag. Summary:

  • Price: Too high.
  • Software: Too buggy (switching off doesn’t work).
  • Dimming: Can’t dim as much as some other dimmers on the market, and minimum level can’t be configured.

If LK would fix the problem of not being able to turn off the dimmer without supplying transition time, this would actually be a pretty decent product. Pricey, but decent, and I would instantly install this dimmer in my family room for controlling our PH5 lamps.

Velux Active KIX 300 integration

It’s been a while since my last post, so just a short one this time. I invested in VELUX ACTIVE with NETATMO in 2019 for controlling my skylights. I knew it was a cloud-based solution with all its cons, and even without any API for integration. This obviously sucks, but suddenly ClientID and ClientSecret was published in an openHAB Community thread, so I no longer had the excuse that I didn’t want to spend time reverse engineering the APK for Android. Now it was just a matter of implementing an integration.

Since I didn’t have experience with Python yet, I decided I wanted to try to use that for an implementation. It was my impression that it had everything I needed: HTTPS, JSON and MQTT. And I was right, so after 90 minutes of google-coding, this is my implementation for fetching my data from my sensor switch (CO2, temperature and humidity). Implementation is based on https://github.com/nougad/velux-cli.

First script is run to get a token which will be used for authentication. Script will ask for the password for the corresponding Velux account:

#!/usr/bin/python3

import getpass
import requests

URL='https://app.velux-active.com/oauth2/token'

# From Android app reverse engineering
CLIENT_ID=''
CLIENT_SECRET=''

# My account
USERNAME='veluxaccount@email.address'

try:
        password = getpass.getpass()
except Exception as error:
        print('Error:', error)

data = {
        'grant_type': 'password',
        'client_id': CLIENT_ID,
        'client_secret': CLIENT_SECRET,
        'username': USERNAME,
        'password': password,
        'user_prefix': 'velux'
}

response = requests.post(URL, data=data)

if response.status_code == 200:
        file = open('token.json', 'w')
        file.write(response.text)
        file.close()
else:
        print('Error:', response)

A file ‘token.json’ will be saved in current directory. Next script will refresh the token, so this must be run once per every few hours. I don’t remember exact expiration period, but it’s in the response.

#!/usr/bin/python3

import json
import requests

URL='https://app.velux-active.com/oauth2/token'

# From Android app reverse engineering
CLIENT_ID=''
CLIENT_SECRET=''

file = open('token.json', 'r')
body = file.read()
file.close()

token = json.loads(body)

data = {
        'grant_type': 'refresh_token',
        'refresh_token': token['refresh_token'],
        'client_id': CLIENT_ID,
        'client_secret': CLIENT_SECRET
}

response = requests.post(URL, data=data)

if response.status_code == 200:
        file = open('token.json', 'w')
        file.write(response.text)
        file.close()
else:
        print('Error:', response)

And finally this last script is run every 5 minutes which seems to be the frequency for new measurements:

#!/usr/bin/python3

import json
import requests
import paho.mqtt.client as mqtt

URL='https://app.velux-active.com/api/homestatus'
MQTT_BROKER='192.168.0.236'
HOME_ID='your_home_id'

file = open('token.json', 'r')
body = file.read()
file.close()

token = json.loads(body)

data = {
        'access_token': token['access_token'],
        'home_id': HOME_ID
}

response = requests.post(URL, data=data)

if response.status_code != 200:
        print('Error:', response)
        exit()

data = json.loads(response.text)
home = data['body']['home']
rooms = home.get('rooms')

if rooms:
        room = rooms[0]
else:
        print('Unexpected response:', response.text)
        exit()

client = mqtt.Client()
client.connect(MQTT_BROKER)

client.publish('velux/hallway/co2', payload=room['co2'], qos=0, retain=False)
client.publish('velux/hallway/humidity', payload=room['humidity'], qos=0, retain=False)
client.publish('velux/hallway/temperature', payload=(room['temperature']/10), qos=0, retain=False)
client.publish('velux/hallway/lux', payload=room['lux'], qos=0, retain=False)

for module in data['body']['home']['modules']:
        if module['type'] == 'NXD': # Departure switch
                client.publish('velux/departure_switch/battery_percent', payload=module['battery_percent'], qos=0, retain=False)
        if module['type'] == 'NXS': # Sensor
                client.publish('velux/sensor1/battery_percent', payload=module['battery_percent'], qos=0, retain=False)

In openHAB I have configured a thing to receive these MQTT updates, so I have them persisted in MySQL, shown in sitemaps, etc.

Homemade Smart Power Strip

This post is not a hardware post, but just a simple way to use a smart plug to replace a conventional smart power strip to avoid unneeded standby power consumption. For my home entertainment system I previously used a conventional smart power strip, but it caused several crashes of my media center, a Raspberry Pi running Kodi. So I decided to replace it with a standard power strip connected to a smart plug, and let openHAB do the magic.

I decided to use a ZigBee smart plug due to low power consumption and since already having a Philips Hue bridge within range. I went with an Innr smart plug, since the Philips Hue smart plug hadn’t been introduced at the time.

As trigger for turning power on or off, I went with my Harmony Hub. This way I can also turn off the network switch, since the Hub is Wi-Fi connected. When any activity is started, requiring any of the powered off devices, I’ll simply turn on the smart plug. When powering off, I need Kodi to shutdown and wait for this. So here are the rules I ended up with:

rule "TV turn on socket"
when
    // This is logically correct, but too slow because it's only fired when
    // activity has completed. It's a fallback solution because of a bug in
    // the binding, see below.
    Item HarmonyHub_CurrentActivity changed from "PowerOff" or
    // These channel triggers are fast, but logic is messy because logic
    // cannot be reversed. The correct solution would be to trigger on an item
    // bound to "Activity Starting Trigger" and use same logic as above:
    // Item HarmonyHub_ActivityStartingTrigger changed from "PowerOff"
    Channel "harmonyhub:hub:HarmonyHub:activityStarting" triggered Watch_tv or
    Channel "harmonyhub:hub:HarmonyHub:activityStarting" triggered Listen_to_music or
    Channel "harmonyhub:hub:HarmonyHub:activityStarting" triggered Watch_a_movie or
    Channel "harmonyhub:hub:HarmonyHub:activityStarting" triggered Kodi or
    Channel "harmonyhub:hub:HarmonyHub:activityStarting" triggered Chromecast
then
    Tv_Socket_Switch.sendCommand(ON)
end

rule "TV turn off socket"
when
    Item HarmonyHub_CurrentActivity changed to "PowerOff"
then
    var num_of_attempts = 20
    var delay_between_attempts = 5000
    var attempt = 0

    var kodi_initial_online_state = NetworkDeviceKodi_Online.state

    // Waiting for Kodi (might be booting up)
    while (NetworkDeviceKodi_Online.state == OFF && attempt < num_of_attempts)
    {
        attempt = attempt + 1
        Thread::sleep(delay_between_attempts)
    }

    if (NetworkDeviceKodi_Online.state == OFF)
    {
        sendPushMessage.apply("Tv turned off", "Kodi is offline. Something wrong?")
    } 
    else if (kodi_initial_online_state == OFF)
    {
        // Initial state offline, now online - waiting for services to start"
        Thread::sleep(30000)
    }

    if (HarmonyHub_CurrentActivity.state == "PowerOff")
    {
        // Attempting to shut down Kodi
        sendHttpPostRequest('http://pi3:80/jsonrpc', 'application/json', '{"jsonrpc":"2.0","method":"System.Shutdown","id":1}')
        Thread::sleep(30000)

        // Waited 30 seconds, checking if activity didn't start again
        if (HarmonyHub_CurrentActivity.state == "PowerOff")
        {
            Tv_Socket_Switch.sendCommand(OFF)
        }
        else
        {
            sendPushMessage.apply("Tv turned off", "Tv turned on again after Kodi was shut down - now offline. Trying to restart.")
            Tv_Socket_Switch.sendCommand(OFF)
            Thread::sleep(5000)
            Tv_Socket_Switch.sendCommand(ON)
        }
    }
    else
    {
        // Shutdown/power off aborted, new activity started.
    }
end



I might look over-complicated, but I wanted a defensive approach to make sure everything is done to not trigger data corruption when power is taken from the Kodi Pi without proper shutdown. For example, if the Pi is still booting when TV is turned off, it won’t be able to accept a shutdown command yet, so I’m waiting for it to complete booting. Also, in case the TV is turned on again while the Pi is shutting down, I try to boot it again by turning it off and on again.

Lock YouTube

Inspired by my own LockU2 utility and Useless Box, I came up with a simple and stupid, yet effective, openHAB rule to prevent my kids from watching YouTube when they are not allowed to do so. So first requirement was ability to turn this lock on or off – just added a new switch item for this, and added it to a sitemap.

The rule makes use of the LGTV binding as well as HarmonyHub binding. Without any of these, I don’t think it would be possible to pull off.

Here goes:

rule "Lock YouTube"
when
    Item LGTV_Application changed to "youtube.leanback.v4" or
    Item LGTV_Application changed to "youtube.leanback.kids.v4"
then
    if (Lock_YouTube.state == ON)
    {
        //HarmonyLGTV_ButtonPress.sendCommand("Exit")
        LGTV_Application.sendCommand("com.webos.app.livetv")
    }
end

rule "Enable Lock YouTube"
when
    Item Lock_YouTube changed to ON
then
    if (HarmonyHub_CurrentActivity.state == "Watch TV" &&
        (LGTV_Application.state == "youtube.leanback.v4" || LGTV_Application.state == "youtube.leanback.kids.v4"))
    {
        //HarmonyLGTV_ButtonPress.sendCommand("Exit")
        LGTV_Application.sendCommand("com.webos.app.livetv")
    }
end

This YouTube blocker won’t actually block the YouTube app on the television, but will instead immediately quit the app once it’s launched. If YouType (or YouTube Kids) is already running when activating the lock, it will also quit the app. Update: Changed to use LGTV binding for quitting YouTube – old method commented out.

I almost couldn’t wait for the premiere which was last Saturday morning. I also have a rule in place for generating notifications when the lock has been triggered. After explicitly instructing my son that YouTube was not allowed that morning, only five minutes later I received the first notification that an attempt was made. After that four more identical notifications. Then a final notification that YouTube Kids had also been attempted. Success.

Playing with openHAB binding for Danfoss Air unit

In summer 2019 we had heat recovery ventilation installed in our house: A Danfoss Air A2 unit with a CCM module connected to our existing Danfoss Link CC Controller. The integration here is pretty useless: The Danfoss Link app can’t do anything other than read outdoor temperature and set vacation mode. Even the Link CC is crippled, compared to the Air Dial – for example it’s not possible to read relative humidity, thus completely impossible to check if the system is running as it should.

A few days after installation I added a WeMo Insight integrated with openHAB, so at least I have logged power consumption data since then. Then in November I finally couldn’t resist installing a network cable to the CCM unit as I saw it having an Ethernet port.

I was able to run the Danfoss HRV PC-Tool and finally read some more data like relative humidity. Naturally, next thing on my mind was reverse engineering of the protocol used. I didn’t have to do much research until I found this openHAB Community thread. Reading through the thread ended with the good news that someone already did all the work and even created an openHAB binding.

Fun

Installing the alpha version of the binding couldn’t be any easier and it worked out of the box without any problems. I linked almost all channels and started seeing and logging useful information like operating mode, fan speeds, boost, humidity, temperatures and remaining filter life.

Next, I could start adding rules to actively monitor how the system was operating. I started getting notifications on my phone when boost was activated to get a feeling about when that usually happens. I could also start making humidity graphs, which got me suspicious about these measurements. Comparing with my Netatmo data from four different indoor stations in the house, the Air unit’s measurements are consistently 5-10 % higher. This of course impacts how the system operates, as humidity is likely the only parameter used for calculating fan speed in “demand” mode.

Energy savings

Next revelation came when I found that some of the channels were writable, like operating mode, manual fan speed and boost. Now this turned into something really useful!

The one thing even the Danfoss Link app can do is set vacation mode when away from the house. This will set the HPV to manual fan speed level 1 which consumes about 9 W. So I figured that this could be automated and also used on weekdays some time after everyone has left the house. I used existing presence logic for that (from Unifi access point), but also decided to add CO2 level as parameter for safety. During the night our phones will also go to sleep at some point, so some additional logic is needed.

Trying to perform humidity/demand calculations like the unit itself does would be cool, but also somewhat more complicated than what I had in mind to begin with. Also, it would require me to integrate some new humidity sensors as I don’t want to rely on Netatmo for this, since data is only refreshed every 10 minutes and also Internet-dependent and Netatmo service-dependent. In other words, untrustworthy. But as safety mechanism for presence-flaws and not needing fast reaction, CO2 measurements could be used.

Nest smoke alarm

I also have a couple of Nest smoke alarms which are integrated in openHAB as I haven’t migrated to Google. So why not use them and trigger boost if smoke is detected?

Rules

So here we go. First, I have a rule that will trigger an Android notification when boost is activated. This includes relative humidity from the Air unit as well as from four different rooms in the house, and includes previous values 20 minutes ago. The rule is too ugly to post, and probably too specific to share anyway, so let’s skip it and go directly to the power-saving rule:

rule "Danfoss control"
when
    Item Anyone_Home changed to ON or
    Item SkynetStationIndoor_Max_CO2 changed or
    Item HomeLeft30MinutesAgo received command OFF
then
    var hasChanged = Anyone_Home.changedSince(now.minusMinutes(29))
    if (Anyone_Home.state == OFF
        && !hasChanged
        && (SkynetStationIndoor_Max_CO2.state as Number).intValue < 500
        && DanfossHRV_Main_Mode.state == "DEMAND")
    {
        DanfossHRV_Main_Mode.sendCommand("MANUAL")
        DanfossHRV_Main_ManualFanSpeed.sendCommand(10)
    }
    else if ((Anyone_Home.state == ON || (SkynetStationIndoor_Max_CO2.state as Number).intValue >= 700)
        && DanfossHRV_Main_Mode.state != "DEMAND")
    {
        DanfossHRV_Main_Mode.sendCommand("DEMAND")
    }
end

SkynetStationIndoor_Max_CO2 is a group with function “MAX” being linked from my four different Netatmo CO2 items. HomeLeft30Minutes ago is a manually created item based on the Expire Binding:

Switch HomeLeft30MinutesAgo { expire="30m,command=OFF" }

Updated from presence.rules:

rule "Anyone home timer start"
when
    Item Anyone_Home changed to OFF
then
    HomeLeft30MinutesAgo.postUpdate(OFF)
    HomeLeft30MinutesAgo.sendCommand(ON)
end

rule "Anyone home timer cancel"
when
    Item Anyone_Home changed to ON
then
    HomeLeft30MinutesAgo.postUpdate(OFF)
end

So this first rule will, in a pretty simple way, just switch to lowest step 30 minutes after everyone left the home and CO2 levels are all below 500. This is a conservative way to take control only when assuming no humidity will be generated. Weakest point is that humidity is not considered at all, so for example when drying clothes indoor, rule might trigger anyway.

Next, the smoke alarm rule (still untested):

rule "Danfoss boost on smoke alarm with oven running"
when
    Item NestProtectFamilyRoom_SmokeAlarmState changed from "OK" or
    Item NestProtectHall_SmokeAlarmState changed from "OK"
then
    if (Oven_Status.state != "Off")
    {
        DanfossHRV_Main_Boost.sendCommand(ON)
    }
end

And last, the filter notification:

rule "Danfoss filter monitoring"
when
    Item DanfossHRV_Service_RemainingFilterLife changed
then
    if (DanfossHRV_Service_RemainingFilterLife.state < 10)
    {
        var body = String::format("Remaining filter life: %d %%", (DanfossHRV_Service_RemainingFilterLife.state as Number).intValue)
        // Use some service to push notification, I use Pushbullet.
    }
end

Of course also added a sitemap section to have some app control, since Danfoss doesn’t provide this (in Danish, but you probably get the idea):

openHAB sitemap

Thanks to pravussum for the binding, which can be found here:

https://github.com/pravussum/openhab2-addons/releases/

Update: Officially integrated into openHAB 2.5.5!

Problem with openHAB UniFi Binding

After upgrading UniFi Controller to version 5.12.35 last week, the openHAB binding started having problems with the Online channel. Going from OFF to ON is still detected correctly, but not the other way around. I’m still not sure if this is a problem in the binding, the controller or in my configuration. Only thing I know for sure is that after upgrading the controller image in Docker and the access point firmware at the same time, binding stopped detected our phones disconnecting from the access point.

openHAB is version 2.5.1. I have asked in the openHAB forums, but is still waiting for feedback.

In the meantime I’ve created a work-around using rules. Problem is that once client goes offline, it seems to be excluded from the list fetched by the binding, and channel stops receiving updates. For LastSeen it makes sense, but Online should be updated to OFF, when client is no longer listed. So I used LastSeen to mimic this desired logic in my rule:

var Timer timerUniFiJacob = null

rule "UniFi work-around Jacob"
when
    Item UniFi_OnePlus5_LastSeen changed
then
    if (Jacob_Home.state == OFF)
    {
        Jacob_Home.sendCommand(ON)
    }

    if (timerUniFiJacob === null)
    {
        timerUniFiJacob = createTimer(now.plusSeconds(180), [ |
            Jacob_Home.sendCommand(OFF)
        ])
    }
    else
    {
        timerUniFiJacob.reschedule(now.plusSeconds(180))
    }
end

This rule simply restarts a 3 minute timer on each LastSeen update. When client goes offline, these updates will stop and after three minutes, item Jacob_Home will be set to OFF.

Luxaflex PowerView roller blinds

In 2018 my girlfriend and I decided to invest in new roller blinds for our living room. We needed to cover six windows right next to each other. Luxaflex offered some appealing designs like Duette and Twist. At the time PowerView motorization wasn’t available for Duette, so we settled with Twist. That sums up the introduction and cosmetic part of this review, so let’s move on to the technical part as this is a technical blog. 🙂

Electrical installation

First challenge was the electrical installation, since the blinds are powered by 18 V DC. Had it been 230 V AC (like Somfy), I could have powered them from a nearby ceiling mount, but this requirement had to be planned carefully. I didn’t want to settle with batteries, as I would have to recharge six blinds something like three times per year. I’m pretty sure this would annoy me more than I would appreciate the motorization. Only option for me was to bore holes in the ceiling and supply power from here.

But that triggered next challenge: Where to place the power supplies? It would have to be somewhere reachable and somewhere near 230 V. As preparation I created a new power socket at the attic. However, ultimately I decided to pull 15 meter 2.5 mm² cable over the ceiling to each pair of motors (so motors to the right, left, right, left, right and left) with individual conductors for each motor. All cables end where I have my electrical installation in another part of the house. Official requirement per motor is 1 A/18 V. This is really to be on the safe side and I decided to go a bit lower than that, so settled with a single Mean Well DR-100-15 for supplying all motors instead of two (after performing some tests and measuring the load) – that’s ~5.4 A.

Installation looks like this:

Luxaflex Twist blinds electrical installation. The lose ends are the antennas.

This year we extended our house, and I of course made sure that we would have 2.5 mm² cables with three conductors inside the wall – for each window. This way I’m in full control, and in the future I will be able to easily replace by 230 V motors if needed. The power supply was upgraded to a Mean Well HDR-150-15 which is now supplying all blinds, including three new roller blinds in the extended part of the house (~8 A in total):

Luxaflex blinds electrical installation.

Quick summary: 18 V is troublesome – separate cables needed from all locations to a power supply. 230 V would have been the better choice for easy installation and less cables.

DC connectors

Now next problem. Standard DC 5.5 x 2.1 mm connectors are used. But the motor doesn’t have an internal connector. Instead it has a small piece of cable (~30 cm) with a male connector on it. So keep that in mind, because that connector needs to be hidden somewhere, and it may have to be able to go through bored holes in the ceiling etc. instead of just the cable itself (which would require a smaller hole).

I had to buy as bunch of these female panel mount connectors to be able to fit them and the male connector inside the housing for built-in mounting in the wall:

RF quality

Since PowerView is wireless, we need to look into the RF implementation/performance. The implementation is proprietary, so no integration possible through ZigBee or Z-Wave. Only Hunter Douglas remotes and Hub can be used. The Pebble remote I bought with the six original blinds performs quite poorly. It litterally needs line-of-sight in order to get transmissions through. If I’m behind a corner in the living room (same room) and want to operate all six blinds at the same time, one or two of the last ones won’t get the signal. So performance is similar to IR.

Luckily the Hunter Douglas Hub (Gen 2) has better range. I initially placed it in my server room, not far from the living room, but still two rooms away. Often one random blind would not receive the command, so I had to move the Hub closer. I first moved it into the same room very close to the blinds. That improved the setup significantly, so most times all blinds would react as they should. However, I was told by support that there’s no feedback from the motors, they just receive 3-5 RF impulses and that’s it. So on rare occations, I can still experience one of the blinds not being in the correct position. This year I moved the Hub on the other side of a wall, and range is still acceptable, but not completely reliable. That’s not quite good enough in my opinion for a product in this price range.

Worst part is that communication is one-way. Not only does it hurt reliability, but also synchronization. If the Pebble remotes are used to operate the blinds directly, the Hub will not be informed, and as a result the state is out of sync. This makes it impossible to create home automation rules based on blind state, or at least it will not work in conjunction with the Pebble remotes.

Hardware summary

A small recap before we move on to the fun part – the software:

  • Voltage: 18 V DC – annoying, but not a showstopper for me.
  • DC connectors not integrated – annoying, but I was able to hide them with some effort.
  • RF proprietary protocol – bad.
  • RF range/reliability – bad, and no work-arounds for this.

Software support

Now the fun part and the reason why I went for Hunter Douglas PowerView back in 2018: I knew that it was supported by Logitech Harmony and also by openHAB. Hunter Douglas also made a nice app to configure and control the blinds through the Hub on local network.

App

The app works pretty decent. It’s not without issues, but overall it does its job. Initially it is used to configure the Hub, i.e. add the blinds, so they can be controlled. It can also be used to create automations like “open blinds 10 minutes before sunset on weekdays”. For most common scenarios, where conditions are not needed, this is sufficient. Automations live on the Hub, so there are no external dependencies. However, if you want blinds to open at sunset or 6:30, whichever comes last, you will have to use home automation like openHAB or interface directly with the API yourself.

openHAB

The openHAB binding works like a charm. It let’s you control/monitor each blind as well as trigger scenes. That’s really everything you need. Configuration is easy with discovery and easy adding of blinds as things.

Logitech Harmony

This integration worked out of the box. The Hunter Douglas Hub was simply added in the Harmony app and after that it was easy to add scenes to hardware buttons on my Harmony Elite remote control as well as include a scene in my Movie activity. This means that all blinds will close when starting the movie activity, and two buttons on the remote are dedicated to trigger open/close scenes.

Scenes can be configured to include any blinds in any individual positions. The downside of using scenes is that the motors are operating at slow speed when triggered from a scene (as opposed to direct commands). This is probably implemented this way because the motors are noisy, so when using automation, it wouldn’t be very discrete. However, I would have preferred this to be configurable, and also that the motors were less noisy.

Conclusion

Overall I’m pretty happy with my setup and I have come to enjoy the automation part more and more, especially as we now have nine motorized blinds in the house. Automations based on sunrise/sunset offsets are really nice and convenient. Most of the time we don’t manually control the blinds anymore, as the automation already did what was needed when it was needed.

RF (lack of) reliability is probably the worst part (apart from the installation) since there is no way to fix it. I wonder how it compares to Somfy.