Update
This commit is contained in:
parent
13f821c23b
commit
2307810ec3
0
lora_nodes/master/Dockerfile
Normal file
0
lora_nodes/master/Dockerfile
Normal file
92
lora_nodes/master/main.py
Normal file
92
lora_nodes/master/main.py
Normal 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()
|
||||||
5
lora_nodes/slave/Dockerfile
Normal file
5
lora_nodes/slave/Dockerfile
Normal 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
122
lora_nodes/slave/main.py
Normal 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()
|
||||||
29
lora_nodes/testing/lora_testing_master.py
Normal file
29
lora_nodes/testing/lora_testing_master.py
Normal 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}")
|
||||||
36
lora_nodes/testing/lora_testing_slave.py
Normal file
36
lora_nodes/testing/lora_testing_slave.py
Normal 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
5
site/.firebaserc
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"projects": {
|
||||||
|
"default": "icl-iot-weather"
|
||||||
|
}
|
||||||
|
}
|
||||||
66
site/.gitignore
vendored
Normal file
66
site/.gitignore
vendored
Normal 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
16
site/firebase.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"hosting": {
|
||||||
|
"public": "views",
|
||||||
|
"ignore": [
|
||||||
|
"firebase.json",
|
||||||
|
"**/.*",
|
||||||
|
"**/node_modules/**"
|
||||||
|
],
|
||||||
|
"rewrites": [
|
||||||
|
{
|
||||||
|
"source": "**",
|
||||||
|
"destination": "/index.html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user