Webserver_Dashboard and basic functionality #1

Merged
Roman_Schenk merged 12 commits from Webserver_Layout into master 2022-08-23 20:28:05 +02:00
7 changed files with 204 additions and 52 deletions
Showing only changes of commit f1d73676f5 - Show all commits

View File

@ -1,15 +1,12 @@
from Zone import Zone from Zone import Zone
def loadZones():
zones = []
for i in range(12):
zones.append(Zone(i+1, "Zone " + str(i+1), 90, 10, True, False))
return zones
class FileIO:
def __init__(self, systemSettings):
self.systemSettings = systemSettings
def loadZones(self):
zones = []
if __name__ == "__main__": for i in range(12):
zones = loadZones() zones.append(Zone(number=i+1, name="Zone " + str(i+1), actualHumidity=100, desiredHumidity=0, autoMode=False, state=False, setState=0, endTimeSetState=0, planedDuration=0))
for zone in zones: return zones
print(zone.name)

6
SystemSettings.py Normal file
View File

@ -0,0 +1,6 @@
class SystemSettings:
def __init__(self, dataDir="/Data", multiZoneIrrigation=False):
self.dataDir = dataDir
self.multiZoneIrrigation = multiZoneIrrigation

View File

@ -66,18 +66,18 @@
<tr> <tr>
<td class="icon"> <td class="icon">
<span class="outer_dot"> <span class="outer_dot">
<span class="inner_icon {{ 'dot_green' if(zone.actualValue >= zone.setValue) else 'dot_red' }}"></span> <span class="inner_icon {{ 'dot_green' if(zone.actualHumidity >= zone.desiredHumidity) else 'dot_red' }}"></span>
</span> </span>
</td> </td>
<td class="property">{{ translater.getTranslation("actual humidity") }}:</td> <td class="property">{{ translater.getTranslation("actual humidity") }}:</td>
<td class="value">{{ zone.actualValue}}</td> <td class="value">{{ zone.actualHumidity}}</td>
</tr> </tr>
<tr> <tr>
<td class="icon"> <td class="icon">
</td> </td>
<td class="property">{{ translater.getTranslation("desired humidity") }}:</td> <td class="property">{{ translater.getTranslation("desired humidity") }}:</td>
<td class="value">{{ zone.setValue }}</td> <td class="value">{{ zone.desiredHumidity }}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@ -1,15 +1,15 @@
from flask import Flask, render_template, request, redirect, url_for from flask import Flask, render_template, request, redirect, url_for
from flask_navigation import Navigation from flask_navigation import Navigation
from FileIO import loadZones from Webserver.Translater import Translater, Language
from Translater import Translater, Language from Zone import Zone
from Zone import getZone
def startWebserver(port, zoneManager):
translater_EN = Translater(Language.ENGLISH)
translater_DE = Translater(Language.GERMAN)
translater = translater_EN
def startWebserver(port, translater, zones): app = Flask("Bewässerungssystem", template_folder="Webserver/templates", static_folder="Webserver/static")
app = Flask("Bewässerungssystem")
nav = Navigation(app) nav = Navigation(app)
nav.Bar('top', [ nav.Bar('top', [
@ -17,31 +17,56 @@ def startWebserver(port, translater, zones):
nav.Item(translater.getTranslation('irrigation zones'), 'showZones'), nav.Item(translater.getTranslation('irrigation zones'), 'showZones'),
nav.Item(translater.getTranslation('blocking times'), 'showTimes'), nav.Item(translater.getTranslation('blocking times'), 'showTimes'),
nav.Item(translater.getTranslation('system settings'), 'showSystem') nav.Item(translater.getTranslation('system settings'), 'showSystem')
#nav.Item('Gfg', 'gfg', {'page': 5}), #(example with pages) # nav.Item('Gfg', 'gfg', {'page': 5}), #(example with pages)
]) ])
#Example Route with pages: # Example Route with pages:
#@app.route('/gfg/<int:page>') # @app.route('/gfg/<int:page>')
#def gfg(page): # def gfg(page):
# return render_template('gfg.html', page=page) # return render_template('gfg.html', page=page)
@app.route('/') @app.route('/')
def startPage(): def startPage():
return redirect(url_for('showDashboard')) return redirect(url_for('showDashboard'))
@app.route('/action/<command>/<index_str>/<value_str>')
def executeAction(command=False, index_str=False, value_str=False):
sucess = False
index = int(index_str)
value = int(value_str)
match command:
case "switch_zone_on":
if (index and value):
zoneManager.switchZoneIndexState(zoneIndex=index, state=True, duration=value)
case "switch_zone_off":
if (index and value):
zoneManager.switchZoneIndexState(zoneIndex=index, state=False, duration=value)
case "switch_zone_mode":
if (index and value):
zone = zoneManager.getZone(index)
match value:
case "automatic":
zone.switchMode(autoMode=True)
case "manual":
zone.switchMode(autoMode=False)
case "set_desired_humidity":
if (index and value):
zone = zoneManager.getZone(index)
zone.desiredHumidity = value
return render_template('action.html', translater=translater, zones=zoneManager.zones)
@app.route('/dashboard') @app.route('/dashboard')
def showDashboard(): def showDashboard():
return render_template('dashboard.html', translater=translater, zones=zones) return render_template('dashboard.html', translater=translater, zones=zoneManager.zones)
@app.route('/zones') @app.route('/zones')
@app.route('/zones/<zoneNumber>') @app.route('/zones/<zoneNumber>')
def showZones(zoneNumber=False): def showZones(zoneNumber=False):
if(zoneNumber): if (zoneNumber):
return render_template('zone.html', translater=translater, zone=getZone(zones, zoneNumber)) return render_template('zone.html', translater=translater, zone=zoneManager.getZone(zoneNumber))
else: else:
return render_template('zones.html', translater=translater, zones=zones) return render_template('zones.html', translater=translater, zones=zoneManager.zones)
@app.route('/times') @app.route('/times')
def showTimes(): def showTimes():
@ -52,8 +77,3 @@ def startWebserver(port, translater, zones):
return render_template('system.html', translater=translater) return render_template('system.html', translater=translater)
app.run(debug=True, port=port) app.run(debug=True, port=port)
if __name__ == "__main__":
zones = loadZones()
translater = Translater(Language.ENGLISH)
startWebserver(80, translater, zones)

91
Zone.py
View File

@ -1,25 +1,84 @@
import time
class Zone: class Zone:
def __init__(self, number=0, name="", actualValue="100", setValue="0", autoMode=False, state=False): def __init__(self, number=0, name="", actualHumidity="100", desiredHumidity="0", autoMode=False, state=False, setState=0, endTimeSetState=0, planedDuration=0):
self.number = number self.number = number
self.name = name self.name = name
self.actualValue = actualValue self.actualHumidity = actualHumidity
self.setValue = setValue self.desiredHumidity = desiredHumidity
self.autoMode = autoMode #False = manual, True = automatic self.autoMode = autoMode #False = manual, True = automatic
self.state = state #True = off, True = on self.state = state #True = on, False = off
self.setState = setState #0=default, 1=turned off for time, 2=turned on for time, 3=command in pipeline
self.endTimeSetState = endTimeSetState
self.planedDuration = planedDuration
def timeOver(self):
return time.time() > self.endTimeSetState
def refreshStatus(self): def refreshStateAutomode(self):
if(self.AutoMode): match self.setState:
if(self.actualValue < self.setValue): case 0:
self.state = True if(self.desiredHumidity > self.actualHumidity):
else: self.state = True
else:
self.state = False
case 1:
if(self.timeOver()):
self.setState = 0
self.refreshStateAutomode()
else:
self.state = False
case 2:
if (self.timeOver()):
self.setState = 0
self.refreshStateAutomode()
else:
self.state = True
case 3:
self.state = False self.state = False
def getStatus(self):
self.refreshStatus()
return self.state
def getZone(zones, number): def refreshStateManualmode(self):
for zone in zones: if(self.setState > 0):
if(zone.number == number): match self.setState:
return zone case 1:
if(self.timeOver()):
self.setState = 0
self.state = False
case 2:
if (self.timeOver()):
self.setState = 0
self.state = False
else:
self.state = True
case 3:
self.state = False
def refreshState(self):
if(self.autoMode):
self.refreshStateAutomode()
else:
self.refreshStateManualmode()
def switchMode(self, autoMode):
if(self.autoMode != autoMode):
self.autoMode = autoMode
self.state = False
self.refreshState()
def switchState(self, state, duration, instant):
if(instant):
if(not state):
self.setState = 1
else:
self.setState = 2
self.endTimeSetState = time.time() + duration
else:
if(state):
self.setState = 3
self.planedDuration = duration
self.refreshState()

58
ZoneManager.py Normal file
View File

@ -0,0 +1,58 @@
from FileIO import FileIO
class ZoneManager:
def __init__(self, systemSettings, fileIO):
self.systemSettings = systemSettings
self.fileIO = FileIO
self.zones = fileIO.loadZones()
self.pipeLine = []
def getZone(self, number):
for zone in self.zones:
if(zone.number == number):
return zone
def addIrrigationJob(self, job):
self.pipeLine.append(job)
def isAnyZoneBusy(self):
for zone in self.zones:
if(zone.state):
return True
return False
def switchZoneState(self, zone, state, duration, instant=False):
if(instant or self.systemSettings.multiZoneIrrigation):
zone.switchState(state=state, duration=duration, instant=True)
else:
self.addIrrigationJob(IrrigationJob(zone, duration))
def switchZoneIndexState(self, zoneIndex, state, duration, instant=False):
zone = self.getZone(zoneIndex)
self.switchZoneState(zone, state, duration, instant)
def refreshStates(self):
for zone in self.zones:
zone.refreshState()
def processPipeline(self):
if(len(self.pipeLine) > 0 and (not self.isAnyZoneBusy())):
irrigationJob = self.pipeLine[0]
irrigationJob.process()
self.pipeLine.pop(0)
def cronJobs(self):
self.refreshStates()
self.processPipeline()
class IrrigationJob:
def __init__(self, zone, duration=0):
self.zone = zone
self.duration = duration
self.zone.switchState(state=True, duration=duration, instant=False)
def process(self):
self.zone.switchState(state=True, duration=self.duration, instant=True)

12
main.py Normal file
View File

@ -0,0 +1,12 @@
from Webserver import startWebserver
from ZoneManager import ZoneManager
from SystemSettings import SystemSettings
from FileIO import FileIO
if __name__ == "__main__":
systemSettings = SystemSettings(dataDir="/Data", multiZoneIrrigation=True)
fileIO = FileIO(systemSettings)
zoneManager = ZoneManager(systemSettings=systemSettings, fileIO=fileIO)
startWebserver(port=80, zoneManager=zoneManager)
print("webserver started")