Example #1
0
    def loop(self):
        # Pause loop to modify trigger.
        # Prevents execution of trigger while variables are
        # being modified.
        if self.pause_loop:
            self.verify_pause_loop = True
            while self.pause_loop:
                time.sleep(0.1)

        if self.trigger_type == 'trigger_infrared_remote_input':
            self.infrared_remote_input()

        elif (self.is_activated and self.timer_period
              and self.timer_period < time.time()):
            check_approved = False

            # Check if the trigger period has elapsed
            if self.trigger_type in [
                    'trigger_sunrise_sunset', 'trigger_run_pwm_method'
            ]:
                while self.running and self.timer_period < time.time():
                    self.timer_period = calculate_sunrise_sunset_epoch(
                        self.trigger)

                if self.trigger_type == 'trigger_run_pwm_method':
                    # Only execute trigger actions when started
                    # Now only set PWM output
                    pwm_duty_cycle, ended = self.get_method_output(
                        self.unique_id_1)
                    if not ended:
                        output_channel = OutputChannel.query.filter(
                            OutputChannel.unique_id ==
                            self.trigger.unique_id_3).first()
                        self.set_output_duty_cycle(
                            self.unique_id_2,
                            pwm_duty_cycle,
                            output_channel=output_channel.channel)
                        if self.trigger_actions_at_period:
                            trigger_function_actions(
                                self.unique_id, debug=self.log_level_debug)
                else:
                    check_approved = True

            elif (self.trigger_type in [
                    'trigger_timer_daily_time_point',
                    'trigger_timer_daily_time_span', 'trigger_timer_duration'
            ]):
                if self.trigger_type == 'trigger_timer_daily_time_point':
                    self.timer_period = epoch_of_next_time(
                        '{hm}:00'.format(hm=self.timer_start_time))
                elif self.trigger_type in [
                        'trigger_timer_duration',
                        'trigger_timer_daily_time_span'
                ]:
                    while self.running and self.timer_period < time.time():
                        self.timer_period += self.period
                check_approved = True

            if check_approved:
                self.attempt_execute(self.check_triggers)
Example #2
0
 def receive_infrared_code_broadcast(self, code):
     if self.word in code:
         timestamp = datetime.datetime.fromtimestamp(
             time.time()).strftime('%Y-%m-%d %H:%M:%S')
         message = "{ts}\n[Trigger {id} ({name})]".format(
             ts=timestamp, name=self.trigger_name, id=self.function_id)
         message += "\nInfrared Remote Input detected " \
                    "'{word}' on program '{prog}'".format(
                     word=self.word, prog=self.program)
         trigger_function_actions(self.function_id, message=message)
Example #3
0
 def trigger_all_actions(
         self, function_id, message=''):
     try:
         return trigger_function_actions(function_id, message=message)
     except Exception as except_msg:
         message = "Could not trigger Conditional Actions:" \
                   " {err}".format(err=except_msg)
         self.logger.exception(message)
Example #4
0
    def check_triggers(self):
        """
        Check if any Triggers are activated and
        execute their actions if so.

        For example, if measured temperature is above 30C, notify [email protected]

        "if measured temperature is above 30C" is the Trigger to check.
        "notify [email protected]" is the Trigger Action to execute if the
        Trigger is True.
        """
        now = time.time()
        timestamp = datetime.datetime.fromtimestamp(now).strftime(
            '%Y-%m-%d %H:%M:%S')
        message = "{ts}\n[Trigger {id} ({name})]".format(
            ts=timestamp,
            name=self.trigger_name,
            id=self.unique_id)

        trigger = db_retrieve_table_daemon(
            Trigger, unique_id=self.unique_id, entry='first')

        device_id = trigger.measurement.split(',')[0]

        # if len(trigger.measurement.split(',')) > 1:
        #     device_measurement = trigger.measurement.split(',')[1]
        # else:
        #     device_measurement = None

        device = None

        input_dev = db_retrieve_table_daemon(
            Input, unique_id=device_id, entry='first')
        if input_dev:
            device = input_dev

        math = db_retrieve_table_daemon(
            Math, unique_id=device_id, entry='first')
        if math:
            device = math

        output = db_retrieve_table_daemon(
            Output, unique_id=device_id, entry='first')
        if output:
            device = output

        pid = db_retrieve_table_daemon(
            PID, unique_id=device_id, entry='first')
        if pid:
            device = pid

        if not device:
            message += " Error: Controller not Input, Math, Output, or PID"
            self.logger.error(message)
            return

        # If the edge detection variable is set, calling this function will
        # trigger an edge detection event. This will merely produce the correct
        # message based on the edge detection settings.
        elif trigger.trigger_type == 'trigger_edge':
            try:
                GPIO.setmode(GPIO.BCM)
                GPIO.setup(int(input_dev.pin), GPIO.IN)
                gpio_state = GPIO.input(int(input_dev.pin))
            except:
                gpio_state = None
                self.logger.error("Exception reading the GPIO pin")
            if (gpio_state is not None and
                    gpio_state == trigger.if_sensor_gpio_state):
                message += " GPIO State Detected (state = {state}).".format(
                    state=trigger.if_sensor_gpio_state)
            else:
                self.logger.error("GPIO not configured correctly or GPIO state not verified")
                return

        # Calculate the sunrise/sunset times and find the next time this trigger should trigger
        elif trigger.trigger_type == 'trigger_sunrise_sunset':
            # Since the check time is the trigger time, we will only calculate and set the next trigger time
            self.timer_period = calculate_sunrise_sunset_epoch(trigger)

        # Check if the current time is between the start and end time
        elif trigger.trigger_type == 'trigger_timer_daily_time_span':
            if not time_between_range(self.timer_start_time,
                                      self.timer_end_time):
                return

        # If the code hasn't returned by now, action should be executed
        trigger_function_actions(
            self.unique_id,
            message=message,
            debug=self.log_level_debug)
Example #5
0
    def initialize_variables(self):
        """ Define all settings """
        self.email_count = 0
        self.allowed_to_send_notice = True

        self.sample_rate = db_retrieve_table_daemon(
            Misc, entry='first').sample_rate_controller_conditional

        self.smtp_max_count = db_retrieve_table_daemon(
            SMTP, entry='first').hourly_max

        self.trigger = db_retrieve_table_daemon(
            Trigger, unique_id=self.unique_id)
        self.trigger_type = self.trigger.trigger_type
        self.trigger_name = self.trigger.name
        self.is_activated = self.trigger.is_activated
        self.log_level_debug = self.trigger.log_level_debug

        self.set_log_level_debug(self.log_level_debug)

        now = time.time()
        self.smtp_wait_timer = now + 3600
        self.timer_period = None

        # Set up trigger timer (daily time point)
        if self.trigger_type == 'trigger_timer_daily_time_point':
            self.timer_start_time = self.trigger.timer_start_time
            self.timer_period = epoch_of_next_time(
                '{hm}:00'.format(hm=self.trigger.timer_start_time))

        # Set up trigger timer (daily time span)
        elif self.trigger_type == 'trigger_timer_daily_time_span':
            self.timer_start_time = self.trigger.timer_start_time
            self.timer_end_time = self.trigger.timer_end_time
            self.period = self.trigger.period
            self.timer_period = now

        # Set up trigger timer (duration)
        elif self.trigger_type == 'trigger_timer_duration':
            self.period = self.trigger.period
            if self.trigger.timer_start_offset:
                self.timer_period = now + self.trigger.timer_start_offset
            else:
                self.timer_period = now

        # Set up trigger Run PWM Method
        elif self.trigger_type == 'trigger_run_pwm_method':
            self.unique_id_1 = self.trigger.unique_id_1
            self.unique_id_2 = self.trigger.unique_id_2
            self.period = self.trigger.period
            self.trigger_actions_at_period = self.trigger.trigger_actions_at_period
            self.trigger_actions_at_start = self.trigger.trigger_actions_at_start
            self.method_start_time = self.trigger.method_start_time
            self.method_end_time = self.trigger.method_end_time
            if self.is_activated:
                self.start_method(self.trigger.unique_id_1)
            if self.trigger_actions_at_start:
                self.timer_period = now + self.trigger.period
                if self.is_activated:
                    pwm_duty_cycle = self.get_method_output(
                        self.trigger.unique_id_1)
                    self.set_output_duty_cycle(
                        self.trigger.unique_id_2, pwm_duty_cycle)
                    trigger_function_actions(self.unique_id,
                                             debug=self.log_level_debug)
            else:
                self.timer_period = now

        elif self.trigger_type == 'trigger_infrared_remote_input':
            import lirc
            self.lirc = lirc
            self.program = self.trigger.program
            self.word = self.trigger.word
            lirc.init(self.program,
                      config_filename='/home/pi/.lircrc',
                      blocking=False)

            # Set up trigger sunrise/sunset
        elif self.trigger_type == 'trigger_sunrise_sunset':
            self.period = 60
            # Set the next trigger at the specified sunrise/sunset time (+-offsets)
            self.timer_period = calculate_sunrise_sunset_epoch(self.trigger)
Example #6
0
    def run(self):
        try:
            self.running = True
            self.logger.info("Activated in {:.1f} ms".format(
                (timeit.default_timer() - self.thread_startup_timer) * 1000))
            self.ready.set()

            while self.running:
                # Pause loop to modify trigger.
                # Prevents execution of trigger while variables are
                # being modified.
                if self.pause_loop:
                    self.verify_pause_loop = True
                    while self.pause_loop:
                        time.sleep(0.1)

                if self.trigger_type == 'trigger_infrared_remote_input':
                    self.infrared_remote_input()

                elif (self.is_activated and self.timer_period
                      and self.timer_period < time.time()):
                    check_approved = False

                    # Check if the trigger period has elapsed
                    if self.trigger_type in [
                            'trigger_sunrise_sunset', 'trigger_run_pwm_method'
                    ]:
                        while self.running and self.timer_period < time.time():
                            self.timer_period += self.period

                        if self.trigger_type == 'trigger_run_pwm_method':
                            # Only execute trigger actions when started
                            # Now only set PWM output
                            pwm_duty_cycle, ended = self.get_method_output(
                                self.unique_id_1)
                            if not ended:
                                self.set_output_duty_cycle(
                                    self.unique_id_2, pwm_duty_cycle)
                                if self.trigger_actions_at_period:
                                    trigger_function_actions(
                                        self.function_id,
                                        debug=self.log_level_debug)
                        else:
                            check_approved = True

                    elif (self.trigger_type in [
                            'trigger_timer_daily_time_point',
                            'trigger_timer_daily_time_span',
                            'trigger_timer_duration'
                    ]):
                        if self.trigger_type == 'trigger_timer_daily_time_point':
                            self.timer_period = epoch_of_next_time(
                                '{hm}:00'.format(hm=self.timer_start_time))
                        elif self.trigger_type in [
                                'trigger_timer_duration',
                                'trigger_timer_daily_time_span'
                        ]:
                            while self.running and self.timer_period < time.time(
                            ):
                                self.timer_period += self.period
                        check_approved = True

                    if check_approved:
                        self.check_triggers()

                time.sleep(self.sample_rate)

            self.running = False
            self.logger.info("Deactivated in {:.1f} ms".format(
                (timeit.default_timer() - self.thread_shutdown_timer) * 1000))
        except Exception as except_msg:
            self.logger.exception("Run Error: {err}".format(err=except_msg))
Example #7
0
    def check_triggers(self):
        """
        Check if any Triggers are activated and
        execute their actions if so.

        For example, if measured temperature is above 30C, notify [email protected]

        "if measured temperature is above 30C" is the Trigger to check.
        "notify [email protected]" is the Trigger Action to execute if the
        Trigger is True.
        """
        last_measurement = None
        gpio_state = None

        logger_cond = logging.getLogger("mycodo.conditional_{id}".format(
            id=self.function_id))

        trigger = db_retrieve_table_daemon(
            Trigger, unique_id=self.function_id, entry='first')

        now = time.time()
        timestamp = datetime.datetime.fromtimestamp(now).strftime('%Y-%m-%d %H:%M:%S')
        message = "{ts}\n[Trigger {id} ({name})]".format(
            ts=timestamp,
            name=trigger.name,
            id=self.function_id)

        device_id = trigger.measurement.split(',')[0]

        if len(trigger.measurement.split(',')) > 1:
            device_measurement = trigger.measurement.split(',')[1]
        else:
            device_measurement = None

        device = None

        input_dev = db_retrieve_table_daemon(
            Input, unique_id=device_id, entry='first')
        if input_dev:
            device = input_dev

        math = db_retrieve_table_daemon(
            Math, unique_id=device_id, entry='first')
        if math:
            device = math

        output = db_retrieve_table_daemon(
            Output, unique_id=device_id, entry='first')
        if output:
            device = output

        pid = db_retrieve_table_daemon(
            PID, unique_id=device_id, entry='first')
        if pid:
            device = pid

        if not device:
            message += " Error: Controller not Input, Math, Output, or PID"
            logger_cond.error(message)
            return

        # If the edge detection variable is set, calling this function will
        # trigger an edge detection event. This will merely produce the correct
        # message based on the edge detection settings.
        elif trigger.trigger_type == 'trigger_edge':
            try:
                GPIO.setmode(GPIO.BCM)
                GPIO.setup(int(input_dev.pin), GPIO.IN)
                gpio_state = GPIO.input(int(input_dev.pin))
            except:
                gpio_state = None
                logger_cond.error("Exception reading the GPIO pin")
            if (gpio_state is not None and
                    gpio_state == trigger.if_sensor_gpio_state):
                message += " GPIO State Detected (state = {state}).".format(
                    state=trigger.if_sensor_gpio_state)
            else:
                logger_cond.error("GPIO not configured correctly or GPIO state not verified")
                return

        # Calculate the sunrise/sunset times and find the next time this trigger should trigger
        elif trigger.trigger_type == 'trigger_sunrise_sunset':
            # Since the check time is the trigger time, we will only calculate and set the next trigger time
            self.timer_period = calculate_sunrise_sunset_epoch(trigger)

        # Check if the current time is between the start and end time
        if trigger.trigger_type == 'trigger_timer_daily_time_span':
            if not time_between_range(self.timer_start_time, self.timer_end_time):
                return

        # If the code hasn't returned by now, action should be executed
        trigger_function_actions(self.function_id, message=message)
Example #8
0
    def setup_settings(self):
        """ Define all settings """
        trigger = db_retrieve_table_daemon(
            Trigger, unique_id=self.function_id)

        self.trigger_type = trigger.trigger_type
        self.is_activated = trigger.is_activated

        self.smtp_max_count = db_retrieve_table_daemon(
            SMTP, entry='first').hourly_max
        self.email_count = 0
        self.allowed_to_send_notice = True

        now = time.time()

        self.smtp_wait_timer = now + 3600
        self.timer_period = None

        # Set up trigger timer (daily time point)
        if self.trigger_type == 'trigger_timer_daily_time_point':
            self.timer_start_time = trigger.timer_start_time
            self.timer_period = epoch_of_next_time(
                '{hm}:00'.format(hm=trigger.timer_start_time))

        # Set up trigger timer (daily time span)
        elif self.trigger_type == 'trigger_timer_daily_time_span':
            self.timer_start_time = trigger.timer_start_time
            self.timer_end_time = trigger.timer_end_time
            self.period = trigger.period
            self.timer_period = now

        # Set up trigger timer (duration)
        elif self.trigger_type == 'trigger_timer_duration':
            self.period = trigger.period
            if trigger.timer_start_offset:
                self.timer_period = now + trigger.timer_start_offset
            else:
                self.timer_period = now

        # Set up trigger Run PWM Method
        elif self.trigger_type == 'trigger_run_pwm_method':
            self.unique_id_1 = trigger.unique_id_1
            self.unique_id_2 = trigger.unique_id_2
            self.period = trigger.period
            self.trigger_actions_at_period = trigger.trigger_actions_at_period
            self.trigger_actions_at_start = trigger.trigger_actions_at_start
            self.method_start_time = trigger.method_start_time
            self.method_end_time = trigger.method_end_time
            if self.is_activated:
                self.start_method(trigger.unique_id_1)
            if self.trigger_actions_at_start:
                self.timer_period = now + trigger.period
                if self.is_activated:
                    pwm_duty_cycle = self.get_method_output(
                        trigger.unique_id_1)
                    self.set_output_duty_cycle(
                        trigger.unique_id_2, pwm_duty_cycle)
                    trigger_function_actions(self.function_id)
            else:
                self.timer_period = now

        # Set up trigger sunrise/sunset
        elif self.trigger_type == 'trigger_sunrise_sunset':
            self.period = 60
            # Set the next trigger at the specified sunrise/sunset time (+-offsets)
            self.timer_period = calculate_sunrise_sunset_epoch(trigger)
Example #9
0
    def run(self):
        try:
            self.running = True
            self.logger.info(
                "Activated in {:.1f} ms".format(
                    (timeit.default_timer() - self.thread_startup_timer) * 1000))
            self.ready.set()

            while self.running:
                # Pause loop to modify trigger.
                # Prevents execution of trigger while variables are
                # being modified.
                if self.pause_loop:
                    self.verify_pause_loop = True
                    while self.pause_loop:
                        time.sleep(0.1)

                if (self.is_activated and self.timer_period and
                        self.timer_period < time.time()):
                    check_approved = False

                    # Check if the trigger period has elapsed
                    if self.trigger_type in ['trigger_sunrise_sunset',
                                             'trigger_run_pwm_method']:
                        while self.running and self.timer_period < time.time():
                            self.timer_period += self.period

                        if self.trigger_type == 'trigger_run_pwm_method':
                            # Only execute trigger actions when started
                            # Now only set PWM output
                            pwm_duty_cycle, ended = self.get_method_output(
                                self.unique_id_1)
                            if not ended:
                                self.set_output_duty_cycle(
                                    self.unique_id_2,
                                    pwm_duty_cycle)
                                if self.trigger_actions_at_period:
                                    trigger_function_actions(self.function_id)
                        else:
                            check_approved = True

                    elif (self.trigger_type in [
                            'trigger_timer_daily_time_point',
                            'trigger_timer_daily_time_span',
                            'trigger_timer_duration']):
                        if self.trigger_type == 'trigger_timer_daily_time_point':
                            self.timer_period = epoch_of_next_time(
                                '{hm}:00'.format(hm=self.timer_start_time))
                        elif self.trigger_type in ['trigger_timer_duration',
                                                   'trigger_timer_daily_time_span']:
                            while self.running and self.timer_period < time.time():
                                self.timer_period += self.period
                        check_approved = True

                    if check_approved:
                        self.check_triggers()

                time.sleep(self.sample_rate)

            self.running = False
            self.logger.info(
                "Deactivated in {:.1f} ms".format(
                    (timeit.default_timer() -
                     self.thread_shutdown_timer) * 1000))
        except Exception as except_msg:
            self.logger.exception("Run Error: {err}".format(
                err=except_msg))