143 lines
5.5 KiB
Python
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
|