Integrating a Grünbeck SD water softener into openHAB

In the wish to integrate our Grünbeck water softener softliQ:SD18 into openHAB I tried the existing community binding with unfortunately no success. So I chose the MQTT way with the help of ioBroker. The way data transits from our water softener to openHAB might not be as straightforward as a direct binding, but it works just fine.
The data arrives in openHAB through the following workflow:
Water-softener => Grünbeck cloud => ioBroker => MQTT broker => openHAB
This might sound complicated, but in fact it is not. It just assumes certain requirements.

Requirements

To integrate data from your water softener into openHAB, you need to have the following appliances set up:

1. Connect ioBroker to the Grünbeck cloud

In order to receive data from your Grünbeck cloud in ioBroker, you have to install the Grünbeck adapter in ioBroker. In ioBroker, click on Adapter and search for Grünbeck. Just hit the vertical three dots and then click the “+”-sign.

ioBroker add Grünbeck adapter

Now go to the Instances tab and fill in your connection data to the Grünbeck Cloud. Your Grünbeck Cloud Username and password are sufficient if you use an SD device.

ioBroker configure your Grünbeck instance

2. Connect ioBroker to your MQTT broker

Install the MQTT-client adapter in ioBroker in the same way you did for the Grünbeck cloud adapter.

ioBroker add MQTT-client adapter

Configure the access data for your MQTT broker in the newly installed MQTT-client instance. MQTT broker IP-address and port are sufficient, if you do not use authentication.

ioBroker configure your MQTT client instance

3. Send your Grünbeck data to the MQTT broker

Now you have to tell ioBroker which information from the Grünbeck adapter you want to have sent to your MQTT broker. If your Grünbeck adapter is correctly configured, your object list should show similar data points like these:

ioBroker objects: available Grünbeck data points

The first subfolder under softliQ gives you information about your device (I hid the name of the folder as it is the serial number of the device). In my installation, this folder includes three subfolders named Stream, measurements and parameters. You have to browse these folders and find out what the different objects mean.

Let’s say you want to have the water counter sent to your openHAB instance. The Stream subfolder includes an object named mcountwater1. This object is the water counter (in liters). You have to click on the gear at the end of the line listing this object (see selected line in the above screenshot).

Object settings for mcountwater1

You should see a menu point for your MQTT client (probably mqtt-client.0, if you have only one MQTT client defined). Define a Topic for this object and activate it. You can freely make the topic tree in MQTT fit to your needs. ioBroker suggests quite a long one based on the structure in the object list. I prefer to reduce the number of subtopics to make it more easily readable.

After saving the MQTT info, your MQTT browser (I use MQTT Explorer) should show the requested data in a few seconds. The following two images show what data points are available in the Stream folder and general folder for my SD18.

ioBroker Grünbeck Objects / data points (part 1)
ioBroker Grünbeck Objects / data points (part 2)

4. Configure openHAB to import the Grünbeck data from the MQTT broker

To read MQTT telegrams in openHAB, you need to install the MQTT binding. Go to openHAB’s administration settingsAdd-ons: Bindings and install the MQTT binding.

To start, you need to add an MQTT Broker bridge. Go to the things tab and add a thing based on the MQTT binding. Select MQTT Broker. Give it a name (example: MQTT bridge). Enter the IP address of the MQTT broker. Save.

Now add a Generic MQTT Thing. Give it a name (example: Grünbeck water softener) and link it to the above created bridge. Save. We will use this thing to centralise all Grünbeck data from our water softener.

Now select the Channels tab in the thing you just created. Click on Add channel and enter for the MQTT State Topic the Topic information you defined in the MQTT settings for your Grünbeck object in ioBroker. If you like, you can add your Unit of Measurement (Show advanced). Click Done.

Channel for mcountwater1 in openHAB

Now add a Link to an item to this channel.

Item associated to the mcountwater1 channel

Now your item should show the amount of water treated by the water softener.

The item should show the value received through MQTT and ioBroker from your Grünbeck Cloud

Add all the channels that you need and integrate the items to your sitemap in openHAB.

Installing SearXNG

If you want to use a meta-search engine that does not track you, SearXNG is an excellent possibility.

To install SearXNG on Ubuntu, I chose to go the docker way described in the official instructions. Unfortunately, I run into some issues, thus deciding to setting up this extended tutorial. I assume you have docker and docker-compose installed.

Step 1: Get searxng-docker

cd /usr/local
git clone https://github.com/searxng/searxng-docker.git
cd searxng-docker

Step 2: Set hostname

Edit the .env file living in the root foled. Be aware that it is hidden. to see the file, you need to use ls -la. Edit the file with: nano .env

# By default listen on https://localhost
# To change this:
# * uncomment SEARXNG_HOSTNAME, and replace <host> by the SearXNG hostname
# * uncomment LETSENCRYPT_EMAIL, and replace <email> by your email (require to create a Let's Encrypt certificate)

SEARXNG_HOSTNAME=searxng.mysite.com
LETSENCRYPT_EMAIL=myaddress@mysite.com

Step 3: Generate your secret key.

sed -i "s|ultrasecretkey|$(openssl rand -hex 32)|g" searxng/settings.yml

You can see your new key in searxng/settings.yml .

Step 4: Adjust IP & port

To change the IP address and port, you need to edit the docker-compose yaml file.
nano docker-compose.yml.
Find the searxng chapter and change the 127.0.0.1:8080/8080 to whatever you prefer. Leaving the standard values (with no port collisions) left me without the ability to access the searXNG engine. So I replaced 127.0.0.1 by 0.0.0.0.

  searxng:
    container_name: searxng
    image: searxng/searxng:latest
    networks:
      - searxng
    ports:
     - "0.0.0.0:8888:8080"

Step 5: Bring searXNG up

Check that everything is working

docker-compose up

Start the daemon in the background with:

docker-compose up -d

If you want your searXNG engine to start on boot you need to start it with systemd.

cp searxng-docker.service.template searxng-docker.service
systemctl enable $(pwd)/searxng-docker.service
systemctl start searxng-docker.service

Run through reverse proxy (optional)

To avoid using a port number in the URL, I have my NGINX reverse proxy forwarding all requests to the docker image. As I then ran into the “too many requests” error, I had to set the limiter to false in the searxng/settings-yml file . If you want to run your instance outside your intranet, you should definitely protect your searXNG instance with an authentication method to avoid having your server flooded with un uncontrollable amount of requests.

searXNG accessed through reverse proxy

To see what containers are running

docker container list

It should list your searXNG container:

CONTAINER ID   IMAGE                     COMMAND                  CREATED             STATUS              PORTS                    NAMES
YOUR_ID        searxng/searxng:latest    "/sbin/tini -- /usr/…"   43 minutes ago      Up 43 minutes       0.0.0.0:8888->8080/tcp   searxng     

Consulting log files

To display the logs of all your running containers, use:

docker-compose logs -f

If you want to only display the logs of one of the specific containers used for searXNG, use one of the following commands:

docker-compose logs -f caddy
docker-compose logs -f searxng
docker-compose logs -f redis

Updating searXNG

To update your searXNG instance, do the following:

docker-compose pull
docker-compose down
docker-compose up

Integrating a Buderus boiler into openHAB

In search to connect our Buderus boiler (heating, warm water system, hot water solar panels) to openHAB, I stumbled over an EMS gateway developed by a dutch engineer.

1. Installing the EMS gateway

I ordered the Wifi edition and connected it via the mini-jack cable to the boiler system. The boiler system also delivers power to the gateway over this cable.

EMS gateway dashboard

The connection to the WIFI network was straight forward (chapter 8.1 of the manual) and the gateway automatically detected all the devices connected to our boiler. It immediately started displaying live data from the boiler.

2. Setting up an MQTT broker

We will use MQTT to send the boiler data to the openHAB system: the EMS gateway will send the boiler data to the MQTT broker which relays it onto the network. openHAB then needs to listen to this telegrams and interpret them.

Installing Mosquitto in an ubuntu VM was straight forward:

sudo apt-get install mosquitto mosquitto-clients

If you run the MQTT broker behind a firewall, it might not be necessary to force authentication. Entering the IP address and port of the MQTT broker in the gateway was straight forward. Do not forget to define a base, a kind of a channel on which MQTT will broadcast your telegrams. I chose ems-esp. The gateway then immediately began sending the boiler data to the broker.

3. prepare openHAB to receive and treat the incoming data

3a: Go to openHAB’s administration settings, Add-ons: Bindings and install the MQTT binding.

3b. Go to openHAB’s administration settings, Add-ons: Other Add-ons, Transformation Add-ons and install the JSONPATH Transformation.

4. Configure openHAB to receive the MQTT telegrams

4a.1: From this step on, you can either add a “HomeAssistant MQTT Component” which auto-detects all EMS things. In order for this to work, you need to activate the “MQTT Discovery (Home Assistant, Domoticz)” in the MQTT settings in the EMS gateway.

4a.2: I decided to go the manual way to have full control over the things and items to add to openHAB.
You need to add an MQTT Broker bridge. Go to the things tab and add a thing based on the MQTT binding. Select MQTT Broker. Enter the IP address of the MQTT broker. Save.

4b. Then add a Generic MQTT Thing. I linked it to the above created bridge. To have a better overview, I created a generic thing for the boiler, one for the warm water and one for the solar data.

4c: Now you have to add the data points that you want to import into openHAB as items. If you don’t know which data points are available, use an MQTT Explorer to get a better insight into your data.

MQTT Explorer showing warm water telegrams
MQTT Explorer showing warm water telegrams (EMS-ESP version 3.7.1)

4d: For each data point, you need to define a channel in openHAB. Open the MQTT generic thing that you created, click on the channel tab, and click add channel. Add the channel identifier, the label and select the corresponding channel type. In our example, we select Number Value, as we want to catch a temperature value.

First step creating the channel

The MQTT State Topic‘s first part is the base that you defined in the MQTT broker settings in the EMS gateway. In our case: ems-esp. The second part of the topic gives more details about the object you want to catch. Your MQTT explorer will help you determine which information telegrams are available.

In order to precise which value of the current object you want to import, you have to click the Show advanced check box.

Second step to precise the value you want to catch

As the object information is received in JSON format, you have to use JSONPATH Transformation to catch the exact value that you need (do not forget to install the JSONPATH tranformation, see 3b above). In our case, enter JSONPATH:$.curflowtemp under Transformation Values: Incoming Value transformations. This will extract the value for the current flow temperature object in the ems-esp/boiler_data telegram. As this is a temperature, you can add the Unit of Measurement if you want. In our case it is in Celsius degrees, so we add °C here.
Click CREATE if you have entered all the necessary information.

Note: Since EMS-ESP firmware version 3.6.5, the data structure has partially changed. The boiler_data_ww does not stipulate WW anymore, but it adds a nested folder called DHW. Adapt the JSONPATH like this: JSONPATH:$.dhw.flowtempoffset .

Now you have to link the channel to an item (click: Add link to Item). This is standard openHAB procedure. As soon as you save the item that you created/linked, the value will show up!

You have to repeat the step 4d for each data point you want to import.

Apache2: create Let’s encrypt certificate for SSL

Install the certbot:

apt install certbot python3-certbot-apache

Set the following in your vhost conf file:

ServerName mydomain.com
ServerAlias www.mydomain.com

Verify that your configuration is fine:

sudo apache2ctl configtest
sudo systemctl reload apache2

Make sure the dns entry in the external dns server points to your proxy server/web-server. Then launch the certification process:

sudo certbot --apache
sudo systemctl status certbot.timer
sudo certbot renew --dry-run

Note: nots ure about the last commands. Needs to be retested.

NGINX: create Let’s encrypt certificate for SSL

Before enabling SSL, make sure your vhost has been activated ( see instructions here: https://gilbert.busana.lu/?p=165 ).
If let’s encrypt’s certbot is not installed, proceed here:

sudo apt install certbot python3-certbot-nginx

To install the let’s encrypt certificate, you need to have your external DNS server pointing to your reverse-proxy/web-server. To install the certificates and have certbot modify your vhost config file for you, do:

sudo certbot --nginx -d www.mydomain.com

If failed, try:

certbot install --cert-name www.domain.com
nginx -t
systemctl restart nginx

If everything went well, your certificate is saved at: /etc/letsencrypt/live/www.mydomain.com/fullchain.pem
The key is saved at: /etc/letsencrypt/live/www.mydomain.com/privkey.pem
Certbot also modifies your vhost vonfiguration file and adds SSL on port 443 and redirects unencrypted (http) traffic to secure sockets (https). Check your configuration file here: /etc/nginx/sites-enabled/www.mydomain.com

NGINX: display reverse proxy headers

If you are having trouble with a web application sitting behind a reverse proxy, debugging can be facilitated by having your (backend) web-server displaying the headers that it receives.

<?php
echo “<h1>Headers received from the reverse proxy</h1>";
$headers =  getallheaders();
foreach($headers as $key=>$val){
  echo $key . ': ' . $val . '<br>';
}
?>
Commandparameter 1parameter 2output
proxy_set_headerX-Real-IP$remote_addr;IP Address of client
proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;IP Address of client
proxy_set_headerX-Forwarded-Host$server_name;called vhost
proxy_set_headerX-Forwarded-Proto$scheme;https or http
proxy_set_header
Header commands and outputs

If you want to test how your page and headers look like from outside, call it from a site like https://testlocal.ly .

NGINX: HTTP basic authentication

The ngx_http_auth_basic_module module allows limiting access to resources by validating the user name and password using the “HTTP Basic Authentication” protocol.
Access can also be limited by address. Simultaneous limitation of access by address and by password is controlled by the satisfy directive.
Add the following to the vhost config file to limit access:

location / {
    auth_basic           “Restricted access";
    auth_basic_user_file /etc/nginx/passwords/passwords;
}

This enables validation of user name and password using the “HTTP Basic Authentication” protocol. The specified parameter is used as a realm. The special value off cancels the effect of the auth_basic directive inherited from the previous configuration level.
Specifies a file that keeps user names and passwords, in the following format:

# comment
name1:password1
name2:password2:comment
name3:password3

The following password types are supported:

  • encrypted with the crypt() function; can be generated using the “htpasswd” utility from the Apache HTTP Server distribution or the “openssl passwd” command;
  • hashed with the Apache variant of the MD5-based password algorithm (apr1); can be generated with the same tools;

Create password for first user:

htpasswd -c /etc/nginx/passwords/passwords paul

To add an additional user:

htpasswd /etc/nginx/passwords/passwords pierre

To allow per adddress:

location / {
    deny  192.168.1.1;
    allow 192.168.1.0/24;
    allow 10.1.1.0/16;
    allow 2001:0db8::/32;
    deny  all;
}

Allows access if all (all) or at least one (any) of the ngx_http_access_module, ngx_http_auth_basic_module, ngx_http_auth_request_module, or ngx_http_auth_jwt_module modules allow access.

location / {
    satisfy any;
    allow 192.168.1.0/24;
    allow 10.0.X.0/24;
    deny  all;

    auth_basic           "closed site";
    auth_basic_user_file conf/htpasswd;
}

Source: https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html
Source: https://nginx.org/en/docs/http/ngx_http_access_module.html

NGINX: enable configuration

After creating a website or a reverse proxy vhost through the configuration file, the vhost has to be enabled:

ln -s /etc/nginx/sites-available/my.domain.com /etc/nginx/sites-enabled/my.domain.com

You can test the configuration file using the following command:

nginx -t

Do not forget to restart NGINX for the changes to be applied:

systemctl restart nginx

ATTENTION:
Always activate the vhost before generating the let’s encrypt SSL certificates. Failure to do so will result in having the default configuration file to be used which might result in the creation of two different vhosts using the same domain name. This will lead to one configuration being skipped on NGINX startup.