mirror of
https://github.com/home-assistant/core.git
synced 2026-08-28 10:16:02 -05:00
116 lines
4.0 KiB
Python
116 lines
4.0 KiB
Python
"""Switch entities for the Fronius Modbus controls."""
|
|
|
|
from dataclasses import dataclass
|
|
from typing import TYPE_CHECKING, Any, Final, override
|
|
|
|
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
|
|
from homeassistant.const import EntityCategory, Platform
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
|
|
|
from .entity import FroniusEntity, FroniusEntityDescription, ModbusComponentFn
|
|
|
|
if TYPE_CHECKING:
|
|
from . import FroniusConfigEntry
|
|
from .coordinator import FroniusModbusSettingsUpdateCoordinator
|
|
|
|
# writes go to one device at a time
|
|
PARALLEL_UPDATES: Final = 1
|
|
|
|
|
|
@dataclass(frozen=True, kw_only=True)
|
|
class FroniusSwitchEntityDescription(FroniusEntityDescription, SwitchEntityDescription):
|
|
"""Describes a Fronius Modbus switch entity.
|
|
|
|
``field`` is the writable field of the model the control lives in.
|
|
"""
|
|
|
|
component_fn: ModbusComponentFn
|
|
field: str
|
|
|
|
|
|
MODBUS_SWITCH_ENTITY_DESCRIPTIONS: list[FroniusSwitchEntityDescription] = [
|
|
FroniusSwitchEntityDescription(
|
|
key="ac_power_limit_enabled",
|
|
component_fn=lambda inverter: inverter.controls,
|
|
field="enabled",
|
|
entity_category=EntityCategory.CONFIG,
|
|
),
|
|
FroniusSwitchEntityDescription(
|
|
key="battery_charge_power_limit_enabled",
|
|
component_fn=lambda inverter: inverter.storage,
|
|
field="charge_limit_enabled",
|
|
entity_category=EntityCategory.CONFIG,
|
|
),
|
|
FroniusSwitchEntityDescription(
|
|
key="battery_discharge_power_limit_enabled",
|
|
component_fn=lambda inverter: inverter.storage,
|
|
field="discharge_limit_enabled",
|
|
entity_category=EntityCategory.CONFIG,
|
|
),
|
|
FroniusSwitchEntityDescription(
|
|
key="battery_grid_charging",
|
|
component_fn=lambda inverter: inverter.storage,
|
|
field="grid_charging",
|
|
entity_category=EntityCategory.CONFIG,
|
|
),
|
|
]
|
|
|
|
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant,
|
|
config_entry: FroniusConfigEntry,
|
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
|
) -> None:
|
|
"""Set up Fronius switch entities based on a config entry."""
|
|
for coordinator in config_entry.runtime_data.modbus_settings_coordinators:
|
|
coordinator.add_entities_for_seen_keys(
|
|
async_add_entities, Platform.SWITCH, ModbusControlSwitch
|
|
)
|
|
|
|
|
|
class ModbusControlSwitch(FroniusEntity, SwitchEntity):
|
|
"""A control of an inverters Modbus interface that is on or off.
|
|
|
|
Turning a limit off doesn't lift it - it hands control back to the next
|
|
priority source, which may impose a limit of its own. To override such a
|
|
source, leave the limit on and set its setpoint to 100%.
|
|
"""
|
|
|
|
entity_description: FroniusSwitchEntityDescription
|
|
coordinator: FroniusModbusSettingsUpdateCoordinator
|
|
|
|
def __init__(
|
|
self,
|
|
coordinator: FroniusModbusSettingsUpdateCoordinator,
|
|
description: FroniusSwitchEntityDescription,
|
|
solar_net_id: str,
|
|
) -> None:
|
|
"""Set up an individual Fronius Modbus control switch."""
|
|
super().__init__(coordinator, description, solar_net_id)
|
|
self._attr_device_info = coordinator.inverter_info.device_info
|
|
self._attr_unique_id = (
|
|
f"{coordinator.inverter_info.unique_id}-modbus-{description.key}"
|
|
)
|
|
|
|
@property
|
|
@override
|
|
def is_on(self) -> bool | None:
|
|
"""Return whether the control is active as the device reports it."""
|
|
return self._device_data()[self.response_key]["value"] # type: ignore[no-any-return]
|
|
|
|
@override
|
|
async def async_turn_on(self, **kwargs: Any) -> None:
|
|
"""Activate the control."""
|
|
await self._async_write(True)
|
|
|
|
@override
|
|
async def async_turn_off(self, **kwargs: Any) -> None:
|
|
"""Deactivate the control."""
|
|
await self._async_write(False)
|
|
|
|
async def _async_write(self, value: bool) -> None:
|
|
await self.coordinator.async_write(
|
|
self.entity_description.component_fn, self.entity_description.field, value
|
|
)
|