Skip to content

Commit c48cb80

Browse files
authored
Updated to use v1 api calls, max battery charge/discharge current sensors added (#339)
* Update sensor.py Some refactoring change Device Detail and Get Variables to use v1 api call (v0 is deprecated). Added 2 variables for hybrid systems: - Max Bat Charge Current - Max Bat Discharge Current * Update README.md Update readme to add max bat charge/discharge current
1 parent 85470ec commit c48cb80

2 files changed

Lines changed: 82 additions & 9 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ Bat SoC | % (single battery systems)
139139
Bat SoC1 | % (dual battery systems)
140140
Bat SoC2 | % (dual battery systems)
141141
Bat SoH | % (single battery systems where BMS supports it)
142+
Max Bat Charge Current | A
143+
Max Bat Discharge Current | A
142144
Inverter Bat Power | kW (negative=charging, positive=discharging)
143145
Inverter Bat Power2 | kW (dual battery systems
144146
Bat Temperature | °C

custom_components/foxess/sensor.py

Lines changed: 80 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@
5757
_ENDPOINT_OA_DOMAIN = "https://www.foxesscloud.com"
5858
_ENDPOINT_OA_BATTERY_SETTINGS = "/op/v0/device/battery/soc/get?sn="
5959
_ENDPOINT_OA_REPORT = "/op/v0/device/report/query"
60-
_ENDPOINT_OA_DEVICE_DETAIL = "/op/v0/device/detail?sn="
60+
_ENDPOINT_OA_DEVICE_DETAIL = "/op/v0/device/detail"
61+
_ENDPOINT_OA_DEVICE_DETAIL_V1 = "/op/v1/device/detail"
6162
_ENDPOINT_OA_DEVICE_VARIABLES = "/op/v0/device/real/query"
6263
_ENDPOINT_OA_DEVICE_VARIABLES_V1 = "/op/v1/device/real/query"
6364
_ENDPOINT_OA_DAILY_GENERATION = "/op/v0/device/generation?sn="
@@ -136,21 +137,24 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
136137
_LOGGER.debug("Device ID: %s", deviceID)
137138
_LOGGER.debug("FoxESS Scan Interval: %s minutes", SCAN_MINUTES)
138139
_LOGGER.debug("Cross Time Zone: %s", xtzone)
140+
_LOGGER.debug("Restrict Variables: %s", RestrictGetVar)
139141
_LOGGER.debug("Extended PV: %s", ExtPV)
140-
_LOGGER.debug("V1 Api Calls: %s", V1_Api)
142+
_LOGGER.debug("v1 Api Calls: %s", V1_Api)
141143
_LOGGER.debug("EVO: %s", Evo)
142-
if V1_Api is not True:
143-
V1_Api = False
144+
if V1_Api is not False:
145+
V1_Api = True
146+
_LOGGER.debug("v1 Api Calls Enabled")
147+
else:
148+
_LOGGER.warning("v1 Api Calls Disabled, using v0")
144149
if ExtPV is not True:
145150
ExtPV = False
151+
_LOGGER.debug("Extended PV Disabled")
146152
else:
147-
ExtPV = True
148153
_LOGGER.warning("Extended PV 1-18 strings enabled")
149-
_LOGGER.debug("Restrict Variables: %s", RestrictGetVar)
150154
if RestrictGetVar is not True:
151155
RestrictGetVar = False
156+
_LOGGER.debug("Get Variables is full variable mode")
152157
else:
153-
RestrictGetVar = True
154158
_LOGGER.warning("Get Variables is in restricted mode")
155159
timeslice = {}
156160
timeslice[devicesn] = RETRY_NEXT_SLOT
@@ -513,6 +517,8 @@ async def async_update_data():
513517
FoxESSPVEnergyTotal(coordinator, name, deviceID),
514518
FoxESSResidualEnergy(coordinator, name, deviceID),
515519
FoxESSResponseTime(coordinator, name, deviceID),
520+
FoxESSMaxBatChargeCurrent(coordinator, name, deviceID),
521+
FoxESSMaxBatDischargeCurrent(coordinator, name, deviceID),
516522
FoxESSRunningState(
517523
coordinator,
518524
name,
@@ -752,10 +758,15 @@ async def waitforAPI():
752758
async def getOADeviceDetail(hass, allData, devicesn, apiKey):
753759
await waitforAPI()
754760

755-
path = "/op/v0/device/detail"
761+
if V1_Api:
762+
path = _ENDPOINT_OA_DEVICE_DETAIL_V1
763+
_LOGGER.debug("Device Detail using V1 API")
764+
else:
765+
path = _ENDPOINT_OA_DEVICE_DETAIL
766+
756767
headerData = GetAuth().get_signature(token=apiKey, path=path)
757768

758-
path = _ENDPOINT_OA_DOMAIN + _ENDPOINT_OA_DEVICE_DETAIL
769+
path = _ENDPOINT_OA_DOMAIN + path + "?sn="
759770
_LOGGER.debug("OADevice Detail fetch %s%s", path, devicesn)
760771
timestamp = round(time.time() * 1000)
761772

@@ -1697,6 +1708,66 @@ def native_value(self) -> str | None:
16971708
return energycharge
16981709
return None
16991710

1711+
class FoxESSMaxBatChargeCurrent(CoordinatorEntity, SensorEntity):
1712+
_attr_state_class: SensorStateClass = SensorStateClass.MEASUREMENT
1713+
_attr_device_class = SensorDeviceClass.CURRENT
1714+
_attr_native_unit_of_measurement = UnitOfElectricCurrent.AMPERE
1715+
1716+
def __init__(self, coordinator, name, deviceID):
1717+
super().__init__(coordinator=coordinator)
1718+
_LOGGER.debug("Initiating Entity - Max Bat Charge Current")
1719+
self._attr_name = name + " - Max Bat Charge Current"
1720+
self._attr_unique_id = deviceID + "max-bat-charge-charge"
1721+
self.status = namedtuple(
1722+
"status",
1723+
[
1724+
ATTR_DATE,
1725+
ATTR_TIME,
1726+
],
1727+
)
1728+
1729+
@property
1730+
def native_value(self) -> str | None:
1731+
if "maxChargeCurrent" not in self.coordinator.data["raw"]:
1732+
_LOGGER.debug("report maxChargeCurrent None")
1733+
else:
1734+
if self.coordinator.data["raw"]["maxChargeCurrent"] == 0:
1735+
charge = 0
1736+
else:
1737+
charge = self.coordinator.data["raw"]["maxChargeCurrent"]
1738+
return charge
1739+
return None
1740+
1741+
class FoxESSMaxBatDischargeCurrent(CoordinatorEntity, SensorEntity):
1742+
_attr_state_class: SensorStateClass = SensorStateClass.MEASUREMENT
1743+
_attr_device_class = SensorDeviceClass.CURRENT
1744+
_attr_native_unit_of_measurement = UnitOfElectricCurrent.AMPERE
1745+
1746+
def __init__(self, coordinator, name, deviceID):
1747+
super().__init__(coordinator=coordinator)
1748+
_LOGGER.debug("Initiating Entity - Max Bat Discharge Current")
1749+
self._attr_name = name + " - Max Bat Discharge Current"
1750+
self._attr_unique_id = deviceID + "max-bat-discharge-charge"
1751+
self.status = namedtuple(
1752+
"status",
1753+
[
1754+
ATTR_DATE,
1755+
ATTR_TIME,
1756+
],
1757+
)
1758+
1759+
@property
1760+
def native_value(self) -> str | None:
1761+
if "maxDischargeCurrent" not in self.coordinator.data["raw"]:
1762+
_LOGGER.debug("report maxDischargeCurrent None")
1763+
else:
1764+
if self.coordinator.data["raw"]["maxDischargeCurrent"] == 0:
1765+
charge = 0
1766+
else:
1767+
charge = self.coordinator.data["raw"]["maxDischargeCurrent"]
1768+
return charge
1769+
return None
1770+
17001771

17011772
class FoxESSEnergyBatDischarge(CoordinatorEntity, SensorEntity):
17021773
_attr_state_class: SensorStateClass = SensorStateClass.TOTAL_INCREASING

0 commit comments

Comments
 (0)