def ProcessCommand(self, args): if ((args.shutterName != "") and (args.down == True)): self.shutter.lower(self.config.ShuttersByName[args.shutterName]) elif ((args.shutterName != "") and (args.up == True)): self.shutter.rise(self.config.ShuttersByName[args.shutterName]) elif ((args.shutterName != "") and (args.stop == True)): self.shutter.stop(self.config.ShuttersByName[args.shutterName]) elif ((args.shutterName != "") and (args.program == True)): self.shutter.program(self.config.ShuttersByName[args.shutterName]) elif ((args.shutterName != "") and (args.demo == True)): self.LogInfo ("lowering shutter for 7 seconds") self.shutter.lowerPartial(self.config.ShuttersByName[args.shutterName], 7) time.sleep(7) self.LogInfo ("rise shutter for 7 seconds") self.shutter.risePartial(self.config.ShuttersByName[args.shutterName], 7) elif ((args.shutterName != "") and (args.duskdawn is not None)): self.schedule.addRepeatEventBySunrise([self.config.ShuttersByName[args.shutterName]], 'up', args.duskdawn[1], ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']) self.schedule.addRepeatEventBySunset([self.config.ShuttersByName[args.shutterName]], 'down', args.duskdawn[0], ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']) self.scheduler = Scheduler(kwargs={'log':self.log, 'schedule':self.schedule, 'shutter': self.shutter, 'config': self.config}) self.scheduler.setDaemon(True) self.scheduler.start() if (args.echo == True): self.alexa.setDaemon(True) self.alexa.start() if (args.mqtt == True): self.mqtt.setDaemon(True) self.mqtt.start() self.scheduler.join() elif (args.auto == True): self.schedule.loadScheudleFromConfig() self.scheduler = Scheduler(kwargs={'log':self.log, 'schedule':self.schedule, 'shutter': self.shutter, 'config': self.config}) self.scheduler.setDaemon(True) self.scheduler.start() if (args.echo == True): self.alexa.setDaemon(True) self.alexa.start() if (args.mqtt == True): self.mqtt.setDaemon(True) self.mqtt.start() self.webServer = FlaskAppWrapper(name='WebServer', static_url_path=os.path.dirname(os.path.realpath(__file__))+'/html', log = self.log, shutter = self.shutter, schedule = self.schedule, config = self.config) self.webServer.run() else: parser.print_help() if (args.echo == True): self.alexa.setDaemon(True) self.alexa.start() if (args.mqtt == True): self.mqtt.setDaemon(True) self.mqtt.start() if (args.echo == True): self.alexa.join() if (args.mqtt == True): self.mqtt.join() self.LogInfo ("Process Command Completed....") self.Close();
def ProcessCommand(self, args): if ((args.shutterName != "") and (args.down == True)): self.shutter.lower(self.config.ShuttersByName[args.shutterName]) elif ((args.shutterName != "") and (args.up == True)): self.shutter.rise(self.config.ShuttersByName[args.shutterName]) elif ((args.shutterName != "") and (args.stop == True)): self.shutter.stop(self.config.ShuttersByName[args.shutterName]) elif ((args.shutterName != "") and (args.program == True)): self.shutter.program(self.config.ShuttersByName[args.shutterName]) elif ((args.shutterName != "") and (args.demo == True)): self.LogInfo ("lowering shutter for 7 seconds") self.shutter.lowerPartial(self.config.ShuttersByName[args.shutterName], 7) time.sleep(7) self.LogInfo ("rise shutter for 7 seconds") self.shutter.risePartial(self.config.ShuttersByName[args.shutterName], 7) elif ((args.shutterName != "") and (args.duskdawn is not None)): self.schedule.addRepeatEventBySunrise([self.config.ShuttersByName[args.shutterName]], 'up', args.duskdawn[1], ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']) self.schedule.addRepeatEventBySunset([self.config.ShuttersByName[args.shutterName]], 'down', args.duskdawn[0], ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']) self.scheduler = Scheduler(kwargs={'log':self.log, 'schedule':self.schedule, 'shutter': self.shutter, 'config': self.config}) self.scheduler.setDaemon(True) self.scheduler.start() if (args.echo == True): self.alexa.setDaemon(True) self.alexa.start() self.scheduler.join() elif (args.auto == True): self.schedule.loadScheudleFromConfig() self.scheduler = Scheduler(kwargs={'log':self.log, 'schedule':self.schedule, 'shutter': self.shutter, 'config': self.config}) self.scheduler.setDaemon(True) self.scheduler.start() if (args.echo == True): self.alexa.setDaemon(True) self.alexa.start() self.webServer = FlaskAppWrapper(name='WebServer', static_url_path=os.path.dirname(os.path.realpath(__file__))+'/html', log = self.log, shutter = self.shutter, schedule = self.schedule, config = self.config) self.webServer.run() else: parser.print_help() if (args.echo == True): self.alexa.setDaemon(True) self.alexa.start() self.alexa.join() self.LogInfo ("Process Command Completed....") self.Close();
class operateShutters(MyLog): def __init__(self, args=None): super(operateShutters, self).__init__() self.ProgramName = "operate Somfy Shutters" self.Version = "Unknown" self.log = None self.IsStopping = False self.ProgramComplete = False if args.ConfigFile is None: self.ConfigFile = "/etc/operateShutters.conf" else: self.ConfigFile = args.ConfigFile self.console = SetupLogger("shutters_console", log_file="", stream=True) if os.geteuid() != 0: self.LogConsole( "You need to have root privileges to run this script.\nPlease try again, this time using 'sudo'." ) sys.exit(1) if not os.path.isfile(self.ConfigFile): self.LogConsole("Creating new config file : " + self.ConfigFile) defaultConfigFile = os.path.dirname( os.path.realpath(__file__)) + '/defaultConfig.conf' print(defaultConfigFile) if not os.path.isfile(defaultConfigFile): self.LogConsole("Failure to create new config file: " + defaultConfigFile) sys.exit(1) else: copyfile(defaultConfigFile, self.ConfigFile) # read config file self.config = MyConfig(filename=self.ConfigFile, log=self.console) result = self.config.LoadConfig() if not result: self.LogConsole("Failure to load configuration parameters") sys.exit(1) # log errors in this module to a file self.log = SetupLogger("shutters", self.config.LogLocation + "operateShutters.log") self.config.log = self.log if self.IsLoaded(): self.LogWarn("operateShutters.py is already loaded.") sys.exit(1) # if not self.startPIGPIO(): # self.LogConsole("Not able to start PIGPIO") # sys.exit(1) self.shutter = Shutter(log=self.log, config=self.config) # atexit.register(self.Close) # signal.signal(signal.SIGTERM, self.Close) # signal.signal(signal.SIGINT, self.Close) self.schedule = Schedule(log=self.log, config=self.config) self.scheduler = None self.webServer = None if args.echo: self.alexa = Alexa(kwargs={ 'log': self.log, 'shutter': self.shutter, 'config': self.config }) if args.mqtt: self.mqtt = MQTT(kwargs={ 'log': self.log, 'shutter': self.shutter, 'config': self.config }) self.ProcessCommand(args) # ------------------------ operateShutters::IsLoaded ----------------------------- # return true if program is already loaded def IsLoaded(self): file_path = '/var/lock/' + os.path.basename(__file__) global file_handle try: file_handle = open(file_path, 'w') fcntl.lockf(file_handle, fcntl.LOCK_EX | fcntl.LOCK_NB) return False except IOError: return True # --------------------- operateShutters::startPIGPIO ------------------------------ def startPIGPIO(self): pigpio_args = "-l -a" pigpio_host = "" pigpio_port = 8888 if os.environ.get('PIGPIO_ARGS') is not None: self.LogInfo("Using the following env PiGPIO args to start: " + os.environ.get('PIGPIO_ARGS')) pigpio_args = os.environ.get('PIGPIO_ARGS') else: self.LogInfo("Using the following PiGPIO args to start: '-l -a'") if self.config.PiGPIOPort is not None: if os.environ.get('PIGPIO_PORT') is not None: self.LogInfo("Using the following env PiGPIO port to start: " + os.environ.get('PIGPIO_PORT')) pigpio_port = os.environ.get('PIGPIO_PORT') else: self.LogInfo( "Using the following default PiGPIO port to start: 8888") pigpio_port = 8888 else: self.LogInfo("Using the following config PiGPIO port to start: " + str(self.config.PiGPIOPort)) pigpio_port = self.config.PiGPIOPort if self.config.PiGPIOHost is not None: if os.environ.get('PIGPIO_ADDR') is not None: self.LogInfo("Using the following env PiGPIO host to start: " + os.environ.get('PIGPIO_ADDR')) pigpio_host = os.environ.get('PIGPIO_ADDR') else: self.LogInfo( "Using the following defaultPiGPIO host to start: ''") pigpio_host = "" else: self.LogInfo("Using the following config PiGPIO host to start: " + str(self.config.PiGPIOHost)) pigpio_host = self.config.PiGPIOHost if sys.version_info[0] < 3: import commands status, process = commands.getstatusoutput('pidof pigpiod') if status: # it wasn't running, so start it self.LogInfo("pigpiod was not running") commands.getstatusoutput('pigpiod ' + pigpio_args) # try to start it time.sleep(0.5) # check it again status, process = commands.getstatusoutput('pidof pigpiod') else: import subprocess status, process = subprocess.getstatusoutput('pidof pigpiod') if status: # it wasn't running, so start it self.LogInfo("pigpiod was not running") subprocess.getstatusoutput('pigpiod ' + pigpio_args) # try to start it time.sleep(0.5) # check it again status, process = subprocess.getstatusoutput('pidof pigpiod') if not status: # if it was started successfully (or was already running)... pigpiod_process = process self.LogInfo("pigpiod is running, process ID is {} ".format( pigpiod_process)) try: if pigpio_host == "": self.LogInfo("Connecting to localhost") pi = pigpio.pi() else: self.LogInfo("Connecting to : " + pigpio_host + ":" + pigpio_port) pi = pigpio.pi(pigpio_host, pigpio_port) self.LogInfo("pigpio's pi instantiated") except Exception as e: start_pigpiod_exception = str(e) self.LogError("problem instantiating pi: {}".format( start_pigpiod_exception)) else: self.LogError("start pigpiod was unsuccessful.") return False return True # --------------------- operateShutters::ProcessCommand ----------------------------------------------- def ProcessCommand(self, args): if (args.shutterName != "") and (args.down == True): self.shutter.lower(self.config.ShuttersByName[args.shutterName]) elif (args.shutterName != "") and (args.up == True): self.shutter.rise(self.config.ShuttersByName[args.shutterName]) elif (args.shutterName != "") and (args.stop == True): self.shutter.stop(self.config.ShuttersByName[args.shutterName]) elif (args.shutterName != "") and (args.program == True): self.shutter.program(self.config.ShuttersByName[args.shutterName]) elif (args.shutterName != "") and (args.demo == True): self.LogInfo("lowering shutter for 7 seconds") self.shutter.lowerPartial( self.config.ShuttersByName[args.shutterName], 7) time.sleep(7) self.LogInfo("rise shutter for 7 seconds") self.shutter.risePartial( self.config.ShuttersByName[args.shutterName], 7) elif (args.shutterName != "") and (args.duskdawn is not None): self.schedule.addRepeatEventBySunrise( [self.config.ShuttersByName[args.shutterName]], 'up', args.duskdawn[1], ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']) self.schedule.addRepeatEventBySunset( [self.config.ShuttersByName[args.shutterName]], 'down', args.duskdawn[0], ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']) self.scheduler = Scheduler( kwargs={ 'log': self.log, 'schedule': self.schedule, 'shutter': self.shutter, 'config': self.config }) self.scheduler.setDaemon(True) self.scheduler.start() if args.echo: self.alexa.setDaemon(True) self.alexa.start() if args.mqtt: self.mqtt.setDaemon(True) self.mqtt.start() self.scheduler.join() elif args.auto: self.schedule.loadScheudleFromConfig() self.scheduler = Scheduler( kwargs={ 'log': self.log, 'schedule': self.schedule, 'shutter': self.shutter, 'config': self.config }) self.scheduler.setDaemon(True) self.scheduler.start() if args.echo: self.alexa.setDaemon(True) self.alexa.start() if args.mqtt: self.mqtt.setDaemon(True) self.mqtt.start() self.webServer = FlaskAppWrapper( name='WebServer', static_url_path=os.path.dirname(os.path.realpath(__file__)) + '/html', log=self.log, shutter=self.shutter, schedule=self.schedule, config=self.config) self.webServer.run() else: parser.print_help() if args.echo: self.alexa.setDaemon(True) self.alexa.start() if args.mqtt: self.mqtt.setDaemon(True) self.mqtt.start() if args.echo: self.alexa.join() if args.mqtt: self.mqtt.join() self.LogInfo("Process Command Completed....") self.Close() # ---------------------operateShutters::Close---------------------------------------- def Close(self, signum=None, frame=None): # we dont really care about the errors that may be generated on shutdown try: self.IsStopping = True except Exception as e1: self.LogErrorLine("Error Closing Monitor: " + str(e1)) self.LogError("operateShutters Shutdown") try: self.ProgramComplete = True if self.scheduler is not None: self.LogError( "Stopping Scheduler. This can take up to 1 second...") self.scheduler.shutdown_flag.set() self.scheduler.join() self.LogError("Scheduler stopped. Now exiting.") if self.alexa is not None: self.LogError( "Stopping Alexa Listener. This can take up to 1 second...") self.alexa.shutdown_flag.set() self.alexa.join() self.LogError("Alexa Listener stopped. Now exiting.") if self.mqtt is not None: self.LogError( "Stopping MQTT Listener. This can take up to 1 second...") self.mqtt.shutdown_flag.set() self.mqtt.join() self.LogError("MQTT Listener stopped. Now exiting.") if self.webServer is not None: self.LogError( "Stopping WebServer. This can take up to 1 second...") self.webServer.shutdown_server() self.LogError("WebServer stopped. Now exiting.") sys.exit(0) except: pass
class operateShutters(MyLog): def __init__(self, args = None): super(operateShutters, self).__init__() self.ProgramName = "operate Somfy Shutters" self.Version = "Unknown" self.log = None self.IsStopping = False self.ProgramComplete = False if args.ConfigFile == None: self.ConfigFile = "/etc/operateShutters.conf" else: self.ConfigFile = args.ConfigFile self.console = SetupLogger("shutters_console", log_file = "", stream = True) if os.geteuid() != 0: self.LogConsole("You need to have root privileges to run this script.\nPlease try again, this time using 'sudo'.") sys.exit(1) if not os.path.isfile(self.ConfigFile): self.LogConsole("Creating new config file : " + self.ConfigFile) defaultConfigFile = os.path.dirname(os.path.realpath(__file__))+'/defaultConfig.conf' print(defaultConfigFile); if not os.path.isfile(defaultConfigFile): self.LogConsole("Failure to create new config file: "+defaultConfigFile) sys.exit(1) else: copyfile(defaultConfigFile, self.ConfigFile) # read config file self.config = MyConfig(filename = self.ConfigFile, log = self.console) result = self.config.LoadConfig(); if not result: self.LogConsole("Failure to load configuration parameters") sys.exit(1) # log errors in this module to a file self.log = SetupLogger("shutters", self.config.LogLocation + "operateShutters.log") self.config.log = self.log if self.IsLoaded(): self.LogWarn("operateShutters.py is already loaded.") sys.exit(1) if not self.startPIGPIO(): self.LogConsole("Not able to start PIGPIO") sys.exit(1) self.shutter = Shutter(log = self.log, config = self.config) # atexit.register(self.Close) # signal.signal(signal.SIGTERM, self.Close) # signal.signal(signal.SIGINT, self.Close) self.schedule = Schedule(log = self.log, config = self.config) self.scheduler = None self.webServer = None self.alexa = Alexa(kwargs={'log':self.log, 'shutter': self.shutter, 'config': self.config}) self.ProcessCommand(args); #------------------------ operateShutters::IsLoaded ----------------------------- #return true if program is already loaded def IsLoaded(self): file_path = '/var/lock/'+os.path.basename(__file__) global file_handle try: file_handle= open(file_path, 'w') fcntl.lockf(file_handle, fcntl.LOCK_EX | fcntl.LOCK_NB) return False except IOError: return True #--------------------- operateShutters::startPIGPIO ------------------------------ def startPIGPIO(self): if sys.version_info[0] < 3: import commands status, process = commands.getstatusoutput('sudo pidof pigpiod') if status: # it wasn't running, so start it self.LogInfo ("pigpiod was not running") commands.getstatusoutput('sudo pigpiod') # try to start it time.sleep(0.5) # check it again status, process = commands.getstatusoutput('sudo pidof pigpiod') else: import subprocess status, process = subprocess.getstatusoutput('sudo pidof pigpiod') if status: # it wasn't running, so start it self.LogInfo ("pigpiod was not running") subprocess.getstatusoutput('sudo pigpiod') # try to start it time.sleep(0.5) # check it again status, process = subprocess.getstatusoutput('sudo pidof pigpiod') if not status: # if it was started successfully (or was already running)... pigpiod_process = process self.LogInfo ("pigpiod is running, process ID is {} ".format(pigpiod_process)) try: pi = pigpio.pi() # local GPIO only self.LogInfo ("pigpio's pi instantiated") except Exception as e: start_pigpiod_exception = str(e) self.LogError ("problem instantiating pi: {}".format(start_pigpiod_exception)) else: self.LogError ("start pigpiod was unsuccessful.") return False return True #--------------------- operateShutters::ProcessCommand ----------------------------------------------- def ProcessCommand(self, args): if ((args.shutterName != "") and (args.down == True)): self.shutter.lower(self.config.ShuttersByName[args.shutterName]) elif ((args.shutterName != "") and (args.up == True)): self.shutter.rise(self.config.ShuttersByName[args.shutterName]) elif ((args.shutterName != "") and (args.stop == True)): self.shutter.stop(self.config.ShuttersByName[args.shutterName]) elif ((args.shutterName != "") and (args.program == True)): self.shutter.program(self.config.ShuttersByName[args.shutterName]) elif ((args.shutterName != "") and (args.demo == True)): self.LogInfo ("lowering shutter for 7 seconds") self.shutter.lowerPartial(self.config.ShuttersByName[args.shutterName], 7) time.sleep(7) self.LogInfo ("rise shutter for 7 seconds") self.shutter.risePartial(self.config.ShuttersByName[args.shutterName], 7) elif ((args.shutterName != "") and (args.duskdawn is not None)): self.schedule.addRepeatEventBySunrise([self.config.ShuttersByName[args.shutterName]], 'up', args.duskdawn[1], ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']) self.schedule.addRepeatEventBySunset([self.config.ShuttersByName[args.shutterName]], 'down', args.duskdawn[0], ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']) self.scheduler = Scheduler(kwargs={'log':self.log, 'schedule':self.schedule, 'shutter': self.shutter, 'config': self.config}) self.scheduler.setDaemon(True) self.scheduler.start() if (args.echo == True): self.alexa.setDaemon(True) self.alexa.start() self.scheduler.join() elif (args.auto == True): self.schedule.loadScheudleFromConfig() self.scheduler = Scheduler(kwargs={'log':self.log, 'schedule':self.schedule, 'shutter': self.shutter, 'config': self.config}) self.scheduler.setDaemon(True) self.scheduler.start() if (args.echo == True): self.alexa.setDaemon(True) self.alexa.start() self.webServer = FlaskAppWrapper(name='WebServer', static_url_path=os.path.dirname(os.path.realpath(__file__))+'/html', log = self.log, shutter = self.shutter, schedule = self.schedule, config = self.config) self.webServer.run() else: parser.print_help() if (args.echo == True): self.alexa.setDaemon(True) self.alexa.start() self.alexa.join() self.LogInfo ("Process Command Completed....") self.Close(); #---------------------operateShutters::Close---------------------------------------- def Close(self, signum = None, frame = None): # we dont really care about the errors that may be generated on shutdown try: self.IsStopping = True except Exception as e1: self.LogErrorLine("Error Closing Monitor: " + str(e1)) self.LogError("operateShutters Shutdown") try: self.ProgramComplete = True if (not self.scheduler == None): self.LogError("Stopping Scheduler. This can take up to 1 second...") self.scheduler.shutdown_flag.set() self.scheduler.join() self.LogError("Scheduler stopped. Now exiting.") if (not self.alexa == None): self.LogError("Stopping Alexa Listener. This can take up to 1 second...") self.alexa.shutdown_flag.set() self.alexa.join() self.LogError("Alexa Listener stopped. Now exiting.") if (not self.webServer == None): self.LogError("Stopping WebServer. This can take up to 1 second...") self.webServer.shutdown_server() self.LogError("WebServer stopped. Now exiting.") sys.exit(0) except: pass