diff --git a/custom_components/ecoflow_cloud/devices/internal/delta3.py b/custom_components/ecoflow_cloud/devices/internal/delta3.py new file mode 100644 index 0000000..b6c9189 --- /dev/null +++ b/custom_components/ecoflow_cloud/devices/internal/delta3.py @@ -0,0 +1,135 @@ +from custom_components.ecoflow_cloud.api import EcoflowApiClient +from custom_components.ecoflow_cloud.devices import const, BaseDevice +from custom_components.ecoflow_cloud.entities import BaseSensorEntity +from custom_components.ecoflow_cloud.number import ChargingPowerEntity, MaxBatteryLevelEntity, MinBatteryLevelEntity, \ + MinGenStartLevelEntity, \ + MaxGenStopLevelEntity +from custom_components.ecoflow_cloud.select import DictSelectEntity, TimeoutDictSelectEntity +from custom_components.ecoflow_cloud.sensor import LevelSensorEntity, WattsSensorEntity, RemainSensorEntity, \ + TempSensorEntity, \ + CyclesSensorEntity, InWattsSensorEntity, OutWattsSensorEntity, OutWattsDcSensorEntity, InWattsSolarSensorEntity, \ + InVoltSolarSensorEntity, InAmpSolarSensorEntity, OutVoltDcSensorEntity, \ + InEnergySensorEntity, OutEnergySensorEntity, MilliVoltSensorEntity, InMilliVoltSensorEntity, \ + OutMilliVoltSensorEntity, AmpSensorEntity, CapacitySensorEntity, QuotaStatusSensorEntity +from custom_components.ecoflow_cloud.switch import BeeperEntity, EnabledEntity + + +class Delta3(BaseDevice): + def sensors(self, client: EcoflowApiClient) -> list[BaseSensorEntity]: + return [ + LevelSensorEntity(client, self, "cmsBattSoc", const.MAIN_BATTERY_LEVEL) + .attr("bmsDesignCap", const.ATTR_DESIGN_CAPACITY, 0) + .attr("bmsMaster.fullCap", const.ATTR_FULL_CAPACITY, 0) + .attr("bmsMaster.remainCap", const.ATTR_REMAIN_CAPACITY, 0), + LevelSensorEntity(client, self, "bmsMaster.f32ShowSoc", const.MAIN_BATTERY_LEVEL_F32, False) + .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, self, "bmsMaster.designCap", const.MAIN_DESIGN_CAPACITY, False), + CapacitySensorEntity(client, self, "bmsMaster.fullCap", const.MAIN_FULL_CAPACITY, False), + CapacitySensorEntity(client, self, "bmsMaster.remainCap", const.MAIN_REMAIN_CAPACITY, False), + LevelSensorEntity(client, self, "bmsMaster.soh", const.SOH), + + LevelSensorEntity(client, self, "ems.lcdShowSoc", const.COMBINED_BATTERY_LEVEL), + LevelSensorEntity(client, self, "ems.f32LcdShowSoc", const.COMBINED_BATTERY_LEVEL_F32, False), + WattsSensorEntity(client, self, "pd.wattsInSum", const.TOTAL_IN_POWER), + WattsSensorEntity(client, self, "pd.wattsOutSum", const.TOTAL_OUT_POWER), + AmpSensorEntity(client, self, "bmsMaster.amp", const.MAIN_BATTERY_CURRENT), + + InWattsSensorEntity(client, self, "powGetAcIn", const.AC_IN_POWER), + OutWattsSensorEntity(client, self, "powOutSumW", const.AC_OUT_POWER), + + InMilliVoltSensorEntity(client, self, "inv.acInVol", const.AC_IN_VOLT), + OutMilliVoltSensorEntity(client, self, "inv.invOutVol", const.AC_OUT_VOLT), + + InWattsSolarSensorEntity(client, self, "mppt.inWatts", const.SOLAR_IN_POWER), + InVoltSolarSensorEntity(client, self, "mppt.inVol", const.SOLAR_IN_VOLTAGE), + InAmpSolarSensorEntity(client, self, "mppt.inAmp", const.SOLAR_IN_CURRENT), + + OutWattsDcSensorEntity(client, self, "mppt.outWatts", const.DC_OUT_POWER), + OutVoltDcSensorEntity(client, self, "mppt.outVol", const.DC_OUT_VOLTAGE), + + OutWattsSensorEntity(client, self, "mppt.carOutWatts", const.DC_CAR_OUT_POWER), + OutWattsSensorEntity(client, self, "mppt.dcdc12vWatts", const.DC_ANDERSON_OUT_POWER), + + OutWattsSensorEntity(client, self, "pd.typec1Watts", const.TYPEC_1_OUT_POWER), + OutWattsSensorEntity(client, self, "pd.typec2Watts", const.TYPEC_2_OUT_POWER), + + OutWattsSensorEntity(client, self, "pd.usb1Watts", const.USB_1_OUT_POWER), + OutWattsSensorEntity(client, self, "pd.usb2Watts", const.USB_2_OUT_POWER), + + OutWattsSensorEntity(client, self, "pd.qcUsb1Watts", const.USB_QC_1_OUT_POWER), + OutWattsSensorEntity(client, self, "pd.qcUsb2Watts", const.USB_QC_2_OUT_POWER), + + RemainSensorEntity(client, self, "ems.chgRemainTime", const.CHARGE_REMAINING_TIME), + RemainSensorEntity(client, self, "ems.dsgRemainTime", const.DISCHARGE_REMAINING_TIME), + CyclesSensorEntity(client, self, "bmsMaster.cycles", const.CYCLES), + + TempSensorEntity(client, self, "bmsMaxCellTemp", const.BATTERY_TEMP) + .attr("bmsMaster.minCellTemp", const.ATTR_MIN_CELL_TEMP, 0) + .attr("bmsMaster.maxCellTemp", const.ATTR_MAX_CELL_TEMP, 0), + TempSensorEntity(client, self, "bmsMaster.minCellTemp", const.MIN_CELL_TEMP, False), + TempSensorEntity(client, self, "bmsMaster.maxCellTemp", const.MAX_CELL_TEMP, False), + + MilliVoltSensorEntity(client, self, "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, self, "bmsMaster.minCellVol", const.MIN_CELL_VOLT, False), + MilliVoltSensorEntity(client, self, "bmsMaster.maxCellVol", const.MAX_CELL_VOLT, False), + + # https://github.com/tolwi/hassio-ecoflow-cloud/discussions/87 + InEnergySensorEntity(client, self, "pd.chgSunPower", const.SOLAR_IN_ENERGY), + InEnergySensorEntity(client, self, "pd.chgPowerAc", const.CHARGE_AC_ENERGY), + InEnergySensorEntity(client, self, "pd.chgPowerDc", const.CHARGE_DC_ENERGY), + OutEnergySensorEntity(client, self, "pd.dsgPowerAc", const.DISCHARGE_AC_ENERGY), + OutEnergySensorEntity(client, self, "pd.dsgPowerDc", const.DISCHARGE_DC_ENERGY), + + # Optional Slave Batteries + LevelSensorEntity(client, self, "bmsSlave1.soc", const.SLAVE_N_BATTERY_LEVEL % 1, 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), + LevelSensorEntity(client, self, "bmsSlave1.f32ShowSoc", const.SLAVE_N_BATTERY_LEVEL_F32 % 1, False, False) + .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, self, "bmsSlave1.designCap", const.SLAVE_N_DESIGN_CAPACITY % 1, False), + CapacitySensorEntity(client, self, "bmsSlave1.fullCap", const.SLAVE_N_FULL_CAPACITY % 1, False), + CapacitySensorEntity(client, self, "bmsSlave1.remainCap", const.SLAVE_N_REMAIN_CAPACITY % 1, False), + LevelSensorEntity(client, self, "bmsSlave1.soh", const.SLAVE_N_SOH % 1), + + TempSensorEntity(client, self, "bmsSlave1.temp", const.SLAVE_N_BATTERY_TEMP % 1, False, True) + .attr("bmsSlave1.minCellTemp", const.ATTR_MIN_CELL_TEMP, 0) + .attr("bmsSlave1.maxCellTemp", const.ATTR_MAX_CELL_TEMP, 0), + WattsSensorEntity(client, self, "bmsSlave1.inputWatts", const.SLAVE_N_IN_POWER % 1, False, True), + WattsSensorEntity(client, self, "bmsSlave1.outputWatts", const.SLAVE_N_OUT_POWER % 1, False, True), + + LevelSensorEntity(client, self, "bmsSlave2.soc", const.SLAVE_N_BATTERY_LEVEL % 2, False, True) + .attr("bmsSlave2.designCap", const.ATTR_DESIGN_CAPACITY, 0) + .attr("bmsSlave2.fullCap", const.ATTR_FULL_CAPACITY, 0) + .attr("bmsSlave2.remainCap", const.ATTR_REMAIN_CAPACITY, 0), + LevelSensorEntity(client, self, "bmsSlave2.f32ShowSoc", const.SLAVE_N_BATTERY_LEVEL_F32 % 2, False, False) + .attr("bmsSlave2.designCap", const.ATTR_DESIGN_CAPACITY, 0) + .attr("bmsSlave2.fullCap", const.ATTR_FULL_CAPACITY, 0) + .attr("bmsSlave2.remainCap", const.ATTR_REMAIN_CAPACITY, 0), + CapacitySensorEntity(client, self, "bmsSlave2.designCap", const.SLAVE_N_DESIGN_CAPACITY % 2, False), + CapacitySensorEntity(client, self, "bmsSlave2.fullCap", const.SLAVE_N_FULL_CAPACITY % 2, False), + CapacitySensorEntity(client, self, "bmsSlave2.remainCap", const.SLAVE_N_REMAIN_CAPACITY % 2, False), + LevelSensorEntity(client, self, "bmsSlave2.soh", const.SLAVE_N_SOH % 2), + MilliVoltSensorEntity(client, self, "bmsSlave1.vol", const.SLAVE_N_BATTERY_VOLT % 1, False), + MilliVoltSensorEntity(client, self, "bmsSlave1.minCellVol", const.SLAVE_N_MIN_CELL_VOLT % 1, False), + MilliVoltSensorEntity(client, self, "bmsSlave1.maxCellVol", const.SLAVE_N_MAX_CELL_VOLT % 1, False), + AmpSensorEntity(client, self, "bmsSlave1.amp", const.SLAVE_N_BATTERY_CURRENT % 1, False), + MilliVoltSensorEntity(client, self, "bmsSlave2.vol", const.SLAVE_N_BATTERY_VOLT % 2, False), + MilliVoltSensorEntity(client, self, "bmsSlave2.minCellVol", const.SLAVE_N_MIN_CELL_VOLT % 2, False), + MilliVoltSensorEntity(client, self, "bmsSlave2.maxCellVol", const.SLAVE_N_MAX_CELL_VOLT % 2, False), + AmpSensorEntity(client, self, "bmsSlave2.amp", const.SLAVE_N_BATTERY_CURRENT % 2, False), + TempSensorEntity(client, self, "bmsSlave2.temp", const.SLAVE_N_BATTERY_TEMP % 2, False, True) + .attr("bmsSlave2.minCellTemp", const.ATTR_MIN_CELL_TEMP, 0) + .attr("bmsSlave2.maxCellTemp", const.ATTR_MAX_CELL_TEMP, 0), + WattsSensorEntity(client, self, "bmsSlave2.inputWatts", const.SLAVE_N_IN_POWER % 2, False, True), + WattsSensorEntity(client, self, "bmsSlave2.outputWatts", const.SLAVE_N_OUT_POWER % 2, False, True), + CyclesSensorEntity(client, self, "bmsSlave1.cycles", const.SLAVE_N_CYCLES % 1, False), + CyclesSensorEntity(client, self, "bmsSlave2.cycles", const.SLAVE_N_CYCLES % 2, False), + QuotaStatusSensorEntity(client, self) + ] \ No newline at end of file diff --git a/custom_components/ecoflow_cloud/devices/public/delta3.py b/custom_components/ecoflow_cloud/devices/public/delta3.py new file mode 100644 index 0000000..6919b0d --- /dev/null +++ b/custom_components/ecoflow_cloud/devices/public/delta3.py @@ -0,0 +1,17 @@ +from .data_bridge import to_plain +from ..internal.delta3 import Delta3 as InternalDelta3 +from ...api import EcoflowApiClient +from ...sensor import StatusSensorEntity + + +class Delta3(InternalDelta3): + + def _prepare_data(self, raw_data) -> dict[str, any]: + res = super()._prepare_data(raw_data) + res = to_plain(res) + return res + + def _status_sensor(self, client: EcoflowApiClient) -> StatusSensorEntity: + return StatusSensorEntity(client, self) + + diff --git a/custom_components/ecoflow_cloud/devices/registry.py b/custom_components/ecoflow_cloud/devices/registry.py index 3675c56..6623131 100644 --- a/custom_components/ecoflow_cloud/devices/registry.py +++ b/custom_components/ecoflow_cloud/devices/registry.py @@ -6,6 +6,7 @@ river2_pro as internal_river2_pro, delta2_max as internal_delta2_max, delta_pro as internal_delta_pro, + delta3 as internal_delta3, river_max as internal_river_max, river_pro as internal_river_pro, river_mini as internal_river_mini, @@ -16,6 +17,7 @@ wave2 as internal_wave2, ) from .public import (delta_pro as public_delta_pro, delta2 as public_delta2, + delta3 as public_delta3, delta2_max as public_delta2_max, river2 as public_river2, river2_max as public_river2_max, @@ -31,6 +33,7 @@ "RIVER_2_MAX": internal_river2_max.River2Max, "RIVER_2_PRO": internal_river2_pro.River2Pro, "DELTA_PRO": internal_delta_pro.DeltaPro, + "DELTA_3": internal_delta3.Delta3, "RIVER_MAX": internal_river_max.RiverMax, "RIVER_PRO": internal_river_pro.RiverPro, "RIVER_MINI": internal_river_mini.RiverMini, @@ -45,6 +48,7 @@ device_by_product: OrderedDict[str, Type[BaseDevice]] = OrderedDict[str, Type[BaseDevice]]({ "DELTA Pro": public_delta_pro.DeltaPro, + "DELTA 3": public_delta3.Delta3, "DELTA 2": public_delta2.Delta2, "DELTA 2 Max": public_delta2_max.Delta2Max, "RIVER 2": public_river2.River2, diff --git a/custom_components/ecoflow_cloud/manifest.json b/custom_components/ecoflow_cloud/manifest.json index 70d972d..a4d4381 100644 --- a/custom_components/ecoflow_cloud/manifest.json +++ b/custom_components/ecoflow_cloud/manifest.json @@ -1,8 +1,8 @@ { "domain": "ecoflow_cloud", - "name": "Ecoflow-Cloud", + "name": "Ecoflow-Cloud-rcolon", "codeowners": [ - "@tolwi" + "@nalditopr" ], "config_flow": true, "dependencies": ["mqtt"], @@ -14,5 +14,5 @@ "protobuf>=4.23.0", "jsonpath-ng>=1.6.1" ], - "version": "1.2.0" + "version": "1.2.21" } \ No newline at end of file