Weather based status for Shelly Plus 2PM
Below a simple script to be used in Shelly Plus 2PM device set with a "Cover Profile" to:
- fully close the cover if the weather is too rainy and too windy
- partially close the cover if the weather is too sunny and/or too hot
// add here your latitude in format XX.YYYYYlet latitude = "xx.yyyyy";
// add here your longitude in format XX.YYYYYlet longitude = "xx.yyyyy";// add here your timezonelet timezone = 'Europe%2FRome';let urlMeteo = 'https://api.open-meteo.com/v1/forecast?' + 'latitude=' + (latitude) + '&' + 'longitude=' + (longitude) + '&' + 'timezone=' + (timezone) + '&' + 'current=precipitation,wind_speed_10m,wind_gusts_10m,' + 'temperature_2m,apparent_temperature,soil_temperature_0cm&' + 'minutely_15=temperature_2m,wind_speed_10m,'+ 'wind_gusts_10m,precipitation,apparent_temperature,' 'soil_temperature_0cm&'+ 'forecast_days=1&' + 'forecast_minutely_15=4';// add here precipitation threshold in mmlet max_prec = 7;// add here wind threshold in km/hlet max_wind = 25;// add here wind gusts threshold in km/hlet max_gust = 25;// add here hot temperature threshold in °Clet max_temp = 27;function CheckMeteo() { Shelly.call( 'HTTP.GET', { url: urlMeteo, timeout: 10, ssl_ca: '*' }, function(response) { try { let resp = JSON.parse(response.body); let cur_prec = parseInt(resp.current.precipitation); let cur_wind = parseInt(resp.current.wind_speed_10m); let cur_gust = parseInt(resp.current.wind_gusts_10m); let cur_temp = parseInt(resp.current.apparent_temperature); let next_prec = parseInt(resp.minutely_15.precipitation[1]); let next_wind = parseInt(resp.minutely_15.wind_speed_10m[1]); let next_gust = parseInt(resp.minutely_15.wind_gusts_10m[1]); let next_temp = parseInt(resp.minutely_15.apparent_temperature[1]); // now it's too windy and too much precipitation if (cur_prec>=max_prec && (cur_wind>=max_wind || cur_gust>=max_gust)) { CoverClose(0); return; } // soon it will be too windy and too much precipitation if (next_prec>=max_prec && (next_wind>=max_wind || next_gust>=max_gust)) { CoverClose(0); return; } // now it's too hot (or soon it will be too hot) if (cur_temp > max_temp || next_temp > max_temp) { CoverTestAndGoTo(0, 65); return; } } catch (ex) { console.log(ex); } } );}function CoverOpen(_id) { Shelly.call('Cover.GoToPosition', { id:_id, pos: 90 } );}function CoverClose(_id) { Shelly.call('Cover.GoToPosition', { id:_id, pos: 0 } );}function CoverGoTo(_id, _pos) { Shelly.call('Cover.GoToPosition', { id:_id, pos:_pos } ); }
function CoverTestAndGoTo(_id, _pos) { Shelly.call('Cover.GetStatus',{ id:_id }, function(result) { let pos = result.current_pos; if (pos > _pos) { CoverGoTo(_id, _pos); } });}CheckMeteo();Timer.set( 1000*60*10, true, function() { CheckMeteo(); })