32 #include <curl/curl.h>
42 static size_t WriteCallback(
void *contents,
size_t size,
size_t nmemb,
void *userp)
44 ((std::string *)userp)->append((
char *)contents, size * nmemb);
52 owmLat = std::numeric_limits<double>::quiet_NaN();
53 owmLong = std::numeric_limits<double>::quiet_NaN();
56 curl_global_init(CURL_GLOBAL_DEFAULT);
61 curl_global_cleanup();
66 return "OpenWeatherMap";
77 if (owmAPIKeyTP[0].
getText() ==
nullptr)
79 LOG_ERROR(
"OpenWeatherMap API Key is not available. Please register your API key at "
80 "www.openweathermap.org and save it under Options.");
96 char api_key[256] = {0};
98 owmAPIKeyTP[0].
fill(
"API_KEY",
"API Key", api_key);
102 addParameter(
"WEATHER_TEMPERATURE",
"Temperature (C)", -10, 30, 15);
103 addParameter(
"WEATHER_PRESSURE",
"Pressure (hPa)", 900, 1100, 15);
104 addParameter(
"WEATHER_HUMIDITY",
"Humidity (%)", 0, 100, 15);
105 addParameter(
"WEATHER_WIND_SPEED",
"Wind (m/s)", 0, 20, 15);
106 addParameter(
"WEATHER_RAIN_HOUR",
"Rain precip (mm)", 0, 0, 15);
107 addParameter(
"WEATHER_SNOW_HOUR",
"Snow precip (mm)", 0, 0, 15);
108 addParameter(
"WEATHER_CLOUD_COVER",
"Clouds (%)", 0, 100, 15);
109 addParameter(
"WEATHER_CODE",
"Status code", 200, 810, 15);
128 owmAPIKeyTP.
update(texts, names, n);
144 owmLong = (longitude > 180) ? (longitude - 360) : longitude;
151 CURL *curl {
nullptr};
153 std::string readBuffer;
154 char errorBuffer[CURL_ERROR_SIZE] = {0};
155 char requestURL[
MAXRBUF] = {0};
158 if (std::isnan(owmLat) || std::isnan(owmLong))
163 snprintf(requestURL,
MAXRBUF,
"http://api.openweathermap.org/data/2.5/weather?lat=%g&lon=%g&appid=%s&units=metric",
164 owmLat, owmLong, owmAPIKeyTP[0].
getText());
166 curl = curl_easy_init();
169 curl_easy_setopt(curl, CURLOPT_URL, requestURL);
170 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
171 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
172 curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);
174 res = curl_easy_perform(curl);
175 curl_easy_cleanup(curl);
178 if(strlen(errorBuffer))
180 LOGF_ERROR(
"Error %d reading data: %s", res, errorBuffer);
184 LOGF_ERROR(
"Error %d reading data: %s", res, curl_easy_strerror(res));
191 double temperature = 0;
202 json weatherReport = json::parse(readBuffer);
204 weatherReport[
"weather"][0][
"id"].
get_to(code);
205 if (code >= 200 && code < 300)
210 else if (code >= 300 && code < 400)
215 else if (code >= 500 && code < 700)
220 else if (code >= 700 && code < 800)
225 else if (code == 800)
230 else if (code >= 801 && code <= 803)
235 else if (code >= 804 && code < 900)
242 weatherReport[
"main"][
"temp"].
get_to(temperature);
244 weatherReport[
"main"][
"pressure"].
get_to(pressure);
246 weatherReport[
"main"][
"humidity"].
get_to(humidity);
248 weatherReport[
"wind"][
"speed"].
get_to(wind);
250 weatherReport[
"clouds"][
"all"].
get_to(clouds);
254 weatherReport[
"rain"][
"h"].
get_to(rain);
256 weatherReport[
"snow"][
"h"].
get_to(snow);
285 owmAPIKeyTP.
save(fp);
const char * getDeviceName() const
INDI::PropertyText getText(const char *name) const
virtual bool saveConfig(bool silent=false, const char *property=nullptr)
Save the current properties in a configuration file.
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.
void defineProperty(INumberVectorProperty *property)
void addDebugControl()
Add Debug control to the driver.
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
const char * getName() const
bool isNameMatch(const char *otherName) const
bool update(const char *const texts[], const char *const names[], int n)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
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 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) override
Update weather station location.
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
bool Connect() override
Connect to the device. INDI::DefaultDevice implementation connects to appropriate connection interfac...
const char * getDefaultName() override
virtual IPState updateWeather() override
updateWeather Update weather conditions from device or service. The function should not change the st...
bool Disconnect() override
Disconnect from device.
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
virtual ~OpenWeatherMap()
a class to store JSON values
ValueType & get_to(ValueType &v) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), v)))
get a value (explicit)
general exception of the basic_json class
const char * what() const noexcept override
returns the explanatory string
const int id
the id of the exception
const char * OPTIONS_TAB
OPTIONS_TAB Where all the driver's options are located. Those may include auxiliary controls,...
int IUGetConfigText(const char *dev, const char *property, const char *member, char *value, int len)
IUGetConfigText Opens configuration file and reads single text property.
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
#define LOGF_ERROR(fmt,...)
basic_json<> json
default specialization
std::unique_ptr< OpenWeatherMap > openWeatherMap(new OpenWeatherMap())