services.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. """Services for Tuya Local integration."""
  2. import asyncio
  3. import logging
  4. import voluptuous as vol
  5. from homeassistant.components import infrared
  6. from homeassistant.components.remote import (
  7. ATTR_DELAY_SECS,
  8. DEFAULT_DELAY_SECS,
  9. )
  10. from homeassistant.components.remote import DOMAIN as REMOTE_DOMAIN
  11. from homeassistant.core import HomeAssistant, ServiceCall
  12. from homeassistant.helpers import service
  13. from .const import DOMAIN
  14. from .infrared import TuyaRemoteCommand
  15. from .remote import TuyaLocalRemote
  16. REMOTE_SEND_IR_COMMAND_SCHEMA = vol.Schema(
  17. {
  18. vol.Required("emitter_entity_id"): str,
  19. vol.Required("code"): str,
  20. vol.Optional("device"): str,
  21. }
  22. )
  23. _LOGGER = logging.getLogger(__name__)
  24. async def async_setup_services(hass: HomeAssistant, entities: list[str]):
  25. """Set up services for the Tuya Local integration."""
  26. if "remote" in entities:
  27. service.async_register_platform_entity_service(
  28. hass,
  29. DOMAIN,
  30. "send_learned_ir_command",
  31. entity_domain=REMOTE_DOMAIN,
  32. schema=REMOTE_SEND_IR_COMMAND_SCHEMA,
  33. func=async_handle_send_ir_command,
  34. )
  35. return True
  36. async def async_handle_send_ir_command(entity, call: ServiceCall):
  37. """Action to send a saved remote command."""
  38. _LOGGER.info("Sending saved remote command: %s", call.data)
  39. if not isinstance(entity, TuyaLocalRemote):
  40. raise ValueError("Entity must be a tuya-local remote")
  41. if not entity._storage_loaded:
  42. await entity._async_load_storage()
  43. emitter = call.data.get("emitter")
  44. device = call.data.get("device")
  45. command = call.data.get("command")
  46. delay = call.data.get(ATTR_DELAY_SECS, DEFAULT_DELAY_SECS)
  47. code_list = entity._extract_codes(
  48. [command], subdevice=device
  49. ) # Validate command and get code
  50. at_least_one_sent = False
  51. for _, codes in code_list:
  52. if at_least_one_sent:
  53. await asyncio.sleep(delay)
  54. if len(codes) > 1:
  55. code = codes[entity._flags[device]]
  56. entity._flags[device] ^= 1
  57. else:
  58. code = codes[0]
  59. if code.startswith("rf:"):
  60. _LOGGER.error("RF emitters are not yet supported by this service")
  61. continue
  62. await infrared.async_send_command(
  63. entity.hass, emitter, cmd=TuyaRemoteCommand(code=code)
  64. )
  65. at_least_one_sent = True