// This #include statement was automatically added by the Spark IDE. #include "neopixel/neopixel.h" #include "application.h" /* The following section contains the configuration for the API key, location and NEOPIXELs */ const char* api_key = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"; // nearest weather station to me is ALBEMARLE, 3238 String location = "3238"; // IMPORTANT: Set pixel COUNT, PIN and TYPE #define PIXEL_PIN A7 #define PIXEL_COUNT 11 #define PIXEL_TYPE WS2812B /* No configuration past this line!!! */ Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE); typedef struct { int hour; int year; int month; int day; int min; int sec; } timestamp_t; typedef struct { char wind_direction[3]; // D int direction_length; // store for length of wind direction float temperature; // T int weather_type; // W float wind_speed; // S float dew_point; // Dp char pressure_tendency; // Pt int wind_gust; // G int visibility; // V float screen_relative_humidity;// H int pressure; // P } weather_t; bool get_weather(timestamp_t* time_data, weather_t* met_responce); bool get_capabilities(timestamp_t* time_data); int update_location (String new_location); #define PI 3.1415926535897932384626433832795 #define M_PI 3.141592653589793238462643 #define TIMEOUT 1000000 TCPClient client; const char* hostname = "datapoint.metoffice.gov.uk"; const char* path = "/public/data/val/wxobs/all/xml/"; const char* path_middle = "?res=hourly&time="; const char* path_end = "Z&key="; const char* capabilities = "/public/data/val/wxobs/all/xml/capabilities?res=hourly&key="; bool location_updated = false; uint32_t next_connection = 0; bool get_capabilities(timestamp_t* time_data) { bool result = false; bool timeout = false; long long int time_of_last_recieve = 0; uint8_t count = 0; char responce[5] = { 0 }; char incoming_data; char store[20] = { 0 }; if (next_connection < micros()) { if (client.connect(hostname, 80)) { //Serial1.println("connected"); client.print("GET "); client.print(capabilities); client.print(api_key); client.println(" HTTP/1.0"); client.print("Host: "); client.println(hostname); client.println("Content-Length: 0"); client.println(); next_connection = micros() + 10000; } else { // Serial1.println("connection failed"); } } Serial1.println("wait"); delay(500); time_of_last_recieve = micros(); while (!timeout) { if (client.available()) { incoming_data = client.read(); time_of_last_recieve = micros(); if( count == 0 ) { responce[3] = incoming_data; incoming_data = 0; if ( strcmp("", responce) == 0 ) { // store the next 20 characters count = 20; responce[0] = 0; responce[1] = 0; responce[2] = 0; responce[3] = 0; } else { responce[0] = responce[1]; responce[1] = responce[2]; responce[2] = responce[3]; } } else { if (( 20 - count ) > 20) { // Serial1.println("count error"); } else { store [20 - count] = incoming_data; } count--; } } if ( ( time_of_last_recieve + TIMEOUT ) < micros() ) { timeout = true; } } result = sscanf(store, "%4u-%2d-%2dT%2d:%2d:%2d", &(time_data->year), &(time_data->month), &(time_data->day), &(time_data->hour), &(time_data->min), &(time_data->sec)); if (!client.connected()) { client.stop(); } return result; } bool get_weather(timestamp_t* time_data, weather_t* met_responce) { bool result = false; bool timeout = false; long long int time_of_last_recieve = 0; uint8_t count = 0; char responce[5] = { 0 }; char store[100] = { 0 }; int8_t index = 0; // int8_t index_end = 0; char incoming_data; if (1)//(next_connection < micros()) { if (client.connect(hostname, 80)) { // Serial1.println("connected"); client.print("GET "); client.print(path); client.print(location); client.print(path_middle); client.print(time_data->year); client.print("-"); if (time_data->month<10) { client.print("0"); } client.print(time_data->month); client.print("-"); if (time_data->day<10) { client.print("0"); } client.print(time_data->day); client.print("T"); if (time_data->hour == 0) { time_data->hour = 24; } if ((time_data->hour-1)<10) { client.print("0"); } client.print((time_data->hour)-1); client.print(path_end); client.print(api_key); client.println(" HTTP/1.0"); client.print("Host: "); client.println(hostname); client.println("Content-Length: 0"); client.println(); } else { // Serial1.println("connection failed"); } } delay(500); time_of_last_recieve = micros(); while (!timeout) { if (client.available()) { incoming_data = client.read(); if( count == 0 ) { responce[3] = incoming_data; time_of_last_recieve = micros(); if( strcmp("wind_gust = 0; while (store[index] != '\0') { if (store[index] == '>') { break; } switch (store[index]) { case 'D': // could be D or Dp { index++; if (store[index] == 'p') // Dew Point { start = temp.indexOf('\"', index) + 1; finish = temp.indexOf('\"', start); met_responce->dew_point = temp.substring(start, finish).toFloat(); index = finish; } else // it's wind direction { start = temp.indexOf('\"', index)+1; finish = temp.indexOf('\"', start); if ( (finish - start) == 3 ) { met_responce->wind_direction[0] = store[start]; met_responce->wind_direction[1] = store[start+1]; met_responce->wind_direction[2] = store[start+2]; met_responce->direction_length = 3; } else if ((finish - start) == 2 ) { met_responce->wind_direction[0] = store[start]; met_responce->wind_direction[1] = store[start+1]; met_responce->wind_direction[2] = 0; met_responce->direction_length = 2; } else { met_responce->wind_direction[0] = store[start]; met_responce->wind_direction[1] = store[start+1]; met_responce->wind_direction[2] = 0; met_responce->direction_length = 1; } index = finish; } break; } case 'P': { if (store[index+1] == 't') // Pressure tendancy { start = temp.indexOf('\"', index) + 1; finish = temp.indexOf('\"', start); met_responce->pressure_tendency = store[start]; index = finish; } else // it's pressure { start = temp.indexOf('\"', index) + 1; finish = temp.indexOf('\"', start); met_responce->pressure = temp.substring(start, finish).toInt(); } index = finish; break; } case 'W': { start = temp.indexOf('\"', index) + 1; finish = temp.indexOf('\"', start); met_responce->weather_type = temp.substring(start, finish).toInt(); index = finish; break; } case 'V': { start = temp.indexOf('\"', index) + 1; finish = temp.indexOf('\"', start); met_responce->visibility = temp.substring(start, finish).toInt(); index = finish; break; } case 'T': { start = temp.indexOf('\"', index) + 1; finish = temp.indexOf('\"', start); met_responce->temperature = temp.substring(start, finish).toFloat(); index = finish; break; } case 'S': { start = temp.indexOf('\"', index) + 1; finish = temp.indexOf('\"', start); met_responce->wind_speed = temp.substring(start, finish).toInt(); index = finish; break; } case 'H': { start = temp.indexOf('\"', index) + 1; finish = temp.indexOf('\"', start); met_responce->screen_relative_humidity = temp.substring(start, finish).toFloat(); index = finish; break; } case 'G': { start = temp.indexOf('\"', index) + 1; finish = temp.indexOf('\"', start); met_responce->wind_gust = temp.substring(start, finish).toInt(); index = finish; break; } } index++; } if (!client.connected()) { client.stop(); } return result; } int update_location(String new_location) { location = new_location; location_updated = true; uint8_t i = 0; for(i=0; i