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:

  1. fully close the cover if the weather is too rainy and too windy
  2. partially close the cover if the weather is too sunny and/or too hot

 // add here your latitude in format XX.YYYYY
let latitude    = "xx.yyyyy";

 // add here your longitude in format XX.YYYYY
let longitude   = "xx.yyyyy";

// add here your timezone
let 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 mm
let max_prec = 7;

// add here wind threshold in km/h
let max_wind = 25;

// add here wind gusts threshold in km/h
let max_gust = 25;

// add here hot temperature threshold in  °C
let 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();
  }
)