Seite 1 von 1

oh-repeater nach Item-State sortieren

Verfasst: 14. Apr 2026 14:48
von lenschith
Hallo zusammen,

ich zeige in einem Custom Widget eine Liste von Tankstellen über oh-repeater (itemsInGroup):

Code: Alles auswählen

- component: oh-repeater
  config:
    for: station
    sourceType: itemsInGroup
    groupItem: =props.group
Anzeige funktioniert (Label, Preis, Status), aber ich bekomme keine Sortierung nach Preis hin (aufsteigend).

Versucht habe ich schon einiges, aber ohne Erfolg.

Ist eine Sortierung im oh-repeater überhaupt möglich?

Hier mein Widget:

Code: Alles auswählen

uid: tankstelle_uebersicht
tags: []
props:
  parameters:
    - context: item
      description: Die Gruppe der Treibstoffpreise (z.B. Treibstoffpreise)
      label: Gruppe
      name: group
      required: true
      type: TEXT
  parameterGroups: []
timestamp: Apr 14, 2026, 12:11:12 PM
component: oh-list-card
config:
  title: Tankstellenübersicht
slots:
  default:
    - component: oh-repeater
      config:
        for: bestItem
        sourceType: itemsInGroup
        groupItem: =props.group
        filter: "(loop.bestItem.state === items[props.group].state) ? true : false"
      slots:
        default:
          - component: oh-label-item
            config:
              icon: f7:money_euro
              iconColor: green
              title: =loop.bestItem.label
              after: =(loop.bestItem.displayState || loop.bestItem.state).replace("EUR", "€")
              badge: '=(items[loop.bestItem.name.replace("_Diesel",
                "_GeoffnetGeschlossen")].state === "OPEN" ||
                items[loop.bestItem.name.replace("_Diesel",
                "_GeoffnetGeschlossen")].state === "ON") ? "OFFEN" : "ZU"'
              badgeColor: '=(items[loop.bestItem.name.replace("_Diesel",
                "_GeoffnetGeschlossen")].state === "OPEN" ||
                items[loop.bestItem.name.replace("_Diesel",
                "_GeoffnetGeschlossen")].state === "ON") ? "green" : "red"'
              footer: Günstigster Preis
              style:
                --f7-list-item-title-text-color: green
                --f7-list-item-after-font-weight: bold
    - component: div
      config:
        style:
          height: 2px
          background-color: lightgrey
          margin: 10px
          border-radius: 5px
    - component: oh-repeater
      config:
        for: station
        sourceType: itemsInGroup
        groupItem: =props.group
      slots:
        default:
          - component: oh-label-item
            config:
              icon: oh:gasoline
              title: =loop.station.label
              subtitle: Diesel
              after: =(loop.station.displayState || loop.station.state).replace("EUR", "€")
              badge: '=(items[loop.station.name.replace("_Diesel",
                "_GeoffnetGeschlossen")].state === "OPEN" ||
                items[loop.station.name.replace("_Diesel",
                "_GeoffnetGeschlossen")].state === "ON") ? "OFFEN" : "ZU"'
              badgeColor: '=(items[loop.station.name.replace("_Diesel",
                "_GeoffnetGeschlossen")].state === "OPEN" ||
                items[loop.station.name.replace("_Diesel",
                "_GeoffnetGeschlossen")].state === "ON") ? "green" : "red"'
Danke.
Gruß Lenschi

Re: oh-repeater nach Item-State sortieren

Verfasst: 14. Apr 2026 16:31
von Harka
Moin,
Warnung: ich habe mit oh-repeater & Co. noch nichts gebastelt.
Was ich probieren würde wäre ein Lösungsansatz mit map nach diesem Beitrag https://community.openhab.org/t/sorted- ... get/164995

Re: oh-repeater nach Item-State sortieren

Verfasst: 14. Apr 2026 19:44
von lenschith
@Harka das mit Map hatte ich schon versucht aber bisher bin ich leider nicht weiter gekommen. :(

Re: oh-repeater nach Item-State sortieren

Verfasst: 14. Apr 2026 21:22
von peter-pan
Leider kann ich dein Problem nicht lösen, da ich deine Items nicht zum Testen habe. Aber stelle dein Problem doch einfach mal im englischen Forum vor.
Ich denke, dass "JustinG" dir sicherlich weiterhelfen kann.
Bei mir hat es geklappt und er hat mir die Lösung mit dem "Map" vorgeschlagen:
sort.jpg

Re: oh-repeater nach Item-State sortieren

Verfasst: 15. Apr 2026 12:04
von nw378
Anderer Lösungsansatz, so sortiere ich meine Spritpreise.

Die Items am Binding sind so konfiguriert:

Code: Alles auswählen

Number:Currency Q1_Istrup_Diesel "Q1 Istrup" (gDiesel) [Point] { stateDescription=" " [pattern="%.3f €"], unit="DEF" }
zusätzlich:

.items

Code: Alles auswählen

Group gDiesel
Group gE10
Group gDiesel_sorted
Group gE5_sorted
Group TankeOpenUnsorted
Group gDieselOpen
Group gE5Open
Group gE5

Number:Currency Diesel_0 (gDiesel_sorted)
Number:Currency Diesel_1 (gDiesel_sorted)
Number:Currency Diesel_2 (gDiesel_sorted)
Number:Currency Diesel_3 (gDiesel_sorted)
Number:Currency Diesel_4 (gDiesel_sorted)
Number:Currency Diesel_5 (gDiesel_sorted)

Contact Diesel_0_open (gDieselOpen)
Contact Diesel_1_open (gDieselOpen)
Contact Diesel_2_open (gDieselOpen)
Contact Diesel_3_open (gDieselOpen)
Contact Diesel_4_open (gDieselOpen)
Contact Diesel_5_open (gDieselOpen)
.rules

Code: Alles auswählen

import org.openhab.core.model.script.ScriptServiceUtil    

rule "Tankerkönig: Kraftstoffpreise sortieren"
when
    Time cron "10 * * * * ?"    
then
    val kraftstoffe = newArrayList("Diesel", "E5")

    kraftstoffe.forEach[prefix |
        val gPreis = ScriptServiceUtil.getItemRegistry.getItem("g" + prefix) as GroupItem
        val gOpen  = ScriptServiceUtil.getItemRegistry.getItem("g" + prefix + "Open") as GroupItem

        // Preis-Items sortieren
        val gSortiert = gPreis.members
            .filter[i | i.state instanceof Number && i.state != NULL]
            .sortBy[i | (i.state as Number).floatValue]

        gSortiert.forEach[item, index |
            val itemParts = item.name.split("_")
            if (itemParts.size < 2) return;

            val tanke = itemParts.get(0)
            val ort   = itemParts.get(1)
            val preis = (item.state as Number).floatValue
            val label = tanke + " " + ort + "[%.3f €]"

            // Sortiertes Preis-Item (z. B. Diesel_0, E5_1)
            val sortedItemName = prefix + "_" + index
            val sortedItem = ScriptServiceUtil.getItemRegistry
                .getItem(sortedItemName) as GenericItem
            if (sortedItem.label != label) sortedItem.setLabel(label)
            sortedItem.postUpdate(preis)

            // Open-Status (z. B. Diesel_0_open, E5_1_open)
            val openName  = tanke + "_" + ort + "_Geoffnet"
            val openSrc   = TankeOpenUnsorted.members
                .findFirst[s | s.name == openName]
            val openState = if (openSrc !== null) openSrc.state else NULL

            val openItemName = prefix + "_" + index + "_open"
            val openItem = gOpen.members
                .findFirst[s | s.name == openItemName]
            if (openItem !== null && openState !== null)
                openItem.postUpdate(openState)

        ]
    ]
end
.sitemap

Code: Alles auswählen

            Text label="Diesel" icon="petrol_dark" labelcolor=["orange"]  {
                Frame {
                    Text item=Diesel_0 icon="none" visibility=[Diesel_0_open == OPEN]
                    Text item=Diesel_1 icon="none" visibility=[Diesel_1_open == OPEN]
                    Text item=Diesel_2 icon="none" visibility=[Diesel_2_open == OPEN]
                    Text item=Diesel_3 icon="none" visibility=[Diesel_3_open == OPEN]
                    Text item=Diesel_4 icon="none" visibility=[Diesel_4_open == OPEN]
                    Text item=Diesel_5 icon="none" visibility=[Diesel_5_open == OPEN]
                }
            }
diesel.jpeg