#include "forecast.h" #include "math.h" #include <string.h> #include <stdlib.h> #include <math.h> #include <Time.h> #include <avr/pgmspace.h> ////////////////////////////////////////////////////////////////////////// // w5100 2 (4 2) // XML 3 15-18 // // 4 ( 1 8, ). ////////////////////////////////////////////////////////////////////////// // w5100.h // MAX_SOCK_NUM 2 // SOCKETS = 2; // SMASK = 0x0FFF; // Tx buffer MASK // RMASK = 0x0FFF; // Rx buffer MASK // SSIZE = 4096; // Max Tx buffer size // RSIZE = 4096; // Max Rx buffer size ////////////////////////////////////////////////////////////////////////// // w5100.cpp // TX_RX_MAX_BUF_SIZE 4096 // writeTMSR(0xAA); // writeRMSR(0xAA); ////////////////////////////////////////////////////////////////////////// // Ethernet.h // MAX_SOCK_NUM 2 ////////////////////////////////////////////////////////////////////////// // Ethernet.cpp // uint8_t EthernetClass::_state[MAX_SOCK_NUM] = { 0, 0 }; // uint16_t EthernetClass::_server_port[MAX_SOCK_NUM] = { 0 , 0 }; ////////////////////////////////////////////////////////////////////////// #include <Ethernet.h> /////////////////////////////////////////////////////////////////////////////////////////////// // PROGMEM , . 504 RAM const char p_FCserver[] PROGMEM = "api.openweathermap.org"; const char p_APIID[] PROGMEM = "&APPID="; // API-, ! const char p_request3Hour[] PROGMEM = "GET /data/2.5/forecast?q=Krasnoyarsk&mode=xml&units=metric"; const char p_request4Day[] PROGMEM = "GET /data/2.5/forecast/daily?q=Krasnoyarsk&mode=xml&units=metric&cnt=4"; const char p_requestToDay[] PROGMEM = "GET /data/2.5/weather?q=Krasnoyarsk&mode=xml&units=metric"; const char p_ConnClose[] PROGMEM = "Connection: close"; const char p_HTTP[] PROGMEM = " HTTP/1.1"; PGM_P const string_table[] PROGMEM = {p_FCserver, p_APIID,p_request3Hour,p_request4Day,p_requestToDay,p_ConnClose,p_HTTP}; char words[80]; /////////////////////////////////////////////////////////////////////////////////////////////// #define MAX_STRING_LEN 100 char tagStr[MAX_STRING_LEN] = ""; char tmpStr[MAX_STRING_LEN] = ""; char endTag[3] = {'<', '/', '\0'}; char inChar; // FORECAST::FORECAST() { fDebug = false; } // EthernetClient, // , .. void FORECAST::Init(EthernetClient& clnt, int timeZone) { client = clnt; tZone = timeZone; tDelay = 1000; } // 3 (2 3 ) int FORECAST::GetForecast3Hour(FORECAST::_WeatherThreeHour *whp) { int p1 = 0,p2 = 0; char TMP[20]; String temp = ""; float T; if (client.connected()) client.stop(); if (client.connect(GetWord(0), 80)) { temp = GetWord(2); //temp += GetWord(1); temp += GetWord(6); //if (fDebug) Serial.println(temp); client.println(temp); client.print("Host: "); client.println(GetWord(0)); client.println(GetWord(5)); client.println(); temp = ""; // , - while (!client.available()) { p1++; delay(50); if ( p1 > tDelay ) { client.stop(); return 0; } } iPacket3H = 0; while (client.available()) { //----------------------------------------------------------- inChar = client.read(); if (inChar == '<') // { addChar(inChar, tmpStr); tagFlag = true; } else if (inChar == '>') // { addChar(inChar, tmpStr); if (tagFlag) // { strncpy(tagStr, tmpStr, strlen(tmpStr)+1); } clearStr(tmpStr); tagFlag = false; } else if (inChar != 10) { if (tagFlag) { addChar(inChar, tmpStr); // Check for </XML> end tag, ignore it if ( tagFlag && strcmp(tmpStr, endTag) == 0 ) { clearStr(tmpStr); tagFlag = false; } } } // - if ((inChar == 10 ) || (inChar == '>')) { dataString = tagStr; if( !strncmp(tagStr,"<time from",10)) { //<time from="2014-11-26T03:00:00" to="2014-11-26T06:00:00"> //if (fDebug) Serial.println(tagStr); p1 = dataString.indexOf('"',1); p1++; p2 = dataString.indexOf('"',p1); temp = dataString.substring(p1,p2-3); temp.replace("T"," "); temp.toCharArray(TMP,temp.length()+1); (*whp)[iPacket3H].Data = _ConvertDateTime(TMP); } else if( !strncmp(tagStr,"<symbol",7)) { // <symbol number="600" name="light snow" var="13d"/> p1 = dataString.indexOf("var"); SubStrA(p1,dataString,temp); temp.toCharArray((*whp)[iPacket3H].Icon,temp.length()+1); } else if( !strncmp(tagStr,"<precipitation",14)) { // <precipitation unit="3h" value="0.125" type="rain"> //if (fDebug) Serial.println(tagStr); int sign; clearStr(TMP); if (dataString.indexOf("rain") > 0) sign = 1; // else if (dataString.indexOf("snow") > 0 || dataString.indexOf("show") > 0) sign = -1; // //29.09.2015 - snow show else sign = 0; // p1 = dataString.indexOf("value"); if (sign != 0) { SubStrA(p1,dataString,temp); temp.toCharArray(TMP,temp.length()+1); (*whp)[iPacket3H].RainVal = atof(TMP) * sign * 100; } else (*whp)[iPacket3H].RainVal = 0; } else if( !strncmp(tagStr,"<windDirection",14)) { //<windDirection deg="235" code="SW" name="Southwest"/> p1 = dataString.indexOf("code"); SubStrA(p1,dataString,temp); temp.toCharArray((*whp)[iPacket3H].WD,temp.length()+1); } else if( !strncmp(tagStr,"<windSpeed",10)) { //<windSpeed mps="4.62" name="Gentle Breeze"/> clearStr(TMP); SubStrA(1,dataString,temp); temp.toCharArray(TMP,temp.length()+1); T = atof(TMP); (*whp)[iPacket3H].WS = round(T); } else if( !strncmp(tagStr,"<temperature",12)) { //<temperature unit="celsius" value="-12.92" min="-17.91" max="-12.92"/> clearStr(TMP); p1 = dataString.indexOf("value"); SubStrA(p1,dataString,temp); temp.toCharArray(TMP,temp.length()+1); T = atof(TMP); (*whp)[iPacket3H].T = round(T); if (T < 0) p1 = dataString.indexOf("min"); else p1 = dataString.indexOf("max"); clearStr(TMP); SubStrA(p1,dataString,temp); temp.toCharArray(TMP,temp.length()+1); T = atof(TMP); (*whp)[iPacket3H].TT = round(T); } else if( !strncmp(tagStr,"<pressure",9)) { //<pressure unit="hPa" value="999.14"/> p1 = dataString.indexOf("value"); SubStrA(p1,dataString,temp); (*whp)[iPacket3H].P = temp.toInt(); (*whp)[iPacket3H].P =((*whp)[iPacket3H].P * 0.75); // - 17 } else if( !strncmp(tagStr,"<humidity",9)) { //<humidity value="73" unit="%"/> SubStrA(1,dataString,temp); (*whp)[iPacket3H].H = temp.toInt(); } else if( !strncmp(tagStr,"<clouds",7)) { // <clouds value="broken clouds" all="56" unit="%"/> p1 = dataString.indexOf("all"); SubStrA(p1,dataString,temp); (*whp)[iPacket3H].Cloud = temp.toInt(); iPacket3H++; } clearStr(tmpStr); clearStr(tagStr); tagFlag = false; } //----------------------------------------------------------- if (iPacket3H==16) {break;} } client.stop(); return 1; } else {return 0;} } /////////////////////////////////////////////// 4 /////////////////////////////////////////////////////// /* int FORECAST::GetForecastDays(FORECAST::_WeatherDay* wdp) { int iPack=0,p=0; char TMP[20]; String temp; float T; if (client.connected()) client.stop(); if (client.connect(GetWord(0), 80)) { temp = GetWord(3); //temp += GetWord(1); temp += GetWord(6); if (fDebug) Serial.println(temp); client.println(temp); client.print("Host: "); client.println(GetWord(0)); client.println(GetWord(5)); client.println(); temp = ""; while (!client.available()) { p++; delay(50); if ( p > tDelay ) { client.stop(); return 0; } } while (client.available()) { inChar = client.read(); if (inChar == '<') // { addChar(inChar, tmpStr); tagFlag = true; } else if (inChar == '>') // { addChar(inChar, tmpStr); if (tagFlag) // { strncpy(tagStr, tmpStr, strlen(tmpStr)+1); } clearStr(tmpStr); tagFlag = false; } else if (inChar != 10) { if (tagFlag) { addChar(inChar, tmpStr); // Check for </XML> end tag, ignore it if ( tagFlag && strcmp(tmpStr, endTag) == 0 ) { clearStr(tmpStr); tagFlag = false; } } } // - if ((inChar == 10 ) || (inChar == '>')) { dataString = tagStr; if( !strncmp(tagStr,"<time day",9)) { //<time day="2014-10-09"> SubStrA(1,dataString,temp); //temp.toCharArray((*wdp)[iPack].Data,temp.length()+1); temp.toCharArray(TMP,temp.length()+1); (*wdp)[iPack].Data = _ConvertDate(TMP); //if (fDebug) Serial.println(temp); } else if( !strncmp(tagStr,"<symbol",7)) { // <symbol number="600" name="light snow" var="13d"/> p = dataString.indexOf("var"); SubStrA(p,dataString,temp); temp.toCharArray((*wdp)[iPack].Icon,temp.length()+1); } else if( !strncmp(tagStr,"<precipitation",14)) { // <precipitation value="1.25" type="snow"/> int sign; clearStr(TMP); if (dataString.indexOf("rain") > 0) sign = 1; // else if (dataString.indexOf("snow") > 0 || dataString.indexOf("show") > 0) sign = -1; // else sign = 0; // if (sign != 0) { p=1; SubStrA(p,dataString,temp); temp.toCharArray(TMP,temp.length()+1); (*wdp)[iPack].RainVal = atof(TMP) * sign * 100; } else (*wdp)[iPack].RainVal = 0; } else if( !strncmp(tagStr,"<windDirection",14)) { //<windDirection deg="235" code="SW" name="Southwest"/> p = dataString.indexOf("code"); SubStrA(p,dataString,temp); temp.toCharArray((*wdp)[iPack].WD,temp.length()+1); } else if( !strncmp(tagStr,"<windSpeed",10)) { //<windSpeed mps="4.62" name="Gentle Breeze"/> clearStr(TMP); SubStrA(1,dataString,temp); temp.toCharArray(TMP,temp.length()+1); T = atof(TMP); (*wdp)[iPack].WS = round(T); } else if( !strncmp(tagStr,"<temperature",12)) { //<temperature day="4.48" min="-1.12" max="4.48" night="-0.94" eve="-1.12" morn="2.26"/> clearStr(TMP); SubStrA(1,dataString,temp); temp.toCharArray(TMP,temp.length()+1); T = atof(TMP); (*wdp)[iPack].TD = round(T); clearStr(TMP); p = dataString.indexOf("night"); SubStrA(p,dataString,temp); temp.toCharArray(TMP,temp.length()+1); T = atof(TMP); (*wdp)[iPack].TN = round(T); } else if( !strncmp(tagStr,"<pressure",9)) { //<pressure unit="hPa" value="999.14"/> p = dataString.indexOf("value"); SubStrA(p,dataString,temp); (*wdp)[iPack].P = temp.toInt(); (*wdp)[iPack].P =((*wdp)[iPack].P * 0.75 - 17); } else if( !strncmp(tagStr,"<humidity",9)) { //<humidity value="73" unit="%"/> SubStrA(1,dataString,temp); (*wdp)[iPack].H = temp.toInt(); } else if( !strncmp(tagStr,"<clouds",7)) { // <clouds value="broken clouds" all="56" unit="%"/> p = dataString.indexOf("all"); SubStrA(p,dataString,temp); (*wdp)[iPack].Cloud = temp.toInt(); iPack++; } clearStr(tmpStr); clearStr(tagStr); tagFlag = false; } } // client.stop(); return 1; } else {return 0;} } */ ///////////////////////////// ////////////////////////////////////////////////////////////// /* int FORECAST::GetForecast(FORECAST::_WeatherPacket& whr) { int p1 = 0; char TMP[20]; String temp = ""; float T; int step = 0; if (client.connected()) client.stop(); if (client.connect(GetWord(0), 80)) { temp = GetWord(4); //temp += GetWord(1); temp += GetWord(6); if (fDebug) Serial.println(temp); client.println(temp); client.print("Host: "); client.println(GetWord(0)); client.println(GetWord(5)); client.println(); temp = ""; while (!client.available()) // { p1++; delay(50); if ( p1 > tDelay ) // - { client.stop(); return 0; } } while (client.available()) // - { // Read a char inChar = client.read(); //if (fDebug) Serial.print(inChar); if (inChar == '<') { addChar(inChar, tmpStr); tagFlag = true; } else if (inChar == '>') { addChar(inChar, tmpStr); if (tagFlag) { strncpy(tagStr, tmpStr, strlen(tmpStr)+1); } clearStr(tmpStr); tagFlag = false; dataFlag = true; } else if (inChar != 10) { if (tagFlag) { addChar(inChar, tmpStr); // Check for </XML> end tag, ignore it if ( tagFlag && strcmp(tmpStr, endTag) == 0 ) { clearStr(tmpStr); tagFlag = false; dataFlag = false; } } } // If a LF, process the line if ((inChar == 10 ) || (inChar == '>')) { dataString = tagStr; if( !strncmp(tagStr,"<sun",4)) { // <sun rise="2014-10-14T00:18:33" set="2014-10-14T10:51:01"/> SubStrA(1,dataString,temp); temp.replace("T"," "); temp.toCharArray(TMP,temp.length()+1); if (fDebug) {Serial.print("SunRise_w_");Serial.println(TMP);} SunRise = _ConvertDateTime(TMP); p1 = dataString.indexOf("set"); p1++; SubStrA(p1,dataString,temp); temp.replace("T"," "); temp.toCharArray(TMP,temp.length()+1); SunSet = _ConvertDateTime(TMP); step++; } else if( !strncmp(tagStr,"<temperature",12)) { //<temperature value="-9.86" min="-16" max="-6.3" unit="celsius"/> clearStr(TMP); SubStrA(1,dataString,temp); temp.toCharArray(TMP,temp.length()+1); T = atof(TMP); whr.T = round(T); step++; if (fDebug) Serial.println(tagStr); } else if( !strncmp(tagStr,"<humidity",9)) { //<humidity value="65" unit="%"/> SubStrA(1,dataString,temp); whr.H = temp.toInt(); step++; } else if( !strncmp(tagStr,"<pressure",9) ) { //<pressure value="1027" unit="hPa"/> SubStrA(1,dataString,temp); // whr.P = round(temp.toInt() * 0.75 - 17); whr.P = temp.toInt() ; step++; if (fDebug) Serial.println(tagStr); } else if( !strncmp(tagStr,"<speed",6) ) { //<speed value="1.51" name=""/> clearStr(TMP); SubStrA(1,dataString,temp); temp.toCharArray(TMP,temp.length()+1); T = atof(TMP); whr.WS = round(T); step++; if (fDebug) Serial.println(tagStr); } else if( !strncmp(tagStr,"<direction",10) ) { //<direction value="160.501" code="SSE" name="South-southeast"/> p1 = dataString.indexOf("code"); SubStrB(p1,dataString,temp); temp.toCharArray(whr.WD,temp.length()+1); step++; if (fDebug) Serial.println(tagStr); } else if( !strncmp(tagStr,"<weather",8) ) { //<weather number="803" value="broken clouds" icon="04d"/> p1 = dataString.indexOf("icon"); SubStrA(p1,dataString,temp); temp.toCharArray(whr.Icon,temp.length()+1); step++; if (fDebug) {Serial.println(tagStr);Serial.println("-------------------");} } clearStr(tmpStr); clearStr(tagStr); tagFlag = false; dataFlag = false; } } // client.stop(); if (step > 5) return 1; else return 0; } else {return 0;} } */ //////////////////// //////////////////////////////////////////////////// void FORECAST::SubStrA(int Num,String& source, String& str) { int p1 = source.indexOf('"',Num); p1++; int p2 = source.indexOf('"',p1); str = source.substring(p1,p2); } // void FORECAST::SubStrB(int Num,String& source, String& str) { int p1 = source.indexOf('"',Num); p1++; int p2 = source.indexOf('"',p1+1); if (p2 - p1 < 1) str = "WNW"; else str = source.substring(p1,p2); } //Function to add a char to a string and check its length void FORECAST::addChar(char ch, char* str) { char const *tagMsg = "!=!"; if (strlen(str) > MAX_STRING_LEN - 2) { if (tagFlag) { clearStr(tagStr); strcpy(tagStr,tagMsg); } // Clear the temp buffer and flags to stop current processing clearStr(tmpStr); tagFlag = false; } else { // Add char to string str[strlen(str)] = ch; } } // Function to clear a string void FORECAST::clearStr(char* str) { int len = strlen(str); for (int c = 0; c < len; c++) { str[c] = 0; } } time_t FORECAST::_ConvertDate(char _Data[11]) { int Y, M, D; TimeElements te; sscanf ( _Data,"%i-%d-%d", &Y, &M, &D); te.Year = Y -1900; te.Month = M; te.Day = D; te.Hour=0; te.Minute=0; te.Second=0; return makeTime(te); } time_t FORECAST::_ConvertDateTime(char _DateTime[17]) { int Y, M, D, hh, mm; TimeElements te; // ( ) sscanf ( _DateTime,"%i-%d-%d %d:%d", &Y, &M, &D, &hh, &mm ); // TimeZone hh = hh + tZone; if (hh > 24) { hh = hh - 24; if ( (M == 2 && D == 28 && Y%4 != 0)|| (M == 2 && D == 29 && Y%4 == 0) || ((M == 1 || M == 3 || M == 5 || M == 7 || M == 8 || M == 10 || M == 12) && D == 31) || ((M == 4 || M == 6 || M == 9 || M == 11) && D == 30) ) { M++; D = 1; if (M==13) {M=1;Y++;} } else D++; } te.Year = Y -1900; te.Month = M; te.Day = D; te.Hour = hh; te.Minute = mm; te.Second=0; return makeTime(te); } // flash - № char* FORECAST::GetWord(uint8_t numWord) { strcpy_P(words, (PGM_P)pgm_read_word(&(string_table[numWord]))); return words; }