Heating switch

Heating switch

for an Oekofen heating system with Openhab

Motivation

Most people switch off the light when they leave their house or apartment. However, the biggest energy consumer is the heating. So it makes sense to have a switch in the hallway in front of the exit with which you can switch off or lower the heating.

System environment

We recently installed a pellet heating system from Oekofen. An infrastructure for home automation with Openhab and Mosquitto already existed.

Components

The configuration described below takes place via the UI and is illustrated accordingly by the YAML snippets from the code tab.

Switch

A Sonoff SwitchMan M5-1C-86 flashed with Tasmota is used as the switch. It switches nothing (directly) but indicates the switching status via an LED. The switch is set up as an MQTT Thing in Openhab.

Channel
MQTT State Topic: stat/schalter-heizung/POWER1
MQTT Command Topic: cmnd/schalter-heizung/POWER1

Heating

Heaters from Ökofen (Pelletronic 4.02b in my case) have a JSON interface accessible via http. This can be reached under

http://<ip pelletronic>:<port, default 4321>/<pwd>/

Under this URL you can find a short documentation. There is also an inofficial documentation on github. Also take a look at the issues.

The heating is configured accordingly as an HTTP Thing.

UID: http:url:<id>
label: Heizung
thingTypeUID: http:url
configuration:
  authMode: BASIC_PREEMPTIVE
  ignoreSSLErrors: false
  baseURL: http://<ip>:4321/<json-pwd>
  delay: 3000
  stateMethod: GET
  refresh: 60
  commandMethod: GET
  encoding: iso8859-1
  timeout: 3000
  bufferSize: 2048
channels:
…
  - id: betriebsart-heizkreis-int
    channelTypeUID: http:number
    label: Betriebsart Heizkreis (int)
    description: ""
    configuration:
      mode: READWRITE
      commandTransformation:
        - ""
      stateExtension: all
      commandExtension: hk1.mode_auto=%2$s
      stateTransformation:
        - JSONPATH:$.hk1.mode_auto

Only the channel relevant for the switch was listed. An item is created for this switch.

label: Betriebsart Heizkreis (int)
type: Number
category: ""
groupNames:
  - SchalterHeizungGruppe
tags:
- Point

For the group see the next section.

HeatingSwitch group

Synchronizing the states of the switch and heater is surprisingly complex. In order to be able to react to all state changes in one rule, a group containing both items is required.

The group is created as an item of the type Group. It has the switch and the operating mode item as direct members.

Transformation

The heating circuit of the heating system has 4 numbered states, while the switch only has 2. The following mapping is therefore used:

$ cat /etc/openhab/transform/heizungsschalter.map 
ON = 1
OFF = 3
# Aus
0 = OFF
# Auto
1 = ON
# Heizen
2 = ON
# Absenken
3 = OFF

Rule

configuration: {}
triggers:
  - id: "1"
    configuration:
      groupName: SchalterHeizungGruppe
    type: core.GroupStateChangeTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      considerConditions: true
      ruleUIDs:
        - 9809810faf
    type: core.RunRuleAction

The action refers to a script. This is a customized variant from a forum post by Udo Hartmann.

// global var has to be defined first (no rules ahead)
var Boolean lock = false

// check if rule already started
if(lock)
  // and break if true
  return;   

// lock rule
lock = true  

val toStateOnOff = [ Item s |
    var state = s.state.toString
    if (state != "ON" && state != "OFF") {
        state = transform("MAP", "heizungsschalter.map", state)
    }
    state
]

logInfo("test", "HeizungSchalterSync called for " + triggeringItem.name);
// get a list of Alarm Switch Items without the triggering one.
SchalterHeizungGruppe.members.filter[j|j.name != triggeringItem.name]
  // only ON/OFF changes should switch
  .filter[j|toStateOnOff.apply(j) != toStateOnOff.apply(triggeringItem)]
  .forEach[i| 
  // and send the command to switch state
  i.sendCommand(
        transform("MAP", "heizungsschalter.map", triggeringItem.state.toString))                        
]
// give some time to rest
Thread::sleep(500)                                                      
// Unlock rule
lock = false 

I hope German as a language is OK.

No, it is not as this is an international community. Please translate your first post.

1 Like

The German version is still available on my site.

1 Like