예제 #1
0
def _command_processing_thread():
    try:
        _log.debug('command_processing_thread started.')

        while True:
            cmd_json = _cloud.wait_for_command()
            _log.debug('Command json: {}'.format(cmd_json))

            cmd_packet = lib_cloud_protocol.CommandPacket(cmd_json)
            cmd_dict = cmd_packet.get_dict()

            if cmd_packet.is_valid():
                if cmd_dict['command'] == 'set-intervals':
                    if 'lock' in cmd_dict['states']:
                        param = lib_device_config.ConfigParam(
                            'telemetryIntervalLock',
                            cmd_dict['states']['lock'])
                        _device_config.set_param(param)
                    if 'unlock' in cmd_dict['states']:
                        param = lib_device_config.ConfigParam(
                            'telemetryIntervalUnlock',
                            cmd_dict['states']['unlock'])
                        _device_config.set_param(param)
                    if 'unavailable' in cmd_dict['states']:
                        param = lib_device_config.ConfigParam(
                            'telemetryIntervalUnavailable',
                            cmd_dict['states']['unavailable'])
                        _device_config.set_param(param)
                elif ((cmd_dict['command'] == 'lock')
                      or (cmd_dict['command'] == 'unlock')
                      or (cmd_dict['command'] == 'unavailable')):
                    # clear threshold detection to avoid immediate alarm after unlock state
                    _acc_thr_detector.clear()
                    param = lib_device_config.ConfigParam(
                        'deviceState', cmd_dict['command'])
                    _device_config.set_param(param)
                    with _last_telemetry_packet_lock:
                        _last_telemetry_events.append(
                            lib_cloud_protocol.StateEvent(cmd_dict['command']))
                elif cmd_dict['command'] == 'beep':
                    _buzzer_pattern_gen.start_pattern(
                        lib_buzzer_pattern.BUZZER_PATTERN_ID.BEEP,
                        cmd_dict['volume'],
                        lib_buzzer_pattern.PATTERN_REPEAT_FOREVER)
                elif cmd_dict['command'] == 'alarm':
                    _buzzer_pattern_gen.start_pattern(
                        lib_buzzer_pattern.BUZZER_PATTERN_ID.ALARM,
                        cmd_dict['volume'],
                        lib_buzzer_pattern.PATTERN_REPEAT_FOREVER)

                _telemetry_send_event.set()
    except:
        _log.error(traceback.format_exc())
        utils_exit.exit(1)
예제 #2
0
def _configuration_processing_thread():
    try:
        _log.debug('configuration_processing_thread started.')

        while True:
            cfg_json = _cloud.wait_for_configuration()
            _log.debug('Configuration json: {}'.format(cfg_json))

    except:
        _log.error(traceback.format_exc())
        utils_exit.exit(1)
예제 #3
0
def main():
    try:
        _log.debug('main started.')
        atexit.register(utils_exit.on_exit)

        app.init()
        app.start()

        _log.error('Application exited unexpectedly.')
        utils_exit.exit(1)
    except:
        _log.error(traceback.format_exc())
        utils_exit.exit(1)
예제 #4
0
    def _event_send_thread(self):
        try:
            while True:
                for event in self._current_pattern:
                    self._led_rgb_driver.set_event(event)

                self._pattern_repeate_count -= 1
                if self._pattern_repeate_count < 0:
                    return
                if self._pattern_thread_stop:
                    return
        except:
            _log.error(traceback.format_exc())
            utils_exit.exit(1)
예제 #5
0
    def _process_thread_func(self):
        try:
            _log.debug('buzzer _process_tone_func thread started.')

            while True:
                self._start_event.wait()

                event: buzzer.BuzzerEvent = self._events_queue.get(True, None)

                self._pigpio.hardware_PWM(self._pwm_pin, event.frequency,
                                          int(event.duty_cycle * 10000))

                time.sleep(event.time)
                self._pigpio.hardware_PWM(self._pwm_pin, 2500, 0)
        except:
            _log.error(traceback.format_exc())
            utils_exit.exit(1)
    def _update(self):
        try:
            acc_data_updated = self._acc_driver.get_data_updated_event()

            while True:
                acc_data_updated.wait()
                acc_data_updated.clear()
                with self._data_lock:
                    self._last_acc_data = self._acc_driver.get_last_data()
                    is_acc_data_threshold = self._acc_driver.is_acc_out_of_threshold(
                    )
                    current_time_ms = int(time.time() * 1000)

                    _log.debug(
                        'Acc data updated: x = {x} mg, y = {y} mg, z = {z} mg. Out of threshold: {thr}.'
                        .format(x=self._last_acc_data.x_mg,
                                y=self._last_acc_data.y_mg,
                                z=self._last_acc_data.z_mg,
                                thr=is_acc_data_threshold))

                    self._calculate_angles()

                    _log.debug(
                        'Acc angles updated: x = {x}, y = {y}, z = {z}.'.
                        format(x=self._acc_angles.x,
                               y=self._acc_angles.y,
                               z=self._acc_angles.z))

                    if self._calc_is_angles_out_of_thr():
                        self._angle_out_of_thr_stop_time_ms = None
                        if self._angle_out_of_thr_start_time_ms == None:
                            self._angle_out_of_thr_start_time_ms = current_time_ms
                    else:
                        if self._angle_out_of_thr_stop_time_ms == None:
                            self._angle_out_of_thr_stop_time_ms = current_time_ms
                        elif ((self._angle_out_of_thr_stop_time_ms +
                               self._angle_total_duration_ms) <=
                              current_time_ms):
                            self._angle_out_of_thr_start_time_ms = None

                    if (self._acc_peak_count !=
                            None) and is_acc_data_threshold:
                        self._acc_out_of_thr_peak_count += 1
        except:
            _log.error(traceback.format_exc())
            utils_exit.exit(1)
예제 #7
0
    def _process_thread_func(self):
        try:
            _log.debug('relay process_thread_func thread started.')

            while True:
                self._start_event.wait()

                state = self._state_queue.get(True, None)

                if state != self._current_state:
                    pin = self._set_pin if state else self._reset_pin
                    GPIO.output(pin, GPIO.HIGH)
                    time.sleep(RelayAdjh23005.STATE_CHANGE_TIME)
                    GPIO.output(pin, GPIO.LOW)
                    self._current_state = state

                time.sleep(0.1)
        except:
            _log.error(traceback.format_exc())
            utils_exit.exit(1)
예제 #8
0
    def _process_thread_func(self):
        try:
            _log.debug('led _process_tone_func thread started.')

            while True:
                self._start_event.wait()

                event: drv_led_rgb.LedRgbEvent = self._events_queue.get(
                    True, None)

                self._neopixel.fill(
                    (int(event.r_bright * 2.55), int(event.g_bright * 2.55),
                     int(event.b_bright * 2.55)))
                self._neopixel.show()

                time.sleep(event.time)
                self._neopixel.fill((0, 0, 0))
                self._neopixel.show()
        except:
            _log.error(traceback.format_exc())
            utils_exit.exit(1)
예제 #9
0
    def _process_thread_func(self):
        try:
            _log.debug('adc process_thread_func thread started.')
            while True:
                self._start_event.wait()

                with _i2c_lock_obj:
                    with self._data_lock:
                        for i in range(4):
                            if self._channels_voltage[i] == 0:
                                self._channels_voltage[i] = self._adc_channels[
                                    i].voltage
                            else:
                                self._channels_voltage[i] = (
                                    (1.0 - _VOLTAGE_LEVEL_FILTER_COEF) *
                                    self._channels_voltage[i] +
                                    _VOLTAGE_LEVEL_FILTER_COEF *
                                    self._adc_channels[i].voltage)
                time.sleep(0.1)
        except:
            _log.error(traceback.format_exc())
            utils_exit.exit(1)
예제 #10
0
    def _process_thread_func(self):
        try:
            _log.debug('acc process_thread_func thread started.')

            while True:
                self._start_event.wait()

                acc_status = self._read_register(ACC_REG_ID.STATUS)
                # if new data available - read it
                if acc_status & 0x08:
                    # read data from acc
                    last_data = self._read_acc_data()
                    # read if data was out of threshold
                    ig_src1_value = self._read_register(ACC_REG_ID.IG_SRC1)
                    is_acc_out_of_threshold = (ig_src1_value & 0x2A) > 0
                    if self._acc_data_threshold_update_required:
                        # update acc threshold
                        threshold = int(
                            (self._acc_data_threshold * 256) / 2000)
                        self._write_register(ACC_REG_ID.IG_THS_X1, threshold)
                        self._write_register(ACC_REG_ID.IG_THS_Y1, threshold)
                        self._write_register(ACC_REG_ID.IG_THS_Z1, threshold)
                        # set duration (for 10 Hz - 100 ms on each sample)
                        duration = int(self._acc_data_threshold_duration / 100)
                        self._write_register(ACC_REG_ID.IG_DUR1,
                                             duration & 0x7F)
                        # read to clear unexpected interrupt
                        ig_src1_value = self._read_register(ACC_REG_ID.IG_SRC1)

                    with self._data_lock:
                        self._acc_data_threshold_update_required = False
                        self._last_data = last_data
                        self._is_acc_out_of_threshold = is_acc_out_of_threshold
                        self._data_event.set()

                    time.sleep(0.1)
        except:
            _log.error(traceback.format_exc())
            utils_exit.exit(1)
    def _event_send_thread(self):
        try:
            while True:
                for event in self._current_pattern:
                    duty_cycle = _DUTY_CYCLE_OFF
                    if event.duty_cycle != _DUTY_CYCLE_OFF:
                        if self._current_pattern_volume != None:
                            duty_cycle = self._current_pattern_volume / 2.0
                        else:
                            duty_cycle = event.duty_cycle
                    event_copy = drv_buzzer.BuzzerEvent(
                        duty_cycle, event.time, event.frequency)
                    self._buzzer_driver.set_event(event_copy)

                self._pattern_repeate_count -= 1
                if self._pattern_repeate_count < 0:
                    return
                if self._pattern_thread_stop:
                    return
        except:
            _log.error(traceback.format_exc())
            utils_exit.exit(1)
예제 #12
0
def _threshold_detection_thread():
    try:
        _log.debug('threshold_detection_thread started.')

        is_acc_out_of_thr = False
        is_angle_out_of_thr = False
        is_gps_data_change_detected = False
        last_longitude = _GNSS.get_longitude()
        last_latitude = _GNSS.get_latitude()
        is_ext_batt_charging = _adc.ext_batt_is_charging()
        ext_batt_voltage = _adc.get_ext_batt_voltage()
        int_batt_voltage = _adc.get_int_batt_voltage()

        alarm_active = False
        alarm_phase = 0
        alarm_start_time_ms = 0

        while True:
            state = _device_config.get_param('deviceState').value

            # Batteries voltages and charging detection
            ext_batt_voltage_new = _adc.get_ext_batt_voltage()
            int_batt_voltage_new = _adc.get_int_batt_voltage()
            is_ext_batt_charging_new = _adc.ext_batt_is_charging()
            int_batt_threshold = _device_config.get_param(
                'intBattThresholdV').value
            ext_batt_threshold = _device_config.get_param(
                'extBattThresholdV').value
            alarm_active = False

            if ((int_batt_voltage_new >= int_batt_voltage + int_batt_threshold)
                    or (int_batt_voltage_new <=
                        int_batt_voltage - int_batt_threshold)):
                int_batt_voltage = int_batt_voltage_new
                _log.debug(
                    'Internal battery voltage: {} V.'.format(int_batt_voltage))
                with _last_telemetry_packet_lock:
                    _last_telemetry_events.append(
                        lib_cloud_protocol.IntBattEvent(int_batt_voltage))
                _telemetry_send_event.set()

            if ((ext_batt_voltage_new >= ext_batt_voltage + ext_batt_threshold)
                    or (ext_batt_voltage_new <=
                        ext_batt_voltage - ext_batt_threshold)):
                ext_batt_voltage = ext_batt_voltage_new
                _log.debug(
                    'External battery voltage: {} V.'.format(ext_batt_voltage))
                with _last_telemetry_packet_lock:
                    _last_telemetry_events.append(
                        lib_cloud_protocol.ExtBattEvent(ext_batt_voltage))
                _telemetry_send_event.set()

            if is_ext_batt_charging_new != is_ext_batt_charging:
                is_ext_batt_charging = is_ext_batt_charging_new
                _log.debug('External battery charge: {}.'.format(
                    is_ext_batt_charging))
                with _last_telemetry_packet_lock:
                    _last_telemetry_events.append(
                        lib_cloud_protocol.ChargingEvent(is_ext_batt_charging))
                _telemetry_send_event.set()

            # Accelerometer movement and angles threshold detection
            is_acc_out_of_thr_new = _acc_thr_detector.is_acc_out_of_threshold()
            is_angle_out_of_thr_new = _acc_thr_detector.is_angles_out_of_threshold(
            )

            if (is_acc_out_of_thr_new != is_acc_out_of_thr) and (state !=
                                                                 'unlock'):
                is_acc_out_of_thr = is_acc_out_of_thr_new
                _log.debug('Acc data out of threshold updated: {}'.format(
                    is_acc_out_of_thr))
                with _last_telemetry_packet_lock:
                    _last_telemetry_events.append(
                        lib_cloud_protocol.AccMovementEvent(is_acc_out_of_thr))
                _telemetry_send_event.set()

            if (is_angle_out_of_thr_new != is_angle_out_of_thr) and (state !=
                                                                     'unlock'):
                is_angle_out_of_thr = is_angle_out_of_thr_new
                angles = _acc_thr_detector.get_angles()
                _log.debug('Angles are: x: {}, y: {}, z: {}.'.format(
                    angles.x, angles.y, angles.z))
                _log.debug('Angle out of threshold updated: {}'.format(
                    is_angle_out_of_thr))
                with _last_telemetry_packet_lock:
                    _last_telemetry_events.append(
                        lib_cloud_protocol.AccFallEvent(is_angle_out_of_thr))
                _telemetry_send_event.set()

            # GPS threshold detection
            is_gps_data_change_detected_new, new_longitude, new_latitude = (
                _GNSS.get_gps_data_change(last_longitude, last_latitude))
            if ((is_gps_data_change_detected_new !=
                 is_gps_data_change_detected) and (state != 'unlock')
                    and (_GNSS.get_valid() == True)):
                if ((new_longitude != "0.0") and (last_longitude != "0.0")
                        and (new_latitude != "0.0")
                        and (last_latitude != "0.0")):
                    is_gps_data_change_detected = is_gps_data_change_detected_new
                last_longitude = new_longitude
                last_latitude = new_latitude
                _log.debug('GPS position has been changed')
                with _last_telemetry_packet_lock:
                    _last_telemetry_events.append(
                        lib_cloud_protocol.GNSSMovementEvent(
                            is_gps_data_change_detected))
                _telemetry_send_event.set()

            alarm_active = (alarm_active or is_gps_data_change_detected
                            or is_acc_out_of_thr or is_angle_out_of_thr)

            # Process alarm if required
            global _is_alarm
            if alarm_active and state != "unlock":
                current_time_ms = int(time.time() * 1000)
                if alarm_start_time_ms == 0:
                    _is_alarm = True
                    alarm_start_time_ms = current_time_ms

                first_phase_timeout_ms = (
                    _device_config.get_param('firstPhaseAlarmTimeout').value *
                    1000)
                second_phase_timeout_ms = (
                    _device_config.get_param('secondPhaseAlarmTimeout').value *
                    1000)
                third_phase_timeout_ms = (
                    _device_config.get_param('thirdPhaseAlarmTimeout').value *
                    1000)

                if alarm_start_time_ms + first_phase_timeout_ms >= current_time_ms:
                    if alarm_phase == 0:
                        _log.debug('Alarm first phase started.')
                        _buzzer_pattern_gen.start_pattern(
                            lib_buzzer_pattern.BUZZER_PATTERN_ID.ALARM_PHASE_1)
                        alarm_phase += 1
                        pass
                elif (alarm_start_time_ms + second_phase_timeout_ms <=
                      current_time_ms
                      and alarm_start_time_ms + third_phase_timeout_ms >=
                      current_time_ms):
                    if alarm_phase == 1:
                        _log.debug('Alarm second phase started.')
                        _buzzer_pattern_gen.start_pattern(
                            lib_buzzer_pattern.BUZZER_PATTERN_ID.ALARM_PHASE_2)
                        alarm_phase += 1
                        pass
                else:
                    if alarm_phase == 2:
                        _log.debug('Alarm third phase started.')
                        _buzzer_pattern_gen.start_pattern(
                            lib_buzzer_pattern.BUZZER_PATTERN_ID.ALARM_PHASE_3,
                            None, lib_buzzer_pattern.PATTERN_REPEAT_FOREVER)
                        alarm_phase += 1
                        pass
            elif alarm_phase != 0:
                _is_alarm = False
                _buzzer_pattern_gen.stop_pattern()
                _log.debug('Alarm finished.')
                alarm_phase = 0
                alarm_start_time_ms = 0
                pass

            time.sleep(0.1)
    except:
        _log.error(traceback.format_exc())
        utils_exit.exit(1)