10
10
11
11
weather_cache_t weather_cache ;
12
12
void weather_cache_parse_response (struct json_object * weather_response_obj );
13
+ void weather_cache_parse_forecast (struct json_object * weather_response_obj );
14
+ void weather_cache_parse_weather_entry (struct json_object * weather_entry_obj , weather_cache_t * cache_entry );
15
+ void weather_entry_free (void * arg );
13
16
14
17
typedef struct response_memory_t
15
18
{
@@ -43,6 +46,8 @@ void weather_cache_init()
43
46
weather_cache .windspeed = 0 ;
44
47
weather_cache .temp = 0 ;
45
48
weather_cache .precipitation = NULL ;
49
+ weather_cache .raw_forecast = NULL ;
50
+ weather_cache .forecast_hourly = stack_create ();
46
51
}
47
52
48
53
void weather_cache_refresh ()
@@ -103,6 +108,43 @@ void weather_cache_refresh()
103
108
json_object_put (weather_response_obj );
104
109
}
105
110
111
+ // Now get the forecast
112
+ free (chunk .memory );
113
+ chunk .memory = malloc (1 ); /* will be grown as needed by the realloc above */
114
+ chunk .size = 0 ; /* no data at this point */
115
+
116
+ snprintf (urlbuf , 511 , "http://api.openweathermap.org/data/2.5/forecast?zip=%d,%s&units=%s&APPID=%s" , weather_zip , weather_country_code , weather_temp_units , "337b07da05ad8ebf391e2252f02196cf" );
117
+
118
+ LOG_DEBUG (DT_WEATHER , "Weather URL %s" , urlbuf );
119
+
120
+ curl_easy_setopt (curl_handle , CURLOPT_URL , urlbuf );
121
+
122
+ /* send all data to this function */
123
+ curl_easy_setopt (curl_handle , CURLOPT_WRITEFUNCTION , write_cb );
124
+
125
+ /* we pass our 'chunk' struct to the callback function */
126
+ curl_easy_setopt (curl_handle , CURLOPT_WRITEDATA , (void * )& chunk );
127
+
128
+ /* some servers don't like requests that are made without a user-agent
129
+ field, so we provide one */
130
+ curl_easy_setopt (curl_handle , CURLOPT_USERAGENT , "libcurl-agent/1.0" );
131
+
132
+ /* get it! */
133
+ res = curl_easy_perform (curl_handle );
134
+
135
+ /* check for errors */
136
+ if (res != CURLE_OK )
137
+ {
138
+ LOG_ERROR (DT_WEATHER , "curl_easy_perform() failed: %s\n" , curl_easy_strerror (res ));
139
+ }
140
+ else
141
+ {
142
+ LOG_DEBUG (DT_WEATHER , "%lu bytes retrieved" , (long )chunk .size );
143
+ struct json_object * weather_response_obj = json_tokener_parse (chunk .memory );
144
+ weather_cache_parse_forecast (weather_response_obj );
145
+ json_object_put (weather_response_obj );
146
+ }
147
+
106
148
/* cleanup curl stuff */
107
149
curl_easy_cleanup (curl_handle );
108
150
@@ -118,7 +160,49 @@ void weather_cache_parse_response(struct json_object* weather_response_obj)
118
160
free (weather_cache .precipitation );
119
161
weather_cache .precipitation = 0 ;
120
162
121
- json_object_object_foreach (weather_response_obj , key , value )
163
+ weather_cache_parse_weather_entry (weather_response_obj , & weather_cache );
164
+
165
+ LOG_DEBUG (DT_WEATHER , "Updated weather values - precipitation: %s, temp: %f, humidity: %d, wind: %f" ,
166
+ weather_cache .precipitation ,
167
+ weather_cache .temp ,
168
+ weather_cache .humidity ,
169
+ weather_cache .windspeed );
170
+ }
171
+
172
+ void weather_cache_parse_forecast (struct json_object * weather_response_obj )
173
+ {
174
+ //printf("jobj from str:\n---\n%s\n---\n", json_object_to_json_string_ext(weather_response_obj, JSON_C_TO_STRING_SPACED | JSON_C_TO_STRING_PRETTY));
175
+ stack_empty (weather_cache .forecast_hourly );
176
+
177
+ free (weather_cache .raw_forecast );
178
+
179
+ json_object * entries_array ;
180
+ json_object_object_get_ex (weather_response_obj , "list" , & entries_array );
181
+ int weather_entries = json_object_array_length (entries_array );
182
+
183
+ for (int i = 0 ; i < weather_entries ; i ++ )
184
+ {
185
+ json_object * entry = json_object_array_get_idx (entries_array , i );
186
+ json_object * date_obj ;
187
+ json_object_object_get_ex (entry , "dt" , & date_obj );
188
+
189
+ weather_forecast_cache_t * forecast_entry = calloc (1 , sizeof (weather_forecast_cache_t ));
190
+ forecast_entry -> timestamp = json_object_get_int (date_obj );
191
+
192
+ weather_cache_parse_weather_entry (entry , & forecast_entry -> weather_entry );
193
+
194
+ variant_t * forecast_entry_variant = variant_create_ptr (DT_PTR , forecast_entry , & weather_entry_free );
195
+ stack_push_back (weather_cache .forecast_hourly , forecast_entry_variant );
196
+ }
197
+
198
+ weather_cache .raw_forecast = strdup (json_object_to_json_string_ext (weather_response_obj , JSON_C_TO_STRING_SPACED | JSON_C_TO_STRING_PRETTY ));
199
+ }
200
+
201
+ void weather_cache_parse_weather_entry (struct json_object * weather_entry_obj , weather_cache_t * cache_entry )
202
+ {
203
+ cache_entry -> precipitation = 0 ;
204
+
205
+ json_object_object_foreach (weather_entry_obj , key , value )
122
206
{
123
207
if (strcmp (key , "weather" ) == 0 )
124
208
{
@@ -131,19 +215,19 @@ void weather_cache_parse_response(struct json_object* weather_response_obj)
131
215
{
132
216
const char * weather_string = json_object_get_string (weather_value );
133
217
int old_len = 0 ;
134
- if (NULL != weather_cache . precipitation )
218
+ if (NULL != cache_entry -> precipitation )
135
219
{
136
- old_len = strlen (weather_cache . precipitation );
220
+ old_len = strlen (cache_entry -> precipitation );
137
221
}
138
- weather_cache . precipitation = realloc (weather_cache . precipitation , (old_len + 2 + strlen (weather_string ))* sizeof (char ));
139
- if (NULL != weather_cache . precipitation )
222
+ cache_entry -> precipitation = realloc (cache_entry -> precipitation , (old_len + 2 + strlen (weather_string ))* sizeof (char ));
223
+ if (NULL != cache_entry -> precipitation )
140
224
{
141
- memset (weather_cache . precipitation + (old_len ), 0 , 2 + strlen (weather_string ));
142
- strcat (weather_cache . precipitation , weather_string );
225
+ memset (cache_entry -> precipitation + (old_len ), 0 , 2 + strlen (weather_string ));
226
+ strcat (cache_entry -> precipitation , weather_string );
143
227
144
228
if (i < weather_entries - 1 )
145
229
{
146
- strcat (weather_cache . precipitation , "|" );
230
+ strcat (cache_entry -> precipitation , "|" );
147
231
}
148
232
}
149
233
}
@@ -154,28 +238,30 @@ void weather_cache_parse_response(struct json_object* weather_response_obj)
154
238
struct json_object * temp_data ;
155
239
if (json_object_object_get_ex (value , "temp" , & temp_data ) == TRUE)
156
240
{
157
- weather_cache . temp = json_object_get_double (temp_data );
241
+ cache_entry -> temp = json_object_get_double (temp_data );
158
242
}
159
243
struct json_object * humidity_data ;
160
244
if (json_object_object_get_ex (value , "humidity" , & humidity_data ) == TRUE)
161
245
{
162
- weather_cache . humidity = json_object_get_int (humidity_data );
246
+ cache_entry -> humidity = json_object_get_int (humidity_data );
163
247
}
164
248
}
165
249
else if (strcmp (key , "wind" ) == 0 )
166
250
{
167
251
struct json_object * wind_data ;
168
252
if (json_object_object_get_ex (value , "speed" , & wind_data ) == TRUE)
169
253
{
170
- weather_cache . windspeed = json_object_get_double (wind_data );
254
+ cache_entry -> windspeed = json_object_get_double (wind_data );
171
255
}
172
256
}
173
257
}
174
-
175
- LOG_DEBUG (DT_WEATHER , "Updated weather values - precipitation: %s, temp: %f, humidity: %d, wind: %f" ,
176
- weather_cache .precipitation ,
177
- weather_cache .temp ,
178
- weather_cache .humidity ,
179
- weather_cache .windspeed );
180
258
}
181
259
260
+ void weather_entry_free (void * arg )
261
+ {
262
+ weather_forecast_cache_t * entry = (weather_forecast_cache_t * )arg ;
263
+ free (entry -> weather_entry .precipitation );
264
+ free (entry -> weather_entry .raw_forecast );
265
+ stack_free (entry -> weather_entry .forecast_hourly );
266
+ free (entry );
267
+ }
0 commit comments