// 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