How to optimize gas station prices processing (Tankerkoenig)

To finish this thread, please find below all related rules, items, sitemaps, etc.

Gas station things

Bridge tankerkoenig:webservice:xxxxxxxxxxx "Bridge_Tankerkoenig Tankerkönig Webservice" [ apikey="xxxxxxxxxxxxxxx", refresh= 15, modeOpeningTime =true ] {

    Thing station station01 "SL_IN_GasStation01 Nordoel (Elmshorn)" @ "Internet"[ locationid = "1ceea95b-d46e-4159-91f6-71f57d612bdb" ]
    Thing station station02 "SL_IN_GasStation02 Nordoel (Uetersen)" @ "Internet"[ locationid = "3d8c2dfb-4612-4aff-8ae7-96e3f88eafe6" ]
    Thing station station03 "SL_IN_GasStation03 HEM (Elmshorn)" @ "Internet"[ locationid = "e1a15081-24e2-9107-e040-0b0a3dfe563c" ]
    Thing station station04 "SL_IN_GasStation04 Star (Elmshorn)" @ "Internet"[ locationid = "005056ba-7cb6-1ed2-bceb-bc577a5e6d4e" ]
    Thing station station05 "SL_IN_GasStation05 HEM (Wedel)" @ "Internet"[ locationid = "e1a15081-254f-9107-e040-0b0a3dfe563c" ]
    Thing station station06 "SL_IN_GasStation06 SB (Wedel)" @ "Internet"[ locationid = "65c348cf-5ce7-4820-a24a-da0dbf816204" ]
}

and all the items that i use

/*---------------------------------------------------------------------------------------------------------------------
  
    Thing: All additional items to prcoess gas station data

---------------------------------------------------------------------------------------------------------------------*/
Group tSL_OH_GasStationItems "Gas station realted items" <scenegasstation> (gSL_openHAB)
    DateTime                    iSL_OH_GasStationItems_LastUpdate
                                "Gas station: Last update [%1$td.%1$tm.%1$ty %1$tH:%1$tM]"
                                <timeclock>
                                (tSL_OH_GasStationItems)

    Switch                      iSL_OH_GasStationItems_Timer
                                "Gas station: Timer [MAP(switch.map):%s]"
                                <timesandglass>
                                (tSL_OH_GasStationItems)
                                { expire="2m,state=OFF" }

    String                      iSL_OH_GasStationItems_Display01
                                "Gas station: Display 01 [%s]"
                                <scenegasstation>
                                (tSL_OH_GasStationItems)

    String                      iSL_OH_GasStationItems_Display02
                                "Gas station: Display 02 [%s]"
                                <scenegasstation>
                                (tSL_OH_GasStationItems)

    String                      iSL_OH_GasStationItems_Display03
                                "Gas station: Display 03 [%s]"
                                <scenegasstation>
                                (tSL_OH_GasStationItems)

    String                      iSL_OH_GasStationItems_Display04
                                "Gas station: Display 04 [%s]"
                                <scenegasstation>
                                (tSL_OH_GasStationItems)

    String                      iSL_OH_GasStationItems_Display05
                                "Gas station: Display 05 [%s]"
                                <scenegasstation>
                                (tSL_OH_GasStationItems)

    String                      iSL_OH_GasStationItems_Display06
                                "Gas station: Display 06 [%s]"
                                <scenegasstation>
                                (tSL_OH_GasStationItems)

/*---------------------------------------------------------------------------------------------------------------------
  
    Thing: SL_IN_GasStation01 - Nordoel (Elmshorn)

---------------------------------------------------------------------------------------------------------------------*/
Group tSL_IN_GasStation01 "Gas station 01: Nordoel (Elmshorn)" <scenegasstation> (gSL_Internet)
    Number                      iSL_IN_GasStation01_Diesel
                                "Gas station 01: Diesel [%.3f €]"
                                <scenegasstation>
                                (tSL_IN_GasStation01, gGasStationPrices, gStandardTimeline)
                                { channel="tankerkoenig:station:100720191523:station01:diesel" }

    Contact                     iSL_IN_GasStation01_Open
                                "Gas station 01: Status [MAP(contact.map):%s]"
                                <scenegasstation>
                                (tSL_IN_GasStation01)
                                { channel="tankerkoenig:station:100720191523:station01:station_open" }


/*---------------------------------------------------------------------------------------------------------------------
  
    Thing: SL_IN_GasStation02 - Nordoel (Uetersen)

---------------------------------------------------------------------------------------------------------------------*/
Group tSL_IN_GasStation02 "Gas station 02: Nordoel (Uetersen)" <scenegasstation> (gSL_Internet)
    Number                      iSL_IN_GasStation02_Diesel
                                "Gas station 02: Diesel [%.3f €]"
                                <scenegasstation>
                                (tSL_IN_GasStation02, gGasStationPrices, gStandardTimeline)
                                { channel="tankerkoenig:station:100720191523:station02:diesel" }

    Contact                     iSL_IN_GasStation02_Open
                                "Gas station 02: Status [MAP(contact.map):%s]"
                                <scenegasstation>
                                (tSL_IN_GasStation02)
                                { channel="tankerkoenig:station:100720191523:station02:station_open" }


/*---------------------------------------------------------------------------------------------------------------------
  
    Thing: SL_IN_GasStation03 - HEM (Elmshorn)

---------------------------------------------------------------------------------------------------------------------*/
Group tSL_IN_GasStation03 "Gas station 03: HEM (Elmshorn)" <scenegasstation> (gSL_Internet)
    Number                      iSL_IN_GasStation03_Diesel
                                "Gas station 03: Diesel [%.3f €]"
                                <scenegasstation>
                                (tSL_IN_GasStation03, gGasStationPrices, gStandardTimeline)
                                { channel="tankerkoenig:station:100720191523:station03:diesel" }

    Contact                     iSL_IN_GasStation03_Open
                                "Gas station 03: Status [MAP(contact.map):%s]"
                                <scenegasstation>
                                (tSL_IN_GasStation03)
                                { channel="tankerkoenig:station:100720191523:station03:station_open" }


/*---------------------------------------------------------------------------------------------------------------------
  
    Thing: SL_IN_GasStation04 - Star (Elmshorn)

---------------------------------------------------------------------------------------------------------------------*/
Group tSL_IN_GasStation04 "Gas station 04: Star (Elmshorn)" <scenegasstation> (gSL_Internet)
    Number                      iSL_IN_GasStation04_Diesel
                                "Gas station 04: Diesel [%.3f €]"
                                <scenegasstation>
                                (tSL_IN_GasStation04, gGasStationPrices, gStandardTimeline)
                                { channel="tankerkoenig:station:100720191523:station04:diesel" }

    Contact                     iSL_IN_GasStation04_Open
                                "Gas station 04: Status [MAP(contact.map):%s]"
                                <scenegasstation>
                                (tSL_IN_GasStation04)
                                { channel="tankerkoenig:station:100720191523:station04:station_open" }


/*---------------------------------------------------------------------------------------------------------------------
  
    Thing: SL_IN_GasStation05 - HEM (Wedel)

---------------------------------------------------------------------------------------------------------------------*/
Group tSL_IN_GasStation05 "Gas station 05: HEM (Wedel)" <scenegasstation> (gSL_Internet)
    Number                      iSL_IN_GasStation05_Diesel
                                "Gas station 05: Diesel [%.3f €]"
                                <scenegasstation>
                                (tSL_IN_GasStation05, gGasStationPrices, gStandardTimeline)
                                { channel="tankerkoenig:station:100720191523:station05:diesel" }

    Contact                     iSL_IN_GasStation05_Open
                                "Gas station 05: Status [MAP(contact.map):%s]"
                                <scenegasstation>
                                (tSL_IN_GasStation05)
                                { channel="tankerkoenig:station:100720191523:station05:station_open" }


/*---------------------------------------------------------------------------------------------------------------------
  
    Thing: SL_IN_GasStation06 - SB (Wedel)

---------------------------------------------------------------------------------------------------------------------*/
Group tSL_IN_GasStation06 "Gas station 06: SB (Wedel)" <scenegasstation> (gSL_Internet)
    Number                      iSL_IN_GasStation06_Diesel
                                "Gas station 06: Diesel [%.3f €]"
                                <scenegasstation>
                                (tSL_IN_GasStation06, gGasStationPrices, gStandardTimeline)
                                { channel="tankerkoenig:station:100720191523:station06:diesel" }

    Contact                     iSL_IN_GasStation06_Open
                                "Gas station 06: Status [MAP(contact.map):%s]"
                                <scenegasstation>
                                (tSL_IN_GasStation06)
                                { channel="tankerkoenig:station:100720191523:station06:station_open" }

and the rules to sort the prices

/*---------------------------------------------------------------------------------------------------------------------
  
    Imports

---------------------------------------------------------------------------------------------------------------------*/
import org.eclipse.smarthome.model.script.ScriptServiceUtil


/*---------------------------------------------------------------------------------------------------------------------
  
    Global variables and constants

---------------------------------------------------------------------------------------------------------------------*/
val String ruleIdentification = "user.gasstationrule."


/*---------------------------------------------------------------------------------------------------------------------
  
    Rule: Gas Station Price Change Trigger

    Description:    This rule triggers the trigger item which is connected to the expire binding. After 2 minutes the
                    switch is reset to Off and the price sort rule is executed.

---------------------------------------------------------------------------------------------------------------------*/
rule "Gas Station Price Changed Trigger"
when
    
    Member of gGasStationPrices changed

then
    
    val String ruleIdentifier = ruleIdentification+"GasStationPriceChangedTrigger"

    logInfo(ruleIdentifier, "Gas station prices have changed. Trigger is {}.", transform("MAP", "i18n_gasstation.map", triggeringItem.name.substring(1, triggeringItem.name.lastIndexOf('_'))))
    iSL_OH_GasStationItems_Timer.postUpdate(ON)

end


/*---------------------------------------------------------------------------------------------------------------------
  
    Rule: Process Gas Station Prices

    Description: Sort gas station prices and setup the diaplay items in the right order.

---------------------------------------------------------------------------------------------------------------------*/
rule "Gas Station Price Sorter"
when

    Item iSL_OH_GasStationItems_Timer changed to OFF     

then
    
    val String ruleIdentifier = ruleIdentification+"GasStationPriceSorter"

    var Double actualPrice
    var Double previousPrice
    var String indicator

    logInfo(ruleIdentifier, "Gas station price sorting has been triggered.")

    gGasStationPrices.members.filter[ price | (price != UNDEF) && (price != NULL) ].sortBy[ state as DecimalType ].forEach[ gasPrice, index |
        
        val stationOpen = ScriptServiceUtil.getItemRegistry.getItem("i"+gasPrice.name.substring(1, gasPrice.name.lastIndexOf('_'))+"_Open") as ContactItem
        val stationDisplay = ScriptServiceUtil.getItemRegistry.getItem("iSL_OH_GasStationItems_Display"+String::format("%02d", index+1)) as StringItem

        stationDisplay.setLabel(transform("MAP", "i18n_gasstation.map", gasPrice.name.substring(1, gasPrice.name.lastIndexOf('_'))))

        if (stationOpen.state == OPEN) {
        
            actualPrice = (gasPrice.state as DecimalType).doubleValue()
            previousPrice = (gasPrice.previousState(true).state as DecimalType).doubleValue()
            indicator = if (actualPrice > previousPrice) "↑" else if (actualPrice < previousPrice) "↓" else "→"
            
            stationDisplay.postUpdate(String::format("%s %.3f €", indicator, actualPrice))
        
        } else {
        
            stationDisplay.postUpdate(transform("MAP", "i18n_contact.map", stationOpen.state.toString))
        
        }
    
    ]

    iSL_OH_GasStationItems_LastUpdate.postUpdate(now.toString)
    logInfo(ruleIdentifier, "Gas station prices are sorted now")

end

and last but not least the sitemap to display the items

sitemap smarthome label="Smart Home" {

    Text label="Information" icon="messageinfo" {

        Frame label="Dieselpreise" {
            Text item=iSL_OH_GasStationItems_LastUpdate label="Letzte Abfrage [%1$tH:%1$tM]" icon="timeclock"
            Text item=iSL_OH_GasStationItems_Display01
            Text item=iSL_OH_GasStationItems_Display02
            Text item=iSL_OH_GasStationItems_Display03
            Text item=iSL_OH_GasStationItems_Display04
            Text item=iSL_OH_GasStationItems_Display05
            Text item=iSL_OH_GasStationItems_Display06
        }

    }

}

and my first try with habpanel based on the matrix theme.

<div class="section">

  <div class="sectionIconContainer">
    <div class="sectionIcon"><svg viewBox="0 0 361 361"><use xlink:href="/static/matrix-theme/knx-uf_icons.svg#scenegasstation"></use></svg></div>
  </div>

  <div class="title">Dieselpreise {{itemValue('iSL_OH_GasStationItems_LastUpdate') | date:'HH:mm'}}</div>

	<div class="controls">

		<div class="widget">
			<div class="icon off"><svg viewBox="0 0 361 361"><use xlink:href="/static/matrix-theme/knx-uf_icons.svg#scenegasstation"></use></svg></div>
			<div class="name">1. {{getItem('iSL_OH_GasStationItems_Display01').label}}</div>
			<div class="valueGroup"><div class="value">{{itemValue('iSL_OH_GasStationItems_Display01')}}</div></div>			
		</div>

		<div class="widget">
			<div class="icon off"><svg viewBox="0 0 361 361"><use xlink:href="/static/matrix-theme/knx-uf_icons.svg#scenegasstation"></use></svg></div>
			<div class="name">2. {{getItem('iSL_OH_GasStationItems_Display02').label}}</div>
			<div class="valueGroup"><div class="value">{{itemValue('iSL_OH_GasStationItems_Display02')}}</div></div>			
		</div>

		<div class="widget">
			<div class="icon off"><svg viewBox="0 0 361 361"><use xlink:href="/static/matrix-theme/knx-uf_icons.svg#scenegasstation"></use></svg></div>
			<div class="name">3. {{getItem('iSL_OH_GasStationItems_Display03').label}}</div>
			<div class="valueGroup"><div class="value">{{itemValue('iSL_OH_GasStationItems_Display03')}}</div></div>			
		</div>

		<div class="widget">
			<div class="icon off"><svg viewBox="0 0 361 361"><use xlink:href="/static/matrix-theme/knx-uf_icons.svg#scenegasstation"></use></svg></div>
			<div class="name">4. {{getItem('iSL_OH_GasStationItems_Display04').label}}</div>
			<div class="valueGroup"><div class="value">{{itemValue('iSL_OH_GasStationItems_Display04')}}</div></div>			
		</div>

		<div class="widget">
			<div class="icon off"><svg viewBox="0 0 361 361"><use xlink:href="/static/matrix-theme/knx-uf_icons.svg#scenegasstation"></use></svg></div>
			<div class="name">5. {{getItem('iSL_OH_GasStationItems_Display05').label}}</div>
			<div class="valueGroup"><div class="value">{{itemValue('iSL_OH_GasStationItems_Display05')}}</div></div>			
		</div>

    <div class="widget">
			<div class="icon off"><svg viewBox="0 0 361 361"><use xlink:href="/static/matrix-theme/knx-uf_icons.svg#scenegasstation"></use></svg></div>
			<div class="name">6. {{getItem('iSL_OH_GasStationItems_Display06').label}}</div>
			<div class="valueGroup"><div class="value">{{itemValue('iSL_OH_GasStationItems_Display06')}}</div></div>			
		</div>

	</div>
  </div>
3 Likes