JSON History Logbook – list card for Item state histories

This widget displays a history of state changes stored as a JSON array in a String Item. It is designed as the companion widget for the rule template Logbook: Save Item State as a JSON History [5.2.1;5.9.9.9], but works with any String Item that contains a JSON array in this format:

[
  {"time":"2026-09-27T14:32:10.512+0200","event":"Derating Running"},
  {"time":"2026-09-27T09:05:43.120+0200","event":"Running"}
]

Each entry is shown as a list item:

  • Title: relative time (e.g. “5 minutes ago”)
  • Subtitle: absolute timestamp (DD.MM.YYYY HH:mm:ss)
  • Right side: the recorded state

Features

  • Works with any history Item, configured through widget parameters
  • Configurable maximum number of displayed entries
  • Handles NULL, UNDEF and invalid content without errors and shows “Keine Einträge vorhanden” (no entries) instead
  • Item picker only offers String Items

Parameters

Parameter Description Default
History Item String Item containing the JSON history (required)
Title Title of the card Logbook
Max Entries Number of entries to display 10

Usage

  1. Set up the rule template for the Item you want to track (or fill a String Item with a JSON array yourself).

  2. Add the widget to a page and select the history Item.

    - component: widget:Widget_JSON_History_Logbook
      config:
        item: MyDevice_State_History
        title: Hot Water Status Logbook
        maxEntries: 10
    

Changelog

Version 0.1

  • initial release

Resources

uid: Widget_JSON_History_Logbook
tags:

* Logbook
* JSON
  props:
  parameterGroups: [ ]
  parameters:
  * context: item
    description: String Item containing the JSON history (from the rule template)
    filterCriteria:
    * name: type
      value: String
      label: History Item
      name: item
      required: true
      type: TEXT
  * default: Logbook
    label: Title
    name: title
    required: false
    type: TEXT
  * default: "10"
    description: Number of entries to display
    label: Max Entries
    name: maxEntries
    required: false
    type: INTEGER
    component: oh-list-card
    config:
    mediaList: true
    title: =props.title || 'Logbook'
    slots:
    default:
  * component: oh-repeater
    config:
    filter: loop.event_idx < (Number(props.maxEntries) || 10)
    for: event
    in: "=(items\[props.item\].state && items\[props.item\].state.startsWith('\[')) ? JSON.parse(items\[props.item\].state) : [ ]"
    sourceType: array
    slots:
    default:
    - component: oh-list-item
    config:
    after: =loop.event.event
    subtitle: =dayjs(loop.event.time).format('DD.MM.YYYY HH:mm:ss')
    title: =dayjs(loop.event.time).fromNow()
  * component: oh-list-item
    config:
    title: No entries
    visible: "=!(items\[props.item\].state && items\[props.item\].state.startsWith('\[') && items\[props.item\].state.length > 2)"
2 Likes