Honeywell CH/DHW via RF - evohome, sundial, hometronics, chronotherm

The 2210 packet is not well understood. Anyone receiving this message is encouraged to PM me with 24h packet logs, and a description of their hardware.

Hi I have now got things up and running and have 131 Ramses entities - For each room I have one Climate control, one heat demand & one Window Open. I also have numerous unassociated entities of heat demand, temperature & battery low. I am guessing that the unassociated entities, heat demand & temperature sensors are further TRVā€™s I have in those locations. How do I associate those as I cant find any corrulating number combos, etc?
Also I have a R8810A OpenTherm Bridge I am not sure what entities it should have created (cant see anything obvious). It is a little way from the reciever so maybe no communication. I pressed the button on the R8810A and got some flashing green lights but nothing else added.
I have read from the top of this topic but so much changed and so much info I may have missed the relevant post.
Thanks

Impressive.

Have a look at the extra state attrs of the various entitles, starting with the one with the address 18:xxxxxx.

For the rest, please provide a packet log, if you wish me to comment on it.

This is better:

ramses_cc:
  serial_port: /dev/ttyUSB1

  packet_log:
    file_name: ramses_packet.log
    rotate_backups: 7
    # restore_cache: false  # set false only when required, and set true after HA reboot

  # there are only 2 reasons, commonly encountered, where CH/DHW (evohome) 
  # needs a hand-crafted schema, and they are both seen below
  01:155672:
    system:
      appliance_control: 10:102998  # 1 of 2 - OTB as appliance controller
    zones:
      "00": { sensor: 01:155672 } # . 2 of 2 - CTL as sensor

  known_list:  # avoid aliases: they are to be deprecated one day
    01:155672: 
    10:102998: 
    13:184464: 
    18:069890: { class: HGI } # only 18: and 30: (RFG) need defining

  ramses_rf:
    enforce_known_list: false  # set true as soon as you can
    # enable_eavesdrop: true  # set true only if required, and only when required
    # use_native_ot: always  # use_native_ot is generally not needed

Thanks for the edited config. Can you please let me know why did you removed the actuators section from the zone config? Is it irrelevant there? The BDR91 turns on/off the pump in the heating system.

Iā€™ll send you the last 24 hours packet log, the

RP --- 01:155672 18:069890 --:------ 000C 006 000F0036D090 < CorruptStateError(Inconsistent schema: 13:184464 (BDR): None cant change parent (01:155672_00 (VAL)_00 to 01:155672 (evohome)_FC)(try restarting the client library))

error still persist in the log if I restart HA. The data for DHW temperature and the boiler output temperature still comes in for a few hours and then turns to unavailable, while other data from the OTB arrives. Really strange.

And one last question: changing parameters in the ramses_cc section in the configuration.yaml need a complete HA restart, or reloading all yaml configuration is enough? For example if I comment out the restore cache: false, I should restart HA?

Unless you disable discovery, ramses_rf can deterministically work out what kit is configured where by simply asking the controller.

When you hand-craft a schema, you are telling ramses_rf what you believe to be true.

If it is left to discovery, then youā€™ll get what is true.

Many, many times people have found out that the former doesnā€™t match the latter!

Anyway, discovery works really well, except in two circumstance (and some other edge-cases), where you canā€™t discover:

  1. When the evohome conttoller is the sensor for a zone
  2. when an OpenTherm bridge is the relay for a heat source

ā€¦ in these cases, you need to supply a hand-crafted schema.

You have to restart HA.

You have provided me with a 24h packet log, and for the benefit of all, I will decode it here:

> cat .secrets/wonders/2023-11-13.log | grep -E ' RP.* 0005 ' | python client.py parse

17:47:52.798 ||  01:155672 |  18:069890 | RP | system_zones     | 0008 || {'zone_type': '08', 'zone_mask': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'zone_class': 'radiator_valve'}
17:47:52.999 ||  01:155672 |  18:069890 | RP | system_zones     | 0009 || {'zone_type': '09', 'zone_mask': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'zone_class': 'underfloor_heating'}
17:47:53.201 ||  01:155672 |  18:069890 | RP | system_zones     | 000A || {'zone_type': '0A', 'zone_mask': [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'zone_class': 'zone_valve'}
17:47:53.402 ||  01:155672 |  18:069890 | RP | system_zones     | 000B || {'zone_type': '0B', 'zone_mask': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'zone_class': 'mixing_valve'}
17:47:53.603 ||  01:155672 |  18:069890 | RP | system_zones     | 0011 || {'zone_type': '11', 'zone_mask': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'zone_class': 'electric_heat'}

The above tells me you have one heating zone, a zone valve zone, and it is zone_idx = '00'.

> cat .secrets/wonders/2023-11-13.log | grep -E ' RP.* 000C ' | python client.py parse

17:46:53.722 ||  01:155672 |  18:069890 | RP | zone_devices     | 0000 || {'zone_type': '00', 'zone_idx': '00', 'device_role': 'zone_actuator', 'devices': ['13:184464']}
17:46:56.814 ||  01:155672 |  18:069890 | RP | zone_devices     | 0004 || {'zone_type': '04', 'zone_idx': '00', 'device_role': 'zone_sensor', 'devices': []}
17:47:49.384 ||  01:155672 |  18:069890 | RP | zone_devices     | 000E || {'zone_type': '0E', 'domain_id': 'FA', 'device_role': 'hotwater_valve', 'devices': []}
17:47:52.479 ||  01:155672 |  18:069890 | RP | zone_devices     | 010E || {'zone_type': '0E', 'domain_id': 'F9', 'device_role': 'heating_valve', 'devices': []}
17:47:52.599 ||  01:155672 |  18:069890 | RP | zone_devices     | 000D || {'zone_type': '0D', 'domain_id': 'FA', 'device_role': 'dhw_sensor', 'devices': []}
17:47:56.901 ||  01:155672 |  18:069890 | RP | zone_devices     | 000F || {'zone_type': '0F', 'domain_id': 'FC', 'device_role': 'appliance_control', 'devices': ['13:184464']}

The above tells me that the error message is appropriate - you system is miss-configured.

The BDR is the relay (actuator) for the zone with idx = ā€œ00ā€ and is also the relay acting as the appliance controller - this is not a valid configuration.

If your system was configured correctly with an OTB, you should see an empty list of actuators, like so:

17:47:56.901 ||  01:155672 |  18:069890 | RP | zone_devices     | 000F || {'zone_type': '0F', 'domain_id': 'FC', 'device_role': 'appliance_control', 'devices': []}

Howeverā€¦

I see that the relationship between the controller and the OTB appears sound:

> cat .secrets/wonders/2023-11-13.log | grep -E 'RP.* 10:' | head | python client.py parse

00:03:30.362 ||  10:102998 |  01:155672 | RP | actuator_state   |      || {'modulation_level': 0.0, '_flags_2': '10', '_flags_3': [0, 0, 0, 0, 0, 0, 1, 0], 'ch_active': True, 'dhw_active': False, 'cool_active': False, 'flame_on':
00:03:36.713 ||  10:102998 |  18:069890 | RP | boiler_setpoint  |      || {'setpoint': 23.0}
00:03:46.560 ||  10:102998 |  01:155672 | RP | boiler_setpoint  |      || {'setpoint': 23.0}
00:03:47.521 ||  10:102998 |  01:155672 | RP | opentherm_msg    |  05  || {'msg_id': 5, 'msg_type': 'Read-Ack', 'msg_name': 'fault_flags', 'value_hb': [0, 0, 0, 0, 0, 0, 0, 0], 'value_lb': 0, 'description': 'Fault flags & OEM faul
00:03:48.154 ||  10:102998 |  01:155672 | RP | opentherm_msg    |  11  || {'msg_id': 17, 'msg_type': 'Read-Ack', 'msg_name': 'RelativeModulationLevel', 'value': 0.0, 'description': 'Relative modulation level'}
00:03:48.656 ||  10:102998 |  01:155672 | RP | opentherm_msg    |  12  || {'msg_id': 18, 'msg_type': 'Unknown-DataId', 'msg_name': 'CHWaterPressure', 'description': 'Central heating water pressure (bar)'}
00:03:49.165 ||  10:102998 |  01:155672 | RP | opentherm_msg    |  13  || {'msg_id': 19, 'msg_type': 'Unknown-DataId', 'msg_name': 'DHWFlowRate', 'description': 'DHW flow rate (litres/minute)'}

The other thing is, I wonder if your BDR should be a HW/heating valve, but isnā€™t, for example:

12:46:27.165 ||  01:145038 |  18:006402 | RP | zone_devices     | 000E || {'zone_type': '0E', 'domain_id': 'FA', 'device_role': 'hotwater_valve', 'devices': ['13:237335']}
12:46:27.188 ||  01:145038 |  18:006402 | RP | zone_devices     | 010E || {'zone_type': '0E', 'domain_id': 'F9', 'device_role': 'heating_valve', 'devices': []}

In summaryā€¦

It appears to me that your system is mis-configured - maybe there is something wrong with the controllerā€™s internal data structuresā€¦

If you enter the setup menu on the controller - what do you see?

Your system is so simple, Iā€™d be tempted to simply wipe the controller, and re-configure it. You only have to bind two devices.

Just backup the schedule beforehand, and you can restore it after.

OK, version 0.30.1 just released - I believe it fixes all report bugs thus far.

Please report more bugs!

This bug can be ignored:

AttributeError: 'NoneType' object has no attribute 'send_frame'

I updated to 0.30.1.

I have ā€˜unavailableā€™ in the Orcon HRC sensors:
sensor.32_139773_exhaust_temperature
sensor.32_139773_indoor_temperature
sensor.32_139773_supply_temperature
sensor.32_139773_outdoor_temperature
sensor.32_139773_remaining_time
The data is present in the logs

2023-11-14 00:40:33.244 INFO (MainThread) [ramses_rf.dispatcher] || 32:139773 | | I | hvac_state | 00 || {'hvac_id': '00', 'fan_info': 'speed 2 temporary override', '_unknown_fan_info_flags': [0, 0, 0], 'air_quality': None, 'co2_level': None, 'indoor_humidity': 0.52, 'outdoor_humidity': 0.53, 'exhaust_temp': 13.3, 'supply_temp': 18.5, 'indoor_temp': 19.75, 'outdoor_temp': 12.51, 'speed_capabilities': ['low_med_high', 'timer', 'auto', 'pre_heater'], 'bypass_position': 0.0, 'exhaust_fan_speed': 0.37, 'supply_fan_speed': 0.37, 'remaining_mins': 14, 'post_heat': None, 'pre_heat': 0.0, 'supply_flow': 30.25, 'exhaust_flow': 30.52}

Also five startup HA core errors:


Logger: ramses_tx.parsers
Source: runner.py:188
First occurred: 00:30:07 (4 occurrences)
Last logged: 00:42:36

I --- 32:131922 32:139773 --:------ 22F1 003 000504 < Support the development of ramses_rf by reporting this packet (mode_idx > mode_max)

###

Logger: ramses_rf.entity_base
Source: runner.py:188
First occurred: 00:21:56 (3 occurrences)
Last logged: 00:22:12

No response for task(22F8|RP|32:139773): throttling to 1/6h
No response for task(2210|RP|32:139773): throttling to 1/6h
No response for task(313E|RP|32:139773): throttling to 1/6h

###

Logger: ramses_tx.message
Source: /usr/local/lib/python3.11/site-packages/ramses_tx/message.py:280
First occurred: 00:21:59 (1 occurrences)
Last logged: 00:21:59

RP --- 32:139773 18:072982 --:------ 2210 042 00FF00FFFFFF0000000000FFFFFFFFFF00FFFFFF0000000000FFFFFFFFFFFFFFFF000000000000020800 < AssertionError(Support the development of ramses_rf by reporting this packet)
Traceback (most recent call last):
  File "/usr/local/lib/python3.11/site-packages/ramses_tx/message.py", line 261, in _validate
    result = PAYLOAD_PARSERS.get(self.code, parser_unknown)(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/ramses_tx/parsers.py", line 173, in wrapper
    result = fnc(payload, msg, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/ramses_tx/parsers.py", line 1350, in parser_2210
    assert payload in (
           ^^^^^^^^^^^^
AssertionError: Support the development of ramses_rf by reporting this packet


###

Logger: ramses_tx.transport
Source: runner.py:188
First occurred: 00:20:03 (1 occurrences)
Last logged: 00:20:03

/dev/serial/by-id/usb-SparkFun_evofw3_atmega32u4-if00: the gateway type is not determinable, will assume evofw3 (check you have the rights to enumerate USB attrs?)

###

Deze fout is ontstaan door een aangepaste integratie.

Logger: ramses_tx.protocol
Source: custom_components/ramses_cc/coordinator.py:141
Integration: RAMSES RF (documentation, issues)
First occurred: 00:20:03 (1 occurrences)
Last logged: 00:20:03

PortProtocol: QoS has been disabled

sensor.32_139773_exhaust_temperature
sensor.32_139773_indoor_temperature
sensor.32_139773_supply_temperature
sensor.32_139773_outdoor_temperature
sensor.32_139773_remaining_time

The unavailable sensors are not found in the logs. I find a lot of
INFO (MainThread) [custom_components.ramses_cc.sensor] Found a Sensor for 32:xxxxxx
notifications, but no notification for the sensors above.

THanks for the pointer to State Attrs, I am now able to identify the seperate TRVā€™s. I am now updating to relevant name and location and will then look at creating known devices, I am still trying to understand fully the config yaml.
My packet log is 27000 entries per day, obviously I dont want to past that in here.
Really appreciate your help on such a fantastic project.

Frist of all, thanks for the analysis!
In the configuration menu I can see that thereā€™s only one zone, the BDR is paired as the zone valve and the OTB is also paired as the OTB and the Evohome controller is the sensor. Nothing special. Do you think this missconfiguration can cause that the OTB stops sending the boiler output temperature and the DHW temperature after a few hours?

This is a breaking change. They are now called:

sensor.32_139773_exhaust_temp
sensor.32_139773_indoor_temp
sensor.32_139773_supply_temp
sensor.32_139773_outdoor_temp
sensor.32_139773_remaining_mins

I will rename them back to what they wereā€¦

I have made my recommendation.

I pushed a new version of ramses_rf and the implication was that there was a bug in the code (which was quite likely). I have since explained to you - in some detail - that there is nothing wrong with the code, and your system appears mis-configured.

The ā€˜stops sending after a few hoursā€™ is likely due to poor reception. You can try moving the dongle closer to the OTB, if you like.

If you are not willing to enact my recommendation - which is completely OK by me - I am not sure I can help you any more.

Hi,

I have an electric (dry) UFH system controlled by two CM927 thermostats which control three HC60NG relay units (one of the thermostats is bound to two of the relays).

I have an SSM-D2 and Iā€™ve been working through the ramses_cc and ramses_protocol wikis.

Iā€™ve got the SSM-D2 picking up the traffic and I can see the Relay demand, Mix zone config, Zone setpoint and System datetime packet types in the packet log.

I am now trying to set up the faking and have got as far as ā€œStep 2: Ensure the device is instantiatedā€.

A schema was automatically generated with both thermostats in an orphans_heat list which I added to the configuration. The automatically generated schema also included a main_tcs property with the value None but when I tried to add this to the configuration, it complained that it was invalid. Should I even be trying to add the schema to the configuration given that it is automatically generated anyway?

At this point, I donā€™t know if I have done everything necessary for the set-up of the faking and I donā€™t know how to check or test it. When it says that the devices will be instantiated (created), does it mean that they will then show up under Settings > Devices & Services > Devices in the UI? There is nothing there currently.

Under ā€œUsing faked devicesā€, it says ā€œyou then use the appropriate service call to cause the faked device to broadcast the relevant packetā€. How do I set this up?

Thanks,

Jonathan

Welcome!

The good new is that I am about to focus on faking / binding, once we iron out the current round of bugs introduced by the refactored client, ramses_rf.

In many ways, that was why the lower layers of ramses_rf were re-written.

You havenā€™t said what youā€™re trying to fake, but I assume its a temperature sensor?

Currently, only sensors (temp, CO2, Humidity), and (HVAC) remotes are supported - actuators will come.

This is the correct move - AFAIK, there is no discovery with CM927s. It will serve to a) instantiate these devices as sensors.

I donā€™t think it will b) create any climate entities, only sensors.

Please confirm a) & b) are both true. Are the CM927s mains powered? I would be interested to see one of your packet logs (you can PM me a link).

Donā€™t add main_tcs to your schema, it serves no purpose.

There is a difference between faking and instantiation.

The schema controls whether a device is instantiated (created) - invariably at startup of HA; the known_list controls how a device s instantiated - what happens if it is instantiated.

So, ā€œimpersonationā€ is faking a real device that is being instantiated because it is in the schema, its packets are in the cache, or it is simply ā€˜talkingā€™.

Pure ā€œfakingā€ is when the device only exists in the schema and is instantiated because of that.

First thing is to get the devices to appear.

Thanks for the help David!

Sorry, a little more background would have been useful. Iā€™m on a time of use tariff (Octopus Agile) and I want to use home assistant to make use of the daily tariff data to automatically determine the best times to run the heating. So Iā€™m guessing that I need to impersonate the CM927ā€™s so that the SSM-D2 can send the heat demand packets to achieve this (and perhaps some of the other packets for system integrity? - not sure if they would be needed or not).

So on the HA overview page there is a Binary Sensor section with thisā€¦

12:xxxxxx battery_low Normal
12:yyyyyy battery_low Normal
18:zzzzzz status OK

and a Sensor section with thisā€¦

12:xxxxxx temperature Unavailable
12:yyyyyy temperature Unavailable

Is this all of the device instantiation that is expected?

They are not.

Sure.

Multiple controllers can bind to a BDR91ā€¦ If the HCG90NG can do the same, then Iā€™d simply use ramses_cc to bind a fake controller to each, so that it can invoke a call for heat.

Impersonating an active CM927 wouldnā€™t work, as it would be calling for (say) 0% heat demand, overruling your faked call for 100%.

Impersonating a deactivated CM927 (i.e. turn off the physical device) would be doable, but would be a lot of work at this stage.

How would this be different from impersonating an active CM927? Wouldnā€™t there still be a conflict?

That was the intention since the CM927 canā€™t use the tariff data. I donā€™t see how I could achieve the overall goal of tariff data-driven heating control if the CM927ā€™s remained active.