Change settings inside the plugin
AnsweredHello,
Is it possible to change settings inside the plugin?
I want to syncrhonize plugin settings with settings outside the plugin.
I know that I can receive setrtings values with `settingValue` function. Is there a way to set a different value to some parameter in settings in the plugin code?
-
Hello Hendrick,
> Is there a way to set a different value to some parameter in settings in the plugin code?
Since your plugin has got settings values from the GUI client it can do what ever is necessary: save to an internal data structure, save to a file, send to an external system over the network etc. I don't really understand what do you mean by that?
Could you please elaborate a bit your scenario?Here is a thread might be worth reading.
https://support.networkoptix.com/hc/en-us/community/posts/360039368793-I-have-a-question-about-ROI-metadataSDK-0 -
Hello Andrey,
My scenario is following: I want to keep settings in the plugin and in the cloud simultaneously, and be able to modify settings automatically in the plugin when they are modified in the cloud. I.e. not just only modify variables in code but modify actual settings so user will see in GUI that some setting was changed.
Thanks for the link, I will examine it.0 -
Hello,
Thank you for explaination.
What you need is to implement getPluginSideSettings.
In current v4.1 release there is a bug, because of which the getPluginSideSettings is not called when plugin settings dialog is being opened. Although it's fixed, the fix will be available with the upcoming hotfix only.
0 -
Hello Andrey,
Do I understand correctly that getPluginSideSettings method will be called every time I open settings? (after the bugfix)
If so I see it in a such way:
1. I receive settings in the plugin from the cloud
2. I store them in a plugin (or in a sqlite db) until the user opens settings or Nx server or plugin is restarted
3. if the user opens settings getPluginSideSettings is called and I return changed Result<const ISettingsResponse*>* , so settings are applied to the networkoptix plugin and are visible in GUI
4. if plugin or server is restarted then settingsReceived is called and I return changed Result<const ISettingsResponse*> so settings are applied to the networkoptix plugin and are visible in GUI
Do I get it right or I'm missing something?0 -
Hello,
There are three classes Plugin, Engine, DeviceAgent comprising an analytics plugin.
1. I receive settings in the plugin from the cloud
Decide which part of the code are you going to go this: Engine, DeviceAgent?2. I store them in a plugin (or in a sqlite db) until the user opens settings or Nx server or plugin is restarted
"plugin is restarted" should be precised.
When plugin is being enabled on a device, an Engine class instance already exists and a DeviceAgent class instance only is created.
When server is being restarted the instances of all classes (Plugin, Engine, DevieAgent) are recreated.
Both Engine and DeviceAgent classes have the getPluginSideSettings method.
You should decide when and where you want to perform step 1 operation.You don't need additional sqlite db, because you have your cloud for long time storing.
3.
settings are applied to the networkoptix plugin and are visible in GUI.
I don't really get it. What is "networkoptix plugin" ?
getPluginSideSettings IS a part of a plugin code. It is invoked for getting settings values from the plugin. Those can be read either from internal structure updated at "step 1" or read right away from the cloud.
Server merges updated values with the values from its DB and sends to the GUI.4. When server is being restarted the instances of all classes (Plugin, Engine, DevieAgent) are recreated.
When Engine class instance is being created the setSettings method is called which invokes doSetSettings (i_engine.h).public: Result<const ISettingsResponse*> setSettings(const IStringMap* settings)
{
Result<const ISettingsResponse*> result;
doSetSettings(&result, settings);
return result;
}The doSetSettings is the place where you should place your code for processing the settings.
the settingReceived is supposed to be called AFTER the settings are saved in the internal structure in your code.void Engine::doSetSettings(
Result<const ISettingsResponse*>* outResult, const IStringMap* settings)
{
if (!logUtils.convertAndOutputStringMap(&m_settings, settings, "Received settings"))
*outResult = error(ErrorCode::invalidParams, "Unable to convert the input string map");
else
*outResult = settingsReceived();
}When plugin is being enabled on a device DeviceAgent class instance in created.
The DeviceAgent class has the setSettings, doSetSettings and settingReceived, as well, called in the same manner as in Engine class.
All of them are for supplying a plugin with the settings values not for getting settings values from the plugin.0 -
>Decide which part of the code are you going to go this: Engine, DeviceAgent?
I need to store settings per camera, so I need to do it in the DeviceAgent
>getPluginSideSettings IS a part of a plugin code. It is invoked for getting settings values from the plugin. Those can be read either from internal structure updated at "step 1" or read right away from the cloud.
I understand that it's a part of a plugin code. I assumed that I can't call this function manually and I need to wait for a moment when user opens settings or when server is restarted. That's why I was thinking about db for permanent storage. If I can call this function manually at any moment (i.e. when settings are changed in the cloud) then all this is unnecessary. Can I call this function at any moment?
>The doSetSettings is the place where you should place your code for processing the settings.
Can I call this function manually?0 -
Hi,
> Can I call this function at any moment?
getPluginSideSettings is declared as protected.
protected: virtual void getPluginSideSettings(
Result<const ISettingsResponse*>* outResult) const = 0;That means you it can be called from inside any descendant. You can call it from any place inside the DevieAgent class.
If you want it be called outside the class, you could create a public method, which would invoke getPluginSideSettings.0 -
Hello Andrey,
Thank you for your answers, I appreciate it.
Now I understand that if I want to receive settings from the cloud I need to receive settings somewhere (not in every DeviceAgent but in a single listener) and then apply settings to DeviceAgents.
I would like to summarize it all and be sure that I get it right.
getPluginSideSettings is called when user opens Plugin Settings. I can call it manually.
There is also doSetSettings in src/nx/sdk/analytics/i_device_agent.h and in src/nx/sdk/analytics/i_engine.hYou recommended to apply settings inside of doSetSettings.
Is there any difference between calling manually getPluginSideSettings and calling manually doSetSettings?
I'm thinking about keep a map of DeviceAgents and listener inside of the Engine. When listener get new settings I need to select a needed DeviceAgent, get it's settings via DeviceAgent::getPluginSideSettings, change settings and then apply settings by calling DeviceAgent::doSetSettings with changed settings. Is it a good idea?0 -
Hi,
doSetSettings and getPluginSideSettings are called under different conditions, on different events.
doSetSettings is for passing settings FROM the Server TO a plugin.
getPluginSideSettings is for getting settings FROM the plugin (possibly from an external application) TO the Server.
> When listener get new settings
From where? What is the source?> I need to select a needed DeviceAgent, get it's settings via DeviceAgent::getPluginSideSettings
If settings are the same for all DeviceAgents, you don't. Your listener just saves the settings in the internal structure. DeviceAgent::getPluginSideSettings is called by the Server and reads the settings from internal structure. Passes to the Server. The Server merges with values read from DB and passes to the GUI.
In GUI user clicks "Apply" or "OK" button, settings values are passed to the server. Server saves to DB and calls doSetSettings.0 -
>From where? What is the source?
Our cloud is the source (not a networkoptix cloud). Now I don't know exactly which method I will use. Probably I will constantly pull some URL or connect to a websocket. The user should be able to turn on and off types of analytics for a specific camera in our web app (i.e. cloud) and in the Nx plugin. So, when user turn on or turn off something for a specific camera in the cloud I need to update it's settings in the networkoptix plugin.0 -
>In GUI user clicks "Apply" or "OK" button, settings values are passed to the server. Server saves to DB and calls doSetSettings.
Ok, I need to do the same process but from the code, when I receive settings from listener.0 -
Hi Hendrik,
My name is Maxim, Andrey is on a vacation now and for some time I will be answering questions on the forum instead of him.
Just wanted to ask if you still have any questions or difficulties considering the subject of this thread.
Thank you.
0 -
Hello Maxim,
I still have a question
I want to share analytics settings between our web app and the networkoptix plugin. For example I have a setting 'detect people' for a specific camera and I want to be able to change it in the plugin and in the web app. If user changed settings in the web app and then opened the settings window in the networkoptix server, user must see already changed settings.
Is it possible?
If so, how can I do it? I need to change settings for a particular camera, so I want to change a DeviceAgent settings.0 -
Hello Hendrik,
There was a lot of discussion about getPluginSideSettings in this thread. Why not using it?
So, you can keep your settings somewhere in your Cloud and pull it when you need it (e.g., when the user opens the plugin settings window).
0 -
Hello Maxim,
I'm sorry for such long delay.
The problem with getPluginSideSettings is don't understand how to use it.
I need to pass Result<const ISettingsResponse*>* outResult to it and I don't know where to get it.
I tried following codevoid DeviceAgent::applySettings(int test) {
m_testSetting = test;
Result<const ISettingsResponse*>* result;
getPluginSideSettings(result);
}void DeviceAgent::getPluginSideSettings(
Result<const ISettingsResponse*>* outResult) const
{
const auto response = new SettingsResponse();
response->setValue("pluginSideTestSpinBox", std::to_string(m_testSetting));*outResult = response;
}
But it doesn't work. I call applySettings function, then go to the plugin settings window and see that pluginSideTestSpinBox setting has not changed.
How can I fix it?Thanks for answer.
0 -
Sorry, actually now I'm surprised that I didn't receive segfault.
I changed code to the following:
void DeviceAgent::applySettings(int test) {
m_testSetting = test;
Result<const ISettingsResponse*>* result = new Result<const ISettingsResponse*>();
getPluginSideSettings(result);
}void DeviceAgent::getPluginSideSettings(
Result<const ISettingsResponse*>* outResult) const
{
const auto response = new SettingsResponse();
response->setValue("pluginSideTestSpinBox", std::to_string(m_testSetting));*outResult = response;
}
And now it works.
I'm afraid of memory leaking because of constant creation of Result<const ISettingsResponse*>* with new but I think I can somehow avoid it.0 -
Hi Hendrik,
Instead of creating a new structure on the heap every time you're using operator new, why don't you just use a variable for storing the result? You can do something like this:
Result<const ISettingsResponse*> result;
getPluginSideSettings(&result);And here's the code of the getPluginSideSettings function from Stub Analytics Plugin: that's a sample plugin and its source code is provided inside our Metadata SDK package. You can find it in the following file: samples/stub_analytics_plugin/src/nx/vms_server_plugins/analytics/stub/engine.cpp. I think, you might find it useful.
void Engine::getPluginSideSettings(Result<const ISettingsResponse*>* outResult) const
{
auto settingsResponse = new SettingsResponse();
settingsResponse->setValue(kEnginePluginSideSetting, kEnginePluginSideSettingValue);
*outResult = settingsResponse;
}0 -
Hi Hendrick,
Did you solve your problem? I have the same task. I want to send the setting from outside (Video Analytics Server).
If you solved it. Could you help me how to do that? Thank you.
0
Please sign in to leave a comment.
Comments
18 comments