Fumis/Austroflamm with OpenHAB

Sun 25 September 2022

household, software

Translations: DE

Here the integration of an Austroflamm pellet stove with a Control unit from Fumis/ATech into an OpenHAB instance is described.

NOTE: This is still work in progress and the software is by far far from finished. If you like, feel free to drop by from time to time.

This hobby project is a prototype of an idea and not a finished of an idea and not a finished product. Since this hack is working with an apperatus producing fire and heat, I can not and will not take any responsibility for what happens with the software!

Hack and use this at your own risk!!!

##General{#General}

Our home pellet stove supports remote control via app. However various things do not sit right with me:

  1. it is a service of a provider hosted by Amazon.
  2. all pellet stoves of this type connect centrally to one server
  3. the authentication via a (apparently permanently assigned) PIN appears to be at least questionable from an IT security point of view
  4. most important to me: it does not play with my locally running building control software (today also smart home) OpenHAB.

So I need another solution, preferably one that keeps all the data literally in the house and does not use cloud services. As a glider pilot I like clouds, but if they control my oven I feel kinda uncomfortable.

Function description

Basically this system uses the so called WiRCU box, a gateway from the ATech/Fumis specific RS485 protocol to WiFi and provides an alternative server to which this box connects.

The box tries to connect to a, as far as I can tell, hardcoded hostname. It uses WebSocket over TLS, which is a good idea.

Communication as intended by the manufacturer

The box delivers JSON encoded data in regular intervals via WebSocket. Thankfully, this is in a halfway sensible tree structure. The box receives similarly formatted JSON objects from the server and sets values in the stove values accordingly.

However, the box readily connects to any host that resolves with said name and happily starts its WebSocket session without checking if the certificate has been certificate is even issued for the host, let alone properly signed. I will not go into why this is not a good idea for an IoT device here at this point. However, this reinforces my decision to not use the cloud service.

So my software now provides a WebSocket server, now you still need to use stunnel or a ReverseProxy TLS server in the home network to pass the connections to the script. This server does not need to have any official certificates, self signed seems to work perfectly and it will not even check the hostname to match the certificate.

Local only configuration

And finally, e.g. by means of dnsmasq, we neeed a DNS server that lies about identity of the hostname api.fumis.si and simply answers the IP of the local TLS server (stunnel or reverse proxy).

The script then forwards all data of the WiRCU box to a MQTT broker and even allows to write back certain commands/setpoints to the box.

Implementation

The script was written for node-js, neither my favorite environment nor language. The goal was a fast implementation and not necessarily absolutely clean design.

It uses the packages “mqtt” and “ws” and builds a thin intermediate layer that connects both worlds together.

Utilities and configuration

It is assumed that the IoT network has the IP range 10.0.0.0/24. The host on which all tools run has the address 10.0.0.123 in this example.

stunnel

stunnel was used to handle the TLS communication with the box, so as not to have TLS in the node-js environment as well.

On debianesque systems you can install stunnel using apt-get install stunnel4.

``ini ; TLS front-end for fumis server, sends clear text connections to localhost:8080 [fumis] accept = 5101 connect = 8080 cert = /etc/stunnel/stunnel.pem


A certificate can be whipped up using the following commands [^1]:
``bash
cd /etc/stunnel/
openssl req -new -x509 -days 365 -nodes -config stunnel.cnf -out stunnel.pem -keyout stunnel.pem
openssl gendh 2048 >> stunnel.pem

Note: It seems that the WiRCU box does not use network time, so the expiration of a certificate of a certificate should not be an issue.

dnsmasq

The dnsmasq daemon works as the home IoT network’s DNS server. Bit with a little twist: It lies about a specific hostname, and it works like this:

local=/api.fumis.si/

To do this, the following entry is added to /etc/hosts.

10.0.0.123 api.fumis.si

node-js

The script was developed using node-js 10.24 and should work on newer versions. On Debian/Ubuntu it is recommended to install the following packages from the from the distribution’s repository:

apt-get install node-ws npm

npm

To load all other dependencies execute in the script’s directory:

npm install

Now there should be a subdirectory node_moules/.

Configuration of the adapter

Now the adapter script described at the beginning has to be configured.

This is done, for the sake of simplicity of implementation, using a JSON file with the following structure:

{
	"mqtt":{
		"username": "user",
		"password": "pass",
		"host": "127.0.0.1",
		"port": "1883"
	},
	"websocket":{
		"known_stoves": { 
			"0016D0000001": "1234" 
		}
	}, "writable": [
		"controller/command",
		"controller/power/setPower"
	]
}

Here the two interfaces are configured, i.e. WebSocket for the stoves and MQTT.

While the MQTT side is relatively self-explanatory, the WebSocket configuration needs some more elaboration: The known_stoves represents a mapping from MAC addresses to PINs. Both information are printed on the WiRCU box, but the MAC address has to be must be entered without separators and with capital letters. Only this way a WiRCU box can register with the server. Several WiRCU boxes can also be connected, although this use case is currently of more theoretical value.

The writable section lists all nodes that should be writable via MQTT with the suffix :set. So far only two of them have been tested, these are mentioned in the example. Most likely several other data points could be written, but I did not have the courage to try.

When starting the script you should see something like this:

$ node main.js /etc/own_stove.json 
Will accecpt stoves: { '0016D0000000': '1234' }
Writable nodes in stoves are:  [ 'controller/command', 'controller/power/setPower' ]
Connecting to mqtt://10.0.0.132:1883
MQTT connected
Stove connected
Data from stove 0016D0000000
Stove 0016D0000000 connected
Subscribe to topic 'fumis/0016D0000000/#'
Data from stove 0016D0000000

Here you can see that the above configuration has been successfully loaded and the stove has has connected to the script via stunnel.

Now in the MQTT broker will see a lot of topics created under fumis/0016D0000000, e.g. fumis/0016D0000000/controller/power/setPower. This can then be set by means of of the topic fumis/0016D0000000/controller/power/setPower:set via MQTT.

The command channel fumis/0016D0000000/controller/command:set supports two known commands:

value meaning
1 switch off oven
2 switch oven on

Configuration of OpenHAB

In this document it is assumed that an MQTT broker has already been is already configured (in this example it has the UID mqtt:broker:0db42c4a).

Furthermore, the “mapping” transformation is needed to map textual descriptions to the numeric status values.

In OpenHAB a Thing is created with the following configuration:

label: pellet stove
thingTypeUID: mqtt:topic
configuration: {}
bridgeUID: mqtt:broker:0db42c4a
location: living room
channels:
  - id: PelletStoveOn
    channelTypeUID: mqtt:switch
    label: Pellet stove
    description: ""
    configuration:
      commandTopic: fumis/0016D0000000/controller/command:set
      allowedStates: 1,2
      qos: 0
      stateTopic: fumis/0016D0000000/controller/command:set
      off: "1"
      on: "2"
  - id: PelletStovePower
    channelTypeUID: mqtt:number
    label: Power
    description: ""
    configuration:
      commandTopic: fumis/0016D0000000/controller/power/setPower:set
      min: 1
      stateTopic: fumis/0016D0000000/controller/power/setPower
      max: 5
  - id: PelletStoveStatus
    channelTypeUID: mqtt:string
    label: Status
    description: ""
    configuration:
      stateTopic: fumis/0016D0000000/controller/status
      transformationPattern: MAP(fumis.map):%s

In /etc/openhab/transform/fumis.map the state values are assigned to texts:

0=CONTROLLER_OFF
1=CONTROLLER_COLD_START_OFF
2=CONTROLLER_WOOD_BURNING_OFF
10=CONTROLLER_HEATUP
20=CONTROLLER_IGNITION
21=CONTROLLER_IGNITION_TEST
30=CONTROLLER_BURNING
40=CONTROLLER_BURNWAIT
50=CONTROLLER_COOLDOWN
60=CONTROLLER_HYBRID_INIT
80=CONTROLLER_HYBRID_START
90=CONTROLLER_WOOD_START
100=CONTROLLER_COLD_START
110=CONTROLLER_WOOD_BURNING

downloads

All source codes are available at https://github.com/ptwz/own_fumis available.