Controlling Viessmann Vitodens Gas Heater Boilers locally (new models 100-W, 200-W, ... after 2018)

Queue issue was caused by two sensors:

  - platform: optolink
   name: Return temperature
   address: 0x0816
   bytes: 2
   div_ratio: 1
   filters:
     multiply: 0.1
   accuracy_decimals: 1
   unit_of_measurement: °C
   device_class: temperature
   update_interval: 72s
   state_class: measurement
   force_update: true

and

  - platform: optolink
    name: Exhaust temperature
    address: 0x0808
    bytes: 2
    div_ratio: 1
    filters:
      multiply: 0.1
    accuracy_decimals: 1
    unit_of_measurement: °C
    device_class: temperature
    update_interval: 78s
    state_class: measurement
    force_update: true

Both of them were showing the same temperature(?)… If both of them were enabled, queue did reach value of 80 within an hour. If only one of them, it took couple of hours.
And now when I keep them disabled, queue’s value is between 0 and 6.

1 Like

Interesting observation. I have not found them useful anyway so I have them both disabled.

@adorobis could you tell me exactly how you enable party mode in your heater?
Is it just toggling party mode switch or something else?
On my side, whatever I do in HA it doesn’t activate party mode… Maybe because when doing it locally (at Viessmann controller) after pushing party mode button I need also to hit OK button to confirm room temperature setpoint…

And when it comes to presets and operation mode.

  • Do I need to change them both simultaneously? I’m asking because when I change operation mode locally - at heater’s controller, I don’t need to choose circulation loops. Question also applies to party modes.
  • forcedReduced and forcedNormal operation modes, what do they do?
  • Are presets (eco & comfort) to be activated by Economy and Party mode switches or the other way around? In my case, only switching to eco mode works.
  • Naming convention:
    1/ Eco preset is reduced/night room temperature?
    2/ Comfort preset is party mode?
    But in normal operation I can see status:
    Zrzut ekranu 2024-12-23 o 12.01.31
    while:
    Zrzut ekranu 2024-12-23 o 12.08.50
    and
    Zrzut ekranu 2024-12-23 o 12.09.32

I’m sorry for so many questions but before setting up any automation, I need to know what I’m about to do :slight_smile:

I just need to enable the toggle switch for party mode and that’s it. One thing I’ve observed is that it does not get activated immediately but after some time (like at least a minute). So the led for the party mode (and similarly for eco mode) on the controller are also turning on with some delay. Similarly if you enable this mode from the physical controller it will get reflected in HA after some time only.

This is probably not needed. Just wait for a moment and the party (or eco) mode will get activated with the temp that was set there before.

No, preset is only used to select the party or eco modes. Like the dedicated buttons on the physical controller. Specifics of those modes are that they will turn off with the next scheduled mode.
Operation mode is the main mode of the heater.
On the controller the top row is Operation mode, the bottom row is the Preset mode.


Let me address rest of the questions in next reply as I need to disconnect now :slight_smile:
Edit: the rest of your questions:

In essence they do what the name suggests: they override the scheduled mode and go into day / heating mode (normal) or night / reduced temp (night) mode. End it stays this way until you change the operation mode to a different one.

It is called Eco and Comfort in HA just because there is only specified set of presets that can be used in HA, if you want to add it to the climate entity. Otherwise I would call it Party and Eco. And as explained above - those presets are turn off automatically on the next scheduled mode change or based on timer (which can be set in the device settings - refer to the installer’s manual of Viessmann heater).

I have not seen such status in my unit: 773 therefore it is not mapped to a text status. You can change this mapping in esphome config of this sensor. I have also used the status names to have them in line with they official Vicare integration and I’ve mapped them according to my unit behaviour.

Hope this clarifies a bit more but I agree that this is overall a bit confusing setup. Some of it is simply caused by very specific names of operation and preset modes in HA.

1 Like

Once again, thanks very much for taking a time and explaining.
In my case, Party mode M2 switch started working when I adjusted in HA “Party Floor Temperature Setpoint” and the same applies to Party mode switch after touching “Party Temperature Setpoint”. So, something was related to those temperatures set points…

BTW, do you have a list or know a website where I can find all available addresses used in opentherm/viessmann heater? I would like to map that 773 status plus find address where solar panels’ temperature is presented (solar panels controller is connected to Viessmann boiler)…

The best place is the OpenV project:

Good starting point for addresses is this one:

But I’ve noticed that some are missing so it is good to dig deeper and here you’ll find dumps with much more data:

in this file you have to find your controller version and browse through the text file.

Most of above is in German but google translate is good enough to figure this out in any language.

Based on this:

  • Solar (3352) HIDDEN:(54_SR=“0 without”)
  • Solar control (941) [K54_Solar_Info~0x7754 (Byte)]
  • Solar storage temperature (5276) [SolarStoragetemperatur~0x6566 (Int)] HIDDEN:(“Solar storage temperature”>{‘CompanyId’: ‘24’, ‘Unit’: ‘Grad C’, ‘DataType’: ‘Float’, ‘Stepping’: 0.1, ‘LowerBorder’: 0.0, ‘UpperBorder’: 127.0} OR “Solar storage temperature”<{‘CompanyId’: ‘24’, ‘Unit’: ‘Grad C’, ‘DataType’: ‘Float’, ‘Stepping’: 0.1, ‘LowerBorder’: 0.0, ‘UpperBorder’: 127.0})
  • Solar collector temperature (5272) [Solar collector temperature~0x6564 (SInt)] HIDDEN:(“Solar collector temperature”>{‘CompanyId’: ‘24’, ‘Unit’: ‘Grad C’, ‘DataType’: ‘Float’, ‘Stepping’: 0.1, ‘LowerBorder’: -20.0, ‘UpperBorder’: 250.0} OR “Solar collector temperature”<{‘CompanyId’: ‘24’, ‘Unit’: ‘Grad C’, ‘DataType’: ‘Float’, ‘Stepping’: 0.1, ‘LowerBorder’: -20.0, ‘UpperBorder’: 250.0} OR “Status solar collector sensor”=“Not available”)
  • Solar Recharge suppression (5273) [SolarNachlade~0x6551 (Byte)]
  • Solar solar pump (5274) [SolarPumpe~0x6552 (Byte)]
  • Solar operating hours (5277) [SolarStunden~0x6568 (Int)]
  • Solar heat quantity (5279) [SolarWaerme~0x6560 (Int4)]

I came up with following:

binary_sensor:
  - platform: optolink
    name: Solar Circulation Pump
    address: 0x6552
    update_interval: 145s
    device_class: power
sensor:
  - platform: optolink
    name: Solar Storage temperature
    address: 0x6566
    bytes: 2
    div_ratio: 1
    filters:
      multiply: 0.1
    accuracy_decimals: 1
    unit_of_measurement: °C
    device_class: temperature
    update_interval: 185s
    state_class: measurement
    force_update: true
  - platform: optolink
    name: Solar Collector temperature
    address: 0x6564
    bytes: 2
    div_ratio: 1
    filters:
      multiply: 0.1
    accuracy_decimals: 1
    unit_of_measurement: °C
    device_class: temperature
    update_interval: 170s
    state_class: measurement
    force_update: true
  - platform: optolink
    name: Solar Operating Hours
    address: 0x6568
    bytes: 4
    device_class: duration
    unit_of_measurement: h
    state_class: total_increasing
    icon: mdi:counter
    update_interval: 1800s
    filters:
      - lambda: return x / 3600;
    accuracy_decimals: 1
    force_update: true
  - platform: optolink
    name: Solar Heat Quantity
    address: 0x6560
    bytes: 4
    unit_of_measurement: J
    update_interval: 493s
    state_class: measurement
    force_update: true

But I don’t see anywhere in those files number of bytes and/or div_ratio information. I copied configuration of similar items but I don’t think Solar Heat Quantity works
At least some of information is displayed (storage is shared with gas boiler):
Zrzut ekranu 2024-12-27 o 18.46.36

I am migrating my smart home controller from FHEM to Home Assistant, the Wemos D1 Mini was working for years, I have reflashed it with ESP Home to use the Optolink module.

Our Viessmann heating is the model V200KO2B, is there a pre-configured yaml which can be used instead of manually write it from the raw addresses? I saw two files here, but it is not clear to me which model is supported

didn’t the pastebin in OP worked out?

So, I found this thread yesterday, and I decided to build an optolink :slight_smile:

I found the 3D printed case here:

the schematics is very simple, even I can build it:

Now, the first difficulty came up in RS components I can’t find a SIR 204 EVL led, and the phototransistor SFH309 is only delivered in 2000 pieces.
I was wondering, does someone have an amazon link of an equivalent of each with a lower head count? I don’t mind to buy a few of each but 2000 is ridiculous :joy:

Depending on where you are in the world, Farnell/CPC can supply:

https://cpc.farnell.com/osram/sfh309fa-4/phototransistor-t1/dp/SC08564
https://cpc.farnell.com/osram/sfh4350/led-3mm-ir-850nm/dp/SC12373

How idiotic of me, of course Farnell. Thank you Paul!

The 3D printed part is ready to go

Hey. I have vitodens. Do you still the code you wrote in Gh? I can’t seem to compile it.

I started finally building this.
I have a Vitodens 200-W but people speak a lot on a difference on the 200W models.

Does this means that I have a 200-W WB2C ?

I tried to install in the esp32 the code from the pastebin, but I get so many errors when it is verifying to install that I’m wondering if this code is still up to date.

@adorobis can you please confirm if this code is the one you are still using in you boiler?

Does someone have working code for the 200-W

With my best regards

Yes, all still works properly. Also compiles without any errors in the latest esphome.

kotrfa, did you finally find a solution?
I think open3e project is perhaps the one to go for if one’s boiler has a CAN interface.

No progress on the project from my end, so nothing new to report. I’m still stuck with the official HA integration for vicare, though I’d rather be using something else. Hoping someone else will be willing to test this out first. The thing is, all those solutions talked about earlier in this thread rely on the legacy Optolink, which isn’t available on newer models (anything from 2020 onward, I think).

open3e looks awesome, but I don’t think my model has CAN bus :cry: . At least that’s what claude thinks when I gave it 128 contractor manual on Vitodens 100-W B1KF and open3e:

I think OpenTherm is the only option unless someone cracks/reverse-engineer the wifi API which I seriously doubt.

But the opentherm integrations seems to be promising, e.g. Compatibility · Laxilef/OTGateway Wiki · GitHub with ESP32/ESP8266 Thermostat Shield - DIYLESS Electronics and so on.

Basically, claude recommended me:

  1. using just OpenTherm Adapter - Hobby Projects - 15$ with esp32 (10$, already have it in the bathroom)
  2. esphome (already using it)

I would love to see this reverse engineered to support local control. It must be possible by running a proxy Veissmann server and directing the api calls to that instead of the web.

Well, I did manage to intercept the traffic by redirecting DNS to servers it’s trying to connect via setting hostnames to:

dc1-3-iothub-02.azure-devices.net
gateway-prod-gw-northeurope-1-g2.northeurope.cloudapp.azure.com

(then restarting the boiler)

to my mitmproxy, but it’s all encrypted. It’s MQTT protocol with SSL, so unless someone gets their hands on on Viessman certificates or finds a way how to respect e.g. mitmproxy certificates, we are out of luck knowing what’s inside it.

mitmproxy logs:

[09:28:15.511][192.168.0.209:57921] client connect
[09:28:15.543][192.168.0.209:57921] Client TLS handshake failed. The client does not trust the proxy's certificate for dc1-3-iothub-02.azure-devices.net (tlsv1 alert unknown ca)
[09:28:15.544][192.168.0.209:57921] client disconnect

and tcpdump -i br-lan -n host 192.168.0.209 and not port 22 from my router:

09:28:36.031226 IP 52.156.218.86.443 > 192.168.0.209.57928: Flags [P.], seq 4961:5671, ack 599, win 63, length 710
09:28:36.031318 IP 52.156.218.86.443 > 192.168.0.209.57928: Flags [F.], seq 5671, ack 599, win 63, length 0
09:28:36.041653 IP 192.168.0.209.57928 > 52.156.218.86.443: Flags [.], ack 5672, win 12287, length 0
09:28:36.049235 IP 192.168.0.209.57928 > 52.156.218.86.443: Flags [F.], seq 599, ack 5672, win 12287, length 0
09:28:36.052895 IP 192.168.0.209.60179 > 192.168.0.1.53: 3921+ A? dc1-3-iothub-02.azure-devices.net. (51)
09:28:36.053304 IP 192.168.0.1.53 > 192.168.0.209.60179: 3921* 1/0/0 A 192.168.0.195 (67)
09:28:36.083664 IP 52.156.218.86.443 > 192.168.0.209.57928: Flags [.], ack 600, win 63, length 0
09:28:41.105851 IP 192.168.0.209.4222 > 192.168.0.1.53: 44590+ A? mgmt.viessmann-platform.io. (44)
09:28:41.112028 IP 192.168.0.1.53 > 192.168.0.209.4222: 44590 2/0/0 CNAME mgmt-global-1-waf-2.northeurope.cloudapp.azure.com., A 52.156.218.86 (124)
09:28:41.116046 IP 192.168.0.209.57930 > 52.156.218.86.443: Flags [S], seq 24734, win 24576, options [mss 1460,nop,wscale 1], length 0
09:28:41.152489 IP 52.156.218.86.443 > 192.168.0.209.57930: Flags [S.], seq 601248823, ack 24735, win 64240, options [mss 1440,nop,wscale 10], length 0
09:28:41.155586 IP 192.168.0.209.57930 > 52.156.218.86.443: Flags [.], ack 1, win 12288, length 0
09:28:41.157320 IP 192.168.0.209.57930 > 52.156.218.86.443: Flags [P.], seq 1:184, ack 1, win 12288, length 183
09:28:41.193447 IP 52.156.218.86.443 > 192.168.0.209.57930: Flags [.], ack 184, win 63, length 0
09:28:41.202836 IP 52.156.218.86.443 > 192.168.0.209.57930: Flags [.], seq 1:1453, ack 184, win 63, length 1452
09:28:41.203074 IP 52.156.218.86.443 > 192.168.0.209.57930: Flags [P.], seq 1453:2905, ack 184, win 63, length 1452
09:28:41.203304 IP 52.156.218.86.443 > 192.168.0.209.57930: Flags [P.], seq 2905:4097, ack 184, win 63, length 1192
09:28:41.203418 IP 52.156.218.86.443 > 192.168.0.209.57930: Flags [P.], seq 4097:4687, ack 184, win 63, length 590
09:28:41.238661 IP 192.168.0.209.57930 > 52.156.218.86.443: Flags [.], ack 2905, win 11562, length 0
09:28:41.279523 IP 192.168.0.209.57930 > 52.156.218.86.443: Flags [.], ack 4687, win 11986, length 0
09:28:41.783994 IP 192.168.0.209.57930 > 52.156.218.86.443: Flags [P.], seq 184:259, ack 4687, win 11986, length 75
09:28:41.862484 IP 52.156.218.86.443 > 192.168.0.209.57930: Flags [.], ack 259, win 63, length 0
09:28:41.865787 IP 192.168.0.209.57930 > 52.156.218.86.443: Flags [P.], seq 259:310, ack 4687, win 11986, length 51
09:28:41.901736 IP 52.156.218.86.443 > 192.168.0.209.57930: Flags [.], ack 310, win 63, length 0
09:28:41.901970 IP 52.156.218.86.443 > 192.168.0.209.57930: Flags [P.], seq 4687:4961, ack 310, win 63, length 274
09:28:41.910804 IP 192.168.0.209.57930 > 52.156.218.86.443: Flags [P.], seq 310:599, ack 4961, win 11849, length 289
09:28:41.958755 IP 52.156.218.86.443 > 192.168.0.209.57930: Flags [P.], seq 4961:5423, ack 599, win 63, length 462
09:28:41.958847 IP 52.156.218.86.443 > 192.168.0.209.57930: Flags [F.], seq 5423, ack 599, win 63, length 0
09:28:41.967685 IP 192.168.0.209.57930 > 52.156.218.86.443: Flags [.], ack 5424, win 11618, length 0
09:28:41.974815 IP 192.168.0.209.57930 > 52.156.218.86.443: Flags [F.], seq 599, ack 5424, win 11618, length 0
09:28:42.010758 IP 52.156.218.86.443 > 192.168.0.209.57930: Flags [.], ack 600, win 63, length 0