29 #include <curl/curl.h>
38 static size_t WSP_WriteCallback(
void *contents,
size_t size,
size_t nmemb,
void *userp)
40 ((std::string *)userp)->append((
char *)contents, size * nmemb);
55 return "Weather Safety Proxy";
72 IUFillText(&keywordT[0],
"WEATHER_CONDITION",
"Weather Condition",
"condition");
76 "/usr/local/share/indi/scripts/weather_status.py");
80 IUFillText(&UrlT[
WSP_URL],
"WEATHER_SAFETY_URL",
"Weather safety URL",
"http://0.0.0.0:5000/weather/safety");
91 0.0, 1000.0, 1.0, 7.0);
95 addParameter(
"WEATHER_SAFETY",
"Weather Safety", 0.9, 1.1, 0);
98 IUFillText(&reasonsT[0],
"Reasons",
"",
nullptr);
136 static bool once =
true;
155 if (strcmp(name, softErrorHysteresisNP.
name) == 0)
158 softErrorHysteresisNP.
s =
IPS_OK;
170 if (strcmp(name, keywordTP.
name) == 0)
178 if (strcmp(name, ScriptsTP.
name) == 0)
186 if (strcmp(name, UrlTP.
name) == 0)
203 if (!strcmp(name, ScriptOrCurlSP.
name))
205 LOG_DEBUG(
"WeatherSafetyProxy::ISNewSwitch");
222 ret = executeScript();
233 LOGF_WARN(
"Soft error %d occurred during SAFE conditions, counting", SofterrorCount);
236 char Warning[] =
"Max softerrors reached while Weather was SAFE";
243 SofterrorRecoveryMode =
true;
249 LOG_WARN(
"Soft error occurred during UNSAFE conditions, ignore");
251 SofterrorRecoveryCount = 0;
261 IPState WeatherSafetyProxy::executeScript()
265 if (access(
cmd, F_OK | X_OK) == -1)
267 LOGF_ERROR(
"Cannot use script [%s], check its existence and permissions",
cmd);
268 LastParseSuccess =
false;
273 FILE *handle = popen(
cmd,
"r");
274 if (handle ==
nullptr)
277 LastParseSuccess =
false;
281 size_t byte_count = fread(buf, 1, BUFSIZ - 1, handle);
287 LastParseSuccess =
false;
290 LOGF_DEBUG(
"Read %d bytes output [%s]", byte_count, buf);
292 return parseSafetyJSON(buf);
295 IPState WeatherSafetyProxy::executeCurl()
299 std::string readBuffer;
301 curl_handle = curl_easy_init();
304 curl_easy_setopt(curl_handle, CURLOPT_URL, UrlT[
WSP_URL].text);
305 curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WSP_WriteCallback);
306 curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &readBuffer);
307 curl_easy_setopt(curl_handle, CURLOPT_USERAGENT,
"libcurl-agent/1.0");
309 res = curl_easy_perform(curl_handle);
312 LOGF_ERROR(
"curl_easy_perform failed with [%s]", curl_easy_strerror(res));
315 curl_easy_cleanup(curl_handle);
316 LOGF_DEBUG(
"Read %d bytes output [%s]", readBuffer.size(), readBuffer.c_str());
317 return parseSafetyJSON(readBuffer);
326 IPState WeatherSafetyProxy::parseSafetyJSON(
const std::string &
buffer)
332 report[
"roof_status"][
"open_ok"].
get_to(NewSafety);
334 if (NewSafety != Safety)
342 if (SofterrorRecoveryMode ==
true)
344 SofterrorRecoveryCount++;
347 LOG_INFO(
"Minimum soft recovery errors reached while Weather was SAFE");
348 SofterrorRecoveryCount = 0;
349 SofterrorRecoveryMode =
false;
353 LOGF_INFO(
"Weather is SAFE but soft error recovery %d is still counting", SofterrorRecoveryCount);
370 report[
"roof_status"][
"reasons"].
get_to(reasons);
371 if (SofterrorRecoveryMode ==
true)
374 snprintf(newReasons,
MAXRBUF,
"SofterrorRecoveryMode, %s", reasons.c_str());
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.
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
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 updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
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...
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
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 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...
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
const char * getDefaultName() override
virtual IPState updateWeather() override
updateWeather Update weather conditions from device or service. The function should not change the st...
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual ~WeatherSafetyProxy()
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
bool Disconnect() override
Disconnect from device.
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 * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
const char * OPTIONS_TAB
OPTIONS_TAB Where all the driver's options are located. Those may include auxiliary controls,...
void IUSaveConfigSwitch(FILE *fp, const ISwitchVectorProperty *svp)
Add a switch vector property value to the configuration file.
void IUFillNumberVector(INumberVectorProperty *nvp, INumber *np, int nnp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a number vector property. The vector's auxiliary elements will be set to NULL.
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 IUSaveText(IText *tp, const char *newtext)
Function to reliably save new text in a IText.
void IUSaveConfigNumber(FILE *fp, const INumberVectorProperty *nvp)
Add a number vector property value to the configuration file.
void IUFillSwitch(ISwitch *sp, const char *name, const char *label, ISState s)
Assign attributes for a switch property. The switch'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 IUFillNumber(INumber *np, const char *name, const char *label, const char *format, double min, double max, double step, double value)
Assign attributes for a number property. The number'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.
void IUFillSwitchVector(ISwitchVectorProperty *svp, ISwitch *sp, int nsp, const char *dev, const char *name, const char *label, const char *group, IPerm p, ISRule r, double timeout, IPState s)
Assign attributes for a switch vector property. The vector's auxiliary elements will be set to NULL.
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
void IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
void IDSetSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
int IUUpdateText(ITextVectorProperty *tvp, char *texts[], char *names[], int n)
Update all text members in a text vector property.
int IUUpdateNumber(INumberVectorProperty *nvp, double values[], char *names[], int n)
Update all numbers in a number vector property.
void IDSetText(const ITextVectorProperty *tvp, const char *fmt,...)
#define LOGF_INFO(fmt,...)
#define LOGF_WARN(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::vector< uint8_t > buffer
basic_json<> json
default specialization
std::unique_ptr< WeatherSafetyProxy > weatherSafetyProxy(new WeatherSafetyProxy())
@ WSP_SOFT_ERROR_RECOVERY