예제 #1
0
def check_form_timer_daily_time_span(form, error):
    """Checks if the submitted form has any errors"""
    if not epoch_of_next_time('{hm}:00'.format(hm=form.timer_start_time.data)):
        error.append("{id} must be a valid HH:MM time format".format(
            id=form.timer_start_time.label.text))
    if not epoch_of_next_time('{hm}:00'.format(hm=form.timer_end_time.data)):
        error.append("{id} must be a valid HH:MM time format".format(
            id=form.timer_end_time.label.text))
    return error
예제 #2
0
def check_form_timer_daily_time_span(form, error):
    """Checks if the submitted form has any errors"""
    if not epoch_of_next_time('{hm}:00'.format(hm=form.timer_start_time.data)):
        error.append("{id} must be a valid HH:MM time format".format(
            id=form.timer_start_time.label.text))
    if not epoch_of_next_time('{hm}:00'.format(hm=form.timer_end_time.data)):
        error.append("{id} must be a valid HH:MM time format".format(
            id=form.timer_end_time.label.text))
    return error
예제 #3
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)

        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 == 'trigger_sunrise_sunset':
                while self.running and self.timer_period < time.time():
                    self.timer_period = suntime_calculate_next_sunrise_sunset_epoch(
                        self.trigger.latitude, self.trigger.longitude,
                        self.trigger.date_offset_days,
                        self.trigger.time_offset_minutes,
                        self.trigger.rise_or_set)
                check_approved = True

            elif 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.trigger.unique_id_1)

                self.timer_period += self.trigger.period
                self.set_output_duty_cycle(pwm_duty_cycle)

                actions = parse_action_information()

                if self.trigger_actions_at_period:
                    trigger_controller_actions(actions,
                                               self.unique_id,
                                               debug=self.log_level_debug)
                check_approved = True

                if ended:
                    self.stop_method()

            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(
                        f'{self.timer_start_time}:00')
                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)
예제 #4
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)
예제 #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)
예제 #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))
예제 #7
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.unique_id_3 = self.trigger.unique_id_3
            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:
                    self.loop()
            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(self.trigger)
예제 #8
0
def trigger_mod(form):
    """Modify a Trigger"""
    messages = {
        "success": [],
        "info": [],
        "warning": [],
        "error": [],
        "name": None
    }

    try:
        trigger = Trigger.query.filter(
            Trigger.unique_id == form.function_id.data).first()
        trigger.name = form.name.data
        messages["name"] = form.name.data
        trigger.log_level_debug = form.log_level_debug.data

        if trigger.trigger_type == 'trigger_edge':
            if not form.measurement.data or form.measurement.data == '':
                messages["error"].append("{meas} must be set".format(
                    meas=form.measurement.label.text))
            trigger.measurement = form.measurement.data
            trigger.edge_detected = form.edge_detected.data

        elif trigger.trigger_type == 'trigger_output':
            if not form.unique_id_1.data:
                messages["error"].append(
                    "{id} must be set".format(id=form.unique_id_1.label.text))
            if not form.output_state.data:
                messages["error"].append(
                    "{id} must be set".format(id=form.output_state.label.text))
            trigger.unique_id_1 = form.unique_id_1.data.split(",")[0]
            trigger.unique_id_2 = form.unique_id_1.data.split(",")[1]
            trigger.output_state = form.output_state.data
            trigger.output_duration = form.output_duration.data

        elif trigger.trigger_type == 'trigger_output_pwm':
            if not form.unique_id_1.data:
                messages["error"].append(
                    "{id} must be set".format(id=form.unique_id_1.label.text))
            if not form.output_state or form.output_state == '':
                messages["error"].append(
                    "State must be set".format(dir=form.output_state))
            if not 0 <= form.output_duty_cycle.data <= 100:
                messages["error"].append("{id} must >= 0 and <= 100".format(
                    id=form.output_duty_cycle.label.text))
            trigger.unique_id_1 = form.unique_id_1.data.split(",")[0]
            trigger.unique_id_2 = form.unique_id_1.data.split(",")[1]
            trigger.output_state = form.output_state.data
            trigger.output_duty_cycle = form.output_duty_cycle.data

        elif trigger.trigger_type == 'trigger_run_pwm_method':
            if not form.period.data or form.period.data <= 0:
                messages["error"].append("Period must be greater than 0")
            if not form.unique_id_1.data:
                messages["error"].append(
                    "{id} must be set".format(id=form.unique_id_1.label.text))
            if not form.unique_id_2.data:
                messages["error"].append(
                    "{id} must be set".format(id=form.unique_id_2.label.text))
            trigger.unique_id_1 = form.unique_id_1.data
            trigger.unique_id_2 = form.unique_id_2.data.split(",")[0]
            trigger.unique_id_3 = form.unique_id_2.data.split(",")[1]
            trigger.period = form.period.data
            trigger.trigger_actions_at_start = form.trigger_actions_at_start.data
            trigger.trigger_actions_at_period = form.trigger_actions_at_period.data

        elif trigger.trigger_type == 'trigger_sunrise_sunset':
            if form.rise_or_set.data not in ['sunrise', 'sunset']:
                messages["error"].append(
                    "{id} must be set to 'sunrise' or 'sunset'".format(
                        id=form.rise_or_set.label.text))
            if -90 > form.latitude.data > 90:
                messages["error"].append(
                    "{id} must be >= -90 and <= 90".format(
                        id=form.latitude.label.text))
            if -180 > form.longitude.data > 180:
                messages["error"].append(
                    "{id} must be >= -180 and <= 180".format(
                        id=form.longitude.label.text))
            if form.zenith.data is None:
                messages["error"].append(
                    "{id} must be set".format(id=form.zenith.label.text))
            if form.date_offset_days.data is None:
                messages["error"].append("{id} must be set".format(
                    id=form.date_offset_days.label.text))
            if form.time_offset_minutes.data is None:
                messages["error"].append("{id} must be set".format(
                    id=form.time_offset_minutes.label.text))
            trigger.rise_or_set = form.rise_or_set.data
            trigger.latitude = form.latitude.data
            trigger.longitude = form.longitude.data
            trigger.zenith = form.zenith.data
            trigger.date_offset_days = form.date_offset_days.data
            trigger.time_offset_minutes = form.time_offset_minutes.data

        elif trigger.trigger_type == 'trigger_timer_daily_time_point':
            if not epoch_of_next_time(
                    '{hm}:00'.format(hm=form.timer_start_time.data)):
                messages["error"].append(
                    "{id} must be a valid HH:MM time format".format(
                        id=form.timer_start_time.label.text))
            trigger.timer_start_time = form.timer_start_time.data

        elif trigger.trigger_type == 'trigger_timer_daily_time_span':
            if not epoch_of_next_time(
                    '{hm}:00'.format(hm=form.timer_start_time.data)):
                messages["error"].append(
                    "{id} must be a valid HH:MM time format".format(
                        id=form.timer_start_time.label.text))
            if not epoch_of_next_time(
                    '{hm}:00'.format(hm=form.timer_end_time.data)):
                messages["error"].append(
                    "{id} must be a valid HH:MM time format".format(
                        id=form.timer_end_time.label.text))
            trigger.period = form.period.data
            trigger.timer_start_time = form.timer_start_time.data
            trigger.timer_end_time = form.timer_end_time.data

        elif trigger.trigger_type == 'trigger_timer_duration':
            if form.period.data <= 0:
                messages["error"].append(
                    "{id} must be > 0".format(id=form.period.label.text))
            if form.timer_start_offset.data < 0:
                messages["error"].append("{id} must be >= 0".format(
                    id=form.timer_start_offset.label.text))
            trigger.period = form.period.data
            trigger.timer_start_offset = form.timer_start_offset.data

        if not messages["error"]:
            db.session.commit()
            messages["success"].append('{action} {controller}'.format(
                action=TRANSLATIONS['modify']['title'],
                controller=TRANSLATIONS['trigger']['title']))

            if trigger.is_activated:
                control = DaemonControl()
                return_value = control.refresh_daemon_trigger_settings(
                    form.function_id.data)
                messages["success"].append(
                    gettext("Daemon response: %(resp)s", resp=return_value))

    except sqlalchemy.exc.OperationalError as except_msg:
        messages["error"].append(str(except_msg))
    except sqlalchemy.exc.IntegrityError as except_msg:
        messages["error"].append(str(except_msg))
    except Exception as except_msg:
        messages["error"].append(str(except_msg))

    return messages
예제 #9
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)
예제 #10
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))
예제 #11
0
    def setup_settings(self):
        """ Define all settings """
        cond = db_retrieve_table_daemon(Conditional, unique_id=self.cond_id)

        self.conditional_type = cond.conditional_type
        self.is_activated = cond.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 measurement conditional
        if self.conditional_type == 'conditional_measurement':
            self.period = cond.period
            self.refractory_period = cond.refractory_period
            self.timer_refractory_period = 0
            self.smtp_wait_timer = now + 3600
            self.timer_period = now + self.period

        # Set up conditional timer (daily time point)
        elif self.conditional_type == 'conditional_timer_daily_time_point':
            self.timer_start_time = cond.timer_start_time
            self.timer_period = epoch_of_next_time(
                '{hm}:00'.format(hm=cond.timer_start_time))

        # Set up conditional timer (daily time span)
        elif self.conditional_type == 'conditional_timer_daily_time_span':
            self.timer_start_time = cond.timer_start_time
            self.timer_end_time = cond.timer_end_time
            self.period = cond.period
            self.timer_period = now

        # Set up conditional timer (duration)
        elif self.conditional_type == 'conditional_timer_duration':
            self.period = cond.period
            if cond.timer_start_offset:
                self.timer_period = now + cond.timer_start_offset
            else:
                self.timer_period = now

        # Set up Run PWM Method conditional
        elif self.conditional_type == 'conditional_run_pwm_method':
            self.unique_id_1 = cond.unique_id_1
            self.unique_id_2 = cond.unique_id_2
            self.period = cond.period
            self.trigger_actions_at_period = cond.trigger_actions_at_period
            self.trigger_actions_at_start = cond.trigger_actions_at_start
            self.method_start_time = cond.method_start_time
            self.method_end_time = cond.method_end_time
            if self.is_activated:
                self.start_method(cond.unique_id_1)
            if self.trigger_actions_at_start:
                self.timer_period = now + cond.period
                if self.is_activated:
                    pwm_duty_cycle = self.get_method_output(cond.unique_id_1)
                    self.set_output_duty_cycle(cond.unique_id_2,
                                               pwm_duty_cycle)
                    self.trigger_conditional_actions(cond.unique_id,
                                                     duty_cycle=pwm_duty_cycle)
            else:
                self.timer_period = now

        # Set up sunrise/sunset conditional
        elif self.conditional_type == 'conditional_sunrise_sunset':
            self.timer_refractory_period = 0
            self.period = 1000
            # Set the next trigger at the specified sunrise/sunset time (+-offsets)
            self.timer_period = self.calculate_sunrise_sunset_epoch(cond)
예제 #12
0
    def run(self):
        try:
            self.running = True
            self.logger.info(
                "Conditional controller activated in {:.1f} ms".format(
                    (timeit.default_timer() - self.thread_startup_timer) *
                    1000))
            self.ready.set()

            while self.running:
                # Pause loop to modify conditional statements.
                # Prevents execution of conditional 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 conditional period has elapsed
                    if ((self.conditional_type == 'conditional_measurement'
                         and self.timer_refractory_period < time.time())
                            or self.conditional_type in [
                                'conditional_sunrise_sunset',
                                'conditional_run_pwm_method'
                            ]):
                        while self.timer_period < time.time():
                            self.timer_period += self.period

                        if self.conditional_type == 'conditional_run_pwm_method':
                            # Only execute conditional 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:
                                    self.trigger_conditional_actions(
                                        duty_cycle=pwm_duty_cycle)
                        else:
                            check_approved = True

                    elif (self.conditional_type in [
                            'conditional_timer_daily_time_point',
                            'conditional_timer_daily_time_span',
                            'conditional_timer_duration'
                    ]):
                        if self.conditional_type == 'conditional_timer_daily_time_point':
                            self.timer_period = epoch_of_next_time(
                                '{hm}:00'.format(hm=self.timer_start_time))
                        elif self.conditional_type in [
                                'conditional_timer_duration',
                                'conditional_timer_daily_time_span'
                        ]:
                            while self.timer_period < time.time():
                                self.timer_period += self.period
                        check_approved = True

                    if check_approved:
                        self.check_conditionals()

                time.sleep(self.sample_rate)

            self.running = False
            self.logger.info(
                "Conditional controller 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))