NGR Heartbeat / Update Solution (Python and Openhab Helper Library)


i have a little Scriptrow, how to fill a Heartbeat item, with using openhab Helper Library.

First, i have some items connect to mqtt, the send no “lastupdate”, only on diffrent times a status.
To fill this status to some item i use this solution.

Every item, with send a status become a group. I use gSendHeartbeat

String EG_Hallway_Smoke_State "Rauchmelder Flur" <fire> (gSmoke, EG_Hallway, gSendHeartbeat){channel="mqtt:topic:bhome:zigbee_Rauchmelder_Flur:smoke"}
Number EG_Hallway_Smoke_Batterie "Rauchmelder Flur Batterie [%.1f %%]" <batterylevel> (gBatterylevel, EG_Hallway, GZigbee, gSendHeartbeat) {channel="mqtt:topic:bhome:zigbee_Rauchmelder_Flur:battery"}
Number EG_Hallway_Smoke_LinkQuality "Rauchmelder Flur Link Quality [%d]" <qualityofservice> (EG_Hallway, gLinkQuality, GZigbee, gSendHeartbeat) {channel="mqtt:topic:bhome:zigbee_Rauchmelder_Flur:linkquality"}

Then we need the Heartbeat Item. In context the name is important, because all items for one thing have the same begin (e.g. EG_Hallway_Smoke_). The group gHeartbeat i use for the Sitemap.

DateTime EG_Hallway_Smoke_Heartbeat "Rauchmelder Flur letzte Meldung [%1$td.%1$tm.%1$ty %1$tH:%1$tM]" <time> (EG_Hallway, gZigbee, gHeartbeat)

OK, then we need the python code:

from core.rules import rule
from core.triggers import when
from import ZonedDateTime, format_date

@rule("Process Heartbeat", description="Setzt eine Heartbeatzeit auf nicht zyklische Zigbeegeräte", tags=["admin"])
@when("Member of gSendHeartbeat received update")
def SendHeartbeat(event):
    events.sendCommand((str(event.itemName)[0:event.itemName.rfind("_")])+"_Heartbeat", format(format_date(

I think, very small solution for all the Things.

The same code for State Items, with no LastUpdated (in my Homeautomation Homemation, HUE have a LastUpdate Item). The different is the trigger (change status, not received update) and a differen group.


Contact FF_Bedroom_Door_State "Balkontür Schlafzimmer  [MAP(]" <door> (FF_Bedroom, gContact, gUpdated, gSendHeartbeat) ["Türkontakt"] {channel="homematic:HM-Sec-SCo:xxxx:MEQxxxxxxxxx:1#STATE"}
DateTime FF_Bedroom_Door_Heartbeat "Tür Schlafzimmer Letzte Meldung [%1$td.%1$tm.%1$ty %1$tH:%1$tM]" <time> (EG_Bedroom, gHeartbeat)
DateTime FF_Bedroom_Door_LastUpdated "Tür Schlafzimmer Letzte Aktualisierung [%1$td.%1$tm.%1$ty %1$tH:%1$tM]" <time> (EG_Bedroom, gLastUpdated) 

Python Code:

@rule("Process Contact Update", description="Aenderung bei Kontaktschaltern", tags=["admin"])
@when("Member of gUpdated changed")
def LastUpdate(event):
events.sendCommand(str(event.itemName)[0:event.itemName.rfind("_")])+"_LastUpdated", format(format_date(

Thats all

Don’t do that… it’s actually not possible in the latest version of Instead, import ZonedDateTime using…

from java.time import ZonedDateTime

BUT wait… you don’t need this.

Without any imports, you can get the current time using…


But wait… you don’t need ANY of this if you use the timestamp-update profile…

DateTime EG_Hallway_Smoke_Heartbeat "Rauchmelder Flur letzte Meldung [%1$td.%1$tm.%1$ty %1$tH:%1$tM]" <time> (EG_Hallway, gZigbee, gHeartbeat) {channel="mqtt:topic:bhome:zigbee_Rauchmelder_Flur:smoke" [profile="timestamp-update"], channel="mqtt:topic:bhome:zigbee_Rauchmelder_Flur:battery" [profile="timestamp-update"], channel="mqtt:topic:bhome:zigbee_Rauchmelder_Flur:linkquality" [profile="timestamp-update"]}

Hey 5iver,

im a donkey. It is really so simpel?

Thanks for the nice solution!!!

1 Like

It’s that simple - so long as you only need to know any update/change.

Sometime’s you’ll want 'if" and 'but only" conditions, and then the longhand rule will be needed. Example, “only timestamp openings, not closings”


by restart the System, is the change from UNDEF a timestamp-change. Thats right, but i want to see ON/OFF or Motion changes.

But i like the simpel way with the update timestamp as heartbeat.