[HomeConnect]: Elegant solution based on a MQTT bridge. Local (no cloud)

Homeconnect is the system provided by SIEMENS and other brands to connect their appliances.
I have a connected oven and its timer alarm is not very loud. My first automation was very basic: use all available channels (TTS, lights,…) to inform me that time was elapsed. Then when the oven door was open, the alarm was dismissed.
That was before HA, and it was working fine with jeedom.

When I switched to HA, I realized that the offical homeconnect integration was not really up to date (many features non functional with my oven). There is also an alternative integration, but it does not support a basic feature as the timer. I contacted the developer who clearly told me that he was not interested in this feature.

So I started searching for other solutions. IFTTT work with homeconnect API but it’s a paying feature.
Finally I found this article:

And I discovered a very elegant solution : a local bridge relaying all messages from home connect to my MQTT broker. This is a cloudless solution ans it’s a plus as I always prefer local vs cloud.
The source code is here: github.com/osresearch/hcpy

The installation took me a couple of hours as I’m not used to install missing python dependencies etc… and I had to applied mods in the code described in the github. But at the end everything is working fine!
I was surprised to get immediate answer with solution in the issue I posted in the github. Actually all the solutions to my problems were already described in the “pull request” section of the github page. I will be happy to share my files to save you some time.

I installed a very light linux container on proxmod with python.
In HA, just 2 very basic sensors in my configuration.yaml file trigger the automations:

mqtt:
   sensor:
     - name: "Porte four"
       state_topic: "homeconnect/oven/state"
       value_template: "{{ value_json.door }}"
     - name: "Alarme four"
       state_topic: "homeconnect/oven/state"
       value_template: "{{ value_json.alarm }}"

I spent time looking for this solution and I would have been very happy to find a post like this one, that’s why I share it.
I hope you’ll enjoy it as much as I do :slight_smile:

EDIT: this is a link to a new fork of this project for Home Assistant:

4 Likes

Hi,

I’m really interested as I just bought a Siemens Dishwasher, and I was looking to have a cloudless connection to HA.
I’m interested by your files. If you could share them, it would be great !

One question though : I’m using supervised HA on a Raspberry. Is there any way to integrate these python scripts “inside” HA, or have I to go with another Raspberry ?

Thanks !

Sure, here are my files. For the install I remember there was some difficulties but I found all the solutions after a bit of googling. Also, two sections of the github were really usefull:

  • issues: here you will see some issues you will face, reported by other people often with the solution.
  • pull request: here you can find some modifications done by other people who share their code.

Here is my file hc2mqtt file. All the credits goes to the authors, it’s coming from the github that I posted herebefore:
The original file did not support mqtt with authentication, it is added here a I don’t remember if I did other changes, I give you the whole file here:

#!/usr/bin/env python3
# Contact Bosh-Siemens Home Connect devices
# and connect their messages to the mqtt server
import json
import sys
import time
import ssl
from threading import Thread

import click
import paho.mqtt.client as mqtt

from HCDevice import HCDevice
from HCSocket import HCSocket, now


@click.command()
@click.argument("config_file")
@click.option("-h", "--mqtt_host", default="192.168.20.100")
@click.option("-p", "--mqtt_prefix", default="homeconnect/")
@click.option("--mqtt_port", default=1883, type=int)
@click.option("--mqtt_username")
@click.option("--mqtt_password")
@click.option("--mqtt_ssl", is_flag=True)
@click.option("--mqtt_cafile")
@click.option("--mqtt_certfile")
@click.option("--mqtt_keyfile")
def hc2mqtt(config_file: str, mqtt_host: str, mqtt_prefix: str, mqtt_port: int, mqtt_username: str,
            mqtt_password: str, mqtt_ssl: bool, mqtt_cafile: str, mqtt_certfile: str, mqtt_keyfile: str):
    click.echo(f"Hello {config_file=} {mqtt_host=} {mqtt_prefix=} {mqtt_port=} {mqtt_username=} {mqtt_password=} "
               f"{mqtt_ssl=} {mqtt_cafile=} {mqtt_certfile=} {mqtt_keyfile=}")

    with open(config_file, "r") as f:
        devices = json.load(f)

    client = mqtt.Client()

    if mqtt_username and mqtt_password:
        client.username_pw_set(mqtt_username, mqtt_password)

    if mqtt_ssl:
        if mqtt_cafile and mqtt_certfile and mqtt_keyfile:
            client.tls_set(ca_certs=mqtt_cafile, certfile=mqtt_certfile, keyfile=mqtt_keyfile, cert_reqs=ssl.CERT_REQUIRED)
        else:
            client.tls_set(cert_reqs=ssl.CERT_NONE)

    client.connect(host=mqtt_host, port=mqtt_port, keepalive=70)

    for device in devices:
        mqtt_topic = mqtt_prefix + device["name"]
        thread = Thread(target=client_connect, args=(client, device, mqtt_topic))
        thread.start()

    client.loop_forever()

# Map their value names to easier state names
topics = {
        "OperationState": "state",
        "DoorState": "door",
        "RemainingProgramTime": "remaining",
        "PowerState": "power",
        "LowWaterPressure": "lowwaterpressure",
        "AquaStopOccured": "aquastop",
        "InternalError": "error",
        "FatalErrorOccured": "error",
        "AlarmClockElapsed": "alarm",
}



def client_connect(client, device, mqtt_topic):
        host = device["host"]

        state = {}
        for topic in topics:
                state[topics[topic]] = None

        while True:
                try:
                        ws = HCSocket(host, device["key"], device.get("iv",None))
                        dev = HCDevice(ws, device.get("features", None))

                        #ws.debug = True
                        ws.reconnect()

                        while True:
                                msg = dev.recv()
                                if msg is None:
                                        break
                                if len(msg) > 0:
                                        print(now(), msg)

                                update = False
                                for topic in topics:
                                        value = msg.get(topic, None)
                                        if value is None:
                                                continue

                                        # Convert "On" to True, "Off" to False
                                        if value == "On":
                                                value = True
                                        elif value == "Off":
                                                value = False

                                        new_topic = topics[topic]
                                        if new_topic == "remaining":
                                                state["remainingseconds"] = value
                                                value = "%d:%02d" % (value / 60 / 60, (value / 60) % 60)

                                        state[new_topic] = value
                                        update = True

                                if not update:
                                        continue

                                msg = json.dumps(state)
                                print("publish", mqtt_topic, msg)
                                client.publish(mqtt_topic + "/state", msg)

                except Exception as e:
                        print("ERROR", host, e, file=sys.stderr)

                time.sleep(5)

if __name__ == "__main__":
        hc2mqtt()

There was also a very little modification in hc-login something like ‘R’ instead of ‘r’ but it is documented in the github:

About your second question, I guess it would be possible but I have no idea how to make it clean (you don’t want your code to be overwritten when HA update). Probably in a kind of docker container.
I run HA in a VM under proxmox, so it was much easier for me to create a new container with minimalistic debian just with python to run this script.

We have forked this to make some faster progress:

Just waiting to get a few commits landed I think it should be able to retrieve all values, set all configuration options, as well as start programs etc.

Currently requires manual MQTT configuration of entities but I have produced some samples.

4 Likes

Just bought 3 connected Siemens devices. So very interesting topic and if possible I am available for testing my dishwasher, oven or my cooker.

1 Like

Very nice to see that you take this in charge :slight_smile:
I will edit my first message to show your github link.

What’s your progress ?
I see you have a homeassistant addon. Is it only the mqtt part ?

Anything local would be great for home connect as the official HA cloud integration(for me at least) loses connection entirely and frequently requiring removal and reinstallation.
Pile of poo to be honest

3 Likes

Initial setup is working great here too for my Siemens oven. I have to experiment further with what is possible but glad to get rid of the cloud (which disconnects / errors out once in a while).

I’m running it in a python environment for now, trying to decide whether a docker image is worth it. I assume this could be a direct integration as well, even skipping mqtt altogether.

I’m highly exited for this, an bought a bosh dishwasher and a neff induction cooktop with a hood especially because I saw this post!

I really want to try, it would be a good learning experience to make a ha addon from it, but the place those should go are still under heavy construction.

Soon!