// list the program as custom weather widget Program.UseWidget( "homegenie/generic/weather" ) // set input fields parameters // <field_name>, <default_value>, <description> .AddOption("Location", "London, UK", "City name", "wunderground.city") .AddOption("Language", "EN", "Language", "text") .AddOption("ApiKey", "?", "OpenWeatherMap API key (APPID)", "text") .AddOption("UpdateInterval", "30", "Update interval (minutes)", "slider:15:1440:15"); // initialize widget program parameters Program.Parameter("Astronomy.Sunset").Value = ""; Program.Parameter("Astronomy.Sunrise").Value = ""; Program.Parameter("Conditions.City").Value = ""; Program.Parameter("Conditions.Temperature").Value = ""; Program.Parameter("Conditions.DisplayLocation").Value = ""; Program.Parameter("Conditions.IconUrl").Value = ""; Program.Parameter("Conditions.Description").Value = ""; Program.Run(); Action<dynamic> UpdateWeatherParameters = (data) => { Program.Parameter("Conditions.City").Value = data.city; Program.Parameter("Conditions.DisplayLocation").Value = data.city; Program.Parameter("Conditions.Country").Value = data.country; Program.Parameter("Conditions.Description").Value = data.weather_description; Program.Parameter("Conditions.IconUrl").Value = data.weather_icon; Program.Parameter("Conditions.Status").Value = data.weather_status; // eg. cloudy, sunny, etc.. Program.Parameter("Conditions.LastUpdated").Value = data.update_dt; // Add values to standard Sensor.* parameters Program.Parameter("Sensor.Temperature").Value = data.temperature; Program.Parameter("Sensor.Temperature.Unit").Value = "Celsius"; Program.Parameter("Sensor.Humidity").Value = data.humidity; Program.Parameter("Sensor.Pressure").Value = data.pressure; Program.Parameter("Sensor.Pressure.Unit").Value = "Mb"; Program.Parameter("Sensor.Wind.Speed").Value = data.wind_speed; Program.Parameter("Sensor.Wind.Speed.Unit").Value = "Kph"; Program.Parameter("Sensor.Wind.Direction").Value = data.wind_direction; Program.Parameter("Sensor.Precipitation.Rain").Value = data.rain_1h_mm; Program.Parameter("Sensor.Precipitation.Rain.Unit").Value = "1h"; Program.Parameter("Sensor.Precipitation.Snow").Value = data.snow_1h_mm; Program.Parameter("Sensor.Precipitation.Snow.Unit").Value = "1h"; Program.Parameter("Sensor.Temperature.FeelsLike").Value = data.feels_like; Program.Parameter("Sensor.Temperature.Max").Value = data.temp_max; // TODO: Program.Parameter("Sensor.UV").Value = "..."; }; Action<int,dynamic> UpdateForecastParameters = (day, data) => { Program.Parameter("Conditions.Forecast." + day + ".Description").Value = data.weather_description; Program.Parameter("Conditions.Forecast." + day + ".Year").Value = data.dt.Year.ToString("YYYY"); Program.Parameter("Conditions.Forecast." + day + ".Month").Value = data.dt.ToString("MMM"); Program.Parameter("Conditions.Forecast." + day + ".Day").Value = data.dt.ToString("dd"); Program.Parameter("Conditions.Forecast." + day + ".Weekday").Value = data.dt.ToString("dddd"); Program.Parameter("Conditions.Forecast." + day + ".IconUrl").Value = data.weather_icon; Program.Parameter("Conditions.Forecast." + day + ".Temperature").Value = data.temperature; Program.Parameter("Conditions.Forecast." + day + ".Humidity").Value = data.humidity; Program.Parameter("Conditions.Forecast." + day + ".Temperature.Min").Value = data.temperature_min; Program.Parameter("Conditions.Forecast." + day + ".Temperature.Max").Value = data.temperature_max; }; Func<string,string> GetWeatherIcon = (type) => { var icon = "unknonwn.png"; switch(type) { case "01d": // clear sky icon = "clear"; break; case "02d": // few clouds icon = "partlycloudy"; break; case "03d": // scattered clouds icon = "scatteredclouds"; break; case "04d": // broken clouds (?) icon = "cloudy"; break; case "09d": // shower rain icon = "showerrain"; break; case "10d": // rain icon = "rain"; break; case "11d": // thunderstorms icon = "thunderstorms"; break; case "13d": // snow icon = "snow"; break; case "50d": // mist icon = "hazy"; break; // Night icons case "01n": // clear sky icon = "clear_night"; break; case "02n": // few clouds icon = "partlycloudy_night"; break; case "03n": // scattered clouds icon = "scatteredclouds"; break; case "04n": // broken clouds (?) icon = "cloudy_night"; break; case "09n": // shower rain icon = "showerrain_night"; break; case "10n": // rain icon = "rain"; break; case "11n": // thunderstorms icon = "thunderstorms"; break; case "13n": // snow icon = "snow_night"; break; case "50n": // mist icon = "hazy"; break; } return icon; }; Func<dynamic, dynamic> CollectWeatherData = (weatherData) => { dynamic data = new ExpandoObject(); data.dt = Utility.JavaTimeStampToDateTime(1000D*(int)weatherData.dt); data.update_dt = data.dt.ToLongDateString() + " " + TimeZoneInfo.ConvertTime(data.dt, TimeZoneInfo.Local).ToLongTimeString(); //weatherData.main.temp = Math.Round(weatherData.main.temp); //data.temperature = weatherData.main.temp.ToString(); data.temperature = String.Format("{0:0n0}", weatherData.main.temp.ToString()); data.temperature_min = weatherData.main.temp_min.ToString(); data.temperature_max = weatherData.main.temp_max.ToString(); data.pressure = weatherData.main.pressure.ToString(); data.humidity = weatherData.main.humidity.ToString(); data.feels_like = weatherData.main.feels_like.ToString(); data.temp_max = weatherData.main.temp_max.ToString(); var rain_1h_mm = "0"; var rain_3h_mm = "0"; if (weatherData.rain != null) { if (weatherData.rain["1h"] != null) rain_1h_mm = weatherData.rain["1h"].ToString(); if (weatherData.rain["3h"] != null) rain_3h_mm = weatherData.rain["3h"].ToString(); } data.rain_1h_mm = rain_1h_mm; var snow_1h_mm = "0"; var snow_3h_mm = "0"; if (weatherData.snow != null) { if (weatherData.snow["1h"] != null) snow_1h_mm = weatherData.snow["1h"].ToString(); if (weatherData.snow["3h"] != null) snow_3h_mm = weatherData.snow["3h"].ToString(); } data.snow_1h_mm = snow_1h_mm; data.wind_speed = weatherData.wind.speed.ToString(); data.wind_direction = ""; if (weatherData.wind.deg != null) data.wind_direction = weatherData.wind.deg.ToString(); data.weather_status = weatherData.weather[0].main.ToString(); data.weather_description = weatherData.weather[0].description.ToString(); data.weather_icon = GetWeatherIcon(weatherData.weather[0].icon.ToString()); // city and country fields are not present in forecast data if (weatherData.name != null) data.city = weatherData.name.ToString(); if (weatherData.sys != null && weatherData.sys.country != null) data.country = weatherData.sys.country.ToString(); return data; }; while (Program.IsEnabled) { string location = Program.Option("Location").Value; string language = Program.Option("Language").Value; string apikey = Program.Option("ApiKey").Value; if (!apikey.Contains("?")) { try { string webserviceurl = "https://api.openweathermap.org/data/2.5/weather?q=" + location + "&lang=" + language + "&units=metric&appid=" + apikey; var weatherData = Net.WebService(webserviceurl).GetData(); var sunset = Utility.JavaTimeStampToDateTime(1000D*(int)weatherData.sys.sunset); var sunrise = Utility.JavaTimeStampToDateTime(1000D*(int)weatherData.sys.sunrise); Program.Parameter("Astronomy.Sunset").Value = TimeZoneInfo.ConvertTime(sunset, TimeZoneInfo.Local).ToShortTimeString(); Program.Parameter("Astronomy.Sunrise").Value = TimeZoneInfo.ConvertTime(sunrise, TimeZoneInfo.Local).ToShortTimeString(); var data = CollectWeatherData(weatherData); UpdateWeatherParameters(data); // get forecast data webserviceurl = "https://api.openweathermap.org/data/2.5/forecast?q=" + location + "&lang="+language+"&units=metric&appid=" + apikey; var forecast = Net.WebService(webserviceurl).GetData(); var forecastDay = 1; var nextDay = DateTime.UtcNow.AddDays(1); nextDay = nextDay.Date + new TimeSpan(12, 0, 0); foreach(var fc in forecast.list) { var forecastTime = Utility.JavaTimeStampToDateTime(1000D*(int)fc.dt); if (forecastTime.Equals(nextDay)) { // collect forecast data for current forecastDay var forecastData = CollectWeatherData(fc); UpdateForecastParameters(forecastDay, forecastData); nextDay = nextDay.AddDays(1); forecastDay++; } // process up to 3 days if (forecastDay > 3) break; } Program.RaiseEvent("Program.UiRefresh", "Data Updated", ""); } catch (Exception e) { Program.Notify("ERROR: unable to get data from service. " + e.Message); Console.WriteLine( e.Message ); Pause(10); } } // var delayMins = Program.Option("UpdateInterval").DecimalValue; if (delayMins < 1) delayMins = 1; Pause(delayMins*60); } HomeAutomation.HomeGenie.Automation
1030
OpenWeatherMap Current weather and forecast information from <strong>Open Weather Map</strong> service. To activate this widget enter a valid <strong>API key</strong> below. Follow instructions from <u>https://openweathermap.org/appid</u> to get your free API key. Weather and Environment false 2020-02-06T15:44:10.108604Z 2020-02-06T15:44:11.426672Z CSharp true