zha-device-handlers
zha-device-handlers copied to clipboard
[Device Support Request] SIN-4-FP-21 - NodOn
Problem description
Missing controls the target temperature of the heater with possible values: comfort, eco, frost_protection, off, comfort_-1, comfort_-2. Currently just an "on, off" switch
Solution description
Add controls of the heater (comfort, eco, frost_protection, off, comfort_-1, comfort_-2.)
Screenshots/Video
Screenshots/Video
Device signature
Device signature
{
"node_descriptor": "NodeDescriptor(logical_type=<LogicalType.Router: 1>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.FullFunctionDevice|MainsPowered|RxOnWhenIdle|AllocateAddress: 142>, manufacturer_code=4747, maximum_buffer_size=82, maximum_incoming_transfer_size=500, server_mask=11264, maximum_outgoing_transfer_size=500, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)",
"endpoints": {
"1": {
"profile_id": "0x0104",
"device_type": "0x0051",
"input_clusters": [
"0x0000",
"0x0003",
"0x0004",
"0x0005",
"0x0006",
"0x0702",
"0x1000",
"0xfc00"
],
"output_clusters": [
"0x0019"
]
},
"242": {
"profile_id": "0xa1e0",
"device_type": "0x0066",
"input_clusters": [
"0x0021"
],
"output_clusters": [
"0x0021"
]
}
},
"manufacturer": "NodOn",
"model": "SIN-4-FP-21",
"class": "zigpy.device.Device"
}
Diagnostic information
Diagnostic information
{
"home_assistant": {
"installation_type": "Home Assistant OS",
"version": "2024.3.0",
"dev": false,
"hassio": true,
"virtualenv": false,
"python_version": "3.12.2",
"docker": true,
"arch": "x86_64",
"timezone": "Europe/Paris",
"os_name": "Linux",
"os_version": "6.6.20-haos",
"supervisor": "2024.03.0",
"host_os": "Home Assistant OS 12.1",
"docker_version": "24.0.7",
"chassis": "vm",
"run_as_root": true
},
"custom_components": {
"zha_toolkit": {
"version": "v1.1.8",
"requirements": [
"pytz"
]
},
"smartlife": {
"version": "0.1.0",
"requirements": [
"tuya-device-sharing-sdk==0.2.0"
]
},
"dyson_local": {
"version": "0.16.4-4",
"requirements": [
"libdyson==0.8.11"
]
},
"espsomfy_rts": {
"version": "2.4.1",
"requirements": [
"websocket-client==1.7.0"
]
},
"scheduler": {
"version": "v0.0.0",
"requirements": []
},
"hacs": {
"version": "1.34.0",
"requirements": [
"aiogithubapi>=22.10.1"
]
}
},
"integration_manifest": {
"domain": "zha",
"name": "Zigbee Home Automation",
"after_dependencies": [
"onboarding",
"usb"
],
"codeowners": [
"@dmulcahey",
"@adminiuga",
"@puddly",
"@TheJulianJES"
],
"config_flow": true,
"dependencies": [
"file_upload"
],
"documentation": "https://www.home-assistant.io/integrations/zha",
"import_executor": true,
"iot_class": "local_polling",
"loggers": [
"aiosqlite",
"bellows",
"crccheck",
"pure_pcapy3",
"zhaquirks",
"zigpy",
"zigpy_deconz",
"zigpy_xbee",
"zigpy_zigate",
"zigpy_znp",
"universal_silabs_flasher"
],
"requirements": [
"bellows==0.38.1",
"pyserial==3.5",
"pyserial-asyncio==0.6",
"zha-quirks==0.0.112",
"zigpy-deconz==0.23.1",
"zigpy==0.63.4",
"zigpy-xbee==0.20.1",
"zigpy-zigate==0.12.0",
"zigpy-znp==0.12.1",
"universal-silabs-flasher==0.0.18",
"pyserial-asyncio-fast==0.11"
],
"usb": [
{
"vid": "10C4",
"pid": "EA60",
"description": "*2652*",
"known_devices": [
"slae.sh cc2652rb stick"
]
},
{
"vid": "10C4",
"pid": "EA60",
"description": "*slzb-07*",
"known_devices": [
"smlight slzb-07"
]
},
{
"vid": "1A86",
"pid": "55D4",
"description": "*sonoff*plus*",
"known_devices": [
"sonoff zigbee dongle plus v2"
]
},
{
"vid": "10C4",
"pid": "EA60",
"description": "*sonoff*plus*",
"known_devices": [
"sonoff zigbee dongle plus"
]
},
{
"vid": "10C4",
"pid": "EA60",
"description": "*tubeszb*",
"known_devices": [
"TubesZB Coordinator"
]
},
{
"vid": "1A86",
"pid": "7523",
"description": "*tubeszb*",
"known_devices": [
"TubesZB Coordinator"
]
},
{
"vid": "1A86",
"pid": "7523",
"description": "*zigstar*",
"known_devices": [
"ZigStar Coordinators"
]
},
{
"vid": "1CF1",
"pid": "0030",
"description": "*conbee*",
"known_devices": [
"Conbee II"
]
},
{
"vid": "0403",
"pid": "6015",
"description": "*conbee*",
"known_devices": [
"Conbee III"
]
},
{
"vid": "10C4",
"pid": "8A2A",
"description": "*zigbee*",
"known_devices": [
"Nortek HUSBZB-1"
]
},
{
"vid": "0403",
"pid": "6015",
"description": "*zigate*",
"known_devices": [
"ZiGate+"
]
},
{
"vid": "10C4",
"pid": "EA60",
"description": "*zigate*",
"known_devices": [
"ZiGate"
]
},
{
"vid": "10C4",
"pid": "8B34",
"description": "*bv 2010/10*",
"known_devices": [
"Bitron Video AV2010/10"
]
}
],
"zeroconf": [
{
"type": "_esphomelib._tcp.local.",
"name": "tube*"
},
{
"type": "_zigate-zigbee-gateway._tcp.local.",
"name": "*zigate*"
},
{
"type": "_zigstar_gw._tcp.local.",
"name": "*zigstar*"
},
{
"type": "_uzg-01._tcp.local.",
"name": "uzg-01*"
},
{
"type": "_slzb-06._tcp.local.",
"name": "slzb-06*"
}
],
"is_built_in": true
},
"data": {
"ieee": "**REDACTED**",
"nwk": 15611,
"manufacturer": "NodOn",
"model": "SIN-4-FP-21",
"name": "NodOn SIN-4-FP-21",
"quirk_applied": false,
"quirk_class": "zigpy.device.Device",
"quirk_id": null,
"manufacturer_code": 4747,
"power_source": "Mains",
"lqi": 124,
"rssi": -69,
"last_seen": "2024-03-13T19:30:27",
"available": true,
"device_type": "Router",
"signature": {
"node_descriptor": "NodeDescriptor(logical_type=<LogicalType.Router: 1>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.FullFunctionDevice|MainsPowered|RxOnWhenIdle|AllocateAddress: 142>, manufacturer_code=4747, maximum_buffer_size=82, maximum_incoming_transfer_size=500, server_mask=11264, maximum_outgoing_transfer_size=500, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)",
"endpoints": {
"1": {
"profile_id": "0x0104",
"device_type": "0x0051",
"input_clusters": [
"0x0000",
"0x0003",
"0x0004",
"0x0005",
"0x0006",
"0x0702",
"0x1000",
"0xfc00"
],
"output_clusters": [
"0x0019"
]
},
"242": {
"profile_id": "0xa1e0",
"device_type": "0x0066",
"input_clusters": [
"0x0021"
],
"output_clusters": [
"0x0021"
]
}
},
"manufacturer": "NodOn",
"model": "SIN-4-FP-21"
},
"active_coordinator": false,
"entities": [
{
"entity_id": "button.chauffage_bureau_identifier",
"name": "NodOn SIN-4-FP-21"
},
{
"entity_id": "select.chauffage_bureau_comportement_au_demarrage",
"name": "NodOn SIN-4-FP-21"
},
{
"entity_id": "sensor.nodon_sin_4_fp_21_rssi_3",
"name": "NodOn SIN-4-FP-21"
},
{
"entity_id": "sensor.nodon_sin_4_fp_21_lqi_3",
"name": "NodOn SIN-4-FP-21"
},
{
"entity_id": "sensor.chauffage_bureau_demande_instantanee",
"name": "NodOn SIN-4-FP-21"
},
{
"entity_id": "sensor.chauffage_bureau_summation_delivered",
"name": "NodOn SIN-4-FP-21"
},
{
"entity_id": "switch.chauffage_bureau_commutateur",
"name": "NodOn SIN-4-FP-21"
}
],
"neighbors": [
{
"device_type": "Coordinator",
"rx_on_when_idle": "On",
"relationship": "Sibling",
"extended_pan_id": "**REDACTED**",
"ieee": "**REDACTED**",
"nwk": "0x0000",
"permit_joining": "Unknown",
"depth": "0",
"lqi": "48"
},
{
"device_type": "Router",
"rx_on_when_idle": "On",
"relationship": "Sibling",
"extended_pan_id": "**REDACTED**",
"ieee": "**REDACTED**",
"nwk": "0x0934",
"permit_joining": "Unknown",
"depth": "15",
"lqi": "32"
},
{
"device_type": "Router",
"rx_on_when_idle": "On",
"relationship": "Sibling",
"extended_pan_id": "**REDACTED**",
"ieee": "**REDACTED**",
"nwk": "0x181E",
"permit_joining": "Unknown",
"depth": "15",
"lqi": "101"
},
{
"device_type": "Router",
"rx_on_when_idle": "On",
"relationship": "Sibling",
"extended_pan_id": "**REDACTED**",
"ieee": "**REDACTED**",
"nwk": "0x2D05",
"permit_joining": "Unknown",
"depth": "15",
"lqi": "136"
},
{
"device_type": "Router",
"rx_on_when_idle": "On",
"relationship": "Parent",
"extended_pan_id": "**REDACTED**",
"ieee": "**REDACTED**",
"nwk": "0x5DE3",
"permit_joining": "Unknown",
"depth": "15",
"lqi": "163"
},
{
"device_type": "Router",
"rx_on_when_idle": "On",
"relationship": "Sibling",
"extended_pan_id": "**REDACTED**",
"ieee": "**REDACTED**",
"nwk": "0xA6CD",
"permit_joining": "Unknown",
"depth": "15",
"lqi": "95"
},
{
"device_type": "Router",
"rx_on_when_idle": "On",
"relationship": "Sibling",
"extended_pan_id": "**REDACTED**",
"ieee": "**REDACTED**",
"nwk": "0xC414",
"permit_joining": "Unknown",
"depth": "15",
"lqi": "70"
},
{
"device_type": "Router",
"rx_on_when_idle": "On",
"relationship": "Sibling",
"extended_pan_id": "**REDACTED**",
"ieee": "**REDACTED**",
"nwk": "0xD9B0",
"permit_joining": "Unknown",
"depth": "15",
"lqi": "90"
},
{
"device_type": "Router",
"rx_on_when_idle": "On",
"relationship": "Sibling",
"extended_pan_id": "**REDACTED**",
"ieee": "**REDACTED**",
"nwk": "0xEA8F",
"permit_joining": "Unknown",
"depth": "15",
"lqi": "240"
}
],
"routes": [
{
"dest_nwk": "0x0000",
"route_status": "Active",
"memory_constrained": false,
"many_to_one": false,
"route_record_required": false,
"next_hop": "0x5DE3"
}
],
"endpoint_names": [
{
"name": "SMART_PLUG"
},
{
"name": "COMBO_BASIC"
}
],
"user_given_name": "Chauffage Bureau",
"device_reg_id": "91995077342180562333b3e9aa0ef82e",
"area_id": "bureau",
"cluster_details": {
"1": {
"device_type": {
"name": "SMART_PLUG",
"id": 81
},
"profile_id": 260,
"in_clusters": {
"0x0000": {
"endpoint_attribute": "basic",
"attributes": {
"0x0001": {
"attribute_name": "app_version",
"value": 3
},
"0xfffd": {
"attribute_name": "cluster_revision",
"value": 3
},
"0x0006": {
"attribute_name": "date_code",
"value": "2021"
},
"0x0014": {
"attribute_name": "disable_local_config",
"value": 0
},
"0x0003": {
"attribute_name": "hw_version",
"value": 52
},
"0x0004": {
"attribute_name": "manufacturer",
"value": "NodOn"
},
"0x0005": {
"attribute_name": "model",
"value": "SIN-4-FP-21"
},
"0x0007": {
"attribute_name": "power_source",
"value": 1
},
"0x0002": {
"attribute_name": "stack_version",
"value": 103
},
"0x4000": {
"attribute_name": "sw_build_id",
"value": "3.0.0-1.4.4"
},
"0x0000": {
"attribute_name": "zcl_version",
"value": 8
}
},
"unsupported_attributes": {}
},
"0x0003": {
"endpoint_attribute": "identify",
"attributes": {
"0xfffd": {
"attribute_name": "cluster_revision",
"value": 2
},
"0x0000": {
"attribute_name": "identify_time",
"value": 0
}
},
"unsupported_attributes": {}
},
"0x0004": {
"endpoint_attribute": "groups",
"attributes": {
"0xfffd": {
"attribute_name": "cluster_revision",
"value": 3
},
"0x0000": {
"attribute_name": "name_support",
"value": 0
}
},
"unsupported_attributes": {}
},
"0x0005": {
"endpoint_attribute": "scenes",
"attributes": {
"0xfffd": {
"attribute_name": "cluster_revision",
"value": 3
},
"0x0000": {
"attribute_name": "count",
"value": 0
},
"0x0002": {
"attribute_name": "current_group",
"value": 0
},
"0x0001": {
"attribute_name": "current_scene",
"value": 0
},
"0x0004": {
"attribute_name": "name_support",
"value": 0
},
"0x0003": {
"attribute_name": "scene_valid",
"value": 0
}
},
"unsupported_attributes": {}
},
"0x0006": {
"endpoint_attribute": "on_off",
"attributes": {
"0xfffd": {
"attribute_name": "cluster_revision",
"value": 2
},
"0x4000": {
"attribute_name": "global_scene_control",
"value": 1
},
"0x4002": {
"attribute_name": "off_wait_time",
"value": 0
},
"0x0000": {
"attribute_name": "on_off",
"value": 1
},
"0x4001": {
"attribute_name": "on_time",
"value": 0
},
"0x4003": {
"attribute_name": "start_up_on_off",
"value": 255
}
},
"unsupported_attributes": {
"0x0011": {},
"0x0001": {}
}
},
"0x0702": {
"endpoint_attribute": "smartenergy_metering",
"attributes": {
"0x0000": {
"attribute_name": "current_summ_delivered",
"value": 4738
},
"0x000a": {
"attribute_name": "default_update_period",
"value": 1
},
"0x0304": {
"attribute_name": "demand_formatting",
"value": 19
},
"0x0302": {
"attribute_name": "divisor",
"value": 1000
},
"0x0400": {
"attribute_name": "instantaneous_demand",
"value": 0
},
"0x0306": {
"attribute_name": "metering_device_type",
"value": 0
},
"0x0301": {
"attribute_name": "multiplier",
"value": 1
},
"0x0200": {
"attribute_name": "status",
"value": 0
},
"0x0303": {
"attribute_name": "summation_formatting",
"value": 59
},
"0x0300": {
"attribute_name": "unit_of_measure",
"value": 0
}
},
"unsupported_attributes": {
"0x0100": {
"attribute_name": "current_tier1_summ_delivered"
},
"0x0102": {
"attribute_name": "current_tier2_summ_delivered"
},
"0x0001": {
"attribute_name": "current_summ_received"
},
"0x0104": {
"attribute_name": "current_tier3_summ_delivered"
},
"0x0106": {
"attribute_name": "current_tier4_summ_delivered"
},
"0x010a": {
"attribute_name": "current_tier6_summ_delivered"
},
"0x0108": {
"attribute_name": "current_tier5_summ_delivered"
}
}
},
"0x1000": {
"endpoint_attribute": "lightlink",
"attributes": {},
"unsupported_attributes": {}
},
"0xfc00": {
"endpoint_attribute": "manufacturer_specific",
"attributes": {},
"unsupported_attributes": {
"0x0000": {},
"0x0001": {},
"0x0020": {}
}
}
},
"out_clusters": {
"0x0019": {
"endpoint_attribute": "ota",
"attributes": {
"0xfffd": {
"attribute_name": "cluster_revision",
"value": 4
},
"0x0002": {
"attribute_name": "current_file_version",
"value": 66564
}
},
"unsupported_attributes": {
"0x0002": {
"attribute_name": "current_file_version"
}
}
}
}
},
"242": {
"device_type": {
"name": "COMBO_BASIC",
"id": 102
},
"profile_id": 41440,
"in_clusters": {
"0x0021": {
"endpoint_attribute": "green_power",
"attributes": {},
"unsupported_attributes": {}
}
},
"out_clusters": {
"0x0021": {
"endpoint_attribute": "green_power",
"attributes": {},
"unsupported_attributes": {}
}
}
}
}
}
}
Logs
Logs
[Paste the logs here]
Custom quirk
Custom quirk
Sorry I didn't manage to make it, obviously I'm not focused enough to understand how to make it. But I'm trying and if I find how to do it, I promise I'll post it here.
Additional information
No response
Related: https://github.com/zigpy/zha-device-handlers/issues/2777
Waiting also for ZHA support...
I've just made some progress on it using quirks v2. It is my first quirk and I'm new to HA so I believe there is room for improvement.
Here is the quirk
"""NodOn on/off switch two channels."""
from typing import Final
from zigpy.quirks import CustomCluster
from zigpy.quirks.v2 import add_to_registry_v2, EntityType, EntityPlatform
from zigpy.zcl.foundation import (
BaseAttributeDefs,
BaseCommandDefs,
ZCLAttributeDef,
ZCLCommandDef
)
from zigpy.zcl import ClusterType
import zigpy.types as t
class NodonPilotWireMode(t.enum16):
OFF = 0x00
COMFORT = 0x01
ECO = 0x02
FROST_PROTECTION = 0x03
COMFORT_MINUS_1 = 0x04
COMFORT_MINUS_2 = 0x05
NODON_PILOT_WIRE_CLUSTER_ID = 0xfc00 #64512
class NodonPilotWireCluster(CustomCluster):
"""NodOn pilot wire manufacturer-specific cluster."""
cluster_id: Final = NODON_PILOT_WIRE_CLUSTER_ID
name: Final = "Pilot Wire"
ep_attribute: Final = "pilot_wire_cluster"
class AttributeDefs(BaseAttributeDefs):
pilot_wire_mode: Final = ZCLAttributeDef(id=0x0000, type=NodonPilotWireMode, access="r")
class ClientCommandDefs(BaseCommandDefs):
setMode: Final = ZCLCommandDef(
id=0x0000,
schema={
"mode": NodonPilotWireMode
},
direction=True,
is_manufacturer_specific=True,
)
(
add_to_registry_v2("NodOn", "SIN-4-FP-21")
.replaces(NodonPilotWireCluster)
.enum("pilot_wire_mode",NodonPilotWireMode,NODON_PILOT_WIRE_CLUSTER_ID,
ClusterType.Server,1,EntityType.STANDARD,EntityPlatform.SELECT,False,True,"pilot_wire_mode")
)
And the result in entity view
And with an addition also_applies_to()
that should solve #2777
(
add_to_registry_v2("NodOn", "SIN-4-FP-21")
.also_applies_to("ADEO", "SIN-4-FP-21_EQU")
.replaces(NodonPilotWireCluster)
.enum("pilot_wire_mode",NodonPilotWireMode,NODON_PILOT_WIRE_CLUSTER_ID,
ClusterType.Server,1,EntityType.STANDARD,EntityPlatform.SELECT,False,True,"pilot_wire_mode")
)
```
Thanks for your work, the Quirks applies correctly but when I try to change modes there is an error message that says
Échec de l'appel du service select/select_option. Failed to write attribute pilot_wire_mode=<NodonPilotWireMode.ECO: 2> :<Status.INVALID_DATA_TYPE: 141>
Maybe I did something wrong
Custom quirk
"""NodOn pilot wire switch two channels."""
from typing import Final
from zigpy.quirks import CustomCluster
from zigpy.quirks.v2 import add_to_registry_v2, EntityType, EntityPlatform
from zigpy.zcl.foundation import (
BaseAttributeDefs,
BaseCommandDefs,
ZCLAttributeDef,
ZCLCommandDef
)
from zigpy.zcl import ClusterType
import zigpy.types as t
class NodonPilotWireMode(t.enum16):
OFF = 0x00
COMFORT = 0x01
ECO = 0x02
FROST_PROTECTION = 0x03
COMFORT_MINUS_1 = 0x04
COMFORT_MINUS_2 = 0x05
NODON_PILOT_WIRE_CLUSTER_ID = 0xfc00 #64512
class NodonPilotWireCluster(CustomCluster):
"""NodOn pilot wire manufacturer-specific cluster."""
cluster_id: Final = NODON_PILOT_WIRE_CLUSTER_ID
name: Final = "Pilot Wire"
ep_attribute: Final = "pilot_wire_cluster"
class AttributeDefs(BaseAttributeDefs):
pilot_wire_mode: Final = ZCLAttributeDef(id=0x0000, type=NodonPilotWireMode, access="r")
class ClientCommandDefs(BaseCommandDefs):
setMode: Final = ZCLCommandDef(
id=0x0000,
schema={
"mode": NodonPilotWireMode
},
direction=True,
is_manufacturer_specific=True,
)
(
add_to_registry_v2("NodOn", "SIN-4-FP-21")
.also_applies_to("ADEO", "SIN-4-FP-21_EQU")
.replaces(NodonPilotWireCluster)
.enum("pilot_wire_mode",NodonPilotWireMode,NODON_PILOT_WIRE_CLUSTER_ID,ClusterType.Server,1,EntityType.STANDARD,EntityPlatform.SELECT,False,True,"pilot_wire_mode")
)
The problem occurs on all 5 modules.
Error logs
Enregistreur: homeassistant.components.websocket_api.http.connection
Source: components/websocket_api/commands.py:239
intégration: Home Assistant WebSocket API ([documentation](https://www.home-assistant.io/integrations/websocket_api), [problèmes](https://github.com/home-assistant/core/issues?q=is%3Aissue+is%3Aopen+label%3A%22integration%3A+websocket_api%22))
S'est produit pour la première fois: 14:23:47 (1 occurrences)
Dernier enregistrement: 14:23:47
[139849444259520] Unexpected exception
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 239, in handle_call_service
response = await hass.services.async_call(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/core.py", line 2738, in async_call
response_data = await coro
^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/core.py", line 2779, in _execute_service
return await target(service_call)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 975, in entity_service_call
single_response = await _handle_entity_call(
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 1047, in _handle_entity_call
result = await task
^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/select/__init__.py", line 191, in async_handle_select_option
await self.async_select_option(option)
File "/usr/src/homeassistant/homeassistant/components/zha/select.py", line 227, in async_select_option
await self._cluster_handler.write_attributes_safe(
File "/usr/src/homeassistant/homeassistant/components/zha/core/cluster_handlers/__init__.py", line 552, in write_attributes_safe
raise HomeAssistantError(
homeassistant.exceptions.HomeAssistantError: Failed to write attribute pilot_wire_mode=<NodonPilotWireMode.COMFORT_MINUS_1: 4>: <Status.INVALID_DATA_TYPE: 141>
Hello, I'm using the quirk on the latest version of HA (2024.5.3). What version do you use ? Quirks v2 are new and support is evolving at every version.
I'm on 2024.5.3 too 🤔
I wonder if the problem could be with the ZigBee key.
I use SkyConnect without multiprotocol
This is not your installation; it is my solution.
The enum entity tries to write the pilot_wire_mode
attribute which is not supported. You must use the command to change the mode.
Some update to catch attribute write and replace by commands
"""NodOn SIN-4-FP-21 pilot wire module."""
from typing import Any, Final
from zigpy.quirks import CustomCluster
from zigpy.quirks.v2 import add_to_registry_v2, EntityType, EntityPlatform
from zigpy.zcl.foundation import (
BaseAttributeDefs,
BaseCommandDefs,
ZCLAttributeDef,
ZCLCommandDef,
WriteAttributesStatusRecord,
Status
)
from zigpy.zcl import ClusterType
import zigpy.types as t
import logging
_LOGGER = logging.getLogger(__name__)
class NodonPilotWireMode(t.enum16):
OFF = 0x00
COMFORT = 0x01
ECO = 0x02
FROST_PROTECTION = 0x03
COMFORT_MINUS_1 = 0x04
COMFORT_MINUS_2 = 0x05
NODON_PILOT_WIRE_CLUSTER_ID = 0xfc00 #64512
class NodonPilotWireCluster(CustomCluster):
"""NodOn pilot wire manufacturer-specific cluster."""
cluster_id: Final = NODON_PILOT_WIRE_CLUSTER_ID
name: Final = "Pilot Wire"
ep_attribute: Final = "pilot_wire_cluster"
class AttributeDefs(BaseAttributeDefs):
pilot_wire_mode: Final = ZCLAttributeDef(id=0x0000, type=NodonPilotWireMode, access="r")
class ClientCommandDefs(BaseCommandDefs):
setMode: Final = ZCLCommandDef(
id=0x0000,
schema={"mode": NodonPilotWireMode},
direction=True,
is_manufacturer_specific=True,
)
async def write_attributes(
self, attributes: dict[str | int, Any], manufacturer: int | None = None
) -> list:
"""Override writes to the pilot_wire_mode attribute."""
if "pilot_wire_mode" in attributes:
await self.client_command(0,attributes.get("pilot_wire_mode"))
return [[WriteAttributesStatusRecord(Status.SUCCESS)]]
return await super().write_attributes(attributes, manufacturer=manufacturer)
(
add_to_registry_v2("NodOn", "SIN-4-FP-21")
.also_applies_to("ADEO", "SIN-4-FP-21_EQU")
.replaces(NodonPilotWireCluster)
.enum("pilot_wire_mode",NodonPilotWireMode,NODON_PILOT_WIRE_CLUSTER_ID,
ClusterType.Server,1,EntityType.STANDARD,EntityPlatform.SELECT,False,True)
)
Oh my boooy it work well. I just took the liberty of translating the different modes. Do you want me to add the Quirk in my initial request (of course mentioning you are the boss)
Happy to see it works for you ! You can add the quirk to your initial request. I would like to work on the HMI but I have other projects in parallel that requires my attention. I'll look into it in some weeks.