I have a robomower at our summer cottage by the sea. I have already lost two robomowers to the sea when the water level rose on to the lawn. My idea is to have OpenHAB monitor the sea water level and send me a telegram message when the sea level rises too high.
Sea level measurements can be obtained from the Finnish Meteorlogical Institue API:
I would like write a rule to call the API every hour and retrieve the latest value, extract the sealevel value, in the above example: 532.0, and compare it to 600 and trigger the telegram binding if 600 is exceeded. The FMI binding does not provide sea level data, so this probably has to be coded by hand, and is beyond my abilities. Once I get the trigger sorted out I do know how to send a telegram message.
The http binding allows you to define a thing based on a url (which you have) and will call that url at intervals that you define. There’s good info on the docs page and tons of examples on the forum for using this binding.
Then you get to define custom channels for that thing (in this case a number type channel) with transformation that convert the data returned by the url call into some viable item state. That’s where the xpath transform comes in. All you’ll need to do is work out the xpath call to extract your information of interest. It should be fairly straightforward in this case. If you need to work it out then just search for an xpath testing site and paste in a sample of the returned xml.
Once that’s all set you just link a number item to the channel as in any other case.
You can do all this though the UI so you don’t need to worry about file-based thing configuration if you don’t already do that.
I tried this, but as this is the first time I attempted using the xpath transformation I was not able to figure out the correct path. Will try this later, as this is an interesting route to solve the challenge, too.
As you’ve already seen from Wolfgang_S’s answer, //BsWfs:ParameterValue is the xpath that gets you all of the results. In xpath you can also directly filter using last() and then extract only the text from the selected element. Probably something like this should work:
There are a couple of things you can always do to troubleshoot the html binding.
Check you logs and make sure the binding isn’t throwing any obvious errors.
Create a basic channel for a string item with no transform on it. Make sure that the string item gets populated by the page content that you expect. If not then you know the problem is the configuration of the binding.
If you can show that the binding is collecting the full returned content into a string item then there’s something wrong with the transform and you can test out the xpath statement with any online xpath tool such as https://www.freeformatter.com/xpath-tester.html
' with function '(XPATH://BsWfs:ParameterValue)[last()]/text()' and format '%s'
2023-08-28 14:56:16.338 [WARN ] [org.eclipse.jetty.http.HttpParser ] - URI is too large >8192
2023-08-28 14:56:16.353 [WARN ] [org.eclipse.jetty.http.HttpParser ] - URI is too large >8192
2023-08-28 14:56:46.200 [WARN ] [.profiles.XPathTransformationProfile] - Could not transform state '<?xml version="1.0" encoding="UTF-8"?>
This works. The item gets populated with the XML file I am looking for.
How to apply the XPATH is still a mystery…
This is what the xpath tool above shows as output:
Execept for the “Text=” this is what I was looking for.
Where should the XPATH be applied? In the channel or item? If so, how?
If Telegram has a place to define a transformation on the Channel, do it there. If not, apply the XPath transform on a Profile on the Link between the Channel and the Item. Or create a Rule and use the transform action.
With the Http binding, that depends entirely on your use case. If you think you are only ever gong to need this one bit of information then, you can apply it to the channel. When you define the channel with the UI, there’s a place right in the wizard to apply the transform:
So, you would make it a number channel and add the XPath transform definition to the channel.
On the other hand if you think that you might want to extra other information someday form this same xml then you should leave the channel as a String Channel, and link a Number Item to it using a profile to apply the transformation:
The HTTP binding can populate multiple channels from one message/document. So even in this case one can define a separate Channel for each piece of data and use a different transform for each to extract all that is desired from the one XML document.