Is the Nx Cloud up? Visit our Status Page for the current health and performance of the Nx Cloud.

Status Page

DeviceAgent variables pertaining only to the attached device

Answered

Comments

9 comments

  • Andrey Terentyev
    • Network Optix team

    Hello Graham Parry,

    Could you, please, provide OS version, VMS build number, Metadata SDK version?

    Could you share the entire plugin code, please?

    0
  • Graham Parry

    Hi Andrey

    So this is Windows, Nx Witness 5.0.0.35745 and MetadataSDK 5.0.

    I seem to have solved one problem in that if I create my variables in device_agent.h protected: they will only pertain to the device attached.   

    However, threading is proving tricky.  If I take the Stub Diagnostics sample as a template I can get notices appearing, but as I start to add other elements I end up with the key thread method only firing once or not at all.

    The code is:

    device_agent.h

    protected:
        virtual void doSetNeededMetadataTypes(
            nx::sdk::Result<void>* outValue,
            const nx::sdk::analytics::IMetadataTypes* neededMetadataTypes) override;

        virtual std::string manifestString() const override;

        virtual nx::sdk::Result<const nx::sdk::ISettingsResponse*> settingsReceived() override;

        virtual bool pushUncompressedVideoFrame(
            const nx::sdk::analytics::IUncompressedVideoFrame* videoFrame) override;

        std::string selectedCameraName;
        long selectedDelayInSeconds;

    device_agent.cpp

    DeviceAgent::DeviceAgent(const nx::sdk::IDeviceInfo* deviceInfo) :
        // Call the DeviceAgent helper class constructor telling it to verbosely report to stderr.
        ConsumingDeviceAgent(deviceInfo, /*enableOutput*/ true)
    {
        selectedCameraName = deviceInfo->name();
        
        startEventThread();
    }

    DeviceAgent::~DeviceAgent()
    {
        stopEventThread();
    }

    void DeviceAgent::startEventThread()
    {
        m_eventThread = std::make_unique<std::thread>([this]() { eventThreadLoop(); });
    }

    void DeviceAgent::stopEventThread()
    {
        {
            std::unique_lock<std::mutex> lock(m_eventThreadMutex);
            m_terminated = true;
            m_eventThreadCondition.notify_all();
        }

        m_eventThread->join();
    }

    void DeviceAgent::eventThreadLoop()
    {
        while (!m_terminated)
        {
            doSomethingHere();
            
            // Sleep until the next event needs to be generated, or the thread is ordered
            // to terminate (hence condition variable instead of sleep()). Return value
            // (whether the timeout has occurred) and spurious wake-ups are ignored.
            {
                std::unique_lock<std::mutex> lock(m_eventThreadMutex);
                if (m_terminated)
                    break;
                static const seconds kEventGenerationPeriod{ selectedDelayInSeconds };
                m_eventThreadCondition.wait_for(lock, kEventGenerationPeriod);
            }
        }
    }

    void DeviceAgent::doSomethingHere()
    {
        std::string caption = "This is a notice from camera " + selectedCameraName;
        std::string description = "At an interval of " + std::to_string(selectedDelayInSeconds) + " seconds";

        pushPluginDiagnosticEvent(
            IPluginDiagnosticEvent::Level::info,
            caption,
            description);
    }

    The delay in seconds is created by a spin box in the settings model

    settings_model.h

    {
                        "type": "SpinBox",       
                        "name": ")json" + kSettingsModelSecondsIntervalSpin + R"json(",
                        "caption": "Interval (seconds) before event",
                        "defaultValue": 20,
                        "minValue": 1,
                        "maxValue": 1000000
      },

    and is picked up here

    device_agent.cpp

    Result<const ISettingsResponse*> DeviceAgent::settingsReceived()
    {
        const auto settingsResponse = new sdk::SettingsResponse();

        settingsResponse->setModel(kSettingsModel);

        selectedDelayInSeconds = std::stol(settingValue(kSettingsModelSecondsIntervalSpin));

        // The manifest depends on some of the above parsed settings, so sending the new manifest.
        pushManifest(manifestString());

        return settingsResponse;
    }

    My project involves multiple cameras attached to the plugin performing a function at an interval set for each device, so I need to get these threading issues sorted before I move on to the more complex procedures. 

    0
  • Andrey Terentyev
    • Network Optix team

    Hello Graham,

    Could you, please, provide OS version, VMS build number, Metadata SDK version?

    So this is Windows, Nx Witness 5.0.0.35745 and MetadataSDK 5.0.

    Which of Windows do you use: 11/10/8/7 ? Could you specify the build number of the Metadata SDK, please?

    Could you share the entire plugin code, please?

    Could you please just archive the folder containing your plugin code, place the archive on any cloud storage you like and share the link here?

    I seem to have solved one problem in that if I create my variables in device_agent.h protected: they will only pertain to the device attached.   

    Congratulations!

    Would you mind elaborating the current issue? What are you doing step-by-step? What is expected result? What is actual result?

    0
  • Graham Parry

    Hi Andrey

    Developing on Windows 10, deploying to Nx Server on Windows 11

    Metadata SDK 5.0.0.35745

    Just one setting for now in the settings model, a spin box.

    The object of this test plugin, for the end user to set a delay in seconds between events.

    Each instance of the DeviceAgent can have separate timings.

    PluginDiagnosticEvent is displayed every x seconds for first camera and y seconds for second camera.  

    The event notice displayed shows the name of the camera displaying the event.

    Cannot get the plugin to display the notice.

    Archive files here

    https://www.dropbox.com/scl/fo/bje3iiqcopyrw0p8oaqcd/h?dl=0&rlkey=eqpxj65cjvplmqdgv8lp0u692 

    0
  • Andrey Terentyev
    • Network Optix team

    Hello Graham,

    I got you code. Will get back later on.

    0
  • Graham Parry

    Many thanks for your help, Andrey.   It's frustrating that what should be a very simple test plugin is proving so tricky.  Clearly a trick is being missed.

    0
  • Andrey Terentyev
    • Network Optix team

    Hello Graham,

    The plugin built right away from the code you've shared without modification makes the Nx Desktop to hang.

    The trick is, that the code of DeviceAgent::eventThreadLoop()

    static const seconds kEventGenerationPeriod{ selectedDelayInSeconds };
    m_eventThreadCondition.wait_for(lock, kEventGenerationPeriod);

    does not initialize the kEventGenerationPeriod varibale with the value stored in selectedDelayInSeconds, just because the variable is declared static. The correct code would be

    const seconds kEventGenerationPeriod{ selectedDelayInSeconds };

    That worked for me.

    0
  • Andrey Terentyev
    • Network Optix team

    In order to display Events in the notification tab in the right-hand panel, you need to define a camera rule.

    0
  • Graham Parry

    Doh.  Schoolboy error on my part.

    Thanks Andrey.  Case closed.

    0

Please sign in to leave a comment.