my goal was to receive the current outside weather temperatures from our norwegian weather service (yr.no). This service provides also data for all other locations using the european weather service. I wasn’t too happy to register at weatherundergrood and yahoo data wasn’t that good?
Dataflow: API --> Script (bash) --> XMLtoJSON --> MQTT --> OpenHab Goal: Get the weather data and have the possibility to extract more info of the forecast. Status: Archieved!
Why yr.no/met.no: quite updated weather reports, no registration - free as in beer.
technical gotchas :
large JSON files (without JSONPATH filter) cause out of memory errors using the current binding
#!/bin/bash
# Getting data to MQTT broker
# Location is Karmøy. Where else would you be?
data=$(curl 'https://api.met.no/weatherapi/locationforecast/1.9/?lat=59.2735&lon=5.1941&msl=30' -X GET >/tmp/yr.xml)
#todo move to temporary yr file and utilize parameter
dataJson=$(python /usr/local/bin/openhab/xmltojson.py /tmp/yr.xml)
dataJson="${dataJson:1:${#dataJson}-2}"
echo $dataJson >/tmp/yr.json
#$.weatherdata.product.time[0].@from
#x.weatherdata.product.time[0].location.temperature.@value
mosquitto_pub -t /Yr -f /tmp/yr.json
#utilize this one to find path http://jsonpathfinder.com/
mv /tmp/yr.json /tmp/yr.json.old
mv /tmp/yr.xml /tmp/yr.xml.old
Converting the XML to JSON Script
user@openhab:/usr/local/bin/openhab# cat xmltojson.py
### Extremely simple XML --> JSON Parser
import xmltodict
import pprint
import json
import sys
fileName=sys.argv[1]
with open(fileName) as fd:
doc = xmltodict.parse(fd.read())
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(json.dumps(doc))
Here is how I have created the MQTT channels and linked them to Items:
The data is xml. Why not use the XPATH transformation to extract the correct value, instead of first converting it to json and then using the json path? ^^
David, totally agree. I tried, but my time cap was hit (multiple times) and I found it more useful to have a solution - than not having one :).
My Issue was that the available tools (xmllint) that I have tried didn’t want to play with me. Can you assist with the correct XPATH transformations and i’ll be happy to update my howto / create a new one!
1)utilizing MQTT I could update multiple clients using the same data. HTTP Data will be a “dump only” approach. Having a “mqtt subscriber” in debug mode will give me the possibility to TSHOOT any issues :).
2) MQTT 2.x examples (working) are very few off. So by learning, documenting and sharing I hope to give something back to the community :).
Number temperature_metNo "[%.1f]" {http="<[metNo:10000:XPATH(number(/weatherdata/product/time[1]/location/temperature/@value))]"}
Number humidity_metNo "[%.1f]" {http="<[metNo:10000:XPATH(number(/weatherdata/product/time[1]/location/humidity/@value))]"}
sitemaps/x.sitemap
Text item=temperature_metNo icon="temperature" label="Température extérieur [%.1f °C]"
Text item=humidity_metNo icon="humidity" label="humidité extérieur [%.1f rel%%]"
I’'ve been searching for a simple way to get the data used on Yr.no for my OpenHAB sitemap. Load up XPATH and the HTTP binding, use your sample above and all the data I need is available.
Just one little typo in the met.No.url above. There should be a “?” between “1.9/” and “lat”.
For OH3, this is an example of a textual configuration for getting the snow depth at a particular location in Norway:
Thing http:url:yrmountain "HTTP thing for snow depth" [baseURL="https://frost.met.no/observations", refresh="3600", username="", username="exxxxxx8-9xx8-4xxb-8xxa-ba77xxxxxx8", password=""] {
Channels:
Type number : snowdepth "Snowdepth" [stateExtension="v0.jsonld?sources=SN51800&referencetime=latest&elements=surface_snow_thickness", mode="READONLY",
stateTransformation="JSONPATH:$.data[0].observations[0].value"]
Type number : temperatur "Temperatur" [stateExtension="v0.jsonld?sources=SN51800&referencetime=latest&elements=air_temperature", mode="READONLY",
stateTransformation="JSONPATH:$.data[0].observations[0].value"]
}
and associated items:
Number Snowdepth {channel="http:url:yrmountain:snodybde", expire="48h"}
Number Mountaintemperature {channel="http:url:yrmountain:temperatur", expire="48h"}