Home Assistant Unofficial Reference 2024.12.1
switch.py
Go to the documentation of this file.
1 """Support for Tuya switches."""
2 
3 from __future__ import annotations
4 
5 from typing import Any
6 
7 from tuya_sharing import CustomerDevice, Manager
8 
10  SwitchDeviceClass,
11  SwitchEntity,
12  SwitchEntityDescription,
13 )
14 from homeassistant.const import EntityCategory
15 from homeassistant.core import HomeAssistant, callback
16 from homeassistant.helpers.dispatcher import async_dispatcher_connect
17 from homeassistant.helpers.entity_platform import AddEntitiesCallback
18 
19 from . import TuyaConfigEntry
20 from .const import TUYA_DISCOVERY_NEW, DPCode
21 from .entity import TuyaEntity
22 
23 # All descriptions can be found here. Mostly the Boolean data types in the
24 # default instruction set of each category end up being a Switch.
25 # https://developer.tuya.com/en/docs/iot/standarddescription?id=K9i5ql6waswzq
26 SWITCHES: dict[str, tuple[SwitchEntityDescription, ...]] = {
27  # Smart Kettle
28  # https://developer.tuya.com/en/docs/iot/fbh?id=K9gf484m21yq7
29  "bh": (
31  key=DPCode.START,
32  translation_key="start",
33  ),
35  key=DPCode.WARM,
36  translation_key="heat_preservation",
37  entity_category=EntityCategory.CONFIG,
38  ),
39  ),
40  # EasyBaby
41  # Undocumented, might have a wider use
42  "cn": (
44  key=DPCode.DISINFECTION,
45  translation_key="disinfection",
46  ),
48  key=DPCode.WATER,
49  translation_key="water",
50  ),
51  ),
52  # Dehumidifier
53  # https://developer.tuya.com/en/docs/iot/s?id=K9gf48r6jke8e
54  "cs": (
56  key=DPCode.ANION,
57  translation_key="ionizer",
58  icon="mdi:atom",
59  entity_category=EntityCategory.CONFIG,
60  ),
62  key=DPCode.CHILD_LOCK,
63  translation_key="child_lock",
64  icon="mdi:account-lock",
65  entity_category=EntityCategory.CONFIG,
66  ),
68  key=DPCode.FILTER_RESET,
69  translation_key="filter_reset",
70  icon="mdi:filter",
71  entity_category=EntityCategory.CONFIG,
72  ),
73  ),
74  # Smart Pet Feeder
75  # https://developer.tuya.com/en/docs/iot/categorycwwsq?id=Kaiuz2b6vydld
76  "cwwsq": (
78  key=DPCode.SLOW_FEED,
79  translation_key="slow_feed",
80  entity_category=EntityCategory.CONFIG,
81  ),
82  ),
83  # Pet Water Feeder
84  # https://developer.tuya.com/en/docs/iot/f?id=K9gf46aewxem5
85  "cwysj": (
87  key=DPCode.FILTER_RESET,
88  translation_key="filter_reset",
89  entity_category=EntityCategory.CONFIG,
90  ),
92  key=DPCode.PUMP_RESET,
93  translation_key="water_pump_reset",
94  entity_category=EntityCategory.CONFIG,
95  ),
97  key=DPCode.SWITCH,
98  translation_key="power",
99  ),
101  key=DPCode.WATER_RESET,
102  translation_key="reset_of_water_usage_days",
103  entity_category=EntityCategory.CONFIG,
104  ),
106  key=DPCode.UV,
107  translation_key="uv_sterilization",
108  entity_category=EntityCategory.CONFIG,
109  ),
110  ),
111  # Light
112  # https://developer.tuya.com/en/docs/iot/f?id=K9i5ql3v98hn3
113  "dj": (
114  # There are sockets available with an RGB light
115  # that advertise as `dj`, but provide an additional
116  # switch to control the plug.
118  key=DPCode.SWITCH,
119  translation_key="plug",
120  ),
121  ),
122  # Circuit Breaker
123  "dlq": (
125  key=DPCode.CHILD_LOCK,
126  translation_key="child_lock",
127  entity_category=EntityCategory.CONFIG,
128  ),
130  key=DPCode.SWITCH,
131  translation_key="switch",
132  ),
133  ),
134  # Wake Up Light II
135  # Not documented
136  "hxd": (
138  key=DPCode.SWITCH_1,
139  translation_key="radio",
140  ),
142  key=DPCode.SWITCH_2,
143  translation_key="alarm_1",
144  entity_category=EntityCategory.CONFIG,
145  ),
147  key=DPCode.SWITCH_3,
148  translation_key="alarm_2",
149  entity_category=EntityCategory.CONFIG,
150  ),
152  key=DPCode.SWITCH_4,
153  translation_key="alarm_3",
154  entity_category=EntityCategory.CONFIG,
155  ),
157  key=DPCode.SWITCH_5,
158  translation_key="alarm_4",
159  entity_category=EntityCategory.CONFIG,
160  ),
162  key=DPCode.SWITCH_6,
163  translation_key="sleep_aid",
164  ),
165  ),
166  # Two-way temperature and humidity switch
167  # "MOES Temperature and Humidity Smart Switch Module MS-103"
168  # Documentation not found
169  "wkcz": (
171  key=DPCode.SWITCH_1,
172  translation_key="switch_1",
173  device_class=SwitchDeviceClass.OUTLET,
174  ),
176  key=DPCode.SWITCH_2,
177  translation_key="switch_2",
178  device_class=SwitchDeviceClass.OUTLET,
179  ),
180  ),
181  # Switch
182  # https://developer.tuya.com/en/docs/iot/s?id=K9gf7o5prgf7s
183  "kg": (
185  key=DPCode.CHILD_LOCK,
186  translation_key="child_lock",
187  entity_category=EntityCategory.CONFIG,
188  ),
190  key=DPCode.SWITCH_1,
191  translation_key="switch_1",
192  device_class=SwitchDeviceClass.OUTLET,
193  ),
195  key=DPCode.SWITCH_2,
196  translation_key="switch_2",
197  device_class=SwitchDeviceClass.OUTLET,
198  ),
200  key=DPCode.SWITCH_3,
201  translation_key="switch_3",
202  device_class=SwitchDeviceClass.OUTLET,
203  ),
205  key=DPCode.SWITCH_4,
206  translation_key="switch_4",
207  device_class=SwitchDeviceClass.OUTLET,
208  ),
210  key=DPCode.SWITCH_5,
211  translation_key="switch_5",
212  device_class=SwitchDeviceClass.OUTLET,
213  ),
215  key=DPCode.SWITCH_6,
216  translation_key="switch_6",
217  device_class=SwitchDeviceClass.OUTLET,
218  ),
220  key=DPCode.SWITCH_7,
221  translation_key="switch_7",
222  device_class=SwitchDeviceClass.OUTLET,
223  ),
225  key=DPCode.SWITCH_8,
226  translation_key="switch_8",
227  device_class=SwitchDeviceClass.OUTLET,
228  ),
230  key=DPCode.SWITCH_USB1,
231  translation_key="usb_1",
232  ),
234  key=DPCode.SWITCH_USB2,
235  translation_key="usb_2",
236  ),
238  key=DPCode.SWITCH_USB3,
239  translation_key="usb_3",
240  ),
242  key=DPCode.SWITCH_USB4,
243  translation_key="usb_4",
244  ),
246  key=DPCode.SWITCH_USB5,
247  translation_key="usb_5",
248  ),
250  key=DPCode.SWITCH_USB6,
251  translation_key="usb_6",
252  ),
254  key=DPCode.SWITCH,
255  translation_key="switch",
256  device_class=SwitchDeviceClass.OUTLET,
257  ),
258  ),
259  # Air Purifier
260  # https://developer.tuya.com/en/docs/iot/f?id=K9gf46h2s6dzm
261  "kj": (
263  key=DPCode.ANION,
264  translation_key="ionizer",
265  entity_category=EntityCategory.CONFIG,
266  ),
268  key=DPCode.FILTER_RESET,
269  translation_key="filter_cartridge_reset",
270  entity_category=EntityCategory.CONFIG,
271  ),
273  key=DPCode.LOCK,
274  translation_key="child_lock",
275  entity_category=EntityCategory.CONFIG,
276  ),
278  key=DPCode.SWITCH,
279  translation_key="power",
280  ),
282  key=DPCode.WET,
283  translation_key="humidification",
284  entity_category=EntityCategory.CONFIG,
285  ),
287  key=DPCode.UV,
288  translation_key="uv_sterilization",
289  entity_category=EntityCategory.CONFIG,
290  ),
291  ),
292  # Air conditioner
293  # https://developer.tuya.com/en/docs/iot/categorykt?id=Kaiuz0z71ov2n
294  "kt": (
296  key=DPCode.ANION,
297  translation_key="ionizer",
298  entity_category=EntityCategory.CONFIG,
299  ),
301  key=DPCode.LOCK,
302  translation_key="child_lock",
303  entity_category=EntityCategory.CONFIG,
304  ),
305  ),
306  # Sous Vide Cooker
307  # https://developer.tuya.com/en/docs/iot/categorymzj?id=Kaiuz2vy130ux
308  "mzj": (
310  key=DPCode.SWITCH,
311  translation_key="switch",
312  entity_category=EntityCategory.CONFIG,
313  ),
315  key=DPCode.START,
316  translation_key="start",
317  entity_category=EntityCategory.CONFIG,
318  ),
319  ),
320  # Power Socket
321  # https://developer.tuya.com/en/docs/iot/s?id=K9gf7o5prgf7s
322  "pc": (
324  key=DPCode.CHILD_LOCK,
325  translation_key="child_lock",
326  entity_category=EntityCategory.CONFIG,
327  ),
329  key=DPCode.SWITCH_1,
330  translation_key="socket_1",
331  device_class=SwitchDeviceClass.OUTLET,
332  ),
334  key=DPCode.SWITCH_2,
335  translation_key="socket_2",
336  device_class=SwitchDeviceClass.OUTLET,
337  ),
339  key=DPCode.SWITCH_3,
340  translation_key="socket_3",
341  device_class=SwitchDeviceClass.OUTLET,
342  ),
344  key=DPCode.SWITCH_4,
345  translation_key="socket_4",
346  device_class=SwitchDeviceClass.OUTLET,
347  ),
349  key=DPCode.SWITCH_5,
350  translation_key="socket_5",
351  device_class=SwitchDeviceClass.OUTLET,
352  ),
354  key=DPCode.SWITCH_6,
355  translation_key="socket_6",
356  device_class=SwitchDeviceClass.OUTLET,
357  ),
359  key=DPCode.SWITCH_USB1,
360  translation_key="usb_1",
361  ),
363  key=DPCode.SWITCH_USB2,
364  translation_key="usb_2",
365  ),
367  key=DPCode.SWITCH_USB3,
368  translation_key="usb_3",
369  ),
371  key=DPCode.SWITCH_USB4,
372  translation_key="usb_4",
373  ),
375  key=DPCode.SWITCH_USB5,
376  translation_key="usb_5",
377  ),
379  key=DPCode.SWITCH_USB6,
380  translation_key="usb_6",
381  ),
383  key=DPCode.SWITCH,
384  translation_key="socket",
385  device_class=SwitchDeviceClass.OUTLET,
386  ),
387  ),
388  # Unknown product with switch capabilities
389  # Fond in some diffusers, plugs and PIR flood lights
390  # Not documented
391  "qjdcz": (
393  key=DPCode.SWITCH_1,
394  translation_key="switch",
395  ),
396  ),
397  # Heater
398  # https://developer.tuya.com/en/docs/iot/categoryqn?id=Kaiuz18kih0sm
399  "qn": (
401  key=DPCode.ANION,
402  translation_key="ionizer",
403  entity_category=EntityCategory.CONFIG,
404  ),
406  key=DPCode.LOCK,
407  translation_key="child_lock",
408  entity_category=EntityCategory.CONFIG,
409  ),
410  ),
411  # Robot Vacuum
412  # https://developer.tuya.com/en/docs/iot/fsd?id=K9gf487ck1tlo
413  "sd": (
415  key=DPCode.SWITCH_DISTURB,
416  translation_key="do_not_disturb",
417  entity_category=EntityCategory.CONFIG,
418  ),
420  key=DPCode.VOICE_SWITCH,
421  translation_key="mute_voice",
422  entity_category=EntityCategory.CONFIG,
423  ),
424  ),
425  # Smart Water Timer
426  "sfkzq": (
428  key=DPCode.SWITCH,
429  translation_key="switch",
430  ),
431  ),
432  # Irrigator
433  # https://developer.tuya.com/en/docs/iot/categoryggq?id=Kaiuz1qib7z0k
434  "ggq": (
436  key=DPCode.SWITCH_1,
437  translation_key="switch_1",
438  ),
440  key=DPCode.SWITCH_2,
441  translation_key="switch_2",
442  ),
443  ),
444  # Siren Alarm
445  # https://developer.tuya.com/en/docs/iot/categorysgbj?id=Kaiuz37tlpbnu
446  "sgbj": (
448  key=DPCode.MUFFLING,
449  translation_key="mute",
450  entity_category=EntityCategory.CONFIG,
451  ),
452  ),
453  # Smart Camera
454  # https://developer.tuya.com/en/docs/iot/categorysp?id=Kaiuz35leyo12
455  "sp": (
457  key=DPCode.WIRELESS_BATTERYLOCK,
458  translation_key="battery_lock",
459  entity_category=EntityCategory.CONFIG,
460  ),
462  key=DPCode.CRY_DETECTION_SWITCH,
463  translation_key="cry_detection",
464  entity_category=EntityCategory.CONFIG,
465  ),
467  key=DPCode.DECIBEL_SWITCH,
468  translation_key="sound_detection",
469  entity_category=EntityCategory.CONFIG,
470  ),
472  key=DPCode.RECORD_SWITCH,
473  translation_key="video_recording",
474  entity_category=EntityCategory.CONFIG,
475  ),
477  key=DPCode.MOTION_RECORD,
478  translation_key="motion_recording",
479  entity_category=EntityCategory.CONFIG,
480  ),
482  key=DPCode.BASIC_PRIVATE,
483  translation_key="privacy_mode",
484  entity_category=EntityCategory.CONFIG,
485  ),
487  key=DPCode.BASIC_FLIP,
488  translation_key="flip",
489  entity_category=EntityCategory.CONFIG,
490  ),
492  key=DPCode.BASIC_OSD,
493  translation_key="time_watermark",
494  entity_category=EntityCategory.CONFIG,
495  ),
497  key=DPCode.BASIC_WDR,
498  translation_key="wide_dynamic_range",
499  entity_category=EntityCategory.CONFIG,
500  ),
502  key=DPCode.MOTION_TRACKING,
503  translation_key="motion_tracking",
504  entity_category=EntityCategory.CONFIG,
505  ),
507  key=DPCode.MOTION_SWITCH,
508  translation_key="motion_alarm",
509  entity_category=EntityCategory.CONFIG,
510  ),
511  ),
512  # Smart Gardening system
513  # https://developer.tuya.com/en/docs/iot/categorysz?id=Kaiuz4e6h7up0
514  "sz": (
516  key=DPCode.SWITCH,
517  translation_key="power",
518  ),
520  key=DPCode.PUMP,
521  translation_key="pump",
522  ),
523  ),
524  # Fingerbot
525  "szjqr": (
527  key=DPCode.SWITCH,
528  translation_key="switch",
529  ),
530  ),
531  # Hejhome whitelabel Fingerbot
532  "znjxs": (
534  key=DPCode.SWITCH,
535  translation_key="switch",
536  ),
537  ),
538  # IoT Switch?
539  # Note: Undocumented
540  "tdq": (
542  key=DPCode.SWITCH_1,
543  translation_key="switch_1",
544  device_class=SwitchDeviceClass.OUTLET,
545  ),
547  key=DPCode.SWITCH_2,
548  translation_key="switch_2",
549  device_class=SwitchDeviceClass.OUTLET,
550  ),
552  key=DPCode.SWITCH_3,
553  translation_key="switch_3",
554  device_class=SwitchDeviceClass.OUTLET,
555  ),
557  key=DPCode.SWITCH_4,
558  translation_key="switch_4",
559  device_class=SwitchDeviceClass.OUTLET,
560  ),
562  key=DPCode.CHILD_LOCK,
563  translation_key="child_lock",
564  entity_category=EntityCategory.CONFIG,
565  ),
566  ),
567  # Solar Light
568  # https://developer.tuya.com/en/docs/iot/tynd?id=Kaof8j02e1t98
569  "tyndj": (
571  key=DPCode.SWITCH_SAVE_ENERGY,
572  translation_key="energy_saving",
573  entity_category=EntityCategory.CONFIG,
574  ),
575  ),
576  # Thermostat
577  # https://developer.tuya.com/en/docs/iot/f?id=K9gf45ld5l0t9
578  "wk": (
580  key=DPCode.CHILD_LOCK,
581  translation_key="child_lock",
582  entity_category=EntityCategory.CONFIG,
583  ),
584  ),
585  # Thermostatic Radiator Valve
586  # Not documented
587  "wkf": (
589  key=DPCode.CHILD_LOCK,
590  translation_key="child_lock",
591  entity_category=EntityCategory.CONFIG,
592  ),
594  key=DPCode.WINDOW_CHECK,
595  translation_key="open_window_detection",
596  entity_category=EntityCategory.CONFIG,
597  ),
598  ),
599  # Air Conditioner Mate (Smart IR Socket)
600  "wnykq": (
602  key=DPCode.SWITCH,
603  name=None,
604  ),
605  ),
606  # SIREN: Siren (switch) with Temperature and humidity sensor
607  # https://developer.tuya.com/en/docs/iot/f?id=Kavck4sr3o5ek
608  "wsdcg": (
610  key=DPCode.SWITCH,
611  translation_key="switch",
612  device_class=SwitchDeviceClass.OUTLET,
613  ),
614  ),
615  # Ceiling Light
616  # https://developer.tuya.com/en/docs/iot/ceiling-light?id=Kaiuz03xxfc4r
617  "xdd": (
619  key=DPCode.DO_NOT_DISTURB,
620  translation_key="do_not_disturb",
621  entity_category=EntityCategory.CONFIG,
622  ),
623  ),
624  # Diffuser
625  # https://developer.tuya.com/en/docs/iot/categoryxxj?id=Kaiuz1f9mo6bl
626  "xxj": (
628  key=DPCode.SWITCH,
629  translation_key="power",
630  ),
632  key=DPCode.SWITCH_SPRAY,
633  translation_key="spray",
634  ),
636  key=DPCode.SWITCH_VOICE,
637  translation_key="voice",
638  entity_category=EntityCategory.CONFIG,
639  ),
640  ),
641  # Smart Electricity Meter
642  # https://developer.tuya.com/en/docs/iot/smart-meter?id=Kaiuz4gv6ack7
643  "zndb": (
645  key=DPCode.SWITCH,
646  translation_key="switch",
647  ),
648  ),
649  # Fan
650  # https://developer.tuya.com/en/docs/iot/categoryfs?id=Kaiuz1xweel1c
651  "fs": (
653  key=DPCode.ANION,
654  translation_key="anion",
655  entity_category=EntityCategory.CONFIG,
656  ),
658  key=DPCode.HUMIDIFIER,
659  translation_key="humidification",
660  entity_category=EntityCategory.CONFIG,
661  ),
663  key=DPCode.OXYGEN,
664  translation_key="oxygen_bar",
665  entity_category=EntityCategory.CONFIG,
666  ),
668  key=DPCode.FAN_COOL,
669  translation_key="natural_wind",
670  entity_category=EntityCategory.CONFIG,
671  ),
673  key=DPCode.FAN_BEEP,
674  translation_key="sound",
675  entity_category=EntityCategory.CONFIG,
676  ),
678  key=DPCode.CHILD_LOCK,
679  translation_key="child_lock",
680  entity_category=EntityCategory.CONFIG,
681  ),
682  ),
683  # Curtain
684  # https://developer.tuya.com/en/docs/iot/f?id=K9gf46o5mtfyc
685  "cl": (
687  key=DPCode.CONTROL_BACK,
688  translation_key="reverse",
689  entity_category=EntityCategory.CONFIG,
690  ),
692  key=DPCode.OPPOSITE,
693  translation_key="reverse",
694  entity_category=EntityCategory.CONFIG,
695  ),
696  ),
697  # Humidifier
698  # https://developer.tuya.com/en/docs/iot/categoryjsq?id=Kaiuz1smr440b
699  "jsq": (
701  key=DPCode.SWITCH_SOUND,
702  translation_key="voice",
703  entity_category=EntityCategory.CONFIG,
704  ),
706  key=DPCode.SLEEP,
707  translation_key="sleep",
708  entity_category=EntityCategory.CONFIG,
709  ),
711  key=DPCode.STERILIZATION,
712  translation_key="sterilization",
713  entity_category=EntityCategory.CONFIG,
714  ),
715  ),
716  # Pool HeatPump
717  "znrb": (
719  key=DPCode.SWITCH,
720  translation_key="switch",
721  ),
722  ),
723 }
724 
725 # Socket (duplicate of `pc`)
726 # https://developer.tuya.com/en/docs/iot/s?id=K9gf7o5prgf7s
727 SWITCHES["cz"] = SWITCHES["pc"]
728 
729 
731  hass: HomeAssistant, entry: TuyaConfigEntry, async_add_entities: AddEntitiesCallback
732 ) -> None:
733  """Set up tuya sensors dynamically through tuya discovery."""
734  hass_data = entry.runtime_data
735 
736  @callback
737  def async_discover_device(device_ids: list[str]) -> None:
738  """Discover and add a discovered tuya sensor."""
739  entities: list[TuyaSwitchEntity] = []
740  for device_id in device_ids:
741  device = hass_data.manager.device_map[device_id]
742  if descriptions := SWITCHES.get(device.category):
743  entities.extend(
744  TuyaSwitchEntity(device, hass_data.manager, description)
745  for description in descriptions
746  if description.key in device.status
747  )
748 
749  async_add_entities(entities)
750 
751  async_discover_device([*hass_data.manager.device_map])
752 
753  entry.async_on_unload(
754  async_dispatcher_connect(hass, TUYA_DISCOVERY_NEW, async_discover_device)
755  )
756 
757 
759  """Tuya Switch Device."""
760 
761  def __init__(
762  self,
763  device: CustomerDevice,
764  device_manager: Manager,
765  description: SwitchEntityDescription,
766  ) -> None:
767  """Init TuyaHaSwitch."""
768  super().__init__(device, device_manager)
769  self.entity_descriptionentity_description = description
770  self._attr_unique_id_attr_unique_id_attr_unique_id = f"{super().unique_id}{description.key}"
771 
772  @property
773  def is_on(self) -> bool:
774  """Return true if switch is on."""
775  return self.devicedevice.status.get(self.entity_descriptionentity_description.key, False)
776 
777  def turn_on(self, **kwargs: Any) -> None:
778  """Turn the switch on."""
779  self._send_command_send_command([{"code": self.entity_descriptionentity_description.key, "value": True}])
780 
781  def turn_off(self, **kwargs: Any) -> None:
782  """Turn the switch off."""
783  self._send_command_send_command([{"code": self.entity_descriptionentity_description.key, "value": False}])
None _send_command(self, list[dict[str, Any]] commands)
Definition: entity.py:295
None __init__(self, CustomerDevice device, Manager device_manager, SwitchEntityDescription description)
Definition: switch.py:766
ElkSystem|None async_discover_device(HomeAssistant hass, str host)
Definition: discovery.py:78
None async_setup_entry(HomeAssistant hass, TuyaConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: switch.py:732
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)
Definition: dispatcher.py:103