FACT++  1.0
void ConnectionWeather::HandleRead ( const boost::system::error_code &  err,
size_t  bytes_received 
)
inlineprotected

Definition at line 65 of file tngweather.cc.

References data, end, Error(), TNGWeather::DimWeather::fAirPressure, TNGWeather::DimWeather::fDewPoint, TNGWeather::DimWeather::fDustTotal, TNGWeather::DimWeather::fHumidity, TNGWeather::DimSeeing::fSeeing, TNGWeather::DimSeeing::fSeeingMed, TNGWeather::DimSeeing::fSeeingStdev, TNGWeather::DimWeather::fSolarimeter, TNGWeather::DimWeather::fTemperature, TNGWeather::DimWeather::fTempTrend, TNGWeather::DimWeather::fWindDirection, TNGWeather::DimWeather::fWindSpeed, hum, Time::IsValid(), and str.

66  {
67  // Do not schedule a new read if the connection failed.
68  if (bytes_received==0 || err)
69  {
70  if (err==ba::error::eof)
71  Warn("Connection closed by remote host.");
72 
73  // 107: Transport endpoint is not connected (bs::error_code(107, bs::system_category))
74  // 125: Operation canceled
75  if (err && err!=ba::error::eof && // Connection closed by remote host
76  err!=ba::error::basic_errors::not_connected && // Connection closed by remote host
77  err!=ba::error::basic_errors::operation_aborted) // Connection closed by us
78  {
79  ostringstream str;
80  str << "Reading from " << URL() << ": " << err.message() << " (" << err << ")";// << endl;
81  Error(str);
82  }
83  PostClose(err!=ba::error::basic_errors::operation_aborted);
84 
85  fRdfData = "";
86  return;
87  }
88 
89  fRdfData += string(fArray.data(), bytes_received);
90 
91  const size_t end = fRdfData.find("\r\n\r\n");
92  if (end==string::npos)
93  {
94  Out() << "Received data corrupted [1]." << endl;
95  Out() << fRdfData << endl;
96  return;
97  }
98 
99  string data(fRdfData);
100  data.erase(0, end+4);
101 
102  size_t pos = 0;
103  while (1)
104  {
105  const size_t chunk = data.find("\r\n", pos);
106  if (chunk==0 || chunk==string::npos)
107  {
108  StartReadReport();
109  return;
110  }
111 
112  size_t len = 0;
113  stringstream val(data.substr(pos, chunk-pos));
114  val >> hex >> len;
115 
116  data.erase(pos, chunk-pos+2);
117  if (len==0)
118  break;
119 
120  pos += len+2; // Count trailing \r\n of chunk
121  }
122 
123 
124  fLastReception = Time();
125  fRdfData = "";
126  PostClose(false);
127 
128  if (fIsVerbose)
129  {
130  Out() << "------------------------------------------------------" << endl;
131  Out() << data << endl;
132  Out() << "------------------------------------------------------" << endl;
133  }
134 
135  QDomDocument doc;
136  if (!doc.setContent(QString(data.data()), false))
137  {
138  Warn("Parsing of xml failed [0].");
139  PostClose(false);
140  return;
141  }
142 
143  if (fIsVerbose)
144  Out() << "Parsed:\n-------\n" << doc.toString().toStdString() << endl;
145 
146  const QDomElement root = doc.documentElement();
147  const QDomElement channel = root.firstChildElement("channel");
148  const QDomElement item = channel.firstChildElement("item");
149 
150  const QDomElement see = item.firstChildElement("tngw:dimmSeeing");
151  const QDomElement mjd = item.firstChildElement("tngw:dimmSeeing.date");
152  const QDomElement med = item.firstChildElement("tngw:dimmSeeing.median");
153  const QDomElement sdev = item.firstChildElement("tngw:dimmSeeing.stdev");
154  const QDomElement dust = item.firstChildElement("tngw:dustTotal");
155  const QDomElement trend = item.firstChildElement("tngw:trend");
156  const QDomElement pres = item.firstChildElement("tngw:airPressure");
157  const QDomElement dew = item.firstChildElement("tngw:dewPoint");
158  const QDomElement wdir = item.firstChildElement("tngw:windDirection");
159  const QDomElement speed = item.firstChildElement("tngw:windSpeed");
160  const QDomElement hum = item.firstChildElement("tngw:hum");
161  const QDomElement tmp = item.firstChildElement("tngw:temperature");
162  const QDomElement solar = item.firstChildElement("tngw:solarimeter");
163  const QDomElement date = item.firstChildElement("tngw:date");
164 
165  if (see.isNull() || mjd.isNull() || med.isNull() || sdev.isNull() ||
166  dust.isNull() || trend.isNull() || pres.isNull() || dew.isNull() ||
167  wdir.isNull() || speed.isNull() || hum.isNull() || tmp.isNull() ||
168  solar.isNull()|| date.isNull())
169  {
170  Warn("Parsing of xml failed [1].");
171  PostClose(false);
172  return;
173  }
174 
175  DimWeather w;
176  w.fDustTotal = dust .text().toFloat();
177  w.fTempTrend = trend.text().toFloat();
178  w.fAirPressure = pres .text().toFloat();
179  w.fDewPoint = dew .text().toFloat();
180  w.fWindDirection = wdir .text().toFloat();
181  w.fWindSpeed = speed.text().toFloat()*3.6;
182  w.fHumidity = hum .text().toFloat();
183  w.fTemperature = tmp .text().toFloat();
184  w.fSolarimeter = solar.text().toFloat();
185 
186  DimSeeing s;
187  s.fSeeing = see .text().toFloat();
188  s.fSeeingMed = med .text().toFloat();
189  s.fSeeingStdev = sdev .text().toFloat();
190 
191  const string dateObj = date.text().toStdString();
192  const string dateSee = mjd .text().toStdString();
193 
194  Time timeObj(dateObj);
195  Time timeSee(dateSee);
196  if (!timeObj.IsValid())
197  {
198  struct tm tm;
199 
200  vector<char> buf(255);
201  if (strptime(dateObj.c_str(), "%c", &tm))
202  timeObj = Time(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
203  tm.tm_hour, tm.tm_min, tm.tm_sec);
204  }
205 
206  if (!timeSee.IsValid())
207  {
208  struct tm tm;
209 
210  vector<char> buf(255);
211  if (strptime(dateSee.c_str(), "%c", &tm))
212  timeSee = Time(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
213  tm.tm_hour, tm.tm_min, tm.tm_sec);
214 
215  Warn("Seeing time invalid ["+dateObj+"]");
216  }
217 
218  if (!timeObj.IsValid())
219  throw runtime_error("object time invalid");
220 
221  if (timeObj!=fLastReport && fIsVerbose)
222  {
223  Out() << endl;
224  Out() << "Date: " << timeObj << endl;
225  Out() << "DustTotal: " << w.fDustTotal << " ugr/m^2" << endl;
226  Out() << "AirPressure: " << w.fAirPressure << " mbar" << endl;
227  Out() << "DewPoint: " << w.fDewPoint << " deg C" << endl;
228  Out() << "WindDirection: " << w.fWindDirection << " deg" << endl;
229  Out() << "WindSpeed: " << w.fWindSpeed << " m/s" << endl;
230  Out() << "Humidity: " << w.fHumidity << "%" << endl;
231  Out() << "Temperature: " << w.fTemperature << " deg C" << endl;
232  Out() << "TempTrend 24h: " << w.fTempTrend << " deg C" << endl;
233  Out() << "Solarimeter: " << w.fSolarimeter << " W/m^2" << endl;
234  Out() << endl;
235  Out() << "Seeing: " << s.fSeeing << " arcsec [" << timeSee << "]" << endl;
236  Out() << "Seeing: " << s.fSeeingMed << " +- " << s.fSeeingStdev << endl;
237  Out() << endl;
238  }
239 
240  fLastReport = timeObj;
241 
242  UpdateWeather(timeObj, w);
243 
244  if (timeSee.IsValid() && fLastSeeing!=timeSee)
245  {
246  UpdateSeeing(timeSee, s);
247  fLastSeeing = timeSee;
248  }
249 
250  if (fDust==w.fDustTotal)
251  return;
252 
253  UpdateDust(timeObj, w.fDustTotal);
254  fDust = w.fDustTotal;
255 
256  ostringstream out;
257  out << setprecision(3) << "Dust: " << fDust << "ug/m^3 [" << timeObj << "]";
258  Message(out);
259  }
Definition: did.h:42
Adds some functionality to boost::posix_time::ptime for our needs.
Definition: Time.h:30
char str[80]
Definition: test_client.c:7
virtual void UpdateSeeing(const Time &, const DimSeeing &)
Definition: tngweather.cc:45
virtual void UpdateWeather(const Time &, const DimWeather &)
Definition: magicweather.cc:40
double end
float hum
Definition: HeadersPFmini.h:55
virtual void UpdateDust(const Time &, const float &)
Definition: tngweather.cc:49
float data[4 *1440]
boost::array< char, 4096 > fArray
Definition: magicweather.cc:46
Error()
Definition: HeadersFTM.h:197

+ Here is the call graph for this function: