Contents

Home automation and weather: how to customize your home according to the weather forecast

Eating breakfast amidst the colors of the weather.

A good habit to start the day on the right foot is to get out of bed and have a soft light around the house. With an RGB lamp or colored LED strip, you can choose the color with which to light the room with the weather forecast, to combine the effect of a nice soft and dynamic colored light with what will be the mood of the day.

Prerequisites and ingredients.

  • A colored lamp or rgb strip controllable by a home automation server (in my case I use rgb strips connected to a very good Shelly RGBW2)
  • a home automation server where to insert the color conversion logic, in my case I use Openhab (take a look at my post on Openhab)
  • the plugin on the home automation server to allow the execution of Javascript scripts (JSScripting)
  • a free registration on the weather provider for the relevant ApiKey.
  • a plugin or provider for weather data, in my case I use the free Openhab plugin called OpenWeatherMap Binding. The plugin must be configured with the provider’s ApiKey and the “Item” elements connected to the variables “Cloudiness”, “Rain”, “Snow” will have to be created.
Configuring weather-related items

Configuring weather-related items

Let’s match the colors

To begin with, let’s match the colors to the weather forecast, so that you can immediately get a clear and intuitive idea of the weather conditions with just a glance at the color. This is just one of the possible combinations that can be made, if you have any suggestions post them in the comments!

  • For rain, obviously the idea is to go from a light blue, to a solid blue for heavy rain, to a purple in case of a thunderstorm with thunderbolts in the theme.
  • In the case of a clear day we definitely start with a nice yellow.
  • As cloudiness increases this color may veer toward a gray.

HSV coordinates

Transcribing this logic by working with RGB coordinates could be complicated, since to match the percentage of cloudiness or the amount of rain to the desired color scales we would have to find mathematical functions that are not intuitive. As engineering teaches us, when the going gets tough, a change of coordinates is necessary! To identify colors there is not only RGB coding, in which each dimension is one of the three primary colors red, green and blue. Another encoding that comes in very handy in this case is HSV or HSB, whose value space we can represent as a cylinder, having on the upper circumference the various hues (identified with degrees at 0 to 360) that fade toward the center of the upper base by decreasing saturation (in percent). At the lower base is black, and longitudinally we can measure brightness (in percent).

Coordinate HSV

Coordinate HSV

The colors

weather % snow % rain % cloudiness color
clear 0 0 0
hsv(40,100,100)
scattered clouds 0 0 5
hsv(95,95,100)
clouds 0 0 95
hsv(95,45,100)
light rain 0 10 -
hsv(180,100,100)
heavy rain 0 70 -
hsv(240,100,100)
thunderstorm 0 100 -
hsv(280,100,100)
snow 30 - -
hsv(10,100,100)

The script

We need to bring this logic to our home automation server. In my case I have chosen a JavaScript script (ECMA 262 Edition 11). The items I refer to in the code and which must already be present are:

  • those related to weather, in my case I chose the 6-hour forecast: LocalWeatherandForecast_ForecastedWeatherCondition6H, LocalWeatherandForecast_ForecastedCloudiness, LocalWeatherandForecast_ForecastedRain, LocalWeatherandForecast_ForecastedSnow. *The item related to the color of our lamp LightRgbSounce_Color.

Here is the script:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

// compatibility with older Openhab script
var runtime = require("@runtime");
var itemRegistry =runtime.itemRegistry, events=runtime.events, HSBType=runtime.HSBType, rules=runtime.rules;

// some functions
var randomColor =function(){
  return (Math.random()*360).toString() +","+((Math.random()*50)+50).toString() +"," + ((Math.random()*50)+50).toString()
}
var hsvColor =function(h,s,v){
  return h.toString() +","+s.toString() +"," + v.toString()
}
var hsvColorRandomIntensity =function(h){
  var intensity=Math.random()*50+50; return h.toString() +","+"100" +"," + intensity.toString()
}

// prende in input:
// minGradoColore numero da 0 a 360 che indica nella scala HSV il minimo valore da considerare per un intervallo di colori (quindi il colore scelto nel caso il valore sia minimo)
// maxGradoColore numero da 0 a 360 che indica nella scala HSV il minimo valore da considerare per un intervallo di colori (quindi il colore scelto nel caso il valore sia uguale o superiore al maxValore)
// maxValore numero da 0 a INF che indica il massimo che può raggiungere valore
// valore numero da 0 a INF che indica il valore attuale e che viene considerato fino a maxValore
// ritorna un valore da 0 a 360 (da minGradoColore a maxGradoColore) che indica il valore rapportato al maxValore nell'intervallo fra maxGradoColore e minGradoColore
var calcolaTinta = function(minGradoColore, maxGradoColore, maxValore, valore){
  valore =  valore<=maxValore ? valore : maxValore;
  valore = valore >= 0 ? valore : 0;
  return (valore*1.0/maxValore)*(maxGradoColore-minGradoColore)+minGradoColore;
};

// recupero dei valori del meteo
var previsioni = items.getItem("LocalWeatherandForecast_ForecastedWeatherCondition6H").getState()+"";
var cloudiness = items.getItem('LocalWeatherandForecast_ForecastedCloudiness').rawState.floatValue();// 0 to 1 
var rain = items.getItem('LocalWeatherandForecast_ForecastedRain').rawState.floatValue()*100.0; // 0 to inf
var snow = items.getItem('LocalWeatherandForecast_ForecastedSnow').rawState.floatValue() ; // 0 to inf

// stampa nei log dei dati attuali
console.info("triggered rule " + 'org.openhab.rule.' + ctx.ruleUID)
console.info(JSON.stringify({cloudiness:cloudiness, rain:rain, snow:snow, previsioni:previsioni}));

// scelgo il colore in base al meteo
var color = hsvColor(0,0,100 ); // di default è bianco
if (snow > 0){
  var minSnow = 0;
  var maxSnow = 20;
  var limiteSnow = 2.0;
  
  color = hsvColorRandomIntensity(calcolaTinta(minSnow, maxSnow, limiteSnow, snow),100);
  console.info("dal meteo imposto il colore per NEVE: " + color);
} else if (rain > 0.04){
  var minRain = 160;
  var maxRain = 280;
  var limiteRain = 1.2;
  
  color = hsvColorRandomIntensity(calcolaTinta(minRain, maxRain, limiteRain, rain),100);
  console.info("dal meteo imposto il colore per PIOGGIA: " + color);
} else if (cloudiness > 0.04){
  var minCloud = 95;
  var maxCloud = 95;
  var limiteCloud = 1.0;
  
  var saturation = 100-cloudiness*50.0;
  color = hsvColorRandomIntensity(calcolaTinta(minCloud, maxCloud, limiteCloud, cloudiness),saturation);
  console.info("dal meteo imposto il colore per NUVOLOSO: " + color);
} else {
  var minSun = 35;
  var maxSun = 45;
  var limiteSun = 0.04;
  
  color = hsvColorRandomIntensity(calcolaTinta(minSun, maxSun, limiteSun, cloudiness),100);
  console.info("dal meteo imposto il colore per SOLE: " + color);
}

// impostiamo il colore e accendiamo la luce!
events.sendCommand("LuceRgbSoggiorno_Color", color); 
events.sendCommand("LuceRgbSoggiorno_Color", "ON"); 

Aggiornamenti di luglio 2023
Apparently, as of about July 2023, the OpenWeatherMap or Openhab extension has changed the handling of the predicted rain field and cloud percentage. The code you see here is compatible with the new releases. Before the update, the “cloudiness” value had to be divided by 100.0, while the rainfall value did not need to be multiplied by 100.0.

Usage

Once the script has been tested, all that remains is to invoke it or match it to home scenarios.

  • you can invoke the script following the pressing of a physical scenario button, so in the morning clicking on the “day” scenario could invoke the logic by gently lighting the house (I’ve already discussed this here)
  • one can use the timing of Openhab, to trigger it at predetermined times of the day, such as sunrise
  • you can trigger it following another event, such as turning on a lamp or appliance
  • you can trigger the scenario from Google Home or Amazon Alexa voice assistants, creating an item in Openhab published on cloud platforms (if you’re interested in this topic I could write an article, let me know in the comments)