Skip to content

Commit

Permalink
refactor: Experimental Battery Capacity sensor - Deye
Browse files Browse the repository at this point in the history
  • Loading branch information
davidrapan committed Dec 20, 2024
1 parent 09058b6 commit 58409d6
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -689,12 +689,12 @@ parameters:
icon: "mdi:current-dc"

- name: "Battery Capacity"
description: Estimates capacity of the battery during charging
description: Estimates capacity of the battery during (dis)charging
class: "power"
state_class: "measurement"
uom: "kW"
rule: 0
digits: 2
digits: 1
icon: "mdi:battery-check"

- group: Grid
Expand Down
4 changes: 2 additions & 2 deletions custom_components/solarman/inverter_definitions/deye_p3.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1990,12 +1990,12 @@ parameters:

# Battery - Capacity
- name: "Battery Capacity"
description: Estimates capacity of the battery during charging
description: Estimates capacity of the battery during (dis)charging
class: "power"
state_class: "measurement"
uom: "kW"
rule: 0
digits: 2
digits: 1
icon: "mdi:battery-check"

# Battery - The state of battery
Expand Down
34 changes: 22 additions & 12 deletions custom_components/solarman/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,26 +118,36 @@ def __init__(self, coordinator, sensor, battery_nominal_voltage, battery_life_cy
class SolarmanBatteryCapacitySensor(SolarmanRestoreSensor):
def __init__(self, coordinator, sensor):
super().__init__(coordinator, sensor)
self._digits = sensor[DIGITS] if DIGITS in sensor else DEFAULT_[DIGITS]
self._states = []
self._temp = []

def update(self):
if (power := get_tuple(self.coordinator.data.get("battery_power_sensor"))) is not None:
if power > -500:
self._states = []
if (power := get_tuple(self.coordinator.data.get("battery_power_sensor"))) is not None and (is_charging := power < 0) is not None and (was_charging := (self._temp[-1][0] < 0) if len(self._temp) > 0 else is_charging) is not None:
if len(self._states) == 0 and self._attr_native_value is not None:
self._attr_extra_state_attributes["states"] = self._states = [float(self._attr_native_value)]
if (power > -300 and was_charging) or (power < 300 and not was_charging):
self._temp = []
return
if (soc := get_tuple(self.coordinator.data.get("battery_sensor"))) is not None and (tbc := get_tuple(self.coordinator.data.get("total_battery_charge_sensor"))) is not None:
self._states.append((power, soc, tbc))
h = l = (soc, tbc)
for i in reversed(self._states):
if (soc := get_tuple(self.coordinator.data.get("battery_sensor"))) is not None and (tb := get_tuple(self.coordinator.data.get("total_battery_charge_sensor" if is_charging else "total_battery_discharge_sensor"))) is not None:
self._temp.append((power, soc, tb))
h = m = l = s = (soc, tb)
for i in reversed(self._temp):
s = (i[1], i[2])
if h[1] > l[1] > s[1]:
if h[1] > m[1] > l[1] > s[1]:
break
if h[1] == s[1]:
h = l = s
if l[1] >= s[1]:
h = m = l = s
if m[1] == h[1] or m[1] == s[1]:
m = l = s
if l[1] == m[1] or l[1] == s[1]:
l = s
if h[1] > l[1] > s[1] and (diff := h[0] - l[0]) > 0:
self.set_state((h[1] - l[1]) * (100 / (diff)))
if h[1] > l[1] > s[1] and (diff := abs(h[0] - l[0])) > 0 and (state := get_number((h[1] - l[1]) * (100 / diff), self._digits)):
self._states.append(state)
self._attr_extra_state_attributes["states"] = self._states
self._temp = [(power, soc, tb)]
if (srtd := sorted(self._states)) and (c := srtd[1:-1] if len(srtd) > 2 else srtd):
self.set_state(get_number((sum(c) + self._states[0]) / (len(c) + 1), self._digits))

class SolarmanBatteryCustomSensor(SolarmanSensor):
def __init__(self, coordinator, sensor, battery_nominal_voltage, battery_life_cycle_rating):
Expand Down

0 comments on commit 58409d6

Please sign in to comment.