Fix unpack, rework main to use ChargeController

This commit is contained in:
Odd Stråbø 2023-12-10 16:08:28 +01:00
parent f0c2057428
commit fe9c6a82ff
4 changed files with 38 additions and 57 deletions

View file

@ -20,7 +20,7 @@ HISTORICAL_KEYS = {
DataName.BATTERY_VOLTAGE_MIN, DataName.BATTERY_VOLTAGE_MIN,
DataName.BATTERY_VOLTAGE_MAX, DataName.BATTERY_VOLTAGE_MAX,
DataName.CHARGE_MAX_CURRENT, DataName.CHARGE_MAX_CURRENT,
DataName._DISCHARGE_MAX_CURRENT, DataName.DISCHARGE_MAX_CURRENT,
DataName.CHARGE_MAX_POWER, DataName.CHARGE_MAX_POWER,
DataName.DISCHARGE_MAX_POWER, DataName.DISCHARGE_MAX_POWER,
DataName.CHARGE_AMP_HOUR, DataName.CHARGE_AMP_HOUR,
@ -58,7 +58,7 @@ KNOWN_KEYS = HISTORICAL_KEYS.union(INSTANT_KEYS)
MAP = { MAP = {
"_internal_temperature?": "internal_temp", "_internal_temperature?": "internal_temp",
"unknown1": "charge_max_current", "unknown1": "charge_max_current",
"unknown2": "_discharge_max_current?", "unknown2": "discharge_max_current",
"internal_temperature": "internal_temp", "internal_temperature": "internal_temp",
"battery_temperature": "battery_temp", "battery_temperature": "battery_temp",
} }

View file

@ -2,15 +2,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import time import time
from decimal import Decimal
from typing import cast
from bluepy.btle import BTLEDisconnectError # type: ignore from bluepy.btle import BTLEDisconnectError # type: ignore
from serial import SerialException # type: ignore from serial import SerialException # type: ignore
from .config import get_config, get_consumers, get_interface from .config import get_config, get_consumers, get_interface
from .protocol import parse_battery_state, parse_historical_entry, try_read_parse from .protocol import ChargeController
from .solar_types import DataName
from .util import Periodical, log from .util import Periodical, log
@ -35,67 +32,51 @@ def main():
with get_interface() as dev: with get_interface() as dev:
log("Connected.") log("Connected.")
cc = ChargeController(dev)
# write(dev, construct_request(0, 32)) # write(dev, construct_request(0, 32))
# Memory dump # Memory dump
# for address in range(0, 0x10000, 16): # for address in range(0, 0x10000, 16):
# log(f"Reading 0x{address:04X}...") # log(f"Reading 0x{address:04X}...")
# write(wd, construct_request(address, 16)) # write(wd, construct_request(address, 16))
days = 7 extra = cc.extra
res = try_read_parse(dev, 0x010B, 21, parse_historical_entry) days = extra.run_days
if res:
log(res) res = cc.today.as_dict()
for consumer in consumers: res.update(extra.as_dict())
consumer.write(res) for consumer in consumers:
days = cast(int, res.get("run_days", 7)) consumer.write(res)
del extra
for i in range(days): for i in range(days):
res = try_read_parse( hist = cc.get_historical(i)
dev, 0xF000 + i, 10, parse_historical_entry res = hist.as_dict()
) log({i: res})
if res: for consumer in consumers:
log({i: res}) consumer.write({str(i): res})
for consumer in consumers:
consumer.write({str(i): res})
while True: while True:
now = time.time() now = time.time()
if per_voltages(now): if per_voltages(now):
data = try_read_parse(dev, 0x0100, 11, parse_battery_state) data = cc.state.as_dict()
if data: log(data)
data[DataName.CALCULATED_BATTERY_POWER] = float( for consumer in consumers:
Decimal(str(data.get(DataName.BATTERY_VOLTAGE, 0))) consumer.write(data)
* Decimal(
str(data.get(DataName.BATTERY_CURRENT, 0))
)
)
data[DataName.CALCULATED_PANEL_POWER] = float(
Decimal(str(data.get(DataName.PANEL_VOLTAGE, 0)))
* Decimal(str(data.get(DataName.PANEL_CURRENT, 0)))
)
data[DataName.CALCULATED_LOAD_POWER] = float(
Decimal(str(data.get(DataName.LOAD_VOLTAGE, 0)))
* Decimal(str(data.get(DataName.LOAD_CURRENT, 0)))
)
log(data)
for consumer in consumers:
consumer.write(data)
if per_current_hist(now): if per_current_hist(now):
data = try_read_parse( data = cc.today.as_dict()
dev, 0x010B, 21, parse_historical_entry data.update(cc.extra.as_dict())
) log(data)
if data: for consumer in consumers:
log(data) consumer.write(data)
for consumer in consumers:
consumer.write(data)
# print(".") # print(".")
for consumer in consumers: for consumer in consumers:
consumer.poll() consumer.poll()
time.sleep(max(0, 1 - time.time() - now)) time.sleep(max(0, 1 - (time.time() - now)))
# if STATUS.get('load_enabled'): # if STATUS.get('load_enabled'):
# write(wd, CMD_DISABLE_LOAD) # write(wd, CMD_DISABLE_LOAD)

View file

@ -13,7 +13,7 @@ MAP_VALUES: Dict[DataName, Dict[str, Any]] = {
# DataName.BATTERY_VOLTAGE_MIN: {}, # DataName.BATTERY_VOLTAGE_MIN: {},
# DataName.BATTERY_VOLTAGE_MAX: {}, # DataName.BATTERY_VOLTAGE_MAX: {},
# DataName.CHARGE_MAX_CURRENT: {}, # DataName.CHARGE_MAX_CURRENT: {},
# DataName._DISCHARGE_MAX_CURRENT: {}, # DataName.DISCHARGE_MAX_CURRENT: {},
# DataName.CHARGE_MAX_POWER: {}, # DataName.CHARGE_MAX_POWER: {},
# DataName.DISCHARGE_MAX_POWER: {}, # DataName.DISCHARGE_MAX_POWER: {},
# DataName.CHARGE_AMP_HOUR: {}, # DataName.CHARGE_AMP_HOUR: {},

View file

@ -22,7 +22,7 @@ class DataName(str, Enum):
BATTERY_VOLTAGE_MIN = "battery_voltage_min" BATTERY_VOLTAGE_MIN = "battery_voltage_min"
BATTERY_VOLTAGE_MAX = "battery_voltage_max" BATTERY_VOLTAGE_MAX = "battery_voltage_max"
CHARGE_MAX_CURRENT = "charge_max_current" CHARGE_MAX_CURRENT = "charge_max_current"
_DISCHARGE_MAX_CURRENT = "_discharge_max_current?" DISCHARGE_MAX_CURRENT = "discharge_max_current"
CHARGE_MAX_POWER = "charge_max_power" CHARGE_MAX_POWER = "charge_max_power"
DISCHARGE_MAX_POWER = "discharge_max_power" DISCHARGE_MAX_POWER = "discharge_max_power"
CHARGE_AMP_HOUR = "charge_amp_hour" CHARGE_AMP_HOUR = "charge_amp_hour"
@ -105,7 +105,7 @@ HISTORICAL_DATA = [
DataItem(DataName.BATTERY_VOLTAGE_MIN, "H", "V", lambda n: n / 10), DataItem(DataName.BATTERY_VOLTAGE_MIN, "H", "V", lambda n: n / 10),
DataItem(DataName.BATTERY_VOLTAGE_MAX, "H", "V", lambda n: n / 10), DataItem(DataName.BATTERY_VOLTAGE_MAX, "H", "V", lambda n: n / 10),
DataItem(DataName.CHARGE_MAX_CURRENT, "H", "A", lambda n: n / 100), DataItem(DataName.CHARGE_MAX_CURRENT, "H", "A", lambda n: n / 100),
DataItem(DataName._DISCHARGE_MAX_CURRENT, "H", "A", lambda n: n / 100), DataItem(DataName.DISCHARGE_MAX_CURRENT, "H", "A", lambda n: n / 100),
DataItem(DataName.CHARGE_MAX_POWER, "H", "W"), DataItem(DataName.CHARGE_MAX_POWER, "H", "W"),
DataItem(DataName.DISCHARGE_MAX_POWER, "H", "W"), DataItem(DataName.DISCHARGE_MAX_POWER, "H", "W"),
DataItem(DataName.CHARGE_AMP_HOUR, "H", "Ah"), DataItem(DataName.CHARGE_AMP_HOUR, "H", "Ah"),
@ -161,7 +161,7 @@ class ChargerState(DecodedData):
_panel_current, _panel_current,
_panel_power, _panel_power,
_load_enabled, _load_enabled,
) = struct.unpack("HHHBBHHHHHHx?", data) ) = struct.unpack("!HHHBBHHHHHHx?", data)
self.battery_charge = _battery_charge self.battery_charge = _battery_charge
self.battery_voltage = _battery_voltage / 10 self.battery_voltage = _battery_voltage / 10
@ -212,7 +212,7 @@ class HistoricalData(DecodedData):
battery_voltage_min: float battery_voltage_min: float
battery_voltage_max: float battery_voltage_max: float
charge_max_current: float charge_max_current: float
_discharge_max_current: float discharge_max_current: float
charge_max_power: int charge_max_power: int
discharge_max_power: int discharge_max_power: int
charge_amp_hour: int charge_amp_hour: int
@ -225,19 +225,19 @@ class HistoricalData(DecodedData):
_battery_voltage_min, _battery_voltage_min,
_battery_voltage_max, _battery_voltage_max,
_charge_max_current, _charge_max_current,
__discharge_max_current, _discharge_max_current,
_charge_max_power, _charge_max_power,
_discharge_max_power, _discharge_max_power,
_charge_amp_hour, _charge_amp_hour,
_discharge_amp_hour, _discharge_amp_hour,
_production_energy, _production_energy,
_consumption_energy, _consumption_energy,
) = struct.unpack("HHHHHHHHHH", data) ) = struct.unpack("!HHHHHHHHHH", data)
self.battery_voltage_min = _battery_voltage_min / 10 self.battery_voltage_min = _battery_voltage_min / 10
self.battery_voltage_max = _battery_voltage_max / 10 self.battery_voltage_max = _battery_voltage_max / 10
self.charge_max_current = _charge_max_current / 100 self.charge_max_current = _charge_max_current / 100
self._discharge_max_current = __discharge_max_current / 100 self.discharge_max_current = _discharge_max_current / 100
self.charge_max_power = _charge_max_power self.charge_max_power = _charge_max_power
self.discharge_max_power = _discharge_max_power self.discharge_max_power = _discharge_max_power
self.charge_amp_hour = _charge_amp_hour self.charge_amp_hour = _charge_amp_hour
@ -250,7 +250,7 @@ class HistoricalData(DecodedData):
DataName.BATTERY_VOLTAGE_MIN: self.battery_voltage_min, DataName.BATTERY_VOLTAGE_MIN: self.battery_voltage_min,
DataName.BATTERY_VOLTAGE_MAX: self.battery_voltage_max, DataName.BATTERY_VOLTAGE_MAX: self.battery_voltage_max,
DataName.CHARGE_MAX_CURRENT: self.charge_max_current, DataName.CHARGE_MAX_CURRENT: self.charge_max_current,
DataName._DISCHARGE_MAX_CURRENT: self._discharge_max_current, DataName.DISCHARGE_MAX_CURRENT: self.discharge_max_current,
DataName.CHARGE_MAX_POWER: self.charge_max_power, DataName.CHARGE_MAX_POWER: self.charge_max_power,
DataName.DISCHARGE_MAX_POWER: self.discharge_max_power, DataName.DISCHARGE_MAX_POWER: self.discharge_max_power,
DataName.CHARGE_AMP_HOUR: self.charge_amp_hour, DataName.CHARGE_AMP_HOUR: self.charge_amp_hour,
@ -278,7 +278,7 @@ class HistoricalExtraInfo(DecodedData):
_total_discharge_amp_hours, _total_discharge_amp_hours,
_total_production_energy, _total_production_energy,
_total_consumption_energy, _total_consumption_energy,
) = struct.unpack("HHHLLLL", data) ) = struct.unpack("!HHHLLLL", data)
self.run_days = _run_days self.run_days = _run_days
self.discharge_count = _discharge_count self.discharge_count = _discharge_count