30 #include <curl/curl.h>
38 static size_t WriteCallback(
void *contents,
size_t size,
size_t nmemb,
void *userp)
40 ((std::string *)userp)->append((
char *)contents, size * nmemb);
60 return (
const char *)
"WunderGround";
65 if (wunderAPIKeyT[0].text ==
nullptr)
67 LOG_ERROR(
"Weather Underground API Key is not available. Please register your API key at "
68 "www.wunderground.com and save it under Options.");
84 IUFillText(&wunderAPIKeyT[0],
"API_KEY",
"API Key",
nullptr);
89 addParameter(
"WEATHER_TEMPERATURE",
"Temperature (C)", -10, 30, 15);
90 addParameter(
"WEATHER_WIND_SPEED",
"Wind (kph)", 0, 20, 15);
91 addParameter(
"WEATHER_WIND_GUST",
"Gust (kph)", 0, 20, 15);
92 addParameter(
"WEATHER_RAIN_HOUR",
"Precip (mm)", 0, 0, 15);
117 if (!strcmp(wunderAPIKeyTP.
name, name))
133 wunderLat = latitude;
134 wunderLong = (longitude > 180) ? (longitude - 360) : longitude;
143 std::string readBuffer;
147 if (wunderLat == -1000 || wunderLong == -1000)
152 snprintf(requestURL,
MAXRBUF,
"http://api.wunderground.com/api/%s/conditions/q/%g,%g.json", wunderAPIKeyT[0].text,
153 wunderLat, wunderLong);
155 curl = curl_easy_init();
158 curl_easy_setopt(curl, CURLOPT_URL, requestURL);
159 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
160 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
161 res = curl_easy_perform(curl);
162 curl_easy_cleanup(curl);
165 char srcBuffer[readBuffer.size()];
166 strncpy(srcBuffer, readBuffer.c_str(), readBuffer.size());
167 char *source = srcBuffer;
171 JsonAllocator allocator;
172 int status = jsonParse(source, &endptr, &value, allocator);
173 if (status != JSON_OK)
175 LOGF_ERROR(
"%s at %zd", jsonStrError(status), endptr - source);
182 JsonIterator observationIterator;
184 for (it = begin(value); it != end(value); ++it)
186 if (!strcmp(it->key,
"current_observation"))
188 for (observationIterator = begin(it->value); observationIterator != end(it->value); ++observationIterator)
190 if (!strcmp(observationIterator->key,
"weather"))
192 char *value = observationIterator->value.toString();
194 if (!strcmp(value,
"Clear"))
196 else if (!strcmp(value,
"Unknown") || !strcmp(value,
"Scattered Clouds") ||
197 !strcmp(value,
"Partly Cloudy") || !strcmp(value,
"Overcast") ||
198 !strcmp(value,
"Patches of Fog") || !strcmp(value,
"Partial Fog") ||
199 !strcmp(value,
"Light Haze"))
204 LOGF_INFO(
"Weather condition: %s", value);
206 else if (!strcmp(observationIterator->key,
"temp_c"))
208 if (observationIterator->value.isDouble())
211 setParameterValue(
"WEATHER_TEMPERATURE", atof(observationIterator->value.toString()));
213 else if (!strcmp(observationIterator->key,
"wind_kph"))
215 if (observationIterator->value.isDouble())
218 setParameterValue(
"WEATHER_WIND_SPEED", atof(observationIterator->value.toString()));
220 else if (!strcmp(observationIterator->key,
"wind_gust_kph"))
222 if (observationIterator->value.isDouble())
225 setParameterValue(
"WEATHER_WIND_GUST", atof(observationIterator->value.toString()));
227 else if (!strcmp(observationIterator->key,
"precip_1hr_metric"))
229 char *value = observationIterator->value.toString();
231 if (!strcmp(value,
"--"))
const char * getDeviceName() const
virtual void ISGetProperties(const char *dev)
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
void setVersion(uint16_t vMajor, uint16_t vMinor)
Set driver version information to be defined in DRIVER_INFO property as vMajor.vMinor.
virtual bool loadConfig(bool silent=false, const char *property=nullptr)
Load the last saved configuration file.
void defineProperty(INumberVectorProperty *property)
void addDebugControl()
Add Debug control to the driver.
void setParameterValue(std::string name, double value)
setParameterValue Update weather parameter value
bool setCriticalParameter(std::string param)
setCriticalParameter Set parameter that is considered critical to the operation of the observatory....
void addParameter(std::string name, std::string label, double numMinOk, double numMaxOk, double percWarning)
addParameter Add a physical weather measurable parameter to the weather driver. The weather value has...
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
void setWeatherConnection(const uint8_t &value)
setWeatherConnection Set Weather connection mode. Child class should call this in the constructor bef...
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
virtual bool saveConfigItems(FILE *fp)
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
const char * getDefaultName()
virtual void ISGetProperties(const char *dev) override
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
virtual bool updateLocation(double latitude, double longitude, double elevation)
Update weather station location.
virtual IPState updateWeather()
updateWeather Update weather conditions from device or service. The function should not change the st...
bool Connect()
Connect to the device. INDI::DefaultDevice implementation connects to appropriate connection interfac...
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
bool Disconnect()
Disconnect from device.
const char * OPTIONS_TAB
OPTIONS_TAB Where all the driver's options are located. Those may include auxiliary controls,...
void IUFillTextVector(ITextVectorProperty *tvp, IText *tp, int ntp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a text vector property. The vector's auxiliary elements will be set to NULL.
void IUFillText(IText *tp, const char *name, const char *label, const char *initialText)
Assign attributes for a text property. The text's auxiliary elements will be set to NULL.
void IUSaveConfigText(FILE *fp, const ITextVectorProperty *tvp)
Add a text vector property value to the configuration file.
int IUUpdateText(ITextVectorProperty *tvp, char *texts[], char *names[], int n)
Update all text members in a text vector property.
void IDSetText(const ITextVectorProperty *tvp, const char *fmt,...)
#define LOGF_INFO(fmt,...)
#define LOGF_DEBUG(fmt,...)
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
#define LOGF_ERROR(fmt,...)
std::unique_ptr< WunderGround > wunderGround(new WunderGround())