示例#1
0
    def load_sensors(self):
        """Load the sensors from the db in the thread to avoid session problems"""
        storage.set(storage.MONITORING_STATE, MONITORING_UPDATING_CONFIG)
        send_sensors_state(None)

        # TODO: wait a little bit to see status for debug
        sleep(3)

        # !!! delete old sensors before load again
        self._sensors = []
        self._sensors = self._db_session.query(Sensor).filter_by(deleted=False).all()
        self._logger.debug("Sensors reloaded!")

        if len(self._sensors) > self._sensorAdapter.channel_count:
            self._logger.info(
                "Invalid number of sensors to monitor (Found=%s > Max=%s)",
                len(self._sensors),
                self._sensorAdapter.channel_count,
            )
            self._sensors = []
            storage.set(storage.MONITORING_STATE, MONITORING_INVALID_CONFIG)
        elif not self.validate_sensor_config():
            self._logger.info("Invalid channel configuration")
            self._sensors = []
            storage.set(storage.MONITORING_STATE, MONITORING_INVALID_CONFIG)
        elif self.has_uninitialized_sensor():
            self._logger.info("Found sensor(s) without reference value")
            self.calibrate_sensors()
            storage.set(storage.MONITORING_STATE, MONITORING_READY)
        else:
            storage.set(storage.MONITORING_STATE, MONITORING_READY)

        send_sensors_state(False)
示例#2
0
    def disarm_monitoring(self, user_id, keypad_id):
        if self._delay_timer:
            self._delay_timer.cancel()
            self._delay_timer = None

        arm = self._db_session.query(Arm).filter_by(end_time=None).first()
        if arm:
            arm.end_time = dt.now()
            arm.end_user_id = user_id
            arm.end_keypad_id = keypad_id
            self._db_session.commit()

        current_state = storage.get(storage.MONITORING_STATE)
        current_arm = storage.get(storage.ARM_STATE)
        if (
            current_state in (
                            MONITORING_ARM_DELAY,
                            MONITORING_ARMED,
                            MONITORING_ALERT_DELAY,
                            MONITORING_ALERT)
                        and current_arm in (ARM_AWAY, ARM_STAY)
                        or current_state == MONITORING_SABOTAGE
        ):
            storage.set(storage.ARM_STATE, ARM_DISARM)
            storage.set(storage.MONITORING_STATE, MONITORING_READY)
        self._stop_alert.set()
示例#3
0
    def run(self):
        self._logger.info("Monitoring started")
        self._db_session = Session()

        # wait some seconds to build up socket IO connection before emit messages
        sleep(5)

        # remove invalid state items from db before startup
        self.cleanup_database()

        # initialize state
        send_alert_state(None)
        send_syren_state(None)
        storage.set(storage.ARM_STATE, ARM_DISARM)

        self.load_sensors()

        while True:
            try:
                message = self._actions.get(True, 1 / int(environ["SAMPLE_RATE"]))
                self._logger.debug("Action: %s" % message)
                if message["action"] == MONITOR_STOP:
                    break
                elif message["action"] == MONITOR_ARM_AWAY:
                    self.arm_monitoring(ARM_AWAY, message.get("user_id", None), message.get("keypad_id", None))
                elif message["action"] == MONITOR_ARM_STAY:
                    self.arm_monitoring(ARM_STAY, message.get("user_id", None), message.get("keypad_id", None))
                elif message["action"] in (MONITORING_ALERT, MONITORING_ALERT_DELAY):
                    if self._delay_timer:
                        self._delay_timer.cancel()
                        self._delay_timer = None
                elif message["action"] == MONITOR_DISARM:
                    self.disarm_monitoring(message.get("user_id", None), message.get("keypad_id", None))
                    continue
                elif message["action"] == MONITOR_UPDATE_CONFIG:
                    self.load_sensors()
            except Empty:
                pass

            self.check_power()
            self.scan_sensors()
            self.handle_alerts()

        self._stop_alert.set()
        self._db_session.close()
        self._logger.info("Monitoring stopped")
示例#4
0
    def check_power(self):
        # load the value once from the adapter
        new_power_source = self._powerAdapter.source_type
        if new_power_source == PowerAdapter.SOURCE_BATTERY:
            storage.set(storage.POWER_STATE, POWER_SOURCE_BATTERY)
            self._logger.debug("System works from battery")
        elif new_power_source == PowerAdapter.SOURCE_NETWORK:
            storage.set(storage.POWER_STATE, POWER_SOURCE_NETWORK)
            self._logger.debug("System works from network")

        if new_power_source == PowerAdapter.SOURCE_BATTERY and self._power_source == PowerAdapter.SOURCE_NETWORK:
            send_power_state(POWER_SOURCE_BATTERY)
            self._logger.info("Power outage started!")
        elif new_power_source == PowerAdapter.SOURCE_NETWORK and self._power_source == PowerAdapter.SOURCE_BATTERY:
            send_power_state(POWER_SOURCE_NETWORK)
            self._logger.info("Power outage ended!")

        self._power_source = new_power_source
示例#5
0
    def __init__(self, broadcaster: Broadcaster):
        """
        Constructor
        """
        super(Monitor, self).__init__(name=THREAD_MONITOR)
        self._logger = logging.getLogger(LOG_MONITOR)
        self._sensorAdapter = SensorAdapter()
        self._powerAdapter = PowerAdapter()
        self._broadcaster = broadcaster
        self._sensors = None
        self._power_source = None
        self._db_session = None
        self._alerts = {}
        self._actions = Queue()
        self._stop_alert = Event()
        self._delay_timer = None

        storage.set(storage.MONITORING_STATE, MONITORING_STARTUP)
        storage.set(storage.ARM_STATE, ARM_DISARM)
        self._broadcaster.register_queue(id(self), self._actions)
        self._logger.info("Monitoring created")
示例#6
0
    def arm_monitoring(self, arm_type, user_id, keypad_id):
        self._db_session.add(
            Arm(
                arm_type=arm_type,
                start_time=dt.now(),
                user_id=user_id,
                keypad_id=keypad_id,
            )
        )

        self._db_session.commit()

        # get max delay of arm
        arm_delay = get_arm_delay(self._db_session, arm_type)

        def stop_arm_delay():
            self._logger.debug("End arm delay => armed!!!")
            storage.set(storage.MONITORING_STATE, MONITORING_ARMED)

        storage.set(storage.ARM_STATE, arm_type)
        self._logger.debug("Arm with delay: %s / %s", arm_delay, arm_type)
        if arm_delay is not None:
            storage.set(storage.MONITORING_STATE, MONITORING_ARM_DELAY)
            self._delay_timer = Timer(arm_delay, stop_arm_delay)
            self._delay_timer.start()
        else:
            storage.set(storage.MONITORING_STATE, MONITORING_ARMED)

        self._stop_alert.clear()
示例#7
0
    def run(self):
        self._logger.info(
            "Alert (%s) started on sensor (id:%s) waiting %s sec before starting syren",
            self._alert_type,
            self._sensor_id,
            self._delay,
        )

        if self._delay > 0:
            storage.set(storage.MONITORING_STATE, MONITORING_ALERT_DELAY)
            self._broadcaster.send_message({"action": MONITORING_ALERT_DELAY})

        if not self._stop_event.wait(self._delay):
            self._logger.info(
                "Start syren because not disarmed (%s) sensor (id:%s) in %s secs",
                self._alert_type,
                self._sensor_id,
                self._delay,
            )
            SyrenAlert.start_syren(self._alert_type, SensorAlert._sensor_queue, self._stop_event)
            SensorAlert._sensor_queue.put(self._sensor_id)
            if self._alert_type == ALERT_SABOTAGE:
                storage.set(storage.MONITORING_STATE, MONITORING_SABOTAGE)
                self._broadcaster.send_message({"action": MONITORING_SABOTAGE})
            else:
                storage.set(storage.MONITORING_STATE, MONITORING_ALERT)
                self._broadcaster.send_message({"action": MONITORING_ALERT})
        else:
            self._logger.info("Sensor alert stopped")
示例#8
0
 def stop_arm_delay():
     self._logger.debug("End arm delay => armed!!!")
     storage.set(storage.MONITORING_STATE, MONITORING_ARMED)