[SOLVED] JSON Path weather warnings DWD (Deutscher Wetterdienst)

I think that will not work, because if there is no more warning, the status is not reset.
BTW: I get no ERROR logs if no warning is present.

That is correct, there would have to be a mechanism, that resets the warning when the returned value is null.

Don’t get me wrong but i would suggest you to take a step back and dig a bit deeper into javascript transformation and how the process works first.
It seems that your trying to simply copy past code that has worked for something different before,
without knowing what really happens inside.
Sorry i don’t want to be rude here, but i think it will help you better on long term, if i point you on this.
Otherwise we will end up writing tons of posts that are just corrections for your code snippets.

To give you some details:

We have a working javascript transformation (getDWDjson.js) for the json from dwd.
It handles a json string and provides valid functionality.

Now you want to convert the unix timestamp with unixtime.js and try again to do some JSON stuff.
But this can’t work, because the timestamp is just a string and not a valid json string.

Why is this no json anymore?

Because you have done a jsonpath transformation before.

var String newStart = transform("JSONPATH", "$.start", newString)

This extracted only the timestamp value (as a string) that you wanted out of the json.

So in fact there simply is no JSON anymore you can deal with.
That’s the first mistake here. You have to know what type your value is of.

So this is how i would implement the unix conversion

First i would add the unixtime.js file with a blank function

(function(timeToConvert){
})(input)

My input value will be a timestamp i want to convert, so that is how i name the variable.

Next step is to parse the timestamp, since it is a string and for timestamps we need an integer for the Date constructor.

(function(timeToConvert){
    // You don't need to add * 1000 since the json already delivers milliseconds
    var timeAsInteger = parseInt(timestamp);

    // Timezone offset was already working correct
    var tzoffset = new Date().getTimezoneOffset() * 60000;

    // This was ok too, i just added the integer value and removed the * 1000
    return new Date(timeAsInteger - tzoffset).toISOString();
})(input)

I have tested that here → Edit fiddle - JSFiddle - Code Playground and it seems to produce a valid ISO string.
Please don’t bother about document.getElementById("Test").innerText = dateVal;.
This is just needed in jsfiddle to show the value, you won’t need it in OH.

Maybe you could even simplify the whole function if you don’t use var String´ and newStart.toString` because this way we have to convert/parse the value two times.

Again:
I don’t want to be rude, i just think it doesn’t help you that much to copy corrected snippets over days.
You will be frustrated because there are always new problems each day, which are confusing maybe.
It will help you a lot more, if you can dig a bit deeper into the process of how the transformation is done and what data is passed in which type.

Just to add my grain of salt…
Can we not just put a unix time stamp into the date time item:

rule

var String newStart = transform("JSONPATH", "$.start", newString)
DWD_Unwetter_start.postUpdate(transform("JS", "unixtime.js", newStart))
(function(timeStamp){
	return parseInt(timeStamp / 1000);
})(input)

I am not sure if there is an internal conversion and can’t test it directly since i am not at home now.

The DateTime item itself works with strings
Reference:

Solution without the js transform:

 var String newStart = transform("JSONPATH", "$.start", newString)
    var DateTime time = new DateTime(Long::parseLong(newStart))
    DWD_Unwetter_start.postUpdate(new DateTimeType(time.toString))

As per this post:

1 Like

Hi there,

any ideas why it looks like the following? I guess something is wrong in my rules, but I’m not able to identify that.

My items:

String		DWD_Unwetter_start					"Start: [%s]"				
String		DWD_Unwetter_end					"Ende: [%s]"
String		DWD_Unwetter_level					"Level: [%s]"
String		DWD_Unwetter_description			"Beschreibung: [%s]"
String		DWD_Unwetter_headline				"Betreff: [%s]"
String		DWD_Unwetter_instruction			"Hinweis: [%s]"
String		DWD_Unwetter_event					"Event: [%s]"

my rules

rule "Unwetterwarnung DWD"
when
   Time cron "0 * * ? * *"     
then
	var String jsonString = sendHttpGetRequest("https://www.dwd.de/DWD/warnungen/warnapp/json/warnings.json")
	jsonString = transform("JS", "getDWDjson.js", jsonString)
	DWD_Unwetter_start.postUpdate(transform("JSONPATH","$start",jsonString))
	DWD_Unwetter_end.postUpdate(transform("JSONPATH","$end",jsonString))
	DWD_Unwetter_level.postUpdate(transform("JSONPATH","$level",jsonString))
	DWD_Unwetter_description.postUpdate(transform("JSONPATH","$description",jsonString))
	DWD_Unwetter_headline.postUpdate(transform("JSONPATH","$headline",jsonString))
	DWD_Unwetter_instruction.postUpdate(transform("JSONPATH","$instruction",jsonString))
	DWD_Unwetter_event.postUpdate(transform("JSONPATH","$event",jsonString))
	DWD_Unwetter_last_update.postUpdate(new DateTimeType())
end

my transformation:

(function(jsonString) {
var newString = jsonString.replace('warnWetter.loadWarnings(','');
newString = newString.replace(');','');
var newJSON = JSON.parse(newString);
var jsonResult = "";
if (newJSON.warnings.hasOwnProperty('501000008')) {
    jsonResult =JSON.stringify(newJSON.warnings['501000008'][0]);
} else jsonResult = 'NULL'
return jsonResult;
})(input)

and my sitemap:

Text item=DWD_Unwetter_start
Text item=DWD_Unwetter_end
Text item=DWD_Unwetter_level
Text item=DWD_Unwetter_description
Text item=DWD_Unwetter_headline
Text item=DWD_Unwetter_instruction
Text item=DWD_Unwetter_event

Many thanks!

Matthias

You hav missed all the dots after the $ sign.

Example

$.Start

Hi @Confectrician,

many thanks, that’s it.

Do you know, if it is possible to display a long text completely in BasicUI, e.g. with line breaks?

Best Regards
Matthias

1 Like

No, not that I know of, unfortunately

1 Like

As @vzorglub already stated, i don’t think that this is possible.

You could of course do some string magic and split up the Description to several parts that would fit into basic ui and use several String items for that.
But that is plenty of additional work of course.

NOW here is my final config:

first of all you need the following Add-ons:

/items/DWD_Warnungen.items

DateTime	DWD_Warnung_start			"von: [%1$td.%1$tm.%1$tY %1$tH:%1$tM Uhr]"	<time>			
DateTime	DWD_Warnung_end				"bis: [%1$td.%1$tm.%1$tY %1$tH:%1$tM Uhr]"	<time>
Number		DWD_Warnung_level			"Warnstufe: [MAP(DWD_Warnung.map):%s]"		<dwdwarnung>
String		DWD_Warnung_description			"Beschreibung: [%s]"				<warnung>
String		DWD_Warnung_headline			"Betreff: [%s]"					<warnung>
String		DWD_Warnung_instruction			"Hinweis: [%s]"					<warnung>
String		DWD_Warnung_event			"Event: [%s]"					<warnung>

/transform/DWD_Warnung.map

0=Keine Warnung (0)
1=Wetterwarnung (1)
2=markantes Wetter (2)
3=Unwetterwarnung (3)
4=extremes Unwetter (4)
10=Hitzewarnung (10)

/transform/get_DWD_warnings_json.js

DO NOT FORGET replace WARNCELLID with your WARNCELLID

http://www.dwd.de/DE/leistungen/gds/help/warnungen/cap_warncellids_csv.csv?__blob=publicationFile&v=4

(function(jsonString) {
var newString = jsonString.replace('warnWetter.loadWarnings(','');
newString = newString.replace(');','');
var newJSON = JSON.parse(newString);
var jsonResult = "";
if (newJSON.warnings.hasOwnProperty('WARNCELLID')) {
	jsonResult =JSON.stringify(newJSON.warnings['WARNCELLID'][0]);
} else jsonResult = 'NULL'
return jsonResult;
})(input)

/rules/Update_DWD_Warnungen.rules

rule "DWD Warnungen"
when
	Time cron "0 */5 * ? * *"  //every 5 Minutes
//	Time cron "0 * * ? * *"    //every 1 Minute
then
	var String jsonString = sendHttpGetRequest("https://www.dwd.de/DWD/warnungen/warnapp/json/warnings.json")
	var String newString = transform("JS", "get_DWD_warnings_json.js", jsonString)
	if (newString !="NULL") {
		var String newStart = transform("JSONPATH", "$.start", newString)
		var DateTime timestart = new DateTime(Long::parseLong(newStart))
		DWD_Warnung_start.postUpdate(new DateTimeType(timestart.toString))
		var String newEnd = transform("JSONPATH", "$.end", newString)
		if (newEnd !==null) {
			var DateTime timeend = new DateTime(Long::parseLong(newEnd))
			DWD_Warnung_end.postUpdate(new DateTimeType(timeend.toString))
		}
		DWD_Warnung_level.postUpdate(transform("JSONPATH","$.level",newString))
		DWD_Warnung_description.postUpdate(transform("JSONPATH","$.description",newString))
		DWD_Warnung_headline.postUpdate(transform("JSONPATH","$.headline",newString))
		DWD_Warnung_instruction.postUpdate(transform("JSONPATH","$.instruction",newString))
		DWD_Warnung_event.postUpdate(transform("JSONPATH","$.event",newString))
	}
	if (newString =="NULL") {
		DWD_Warnung_start.postUpdate("NULL")
		DWD_Warnung_end.postUpdate("NULL")
		DWD_Warnung_level.postUpdate(0)
		DWD_Warnung_description.postUpdate("-")
		DWD_Warnung_headline.postUpdate("derzeit keine Warnungen")
		DWD_Warnung_instruction.postUpdate("-")
		DWD_Warnung_event.postUpdate("-")	
	}
end

sitemap

Frame label=" "	{
	Text item=DWD_Warnung_headline	label=""  valuecolor=[DWD_Warnung_level==1="#ffff00", DWD_Warnung_level==2="#ffa500", DWD_Warnung_level==3="#ff0000", DWD_Warnung_level==4="#800000", DWD_Warnung_level==10="#ff00ff"]
	Text item=DWD_Warnung_level  visibility=[DWD_Warnung_level!=0]	valuecolor=[1="#ffff00", 2="#ffa500", 3="#ff0000", 4="#800000", 10=ff00ff"]
	Text item=DWD_Warnung_start  visibility=[DWD_Warnung_start!="NULL"]
	Text item=DWD_Warnung_end  icon="null"  visibility=[DWD_Warnung_end!="NULL"]
}
Frame label=" " {
	Text item=DWD_Warnung_description  visibility=[DWD_Warnung_description!="-"]
	Text item=DWD_Warnung_instruction	icon="null"  visibility=[DWD_Warnung_instruction!="-"]
}
Frame label=" " {
	Text item=DWD_Warnung_event  visibility=[DWD_Warnung_event!="-"]  valuecolor=[DWD_Warnung_level==1="#ffff00", DWD_Warnung_level==2="#ffa500", DWD_Warnung_level==3="#ff0000", DWD_Warnung_level==4="#800000", DWD_Warnung_level==10="#ff00ff"]
}

Here are different screenshots

WARNING LEVEL 3

WARNING LEVEL 2

No WARNINGs

many thanks to @vzorglub @Confectrician for your support

1 Like

Hi, I’m glad you found a solution. I went a totally different way the last few days, and maybe it’s interesting for somebody.
I dont’s use the json file of the DWD, but the xml files which are on a municipality level (Gemeinde statt Landkreis). I display up to 3 different warnings, my dashboard you can see here:

I think the best way would be via xslt, but I didn’t get that to work, that’s why I use a shell script (I’m more familiar with :smiley:)
I use the following items:

/* Wetterwarnungen */
String DWD_Warnung_1_Event "DWD Warn 1 Event [%s]" (gWarnUnwetter)
String DWD_Warnung_2_Event "DWD Warn 2 Event [%s]" (gWarnUnwetter)
String DWD_Warnung_3_Event "DWD Warn 3 Event [%s]" (gWarnUnwetter)
String DWD_Warnung_1_Severity "DWD Warn 1 Severity [%s]" (gWarnUnwetter)
String DWD_Warnung_2_Severity "DWD Warn 2 Severity [%s]" (gWarnUnwetter)
String DWD_Warnung_3_Severity "DWD Warn 3 Severity [%s]" (gWarnUnwetter)
DateTime DWD_Warnung_1_Start "DWD Warn 1 Start [%1$td.%1$tm %1$tH:%1$tM]" (gWarnUnwetter)
DateTime DWD_Warnung_2_Start "DWD Warn 2 Start [%1$td.%1$tm %1$tH:%1$tM]" (gWarnUnwetter)
DateTime DWD_Warnung_3_Start "DWD Warn 3 Start [%1$td.%1$tm %1$tH:%1$tM]" (gWarnUnwetter)
DateTime DWD_Warnung_1_End "DWD Warn 1 End [%1$td.%1$tm %1$tH:%1$tM]" (gWarnUnwetter)
DateTime DWD_Warnung_2_End "DWD Warn 2 End [%1$td.%1$tm %1$tH:%1$tM]" (gWarnUnwetter)
DateTime DWD_Warnung_3_End "DWD Warn 3 End [%1$td.%1$tm %1$tH:%1$tM]" (gWarnUnwetter)
String DWD_Warnung_1_Group "DWD Warn 1 Group [%s]" (gWarnUnwetter)
String DWD_Warnung_2_Group "DWD Warn 2 Group [%s]" (gWarnUnwetter)
String DWD_Warnung_3_Group "DWD Warn 3 Group [%s]" (gWarnUnwetter)
String DWD_Warnung_1_Parameter "DWD Warn 1 Param [%s]" (gWarnUnwetter)
String DWD_Warnung_2_Parameter "DWD Warn 2 Param [%s]" (gWarnUnwetter)
String DWD_Warnung_3_Parameter "DWD Warn 3 Param [%s]" (gWarnUnwetter)
String DWD_Warnung_1_Start_lesbar "DWD Warn 1 Start lb [%s]" (gWarnUnwetter)
String DWD_Warnung_2_Start_lesbar "DWD Warn 2 Start lb [%s]" (gWarnUnwetter)
String DWD_Warnung_3_Start_lesbar "DWD Warn 3 Start lb [%s]" (gWarnUnwetter)
String DWD_Warnung_1_End_lesbar "DWD Warn 1 End lb [%s]" (gWarnUnwetter)
String DWD_Warnung_2_End_lesbar "DWD Warn 2 End lb [%s]" (gWarnUnwetter)
String DWD_Warnung_3_End_lesbar "DWD Warn 3 End lb [%s]" (gWarnUnwetter)
String DWD_Warnung_Max_Severity "DWD Warn Max Severity [%s]" (gWarnUnwetter)

They get updated by the following shell sript (triggered every 5 Minutes via rule or crontab) - warncellid to be adjusted, the number between the two “%27” - starting with an 8

# check current value of Warnung_1_Event
value_old=$(curl -s "http://openhabianpi:8080/rest/items/DWD_Warnung_1_Event/state")
# download xml for warncellid or ids
rm /etc/openhab2/html/dwd/warnings.xml
wget -q -O /etc/openhab2/html/dwd/warnings.xml "https://maps.dwd.de/geoserver/dwd/ows?service=WFS&version=2.0.0&request=GetFeature&typeName=dwd:Warnungen_Gemeinden&CQL_FILTER=WARNCELLID%20IN%20(%27800000000%27)"
if [ ! -s /etc/openhab2/html/dwd/warnings.xml ]; then
	echo "xml-Datei ist leer. Vermutlich kein Internet. Ich geh wieder schlafen..."
	exit
fi
#
# Events
value=$(</etc/openhab2/html/dwd/warnings.xml awk -F"<dwd:EVENT>" '{print $2}' | awk -F"</dwd:EVENT>" '{print $1}')
if [ -n "$value" ]; then
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "$value" "http://openhabianpi:8080/rest/items/DWD_Warnung_1_Event/state"
else
	if [ "$value_old" = "0" ]; then
#		echo "Keine Warnung gefunden, Wert in OH ist schon 0, ich geh wieder schlafen..."
		exit
	fi
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "0" "http://openhabianpi:8080/rest/items/DWD_Warnung_1_Event/state"
fi
value=$(</etc/openhab2/html/dwd/warnings.xml awk -F"<dwd:EVENT>" '{print $3}' | awk -F"</dwd:EVENT>" '{print $1}')
if [ -n "$value" ]; then
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "$value" "http://openhabianpi:8080/rest/items/DWD_Warnung_2_Event/state"
else
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "0" "http://openhabianpi:8080/rest/items/DWD_Warnung_2_Event/state"
fi
value=$(</etc/openhab2/html/dwd/warnings.xml awk -F"<dwd:EVENT>" '{print $4}' | awk -F"</dwd:EVENT>" '{print $1}')
if [ -n "$value" ]; then
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "$value" "http://openhabianpi:8080/rest/items/DWD_Warnung_3_Event/state"
else
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "0" "http://openhabianpi:8080/rest/items/DWD_Warnung_3_Event/state"
fi
#
# Severity
value=$(</etc/openhab2/html/dwd/warnings.xml awk -F"<dwd:SEVERITY>" '{print $2}' | awk -F"</dwd:SEVERITY>" '{print $1}')
if [ -n "$value" ]; then
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "$value" "http://openhabianpi:8080/rest/items/DWD_Warnung_1_Severity/state"
else
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "0" "http://openhabianpi:8080/rest/items/DWD_Warnung_1_Severity/state"
fi
value=$(</etc/openhab2/html/dwd/warnings.xml awk -F"<dwd:SEVERITY>" '{print $3}' | awk -F"</dwd:SEVERITY>" '{print $1}')
if [ -n "$value" ]; then
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "$value" "http://openhabianpi:8080/rest/items/DWD_Warnung_2_Severity/state"
else
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "0" "http://openhabianpi:8080/rest/items/DWD_Warnung_2_Severity/state"
fi
value=$(</etc/openhab2/html/dwd/warnings.xml awk -F"<dwd:SEVERITY>" '{print $4}' | awk -F"</dwd:SEVERITY>" '{print $1}')
if [ -n "$value" ]; then
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "$value" "http://openhabianpi:8080/rest/items/DWD_Warnung_3_Severity/state"
else
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "0" "http://openhabianpi:8080/rest/items/DWD_Warnung_3_Severity/state"
fi
#
# Start
value=$(</etc/openhab2/html/dwd/warnings.xml awk -F"<dwd:ONSET>" '{print $2}' | awk -F"</dwd:ONSET>" '{print $1}')
if [ -n "$value" ]; then
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "$value" "http://openhabianpi:8080/rest/items/DWD_Warnung_1_Start/state"
else
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "2000-01-01T00:00:00Z" "http://openhabianpi:8080/rest/items/DWD_Warnung_1_Start/state"
fi
value=$(</etc/openhab2/html/dwd/warnings.xml awk -F"<dwd:ONSET>" '{print $3}' | awk -F"</dwd:ONSET>" '{print $1}')
if [ -n "$value" ]; then
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "$value" "http://openhabianpi:8080/rest/items/DWD_Warnung_2_Start/state"
else
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "2000-01-01T00:00:00Z" "http://openhabianpi:8080/rest/items/DWD_Warnung_2_Start/state"
fi
value=$(</etc/openhab2/html/dwd/warnings.xml awk -F"<dwd:ONSET>" '{print $4}' | awk -F"</dwd:ONSET>" '{print $1}')
if [ -n "$value" ]; then
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "$value" "http://openhabianpi:8080/rest/items/DWD_Warnung_3_Start/state"
else
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "2000-01-01T00:00:00Z" "http://openhabianpi:8080/rest/items/DWD_Warnung_3_Start/state"
fi
#
# End
value=$(</etc/openhab2/html/dwd/warnings.xml awk -F"<dwd:EXPIRES>" '{print $2}' | awk -F"</dwd:EXPIRES>" '{print $1}')
if [ -n "$value" ]; then
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "$value" "http://openhabianpi:8080/rest/items/DWD_Warnung_1_End/state"
else
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "2000-01-01T00:00:00Z" "http://openhabianpi:8080/rest/items/DWD_Warnung_1_End/state"
fi
value=$(</etc/openhab2/html/dwd/warnings.xml awk -F"<dwd:EXPIRES>" '{print $3}' | awk -F"</dwd:EXPIRES>" '{print $1}')
if [ -n "$value" ]; then
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "$value" "http://openhabianpi:8080/rest/items/DWD_Warnung_2_End/state"
else
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "2000-01-01T00:00:00Z" "http://openhabianpi:8080/rest/items/DWD_Warnung_2_End/state"
fi
value=$(</etc/openhab2/html/dwd/warnings.xml awk -F"<dwd:EXPIRES>" '{print $4}' | awk -F"</dwd:EXPIRES>" '{print $1}')
if [ -n "$value" ]; then
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "$value" "http://openhabianpi:8080/rest/items/DWD_Warnung_3_End/state"
else
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "2000-01-01T00:00:00Z" "http://openhabianpi:8080/rest/items/DWD_Warnung_3_End/state"
fi
#
# Group
value=$(</etc/openhab2/html/dwd/warnings.xml awk -F"<dwd:EC_GROUP>" '{print $2}' | awk -F"</dwd:EC_GROUP>" '{print $1}')
if [ -n "$value" ]; then
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "$value" "http://openhabianpi:8080/rest/items/DWD_Warnung_1_Group/state"
else
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "0" "http://openhabianpi:8080/rest/items/DWD_Warnung_1_Group/state"
fi
value=$(</etc/openhab2/html/dwd/warnings.xml awk -F"<dwd:EC_GROUP>" '{print $3}' | awk -F"</dwd:EC_GROUP>" '{print $1}')
if [ -n "$value" ]; then
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "$value" "http://openhabianpi:8080/rest/items/DWD_Warnung_2_Group/state"
else
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "0" "http://openhabianpi:8080/rest/items/DWD_Warnung_2_Group/state"
fi
value=$(</etc/openhab2/html/dwd/warnings.xml awk -F"<dwd:EC_GROUP>" '{print $4}' | awk -F"</dwd:EC_GROUP>" '{print $1}')
if [ -n "$value" ]; then
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "$value" "http://openhabianpi:8080/rest/items/DWD_Warnung_3_Group/state"
else
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "0" "http://openhabianpi:8080/rest/items/DWD_Warnung_3_Group/state"
fi
#
# Parameter
value=$(</etc/openhab2/html/dwd/warnings.xml awk -F"<dwd:PARAMATERVALUE>" '{print $2}' | awk -F"</dwd:PARAMATERVALUE>" '{print $1}' | sed 's/&lt;/</g' | sed 's/&gt;/>/g')
if [ -n "$value" ]; then
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "$value" "http://openhabianpi:8080/rest/items/DWD_Warnung_1_Parameter/state"
else
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "0" "http://openhabianpi:8080/rest/items/DWD_Warnung_1_Parameter/state"
fi
value=$(</etc/openhab2/html/dwd/warnings.xml awk -F"<dwd:PARAMATERVALUE>" '{print $3}' | awk -F"</dwd:PARAMATERVALUE>" '{print $1}' | sed 's/&lt;/</g' | sed 's/&gt;/>/g')
if [ -n "$value" ]; then
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "$value" "http://openhabianpi:8080/rest/items/DWD_Warnung_2_Parameter/state"
else
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "0" "http://openhabianpi:8080/rest/items/DWD_Warnung_2_Parameter/state"
fi
value=$(</etc/openhab2/html/dwd/warnings.xml awk -F"<dwd:PARAMATERVALUE>" '{print $4}' | awk -F"</dwd:PARAMATERVALUE>" '{print $1}' | sed 's/&lt;/</g' | sed 's/&gt;/>/g')
if [ -n "$value" ]; then
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "$value" "http://openhabianpi:8080/rest/items/DWD_Warnung_3_Parameter/state"
else
	curl -s -X PUT --header "Content-Type: text/plain" --header "Accept: application/json" -d "0" "http://openhabianpi:8080/rest/items/DWD_Warnung_3_Parameter/state"
fi

I use the following rules to improve the readability of the start and end date (make it “lesbar” :grinning:)

rule "Wetterwarnungen lesbarer machen - 1 Start"
when
	Item DWD_Warnung_1_Start changed
then
	val DateTime Start = new DateTime((DWD_Warnung_1_Start.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli)
	val DateTime Start_Tag = new DateTime((DWD_Warnung_1_Start.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli).withTimeAtStartOfDay
	val Long Diff = Math::round((Start_Tag.millis - now.withTimeAtStartOfDay.millis) / (86400000.0))
	val String Uhrzeit = Start.toString.substring(11,16)
	val String Tag = Start.toString.substring(8,10)
	val String Monat = Start.toString.substring(5,7)
	if ( Diff == 0 ) {
		DWD_Warnung_1_Start_lesbar.postUpdate("heute " +Uhrzeit)
	} else if ( Diff == 1 ) {
		DWD_Warnung_1_Start_lesbar.postUpdate("morgen " +Uhrzeit)
	} else if ( Diff == -1 ) {
		DWD_Warnung_1_Start_lesbar.postUpdate("gestern " +Uhrzeit)
	} else {
		DWD_Warnung_1_Start_lesbar.postUpdate(Tag +"." +Monat +". " +Uhrzeit)
	}
	Thread::sleep(3000)
	if (DWD_Warnung_1_Severity.state!="0") {
		if (DWD_Warnung_1_Event.state=="UV-INDEX") {
			sendTelegram("haus_an_mich_bot", "UV-Warnung von %s bis %s", DWD_Warnung_1_Start_lesbar.state.toString, DWD_Warnung_1_End_lesbar.state.toString)
		} else {
			sendTelegram("haus_an_mich_bot", "%s von %s bis %s (%s) [%s]", DWD_Warnung_1_Event.state.toString, DWD_Warnung_1_Start_lesbar.state.toString, DWD_Warnung_1_End_lesbar.state.toString, DWD_Warnung_1_Parameter.state.toString, DWD_Warnung_1_Severity.state.toString)
		}
	}
end

rule "Wetterwarnungen lesbarer machen - 2 Start"
when
	Item DWD_Warnung_2_Start changed
then
	val DateTime Start = new DateTime((DWD_Warnung_2_Start.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli)
	val DateTime Start_Tag = new DateTime((DWD_Warnung_2_Start.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli).withTimeAtStartOfDay
	val Long Diff = Math::round((Start_Tag.millis - now.withTimeAtStartOfDay.millis) / (86400000.0))
	val String Uhrzeit = Start.toString.substring(11,16)
	val String Tag = Start.toString.substring(8,10)
	val String Monat = Start.toString.substring(5,7)
	if ( Diff == 0 ) {
		DWD_Warnung_2_Start_lesbar.postUpdate("heute " +Uhrzeit)
	} else if ( Diff == 1 ) {
		DWD_Warnung_2_Start_lesbar.postUpdate("morgen " +Uhrzeit)
	} else if ( Diff == -1 ) {
		DWD_Warnung_2_Start_lesbar.postUpdate("gestern " +Uhrzeit)
	} else {
		DWD_Warnung_2_Start_lesbar.postUpdate(Tag +"." +Monat +". " +Uhrzeit)
	}
	Thread::sleep(3000)
	if (DWD_Warnung_2_Severity.state!="0") {
		if (DWD_Warnung_2_Event.state=="UV-INDEX") {
			sendTelegram("haus_an_mich_bot", "UV-Warnung von %s bis %s", DWD_Warnung_2_Start_lesbar.state.toString, DWD_Warnung_2_End_lesbar.state.toString)
		} else {
			sendTelegram("haus_an_mich_bot", "%s von %s bis %s (%s) [%s]", DWD_Warnung_2_Event.state.toString, DWD_Warnung_2_Start_lesbar.state.toString, DWD_Warnung_2_End_lesbar.state.toString, DWD_Warnung_2_Parameter.state.toString, DWD_Warnung_2_Severity.state.toString)
		}
	}
end

rule "Wetterwarnungen lesbarer machen - 3 Start"
when
	Item DWD_Warnung_3_Start changed
then
	val DateTime Start = new DateTime((DWD_Warnung_3_Start.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli)
	val DateTime Start_Tag = new DateTime((DWD_Warnung_3_Start.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli).withTimeAtStartOfDay
	val Long Diff = Math::round((Start_Tag.millis - now.withTimeAtStartOfDay.millis) / (86400000.0))
	val String Uhrzeit = Start.toString.substring(11,16)
	val String Tag = Start.toString.substring(8,10)
	val String Monat = Start.toString.substring(5,7)
	if ( Diff == 0 ) {
		DWD_Warnung_3_Start_lesbar.postUpdate("heute " +Uhrzeit)
	} else if ( Diff == 1 ) {
		DWD_Warnung_3_Start_lesbar.postUpdate("morgen " +Uhrzeit)
	} else if ( Diff == -1 ) {
		DWD_Warnung_3_Start_lesbar.postUpdate("gestern " +Uhrzeit)
	} else {
		DWD_Warnung_3_Start_lesbar.postUpdate(Tag +"." +Monat +". " +Uhrzeit)
	}
	Thread::sleep(3000)
	if (DWD_Warnung_3_Severity.state!="0") {
		if (DWD_Warnung_3_Event.state=="UV-INDEX") {
			sendTelegram("haus_an_mich_bot", "UV-Warnung von %s bis %s", DWD_Warnung_3_Start_lesbar.state.toString, DWD_Warnung_3_End_lesbar.state.toString)
		} else {
			sendTelegram("haus_an_mich_bot", "%s von %s bis %s (%s) [%s]", DWD_Warnung_3_Event.state.toString, DWD_Warnung_3_Start_lesbar.state.toString, DWD_Warnung_3_End_lesbar.state.toString, DWD_Warnung_3_Parameter.state.toString, DWD_Warnung_3_Severity.state.toString)
		}
	}
end

rule "Wetterwarnungen lesbarer machen - 1 End"
when
	Item DWD_Warnung_1_End changed
then
	val DateTime Start = new DateTime((DWD_Warnung_1_End.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli)
	val DateTime Start_Tag = new DateTime((DWD_Warnung_1_End.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli).withTimeAtStartOfDay
	val Long Diff = Math::round((Start_Tag.millis - now.withTimeAtStartOfDay.millis) / (86400000.0))
	val String Uhrzeit = Start.toString.substring(11,16)
	val String Tag = Start.toString.substring(8,10)
	val String Monat = Start.toString.substring(5,7)
	if ( Diff == 0 ) {
		DWD_Warnung_1_End_lesbar.postUpdate("heute " +Uhrzeit)
	} else if ( Diff == 1 ) {
		DWD_Warnung_1_End_lesbar.postUpdate("morgen " +Uhrzeit)
	} else if ( Diff == -1 ) {
		DWD_Warnung_1_End_lesbar.postUpdate("gestern " +Uhrzeit)
	} else {
		DWD_Warnung_1_End_lesbar.postUpdate(Tag +"." +Monat +". " +Uhrzeit)
	}
end

rule "Wetterwarnungen lesbarer machen - 2 End"
when
	Item DWD_Warnung_2_End changed
then
	val DateTime Start = new DateTime((DWD_Warnung_2_End.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli)
	val DateTime Start_Tag = new DateTime((DWD_Warnung_2_End.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli).withTimeAtStartOfDay
	val Long Diff = Math::round((Start_Tag.millis - now.withTimeAtStartOfDay.millis) / (86400000.0))
	val String Uhrzeit = Start.toString.substring(11,16)
	val String Tag = Start.toString.substring(8,10)
	val String Monat = Start.toString.substring(5,7)
	if ( Diff == 0 ) {
		DWD_Warnung_2_End_lesbar.postUpdate("heute " +Uhrzeit)
	} else if ( Diff == 1 ) {
		DWD_Warnung_2_End_lesbar.postUpdate("morgen " +Uhrzeit)
	} else if ( Diff == -1 ) {
		DWD_Warnung_2_End_lesbar.postUpdate("gestern " +Uhrzeit)
	} else {
		DWD_Warnung_2_End_lesbar.postUpdate(Tag +"." +Monat +". " +Uhrzeit)
	}
end

rule "Wetterwarnungen lesbarer machen - 3 End"
when
	Item DWD_Warnung_3_End changed
then
	val DateTime Start = new DateTime((DWD_Warnung_3_End.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli)
	val DateTime Start_Tag = new DateTime((DWD_Warnung_3_End.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli).withTimeAtStartOfDay
	val Long Diff = Math::round((Start_Tag.millis - now.withTimeAtStartOfDay.millis) / (86400000.0))
	val String Uhrzeit = Start.toString.substring(11,16)
	val String Tag = Start.toString.substring(8,10)
	val String Monat = Start.toString.substring(5,7)
	if ( Diff == 0 ) {
		DWD_Warnung_3_End_lesbar.postUpdate("heute " +Uhrzeit)
	} else if ( Diff == 1 ) {
		DWD_Warnung_3_End_lesbar.postUpdate("morgen " +Uhrzeit)
	} else if ( Diff == -1 ) {
		DWD_Warnung_3_End_lesbar.postUpdate("gestern " +Uhrzeit)
	} else {
		DWD_Warnung_3_End_lesbar.postUpdate(Tag +"." +Monat +". " +Uhrzeit)
	}
end

rule "Wetterwarnungen - Max Severity"
when
	Item DWD_Warnung_1_Severity changed or
	Item DWD_Warnung_2_Severity changed or
	Item DWD_Warnung_3_Severity changed or
	Item DelayedStartup changed from OFF to ON
then
	var String MaxSeverity = "0"
	if((DWD_Warnung_1_Severity.state=="Minor") || (DWD_Warnung_2_Severity.state=="Minor") || (DWD_Warnung_3_Severity.state=="Minor")) {
		MaxSeverity = "Minor"
	}
	if((DWD_Warnung_1_Severity.state=="Moderate") || (DWD_Warnung_2_Severity.state=="Moderate") || (DWD_Warnung_3_Severity.state=="Moderate")) {
		MaxSeverity = "Moderate"
	}
	if((DWD_Warnung_1_Severity.state=="Severe") || (DWD_Warnung_2_Severity.state=="Severe") || (DWD_Warnung_3_Severity.state=="Severe")) {
		MaxSeverity = "Severe"
	}
	if((DWD_Warnung_1_Severity.state=="Extreme") || (DWD_Warnung_2_Severity.state=="Extreme") || (DWD_Warnung_3_Severity.state=="Extreme")) {
		MaxSeverity = "Extreme"
	}
	DWD_Warnung_Max_Severity.postUpdate(MaxSeverity)
end

And finally, that stuff is displayes in a custom widget (with a blinking icon if there’s a warning):
wetterwarnungen.widget.json (9.6 KB)
(for a preview please see my first link of this post)

So, have fun :sunglasses: and if you have an improvement, I’d be happy if you share it :grinning:

1 Like

Hello Jochen,

your script is great!

I’m trying to learn from it and therefore running only this command:

wget -q -O /home/user/warnings.xml "https://maps.dwd.de/geoserver/dwd/ows?service=WFS&version=2.0.0&request=GetFeature&typeName=dwd:Warnungen_Gemeinden&CQL_FILTER=WARNCELLID%20IN%20(%27112065000%27)"

At this time, i put in a warncell ID form Link DWD with a actual warning: “112065000”

But with “cat warnings.xml”, there seems to be no warning in this xml file. Can you please give me a hint? Thank you!

Richard

Hi Richard,
I think you need the warncell-id of your “Gemeinde”, starting with 7 or 8. It’s described here:


Especially pages 10-13 will help.
And the file with the IDs you find here:
https://www.dwd.de/DE/leistungen/opendata/help/warnungen/cap_warncellids_csv.csv

Sorry, I missed that part… Well, if there is no warning at the moment, there’s no warning in the file.
At the moment, there’s a warning for example in Torgau, warncell-id 814730310 (until 15:00). That’s what I did during debugging - look where’s a warning at the moment in insert that id.

That’s what my xml looks like if there’s no warning at the moment:

<?xml version="1.0" encoding="UTF-8"?><wfs:FeatureCollection xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dwd="http://www.dwd.de" xmlns:wfs="http://www.opengis.net/wfs/2.0" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" numberMatched="0" numberReturned="0" timeStamp="2018-07-12T09:15:01.908Z" xsi:schemaLocation="http://www.dwd.de https://maps.dwd.de:443/geoserver/dwd/wfs?service=WFS&amp;version=2.0.0&amp;request=DescribeFeatureType&amp;typeName=dwd%3AWarnungen_Gemeinden http://www.opengis.net/wfs/2.0 https://maps.dwd.de:443/geoserver/schemas/wfs/2.0/wfs.xsd http://www.opengis.net/gml/3.2 https://maps.dwd.de:443/geoserver/schemas/gml/3.2.1/gml.xsd"/>

Then the script set all the values to 0 (and the dates I tink to 1.1.2000 or something, but that wouldn’t be necessary at all as the widget only checks the item “…event”)

Thank you @The-Elk for the great tutorial. Can you please provide the images files for the DWD icons you are using in your sitemap?

Regards

Philipp

here:

dwd
dwdwarnung-0dwdwarnung-1dwdwarnung-3

dwdwarnungdwdwarnung-4dwdwarnung-2
warnung

1 Like

And the warning triangles are from the DWD homepage?

Hello Stefan,

i renamed the icons like this:

DWD%20Unwetter%20Icons

(and copied them to /icons/classic, seemed to take a while, till they are shown up in the UI. Also: watch out for the Option “Vector oder Bitmap” File in PaperUI!)

I’m struggeling with the blue “DWD Icon”. In your upper post, that one with the screenshots of your sitemaps, your are using it in the first frame of your sitemap: (Blue Icon, “Wetter”, Dropdown Box “Warnungen”).

What is behind this frame? What item are you using?

Best regards
Richard

It is a proxy Item for several visibility frames like “Warnungen” “Pollenflug” etc.