diff --git a/exec/ircbots/weather/weather_commands.js b/exec/ircbots/weather/weather_commands.js index 8cfb5e4646a63c0c4647ed5194194a814ed38dfa..0aed4850dafd21a9bfc5d2e316e1fd53a4972c62 100644 --- a/exec/ircbots/weather/weather_commands.js +++ b/exec/ircbots/weather/weather_commands.js @@ -39,3 +39,65 @@ Bot_Commands["WEATHER"].command = function (target, onick, ouh, srv, lvl, cmd) { return true; } + +Bot_Commands["FORECAST"] = new Bot_Command(0,false,false); +Bot_Commands["FORECAST"].command = function (target, onick, ouh, srv, lvl, cmd) { + + // Remove empty cmd args + for (var i = 1; i < cmd.length; i++) { + if (cmd[i].search(/^\s*$/) == 0) { + cmd.splice(i, 1); + i--; + } + } + cmd.shift(); + + try { + const params = get_params(cmd, onick, srv); + if (!params) { + throw("error parsing parameters"); + } + const res = owm.call_api('forecast', params); + if(!res || res.cod != 200) { + throw(JSON.stringify(res)); + } + + var output = []; + srv.o(target,ctrl_a_to_mirc('Forecast for \1h\1c' + res.city.name + ' \1n\1m(\1h\1mProvided by OpenWeatherMap.org\1n\1m)\1n\1r:')); + //output.push('\0010\1n\1rForecast for \1h\1c' + res.city.name + ' \1n\1m(\1h\1mProvided by OpenWeatherMap.org\1n\1m)\1n\1r:'); + for(var d=0; d<res.list.length; d+=8) { + var day_forecast = res.list.slice(d,d+8); + if(day_forecast.length > 0) { + output.push(get_day_forecast_rows(day_forecast)); + } + writeln(d + ": " + JSON.stringify(day_forecast)); + // output.push( + // '\0010\1h\1c ' + days[forecast_date.getDay()] + '\1n\1r, \1h\1c' + months[forecast_date.getMonth()] + ' ' + forecast_date.getDate() + '\1n\1r: ' + // + '\1h\1c' + day_forecast.weather[0].main + ' \1n\1r(\1c' + day_forecast.weather[0].description + '\1r), ' + // + '\1h\1c' + day_forecast.clouds.all + '% cloudy\1n\1r, ' + // + 'Min temp: \1h\1c' + temperature_str(day_forecast.main.temp_min) + '\1n\1r, ' + // + 'Max temp: \1h\1c' + temperature_str(day_forecast.main.temp_max) + '\1n\1r, ' + // + 'Wind: \1h\1c' + day_forecast.wind.speed + ' KM/h ' + owm.wind_direction(day_forecast.wind.deg) + '\1n\1r, ' + // + 'Humidity: \1h\1c' + day_forecast.main.humidity + '%\1n\1r, ' + // + 'Pressure: \1h\1c' + day_forecast.main.pressure + ' hPa' + // ); + } + // while(output.length > 0) { + // srv.o(target, ctrl_a_to_mirc(output.shift())); + // } + for(var r=0;r<output[0].length;r++) { + var row_string = ""; + for(var o=0;o<output.length;o++) { + row_string += ctrl_a_to_mirc('\0010' + output[o][r]); + } + srv.o(target,row_string); + } + + } catch (err) { + log(LOG_DEBUG, 'Failed to display weather conditions: ' + err); + srv.o(target, 'Failed to fetch weather conditions: ' + err); + } + + return true; +} + diff --git a/exec/ircbots/weather/weather_functions.js b/exec/ircbots/weather/weather_functions.js index ad48b07416beba37f87f68c9d5211ee8bcaf3020..9fde61ad87104425e64a707f79eb96f34ea24c1f 100644 --- a/exec/ircbots/weather/weather_functions.js +++ b/exec/ircbots/weather/weather_functions.js @@ -3,6 +3,8 @@ if (!js.global.get_nicklocation) js.global.load(js.global, "nicklocate.js"); if (!js.global.OpenWeatherMap) js.global.load(js.global, 'openweathermap.js'); var owm = new OpenWeatherMap(); +var short_months = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]; +var short_days = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]; function locate_user(nick, srv) { const ret = { units: 'metric' }; @@ -61,5 +63,100 @@ function get_params(cmd, nick, srv) { } function temperature_str(n) { - return n + '\xC2\xB0C \1n\1r(\1h\1c' + owm.c_to_f(n) + '\xC2\xB0F\1n\1r)'; + return Math.round(n) + '\xC2\xB0C \1n\1r(\1h\1c' + owm.c_to_f(n) + '\xC2\xB0F\1n\1r)'; +} + +function temperature_str_plain(n) { + return Math.round(n) + '\xC2\xB0C (' + owm.c_to_f(n) + '\xC2\xB0F)'; +} + +function get_day_forecast_rows(forecasts) { + var bar = [ + format_graph_row(get_forecast_day(forecasts),20), + format_graph_row(get_avg_weather(forecasts),20), + format_graph_row(get_low_temp(forecasts),26), + format_graph_row(get_high_temp(forecasts),26), + format_graph_row(get_avg_wind(forecasts),24)//, + // format_graph_row(get_avg_humidity(forecasts),16), + // format_graph_row(get_avg_pressure(forecasts),16) + ]; + return bar; +} + +function get_low_temp(forecasts) { + var low = undefined; + for(var f=0;f<forecasts.length;f++) { + var weather = forecasts[f].main; + if(low === undefined || weather.temp_min < low) { + low = weather.temp_min; + } + } + return "\1n\1wL:\1h\1c " + temperature_str_plain(low); +} + +function get_high_temp(forecasts) { + var high = undefined; + for(var f=0;f<forecasts.length;f++) { + var weather = forecasts[f].main; + if(high === undefined || weather.temp_max > high) { + high = weather.temp_max; + } + } + return "\1n\1wH:\1n\1r " + temperature_str_plain(high); +} + +function get_forecast_day(forecasts) { + var forecast_utc = forecasts[0].dt * 1000; + var forecast_date = new Date(forecast_utc); + var day_str = days[forecast_date.getDay()] + ', ' + months[forecast_date.getMonth()] + ' ' + forecast_date.getDate(); + return "\1n\1w" + day_str; +} + +function get_avg_weather(forecasts) { + var modeMap = {}; + var maxEl = forecasts[0], maxCount = 1; + for(var i = 0; i < forecasts.length; i++) + { + var el = forecasts[i].weather[0].main; + if(modeMap[el] == null) + modeMap[el] = 1; + else + modeMap[el]++; + if(modeMap[el] > maxCount) + { + maxEl = forecasts[i]; + maxCount = modeMap[el]; + } + } + return "\1h\1y" + maxEl.weather[0].main; +} + +function get_avg_wind(forecasts) { + var total_wind = 0; + var total_dir = 0; + for(var f=0;f<forecasts.length;f++) { + total_wind += forecasts[f].wind.speed; + total_dir += forecasts[f].wind.deg + } + return "\1n\1wW:\1h\1y " + Math.round(total_wind/forecasts.length) + ' KM/h ' + owm.wind_direction(Math.round(total_dir/forecasts.length)) +} + +function get_avg_humidity(forecasts) { + var total_hum = 0; + for(var f=0;f<forecasts.length;f++) { + total_hum += forecasts[f].main.humidity; + } + return "\1n\1wH:\1h\1y " + Math.round(total_hum/forecasts.length) + '%'; +} + +function get_avg_pressure(forecasts) { + var total_press = 0; + for(var f=0;f<forecasts.length;f++) { + total_press += forecasts[f].main.pressure; + } + return "\1n\1wP:\1h\1y " + Math.round(total_press/forecasts.length) + ' hPa'; +} + +function format_graph_row(str, len) { + return format("%-*s",len,str); }