I try to write a rule that checks if all sensors are sending updates.
Therefore I need to calculate the delta between the current DateTime and the last update of the sensor.
This is what I have so far:
var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID);
var NotificationAction = org.openhab.io.openhabcloud.NotificationAction;
var ZonedDateTime = Java.type("java.time.ZonedDateTime");
var currentDateTime = ZonedDateTime.now();
//get the required item states
var lightSensorEastLastUpdated = itemRegistry.getItem('LichtsensorOsten_LastUpdated').getState();
var lightSensorSouthLastUpdated = itemRegistry.getItem('LichtsensorSuden_LastUpdated').getState();
var lightSensorWestLastUpdated = itemRegistry.getItem('LichtsensorWesten_LastUpdated').getState();
logger.info("currentDateTime: " + currentDateTime);
logger.info("lightSensorEastLastUpdated: " + lightSensorEastLastUpdated);
logger.info("lightSensorSouthLastUpdated: " + lightSensorSouthLastUpdated);
logger.info("lightSensorWestLastUpdated: " + lightSensorWestLastUpdated);
logger.info(typeof currentDateTime);
logger.info(typeof lightSensorWestLastUpdated);
//this does not work :(
//var deltaTimeLightSensorWestLastUpdated = currentDateTime - lightSensorWestLastUpdated;
//logger.info("deltaTimeLightSensorWestLastUpdated: " + deltaTimeLightSensorWestLastUpdated);
I tried to subtract the LastUpdate-DateTime object from the Current-DateTime object. But the result is âNaNâ
//this does not work :(
var deltaTimeLightSensorWestLastUpdated = currentDateTime - lightSensorWestLastUpdated;
logger.info("deltaTimeLightSensorWestLastUpdated: " + deltaTimeLightSensorWestLastUpdated);
You are working with JavaScript Objects though. currentDateTime is a java.time.ZonedDateTime and lightSensorWestLastUpdated is an org.openhab.core.library.types.DateTimeType.
Pretty much everything you are working with in openHAB rules, no matter the scripting language, is working with Java Objects, not native to the scripting language Objects.
Well, as I said, the Itemâs state isnât a ZonedDateTime, itâs a DateTimeType. But as I showed above, there is a getZonedDateTime() method you can call to get one which you can use in comparisons and such with currentZonedDateTime etc.
As I indicated above, I think your original question is an XY Problem. You donât need to calculate the difference between two date times, you just need to compare two date times to see if the Itemâs state is before a certain amount of time in the past.
But there can be cases where it is necessary to calculate the difference between two date times and for that youâd use Duration (Java SE 11 & JDK 11 ).
sorry to hijack this thread but I have âexactlyâ the same issue and not able to figure it out.
I am in process of moving from 2.x to 3.
I just copied my old rules (text files) into OH3. I try to update them rather than rewriting everything. Changing the items and things already took days.
Anyhow, this is what I have:
rule one, which updates with a new timestamp every time the sensor is updated:
rule "Wetterstation2"
when
Item roofTemp01 changed
then
postUpdate(Temp_Roof_LastUpdate, new DateTimeType())
end
second rule which shall compare if it was updated within last 15 minutes.
According to @rlkoshak this should work:
var currentDateTime = LocalDateTime.now();
if(Temp_Roof_LastUpdate.getZonedDateTime().isBefore(currentDateTime.minusMinutes(15))){
//do something
}
But it is not. getting this
failed: 'getZonedDateTime' is not a member of 'org.openhab.core.library.items.DateTimeItem'
any idea? It shouldnât be so complicated to do a simple comparison.
Notice the .state. As has always been the case, to access the state of an Item one must call .state. In Python and JavaScript there is a dict that has all the states of Items using the Item name as the key.
I donât think thatâs the case. By default MyItem.state returns an Object of type State. Thatâs why we need to cast it so often when we want to do stuff with the state. org.openhab.core.types.State doesnât define a method called getZonedDateTime which, of course it doesnât. Thatâs specific to DateTimeType which is itself of type State.
This is one area where JavaScript and Jython do a little better than Rules DSL. In both of these languages they are much better able to look down, not just up. For example, given a hierarchy like:
Object
\_State
\_DateTimeType
Rules DSL will see the State and only look up to see that itâs also an Object. But it wonât look down to see DateTimeType and see that it does in fact implement getZonedDateTime(). Itâs one of my many growing frustrations with rules coding in general and one of the things that has held me back from completing the Getting Started Tutorial. Itâs like the English language; for every rule of thumb youâll find a dozen exceptions. I canât come up with a âHereâs how to write rules regardless of the languageâ followed by âand here is whatâs specific to JavaScript.â
I did not have to calculate the delta. As @rlkoshak suggested, I use the âisBefore()â function.
My rule now looks like this:
var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID);
var NotificationAction = org.openhab.io.openhabcloud.NotificationAction;
var ZonedDateTime = Java.type("java.time.ZonedDateTime");
var currentZonedDateTime = ZonedDateTime.now();
//get the required item states
var lightSensorEastLastUpdated = itemRegistry.getItem('LichtsensorOsten_LastUpdated').getState();
var lightSensorSouthLastUpdated = itemRegistry.getItem('LichtsensorSuden_LastUpdated').getState();
var lightSensorWestLastUpdated = itemRegistry.getItem('LichtsensorWesten_LastUpdated').getState();
var waterLeakageSensorHeatingLastUpdated = itemRegistry.getItem('WassersensorHeizung_LastUpdated').getState();
var waterLeakageSensorWashingMachineLastUpdated = itemRegistry.getItem('WassersensorWaschmaschine_LastUpdated').getState();
if(lightSensorEastLastUpdated.getZonedDateTime().isBefore(currentZonedDateTime.minusDays(1)))
{
var message = "Lichtsensor Osten sendet keine Updates mehr!";
logger.warn(message);
NotificationAction.sendBroadcastNotification(message);
}
if(lightSensorSouthLastUpdated.getZonedDateTime().isBefore(currentZonedDateTime.minusDays(1)))
{
var message = "Lichtsensor SĂŒden sendet keine Updates mehr!";
logger.warn(message);
NotificationAction.sendBroadcastNotification(message);
}
if(lightSensorWestLastUpdated.getZonedDateTime().isBefore(currentZonedDateTime.minusDays(1)))
{
var message = "Lichtsensor Westen sendet keine Updates mehr!";
logger.warn(message);
NotificationAction.sendBroadcastNotification(message);
}
if(waterLeakageSensorHeatingLastUpdated.getZonedDateTime().isBefore(currentZonedDateTime.minusDays(1)))
{
var message = "Wassersensor Heizung sendet keine Updates mehr!";
logger.warn(message);
NotificationAction.sendBroadcastNotification(message);
}
if(waterLeakageSensorWashingMachineLastUpdated.getZonedDateTime().isBefore(currentZonedDateTime.minusDays(1)))
{
var message = "Wassersensor Waschmaschine sendet keine Updates mehr!";
logger.warn(message);
NotificationAction.sendBroadcastNotification(message);
}