Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
85b14a73ed | ||
d0f11e3398 | |||
fda8bcddc8 | |||
|
8274c5cd1a | ||
|
6c02fd1bca |
@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=idle
|
Type=idle
|
||||||
ExecStart=/usr/bin/python3 -m greenhouse
|
ExecStart=gunicorn --bind 0.0.0.0:80 greenhouse:app
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
|
import os
|
||||||
|
import site
|
||||||
import json
|
import json
|
||||||
import datetime
|
import datetime
|
||||||
|
import logging
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
@ -12,17 +15,26 @@ from w1thermsensor import W1ThermSensor
|
|||||||
import RPi.GPIO as GPIO
|
import RPi.GPIO as GPIO
|
||||||
|
|
||||||
sensor = W1ThermSensor()
|
sensor = W1ThermSensor()
|
||||||
water_pin = 17 #17/27/22
|
water_pin = 22 #17/27/22
|
||||||
heat_pin = 26
|
heat_pin = 26
|
||||||
|
|
||||||
heat_state = False
|
heat_state = False
|
||||||
|
|
||||||
CONFIG_FILE = "/etc/greenhouse/greenhouse.json"
|
PACKAGE_PATH = site.getsitepackages()[0]
|
||||||
|
CONFIG_FILE = os.path.join(PACKAGE_PATH, "greenhouse/config/greenhouse.json")
|
||||||
|
|
||||||
GPIO.setwarnings(False)
|
GPIO.setwarnings(False)
|
||||||
GPIO.setmode(GPIO.BCM)
|
GPIO.setmode(GPIO.BCM)
|
||||||
GPIO.setup(water_pin, GPIO.OUT)
|
GPIO.setup(water_pin, GPIO.OUT)
|
||||||
|
|
||||||
|
log_level = logging.INFO
|
||||||
|
LOG_FILE = "/var/log/greenhouse.log"
|
||||||
|
LOG_FORMAT = "%(asctime)s %(levelname)s %(message)s"
|
||||||
|
|
||||||
|
# logging.basicConfig(format=LOG_FORMAT, level=log_level, filename=LOG_FILE)
|
||||||
|
logging.basicConfig(format=LOG_FORMAT, level=log_level)
|
||||||
|
log = logging.getLogger('greenhouse')
|
||||||
|
|
||||||
class Heat(Thread):
|
class Heat(Thread):
|
||||||
def __init__(self, pin):
|
def __init__(self, pin):
|
||||||
super(Heat, self).__init__()
|
super(Heat, self).__init__()
|
||||||
@ -36,11 +48,11 @@ class Heat(Thread):
|
|||||||
|
|
||||||
def on(self):
|
def on(self):
|
||||||
self.__state = True
|
self.__state = True
|
||||||
GPIO.output(self.__pin, 1)
|
GPIO.output(self.__pin, 0)
|
||||||
|
|
||||||
def off(self):
|
def off(self):
|
||||||
self.__state = False
|
self.__state = False
|
||||||
GPIO.output(self.__pin, 0)
|
GPIO.output(self.__pin, 1)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self.__next_update = datetime.datetime.now()
|
self.__next_update = datetime.datetime.now()
|
||||||
@ -49,9 +61,9 @@ class Heat(Thread):
|
|||||||
if now >= self.__next_update:
|
if now >= self.__next_update:
|
||||||
if self.__state:
|
if self.__state:
|
||||||
# Do a power cycle to prevent auto-poweroff
|
# Do a power cycle to prevent auto-poweroff
|
||||||
GPIO.output(self.__pin, 0)
|
|
||||||
sleep(5)
|
|
||||||
GPIO.output(self.__pin, 1)
|
GPIO.output(self.__pin, 1)
|
||||||
|
sleep(5)
|
||||||
|
GPIO.output(self.__pin, 0)
|
||||||
self.__next_update = now + datetime.timedelta(minutes=5)
|
self.__next_update = now + datetime.timedelta(minutes=5)
|
||||||
sleep(1)
|
sleep(1)
|
||||||
|
|
||||||
@ -93,8 +105,10 @@ class GreenControl(Thread):
|
|||||||
temperature = sensor.get_temperature()
|
temperature = sensor.get_temperature()
|
||||||
if float(temperature) < float(self.config['heat']['on_temperature']) and not heat.state():
|
if float(temperature) < float(self.config['heat']['on_temperature']) and not heat.state():
|
||||||
heat.on()
|
heat.on()
|
||||||
|
log.info("Switch heat on by temperature level: %.1f °C", float(temperature))
|
||||||
elif float(temperature) > float(self.config['heat']['off_temperature']) and heat.state():
|
elif float(temperature) > float(self.config['heat']['off_temperature']) and heat.state():
|
||||||
heat.off()
|
heat.off()
|
||||||
|
log.info("Switch heat off by temperature level: %.1f °C", float(temperature))
|
||||||
elif heat.state():
|
elif heat.state():
|
||||||
# Do a power cycle to prevent auto-poweroff
|
# Do a power cycle to prevent auto-poweroff
|
||||||
heat.off()
|
heat.off()
|
||||||
@ -113,11 +127,13 @@ class GreenControl(Thread):
|
|||||||
off_time = now.replace(hour=int(off_time_pattern[0]), minute=int(off_time_pattern[1]), second=0, microsecond=0)
|
off_time = now.replace(hour=int(off_time_pattern[0]), minute=int(off_time_pattern[1]), second=0, microsecond=0)
|
||||||
|
|
||||||
if now > on_time and now <= off_time and not self.__water_state:
|
if now > on_time and now <= off_time and not self.__water_state:
|
||||||
GPIO.output(water_pin, 1)
|
|
||||||
self.__water_state = True
|
|
||||||
elif now > off_time and self.__water_state:
|
|
||||||
GPIO.output(water_pin, 0)
|
GPIO.output(water_pin, 0)
|
||||||
|
self.__water_state = True
|
||||||
|
log.info("Switch water on by time")
|
||||||
|
elif now > off_time and self.__water_state:
|
||||||
|
GPIO.output(water_pin, 1)
|
||||||
self.__water_state = False
|
self.__water_state = False
|
||||||
|
log.info("Switch water off by time")
|
||||||
sleep(1)
|
sleep(1)
|
||||||
|
|
||||||
|
|
||||||
@ -165,7 +181,7 @@ def get_sample():
|
|||||||
temperature = None
|
temperature = None
|
||||||
|
|
||||||
water_state = False
|
water_state = False
|
||||||
if GPIO.input(water_pin):
|
if not GPIO.input(water_pin):
|
||||||
water_state = True
|
water_state = True
|
||||||
|
|
||||||
res = {}
|
res = {}
|
||||||
@ -183,14 +199,18 @@ def patch_sample():
|
|||||||
record = json.loads(request.data)
|
record = json.loads(request.data)
|
||||||
if "water" in record:
|
if "water" in record:
|
||||||
if record["water"]:
|
if record["water"]:
|
||||||
GPIO.output(water_pin, 1)
|
|
||||||
else:
|
|
||||||
GPIO.output(water_pin, 0)
|
GPIO.output(water_pin, 0)
|
||||||
|
log.info("Switch water on by button: {}".format(datetime.datetime.now()))
|
||||||
|
else:
|
||||||
|
GPIO.output(water_pin, 1)
|
||||||
|
log.info("Switch water off by button: {}".format(datetime.datetime.now()))
|
||||||
if "heat" in record:
|
if "heat" in record:
|
||||||
if record["heat"]:
|
if record["heat"]:
|
||||||
heat.on()
|
heat.on()
|
||||||
|
log.info("Switch heat on by button: {}".format(datetime.datetime.now()))
|
||||||
else:
|
else:
|
||||||
heat.off()
|
heat.off()
|
||||||
|
log.info("Switch heat off by button: {}".format(datetime.datetime.now()))
|
||||||
|
|
||||||
res = make_response("", 204)
|
res = make_response("", 204)
|
||||||
return res
|
return res
|
||||||
|
15
setup.py
15
setup.py
@ -1,6 +1,3 @@
|
|||||||
import shutil
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
|
|
||||||
NAME = 'Greenhouse'
|
NAME = 'Greenhouse'
|
||||||
@ -11,14 +8,8 @@ PACKAGES = ['greenhouse']
|
|||||||
REQUIRES = ['Flask', 'w1thermsensor', 'RPi.GPIO']
|
REQUIRES = ['Flask', 'w1thermsensor', 'RPi.GPIO']
|
||||||
CONFIG_FOLDER = '/etc/greenhouse'
|
CONFIG_FOLDER = '/etc/greenhouse'
|
||||||
CONFIG_FILE = 'greenhouse.json'
|
CONFIG_FILE = 'greenhouse.json'
|
||||||
|
PACKAGE_DATA = {'greenhouse': ['templates/*', 'static/css/*', 'static/scripts/*', 'config/*']}
|
||||||
|
|
||||||
setup(name=NAME, version=VERSION, long_description=__doc__, author=AUTHOR, author_email=EMAIL,
|
setup(name=NAME, version=VERSION, long_description=__doc__, author=AUTHOR, author_email=EMAIL,
|
||||||
packages=PACKAGES, include_package_data=True, zip_safe=False, install_requires=REQUIRES)
|
packages=PACKAGES, include_package_data=True, package_data=PACKAGE_DATA, zip_safe=False,
|
||||||
|
install_requires=REQUIRES)
|
||||||
if sys.argv[1] == 'install':
|
|
||||||
try:
|
|
||||||
os.makedirs(CONFIG_FOLDER)
|
|
||||||
shutil.copyfile(CONFIG_FILE, os.path.join(CONFIG_FOLDER, CONFIG_FILE))
|
|
||||||
except FileExistsError:
|
|
||||||
#FIXME: handle overwriting the config file
|
|
||||||
pass
|
|
||||||
|
Loading…
Reference in New Issue
Block a user