Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Review battery level in all devices #144

Merged
merged 2 commits into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 33 additions & 5 deletions custom_components/ecoflow_cloud/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er


from .config.const import CONF_DEVICE_TYPE, CONF_USERNAME, CONF_PASSWORD, OPTS_POWER_STEP, OPTS_REFRESH_PERIOD_SEC, \
DEFAULT_REFRESH_PERIOD_SEC
DEFAULT_REFRESH_PERIOD_SEC, CONF_DEVICE_ID
from .mqtt.ecoflow_mqtt import EcoflowMQTTClient, EcoflowAuthentication

_LOGGER = logging.getLogger(__name__)

DOMAIN = "ecoflow_cloud"
CONFIG_VERSION = 3

_PLATFORMS = {
Platform.NUMBER,
Expand All @@ -30,17 +33,42 @@
async def async_migrate_entry(hass, config_entry: ConfigEntry):
"""Migrate old entry."""
if config_entry.version == 1:
from .devices.registry import devices
device = devices[config_entry.data[CONF_DEVICE_TYPE]]
from .devices.registry import devices as device_registry
device = device_registry[config_entry.data[CONF_DEVICE_TYPE]]

new_data = {**config_entry.data}
new_options = {OPTS_POWER_STEP: device.charging_power_step(),
OPTS_REFRESH_PERIOD_SEC: DEFAULT_REFRESH_PERIOD_SEC}

config_entry.version = 2
hass.config_entries.async_update_entry(config_entry, data=new_data, options=new_options)

_LOGGER.info("Migration to version %s successful", config_entry.version)
_LOGGER.info("Migration to version %s successful", config_entry.version)

if config_entry.version < CONFIG_VERSION:
from .devices.registry import devices as device_registry
from .entities import EcoFlowAbstractEntity
from .devices import EntityMigration, MigrationAction

device = device_registry[config_entry.data[CONF_DEVICE_TYPE]]
device_sn = config_entry.data[CONF_DEVICE_ID]
entity_registry = er.async_get(hass)

for v in (config_entry.version, CONFIG_VERSION):
migrations: list[EntityMigration] = device.migrate(v)
for m in migrations:
if m.action == MigrationAction.REMOVE:
entity_id = entity_registry.async_get_entity_id(
domain=m.domain,
platform=DOMAIN,
unique_id=EcoFlowAbstractEntity.gen_unique_id(sn=device_sn, key=m.key))

if entity_id:
_LOGGER.info(".... removing entity_id = %s", entity_id)
entity_registry.async_remove(entity_id)

config_entry.version = CONFIG_VERSION
hass.config_entries.async_update_entry(config_entry)
_LOGGER.info("Migration to version %s successful", config_entry.version)

return True

Expand Down
4 changes: 2 additions & 2 deletions custom_components/ecoflow_cloud/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
from homeassistant.data_entry_flow import FlowResult
from homeassistant.helpers import selector

from . import DOMAIN
from . import DOMAIN, CONFIG_VERSION
from .config.const import EcoflowModel, CONF_USERNAME, CONF_PASSWORD, CONF_DEVICE_TYPE, CONF_DEVICE_NAME, \
CONF_DEVICE_ID, OPTS_POWER_STEP, OPTS_REFRESH_PERIOD_SEC, DEFAULT_REFRESH_PERIOD_SEC

_LOGGER = logging.getLogger(__name__)


class EcoflowConfigFlow(ConfigFlow, domain=DOMAIN):
VERSION = 2
VERSION = CONFIG_VERSION

async def async_step_user(self, user_input: dict[str, Any] | None = None):
errors: Dict[str, str] = {}
Expand Down
21 changes: 18 additions & 3 deletions custom_components/ecoflow_cloud/devices/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
from abc import ABC, abstractmethod
from enum import StrEnum

from homeassistant.components.number import NumberEntity
from homeassistant.components.select import SelectEntity
from homeassistant.components.sensor import SensorEntity
from homeassistant.components.switch import SwitchEntity
from homeassistant.const import Platform

from ..mqtt.ecoflow_mqtt import EcoflowMQTTClient
from ..entities import BaseNumberEntity, BaseSelectEntity
from ..entities import BaseSensorEntity
from ..entities import BaseSwitchEntity


class MigrationAction(StrEnum):
REMOVE = "remove"


class EntityMigration:

def __init__(self, key: str, domain: Platform, action: MigrationAction, **kwargs):
self.key = key
self.domain = domain
self.action = action
self.args = kwargs


class BaseDevice(ABC):
Expand All @@ -32,6 +44,9 @@ def switches(self, client: EcoflowMQTTClient) -> list[SwitchEntity]:
def selects(self, client: EcoflowMQTTClient) -> list[SelectEntity]:
pass

def migrate(self, version) -> list[EntityMigration]:
return []


class DiagnosticDevice(BaseDevice):

Expand Down
15 changes: 12 additions & 3 deletions custom_components/ecoflow_cloud/devices/delta2.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from . import const, BaseDevice
from homeassistant.const import Platform

from . import const, BaseDevice, EntityMigration, MigrationAction
from .const import ATTR_DESIGN_CAPACITY, ATTR_FULL_CAPACITY, ATTR_REMAIN_CAPACITY
from .. import EcoflowMQTTClient
from ..entities import BaseSensorEntity, BaseNumberEntity, BaseSwitchEntity, BaseSelectEntity
from ..entities import BaseSensorEntity, BaseNumberEntity, BaseSwitchEntity, BaseSelectEntity, EcoFlowAbstractEntity
from ..number import ChargingPowerEntity, MinBatteryLevelEntity, MaxBatteryLevelEntity, \
MaxGenStopLevelEntity, MinGenStartLevelEntity, BatteryBackupLevel
from ..select import DictSelectEntity, TimeoutDictSelectEntity
Expand All @@ -14,7 +16,7 @@
class Delta2(BaseDevice):
def sensors(self, client: EcoflowMQTTClient) -> list[BaseSensorEntity]:
return [
LevelSensorEntity(client, "pd.soc", const.MAIN_BATTERY_LEVEL)
LevelSensorEntity(client, "bms_bmsStatus.soc", const.MAIN_BATTERY_LEVEL)
.attr("bms_bmsStatus.designCap", ATTR_DESIGN_CAPACITY, 0)
.attr("bms_bmsStatus.fullCap", ATTR_FULL_CAPACITY, 0)
.attr("bms_bmsStatus.remainCap", ATTR_REMAIN_CAPACITY, 0),
Expand Down Expand Up @@ -170,3 +172,10 @@ def selects(self, client: EcoflowMQTTClient) -> list[BaseSelectEntity]:
"params": {"standbyMins": value}})

]

def migrate(self, version) -> list[EntityMigration]:
if version == 2:
return [
EntityMigration("pd.soc", Platform.SENSOR, MigrationAction.REMOVE)
]
return []
18 changes: 15 additions & 3 deletions custom_components/ecoflow_cloud/devices/delta2_max.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from . import const, BaseDevice
from homeassistant.const import Platform

from . import const, BaseDevice, EntityMigration, MigrationAction
from .const import ATTR_DESIGN_CAPACITY, ATTR_FULL_CAPACITY, ATTR_REMAIN_CAPACITY
from .. import EcoflowMQTTClient
from ..entities import BaseSensorEntity, BaseNumberEntity, BaseSwitchEntity, BaseSelectEntity
Expand All @@ -14,11 +16,13 @@
class Delta2Max(BaseDevice):
def sensors(self, client: EcoflowMQTTClient) -> list[BaseSensorEntity]:
return [
LevelSensorEntity(client, "pd.soc", const.MAIN_BATTERY_LEVEL)
LevelSensorEntity(client, "bms_bmsStatus.soc", const.MAIN_BATTERY_LEVEL)
.attr("bms_bmsStatus.designCap", ATTR_DESIGN_CAPACITY, 0)
.attr("bms_bmsStatus.fullCap", ATTR_FULL_CAPACITY, 0)
.attr("bms_bmsStatus.remainCap", ATTR_REMAIN_CAPACITY, 0),
LevelSensorEntity(client, "bms_emsStatus.f32LcdShowSoc", const.COMBINED_BATTERY_LEVEL),

LevelSensorEntity(client, "bms_emsStatus.lcdShowSoc", const.COMBINED_BATTERY_LEVEL),

InWattsSensorEntity(client, "pd.wattsInSum", const.TOTAL_IN_POWER),
OutWattsSensorEntity(client, "pd.wattsOutSum", const.TOTAL_OUT_POWER),

Expand Down Expand Up @@ -149,3 +153,11 @@ def selects(self, client: EcoflowMQTTClient) -> list[BaseSelectEntity]:
"moduleSn": client.device_sn,
"params": {"standbyMins": value}}),
]

def migrate(self, version) -> list[EntityMigration]:
if version == 2:
return [
EntityMigration("pd.soc", Platform.SENSOR, MigrationAction.REMOVE),
EntityMigration("bms_emsStatus.f32LcdShowSoc", Platform.SENSOR, MigrationAction.REMOVE)
]
return []
16 changes: 12 additions & 4 deletions custom_components/ecoflow_cloud/devices/delta_max.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
from . import const, BaseDevice
from homeassistant.const import Platform

from . import const, BaseDevice, EntityMigration, MigrationAction
from .const import ATTR_DESIGN_CAPACITY, ATTR_FULL_CAPACITY, ATTR_REMAIN_CAPACITY
from .. import EcoflowMQTTClient
from ..entities import BaseSensorEntity, BaseNumberEntity, BaseSwitchEntity, BaseSelectEntity
from ..number import ChargingPowerEntity, MinBatteryLevelEntity, MaxBatteryLevelEntity, \
MaxGenStopLevelEntity, MinGenStartLevelEntity
from ..select import DictSelectEntity, TimeoutDictSelectEntity
from ..sensor import LevelSensorEntity, RemainSensorEntity, TempSensorEntity, CyclesSensorEntity, \
InWattsSensorEntity, OutWattsSensorEntity, VoltSensorEntity, StatusSensorEntity, MilliVoltSensorEntity, \
InWattsSensorEntity, OutWattsSensorEntity, StatusSensorEntity, MilliVoltSensorEntity, \
InMilliVoltSensorEntity, OutMilliVoltSensorEntity
from ..switch import BeeperEntity, EnabledEntity


class DeltaMax(BaseDevice):
def sensors(self, client: EcoflowMQTTClient) -> list[BaseSensorEntity]:
return [
LevelSensorEntity(client, "pd.soc", const.MAIN_BATTERY_LEVEL)
LevelSensorEntity(client, "bmsMaster.soc", const.MAIN_BATTERY_LEVEL)
.attr("bmsMaster.designCap", ATTR_DESIGN_CAPACITY, 0)
.attr("bmsMaster.fullCap", ATTR_FULL_CAPACITY, 0)
.attr("bmsMaster.remainCap", ATTR_REMAIN_CAPACITY, 0),
Expand Down Expand Up @@ -146,3 +147,10 @@ def selects(self, client: EcoflowMQTTClient) -> list[BaseSelectEntity]:
# "params": {"standbyMins": value}})

]

def migrate(self, version) -> list[EntityMigration]:
if version == 2:
return [
EntityMigration("pd.soc", Platform.SENSOR, MigrationAction.REMOVE),
]
return []
15 changes: 13 additions & 2 deletions custom_components/ecoflow_cloud/devices/delta_mini.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from . import const, BaseDevice
from homeassistant.const import Platform

from . import const, BaseDevice, EntityMigration, MigrationAction
from .const import ATTR_DESIGN_CAPACITY, ATTR_FULL_CAPACITY, ATTR_REMAIN_CAPACITY
from ..entities import BaseSensorEntity, BaseNumberEntity, BaseSwitchEntity, BaseSelectEntity
from ..mqtt.ecoflow_mqtt import EcoflowMQTTClient
Expand All @@ -16,10 +18,12 @@
class DeltaMini(BaseDevice):
def sensors(self, client: EcoflowMQTTClient) -> list[BaseSensorEntity]:
return [
LevelSensorEntity(client, "pd.soc", const.MAIN_BATTERY_LEVEL)
LevelSensorEntity(client, "bmsMaster.soc", const.MAIN_BATTERY_LEVEL)
.attr("bmsMaster.designCap", ATTR_DESIGN_CAPACITY, 0)
.attr("bmsMaster.fullCap", ATTR_FULL_CAPACITY, 0)
.attr("bmsMaster.remainCap", ATTR_REMAIN_CAPACITY, 0),
LevelSensorEntity(client, "ems.lcdShowSoc", const.COMBINED_BATTERY_LEVEL),

WattsSensorEntity(client, "pd.wattsInSum", const.TOTAL_IN_POWER),
WattsSensorEntity(client, "pd.wattsOutSum", const.TOTAL_OUT_POWER),

Expand Down Expand Up @@ -132,3 +136,10 @@ def selects(self, client: EcoflowMQTTClient) -> list[BaseSelectEntity]:
"params": {"standByMins": value, "id": 153}}),

]

def migrate(self, version) -> list[EntityMigration]:
if version == 2:
return [
EntityMigration("pd.soc", Platform.SENSOR, MigrationAction.REMOVE),
]
return []
17 changes: 14 additions & 3 deletions custom_components/ecoflow_cloud/devices/delta_pro.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from . import const, BaseDevice
from homeassistant.const import Platform

from . import const, BaseDevice, EntityMigration, MigrationAction
from .const import ATTR_DESIGN_CAPACITY, ATTR_FULL_CAPACITY, ATTR_REMAIN_CAPACITY
from ..entities import BaseSensorEntity, BaseNumberEntity, BaseSwitchEntity, BaseSelectEntity
from ..mqtt.ecoflow_mqtt import EcoflowMQTTClient
Expand All @@ -16,10 +18,12 @@
class DeltaPro(BaseDevice):
def sensors(self, client: EcoflowMQTTClient) -> list[BaseSensorEntity]:
return [
LevelSensorEntity(client, "pd.soc", const.MAIN_BATTERY_LEVEL)
LevelSensorEntity(client, "bmsMaster.soc", const.MAIN_BATTERY_LEVEL)
.attr("bmsMaster.designCap", ATTR_DESIGN_CAPACITY, 0)
.attr("bmsMaster.fullCap", ATTR_FULL_CAPACITY, 0)
.attr("bmsMaster.remainCap", ATTR_REMAIN_CAPACITY, 0),
LevelSensorEntity(client, "ems.lcdShowSoc", const.COMBINED_BATTERY_LEVEL),

WattsSensorEntity(client, "pd.wattsInSum", const.TOTAL_IN_POWER),
WattsSensorEntity(client, "pd.wattsOutSum", const.TOTAL_OUT_POWER),

Expand Down Expand Up @@ -127,7 +131,7 @@ def switches(self, client: EcoflowMQTTClient) -> list[BaseSwitchEntity]:
lambda value: {"moduleType": 0, "operateType": "TCP", "params": {"id": 95, "acautooutConfig": value}}),
EnabledEntity(client, "pd.bppowerSoc", const.BP_ENABLED,
lambda value, params: {"moduleType": 0, "operateType": "TCP", "params": {"id": 94, "isConfig": value,
"bpPowerSoc": int(params["pd.bppowerSoc"]),
"bpPowerSoc": int(params.get("pd.bppowerSoc", 0)),
"minDsgSoc": 0,
"maxChgSoc": 0}}),
]
Expand All @@ -151,3 +155,10 @@ def selects(self, client: EcoflowMQTTClient) -> list[BaseSelectEntity]:
"params": {"standByMins": value, "id": 153}}),

]

def migrate(self, version) -> list[EntityMigration]:
if version == 2:
return [
EntityMigration("pd.soc", Platform.SENSOR, MigrationAction.REMOVE),
]
return []
15 changes: 13 additions & 2 deletions custom_components/ecoflow_cloud/devices/river2.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from . import const, BaseDevice
from homeassistant.const import Platform

from . import const, BaseDevice, EntityMigration, MigrationAction
from .const import ATTR_DESIGN_CAPACITY, ATTR_FULL_CAPACITY, ATTR_REMAIN_CAPACITY, BATTERY_CHARGING_STATE
from ..entities import BaseSensorEntity, BaseNumberEntity, BaseSwitchEntity, BaseSelectEntity
from ..mqtt.ecoflow_mqtt import EcoflowMQTTClient
Expand All @@ -16,11 +18,13 @@ def charging_power_step(self) -> int:

def sensors(self, client: EcoflowMQTTClient) -> list[BaseSensorEntity]:
return [
LevelSensorEntity(client, "pd.soc", const.MAIN_BATTERY_LEVEL)
LevelSensorEntity(client, "bms_bmsStatus.soc", const.MAIN_BATTERY_LEVEL)
.attr("bms_bmsStatus.designCap", ATTR_DESIGN_CAPACITY, 0)
.attr("bms_bmsStatus.fullCap", ATTR_FULL_CAPACITY, 0)
.attr("bms_bmsStatus.remainCap", ATTR_REMAIN_CAPACITY, 0),

LevelSensorEntity(client, "bms_emsStatus.lcdShowSoc", const.COMBINED_BATTERY_LEVEL),

ChargingBinarySensorEntity(client, "bms_emsStatus.chgState", BATTERY_CHARGING_STATE),

InWattsSensorEntity(client, "pd.wattsInSum", const.TOTAL_IN_POWER),
Expand Down Expand Up @@ -113,3 +117,10 @@ def selects(self, client: EcoflowMQTTClient) -> list[BaseSelectEntity]:
lambda value: {"moduleType": 5, "operateType": "acStandby",
"params": {"standbyMins": value}})
]

def migrate(self, version) -> list[EntityMigration]:
if version == 2:
return [
EntityMigration("pd.soc", Platform.SENSOR, MigrationAction.REMOVE),
]
return []
15 changes: 13 additions & 2 deletions custom_components/ecoflow_cloud/devices/river2_max.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from . import const, BaseDevice
from homeassistant.const import Platform

from . import const, BaseDevice, EntityMigration, MigrationAction
from .const import ATTR_DESIGN_CAPACITY, ATTR_FULL_CAPACITY, ATTR_REMAIN_CAPACITY, BATTERY_CHARGING_STATE
from ..entities import BaseSensorEntity, BaseNumberEntity, BaseSwitchEntity, BaseSelectEntity
from ..mqtt.ecoflow_mqtt import EcoflowMQTTClient
Expand All @@ -18,11 +20,13 @@ def charging_power_step(self) -> int:

def sensors(self, client: EcoflowMQTTClient) -> list[BaseSensorEntity]:
return [
LevelSensorEntity(client, "pd.soc", const.MAIN_BATTERY_LEVEL)
LevelSensorEntity(client, "bms_bmsStatus.soc", const.MAIN_BATTERY_LEVEL)
.attr("bms_bmsStatus.designCap", ATTR_DESIGN_CAPACITY, 0)
.attr("bms_bmsStatus.fullCap", ATTR_FULL_CAPACITY, 0)
.attr("bms_bmsStatus.remainCap", ATTR_REMAIN_CAPACITY, 0),

LevelSensorEntity(client, "bms_emsStatus.lcdShowSoc", const.COMBINED_BATTERY_LEVEL),

ChargingBinarySensorEntity(client, "bms_emsStatus.chgState", BATTERY_CHARGING_STATE),

InWattsSensorEntity(client, "pd.wattsInSum", const.TOTAL_IN_POWER),
Expand Down Expand Up @@ -140,3 +144,10 @@ def selects(self, client: EcoflowMQTTClient) -> list[BaseSelectEntity]:
lambda value: {"moduleType": 5, "operateType": "acStandby",
"params": {"standbyMins": value}})
]

def migrate(self, version) -> list[EntityMigration]:
if version == 2:
return [
EntityMigration("pd.soc", Platform.SENSOR, MigrationAction.REMOVE),
]
return []
Loading
Loading