import json import threading from random import Random from FileIO import FileIO class ZoneManager: def __init__(self, systemSettings, fileIO): self.random = Random() self.systemSettings = systemSettings self.fileIO = FileIO self.zones = fileIO.loadZones() for zone in self.zones: zone.setZoneManager(self) self.pipeLine = [] self.piplineMutexLock = threading.Lock() def zonesToJSON(self, translater): zoneList = [] for zone in self.zones: zoneList.append(zone.toJSON(translater)) return zoneList def pipelineToJSON(self, translater): jobList = [] with self.piplineMutexLock: for irrigationJob in self.pipeLine: jobList.append(irrigationJob.toJSON(translater)) return jobList def getZone(self, number): for zone in self.zones: if(zone.number == number): return zone def addIrrigationJob(self, job): with self.piplineMutexLock: self.pipeLine.append(job) def deleteIrrigationJobByID(self, id): i = 0 with self.piplineMutexLock: while i < (len(self.pipeLine)): irrigationJob = self.pipeLine[i] if(irrigationJob.id == id): self.pipeLine.pop(i) break else: i = i + 1 def deleteIrrigationJobsForZone(self, zone): i = 0 with self.piplineMutexLock: while i < (len(self.pipeLine)): irrigationJob = self.pipeLine[i] if (irrigationJob.zone == zone): self.pipeLine.pop(i) else: i = i + 1 def isAnyZoneBusy(self): for zone in self.zones: if(zone.state): return True return False def switchZoneState(self, zone, state, duration, instant=False): 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()) zone.switchState(state=state, duration=duration, instant=True) else: self.addIrrigationJob(IrrigationJob(id=self.random.randint(a=100000000, b=999999999), zone=zone, duration=duration)) def switchZoneIndexState(self, zoneIndex, state, duration, instant=False): zone = self.getZone(zoneIndex) self.switchZoneState(zone, state, duration, instant) def getPlanedDurationForZone(self, zone): totalDuration = 0 with self.piplineMutexLock: for irrigationJob in self.pipeLine: if(irrigationJob.zone == zone): totalDuration = totalDuration + irrigationJob.duration return totalDuration def refreshStates(self): for zone in self.zones: zone.refreshState() def processPipeline(self): 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() def cronJobs(self): self.refreshStates() self.processPipeline() print("Executed Cron Jobs of ZoneManager.") class IrrigationJob: def __init__(self, id, zone, duration=0): self.id = id self.zone = zone self.duration = duration self.zone.switchState(state=True, duration=duration, instant=False) def toJSON(self, translater): return { "id": self.id, "zone": self.zone.toJSON(translater), "duration": self.duration, } def process(self): self.zone.switchState(state=True, duration=self.duration, instant=True)