From 2307810ec33443c8e18ceaf07f2dd18d15c5f8ee Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 21 Dec 2020 19:04:20 +0000 Subject: [PATCH] Update --- lora_nodes/master/Dockerfile | 0 lora_nodes/master/main.py | 92 ++++++++++++++++ lora_nodes/slave/Dockerfile | 5 + lora_nodes/slave/main.py | 122 ++++++++++++++++++++++ lora_nodes/testing/lora_testing_master.py | 29 +++++ lora_nodes/testing/lora_testing_slave.py | 36 +++++++ site/.firebaserc | 5 + site/.gitignore | 66 ++++++++++++ site/firebase.json | 16 +++ 9 files changed, 371 insertions(+) create mode 100644 lora_nodes/master/Dockerfile create mode 100644 lora_nodes/master/main.py create mode 100644 lora_nodes/slave/Dockerfile create mode 100644 lora_nodes/slave/main.py create mode 100644 lora_nodes/testing/lora_testing_master.py create mode 100644 lora_nodes/testing/lora_testing_slave.py create mode 100644 site/.firebaserc create mode 100644 site/.gitignore create mode 100644 site/firebase.json diff --git a/lora_nodes/master/Dockerfile b/lora_nodes/master/Dockerfile new file mode 100644 index 0000000..e69de29 diff --git a/lora_nodes/master/main.py b/lora_nodes/master/main.py new file mode 100644 index 0000000..fe70786 --- /dev/null +++ b/lora_nodes/master/main.py @@ -0,0 +1,92 @@ +#!/usr/local/bin/python +import board +import busio +import digitalio +import logging +import time + +import adafruit_rfm69 + + +class LoRa: + __SIGNAL_FREQUENCY = 915.0 + __ENCRYPTION_KEY = b"\x01\x01\x01\x01\x01\x01\x01\x01\x02\x02\x02\x02\x02\x02\x02\x02" + __PINS = { + 'miso': board.MISO, + 'mosi': board.MOSI, + 'sck': board.SCK, + 'cs': board.D22, + 'rst': board.D27 + } + __PACKET_WAIT = 3 + __MAX_ATTEMPTS = 3 + + def __init__(self): + spi = busio.SPI(self.__PINS['sck'], + MOSI=self.__PINS['mosi'], + MISO=self.__PINS['miso']) + cs = digitalio.DigitalInOut(self.__PINS['cs']) + rst = digitalio.DigitalInOut(self.__PINS['rst']) + self.lora = adafruit_rfm69.RFM69(spi, cs, rst, self.__SIGNAL_FREQUENCY) + self.lora.encryption_key = self.__ENCRYPTION_KEY + logging.debug(f'Init\'d LoRa board with freq: {self.lora.frequency_mhz}, bitrate: {self.lora.bitrate / 1000} kbit/s, f. deviation: {self.lora.frequency_deviation/1000} khz, and encryption key: {self.lora.encryption_key}') + + def receive_message(self): + logging.debug('Waiting for message...') + packets = self.lora.receive(timeout=self.__PACKET_WAIT) + if packets: + logging.debug(f'Got packets: {packets}') + return packets + return False + + def send_message(self, message): + logging.debug(f'Sending message: {message}') + packets = bytes(message, 'utf-8') + self.lora.send(packets) + + def send_and_wait(self, message): + attempt = 0 + max_attempts = self.__MAX_ATTEMPTS + waiting_for_response = True + response = None + + while waiting_for_response: + logging.debug(f'Attempt {attempt}...') + attempt += 1 + + self.send_message(message) + response = self.receive_message() + + if attempt > max_attempts or response: + waiting_for_response = False + + return response + + +class Master: + + def __init__(self): + self.com = LoRa() + logging.info('Pining slave') + rsp = self.com.send_and_wait('ping|') + print(f'Slave is {rsp}') + + def get_temp(self): + temp = self.com.send_and_wait('iot_g_temp|') + logging.info(f'Got temp from slave: {temp}ÂșC') + return temp + + def get_hmdt(self): + hmdt = self.com.send_and_wait('iot_g_hmdt|') + logging.info(f'Got hmdt from slave: {hmdt}') + return hmdt + + def run_pump(self, volume): + status = self.com.send_and_wait(f'iot_pmp_ctrl|{str(volume)}') + logging.info(status) + return status + + +if __name__ == "__main__": + logging.root.setLevel(logging.DEBUG) + master = Master() diff --git a/lora_nodes/slave/Dockerfile b/lora_nodes/slave/Dockerfile new file mode 100644 index 0000000..677989b --- /dev/null +++ b/lora_nodes/slave/Dockerfile @@ -0,0 +1,5 @@ +FROM python:3.8 +WORKDIR /code +COPY . . +RUN pip install -r requirements.txt +CMD "/code/main.py" diff --git a/lora_nodes/slave/main.py b/lora_nodes/slave/main.py new file mode 100644 index 0000000..754a4ce --- /dev/null +++ b/lora_nodes/slave/main.py @@ -0,0 +1,122 @@ +#!/usr/local/bin/python +import board +import busio +import digitalio +import time +import logging + +import adafruit_rfm69 +from adafruit_seesaw.seesaw import Seesaw + + +class LoRa: + __SIGNAL_FREQUENCY = 915.0 + __ENCRYPTION_KEY = b"\x01\x01\x01\x01\x01\x01\x01\x01\x02\x02\x02\x02\x02\x02\x02\x02" + __PINS = { + 'miso': board.MISO, + 'mosi': board.MOSI, + 'sck': board.SCK, + 'cs': board.D22, + 'rst': board.D27 + } + __PACKET_WAIT = 2 + + def __init__(self): + spi = busio.SPI(self.__PINS['sck'], + MOSI=self.__PINS['mosi'], + MISO=self.__PINS['miso']) + cs = digitalio.DigitalInOut(self.__PINS['cs']) + rst = digitalio.DigitalInOut(self.__PINS['rst']) + self.lora = adafruit_rfm69.RFM69(spi, cs, rst, self.__SIGNAL_FREQUENCY) + self.lora.encryption_key = self.__ENCRYPTION_KEY + logging.debug(f'Init\'d LoRa board with freq: {self.lora.frequency_mhz}, bitrate: {self.lora.bitrate / 1000} kbit/s, f. deviation: {self.lora.frequency_deviation/1000} khz, and encryption key: {self.lora.encryption_key}') + + def receive_message(self): + packets = self.lora.receive(timeout=self.__PACKET_WAIT) + if packets: + logging.debug(f'Got packets: {packets}') + return packets + return False + + def send_message(self, message): + logging.debug(f'Sending message: {message}') + packets = bytes(message, 'utf-8') + self.lora.send(packets) + + +class WateringPump: + def __init__(self): + pass + + +class SoliSensor: + __PINS = { + 'sda': board.SDA, + 'scl': board.SCL + } + + def __init__(self): + i2c = busio.I2C(self.__PINS['scl'], self.__PINS['sda']) + self.sensor = Seesaw(i2c, addr=0x36) + logging.debug(f'Init\'d soil sensor, humidity: {self.sensor.moisture_read()}, temp: {self.sensor.get_temp()}') + + def get_temp(self): + temp = self.sensor.get_temp() + logging.debug(f'Temp: {temp}') + return temp + + def get_hmdt(self): + hmdt = self.sensor.moisture_read() + logging.debug(f'Humidity: {hmdt}') + return hmdt + + +class Slave: + + def __init__(self): + self.com = LoRa() + self.probe = SoliSensor() + self.pump = WateringPump() + + def wait_for_instructions(self): + self.__instrucitons = { + 'ping': self.ping, + 'iot_g_temp': self.get_soil_temp, + 'iot_g_hmdt': self.get_soil_hmdt, + 'iot_pmp_ctrl': self.pump_control + } + while True: + command = self.com.receive_message() + if command: + command = command.decode() + logging.debug(f'Decoded command: {command}') + commands = str(command).split('|') + logging.debug(f'Processed commands: {commands}') + self.__instrucitons[commands[0]](commands[1]) + + def ping(self, *_): + time.sleep(0.5) + self.com.send_message('OK') + + def get_soil_temp(self, *_): + soil_temp = self.probe.get_temp() + time.sleep(0.5) + self.com.send_message(str(soil_temp)) + + def get_soil_hmdt(self, *_): + soil_hmdt = self.probe.get_hmdt() + time.sleep(0.5) + self.com.send_message(str(soil_hmdt)) + + def pump_control(self, volume): + water_qty = int(volume) + print(f'Running pump for {water_qty} ml.') + time.sleep(0.5) + self.com.send_message('OK') + time.sleep(water_qty) + + +if __name__ == "__main__": + logging.root.setLevel(logging.DEBUG) + slave = Slave() + slave.wait_for_instructions() diff --git a/lora_nodes/testing/lora_testing_master.py b/lora_nodes/testing/lora_testing_master.py new file mode 100644 index 0000000..7d37fa8 --- /dev/null +++ b/lora_nodes/testing/lora_testing_master.py @@ -0,0 +1,29 @@ +import board +import busio +import digitalio + +import adafruit_rfm69 + +SIGNAL_FREQUENCY = 915.0 +ENCRYPTION_KEY = b"\x01\x01\x01\x01\x01\x01\x01\x01\x02\x02\x02\x02\x02\x02\x02\x02" + +pins = { + 'miso': board.MISO, + 'mosi': board.MOSI, + 'sck': board.SCK, + 'cs': board.D22, + 'rst': board.D27 +} + +spi = busio.SPI(pins['sck'], MOSI=pins['mosi'], MISO=pins['miso']) +cs = digitalio.DigitalInOut(pins['cs']) +reset = digitalio.DigitalInOut(pins['rst']) + +lora = adafruit_rfm69.RFM69(spi, cs, reset, SIGNAL_FREQUENCY) +lora.encryption_key = (ENCRYPTION_KEY) + +while True: + packet = lora.receive(timeout=2) + if packet: + print(f"Recieved data: {packet}") + print(f"RSSI: {lora.rssi}") diff --git a/lora_nodes/testing/lora_testing_slave.py b/lora_nodes/testing/lora_testing_slave.py new file mode 100644 index 0000000..979c96b --- /dev/null +++ b/lora_nodes/testing/lora_testing_slave.py @@ -0,0 +1,36 @@ +import board +import busio +import digitalio +import time + +import adafruit_rfm69 + +SIGNAL_FREQUENCY = 915.0 +ENCRYPTION_KEY = b"\x01\x01\x01\x01\x01\x01\x01\x01\x02\x02\x02\x02\x02\x02\x02\x02" + +pins = { + 'miso': board.MISO, + 'mosi': board.MOSI, + 'sck': board.SCK, + 'cs': board.D22, + 'rst': board.D27 +} + +spi = busio.SPI(pins['sck'], MOSI=pins['mosi'], MISO=pins['miso']) +cs = digitalio.DigitalInOut(pins['cs']) +reset = digitalio.DigitalInOut(pins['rst']) + +lora = adafruit_rfm69.RFM69(spi, cs, reset, SIGNAL_FREQUENCY) +lora.encryption_key = (ENCRYPTION_KEY) + +while True: + print("Temperature: {0}C".format(lora.temperature)) + print("Frequency: {0}mhz".format(lora.frequency_mhz)) + print("Bit rate: {0}kbit/s".format(lora.bitrate / 1000)) + print("Frequency deviation: {0}hz".format(lora.frequency_deviation)) + + str_time = str(time.time()) + msg = f"Testing message {str_time}" + lora.send(bytes(msg, 'utf-8')) + print(f'Sent message: {msg}') + time.sleep(2) diff --git a/site/.firebaserc b/site/.firebaserc new file mode 100644 index 0000000..70926c7 --- /dev/null +++ b/site/.firebaserc @@ -0,0 +1,5 @@ +{ + "projects": { + "default": "icl-iot-weather" + } +} diff --git a/site/.gitignore b/site/.gitignore new file mode 100644 index 0000000..dbb58ff --- /dev/null +++ b/site/.gitignore @@ -0,0 +1,66 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +firebase-debug.log* +firebase-debug.*.log* + +# Firebase cache +.firebase/ + +# Firebase config + +# Uncomment this if you'd like others to create their own Firebase project. +# For a team working on the same Firebase project(s), it is recommended to leave +# it commented so all members can deploy to the same project(s) in .firebaserc. +# .firebaserc + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env diff --git a/site/firebase.json b/site/firebase.json new file mode 100644 index 0000000..d3febc5 --- /dev/null +++ b/site/firebase.json @@ -0,0 +1,16 @@ +{ + "hosting": { + "public": "views", + "ignore": [ + "firebase.json", + "**/.*", + "**/node_modules/**" + ], + "rewrites": [ + { + "source": "**", + "destination": "/index.html" + } + ] + } +}