aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller/Weather/WeatherClient.cs
blob: c4abdc171e7c588be46a5e4cb043e19b5de60623 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Cache;
using System.Net.Http;
using System.Threading.Tasks;
using MediaBrowser.Common.Logging;
using MediaBrowser.Common.Serialization;
using MediaBrowser.Model.Weather;

namespace MediaBrowser.Controller.Weather
{
    /// <summary>
    /// Based on http://www.worldweatheronline.com/free-weather-feed.aspx
    /// The classes in this file are a reproduction of the json output, which will then be converted to our weather model classes
    /// </summary>
    public class WeatherClient
    {
        private HttpClient HttpClient { get; set; }

        public WeatherClient()
        {
            WebRequestHandler handler = new WebRequestHandler();

            handler.AutomaticDecompression = DecompressionMethods.Deflate;
            handler.CachePolicy = new RequestCachePolicy(RequestCacheLevel.Revalidate);

            HttpClient = new HttpClient(handler);
        }

        public async Task<WeatherInfo> GetWeatherInfoAsync(string zipCode)
        {
            if (string.IsNullOrWhiteSpace(zipCode))
            {
                return null;
            }

            int numDays = 5;
            string apiKey = "24902f60f1231941120109";

            string url = "http://free.worldweatheronline.com/feed/weather.ashx?q=" + zipCode + "&format=json&num_of_days=" + numDays + "&key=" + apiKey;

            Logger.LogInfo("Accessing weather from " + url);

            using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
            {
                WeatherData data = JsonSerializer.DeserializeFromStream<WeatherResult>(stream).data;

                return GetWeatherInfo(data);
            }
        }

        /// <summary>
        /// Converst the json output to our WeatherInfo model class
        /// </summary>
        private WeatherInfo GetWeatherInfo(WeatherData data)
        {
            WeatherInfo info = new WeatherInfo();

            if (data.current_condition != null)
            {
                if (data.current_condition.Any())
                {
                    info.CurrentWeather = data.current_condition.First().ToWeatherStatus();
                }
            }

            if (data.weather != null)
            {
                info.Forecasts = data.weather.Select(w => w.ToWeatherForecast()).ToArray();
            }

            return info;
        }
    }

    class WeatherResult
    {
        public WeatherData data { get; set; }
    }

    public class WeatherData
    {
        public WeatherCondition[] current_condition { get; set; }
        public DailyWeatherInfo[] weather { get; set; }
    }

    public class WeatherCondition
    {
        public string temp_C { get; set; }
        public string temp_F { get; set; }
        public string humidity { get; set; }
        public string weatherCode { get; set; }

        public WeatherStatus ToWeatherStatus()
        {
            return new WeatherStatus()
            {
                TemperatureCelsius = int.Parse(temp_C),
                TemperatureFahrenheit = int.Parse(temp_F),
                Humidity = int.Parse(humidity),
                Condition = DailyWeatherInfo.GetCondition(weatherCode)
            };
        }
    }

    public class DailyWeatherInfo
    {
        public string date { get; set; }
        public string precipMM { get; set; }
        public string tempMaxC { get; set; }
        public string tempMaxF { get; set; }
        public string tempMinC { get; set; }
        public string tempMinF { get; set; }
        public string weatherCode { get; set; }
        public string winddir16Point { get; set; }
        public string winddirDegree { get; set; }
        public string winddirection { get; set; }
        public string windspeedKmph { get; set; }
        public string windspeedMiles { get; set; }

        public WeatherForecast ToWeatherForecast()
        {
            return new WeatherForecast()
            {
                Date = DateTime.Parse(date),
                HighTemperatureCelsius = int.Parse(tempMaxC),
                HighTemperatureFahrenheit = int.Parse(tempMaxF),
                LowTemperatureCelsius = int.Parse(tempMinC),
                LowTemperatureFahrenheit = int.Parse(tempMinF),
                Condition = GetCondition(weatherCode)
            };
        }

        public static WeatherConditions GetCondition(string weatherCode)
        {
            switch (weatherCode)
            {
                case "362":
                case "365":
                case "320":
                case "317":
                case "182":
                    return WeatherConditions.Sleet;
                case "338":
                case "335":
                case "332":
                case "329":
                case "326":
                case "323":
                case "377":
                case "374":
                case "371":
                case "368":
                case "395":
                case "392":
                case "350":
                case "227":
                case "179":
                    return WeatherConditions.Snow;
                case "314":
                case "311":
                case "308":
                case "305":
                case "302":
                case "299":
                case "296":
                case "293":
                case "284":
                case "281":
                case "266":
                case "263":
                case "359":
                case "356":
                case "353":
                case "185":
                case "176":
                    return WeatherConditions.Rain;
                case "260":
                case "248":
                    return WeatherConditions.Fog;
                case "389":
                case "386":
                case "200":
                    return WeatherConditions.Thunderstorm;
                case "230":
                    return WeatherConditions.Blizzard;
                case "143":
                    return WeatherConditions.Mist;
                case "122":
                    return WeatherConditions.Overcast;
                case "119":
                    return WeatherConditions.Cloudy;
                case "115":
                    return WeatherConditions.PartlyCloudy;
                default:
                    return WeatherConditions.Sunny;
            }
        }
    }
}