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 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!" [ $(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 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! 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 Required python modules
----------------------- -----------------------
Some modules are not installed by default on a RaspberryPi, therefore add them manually: Some modules are not installed by default on a RaspberryPi, therefore add them manually:
``` ```code
pip install crcmod pyyaml paho-mqtt SunTimes pip install crcmod pyyaml paho-mqtt SunTimes
``` ```
@ -122,7 +123,7 @@ Python parameters
The application describes itself The application describes itself
``` ```code
python3 -m hoymiles --help python3 -m hoymiles --help
usage: hoymiles [-h] -c [CONFIG_FILE] [--log-transactions] [--verbose] 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 model = self.inverter_model
command = self.request_command command = self.request_command
c_datetime = self.time_rx.strftime("%Y-%m-%d %H:%M:%S.%f") if HOYMILES_DEBUG_LOGGING:
logging.info(f'{c_datetime} model_decoder: {model}Decode{command.upper()}') 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') model_decoders = __import__('hoymiles.decoders')
if hasattr(model_decoders, f'{model}Decode{command.upper()}'): if hasattr(model_decoders, f'{model}Decode{command.upper()}'):
device = getattr(model_decoders, f'{model}Decode{command.upper()}') device = getattr(model_decoders, f'{model}Decode{command.upper()}')
else: else:
if HOYMILES_DEBUG_LOGGING: device = getattr(model_decoders, 'DebugDecodeAny')
device = getattr(model_decoders, 'DebugDecodeAny')
return device(self.response, return device(self.response,
time_rx=self.time_rx, 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 # Handle the response data if any
if response: if response:
c_datetime = datetime.now()
if hoymiles.HOYMILES_DEBUG_LOGGING: if hoymiles.HOYMILES_DEBUG_LOGGING:
c_datetime = datetime.now()
logging.debug(f'{c_datetime} Payload: ' + hoymiles.hexify_payload(response)) logging.debug(f'{c_datetime} Payload: ' + hoymiles.hexify_payload(response))
# prepare decoder object # prepare decoder object
@ -195,6 +195,7 @@ def poll_inverter(inverter, dtu_ser, do_init, retries):
# get decoder object # get decoder object
result = decoder.decode() result = decoder.decode()
if hoymiles.HOYMILES_DEBUG_LOGGING: if hoymiles.HOYMILES_DEBUG_LOGGING:
c_datetime = datetime.now()
logging.info(f'{c_datetime} Decoded: {result.__dict__()}') logging.info(f'{c_datetime} Decoded: {result.__dict__()}')
# check decoder object for output # check decoder object for output

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

@ -110,6 +110,9 @@ class StatusResponse(Response):
:rtype: tuple :rtype: tuple
""" """
size = struct.calcsize(fmt) 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]) return struct.unpack(fmt, self.response[base:base+size])
@property @property
@ -331,10 +334,12 @@ class EventsResponse(UnknownResponse):
logging.debug(' '.join([f'{byte:02x}' for byte in chunk]) + ': ') logging.debug(' '.join([f'{byte:02x}' for byte in chunk]) + ': ')
opcode, a_code, a_count, uptime_sec = struct.unpack('>BBHH', chunk[0:6]) if (len(chunk[0:6]) == 6):
a_text = self.alarm_codes.get(a_code, 'N/A') 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}') 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 = '' dbg = ''
for fmt in ['BBHHHHH']: for fmt in ['BBHHHHH']:
@ -362,7 +367,10 @@ class HardwareInfoResponse(UnknownResponse):
""" Base values, availabe in each __dict__ call """ """ Base values, availabe in each __dict__ call """
responce_info = self.response 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]) fw_version, fw_build_yyyy, fw_build_mmdd, fw_build_hhmm, hw_id = struct.unpack('>HHHHH', self.response[0:10])

Loading…
Cancel
Save