def onNagTimer(zone, nagSensors): ''' You should do something about the open doors! ''' sdf = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss") logMsg = '' msg = '' for i in range(len(nagSensors)): sensor = nagSensors[i] msg += sensor.label logMsg += sensor.label logMsg += u' opened ' + sdf.print(sensor.getLastUpdate()) if i + 2 == len(nagSensors): msg += ' and ' logMsg += ' and ' elif i + 1 == len(nagSensors): msg += '.' logMsg += '.' elif i + 2 < len(nagSensors): msg += ', ' logMsg += ', ' msg = u'Open sections in ' + zone.name.decode('utf-8') + '. ' + msg log.info(msg) if zone.zoneNumber in [ 1, 3, 4 ] and itemRegistry.getItem('Z1_Block_Nag_Timer').state != ON: tts(msg, PRIO['HIGH']) elif zone.zoneNumber == 2 and itemRegistry.getItem( 'Z2_Block_Nag').state != ON: tts(msg, PRIO['MODERATE'])
def getItemValue(itemName, defVal): ''' Returns the items value if the item is initialized otherwise return the default value. itemRegistry.getItem will return an object also for uninitialized items but it has less methods. ''' item = itemRegistry.getItem(itemName) if type(defVal) is int: return item.state.intValue() if item.state not in [NULL, UNDEF ] else defVal elif type(defVal) is float: return item.state.floatValue() if item.state not in [NULL, UNDEF ] else defVal elif defVal in [ON, OFF, OPEN, CLOSED]: return item.state if item.state not in [NULL, UNDEF] else defVal elif type(defVal) is str: return item.state.toFullString() if item.state not in [NULL, UNDEF ] else defVal elif type(defVal) is DateTime: # We return a to a org.joda.time.DateTime from a org.eclipse.smarthome.core.library.types.DateTimeType return DateTime( item.state.calendar.timeInMillis) if item.state not in [ NULL, UNDEF ] else defVal else: log.error('The type of the passed default value is not handled') return None
def postUpdate(item, newValue): ''' Posts an update to an item regerdless of it's current state The item can be passed as an OH item type or by using the item's name (string) ''' events.postUpdate( (itemRegistry.getItem(item) if isinstance(item, basestring) else item), newValue)
def sendCommand(item, newValue): ''' Sends a command to an item regerdless of it's current state The item can be passed as an OH item type or by using the item's name (string) ''' events.sendCommand( (itemRegistry.getItem(item) if isinstance(item, basestring) else item), newValue)
def postUpdateCheckFirst(itemName, newValue, sendACommand=False, floatPrecision=-1): ''' newValue must be of a type supported by the item Checks if the current state of the item is different than the desired new state. If the target state is the same, no update is posted. sendCommand vs postUpdate: If you want to tell something to change, (turn a light on, change the thermostat to a new temperature, start raising the blinds, etc.), then you want to send a command to an item using sendCommand. If your items' states are not being updated by a binding, the autoupdate feature or something else external, you will probably want to update the state in a rule using postUpdate. ''' compareValue = None item = itemRegistry.getItem(itemName) if item.state not in [NULL, UNDEF]: if type(newValue) is int: compareValue = itemRegistry.getItem(itemName).state.intValue() elif type(newValue) is float: ''' Unfortunately, most decimal fractions cannot be represented exactly as binary fractions. A consequence is that, in general, the decimal floating-point numbers you enter are only approximated by the binary floating-point numbers actually stored in the machine. Therefore, comparing the stored value with the new value will most likely always result in a difference. You can supply the named argument floatPrecision to round the value before comparing ''' if floatPrecision == -1: compareValue = itemRegistry.getItem( itemName).state.floatValue() else: compareValue = round( itemRegistry.getItem(itemName).state.floatValue(), floatPrecision) elif newValue in [ON, OFF, OPEN, CLOSED]: compareValue = itemRegistry.getItem(itemName).state elif type(newValue) is str: compareValue = itemRegistry.getItem(itemName).state.toString() else: log.error('Can not set ' + str(itemName) + ' to the unsupported type ' + str(type(newValue)) + '. Value: ' + str(newValue)) if (compareValue is not None and compareValue != newValue) or item.state in [NULL, UNDEF]: if sendACommand: log.debug('New sendCommand value for ' + itemName + ' is ' + str(newValue)) events.sendCommand(item, newValue) else: log.debug('New postUpdate value for ' + itemName + ' is ' + str(newValue)) events.postUpdate(item, newValue) return True else: return False
def getLastUpdate(self): ''' Returns the sensors last update time (if available). type is 'org.joda.time.DateTime', http://joda-time.sourceforge.net/apidocs/org/joda/time/DateTime.html ''' try: lastUpdate = PersistenceExtensions.lastUpdate( itemRegistry.getItem(self.name)).toDateTime() except: lastUpdate = DateTime(0) self.log.info('Could not retrieve persistence data for sensor: ' + self.name.decode('utf8')) return lastUpdate
def __init__(self, parent, cfg): ''' Initialise the IdeAlarmSensor class Expects: - Parent object - cfg (dictionary) The sensor's configuration dictionary ''' self.name = cfg['name'] _label = itemRegistry.getItem(self.name).label self.label = _label if _label is not None else 'Sensor has no label' self.parent = weakref.ref(parent) # <= garbage-collector safe! self.sensorClass = cfg['sensorClass'] self.nag = cfg['nag'] self.nagTimeoutMins = cfg['nagTimeoutMins'] self.armWarn = cfg['armWarn'] self.enabled = cfg['enabled'] self.log = logging.getLogger(LOG_PREFIX + '.IdeAlarmSensor.' + self.name.decode('utf8'))
def sayHello(): hour = DateTime.now().getHourOfDay() if not (hour > 7 and hour < 22): return greetings = [greeting(), 'Hello', 'Greetings', 'Hi'] peopleAtHome = [] for member in itemRegistry.getItem('G_Presence_Family').getAllMembers(): if member.state == OPEN: peopleAtHome.append(member.label) random.shuffle(peopleAtHome) msg = random.choice(greetings) for i in range(len(peopleAtHome)): person = peopleAtHome[i] msg += ' ' + person if i + 2 == len(peopleAtHome): msg += ' and' elif i + 1 == len(peopleAtHome): msg += '.' elif i + 2 < len(peopleAtHome): msg += ',' tts(msg)
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('Checking sensor: '+sensor.name+'. : '+ str(sensor.isEnabled() and sensor.isActive())) if sensor.isEnabled() and sensor.isActive() \ and ('G_Motion' not in itemRegistry.getItem(sensor.name).groupNames or self.getArmingMode() in [ARMINGMODE['ARMED_AWAY']]): self.openSections += 1 self.log.debug('Open sensor: ' + sensor.name) self.log.debug('Number of open sections in ' + self.name.decode('utf-8') + ' is: ' + str(self.openSections)) postUpdateCheckFirst('Z' + str(self.zoneNumber) + '_Open_Sections', self.openSections) return self.openSections
def hasReloadFinished(exitScript=False): ''' Sometimes scripts are running before all Items have finished loading. To prevent that, place an item, only for this purpose last in your last items file.(alphabetic order). The item must be persisted on change. We will check if this item has a specific value. Define the name of the item in your lucid config file. Name it whatever you like but it's better if it starts with the last letter in the alphabet. Example Item: String ZZZ_Test_Reload_Finished (G_PersistOnChange) ''' HELLO = 'Hello' try: if itemRegistry.getItem(config.customItemNames['reloadFinished'] ).state.toString == HELLO: return True except: if exitScript: return False timeToSleep = 0.5 + random.uniform(0, 1) time.sleep(timeToSleep) log.info('WAITING ' + str(timeToSleep) + ' sec !!!') postUpdateCheckFirst(config.customItemNames['reloadFinished'], HELLO) return True
def isActive(self): ''' The sensor is considered active when its OPEN, ON or NULL. Locks are different. ''' return isActive(itemRegistry.getItem(self.name))