Exemplo n.º 1
0
class operateGarage(MyLog):
    def __init__(self, args=None):
        super(operateGarage, self).__init__()
        self.ProgramName = "operate Garage Shutters"
        self.Version = "Unknown"
        self.log = None
        self.IsStopping = False
        self.ProgramComplete = False

        if args.ConfigFile == None:
            self.ConfigFile = "/etc/operateGarage.conf"
        else:
            self.ConfigFile = args.ConfigFile

        self.console = SetupLogger("shutters_console",
                                   log_file="",
                                   stream=True)

        ## should be re-enabled before actual production use
        # 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 + "operateGarage.log")
        self.config.log = self.log

        if self.IsLoaded():
            self.LogWarn("operateGarage.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.mqtt = MQTT(kwargs={
            'log': self.log,
            'shutter': self.shutter,
            'config': self.config
        })

        self.ProcessCommand(args)

    #------------------------ operateGarage::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

    #--------------------- operateGarage::startPIGPIO ------------------------------
    def startPIGPIO(self):
        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(
                    'sudo pigpiod -l -n localhost')  # 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(
                    'sudo pigpiod -l -n localhost')  # 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:
                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

    #--------------------- operateGarage::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.mqtt == True):
            self.mqtt.setDaemon(True)
            self.mqtt.start()

        else:
            parser.print_help()

    #    if (args.mqtt == True):
    #        self.mqtt.setDaemon(True)
    #        self.mqtt.start()

    #    if (args.mqtt == True):
    #    self.mqtt.join()
        self.LogInfo("Process Command Completed....")
        #self.Close()

    #---------------------operateGarage::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("operateGarage Shutdown")

        try:
            self.ProgramComplete = True
            if (not self.mqtt == 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.")
            sys.exit(0)
        except:
            pass
Exemplo n.º 2
0
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