@@ -128,6 +128,19 @@ class BoschControlSequenceOfOperation(t.enum8):
128
128
)
129
129
130
130
131
+ def get_attribute_id_or_name (
132
+ attribute : ZCLAttributeDef , attributes : dict [str | int , Any ] | list [int | str ]
133
+ ) -> int | str | None :
134
+ """Return the attribute id/name when the id/name of the attribute is in the attributes list or None otherwise."""
135
+
136
+ if attribute .id in attributes :
137
+ return attribute .id
138
+ elif attribute .name in attributes :
139
+ return attribute .name
140
+ else :
141
+ return None
142
+
143
+
131
144
class BoschThermostatCluster (CustomCluster , Thermostat ):
132
145
"""Bosch thermostat cluster."""
133
146
@@ -196,24 +209,21 @@ async def write_attributes(
196
209
- do not write it to the device since it is not supported
197
210
- keep the value to be converted to the supported operating_mode
198
211
"""
199
- if SYSTEM_MODE_ATTR . id in attributes :
200
- remaining_attributes . pop ( SYSTEM_MODE_ATTR . id )
201
- system_mode_value = attributes . get ( SYSTEM_MODE_ATTR . id )
202
- elif SYSTEM_MODE_ATTR . name in attributes :
203
- remaining_attributes .pop (SYSTEM_MODE_ATTR . name )
204
- system_mode_value = attributes .get (SYSTEM_MODE_ATTR . name )
212
+ system_mode_attribute_id = get_attribute_id_or_name (
213
+ SYSTEM_MODE_ATTR , attributes
214
+ )
215
+ if system_mode_attribute_id is not None :
216
+ remaining_attributes .pop (system_mode_attribute_id )
217
+ system_mode_value = attributes .get (system_mode_attribute_id )
205
218
206
219
"""Check if operating_mode_attr is being written (can be numeric or string).
207
220
- ignore incoming operating_mode when system_mode is also written
208
221
- system_mode has priority and its value would be converted to operating_mode
209
222
- add resulting system_mode to the internal zigpy Cluster cache
210
223
"""
211
- operating_mode_attribute_id = None
212
- if operating_mode_attr .id in attributes :
213
- operating_mode_attribute_id = operating_mode_attr .id
214
- elif operating_mode_attr .name in attributes :
215
- operating_mode_attribute_id = operating_mode_attr .name
216
-
224
+ operating_mode_attribute_id = get_attribute_id_or_name (
225
+ operating_mode_attr , attributes
226
+ )
217
227
if operating_mode_attribute_id is not None :
218
228
if system_mode_value is not None :
219
229
operating_mode_value = remaining_attributes .pop (
@@ -259,35 +269,32 @@ async def write_attributes(
259
269
"""Sync system_mode with ctrl_sequence_of_oper."""
260
270
ctrl_sequence_of_oper_attr = Thermostat .AttributeDefs .ctrl_sequence_of_oper
261
271
262
- ctrl_sequence_of_oper_value = None
263
- if ctrl_sequence_of_oper_attr .id in attributes :
264
- ctrl_sequence_of_oper_value = attributes .get (
265
- ctrl_sequence_of_oper_attr .id
266
- )
267
- elif ctrl_sequence_of_oper_attr .name in attributes :
272
+ ctrl_sequence_of_oper_attribute_id = get_attribute_id_or_name (
273
+ ctrl_sequence_of_oper_attr , attributes
274
+ )
275
+ if ctrl_sequence_of_oper_attribute_id is not None :
268
276
ctrl_sequence_of_oper_value = attributes .get (
269
- ctrl_sequence_of_oper_attr .name
270
- )
271
-
272
- if ctrl_sequence_of_oper_value is not None :
273
- successful_r , failed_r = await super ().read_attributes (
274
- [operating_mode_attr .name ], True , False , manufacturer
277
+ ctrl_sequence_of_oper_attribute_id
275
278
)
276
- if operating_mode_attr . name in successful_r :
277
- operating_mode_attr_value = successful_r . pop (
278
- operating_mode_attr .name
279
+ if ctrl_sequence_of_oper_value is not None :
280
+ successful_r , failed_r = await super (). read_attributes (
281
+ [ operating_mode_attr .name ], True , False , manufacturer
279
282
)
280
- if operating_mode_attr_value == BoschOperatingMode .Manual :
281
- new_system_mode_value = Thermostat .SystemMode .Heat
282
- if (
283
- ctrl_sequence_of_oper_value
284
- == BoschControlSequenceOfOperation .Cooling
285
- ):
286
- new_system_mode_value = Thermostat .SystemMode .Cool
287
-
288
- self ._update_attribute (
289
- SYSTEM_MODE_ATTR .id , new_system_mode_value
283
+ if operating_mode_attr .name in successful_r :
284
+ operating_mode_attr_value = successful_r .pop (
285
+ operating_mode_attr .name
290
286
)
287
+ if operating_mode_attr_value == BoschOperatingMode .Manual :
288
+ new_system_mode_value = Thermostat .SystemMode .Heat
289
+ if (
290
+ ctrl_sequence_of_oper_value
291
+ == BoschControlSequenceOfOperation .Cooling
292
+ ):
293
+ new_system_mode_value = Thermostat .SystemMode .Cool
294
+
295
+ self ._update_attribute (
296
+ SYSTEM_MODE_ATTR .id , new_system_mode_value
297
+ )
291
298
292
299
"""Write the remaining attributes to thermostat cluster."""
293
300
if remaining_attributes :
@@ -310,16 +317,14 @@ async def read_attributes(
310
317
311
318
successful_r , failed_r = {}, {}
312
319
remaining_attributes = attributes .copy ()
313
- system_mode_attribute_id = None
314
320
315
321
"""Check if SYSTEM_MODE_ATTR is being read (can be numeric or string)."""
316
- if SYSTEM_MODE_ATTR .id in attributes :
317
- system_mode_attribute_id = SYSTEM_MODE_ATTR .id
318
- elif SYSTEM_MODE_ATTR .name in attributes :
319
- system_mode_attribute_id = SYSTEM_MODE_ATTR .name
320
-
321
- """Read operating_mode instead and convert it to system_mode."""
322
+ system_mode_attribute_id = get_attribute_id_or_name (
323
+ SYSTEM_MODE_ATTR , attributes
324
+ )
322
325
if system_mode_attribute_id is not None :
326
+ """Read operating_mode instead and convert it to system_mode."""
327
+
323
328
remaining_attributes .remove (system_mode_attribute_id )
324
329
325
330
ctrl_sequence_of_oper_attr = Thermostat .AttributeDefs .ctrl_sequence_of_oper
0 commit comments