Browse Source

RPI:error handling while getting corruppted data

extended error handling while getting corruppted data on 64 bit operating system (bullseye)
lots of currupted data are reseived on Debian 11 OS. So we have to check the data length before using strict.unpack
pull/641/head
Knuti_in_Paese 2 years ago
parent
commit
0d552e3007
  1. 13
      tools/rpi/README.md
  2. 8
      tools/rpi/hoymiles/__init__.py
  3. 3
      tools/rpi/hoymiles/__main__.py
  4. 18
      tools/rpi/hoymiles/decoders/__init__.py

13
tools/rpi/README.md

@ -78,8 +78,12 @@ cd examples_linux/
python3 getting_started.py # to test and see whether RF24 class can be loaded as module in python correctly
```
If there are no error messages on the last step, then the NRF24 Wrapper has been installed successfully.
``` for bullseye - Debian 11 on 64 bit operating system
for Debian 11 (bullseye) 64 bit operating system
-------------------------------------------------
```code
[ $(lscpu | grep Architecture | awk '{print $2}') != "aarch64" ]] && echo "Not a 64 bit architecture for this step!"
git clone --recurse-submodules https://github.com/nRF24/pyRF24.git
@ -87,15 +91,12 @@ cd pyRF24
python -m pip install . -v # this step takes about 5 minutes!
```
If there are no error messages on the last step, then the NRF24 Wrapper has been installed successfully.
Required python modules
-----------------------
Some modules are not installed by default on a RaspberryPi, therefore add them manually:
```
```code
pip install crcmod pyyaml paho-mqtt SunTimes
```
@ -122,7 +123,7 @@ Python parameters
The application describes itself
```
```code
python3 -m hoymiles --help
usage: hoymiles [-h] -c [CONFIG_FILE] [--log-transactions] [--verbose]

8
tools/rpi/hoymiles/__init__.py

@ -170,15 +170,15 @@ class ResponseDecoder(ResponseDecoderFactory):
model = self.inverter_model
command = self.request_command
c_datetime = self.time_rx.strftime("%Y-%m-%d %H:%M:%S.%f")
logging.info(f'{c_datetime} model_decoder: {model}Decode{command.upper()}')
if HOYMILES_DEBUG_LOGGING:
c_datetime = self.time_rx.strftime("%Y-%m-%d %H:%M:%S.%f")
logging.info(f'{c_datetime} model_decoder: {model}Decode{command.upper()}')
model_decoders = __import__('hoymiles.decoders')
if hasattr(model_decoders, f'{model}Decode{command.upper()}'):
device = getattr(model_decoders, f'{model}Decode{command.upper()}')
else:
if HOYMILES_DEBUG_LOGGING:
device = getattr(model_decoders, 'DebugDecodeAny')
device = getattr(model_decoders, 'DebugDecodeAny')
return device(self.response,
time_rx=self.time_rx,

3
tools/rpi/hoymiles/__main__.py

@ -179,8 +179,8 @@ def poll_inverter(inverter, dtu_ser, do_init, retries):
# Handle the response data if any
if response:
c_datetime = datetime.now()
if hoymiles.HOYMILES_DEBUG_LOGGING:
c_datetime = datetime.now()
logging.debug(f'{c_datetime} Payload: ' + hoymiles.hexify_payload(response))
# prepare decoder object
@ -195,6 +195,7 @@ def poll_inverter(inverter, dtu_ser, do_init, retries):
# get decoder object
result = decoder.decode()
if hoymiles.HOYMILES_DEBUG_LOGGING:
c_datetime = datetime.now()
logging.info(f'{c_datetime} Decoded: {result.__dict__()}')
# check decoder object for output

18
tools/rpi/hoymiles/decoders/__init__.py

@ -110,6 +110,9 @@ class StatusResponse(Response):
:rtype: tuple
"""
size = struct.calcsize(fmt)
if (len(self.response) < base+size):
logging.error(f'base: {base} size: {size} len: {len(self.response)} fmt: {fmt} rep: {self.response}')
return [0]
return struct.unpack(fmt, self.response[base:base+size])
@property
@ -331,10 +334,12 @@ class EventsResponse(UnknownResponse):
logging.debug(' '.join([f'{byte:02x}' for byte in chunk]) + ': ')
opcode, a_code, a_count, uptime_sec = struct.unpack('>BBHH', chunk[0:6])
a_text = self.alarm_codes.get(a_code, 'N/A')
logging.debug(f' uptime={timedelta(seconds=uptime_sec)} a_count={a_count} opcode={opcode} a_code={a_code} a_text={a_text}')
if (len(chunk[0:6]) == 6):
opcode, a_code, a_count, uptime_sec = struct.unpack('>BBHH', chunk[0:6])
a_text = self.alarm_codes.get(a_code, 'N/A')
logging.debug(f' uptime={timedelta(seconds=uptime_sec)} a_count={a_count} opcode={opcode} a_code={a_code} a_text={a_text}')
else:
logging.error(f'length of chunk must be greater or equal 6 bytes: {chunk}')
dbg = ''
for fmt in ['BBHHHHH']:
@ -362,7 +367,10 @@ class HardwareInfoResponse(UnknownResponse):
""" Base values, availabe in each __dict__ call """
responce_info = self.response
logging.info(f'HardwareInfoResponse: {struct.unpack(">HHHHHHHH", responce_info)}')
if (len(responce_info) >= 16):
logging.info(f'HardwareInfoResponse: {struct.unpack(">HHHHHHHH", responce_info)}')
else:
logging.error(f'wrong length of HardwareInfoResponse: {responce_info}')
fw_version, fw_build_yyyy, fw_build_mmdd, fw_build_hhmm, hw_id = struct.unpack('>HHHHH', self.response[0:10])

Loading…
Cancel
Save