#!/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
from http.server import HTTPServer, BaseHTTPRequestHandler
from threading import Thread
client = paho.Client(paho.CallbackAPIVersion.VERSION2)
client.connect("stanley")
Watering = namedtuple('Watering', 'voltage moisture pump_speed pump_running errors')
WateringStruct = '<HHB?B'
Command = namedtuple('Command', 'proc arg')
CommandStruct = '<BB'
class WaterActor(pykka.ThreadingActor):
def __init__(self, client):
super().__init__()
self.client = client
self.cmds = []
def greenhouse(self, payload):
try:
message = Watering._make(unpack(WateringStruct, payload.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))
if len(self.cmds) > 0:
time.sleep(0.5)
for cmd in self.cmds:
print("Sending: " + str(cmd))
try:
reply = pack(CommandStruct, *cmd)
print(reply)
lora.send(reply, 2)
except Exception as e:
print(e)
self.cmds.clear()
lora.set_mode_rx()
def queue_command(self, command):
self.cmds.append(command)
a = WaterActor.start(client).proxy()
class SprinklerHTTPRequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "text/plain")
self.end_headers()
self.flush_headers()
if self.path == '/on':
a.queue_command(Command(1, 248))
self.wfile.write(bytes("Switching pump on", "utf-8"))
elif self.path == '/off':
a.queue_command(Command(0, 0))
self.wfile.write(bytes("Switching pump off", "utf-8"))
httpd = HTTPServer(('', 80), SprinklerHTTPRequestHandler)
Thread(target=httpd.serve_forever, daemon=True).start()
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)
Thread(target=client.loop_forever,
kwargs={"retry_first_connection": False},
daemon=True).start()