Compare commits
74 Commits
renovate/s
...
titan-scan
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f4d3740d6 | ||
|
|
abdc323dc6 | ||
|
|
35efa65410 | ||
|
|
399d0b58ff | ||
|
|
2b4bd2922c | ||
|
|
3eba999a2b | ||
|
|
ad8a902ac6 | ||
|
|
fda4008036 | ||
|
|
e7e693c0b6 | ||
|
|
98665b3aac | ||
|
|
6b488e5269 | ||
|
|
010ae2b2c7 | ||
|
|
24840e67c0 | ||
|
|
2dd89d3174 | ||
|
|
c84b610229 | ||
|
|
5dc890dde0 | ||
|
|
0c10cc32dc | ||
|
|
71f581eb0b | ||
|
|
a4acddd769 | ||
|
|
724f6f3b22 | ||
|
|
18c3020282 | ||
|
|
e127716317 | ||
|
|
5790b657d0 | ||
|
|
5d4ff9051d | ||
|
|
595b68ba03 | ||
|
|
d7628689f0 | ||
|
|
e074a39f5a | ||
|
|
9852f44dfa | ||
|
|
c7d0a91371 | ||
|
|
5b68610f78 | ||
|
|
0b79a37fe7 | ||
|
|
00e9a4534d | ||
|
|
3a94afb48d | ||
|
|
949f3c9608 | ||
|
|
cd2f41a713 | ||
|
|
84034127e3 | ||
|
|
22d59ed659 | ||
|
|
cfe2c9cb9d | ||
|
|
39aba31bbd | ||
|
|
a1441fb4fd | ||
|
|
f2ade43410 | ||
|
|
8f695518bd | ||
|
|
b3068a256c | ||
|
|
2336955bb8 | ||
|
|
8a745b2d10 | ||
|
|
518375e8a8 | ||
|
|
b57ded1a73 | ||
|
|
41aeac4168 | ||
|
|
5a0ef30ceb | ||
|
|
4c15495670 | ||
|
|
ca610b15ff | ||
|
|
0c824b4a2a | ||
|
|
95f817a92b | ||
|
|
2ef7a7e201 | ||
|
|
2be0ef67af | ||
|
|
43700b3da8 | ||
|
|
7b6810cb46 | ||
|
|
aa7c1832ef | ||
|
|
73526b7dc6 | ||
|
|
b6761e7517 | ||
|
|
209956865b | ||
|
|
bc54944077 | ||
|
|
37c977c2fe | ||
|
|
d5c369e5fe | ||
|
|
89c2c11ed9 | ||
|
|
eea725b8da | ||
|
|
0b437cf3bc | ||
|
|
ae4bcee41f | ||
|
|
edc0f7a6af | ||
|
|
9ffcfbc9ce | ||
|
|
b7c63b5cf8 | ||
|
|
af81aef07c | ||
|
|
f216c2434e | ||
|
|
39540678fb |
@@ -186,9 +186,11 @@ class Talent(Message):
|
||||
|
||||
if 2 == (exp_cnt % 30):
|
||||
# logging.info("Regular Modbus Status request")
|
||||
self._send_modbus_cmd(Modbus.READ_REGS, 0x2000, 96, logging.DEBUG)
|
||||
self._send_modbus_cmd(Modbus.INV_ADDR, Modbus.READ_REGS, 0x2000,
|
||||
96, logging.DEBUG)
|
||||
else:
|
||||
self._send_modbus_cmd(Modbus.READ_REGS, 0x3000, 48, logging.DEBUG)
|
||||
self._send_modbus_cmd(Modbus.INV_ADDR, Modbus.READ_REGS, 0x3000,
|
||||
48, logging.DEBUG)
|
||||
|
||||
def _init_new_client_conn(self) -> bool:
|
||||
contact_name = self.contact_name
|
||||
|
||||
@@ -253,7 +253,8 @@ class SolarmanBase(Message):
|
||||
class SolarmanV5(SolarmanBase):
|
||||
AT_CMD = 1
|
||||
MB_RTU_CMD = 2
|
||||
MB_CLIENT_DATA_UP = 30
|
||||
'''regular Modbus polling time in server mode'''
|
||||
MB_CLIENT_DATA_UP = 10
|
||||
'''Data up time in client mode'''
|
||||
HDR_FMT = '<BLLL'
|
||||
'''format string for packing of the header'''
|
||||
@@ -328,7 +329,11 @@ class SolarmanV5(SolarmanBase):
|
||||
if 'at_acl' in g3p_cnf: # pragma: no cover
|
||||
self.at_acl = g3p_cnf['at_acl']
|
||||
|
||||
self.sensor_list = 0
|
||||
self.sensor_list = 0x0000
|
||||
self.mb_start_reg = 0x0001 # 0x7001
|
||||
self.mb_incr_reg = 0x100 # 4
|
||||
self.mb_inv_no = 144 # 3
|
||||
self.mb_scan_len = 4
|
||||
|
||||
'''
|
||||
Our puplic methods
|
||||
@@ -364,7 +369,23 @@ class SolarmanV5(SolarmanBase):
|
||||
self.new_data['controller'] = True
|
||||
|
||||
self.state = State.up
|
||||
self._send_modbus_cmd(Modbus.READ_REGS, 0x3000, 48, logging.DEBUG)
|
||||
# self.__build_header(0x1710)
|
||||
# self.ifc.write += struct.pack('<B', 0)
|
||||
# self.__finish_send_msg()
|
||||
# hex_dump_memory(logging.INFO, f'Send StartCmd:{self.addr}:',
|
||||
# self.ifc.write, len(self.ifc.write))
|
||||
# self.writer.write(self.ifc.write)
|
||||
# self.ifc.write = bytearray(0) # self.ifc.write[sent:]
|
||||
|
||||
if self.sensor_list != 0x02b0:
|
||||
self._send_modbus_cmd(self.mb_inv_no, Modbus.READ_REGS,
|
||||
self.mb_start_reg, self.mb_scan_len,
|
||||
logging.INFO)
|
||||
else:
|
||||
self.mb_inv_no = Modbus.INV_ADDR
|
||||
self._send_modbus_cmd(self.mb_inv_no, Modbus.READ_REGS, 0x3000,
|
||||
48, logging.DEBUG)
|
||||
|
||||
self.mb_timer.start(self.mb_timeout)
|
||||
|
||||
def new_state_up(self):
|
||||
@@ -467,12 +488,29 @@ class SolarmanV5(SolarmanBase):
|
||||
|
||||
def mb_timout_cb(self, exp_cnt):
|
||||
self.mb_timer.start(self.mb_timeout)
|
||||
if self.sensor_list != 0x02b0:
|
||||
self.mb_start_reg += self.mb_incr_reg
|
||||
if self.mb_start_reg > 0xffff:
|
||||
self.mb_start_reg = self.mb_start_reg & 0xffff
|
||||
self.mb_inv_no += 1
|
||||
logging.info(f"Next Round: inv:{self.mb_inv_no}"
|
||||
f" reg:{self.mb_start_reg:04x}")
|
||||
if (self.mb_start_reg & 0xfffc) % 0x80 == 0:
|
||||
logging.info(f"Scan info: inv:{self.mb_inv_no}"
|
||||
f" reg:{self.mb_start_reg:04x}")
|
||||
self._send_modbus_cmd(self.mb_inv_no, Modbus.READ_REGS,
|
||||
self.mb_start_reg, self.mb_scan_len,
|
||||
logging.INFO)
|
||||
else:
|
||||
self._send_modbus_cmd(Modbus.INV_ADDR, Modbus.READ_REGS, 0x3000,
|
||||
48, logging.DEBUG)
|
||||
|
||||
self._send_modbus_cmd(Modbus.READ_REGS, 0x3000, 48, logging.DEBUG)
|
||||
|
||||
if 1 == (exp_cnt % 30):
|
||||
# logging.info("Regular Modbus Status request")
|
||||
self._send_modbus_cmd(Modbus.READ_REGS, 0x2000, 96, logging.DEBUG)
|
||||
if 1 == (exp_cnt % 30):
|
||||
# logging.info("Regular Modbus Status request")
|
||||
self._send_modbus_cmd(Modbus.INV_ADDR, Modbus.READ_REGS,
|
||||
0x5000, 8, logging.DEBUG)
|
||||
self._send_modbus_cmd(Modbus.INV_ADDR, Modbus.READ_REGS,
|
||||
0x2000, 96, logging.DEBUG)
|
||||
|
||||
def at_cmd_forbidden(self, cmd: str, connection: str) -> bool:
|
||||
return not cmd.startswith(tuple(self.at_acl[connection]['allow'])) or \
|
||||
@@ -685,6 +723,21 @@ class SolarmanV5(SolarmanBase):
|
||||
if valid == 1 and modbus_msg_len > 4:
|
||||
# logger.info(f'first byte modbus:{data[14]}')
|
||||
inv_update = self.__parse_modbus_rsp(data)
|
||||
self.modbus_elms = 0
|
||||
if (self.sensor_list != 0x02b0 and data[15] != 0):
|
||||
logging.info('Valid MODBUS data '
|
||||
f'(inv:{self.mb_inv_no} '
|
||||
f'reg: 0x{self.mb.last_reg:04x}):')
|
||||
hex_dump_memory(logging.INFO, 'Valid MODBUS data '
|
||||
f'(reg: 0x{self.mb.last_reg:04x}):',
|
||||
data[14:], modbus_msg_len)
|
||||
for key, update, _ in self.mb.recv_resp(self.db, data[14:]):
|
||||
self.modbus_elms += 1
|
||||
if update:
|
||||
if key == 'inverter':
|
||||
inv_update = True
|
||||
self._set_mqtt_timestamp(key, self._timestamp())
|
||||
self.new_data[key] = True
|
||||
if inv_update:
|
||||
self.__build_model_name()
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ class Message(ProtocolIfc):
|
||||
'''maximum default time without a received msg in sec'''
|
||||
MB_START_TIMEOUT = 40
|
||||
'''start delay for Modbus polling in server mode'''
|
||||
MB_REGULAR_TIMEOUT = 60
|
||||
MB_REGULAR_TIMEOUT = 20
|
||||
'''regular Modbus polling time in server mode'''
|
||||
|
||||
def __init__(self, node_id, ifc: "AsyncIfc", server_side: bool,
|
||||
@@ -168,15 +168,15 @@ class Message(ProtocolIfc):
|
||||
to = self.MAX_DEF_IDLE_TIME
|
||||
return to
|
||||
|
||||
def _send_modbus_cmd(self, func, addr, val, log_lvl) -> None:
|
||||
def _send_modbus_cmd(self, mb_no, func, addr, val, log_lvl) -> None:
|
||||
if self.state != State.up:
|
||||
logger.log(log_lvl, f'[{self.node_id}] ignore MODBUS cmd,'
|
||||
' as the state is not UP')
|
||||
return
|
||||
self.mb.build_msg(Modbus.INV_ADDR, func, addr, val, log_lvl)
|
||||
self.mb.build_msg(mb_no, func, addr, val, log_lvl)
|
||||
|
||||
async def send_modbus_cmd(self, func, addr, val, log_lvl) -> None:
|
||||
self._send_modbus_cmd(func, addr, val, log_lvl)
|
||||
self._send_modbus_cmd(Modbus.INV_ADDR, func, addr, val, log_lvl)
|
||||
|
||||
'''
|
||||
Our puplic methods
|
||||
|
||||
@@ -103,8 +103,8 @@ class Modbus():
|
||||
'''Response handler to forward the response'''
|
||||
self.timeout = timeout
|
||||
'''MODBUS response timeout in seconds'''
|
||||
self.max_retries = 1
|
||||
'''Max retransmit for MODBUS requests'''
|
||||
self.max_retries = 0
|
||||
'''Max retransmit for MODBU requests'''
|
||||
self.retry_cnt = 0
|
||||
self.last_req = b''
|
||||
self.counter = {}
|
||||
|
||||
@@ -1730,6 +1730,7 @@ async def test_modbus_polling(config_tsun_inv1, heartbeat_ind_msg, heartbeat_rsp
|
||||
assert asyncio.get_running_loop() == m.mb_timer.loop
|
||||
m.db.stat['proxy']['Unknown_Ctrl'] = 0
|
||||
assert m.mb_timer.tim == None
|
||||
|
||||
m.read() # read complete msg, and dispatch msg
|
||||
assert not m.header_valid # must be invalid, since msg was handled and buffer flushed
|
||||
assert m.msg_count == 1
|
||||
@@ -1767,6 +1768,10 @@ async def test_start_client_mode(config_tsun_inv1, str_test_ip):
|
||||
_ = config_tsun_inv1
|
||||
assert asyncio.get_running_loop()
|
||||
m = MemoryStream(b'')
|
||||
m.mb_start_reg = 0x3000
|
||||
m.mb_incr_reg = 0x00 # 4
|
||||
m.mb_scan_len = 48
|
||||
|
||||
assert m.state == State.init
|
||||
assert m.no_forwarding == False
|
||||
assert m.mb_timer.tim == None
|
||||
|
||||
Reference in New Issue
Block a user