Environment Agency river levels

I have a river running close to my house and I have set up the following items to monitor the level:

Number RiverLevel “River Level [%.3f]” (River) {http="<[http://environment.data.gov.uk/flood-monitoring/id/stations/E21511/measures:1800000:JSONPATH($.items[0].latestReading.value)]"}
DateTime LastObs “Last measurement [%1$tR]” (River) {http="<[http://environment.data.gov.uk/flood-monitoring/id/stations/E21511/measures:1800000:JSONPATH($.items[0].latestReading.dateTime)]"}

There are other data feeds, including typical and maximum levels. Documentation can be found on the EA website: http://environment.data.gov.uk/flood-monitoring/doc/reference.

Might be of interest to anyone who has a river nearby or lives near the coast.

I also wanted to be able to extract the flood warning data but I can’t get that working:
String FloodMessage “Flood warning [%s]” (River) {http="<[http://environment.data.gov.uk/flood-monitoring/id/floodAreas/122WAF933:900000:JSONPATH($.items[].message)]"}
Number FloodSev “Flood warning severity [%.1f]” (River) {http="<[http://environment.data.gov.uk/flood-monitoring/id/floodAreas/122WAF933:900000:JSONPATH($.items[
].severityLevel)]"}
String FloodSevText “Flood warning severity [%s]” (River) {http="<[http://environment.data.gov.uk/flood-monitoring/id/floodAreas/122WAF933:900000:JSONPATH($.items[].severity)]"}
DateTime FloodUpdate “Time of last update [%1$tT, %1$tF]” (River) {http="<[http://environment.data.gov.uk/flood-monitoring/id/floodAreas/122WAF933:900000:JSONPATH($.items[
].timeMessageChanged)]"}

3 Likes

Very nice. You could improve efficiency, so that each item does not GET the same URL on every poll. See Caching. In openhab.cfg:

http:riverLevel.url=http://environment.data.gov.uk/flood-monitoring/id/stations/E21511/measures
http:riverLevel.updateInterval=1800000
http:floodWarning.url=http://environment.data.gov.uk/flood-monitoring/id/floodAreas/122WAF933
http:floodWarning.updateInterval=900000

and your items:

Number RiverLevel "River Level [%.3f]" (River) {http="<[riverLevel:1800000:JSONPATH($.items[0].latestReading.value)]"}
DateTime LastObs "Last measurement [%1$tR]" (River) {http="<[riverLevel:1800000:JSONPATH($.items[0].latestReading.dateTime)]"}

String FloodMessage "Flood warning [%s]" (River) {http="<[floodWarning:900000:JSONPATH($.items.currentWarning.message)]"}
Number FloodSev "Flood warning severity [%.1f]" (River) {http="<[floodWarning:900000:JSONPATH($.items.currentWarning.severityLevel)]"}
String FloodSevText "Flood warning severity [%s]" (River) {http="<[floodWarning:900000:JSONPATH($.items.currentWarning.severity)]"}
DateTime FloodUpdate "Time of last update [%1$tT, %1$tF]" (River) {http="<[floodWarning:900000:JSONPATH($.items.currentWarning.timeMessageChanged)]"}
1 Like

Thanks, that’s brilliant. I was wondering about making the same call multiple times but hadn’t looked at how to solve it so I appreciate that.

I’m still not sure why the flood warning doesn’t work. I’ve tried the result of the URL with an online JSONPATH parser and I get the right result but in openHAB, I just get “Uninitialized”

I pasted the response body from http://environment.data.gov.uk/flood-monitoring/id/floodAreas/122WAF933 into a JSONPATH tester, changed the JSONPATH strings to the same as above, and it seemed to work. If you run openHAB in DEBUG mode, it’s possible that you will get back some indication in openhab.log that shines a light.

In the meantime, stay dry! I’m not too far from you and I half expect Noah to float by.

Tried again using the syntax suggested above and it’s now working for area 122WAF933. I’ve therefore edited the URL to refer to my local area, which fortunately doesn’t have a warning out at the moment. The problem is I’m getting errors in the log file because the “current.Warning” can’t be found within the JSON response. With no warning in place, this is expected. Is there a way I can suppress this error as it’s filling up my log file.

Are your log messages like

... transformation throws exception [transformation=JSONPATH(...), response=<whole document> followed by the transformation exception stack trace?

I’ve looked at the options for suppressing log messages:

  • Suppress stack traces from being logged by editing logback.xml and changing the <pattern> to include %nopex:
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%-30.30logger{36}] - %msg%nopex%n</pattern>
  • or to set the HTTP binding log level to OFF:
<logger name="org.openhab.binding.http" level="OFF"/>

But the better answer is to switch to a JavaScript transform JS(currentWarning.js) that evaluates the JSON and handles the case where currentWarning is not present, returning an empty string or a string like “No current warning.”

transform/currentWarning.js (not tested):

(function(json){
  var flood = JSON.parse(json);
  return (typeof flood.items.currentWarning === "undefined") ? "No current warning." : flood.items.currentWarning.message;
})(input)

This may be a just JSON queerie but is Environment Agency related.

Which appears to be a wealth of information for people near rivers/the sea.

Number RiverLevel "River Level [%.3f]" (River) { http="<[http://environment.data.gov.uk/flood-monitoring/id/stations/E14120/items:1800000:JSONPATH($.latestReading.value)]" }

ive checked the JSONPATH string against jsonpath.com which appears to work
? but with my result
[
1.568
]
in square brackets, but my basic ui

Text item=RiverLevel -

a dash, not a value

Ok, couple of bits:
the URL is incorrect
the JSONPATH is incorrect:
Try:

Number RiverLevel "River Level [%.3f]" (River) { http="<[http://environment.data.gov.uk/flood-monitoring/id/stations/E14120:1800000:JSONPATH($.items.measures.latestReading.value)]" }

Good luck

Thanks for your input, i got lost with so many attempts of syntax that looked correct. its still not working, I will get the debug up and see if that helps

What is your item definition now?

Number RiverLevel "River Level [%.3f]" { http="<[http://environment.data.gov.uk/flood-monitoring/id/stations/E14120:1800000:JSONPATH($.items.measures.latestReading.value)]" }

The API description from the Envirionment Agency (https://environment.data.gov.uk/flood-monitoring/doc/reference) states other URL:

Root-URL {root}:

http://environment.data.gov.uk/flood-monitoring

All measures available from a particular Station:

{root}/id/stations/{id}/measures 

With your ID E14120 you get a JSON like this:

{ 
  "@context" : "http://environment.data.gov.uk/flood-monitoring/meta/context.jsonld" ,
  "meta" : { 
    "publisher" : "Environment Agency" ,
    "licence" : "http://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/" ,
    "documentation" : "http://environment.data.gov.uk/flood-monitoring/doc/reference" ,
    "version" : "0.9" ,
    "comment" : "Status: Beta service" ,
    "hasFormat" : [ "http://environment.data.gov.uk/flood-monitoring/id/stations/E14120/measures.csv", "http://environment.data.gov.uk/flood-monitoring/id/stations/E14120/measures.rdf", "http://environment.data.gov.uk/flood-monitoring/id/stations/E14120/measures.ttl", "http://environment.data.gov.uk/flood-monitoring/id/stations/E14120/measures.html" ]
  }
   ,
  "items" : [ { 
    "@id" : "http://environment.data.gov.uk/flood-monitoring/id/measures/E14120-level-stage-i-15_min-mAOD" ,
    "datumType" : "http://environment.data.gov.uk/flood-monitoring/def/core/datumAOD" ,
    "label" : "TOTTON RL - level-stage-i-15_min-mAOD" ,
    "latestReading" : { 
      "@id" : "http://environment.data.gov.uk/flood-monitoring/data/readings/E14120-level-stage-i-15_min-mAOD/2018-03-21T04-30-00Z" ,
      "date" : "2018-03-21" ,
      "dateTime" : "2018-03-21T04:30:00Z" ,
      "measure" : "http://environment.data.gov.uk/flood-monitoring/id/measures/E14120-level-stage-i-15_min-mAOD" ,
      "value" : 1.596
    }
     ,
    "notation" : "E14120-level-stage-i-15_min-mAOD" ,
    "parameter" : "level" ,
    "parameterName" : "Water Level" ,
    "period" : 900 ,
    "qualifier" : "Stage" ,
    "station" : "http://environment.data.gov.uk/flood-monitoring/id/stations/E14120" ,
    "stationReference" : "E14120" ,
    "unit" : "http://qudt.org/1.1/vocab/unit#Meter" ,
    "unitName" : "mAOD" ,
    "valueType" : "instantaneous"
  }
   ]
}

With

JSONPATH($.items[0].latestReading.value)

you get the value, but I get it also in square brackets (checked on http://jsonpath.com/)…

Did a quick search for solution of the square brackets probloem but didn’t find one…

Andreas

Edit: Maybe this could give you a hint…

1 Like
Number RiverLevel "River Level [%.3f]" { http="<[http://environment.data.gov.uk/flood-monitoring/id/stations/E14120:1800000:JSONPATH($.items.measures.latestReading.value)]" }

Works for me:

2018-03-21 07:53:01.937 [vent.ItemStateChangedEvent] - RiverLevel changed from NULL to 1.596

1 Like

Yes mine is working with no alteration, it appears to take a while to “catch up” ? I assumed it was not working correctly due to the delay, and assumed the [ ] I could see were an issue.

Thanks for all the input, I will continue to monitor these values and try a few more

The square bracket are only on the output side of jsonpath.com
They are not returned with the value of the jsonpath transform

Regards

Now if I could figure out a rule to use the min and max ( found on the UK Environment Agency web site) of a river/tide and therefore calculate the % level from the actual level as fetched

some have a range 0.0 - 2.3
some have values -2.7 - 3.0

also trapping null and other errors

Hi, Jeff what exactly do you have in mind, what are the calculations involved?

I’ve found a few local levels from the Environment Agency API I have
manually written some simple rules to flag up the “High levels” using the usual min/max

Could a look up array be used for a list of usual high, against locations, then for example colour yellow at 95% red at 100% or more

I have manually used valuecolor=[>2.26=“Red”] per entry on my items

No, the dynamic appearance with colours on the sitemap is in the sitemap and cannot be referred to an outside array
Your could try to use Habpanel with custom widgets
But that is not my area of expertise

Ive an idea, i have seen items updated via a rule (speedtest for example) so i will take a look at a variation of that