1919from homeassistant .helpers .entity_platform import AddConfigEntryEntitiesCallback
2020
2121from . import TuyaConfigEntry
22- from .const import TUYA_DISCOVERY_NEW , DeviceCategory , DPCode , DPType
22+ from .const import TUYA_DISCOVERY_NEW , DeviceCategory , DPCode
2323from .entity import TuyaEntity
24- from .models import EnumTypeData , find_dpcode
24+ from .models import DPCodeEnumWrapper
2525from .util import get_dpcode
2626
2727
@@ -85,9 +85,21 @@ def async_discover_device(device_ids: list[str]) -> None:
8585 device = manager .device_map [device_id ]
8686 if descriptions := ALARM .get (device .category ):
8787 entities .extend (
88- TuyaAlarmEntity (device , manager , description )
88+ TuyaAlarmEntity (
89+ device ,
90+ manager ,
91+ description ,
92+ action_dpcode_wrapper = action_dpcode_wrapper ,
93+ state_dpcode_wrapper = DPCodeEnumWrapper .find_dpcode (
94+ device , description .master_state
95+ ),
96+ )
8997 for description in descriptions
90- if description .key in device .status
98+ if (
99+ action_dpcode_wrapper := DPCodeEnumWrapper .find_dpcode (
100+ device , description .key , prefer_function = True
101+ )
102+ )
91103 )
92104 async_add_entities (entities )
93105
@@ -103,41 +115,31 @@ class TuyaAlarmEntity(TuyaEntity, AlarmControlPanelEntity):
103115
104116 _attr_name = None
105117 _attr_code_arm_required = False
106- _master_state : EnumTypeData | None = None
107118 _alarm_msg_dpcode : DPCode | None = None
108119
109120 def __init__ (
110121 self ,
111122 device : CustomerDevice ,
112123 device_manager : Manager ,
113124 description : TuyaAlarmControlPanelEntityDescription ,
125+ * ,
126+ action_dpcode_wrapper : DPCodeEnumWrapper ,
127+ state_dpcode_wrapper : DPCodeEnumWrapper | None ,
114128 ) -> None :
115129 """Init Tuya Alarm."""
116130 super ().__init__ (device , device_manager )
117131 self .entity_description = description
118132 self ._attr_unique_id = f"{ super ().unique_id } { description .key } "
133+ self ._action_dpcode_wrapper = action_dpcode_wrapper
134+ self ._state_dpcode_wrapper = state_dpcode_wrapper
119135
120136 # Determine supported modes
121- if supported_modes := find_dpcode (
122- self .device , description .key , dptype = DPType .ENUM , prefer_function = True
123- ):
124- if Mode .HOME in supported_modes .range :
125- self ._attr_supported_features |= AlarmControlPanelEntityFeature .ARM_HOME
126-
127- if Mode .ARM in supported_modes .range :
128- self ._attr_supported_features |= AlarmControlPanelEntityFeature .ARM_AWAY
129-
130- if Mode .SOS in supported_modes .range :
131- self ._attr_supported_features |= AlarmControlPanelEntityFeature .TRIGGER
132-
133- # Determine master state
134- if enum_type := find_dpcode (
135- self .device ,
136- description .master_state ,
137- dptype = DPType .ENUM ,
138- prefer_function = True ,
139- ):
140- self ._master_state = enum_type
137+ if Mode .HOME in action_dpcode_wrapper .type_information .range :
138+ self ._attr_supported_features |= AlarmControlPanelEntityFeature .ARM_HOME
139+ if Mode .ARM in action_dpcode_wrapper .type_information .range :
140+ self ._attr_supported_features |= AlarmControlPanelEntityFeature .ARM_AWAY
141+ if Mode .SOS in action_dpcode_wrapper .type_information .range :
142+ self ._attr_supported_features |= AlarmControlPanelEntityFeature .TRIGGER
141143
142144 # Determine alarm message
143145 if dp_code := get_dpcode (self .device , description .alarm_msg ):
@@ -149,8 +151,8 @@ def alarm_state(self) -> AlarmControlPanelState | None:
149151 # When the alarm is triggered, only its 'state' is changing. From 'normal' to 'alarm'.
150152 # The 'mode' doesn't change, and stays as 'arm' or 'home'.
151153 if (
152- self ._master_state is not None
153- and self .device .status .get (self ._master_state .dpcode ) == State .ALARM
154+ self ._state_dpcode_wrapper is not None
155+ and self .device .status .get (self ._state_dpcode_wrapper .dpcode ) == State .ALARM
154156 ):
155157 # Only report as triggered if NOT a battery warning
156158 if (
@@ -166,28 +168,26 @@ def alarm_state(self) -> AlarmControlPanelState | None:
166168 def changed_by (self ) -> str | None :
167169 """Last change triggered by."""
168170 if (
169- self ._master_state is not None
171+ self ._state_dpcode_wrapper is not None
170172 and self ._alarm_msg_dpcode is not None
171- and self .device .status .get (self ._master_state .dpcode ) == State .ALARM
173+ and self .device .status .get (self ._state_dpcode_wrapper .dpcode ) == State .ALARM
172174 and (encoded_msg := self .device .status .get (self ._alarm_msg_dpcode ))
173175 ):
174176 return b64decode (encoded_msg ).decode ("utf-16be" )
175177 return None
176178
177- def alarm_disarm (self , code : str | None = None ) -> None :
179+ async def async_alarm_disarm (self , code : str | None = None ) -> None :
178180 """Send Disarm command."""
179- self ._send_command (
180- [{"code" : self .entity_description .key , "value" : Mode .DISARMED }]
181- )
181+ await self ._async_send_dpcode_update (self ._action_dpcode_wrapper , Mode .DISARMED )
182182
183- def alarm_arm_home (self , code : str | None = None ) -> None :
183+ async def async_alarm_arm_home (self , code : str | None = None ) -> None :
184184 """Send Home command."""
185- self ._send_command ([{ "code" : self .entity_description . key , "value" : Mode .HOME }] )
185+ await self ._async_send_dpcode_update ( self ._action_dpcode_wrapper , Mode .HOME )
186186
187- def alarm_arm_away (self , code : str | None = None ) -> None :
187+ async def async_alarm_arm_away (self , code : str | None = None ) -> None :
188188 """Send Arm command."""
189- self ._send_command ([{ "code" : self .entity_description . key , "value" : Mode .ARM }] )
189+ await self ._async_send_dpcode_update ( self ._action_dpcode_wrapper , Mode .ARM )
190190
191- def alarm_trigger (self , code : str | None = None ) -> None :
191+ async def async_alarm_trigger (self , code : str | None = None ) -> None :
192192 """Send SOS command."""
193- self ._send_command ([{ "code" : self .entity_description . key , "value" : Mode .SOS }] )
193+ await self ._async_send_dpcode_update ( self ._action_dpcode_wrapper , Mode .SOS )
0 commit comments