#!/bin/env python3 from pyLoraRFM9x import LoRa, ModemConfig import time from collections import namedtuple from struct import * import pykka import paho.mqtt.client as paho from paho import mqtt import json client = paho.Client(paho.CallbackAPIVersion.VERSION2) client.connect("stanley") Watering = namedtuple('Watering', 'voltage moisture intervals dry wet state delay_hours max_time_mins pump_speed pump_running errors') WateringStruct = '<HHHHHBBBB?B' class WaterActor(pykka.ThreadingActor): def __init__(self, client): super().__init__() self.client = client self.state = None self.updates = [] def greenhouse(self, payload): try: message = Watering._make(unpack(WateringStruct, payload.message)) self.state = message to_send = message._asdict() to_send['rssi'] = payload.rssi to_send['snr'] = payload.snr client.publish('events/greenhouse', payload=json.dumps(to_send)) except Exception as e: client.publish('events/greenhouse', payload=str(e)) updated_state = self.state for update in self.updates: updated_state = updated_state._replace(**update) self.updates = [] if self.state != updated_state: reply = pack(WateringStruct, *updated_state) print("Sending: " + str(updated_state)) lora.send(reply, 2) lora.set_mode_rx() def queue_update(self, update): self.updates.append(update) a = WaterActor.start(client).proxy() def on_radio_recv(payload): a.greenhouse(payload) lora = LoRa(1, 24, 1, reset_pin = 25, modem_config=ModemConfig.Bw125Cr45Sf128, tx_power=14, acks=False, freq=868, receive_all=False) lora.on_recv = on_radio_recv lora.set_mode_rx() def on_mqtt_message(client, userdata, message): try: update = json.loads(message.payload) a.queue_update(update) except Exception as e: client.publish('events/greenhouse', payload=str(e)) client.on_message = on_mqtt_message client.subscribe("commands/greenhouse") client.loop_forever(retry_first_connection=False)