mirror of
https://github.com/home-assistant/core.git
synced 2026-07-04 21:25:26 +01:00
158 lines
4.9 KiB
Python
158 lines
4.9 KiB
Python
"""Support for iTach IR devices."""
|
|
|
|
from collections.abc import Iterable
|
|
import logging
|
|
from typing import Any
|
|
|
|
import pyitachip2ir
|
|
import voluptuous as vol
|
|
|
|
from homeassistant.components import remote
|
|
from homeassistant.components.remote import (
|
|
ATTR_NUM_REPEATS,
|
|
DEFAULT_NUM_REPEATS,
|
|
PLATFORM_SCHEMA as REMOTE_PLATFORM_SCHEMA,
|
|
)
|
|
from homeassistant.const import (
|
|
CONF_DEVICES,
|
|
CONF_HOST,
|
|
CONF_MAC,
|
|
CONF_NAME,
|
|
CONF_PORT,
|
|
DEVICE_DEFAULT_NAME,
|
|
)
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers import config_validation as cv
|
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
DEFAULT_PORT = 4998
|
|
CONNECT_TIMEOUT = 5000
|
|
DEFAULT_MODADDR = 1
|
|
DEFAULT_CONNADDR = 1
|
|
DEFAULT_IR_COUNT = 1
|
|
|
|
CONF_MODADDR = "modaddr"
|
|
CONF_CONNADDR = "connaddr"
|
|
CONF_COMMANDS = "commands"
|
|
CONF_DATA = "data"
|
|
CONF_IR_COUNT = "ir_count"
|
|
|
|
EMPTY_COMMAND_PLACEHOLDER = '""'
|
|
|
|
PLATFORM_SCHEMA = REMOTE_PLATFORM_SCHEMA.extend(
|
|
{
|
|
vol.Optional(CONF_MAC): cv.string,
|
|
vol.Required(CONF_HOST): cv.string,
|
|
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
|
|
vol.Required(CONF_DEVICES): vol.All(
|
|
cv.ensure_list,
|
|
[
|
|
{
|
|
vol.Optional(CONF_NAME): cv.string,
|
|
vol.Optional(CONF_MODADDR): cv.positive_int,
|
|
vol.Required(CONF_CONNADDR): cv.positive_int,
|
|
vol.Optional(CONF_IR_COUNT): cv.positive_int,
|
|
vol.Required(CONF_COMMANDS): vol.All(
|
|
cv.ensure_list,
|
|
[
|
|
{
|
|
vol.Required(CONF_NAME): cv.string,
|
|
vol.Required(CONF_DATA): cv.string,
|
|
}
|
|
],
|
|
),
|
|
}
|
|
],
|
|
),
|
|
}
|
|
)
|
|
|
|
|
|
def _format_command_value(value: str) -> str:
|
|
"""Format a command name or command data value."""
|
|
value = value.strip()
|
|
return value or EMPTY_COMMAND_PLACEHOLDER
|
|
|
|
|
|
def _format_command_table(commands: Iterable[dict[str, str]]) -> str:
|
|
"""Format YAML commands for pyitachip2ir."""
|
|
return "".join(
|
|
f"{_format_command_value(command[CONF_NAME])}\n"
|
|
f"{_format_command_value(command[CONF_DATA])}\n"
|
|
for command in commands
|
|
)
|
|
|
|
|
|
def _setup_remote_entity(
|
|
itachip2ir: Any, device_config: dict[str, Any]
|
|
) -> ITachIP2IRRemote:
|
|
"""Create an iTach remote entity from YAML device config."""
|
|
name = device_config.get(CONF_NAME)
|
|
modaddr = int(device_config.get(CONF_MODADDR, DEFAULT_MODADDR))
|
|
connaddr = int(device_config.get(CONF_CONNADDR, DEFAULT_CONNADDR))
|
|
ir_count = int(device_config.get(CONF_IR_COUNT, DEFAULT_IR_COUNT))
|
|
command_table = _format_command_table(device_config[CONF_COMMANDS])
|
|
|
|
itachip2ir.addDevice(name, modaddr, connaddr, command_table)
|
|
return ITachIP2IRRemote(itachip2ir, name, ir_count)
|
|
|
|
|
|
def setup_platform(
|
|
hass: HomeAssistant,
|
|
config: ConfigType,
|
|
add_entities: AddEntitiesCallback,
|
|
discovery_info: DiscoveryInfoType | None = None,
|
|
) -> None:
|
|
"""Set up the ITach connection and devices."""
|
|
itachip2ir = pyitachip2ir.ITachIP2IR(
|
|
config.get(CONF_MAC), config[CONF_HOST], int(config[CONF_PORT])
|
|
)
|
|
|
|
if not itachip2ir.ready(CONNECT_TIMEOUT):
|
|
_LOGGER.error("Unable to find iTach")
|
|
return
|
|
|
|
devices = [
|
|
_setup_remote_entity(itachip2ir, device_config)
|
|
for device_config in config[CONF_DEVICES]
|
|
]
|
|
add_entities(devices, True)
|
|
|
|
|
|
class ITachIP2IRRemote(remote.RemoteEntity):
|
|
"""Device that sends commands to an ITachIP2IR device."""
|
|
|
|
def __init__(self, itachip2ir: Any, name: str | None, ir_count: int) -> None:
|
|
"""Initialize device."""
|
|
self.itachip2ir = itachip2ir
|
|
self._attr_is_on = False
|
|
self._attr_name = name or DEVICE_DEFAULT_NAME
|
|
self._ir_count = ir_count or DEFAULT_IR_COUNT
|
|
|
|
def turn_on(self, **kwargs: Any) -> None:
|
|
"""Turn the device on."""
|
|
self._attr_is_on = True
|
|
self.itachip2ir.send(self.name, "ON", self._ir_count)
|
|
self.schedule_update_ha_state()
|
|
|
|
def turn_off(self, **kwargs: Any) -> None:
|
|
"""Turn the device off."""
|
|
self._attr_is_on = False
|
|
self.itachip2ir.send(self.name, "OFF", self._ir_count)
|
|
self.schedule_update_ha_state()
|
|
|
|
def send_command(self, command: Iterable[str], **kwargs: Any) -> None:
|
|
"""Send a command to one device."""
|
|
num_repeats = kwargs.get(ATTR_NUM_REPEATS, DEFAULT_NUM_REPEATS)
|
|
for single_command in command:
|
|
self.itachip2ir.send(
|
|
self.name, single_command, self._ir_count * num_repeats
|
|
)
|
|
|
|
def update(self) -> None:
|
|
"""Update the device."""
|
|
self.itachip2ir.update()
|