Пример #1
0
def setDayMode(event):
    # setDayMode.log = logging.getLogger("{}.setDayMode".format(LOG_PREFIX))
    setDayMode.log.info(
        "Enter Day_Mode with Day_Mode [{}], Clouds [{}], Astro_Day_Phase [{}]".format(
            ir.getItem("Day_Mode").state,
            ir.getItem("Weather_Cloudy").state,
            ir.getItem("Astro_Day_Phase").state
        )
    )

    cloudy = str(ir.getItem("Weather_Cloudy").state)  or "OFF"

    keyItem = DAY_PHASES_DICT.get(str(ir.getItem("Astro_Day_Phase").state) )
    setDayMode.log.info("Day Phase entry is [{}]".format(keyItem.get("mode")))

    if keyItem.get("mode") == "time":
        if DateTime.now().getHourOfDay() < keyItem.get("mode_time"):
            newState = keyItem.get("before_state")
        else:
            newState = keyItem.get("after_state")
        # TODO: Fix this hack:
        if str(ir.getItem("Astro_Day_Phase").state) in ["NIGHT", "NAUTIC_DAWN", "CIVIL_DAWN", "ASTRO_DAWN"] and DateTime.now().getHourOfDay() < 6:
            newState = "NIGHT"
    else:
        newState = keyItem.get("clear_state") if cloudy == "OFF" else keyItem.get("cloudy_state")

    setDayMode.log.info("Set Day_Mode to [{}], if different from [{}]".format(newState, ir.getItem("Day_Mode").state))
    postUpdateCheckFirst("Day_Mode", str(newState))
Пример #2
0
    def setArmingMode(self, newArmingMode, sendCommand=False):
        '''
        Sets the zones current arming mode
        '''
        oldArmingMode = self._armingMode

        if newArmingMode not in [
                ARMINGMODE['DISARMED'], ARMINGMODE['ARMED_HOME'],
                ARMINGMODE['ARMED_AWAY']
        ]:
            raise IdeAlarmError(
                "Trying to set an invalid arming mode: {}".format(
                    newArmingMode))

        # There might be open sensors when trying to arm. If so, the custom function onArmingWithOpenSensors
        # gets called. (That doesn't necessarily need to be an error condition).
        # However if the zone has been configured not to allow opened sensors during arming,
        # the zone status will be set to ERROR and onZoneStatusChange will be able to trap track it down.
        if newArmingMode in [ARMINGMODE['ARMED_AWAY'], ARMINGMODE['ARMED_HOME']] \
        and self.getZoneStatus() != ZONESTATUS['ARMING'] and self.getZoneStatus() is not None \
        and self.openSections > 0:
            if 'onArmingWithOpenSensors' in dir(custom):
                custom.onArmingWithOpenSensors(self, newArmingMode)
            if not self.canArmWithTrippedSensors:
                self.setZoneStatus(
                    ZONESTATUS['ERROR'],
                    errorMessage='Arming is not allowed with open sensors')
                self.log.warn(
                    u"Zone \'{}'\' can not be set to new arming mode: {} due to that there are open sensors!"
                    .format(self.name.decode('utf8'),
                            kw(ARMINGMODE, newArmingMode)))
                import time
                time.sleep(1)
                self.setZoneStatus(ZONESTATUS['NORMAL'])
                return

        # Don't set arming mode to 'ARMED_AWAY' immediately, we need to wait for the exit timer
        # self.getZoneStatus() returns None when initializing
        if newArmingMode == ARMINGMODE['ARMED_AWAY'] \
        and self.getZoneStatus() is not None and self.getZoneStatus() != ZONESTATUS['ARMING']:
            self.setZoneStatus(ZONESTATUS['ARMING'])
            postUpdateCheckFirst("Z{}_Exit_Timer".format(self.zoneNumber),
                                 scope.ON)
            return
        self._armingMode = newArmingMode

        # Sync the Item
        postUpdateCheckFirst(self.armingModeItem, newArmingMode, sendCommand)

        # Call custom function if available
        if 'onArmingModeChange' in dir(custom):
            custom.onArmingModeChange(self, newArmingMode, oldArmingMode)

        # Whenever the arming mode is set, reset the zones status to NORMAL
        self.setZoneStatus(ZONESTATUS['NORMAL'])
Пример #3
0
def exampleSolarTimeOfDay(event):
    time.sleep(2)  # wait for Items to update
    dawn_start = DateTime(items['V_CivilDawn'].toString())
    day_start = DateTime(items['V_Sunrise'].toString())
    dusk_start = DateTime(items['V_CivilDuskStart'].toString())
    night_start = DateTime(items['V_CivilDuskEnd'].toString())

    curr = None
    now = DateTime.now()
    exampleSolarTimeOfDay.log.debug("dawn_start  [{}]".format(dawn_start))
    exampleSolarTimeOfDay.log.debug("day_start   [{}]".format(day_start))
    exampleSolarTimeOfDay.log.debug("dusk_start  [{}]".format(dusk_start))
    exampleSolarTimeOfDay.log.debug("night_start [{}]".format(night_start))
    exampleSolarTimeOfDay.log.debug("now         [{}]".format(now))

    if now.isAfter(dawn_start) and now.isBefore(day_start):
        curr = SOLARTIME['DAWN']
    elif now.isAfter(day_start) and now.isBefore(dusk_start):
        curr = SOLARTIME['DAY']
    elif now.isAfter(dusk_start) and now.isBefore(night_start):
        curr = SOLARTIME['DUSK']
    else:
        curr = SOLARTIME['NIGHT']

    if postUpdateCheckFirst('V_SolarTime', curr):
        exampleSolarTimeOfDay.log.info("Solar time is now [{}]".format(
            kw(SOLARTIME, curr)))
Пример #4
0
def exampleTimeOfDay(event):
    # Get the time period start times for today
    now = DateTime.now()
    morningStart = now.withTime(timeOfDay['morningStart']['Hour'],
                                timeOfDay['morningStart']['Minute'], 0,
                                0).toInstant()
    dayStart = now.withTime(timeOfDay['dayStart']['Hour'],
                            timeOfDay['dayStart']['Minute'], 0, 0).toInstant()
    eveningStart = now.withTime(timeOfDay['eveningStart']['Hour'],
                                timeOfDay['eveningStart']['Minute'], 0,
                                0).toInstant()
    nightStart = now.withTime(timeOfDay['nightStart']['Hour'],
                              timeOfDay['nightStart']['Minute'], 0,
                              0).toInstant()

    timeOfDay = TIMEOFDAY['NIGHT']
    if (now.isAfter(morningStart) and now.isBefore(dayStart)):
        timeOfDay = TIMEOFDAY['MORNING']
    elif (now.isAfter(dayStart) and now.isBefore(eveningStart)):
        timeOfDay = TIMEOFDAY['DAY']
    elif (now.isAfter(eveningStart) and now.isBefore(nightStart)):
        timeOfDay = TIMEOFDAY['EVENING']

    if postUpdateCheckFirst('V_TimeOfDay', timeOfDay):
        exampleTimeOfDay.log.debug("Time of day now: [{}]".format(
            kw(TIMEOFDAY, timeOfDay)))
Пример #5
0
    def onSensorChange(self, sensor):
        '''
        Called whenever an enabled sensor has tripped ON or OPEN
        '''
        if self.getArmingMode() not in [ARMINGMODE['ARMED_HOME'], ARMINGMODE['ARMED_AWAY']] \
        or self.getZoneStatus() not in [ZONESTATUS['NORMAL']] \
        or (self.getArmingMode() == ARMINGMODE['ARMED_HOME'] and sensor.sensorClass == 'B') \
        or getItemValue("Z{}_Exit_Timer".format(self.zoneNumber), scope.OFF) == scope.ON:
            self.log.info(u"{} was tripped, but we are ignoring it".format(
                sensor.name.decode('utf8')))
            return

        self.setZoneStatus(ZONESTATUS['TRIPPED'])
        self.log.info(u"{} was tripped, starting entry timer".format(
            sensor.name.decode('utf8')))
        postUpdateCheckFirst("Z{}_Entry_Timer".format(self.zoneNumber),
                             scope.ON)
Пример #6
0
    def onEntryTimer(self):
        '''
        Called whenever the entry timer times out.
        '''
        # Double check that the zone status is tripped, we can probably remove this check later
        if self.getZoneStatus() not in [ZONESTATUS['TRIPPED']]:
            raise IdeAlarmError(
                'Entry Timer timed out but zone status is not tripped')
        self.setZoneStatus(ZONESTATUS['ALERT'])

        # We need to make some noise here!
        if not self.alarmTestMode:
            for alertDevice in self.alertDevices:
                sendCommandCheckFirst(alertDevice, scope.ON)
            self.log.info('You should be able to hear the sirens now...')
        else:
            self.log.info('ALARM_TEST_MODE is activated. No sirens!')
        postUpdateCheckFirst("Z{}_Alert_Max_Timer".format(self.zoneNumber),
                             scope.ON)
Пример #7
0
 def countOpenSections(self):
     '''
     A sensor has changed its state. We are here to calculate how many open
     sensors there are in the zone at this very moment. Saves the result in
     self.openSections and returns it. WE DO NOT INCLUDE MOTION DETECTORS
     IN THE COUNT UNLESS ARMED AWAY! E.G. Those sensors that belongs to
     group 'G_Motion'
     '''
     self.openSections = 0
     for sensor in self.sensors:
         #self.log.debug(u"Checking sensor: {} : {}".format(sensor.name.decode('utf8'), sensor.isEnabled() and sensor.isActive()))
         if sensor.isEnabled() and sensor.isActive() \
         and ('G_Motion' not in scope.itemRegistry.getItem(sensor.name).groupNames or self.getArmingMode() in [ARMINGMODE['ARMED_AWAY']]):
             self.openSections += 1
             self.log.debug(u"Open sensor: {}".format(
                 sensor.name.decode('utf8')))
     self.log.debug(u"Number of open sections in {} is: {}".format(
         self.name.decode('utf8'), self.openSections))
     postUpdateCheckFirst("Z{}_Open_Sections".format(self.zoneNumber),
                          self.openSections)
     return self.openSections
Пример #8
0
 def getNagSensors(self, timerTimedOut=False):
     '''
     Check if nagging is required. Performed when a sensor changes its state and when the nag timer ends.
     Nagging is only performed when a zone is disarmed.
     '''
     nagSensors = []
     for sensor in self.sensors:
         if sensor.isEnabled() and sensor.isActive(
         ) and sensor.nag and self.getArmingMode(
         ) == ARMINGMODE['DISARMED']:
             nagSensors.append(sensor)
     if len(nagSensors) == 0:
         postUpdateCheckFirst("Z{}_Nag_Timer".format(self.zoneNumber),
                              scope.OFF)  # Cancel the nag timer
     else:
         postUpdateCheckFirst("Z{}_Nag_Timer".format(self.zoneNumber),
                              scope.ON)
         if timerTimedOut and 'onNagTimer' in dir(custom):
             self.log.debug('Calling custom onNagTimer function')
             custom.onNagTimer(self, nagSensors)
     return nagSensors
Пример #9
0
    def setZoneStatus(self,
                      newZoneStatus,
                      sendCommand=False,
                      errorMessage=None):
        '''
        Sets the zones current status
        '''
        if newZoneStatus not in [
                ZONESTATUS['NORMAL'], ZONESTATUS['ALERT'], ZONESTATUS['ERROR'],
                ZONESTATUS['TRIPPED'], ZONESTATUS['ARMING']
        ]:
            raise IdeAlarmError('Trying to set an invalid zone status')
        oldZoneStatus = self._zoneStatus
        self._zoneStatus = newZoneStatus

        if newZoneStatus in [ZONESTATUS['NORMAL']]:

            # Cancel all timers so they won't fire
            postUpdateCheckFirst("Z{}_Entry_Timer".format(self.zoneNumber),
                                 scope.OFF)
            postUpdateCheckFirst("Z{}_Exit_Timer".format(self.zoneNumber),
                                 scope.OFF)
            postUpdateCheckFirst("Z{}_Alert_Max_Timer".format(self.zoneNumber),
                                 scope.OFF)

            # Cancel sirens
            for alertDevice in self.alertDevices:
                sendCommandCheckFirst(alertDevice, scope.OFF)

        # Sync the Zone Status Item
        postUpdateCheckFirst(self.statusItem, newZoneStatus, sendCommand)

        # Call custom function if available
        if 'onZoneStatusChange' in dir(custom):
            custom.onZoneStatusChange(self,
                                      newZoneStatus,
                                      oldZoneStatus,
                                      errorMessage=errorMessage)