Heating and Ventilation Control
/HvcRollerShutter
Keine Erläuterungen gefunden.
import os from stat import * import urllib.request import json import datetime import time class HvcRollerShutter: #==========================# def __init__(self, debug=False): self.debug = debug self.stateFile = "./ConfDir/RSstate.json" self.logPath = "./LogDir/" self.IPs = {} self.IPs["EG1"] = "http://192.168.178.141" #Wohnzimmer gross self.IPs["EG2"] = "http://192.168.178.142" #Wohnzimmer Erker links self.IPs["EG3"] = "http://192.168.178.143" #Wohnzimmer Erker mitte self.IPs["EG4"] = "http://192.168.178.144" #Wohnzimmer Erker rechts self.IPs["EG5"] = "http://192.168.178.145" #Diele links self.IPs["EG6"] = "http://192.168.178.146" #Diele rechts self.operationTime = {} self.operationTime["EG1"] = 35 #sec self.operationTime["EG2"] = 30 #sec self.operationTime["EG3"] = 39 #sec self.operationTime["EG4"] = 30 #sec self.operationTime["EG5"] = 44 #sec self.operationTime["EG6"] = 35 #sec self.names = list(self.IPs.keys()) self.stopTime = {} self.state = {} self.action = {} self.error = {} for n in self.names: self.stopTime[n] = -1 self.state[n] = "auto" self.action[n] = "stop" self.error[n] = 0 #==========================# def checkState(self): """ Check for changes of the RSstate file, and load it on change. """ try: st = os.stat(self.stateFile) except IOError: print("failed to get information about", self.stateFile) else: lastModTime = st[ST_MTIME] changed = 0 if self.lastModTime != lastModTime: changed = 1 self.lastModTime = lastModTime with open(self.stateFile) as json_file: newState = json.load(json_file) else: newState = {} return newState, changed #==========================# def activate(self, trigger): """ The 'trigger' sets the intended state and action for all shutters. If any such trigger switches to open/close, the stopTime of the shutter is set. state: persistent state of shutter {open, close, auto, (stop)} action: next message to shutter {open, stop, close} """ myResults = [] for n in self.names: if trigger[n] != self.state[n]: if trigger[n] == "auto": self.state[n] = "auto" #keep operation as is... else: self.state[n] = trigger[n] self.action[n] = trigger[n] self.stopTime[n] = time.time() + self.operationTime[n] myResults.append( self.operate(n, 99.99) ) self.writeLog(myResults) if self.debug: print("HvcRollerShutter.activate") print("stopTime:",self.stopTime) #==========================# def timeout(self): """ Stop any shutter motion, if operationTime is over. """ myResults = [] now = time.time() if self.debug: Delta = {} print("now:", now) print("action: ", self.action) for n in self.names: if self.debug: Delta[n] = now - self.stopTime[n] if self.action[n] == "open" or self.action[n] == "close": if now > self.stopTime[n]: self.action[n] = "stop" myResults.append( self.operate(n, now) ) self.writeLog(myResults) if self.debug: print("RollerShutter.timeout Delta:") print("Delta:",Delta) #print("stopTime:", self.stopTime) #print("action: ", self.action) #==========================# def control(self, OM, now, sunSetTime=23.99): parameter = OM.parameters myResults = [] if self.debug: print("HvcRollerShutter.control()") print("myTime",now) print("shutterOpenTime",parameter["shutterOpenTime"]) for n in self.names: anyChange = False if self.state[n] == "auto": if now < 12.0: #vormittags, Rolllaeden auf if now == parameter["shutterOpenTime"]: anyChange = True self.action[n] = "open" print(n,self.action[n]) elif now<23.99: #nachmittags, Rollaeden zu offset = parameter["shutterCloseOffset"] if n == "EG1": offset = offset + 0.5 #h if now == sunSetTime + offset: anyChange = True self.action[n] = "close" if anyChange or self.error[n] > 0: self.stopTime[n] = time.time() + self.operationTime[n] myResults.append( self.operate(n, now) ) self.writeLog(myResults) return #==========================# def operate(self, thisName, now): """ Operate one roller shutter, according to action[n]. Either it will last for the time configured in shelly, or by some external timer, signal a 'stop' at certain time. """ if self.action[thisName]=="open" or self.action[thisName]==1: url = self.IPs[thisName] + "/roller/0?go=open" elif self.action[thisName]=="close" or self.action[thisName]==-1: url = self.IPs[thisName] + "/roller/0?go=close" elif self.action[thisName]=="stop" or self.action[thisName]==0: url = self.IPs[thisName] + "/roller/0?go=stop" else: url = self.IPs[thisName] + "/roller/0?go=stop" try: with urllib.request.urlopen(url) as response: result = response.read() resData = result.decode('utf-8') result2 = json.loads(resData) if result2["is_valid"]: self.error[thisName] = 0 else: self.error[thisName] = 1 if self.debug: print(result) except: self.error[thisName] = 2 if self.error[thisName] > 0: result1 = str(now) + "calling URL did not work: " + url + " " + str(self.error[thisName]) + "\n" result1 = result1 + str(result) + "\n" fp = open("LogDir/RS.log", 'a', encoding='utf-8') fp.write(result1+"\n") fp.close() #print(result) return result #==========================# def writeLog(self,results): #doWrite = True doWrite = False if doWrite: file = self.logPath + "shutter.log" if os.path.exists(file): #append to file fp = open(file, 'a', encoding='utf-8') else: #create file with header fp = open(file, 'w', encoding='utf-8') for res in results: fp.write(res+"\n") fp.close() #persistant values: HvcRollerShutter.lastModTime = 0 #==========================# if __name__ == "__main__": from time import sleep from HvcOperationMode import HvcOperationMode #read set of standard parameters OM = HvcOperationMode() newOm,parameter,changed = OM.read() #initialize class myRS = HvcRollerShutter(True) #default myRSstate structure, to be utilized somehow myRSstate = {} for n in myRS.names: myRSstate[n] = "stop" #activate some shutter firstName = myRS.names[0] firstName = "EG5" myRSstate[firstName] = "close" myRS.operationTime[firstName] = 2 print(myRSstate) myRS.activate(myRSstate) #rudimentary time loop: for second in range(1220): sleep(1) newState, changed = myRS.checkState() if changed: myRS.activate(newState) if second<60: print("second:",second) myRS.timeout() if second == 10: myRSstate[firstName] = "open" myRS.activate(myRSstate) if second == 60 or second == 120: now = datetime.datetime.now() #year = now.strftime("%Y") #mon = now.strftime("%m") #day = now.strftime("%d") hour = now.strftime("%H") minute = now.strftime("%M") myTime = float(hour) + float(minute)/60.0 myRS.control(OM, myTime)
python
php
Der gesamte Sourcecode darf gemäß GNU General Public License weiterverbreitet werden.