Browse Source

Merge pull request #1034 from PaeserBastelstube/main

RPi: crash while using multi inverters with diff num of strings
pull/1056/head
Lukas Pusch 1 year ago
committed by GitHub
parent
commit
1ae55252dd
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 41
      tools/rpi/hoymiles/__init__.py
  2. 20
      tools/rpi/hoymiles/__main__.py
  3. 2
      tools/rpi/hoymiles/decoders/__init__.py

41
tools/rpi/hoymiles/__init__.py

@ -179,20 +179,43 @@ class ResponseDecoder(ResponseDecoderFactory):
command = self.request_command
if HOYMILES_DEBUG_LOGGING:
if command.upper() == '01':
if command.upper() == '00':
model_desc = "Inverter Dev Inform Simple"
elif command.upper() == '01':
model_desc = "Firmware version / date"
elif command.upper() == '02':
model_desc = "Inverter generic events log"
elif command.upper() == '05':
elif command.upper() == '03': ## HardWareConfig
model_desc = "Hardware configuration"
elif command.upper() == '04': ## SimpleCalibrationPara
model_desc = "Simple Calibration Parameter"
elif command.upper() == '05': ## SystemConfigPara
model_desc = "Inverter generic SystemConfigPara"
elif command.upper() == '0B':
elif command.upper() == '0B': ## 11 - RealTimeRunData_Debug
model_desc = "mirco-inverters status data"
elif command.upper() == '0C':
elif command.upper() == '0C': ## 12 - RealTimeRunData_Reality
model_desc = "mirco-inverters status data"
elif command.upper() == '11':
elif command.upper() == '0D': ## 13 - RealTimeRunData_A_Phase
model_desc = "Real-Time Run Data A Phase "
elif command.upper() == '0E': ## 14 - RealTimeRunData_B_Phase
model_desc = "Real-Time Run Data B Phase "
elif command.upper() == '0F': ## 15 - RealTimeRunData_C_Phase
model_desc = "Real-Time Run Data C Phase "
elif command.upper() == '11': ## 17 - AlarmData
model_desc = "Inverter generic events log"
elif command.upper() == '12':
elif command.upper() == '12': ## 18 - AlarmUpdate
model_desc = "Inverter major events log"
elif command.upper() == '13': ## 19 - RecordData
model_desc = "Record Data"
elif command.upper() == '14': ## 20 - InternalData
model_desc = "Internal Data"
elif command.upper() == '15': ## 21 - GetLossRate
model_desc = "Get Loss Rate"
elif command.upper() == '1E': ## 30 - GetSelfCheckState
model_desc = "Get Self Check State"
elif command.upper() == 'FF': ## 255 - InitDataState
model_desc = "Initi Data State"
else:
model_desc = "event not configured - check ahoy script"
logging.info(f'model_decoder: {model}Decode{command.upper()} - {model_desc}')
@ -294,10 +317,9 @@ class InverterPacketFragment:
:return: log line received frame
:rtype: str
"""
c_datetime = self.time_rx.strftime("%Y-%m-%d %H:%M:%S.%f")
size = len(self.frame)
channel = f' channel {self.ch_rx}' if self.ch_rx else ''
return f"{c_datetime} Received {size} bytes{channel}: {hexify_payload(self.frame)}"
return f"Received {size} bytes{channel}: {hexify_payload(self.frame)}"
class HoymilesNRF:
"""Hoymiles NRF24 Interface"""
@ -747,9 +769,8 @@ class InverterTransaction:
:return: log line of payload for transmission
:rtype: str
"""
c_datetime = self.request_time.strftime("%Y-%m-%d %H:%M:%S.%f")
size = len(self.request)
return f'{c_datetime} Transmit | {hexify_payload(self.request)}'
return f'Transmit | {hexify_payload(self.request)}'
def hexify_payload(byte_var):
"""

20
tools/rpi/hoymiles/__main__.py

@ -129,6 +129,11 @@ def main_loop(ahoy_config):
sunset.sun_status2mqtt(dtu_ser, dtu_name)
loop_interval = ahoy_config.get('interval', 1)
transmit_retries = ahoy_config.get('transmit_retries', 5)
if (transmit_retries <= 0):
logging.critical('Parameter "transmit_retries" must be >0 - please check ahoy.yml.')
# print message to console too
print('Parameter "transmit_retries" must be >0 - please check ahoy.yml - STOP(0)x')
sys.exit(0)
try:
do_init = True
@ -175,15 +180,16 @@ def poll_inverter(inverter, dtu_ser, do_init, retries):
inv_str = str(inverter_ser)
if do_init:
command_queue[inv_str].append(hoymiles.compose_send_time_payload(InfoCommands.InverterDevInform_All))
command_queue[inv_str].append(hoymiles.compose_send_time_payload(InfoCommands.SystemConfigPara))
#command_queue[inv_str].append(hoymiles.compose_send_time_payload(InfoCommands.SystemConfigPara))
command_queue[inv_str].append(hoymiles.compose_send_time_payload(InfoCommands.RealTimeRunData_Debug))
# Put all queued commands for current inverter on air
while len(command_queue[inv_str]) > 0:
payload = command_queue[inv_str].pop(0)
payload = command_queue[inv_str].pop(0) ## Sub.Cmd
# Send payload {ttl}-times until we get at least one reponse
payload_ttl = retries
response = None
while payload_ttl > 0:
payload_ttl = payload_ttl - 1
com = hoymiles.InverterTransaction(
@ -197,7 +203,6 @@ def poll_inverter(inverter, dtu_ser, do_init, retries):
src=dtu_ser,
dst=inverter_ser
)))
response = None
while com.rxtx():
try:
response = com.get_payload()
@ -210,8 +215,7 @@ def poll_inverter(inverter, dtu_ser, do_init, retries):
# Handle the response data if any
if response:
if hoymiles.HOYMILES_TRANSACTION_LOGGING:
c_datetime = datetime.now()
logging.debug(f'{c_datetime} Payload: ' + hoymiles.hexify_payload(response))
logging.debug(f'Payload: ' + hoymiles.hexify_payload(response))
# prepare decoder object
decoder = hoymiles.ResponseDecoder(response,
@ -319,9 +323,11 @@ def init_logging(ahoy_config):
max_log_files = log_config.get('max_log_files', max_log_files)
if hoymiles.HOYMILES_TRANSACTION_LOGGING:
lvl = logging.DEBUG
logging.basicConfig(handlers=[RotatingFileHandler(fn, maxBytes=max_log_filesize, backupCount=max_log_files)], format='%(asctime)s %(levelname)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S', level=lvl)
logging.basicConfig(handlers=[RotatingFileHandler(fn, maxBytes=max_log_filesize, backupCount=max_log_files)],
format='%(asctime)s %(levelname)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S.%s', level=lvl)
dtu_name = ahoy_config.get('dtu',{}).get('name','hoymiles-dtu')
logging.info(f'start logging for {dtu_name} with level: {logging.root.level}')
logging.info(f'start logging for {dtu_name} with level: {logging.getLevelName(logging.root.level)}')
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Ahoy - Hoymiles solar inverter gateway', prog="hoymiles")

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

@ -151,7 +151,7 @@ class StatusResponse(Response):
"""
strings = []
s_exists = True
while s_exists:
while s_exists and len(strings) < len(self.inv_strings):
s_exists = False
string_id = len(strings)
if string_id < len(self.inv_strings):

Loading…
Cancel
Save