From e463cfd3cbd419dc38583fe25b93be36b330a606 Mon Sep 17 00:00:00 2001 From: Gaspar Fernandez Date: Fri, 12 Aug 2016 01:29:28 +0200 Subject: Version 0.4d --- src/localtemp.cpp | 359 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 359 insertions(+) create mode 100644 src/localtemp.cpp (limited to 'src/localtemp.cpp') diff --git a/src/localtemp.cpp b/src/localtemp.cpp new file mode 100644 index 0000000..388de6e --- /dev/null +++ b/src/localtemp.cpp @@ -0,0 +1,359 @@ + /******************************************************************************* + * File: localtemp.cpp * + * Version: 0.3 * + * Date: 20080508 * + * Author: Gaspar Fernández (helyo@totaki.com) * + * * + * Copyright (C) 2008 Gaspar Fernández * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ******************************************************************************** + * Description: + * It is part of a Window Maker dockapp called dwgo. This class reads weather + * of a selected location from National Weather Service (http://weather.noaa.gov/) + * and parses some information to display it formatted on screen. + * I know it parses unnecesary information, but I'm planning to update dwgo + * with some improvements that use all this information. + * + * Change History: + * Date (D.M.Y) Author Modification + * 08.05.2008 Gaspar Fernández Initial release + * 31.10.2010 Gaspar Fernández Bug Corrections + * + ********************************************************************************/ + +#include "localtemp.h" +#include "MySock.h" +#include "dwgo.h" // Theme numbers + +using namespace std; + +/************************************************************* + * Constructur: localtemp * + ************************************************************* + * Description: * + * Initializes variables * + * * + * Input: * + * char *metar - ICAO name locator (4 chars) * + * char location_name - Name of this location * + * * + * Change History: * + * Date Author Modification * + * * + *************************************************************/ +localtemp::localtemp(char *metar, char *location_name) +{ + this->metar=metar; + this->location_name=location_name; + this->celsius=0; + this->fahrenheit=0; + this->loaded=false; + this->theme=DEFAULT_THEME; +} + +/************************************************************* + * Method: set_temp * + ************************************************************* + * Description: * + * Extract temperature information. In Celsius and * + * Fahrenheit * + * * + * Input: * + * string tmp_str - Temporary string containing * + * temperature in Celsius and Fahrenheit * + * * + * Change History: * + * Date Author Modification * + * * + *************************************************************/ +void localtemp::set_temp(string tmp_str) +{ + char buf[8],buf3[8]; + // Format xx F (xx C) + sscanf(tmp_str.data(), "%s %s (%s", buf, buf3, buf3); // We don't want to store the middle F + this->celsius=atoi(buf3); + this->fahrenheit=atoi(buf); +} + +/************************************************************* + * Method: set_humidity * + ************************************************************* + * Description: * + * Extract humidity information. * + * * + * Input: * + * string hum - Temporary string containing humidity info. * + * * + * Change History: * + * Date Author Modification * + * * + *************************************************************/ +void localtemp::set_humidity(string hum) +{ + char buf[5]; // Be able to store a 100%\0 + // Format (xxx%) + sscanf(hum.data(), "%s", buf); + this->humidity=atoi(buf); +} + +/************************************************************* + * Method: get_ob_info * + ************************************************************* + * Description: * + * Extracts METAR encoded information. We find it in * + * the line starting with "ob: ". We parse this information * + * and fill in variables. Used for time and sky conditions. * + * * + * Input: * + * Nothing * + * * + * Change History: * + * Date Author Modification * + * * + *************************************************************/ +void localtemp::get_ob_info() // ob: line stores METAR information. This info. is useful to know more exactly sky conditions. +{ // It stores also temperature, time and other info extracted by the decoded text + + size_t pos; + struct tm *localtm; + struct tm *remotetm; + remotetm =new struct tm; + string timeinfo; +try + { + timeinfo=this->ob.substr(6,this->ob.find(' ',6)-6); // DDHHMM[Z] Day Hour Minute Z (Zulu, Aviation Time Reference) + } catch (exception &e) + { + cout<<"fallo en 1"<tm_mday=atoi(timeinfo.substr(0,2).data()); + remotetm->tm_hour=atoi(timeinfo.substr(2,2).data()); + remotetm->tm_min=atoi(timeinfo.substr(4,2).data()); + } catch (exception &e) + { + cout<<"fallo en 2"<tm_mon=localtm->tm_mon; + remotetm->tm_year=localtm->tm_year; + remotetm->tm_sec=0; + + if (remotetm->tm_mday==1) // Month of the data + { + if (remotetm->tm_mday!=localtm->tm_mday) + remotetm->tm_mon++; + if (remotetm->tm_mon==12) // It can't be 12!! + { + remotetm->tm_mon=0; + remotetm->tm_year++; + } + } + info_time=mktime(remotetm); + +try + { + this->ob=this->ob.substr(ob.find(' ',6)); // Extract ICAO station name and TIME INFO. + // It will prevent some errors. We could find any of these strings in that name. + + //this->ob=this->ob.substr(this->ob.find(this->metar)+5); + this->ob=this->ob.substr(0,this->ob.rfind('/')-2); // The info. we want is located betweet the last + + pos=this->ob.rfind('/'); // 2 slashes. The las one indicates temperature and dew point + if (pos!=string::npos) // The other one, may not exists but sometimes it does. + this->ob=this->ob.substr(this->ob.rfind('/')); + + } catch (exception &e) + { + cout <<"Fallo en 3"<ob.find("TCU")!=string::npos) + mInfo.sky=tcu; + else if ((this->ob.find("BKN")!=string::npos) || + (this->ob.find("OVC")!=string::npos)) + mInfo.sky=brkovc; + else if ((this->ob.find("FEW")!=string::npos) || + (this->ob.find("SCT")!=string::npos)) + mInfo.sky=cloudy; + else if ((this->ob.find("CAVOK")!=string::npos) || + (this->ob.find("SKC")!=string::npos) || + (this->ob.find("CLR")!=string::npos)) + mInfo.sky=clear; + else + mInfo.sky=undef_sky; + + mInfo.CB=(this->ob.find("CB")!=string::npos); + + + //Rain + if ((this->ob.find("DZ")!=string::npos) || + (this->ob.find("RA")!=string::npos)) + mInfo.rain=rain; + else if ((this->ob.find("SN")!=string::npos) || + (this->ob.find("SG")!=string::npos)) + mInfo.rain=snow; + else if ((this->ob.find("GS")!=string::npos) || + (this->ob.find("GR")!=string::npos)) + mInfo.rain=hail; + else + mInfo.rain=undef_rain; + + //Fog + if ((this->ob.find("BR")!=string::npos) || + (this->ob.find("FG")!=string::npos)) + mInfo.fog=fog; + else if ((this->ob.find("DU")!=string::npos) || + (this->ob.find("DS")!=string::npos)) + mInfo.fog=dust; + else if ((this->ob.find("FC")!=string::npos) || + (this->ob.find("FU")!=string::npos) || + (this->ob.find("HZ")!=string::npos) || + (this->ob.find("SA")!=string::npos) || + (this->ob.find("SS")!=string::npos) || + (this->ob.find("VA")!=string::npos)) + mInfo.fog=other; + else + mInfo.fog=undef_fog; + + // The most important for the display theme is rain, then fog and then sky conditions + if (mInfo.rain!=undef_rain) + { + switch (mInfo.rain) + { + case rain: theme=RAINY_THEME; break; + case snow: theme=SNOWY_THEME; break; + case hail: theme=HAIL_THEME; break; + default: break; + } + } + else if (mInfo.fog!=undef_fog) + { + switch (mInfo.fog) + { + case fog : theme=FOG_THEME; break; + case dust : theme=DUST_THEME; break; + case other: theme=PARTS_THEME; break; + default: break; + } + } + else if (mInfo.sky!=undef_sky) + { + switch (mInfo.sky) + { + case clear : theme=CLEAR_THEME; break; + case cloudy : theme=CLOUDY_THEME; break; + case brkovc : theme=BROKEN_THEME; break; + case tcu : theme=TCU_THEME; break; + default: break; + } + } + else + theme=DEFAULT_THEME; // Nothing significant found. +} + +/************************************************************* + * Method: getInfo * + ************************************************************* + * Description: * + * Fetch information and parse the file * + * * + * Output: * + * True if we downloaded it right, false if not. * + * * + * Change History: * + * Date Author Modification * + * 20101031 Gaspar Fernández Bug in skt * + *************************************************************/ +bool localtemp::getInfo() +{ + char *metar_fetch; // Get Metar data URL + MySock *skt; + HTTP_Request *http; + string::size_type pos, pos2; + TKey_Value datarl; + this->error=0; // No error + this->loaded=false; + metar_fetch= (char*) malloc(80); + string tmp; + + sprintf(metar_fetch, METAR_URL, this->metar.data()); + + skt = new MySock(metar_fetch); + verbsth(VERB_ASTTO, "Open connection: "); + + http=skt->GetHTTPData(); + + delete skt; // We don't need this anymore + + if (http!=NULL) + { + if (http->status==200) + { + time(&get_time); // We got the file at this moment + pos=0; + + verbsth(VERB_ASTTO, "Get Data: "); + + do + { + pos2=http->data.find("\n",pos+1); + if (pos==0) // Extracts the first line (Name of the Station) + { + this->long_location=http->data.substr(0, http->data.find("(",0)-1); + verbsth(VERB_ASTTO, "Station name: "+this->long_location); + } + if (pos2!=string::npos) + { + tmp = http->data.substr(pos,pos2-pos); + datarl.key=tmp.substr(0, tmp.find(":")); + datarl.value=tmp.substr(tmp.find(":")+1); + if (datarl.key=="Temperature") + this->set_temp(datarl.value); + else if (datarl.key=="Relative Humidity") + this->set_humidity(datarl.value); + else if (datarl.key=="Sky conditions") + this->sky=datarl.value; + else if (datarl.key=="ob") + this->ob=datarl.value; + // Search interesting data + pos=pos2+1; + } + } while (pos2!=string::npos); + verbsth(VERB_ASTTO, "Get ob info: "); + + get_ob_info(); // Get info from the METAR string + this->loaded=true; + verbsth(VERB_ASTTO, "Close connection: "); + + } + else +// { + this->error=1; // Not found + // Print request +// cout<data<