Dev 0.11 (#190)
* Code Cleanup (#158) * print coverage report * create sonar-project property file * install all py dependencies in one step * code cleanup * reduce cognitive complexity * do not build on *.yml changes * optimise versionstring handling (#159) - Reading the version string from the image updates it even if the image is re-pulled without re-deployment * fix linter warning * exclude *.pyi filese * ignore some rules for tests * cleanup (#160) * Sonar qube 3 (#163) fix SonarQube warnings in modbus.py * Sonar qube 3 (#164) * fix SonarQube warnings * Sonar qube 3 (#165) * cleanup * Add support for TSUN Titan inverter Fixes #161 * fix SonarQube warnings * fix error * rename field "config" * SonarQube reads flake8 output * don't stop on flake8 errors * flake8 scan only app/src for SonarQube * update flake8 run * ignore flake8 C901 * cleanup * fix linter warnings * ignore changed *.yml files * read sensor list solarman data packets * catch 'No route to' error and log only in debug mode * fix unit tests * add sensor_list configuration * adapt unit tests * fix SonarQube warnings * Sonar qube 3 (#166) * add unittests for mqtt.py * add mock * move test requirements into a file * fix unit tests * fix formating * initial version * fix SonarQube warning * Sonar qube 4 (#169) * add unit test for inverter.py * fix SonarQube warning * Sonar qube 5 (#170) * fix SonarLints warnings * use random IP adresses for unit tests * Docker: The description ist missing (#171) Fixes #167 * S allius/issue167 (#172) * cleanup * Sonar qube 6 (#174) * test class ModbusConn * Sonar qube 3 (#178) * add more unit tests * GEN3: don't crash on overwritten msg in the receive buffer * improve test coverage und reduce test delays * reduce cognitive complexity * fix merge * fix merge conflikt * fix merge conflict * S allius/issue182 (#183) * GEN3: After inverter firmware update the 'Unknown Msg Type' increases continuously Fixes #182 * add support for Controller serial no and MAC * test hardening * GEN3: add support for new messages of version 3 firmwares * bump libraries to latest versions - bump aiomqtt to version 2.3.0 - bump aiohttp to version 3.10.5 * improve test coverage * reduce cognective complexity * fix target preview * remove dubbled fixtures * increase test coverage * Update README.md (#185) update badges * S allius/issue186 (#187) * Parse more values in Server Mode Fixes #186 * read OUTPUT_COEFFICIENT and MAC_ADDR in SrvMode * fix unit test * increase test coverage * S allius/issue186 (#188) * increase test coverage * update changelog * add dokumentation * change default config * Update README.md (#189) Config file is now foldable
This commit is contained in:
@@ -56,20 +56,24 @@ class Talent(Message):
|
||||
0x00: self.msg_contact_info,
|
||||
0x13: self.msg_ota_update,
|
||||
0x22: self.msg_get_time,
|
||||
0x99: self.msg_act_time,
|
||||
0x71: self.msg_collector_data,
|
||||
# 0x76:
|
||||
0x77: self.msg_modbus,
|
||||
# 0x78:
|
||||
0x87: self.msg_modbus2,
|
||||
0x04: self.msg_inverter_data,
|
||||
}
|
||||
self.log_lvl = {
|
||||
0x00: logging.INFO,
|
||||
0x13: logging.INFO,
|
||||
0x22: logging.INFO,
|
||||
0x99: logging.INFO,
|
||||
0x71: logging.INFO,
|
||||
# 0x76:
|
||||
0x77: self.get_modbus_log_lvl,
|
||||
# 0x78:
|
||||
0x87: self.get_modbus_log_lvl,
|
||||
0x04: logging.INFO,
|
||||
}
|
||||
self.modbus_elms = 0 # for unit tests
|
||||
@@ -127,6 +131,7 @@ class Talent(Message):
|
||||
logger.debug(f'SerialNo {serial_no} not known but accepted!')
|
||||
|
||||
self.unique_id = serial_no
|
||||
self.db.set_db_def_value(Register.COLLECTOR_SNR, serial_no)
|
||||
|
||||
def read(self) -> float:
|
||||
'''process all received messages in the _recv_buffer'''
|
||||
@@ -170,6 +175,25 @@ class Talent(Message):
|
||||
logger.info(self.__flow_str(self.server_side, 'forwrd') +
|
||||
f' Ctl: {int(self.ctrl):#02x} Msg: {fnc.__name__!r}')
|
||||
|
||||
def forward_snd(self) -> None:
|
||||
'''add the actual receive msg to the forwarding queue'''
|
||||
tsun = Config.get('tsun')
|
||||
if tsun['enabled']:
|
||||
_len = len(self._send_buffer) - self.send_msg_ofs
|
||||
struct.pack_into('!l', self._send_buffer, self.send_msg_ofs,
|
||||
_len-4)
|
||||
|
||||
buffer = self._send_buffer[self.send_msg_ofs:]
|
||||
buflen = _len
|
||||
self._forward_buffer += buffer[:buflen]
|
||||
hex_dump_memory(logging.INFO, 'Store for forwarding:',
|
||||
buffer, buflen)
|
||||
|
||||
fnc = self.switch.get(self.msg_id, self.msg_unknown)
|
||||
logger.info(self.__flow_str(self.server_side, 'forwrd') +
|
||||
f' Ctl: {int(self.ctrl):#02x} Msg: {fnc.__name__!r}')
|
||||
self._send_buffer = self._send_buffer[:self.send_msg_ofs]
|
||||
|
||||
def send_modbus_cb(self, modbus_pdu: bytearray, log_lvl: int, state: str):
|
||||
if self.state != State.up:
|
||||
logger.warning(f'[{self.node_id}] ignore MODBUS cmd,'
|
||||
@@ -400,6 +424,8 @@ class Talent(Message):
|
||||
result = struct.unpack_from('!q', self._recv_buffer,
|
||||
self.header_len)
|
||||
self.ts_offset = result[0]-ts
|
||||
if self.remote_stream:
|
||||
self.remote_stream.ts_offset = self.ts_offset
|
||||
logger.debug(f'tsun-time: {int(result[0]):08x}'
|
||||
f' proxy-time: {ts:08x}'
|
||||
f' offset: {self.ts_offset}')
|
||||
@@ -410,6 +436,41 @@ class Talent(Message):
|
||||
|
||||
self.forward()
|
||||
|
||||
def msg_act_time(self):
|
||||
if self.ctrl.is_ind():
|
||||
if self.data_len == 9:
|
||||
self.state = State.up # allow MODBUS cmds
|
||||
if (self.modbus_polling):
|
||||
self.mb_timer.start(self.mb_first_timeout)
|
||||
self.db.set_db_def_value(Register.POLLING_INTERVAL,
|
||||
self.mb_timeout)
|
||||
self.__build_header(0x99)
|
||||
self._send_buffer += b'\x02'
|
||||
self.__finish_send_msg()
|
||||
|
||||
result = struct.unpack_from('!Bq', self._recv_buffer,
|
||||
self.header_len)
|
||||
resp_code = result[0]
|
||||
ts = result[1]+self.ts_offset
|
||||
logger.debug(f'inv-time: {int(result[1]):08x}'
|
||||
f' tsun-time: {ts:08x}'
|
||||
f' offset: {self.ts_offset}')
|
||||
self.__build_header(0x91)
|
||||
self._send_buffer += struct.pack('!Bq', resp_code, ts)
|
||||
self.forward_snd()
|
||||
return
|
||||
elif self.ctrl.is_resp():
|
||||
result = struct.unpack_from('!B', self._recv_buffer,
|
||||
self.header_len)
|
||||
resp_code = result[0]
|
||||
logging.debug(f'TimeActRespCode: {resp_code}')
|
||||
return
|
||||
else:
|
||||
logger.warning(self.TXT_UNKNOWN_CTRL)
|
||||
self.inc_counter('Unknown_Ctrl')
|
||||
|
||||
self.forward()
|
||||
|
||||
def parse_msg_header(self):
|
||||
result = struct.unpack_from('!lB', self._recv_buffer, self.header_len)
|
||||
|
||||
@@ -492,6 +553,15 @@ class Talent(Message):
|
||||
modbus_len = result[1]
|
||||
return msg_hdr_len, modbus_len
|
||||
|
||||
def parse_modbus_header2(self):
|
||||
|
||||
msg_hdr_len = 6
|
||||
|
||||
result = struct.unpack_from('!lBBB', self._recv_buffer,
|
||||
self.header_len)
|
||||
modbus_len = result[2]
|
||||
return msg_hdr_len, modbus_len
|
||||
|
||||
def get_modbus_log_lvl(self) -> int:
|
||||
if self.ctrl.is_req():
|
||||
return logging.INFO
|
||||
@@ -501,6 +571,13 @@ class Talent(Message):
|
||||
|
||||
def msg_modbus(self):
|
||||
hdr_len, _ = self.parse_modbus_header()
|
||||
self.__msg_modbus(hdr_len)
|
||||
|
||||
def msg_modbus2(self):
|
||||
hdr_len, _ = self.parse_modbus_header2()
|
||||
self.__msg_modbus(hdr_len)
|
||||
|
||||
def __msg_modbus(self, hdr_len):
|
||||
data = self._recv_buffer[self.header_len:
|
||||
self.header_len+self.data_len]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user