Member of Group Min -> TTS of the cheapest value doesn't work

Group:Number:MIN gGasStations   "Cheapest Gas Price[%.3f €]"
Number Aral_G1                  "Aral_G1[%.3f]"                 (gGasStations) {channel="tankerkoenig:station:WebserviceName:Aral:e5"}
Number Shell_G1                 "Shell_G1[%.3f]"                (gGasStations) {channel="tankerkoenig:station:WebserviceName:Shell:e5"}
Number Aral_G2                  "Aral_G2[%.3f]"                 (gGasStations) {channel="tankerkoenig:station:WebserviceName:AralGK:e5"}
Number Star                     "Star[%.3f]"                    (gGasStations) {channel="tankerkoenig:station:WebserviceName:Star:e5"}
Number PM_G1                    "PM_G1[%.3f]"                   (gGasStations) {channel="tankerkoenig:station:WebserviceName:PM:e5"}
String CheapestGasStation       "Cheapest Gas Station(s)[%s]"
String cgsDummy
rule "My cheapest gas station"
when 
   Item gGasStations received update
then
    cgsDummy.postUpdate("")
    gGasStations.allMembers.forEach [ item | if (item.state == gGasStations.state) {
        Thread::sleep(30)
        if (cgsDummy.state == "") {cgsDummy.postUpdate(item.label)} else {cgsDummy.postUpdate(cgsDummy.state + "; " + item.label)}}]
    CheapestGasStation.postUpdate(cgsDummy.state)
//  logInfo("___", gGasStations.state.toString +" "+ CheapestGasStation.state)
end

Shows cheapest gas price and station(s).

you have to change additional

rule "Tanken PM"
when 
    Item gGasStations changed or
    Item CheapestGasStation changed
then
    if(now.getHourOfDay() >8 && now.getHourOfDay() <21){
        Wohnzimmer_TTS.sendCommand(... + CheapestGasStation.state +" "+ gGasStations.state.toString + " Euro")      
    }
end

Hi Harry.
So much thanks for your help. :slight_smile:
But if i use the rule it logs two item.labels (“1.439 PM_G1;Star”)

2018-06-29 17:56:14.948 [vent.ItemStateChangedEvent] - cgsDummy changed from PM_G1 to PM_G1; Star

Could it be a problem if two or more Stations have the same price?
Greetings,
Markus

Okay PM-G1 and Star have the same price. Is it possible to give both labels to the TTS command.
And after changing the local it still gives 1 thousand 4 houndred and 39. ?

I think (not knowing!) that is caused by the TTS service. You could prove that by changing the item to show only two decimal places, I would expect the TTS to say either 1 hundred and 39 or 1 thousend and 39 for 1.39.

Group:Number:MIN gGasStations   "Cheapest Gas Price[%.3f €]"
Number Aral_G1                  "Aral_G1[%.3f €]"                 (gGasStations) {channel="tankerkoenig:station:WebserviceName:Aral:e5"}
Number Shell_G1                 "Shell_G1[%.3f €]"                (gGasStations) {channel="tankerkoenig:station:WebserviceName:Shell:e5"}
Number Aral_G2                  "Aral_G2[%.3f €]"                 (gGasStations) {channel="tankerkoenig:station:WebserviceName:AralGK:e5"}
Number Star                     "Star[%.3f €]"                    (gGasStations) {channel="tankerkoenig:station:WebserviceName:Star:e5"}
Number PM_G1                    "PM_G1[%.3f €]"                   (gGasStations) {channel="tankerkoenig:station:WebserviceName:PM:e5"}
String CheapestGasStation       "Cheapest Gas Station/s[%s]"
rule "My cheapest gas station"
when 
    Item gGasStations received update
then
    val StringBuilder sb = new StringBuilder
    gGasStations.members.filter[ i | i.state == gGasStations.state].forEach[i | sb.append(", " + i.name) ]
    CheapestGasStation.postUpdate(sb.substring(2))
//  logInfo("***", String::format("%s %.3f Euro", CheapestGasStation.state, (gGasStations.state as DecimalType).floatValue))
//  if(now.getHourOfDay() >8 && now.getHourOfDay() <21){Wohnzimmer_TTS.sendCommand(String::format("%s %.3f Euro", CheapestGasStation.state, (gGasStations.state as DecimalType).floatValue))}    
end
sitemap tmp label="TMP" {
    Text     item=gGasStations
    Setpoint item=Aral_G1  minValue=1.309 maxValue=1.709 step=0.01
    Setpoint item=Shell_G1 minValue=1.309 maxValue=1.709 step=0.01
    Setpoint item=Aral_G2  minValue=1.309 maxValue=1.709 step=0.01
    Setpoint item=Star     minValue=1.309 maxValue=1.709 step=0.01
    Setpoint item=PM_G1    minValue=1.309 maxValue=1.709 step=0.01
    Default  item=CheapestGasStation
}

Hi Harry.
It’s running beautiful. Thank you very much for your help and time.
I have changed %.3f to %.2f to get a correct value in Euro.
The only thing that happens is that the TTS command repeats for every change. And Alexa says by 5 changes to the same time: Hey,Hey,Hey,Hey,Hey, die Spritpreise haben sich geändert…
I will test it with a ‘,’ before the text, so in background it will fire the rule five times but you cannot hear it. :slight_smile:
Thanks so much.
Greetings,
Markus

If you use

Item gGasStations changed

the rule runs only, if the cheapest price changed ,but not if one station added or remove from the list of cheapest.

untested

var lastgGasStations = 0.0
var lastCheapestGasStation = ""

rule "My cheapest gas station"
when 
    Item gGasStations received update
then
    ...
    if((lastCheapestGasStation != CheapestGasStation.state || lastgGasStations != gGasStations.state) && now.getHourOfDay() >8 && now.getHourOfDay() <21) {
        lastgGasStations = gGasStations.state
        lastCheapestGasStation = CheapestGasStation.state
        Wohnzimmer_TTS.sendCommand(String::format("%s %.3f Euro", CheapestGasStation.state, (gGasStations.state as DecimalType).floatValue))}*/
end

Hi Harry.
I have tested it an the log shows:


2018-07-04 10:36:44.483 [vent.ItemStateChangedEvent] - Star changed from 1.499 to 1.459

2018-07-04 10:36:44.483 [GroupItemStateChangedEvent] - gGasStations changed from 1.499 to 1.459 through Star

2018-07-04 10:36:44.692 [vent.ItemStateChangedEvent] - Hausserver_LastUpdated changed from 2018-07-04T10:36:34.691+0200 to 2018-07-04T10:36:44.691+0200

2018-07-04 10:36:44.693 [vent.ItemStateChangedEvent] - FlowerCare_LastUpdated changed from 2018-07-04T10:36:34.691+0200 to 2018-07-04T10:36:44.691+0200

2018-07-04 10:36:44.913 [vent.ItemStateChangedEvent] - Aral_G1_Update changed from 2018-07-04T09:36:53.733+0200 to 2018-07-04T10:36:44.911+0200

2018-07-04 10:36:44.913 [vent.ItemStateChangedEvent] - PM_G1_Update changed from 2018-07-04T09:36:53.633+0200 to 2018-07-04T10:36:44.911+0200

==> /var/log/openhab2/openhab.log <==

2018-07-04 10:36:44.915 [INFO ] [g.eclipse.smarthome.model.script.***] - Star 1,459 Euro

2018-07-04 10:36:44.916 [INFO ] [g.eclipse.smarthome.model.script.***] - Star 1,459 Euro

==> /var/log/openhab2/events.log <==

2018-07-04 10:36:44.916 [vent.ItemStateChangedEvent] - Shell_G1_Update changed from 2018-07-04T09:36:53.672+0200 to 2018-07-04T10:36:44.911+0200

2018-07-04 10:36:44.916 [vent.ItemStateChangedEvent] - Aral_G1_Update changed from 2018-07-04T09:36:53.685+0200 to 2018-07-04T10:36:44.911+0200

2018-07-04 10:36:44.918 [vent.ItemStateChangedEvent] - CheapestGasStation changed from Star, PM_G1 to Star

==> /var/log/openhab2/openhab.log <==

2018-07-04 10:36:44.918 [INFO ] [g.eclipse.smarthome.model.script.***] - Star 1,459 Euro

==> /var/log/openhab2/events.log <==

2018-07-04 10:36:44.925 [ome.event.ItemCommandEvent] - Item 'Wohnzimmer_TTS' received command Star 1,459 Euro

2018-07-04 10:36:44.925 [ome.event.ItemCommandEvent] - Item 'Wohnzimmer_TTS' received command Star 1,459 Euro

2018-07-04 10:36:44.925 [vent.ItemStateChangedEvent] - Star_Update changed from 2018-07-04T09:36:53.656+0200 to 2018-07-04T10:36:44.917+0200

2018-07-04 10:36:44.926 [vent.ItemStateChangedEvent] - Wohnzimmer_TTS changed from  to Star 1,459 Euro

==> /var/log/openhab2/openhab.log <==

2018-07-04 10:36:45.045 [INFO ] [g.eclipse.smarthome.model.script.***] - Star 1,459 Euro

2018-07-04 10:36:45.046 [INFO ] [g.eclipse.smarthome.model.script.***] - Star 1,459 Euro

There are again two commands to the TTS and Alexa will stutter.

Greetings,
Markus

Please post your actuel rule.

var lastgGasStations = 0.0
var lastCheapestGasStation = ""

rule "My cheapest gas station"

when 
    Item gGasStations received update
then
    val StringBuilder sb = new StringBuilder
    gGasStations.members.filter[ i | i.state == gGasStations.state].forEach[i | sb.append(", " + i.name) ]
    CheapestGasStation.postUpdate(sb.substring(2))
    logInfo("***", String::format("%s %.3f Euro", CheapestGasStation.state, (gGasStations.state as DecimalType).floatValue))
    if((lastCheapestGasStation != CheapestGasStation.state || lastgGasStations != gGasStations.state) && now.getHourOfDay() >7 && now.getHourOfDay() <21) {
        lastgGasStations = *gGasStations.state* error 1
        lastCheapestGasStation = *CheapestGasStation.state* error 2
        Wohnzimmer_TTS.sendCommand(',' + String::format("%s %.3f Euro", CheapestGasStation.state, (gGasStations.state as DecimalType).floatValue))}
end

error 1 Type mismatch: cannot convert from State to double
error 2 Type mismatch: cannot convert from State to String

Visual Studio code doesn’t show me the error before.
So after restart Vsc,copying and sending you the code i have seen it. :slight_smile:

This could ba a solution

include java.util.concurrent.locks.ReentrantLock
val ReentrantLock stompingLock = new ReentrantLock

rule ...
when
...
then
    try {
        stompingLock.lock()
...
    } catch(Throwable t) { }
    finally {
        stompingLock.unlock()
    }
end

Thanks for your rule, but i doen’t understand where i have to copy it.
And i don’t understand the code too. :slight_smile:

This code extension will lock the code as long it is in use, in other words it can not be started again while it is running.
In order to use it copy the name of your rule onto the first three dots, copy rhe"when" part of your actual code onto the second three dots and all your code in the “then” part (except the “end”) onto the last three dots.

var Number lastgGasStations = 0
var String lastCheapestGasStation = ""

rule "My cheapest gas station"
when
    Item gGasStations received update
then
    val StringBuilder sb = new StringBuilder
    gGasStations.members.filter[ i | i.state == gGasStations.state].forEach[i | sb.append(", " + i.name) ]
    CheapestGasStation.postUpdate(sb.substring(2))
    if ((lastCheapestGasStation != CheapestGasStation.state.toString || lastgGasStations != gGasStations.state) && now.getHourOfDay() >7 && now.getHourOfDay() <21) {
        lastgGasStations = gGasStations.state as Number
        lastCheapestGasStation = CheapestGasStation.state.toString
        Wohnzimmer_TTS.sendCommand(String::format("xxx %s xxx %.3f Euro", CheapestGasStation.state, (gGasStations.state as DecimalType).floatValue))}
end

Okay i understand it now. :slight_smile:
“Include” gives me a:
missing EOF at ‘include’

include java.util.concurrent.locks.ReentrantLock
val ReentrantLock stompingLock = new ReentrantLock

var Number lastgGasStations = 0
var String lastCheapestGasStation = ""

rule "My cheapest gas station"

when 
    Item gGasStations received update
then
    try {
        stompingLock.lock()
    val StringBuilder sb = new StringBuilder
    gGasStations.members.filter[ i | i.state == gGasStations.state].forEach[i | sb.append(", " + i.name) ]
    CheapestGasStation.postUpdate(sb.substring(2))
    logInfo("***", String::format("%s %.3f Euro", CheapestGasStation.state, (gGasStations.state as DecimalType).floatValue))
    if((lastCheapestGasStation != CheapestGasStation.state || lastgGasStations != gGasStations.state) && now.getHourOfDay() >7 && now.getHourOfDay() <21) {
        lastgGasStations = gGasStations.state as Number
        lastCheapestGasStation = CheapestGasStation.state.toString
        Wohnzimmer_TTS.sendCommand(',' + String::format("%s %.3f Euro", CheapestGasStation.state, (gGasStations.state as DecimalType).floatValue))}

 
    } catch(Throwable t) { }
    finally {
        stompingLock.unlock()
    }
end

You can try first my last example without lock.It work fine.

Okay I will test it. Thank you very much.
Greetings,
Markus