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

PowerOcean Public API #319

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 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
39 changes: 38 additions & 1 deletion custom_components/ecoflow_cloud/devices/public/data_bridge.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,41 @@ def to_plain(raw_data: dict[str, any]) -> dict[str, any]:

return result

return raw_data
return raw_data

def to_plain_other(raw_data: dict[str, any]) -> dict[str, any]:

if "cmdFunc" in raw_data and "cmdId" in raw_data:
new_params = {}

if "param" in raw_data:
if raw_data["addr"] == "ems":
phases = ["pcsAPhase", "pcsBPhase", "pcsCPhase"]
for i, phase in enumerate(phases):
for k, v in raw_data["param"][phase].items():
new_params[f"{phase}.{k}"] = v

n_strings = len(raw_data["param"]["mpptHeartBeat"][0]["mpptPv"])
mpptpvs = []
for i in range(1, n_strings + 1):
mpptpvs.append(f"mpptPv{i}")
for i, mpptpv in enumerate(mpptpvs):
for k, v in raw_data["param"]["mpptHeartBeat"][0]["mpptPv"][i].items():
new_params[f"{mpptpv}.{k}"] = v
else:
for (k, v) in raw_data["param"].items():
new_params[k] = v

if "params" in raw_data:
for (k, v) in raw_data["params"].items():
new_params[k] = v


result = {"params": new_params}
for (k, v) in raw_data.items():
if k not in ("param", "params"):
result[k] = v

return result

return raw_data
85 changes: 85 additions & 0 deletions custom_components/ecoflow_cloud/devices/public/powerocean.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
from .data_bridge import to_plain_other

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 custom_components.ecoflow_cloud import EcoflowApiClient
from custom_components.ecoflow_cloud.devices import BaseDevice, const
from custom_components.ecoflow_cloud.number import BrightnessLevelEntity
from custom_components.ecoflow_cloud.sensor import (
LevelSensorEntity,
WattsSensorEntity,
VoltSensorEntity,
AmpSensorEntity,
StatusSensorEntity,
SolarPowerSensorEntity,
SolarAmpSensorEntity,
SystemPowerSensorEntity,
)
from custom_components.ecoflow_cloud.switch import EnabledEntity

import logging

_LOGGER = logging.getLogger(__name__)


class PowerOcean(BaseDevice):
def sensors(self, client: EcoflowApiClient) -> list[SensorEntity]:
return [
SolarPowerSensorEntity(client, self, "mpptPwr", "mpptPwr"),
LevelSensorEntity(client, self, "bpSoc", "bpSoc"),
WattsSensorEntity(client, self, "bpPwr", "bpPwr"),
SystemPowerSensorEntity(client, self, "sysLoadPwr", "sysLoadPwr"),
SystemPowerSensorEntity(client, self, "sysGridPwr", "sysGridPwr"),
# TODO: flatten Structure?
# String 1
SolarPowerSensorEntity(client, self, "mpptPv1.pwr", "mpptPv1.pwr"),
SolarAmpSensorEntity(client, self, "mpptPv1.amp", "mpptPv1.amp"),
VoltSensorEntity(client, self, "mpptPv1.vol", "mpptPv1.vol"),

# String 2
SolarPowerSensorEntity(client, self, "mpptPv2.pwr", "mpptPv2.pwr"),
SolarAmpSensorEntity(client, self, "mpptPv2.amp", "mpptPv2.amp"),
VoltSensorEntity(client, self, "mpptPv2.vol", "mpptPv2.vol"),

VoltSensorEntity(client, self, "pcsAPhase.vol", "pcsAPhase.vol"),
AmpSensorEntity(client, self, "pcsAPhase.amp", "pcsAPhase.amp"),
WattsSensorEntity(client, self, "pcsAPhase.actPwr", "pcsAPhase.actPwr"),
WattsSensorEntity(client, self, "pcsAPhase.reactPwr", "pcsAPhase.reactPwr"),
WattsSensorEntity(client, self, "pcsAPhase.apparentPwr", "pcsAPhase.apparentPwr"),

VoltSensorEntity(client, self, "pcsBPhase.vol", "pcsBPhase.vol"),
AmpSensorEntity(client, self, "pcsBPhase.amp", "pcsBPhase.amp"),
WattsSensorEntity(client, self, "pcsBPhase.actPwr", "pcsBPhase.actPwr"),
WattsSensorEntity(client, self, "pcsBPhase.reactPwr", "pcsBPhase.reactPwr"),
WattsSensorEntity(client, self, "pcsBPhase.apparentPwr", "pcsBPhase.apparentPwr"),

VoltSensorEntity(client, self, "pcsCPhase.vol", "pcsCPhase.vol"),
AmpSensorEntity(client, self, "pcsCPhase.amp", "pcsCPhase.amp"),
WattsSensorEntity(client, self, "pcsCPhase.actPwr", "pcsCPhase.actPwr"),
WattsSensorEntity(client, self, "pcsCPhase.reactPwr", "pcsCPhase.reactPwr"),
WattsSensorEntity(client, self, "pcsCPhase.apparentPwr", "pcsCPhase.apparentPwr"),


StatusSensorEntity(client, self),
]

def numbers(self, client: EcoflowApiClient) -> list[NumberEntity]:
return []

def switches(self, client: EcoflowApiClient) -> list[SwitchEntity]:
return []

def selects(self, client: EcoflowApiClient) -> list[SelectEntity]:
return []

def _prepare_data(self, raw_data) -> dict[str, any]:
res = super()._prepare_data(raw_data)
_LOGGER.info(f"_prepare_data {raw_data}")
res = to_plain_other(res)
return res

def _status_sensor(self, client: EcoflowApiClient) -> StatusSensorEntity:
return StatusSensorEntity(client)
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 @@ -22,6 +22,7 @@
river2_pro as public_river2_pro,
smart_plug as public_smart_plug,
powerstream as public_powerstream,
powerocean as public_powerocean,
)
from ..devices import BaseDevice, DiagnosticDevice

Expand Down Expand Up @@ -52,5 +53,6 @@
"RIVER 2 Pro": public_river2_pro.River2Pro,
"Smart Plug": public_smart_plug.SmartPlug,
"PowerStream": public_powerstream.PowerStream,
"PowerOcean": public_powerocean.PowerOcean, # key is not verified
"Diagnostic": DiagnosticDevice
})
12 changes: 12 additions & 0 deletions custom_components/ecoflow_cloud/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,3 +383,15 @@ def _actualize_status(self) -> bool:
else:
return super()._actualize_status()

class SolarPowerSensorEntity(WattsSensorEntity):
_attr_entity_category = None
_attr_suggested_display_precision = 1
_attr_icon = "mdi:solar-power"

class SolarAmpSensorEntity(AmpSensorEntity):
_attr_suggested_display_precision = 1
_attr_icon = "mdi:current-dc"

class SystemPowerSensorEntity(WattsSensorEntity):
_attr_entity_category = None
_attr_suggested_display_precision = 1