diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..bf9fb4c
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,27 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Python: Flask",
+ "type": "python",
+ "request": "launch",
+ "module": "flask",
+ "env": {
+ "FLASK_APP": "greenhouse/app.py",
+ "FLASK_ENV": "development",
+ "FLASK_DEBUG": "0"
+ },
+ "args": [
+ "run",
+ "--no-debugger",
+ "--no-reload",
+ "--host=0.0.0.0",
+ "--port=8000"
+ ],
+ "jinja": true
+ }
+ ]
+}
\ No newline at end of file
diff --git a/greenhouse/__init__.py b/greenhouse/__init__.py
index e69de29..c07c459 100644
--- a/greenhouse/__init__.py
+++ b/greenhouse/__init__.py
@@ -0,0 +1 @@
+from .app import app
diff --git a/greenhouse/app.py b/greenhouse/app.py
new file mode 100644
index 0000000..6fa68ef
--- /dev/null
+++ b/greenhouse/app.py
@@ -0,0 +1,119 @@
+from flask import Flask
+from flask import render_template
+from flask import redirect
+from flask import url_for
+from flask import make_response
+from flask import request
+
+import json
+
+from datetime import datetime, timedelta
+from threading import Thread
+from time import sleep
+
+from w1thermsensor import W1ThermSensor
+import RPi.GPIO as GPIO
+
+sensor = W1ThermSensor()
+water_pin = 26 #17/27/22
+heat_pin = 20
+
+heat_state = False
+
+GPIO.setwarnings(False)
+GPIO.setmode(GPIO.BCM)
+GPIO.setup(water_pin, GPIO.OUT)
+
+class Heat(Thread):
+ def __init__(self, pin):
+ super(Heat, self).__init__()
+ self.__pin = pin
+ self.__state = False
+ GPIO.setup(pin, GPIO.OUT)
+ if GPIO.input(pin):
+ self.__state = True
+ self.__run_condition = True
+ self.__next_update = datetime.now()
+
+ def on(self):
+ self.__state = True
+ GPIO.output(self.__pin, 1)
+
+ def off(self):
+ self.__state = False
+ GPIO.output(self.__pin, 0)
+
+ def run(self):
+ self.__next_update = datetime.now()
+ while self.__run_condition:
+ now = datetime.now()
+ if now >= self.__next_update:
+ if self.__state:
+ # Do a power cycle to prevent auto-poweroff
+ GPIO.output(self.__pin, 0)
+ sleep(5)
+ GPIO.output(self.__pin, 1)
+ self.__next_update = now + timedelta(minutes=5)
+ sleep(1)
+
+ def stop(self):
+ self.__run_condition = False
+ self.join()
+
+
+ def state(self):
+ return self.__state
+
+
+heat = Heat(heat_pin)
+heat.start()
+
+app = Flask(__name__)
+
+
+@app.route('/')
+def index():
+ return render_template('index.html')
+
+
+@app.route('/sample', methods=['GET'])
+def get_sample():
+ global heat
+ global sensor
+ try:
+ temperature = f"{float(sensor.get_temperature()):.1f}"
+ except SensorNotReadyError:
+ temperature = None
+
+ water_state = False
+ if GPIO.input(water_pin):
+ water_state = True
+
+ res = {}
+ res["id"] = str(1)
+ if(temperature):
+ res["temperature"] = temperature
+ res["water"] = water_state
+ res["heat"] = heat.state()
+ return res
+
+
+@app.route('/sample', methods=['PATCH'])
+def patch_reroute():
+ global heat
+ record = json.loads(request.data)
+ if "water" in record:
+ water_state = record["water"]
+ if water_state:
+ GPIO.output(water_pin, 1)
+ else:
+ GPIO.output(water_pin, 0)
+ if "heat" in record:
+ heat_state = record["heat"]
+ if heat_state:
+ heat.on()
+ else:
+ heat.off()
+
+ res = make_response("", 204)
+ return res
\ No newline at end of file
diff --git a/greenhouse/static/css/style.css b/greenhouse/static/css/style.css
new file mode 100644
index 0000000..4d3e907
--- /dev/null
+++ b/greenhouse/static/css/style.css
@@ -0,0 +1,35 @@
+html, body {
+ font-size: 22px !important;
+ font-family: arial, verdana, helvetica, sans-serif;
+ color: #b6b6b6;
+ background: #282929;
+}
+
+h1 {text-align: center;}
+p {text-align: center;}
+div {text-align: center;}
+
+.center {
+ margin-left: auto;
+ margin-right: auto;
+ text-align: center;
+}
+
+input[type="submit" i] {
+ color: #b6b6b6;
+ background-color: #282929;
+ padding: 10px;
+ margin: 10px 0;
+ border-color: #b6b6b6;
+ border-width: 3px;
+ border-radius: 18px;
+ font-size: 20px;
+}
+
+td {
+ padding: 8px;
+}
+
+.table_left {
+ text-align: right;
+}
\ No newline at end of file
diff --git a/greenhouse/static/scripts/index.js b/greenhouse/static/scripts/index.js
new file mode 100644
index 0000000..1f03f66
--- /dev/null
+++ b/greenhouse/static/scripts/index.js
@@ -0,0 +1,66 @@
+var on_switch_heat = function() {
+ var state = true;
+ if(document.getElementById("heat_switch").value == "ausschalten") {
+ state = false;
+ }
+ var json_str = JSON.stringify({"id": "1", "heat": state});
+ patch_sample(json_str);
+}
+
+var on_switch_water = function() {
+ var state = true;
+ if(document.getElementById("water_switch").value == "ausschalten") {
+ state = false;
+ }
+ var json_str = JSON.stringify({"id": "1", "water": state});
+ patch_sample(json_str);
+}
+
+var patch_http = new XMLHttpRequest();
+var patch_sample = function(sample) {
+ patch_http.abort();
+ patch_http.open("PATCH", "/sample");
+ patch_http.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
+ patch_http.send(sample);
+}
+
+var get_sample = function (event) {
+ var sample = JSON.parse(event)
+ output = "einschalten"
+ out_state = "aus"
+ if(sample.water) {
+ output = "ausschalten"
+ out_state = "an"
+ }
+ document.getElementById("temperature_value").innerHTML = sample.temperature + " °C";
+ document.getElementById("water_switch").value = output;
+ document.getElementById("water_state").innerHTML = out_state;
+ if(sample.heat) {
+ output = "ausschalten"
+ out_state = "an"
+ } else {
+ output = "einschalten"
+ out_state = "aus"
+ }
+ document.getElementById("heat_switch").value = output;
+ document.getElementById("heat_state").innerHTML = out_state;
+}
+
+var http = new XMLHttpRequest();
+http.onreadystatechange = function () {
+ if (http.readyState === 4) {
+ var status = http.status;
+ if (status === 0 || (status >= 200 && status < 400)) {
+ // The request has been completed successfully
+ get_sample(http.responseText);
+ setTimeout(function () {
+ http.open("GET", 'sample');
+ http.send();
+ }, 500);
+ }
+ } else {
+ // request error
+ }
+}
+http.open("GET", "sample");
+http.send();
diff --git a/greenhouse/templates/index.html b/greenhouse/templates/index.html
new file mode 100644
index 0000000..a073c84
--- /dev/null
+++ b/greenhouse/templates/index.html
@@ -0,0 +1,36 @@
+
+
+
+ Gewächshaus
+
+
+
+
+
+
+ Gewächshaus
+
+
+
+
+
diff --git a/setup.py b/setup.py
index 8f2cc69..703ba75 100755
--- a/setup.py
+++ b/setup.py
@@ -1,29 +1,16 @@
-#!/usr/bin/python3
-'''
-@author: Thomas Klaehn
-'''
-from setuptools import setup
+import sys
import os
import shutil
import stat
-import sys
+from setuptools import setup
-NAME = 'greenhouse'
-VERSION = '1.0.0'
+NAME = 'Greenhouse'
+VERSION = '1'
AUTHOR = 'Thomas Klaehn'
EMAIL = 'tkl@blackfinn.de'
-SYSTEMD_SCRIPTS = ['greenhouse.service']
PACKAGES = ['greenhouse']
-PACKAGE_DIRS = {'greenhouse':'greenhouse'}
-REQUIRES = ['RPi.GPIO', 'w1thermsensor']
+REQUIRES = ['Flask', 'w1thermsensor', 'RPi.GPIO']
-SYSTEMD_PATH = '/lib/systemd/system/'
-if sys.argv[1] == 'install':
- for script in SYSTEMD_SCRIPTS:
- shutil.copyfile(script, os.path.join(SYSTEMD_PATH, script))
- os.chmod(os.path.join(SYSTEMD_PATH, script), stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
- setup(name=NAME, version=VERSION, author=AUTHOR, author_email=EMAIL, package_dir=PACKAGE_DIRS, packages=PACKAGES, install_requires=REQUIRES)
-elif sys.argv[1] == 'sdist':
- setup(name=NAME, version=VERSION, author=AUTHOR, author_email=EMAIL, package_dir=PACKAGE_DIRS, packages=PACKAGES, install_requires=REQUIRES,
- scripts=SYSTEMD_SCRIPTS)
+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)