Skip to content

Commit

Permalink
fix: rounding of whole numbers (integers)
Browse files Browse the repository at this point in the history
fix: Properly handle uint of custom sensors
fix: readme.md feature set updated according to the recent changes
  • Loading branch information
davidrapan committed Jul 16, 2024
1 parent 09426ff commit bd2a1a1
Show file tree
Hide file tree
Showing 7 changed files with 17 additions and 16 deletions.
3 changes: 3 additions & 0 deletions custom_components/solarman/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ def format_exception(e):
def Raise(exception) -> None:
raise exception

def get_number(value, digits):
return int(value) if isinstance(value, int) or (isinstance(value, float) and value.is_integer()) else (n if (n := round(value, digits)) and not n.is_integer() else int(n))

def get_request_code(request):
return request[REQUEST_CODE] if REQUEST_CODE in request else request[REQUEST_CODE_ALT]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1361,6 +1361,7 @@ parameters:
rule: 1
digits: 0
registers: [0x024E, 0x02A0, 0x02A1, 0x02A2, 0x02A3, 0x027C, 0x02B6]
uint: enforce
sensors:
- signed:
scale: 10
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1376,6 +1376,7 @@ parameters:
rule: 1
digits: 0
registers: [0x024E, 0x02A0, 0x02A1, 0x02A2, 0x02A3, 0x027C, 0x02B6]
uint: enforce
sensors:
- signed:
registers: [0x024E]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1379,6 +1379,7 @@ parameters:
rule: 1
digits: 0
registers: [0x024E, 0x02A0, 0x02A1, 0x02A2, 0x02A3, 0x027C, 0x02B6]
uint: enforce
sensors:
- signed:
registers: [0x024E]
Expand Down
13 changes: 5 additions & 8 deletions custom_components/solarman/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,6 @@ def set_state(self, key, value):
self._result[key] = {}
self._result[key]["state"] = value

def set_state_number(self, key, value, digits):
if isinstance(value, int) or (isinstance(value, float) and value.is_integer()):
self.set_state(key, int(value))
else:
self.set_state(key, round(value, digits))

def get_sensors(self):
result = [{"name": "Connection Status", "artificial": ""}]
for i in self.lookup():
Expand Down Expand Up @@ -242,6 +236,9 @@ def try_parse_unsigned(self, rawData, definition, start, length):
found = value is not None

if found:
if "uint" in definition and value < 0:
value = 0

if "lookup" in definition:
self.set_state(key, self.lookup_value(value, definition["lookup"]))
self._result[key]["value"] = int(value)
Expand All @@ -250,7 +247,7 @@ def try_parse_unsigned(self, rawData, definition, start, length):
if not self.do_validate(key, value, definition["validation"]):
return

self.set_state_number(key, value, definition["digits"] if "digits" in definition else self._digits)
self.set_state(key, get_number(value, definition["digits"] if "digits" in definition else self._digits))

return

Expand All @@ -263,7 +260,7 @@ def try_parse_signed(self, rawData, definition, start, length):
if not self.do_validate(key, value, definition["validation"]):
return

self.set_state_number(key, value, definition["digits"] if "digits" in definition else self._digits)
self.set_state(key, get_number(value, definition["digits"] if "digits" in definition else self._digits))

return

Expand Down
7 changes: 3 additions & 4 deletions custom_components/solarman/sensor.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from __future__ import annotations

import re
import logging
import asyncio
import voluptuous as vol
Expand Down Expand Up @@ -255,7 +254,7 @@ def update(self):
total_battery_charge = self.get_data("Total Battery Charge", None)
today_battery_charge = self.get_data("Today Battery Charge", None)
if total_battery_charge and battery_capacity and self._battery_nominal_voltage and self._battery_life_cycle_rating:
self._attr_state = round(100 - total_battery_charge / get_battery_power_capacity(battery_capacity, self._battery_nominal_voltage) / (self._battery_life_cycle_rating * 0.05), self._digits)
self._attr_state = get_number(100 - total_battery_charge / get_battery_power_capacity(battery_capacity, self._battery_nominal_voltage) / (self._battery_life_cycle_rating * 0.05), self._digits)
case "Battery State":
battery_power = self.get_data("Battery Power", None)
if battery_power:
Expand All @@ -265,10 +264,10 @@ def update(self):
total_battery_charge = self.get_data("Total Battery Charge", None)
today_battery_charge = self.get_data("Today Battery Charge", None)
if today_battery_charge and battery_capacity and self._battery_nominal_voltage:
self._attr_state = round(get_battery_cycles(today_battery_charge, battery_capacity, self._battery_nominal_voltage), self._digits)
self._attr_state = get_number(get_battery_cycles(today_battery_charge, battery_capacity, self._battery_nominal_voltage), self._digits)
case "Total Battery Life Cycles":
battery_capacity = self.get_data("Battery Capacity", None)
total_battery_charge = self.get_data("Total Battery Charge", None)
today_battery_charge = self.get_data("Today Battery Charge", None)
if total_battery_charge and battery_capacity and self._battery_nominal_voltage:
self._attr_state = round(get_battery_cycles(total_battery_charge, battery_capacity, self._battery_nominal_voltage), self._digits)
self._attr_state = get_number(get_battery_cycles(total_battery_charge, battery_capacity, self._battery_nominal_voltage), self._digits)
7 changes: 3 additions & 4 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@
> - Fetching is implemented through DataUpdateCoordinator + incorporates many more up to date features of HA
> - Improved stability (no more disconnects and missing values)
> - Discovery and not just for configuration but also as part of initialization (i.e. adapts to changed IP)
> - Registers which are requested are decided dynamically (when missing from the inverter definition file)
> - Different registers can be requested in different intervals according to their 'update_interval' set in inverter definition file
> - New Inverter profiles features **See 'deye_sg04lp3.yaml' for examples*:
> - Different registers can be requested in different intervals according to their 'update_interval' set in inverter definition file
> - Registers which will be part of a request are decided dynamically (when missing from the inverter definition file)
> - Added attribute type of a sensor which can be attached to any other sensor
> - Added template sensors defined by simple formulas and parameters which are then evaluated during runtime
> - Added configuration for Battery Nominal Voltage and Battery Life Cycle Rating for calculating SOH of the battery
> - Added configuration for Battery Nominal Voltage and Battery Life Cycle Rating for calculating SOH and life cycles of the battery
> - And many more fixes and improvements (while trying to fully preserve backward compatibility)
> [!WARNING]
Expand Down

0 comments on commit bd2a1a1

Please sign in to comment.