From 5bbc6cb56995d23cb8a4eb584ef0161be092da1f Mon Sep 17 00:00:00 2001 From: Romain Forlot Date: Sat, 16 Sep 2017 19:52:41 +0200 Subject: Adding new verb, implemented basic signal method Change-Id: I453ddc0ca374436275e7d76cdc27b3d843a2770f Signed-off-by: Romain Forlot --- signal-composer-binding/signal-composer-apidef.h | 20 ++++++-- .../signal-composer-apidef.json | 6 +++ .../signal-composer-binding.cpp | 30 ++++++++++- signal-composer-binding/signal-composer.cpp | 59 +++++++++++++++++++++- signal-composer-binding/signal-composer.hpp | 1 + signal-composer-binding/signal.cpp | 38 ++++++++++++-- signal-composer-binding/signal.hpp | 8 +-- 7 files changed, 148 insertions(+), 14 deletions(-) diff --git a/signal-composer-binding/signal-composer-apidef.h b/signal-composer-binding/signal-composer-apidef.h index b480430..713d2d1 100644 --- a/signal-composer-binding/signal-composer-apidef.h +++ b/signal-composer-binding/signal-composer-apidef.h @@ -32,16 +32,19 @@ static const char _afb_description_v2_signal_composer[] = "\"event\",\"required\":false,\"schema\":{\"type\":\"string\"}}],\"respon" "ses\":{\"200\":{\"$ref\":\"#/components/responses/200\"}}},\"/get\":{\"d" "escription\":\"Get informations about a resource or element\",\"response" - "s\":{\"200\":{\"$ref\":\"#/components/responses/200\"}}},\"/loadConf\":{" - "\"description\":\"Load config file in directory passed as argument searc" - "hing for pattern 'sig' in filename\",\"parameters\":[{\"in\":\"query\",\"" - "name\":\"path\",\"required\":true,\"schema\":{\"type\":\"string\"}}],\"r" - "esponses\":{\"200\":{\"$ref\":\"#/components/responses/200\"}}}}}" + "s\":{\"200\":{\"$ref\":\"#/components/responses/200\"}}},\"/list\":{\"de" + "scription\":\"List all signals already configured\",\"responses\":{\"200" + "\":{\"$ref\":\"#/components/responses/200\"}}},\"/loadConf\":{\"descript" + "ion\":\"Load config file in directory passed as argument searching for p" + "attern 'sig' in filename\",\"parameters\":[{\"in\":\"query\",\"name\":\"" + "path\",\"required\":true,\"schema\":{\"type\":\"string\"}}],\"responses\"" + ":{\"200\":{\"$ref\":\"#/components/responses/200\"}}}}}" ; void subscribe(struct afb_req req); void unsubscribe(struct afb_req req); void get(struct afb_req req); + void list(struct afb_req req); void loadConf(struct afb_req req); static const struct afb_verb_v2 _afb_verbs_v2_signal_composer[] = { @@ -66,6 +69,13 @@ static const struct afb_verb_v2 _afb_verbs_v2_signal_composer[] = { .info = "Get informations about a resource or element", .session = AFB_SESSION_NONE_V2 }, + { + .verb = "list", + .callback = list, + .auth = NULL, + .info = "List all signals already configured", + .session = AFB_SESSION_NONE_V2 + }, { .verb = "loadConf", .callback = loadConf, diff --git a/signal-composer-binding/signal-composer-apidef.json b/signal-composer-binding/signal-composer-apidef.json index c9e898e..eaf27b3 100644 --- a/signal-composer-binding/signal-composer-apidef.json +++ b/signal-composer-binding/signal-composer-apidef.json @@ -131,6 +131,12 @@ "200": {"$ref": "#/components/responses/200"} } }, + "/list": { + "description": "List all signals already configured", + "responses": { + "200": {"$ref": "#/components/responses/200"} + } + }, "/loadConf": { "description": "Load config file in directory passed as argument searching for pattern 'sig' in filename", "parameters": [ diff --git a/signal-composer-binding/signal-composer-binding.cpp b/signal-composer-binding/signal-composer-binding.cpp index 5ff24b0..b0c6821 100644 --- a/signal-composer-binding/signal-composer-binding.cpp +++ b/signal-composer-binding/signal-composer-binding.cpp @@ -71,7 +71,7 @@ void loadConf(afb_req request) } /// @brief entry point for get requests. Treatment itself is made in SigComp class. -void get(afb_req request) +void list(afb_req request) { if(true) { @@ -83,6 +83,34 @@ void get(afb_req request) } } +/// @brief entry point for get requests. +void get(struct afb_req request) +{ + int err = 0; + struct json_object* args = nullptr, *ans = nullptr, + *options = nullptr; + const char* sig; + + args = afb_req_json(request); + + // Process about Raw CAN message on CAN bus directly + err = wrap_json_unpack(args, "{ss,s?o!}", "signals", &sig, + "options", &options); + if(err) + { + AFB_ERROR("Can't process your request '%s'. Valid arguments are: string for 'signal' and JSON object for 'options' (optionnal)", json_object_to_json_string_ext(args, JSON_C_TO_STRING_PRETTY)); + afb_req_fail(request, "error", NULL); + return; + } + + ans = bindingApp::instance().getSignalValue(sig, options); + + if (ans) + afb_req_success(request, ans, NULL); + else + afb_req_fail(request, "error", NULL); +} + int loadConf() { int err = 0; diff --git a/signal-composer-binding/signal-composer.cpp b/signal-composer-binding/signal-composer.cpp index 3158797..9288e56 100644 --- a/signal-composer-binding/signal-composer.cpp +++ b/signal-composer-binding/signal-composer.cpp @@ -285,7 +285,7 @@ std::shared_ptr bindingApp::searchSignal(const std::string& aName) std::vector> allSignals = getAllSignals(); for (std::shared_ptr& sig : allSignals) { - if(sig->id() == aName) + if(*sig == aName) {return sig;} } } @@ -321,3 +321,60 @@ int bindingApp::execSubscription() const } return err; } + +json_object* bindingApp::getSignalValue(const std::string& sig, json_object* options) +{ + const char **opts = nullptr; + json_object *response = nullptr; + + wrap_json_unpack(options, "{s?s?s?s?!}", + &opts[0], + &opts[1], + &opts[2], + &opts[3]); + + std::shared_ptr sigP = searchSignal(sig); + wrap_json_pack(&response, "{ss}", + "signal", sigP->id().c_str()); + for(int idx=0; idx < sizeof(opts); idx++) + { + bool avg = false, min = false, max = false, last = false; + if (strcasestr(opts[idx], "average") && !avg) + { + avg = true; + double value = sigP->average(); + json_object_object_add(response, "average", + json_object_new_double(value)); + } + if (strcasestr(opts[idx], "min") && !min) + { + min = true; + double value = sigP->minimum(); + json_object_object_add(response, "min", + json_object_new_double(value)); + } + if (strcasestr(opts[idx], "max") && !max) + { + max = true; + double value = sigP->maximum(); + json_object_object_add(response, "max", + json_object_new_double(value)); + } + if (strcasestr(opts[idx], "last") && !last) + { + last = true; + double value = sigP->last(); + json_object_object_add(response, "last", + json_object_new_double(value)); + } + } + + if (!opts) + { + double value = sigP->last(); + json_object_object_add(response, "last", + json_object_new_double(value)); + } + + return response; +} diff --git a/signal-composer-binding/signal-composer.hpp b/signal-composer-binding/signal-composer.hpp index 2a79779..2c7c2e2 100644 --- a/signal-composer-binding/signal-composer.hpp +++ b/signal-composer-binding/signal-composer.hpp @@ -51,6 +51,7 @@ public: std::vector> getAllSignals(); SourceAPI* getSourceAPI(const std::string& api); std::shared_ptr searchSignal(const std::string& aName); + json_object* getSignalValue(const std::string& sig, json_object* options); int execSubscription() const; }; diff --git a/signal-composer-binding/signal.cpp b/signal-composer-binding/signal.cpp index 2dc517c..147aef0 100644 --- a/signal-composer-binding/signal.cpp +++ b/signal-composer-binding/signal.cpp @@ -15,6 +15,8 @@ * limitations under the License. */ +#include +#include #include #include "signal.hpp" @@ -45,12 +47,12 @@ bool Signal::operator ==(const Signal& other) const return false; } -bool Signal::operator==(const std::string& aName) const +bool Signal::operator ==(const std::string& aName) const { - if(id_ == aName) {return true;} + if(! fnmatch(aName.c_str(), id_.c_str(), FNM_CASEFOLD)) {return true;} for( const std::string& src : signalSigList_) { - if(src == aName) {return true;} + if(! fnmatch(aName.c_str(), src.c_str(), FNM_CASEFOLD)) {return true;} } return false; } @@ -152,3 +154,33 @@ int Signal::recursionCheck() } return 0; } + +double Signal::average(int seconds) const +{ + return 0.0; +} +double Signal::minimum() const +{ + double min = DBL_MAX; + for (auto& v : history_) + { + double temp_min = v.second; + if(temp_min < min) { min = temp_min;} + } + return min; +} + +double Signal::maximum() const +{ + double max = 0.0; + for (auto& v : history_) + { + double temp_max = v.second; + if(temp_max > max) { max = temp_max;} + } + return max; +} +double Signal::last() const +{ + return history_.rbegin()->second; +} diff --git a/signal-composer-binding/signal.hpp b/signal-composer-binding/signal.hpp index 4d4c641..ac3b678 100644 --- a/signal-composer-binding/signal.hpp +++ b/signal-composer-binding/signal.hpp @@ -54,9 +54,9 @@ public: void attachToSourceSignals(bindingApp& bApp); void notify(); - //virtual double average() const; - //virtual double min() const; - //virtual double max() const; - //double lastValue() const; + double average(int seconds = 0) const; + double minimum() const; + double maximum() const; + double last() const; int recursionCheck(); }; -- cgit 1.2.3-korg