Drayton Wiser Home Assistant Integration

Thanks @dunxd for the thoughts here! Really appreciate it.

I think I’m going to just go with Shelly anyway for this use case. I realised, it’s a much better tool for this job! Being in Drayton would have been nice, so that everything is in one place for the heating, but the towel rails are not going to have manual intervention very often anyway. They’ll likely be on a schedule to heat for a few hours throughout the day, once in the morning, once in the evening.

Just to follow up that I don’t see in the v2 Opentherm spec Ch return temperature

Opentherm Protocal

You’ll not get any meaningful consumption figures just using burner on time.
Boilers ‘modulate’ their output. (Check your boiler ratings modulation ratio figure).
EG. If the modulation ratio is 4:1 -
When the burner is on, a 20kw rated boiler could be consuming 20kW of gas, or as a low as 5kW of gas, to achieve the flow temperature.
As far as I’m aware, gas consumption is usually obtained via the SMET2 meter route, assuming you have a smart meter fitted.

Thanks for your reply. I don’t have any smart meters fitted at my home, only the old mechanical ones.

I realise that the boiler modulates the flame, but my system is relatively small (7 radiators total, only 3 max being on at any one time) and thus I’d have thought it would stabilise quickly. Plus, if the modulation behaves in a linear fashion, an average value could prove to be useful.

I’ve managed to find a thread on the HA forum of someone attempting the same thing, using powercalc integration to create a virtual power sensor for the burner. Its value is set by running the boiler for a length of time, observing the actual m3 gas usage from the gas meter, then converting to kWh. This can be fed into the energy dashboard. The guy claims that once he tweaked the kWh value, it was surprisingly accurate despite all of the caveats and tallied up with his meter readings. I might give it a go and see what happens.

1 Like

That sounds interesting - do you mind linking to the thread?

Yes sure, see below. I have pretty much done exactly as he has implemented (I was already using powercalc for other things), except for the gas valve sensor. For this, I decided to use a smart socket that can detect the power spike when the boiler’s exhaust fan is running. So far so good - I just need to tweak the converted kWh value once we have the CH running fully.

1 Like

Message ID 28 is the return temperature. This is an optional message so maybe boilers don’t all support it, but it may also be an issue with the Wiser OpenTherm interface. Because I have a system boiler, and Wiser (at least when I installed it) only supported combis for OpenTherm I use a separate OpenTherm interface and carefully mapped out exactly the messages my boiler would provide. BTW I use relative modulation level to derive the instantaneous and cumulative boiler output power. Checking with my gas meter I think the simple calculation is I use is probably within 5% of actual.

I’ve seen a few people asking about how the OpenTherm Relative Modulation Level (RML) parameter works on the Wiser Integration. So decide to have a play. According to the Opentherm Protocol it should be 0-100% for some reason the wiser integration is out by a factor of 10. So 1000 is 100%, 500 is 50% etc (Fix needed there I think). I’ve been monitoring my RML for the last few days. The RML seems to be a percentage of the span between the boiler minimum and maximum firing level. My boiler has a minimum firing level of 12kw and a max of 37kw. Which gives a span of 25kw. The boiler is vastly oversized and has been limited to an output of 22kW, House heat loss is only 15kw. When I turn a hot tap on the boiler goes to full firing (22kw) with gives an RML of ~40%. So if you calculate 40% of the span you get 10kw add on the minimum firing of 12kw and you get 22kw. Which correlates to the limited output setting. Can anybody else confirm this on their own systems?

Although I use an independent OpenTherm interface that’s exactly the calculation I use to determine relative power on my ideal boiler - except that I gate it with the burner flame on signal - because the on the ideal boiler the RM level appears to reflect the boiler fan speed and shows high levels during the pre and post burn combustion chamber purge when the burner is not on.

Unfortunately dont get a flame on from a Vailliant Boiler.

Oh that’s a disappointment - the flag is part of the slave status message (bit field) returned as a specific response to a MSG ID 0 query. It’s my understanding that the return of the status flags is mandatory, but maybe Vaillant have chosen to interpret the spec differently. If the Wiser OT interface exposes the bit field, you might be able to unpack that yourself with a template.

@msp1974 The integration has suddenly started to fail to load/setup as of this evening. Errors in logs as follows:

This error originated from a custom integration.

Logger: custom_components.wiser.coordinator
Source: custom_components/wiser/coordinator.py:138
Integration: Drayton Wiser Integration for Home Assistant (documentation, issues)
First occurred: 20:18:43 (1 occurrences)
Last logged: 20:18:43

Unexpected error fetching wiser (wiser-WiserHeatXXXXXX) data: unsupported operand type(s) for +: 'NoneType' and 'float'
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 290, in _async_refresh
    self.data = await self._async_update_data()
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 246, in _async_update_data
    return await self.update_method()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/wiser/coordinator.py", line 159, in async_update_data
    raise ex
  File "/config/custom_components/wiser/coordinator.py", line 138, in async_update_data
    await self.wiserhub.read_hub_data()
  File "/usr/local/lib/python3.11/site-packages/aioWiserHeatAPI/wiserhub.py", line 138, in read_hub_data
    if await automations.run_automations():
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/aioWiserHeatAPI/helpers/automations.py", line 21, in run_automations
    return await self.passive_mode_control()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/aioWiserHeatAPI/helpers/automations.py", line 60, in passive_mode_control
    room.current_temperature
TypeError: unsupported operand type(s) for +: 'NoneType' and 'float'

and:

This error originated from a custom integration.

Logger: custom_components.wiser.coordinator
Source: custom_components/wiser/coordinator.py:158
Integration: Drayton Wiser Integration for Home Assistant (documentation, issues)
First occurred: 20:18:43 (1 occurrences)
Last logged: 20:18:43

unsupported operand type(s) for +: 'NoneType' and 'float'

Any idea what has caused this and how to fix it? I think it may have started after adjusting a couple of schedules through the integration. I’ve powered off the hub for a while and restarted Home Assistant, but I can’t clear the problem. The Wiser App appears to be working as normal.

Ive had this caused by a trv with a flat battery. I have on list to fix but didnt think urgent as noone else reported. I found if you leave it, it will come back or take whichever room has a flat battery out of passive mode. You may have to edit the file in config/.storage. or put a new battery in it obviously! :grinning:

Your right. Found the flame on in the Slave status and just confirmed working. Thanks
The new sensor:

- sensor:
    - name: "Boiler Status"
      state: >-
         {{ state_attr('sensor.wiser_lts_boiler_flow_temperature','slave_status') }}
      attributes:
        fault: "{% if state_attr('sensor.wiser_lts_boiler_flow_temperature','slave_status') | int | bitwise_and(1) %}on{% else %}off{% endif %}"
        ch1_mode: "{% if state_attr('sensor.wiser_lts_boiler_flow_temperature','slave_status') | int | bitwise_and(2) %}on{% else %}off{% endif %}"
        dhw_mode: "{% if state_attr('sensor.wiser_lts_boiler_flow_temperature','slave_status') | int | bitwise_and(4) %}on{% else %}off{% endif %}"
        flame_status: "{% if state_attr('sensor.wiser_lts_boiler_flow_temperature','slave_status') | int | bitwise_and(8) %}on{% else %}off{% endif %}"
        cooling_status: "{% if state_attr('sensor.wiser_lts_boiler_flow_temperature','slave_status') | int | bitwise_and(16) %}on{% else %}off{% endif %}"
        ch2_mode: "{% if state_attr('sensor.wiser_lts_boiler_flow_temperature','slave_status') | int | bitwise_and(32) %}on{% else %}off{% endif %}"
        diagnostic: "{% if state_attr('sensor.wiser_lts_boiler_flow_temperature','slave_status') | int | bitwise_and(64) %}on{% else %}off{% endif %}"

Thanks @msp1974. We’ve not long returned from holiday and the batteries in the Garage iTRV were completely flat. I can confirm that the Garage is in Passive Mode and I replaced the batteries and it’s loading/setting up fine again now.

It looks like it’s time to replace all the iTRV batteries as we go into the heating season, as they are all showing low. I guess a once a year/season replacement schedule is fairly normal for the iTRVs (Room Thermostats are all still at 100%)? It’s only the second year/season I have been using Wiser and the first time I have had to replace any batteries.

you maybe want to change the | int to |int(0), so you do not get errors on startup (when the sensor could be None and not a value

2023-10-04 12:36:38.912 ERROR (MainThread) [homeassistant.components.template.template_entity] TemplateError('ValueError: Template error: int got invalid input 'None' when rendering template '{% if state_attr('sensor.wiser_lts_boiler_flow_temperature','slave_status') | int | bitwise_and(1) %}on{% else %}off{% endif %}' but no default was specified') while processing template 'Template<template=({% if state_attr('sensor.wiser_lts_boiler_flow_temperature','slave_status') | int | bitwise_and(1) %}on{% else %}off{% endif %}) renders=4>' for attribute 'fault' in entity 'sensor.heating_state'
      fault: "{% if state_attr('sensor.wiser_lts_boiler_flow_temperature','slave_status') | int(0) | bitwise_and(1) %}on{% else %}off{% endif %}"
      ch1_mode: "{% if state_attr('sensor.wiser_lts_boiler_flow_temperature','slave_status') | int(0) | bitwise_and(2) %}on{% else %}off{% endif %}"
      dhw_mode: "{% if state_attr('sensor.wiser_lts_boiler_flow_temperature','slave_status') | int(0) | bitwise_and(4) %}on{% else %}off{% endif %}"
      flame_status: "{% if state_attr('sensor.wiser_lts_boiler_flow_temperature','slave_status') | int(0) | bitwise_and(8) %}on{% else %}off{% endif %}"
      cooling_status: "{% if state_attr('sensor.wiser_lts_boiler_flow_temperature','slave_status') | int(0) | bitwise_and(16) %}on{% else %}off{% endif %}"
      ch2_mode: "{% if state_attr('sensor.wiser_lts_boiler_flow_temperature','slave_status') | int(0) | bitwise_and(32) %}on{% else %}off{% endif %}"
      diagnostic: "{% if state_attr('sensor.wiser_lts_boiler_flow_temperature','slave_status') | int(0) | bitwise_and(64) %}on{% else %}off{% endif %}"

Glad it worked. And not to worry, it will def be fixed by start of next season. Also, how posh are you with heating in the garage! :grin:

3 Likes

got to keep his “Baby” warm :smiley:

1 Like

It’s a newish (five year old) house and the garage is integral to the house and consequently insulated. Unusual I know. :smile:

I live in a 1970’s house with crap insulation, so I am getting my house Externally Insulated and Rendered next year, so hopefully this will be my last winter with costly GAS bills.