This commit is contained in:
Max 2020-12-21 19:04:20 +00:00
parent 13f821c23b
commit 2307810ec3
9 changed files with 371 additions and 0 deletions

View File

92
lora_nodes/master/main.py Normal file
View File

@ -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()

View File

@ -0,0 +1,5 @@
FROM python:3.8
WORKDIR /code
COPY . .
RUN pip install -r requirements.txt
CMD "/code/main.py"

122
lora_nodes/slave/main.py Normal file
View File

@ -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()

View File

@ -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}")

View File

@ -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)

5
site/.firebaserc Normal file
View File

@ -0,0 +1,5 @@
{
"projects": {
"default": "icl-iot-weather"
}
}

66
site/.gitignore vendored Normal file
View File

@ -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

16
site/firebase.json Normal file
View File

@ -0,0 +1,16 @@
{
"hosting": {
"public": "views",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}