add msg_data_ind() handler
This commit is contained in:
@@ -26,14 +26,14 @@ class SolarmanV5(Message):
|
||||
# self.await_conn_resp_cnt = 0
|
||||
# self.id_str = id_str
|
||||
self.switch = {
|
||||
0x4110: self.msg_dev_ind, # hello
|
||||
0x4110: self.msg_dev_ind, # hello
|
||||
0x1110: self.msg_dev_rsp,
|
||||
0x4210: self.msg_unknown, # data
|
||||
0x4210: self.msg_data_ind, # data every 5 minutes
|
||||
0x1210: self.msg_data_rsp,
|
||||
0x4310: self.msg_unknown,
|
||||
0x4710: self.msg_unknown, # heatbeat
|
||||
0x1710: self.msg_hbeat_rsp,
|
||||
0x4810: self.msg_unknown, # hello end
|
||||
0x4310: self.msg_unknown, # regulary after 3-6 hours
|
||||
0x4710: self.msg_hbeat_ind, # heatbeat
|
||||
0x1710: self.msg_hbeat_rsp, # every 2 minutes
|
||||
0x4810: self.msg_unknown, # hello end
|
||||
}
|
||||
|
||||
'''
|
||||
@@ -229,17 +229,17 @@ class SolarmanV5(Message):
|
||||
def msg_dev_ind(self):
|
||||
data = self._recv_buffer[self.header_len:]
|
||||
result = struct.unpack_from('<BLLL', data, 0)
|
||||
code = result[0] # always 2
|
||||
ftype = result[0] # always 2
|
||||
total = result[1]
|
||||
tim = result[2]
|
||||
res = result[3] # always zero
|
||||
logger.info(f'code:{code} total:{total}s'
|
||||
logger.info(f'frame type:{ftype} total:{total}s'
|
||||
f' timer:{tim:08x}s null:{res}')
|
||||
dt = datetime.fromtimestamp(total)
|
||||
logger.info(f'ts: {dt.strftime("%Y-%m-%d %H:%M:%S")}')
|
||||
|
||||
if (code == 2):
|
||||
result = struct.unpack_from('<BBBBBB40s', data, 13)
|
||||
if (ftype == 2):
|
||||
result = struct.unpack_from('!BBBBBB40s', data, 13)
|
||||
upload_period = result[0]
|
||||
data_acq_period = result[1]
|
||||
heart_beat = result[2]
|
||||
@@ -258,20 +258,68 @@ class SolarmanV5(Message):
|
||||
def msg_dev_rsp(self):
|
||||
self.msg_response()
|
||||
|
||||
def msg_data_ind(self):
|
||||
data = self._recv_buffer
|
||||
result = struct.unpack_from('<BLLLLL', data, self.header_len)
|
||||
ftype = result[0] # 1 or 0x81
|
||||
total = result[1]
|
||||
tim = result[2]
|
||||
offset = result[3]
|
||||
unkn = result[4]
|
||||
cnt = result[5]
|
||||
logger.info(f'ftype:{ftype} total:{total}s'
|
||||
f' timer:{tim:08x}s ofs:{offset}'
|
||||
f' ??: {unkn:08x} cnt:{cnt}')
|
||||
dt = datetime.fromtimestamp(total)
|
||||
logger.info(f'ts: {dt.strftime("%Y-%m-%d %H:%M:%S")}')
|
||||
|
||||
if (ftype == 1):
|
||||
result = struct.unpack_from('!HH', data, 0xdc)
|
||||
rated = result[0]/1
|
||||
actual = result[1]/10
|
||||
logger.info(f'Rated Power:{rated}W, Actual Power:{actual}W')
|
||||
|
||||
result = struct.unpack_from('!HLHLHLHLHL', data, 0xf8)
|
||||
daily = result[0]/100
|
||||
total = result[1]/100
|
||||
pv1_daily = result[2]/100
|
||||
pv1_total = result[3]/100
|
||||
pv2_daily = result[4]/100
|
||||
pv2_total = result[5]/100
|
||||
pv3_daily = result[6]/100
|
||||
pv3_total = result[7]/100
|
||||
pv4_daily = result[8]/100
|
||||
pv4_total = result[9]/100
|
||||
logger.info(f'daily:{daily}kWh '
|
||||
f'tolal:{total}kWh\n'
|
||||
f'pv daily:{pv1_daily}kWh, {pv2_daily}kWh, {pv3_daily}kWh, {pv4_daily}kWh\n' # noqa: E501
|
||||
f'pv total:{pv1_total}kWh, {pv2_total}kWh, {pv3_total}kWh, {pv4_total}kWh') # noqa: E501
|
||||
|
||||
self.forward(self._recv_buffer, self.header_len+self.data_len+2)
|
||||
|
||||
def msg_data_rsp(self):
|
||||
self.msg_response()
|
||||
|
||||
def msg_hbeat_ind(self):
|
||||
data = self._recv_buffer[self.header_len:]
|
||||
result = struct.unpack_from('<B', data, 0)
|
||||
ftype = result[0] # always 0
|
||||
if ftype != 0:
|
||||
logger.info(f'hb frame_type:{ftype}')
|
||||
|
||||
self.forward(self._recv_buffer, self.header_len+self.data_len+2)
|
||||
|
||||
def msg_hbeat_rsp(self):
|
||||
self.msg_response()
|
||||
|
||||
def msg_response(self):
|
||||
data = self._recv_buffer[self.header_len:]
|
||||
result = struct.unpack_from('<BBLL', data, 0)
|
||||
code = result[0] # always 2
|
||||
ftype = result[0] # always 2
|
||||
valid = result[1] == 1 # status
|
||||
ts = result[2]
|
||||
repeat = result[3] # always 60
|
||||
logger.info(f'code:{code} accepted:{valid}'
|
||||
logger.info(f'ftype:{ftype} accepted:{valid}'
|
||||
f' ts:{ts:08x} repeat:{repeat}s')
|
||||
|
||||
dt = datetime.fromtimestamp(ts)
|
||||
|
||||
@@ -45,6 +45,44 @@ def MsgContactResp(): # Contact Response message
|
||||
msg += b'\x65\x3c\x00\x00\x00\x75\x15'
|
||||
return msg
|
||||
|
||||
@pytest.fixture
|
||||
def MsgDataInd():
|
||||
msg = b'\xa5\x99\x01\x10\x42\x59\x84' +get_sn() +b'\x01\xb0\x02\x2c\x87'
|
||||
msg += b'\x22\x32\xb7\x29\x00\x00\xd6\xcf\xe1\x33\x01\x00\x0c\x05\x00\x00'
|
||||
msg += b'\x59\x31\x37\x45\x37\x41\x30\x46\x30\x31\x30\x42\x30\x31\x33\x45'
|
||||
msg += b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
msg += b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
msg += b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
msg += b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
msg += b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
msg += b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
msg += b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
msg += b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
msg += b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
msg += b'\x00\x01\x12\x02\x12\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
msg += b'\x40\x10\x08\xd8\x00\x09\x13\x84\x00\x35\x00\x00\x02\x58\x00\xd8'
|
||||
msg += b'\x01\x3f\x00\x17\x00\x4d\x01\x44\x00\x14\x00\x43\x01\x45\x00\x18'
|
||||
msg += b'\x00\x52\x00\x12\x00\x01\x00\x00\x00\x7c\x00\x00\x24\xed\x00\x2c'
|
||||
msg += b'\x00\x00\x0b\x10\x00\x26\x00\x00\x0a\x0f\x00\x30\x00\x00\x0b\x76'
|
||||
msg += b'\x00\x00\x00\x00\x06\x16\x00\x00\x00\x00\x55\xaa\x00\x01\x00\x00'
|
||||
msg += b'\x00\x00\x00\x00\xff\xff\x07\xd0\x00\x03\x04\x00\x04\x00\x04\x00'
|
||||
msg += b'\x04\x00\x00\x01\xff\xff\x00\x01\x00\x06\x00\x68\x00\x68\x05\x00'
|
||||
msg += b'\x09\xcd\x07\xb6\x13\x9c\x13\x24\x00\x01\x07\xae\x04\x0f\x00\x41'
|
||||
msg += b'\x00\x0f\x0a\x64\x0a\x64\x00\x06\x00\x06\x09\xf6\x12\x8c\x12\x8c'
|
||||
msg += b'\x00\x10\x00\x10\x14\x52\x14\x52\x00\x10\x00\x10\x01\x51\x00\x05'
|
||||
msg += b'\x04\x00\x00\x01\x13\x9c\x0f\xa0\x00\x4e\x00\x66\x03\xe8\x04\x00'
|
||||
msg += b'\x09\xce\x07\xa8\x13\x9c\x13\x26\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
msg += b'\x00\x00\x00\x00\x04\x00\x04\x00\x00\x00\x00\x00\xff\xff\x00\x00'
|
||||
msg += b'\x00\x00\x00\x00\x24\x15'
|
||||
return msg
|
||||
|
||||
@pytest.fixture
|
||||
def MsgDataResp(): # Contact Response message
|
||||
msg = b'\xa5\x0a\x00\x10\x12\x80\x84' +get_sn() +b'\x01\x01\xd1\x96\x04'
|
||||
msg += b'\x66\x3c\x00\x00\x00\xed\x15'
|
||||
return msg
|
||||
|
||||
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
@@ -98,4 +136,15 @@ def test_conn_msg(ClientConnection,MsgContactInfo, MsgContactResp):
|
||||
except TimeoutError:
|
||||
pass
|
||||
# time.sleep(2.5)
|
||||
checkResponse(data, MsgContactResp)
|
||||
checkResponse(data, MsgContactResp)
|
||||
|
||||
def test_data_ind(ClientConnection,MsgDataInd, MsgDataResp):
|
||||
s = ClientConnection
|
||||
try:
|
||||
s.sendall(MsgDataInd)
|
||||
# time.sleep(2.5)
|
||||
data = s.recv(1024)
|
||||
except TimeoutError:
|
||||
pass
|
||||
# time.sleep(2.5)
|
||||
checkResponse(data, MsgDataResp)
|
||||
Reference in New Issue
Block a user