OH3: HTTP-Binding / XPATH - no values

Hello community,
i have a problem with XPath on OH3. I would like to read a value from a website and have created the following thing/channel for it:

UID: http:url:xpath_zamg
label: xpath_zamg
thingTypeUID: http:url
configuration:
  authMode: BASIC
  ignoreSSLErrors: false
  baseURL: https://www.zamg.ac.at/cms/de/wetter/wetterwerte-analysen/tirol
  refresh: 30
  commandMethod: GET
  timeout: 3000
  bufferSize: 2048
location: system
channels:
  - id: location
    channelTypeUID: http:string
    label: Standort
    description: ""
    configuration: {}

According to the log file, i only get the following message:

[INFO ] [inding.http.internal.HttpThingHandler] - Using the secure client for thing 'http:url:xpath_zamg'
[INFO ] [openhab.event.ItemStateChangedEvent  ] - Item 'xpath_zamg_location' changed from NULL to 

I can successfully determine the value via http://xpather.com/

My Link looks like this:

However, no value is displayed:

The XPath Transformation Service is already installed. Does anyone have any idea why this could be?

Many thanks,
greetings Christoph

The documentation only references xml and that is html so maybe the transform doesn’t do html?

I haven’t tried html but I did get xml to work.

1 Like

It should work on HTML but only if it’s xhtml, meaning that it conforms to the XML standard. That means every open tag must have a closing tag and a few other similar requirements. Browsers are not as strict and will be happy to render a page that is missing such things.

But the header shows that the page is claiming to be XHTML so XPath shouldn’t have a problem with it.

Given the data is pulled by the HTTP binding, why not apply the transform there? If there is an error it will be more apparent there as I think the Profile fails silently.

Hi @rlkoshak , thank you for your feedback.
I’ve also read that XHTML should work with XPATH. You mean the XPATH command can be executed directly via the binding? I’ve tried this now and i’m one step further. But now the whole XHTML code is downloaded and the desired value is not selected.

UID: http:url:xpath_zamg
label: xpath_zamg
thingTypeUID: http:url
configuration:
  authMode: BASIC
  ignoreSSLErrors: false
  baseURL: https://www.zamg.ac.at/cms/de/wetter/wetterwerte-analysen/tirol
  delay: 0
  stateMethod: GET
  refresh: 60
  commandMethod: GET
  stateTransformation: XPath://html/body/div/div[2]/div[2]/div[1]/div[1]/div/div[2]/div/div/div[3]/table/tr[3]/td[1]
  timeout: 3000
  bufferSize: 2048
location: system
channels:
  - id: xpath_zamg_location
    channelTypeUID: http:string
    label: Standort
    description: ""
    configuration: {}

From the HTTP-binding i get this log-output with the code from the whole website:

19:16:45.652 [INFO ] [inding.http.internal.HttpThingHandler] - Using the secure client for thing 'http:url:xpath_zamg'.

I’ve already tried the ending /text() /@Value /@* …, unfortunately without success.

That indicates that the actual xpath is not being found. I can’t explain why the online tester works and this does not. Often different programming languages will have slightly different behaviors. Perhaps Java works a little differently.

Hi @rlkoshak, thanks, then i will try another way…
I have now extracted the data via Python-script and BeautifulSoup and saved it in a file. Now i would like to import this output (file) using HTTP binding and output it using an item. In your opinion, is it better to save the data in a csv-file or in a txt-file? (only the values are listed one below the other) Unfortunately, i haven’t found much for OH3 - can i configure everything via the GUI or does a script have to be created for this?

The HTTP binding doesn’t load files. What exactly are you trying to do with the binding here?

The best depends on the nature of the data and your ability to code what needs to load and process that data in a rule.

That’s not an either or. You can create Script Actions in UI rules which is where you write code for a rule. But to load and parse a file you will have to write some code.

I thought, i might be able to load the file via the binding and process the content in OH.

But what i actually want to do, i fetch the content of the website once an hour using a Python-script and save the content in a file. I store this file in a defined location, from which OH reads the content of the file and displays it in/with an item. For example, the content of the file looks like this:

Kitzbühel
767m
28.5°
29 %
Südost, 13 km/h
29 km/h
0.0 mm
81 %
1002.3 hPa

Unfortunately, i don’t really know how to approach this matter. I can certainly look up the individual steps via the forum, but i don’t know what options there are in general and which of them are also useful for my project.
I am currently in the process of familiarizing myself with HABApp, so I would like to implement it in Python if possible.

I can’t help with HABApp. That’s a completely separate rule engine. You definitely cannot use the OH UI to create or manage HABApp rules.

The HTTP binding can only interact with HTTP servers. It can’t load some random file from your file system.

If you are planning on using HABApp you’ll need to learn how to load a file using Python 3 and parse its contents. Then use HABApp features to issue the updates and commands to the relevant Items.

Okay i understand, thanks for the explanation. And if i wanted to do everything with OH, how would that go about here? The rule engine HABApp is not so important to me now, if i could solve this via the internal rule engine, i would honestly prefer that. The only thing that matters to me is that i can do it with Python. The OH Python-binding has already been installed and also works.

Pretty much the same thing. You’ll need to figure out how to load and parse a file in Python and issue updates and commands to the relevant Items.

You’ll most likely want to use GitHub - CrazyIvan359/openhab-helper-libraries: JSR223-Jython scripts and modules for use with openHAB.

You can potentially write a Script Action using Python through MainUI but there are a few limitations and you’ll want the Helper Libraries anyway.

Okay thank you very much! Then i’ll give it a try and if i manage to do it, i’ll share the procedure here.

I’m not sure why you’re messing with files.

You’ve done the hard part, getting the raw data into openHAB.
Manipulating it to extract a value can be done directly in rules, or via a transformation. If you can’t make XPATH work with it, the whole of javascript is available too.

EDIT - the XPATH trouble is about namespace.
The returned webpage includes
<html xmlns="http://www.w3.org/1999/xhtml" lang="de">
so all the enclosed html tags are in that namespace.

I had a play in a rule; XPath with
"/html/head/title/text()"
returns nothing, because it searches for no-namespace tags.
"/*[name()='html']/*[name()='head']/*[name()='title']/text()"
returns Tirol ZAMG from the
<title>Tirol &mdash; ZAMG</title>
section, using namespace.

namespace is discussed in the transformation doc

but I find it hard to follow.

Thank you very much @rossko57 you gave me the right hint, now it works!

For all those who find it a little difficult to create the path, chrome has the option of displaying the XPATH path in the developer tools. You still have to modify the output a bit, but it makes the creation of the path a lot easier.

@boogie, are you able to able to provide any more details on what your final XPATH expression was here?
In the XHTML I am trying to parse through (from my old-ish Brother printer), the XPATH expression should ideally be something like:

/html/body/div/div/div[2]/div[2]/div[2]/div/div/div[2]/form/div[2]/dl/dd[3]/div/table/tbody/tr[2]/td/img/@height

… the specific XHTML fragment of interest looks like:
(in the interests of brevity I have left out much of the rest of the XHTML)

<dt>Toner&#32;Level</dt>
<dd>
	<div id="ink_level">
		<table id="inkLevelMono"
			   summary="ink level">
			<tr>
				<th/>
			</tr>
			<tr>
				<td>
					<img src="../common/images/black.gif"
						 alt="Black"
						 class="tonerremain"
						 height="50"/>
				</td>
			</tr>
			<tr>
				<th>BK</th>
			</tr>
		</table>
	</div>
</dd>

The value that I want is the ‘50’. It is representative of my printer toner quantity remaining.

I have tried expanding out my XPATH string, something like:
"/*[name()='html']/*[name()='body']/*[name()='div']/*[name()='div']/*[name(2)='div']/*[name(2)='div']/ … etc. but that did not seem to work.

The XPATH documentation does not provide any details on how to delve into duplicate tags on the same level of the tree, or how to retrieve properties of tags rather than the text contained within the tags…

Thanks for any insight you can provide!

I have got exactly the same problem… :frowning: maybe @rossko57 can help…

Quick nudge … any feedback here?