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

Added Glacier Support #182

Merged
merged 1 commit into from
Jan 6, 2024
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
2 changes: 2 additions & 0 deletions custom_components/ecoflow_cloud/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
Platform.SELECT,
Platform.SENSOR,
Platform.SWITCH,
Platform.BUTTON,

}

ATTR_STATUS_SN = "SN"
Expand Down
34 changes: 34 additions & 0 deletions custom_components/ecoflow_cloud/button.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import logging
from typing import Any

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
from .entities import BaseButtonEntity
from .mqtt.ecoflow_mqtt import EcoflowMQTTClient

_LOGGER = logging.getLogger(__name__)


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback):
client: EcoflowMQTTClient = hass.data[DOMAIN][entry.entry_id]

from .devices.registry import devices
async_add_entities(devices[client.device_type].buttons(client))


class EnabledButtonEntity(BaseButtonEntity):

def press(self, **kwargs: Any) -> None:
if self._command:
self.send_set_message(0, self.command_dict(0))

class DisabledButtonEntity(BaseButtonEntity):

async def async_press(self, **kwargs: Any) -> None:
if self._command:
self.send_set_message(0, self.command_dict(0))

1 change: 1 addition & 0 deletions custom_components/ecoflow_cloud/config/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class EcoflowModel(Enum):
DELTA_2_MAX = 9,
DELTA_MINI = 15, # productType = 15
POWERSTREAM = 51,
GLACIER = 46,
DIAGNOSTIC = 99

@classmethod
Expand Down
8 changes: 8 additions & 0 deletions custom_components/ecoflow_cloud/devices/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from homeassistant.components.select import SelectEntity
from homeassistant.components.sensor import SensorEntity
from homeassistant.components.switch import SwitchEntity
from homeassistant.components.button import ButtonEntity
from homeassistant.const import Platform

from ..mqtt.ecoflow_mqtt import EcoflowMQTTClient
Expand Down Expand Up @@ -40,6 +41,10 @@ def numbers(self, client: EcoflowMQTTClient) -> list[NumberEntity]:
def switches(self, client: EcoflowMQTTClient) -> list[SwitchEntity]:
pass

@abstractmethod
def buttons(self, client: EcoflowMQTTClient) -> list[ButtonEntity]:
pass

@abstractmethod
def selects(self, client: EcoflowMQTTClient) -> list[SelectEntity]:
pass
Expand All @@ -59,5 +64,8 @@ def numbers(self, client: EcoflowMQTTClient) -> list[NumberEntity]:
def switches(self, client: EcoflowMQTTClient) -> list[SwitchEntity]:
return []

def buttons(self, client: EcoflowMQTTClient) -> list[ButtonEntity]:
return []

def selects(self, client: EcoflowMQTTClient) -> list[SelectEntity]:
return []
4 changes: 4 additions & 0 deletions custom_components/ecoflow_cloud/devices/delta2.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ def switches(self, client: EcoflowMQTTClient) -> list[BaseSwitchEntity]:
"isConfig": value,
"minDsgSoc": 0}}),
]

def buttons(self, client: EcoflowMQTTClient) -> list[BaseSwitchEntity]:
return [
]

def selects(self, client: EcoflowMQTTClient) -> list[BaseSelectEntity]:
return [
Expand Down
4 changes: 4 additions & 0 deletions custom_components/ecoflow_cloud/devices/delta2_max.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ def switches(self, client: EcoflowMQTTClient) -> list[BaseSwitchEntity]:
"moduleSn": client.device_sn,
"params": {"xboost": value}})
]

def buttons(self, client: EcoflowMQTTClient) -> list[BaseSwitchEntity]:
return [
]

def selects(self, client: EcoflowMQTTClient) -> list[BaseSelectEntity]:
return [
Expand Down
4 changes: 4 additions & 0 deletions custom_components/ecoflow_cloud/devices/delta_max.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ def switches(self, client: EcoflowMQTTClient) -> list[BaseSwitchEntity]:
lambda value: {"moduleType": 0, "operateType": "TCP", "params": {"enabled": value, "id": 81 }}),

]

def buttons(self, client: EcoflowMQTTClient) -> list[BaseSwitchEntity]:
return [
]

def selects(self, client: EcoflowMQTTClient) -> list[BaseSelectEntity]:
return [
Expand Down
4 changes: 4 additions & 0 deletions custom_components/ecoflow_cloud/devices/delta_mini.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ def switches(self, client: EcoflowMQTTClient) -> list[BaseSwitchEntity]:
# EnabledEntity(client, "pd.bpPowerSoc", const.BP_ENABLED,
# lambda value: {"moduleType": 0, "operateType": "TCP", "params": {"isConfig": value}}),
]

def buttons(self, client: EcoflowMQTTClient) -> list[BaseSwitchEntity]:
return [
]

def selects(self, client: EcoflowMQTTClient) -> list[BaseSelectEntity]:
return [
Expand Down
4 changes: 4 additions & 0 deletions custom_components/ecoflow_cloud/devices/delta_pro.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ def switches(self, client: EcoflowMQTTClient) -> list[BaseSwitchEntity]:
"minDsgSoc": 0,
"maxChgSoc": 0}}),
]

def buttons(self, client: EcoflowMQTTClient) -> list[BaseSwitchEntity]:
return [
]

def selects(self, client: EcoflowMQTTClient) -> list[BaseSelectEntity]:
return [
Expand Down
124 changes: 124 additions & 0 deletions custom_components/ecoflow_cloud/devices/glacier.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
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, BaseButtonEntity
from ..mqtt.ecoflow_mqtt import EcoflowMQTTClient
from ..number import ChargingPowerEntity, MaxBatteryLevelEntity, MinBatteryLevelEntity, SetTempEntity
from ..select import DictSelectEntity, TimeoutDictSelectEntity
from ..sensor import LevelSensorEntity, RemainSensorEntity, SecondsRemainSensorEntity, TempSensorEntity, \
CyclesSensorEntity, InWattsSensorEntity, OutWattsSensorEntity, VoltSensorEntity, QuotasStatusSensorEntity, \
MilliVoltSensorEntity, InMilliVoltSensorEntity, OutMilliVoltSensorEntity, ChargingStateSensorEntity, \
FanSensorEntity, MiscBinarySensorEntity, DecicelsiusSensorEntity, MiscSensorEntity
from ..switch import EnabledEntity
from ..button import EnabledButtonEntity


class Glacier(BaseDevice):
def charging_power_step(self) -> int:
return 50

def sensors(self, client: EcoflowMQTTClient) -> list[BaseSensorEntity]:
return [
# Power and Battery Entities
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.f32LcdSoc", const.COMBINED_BATTERY_LEVEL),

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

InWattsSensorEntity(client, "bms_bmsStatus.inWatts", const.TOTAL_IN_POWER),
OutWattsSensorEntity(client, "bms_bmsStatus.outWatts", const.TOTAL_OUT_POWER),

OutWattsSensorEntity(client, "pd.motorWat", "Motor Power"),

RemainSensorEntity(client, "bms_emsStatus.chgRemain", const.CHARGE_REMAINING_TIME),
RemainSensorEntity(client, "bms_emsStatus.dsgRemain", const.DISCHARGE_REMAINING_TIME),

CyclesSensorEntity(client, "bms_bmsStatus.cycles", const.CYCLES),

TempSensorEntity(client, "bms_bmsStatus.tmp", const.BATTERY_TEMP),
TempSensorEntity(client, "bms_bmsStatus.minCellTmp", const.MIN_CELL_TEMP, False),
TempSensorEntity(client, "bms_bmsStatus.maxCellTmp", const.MAX_CELL_TEMP, False),

VoltSensorEntity(client, "bms_bmsStatus.vol", const.BATTERY_VOLT, False),
MilliVoltSensorEntity(client, "bms_bmsStatus.minCellVol", const.MIN_CELL_VOLT, False),
MilliVoltSensorEntity(client, "bms_bmsStatus.maxCellVol", const.MAX_CELL_VOLT, False),

MiscBinarySensorEntity(client,"pd.batFlag","Battery Present"),

MiscSensorEntity(client, "pd.xt60InState", "XT60 State"),

#Fridge Entities
FanSensorEntity(client, "bms_emsStatus.fanLvl", "Fan Level"),

DecicelsiusSensorEntity(client, "pd.ambientTmp", "Ambient Temperature"),
DecicelsiusSensorEntity(client, "pd.exhaustTmp", "Exhaust Temperature"),
DecicelsiusSensorEntity(client, "pd.tempWater", "Water Temperature"),
DecicelsiusSensorEntity(client, "pd.tmpL", "Left Temperature"),
DecicelsiusSensorEntity(client, "pd.tmpR", "Right Temperature"),

MiscBinarySensorEntity(client,"pd.flagTwoZone","Dual Zone Mode"),

SecondsRemainSensorEntity(client, "pd.iceTm", "Ice Time Remain"),
LevelSensorEntity(client, "pd.icePercent", "Ice Percentage"),

MiscSensorEntity(client, "pd.iceMkMode", "Ice Make Mode"),

MiscBinarySensorEntity(client,"pd.iceAlert","Ice Alert"),
MiscBinarySensorEntity(client,"pd.waterLine","Ice Water Level OK"),

QuotasStatusSensorEntity(client)

]

def numbers(self, client: EcoflowMQTTClient) -> list[BaseNumberEntity]:
return [
SetTempEntity(client,"pd.tmpLSet", "Left Set Temperature",-25, 10,
lambda value, params: {"moduleType": 1, "operateType": "temp",
"params": {"tmpM": int(params.get("pd.tmpMSet", 0)),
"tmpL": int(value),
"tmpR": int(params.get("pd.tmpRSet", 0))}}),

SetTempEntity(client,"pd.tmpMSet", "Combined Set Temperature",-25, 10,
lambda value, params: {"moduleType": 1, "operateType": "temp",
"params": {"tmpM": int(value),
"tmpL": int(params.get("pd.tmpLSet", 0)),
"tmpR": int(params.get("pd.tmpRSet", 0))}}),

SetTempEntity(client,"pd.tmpRSet", "Right Set Temperature",-25, 10,
lambda value, params: {"moduleType": 1, "operateType": "temp",
"params": {"tmpM": int(params.get("pd.tmpMSet", 0)),
"tmpL": int(params.get("pd.tmpLSet", 0)),
"tmpR": int(value)}}),

]

def switches(self, client: EcoflowMQTTClient) -> list[BaseSwitchEntity]:
return [

]

def buttons(self, client: EcoflowMQTTClient) -> list[BaseButtonEntity]:
return [
EnabledButtonEntity(client, "smlice", "Make Small Ice", lambda value: {"moduleType": 1, "operateType": "iceMake", "params": {"enable": 1, "iceShape": 0}}),
EnabledButtonEntity(client, "lrgice", "Make Large Ice", lambda value: {"moduleType": 1, "operateType": "iceMake", "params": {"enable": 1, "iceShape": 1}}),
EnabledButtonEntity(client, "deice", "Detach Ice", lambda value: {"moduleType": 1, "operateType": "deIce", "params": {"enable": 1}})

]


def selects(self, client: EcoflowMQTTClient) -> list[BaseSelectEntity]:
return [

]

def migrate(self, version) -> list[EntityMigration]:
if version == 2:
return [
EntityMigration("pd.soc", Platform.SENSOR, MigrationAction.REMOVE),
]
return []
4 changes: 4 additions & 0 deletions custom_components/ecoflow_cloud/devices/powerstream.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ def numbers(self, client: EcoflowMQTTClient) -> list[BaseNumberEntity]:

def switches(self, client: EcoflowMQTTClient) -> list[BaseSwitchEntity]:
return []

def buttons(self, client: EcoflowMQTTClient) -> list[BaseSwitchEntity]:
return [
]

def selects(self, client: EcoflowMQTTClient) -> list[BaseSelectEntity]:
return [
Expand Down
2 changes: 2 additions & 0 deletions custom_components/ecoflow_cloud/devices/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from custom_components.ecoflow_cloud.devices.delta_max import DeltaMax
from custom_components.ecoflow_cloud.devices.delta2_max import Delta2Max
from custom_components.ecoflow_cloud.devices.powerstream import PowerStream
from custom_components.ecoflow_cloud.devices.glacier import Glacier

devices: dict[str, BaseDevice] = {
EcoflowModel.DELTA_2.name: Delta2(),
Expand All @@ -24,5 +25,6 @@
EcoflowModel.DELTA_MAX.name: DeltaMax(),
EcoflowModel.DELTA_2_MAX.name: Delta2Max(),
EcoflowModel.POWERSTREAM.name: PowerStream(),
EcoflowModel.GLACIER.name: Glacier(),
EcoflowModel.DIAGNOSTIC.name: DiagnosticDevice()
}
4 changes: 4 additions & 0 deletions custom_components/ecoflow_cloud/devices/river2.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ def switches(self, client: EcoflowMQTTClient) -> list[BaseSwitchEntity]:
lambda value: {"moduleType": 5, "operateType": "mpptCar", "params": {"enabled": value}})
]

def buttons(self, client: EcoflowMQTTClient) -> list[BaseSwitchEntity]:
return [
]

def selects(self, client: EcoflowMQTTClient) -> list[BaseSelectEntity]:
return [
DictSelectEntity(client, "mppt.dcChgCurrent", const.DC_CHARGE_CURRENT, const.DC_CHARGE_CURRENT_OPTIONS,
Expand Down
4 changes: 4 additions & 0 deletions custom_components/ecoflow_cloud/devices/river2_max.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ def switches(self, client: EcoflowMQTTClient) -> list[BaseSwitchEntity]:
"minDsgSoc": 0,
"minChgSoc": 0}})
]

def buttons(self, client: EcoflowMQTTClient) -> list[BaseSwitchEntity]:
return [
]

def selects(self, client: EcoflowMQTTClient) -> list[BaseSelectEntity]:
return [
Expand Down
4 changes: 4 additions & 0 deletions custom_components/ecoflow_cloud/devices/river2_pro.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ def switches(self, client: EcoflowMQTTClient) -> list[BaseSwitchEntity]:
EnabledEntity(client, "pd.carState", const.DC_ENABLED,
lambda value: {"moduleType": 5, "operateType": "mpptCar", "params": {"enabled": value}})
]

def buttons(self, client: EcoflowMQTTClient) -> list[BaseSwitchEntity]:
return [
]

def selects(self, client: EcoflowMQTTClient) -> list[BaseSelectEntity]:
return [
Expand Down
4 changes: 4 additions & 0 deletions custom_components/ecoflow_cloud/devices/river_max.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ def switches(self, client: EcoflowMQTTClient) -> list[BaseSwitchEntity]:
EnabledEntity(client, "inv.cfgAcXboost", const.XBOOST_ENABLED, lambda value: {"moduleType": 0, "operateType": "TCP", "params": {"id": 66, "xboost": value}})

]

def buttons(self, client: EcoflowMQTTClient) -> list[BaseSwitchEntity]:
return [
]

def selects(self, client: EcoflowMQTTClient) -> list[BaseSelectEntity]:
return [
Expand Down
4 changes: 4 additions & 0 deletions custom_components/ecoflow_cloud/devices/river_pro.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ def switches(self, client: EcoflowMQTTClient) -> list[BaseSwitchEntity]:
EnabledEntity(client, "inv.cfgAcEnabled", const.AC_ENABLED, None),
EnabledEntity(client, "inv.cfgAcXboost", const.XBOOST_ENABLED, None)
]

def buttons(self, client: EcoflowMQTTClient) -> list[BaseSwitchEntity]:
return [
]

def selects(self, client: EcoflowMQTTClient) -> list[BaseSelectEntity]:
return [
Expand Down
6 changes: 6 additions & 0 deletions custom_components/ecoflow_cloud/entities/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from homeassistant.components.select import SelectEntity
from homeassistant.components.sensor import SensorEntity
from homeassistant.components.switch import SwitchEntity
from homeassistant.components.button import ButtonEntity
from homeassistant.helpers.entity import Entity, EntityCategory

from ..mqtt.ecoflow_mqtt import EcoflowMQTTClient
Expand Down Expand Up @@ -143,3 +144,8 @@ class BaseSwitchEntity(SwitchEntity, EcoFlowBaseCommandEntity):

class BaseSelectEntity(SelectEntity, EcoFlowBaseCommandEntity):
pass


class BaseButtonEntity(ButtonEntity, EcoFlowBaseCommandEntity):
pass

7 changes: 6 additions & 1 deletion custom_components/ecoflow_cloud/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from homeassistant.components.number import NumberMode
from homeassistant.components.sensor import SensorDeviceClass
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import PERCENTAGE, POWER_WATT
from homeassistant.const import PERCENTAGE, POWER_WATT, UnitOfTemperature
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback

Expand Down Expand Up @@ -79,3 +79,8 @@ class MinGenStartLevelEntity(LevelEntity):

class MaxGenStopLevelEntity(LevelEntity):
_attr_icon = "mdi:engine-off"


class SetTempEntity(ValueUpdateEntity):
_attr_native_unit_of_measurement = UnitOfTemperature.CELSIUS

13 changes: 13 additions & 0 deletions custom_components/ecoflow_cloud/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,19 @@ def _update_value(self, val: Any) -> Any:
ival = 0

return super()._update_value(ival)

class SecondsRemainSensorEntity(BaseSensorEntity):
_attr_device_class = SensorDeviceClass.DURATION
_attr_native_unit_of_measurement = UnitOfTime.SECONDS
_attr_state_class = SensorStateClass.MEASUREMENT
_attr_native_value = 0

def _update_value(self, val: Any) -> Any:
ival = int(val)
if ival < 0 or ival > 5000:
ival = 0

return super()._update_value(ival)


class TempSensorEntity(BaseSensorEntity):
Expand Down
Loading