diff --git a/zhaquirks/bosch/rbsh_trv0_zb_eu.py b/zhaquirks/bosch/rbsh_trv0_zb_eu.py new file mode 100644 index 0000000000..2c17055ba5 --- /dev/null +++ b/zhaquirks/bosch/rbsh_trv0_zb_eu.py @@ -0,0 +1,161 @@ +"""Device handler for Bosch RBSH-TRV0-ZB-EU thermostat.""" + +from zigpy.profiles import zha +import zigpy.types as t +from zigpy.quirks import CustomDevice +from zigpy.zcl.clusters import general, hvac, homeautomation + +from zigpy.zcl.clusters.general import ( + Basic, + Identify, + Ota, + PollControl, + Groups, + Time, + PowerConfiguration, + ZCLAttributeDef, +) +from zigpy.zcl.clusters.hvac import Thermostat, UserInterface +from zigpy.zcl.clusters.homeautomation import Diagnostic + +from zhaquirks import CustomCluster +from zhaquirks.const import ( + DEVICE_TYPE, + ENDPOINTS, + INPUT_CLUSTERS, + MODELS_INFO, + OUTPUT_CLUSTERS, + PROFILE_ID, +) + + +class BoschOperatingMode(t.enum8): + Schedule = 0x00 + Manual = 0x01 + Pause = 0x05 + + +class State(t.enum8): + Off = 0x00 + On = 0x01 + + +class BoschDisplayOrientation(t.enum8): + Normal = 0x00 + Flipped = 0x01 + + +class BoschDisplayedTemperature(t.enum8): + Target = 0x00 + Measured = 0x01 + + +class BoschThermostatCluster(CustomCluster, Thermostat): + """Bosch thermostat cluster.""" + + class AttributeDefs(Thermostat.AttributeDefs): + operating_mode = ZCLAttributeDef( + id=0x4007, + type=BoschOperatingMode, + is_manufacturer_specific=True, + ) + + pi_heating_demand = ZCLAttributeDef( + id=0x4020, + # Values range from 0-100 + type=t.enum8, + is_manufacturer_specific=True, + ) + + window_open = ZCLAttributeDef( + id=0x4042, + type=State, + is_manufacturer_specific=True, + ) + + boost = ZCLAttributeDef( + id=0x4043, + type=State, + is_manufacturer_specific=True, + ) + + +class BoschUserInterfaceCluster(CustomCluster, UserInterface): + """Bosch UserInterface cluster.""" + + class AttributeDefs(UserInterface.AttributeDefs): + display_orientation = ZCLAttributeDef( + id=0x400B, + type=BoschDisplayOrientation, + is_manufacturer_specific=True, + ) + + display_ontime = ZCLAttributeDef( + id=0x403A, + # Usable values range from 2-30 + type=t.enum8, + is_manufacturer_specific=True, + ) + + display_brightness = ZCLAttributeDef( + id=0x403B, + # Values range from 0-10 + type=t.enum8, + is_manufacturer_specific=True, + ) + + displayed_temperature = ZCLAttributeDef( + id=0x4039, + type=BoschDisplayedTemperature, + is_manufacturer_specific=True, + ) + + +class BoschThermostat(CustomDevice): + """Bosch thermostat custom device.""" + + signature = { + MODELS_INFO: [("BOSCH", "RBSH-TRV0-ZB-EU")], + ENDPOINTS: { + # + 1: { + PROFILE_ID: zha.PROFILE_ID, + DEVICE_TYPE: zha.DeviceType.THERMOSTAT, + INPUT_CLUSTERS: [ + general.Basic.cluster_id, + general.PowerConfiguration.cluster_id, + general.Identify.cluster_id, + general.Groups.cluster_id, + general.PollControl.cluster_id, + hvac.Thermostat.cluster_id, + hvac.UserInterface.cluster_id, + homeautomation.Diagnostic.cluster_id, + ], + OUTPUT_CLUSTERS: [general.Ota.cluster_id, + general.Time.cluster_id], + }, + }, + } + + replacement = { + ENDPOINTS: { + 1: { + INPUT_CLUSTERS: [ + Basic, + BoschThermostatCluster, + BoschUserInterfaceCluster, + Diagnostic, + Groups, + Identify, + Ota, + PollControl, + PowerConfiguration, + Time, + ], + OUTPUT_CLUSTERS: [Ota, Time], + }, + }, + }