void mexFunction( int nl, mxArray *pl[], int nr, const mxArray *pr[] ) { char action[1024]; if(!nr) mexErrMsgTxt("Inputs expected."); mxGetString(pr[0],action,1024); nr--; pr++; char *endptr; JsonValue val; JsonAllocator allocator; if( nl>1 ) mexErrMsgTxt("One output expected."); if(!strcmp(action,"convert")) { if( nr!=1 ) mexErrMsgTxt("One input expected."); if( mxGetClassID(pr[0])==mxCHAR_CLASS ) { // object = mexFunction( string ) char *str = mxArrayToStringRobust(pr[0]); int status = jsonParse(str, &endptr, &val, allocator); if( status != JSON_OK) mexErrMsgTxt(jsonStrError(status)); pl[0] = json(val); mxFree(str); } else { // string = mexFunction( object ) ostrm S; S << std::setprecision(12); json(S,pr[0]); pl[0]=mxCreateStringRobust(S.str().c_str()); } } else if(!strcmp(action,"split")) { // strings = mexFunction( string, k ) if( nr!=2 ) mexErrMsgTxt("Two input expected."); char *str = mxArrayToStringRobust(pr[0]); int status = jsonParse(str, &endptr, &val, allocator); if( status != JSON_OK) mexErrMsgTxt(jsonStrError(status)); if( val.getTag()!=JSON_ARRAY ) mexErrMsgTxt("Array expected"); siz i=0, t=0, n=length(val), k=(siz) mxGetScalar(pr[1]); k=(k>n)?n:(k<1)?1:k; k=ceil(n/ceil(double(n)/k)); pl[0]=mxCreateCellMatrix(1,k); ostrm S; S<<std::setprecision(12); for(auto o:val) { if(!t) { S.str(std::string()); S << "["; t=ceil(double(n)/k); } json(S,&o->value); t--; if(!o->next) t=0; S << (t ? "," : "]"); if(!t) mxSetCell(pl[0],i++,mxCreateStringRobust(S.str().c_str())); } } else if(!strcmp(action,"merge")) { // string = mexFunction( strings ) if( nr!=1 ) mexErrMsgTxt("One input expected."); if(!mxIsCell(pr[0])) mexErrMsgTxt("Cell array expected."); siz n = mxGetNumberOfElements(pr[0]); ostrm S; S << std::setprecision(12); S << "["; for( siz i=0; i<n; i++ ) { char *str = mxArrayToStringRobust(mxGetCell(pr[0],i)); int status = jsonParse(str, &endptr, &val, allocator); if( status != JSON_OK) mexErrMsgTxt(jsonStrError(status)); if( val.getTag()!=JSON_ARRAY ) mexErrMsgTxt("Array expected"); for(auto j:val) json(S,&j->value) << (j->next ? "," : ""); mxFree(str); if(i<n-1) S<<","; } S << "]"; pl[0]=mxCreateStringRobust(S.str().c_str()); } else mexErrMsgTxt("Invalid action."); }
void parse(const char *csource, bool ok) { char *source = strdup(csource); char *endptr; JsonValue value; JsonAllocator allocator; int result = jsonParse(source, &endptr, &value, allocator); if (ok && result) { fprintf(stderr, "FAILED %d: %s\n%s\n%*s - \\x%02X\n", parsed, jsonStrError(result), csource, (int)(endptr - source + 1), "^", *endptr); ++failed; } if (!ok && !result) { fprintf(stderr, "PASSED %d:\n%s\n", parsed, csource); ++failed; } ++parsed; free(source); }
IPState WunderGround::updateWeather() { CURL *curl; CURLcode res; std::string readBuffer; char requestURL[MAXRBUF]; // If location is not updated yet, return busy if (wunderLat == -1000 || wunderLong == -1000) return IPS_BUSY; char *orig = setlocale(LC_NUMERIC,"C"); snprintf(requestURL, MAXRBUF, "http://api.wunderground.com/api/%s/conditions/q/%g,%g.json", wunderAPIKeyT[0].text, wunderLat, wunderLong); curl = curl_easy_init(); if(curl) { curl_easy_setopt(curl, CURLOPT_URL, requestURL); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); res = curl_easy_perform(curl); curl_easy_cleanup(curl); } char srcBuffer[readBuffer.size()]; strncpy(srcBuffer, readBuffer.c_str(), readBuffer.size()); char *source = srcBuffer; // do not forget terminate source string with 0 char *endptr; JsonValue value; JsonAllocator allocator; int status = jsonParse(source, &endptr, &value, allocator); if (status != JSON_OK) { DEBUGF(INDI::Logger::DBG_ERROR, "%s at %zd", jsonStrError(status), endptr - source); DEBUGF(INDI::Logger::DBG_DEBUG, "%s", requestURL); DEBUGF(INDI::Logger::DBG_DEBUG, "%s", readBuffer.c_str()); setlocale(LC_NUMERIC,orig); return IPS_ALERT; } JsonIterator it; JsonIterator observationIterator; for (it = begin(value); it!= end(value); ++it) { if (!strcmp(it->key, "current_observation")) { for (observationIterator = begin(it->value); observationIterator!= end(it->value); ++observationIterator) { if (!strcmp(observationIterator->key, "weather")) { char *value = observationIterator->value.toString(); if (!strcmp(value, "Clear")) setParameterValue("WEATHER_FORECAST", 0); else if (!strcmp(value, "Unknown") || !strcmp(value, "Scattered Clouds") || !strcmp(value, "Partly Cloudy") || !strcmp(value, "Overcast") || !strcmp(value, "Patches of Fog") || !strcmp(value, "Partial Fog") || !strcmp(value, "Light Haze")) setParameterValue("WEATHER_FORECAST", 1); else setParameterValue("WEATHER_FORECAST", 2); DEBUGF(INDI::Logger::DBG_SESSION, "Weather condition: %s", value); } else if (!strcmp(observationIterator->key, "temp_c")) { if (observationIterator->value.isDouble()) setParameterValue("WEATHER_TEMPERATURE", observationIterator->value.toNumber()); else setParameterValue("WEATHER_TEMPERATURE", atof(observationIterator->value.toString())); } else if (!strcmp(observationIterator->key, "wind_kph")) { if (observationIterator->value.isDouble()) setParameterValue("WEATHER_WIND_SPEED", observationIterator->value.toNumber()); else setParameterValue("WEATHER_WIND_SPEED", atof(observationIterator->value.toString())); } else if (!strcmp(observationIterator->key, "wind_gust_kph")) { if (observationIterator->value.isDouble()) setParameterValue("WEATHER_WIND_GUST", observationIterator->value.toNumber()); else setParameterValue("WEATHER_WIND_GUST", atof(observationIterator->value.toString())); } else if (!strcmp(observationIterator->key, "precip_1hr_metric")) { char *value = observationIterator->value.toString(); double mm=-1; if (!strcmp(value, "--")) setParameterValue("WEATHER_RAIN_HOUR", 0); else { mm = atof(value); if (mm >= 0) setParameterValue("WEATHER_RAIN_HOUR", mm); } } } } } setlocale(LC_NUMERIC,orig); return IPS_OK; }
/** * Connect and set position values from focuser response. **/ bool IpFocus::Connect() { if (FocuserEndpointT[0].text == NULL) { DEBUG(INDI::Logger::DBG_ERROR, "Focuser HTTP API endpoint is not available. Set it in the options tab"); return false; } CURL *curl; CURLcode res; std::string readBuffer; curl = curl_easy_init(); if(curl) { curl_easy_setopt(curl, CURLOPT_URL, FocuserEndpointT[0].text); curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L); //10 sec timeout curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); res = curl_easy_perform(curl); /* Check for errors */ if(res != CURLE_OK) { DEBUGF(INDI::Logger::DBG_ERROR, "Connecttion to FOCUSER failed:%s",curl_easy_strerror(res)); DEBUG(INDI::Logger::DBG_ERROR, "Is the HTTP API endpoint correct? Set it in the options tab. Can you ping the focuser?"); return false; } /* always cleanup */ curl_easy_cleanup(curl); char srcBuffer[readBuffer.size()]; strncpy(srcBuffer, readBuffer.c_str(), readBuffer.size()); char *source = srcBuffer; // do not forget terminate source string with 0 char *endptr; JsonValue value; JsonAllocator allocator; int status = jsonParse(source, &endptr, &value, allocator); if (status != JSON_OK) { DEBUGF(INDI::Logger::DBG_ERROR, "%s at %zd", jsonStrError(status), endptr - source); DEBUGF(INDI::Logger::DBG_DEBUG, "%s", readBuffer.c_str()); return IPS_ALERT; } DEBUGF(INDI::Logger::DBG_DEBUG, "Focuser response %s", readBuffer.c_str()); JsonIterator it; for (it = begin(value); it!= end(value); ++it) { DEBUGF(INDI::Logger::DBG_DEBUG, "iterating %s", it->key); if (!strcmp(it->key, "absolutePosition")) { DEBUGF(INDI::Logger::DBG_DEBUG, "Setting absolute position from response %g", it->value.toNumber()); FocusAbsPosN[0].value = it->value.toNumber(); } if (!strcmp(it->key, "maxPosition")) { DEBUGF(INDI::Logger::DBG_DEBUG, "Setting max position from response %g", it->value.toNumber()); FocusAbsPosN[0].max = it->value.toNumber(); } if (!strcmp(it->key, "minPosition")) { DEBUGF(INDI::Logger::DBG_DEBUG, "Setting min position from response %g", it->value.toNumber()); FocusAbsPosN[0].min = it->value.toNumber(); } } } return true; }
IPState WeatherSafetyProxy::parseSafetyJSON(const char *clean_buf, int byte_count) { // copy clean_buf to buf which jsonParse can destroy char buf[BUFSIZ]; strncpy(buf, clean_buf, byte_count); char *source = buf; char *endptr; JsonValue value; JsonAllocator allocator; int status = jsonParse(source, &endptr, &value, allocator); if (status != JSON_OK) { LOGF_ERROR("jsonParse %s at position %zd", jsonStrError(status), endptr - source); LastParseSuccess = false; return IPS_ALERT; } JsonIterator it; JsonIterator observationIterator; bool roof_status_found = false; bool open_ok_found = false; bool reasons_found = false; bool error_found = false; for (it = begin(value); it != end(value); ++it) { if (!strcmp(it->key, "roof_status")) { roof_status_found = true; for (observationIterator = begin(it->value); observationIterator != end(it->value); ++observationIterator) { if (!strcmp(observationIterator->key, "open_ok")) { open_ok_found = true; int NewSafety = observationIterator->value.toNumber(); if (NewSafety != Safety) { if (NewSafety == WSP_UNSAFE) { LOG_WARN("Weather is UNSAFE"); } else if (NewSafety == WSP_SAFE) { if (SofterrorRecoveryMode == true) { SofterrorRecoveryCount++; if (SofterrorRecoveryCount > softErrorHysteresisN[WSP_SOFT_ERROR_RECOVERY].value) { LOG_INFO("Minimum soft recovery errors reached while Weather was SAFE"); SofterrorRecoveryCount = 0; SofterrorRecoveryMode = false; } else { LOGF_INFO("Weather is SAFE but soft error recovery %d is still counting", SofterrorRecoveryCount); NewSafety = WSP_UNSAFE; } } else { LOG_INFO("Weather is SAFE"); } } Safety = NewSafety; } setParameterValue("WEATHER_SAFETY", NewSafety); } else if (!strcmp(observationIterator->key, "reasons")) { reasons_found = true; char *reasons = observationIterator->value.toString(); if (SofterrorRecoveryMode == true) { char newReasons[MAXRBUF]; snprintf(newReasons, MAXRBUF, "SofterrorRecoveryMode, %s", reasons); IUSaveText(&reasonsT[0], newReasons); } else { IUSaveText(&reasonsT[0], reasons); } reasonsTP.s = IPS_OK; IDSetText(&reasonsTP, nullptr); } } } if (!strcmp(it->key, "error")) { error_found = true; } } if (error_found) { LOGF_ERROR("Error hint found in JSON [%s]", clean_buf); LastParseSuccess = false; return IPS_ALERT; } if (!roof_status_found) { LOGF_ERROR("Found no roof_status field in JSON [%s]", clean_buf); LastParseSuccess = false; return IPS_ALERT; } if (!open_ok_found) { LOGF_ERROR("Found no open_ok field in roof_status JSON [%s]", clean_buf); LastParseSuccess = false; return IPS_ALERT; } // do not error if reasons are missing, they're not required for safety if (!LastParseSuccess) { // show the good news. Once. LOGF_INFO("Script output fully parsed, weather is %s", (Safety == 1) ? "SAFE" : "UNSAFE"); LastParseSuccess = true; } return IPS_OK; }