Closed rkoshak closed 1 year ago
There are no breaking changes at least up through openhab-js 4.2.0 and in fact all the Timer classes depend on 4.2.0 for certain when
types. I still need to do the syntax update though so I'll keep this open for now.
I think something broke your dadMotionTimer example. timers.check dies for me. It seems like it tries to convert ZDT to ZDT.
2023-07-29 09:40:50.174 [ERROR] [b.automation.script.file.bathroom.js] - Failed to execute rule BathroomLightOff: Error: "2023-07-29T09:41:00.153Z[SYSTEM]" is an unsupported type for conversion to time.ZonedDateTime: Error: "2023-07-29T09:41:00.153Z[SYSTEM]" is an unsupported type for conversion to time.ZonedDateTime at toZDT (/node_modules/openhab.js:2) at check (/etc/openhab/automation/js/node_modules/openhab_rules_tools/timerMgr.js:46)
Which version of the openhab-js library are you using? toZDT
lives there now and there were some changes made so that it should support RFC type strings like that now. Recent versions have a utils.OPENHAB_JS_VERSION
that contains the library version.
As for "dadMotionTimer", are you referring to a specific tutorial or design pattern, or an example that comes from the Threshold Alert rule tempalte?
Which version of the openhab-js library are you using?
latest available via npm I think, variable says 4.5.0
As for "dadMotionTimer", are you referring to a specific tutorial or design pattern, or an example that comes from the Threshold Alert rule tempalte?
code copied from the discourse thread where the tools were presented.
code copied from the discourse thread where the tools were presented.
That's where I'm confused as there is no mention of "dadMotionTimer" at https://community.openhab.org/t/announcing-the-initial-release-of-openhab-rules-tools/132032
I don't know where else I've written that example by that name so 🤷 .
OK, thanks, that helps. That example is approaching two years old now. A lot has changed in both openhab-js and OHRT since then and I've moved pretty far beyond that implementation now. I forgot I even made that post. And those examples were never intended to remain working forever.
Error: "2023-07-29T09:41:00.153Z[SYSTEM]" is an unsupported type for conversion to time.ZonedDateTime: Error: "2023-07-29T09:41:00.153Z[SYSTEM]" is an unsupported type for conversion to time.ZonedDateTime
There was a bug in openhab-js which has since been fixed where time.toZDT()
was not correctly identifying DateTime Items. It has been fixed in the latest version of the library (a few version back at this point actually) and a simple work around is to pass the state of the Item instead of the Item itself.
These days I implement this using the Threshold Alert rule template: https://community.openhab.org/t/threshold-alert-and-open-reminder-4-0-0-0-4-9-9-9/144863 with the following config (the second or third post on that thread has a full explanation of this config):
configuration:
dndEnd: 08:00
rateLimit: ""
invert: false
initAlertRule: ""
dndStart: 22:00
alertRule: dad_motion_alerting
endAlertRule: dad_motion_alerting
thresholdState: ON
defaultRemPeriod: PT8H
operator: ==
hysteresis: ""
reschedule: true
namespace: thresholdAlert
gkDelay: 0
defaultAlertDelay: PT8H
group: MotionSensors
and the dad_motion_alerting
rule is
configuration: {}
triggers: []
conditions: []
actions:
- inputs: {}
id: "1"
configuration:
type: application/javascript;version=ECMAScript-2021
script: >-
if(isAlerting) console.log('It has been a long time since dad moved.');
else console.log('Motion detected at dad\'s house after alerting.');
type: script.ScriptAction
I'm just going to do a quick and dirty edit on that example here adopting it to changes made in the openhab-js library. But I'm just typing in the changes without testing. There almost certainly will be typos. But it should show what needs to change.
configuration: {}
triggers:
- id: "2"
configuration:
itemName: Dads_Motion_Timeout
type: core.ItemStateChangeTrigger
- id: "4"
configuration:
startlevel: 100
type: core.SystemStartlevelTrigger
- id: "1"
configuration:
itemName: MotionSensor_LastMotion
type: core.ItemStateChangeTrigger
conditions: []
actions:
- inputs: {}
id: "3"
configuration:
type: application/javascript;version=ECMAScript-2021
script: >
var {alerting} = require('personal');
var {timeUtils, TimerMgr} = require('openhab_rules_tools');
var formatDT = function(dt) {
// TODO revist after this gets fixed in the library I don't know if this ever got fixed
// See https://js-joda.github.io/js-joda/class/packages/core/src/ZonedDateTime.js~ZonedDateTime.html
// for details. I'm assuming this works but have never tested it
return time.DateTimeFormatter.ofPattern("h:mm a, ccc MMM dd").format(time.toZDT(dt)); // I've not tested the pattern
}
var dadTimerExpiredGenerator = function(){
return function() {
if(items.Dads_Motion_Alert.state == 'ON') {
alerting.sendInfo('It has been awhile since dad has moved. Last movement detected at '
+ formatDT(items.MotionSensor_LastMotion));
}
else {
console.info("Dad's motion timer went off but alerting is OFF");
}
}
}
// Initialize variables
var timers = cache.get(ruleUID+'_tm', () => TimerMgr());
var lastMotionItem = items.getItem('MotionSensor_LastMotion');
var timeout = items.getItem('Dads_Motion_Timeout');
var motionTime = (lastMotionItem.isUninitialized) ? time.toZDT() : time.toZDT(lastMotionItem.state);
var motionTime_Str = formatDT(motionTime);
var timerHours = 12;
// If it's not set move the timout to 12 hours
logger.debug('Timeout is {}', timeout.state);
if(timeout.isUninitialized) {
timeout.postUpdate('12');
}
else {
timerHours = timeout.state;
}
// Calculate the alert time, move it to tomorrow if it'll go off at night
var timerTime = motionTime.plusHours(timerHours);
var nightStart = time.toZDT('22:00');
var nightEnd = time.toZDT('09:00');
if(timerTime.isBetweenTimes(nightStart, nightEnd)) {
timerTime = nightEnd;
}
var timerTime_Str = formatDT(timerTime);
// If it's already been too much time, alert now
if(timerTime.isBefore(time.toZDT())) {
console.warn('timerTime is in the past! {}', timerTime_Str);
dadTimerExpiredGenerator()();
}
// Set or reschedule a timer to alert if there is no motion for too much time
else {
console.debug("Motion detected at Dad's at {} or reminder time has changed, setting reminder to expire at {}",
motionTime_Str, timerTime_Str);
timers.check('alertTimer', timerTime, dadTimerExpiredGenerator(), true);
}
type: script.ScriptAction
I've run with #107 for awhile and it all checks out. I'm closing this now.
I don't think there are any breaking changes but I only did a cursory look. This is to remind me to look more carefully.
I also need to update the syntax to take advantage of changes in the openhab-js library.
I do not intend this to apply to rule templates which I'm doing one by one independently from the library.
See https://github.com/rkoshak/openhab-rules-tools/pull/107 .