Control Junkers gas heating (1-2-4 interface) with Home Assistant

Situation: I am living in a flat (not my own) where a gas heater is given and cannot be changed. Gas heater is a JUNKERS (Bosch Group) ZWN 16-6 KE23 and the temperature control is a JUNKERS FR120.

Problem: Currently, I have to control the temperature for each room manually in two steps: (1) Turning up the thermostat in the room and (2) activating the central heating on the FR120. That’s laborious!

Goal: I would like to control each room automatically using Home Assistant at the best.

For the control of each single room I could easily install smart thermostats and connect them with Home Assistant. But how to control the central heating (currently controlled by JUNKERS FR120)?

According to my research, the gas heater has only a 1-2-4 analog interface. Therefore I cannot easily install smart solutions I guess, since they require a data bus. Am i right? I thought about a solution using ESP32 microcontroller. But I am also not the electronics expert.

Does anyone have experience how to solve this?

Cheers, red

1 Like

Maybe it works with ems-esp?
https://bbqkees-electronics.nl/ems-device-compatibility/

@VDRainer thanks for the quick hint!

If I understand correctly, I cannot send any commands to the FR120 so that the heating gets on or off, right?

On this page I also found an information for my boiler/heater (JUNKERS (Bosch Group) ZWN 16-6 KE23), which seems to be one of the “non-compatible boilers”, right?

The simplest solution would be that I can switch the boiler on/off using Home Assistant. But not sure how to realize this. I am happy about any answers.

Cheers, red

They dont use the modulation and switch the heater on/off with a shelly PM in the 24V control circuit.

found this sophisticated solution

1 Like

Oooooooh, this looks like a super nice solution! :heart:

@pelim: Have you just found this solution or have you even tried it in Home Assistant?

Otherwise it’s still too faaaaar away for me, since there are two big challenges for me :roll_eyes:

  1. I’m not very experienced with electronics or making such boards.
  2. The software in this github repository is designed for blynk. But I would love to find a solution for Esphome & Home Assistant.
1 Like

Thx for the link. I actually got the pcbs from pcbway and built the project today.
I used ESPHome instead and still fine tuning a bit but it’s working! :slight_smile:
I’ve got 4 pcbs still left if someone from germany is interested write me a PM. PcbWay has 5 units purchases minimum.
I can also share the list of components I purchased from reichelt.de

1 Like

Hi jwm ,

I’m interested by your esphome script to control the smarTtherm board from HA. Could you please share it with me :relaxed:
Thanks for your help

1 Like

Hi,

yes sure. I’m still tuning it a bit but here is the current version.

Yaml:

ESPHome
substitutions:
  unit_name: "smarttherm"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  fast_connect: true
  reboot_timeout: 0s

  ap:
    ssid: ${unit_name} Fallback Hotspot
    password: !secret fallback_password

captive_portal:

ota:
  password: !secret ota_password

api:
  password: !secret api_password

web_server:
  auth:
    username: !secret web_server_username
    password: !secret web_server_password

esphome:
  name: ${unit_name}
  platform: ESP8266
  board: d1_mini
  esp8266_restore_from_flash: True # for slider position and switch state
  on_boot:
    priority: -100 # after everything is initialized
    then:
      - script.execute: update_pwm_level

logger:
  level: INFO

output:
  - platform: esp8266_pwm
    pin: D8 # octocopler drive
    frequency: 1000 Hz # default
    id: pwm_output

switch:
  - platform: gpio
    pin: D4
    id: onboard_led
    inverted: True
    internal: True

  - platform: template
    name: ${unit_name}_heating
    id: heating
    entity_category: config
    restore_state: True
    optimistic: True
    turn_on_action:
      - switch.turn_on: onboard_led
      - script.execute: set_pwm_level_from_slider
    turn_off_action:
      - switch.turn_off: onboard_led
      - script.execute: set_pwm_low_level

script:
  - id: set_pwm_level_from_slider
    then:
      - lambda: |-
          id(pwm_output).set_level(id(pwm_output_level).state);

  - id: set_pwm_low_level
    then:
      - lambda: |-
          id(pwm_output).set_level(0.07);// ~5v off

  - id: update_pwm_level
    then:
      - lambda: |-
          if (id(heating).state) {
            id(set_pwm_level_from_slider).execute();
          } else {
            id(set_pwm_low_level).execute();
          }

number:
  # power slider in percent for home assistant
  - platform: template
    name: ${unit_name}_power_level
    id: power_level
    restore_value: True
    step: 1
    min_value: 1
    max_value: 100
    unit_of_measurement: "%"
    mode: slider
    optimistic: True
    entity_category: config
    on_value:
      then:
      - sensor.template.publish:
          id: pwm_output_level
          state: !lambda "return x;"

sensor:
  # map percent slider value to float level of pwm output
  - platform: template
    id: pwm_output_level
    internal: True
    lambda: |-
      return id(power_level).state;
    filters:
      - calibrate_linear:
        - 1 -> 0.25 # ~8v min
        - 100.0 -> 0.62 # ~15v max
    on_value:
      then:
      - logger.log:
          level: INFO
          format: "pwm ouput level: %.2f"
          args: ['x']
      - script.execute: update_pwm_level

## optional:

  - platform: adc # ranges from 0v to 1v
    pin: A0
    name: ${unit_name}_ldr
    unit_of_measurement: "mV"
    filters:
      - multiply: 1000

  - platform: dht # for DS18B20 see https://esphome.io/components/sensor/dallas.html
    pin: D3
    model: DHT22_TYPE2
    humidity:
      name: ${unit_name}_humidity
    temperature:
      name: ${unit_name}_temperature
      on_value_range: # backup control
      - below: 17.0
        then:
          - logger.log:
              level: WARN
              format: "turn on heating, current temperature: %.2f"
              args: ['x']
          - switch.turn_on: heating
      - above: 22.0
        then:
          - logger.log:
              level: WARN
              format: "turn off heating, current temperature: %.2f"
              args: ['x']
          - switch.turn_off: heating

binary_sensor:
  - platform: gpio
    pin:
      number: D1 # octocopler output of 24v line
      inverted: True
      mode:
        input: True
        pullup: True
    name: ${unit_name}_active
    id: power_active
    filters: # debounce
      - delayed_on: 5s
      - delayed_off: 5s

Home Assistant
climate:
  - platform: generic_thermostat
    unique_id: junkers_therme
    name: junkers_therme
    heater: switch.smarttherm_heating
    target_temp: 20
    max_temp: 22
    min_temp: 17
    target_sensor: sensor.inside_temperature
    precision: 0.5
    min_cycle_duration:
      seconds: 30
    comfort_temp: 20.5
    sleep_temp: 19.5
    away_temp: 19

input_boolean:
  sleeping_time:

automation:
  - alias: sync_smarttherm_state_with_climate
    trigger:
      - platform: state
        entity_id: switch.smarttherm_heating
        from: "unavailable"
        to:
          - "on"
          - "off"
    action:
      entity_id: switch.smarttherm_heating
      service: >-
        {% if is_state_attr('climate.junkers_therme', 'hvac_action', 'heat') %}
          switch.turn_on
        {% else %}
          switch.turn_off
        {% endif %}

  - alias: set_smarttherm_power_level
    trigger:
      - platform: state
        entity_id: climate.junkers_therme
        attribute: current_temperature
        not_to: "unavailable"
      - platform: state
        entity_id: climate.junkers_therme
        attribute: temperature
        not_to: "unavailable"
    condition: >-
      {{ states('number.smarttherm_power_level') | is_number }}
    action:
      service: number.set_value
      target:
        entity_id: number.smarttherm_power_level
      data:
        value: >-
          {% set target_temp = state_attr('climate.junkers_therme','temperature') | float(-1) %}
          {% set current_temp = state_attr('climate.junkers_therme','current_temperature') | float(-1) %}
          {% if ((target_temp > 0) and (current_temp > 0)) and (target_temp > current_temp) %}
            {% set val = (target_temp - current_temp)**3 %}
            {{ (100 if val > 100 else val) | round(0, "ceil") }}
          {% else %}
            1
          {% endif %}

Previews:

ESPHome Webfrontend

Home Assitant Device

2 Likes

I am also looking for a solution that keeps modulation. @jwm I would be very interested in your work, how can I learn more?

1 Like

I would also love to have a solution which integrates the modulation

@jwm Do you still have some boards left over? I am interested.

I don’t have any boards left, but you can order the PCBs yourself with the gerber-files. I will update the github repo soon with all the informations and send here an update.

2 Likes

would love to have them, thank you!

Hello jwm.

Looking forward for your github repo :slight_smile:

Thanks
Brano

I’ve uploaded all the files in a fork of the original repo: GitHub - jensweimann/SmartTherm: Controlling a Junkers heating (Eurostar ZWE24) with an IoT thermostat

Gerber files: SmartTherm/SmartTherm-v2-gerber-files.zip at 9df31b70dcf4673e71ec266d890e722d3b00563c · jensweimann/SmartTherm · GitHub
Needed components: SmartTherm/SmartTherm-v2-components.pdf at 9df31b70dcf4673e71ec266d890e722d3b00563c · jensweimann/SmartTherm · GitHub

Also if you want to power the Wemos D1 Mini from 24v of the boiler, you will need a step down voltage converter (aka Buck Converter) from 24V to 5V DC, for example an LM2596s.

There is a quite similar project: GitHub - RobinMeis/Junkers_1-2-4_ESP32: Ein ESP32 Arduino Sketch für die Steuerung einer Junkers Gastherme an einer 1-2-4 Schnittstelle (Junkers Therme mit WLAN und MQTT - robin.meis.space)