Template Example: Weather Binding

template
Tags: #<Tag:0x00007f6ce47a3638>

(Andy) #42

Hi @opus,

The section of code that displays the image files is:

<img src="{{ServerPath}}/images/{{IconSet}}/{{itemValue('Condition0').replace(' ','-') | lowercase }}.png"/>

It essentially points to the **file location** + **path** + **file name of the image file**. In addition any spaces in the condition value are replaced by hyphen (-) characters and the string is converted to lowercase so that it matches the icon names that are used in the original openHAB v1 solution. For example, if the weather condition is **Partly Cloudy Day** then the img src string generated at runtime would be:

<img src="http://192.168.4.34:8080/static/images/flat_white/partly-cloudy-day.png"/>

Because you are using German, the condition name will no longer match the name of the image file when it is "inserted" into the **img src** string at runtime. I think you have two choices: Method1: Rename the image files to match the German condition values. Remember to substitute spaces with hyphens and remove any brackets ( and ). There does not appear to be a way to get a definitive list of these values in any language and be aware that some of the lists you will find on the internet do not seem to be accurate / reflect the values coming back from the API today! Method 2: Rename the image files to use the condition ID numbers. These are listed in English at [https://developer.yahoo.com/weather/documentation.html#codes](https://developer.yahoo.com/weather/documentation.html#codes). In addition you would need to add three new items:

String   Condition_ID0  "Condition id [%s]"  {weather="locationId=[your location], forecast=0, type=condition, property=id"}
String   Condition_ID1  "Condition id [%s]"  {weather="locationId=[your location], forecast=1, type=condition, property=id"}
String   Condition_ID2  "Condition id [%s]"  {weather="locationId=[your location], forecast=2, type=condition, property=id"}

and change the four **img src ** code lines:

from:
<img src="{{ServerPath}}/images/{{IconSet}}/{{itemValue('Condition0').replace(' ','-') | lowercase }}.png"/>

to:
<img src="{{ServerPath}}/images/{{IconSet}}/{{itemValue('Condition_ID0').replace(' ','-') | lowercase }}.png"/>

The second method works well (tested on my set-up) and would provide a solution for any language, just needs some time to go through all the icon files to rename them. If I get a chance I will try and get this done.

Sorry that neither of these solutions is very elegant. Some of the limitations come from the original approach of converting the original v1 code for use in HABpanel re-using as much of the original work as possible. I was and am still learning how to do these things better.

Regards, Andy


(Andy) #43

Grrrr... don't know why all my formatting as disappeared... hopefully still readable...


(Jürgen Baginski) #44

Thanks for the input, will go for the ID-version.


(Andy) #45

Here is a quick script which will rename the icons to match the appropriate Condition ID number.

These cover the ID numbers that were represented in the original icon sets. I am assuming that you will not be too worried that Tornado was always missing... I guess these are as rare in Germany as here in the UK :wink:

The script is written to run from a Windows PC with the file executed within the directory where your chosen icon set is located. I simply mapped a drive to run on Windows to my raspberry pi install etc.

Hope this helps. Andy

COPY storm.png 1.png
COPY thunder.png 4.png
COPY rain-and-snow.png 5.png
COPY rain-and-sleet.png 6.png
COPY snow-and-sleet.png 7.png
COPY freezing-drizzle.png 8.png
COPY freezing-rain.png 10.png
COPY few-showers.png 11.png
COPY rain.png 12.png
COPY snow-flurries.png 13.png
COPY light-snow.png 14.png
COPY blowing-snow.png 15.png
COPY snow.png 16.png
COPY sleet.png 18.png
COPY dust.png 19.png
COPY fog.png 20.png
COPY wind.png 24.png
COPY cloudy.png 26.png
COPY mostly-cloudy-night.png 27.png
COPY mostly-cloudy-day.png 28.png
COPY partly-cloudy-night.png 29.png
COPY partly-cloudy-day.png 30.png
COPY clear-night.png 31.png
COPY sunny.png 32.png
COPY hot.png 36.png
COPY scattered-thundershowers.png 47.png
COPY scattered-thunder.png 38.png
COPY scattered-thunder.png 39.png
COPY scattered-showers.png 40.png
COPY thundershower.png 45.png
COPY snow-showers.png 46.png
COPY unknown.png 3200.png


(Tom Araya) #46

Hi Ben, your weather widget looks awesome. it would be great if you would share it! Thanks


(Markus Schneider) #47

Hello,

I'm having a Problem with the data from wunderground.
From about 17 o'clock to midnight there is no max temperature delivered.

It looks bad:

How to handle this?


(Andy) #48

Try this... I have the same problem with occasional UNDEF (undefined items). The reason they do not render correctly on screen (or just display UNDEF) is the formatting functions that error when they do not receive a number or date, as input that they expect.

Note: this code used the numeric Condition_IDn icon names discussed above. If you want to use the icons as originally supplied replace these with Condition0 etc.

Sorry for being a bit slow to respond... been busy trying to take over the authoring of the TiVo binding. Another learning curve :wink:

Hope this helps... Andy

<div ng-init="ServerPath='../static'; IconSet='flat_colorful'">
<link rel="stylesheet" type="text/css" href="{{ServerPath}}/layouts/example.css" />
</div>

<table id="weather-table">
	<tr>
		<td colspan="4" ng-if="itemValue('ObservationTime0')!='UNDEF'">My Weather {{itemValue('ObservationTime0') | date:'short'}}</td>
		<td colspan="4" ng-if="itemValue('ObservationTime0')=='UNDEF'">My Weather --/--/----</td>
	</tr>
	<tr>
		<td rowspan="2" colspan="2" ng-if="itemValue('Condition0')!='UNDEF'"><img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/{{itemValue('Condition_ID0').replace(' ','-') | lowercase }}.png"/></td>
		<td rowspan="2" colspan="2" ng-if="itemValue('Condition0')=='UNDEF'"><img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/3200.png"/></td>
		<td colspan="2" id="weather-temp"  align="left" ng-if="itemValue('Temperature')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temperature')}}<font id="weather-temp-sign">°C</font></td>
		<td colspan="2" id="weather-temp"  align="left" ng-if="itemValue('Temperature')=='UNDEF'">--</td>
	</tr>
	<tr>
		<td colspan="2">
			<table id="weather-table-details">
				<tr>
					<td>Humidity:</td>
					<td ng-if="itemValue('Humidity')!='UNDEF'">{{itemValue('Humidity')}} %</td>
					<td ng-if="itemValue('Humidity')=='UNDEF'">-- %</td>
				</tr>
				<tr>
					<td>Pressure:</td>
					<td ng-if="itemValue('Pressure')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Pressure') / 1000}} MPa</td>
					<td ng-if="itemValue('Pressure')=='UNDEF'">-- MPa</td>
				</tr>
			</table>
		</td>
	</tr>
	<tr colspan="4">
	 <td height="20"></td>
	</tr>
	<tr>
		<td/>
		<td>Today</td>
		<td ng-if="itemValue('ObservationTime1')!='UNDEF'">{{itemValue('ObservationTime1') | date:'EEEE'}}</td>
		<td ng-if="itemValue('ObservationTime1')=='UNDEF'">--</td>
		<td ng-if="itemValue('ObservationTime2')!='UNDEF'">{{itemValue('ObservationTime2') | date:'EEEE'}}</td>
		<td ng-if="itemValue('ObservationTime2')=='UNDEF'">--</td>
	</tr>
	<tr>
		<td/>
		<td ng-if="itemValue('Condition_ID0')!='UNDEF'">
			<img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/{{itemValue('Condition_ID0').replace(' ','-') | lowercase }}.png"/>
			<p> {{itemValue('Condition0')}} </p>
		</td>
		<td ng-if="itemValue('Condition_ID0')=='UNDEF'">
			<img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/3200.png"/>
			<p>--</p>
		</td>
		<td ng-if="itemValue('Condition_ID1')!='UNDEF'">
			<img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/{{itemValue('Condition_ID1').replace(' ','-') | lowercase }}.png"/>
			<p> {{itemValue('Condition1')}} </p>
		</td>
		<td ng-if="itemValue('Condition_ID1')=='UNDEF'">
			<img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/3200.png"/>
			<p>--</p>
		</td>
				<td ng-if="itemValue('Condition_ID2')!='UNDEF'">
			<img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/{{itemValue('Condition_ID2').replace(' ','-') | lowercase }}.png"/>
			<p> {{itemValue('Condition2')}} </p>
		</td>
		<td ng-if="itemValue('Condition_ID2')=='UNDEF'">
			<img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/3200.png"/>
			<p>--</p>
		</td>
	</tr>
	<tr>
		<td class="col-xs-4" style="color:red">Max</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max0')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Max0')}} °C</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max0')=='UNDEF'">-- °C</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max1')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Max1')}} °C</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max1')=='UNDEF'">-- °C</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max2')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Max2')}} °C</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max2')=='UNDEF'">-- °C</td>
	</tr>
	<tr>
		<td class="col-xs-4" style="color:#0db9f0">Min</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min0')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Min0')}} °C</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min0')=='UNDEF'">-- °C</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min1')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Min1')}} °C</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min1')=='UNDEF'">-- °C</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min2')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Min2')}} °C</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min2')=='UNDEF'">-- °C</td>
	</tr>
</table>

LOL and while I was writing this, my own config went wrong... so here is a pic of what you get when an item is Undefined (UNDEF) :slight_smile:


(Nathan Wilcox) #49

Hi All,

I'm new to all this, so I thought this would be a great starting position for me but I seem to be falling down somewhere.

I've run through all of the above and believe I have copied it all. I've had to create the default.items file with the details in.

I've configured my weather.cfg to look like the following

and used the HTML code in the widget

<div ng-init="ServerPath='http://192.168.1.125:8080/static'; IconSet='flat_white'">
<link rel="stylesheet" type="text/css" href="{{ServerPath}}/openHAB-conf/html/layouts/example.css" />
</div>

<div id="weather-location-name" >
	My Weather {{itemValue('ObservationTime0') | date:'short'}} 
</div>

<table id="weather-table">
	<tr>
		<td rowspan="2"><img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/{{itemValue('Condition0').replace(' ','-') | lowercase }}.png"/></td>
		<td id="weather-temp">{{'%.1f' | sprintf:itemValue('Temperature')}}</td>
		<td id="weather-temp-sign">°C</td>
	</tr>
	<tr>
		<td colspan="2">
			<table id="weather-table-details">
				<tr>
					<td>Humidity:</td>
					<td>{{itemValue('Humidity')}} %</td>
				</tr>
				<tr>
					<td>Pressure:</td>
					<td>{{'%.0f' | sprintf:itemValue('Pressure') / 1000}} MPa</td>
				</tr>
			</table>
		</td>
	</tr>
</table>
<p/>
<table id="weather-forecast-table">
	<tr>
		<td/>
		<td>Today</td>
		<td>{{itemValue('ObservationTime1') | date:'EEEE'}}</td>
		<td>{{itemValue('ObservationTime2') | date:'EEEE'}}</td>
	</tr>
	<tr>
		<td/>
		<td>
			<img src="{{ServerPath}}/images/{{IconSet}}/{{itemValue('Condition0').replace(' ','-') | lowercase }}.png"/>
			<p>{{itemValue('Condition0')}}</p>
		</td>
		<td>
			<img src="{{ServerPath}}/images/{{IconSet}}/{{itemValue('Condition1').replace(' ','-') | lowercase }}.png"/>
			<p>{{itemValue('Condition1')}}</p>
		</td>
		<td>
			<img src="{{ServerPath}}/images/{{IconSet}}/{{itemValue('Condition2').replace(' ','-') | lowercase }}.png"/>
			<p>{{itemValue('Condition2')}}</p>
		</td>
	</tr>
	<tr>
		<td class="col-xs-4" style="color:red">Max</td>
		<td class="col-xs-4" style="color:red">{{'%.0f' | sprintf:itemValue('Temp_Max0')}} °C</td>
		<td class="col-xs-4" style="color:red">{{'%.0f' | sprintf:itemValue('Temp_Max1')}} °C</td>
		<td class="col-xs-4" style="color:red">{{'%.0f' | sprintf:itemValue('Temp_Max2')}} °C</td>
	</tr>
	<tr>
		<td class="col-xs-4" style="color:#0db9f0">Min</td>
		<td class="col-xs-4" style="color:#0db9f0">{{'%.0f' | sprintf:itemValue('Temp_Min0')}} °C</td>
		<td class="col-xs-4" style="color:#0db9f0">{{'%.0f' | sprintf:itemValue('Temp_Min1')}} °C</td>
		<td class="col-xs-4" style="color:#0db9f0">{{'%.0f' | sprintf:itemValue('Temp_Min2')}} °C</td>
	</tr>
</table>

But I end up with this:

Any help will be greatly appreciated!


(Andy) #50

Hi Nathan,

I can't see anything wrong with the configuration (but sometimes this is hard as a single character error is all it takes sometimes). Based on your screenshots I think that the template is working (you would usually loose something of the 'structure' of the template if there was an error in the HTML). In your image the structure is OK, just all the data is missing :frowning:

As you will see from my previous post, there is a new set of HTML that "hides" the error codes when data is not being returned by the binding (in the logs these come back as UNDEF). I would suggest that you use that. If you see double hyphens everywhere then all of your items are UNDEF (Undefined).

First, this would then point to the configuration of your weather.cfg.

I would also look at the frequency 5 is low and you may have exceeded the limit on the number of queries permitted per day. I don't use that provider but the other two I have tried have limits.

BTW, you may want to hide your API key as this is usually personal to you (you can edit your post). If the number of queries are limited, it would be frustrating to find out someone else was using them all up :wink:

You could also try another provider. Yahoo is free etc. See if you get anything different.

Check for the initialisation of the binding in the openHAB logs. You should look for something like this (not real API)

2017-01-17 10:53:41.730 [INFO ] [eather.internal.common.WeatherConfig] - ProviderConfig[providerName=WORLDWEATHERONLINE,apiKey=000000000000000000]
2017-01-17 10:53:41.734 [INFO ] [eather.internal.common.WeatherConfig] - LocationConfig[providerName=WORLDWEATHERONLINE,language=gb,updateInterval=20,latitude=00.0000,longitude=-0.0000,woeid=00000,locationId=Stevenage,name=Stevenage]

After that scan for some items being set or any errors / warnings. They should point you in the right direction.

I would also just test using a simple, dummy widget for say Temperature in HABpanel. In simple terms as soon as you can get one item working then getting the rest should be easy.

Sorry can't pinpoint it in one. Hope this helps, Andy


(Jürgen Baginski) #51

In what directory did you put the weather. Html ?

Edit: Forget it, I missed that the question was concerning habpanel.


(Frank Reeth) #52

@Nathan_Wilcox: I had the same problem. My solution: rewrite the item values. For example "{{itemValue('Humidity')}}" to "{{itemValue(config.Humidity)}}".


(Markus Michels) #53

@AndyMB could please please post a consistent zip containing all data, icons, templates etc. This makes it much more easier to get a clean setup. Copying partly peaces of this post "guarantees" that something is copied wrong. I also struggle to find the correct setup for German, even using the ID concept. Many thanks in advance, Markus
by the way: I'm using OH2RC1 - is there any way to get more debugging on a OH2 with Weather 1.9?


(Andy) #56

Markus, sorry, I wont be providing a download because:

  • the original icons are part of someone else's work and I would not feel comfortable repackaging them
  • the effort to cut / paste from screen is the same as to do the same cut / paste operations from file. I would always suggest using a PC/MAC to do this rather than a tablet or mobile device though.
  • there are so many different permutations and languages to support I could be updating forever (unless you are offering to pay me to do it ?? :wink:)

The first post has been updated many times with (hopefully) all of the changes / improvements that people have suggested. If I missed something good you only have to shout!

This excludes the language changes, simple because we only have a "dirty" solution right now.

Having said that here is the template HTML code with language support for German days:

<div ng-init="ServerPath='../static'; IconSet='flat_colorful'; daynames={'Sunday': 'Sonntag', 'Monday': 'Montag', 'Tuesday': 'Dienstag', 'Wednesday': 'Mittwoch', 'Thursday': 'Donnerstag', 'Friday': 'Freitag', 'Saturday': 'Samstag', 'Sunday': 'Sonntag'}">
<link rel="stylesheet" type="text/css" href="{{ServerPath}}/layouts/example.css" />
</div>

<table id="weather-table">
	<tr>
		<td colspan="4" ng-if="itemValue('ObservationTime0')!='UNDEF'">My Weather {{itemValue('ObservationTime0') | date:'short'}}</td>
		<td colspan="4" ng-if="itemValue('ObservationTime0')=='UNDEF'">My Weather --/--/----</td>
	</tr>
	<tr>
		<td rowspan="2" colspan="2" ng-if="itemValue('Condition0')!='UNDEF'"><img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/{{itemValue('Condition_ID0').replace(' ','-') | lowercase }}.png"/></td>
		<td rowspan="2" colspan="2" ng-if="itemValue('Condition0')=='UNDEF'"><img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/3200.png"/></td>
		<td colspan="2" id="weather-temp"  align="left" ng-if="itemValue('Temperature')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temperature')}}<font id="weather-temp-sign">°C</font></td>
		<td colspan="2" id="weather-temp"  align="left" ng-if="itemValue('Temperature')=='UNDEF'">--</td>
	</tr>
	<tr>
		<td colspan="2">
			<table id="weather-table-details">
				<tr>
					<td>Humidity:</td>
					<td ng-if="itemValue('Humidity')!='UNDEF'">{{itemValue('Humidity')}} %</td>
					<td ng-if="itemValue('Humidity')=='UNDEF'">-- %</td>
				</tr>
				<tr>
					<td>Pressure:</td>
					<td ng-if="itemValue('Pressure')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Pressure') / 1000}} MPa</td>
					<td ng-if="itemValue('Pressure')=='UNDEF'">-- MPa</td>
				</tr>
			</table>
		</td>
	</tr>
	<tr colspan="4">
	 <td height="20"></td>
	</tr>
	<tr>
		<td/>
		<td>Today</td>
		<td ng-if="itemValue('ObservationTime1')!='UNDEF'">{{daynames[(itemValue('ObservationTime1') | date:'EEEE')]}}</td>
		<td ng-if="itemValue('ObservationTime1')=='UNDEF'">--</td>
		<td ng-if="itemValue('ObservationTime2')!='UNDEF'">{{daynames[(itemValue('ObservationTime2') | date:'EEEE')]}}</td>
		<td ng-if="itemValue('ObservationTime2')=='UNDEF'">--</td>
	</tr>
	<tr>
		<td/>
		<td ng-if="itemValue('Condition_ID0')!='UNDEF'">
			<img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/{{itemValue('Condition_ID0').replace(' ','-') | lowercase }}.png"/>
			<p> {{itemValue('Condition0')}} </p>
		</td>
		<td ng-if="itemValue('Condition_ID0')=='UNDEF'">
			<img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/3200.png"/>
			<p>--</p>
		</td>
		<td ng-if="itemValue('Condition_ID1')!='UNDEF'">
			<img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/{{itemValue('Condition_ID1').replace(' ','-') | lowercase }}.png"/>
			<p> {{itemValue('Condition1')}} </p>
		</td>
		<td ng-if="itemValue('Condition_ID1')=='UNDEF'">
			<img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/3200.png"/>
			<p>--</p>
		</td>
				<td ng-if="itemValue('Condition_ID2')!='UNDEF'">
			<img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/{{itemValue('Condition_ID2').replace(' ','-') | lowercase }}.png"/>
			<p> {{itemValue('Condition2')}} </p>
		</td>
		<td ng-if="itemValue('Condition_ID2')=='UNDEF'">
			<img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/3200.png"/>
			<p>--</p>
		</td>
	</tr>
	<tr>
		<td class="col-xs-4" style="color:red">Max</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max0')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Max0')}} °C</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max0')=='UNDEF'">-- °C</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max1')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Max1')}} °C</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max1')=='UNDEF'">-- °C</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max2')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Max2')}} °C</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max2')=='UNDEF'">-- °C</td>
	</tr>
	<tr>
		<td class="col-xs-4" style="color:#0db9f0">Min</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min0')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Min0')}} °C</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min0')=='UNDEF'">-- °C</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min1')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Min1')}} °C</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min1')=='UNDEF'">-- °C</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min2')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Min2')}} °C</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min2')=='UNDEF'">-- °C</td>
	</tr>
</table>

This version uses the Condition IDn (where n is the forecast day number 0,1,2 etc) format, so the icons will display whatever language you select in the weather binding. Remember to rename the icons from the condition name format to a number (see my previous post).

The weather binding configuration file will need the following added / changed to translate the weather 'Condition...' items (the words) into German.
location.<locationId1>.language=de

To use this code for another language you only need to amend the first line and change:
daynames={'Sunday': 'Sonntag', 'Monday': 'Montag', 'Tuesday': 'Dienstag', 'Wednesday': 'Mittwoch', 'Thursday': 'Donnerstag', 'Friday': 'Freitag', 'Saturday': 'Samstag', 'Sunday': 'Sonntag'}'

Replacing the German day names with the language of your choice.

Other than these two changes, the rest of the instructions in the first post should get you to a working solution.

Hope this helps.

Sorry not aware of any way to do this (others may know this). It may not be possible as it was developed for the previous version of OH etc. I did not develop this, so I can't help very much with general questions about the binding.

I hope someone out there is working on a v2.0. But right now I'm struggling to get the TiVo binding, that I have adopted working... so no time to even thing about that :wink:

Good luck and do let us know how you get on. It's always helpful when other people confirm that stuff works as there are so many ways this can be configured and I only have my one English :wink: setup to test with.

Andy


(Nic P) #57

Hi Ben, Are you planning on sharing this code, very interested in your weather widget!


(Jay) #58

Hi! Great post!

Unfortunately my data is showing as "Light snow (1–2 cm.) throughout the day." Any way to strip that do do something so it works nice with the icons??

thanks!!


(Jay) #59

Ok, forecastio/opensky api uses long descriptions on all forecasts except current so that's my issue.. Is their a fix or do i need to change providers is the question now... ;(


(Andy) #60

Hi Jay,

I sympathise, it's become incresingly apparent that the named icons are problematic even before we get into multiple language support. Hindsight is a wonderful thing.

In the original solution, a transformation .map file was provided. This would have been the obvios location to normalise the names to match the icon file names. Sadly not an option right now with HABpanel.

Before looking for something more complex, I would see if the Condition ID fields are populated. If so, then the code above that uses these numbers and the icons renamed as numbers would be the path of least resistance.

Alternatively you could simply copy the icons to match each of the new names that happen over time, tedious but low tech :wink: Depends on how complex the condition names they supply turns out to be.

You could also use the technique used in the day mapping code / language translation above. Could get complicated but that again depends on how complex the descrptions turn out to be.

If all else fails, then maybe another provider would be the way to go.

Let us know how you get on.

Regards, Andy


(Jay) #61

I forgot i already had a wunderground api key set with Forecastio also. I just switched to wunderground instead and all is fixed.


(Rob Pope) #62

Has anybody using Wunderground as their source managed to use the Condition ID format for icons? I always seem to get undef as my value.


(Mark Herwege) #63

I was struggling with icons all the time myself. The condition names are different by provider and are also different by language. But the condition ID's would also be different by provider.
I am now using the Weather Underground 2.0 binding, which is not in the distribution yet, but you can find a link in this PR #2748. It contains a channel providing a link to the weather condition icon from Wunderground. I use that icon in the template. It may not look quit as nice, but it works perfectly well for me.

You will need to have the corresponding items in the panel definition below. I set them all up through PaperUI.

Here is my dashboard code:

<div ng-init="ServerPath='../static/weather-data'; IconSet='flat_colorful'">
<link rel="stylesheet" type="text/css" href="{{ServerPath}}/layouts/example.css" />
</div>

<div ng-init="daysnames={'Sunday': 'Zondag', 'Monday': 'Maandag', 'Tuesday': 'Dinsdag', 'Wednesday' : 'Woensdag', 'Thursday' : 'Donderdag', 'Friday' : 'Vrijdag', 'Saturday' : 'Zaterdag'}">
</div>

<table id="weather-table">
	<tr>
		<td colspan="9" id="header" align="center" ng-if="itemValue('WeatherInformation_Current_ObservationTime')!='UNDEF'"><b>Weersvoorspelling van {{itemValue('WeatherInformation_Current_ObservationTime') | date:'d/M/yy H:mm'}}</b></td>
		<td colspan="9" id="header" align="center" ng-if="itemValue('WeatherInformation_Current_ObservationTime')=='UNDEF'"><b>Weersvoorspelling van --/--/----</b></td>
	</tr>
	<tr colspan="9">
	 <td height="10"></td>
	</tr>
	<tr>
	  <td rowspan="2" colspan="3" ng-if="itemValue('Condition')!='UNDEF'"><img id="weather-icon" src="{{itemValue('WeatherInformation_Current_WeatherIconURL')}}"/></td>
    <td rowspan="2" colspan="3" ng-if="itemValue('Condition')=='UNDEF'"><img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/3200.png"/></td>
		<td colspan="3" id="weather-temp"  align="center" ng-if="itemValue('Temperature')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temperature')}}<font id="weather-temp-sign">°C</font></td>
		<td colspan="3" id="weather-temp"  align="center" ng-if="itemValue('Temperature')=='UNDEF'">--</td>
	</tr>
	<tr>
		<td>
			<table id="weather-table-details">
				<tr>
					<td align="left">Luchtvochtigheid:</td>
				</tr>
				<tr>
					<td align="left">Luchtdruk:</td>
				</tr>
			</table>
		</td>
		<td>
			<table id="weather-table-details">
				<tr>
					<td align="right" ng-if="itemValue('Humidity')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Humidity')}} %</td>
					<td align="right" ng-if="itemValue('Humidity')=='UNDEF'">-- %</td>
				</tr>
				<tr>
					<td align="right" ng-if="itemValue('Pressure')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Pressure')}} hPa</td>
					<td align="right" ng-if="itemValue('Pressure')=='UNDEF'">-- hPa</td>
				</tr>
			</table>
		</td>
	</tr>
	<tr colspan="9">
	 <td height="20"></td>
	</tr>
	<tr>
		<td/>
		<td>Vandaag</td>
    <td>Morgen</td>
		<td ng-if="itemValue('ObservationTime3')!='UNDEF'">{{daysnames[(itemValue('ObservationTime2') | date:'EEEE')]}}</td>
		<td ng-if="itemValue('ObservationTime2')=='UNDEF'">--</td>
		<td ng-if="itemValue('ObservationTime3')!='UNDEF'">{{daysnames[(itemValue('ObservationTime3') | date:'EEEE')]}}</td>
		<td ng-if="itemValue('ObservationTime3')=='UNDEF'">--</td>
		<td ng-if="itemValue('ObservationTime4')!='UNDEF'">{{daysnames[(itemValue('ObservationTime4') | date:'EEEE')]}}</td>
		<td ng-if="itemValue('ObservationTime4')=='UNDEF'">--</td>
		<td ng-if="itemValue('ObservationTime5')!='UNDEF'">{{daysnames[(itemValue('ObservationTime5') | date:'EEEE')]}}</td>
		<td ng-if="itemValue('ObservationTime5')=='UNDEF'">--</td>
		<td ng-if="itemValue('ObservationTime6')!='UNDEF'">{{daysnames[(itemValue('ObservationTime6') | date:'EEEE')]}}</td>
		<td ng-if="itemValue('ObservationTime6')=='UNDEF'">--</td>
		<td ng-if="itemValue('ObservationTime7')!='UNDEF'">{{daysnames[(itemValue('ObservationTime7') | date:'EEEE')]}}</td>
		<td ng-if="itemValue('ObservationTime7')=='UNDEF'">--</td>
	</tr>
	<tr>
		<td/>
		<td ng-if="itemValue('Condition0')!='UNDEF'">
			<img id="weather-icon" src="{{itemValue('WeatherInformation_ForecastToday_WeatherIconURL')}}"/>
		</td>
		<td ng-if="itemValue('Condition0')=='UNDEF'">
			<img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/3200.png"/>
		</td>
		<td ng-if="itemValue('Condition1')!='UNDEF'">
			<img id="weather-icon" src="{{itemValue('WeatherInformation_ForecastTomorrow_WeatherIconURL')}}"/>
		</td>
		<td ng-if="itemValue('Condition1')=='UNDEF'">
			<img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/3200.png"/>
		</td>
		<td ng-if="itemValue('Condition2')!='UNDEF'">
			<img id="weather-icon" src="{{itemValue('WeatherInformation_ForecastDay2_WeatherIconURL')}}"/>
		</td>
		<td ng-if="itemValue('Condition2')=='UNDEF'">
			<img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/3200.png"/>
		</td>
		<td ng-if="itemValue('Condition3')!='UNDEF'">
			<img id="weather-icon" src="{{itemValue('WeatherInformation_ForecastDay3_WeatherIconURL')}}"/>
		</td>
		<td ng-if="itemValue('Condition3')=='UNDEF'">
			<img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/3200.png"/>
		</td>
		<td ng-if="itemValue('Condition4')!='UNDEF'">
			<img id="weather-icon" src="{{itemValue('WeatherInformation_ForecastDay4_WeatherIconURL')}}"/>
		</td>
		<td ng-if="itemValue('Condition4')=='UNDEF'">
			<img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/3200.png"/>
		</td>
		<td ng-if="itemValue('Condition5')!='UNDEF'">
			<img id="weather-icon" src="{{itemValue('WeatherInformation_ForecastDay5_WeatherIconURL')}}"/>
		</td>
		<td ng-if="itemValue('Condition5')=='UNDEF'">
			<img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/3200.png"/>
		</td>
		<td ng-if="itemValue('Condition6')!='UNDEF'">
			<img id="weather-icon" src="{{itemValue('WeatherInformation_ForecastDay6_WeatherIconURL')}}"/>
		</td>
		<td ng-if="itemValue('Condition6')=='UNDEF'">
			<img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/3200.png"/>
		</td>
		<td ng-if="itemValue('Condition7')!='UNDEF'">
			<img id="weather-icon" src="{{itemValue('WeatherInformation_ForecastDay7_WeatherIconURL')}}"/>
		</td>
		<td ng-if="itemValue('Condition7')=='UNDEF'">
			<img id="weather-icon" src="{{ServerPath}}/images/{{IconSet}}/3200.png"/>
		</td>
	</tr>
	<tr>
		<td class="col-xs-4" style="color:red">Max</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max0')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Max0')}} °C</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max0')=='UNDEF'">-- °C</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max1')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Max1')}} °C</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max1')=='UNDEF'">-- °C</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max2')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Max2')}} °C</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max2')=='UNDEF'">-- °C</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max3')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Max3')}} °C</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max3')=='UNDEF'">-- °C</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max4')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Max4')}} °C</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max4')=='UNDEF'">-- °C</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max5')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Max5')}} °C</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max5')=='UNDEF'">-- °C</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max6')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Max6')}} °C</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max6')=='UNDEF'">-- °C</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max7')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Max7')}} °C</td>
		<td class="col-xs-4" style="color:red" ng-if="itemValue('Temp_Max7')=='UNDEF'">-- °C</td>
	</tr>
	<tr>
		<td class="col-xs-4" style="color:#0db9f0">Min</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min0')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Min0')}} °C</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min0')=='UNDEF'">-- °C</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min1')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Min1')}} °C</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min1')=='UNDEF'">-- °C</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min2')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Min2')}} °C</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min2')=='UNDEF'">-- °C</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min3')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Min3')}} °C</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min3')=='UNDEF'">-- °C</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min4')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Min4')}} °C</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min4')=='UNDEF'">-- °C</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min5')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Min5')}} °C</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min5')=='UNDEF'">-- °C</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min6')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Min6')}} °C</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min6')=='UNDEF'">-- °C</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min7')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Temp_Min7')}} °C</td>
		<td class="col-xs-4" style="color:#0db9f0" ng-if="itemValue('Temp_Min7')=='UNDEF'">-- °C</td>
	</tr>
	<tr>
		<td class="col-xs-4">Neerslag</td>
		<td class="col-xs-4" ng-if="itemValue('Precip_Prob0')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Precip_Prob0')}} %</td>
		<td class="col-xs-4" ng-if="itemValue('Precip_Prob0')=='UNDEF'">-- %</td>
		<td class="col-xs-4" ng-if="itemValue('Precip_Prob1')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Precip_Prob1')}} %</td>
		<td class="col-xs-4" ng-if="itemValue('Precip_Prob1')=='UNDEF'">-- %</td>
		<td class="col-xs-4" ng-if="itemValue('Precip_Prob2')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Precip_Prob2')}} %</td>
		<td class="col-xs-4" ng-if="itemValue('Precip_Prob2')=='UNDEF'">-- %</td>
		<td class="col-xs-4" ng-if="itemValue('Precip_Prob3')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Precip_Prob3')}} %</td>
		<td class="col-xs-4" ng-if="itemValue('Precip_Prob3')=='UNDEF'">-- %</td>
		<td class="col-xs-4" ng-if="itemValue('Precip_Prob4')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Precip_Prob4')}} %</td>
		<td class="col-xs-4" ng-if="itemValue('Precip_Prob4')=='UNDEF'">-- %</td>
		<td class="col-xs-4" ng-if="itemValue('Precip_Prob5')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Precip_Prob5')}} %</td>
		<td class="col-xs-4" ng-if="itemValue('Precip_Prob5')=='UNDEF'">-- %</td>
		<td class="col-xs-4" ng-if="itemValue('Precip_Prob6')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Precip_Prob6')}} %</td>
		<td class="col-xs-4" ng-if="itemValue('Precip_Prob6')=='UNDEF'">-- %</td>
		<td class="col-xs-4" ng-if="itemValue('Precip_Prob7')!='UNDEF'">{{'%.0f' | sprintf:itemValue('Precip_Prob7')}} %</td>
		<td class="col-xs-4" ng-if="itemValue('Precip_Prob7')=='UNDEF'">-- %</td>
	</tr>
	<tr>
		<td class="col-xs-4"></td>
		<td class="col-xs-4" ng-if="itemValue('RainFallMm0')!='UNDEF'">{{'%.0f' | sprintf:itemValue('RainFallMm0')}} mm</td>
		<td class="col-xs-4" ng-if="itemValue('RainFallMm0')=='UNDEF'">-- mm</td>
		<td class="col-xs-4" ng-if="itemValue('RainFallMm1')!='UNDEF'">{{'%.0f' | sprintf:itemValue('RainFallMm1')}} mm</td>
		<td class="col-xs-4" ng-if="itemValue('RainFallMm1')=='UNDEF'">-- mm</td>
		<td class="col-xs-4" ng-if="itemValue('RainFallMm2')!='UNDEF'">{{'%.0f' | sprintf:itemValue('RainFallMm2')}} mm</td>
		<td class="col-xs-4" ng-if="itemValue('RainFallMm2')=='UNDEF'">-- mm</td>
		<td class="col-xs-4" ng-if="itemValue('RainFallMm3')!='UNDEF'">{{'%.0f' | sprintf:itemValue('RainFallMm3')}} mm</td>
		<td class="col-xs-4" ng-if="itemValue('RainFallMm3')=='UNDEF'">-- mm</td>
		<td class="col-xs-4" ng-if="itemValue('RainFallMm4')!='UNDEF'">{{'%.0f' | sprintf:itemValue('RainFallMm4')}} mm</td>
		<td class="col-xs-4" ng-if="itemValue('RainFallMm4')=='UNDEF'">-- mm</td>
		<td class="col-xs-4" ng-if="itemValue('RainFallMm5')!='UNDEF'">{{'%.0f' | sprintf:itemValue('RainFallMm5')}} mm</td>
		<td class="col-xs-4" ng-if="itemValue('RainFallMm5')=='UNDEF'">-- mm</td>
		<td class="col-xs-4" ng-if="itemValue('RainFallMm6')!='UNDEF'">{{'%.0f' | sprintf:itemValue('RainFallMm6')}} mm</td>
		<td class="col-xs-4" ng-if="itemValue('RainFallMm6')=='UNDEF'">-- mm</td>
		<td class="col-xs-4" ng-if="itemValue('RainFallMm7')!='UNDEF'">{{'%.0f' | sprintf:itemValue('RainFallMm7')}} mm</td>
		<td class="col-xs-4" ng-if="itemValue('RainFallMm7')=='UNDEF'">-- mm</td>
	</tr>
</table>

Weather Widget Question