zigpy / zha-device-handlers

ZHA device handlers bridge the functionality gap created when manufacturers deviate from the ZCL specification, handling deviations and exceptions by parsing custom messages to and from Zigbee devices.
Apache License 2.0
760 stars 698 forks source link

[Device Support Request] TS0601 _TZE200_hue3yfsn / TV02 Zigbee TRV #1027

Closed dodekaphilist closed 2 years ago

dodekaphilist commented 3 years ago

Is your feature request related to a problem? Please describe. I bought this thermostat from AliExpress. It's possible to pair with ZHA, but no entities are exposed.

Describe the solution you'd like Ideally, I'd like to control all settings these Tuya based thermostats have. I know that Zigbee2MQTT seems to be able to do that (Source)

Device signature

  "node_descriptor": "NodeDescriptor(logical_type=<LogicalType.EndDevice: 2>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress: 128>, manufacturer_code=4098, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)",
  "endpoints": {
    "1": {
      "profile_id": 260,
      "device_type": "0x0051",
      "in_clusters": [
        "0x0000",
        "0x0004",
        "0x0005",
        "0xef00"
      ],
      "out_clusters": [
        "0x000a",
        "0x0019"
      ]
    }
  },
  "manufacturer": "_TZE200_hue3yfsn",
  "model": "TS0601",
  "class": "zigpy.device.Device"
}

Additional context The thermostat has no branding whatsoever (neither the device itself, nor the packaging material), I can't tell who is the actual manufacturer. In the included manual it's refered to as TV02 Zigbee Thermostat Radiator Valve I bought it from this link: AliExpress

diti1377 commented 3 years ago

Vielleicht kann das weiter helfen, ich hab meine TRVs angebunden. 10 frost: 0 Frost Protection
101 KSSW: 1 SECOND 102 KCWD: 5 度 Open Window 104 SSWD: 21 度 Comfortable Temp 105 JLWD: 17 度 ECO Temp 107 Heating_Stopping: 0 Heating Stop 108 mod_program001: Zeitplan Montag 109 wed_program003: 110 fri_program005:
111 sun_program007: 112 tue_program002: 113 thur_program004: 114 sat_program006: 115 online: 1 16 temp_set: 18.5 ℃ (SET.Temp)
2 mode: auto 24 temp_current: 21.8 ℃
27 temp_correction: 0.1
31 work_days: all 32 holiday_temp_set: 17 ℃ Holiday Mode 35 battery_percentage: 100 %; 40 child_lock: 0
45 fault: 1 46 holiday_set: 201
8 window_check: 0 ;

dodekaphilist commented 3 years ago

Can you state more precisely where this information needs to go to?

rforro commented 3 years ago

It looks like the LIDL Thermostat #1061 uses the same attributes. Read the whole discussion, especially this comment.

MattWestb commented 3 years ago

If its using the same DPs ad the LIDL TRV then is shall working if adding the device id as in #1061. I dont have the device but adding the device ID in one new line in the block: https://github.com/zigpy/zha-device-handlers/blob/9a5bcd45bb99d0df8b014703e0bad9efe067609c/zhaquirks/tuya/valve.py#L986 Like this:

        MODELS_INFO: [
            ("_TZE200_ckud7u2l", "TS0601"),
            ("_TZE200_ywdxldoj", "TS0601"),
            ("_TZE200_cwnjrr72", "TS0601"),
            ("_TZE200_b6wax7g0", "TS0601"),
            ("_TZE200_hue3yfsn", "TS0601"),
        ],

Its also needed adding the device ID in ZHA for getting all function to working all the way as being done in thes PR home-assistant/core#52065.

If some brave user like testing its being great getting it verified if its working OK or not.

Edit: Need fixing the cluster for getting the quirk to loading :-(( Edit 2: False alarm the Zigbee module is having the same cluster config so it shall loading OK.

MattWestb commented 3 years ago

@diti1377 You was writing in Iobroker that one user have written one quirk for one TRV in ZHA that have the same DPs like this but i cant finding the user name and the quirk. Can you pleas putting my in the right direction to finding it pleas ?

MattWestb commented 3 years ago

OK i think i getting it its the

Zonnsmart | TV01-ZG -- | --

:-)))

MattWestb commented 3 years ago

If one brave user like testing if its working by adding this around this line: https://github.com/zigpy/zha-device-handlers/blob/b5d29f52211f3a613410e22d356b31e1ba835e16/zhaquirks/tuya/valve.py#L1072 By adding the lat line in the MODEL_INFO:

        MODELS_INFO: [
            ("_TZE200_e9ba97vf", "TS0601"),
            ("_TZE200_husqqvux", "TS0601"),
            ("_TZE200_hue3yfsn", "TS0601"),
        ],

Configuring local quirk in HA and adding the updated valve.py in the folder and restarting HA.

dodekaphilist commented 3 years ago

Its also needed adding the device ID in ZHA for getting all function to working all the way as being done in thes PR home-assistant/core#52065.

@MattWestb Do you know if there is an easy way of doing this locally for testing purposes?

Without this change, I tried to add the model info to all thermostat classes that match the signature of this TRV, but none of them worked. While I get some entities, those can't be controlled or give any information. image

MattWestb commented 3 years ago

If you is adding the model_id to more signatures and more then one is matching i think ZHA is using the first match (or the last one i dont knowing the logic).

Your device is having one on/off switch so i think its one Moes or one Sas that is loaded. You can see the name of the loaded quirk in the last line on the device profile or on the device card.

Deleting all your added model_ids and only adding it to the ZonnsmartTV01_ZG then its looks matching your device DPs and restarting HA.

With the last ZonnsmartTV01_ZG you shall not do the ZAH fix then its not using the Moes TRV quirk so only adding the model _id or you is getting errors and HA is not starting.

dodekaphilist commented 3 years ago

Ok, maybe I should clarify that I tested each class separately one at a time and didn't add the model info to all classes simultaneously. Each time with a similar result.

MattWestb commented 3 years ago

OK then its little different.

If you is doing the changes in the local quirk you must deleting the __pycache__ folder between the changes and restart of HA or the system is using old cached code. Its the same if you is doing the changes in the HA container.

Witch method is you using local quirk or editing the HA container ?

Then you is getting one thermostat in ZHA GUI you can configuring debug logging by adding:

    zhaquirks.tuya: debug

in HA config.

Then removing the battery for some minutes and putting them back and you shall getting all DP the device can / is using sent to ZHA from it. If you is getting the DP log pleas posting the log so we can comparing it with all known devices.

dodekaphilist commented 3 years ago

Okay, so I reset the device and started a new pairing process with the model info added to the ZonnsmartTV01_ZG class, loaded via a local quirk and deleted the pycache folder. image It did work and I got some correct information, while some entities are missing. You can check the logs below

[0x0000:zdo] ZDO request ZDOCmd.Mgmt_Permit_Joining_req: [60, <Bool.false: 0>]
New device 0xf64f (50:32:5f:ff:fe:67:7a:76) joined the network
[0xf64f] Scheduling initialization
Received frame on uninitialized device <Device model=None manuf=None nwk=0xF64F ieee=50:32:5f:ff:fe:67:7a:76 is_initialized=False> from ep 0 to ep 0, cluster 19: b'\x84O\xf6vzg\xfe\xff_2P\x80'
[0xf64f:zdo] ZDO request ZDOCmd.Device_annce: [0xF64F, 50:32:5f:ff:fe:67:7a:76, 128]
Tries remaining: 3
[0xf64f] Requesting 'Node Descriptor'
Tries remaining: 2
[0xf64f] Extending timeout for 0x1f request
Received frame on uninitialized device <Device model=None manuf=None nwk=0xF64F ieee=50:32:5f:ff:fe:67:7a:76 is_initialized=False> from ep 0 to ep 0, cluster 32770: b'\x1f\x00O\xf6\x02@\x80\x02\x10RR\x00\x00,R\x00\x00'
[0xf64f] Got Node Descriptor: NodeDescriptor(logical_type=<LogicalType.EndDevice: 2>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress: 128>, manufacturer_code=4098, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)
[0xf64f] Discovering endpoints
Tries remaining: 3
[0xf64f] Extending timeout for 0x21 request
Received frame on uninitialized device <Device model=None manuf=None nwk=0xF64F ieee=50:32:5f:ff:fe:67:7a:76 is_initialized=False> from ep 0 to ep 0, cluster 32773: b'!\x00O\xf6\x01\x01'
[0xf64f] Discovered endpoints: [1]
[0xf64f] Initializing endpoints [<Endpoint id=1 in=[] out=[] status=<Status.NEW: 0>>]
[0xf64f:1] Discovering endpoint information
Tries remaining: 3
[0xf64f] Extending timeout for 0x23 request
Received frame on uninitialized device <Device model=None manuf=None nwk=0xF64F ieee=50:32:5f:ff:fe:67:7a:76 is_initialized=False> from ep 0 to ep 0, cluster 32772: b'#\x00O\xf6\x14\x01\x04\x01Q\x00\x01\x04\x00\x00\x04\x00\x05\x00\x00\xef\x02\x19\x00\n\x00'
[0xf64f:1] Discovered endpoint information: SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=81, device_version=1, input_clusters=[0, 4, 5, 61184], output_clusters=[25, 10])
Unknown cluster 61184
[0xf64f] Extending timeout for 0x25 request
[0xf64f:1:0x0000] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=37 command_id=Command.Read_Attributes_rsp>
[0xf64f] Read model 'TS0601' and manufacturer '_TZE200_hue3yfsn' from <Endpoint id=1 in=[basic:0x0000, groups:0x0004, scenes:0x0005, None:0xEF00] out=[ota:0x0019, time:0x000A] status=<Status.ZDO_INIT: 1>>
[0xf64f] Discovered basic device information for <Device model='TS0601' manuf='_TZE200_hue3yfsn' nwk=0xF64F ieee=50:32:5f:ff:fe:67:7a:76 is_initialized=True>
Device is initialized <Device model='TS0601' manuf='_TZE200_hue3yfsn' nwk=0xF64F ieee=50:32:5f:ff:fe:67:7a:76 is_initialized=True>
Checking quirks for _TZE200_hue3yfsn TS0601 (50:32:5f:ff:fe:67:7a:76)
Considering <class 'tuya.valve.ZonnsmartTV01_ZG'>
Found custom device replacement for 50:32:5f:ff:fe:67:7a:76: <class 'tuya.valve.ZonnsmartTV01_ZG'>
device - 0xF64F:50:32:5f:ff:fe:67:7a:76 entering async_device_initialized - is_new_join: True
device - 0xF64F:50:32:5f:ff:fe:67:7a:76 has joined the ZHA zigbee network
[0xF64F](TS0601): started configuration
[0xF64F:ZDO](TS0601): 'async_configure' stage succeeded
[0xF64F:1:0x0201]: bound 'thermostat' cluster: Status.SUCCESS
[0xF64F:1:0x0201]: Successfully configured reporting for '{'local_temp': (30, 900, 25), 'occupied_cooling_setpoint': (30, 900, 25), 'occupied_heating_setpoint': (30, 900, 25)}' on 'thermostat' cluster: [ConfigureReportingResponseRecord(status=0)]
[0xF64F:1:0x0201]: Successfully configured reporting for '{'unoccupied_cooling_setpoint': (30, 900, 25), 'unoccupied_heating_setpoint': (30, 900, 25), 'running_mode': (30, 900, 25)}' on 'thermostat' cluster: [ConfigureReportingResponseRecord(status=0)]
[0xF64F:1:0x0201]: Successfully configured reporting for '{'running_state': (30, 900, 5), 'system_mode': (30, 900, 25), 'occupancy': (30, 900, 1)}' on 'thermostat' cluster: [ConfigureReportingResponseRecord(status=0)]
[0xF64F:1:0x0201]: Successfully configured reporting for '{'pi_cooling_demand': (30, 900, 5), 'pi_heating_demand': (30, 900, 5)}' on 'thermostat' cluster: [ConfigureReportingResponseRecord(status=0)]
[0xF64F:1:0x0201]: finished channel configuration
[0xF64F:1:0x0000]: finished channel configuration
[0xF64F:1:0x0001]: bound 'power' cluster: Status.SUCCESS
[0xF64F:1:0x0001]: Successfully configured reporting for '{'battery_voltage': (3600, 10800, 1), 'battery_percentage_remaining': (3600, 10800, 1)}' on 'power' cluster: [ConfigureReportingResponseRecord(status=0)]
[0xF64F:1:0x0001]: finished channel configuration
[0xF64F:1:0x0019]: finished channel configuration
Error handling '_save_attribute' event with (50:32:5f:ff:fe:67:7a:76, 1, 0, 4, '_TZE200_hue3yfsn') params: FOREIGN KEY constraint failed
[0xF64F:1:0x0201]: 'async_configure' stage succeeded
[0xF64F:1:0x0000]: 'async_configure' stage succeeded
[0xF64F:1:0x0001]: 'async_configure' stage succeeded
[0xF64F:1:0x0019]: 'async_configure' stage succeeded
Error handling '_save_attribute' event with (50:32:5f:ff:fe:67:7a:76, 1, 0, 5, 'TS0601') params: FOREIGN KEY constraint failed
[0xF64F](TS0601): completed configuration
[0xF64F](TS0601): stored in registry: ZhaDeviceEntry(name='_TZE200_hue3yfsn TS0601', ieee='50:32:5f:ff:fe:67:7a:76', last_seen=1634410438.0997021)
[0xF64F](TS0601): started initialization
[0xF64F:ZDO](TS0601): 'async_initialize' stage succeeded
[0xF64F:1:0x0201]: initializing channel: from_cache: False
[0xF64F:1:0x0201]: Attribute report 'ZONNSMARTThermostat'[ctrl_seqe_of_oper] = ControlSequenceOfOperation.Heating_Only
[0xF64F:1:0x0201]: Attribute report 'ZONNSMARTThermostat'[ctrl_seqe_of_oper] = ControlSequenceOfOperation.Heating_Only
[0xF64F:1:0x0201]: Attribute report 'ZONNSMARTThermostat'[ctrl_seqe_of_oper] = ControlSequenceOfOperation.Heating_Only
[0xF64F:1:0x0201]: finished channel configuration
[0xF64F:1:0x0000]: initializing channel: from_cache: False
[0xF64F:1:0x0000]: finished channel configuration
[0xF64F:1:0x0001]: initializing channel: from_cache: False
[0xF64F:1:0x0001]: finished channel configuration
[0xF64F:1:0x0019]: initializing channel: from_cache: False
[0xF64F:1:0x0019]: finished channel configuration
[0xF64F:1:0x0201]: 'async_initialize' stage succeeded
[0xF64F:1:0x0000]: 'async_initialize' stage succeeded
[0xF64F:1:0x0001]: 'async_initialize' stage succeeded
[0xF64F:1:0x0019]: 'async_initialize' stage succeeded
[0xF64F](TS0601): power source: Battery or Unknown
[0xF64F](TS0601): completed initialization
Error handling '_unsupported_attribute_added' event with (50:32:5f:ff:fe:67:7a:76, 1, 513, 0) params: FOREIGN KEY constraint failed
Error handling '_unsupported_attribute_added' event with (50:32:5f:ff:fe:67:7a:76, 1, 513, 17) params: FOREIGN KEY constraint failed
Error handling '_unsupported_attribute_added' event with (50:32:5f:ff:fe:67:7a:76, 1, 513, 18) params: FOREIGN KEY constraint failed
Error handling '_unsupported_attribute_added' event with (50:32:5f:ff:fe:67:7a:76, 1, 513, 19) params: FOREIGN KEY constraint failed
Error handling '_unsupported_attribute_added' event with (50:32:5f:ff:fe:67:7a:76, 1, 513, 20) params: FOREIGN KEY constraint failed
Error handling '_unsupported_attribute_added' event with (50:32:5f:ff:fe:67:7a:76, 1, 513, 30) params: FOREIGN KEY constraint failed
Error handling '_unsupported_attribute_added' event with (50:32:5f:ff:fe:67:7a:76, 1, 513, 41) params: FOREIGN KEY constraint failed
Error handling '_unsupported_attribute_added' event with (50:32:5f:ff:fe:67:7a:76, 1, 513, 28) params: FOREIGN KEY constraint failed
Error handling '_unsupported_attribute_added' event with (50:32:5f:ff:fe:67:7a:76, 1, 513, 2) params: FOREIGN KEY constraint failed
Error handling '_unsupported_attribute_added' event with (50:32:5f:ff:fe:67:7a:76, 1, 513, 7) params: FOREIGN KEY constraint failed
Error handling '_unsupported_attribute_added' event with (50:32:5f:ff:fe:67:7a:76, 1, 513, 8) params: FOREIGN KEY constraint failed
Error handling '_unsupported_attribute_added' event with (50:32:5f:ff:fe:67:7a:76, 1, 1, 32) params: FOREIGN KEY constraint failed
Error handling '_unsupported_attribute_added' event with (50:32:5f:ff:fe:67:7a:76, 1, 1, 33) params: FOREIGN KEY constraint failed
Error handling '_unsupported_attribute_added' event with (50:32:5f:ff:fe:67:7a:76, 1, 1, 49) params: FOREIGN KEY constraint failed
Error handling '_unsupported_attribute_added' event with (50:32:5f:ff:fe:67:7a:76, 1, 1, 51) params: FOREIGN KEY constraint failed
[0xf64f:1:0x000a] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=False disable_default_response=False> manufacturer=None tsn=67 command_id=Command.Read_Attributes>
[0xf64f:1:0x000a] ZCL request 0x0000: [[7]]
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=68 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=16, command_id=1026, function=0, data=[1, 1])]
[0xF64F:1:0x0201]: Attribute report 'ZONNSMARTThermostat'[system_mode] = SystemMode.Heat
[0xF64F:1:0x0201]: Attribute report 'ZONNSMARTThermostat'[programing_oper_mode] = ProgrammingOperationMode.Simple
climate.tze200_hue3yfsn_ts0601_767a67fe_thermostat: Attribute 'system_mode' = SystemMode.Heat update
climate.tze200_hue3yfsn_ts0601_767a67fe_thermostat: Attribute 'programing_oper_mode' = ProgrammingOperationMode.Simple update
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=69 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=17, command_id=264, function=0, data=[1, 0])]
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=70 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=18, command_id=266, function=0, data=[1, 0])]
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=71 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=19, command_id=528, function=0, data=[4, 0, 0, 0, 100])]
[0xF64F:1:0x0201]: Attribute report 'ZONNSMARTThermostat'[occupied_heating_setpoint] = 1000
climate.tze200_hue3yfsn_ts0601_767a67fe_thermostat: Attribute 'occupied_heating_setpoint' = 1000 update
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=72 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=20, command_id=536, function=0, data=[4, 0, 0, 0, 218])]
[0xF64F:1:0x0201]: Attribute report 'ZONNSMARTThermostat'[local_temp] = 2180
climate.tze200_hue3yfsn_ts0601_767a67fe_thermostat: Attribute 'local_temp' = 2180 update
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=73 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=21, command_id=539, function=0, data=[4, 0, 0, 0, 0])]
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=74 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=22, command_id=1055, function=0, data=[1, 0])]
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=75 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=23, command_id=544, function=0, data=[4, 0, 0, 0, 170])]
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=76 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=24, command_id=547, function=0, data=[4, 0, 0, 0, 0])]
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=77 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=25, command_id=296, function=0, data=[1, 0])]
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=78 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=26, command_id=1325, function=0, data=[1, 0])]
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=79 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=27, command_id=547, function=0, data=[4, 0, 0, 0, 100])]
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=80 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=28, command_id=814, function=0, data=[24, 50, 48, 50, 49, 48, 49, 48, 49, 48, 49, 48, 49, 50, 48, 50, 49, 48, 49, 48, 49, 48, 49, 48, 49])]
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=81 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=29, command_id=613, function=0, data=[4, 0, 0, 0, 0])]
Error calling listener.temperature_change: 'boost_duration_seconds'
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=82 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=30, command_id=614, function=0, data=[4, 0, 0, 0, 210])]
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=83 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=31, command_id=616, function=0, data=[4, 0, 0, 0, 210])]
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=84 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=32, command_id=617, function=0, data=[4, 0, 0, 0, 170])]
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=85 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=33, command_id=363, function=0, data=[1, 0])]
[0xF64F:1:0x0201]: Attribute report 'ZONNSMARTThermostat'[running_mode] = RunningMode.Heat
[0xF64F:1:0x0201]: Attribute report 'ZONNSMARTThermostat'[running_state] = RunningState.Heat_State_On
climate.tze200_hue3yfsn_ts0601_767a67fe_thermostat: Attribute 'running_mode' = RunningMode.Heat update
climate.tze200_hue3yfsn_ts0601_767a67fe_thermostat: Attribute 'running_state' = RunningState.Heat_State_On update
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=86 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=34, command_id=110, function=0, data=[30, 36, 0, 170, 72, 0, 210, 84, 0, 170, 102, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210])]
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=87 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=35, command_id=114, function=0, data=[30, 36, 0, 170, 72, 0, 210, 84, 0, 170, 102, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210])]
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=88 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=36, command_id=111, function=0, data=[30, 36, 0, 170, 72, 0, 210, 84, 0, 170, 102, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210])]
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=89 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=37, command_id=108, function=0, data=[30, 36, 0, 170, 72, 0, 210, 84, 0, 170, 102, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210])]
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=90 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=38, command_id=112, function=0, data=[30, 36, 0, 170, 72, 0, 210, 84, 0, 170, 102, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210])]
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=91 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=39, command_id=109, function=0, data=[30, 36, 0, 170, 72, 0, 210, 84, 0, 170, 102, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210])]
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=92 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=40, command_id=113, function=0, data=[30, 36, 0, 170, 72, 0, 210, 84, 0, 170, 102, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210])]
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=93 command_id=1>
[0xf64f:1:0xef00] ZCL request 0x0001: [Command(status=0, tsn=41, command_id=1139, function=0, data=[1, 1])]
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=94 command_id=36>
[0xf64f:1:0xef00] ZCL request 0x0024: [[0, 0]]
[0xf64f:1:0xef00] No handler for cluster command 36
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=95 command_id=36>
[0xf64f:1:0xef00] ZCL request 0x0024: [[0, 0]]
[0xf64f:1:0xef00] No handler for cluster command 36
[0xf64f:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=96 command_id=36>
[0xf64f:1:0xef00] ZCL request 0x0024: [[0, 18]]
[0xf64f:1:0xef00] No handler for cluster command 36
MattWestb commented 3 years ago

Its looks like its paired OK and the quirk is loaded OK. Some errors then saving attributes from the device but i dont knowing its bad or OK.

Can you controlling and getting reports from the TRV ? I have seen battery, local and setpoint temperature in the log and on the screenshot that looks realistic.

And can you configuring the debug setting i was writing in the post before then i like to see how the tuya DP commands is working. On my TRVs its looks like this then there is reporting the temperature:

2021-10-16 15:12:09 DEBUG (MainThread) [zhaquirks.tuya] [0x0c26:1:0xef00] Received value [0, 0, 0, 245] for attribute 0x0203 (command 0x0001)
2021-10-16 15:49:55 DEBUG (MainThread) [zhaquirks.tuya] [0x5ce2:1:0xef00] Received value [0, 0, 0, 235] for attribute 0x0203 (command 0x0001)
2021-10-16 15:50:09 DEBUG (MainThread) [zhaquirks.tuya] [0x7f8b:1:0xef00] Received value [0, 0, 0, 248] for attribute 0x0203 (command 0x0001)
2021-10-16 16:16:16 DEBUG (MainThread) [zhaquirks.tuya] [0x0c26:1:0xef00] Received value [0, 0, 0, 245] for attribute 0x0203 (command 0x0001)
2021-10-16 16:52:53 DEBUG (MainThread) [zhaquirks.tuya] [0x5ce2:1:0xef00] Received value [0, 0, 0, 232] for attribute 0x0203 (command 0x0001)
2021-10-16 16:55:21 DEBUG (MainThread) [zhaquirks.tuya] [0x7f8b:1:0xef00] Received value [0, 0, 0, 247] for attribute 0x0203 (command 0x0001)
2021-10-16 17:15:06 DEBUG (MainThread) [zhaquirks.tuya] [0x0c26:1:0xef00] Received value [0, 0, 0, 235] for attribute 0x0203 (command 0x0001)

And then taking out the battery for one minute and putting it in then the TRV is sending all DPs is using to the coordinator.

dodekaphilist commented 3 years ago

Looks like it's not possible to filter for a certain integration? Anyway, my log basically only contains entries like the following:

DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0x0201] Mapping standard system_mode (0x001c) with value <SystemMode.Off: 0> to custom {363: 1}
DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0, 0, 0, 150] for attribute 0x0210 (command 0x0001)
DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [1] for attribute 0x0402 (command 0x0001)
DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0, 0, 0, 170] for attribute 0x0210 (command 0x0001)
DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0, 0, 0, 175] for attribute 0x0210 (command 0x0001)
DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0, 0, 0, 180] for attribute 0x0210 (command 0x0001)
DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0, 0, 0, 185] for attribute 0x0210 (command 0x0001)
DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0] for attribute 0x0402 (command 0x0001)
DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [3] for attribute 0x0402 (command 0x0001)
DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0, 0, 0, 150] for attribute 0x0210 (command 0x0001)
DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0] for attribute 0x016b (command 0x0001)
MattWestb commented 3 years ago

The log with tuya DP attribute / commands looks OK but i have not looking on every DP.

Can you putting out the battery for one minute and then back ? If the TRV is making it normal tuya way its sending all DP is using and can comparing with other devices.

How is the normal control working like changing the set point and working mode and the feed back to ZHA ?

dodekaphilist commented 3 years ago

When I remove the battery, the device resets itself, needs to reconfigure and I need to re-pair it with the gateway. I'm not sure, if this is correct behaviour though.

Currently working:

(see screenshot) image

Stuff that's missing (at least)

MattWestb commented 3 years ago

That looks like one step forwards :-))

That the Zigbee module is loosing the network is not normal perhaps the tuya MCU was doing somthing wrong and was like killing it :-( And if its do so on every re power its not possible getting the DPs from the device. If possible make only one short power off on the device and see is its "surviving" it without resetting the Zigbee module, and if it dose look in the log if its have sending all the DPs.

The good is that you have getting the basic function of on/off setting and reading the set point and reading the local temperature.

Window open and schedules is great to have but i have not doing the code so i cant implanting it but if we is getting the DPs from the device is very likely some can helping doing that.

dodekaphilist commented 3 years ago

Looks like I was wrong. You don't have to actually re-pair the device, it re-configures anyway though.

Log:

2021-10-19 15:46:13 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0] for attribute 0x0402 (command 0x0001)
2021-10-19 15:46:13 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0] for attribute 0x0108 (command 0x0001)
2021-10-19 15:46:13 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0] for attribute 0x010a (command 0x0001)
2021-10-19 15:46:13 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0, 0, 0, 170] for attribute 0x0210 (command 0x0001)
2021-10-19 15:46:13 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0, 0, 0, 207] for attribute 0x0218 (command 0x0001)
2021-10-19 15:46:13 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0, 0, 0, 0] for attribute 0x021b (command 0x0001)
2021-10-19 15:46:13 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0] for attribute 0x041f (command 0x0001)
2021-10-19 15:46:14 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0, 0, 0, 170] for attribute 0x0220 (command 0x0001)
2021-10-19 15:46:14 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0, 0, 0, 0] for attribute 0x0223 (command 0x0001)
2021-10-19 15:46:14 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0] for attribute 0x0128 (command 0x0001)
2021-10-19 15:46:14 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0] for attribute 0x052d (command 0x0001)
2021-10-19 15:46:14 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0, 0, 0, 100] for attribute 0x0223 (command 0x0001)
2021-10-19 15:46:14 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [50, 48, 50, 49, 48, 49, 48, 49, 48, 49, 48, 49, 50, 48, 50, 49, 48, 49, 48, 49, 48, 49, 48, 49] for attribute 0x032e (command 0x0001)
2021-10-19 15:46:14 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0, 0, 0, 0] for attribute 0x0265 (command 0x0001)
2021-10-19 15:46:14 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0, 0, 0, 210] for attribute 0x0266 (command 0x0001)
2021-10-19 15:46:15 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0, 0, 0, 210] for attribute 0x0268 (command 0x0001)
2021-10-19 15:46:15 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0, 0, 0, 170] for attribute 0x0269 (command 0x0001)
2021-10-19 15:46:15 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0] for attribute 0x016b (command 0x0001)
2021-10-19 15:46:15 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [36, 0, 170, 72, 0, 210, 84, 0, 170, 102, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210] for attribute 0x006e (command 0x0001)
2021-10-19 15:46:15 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [36, 0, 170, 72, 0, 210, 84, 0, 170, 102, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210] for attribute 0x0072 (command 0x0001)
2021-10-19 15:46:15 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [36, 0, 170, 72, 0, 210, 84, 0, 170, 102, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210] for attribute 0x006f (command 0x0001)
2021-10-19 15:46:15 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [36, 0, 170, 72, 0, 210, 84, 0, 170, 102, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210] for attribute 0x006c (command 0x0001)
2021-10-19 15:46:15 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [36, 0, 170, 72, 0, 210, 84, 0, 170, 102, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210] for attribute 0x0070 (command 0x0001)
2021-10-19 15:46:16 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [36, 0, 170, 72, 0, 210, 84, 0, 170, 102, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210] for attribute 0x006d (command 0x0001)
2021-10-19 15:46:16 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [36, 0, 170, 72, 0, 210, 84, 0, 170, 102, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210] for attribute 0x0071 (command 0x0001)
2021-10-19 15:46:16 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0x0201] Mapping standard occupied_heating_setpoint (0x0012) with value 1700 to custom {528: 170}
2021-10-19 15:46:16 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [1] for attribute 0x0473 (command 0x0001)
2021-10-19 15:46:17 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0x0201] Mapping standard occupied_heating_setpoint (0x0012) with value 2150 to custom {528: 215}
2021-10-19 15:46:18 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0xef00] Received value [0, 0, 0, 215] for attribute 0x0210 (command 0x0001)
2021-10-19 15:46:20 DEBUG (MainThread) [zhaquirks.tuya] [0xf64f:1:0x0201] Mapping standard occupied_heating_setpoint (0x0012) with value 1200 to custom {528: 120}
MattWestb commented 3 years ago

Looks great 25 DPs and my Siterwell only have 12 ;-((

Some is easy finding the function and correcting but other needs more testing for getting it right. The good thing your TRV is supporting schedules i can see of the long strings.

Then i have time i shall looking if i can finding some miss match with the original Moes that can being fixed.

You can changing functions on the TRV like window detection or children lock and looking what you is getting for DP commands in the log then it can being easier remapping the functions OK.

MattWestb commented 3 years ago

You can comparing with "More" TRVs: https://github.com/zigpy/zha-device-handlers/blob/869b78d33d1127b2db2c28a6507dfbb625c3c4d1/zhaquirks/tuya/ts0601_trv.py#L138-L164 And ZONNSMART: https://github.com/zigpy/zha-device-handlers/blob/869b78d33d1127b2db2c28a6507dfbb625c3c4d1/zhaquirks/tuya/ts0601_trv.py#L755-L766 The last dont have schedules so not likely not match but perhaps other DP is the same.

Droggel00 commented 3 years ago

I recently got the TV02 TRV and got it working to some point with the Zonnsmart Quirk. At the moment I´m encountering the problem, that the valve doesn´t send it´s current temperature. Temperature regulation and everything is working, but it doesn´t send the current temperature it´s measuring.

Does somebody maybe have an idea to fix it?

rforro commented 3 years ago

This TRV is bit strange. It shares like a 95% of DPs with Lidl, but it's completely different device. Actually in one listing you can find the word Zonnsmart. Look here https://de.aliexpress.com/item/1005003190631469.html (Zonnsmart it's not in the description but in comparison image in Energy Saving section)

My assumption is that it needs to be build on top of the current Zonnsmart integration.

@Droggel00 The last two days I was observing mine and it never publishes current temperature. It doesn't matter if auto or manual mode. The only option is to restart the device. Does somebody know if it has to be manually requested?

MattWestb commented 3 years ago

If using Zonnsmart quirk and correcting it for different DP, is one problem with the Zonnsmart implementation its dont updating the local temperature and the same person that was doing the Zonnsmart quirk is doing the same in Z2M and they is having the same problem with the device so very likely some strange in the device firmware. One way is using the "Moes" quirk that is the one with most functions and working well and adjusting the DP and functions for SHENZHEN RSH TRVs and see if its working better.

If setting zhaquirks,tuya debug in HA you can see the DP commands sent and revived is you getting any with the DP for local temperature or some other that can being that ?

Moes TRVs users is sending Calibrating local temperature from HA automation for getting more frequent update then one time in the hour that the Moes (and most tuya) TRVs is doing.

rforro commented 3 years ago

I was able to extend the zonnsmart quirk with ECO_TEMP, CONFORT_TEMP and TEMP_CORRECTION. I'm pretty sure that this device is ZONNSMART because it uses the same DPs.

As was said by @dodekaphilist here by just adding it to current ZONNSMART quirk you'll get current temp, set temp, turn heating on/off. This attributes can be controlled using HA frontend, but by sending values over developer tools you can control child lock, window detection and mode as well. I've extended this quirk with ECO_TEMP, COMFORT_TEMP and TEMP_CORRECTION (aka calibration) which was pretty easy. After that I looked at zigbee2mqtt, now I'm sure that this zonnsmart quirk is just missing a lot of attributes.

I can extend this quirk, that's no problem, but I have no idea how to get entities like child_lock, mode, eco_temp, etc. appear on HA frontend. @MattWestb can you navigate me in right direction?

About the current-temp-bug you were right, I could force the publishing by setting the local temperature calibration value. But I'm not the only person who is experiencing this behaviour. Same device same solution and here as well, but another solution. One user offered that he'll try to sniff the communication with tyua hub, we need to be patient.

EDIT: there is a third issue

MattWestb commented 3 years ago

Great findings and work !!

You dont need using the development tool if you like only manage cluster from the device card and you is having all functions on the new tuya clusters for your device like window detection and child lock if they is implanted OK.

The original implanting was done early in ZHA and all functions was not discovered but the dev have implanting them in Z2M so shall being possible doing i ZHA.

So this is one Zonnsmart TV01-ZG with LED display on the side :-)) Shall i making on PR for adding it in the quirk so user can start using it in one easy way ?

The original implantation was not using presets in ZHA clima component so its have very little working modes in ZHA. Adding them is prity easy but must being made in both the quirk and in ZHA or its braking the function of changing mode in ZHA.

You can looking how the Moes TRVs is implanted and copy it. I have making one PR for adding this future in the Siterwell TRV but i cant getting it thru then i braking many tests in Zogpy :-(( The problem with Siterwell is that is many in use so not nice braking them but it can being needed doing for getting all function working in ZHA. Looks on my Siterwell upgrading project https://github.com/zigpy/zha-device-handlers/discussions/1084.

Switched and reporting alarm and status is coming then https://github.com/zigpy/zha-device-handlers/issues/1061 is getting working OK its possible implanting this functions in the same way but its not tested in production but is coming very soon.

One more time great work done !!

rforro commented 3 years ago

Wow thanks about the "manage cluster" info, this could save me a lot of time. But better now than never :)

Tomorrow I'll add those missing DPs and do PR. Just to be noted for known reasons I don't plan to integrate scheduler. After that we can work on displaying those entities on HA frontend.

MattWestb commented 3 years ago

If you like implanting presets in ZHA i have making one climate.py for ZS with the hue3yfs ID and the normal ZS ones that you can patching in your HA container and getting the presets working (I have copy the Moes TRV that is having most presets and if you dont need some its only deleting them later but good for testing).

If running HA 2021.11 copy the extracted climate.py in to your HA config directory. Open one terminal in your HA docker container and copy the new file to its right place:

cd  /usr/src/homeassistant/homeassistant/components/zha/
cp /config/climate.py climate.py

Have moving the device to ZS in the tuya TRV matrix and setting status "working with quirk in PR" so its looks better.

rforro commented 3 years ago

Currently I've only expanded the known DPs and tested them by setting/getting the values manually.

Following DPs works and they behaviour is more o less clear:

-MODE        2021-11-04 19:27:40 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [0] for attribute 0x0402 (command 0x0001)
-WINDOW      2021-11-04 19:27:40 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [0] for attribute 0x0108 (command 0x0001)
-FROST       2021-11-04 19:27:40 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [0] for attribute 0x010a (command 0x0001)
-HEATTEMP    2021-11-04 19:27:40 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [0, 0, 0, 170] for attribute 0x0210 (command 0x0001)
-CURTEMP     2021-11-04 19:27:40 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [0, 0, 0, 205] for attribute 0x0218 (command 0x0001)
-CORRTEMP    2021-11-04 19:27:40 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [0, 0, 0, 0] for attribute 0x021b (command 0x0001)
-WORKDAYS    2021-11-04 19:27:40 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [0] for attribute 0x041f (command 0x0001)
-HOLIDAYTEMP 2021-11-04 19:27:41 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [0, 0, 0, 170] for attribute 0x0220 (command 0x0001)
-BATT        2021-11-04 19:27:41 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [0, 0, 0, 100] for attribute 0x0223 (command 0x0001)
-CHILDLOCK   2021-11-04 19:27:41 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [0] for attribute 0x0128 (command 0x0001)
-BOOST       2021-11-04 19:27:41 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [0, 0, 0, 0] for attribute 0x0265 (command 0x0001)
-COMFORTTEMP 2021-11-04 19:27:42 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [0, 0, 0, 210] for attribute 0x0268 (command 0x0001)
-ECOTEMP     2021-11-04 19:27:42 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [0, 0, 0, 170] for attribute 0x0269 (command 0x0001)
-HEATSTOP    2021-11-04 19:27:42 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [0] for attribute 0x016b (command 0x0001)

In those ones I don't understand the meaning or values.

?FAULTY      2021-11-04 19:27:41 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [0] for attribute 0x052d (command 0x0001)
?HOLIDAY     2021-11-04 19:27:41 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [50, 48, 50, 49, 48, 49, 48, 49, 48, 49, 48, 49, 50, 48, 50, 49, 48, 49, 48, 49, 48, 49, 48, 49] for attribute 0x032e (command 0x0001)
?WINDOW TEMP 2021-11-04 19:27:42 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [0, 0, 0, 210] for attribute 0x0266 (command 0x0001)
?ONLINE      2021-11-04 19:27:47 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [1] for attribute 0x0473 (command 0x0001)

And as I said the scheduler is ignored

2021-11-04 19:27:43 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [36, 0, 170, 72, 0, 210, 84, 0, 170, 102, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210] for attribute 0x006e (command 0x0001)
2021-11-04 19:27:43 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [36, 0, 170, 72, 0, 210, 84, 0, 170, 102, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210] for attribute 0x0072 (command 0x0001)
2021-11-04 19:27:44 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [36, 0, 170, 72, 0, 210, 84, 0, 170, 102, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210] for attribute 0x006f (command 0x0001)
2021-11-04 19:27:45 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [36, 0, 170, 72, 0, 210, 84, 0, 170, 102, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210] for attribute 0x006c (command 0x0001)
2021-11-04 19:27:45 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [36, 0, 170, 72, 0, 210, 84, 0, 170, 102, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210] for attribute 0x0070 (command 0x0001)
2021-11-04 19:27:46 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [36, 0, 170, 72, 0, 210, 84, 0, 170, 102, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210] for attribute 0x006d (command 0x0001)
2021-11-04 19:27:46 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [36, 0, 170, 72, 0, 210, 84, 0, 170, 102, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210, 144, 0, 170, 144, 0, 210] for attribute 0x0071 (command 0x0001)

Working quirk valve.zip can be downloaded. Now I can work on ZHA integration.

MattWestb commented 3 years ago

Siterwell is having valve detect / anti calk function and if the valve is jammed the valve is sending one alarm. I was testing it by setting the setpoint to high and the valve was trying getting the temperature up but was failing after some time and was having the ! in the display and and sending the DP for valve jammed.

I think the best is as you have saying all known DP to working OK and try finding the function for the not known function and leave the scheduler until ZHA have getting better support for it.

Look little on Moes and the LIDL implantation and you can see different ways for window and holiday is working and i dont knowing if the online is called ping in some issues but i dont knowing how it working.

rforro commented 3 years ago

I was able to implement:

Clipboard01

Probably this TRV will be needing its own class because I can't test it with original ZONNSMART. The behaviour like ability to turn it off is missing on most devices like SITERWELL or LIDL.

Unique behaviour of this TRV:

Off

You can turn this TRV off, by setting ZONNSMART_HEATING_STOPPING = 0x016B to 1. On the TRV will be show HS (heating stopped) and you can't do anything till you deactivate it.

Present

Manual and Schedule works like expected but holiday mode cannot be started by selecting the mode. It only shows the holiday mode temperature and after 5sec it switches back to schedule mode. (FYI holiday mode is activated automatically by setting begin and end timestamp = not implemented)

Frost Protection (not implemeted)

I don't know how to implement this one, because it's like one of those Present Modes. After setting ZONNSMART_FROST_PROTECT_ATTR = 0x010a attribute, on TRV will be shown AF (antifreeze), it sets temperature to 8 degrees and you cannot do anything until you disable this.

Don't publishes room temperature

This TRV never publishes room temperature, it has to be manually requested. Currently the only way is to set temperature offset (even with 0), after that the room temperature will be published.

If someone will test it, here is the quirk: valve.zip but for presets to work, you have to add to /components/zha/climate.py following lines:

@STRICT_MATCH(
    channel_names=CHANNEL_THERMOSTAT,
    manufacturers={
        "_TZE200_hue3yfsn",
        },
)

class ZONNSMARTThermostat(Thermostat):
    """ZONNSMART Thermostat implementation"""
    def __init__(self, unique_id, zha_device, channels, **kwargs):
        """Initialize ZHA Thermostat instance."""
        super().__init__(unique_id, zha_device, channels, **kwargs)
            self._presets = [
            PRESET_SCHEDULE,
            PRESET_NONE,
            PRESET_AWAY,
        ]
        self._supported_flags |= SUPPORT_PRESET_MODE

    async def async_attribute_updated(self, record):
        """Handle attribute update from device."""
        if record.attr_name == "operation_preset":
            if record.value == 0:
                self._preset = PRESET_SCHEDULE
            if record.value == 1:
                self._preset = PRESET_NONE
            if record.value == 3:
                self._preset = PRESET_AWAY
        await super().async_attribute_updated(record)

    async def async_preset_handler(self, preset: str, enable: bool = False) -> bool:
        """Set the preset mode."""
        mfg_code = self._zha_device.manufacturer_code
        if not enable:
            return await self._thrm.write_attributes(
                {"operation_preset": 1}, manufacturer=mfg_code
            )
        if preset == PRESET_SCHEDULE:
            return await self._thrm.write_attributes(
                {"operation_preset": 0}, manufacturer=mfg_code
            )
        if preset == PRESET_AWAY:
            return await self._thrm.write_attributes(
                {"operation_preset": 3}, manufacturer=mfg_code
            )
        return False
jacekk015 commented 3 years ago

Present

Manual and Schedule works like expected but holiday mode cannot be started by selecting the mode. It only shows the holiday mode temperature and after 5sec it switches back to schedule mode."

Holiday mode often has date/time of start and time duration. If present time is after the values were set it switches back to Schedule after some time. That 5 sec. for Maxsmart is to start setting the parameters on the TRV.

Frost Protection (not implemeted)

For frost protection you would need to add another switch and a proper code + bus listener

Catch the attribute and set temperature manually if you don't have an attribute for it. ZONNSMARTManufCluster:

        elif attrid == ZONNSMART_FROST_PROTECT_ATTR:
            self.endpoint.device.thermostat_bus.listener_event(
                "temperature_change",
                self.DIRECT_MAPPED_ATTRS[ZONNSMART_TARGET_TEMP_ATTR][0],
                800)
           self.endpoint.device.frost_protection_bus.listener_event(
                "frost_protection_change", mode)

Copy&paste child lock class and rename it to frost protection.

class ZONNSMARTFrostProtection(LocalDataCluster, OnOff):
    """On/Off cluster for the frost protection function of the heating thermostats."""

    def __init__(self, *args, **kwargs):
        """Init."""
        super().__init__(*args, **kwargs)
        self.endpoint.device.frost_protection_bus.add_listener(self)

    def frost_protection_change(self, value):
        """Frost protection change."""
        self._update_attribute(self.attridx["on_off"], value)

    async def write_attributes(self, attributes, manufacturer=None):
        """Defer attributes writing to the set_data tuya command."""
        records = self._write_attr_records(attributes)
        if not records:
            return [[foundation.WriteAttributesStatusRecord(foundation.Status.SUCCESS)]]

        has_change = False
        for record in records:
            attr_name = self.attributes[record.attrid][0]
            if attr_name == "on_off":
                value = record.value.value
                has_change = True

        if has_change:
            return await self.endpoint.tuya_manufacturer.write_attributes(
                {ZONNSMART_FROST_PROTECT_ATTR: value}, manufacturer=manufacturer
            )

        return [
            [
                foundation.WriteAttributesStatusRecord(
                    foundation.Status.FAILURE, r.attrid
                )
                for r in records
            ]
        ]

    async def command(
        self,
        command_id: Union[foundation.Command, int, t.uint8_t],
        *args,
        manufacturer: Optional[Union[int, t.uint16_t]] = None,
        expect_reply: bool = True,
        tsn: Optional[Union[int, t.uint8_t]] = None,
    ):
        """Override the default Cluster command."""

        if command_id in (0x0000, 0x0001, 0x0002):
            if command_id == 0x0000:
                value = False
            elif command_id == 0x0001:
                value = True
            else:
                attrid = self.attridx["on_off"]
                success, _ = await self.read_attributes(
                    (attrid,), manufacturer=manufacturer
                )
                try:
                    value = success[attrid]
                except KeyError:
                    return foundation.Status.FAILURE
                value = not value

            (res,) = await self.write_attributes(
                {"on_off": value},
                manufacturer=manufacturer
            )

            return [command_id, res]

        return [command_id, foundation.Status.UNSUP_CLUSTER_COMMAND]

Add another endpoint to ZonnsmartTV01_ZG

            3: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
                INPUT_CLUSTERS: [
                    ZONNSMARTFrostProtection,
                ],
                OUTPUT_CLUSTERS: [],
            },

Don't forget to INIT bus in ZonnsmartTV01_ZG ->def init

self.frost_protection_bus= Bus()

Pretty simple

jacekk015 commented 3 years ago

If above code will not work[probably won't] do three more steps: Add ZONNSMARTManufClusterSelf variable like below:

ZONNSMART_HOLIDAY_DATETIME_ATTR = 0x032e  # holiday mode date and time of begin and end
ZONNSMART_WEEK_FORMAT_ATTR = 0x041f  # # [0] 5+2 days [1] 6+1 days, [2] 7 days
ZONNSMART_FAULT_DETECTION_ATTR = 0x052d  # [0] no fault [1] fault detected
ZONNSMARTManufClusterSelf = None

Add INIT to ZONNSMARTManufCluster before manufacturer_attributes:

    def __init__(self, *args, **kwargs):
        """Init."""
        super().__init__(*args, **kwargs)
        self.endpoint.device.ZONNSMARTManufCluster .add_listener(self)
        global ZONNSMARTManufClusterSelf 
        ZONNSMARTManufClusterSelf = self

Then use that variable in the write_attributes of ZONNSMARTFrostProtection Change line to:

        if has_change:
            return await ZONNSMARTManufClusterSelf.endpoint.tuya_manufacturer.write_attributes(
                {ZONNSMART_FROST_PROTECT_ATTR: value}, manufacturer=manufacturer
            )

That's needed because your ZONNSMARTFrostProtection is on endpoint 3 and ZONNSMART_FROST_PROTECT_ATTR is on endpoint 1. If you do self. it assumes that the self. is on same endpoint - but here it isn't. We just created a reference to endpoint 1 class.

rforro commented 3 years ago

Present

Manual and Schedule works like expected but holiday mode cannot be started by selecting the mode. It only shows the holiday mode temperature and after 5sec it switches back to schedule mode."

Holiday mode often has date/time of start and time duration. If present time is after the values were set it switches back to Schedule after some time. That 5 sec. for Maxsmart is to start setting the parameters on the TRV.

Yes I know how it works, I wrote that it starts automatically by setting begin and end time, but here is the format different than the Maxsmart. This TRV uses only one attribute, its value is [50, 48, 50, 49, 48, 49, 48, 49, 48, 49, 48, 49, 50, 48, 50, 49, 48, 49, 48, 49, 48, 49, 48, 49] which represents 20210101 01:01 20210101 01:01. You could in theory use Input Datetime but it will take too much time to develop. I'd rather use HA automation for this.

Frost Protection (not implemeted)

For frost protection you would need to add another switch and a proper code + bus listener.

The implementation into source code is not the problem, what I meant is the behavior. When I activate frost protection the TRV publishes following:

which is misinterpreted by HA fronted climate component. This is what I meant. It should display in HA frontend that the heating is off and the input_boolean frost protection is active.

MattWestb commented 3 years ago

If looking in the commit for the first added tuya TRV presets its looks being easy (if not need adding tests) more presets in ZHA climate component. https://github.com/home-assistant/core/pull/48178/files

I think one Holiday for this and one FI for Site can being good but if its possible making them not possible to select but is showing in the GUI and having one witch on the device card and with date and time for the holiday mode . Then if setting one holiday date on the device card is ZHA shoeing holiday but cant changing it = OK then it must being cancelled in the device card. The same with the FI cant being sett in ZHA GUI but with commands from cluster or switch on the device card and the user can see that the device is in that mode.

jacekk015 commented 3 years ago

If you have frost protection then heating isn't really off. But if you insist then change my code above to:

        elif attrid == ZONNSMART_FROST_PROTECT_ATTR:
            self.endpoint.device.thermostat_bus.listener_event(
                "temperature_change",
                self.DIRECT_MAPPED_ATTRS[ZONNSMART_TARGET_TEMP_ATTR][0],
                800)
            self.endpoint.device.thermostat_bus.listener_event(
                "state_change",
                0)
           self.endpoint.device.frost_protection_bus.listener_event(
                "frost_protection_change", mode)

That's all you need. state_change -> value = 0 OFF state_change -> value = 1 HEAT

Ah - and you can't use Input Datetime - it's not implemented in ZHA ;-) https://www.home-assistant.io/integrations/zha/

There is currently support for the following device types within Home Assistant:

Alarm Control Panel
Binary Sensor
Climate (beta)
Cover
Fan
Light
Lock
Number (i.e. analog output)
Sensor
Switch

https://github.com/home-assistant/core/tree/dev/homeassistant/components/zha

rforro commented 3 years ago

That's all you need. state_change -> value = 0 OFF state_change -> value = 1 HEAT

I think that I'll just do the switch. I don't care about this function, if someone does the code can be anytime changed.

Ah - and you can't use Input Datetime - it's not implemented in ZHA ;-) https://www.home-assistant.io/integrations/zha/

There is currently support for the following device types within Home Assistant:

Alarm Control Panel
Binary Sensor
Climate (beta)
Cover
Fan
Light
Lock
Number (i.e. analog output)
Sensor
Switch

https://github.com/home-assistant/core/tree/dev/homeassistant/components/zha

Thats what I meant with:

You could in theory use Input Datetime but it will take too much time to develop. I'd rather use HA automation for this.

One could implement Input Datetime into ZHA, but not me :D

BTW. I'd rather invest the time into naming those entities like I mentioned here https://github.com/zigpy/zha-device-handlers/issues/1061#issuecomment-962846745. FYI I've raise an issue on zigpy, I'll overlook integration of description into onoff cluster.

alexd321 commented 3 years ago

I have been testing this and seems to work mostly ok (sometimes gets confused and stuck in "off" mode.

Anyone else noticed the valve changing climate setpoints by itself?

I have a HA automation set to send a '0' to the number analog_output_temperature_offset every 15 mins to get the current temperature and the set point seems to jump back to 21°C randomly (not every request).

rforro commented 3 years ago

To be honest, I never installed this TRV, it was just sitting on my desk to development purposes 😄 But I've installed it today.

I'll try to investigate the changing climate setpoint, but can you elaborate what are your settings? Are you using Schedule mode or Manual? What are your automations?

alexd321 commented 3 years ago

I just left the valve in "🏠" (home mode) which I guess is schedule?

Maybe the device comes with a built-in schedule?

alias: 'Radiator: request room temp'
description: Hack to request room temperature every 15 mins
trigger:
  - platform: time_pattern
    minutes: /15
condition: []
action:
  - service: number.set_value
    data:
      value: '0'
    target:
      entity_id:
        - >-
          number.tze200_hue3yfsn_ts0601_5222c3fe_analog_output_temperature_offset
        - >-
          number.tze200_hue3yfsn_ts0601_11307cfe_analog_output_temperature_offset
mode: single

And

To adjust setpoint (essentially faking a schedule):

alias: 'Radiator: bedroom schedule'
description: ''
trigger:
  - platform: time
    at: input_datetime.morning_heating_on
    id: morning
  - platform: time
    id: evening
    at: '20:15'
  - platform: time
    at: input_datetime.daytime_temp_setback_time
    id: day setback
  - platform: time
    at: input_datetime.weekend_daytime_temp_setback_time
    id: weekend daytime setback
condition:
  - condition: not
    conditions:
      - condition: state
        entity_id: climate.central_heating
        state: 'off'
action:
  - choose:
      - conditions:
          - condition: trigger
            id: morning
        sequence:
          - service: climate.set_temperature
            target:
              entity_id: climate.bedroom_radiator
            data:
              temperature: 16.5
          - service: notify.mobile_app_alex_samsung
            data:
              message: Bedroom Radiator reset morning
              title: Bedroom Radiator
      - conditions:
          - condition: trigger
            id: day setback
          - condition: time
            weekday:
              - mon
              - tue
              - wed
              - thu
              - fri
        sequence:
          - service: climate.set_temperature
            target:
              entity_id: climate.bedroom_radiator
            data:
              temperature: 10
          - service: notify.mobile_app_alex_samsung
            data:
              message: Bedroom Radiator turned off daytime setback
              title: Bedroom Radiator
      - conditions:
          - condition: trigger
            id: evening
        sequence:
          - service: climate.set_temperature
            target:
              entity_id: climate.bedroom_radiator
            data:
              temperature: 16
          - service: notify.mobile_app_alex_samsung
            data:
              message: Bedroom Radiator activated late evening
              title: Bedroom Radiator
      - conditions:
          - condition: trigger
            id: weekend setback
          - condition: time
            weekday:
              - sat
              - sun
        sequence:
          - service: climate.set_temperature
            target:
              entity_id: climate.bedroom_radiator
            data:
              temperature: 10
          - service: notify.mobile_app_alex_samsung
            data:
              message: Bedroom Radiator turned off weekend setback
              title: Bedroom Radiator
    default: []
mode: single

Screenshot_20211110-093501_Home Assistant.png

The jumps to 21C were not me (manual or automation)

I will try the valve in ✋ (hand) mode and see if that improves things.

dodekaphilist commented 3 years ago

@alexd321 I had the same issue, it is indeed related to the pre-programmed schedule. Unfortunately, we cannot customize the schedule yet, but the manual mode is a good workaround

LennardPlay commented 3 years ago

Currently working:

* ambient temperature is sent to HA

* setting a temperature is sent between devices vice-versa (independant of mode)

* off-mode and manual mode can be toggled

I think I have the same thermostat. Can you help me to get at least the temperature control working? I sadly don't really understand what device class and so on is. Would be lovely if you could help me getting it to work :)

LennardPlay commented 3 years ago

Sorry for not explaining myself very well in the last message. I'm wondering how I can use the custom ZONNSMART quirk. Which steps should I take to activate it?

ayonix commented 2 years ago

Is there anything left to do to get this into the next release?

ALERTua commented 2 years ago

I am also interested in this device support. just bought a few valves. thank you.

jacekk015 commented 2 years ago

@rforro are you able to publish the quirk so the users could use it?

rforro commented 2 years ago

@jacekk015 I was waiting if your PR will be accepted or you'll have to replace the Bus.

@ayonix I'm waiting if #1129 PR will be merged or not, because this is more or less the same case.

alexd321 commented 2 years ago

I think I have the same thermostat. Can you help me to get at least the temperature control working? I sadly don't really understand what device class and so on is. Would be lovely if you could help me getting it to work :)

@LennardPlay To get the valve partly working, I just:

  1. downloaded the valve.zip file
  2. uploaded the extracted contents of this zip file (valve.py) to /config/custon_zha_quirks/
  3. added the following to configuration.yaml:
    zha:
    custom_quirks_path: /config/custom_zha_quirks/
  4. restarted home assistant

I haven't modified climate.py yet as I was worried about breaking things/ran out of time/it looked a bit more in depth/

Update: I got an error when modifying climate.py - setup failed for ZHA - indentation error

File "/usr/src/homeassistant/homeassistant/components/zha/climate.py", line 714 self._presets = [

I guess my indentation is incorrect, but I copied your above code

alexd321 commented 2 years ago

There is a small indentation error in https://github.com/zigpy/zha-device-handlers/issues/1027#issuecomment-962854799 @rforro

class ZONNSMARTThermostat(Thermostat):
    """ZONNSMART Thermostat implementation"""
    def __init__(self, unique_id, zha_device, channels, **kwargs):
        """Initialize ZHA Thermostat instance."""
        super().__init__(unique_id, zha_device, channels, **kwargs)
            self._presets = [
            PRESET_SCHEDULE,

should instead be:

class ZONNSMARTThermostat(Thermostat):
    """ZONNSMART Thermostat implementation"""
    def __init__(self, unique_id, zha_device, channels, **kwargs):
        """Initialize ZHA Thermostat instance."""
        super().__init__(unique_id, zha_device, channels, **kwargs)
        self._presets = [
            PRESET_SCHEDULE,

self._presets line changed

rforro commented 2 years ago

I'm working on this to include boost and anti-freeze mode, but there is one thing which won't let me sleep.

2021-11-04 19:27:47 DEBUG (MainThread) [zhaquirks.tuya] [0xb5eb:1:0xef00] Received value [1] for attribute 0x0473 (command 0x0001)

There is this ONLINE datapoint which publishes value 1 at pairing only. Now I understand its purpose. Using original Tuya App or Zigbee2mqtt by publishing value 0 (boolean false) to this datapoint the TRV switches itself to "online mode" (antenna icon lights up) and for ca. 1 minute the TRV will be publishing all parameters including current room temperature automatically. The problem is for some reason I cannot publish the correct value (0 or false) which will be accepted by TRV from ZHA. I've tried t.Bool and t.uint8_t but the TRV just ignores the value and publishes some strange data:

2022-01-06 10:59:57 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=61184, SrcAddr=0x59A9, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=115, SecurityUse=<Bool.false: 0>, TimeStamp=9468090, TSN=0, Data=b'\x0C\x02\x10\x18\x0B\x00\x00', MacSrcAddr=0x59A9, MsgResultRadius=29)
2022-01-06 10:59:57 DEBUG (MainThread) [zigpy.zcl] [0x59a9:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=True is_reply=True disable_default_response=False> manufacturer=4098 tsn=24 command_id=Command.Default_Response>

Correct data for Online DP

2022-01-06 10:32:28 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=61184, SrcAddr=0x59A9, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=110, SecurityUse=<Bool.false: 0>, TimeStamp=4312484, TSN=0, Data=b'\x09\x44\x01\x00\x71\x73\x04\x00\x01\x01', MacSrcAddr=0x59A9, MsgResultRadius=29)
2022-01-06 10:32:28 DEBUG (MainThread) [zigpy.zcl] [0x59a9:1:0xef00] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=68 command_id=1>

Can some zigpy-pro dev point me into right direction?

Perrudi commented 2 years ago

If testing is needed: I have a 'TV02-ZG LED display on the side and rotating knob on the top.' as shown in https://github.com/zigpy/zigpy/discussions/653 and it would be nice if i could help. But i am standard user - no developer or professional in coding and implementing...