Event logs in UI & node status monitoring

I currently have an ESP8266 and have been playing around to see what I can do with it and Openhab. I have it updating temperature to Openhab with MQTT and can also control the LED from the UI, it’s been working great. I have a few questions though:

How to store and present item state log in user interface? For example, last 10 events for a switch or “last updated” for temp sensor? Should I somehow utilize events.log?

How to present any log in user interface?

What is the best way to track node status (online/offline) and present the information in UI? For example, show a list of offline nodes and/or mark offline items with red background/exclamation mark? Would it be a good idea to have all nodes update their own timestamp to Openhab and have a rule to check if anyone stops updating? Or should I ping them? Are there any best practices?

If it is numerical you can use a chart. Otherwise you will need to create 10 items and a rule to move the values down the list on a change. Keep in mind that a chart will be time based, not number of values based. You will need to set up persistence.

There is nothing built into OH to do this. I saw someone post about using some sort of third party tool to shoe the log through a webview.

Since you are using MQTT use the LWT feature and a switch to listen for that message. When it sees the LWT message turn the switch off. When you receive other messages from that device write a rule to turn the status switch back on. There are icons that will change to red when the switch turns off and green when on.

Thank you. I decided to battle the easier part first (node state & item last update):

Items

// Last Updates

DateTime lastupdate_temp "Temp updated [%1$td-%1$tm-%1$tY %1$tR]"
DateTime lastupdate_hum “Hum updated [%1$td-%1$tm-%1$tY %1$tR]”

// Node Monitors

String espmon “Online? [%s]” (Monitors) {mqtt="<[broker:/home/1/mon/state:state:default]"}

Rules

import org.openhab.core.library.types.*
import java.util.Date
import java.text.SimpleDateFormat

var SimpleDateFormat df = new SimpleDateFormat( “dd-MM-YYYY HH:mm” )

rule "ESP-monitor_offline"
when
Item espmon changed to OFFLINE
then
var String Timestamp = df.format( new Date() )
postUpdate(espmon, "DOWN: "+Timestamp)
end

rule "ESP-monitor_online"
when
Item espmon changed to ONLINE
then
var String Timestamp = df.format( new Date() )
postUpdate(espmon, "UP: "+Timestamp)

rule "temp_updated"
when
Item temp received update
then
postUpdate(lastupdate_temp, new DateTimeType())
end

rule "hum_updated"
when
Item humidity received update
then
postUpdate(lastupdate_hum, new DateTimeType())
end

Sitemap

Text item=temp valuecolor=[lastupdate_temp >60=“red”] {
Text item=lastupdate_temp }
Text item=humidity valuecolor=[lastupdate_temp >60=“red”] {
Text item=lastupdate_hum }
Text item=espmon

So now I have “last updated” for temp and humidity and the value colors change to red if no update have been received in one minute. I also have “will” set up for the ESP which will trigger the “ESP-monitor_offline” rule when it goes offline. These are working great. The only thing I’d still like to change is the rule “ESP-monitor_online”. If Openhab restarts (or items file updates) the item values are reset and I will lose the “Online” message until the ESP is restarted. The ESP sends the “ONLINE” message only once when it reboots - I could send it every time the temp/hum values are sent, but wouldn’t this be wasteful since I can figure the same thing out with a rule? So the problem:
I want to base the ONLINE status to receiving temp/hum updates like you suggested. To prevent it turning into “last updated” timestamp, I’d have to determine if the state is already “UP: xxxxxx”. So something like

rule "ESP-monitor_online"
when
Item temp received update
then
if(espmon.state!=“UP:*”) {
var String Timestamp = df.format( new Date() )
postUpdate(espmon, "UP: "+Timestamp)
}

But that asterisk of course won’t work and I can’t make it work… Any idea of the syntax here?

This looks overly complex to me. Why not just add

espmon.postUpdate("UP: " + Timestamp)

to your “temp_updated” and “hum_updated” and sidestep the new rule entirely?

Furthermore, why not just use a Switch to represent its online status? You are already capturing the timesamps in other items so trying to maintain a “UP: xxxxx” type String seems like a lot of extra work for no benefit. Furthermore, if you use persistence you can get the timestamp of the last update with a simple espmon.lastUpdate and it will already be a Joda DateTime so you wouldn’t need to parse it.

All that being said, to answer your actual question:

if(!espmon.state.toString.startsWith("UP:")) {

Some notes:

  • You are missing a closing end on your ESP-monitor_online rule.
  • You are also missing the end on the “ESP-monitor_online” rule
  • To do a comparison use ==. = is an assignment
  • The .state method returns an Object of type State. When you want to deal with the state as a String you need to call .toString. If it is a Number you need to case it to DecimalType in order to do math with the state.

It’s complex because I’m a noob and this was the first way that worked :slight_smile:

The rule ESP-monitor_online was there just as a placeholder until I could learn how to do the “startsWith” syntax (the ESP sent the ONLINE string only once when it booted - if I had it update with temp, it would have worked as a “last update” field). I shouldn’t have made the last code example like that. I have now ditched it and have it like this:

    rule "temp_updated"
    when
        Item temp received update 
    then
        postUpdate(lastupdate_temp, new DateTimeType())
        if(!espmon.state.toString.startsWith("UP")) {
            var SimpleDateFormat df = new SimpleDateFormat( "dd-MM-YYYY HH:mm" )
            var String Timestamp = df.format( new Date() )
            postUpdate(espmon, "UP: "+Timestamp)
            }
    end

About using switch and not using a string: how would the switch work in showing the status & timestamp, aren’t they meant for switching lights and so on? :hushed: If I don’t use a String, how can I get the Up or Down text to show appropriately? Remember I only want the “online status” timestamp to update once when the node goes online/offline.

I’m not yet that familiar with the different persistence options, so your advice about that unfortunately goes a bit over my head at the moment. I will of course keep optimizing stuff as I learn more.

Thank you for all the advice this far.

A switch has two states and therefore can be treated as a boolean. An ON switch can indicate your device is UP and an OFF switch can indicate your device is DOWN. If a Switch isn’t your speed you can also use a Contact which also only has two states. However, most of the status icons expect to be used with a Switch. For example, if you use the “network” icon with a Switch that indicates the online status of a device, it will be red when the device is down and green when it is online.

Now, if you want the timestamp you can use the same approach you use for your temp and humidity. But that begs the question of why? Is it just to see a date/time string on your sitemap? Perhaps I’m biased but frankly I find it much more useful to have state stored in a format that is easy to use (e.g. Switch for booleans and DateTime for timestamps) than it is to store it in a String I have to parse (even minimally). And since I only use the sitemap for debugging I pretty much only care whether the remote device is online or not and couldn’t care a bit as to when it came online. If I want to find out when I can check the openhab.log or events.log. The time isn’t useful in any rules nor does it change my approach.

So I would still probably recommend storing the timestamp in a DateTime Item, the Up/Down status in a Switch Item and if you want to see them both on one line in your sitemap (i.e. see the right icon next to the DateTime string) there are ways to do that using the visibility flag.

I have all the devices logged with logging.persist. I then use an AutoIt script to check the file last modification time of each log hourly and if any are old, stop and restart openHAB.