def on_receive(p, ch_rx=None, ch_tx=None): """ Callback: get's invoked whenever a packet has been received. :param p: Payload of the received packet. """ d = {} t_now_ns = time.monotonic_ns() ts = datetime.utcnow() ts_unixtime = ts.timestamp() #d['ts_unixtime'] = ts_unixtime d['isodate'] = ts.isoformat() #d['rawdata'] = " ".join([f"{b:02x}" for b in p]) # print(ts.isoformat(), end='Z ') # check crc8 crc8 = f_crc8(p[:-1]) #d['crc8_valid'] = True if crc8==p[-1] else False # interpret content mid = p[0] #d['mid'] = mid #d['response_time_ns'] = t_now_ns-t_last_tx #d['ch_rx'] = ch_rx #d['ch_tx'] = ch_tx #d['src'] = 'src_unkn' #d['name'] = 'name_unkn' if mid == 0x95: src, dst, cmd = struct.unpack('>LLB', p[1:10]) #d['src'] = f'{src:08x}' #d['dst'] = f'{dst:08x}' d['cmd'] = cmd # print(f'MSG src={d["src"]}, dst={d["dst"]}, cmd={d["cmd"]}:') if cmd==1: # d['name'] = 'dcdata1' uk1, u1, i1, i2, p1, p2, uk2, t1Wh = struct.unpack( '>HHHHHHHH', p[10:26]) d['uk_1_1'] = uk1 d['uk_1_2'] = uk2 d['u12_V'] = u1/10 d['i1_A'] = i1/100 d['i2_A'] = i2/100 d['p1_W'] = p1/10 d['p2_W'] = p2/10 d['Tot1_kWh'] = t1Wh/1000 d['(pA12_W)'] = round(d['u12_V']*(d['i1_A']+d["i2_A"]), 1) elif cmd==2: # d['name'] = 'dcdata2' uk3, t2Wh, d1Wh, d2Wh, u2, i3, i4, p3 = struct.unpack( '>HHHHHHHH', p[10:26]) d['uk_2_1'] = uk3 d['u34_V'] = u2/10 d['i3_A'] = i3/100 d['i4_A'] = i4/100 d['p3_W'] = p3/10 d['Day1_Wh'] = d1Wh d['Day2_Wh'] = d2Wh d['Tot2_kWh'] = t2Wh/1000 d['(pA34_W)'] = round(d['u34_V']*(d['i3_A']+d['i4_A']), 1) elif cmd==3: # d['name'] = 'ACdata1' p4, uk4, t4Wh, uk5, t3Wh, d4Wh, d3Wh, U_ac = struct.unpack( '>HHHHHHHH', p[10:26]) d['uk_3_1'] = uk4 d['p4_W'] = p4/10 d['Day3_Wh'] = d3Wh d['Day4_Wh'] = d4Wh d['Tot3_kWh'] = t3Wh/1000 d['Tot4_kWh'] = t4Wh/1000 d['U_ac_V'] = U_ac/10 elif cmd==132: # 0x84 # d['name'] = 'ACdata2' f, P, uk5, iac, uk6, t_wr, uk7, uk8 = struct.unpack( '>HHHHHHHH', p[10:26]) d['uk_132_1'] = uk5 d['uk_132_2'] = uk6 d['uk_132_3'] = uk7 d['uk_132_4'] = uk8 d['f'] = f/100 d['Iac_A'] = iac/100 d['twr_C'] = t_wr/10 d['Pac_W'] = P/10 else: print(f'unknown cmd {cmd}') else: print(f'unknown frame id {p[0]}') # output to stdout if d: print(json.dumps(d, indent=4, separators=(", ", ": "))) # output to MQTT ''' if d: j = json.dumps(d) mqtt_client.publish(f"ahoy/{d['src']}/{d['name']}", j) if d['cmd']==2: mqtt_client.publish(f'ahoy/{d["src"]}/emeter/0/voltage', d['u_V']) mqtt_client.publish(f'ahoy/{d["src"]}/emeter/0/power', d['p_W']) mqtt_client.publish(f'ahoy/{d["src"]}/emeter/0/total', d['wtot1_Wh']) mqtt_client.publish(f'ahoy/{d["src"]}/frequency', d['f_Hz']) if d['cmd']==1: mqtt_client.publish(f'ahoy/{d["src"]}/emeter-dc/0/power', d['p1_W']) mqtt_client.publish(f'ahoy/{d["src"]}/emeter-dc/0/voltage', d['u1_V']) mqtt_client.publish(f'ahoy/{d["src"]}/emeter-dc/0/current', d['i1_A']) mqtt_client.publish(f'ahoy/{d["src"]}/emeter-dc/1/power', d['p2_W']) # mqtt_client.publish(f'ahoy/{d["src"]}/emeter-dc/1/voltage', d['u2_V']) mqtt_client.publish(f'ahoy/{d["src"]}/emeter-dc/1/current', d['i2_A']) if d['cmd']==131: mqtt_client.publish(f'ahoy/{d["src"]}/temperature', d['t_C']) '''