Retry on read error

This commit is contained in:
Odd Stråbø 2021-11-18 23:38:52 +01:00
parent 57709242fa
commit b008f524bf

View file

@ -6,7 +6,7 @@ import struct
import sys import sys
import time import time
from io import RawIOBase from io import RawIOBase
from typing import Collection, Optional, cast from typing import Callable, Collection, Optional, cast
from bluepy import btle from bluepy import btle
from libscrc import modbus from libscrc import modbus
@ -293,6 +293,27 @@ class Periodical:
return False 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__": if __name__ == "__main__":
conf = get_config() conf = get_config()
consumers = get_consumers(conf) consumers = get_consumers(conf)
@ -304,7 +325,7 @@ if __name__ == "__main__":
while True: while True:
try: try:
log("Connecting...") log("Connecting...")
with BTLEUart(MAC, timeout=10) as dev: with BTLEUart(MAC, timeout=5) as dev:
log("Connected.") log("Connected.")
# write(dev, construct_request(0, 32)) # write(dev, construct_request(0, 32))
@ -314,58 +335,45 @@ if __name__ == "__main__":
# 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 days = 7
res = readMemory(dev, 0x010B, 21) res = try_read_parse(dev, 0x010B, 21, parse_historical_entry)
if res: if res:
d = parse_historical_entry(res) log(res)
log(d)
for consumer in consumers: for consumer in consumers:
consumer.write(d) consumer.write(res)
days = cast(int, d.get("run_days", 7)) days = cast(int, res.get("run_days", 7))
for i in range(days): for i in range(days):
res = readMemory(dev, 0xF000 + i, 10) res = try_read_parse(
dev, 0xF000 + i, 10, parse_historical_entry
)
if res: if res:
d = parse_historical_entry(res) log({i: res})
log({i: d})
for consumer in consumers: for consumer in consumers:
consumer.write({str(i): d}) consumer.write({str(i): res})
while True: while True:
now = time.time() now = time.time()
if per_voltages(now): if per_voltages(now):
# CMD_GET_BATTERY_STATE + CMD_GET_PANEL_STATUS data = try_read_parse(dev, 0x0100, 11, parse_battery_state)
res = readMemory(dev, 0x0100, 11) if data:
if res: log(data)
try: for consumer in consumers:
d = parse_battery_state(res) consumer.write(data)
log(d)
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),
)
if per_current_hist(now): if per_current_hist(now):
res = readMemory(dev, 0x010B, 21) data = try_read_parse(
if res: dev, 0x010B, 21, parse_historical_entry
try: )
d = parse_historical_entry(res) if data:
log(d) log(data)
for consumer in consumers: for consumer in consumers:
consumer.write(d) consumer.write(data)
except struct.error as e:
log(e)
log("0x010B Unpack error:", len(res), res)
log(
"Flushed from read buffer; ",
dev.read(timeout=0.5),
)
# 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'):