Sync library with live findings: raw socket docs, wire reply parsing, pack-id BMS, empty-slot guard
This commit is contained in:
1 parent
3d59a75f14
commit
c11188dd0b
6 files changed
+83
-31
No files matched your search
@@ -125,6 +125,23 @@ def _soc_detail(data: Dict[str, Any]) -> Dict[str, Any]:
|
||||
return detail
|
||||
|
||||
|
||||
def _is_empty_pack(reply: Dict[str, Any], result: Dict[str, Any]) -> bool:
|
||||
"""True when a BMS reply is the all-zero placeholder slot.
|
||||
|
||||
A genuine 0 % pack still reports health/voltage (``batSoh``,
|
||||
``batTotalVolt``); the unaddressed ``id: 0`` slot reports literal
|
||||
zeros with ``result == 0``. Returning ``0.0`` for that slot would
|
||||
mask the real packs, so the caller keeps probing instead.
|
||||
"""
|
||||
if result.get("source") != "batSoc" or result.get("value") != 0:
|
||||
return False
|
||||
data = reply.get("dataArea", reply)
|
||||
if not isinstance(data, dict):
|
||||
return False
|
||||
return (data.get("result") == 0 and data.get("batSoh") == 0
|
||||
and data.get("batTotalVolt") == 0)
|
||||
|
||||
|
||||
def get_battery(
|
||||
sn: str,
|
||||
host: str = "10.100.1.1",
|
||||
@@ -175,7 +192,8 @@ def get_battery(
|
||||
continue
|
||||
result = extract_soc(reply)
|
||||
result.update({"cmd": str(cmd), "port": port, "reply": reply})
|
||||
if result["value"] is not None:
|
||||
if result["value"] is not None and not _is_empty_pack(
|
||||
reply, result):
|
||||
return result
|
||||
last_err = ValueError(f"reply on port {port} cmd {cmd} has no SoC field")
|
||||
raise ConnectionError(f"no battery reply via {host}:{list(ports)}") from last_err
|
||||
@@ -279,7 +297,7 @@ def probe_transport(
|
||||
prefixes (LE16/BE16/LE32), an MQTT CONNECT, and a double-send over one
|
||||
persistent connection. Each entry carries exact ``tx``/``rx`` bytes.
|
||||
"""
|
||||
from .protocol import decrypt_data
|
||||
from .protocol import decrypt_wire
|
||||
|
||||
results: List[Dict[str, Any]] = []
|
||||
for port in ports:
|
||||
@@ -312,7 +330,10 @@ def probe_transport(
|
||||
except (ConnectionError, socket.error, TimeoutError) as exc:
|
||||
entry["error"] = f"{type(exc).__name__}: {exc}"
|
||||
if entry["rx"]:
|
||||
decoded = decrypt_data(entry["rx"], radix=key_radix)
|
||||
try:
|
||||
decoded = decrypt_wire(entry["rx"], radix=key_radix)
|
||||
except ValueError:
|
||||
decoded = ""
|
||||
if decoded:
|
||||
try:
|
||||
entry["reply"] = json.loads(decoded)
|
||||
|
||||
Reference in new issue
Block a user