[SOLVED] HTTP Binding updateInterval configuration

  • Platform information:
    • Hardware: Raspberry Pi 3 Model B Rev 1.2
    • OS: Raspbian GNU/Linux 9 (stretch)
  • Issue of the topic: No issue: I need to understand the difference of the updateInterval in http.cfg and the one in the ITEM

Hello, I did a http binding to MeteoBlue to retrieve the sunshine forecast. Meteoblue allows me max 24 data feeds per day (max one per hour).

http.cfg:

meteoBlueCache.url=http://my.meteoblue.com/packages/basic-day_clouds-1h?name=Pucon&lat=-39.2822&lon=-71.9543&asl=236&tz=America%2FSantiago&apikey=xyzungeloest&temperature=C&windspeed=ms-1&winddirection=degree&precipitationamount=mm&timeformat=iso8601&format=json
meteoBlueCache.updateInterval=3600000

Note for other OH members: never use accents, Pucón is not allowed so I had to use Pucon. I spent a full day day of my short life for a ridiculous ó !!

Items:

String jMeteoBlue "Meteo [%s]" { http="<[meteoBlueCache:3600000:REGEX((.*))]" }
String sUpdateTime "mg uTime [%s]" { http="<[meteoBlueCache:3600000:JSONPATH($.metadata.modelrun_updatetime_utc)]" }

My question is here, what is the difference between the updateInterval in the http.cfg file and on the Item http="<[meteoBlueCache:3600000:… The http.cfg reads each updateInterval into the cache buffer and the Item reads from the cache without accessing the URL again?

I need to be sure: If I have many ITEMS accessing my Cache this is no extra traffic or other URL access?

Extra infos:

I’m parsing from MeteoBlue the sunshine time for the next day. I have a off-grid PV on Battery and I need to know how much electricity I can spend today depending on how much Sun I will have tomorrow. If the battery is very low and there is no sun coming I can start a generator.

The parsing of the MeteoBlue.JSON is done on a rule. I’m happy to share the code. It seems to work fine but if if someone helps me to optimize the code it would be great.

/*---------------------------------------------------------------------------------
;
;	Read SunShine info
;
----------------------------------------------------------------------------------*/

rule "get sunshine"
		
when
    Item jMeteoBlue changed
    or Item POWERDHT changed                    // only for testing
then

    if( jMeteoBlue.state != NULL ) {

        var String jMeteo = jMeteoBlue.state.toString

        var String sStart = transform( "JSONPATH", "$.data_day.indexto1hvalues_start[0]", jMeteo )
        var String sEnd = transform( "JSONPATH", "$.data_day.indexto1hvalues_end[0]", jMeteo )

        var int nStart = Float::parseFloat( sStart ).intValue
        var int nEnd = Float::parseFloat( sEnd ).intValue

        // logInfo( "SUN", "start " + nStart )
        // logInfo( "SUN", "end " + nEnd )

        var String sSun
        var int nSunMinute = 0
        var String jSon
        //var int cnt =0
        var int nSun

        while( nStart < nEnd ) {

            jSon = "$.data_1h.sunshinetime["
            jSon += nStart
            jSon += "]"

            logInfo( "SUN", jSon );

            nStart = nStart + 1

            sSun = transform( "JSONPATH", jSon, jMeteo )
            //logInfo( "SUN", "sSun " + sSun )
            nSun = Float::parseFloat( sSun ).intValue
            nSunMinute += nSun
        }

        vMeteoBlue.postUpdate( nSunMinute )   
    }

    else vMeteoBlue.postUpdate( -1 )

end

I’m also parsing from MeteoGroup and checking the accuracy of both providers. Maybe I do an average. No many weather forecast provide the Sunshine data.

thanks !!

Correct. The HTTP binding will pull down and cache the result from Meteo every 3600000 msec. The Item jMeteoBlue will pull from and apply the REGEX from the cache every 3600000 msec.

The updateInterval in the http.cfg file controls how often the remote service is polled. The one on the Item controls how often the Item is updated from the cached version the binding already pulled from the remote service.

Correct, the Items only pull from the cache and do not hit the remote service.

It is best to avoid primitives as much as possible. Primitives is known to cause exaggerated rules parsing and loading times, particularly on SPCs like RPis.

You can use:

        val nStart = new BigDecimal(sStart)
        val nEnd = new BigDecimal(sEnd)
        ...
        var nSunMinute = 0
        ...
        var Number nSun

It is not at all clear to me what the while loop is doing.

Hello Rich, thanks for the prompt response and explaining well the updateInterval. This is a very good feature since I’m on 3G internet. Also thank you for the coding tips.

Meteoblue gives me minute time in a Json format:

This time is in minutes, and I have to get it between the indexto1hvalues_start and the indexto1hvalues_end. I add the sunshine minutes for this day.

		"indexto1hvalues_start": [3, 27, 51, 75, 99, 123, 147], 
		"indexto1hvalues_end": [26, 50, 74, 98, 122, 146, 170]

I could do it with a for(…) loop, but I had problems with casting. I’m used to C++ and Xtend / Java is a to different thinking for my old brain. This is the reason I appreciate any better coding suggestion.

I was a little confused by the jSon variable. That’s really the jsonpath. jMeteo is the JSON.

So the loop is iterating over an array in the JSON and summing them.

There was a PR awhile ago that corrects the JSONPATH transform such that it should work properly with arrays. I think it’s in the snapshot but I can’t find the PR anymore. It’s definitely something merged post 2.5 M1 so may not be available to you.

So, except for the primitives the loop makes sense to me now.

Hello Rich

Now I optimized the code:

/*---------------------------------------------------------------------------------
;
;	Get Sunshine forecast from meteoblue
;
----------------------------------------------------------------------------------*/

rule "get sunshine"
		
when
    Item jMeteoBlue changed
    or Item qHausLightSimulator changed             // for debugging

then
    if( jMeteoBlue.state != NULL ) {

        val String jMeteo = jMeteoBlue.state.toString       // full jSon string in items, ~ 13 kBytes
        
        val String sStart = transform( "JSONPATH", "$.data_day.indexto1hvalues_start[0]", jMeteo )
        val String sEnd = transform( "JSONPATH", "$.data_day.indexto1hvalues_end[0]", jMeteo )
        val String sPostDate = transform( "JSONPATH", "$.data_1h.time[0]", jMeteo )
        
        logInfo( "SUN", "Sunshine rule Update = " + sPostDate )

        var nStart = new Integer(sStart)
        val nEnd = new Integer(sEnd)
            
        var String jSon
        var nSunMinute = 0.0

        while( nStart <= nEnd ) {

            jSon = "$.data_1h.sunshinetime["
            jSon += nStart
            jSon += "]"

            var nSun = new Integer(transform( "JSONPATH", jSon, jMeteo ))
            nSunMinute += nSun
            nStart = nStart+1
        }

    nSunMinute = nSunMinute/60                  // post sunshine in hours

    sUpdateTime.postUpdate( sPostDate )
    vMeteoBlue.postUpdate( nSunMinute )   
    }

    else vMeteoBlue.postUpdate( -1 )

end

Tank you for your help !

Hello, I have a strange behaviour with the following rule. It is like to be interrupted and called again mid in the rule execution.

I’m parsing a long jSon string with sunshine information in minutes, adding them in a day, building a kind of a daily week string (see debug info). There you see it parses ‘quite correct’ 4 days and then the same function is interrupted, parses all 7 groups well and then it finishes with the last 3 days of the first run (sorry for the bad explaining).

Should I set a flag or a latch at the beginning of the rule to know it is running and do nothing? Or is this already handled by the rule engine?

019-07-28 16:12:57.483 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - MeteoBlu Sunshine Update : 2019-07-28T09:37-04:00 
2019-07-28 16:12:57.533 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nStart : 3 
2019-07-28 16:12:57.549 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nEnd : 26 
2019-07-28 16:12:57.811 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nStart : 27 
2019-07-28 16:12:57.814 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nEnd : 50 
2019-07-28 16:12:58.032 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nStart : 51 
2019-07-28 16:12:58.036 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nEnd : 74 
2019-07-28 16:12:58.237 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nStart : 75 
2019-07-28 16:12:58.241 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nEnd : 98 
2019-07-28 16:12:58.311 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - MeteoBlu Sunshine Update : 2019-07-28T09:37-04:00 
2019-07-28 16:12:58.336 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nStart : 3 
2019-07-28 16:12:58.339 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nEnd : 26 
2019-07-28 16:12:58.483 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nStart : 99 
2019-07-28 16:12:58.486 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nEnd : 122 
2019-07-28 16:12:58.555 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nStart : 27 
2019-07-28 16:12:58.560 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nEnd : 50 
2019-07-28 16:12:58.672 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nStart : 123 
2019-07-28 16:12:58.675 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nEnd : 146 
2019-07-28 16:12:58.771 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nStart : 51 
2019-07-28 16:12:58.774 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nEnd : 74 
2019-07-28 16:12:58.861 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nStart : 147 
2019-07-28 16:12:58.864 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nEnd : 170 
2019-07-28 16:12:58.946 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nStart : 75 
2019-07-28 16:12:58.950 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nEnd : 98 
2019-07-28 16:12:59.053 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - sSunHour = MB { 0.0, 0.0, 0.0, 0.0, 1.3, 8.2, 9.2, }
2019-07-28 16:12:59.141 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nStart : 99 
2019-07-28 16:12:59.144 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nEnd : 122 
2019-07-28 16:12:59.313 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nStart : 123 
2019-07-28 16:12:59.315 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nEnd : 146 
2019-07-28 16:12:59.490 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nStart : 147 
2019-07-28 16:12:59.493 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - nEnd : 170 
2019-07-28 16:12:59.649 [INFO ] [ome.model.script.SOL_MeteoBlue.rules] - sSunHour = MB { 0.0, 0.0, 0.0, 0.0, 1.3, 8.2, 9.2, }
[16:2

I know my coding is not very good because I still have a lot to learn. So any coding suggestion to improve this rule is welcome.

/*---------------------------------------------------------------------------------
;
;	Get Sunshine forecast from MeteoBlue
;
----------------------------------------------------------------------------------*/

rule "SOL_MeteoBlue"

when
    Item jMeteoBlue changed
    or Item qHausLightSimulator changed             // for debugging

then
    if( jMeteoBlue.state != NULL ) {

        val String jMeteo = jMeteoBlue.state.toString       // full jSon string in items, ~ 13 kBytes
        val String sPostDate = transform( "JSONPATH", "$.metadata.modelrun_updatetime_utc", jMeteo )
        logInfo( "SOL_MeteoBlue.rules", "MeteoBlu Sunshine Update : {} ", sPostDate )
        
        tMeteoBlue_Time.postUpdate( sPostDate )

        var String sSunHour = "MB { "
        
        for( cnt: 0..6 ) {

            var String sStart = transform( "JSONPATH", "$.data_day.indexto1hvalues_start[" + cnt + "]", jMeteo )
            var String sEnd = transform( "JSONPATH", "$.data_day.indexto1hvalues_end[" + cnt + "]", jMeteo )

            var nStart = new Integer(sStart)
            var nEnd = new Integer(sEnd)

            var String jSon
            var nSunMinute = 0.0

            logInfo( "SOL_MeteoBlue.rules", "nStart : {} ", nStart )
            logInfo( "SOL_MeteoBlue.rules", "nEnd : {} ", nEnd )

            while( nStart <= nEnd ) {

                jSon = "$.data_1h.sunshinetime["
                jSon += nStart + 1
                jSon += "]"

                var nSun = new Integer(transform( "JSONPATH", jSon, jMeteo ))
                nSunMinute += nSun
                nStart = nStart+1
            }
            
            nSunMinute = nSunMinute/60                  // post sunshine in hours
              
            if( cnt==0 ) vMeteoBlue_Sol.postUpdate( nSunMinute as Number )

            sSunHour += String.format( "%.1f", nSunMinute) + ", "
        }

        sSunHour += "}"
        logInfo( "SOL_MeteoBlue.rules", "sSunHour = " + sSunHour )
        
        sMeteoBlue_Sol.postUpdate( sSunHour )

     }

    else vMeteoBlue_Sol.postUpdate( -1 )

end

Thanks.

Not interrupted, triggered again so you have two copies of the rule running at the same time.

Look at events.log. I suspect you will see two events very close together that trigger the rule to run twice.

It’s not handled by the rule engine, as evidenced here in these logs. But is this really a problem? It looks like you end up with the right answer in the end so it’s there really a problem here to be solved?