CHECKPOINT BEFORE SITE IS DELETED FROM PROJECT
@ -55,21 +55,21 @@ class DataCollector:
|
||||
# or push previous data
|
||||
return {"data": "TODO"}
|
||||
|
||||
# try:
|
||||
try:
|
||||
rsp = api_get(self.__NODE_H_ENDPOINT)
|
||||
rsp_json = rsp.json()
|
||||
local_hmdt = rsp_json.get('value', False)
|
||||
# except Exception:
|
||||
# logging.error('Failed to get data from humidity node!!!')
|
||||
# local_hmdt = 0
|
||||
except Exception as e:
|
||||
logging.error(f'Failed to get data from humidity node!!!, {e}')
|
||||
local_hmdt = -50
|
||||
|
||||
try:
|
||||
rsp = api_get(self.__NODE_T_ENDPOINT)
|
||||
rsp_json = rsp.json()
|
||||
local_temp = rsp_json.get('value', False)
|
||||
except Exception:
|
||||
logging.error('Failed to get data from local temp node!!!')
|
||||
local_temp = 0
|
||||
except Exception as e:
|
||||
logging.error(f'Failed to get data from local temp node!!!, {e}')
|
||||
local_temp = -50
|
||||
|
||||
weather_data = api_data.json()
|
||||
station_data = weather_data.get('main', False)
|
||||
|
||||
1811
data_processing/datasets(old)/exported_dataset.csv
Normal file
7
lora_nodes/master/irrigator/Dockerfile
Normal file
@ -0,0 +1,7 @@
|
||||
FROM python:3.8
|
||||
WORKDIR /code
|
||||
COPY . .
|
||||
RUN pip install requests
|
||||
RUN pip install -r requirements.txt
|
||||
EXPOSE 3333
|
||||
CMD "/code/irrigator.py"
|
||||
94
lora_nodes/master/irrigator/irrigator.py
Normal file
@ -0,0 +1,94 @@
|
||||
#!/usr/local/bin/python
|
||||
import board
|
||||
import busio
|
||||
import digitalio
|
||||
import logging
|
||||
from requests import get as api_get
|
||||
|
||||
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 = 2
|
||||
__MAX_ATTEMPTS = 5
|
||||
|
||||
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 Irrigator:
|
||||
__DATA_ENDPOINT = "http://todo.maxhunt/design/water"
|
||||
|
||||
def __init__(self):
|
||||
self.com = LoRa()
|
||||
self.yesterday_water = 0
|
||||
|
||||
def get_today_watering_vol(self):
|
||||
endpoint = self.__DATA_ENDPOINT
|
||||
rsp = api_get(endpoint)
|
||||
if rsp.status_code != 200:
|
||||
logging.error(f'Got code {rsp.status_code} from server, using yesterday\'s value')
|
||||
return self.yesterday_water
|
||||
today_water = rsp.json().get('value')
|
||||
self.yesterday_water = today_water
|
||||
return today_water
|
||||
|
||||
def send_watering_command(self, volume: int):
|
||||
self.com.send_and_wait(f'iot_pmp_ctrl|{str(volume)}')
|
||||
|
||||
def mainloop(self):
|
||||
while True:
|
||||
watering_vol = self.get_today_watering_vol()
|
||||
self.send_watering_command(watering_vol)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
irrigator = Irrigator()
|
||||
irrigator.mainloop()
|
||||
6
lora_nodes/master/irrigator/requirements.txt
Normal file
@ -0,0 +1,6 @@
|
||||
Adafruit-Blinka==5.9.1
|
||||
adafruit-circuitpython-busdevice==5.0.1
|
||||
adafruit-circuitpython-rfm69==2.1.0
|
||||
Adafruit-PlatformDetect==2.23.0
|
||||
Adafruit-PureIO==1.1.8
|
||||
RPi.GPIO==0.7.0
|
||||
@ -106,6 +106,7 @@ if __name__ == "__main__":
|
||||
|
||||
@node.route("/hmdt")
|
||||
def humidity():
|
||||
global prev_hmdt
|
||||
humidity = master.get_hmdt()
|
||||
if humidity:
|
||||
prev_hmdt = humidity
|
||||
@ -114,6 +115,7 @@ if __name__ == "__main__":
|
||||
|
||||
@node.route("/temp")
|
||||
def temp():
|
||||
global prev_temp
|
||||
temp = master.get_temp()
|
||||
if temp:
|
||||
prev_temp = temp
|
||||
|
||||
@ -63,7 +63,7 @@ class WateringPump:
|
||||
'''
|
||||
flow_rate = self.__FLOW_RATE
|
||||
run_duration_seconds = volume*60/flow_rate
|
||||
self.run_for(run_duration_seconds)
|
||||
self.__run_for(run_duration_seconds)
|
||||
|
||||
def __run_for(self, duration: float):
|
||||
start_time = time.time()
|
||||
@ -125,7 +125,10 @@ class SensorNode:
|
||||
logging.debug(f'Decoded command: {command}')
|
||||
commands = str(command).split('|')
|
||||
logging.debug(f'Processed commands: {commands}')
|
||||
try:
|
||||
self.__instrucitons[commands[0]](commands[1])
|
||||
except Exception as e:
|
||||
logging.error(f'Exception: {e}')
|
||||
|
||||
def ping(self, *_):
|
||||
time.sleep(0.5)
|
||||
@ -143,10 +146,10 @@ class SensorNode:
|
||||
|
||||
def pump_control(self, volume):
|
||||
water_qty = int(volume)
|
||||
logging.info(f'Running pump for {water_qty} ml.')
|
||||
logging.info(f'Dispensing {water_qty} ml.')
|
||||
time.sleep(0.5)
|
||||
self.com.send_message('OK')
|
||||
self.pump.dispense(volume)
|
||||
self.pump.dispense(water_qty)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
BIN
project media/0154B9EC-45B9-4BFC-9143-5A19A0AE13E0.JPG
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
project media/17439CCA-8A93-4303-933B-59A431194B29.JPG
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
project media/87573994-8C9B-4D46-945B-DB478AB7F644.JPG
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
project media/F88F2801-3B5B-458E-83E0-C740C124A312.JPG
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
BIN
project media/IMG_8993.JPG
Normal file
|
After Width: | Height: | Size: 3.6 MiB |
BIN
project media/IMG_9021.JPG
Normal file
|
After Width: | Height: | Size: 3.4 MiB |
BIN
project media/IMG_9023.JPG
Normal file
|
After Width: | Height: | Size: 4.6 MiB |
BIN
project media/IMG_9024.JPG
Normal file
|
After Width: | Height: | Size: 4.5 MiB |
BIN
project media/IMG_9025.JPG
Normal file
|
After Width: | Height: | Size: 4.3 MiB |
BIN
project media/IMG_9026.JPG
Normal file
|
After Width: | Height: | Size: 7.7 MiB |
BIN
project media/IMG_9027.JPG
Normal file
|
After Width: | Height: | Size: 5.7 MiB |
BIN
project media/IMG_9028.JPG
Normal file
|
After Width: | Height: | Size: 7.7 MiB |
BIN
project media/IMG_9029.JPG
Normal file
|
After Width: | Height: | Size: 3.3 MiB |
BIN
project media/IMG_9030.JPG
Normal file
|
After Width: | Height: | Size: 2.8 MiB |
BIN
project media/IMG_9031.JPG
Normal file
|
After Width: | Height: | Size: 4.1 MiB |
BIN
project media/IMG_9032.JPG
Normal file
|
After Width: | Height: | Size: 3.9 MiB |
BIN
project media/IMG_9033.JPG
Normal file
|
After Width: | Height: | Size: 6.6 MiB |
BIN
project media/IMG_9034.JPG
Normal file
|
After Width: | Height: | Size: 5.8 MiB |
BIN
project media/IMG_9035.JPG
Normal file
|
After Width: | Height: | Size: 6.0 MiB |
BIN
project media/IMG_9036.JPG
Normal file
|
After Width: | Height: | Size: 6.1 MiB |
@ -9,16 +9,20 @@ app.set('view engine', 'ejs')
|
||||
app.set('views', __dirname + '/views')
|
||||
|
||||
|
||||
app.get('/', function(request, responce){
|
||||
responce.render('index.ejs')
|
||||
// app.get('/', function(request, responce) {
|
||||
// responce.render('index.ejs')
|
||||
// })
|
||||
|
||||
app.get('/water', function(req, res) {
|
||||
res.send({ success: true, value: 20 })
|
||||
})
|
||||
|
||||
app.get('*', function(request, responce){
|
||||
responce.render('404.ejs')
|
||||
app.get('*', function(request, responce) {
|
||||
res.redirect('siot.maxhunt.design');
|
||||
})
|
||||
|
||||
app.post('*', function(request, responce){
|
||||
responce.status(404).send({success:false, error:"404"})
|
||||
app.post('*', function(request, responce) {
|
||||
responce.status(404).send({ success: false, error: "404" })
|
||||
})
|
||||
|
||||
var port = 5050
|
||||
|
||||