from homeassistant.const import Platform from . import const, BaseDevice, EntityMigration, MigrationAction from ..entities import BaseSensorEntity, BaseNumberEntity, BaseSwitchEntity, BaseSelectEntity from ..mqtt.ecoflow_mqtt import EcoflowMQTTClient from ..number import MaxBatteryLevelEntity from ..select import TimeoutDictSelectEntity from ..sensor import LevelSensorEntity, WattsSensorEntity, RemainSensorEntity, TempSensorEntity, \ CyclesSensorEntity, InEnergySensorEntity, InWattsSensorEntity, OutEnergySensorEntity, OutWattsSensorEntity, VoltSensorEntity, InVoltSensorEntity, \ InAmpSensorEntity, AmpSensorEntity, StatusSensorEntity, MilliVoltSensorEntity, InMilliVoltSensorEntity, \ OutMilliVoltSensorEntity, CapacitySensorEntity from ..switch import EnabledEntity, BeeperEntity class RiverPro(BaseDevice): def sensors(self, client: EcoflowMQTTClient) -> list[BaseSensorEntity]: return [ LevelSensorEntity(client, "bmsMaster.soc", const.MAIN_BATTERY_LEVEL) .attr("bmsMaster.designCap", const.ATTR_DESIGN_CAPACITY, 0) .attr("bmsMaster.fullCap", const.ATTR_FULL_CAPACITY, 0) .attr("bmsMaster.remainCap", const.ATTR_REMAIN_CAPACITY, 0), CapacitySensorEntity(client, "bmsMaster.designCap", const.MAIN_DESIGN_CAPACITY, False), CapacitySensorEntity(client, "bmsMaster.fullCap", const.MAIN_FULL_CAPACITY, False), CapacitySensorEntity(client, "bmsMaster.remainCap", const.MAIN_REMAIN_CAPACITY, False), WattsSensorEntity(client, "pd.wattsInSum", const.TOTAL_IN_POWER), WattsSensorEntity(client, "pd.wattsOutSum", const.TOTAL_OUT_POWER), InAmpSensorEntity(client, "inv.dcInAmp", const.SOLAR_IN_CURRENT), InVoltSensorEntity(client, "inv.dcInVol", const.SOLAR_IN_VOLTAGE), InWattsSensorEntity(client, "inv.inputWatts", const.AC_IN_POWER), OutWattsSensorEntity(client, "inv.outputWatts", const.AC_OUT_POWER), InMilliVoltSensorEntity(client, "inv.acInVol", const.AC_IN_VOLT), OutMilliVoltSensorEntity(client, "inv.invOutVol", const.AC_OUT_VOLT), OutWattsSensorEntity(client, "pd.carWatts", const.DC_OUT_POWER), OutWattsSensorEntity(client, "pd.typecWatts", const.TYPEC_OUT_POWER), # disabled by default because they aren't terribly useful TempSensorEntity(client, "pd.carTemp", const.DC_CAR_OUT_TEMP, False), TempSensorEntity(client, "pd.typecTemp", const.USB_C_TEMP, False), OutWattsSensorEntity(client, "pd.usb1Watts", const.USB_1_OUT_POWER), OutWattsSensorEntity(client, "pd.usb2Watts", const.USB_2_OUT_POWER), OutWattsSensorEntity(client, "pd.usb3Watts", const.USB_3_OUT_POWER), RemainSensorEntity(client, "pd.remainTime", const.REMAINING_TIME), TempSensorEntity(client, "bmsMaster.temp", const.BATTERY_TEMP) .attr("bmsMaster.minCellTemp", const.ATTR_MIN_CELL_TEMP, 0) .attr("bmsMaster.maxCellTemp", const.ATTR_MAX_CELL_TEMP, 0), TempSensorEntity(client, "bmsMaster.minCellTemp", const.MIN_CELL_TEMP, False), TempSensorEntity(client, "bmsMaster.maxCellTemp", const.MAX_CELL_TEMP, False), TempSensorEntity(client, "inv.inTemp", const.INV_IN_TEMP), TempSensorEntity(client, "inv.outTemp", const.INV_OUT_TEMP), # https://github.com/tolwi/hassio-ecoflow-cloud/discussions/87 InEnergySensorEntity(client, "pd.chgSunPower", const.SOLAR_IN_ENERGY), InEnergySensorEntity(client, "pd.chgPowerAC", const.CHARGE_AC_ENERGY), InEnergySensorEntity(client, "pd.chgPowerDC", const.CHARGE_DC_ENERGY), OutEnergySensorEntity(client, "pd.dsgPowerAC", const.DISCHARGE_AC_ENERGY), OutEnergySensorEntity(client, "pd.dsgPowerDC", const.DISCHARGE_DC_ENERGY), AmpSensorEntity(client, "bmsMaster.amp", const.BATTERY_AMP, False), MilliVoltSensorEntity(client, "bmsMaster.vol", const.BATTERY_VOLT, False) .attr("bmsMaster.minCellVol", const.ATTR_MIN_CELL_VOLT, 0) .attr("bmsMaster.maxCellVol", const.ATTR_MAX_CELL_VOLT, 0), MilliVoltSensorEntity(client, "bmsMaster.minCellVol", const.MIN_CELL_VOLT, False), MilliVoltSensorEntity(client, "bmsMaster.maxCellVol", const.MAX_CELL_VOLT, False), CyclesSensorEntity(client, "bmsMaster.cycles", const.CYCLES), # Optional Slave Batteries LevelSensorEntity(client, "bmsSlave1.soc", const.SLAVE_BATTERY_LEVEL, False, True) .attr("bmsSlave1.designCap", const.ATTR_DESIGN_CAPACITY, 0) .attr("bmsSlave1.fullCap", const.ATTR_FULL_CAPACITY, 0) .attr("bmsSlave1.remainCap", const.ATTR_REMAIN_CAPACITY, 0), CapacitySensorEntity(client, "bmsSlave1.designCap", const.SLAVE_DESIGN_CAPACITY, False), CapacitySensorEntity(client, "bmsSlave1.fullCap", const.SLAVE_FULL_CAPACITY, False), CapacitySensorEntity(client, "bmsSlave1.remainCap", const.SLAVE_REMAIN_CAPACITY, False), CyclesSensorEntity(client, "bmsSlave1.cycles", const.SLAVE_CYCLES, False, True), TempSensorEntity(client, "bmsSlave1.temp", const.SLAVE_BATTERY_TEMP, False, True) .attr("bmsSlave1.minCellTemp", const.ATTR_MIN_CELL_TEMP, 0) .attr("bmsSlave1.maxCellTemp", const.ATTR_MAX_CELL_TEMP, 0), AmpSensorEntity(client, "bmsSlave1.amp", const.SLAVE_BATTERY_AMP, False), MilliVoltSensorEntity(client, "bmsSlave1.vol", const.SLAVE_BATTERY_VOLT, False) .attr("bmsSlave1.minCellVol", const.ATTR_MIN_CELL_VOLT, 0) .attr("bmsSlave1.maxCellVol", const.ATTR_MAX_CELL_VOLT, 0), MilliVoltSensorEntity(client, "bmsSlave1.minCellVol", const.SLAVE_MIN_CELL_VOLT, False), MilliVoltSensorEntity(client, "bmsSlave1.maxCellVol", const.SLAVE_MAX_CELL_VOLT, False), StatusSensorEntity(client), ] def numbers(self, client: EcoflowMQTTClient) -> list[BaseNumberEntity]: return [ MaxBatteryLevelEntity(client, "bmsMaster.maxChargeSoc", const.MAX_CHARGE_LEVEL, 30, 100, lambda value: {"moduleType": 0, "operateType": "TCP", "params": {"id": 49, "maxChgSoc": value}}), # MinBatteryLevelEntity(client, "bmsMaster.minDsgSoc", const.MIN_DISCHARGE_LEVEL, 0, 30, None), ] def switches(self, client: EcoflowMQTTClient) -> list[BaseSwitchEntity]: return [ BeeperEntity(client, "pd.beepState", const.BEEPER, lambda value: {"moduleType": 0, "operateType": "TCP", "params": {"id": 38, "enabled": value}}), EnabledEntity(client, "inv.acAutoOutConfig", const.AC_ALWAYS_ENABLED, lambda value: {"moduleType": 0, "operateType": "TCP", "params": {"id": 95, "acautooutConfig": value, "minAcoutSoc": 255}}), EnabledEntity(client, "pd.carSwitch", const.DC_ENABLED, lambda value: {"moduleType": 0, "operateType": "TCP", "params": {"id": 34, "enabled": value}}), EnabledEntity(client, "inv.cfgAcEnabled", const.AC_ENABLED, lambda value: {"moduleType": 0, "operateType": "TCP", "params": {"id": 66, "enabled": value}}), EnabledEntity(client, "inv.cfgAcXboost", const.XBOOST_ENABLED, lambda value: {"moduleType": 0, "operateType": "TCP", "params": {"id": 66, "xboost": value}}), EnabledEntity(client, "inv.cfgAcChgModeFlg", const.AC_SLOW_CHARGE, lambda value: {"moduleType": 0, "operateType": "TCP", "params": {"id": 65, "workMode": value}}), EnabledEntity(client, "inv.cfgFanMode", const.AUTO_FAN_SPEED, lambda value: {"moduleType": 0, "operateType": "TCP", "params": {"id": 73, "fanMode": value}}) ] def selects(self, client: EcoflowMQTTClient) -> list[BaseSelectEntity]: return [ TimeoutDictSelectEntity(client, "pd.standByMode", const.UNIT_TIMEOUT, const.UNIT_TIMEOUT_OPTIONS_LIMITED, lambda value: {"moduleType": 0, "operateType": "TCP", "params": {"id": 33, "standByMode": value}}), TimeoutDictSelectEntity(client, "pd.carDelayOffMin", const.DC_TIMEOUT, const.DC_TIMEOUT_OPTIONS_LIMITED, lambda value: {"moduleType": 0, "operateType": "TCP", "params": {"cmdSet": 32, "id": 84, "carDelayOffMin": value}}), TimeoutDictSelectEntity(client, "inv.cfgStandbyMin", const.AC_TIMEOUT, const.AC_TIMEOUT_OPTIONS_LIMITED, lambda value: {"moduleType": 0, "operateType": "TCP", "params": {"id": 153, "standByMins": value}}) # lambda is confirmed correct, but pd.lcdOffSec is missing from status # TimeoutDictSelectEntity(client, "pd.lcdOffSec", const.SCREEN_TIMEOUT, const.SCREEN_TIMEOUT_OPTIONS, # lambda value: {"moduleType": 0, "operateType": "TCP", # "params": {"lcdTime": value, "id": 39}}) ] def migrate(self, version) -> list[EntityMigration]: if version == 2: return [ EntityMigration("pd.soc", Platform.SENSOR, MigrationAction.REMOVE), ] return []