2021-04-29 07:16:56 +02:00

177 lines
5.7 KiB
Python

import os
import json
import datetime
import logging
import shutil
from threading import Thread
from time import sleep
from flask import Flask
from flask import render_template
from flask import make_response
from flask import request
from flask import jsonify
import RPi.GPIO as GPIO
log_level = logging.INFO
LOG_FILE = "/var/log/hochbeet.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('hochbeet')
class GreenControl(Thread):
def __init__(self):
super(GreenControl, self).__init__()
self.__config_file = os.path.join(os.path.expanduser('~'), ".config/hochbeet/config.json")
self.__config = None
self.__pin = None
self.__run_condition = True
self.__water_state = False
self.__trigger_read_config = True
try:
with open(self.__config_file, "r") as handle:
self.__config = json.load(handle)
except FileNotFoundError:
# create default config
os.makedirs(os.path.dirname(self.__config_file), exist_ok=True)
pwd = os.getcwd()
shutil.copyfile("config/config.json", self.__config_file)
with open(self.__config_file, "r") as handle:
self.__config = json.load(handle)
def run(self):
while self.__run_condition:
if self.__trigger_read_config:
self.__trigger_read_config = False
with open(self.__config_file, "r") as f:
self.__config = json.load(f)
self.__pin = int(self.__config['water'][0]['pin'])
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(self.__pin, GPIO.OUT)
now = datetime.datetime.now()
if self.__config['water'][0]['autostate']:
idx = 0
if int(now.hour) >= 12:
idx = 1
on_time_pattern = self.__config['water'][0]['times'][idx]['on_time']
on_time_pattern = on_time_pattern.split(':')
on_time = now.replace(hour=int(on_time_pattern[0]),
minute=int(on_time_pattern[1]),
second=0,
microsecond=0)
off_time_pattern = self.__config['water'][0]['times'][idx]['off_time']
off_time_pattern = off_time_pattern.split(':')
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:
GPIO.output(self.__pin, 1)
self.__water_state = True
log.info("Switch water on by time")
elif now > off_time and self.__water_state:
GPIO.output(self.__pin, 0)
self.__water_state = False
log.info("Switch water off by time")
sleep(1)
def state(self):
return self.__water_state
def get_auto_state(self):
state = False
if self.__config['water'][0]['autostate']:
state = self.__config['water'][0]['autostate']
return state
def set_auto_state(self, state):
self.__config['water'][0]['autostate'] = state
with open(self.__config_file, "w") as handle:
json.dump(self.__config, handle)
self.__trigger_read_config = True
def get_times(self):
times = None
if self.__config['water'][0]['times']:
times = self.__config['water'][0]['times']
return times
def set_times(self, times):
self.__config['water'][0]['times'] = times
with open(self.__config_file, "w") as handle:
json.dump(self.__config, handle)
self.__trigger_read_config = True
def switch_water(self, state):
if state:
GPIO.output(self.__pin, 1)
else:
GPIO.output(self.__pin, 0)
green_ctrl = GreenControl()
green_ctrl.start()
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/sample', methods=['GET'])
def get_sample():
global green_ctrl
sample = {}
sample["id"] = str(1)
sample["state"] = green_ctrl.state()
return make_response(jsonify(sample), 200)
@app.route('/sample', methods=['PATCH'])
def patch_sample():
global green_ctrl
record = json.loads(request.data)
if "waterstate" in record:
if record["waterstate"]:
log.info("Switch water on by button: %s", datetime.datetime.now())
else:
log.info("Switch water off by button: %s", datetime.datetime.now())
return make_response("", 204)
@app.route('/config', methods=['GET'])
def get_config():
global green_ctrl
config = {}
config["autostate"] = green_ctrl.get_auto_state()
config["times"] = green_ctrl.get_times()
return make_response(jsonify(config), 200)
@app.route('/config', methods=['PATCH'])
def patch_config():
global green_ctrl
record = json.loads(request.data)
if "id" in record and record['id'] == '1':
if "autostate" in record:
green_ctrl.set_auto_state(record['autostate'])
if "times" in record:
green_ctrl.set_times(record['times'])
config = {}
config["autostate"] = green_ctrl.get_auto_state()
config["times"] = green_ctrl.get_times()
return make_response(jsonify(config), 200)
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=8000)