Compare commits

..

5 Commits
web ... master

Author SHA1 Message Date
Thomas Klaehn
85b14a73ed config: Move config file 2021-04-06 08:51:12 +02:00
tkl
d0f11e3398 setup.py: Add package_data 2021-04-06 05:39:43 +00:00
tkl
fda8bcddc8 log output to std 2021-04-04 07:02:39 +00:00
Thomas Klaehn
8274c5cd1a Fix systemd service file 2021-04-04 08:50:25 +02:00
Thomas Klaehn
6c02fd1bca Fix heat pin handling 2021-04-04 08:49:35 +02:00
4 changed files with 44 additions and 32 deletions

View File

@ -1,10 +1,11 @@
[Unit] [Unit]
Description=Greenhouse service Description=Greenhouse service
After=multi-user.target After=multi-user.target
[Service] [Service]
Type=idle Type=idle
ExecStart=/usr/bin/python3 -m greenhouse ExecStart=gunicorn --bind 0.0.0.0:80 greenhouse:app
[Install]
WantedBy=multi-user.target
[Install]
WantedBy=multi-user.target

View File

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

View File

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