diff --git a/rule-templates/thresholdAlert/newThresholdAlert.yaml b/rule-templates/thresholdAlert/newThresholdAlert.yaml index 5037735..de75c6e 100644 --- a/rule-templates/thresholdAlert/newThresholdAlert.yaml +++ b/rule-templates/thresholdAlert/newThresholdAlert.yaml @@ -41,6 +41,12 @@ configDescriptions: type: BOOLEAN defaultValue: false required: false + - name: reschedule + label: Reschedule + description: If an alert timer already exists from a previous run of the rule, when true reschedule it. Otherwise the alert is ignored and the alert rule is called based on the previous event. + type: BOOLEAN + defaultValue: false + required: false - name: hysteresis label: Hysteresis description: Optional value above/below the threshold the state must achieve before it is considered to nolonger alerting. @@ -165,6 +171,7 @@ actions: var rateLimitPeriod = '{{rateLimit}}'; + var reschedule = '{{reschedule}}'; // ~~~~~~~~~~~Functions @@ -238,7 +245,10 @@ actions: * @return {time.ZonedDateTime} adjusted time to send the alert */ var generateAlertTime = (timeout, dndStart, dndEnd) => { - if(!timeout) return null; + if(!validateDuration(timeout)) { + console.debug('Timeout ' + timeout + ' is not valid, using timeout of now'); + timeout = 'PT0S'; + } let rval = time.toZDT(timeout); let start = time.toZDT(dndStart); @@ -247,6 +257,7 @@ actions: console.debug('Alert is scheduled during do not distrub time, moving to ' + dndEnd); rval = dndEnd; if(time.toZDT(rval).isBefore(time.toZDT())) { + console.debug('Moving alert time to tomorrow'); rval = timeUtils.toTomorrow(dndEnd); } } @@ -357,13 +368,18 @@ actions: // Set a timer for how long the Item needs to be in the alerting state before alerting. // If one is already set, ignore it + let timeout = generateAlertTime(record.alertDelay, record.dndStart, record.dndEnd); + if(timeout === null) timeout = 'PT0S'; // run now + if(record.alertTimer === null) { - let timeout = generateAlertTime(record.alertDealy, record.dndStart, record.dndEnd); - if(timeout === null) timeout = 'PT0S'; // run now console.debug('Creating looping alert timer for ' + record.name + ' at ' + timeout); record.alertTimer = new loopingTimer.LoopingTimer(); record.alertTimer.loop(sendAlertGenerator(record), timeout); } + else if(record.alertTimer !== null && record.reschedule) { + console.debug('Rescheduling the timer'); + record.alertTimer.timer.reschedule(time.toZDT(timeout)); + } else { console.debug(record.name + ' already has an alert timer, ignoring event.'); } @@ -567,7 +583,8 @@ actions: if(md['threshold'] !== undefined) record.threshold = stateToValue(md['threshold']); if(md['thresholdItem'] !== undefined) record.threshold = stateToValue(items[md['thresholdItem']].rawState); record.operator = (md['operator'] !== undefined) ? md['operator'] : operator; - record.invert = (md['invert'] !== undefined) ? (md['invert'].toString().toLowerCase() == 'true') ? true : false : invert; + record.invert = (md['invert'] !== undefined) ? md['invert'] === true : invert; + record.reschedule = (md['reschedule'] !== undefined) ? md['reschedule'] === true : reschedule; record.compare = generateComparison(record.operator); record.alertDelay = (md['alertDelay'] !== undefined) ? md['alertDelay'] : defaultAlertDelay; record.remPeriod = (md['remPeriod'] !== undefined) ? md['remPeriod'] : defaultRemPeriod; @@ -582,6 +599,7 @@ actions: + ' Threshold - ' + record.threshold + '\n' + ' Operator - ' + record.operator + '\n' + ' Invert - ' + record.invert + '\n' + + ' Reschedule - ' + record.reschedule + '\n' + ' Alert Delay - ' + record.alertDelay + '\n' + ' Reminder Period - ' + record.remPeriod + '\n' + ' Alert Rule ID - ' + record.alertRule + '\n' @@ -690,6 +708,7 @@ actions: + ' Threhsold - ' + thresholdStr + '\n' + ' Operator - ' + operator + '\n' + ' Invert Operator - ' + invert + '\n' + + ' Reschedule - ' + reschedule + '\n' + ' Default Alert Delay - ' + defaultAlertDelay + '\n' + ' Default Reminder Duration - ' + defaultRemPeriod + '\n' + ' DND Start - ' + dndStart + '\n' @@ -877,6 +896,10 @@ actions: error = true; console.error('Item ' + item.name + ' has an unparsible invert ' + md['invert'] + ' in ' + namespace + ' metadata'); } + if(md['reschedule'] !== undefined && (md['reschedule'] !== true && md['reschedule'] !== false)) { + error = true; + console.error('Item ' + item.name + ' has an unparsible reschedule ' + md['reschedule'] + ' in ' + namespace + ' metadata'); + } if(md['alertDelay'] !== undefined && !validateDuration(md['alertDelay'])) { error = true; console.error('Item ' + item.name + ' has an unparsable alertDelay ' + md['alertDelay'] + ' in ' + namespace + ' metadata');