Not yet tested as rule template!
This rule is used to set a switch item (ON / OFF) following the person presence last seen channel from Netatmo Welcome camera.
The destination item (switch) is part of the Generic Presence Detection , as a PersonSensor (Thanks Rich Koshak).
Language: javascript
Dependencies:
- Netatmo Welcome camera or any Things that provides person “last seen” channel
- One or more Switches determines whether someone is present
- A group with all persons last seen channel
- The label (of the person last seen channel) should be the uid of the switch item.
Changelog
Version 0.1
- initial release
Resources
uid: rules_tools:presence_lastSeen
label: Presence detection on person last seen channel
description: This rule is used to set a switch item (ON / OFF) following the person presence last seen channel (from Netatmo Welcome camera).
configDescriptions:
- name: trigger
label: Run frequency
description: Cron trigger to define how often the rule will run.
type: TEXT
context:
required: false
defaultValue: 0 0/2 * * * ? *
- name: lastSeenChannelGroup
label: Last Seen Group
description: A group with all persons last seen channel.
type: TEXT
required: true
- name: duration
label: Duration (min)
description: Duration (min) during which you consider the person present at home after last seen.
type: TEXT
required: false
defaultValue: 15
triggers:
- id: "1"
configuration:
cronExpression: "{{trigger}}"
type: timer.GenericCronTrigger
conditions: []
actions:
- inputs: {}
id: "2"
configuration:
type: application/javascript
script: >-
if(typeof(require) === "function") Object.assign(this, require('@runtime'));
var X, msg, rawLabel, lastSeen;
var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID);
var dtf = Java.type("java.time.format.DateTimeFormatter");
var zdt = Java.type("java.time.ZonedDateTime");
/* Try to detect the format based on its length */
function getZonedDateTime(datetime) {
datetime = String(datetime).replace('T', ' ')
switch (datetime.length) {
case 10: return zdt.parse(datetime + ' 00:00:00+00:00', dtf.ofPattern('yyyy-MM-dd HH:mm:ssz'));
case 16: return zdt.parse(datetime + ':00+00:00', dtf.ofPattern('yyyy-MM-dd HH:mm:ssz'));
case 19: return zdt.parse(datetime + '+00:00', dtf.ofPattern('yyyy-MM-dd HH:mm:ssz'));
case 25: return zdt.parse(datetime, dtf.ofPattern('yyyy-MM-dd HH:mm:ssz'));
case 23: return zdt.parse(datetime + ' +00:00', dtf.ofPattern('yyyy-MM-dd HH:mm:ss.SSS z'));
case 26: return zdt.parse(datetime + ' +00:00', dtf.ofPattern('yyyy-MM-dd HH:mm:ss.SSSSSS z'));
case 29: return zdt.parse(datetime, dtf.ofPattern('yyyy-MM-dd HH:mm:ss.SSSSz'));
case 32: return zdt.parse(datetime, dtf.ofPattern('yyyy-MM-dd HH:mm:ss.SSSSSSSz'));
case 28: return zdt.parse(datetime.slice(0,26) + ':' + datetime.slice(26,28), dtf.ofPattern('yyyy-MM-dd HH:mm:ss.SSSSz'));
default: return zdt.parse(datetime);
}
}
function createZonedDateTime(year, month, day, hour, minute, second, nano, offsetString, timezoneString) {
stringToParse = '' + year;
stringToParse += '-' + ('0' + month).slice(-2);
stringToParse += '-' + ('0' + day).slice(-2);
stringToParse += 'T' + ('0' + hour).slice(-2);
stringToParse += ':' + ('0' + minute).slice(-2);
stringToParse += ':' + ('0' + second).slice(-2);
stringToParse += '.' + nano + offsetString + '[' + timezoneString + ']';
return zdt.parse(stringToParse, dtf.ISO_ZONED_DATE_TIME);
}
logger.info('Starting Netatmo presence check');
var X_list = Java.from(itemRegistry.getItem('{{lastSeenChannelGroup}}').members);
for (var X_index in X_list) {
X = X_list[X_index];
msg = 'Netatmo presence: ';
rawLabel = X.getLabel();
lastSeen = X.getState();
logger.info(rawLabel);
logger.info(lastSeen);
if ((zdt.now()) > lastSeen && zdt.now().minusMinutes({{duration}}) <= lastSeen) {
events.sendCommand(rawLabel, 'ON');
msg += String(rawLabel);
msg += ' ON';
} else {
events.sendCommand(rawLabel, 'OFF');
msg += String(rawLabel);
msg += ' OFF';
}
logger.info(msg);
msg = '';
rawLabel = '';
lastSeen = '';
}
logger.info('Ending Netatmo presence check');
type: script.ScriptAction