Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update python ahoy script #1

Merged
merged 9 commits into from
Apr 6, 2022
Merged
9 changes: 9 additions & 0 deletions tools/rpi/ahoy.conf.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[mqtt]
host = 192.168.84.2
port = 1883

[dtu]
serial = 99978563412

[inverter]
serial = 444473104619
104 changes: 80 additions & 24 deletions tools/rpi/ahoy.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,10 @@
mqtt_client.connect(mqtt_host, mqtt_port)

# Master Address ('DTU')
dtu_ser = 99978563412 # identical to fc22's
dtu_ser = cfg.get('dtu', 'serial', fallback='99978563412') # identical to fc22's

# inverter serial numbers
#inv_ser = 444473104619 # identical to fc22's #99972220200
inv_ser = 114174608145 # my inverter
inv_ser = cfg.get('inverter', 'serial', fallback='444473104619') # my inverter

# all inverters
#...
Expand Down Expand Up @@ -163,6 +162,34 @@ def on_receive(p):
d['wday2_Wh'] = uk5
d['uk2'] = uk2

elif cmd==129:
name = 'error'
print('Command error')

elif cmd==131:
name = 'statedata'
uk1, l, uk3, t, uk5, uk6 = struct.unpack('>HHHHHH', p[10:22])
print(f'l={l}%, t={t/10:.2f}C, ', end='')
print(f'uk1={uk1}, ', end='')
print(f'uk3={uk3}, ', end='')
print(f'uk5={uk5}, ', end='')
print(f'uk6={uk6}')
d['l_Pct'] = l
d['t_C'] = t/10

elif cmd==132:
name = 'unknown'
uk1, uk2, uk3, uk4, uk5, uk6, uk7, uk8 = struct.unpack(
'>HHHHHHHH', p[10:26])
print(f'uk1={uk1}, ', end='')
print(f'uk2={uk2}, ', end='')
print(f'uk3={uk3}, ', end='')
print(f'uk4={uk4}, ', end='')
print(f'uk5={uk5}, ', end='')
print(f'uk6={uk6}, ', end='')
print(f'uk7={uk7}, ', end='')
print(f'uk8={uk8}')

else:
print(f'unknown cmd {cmd}')
else:
Expand All @@ -173,11 +200,20 @@ def on_receive(p):
j = json.dumps(d)
mqtt_client.publish(f'ahoy/{src}/{name}', j)
if d['cmd']==2:
mqtt_client.publish(f'ahoy/{src}/{name}/p_W', d['p_W'])
mqtt_client.publish(f'ahoy/{src}/emeter/0/voltage', d['u_V'])
mqtt_client.publish(f'ahoy/{src}/emeter/0/power', d['p_W'])
mqtt_client.publish(f'ahoy/{src}/emeter/0/total', d['wtot1_Wh'])
mqtt_client.publish(f'ahoy/{src}/frequency', d['f_Hz'])
if d['cmd']==1:
mqtt_client.publish(f'ahoy/{src}/{name}/p1_W', d['p1_W'])
mqtt_client.publish(f'ahoy/{src}/{name}/p2_W', d['p2_W'])
mqtt_client.publish(f'ahoy/{src}/{name}/p_W', d['p1_W']+d['p2_W'])
mqtt_client.publish(f'ahoy/{src}/emeter-dc/0/power', d['p1_W'])
mqtt_client.publish(f'ahoy/{src}/emeter-dc/0/voltage', d['u1_V'])
mqtt_client.publish(f'ahoy/{src}/emeter-dc/0/current', d['i1_A'])
mqtt_client.publish(f'ahoy/{src}/emeter-dc/1/power', d['p2_W'])
mqtt_client.publish(f'ahoy/{src}/emeter-dc/1/voltage', d['u2_V'])
mqtt_client.publish(f'ahoy/{src}/emeter-dc/1/current', d['i2_A'])
if d['cmd']==131:
mqtt_client.publish(f'ahoy/{src}/temperature', d['t_C'])



def main_loop():
Expand All @@ -190,53 +226,73 @@ def main_loop():
print_addr(dtu_ser)

ctr = 1
last_tx_message = ''

ts = int(time.time()) # see what happens if we always send one and the same (constant) time!
rx_channels = [3,23,61,75]
rx_channel_id = 0
rx_channel = rx_channels[rx_channel_id]

tx_channels = [40]
tx_channel_id = 0
tx_channel = tx_channels[tx_channel_id]

while True:
radio.setChannel(3)
# Sweep receive start channel
rx_channel_id = ctr % len(rx_channels)
rx_channel = rx_channels[rx_channel_id]

radio.setChannel(rx_channel)
radio.enableDynamicPayloads()
radio.setAutoAck(False)
radio.setAutoAck(True)
radio.setPALevel(RF24_PA_MAX)
radio.setDataRate(RF24_250KBPS)
radio.openWritingPipe(ser_to_esb_addr(inv_ser))
radio.flush_rx()
radio.flush_tx()
radio.openReadingPipe(1,ser_to_esb_addr(dtu_ser))
#radio.openReadingPipe(1,ser_to_esb_addr(inv_ser))
radio.startListening()

if ctr<3:
pass
# radio.printPrettyDetails()

t_end = time.monotonic_ns()+1e9
while time.monotonic_ns() < t_end:
has_payload, pipe_number = radio.available_pipe()
if has_payload:
size = radio.getDynamicPayloadSize()
payload = radio.read(size)
print(f"Received {size} bytes on pipe {pipe_number}: " +
print(last_tx_message, end='')
last_tx_message = ''
dt = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
print(f"{dt} Received {size} bytes on channel {rx_channel} pipe {pipe_number}: " +
" ".join([f"{b:02x}" for b in payload]))
on_receive(payload)
else:
radio.stopListening()
radio.setChannel(rx_channel)
radio.startListening()
rx_channel_id = rx_channel_id + 1
if rx_channel_id >= len(rx_channels):
rx_channel_id = 0
rx_channel = rx_channels[rx_channel_id]
time.sleep(0.01)

tx_channel_id = tx_channel_id + 1
if tx_channel_id >= len(tx_channels):
tx_channel_id = 0
tx_channel = tx_channels[tx_channel_id]

radio.stopListening() # put radio in TX mode
radio.setChannel(40)
radio.setChannel(tx_channel)
radio.openWritingPipe(ser_to_esb_addr(inv_ser))

if ctr<3:
pass
# radio.printPrettyDetails()

# ts = int(time.time())
ts = int(time.time())
payload = compose_0x80_msg(src_ser_no=dtu_ser, dst_ser_no=inv_ser, ts=ts)
print(f"{ctr:5d}: len={len(payload)} | " + " ".join([f"{b:02x}" for b in payload]),
flush=True)
dt = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
last_tx_message = f"{dt} Transmit {ctr:5d}: channel={tx_channel} len={len(payload)} | " + \
" ".join([f"{b:02x}" for b in payload]) + "\n"
radio.write(payload) # will always yield 'True' because auto-ack is disabled
ctr = ctr + 1

print(flush=True, end='')




Expand Down
1 change: 1 addition & 0 deletions tools/rpi/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
paho-mqtt
crcmod