Files
homeassistant_config/config/custom_components/ecoflow/binary_sensor.py
2024-08-26 13:38:09 +02:00

143 lines
5.5 KiB
Python

from typing import Any
import reactivex.operators as ops
from homeassistant.components.binary_sensor import (BinarySensorDeviceClass,
BinarySensorEntity)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import (DOMAIN, EcoFlowBaseEntity, EcoFlowEntity, HassioEcoFlowClient,
select_bms)
from .ecoflow import is_delta, is_power_station, is_river
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback):
client: HassioEcoFlowClient = hass.data[DOMAIN][entry.entry_id]
entities = []
if is_power_station(client.product):
entities.extend([
ChargingEntity(client),
MainErrorEntity(client),
])
if is_delta(client.product):
entities.extend([
ExtraErrorEntity(client, client.bms.pipe(select_bms(
1), ops.share()), "battery_error", "Extra1 status", 1),
ExtraErrorEntity(client, client.bms.pipe(select_bms(
2), ops.share()), "battery_error", "Extra2 status", 2),
InputEntity(client, client.inverter, "ac_in_type", "AC input"),
InputEntity(client, client.mppt, "dc_in_state", "DC input"),
CustomChargeEntity(client, client.inverter,
"ac_in_limit_switch", "AC custom charge speed"),
])
if is_river(client.product):
entities.extend([
ExtraErrorEntity(client, client.bms.pipe(select_bms(
1), ops.share()), "battery_error", "Extra status", 1),
InputEntity(client, client.inverter, "in_type", "Input"),
])
async_add_entities(entities)
class BaseEntity(BinarySensorEntity, EcoFlowEntity):
def _on_updated(self, data: dict[str, Any]):
self._attr_is_on = bool(data[self._key])
class ChargingEntity(BinarySensorEntity, EcoFlowBaseEntity):
_attr_device_class = BinarySensorDeviceClass.BATTERY_CHARGING
_battery_level = None
_battery_level_max = None
_in_power = None
_out_power = None
def __init__(self, client: HassioEcoFlowClient):
super().__init__(client)
self._attr_name = "Charging"
self._attr_unique_id += "-in-charging"
async def async_added_to_hass(self):
await super().async_added_to_hass()
self._subscribe(self._client.pd, self.__updated)
self._subscribe(self._client.ems, self.__updated)
def __updated(self, data: dict[str, Any]):
self._attr_available = True
self._on_updated(data)
self.async_write_ha_state()
def _on_updated(self, data: dict[str, Any]):
if "in_power" in data:
self._in_power = data["in_power"]
if "out_power" in data:
self._out_power = data["out_power"]
if "battery_level" in data:
self._battery_level = data["battery_level"]
if "battery_level_max" in data:
self._battery_level_max = data["battery_level_max"]
if not self._in_power:
self._attr_is_on = False
elif (self._battery_level is not None) and (self._battery_level_max is not None) and (self._battery_level_max < self._battery_level):
self._attr_is_on = False
elif (self._in_power is not None) and (self._out_power is not None) and (self._in_power <= self._out_power):
self._attr_is_on = False
else:
self._attr_is_on = True
class CustomChargeEntity(BaseEntity):
_attr_entity_category = EntityCategory.CONFIG
def _on_updated(self, data: dict[str, Any]):
self._attr_is_on = data[self._key] == 2
class ExtraErrorEntity(BaseEntity):
_attr_device_class = BinarySensorDeviceClass.PROBLEM
def _on_updated(self, data: dict[str, Any]):
self._attr_is_on = data[self._key] not in [0, 6]
self._attr_extra_state_attributes = {"code": data[self._key]}
class MainErrorEntity(BinarySensorEntity, EcoFlowBaseEntity):
_attr_device_class = BinarySensorDeviceClass.PROBLEM
def __init__(self, client: HassioEcoFlowClient):
super().__init__(client)
self._attr_name = "Main status"
self._attr_unique_id += "-error"
self._attr_extra_state_attributes = {}
@property
def is_on(self):
return next((True for x in self._attr_extra_state_attributes.values() if x not in [0, 6]), False)
async def async_added_to_hass(self):
await super().async_added_to_hass()
self._subscribe(self._client.pd, self.__updated)
self._subscribe(self._client.ems, self.__updated)
self._subscribe(self._client.inverter, self.__updated)
self._subscribe(self._client.mppt, self.__updated)
def __updated(self, data: dict[str, Any]):
self._attr_available = True
if "ac_error" in data:
self._attr_extra_state_attributes["ac"] = data["ac_error"]
if "battery_main_error" in data:
self._attr_extra_state_attributes["battery"] = data["battery_main_error"]
if "dc_in_error" in data:
self._attr_extra_state_attributes["dc"] = data["dc_in_error"]
if "pd_error" in data:
self._attr_extra_state_attributes["system"] = data["pd_error"]
self.async_write_ha_state()
class InputEntity(BaseEntity):
_attr_device_class = BinarySensorDeviceClass.POWER