diff options
m--------- | ctl-utilities | 0 | ||||
-rw-r--r-- | plugins/builtin.cpp | 14 | ||||
-rw-r--r-- | plugins/gps.cpp | 2 | ||||
-rw-r--r-- | plugins/low-can.cpp | 34 | ||||
-rw-r--r-- | signal-composer-binding/signal-composer-binding.cpp | 4 | ||||
-rw-r--r-- | signal-composer-binding/signal-composer.cpp | 62 | ||||
-rw-r--r-- | signal-composer-binding/signal.cpp | 139 | ||||
-rw-r--r-- | signal-composer-binding/signal.hpp | 45 | ||||
-rw-r--r-- | signal-composer-binding/source.cpp | 2 |
9 files changed, 126 insertions, 176 deletions
diff --git a/ctl-utilities b/ctl-utilities -Subproject ff14c58cb3390065a20f598d58efaea088d7107 +Subproject a58d83be3c4dc0ea780ab4094b12dd9d125368b diff --git a/plugins/builtin.cpp b/plugins/builtin.cpp index e56d413..28bcba7 100644 --- a/plugins/builtin.cpp +++ b/plugins/builtin.cpp @@ -32,27 +32,23 @@ CTLP_LUA_REGISTER("builtin"); CTLP_LUA2C (setSignalValueWrap, source, argsJ, responseJ) { const char* name = nullptr; - double resultNum; + json_object* resultNumJ; uint64_t timestamp; struct signalCBT* ctx = (struct signalCBT*)source->context; - if(! wrap_json_unpack(argsJ, "{ss, sF, sI? !}", + if(! wrap_json_unpack(argsJ, "{ss, so, sI? !}", "name", &name, - "value", &resultNum, + "value", &resultNumJ, "timestamp", ×tamp)) { - *responseJ = json_object_new_string("Fail to unpack JSON arguments value"); return -1; } - *responseJ = json_object_new_string(json_object_to_json_string(argsJ)); - - struct signalValue result = resultNum; if(ctx->aSignal) - {ctx->setSignalValue(ctx->aSignal, timestamp*NANO, result);} + ctx->setSignalValue(ctx->aSignal, timestamp*NANO, resultNumJ); else - {ctx->searchNsetSignalValue(name, timestamp*NANO, result);} + ctx->searchNsetSignalValue(name, timestamp*NANO, resultNumJ); return 0; } diff --git a/plugins/gps.cpp b/plugins/gps.cpp index 646754a..4913f31 100644 --- a/plugins/gps.cpp +++ b/plugins/gps.cpp @@ -59,7 +59,7 @@ CTLP_CAPI (getHeading, source, argsJ, eventJ) { if(coordUpdated) { heading = round(r2d * atan2((curLon - prvLon) * cos(d2r * curLat), curLat - prvLat)); - ctx->setSignalValue(ctx->aSignal, 0, heading); + ctx->setSignalValue(ctx->aSignal, 0, json_object_new_double(heading)); } AFB_NOTICE("======== Heading: %f", heading); diff --git a/plugins/low-can.cpp b/plugins/low-can.cpp index 7bbe763..5153ee9 100644 --- a/plugins/low-can.cpp +++ b/plugins/low-can.cpp @@ -31,8 +31,8 @@ extern "C" CTLP_CAPI_REGISTER("low-can"); typedef struct { - bool door; - bool window; + json_object* door; + json_object* window; } doorT; typedef struct { @@ -47,11 +47,13 @@ struct pluginCtxT { allDoorsCtxT allDoorsCtx; }; -void setDoor(doorT* aDoor, const char* eventName, int eventStatus) +void setDoor(doorT* aDoor, const char* eventName, json_object* eventStatus) { - if(strcasestr(eventName, "door")) {aDoor->door = eventStatus;} - else if(strcasestr(eventName, "window")) {aDoor->window = eventStatus;} - else {AFB_WARNING("Unexpected behavior, this '%s' is not a door ! ", eventName);} + if(json_object_is_type(eventStatus, json_type_boolean)) { + if(strcasestr(eventName, "door")) aDoor->door = eventStatus; + else if(strcasestr(eventName, "window")) aDoor->window = eventStatus; + else AFB_WARNING("Unexpected behavior, this '%s' is not a door ! ", eventName); + } } // Call at initialisation time @@ -132,12 +134,12 @@ CTLP_CAPI (subscribeToLow, source, argsJ, eventJ) { CTLP_CAPI (isOpen, source, argsJ, eventJ) { const char *eventName = nullptr; - int eventStatus; + json_object *eventStatus; uint64_t timestamp; struct signalCBT* context = reinterpret_cast<struct signalCBT*>(source->context); struct pluginCtxT* pluginCtx = reinterpret_cast<struct pluginCtxT*>(context->pluginCtx); - int err = wrap_json_unpack(eventJ, "{ss,sb,s?I}", + int err = wrap_json_unpack(eventJ, "{ss,so,s?I}", "name", &eventName, "value", &eventStatus, "timestamp", ×tamp); @@ -177,14 +179,14 @@ CTLP_CAPI (isOpen, source, argsJ, eventJ) { source->uid, argsJ ? json_object_to_json_string(argsJ):"", eventJ ? json_object_to_json_string(eventJ):"", - pluginCtx->allDoorsCtx.front_left.door ? "true":"false", - pluginCtx->allDoorsCtx.front_left.window ? "true":"false", - pluginCtx->allDoorsCtx.front_right.door ? "true":"false", - pluginCtx->allDoorsCtx.front_right.window ? "true":"false", - pluginCtx->allDoorsCtx.rear_left.door ? "true":"false", - pluginCtx->allDoorsCtx.rear_left.window ? "true":"false", - pluginCtx->allDoorsCtx.rear_right.door ? "true":"false", - pluginCtx->allDoorsCtx.rear_right.window ? "true":"false" + json_object_get_string(pluginCtx->allDoorsCtx.front_left.door), + json_object_get_string(pluginCtx->allDoorsCtx.front_left.window), + json_object_get_string(pluginCtx->allDoorsCtx.front_right.door), + json_object_get_string(pluginCtx->allDoorsCtx.front_right.window), + json_object_get_string(pluginCtx->allDoorsCtx.rear_left.door), + json_object_get_string(pluginCtx->allDoorsCtx.rear_left.window), + json_object_get_string(pluginCtx->allDoorsCtx.rear_right.door), + json_object_get_string(pluginCtx->allDoorsCtx.rear_right.window) ); return 0; diff --git a/signal-composer-binding/signal-composer-binding.cpp b/signal-composer-binding/signal-composer-binding.cpp index 0d9c8e3..f7c8c73 100644 --- a/signal-composer-binding/signal-composer-binding.cpp +++ b/signal-composer-binding/signal-composer-binding.cpp @@ -32,10 +32,8 @@ /// @param[in] object - eventual data that comes with the event void onEvent(const char *event, json_object *object) { - Composer& composer = Composer::instance(); - AFB_NOTICE("event: %s", json_object_to_json_string(object)); + std::vector<std::shared_ptr<Signal>> signals { Composer::instance().searchSignals(event) }; - std::vector<std::shared_ptr<Signal>> signals = composer.searchSignals(event); if(!signals.empty()) { // If there is more than 1 element then maybe we can find a more diff --git a/signal-composer-binding/signal-composer.cpp b/signal-composer-binding/signal-composer.cpp index 99129b4..f7c1971 100644 --- a/signal-composer-binding/signal-composer.cpp +++ b/signal-composer-binding/signal-composer.cpp @@ -21,7 +21,7 @@ #include "clientApp.hpp" -extern "C" void searchNsetSignalValueHandle(const char* aName, uint64_t timestamp, struct signalValue value) +extern "C" void searchNsetSignalValueHandle(const char* aName, uint64_t timestamp, json_object* value) { std::vector<std::shared_ptr<Signal>> signals = Composer::instance().searchSignals(aName); if(!signals.empty()) @@ -31,7 +31,7 @@ extern "C" void searchNsetSignalValueHandle(const char* aName, uint64_t timestam } } -extern "C" void setSignalValueHandle(void* aSignal, uint64_t timestamp, struct signalValue value) +extern "C" void setSignalValueHandle(void* aSignal, uint64_t timestamp, json_object* value) { Signal* sig = static_cast<Signal*>(aSignal); sig->set(timestamp, value); @@ -380,47 +380,25 @@ void Composer::processOptions(const std::map<std::string, int>& opts, std::share { avg = true; double value = sig->average(o.second); - json_object_object_add(response, "value", - json_object_new_double(value)); + json_object_object_add(response, "value", json_object_new_double(value)); } else if (o.first.compare("minimum") && !min) { min = true; double value = sig->minimum(); - json_object_object_add(response, "value", - json_object_new_double(value)); + json_object_object_add(response, "value", json_object_new_double(value)); } else if (o.first.compare("maximum") && !max) { max = true; double value = sig->maximum(); - json_object_object_add(response, "value", - json_object_new_double(value)); + json_object_object_add(response, "value", json_object_new_double(value)); } else if (o.first.compare("last") && !last) { last = true; - struct signalValue value = sig->last_value(); - if(value.hasBool) - { - json_object_object_add(response, "value", - json_object_new_boolean(value.boolVal)); - } - else if(value.hasNum) - { - json_object_object_add(response, "value", - json_object_new_double(value.numVal)); - } - else if(value.hasStr) - { - json_object_object_add(response, "value", - json_object_new_string(value.strVal.c_str())); - } - else - { - json_object_object_add(response, "value", - json_object_new_string("No recorded value so far.")); - } + json_object* value = sig->last_value(); + json_object_object_add(response, "value", value); } else { @@ -568,8 +546,9 @@ std::vector<std::shared_ptr<Signal>> Composer::searchSignals(const std::string& if(sep != std::string::npos) { api = aName.substr(0, sep); + std::string signal_id = aName.substr(sep + 1, std::string::npos); std::shared_ptr<SourceAPI> source = getSourceAPI(api); - return source->searchSignals(aName); + return source->searchSignals(signal_id); } else { @@ -603,27 +582,8 @@ json_object* Composer::getsignalValue(const std::string& sig, json_object* optio "signal", sig->id().c_str()); if (opts.empty()) { - struct signalValue value = sig->last_value(); - if(value.hasBool) - { - json_object_object_add(response, "value", - json_object_new_boolean(value.boolVal)); - } - else if(value.hasNum) - { - json_object_object_add(response, "value", - json_object_new_double(value.numVal)); - } - else if(value.hasStr) - { - json_object_object_add(response, "value", - json_object_new_string(value.strVal.c_str())); - } - else - { - json_object_object_add(response, "value", - json_object_new_string("No recorded value so far.")); - } + json_object* value = sig->last_value(); + json_object_object_add(response, "value", value); } else {processOptions(opts, sig, response);} diff --git a/signal-composer-binding/signal.cpp b/signal-composer-binding/signal.cpp index 2f1aa57..14e85ba 100644 --- a/signal-composer-binding/signal.cpp +++ b/signal-composer-binding/signal.cpp @@ -148,9 +148,8 @@ json_object* Signal::toJSON() const if(timestamp_) json_object_object_add(sigJ, "timestamp", json_object_new_int64(timestamp_)); - if (value_.hasBool) {json_object_object_add(sigJ, "value", json_object_new_boolean(value_.boolVal));} - else if (value_.hasNum) {json_object_object_add(sigJ, "value", json_object_new_double(value_.numVal));} - else if (value_.hasStr) {json_object_object_add(sigJ, "value", json_object_new_string(value_.strVal.c_str()));} + if(value_) + json_object_object_add(sigJ, "value", value_); return sigJ; } @@ -198,19 +197,21 @@ json_object *Signal::getSignalsArgs() /// /// @param[in] timestamp - timestamp of occured signal /// @param[in] value - value of change -void Signal::set(uint64_t timestamp, struct signalValue& value) +void Signal::set(uint64_t timestamp, json_object*& value) { uint64_t diff = retention_+1; value_ = value; timestamp_ = timestamp; - history_[timestamp_] = value_; + history_[timestamp_] = json_object_get(value_); while(diff > retention_) { uint64_t first = history_.begin()->first; diff = (timestamp_ - first)/NANO; - if(diff > retention_) - {history_.erase(history_.cbegin());} + if(diff > retention_) { + json_object_put(history_.cbegin()->second); + history_.erase(history_.cbegin()); + } } notify(); @@ -253,37 +254,22 @@ void Signal::update(Signal* sig) /// @param[in] eventJ - json_object containing event data to process /// /// @return 0 if ok, -1 or others if not -void Signal::defaultReceivedCB(json_object *eventJ) +void Signal::defaultReceivedCB(Signal *signal, json_object *eventJ) { uint64_t ts = 0; - struct signalValue sv; + json_object* sv = nullptr; json_object_iterator iter = json_object_iter_begin(eventJ); json_object_iterator iterEnd = json_object_iter_end(eventJ); + while(!json_object_iter_equal(&iter, &iterEnd)) { std::string key = json_object_iter_peek_name(&iter); std::transform(key.begin(), key.end(), key.begin(), ::tolower); json_object *value = json_object_iter_peek_value(&iter); if (key.find("value") != std::string::npos || - key.find(id_) != std::string::npos) + key.find(signal->id()) != std::string::npos) { - switch (json_object_get_type(value)) { - case json_type_double: - sv = json_object_get_double(value); - break; - case json_type_int: - sv = json_object_get_int(value); - break; - case json_type_boolean: - sv = json_object_get_int(value); - break; - case json_type_string: - sv = json_object_get_string(value); - break; - default: - sv = signalValue(); - break; - } + sv = json_object_get(value); } else if (key.find("timestamp") != std::string::npos) { @@ -292,9 +278,9 @@ void Signal::defaultReceivedCB(json_object *eventJ) json_object_iter_next(&iter); } - if(!sv.hasBool && !sv.hasNum && !sv.hasStr) + if(!sv) { - AFB_ERROR("No data found to set signal %s in %s", id_.c_str(), json_object_to_json_string(eventJ)); + AFB_ERROR("No data found to set signal %s in %s", signal->id().c_str(), json_object_to_json_string(eventJ)); return; } else if(ts == 0) @@ -305,7 +291,7 @@ void Signal::defaultReceivedCB(json_object *eventJ) ts = (uint64_t)(t.tv_sec) * (uint64_t)NANO + (uint64_t)(t.tv_nsec); } - set(ts, sv); + signal->set(ts, sv); } /// @brief Notify observers that there is a change and execute callback defined @@ -343,7 +329,7 @@ void Signal::onReceivedCB(json_object *eventJ) if (onReceived_) ActionExecOne(&source, onReceived_, json_object_get(eventJ)); else - defaultReceivedCB(eventJ); + defaultReceivedCB(this, eventJ); } /// @brief Make a Signal observer observes Signals observables @@ -382,22 +368,31 @@ double Signal::average(int seconds) const double total = 0.0; int nbElt = 0; - for (const auto& val: history_) + for(const auto& val: history_) { - if(val.first >= end) - {break;} - if(val.second.hasNum) + if(val.first >= end) { + break; + } + if(val.second) { - total += val.second.numVal; + switch(json_object_get_type(val.second)) { + case json_type_int: + total += static_cast<double>(json_object_get_int64(val.second)); + break; + case json_type_double: + total += json_object_get_double(val.second); + break; + default: + AFB_ERROR("The stored value '%s' for the signal '%s' isn't numeric, it is not possible to compute an average value.", json_object_get_string(val.second), id_.c_str()); + break; + } nbElt++; } else { - AFB_ERROR("There isn't numerical value to compare with in that signal '%s'. Stored value : bool %d, num %lf, str: %s", + AFB_ERROR("There isn't numerical value to compare with in that signal '%s'. Stored value: %s", id_.c_str(), - val.second.boolVal, - val.second.numVal, - val.second.strVal.c_str()); + json_object_get_string(val.second)); break; } } @@ -416,21 +411,34 @@ double Signal::minimum(int seconds) const uint64_t end = seconds ? begin+(seconds*NANO) : history_.rbegin()->first; + double current = 0.0; double min = DBL_MAX; - for (auto& v : history_) + for(const auto& val : history_) { - if(v.first >= end) - {break;} - else if(v.second.hasNum && v.second.numVal < min) - {min = v.second.numVal;} + if(val.first >= end) { + break; + } + else if(val.second) { + switch(json_object_get_type(val.second)) { + case json_type_int: + current = static_cast<double>(json_object_get_int64(val.second)); + min = current < min ? current : min; + break; + case json_type_double: + current = json_object_get_double(val.second); + min = current < min ? current : min; + break; + default: + AFB_ERROR("The stored value '%s' for signal '%s' isn't numeric, it is not possible to find a minimum value.", json_object_get_string(val.second), id_.c_str()); + break; + } + } else { - AFB_ERROR("There isn't numerical value to compare with in that signal '%s'. Stored value : bool %d, num %lf, str: %s", + AFB_ERROR("There isn't numerical value to compare with in that signal '%s'. Stored value: %s", id_.c_str(), - v.second.boolVal, - v.second.numVal, - v.second.strVal.c_str()); + json_object_get_string(val.second)); break; } } @@ -448,21 +456,34 @@ double Signal::maximum(int seconds) const uint64_t end = seconds ? begin+(seconds*NANO) : history_.rbegin()->first; + double current = 0.0; double max = 0.0; - for (auto& v : history_) + for(const auto& val : history_) { - if(v.first >= end) - {break;} - else if(v.second.hasNum && v.second.hasNum > max) - {max = v.second.numVal;} + if(val.first >= end) { + break; + } + else if(val.second) { + switch(json_object_get_type(val.second)) { + case json_type_int: + current = static_cast<double>(json_object_get_int64(val.second)); + max = current > max ? current : max; + break; + case json_type_double: + current = json_object_get_double(val.second); + max = current > max ? current : max; + break; + default: + AFB_ERROR("The stored value '%s' for signal '%s' isn't numeric, it is not possible to find a maximum value.", json_object_get_string(val.second), id_.c_str()); + break; + } + } else { - AFB_ERROR("There isn't numerical value to compare with in that signal '%s'. Stored value : bool %d, num %lf, str: %s", + AFB_ERROR("There isn't numerical value to compare with in that signal '%s'. Stored value: %s", id_.c_str(), - v.second.boolVal, - v.second.numVal, - v.second.strVal.c_str()); + json_object_get_string(val.second)); break; } } @@ -472,7 +493,7 @@ double Signal::maximum(int seconds) const /// @brief Return last value recorded /// /// @return Last value -struct signalValue Signal::last_value() const +json_object* Signal::last_value() const { return value_; } diff --git a/signal-composer-binding/signal.hpp b/signal-composer-binding/signal.hpp index 0a12b16..6c7f43f 100644 --- a/signal-composer-binding/signal.hpp +++ b/signal-composer-binding/signal.hpp @@ -28,40 +28,14 @@ class Composer; -/// @brief Structure holding a possible value of a Signal -/// as it could be different type of value, we declare all -/// possibility. -/// Not very efficient or optimized, maybe use of Variant in -/// C++17 but this is a bit too new to uses it for now -struct signalValue { - bool undefined; - bool hasBool; - bool boolVal; - bool hasNum; - double numVal; - bool hasStr; - std::string strVal; - - signalValue(): - undefined(true), hasBool(false), boolVal(false), hasNum(false), numVal(0), hasStr(false), strVal("") {}; - signalValue(bool b): - undefined(false), hasBool(true), boolVal(b), hasNum(false), numVal(0), hasStr(false), strVal("") {}; - signalValue(int i): - undefined(false), hasBool(false), boolVal(false), hasNum(true), numVal(i), hasStr(false), strVal("") {}; - signalValue(double d): - undefined(false), hasBool(false), boolVal(false), hasNum(true), numVal(d), hasStr(false), strVal("") {}; - signalValue(const std::string& s): - undefined(false), hasBool(false), boolVal(false), hasNum(false), numVal(0), hasStr(true), strVal(s) {}; -}; - -extern "C" void searchNsetSignalValueHandle(const char* aName, uint64_t timestamp, struct signalValue value); -extern "C" void setSignalValueHandle(void* aSignal, uint64_t timestamp, struct signalValue value); +extern "C" void searchNsetSignalValueHandle(const char* aName, uint64_t timestamp, json_object* value); +extern "C" void setSignalValueHandle(void* aSignal, uint64_t timestamp, json_object* value); /// @brief Holds composer callbacks and obj to manipulate struct signalCBT { - void (*searchNsetSignalValue)(const char* aName, uint64_t timestamp, struct signalValue value); - void (*setSignalValue)(void* aSignal, uint64_t timestamp, struct signalValue value); + void (*searchNsetSignalValue)(const char* aName, uint64_t timestamp, json_object* value); + void (*setSignalValue)(void* aSignal, uint64_t timestamp, json_object* value); void* aSignal; void* pluginCtx; }; @@ -80,8 +54,8 @@ private: std::string event_; std::vector<std::string> dependsSigV_; uint64_t timestamp_; - struct signalValue value_; - std::map<uint64_t, struct signalValue> history_; ///< history_ - Hold signal value history in map with <timestamp, value> + json_object* value_; + std::map<uint64_t, json_object*> history_; ///< history_ - Hold signal value history in map with <timestamp, value> int retention_; double frequency_; std::string unit_; @@ -107,17 +81,16 @@ public: struct signalCBT* get_context(); json_object *getSignalsArgs(); - void set(uint64_t timestamp, struct signalValue& value); + void set(uint64_t timestamp, json_object*& value); void update(Signal* sig); - static int defaultOnReceivedCB(CtlSourceT* source, json_object* argsJ, json_object *queryJ); - void defaultReceivedCB(json_object *eventJ); + static void defaultReceivedCB(Signal *signal, json_object *eventJ); void onReceivedCB(json_object *eventJ); void attachToSourceSignals(Composer& composer); double average(int seconds = 0) const; double minimum(int seconds = 0) const; double maximum(int seconds = 0) const; - struct signalValue last_value() const; + json_object* last_value() const; uint64_t last_timestamp() const; int initialRecursionCheck(); diff --git a/signal-composer-binding/source.cpp b/signal-composer-binding/source.cpp index a46e766..bd988c9 100644 --- a/signal-composer-binding/source.cpp +++ b/signal-composer-binding/source.cpp @@ -122,7 +122,7 @@ std::vector<std::shared_ptr<Signal>> SourceAPI::searchSignals(const std::string& if(signalsM_.count(name)) {signals.emplace_back(signalsM_[name]);} - if(newSignalsM_.count(name)) + else if(newSignalsM_.count(name)) {signals.emplace_back(signalsM_[name]);} else { |