How to monitor if item is frequently updated

I have several items that are updated via RestApi (from a HomeAssistant system)

What would be an good approach to monitor if the items are updated frequently?

Persistence method countChangesSince

Or write a rule that increases a counter.

Are you really after being notified if the Item is updated too frequently, or are you more interested in the Item that normally updates frequently stops updating?

If the latter I use Threshold Alert and Open Reminder [4.0.0.0;4.9.9.9].

I am also interested in such a rule …to check if the item stops updating

This is my solution

rules.JSRule({
  name: "Check Item Update with Persistence",
  description: "ĂśberprĂĽft alle 5 Minuten, ob ein Item aktualisiert wurde",
  triggers: [
    triggers.GenericCronTrigger("0 0/5 * * * ?")
  ],
  execute: function (event) {
    var itemName = "DeinItemName";  // Das zu ĂĽberwachende Item

    // Den letzten Aktualisierungszeitpunkt des Items abrufen
    var lastUpdate = time.ZonedDateTime.now().minusMinutes(5);
    var lastUpdateTime = items.getItem(itemName).persistence.lastUpdate();

    if (lastUpdateTime !== null) {

      if (lastUpdateTime.isBefore(lastUpdate)) {
        // Aktion ausfĂĽhren, wenn das Item nicht in den letzten 5 Minuten aktualisiert wurde
        console.log(itemName + " wurde seit mehr als 5 Minuten nicht aktualisiert!");
        // Hier kannst du weitere Aktionen einfĂĽgen, z.B. eine Benachrichtigung senden
      } else {
        console.log(itemName + " wurde innerhalb der letzten 5 Minuten aktualisiert.");
      }
    } else {
      console.log("Keine historischen Daten fĂĽr " + itemName + " verfĂĽgbar.");
    }
  }
});

Is there a better one?

That’s my solution also.

requirements

  • items get updated via REST/MQTT/… at least every x minutes
  • it’s known, that the item gets at least a new persistence timestamp

so my script does like yours

  • checking every x minutes on crucial items (not all, e.g. only one item out of the bunch of 60 items getting updated from one device)
  • alerting, if that’s not the case
  • bonus: the script can try to e.g. restart something, if there are known issues with the external source

what’s different in my script:

  1. I do a console.warn, if there’s no update for x minutes and a console.error if it’s 2times x minutes.
  2. I do a sendNotification in parallel to inform me via openHAB App
  3. and I do a sendMail also, in case openHAB Cloud is offline :wink:

Add `getLastChange`, `getLastUpdate`, and `getPreviousState` to GenericItem by jimtng · Pull Request #4351 · openhab/openhab-core · GitHub would help you to solve this use case without the need for persistence, so stay tuned — I hope this PR is merged for openHAB 4.3.

3 Likes

Hello @binderth ,

Can you post your rule?

sure, it’s a JS-Scripting rule:

/*
Checks on Updates of itemns
if there's no Update for 5min => logfile and message
if there's still no Update for 15 min => some Service could be restarted
*/

var interval5min  = time.ZonedDateTime.now().minusMinutes(5);
var interval15min  = time.ZonedDateTime.now().minusMinutes(15);
var ServiceOffline = false;
var ServiceRestart = false;
var letztesUpdate = time.ZonedDateTime.now().minusDays(1);
var cliCommand = "yourCommandOrScript";
var cliParam1 = "firstParameter";
var cliParam2 = "secondParameter";
var cliParam3 = "thirdParameter";


function lastUpdateHappened(itemName) {
  lastUpdate = items.getItem(itemName).persistence.lastUpdate('jdbc');
  console.debug("DEBUG CheckItem: last Update (" + itemName + "): " + lastUpdate);

  if (lastUpdate.isBeforeDateTime(interval5min)) {
    ServiceOffline = true;
    return false;
    console.warn("WARNCheck: Last Update FAILED for: " + itemName + " at " + letztesUpdate);
  } else {
    console.debug("INFO Check: Last Update PASSED for: " + itemName + " at " + letztesUpdate);
    return true;
  }
  if (lastUpdate.isBeforeDateTime(interval15min)) {
    ServiceRestart = true;
    console.error("ERROR ItemCheck: RESTART of Service, because Last Update longer as 15min FAILED for: " + itemName);
  }
}

lastUpdateHappened("YourFirstItemToCheck");
lastUpdateHappened("YourSecondItemToCheck");
lastUpdateHappened("YourThirdItemToCheck");
... 

if (ServiceOffline == true) {
  console.warn("WARN ItemCheck: Service is offline");
  actions.NotificationAction.sendNotification("Your@email.de", "Service apparently offline - please check!");
}

if (ServiceRestart == true) {
  console.info("INFO Check: RESTART of Service now!");
  exec = actions.Exec.executeCommandLine(time.Duration.ofSeconds(25), cliCommand, cliParam1, cliParam2, cliParam3);
  console.info("INFO Check: RESTART of Service finished! Response: ", exec);
}

In my script, there’s no differentiation of “offline-Services” as presently I’m just testing for updates from one service (my external mqtt-server). I had some issues, and a restart of the mqtt-server solved it. Since the last update, mosquitto-mqtt works without issues now. :wink: (but I’ll let the rule still run every 5 mins. You could incorporate e.g. restarts of a binding with it, or whatever you like - or even just a log-entry and perhaps a notification…

edit:
of course Rich will say the above time calculations can be shortened to

  • time.toZDT('PT-5m'); // and every other minute :wink:

and this is correct! :wink:

1 Like

I wasn’t going to but glad you mentioned it.

1 Like

just to make sure, that I understand this correctly.

items.getItem(itemName).persistence.lastUpdate()

will return the timestamp of the last update to the persistence database, it is not the last update of the item itself.
So my persistence definition is crucial, when my persistence definition is “every minute”, lastUpdate would never return a value older than 59 seconds, right?

This is what @florian-h05 mentioned above.

You should therefore better use .changedSince()

Not exactly, what I mentioned above is a enhancement that would allow the same functionality as persistence .changedSince(), but without the need for persistence.

correct