Files
core/homeassistant/components/onewire/switch.py
T

221 lines
6.9 KiB
Python

"""Support for 1-Wire environment switches."""
from datetime import timedelta
import os
from typing import Any, override
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .const import DEVICE_KEYS_0_3, DEVICE_KEYS_0_7, DEVICE_KEYS_A_B
from .entity import OneWireEntity
from .onewirehub import (
SIGNAL_NEW_DEVICE_CONNECTED,
OneWireConfigEntry,
OneWireHub,
OWDeviceDescription,
)
# the library uses non-persistent connections
# and concurrent access to the bus is managed by the server
PARALLEL_UPDATES = 0
SCAN_INTERVAL = timedelta(seconds=30)
DEVICE_SWITCHES: dict[str, tuple[SwitchEntityDescription, ...]] = {
"05": (
SwitchEntityDescription(
key="PIO",
entity_registry_enabled_default=False,
translation_key="pio",
),
),
"12": tuple(
[
SwitchEntityDescription(
key=f"PIO.{device_key}",
entity_registry_enabled_default=False,
translation_key="pio_id",
translation_placeholders={"id": str(device_key)},
)
for device_key in DEVICE_KEYS_A_B
]
+ [
SwitchEntityDescription(
key=f"latch.{device_key}",
entity_registry_enabled_default=False,
translation_key="latch_id",
translation_placeholders={"id": str(device_key)},
)
for device_key in DEVICE_KEYS_A_B
]
),
"26": (
SwitchEntityDescription(
key="IAD",
entity_registry_enabled_default=False,
entity_category=EntityCategory.CONFIG,
translation_key="iad",
),
),
"29": tuple(
[
SwitchEntityDescription(
key=f"PIO.{device_key}",
entity_registry_enabled_default=False,
translation_key="pio_id",
translation_placeholders={"id": str(device_key)},
)
for device_key in DEVICE_KEYS_0_7
]
+ [
SwitchEntityDescription(
key=f"latch.{device_key}",
entity_registry_enabled_default=False,
translation_key="latch_id",
translation_placeholders={"id": str(device_key)},
)
for device_key in DEVICE_KEYS_0_7
]
),
"3A": tuple(
SwitchEntityDescription(
key=f"PIO.{device_key}",
entity_registry_enabled_default=False,
translation_key="pio_id",
translation_placeholders={"id": str(device_key)},
)
for device_key in DEVICE_KEYS_A_B
),
"EF": (), # "HobbyBoard": special
}
# EF sensors are usually hobbyboards specialized sensors.
HOBBYBOARD_EF: dict[str, tuple[SwitchEntityDescription, ...]] = {
"HB_HUB": tuple(
SwitchEntityDescription(
key=f"hub/branch.{device_key}",
entity_registry_enabled_default=False,
entity_category=EntityCategory.CONFIG,
translation_key="hub_branch_id",
translation_placeholders={"id": str(device_key)},
)
for device_key in DEVICE_KEYS_0_3
),
"HB_MOISTURE_METER": tuple(
[
SwitchEntityDescription(
key=f"moisture/is_leaf.{device_key}",
entity_registry_enabled_default=False,
entity_category=EntityCategory.CONFIG,
translation_key="leaf_sensor_id",
translation_placeholders={"id": str(device_key)},
)
for device_key in DEVICE_KEYS_0_3
]
+ [
SwitchEntityDescription(
key=f"moisture/is_moisture.{device_key}",
entity_registry_enabled_default=False,
entity_category=EntityCategory.CONFIG,
translation_key="moisture_sensor_id",
translation_placeholders={"id": str(device_key)},
)
for device_key in DEVICE_KEYS_0_3
]
),
}
def get_sensor_types(
device_sub_type: str,
) -> dict[str, tuple[SwitchEntityDescription, ...]]:
"""Return the proper info array for the device type."""
if "HobbyBoard" in device_sub_type:
return HOBBYBOARD_EF
return DEVICE_SWITCHES
async def async_setup_entry(
hass: HomeAssistant,
config_entry: OneWireConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up 1-Wire platform."""
async def _add_entities(
hub: OneWireHub, devices: list[OWDeviceDescription]
) -> None:
"""Add 1-Wire entities for all devices."""
if not devices:
return
async_add_entities(get_entities(hub, devices), True)
hub = config_entry.runtime_data
await _add_entities(hub, hub.devices)
config_entry.async_on_unload(
async_dispatcher_connect(hass, SIGNAL_NEW_DEVICE_CONNECTED, _add_entities)
)
def get_entities(
onewire_hub: OneWireHub, devices: list[OWDeviceDescription]
) -> list[OneWireSwitchEntity]:
"""Get a list of entities."""
entities: list[OneWireSwitchEntity] = []
for device in devices:
family = device.family
device_type = device.type
device_id = device.id
device_info = device.device_info
device_sub_type = "std"
if device_type and "EF" in family:
device_sub_type = "HobbyBoard"
family = device_type
elif "A6" in family:
# A6 is a secondary family code for DS2438
family = "26"
if family not in get_sensor_types(device_sub_type):
continue
for description in get_sensor_types(device_sub_type)[family]:
device_file = os.path.join(os.path.split(device.path)[0], description.key)
entities.append(
OneWireSwitchEntity(
description=description,
device_id=device_id,
device_file=device_file,
device_info=device_info,
owproxy=onewire_hub.owproxy,
)
)
return entities
class OneWireSwitchEntity(OneWireEntity, SwitchEntity):
"""Implementation of a 1-Wire switch."""
@property
@override
def is_on(self) -> bool | None:
"""Return true if switch is on."""
if (state := self._state) is None:
return None
return state == "1"
@override
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the entity on."""
await self._write_value(b"1")
@override
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the entity off."""
await self._write_value(b"0")