Template Example: Weather Binding

Thought i would share my first attempt at some code for the HABPanel template widget.

The aim was to adapt the look and feel of the original solution presented in the v1.x Weather binding wiki page for HABpanel use and to get to grips with some of the new (to me) techniques required.

The result looks like this:

The template makes use of the icons and to a lesser extent the .CSS from the original wiki example (all credit to the original authors).

  • Download the icons from the link at the bottom of the original Wiki page or here.

  • Extract the files to your conf/html directory. You should end up with two sub directories named images and layouts containing the extracted files.

  • From your chosen icon set sub directory, copy the following icons file names to the new names indicated. This overcomes the limitation in some service providers that do not use the day / night status suffix (this function was originally performed in the mapping / transformation file within the original confiuration):

COPY				  TO:
sunny.png               -->       clear.png
partly-cloudy-day.png	-->	  partly-cloudy.png
mostly-cloudy-day.png	-->	  mostly-cloudy.png

  • Paste the following HTML into the template widget.
<div ng-init="ServerPath='http://[your IP/host name goes here]:8080/static'; IconSet='[icon folder name]'">
<link rel="stylesheet" type="text/css" href="{{ServerPath}}/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>
  • Amend the first line of code to reflect your openHAB server’s IP or host name details and the name of the folder that contains the weather icon set that you want to use.
<div ng-init="ServerPath='http://[your IP/host name goes here]:8080/static'; IconSet='[icon folder name]'">

For example:

<div ng-init="ServerPath='http://192.168.4.34:8080/static'; IconSet='flat_white'">
  • The icon folder name is the name of one of the sub direcories contained within the path conf/html/images

  • Choose an icon set that contrasts with the background of your panels (depending on the theme you have chosen).

  • If you have not set up the Weather binding before, you will need a minimum of the following items defined:

Number   Temperature       "Temperature [%.2f °C]"      {weather="locationId=[your location], type=temperature, property=current"}
Number   	Humidity   "Humidity [%d %%]"      	{weather="locationId=[your location], type=atmosphere, property=humidity"}
Number   	Pressure   "Pressure [%.2f mb]"         {weather="locationId=[your location], type=atmosphere, property=pressure"}

DateTime ObservationTime0  "Observation time [%1$td.%1$tm.%1$tY %1$tH:%1$tM]" 	{weather="locationId=[your location], forecast=0, type=condition, property=observationTime"}
DateTime ObservationTime1  "Observation time [%1$td.%1$tm.%1$tY %1$tH:%1$tM]"   {weather="locationId=[your location], forecast=1, type=condition, property=observationTime"}
DateTime ObservationTime2  "Observation time [%1$td.%1$tm.%1$tY %1$tH:%1$tM]"   {weather="locationId=[your location], forecast=2, type=condition, property=observationTime"}

Number   Temp_Min0         "Temperature min [%.2f °C]"  {weather="locationId=[your location], forecast=0, type=temperature, property=min"}
Number   Temp_Max0         "Temperature max [%.2f °C]"  {weather="locationId=[your location], forecast=0, type=temperature, property=max"}
Number   Temp_Min1         "Temperature min [%.2f °C]"  {weather="locationId=[your location], forecast=1, type=temperature, property=min"}
Number   Temp_Max1         "Temperature max [%.2f °C]"  {weather="locationId=[your location], forecast=1, type=temperature, property=max"}
Number   Temp_Min2         "Temperature min [%.2f °C]"  {weather="locationId=[your location], forecast=2, type=temperature, property=min"}
Number   Temp_Max2         "Temperature max [%.2f °C]"  {weather="locationId=[your location], forecast=2, type=temperature, property=max"}

String   Condition0        "Condition [%s]"    	        {weather="locationId=[your location], forecast=0, type=condition, property=text"}
String   Condition1        "Condition [%s]"   	        {weather="locationId=[your location], forecast=1, type=condition, property=text"}
String   Condition2        "Condition [%s]"		{weather="locationId=[your location], forecast=2, type=condition, property=text"}

Tricks I had to learn along the way (i’m not saying these are good practice):

  1. ng-init can be used to specify static variables to save on re-coding time / make the code more generic. There seems to be some debate on the forums wether this is good technique (but it works for me)…

  2. You can refer tp the variables you create using the {{variable_name}} notation anywhere in your subsequent HTML.

  3. {{itemValue('Condition2').replace(' ','-') | lowercase }} this neatly modified the weather condition supplied by the binding to match the (case sensitive and hypenated) icon file names.

There are undoubtedly many improvements that could be made to this and other ways to achieve the same end. As a first attempt it was fun to blow the cobwebs off my HTML knowledge and start to learn some new tricks.

Hope this is useful. Andy

26 Likes

Very nice stuff @AndyMB !

Question: Shouldn’t we define additional items for the Condition in order to display properly the icons?

something like:

String  Condition0      "Condition [%s]"      {weather="locationId=[your location], forecast=0,type=condition, property=text"}
String  Condition1      "Condition [%s]"      {weather="locationId=[your location], forecast=1,type=condition, property=text"}
String  Condition2      "Condition [%s]"      {weather="locationId=[your location], forecast=2,type=condition, property=text"}

It seems that you are using itemValue of Condition0 but I don’t see the items defined.

Also: I copied partly-cloudy-day.png to partly-cloudy.png because my {{itemValue('Condition0')}} was coming up as Partly Cloudy :slight_smile: (since we are not using the weather.map)

BR,
Dim

1 Like

Hi @Dim,

100% correct, sir! I’ve updated my original post with:

  1. The addition of the required Condition parameters
  2. The two icon files you need to rename

Enjoy the sunshine tomorrow, though looks like you will need to wrap up warm :wink:

1 Like

Nice work @AndyMB , thanks for sharing!
This is a great example of what I had in mind with this template widget.

Could anybody please send me the icon files for this template?
I’ve requested google drive access to download these files a few times now, but they have not been granted…

Thanks in advance!

Cheers

…but there is not need for granting access… they are publicly shared on google drive.

Try the direct download link:
https://docs.google.com/uc?id=0Bw7zjCgsXYnHQTlGcndMR19DSUk&export=download

It should work

BR,
Dim

Also the direct download link denies me from downloading the files

Temp is going down here and Sun is shinning ! All is good :slight_smile:

By the way, I have a recommendation for a small improvement:

Instead of using ObservationTime0 to display the timestamp on the top of the widget, I use the LastUpdate item which is defined as follows:

DateTime	LastUpdate	"Last update [%1$td.%1$tm.%1$tY %1$tH:%1$tM]"	{weather="locationId=[your location], type=condition, property=lastUpdate"}

So my widget template starts with:

<div ng-init="ServerPath='http://[your IP/host name goes here]/static'; IconSet='[icon folder name]'">
<link rel="stylesheet" type="text/css" href="{{ServerPath}}/layouts/example.css" />
</div>

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

In this way, I can see the hh:mm of the last weather forecast update.

BR,
Dim

1 Like

Never mind… tried it using Safari instead of Chrome and i’m able to download the files… weird…

why this URL rewrite?

Strange chrome behaviour… it does rewrite the URL, but only when i’m logged in using my google apps account. When logging out or just using my regular gmail account this does not happen… :slight_smile:

Very nice @AndyMB this is really nice. I’ll add that clear-night also needs to be renamed to clear.

Time for another side project to be put on the list methinks…

What is the best way to translate the days?

True :slight_smile:

I copied “sunny.png” to “clear.png” for a day display

Thanks @Dim and @pahansen,

Original post updated. I’d did the icon changes weeks ago and completely forgot all the changes when doing the post. Lesson learnt… Andy :slight_smile:

1 Like

Amended the original post to use the link that @dim provided.

Looks awesome, I like how much easily readable info you have on yours. I made a very similar Weather widget, however I used the Climacons font which I had to upload to the web/assets folder. Happy to share the HTML if people are interested, but I may need to upload it somewhere as it is quite long due to the very sloppy embeded CSS.

6 Likes

Hi Ben, I would like to see your HTML code. Especially I am interested how you integrated the climacons font.

I would love to see an animated weather conditions background possible in HABPanel, like what is done in the Nest web interface, or like what is done here: http://www.mmmbridgecity.org/estilos/WeatherSlider/example/example.html

(Evidently, it’s snowing in Berlin. The snowflakes are falling in this example. Others, rain is falling, clouds, are drifting, lightning is striking, etc.)

1 Like

wow - that screen looks awesome, would be nice with some animated screens :slight_smile: