-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add functionality that adds value to dynamic string (#42)
This means e.g. overlay widget gauges (in a camera with support for that) can display the digital value on screen. Along with this update, we also move to the current version of native ACAP 4 SDK for building and hence drop support for legacy versions of Axis OS. For legacy devices, the previous commit can still be successfully used, only that it (at this point) will not have the data written to the dynamic string. Signed-off-by: Joakim Roubert <[email protected]>
- Loading branch information
1 parent
a39d8b4
commit c0390e5
Showing
15 changed files
with
286 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/** | ||
* Copyright (C) 2024, Axis Communications AB, Lund, Sweden | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <chrono> | ||
#include <curl/curl.h> | ||
#include <glib.h> | ||
#include <string> | ||
|
||
/** | ||
* brief A type for handling setting dynamic text overlay string via VAPIX. | ||
* | ||
* This is not needed for OPC UA, but enables the camera to use the extracted | ||
* gauge reading in overlays, which can add value to the live view. | ||
*/ | ||
class DynStrHandler | ||
{ | ||
public: | ||
DynStrHandler(const guint8 nbr); | ||
~DynStrHandler(); | ||
void SetStrNumber(const guint8 newnbr); | ||
void UpdateStr(const double value); | ||
|
||
private: | ||
std::string RetrieveVapixCredentials(const char &username) const; | ||
gboolean VapixGet(const std::string &url); | ||
|
||
CURL *curl; | ||
guint8 nbr; | ||
std::chrono::time_point<std::chrono::steady_clock> lastupdate; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,33 @@ | ||
{ | ||
"schemaVersion": "1.3", | ||
"schemaVersion": "1.7.0", | ||
"acapPackageConf": { | ||
"setup": { | ||
"friendlyName": "OPC UA Gauge Reader", | ||
"appName": "opcuagaugereader", | ||
"vendor": "Axis Communications AB", | ||
"embeddedSdkVersion": "3.0", | ||
"user": { | ||
"group": "sdk", | ||
"username": "sdk" | ||
}, | ||
"vendorUrl": "https://www.axis.com/", | ||
"runMode": "respawn", | ||
"version": "1.2.1" | ||
"version": "2.0.0" | ||
}, | ||
"configuration": { | ||
"settingPage": "settings.html", | ||
"paramConfig": [ | ||
{"name": "clockwise", "type": "bool:0,1", "default": "1"}, | ||
{"name": "maxX", "type": "int:min=0,max=639", "default": "150"}, | ||
{"name": "maxY", "type": "int:min=0,max=359", "default": "150"}, | ||
{"name": "centerX", "type": "int:min=0,max=639", "default": "100"}, | ||
{"name": "centerY", "type": "int:min=0,max=359", "default": "170"}, | ||
{"name": "minX", "type": "int:min=0,max=639", "default": "50"}, | ||
{"name": "minY", "type": "int:min=0,max=359", "default": "150"}, | ||
{"name": "port", "type": "int:min=1,max=65535", "default": "4840"} | ||
] | ||
} | ||
"configuration": { | ||
"settingPage": "settings.html", | ||
"paramConfig": [ | ||
{"name": "DynamicStringNumber", "type": "int:min=1,max=16", "default": "1"}, | ||
{"name": "clockwise", "type": "bool:0,1", "default": "1"}, | ||
{"name": "maxX", "type": "int:min=0,max=639", "default": "150"}, | ||
{"name": "maxY", "type": "int:min=0,max=359", "default": "150"}, | ||
{"name": "centerX", "type": "int:min=0,max=639", "default": "100"}, | ||
{"name": "centerY", "type": "int:min=0,max=359", "default": "170"}, | ||
{"name": "minX", "type": "int:min=0,max=639", "default": "50"}, | ||
{"name": "minY", "type": "int:min=0,max=359", "default": "150"}, | ||
{"name": "port", "type": "int:min=1,max=65535", "default": "4840"} | ||
] | ||
} | ||
}, | ||
"resources": { | ||
"dbus": { | ||
"requiredMethods": ["com.axis.HTTPConf1.VAPIXServiceAccounts1.GetCredentials"] | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
/** | ||
* Copyright (C) 2024, Axis Communications AB, Lund, Sweden | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#include <assert.h> | ||
#include <cstdlib> | ||
#include <gio/gio.h> | ||
|
||
#include "common.hpp" | ||
#include "dynstrhandler.hpp" | ||
|
||
using namespace std; | ||
using namespace std::chrono; | ||
|
||
static size_t append_to_string_callback(char *ptr, size_t size, size_t nmemb, string *response) | ||
{ | ||
assert(nullptr != response); | ||
auto totalsize = size * nmemb; | ||
response->append(ptr, totalsize); | ||
|
||
return totalsize; | ||
} | ||
|
||
DynStrHandler::DynStrHandler(const guint8 nbr) : curl(nullptr), nbr(nbr), lastupdate(steady_clock::now()) | ||
{ | ||
assert(1 <= nbr); | ||
assert(16 >= nbr); | ||
|
||
curl_global_init(CURL_GLOBAL_DEFAULT); | ||
curl = curl_easy_init(); | ||
assert(nullptr != curl); | ||
|
||
const gchar *user = "example-vapix-user"; | ||
auto credentials = RetrieveVapixCredentials(*user); | ||
|
||
auto curl_init = | ||
(CURLE_OK == curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long)(CURLAUTH_DIGEST | CURLAUTH_BASIC)) && | ||
CURLE_OK == curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 2L) && | ||
CURLE_OK == curl_easy_setopt(curl, CURLOPT_USERPWD, credentials.c_str()) && | ||
CURLE_OK == curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L) && | ||
CURLE_OK == curl_easy_setopt(curl, CURLOPT_TIMEOUT, 1) && | ||
CURLE_OK == curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, append_to_string_callback)); | ||
|
||
assert(curl_init); | ||
LOG_I("%s/%s: Dynamic string handler constructor is done!", __FILE__, __FUNCTION__); | ||
} | ||
|
||
DynStrHandler::~DynStrHandler() | ||
{ | ||
assert(nullptr != curl); | ||
curl_easy_cleanup(curl); | ||
curl_global_cleanup(); | ||
} | ||
|
||
void DynStrHandler::SetStrNumber(const guint8 newnbr) | ||
{ | ||
nbr = newnbr; | ||
LOG_I("Now using dynamic string number %u", newnbr); | ||
} | ||
|
||
void DynStrHandler::UpdateStr(const double value) | ||
{ | ||
// We don't need to update too frequently | ||
auto nowtime = steady_clock::now(); | ||
if (1 > duration_cast<seconds>(nowtime - lastupdate).count()) | ||
{ | ||
return; | ||
} | ||
|
||
auto url = "http://127.0.0.12/axis-cgi/dynamicoverlay.cgi?action=settext&text_index=" + to_string(nbr) + | ||
"&text=" + to_string(value); | ||
if (!VapixGet(url)) | ||
{ | ||
LOG_E("%s/%s: Failed to update dynamic string", __FILE__, __FUNCTION__); | ||
} | ||
lastupdate = nowtime; | ||
} | ||
|
||
string DynStrHandler::RetrieveVapixCredentials(const char &username) const | ||
{ | ||
GError *error = nullptr; | ||
auto connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &error); | ||
if (nullptr == connection) | ||
{ | ||
LOG_E("Error connecting to D-Bus: %s", error->message); | ||
g_error_free(error); | ||
return nullptr; | ||
} | ||
|
||
const char *bus_name = "com.axis.HTTPConf1"; | ||
const char *object_path = "/com/axis/HTTPConf1/VAPIXServiceAccounts1"; | ||
const char *interface_name = "com.axis.HTTPConf1.VAPIXServiceAccounts1"; | ||
const char *method_name = "GetCredentials"; | ||
|
||
auto result = g_dbus_connection_call_sync( | ||
connection, | ||
bus_name, | ||
object_path, | ||
interface_name, | ||
method_name, | ||
g_variant_new("(s)", &username), | ||
NULL, | ||
G_DBUS_CALL_FLAGS_NONE, | ||
-1, | ||
NULL, | ||
&error); | ||
if (nullptr == result) | ||
{ | ||
LOG_E("Error invoking D-Bus method: %s", error->message); | ||
g_error_free(error); | ||
return ""; | ||
} | ||
|
||
// Extract credentials string | ||
const char *credentials_string = nullptr; | ||
g_variant_get(result, "(&s)", &credentials_string); | ||
string credentials(credentials_string); | ||
g_variant_unref(result); | ||
|
||
return credentials; | ||
} | ||
|
||
gboolean DynStrHandler::VapixGet(const string &url) | ||
{ | ||
assert(nullptr != curl); | ||
|
||
string response; | ||
|
||
if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_URL, url.c_str()) || | ||
CURLE_OK != curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response)) | ||
{ | ||
LOG_E("%s/%s: Failed to set up cURL options", __FILE__, __FUNCTION__); | ||
return FALSE; | ||
} | ||
|
||
auto res = curl_easy_perform(curl); | ||
if (res != CURLE_OK) | ||
{ | ||
LOG_E("%s/%s: curl fail %d '%s''", __FILE__, __FUNCTION__, res, curl_easy_strerror(res)); | ||
return FALSE; | ||
} | ||
|
||
long response_code; | ||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); | ||
if (200 != response_code) | ||
{ | ||
LOG_E("Got response code %ld with response '%s'", response_code, response.c_str()); | ||
return FALSE; | ||
} | ||
|
||
return TRUE; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.