Retry on read error

This commit is contained in:
Odd Stråbø 2021-11-18 23:38:52 +01:00
parent 57709242fa
commit b008f524bf
1 changed files with 48 additions and 40 deletions

View File

@ -6,7 +6,7 @@ import struct
import sys
import time
from io import RawIOBase
from typing import Collection, Optional, cast
from typing import Callable, Collection, Optional, cast
from bluepy import btle
from libscrc import modbus
@ -293,6 +293,27 @@ class Periodical:
return False
def try_read_parse(
dev: BTLEUart,
address: int,
words: int = 1,
parser: Callable = None,
attempts=5,
) -> Optional[dict]:
while attempts:
attempts -= 1
res = readMemory(dev, address, words)
if res:
try:
if parser:
return parser(res)
except struct.error as e:
log(e)
log("0x0100 Unpack error:", len(res), res)
log("Flushed from read buffer; ", dev.read(timeout=0.5))
return None
if __name__ == "__main__":
conf = get_config()
consumers = get_consumers(conf)
@ -304,7 +325,7 @@ if __name__ == "__main__":
while True:
try:
log("Connecting...")
with BTLEUart(MAC, timeout=10) as dev:
with BTLEUart(MAC, timeout=5) as dev:
log("Connected.")
# write(dev, construct_request(0, 32))
@ -314,58 +335,45 @@ if __name__ == "__main__":
# log(f"Reading 0x{address:04X}...")
# write(wd, construct_request(address, 16))
days = 7
res = readMemory(dev, 0x010B, 21)
res = try_read_parse(dev, 0x010B, 21, parse_historical_entry)
if res:
d = parse_historical_entry(res)
log(d)
log(res)
for consumer in consumers:
consumer.write(d)
days = cast(int, d.get("run_days", 7))
consumer.write(res)
days = cast(int, res.get("run_days", 7))
for i in range(days):
res = readMemory(dev, 0xF000 + i, 10)
res = try_read_parse(
dev, 0xF000 + i, 10, parse_historical_entry
)
if res:
d = parse_historical_entry(res)
log({i: d})
log({i: res})
for consumer in consumers:
consumer.write({str(i): d})
consumer.write({str(i): res})
while True:
now = time.time()
if per_voltages(now):
# CMD_GET_BATTERY_STATE + CMD_GET_PANEL_STATUS
res = readMemory(dev, 0x0100, 11)
if res:
try:
d = parse_battery_state(res)
log(d)
data = try_read_parse(dev, 0x0100, 11, parse_battery_state)
if data:
log(data)
for consumer in consumers:
consumer.write(d)
except struct.error as e:
log(e)
log("0x0100 Unpack error:", len(res), res)
log(
"Flushed from read buffer; ",
dev.read(timeout=0.5),
)
consumer.write(data)
if per_current_hist(now):
res = readMemory(dev, 0x010B, 21)
if res:
try:
d = parse_historical_entry(res)
log(d)
for consumer in consumers:
consumer.write(d)
except struct.error as e:
log(e)
log("0x010B Unpack error:", len(res), res)
log(
"Flushed from read buffer; ",
dev.read(timeout=0.5),
data = try_read_parse(
dev, 0x010B, 21, parse_historical_entry
)
if data:
log(data)
for consumer in consumers:
consumer.write(data)
# print(".")
for consumer in consumers:
consumer.poll()
time.sleep(max(0, 1 - time.time() - now))
# if STATUS.get('load_enabled'):