2022-08-23 23:47:43 +02:00
|
|
|
import json
|
2022-08-17 02:14:53 +02:00
|
|
|
import threading
|
|
|
|
from random import Random
|
2022-08-23 23:47:43 +02:00
|
|
|
|
2022-08-17 02:14:53 +02:00
|
|
|
|
2022-08-15 23:58:07 +02:00
|
|
|
from FileIO import FileIO
|
|
|
|
|
|
|
|
class ZoneManager:
|
|
|
|
def __init__(self, systemSettings, fileIO):
|
2022-08-17 02:14:53 +02:00
|
|
|
self.random = Random()
|
2022-08-15 23:58:07 +02:00
|
|
|
self.systemSettings = systemSettings
|
|
|
|
self.fileIO = FileIO
|
|
|
|
self.zones = fileIO.loadZones()
|
2022-08-16 03:13:10 +02:00
|
|
|
for zone in self.zones:
|
|
|
|
zone.setZoneManager(self)
|
2022-08-23 14:31:23 +02:00
|
|
|
self.pipeLine = []
|
|
|
|
self.piplineMutexLock = threading.Lock()
|
2022-08-15 23:58:07 +02:00
|
|
|
|
2022-08-27 00:29:22 +02:00
|
|
|
def zonesToJSON(self, translater):
|
2022-08-23 23:47:43 +02:00
|
|
|
zoneList = []
|
|
|
|
for zone in self.zones:
|
2022-08-27 00:29:22 +02:00
|
|
|
zoneList.append(zone.toJSON(translater))
|
2022-08-23 23:47:43 +02:00
|
|
|
return zoneList
|
|
|
|
|
2022-08-27 00:29:22 +02:00
|
|
|
def pipelineToJSON(self, translater):
|
2022-08-23 23:47:43 +02:00
|
|
|
jobList = []
|
|
|
|
with self.piplineMutexLock:
|
|
|
|
for irrigationJob in self.pipeLine:
|
2022-08-27 00:29:22 +02:00
|
|
|
jobList.append(irrigationJob.toJSON(translater))
|
2022-08-23 23:47:43 +02:00
|
|
|
return jobList
|
|
|
|
|
|
|
|
|
2022-08-15 23:58:07 +02:00
|
|
|
def getZone(self, number):
|
|
|
|
for zone in self.zones:
|
|
|
|
if(zone.number == number):
|
|
|
|
return zone
|
|
|
|
|
|
|
|
def addIrrigationJob(self, job):
|
2022-08-23 14:31:23 +02:00
|
|
|
with self.piplineMutexLock:
|
2022-08-17 02:14:53 +02:00
|
|
|
self.pipeLine.append(job)
|
|
|
|
|
|
|
|
def deleteIrrigationJobByID(self, id):
|
2022-08-23 14:31:23 +02:00
|
|
|
i = 0
|
|
|
|
with self.piplineMutexLock:
|
2022-08-17 02:14:53 +02:00
|
|
|
while i < (len(self.pipeLine)):
|
|
|
|
irrigationJob = self.pipeLine[i]
|
|
|
|
if(irrigationJob.id == id):
|
|
|
|
self.pipeLine.pop(i)
|
2022-08-23 14:31:23 +02:00
|
|
|
break
|
2022-08-17 02:14:53 +02:00
|
|
|
else:
|
|
|
|
i = i + 1
|
|
|
|
|
|
|
|
def deleteIrrigationJobsForZone(self, zone):
|
2022-08-23 14:31:23 +02:00
|
|
|
i = 0
|
|
|
|
with self.piplineMutexLock:
|
2022-08-17 02:14:53 +02:00
|
|
|
while i < (len(self.pipeLine)):
|
|
|
|
irrigationJob = self.pipeLine[i]
|
|
|
|
if (irrigationJob.zone == zone):
|
|
|
|
self.pipeLine.pop(i)
|
|
|
|
else:
|
|
|
|
i = i + 1
|
2022-08-15 23:58:07 +02:00
|
|
|
|
|
|
|
def isAnyZoneBusy(self):
|
|
|
|
for zone in self.zones:
|
|
|
|
if(zone.state):
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
|
|
def switchZoneState(self, zone, state, duration, instant=False):
|
2022-08-27 00:29:22 +02:00
|
|
|
if(not duration > 0):
|
|
|
|
zone.switchState(state=False, duration=0, instant=True)
|
|
|
|
elif(instant or self.systemSettings.multiZoneIrrigation or state==False ): #or (not self.isAnyZoneBusy())
|
2022-08-15 23:58:07 +02:00
|
|
|
zone.switchState(state=state, duration=duration, instant=True)
|
|
|
|
else:
|
2022-08-17 02:14:53 +02:00
|
|
|
self.addIrrigationJob(IrrigationJob(id=self.random.randint(a=100000000, b=999999999), zone=zone, duration=duration))
|
2022-08-15 23:58:07 +02:00
|
|
|
|
|
|
|
def switchZoneIndexState(self, zoneIndex, state, duration, instant=False):
|
|
|
|
zone = self.getZone(zoneIndex)
|
|
|
|
self.switchZoneState(zone, state, duration, instant)
|
|
|
|
|
2022-08-17 02:14:53 +02:00
|
|
|
def getPlanedDurationForZone(self, zone):
|
|
|
|
totalDuration = 0
|
2022-08-23 14:31:23 +02:00
|
|
|
with self.piplineMutexLock:
|
|
|
|
for irrigationJob in self.pipeLine:
|
|
|
|
if(irrigationJob.zone == zone):
|
|
|
|
totalDuration = totalDuration + irrigationJob.duration
|
2022-08-17 02:14:53 +02:00
|
|
|
return totalDuration
|
|
|
|
|
2022-08-15 23:58:07 +02:00
|
|
|
def refreshStates(self):
|
|
|
|
for zone in self.zones:
|
|
|
|
zone.refreshState()
|
|
|
|
|
|
|
|
def processPipeline(self):
|
2022-08-23 14:31:23 +02:00
|
|
|
self.piplineMutexLock.acquire()
|
|
|
|
if(len(self.pipeLine) > 0 and (not self.isAnyZoneBusy())):
|
|
|
|
irrigationJob = self.pipeLine[0]
|
|
|
|
self.pipeLine.pop(0)
|
|
|
|
self.piplineMutexLock.release()
|
|
|
|
irrigationJob.process()
|
|
|
|
else:
|
|
|
|
self.piplineMutexLock.release()
|
|
|
|
|
|
|
|
|
2022-08-15 23:58:07 +02:00
|
|
|
|
|
|
|
def cronJobs(self):
|
|
|
|
self.refreshStates()
|
|
|
|
self.processPipeline()
|
2022-08-23 14:31:23 +02:00
|
|
|
print("Executed Cron Jobs of ZoneManager.")
|
2022-08-15 23:58:07 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class IrrigationJob:
|
2022-08-17 02:14:53 +02:00
|
|
|
def __init__(self, id, zone, duration=0):
|
|
|
|
self.id = id
|
2022-08-15 23:58:07 +02:00
|
|
|
self.zone = zone
|
|
|
|
self.duration = duration
|
|
|
|
self.zone.switchState(state=True, duration=duration, instant=False)
|
|
|
|
|
2022-08-27 00:29:22 +02:00
|
|
|
def toJSON(self, translater):
|
2022-08-23 23:47:43 +02:00
|
|
|
return {
|
|
|
|
"id": self.id,
|
2022-08-27 00:29:22 +02:00
|
|
|
"zone": self.zone.toJSON(translater),
|
2022-08-23 23:47:43 +02:00
|
|
|
"duration": self.duration,
|
|
|
|
}
|
|
|
|
|
2022-08-15 23:58:07 +02:00
|
|
|
def process(self):
|
|
|
|
self.zone.switchState(state=True, duration=self.duration, instant=True)
|