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

Status Page

How to capture intercom button press event in plugin DLL via Metadata SDK (SDK 5.1.3)

Answered

Comments

18 comments

  • Ichiro
    • Network Optix team

    Hi Subramanian, 

    Thanks for your question, and it is good to know that you have been doing the integration with MetaSDK. 

    In fact, the Intercom event has no difference to the motion events. They are the same logic.
    You will implement the device_agent for the intercom device, and you will listen to the event that generated by the device - It could be proprietary API of the device or other communication protocol..etc.

     

    Is it possible to detect a button press event from an intercom device using the Metadata SDK?

    Yes, this is possible. The logic is the same as you detect the motion events.

     

    If so, how can I receive that event in my plugin DLL?

    As mentioned above, you will need to implement the logic in the device_agent for the intercom device, and you will listen to the event or signal that generated by the device - It could be proprietary API of the device or other communication protocol..etc. In short, you listen to the intercom events from devices.

     

    Is there a specific metadata type or event packet I should be listening for from the VMS?

    No, this is your custome event, you are able to define your own eventType. Please refer to the manifest.md and taxonomy.md in the MetaSDK.  The STUB:events sample also gives the general idea to start with.

    Hope this helps, thank.

     

    0
  • Subramanian

     can i use this method if i can is there a sample to capture the eventsDeviceAgent::generateEventMetadataPacket()

     

    0
  • Subramanian

    I would like to capture this event exactly in my plugin .I can very well see the event in vms when Proximity sensor is triggered and can hear bell sound .so need to know is it possible to capture this event when trigger 

     

     

    is it possibleto use any of the code from this git
    https://github.com/networkoptix/nx_open_integrations/tree/master/cpp/vms_server_plugins/opencv_object_detection_analytics_plugin

    0
  • Subramanian

    **What I’ve Tried:**
    - Implemented a device_agent to listen to device signals.
    - Injected EventMetadataPacket with custom eventType.
    - Queried IEventMetadataPacket in plugin DLL.

    **Code Snippet:**
    ```cpp
    for (int i = 0; i < metadataPacketCount; ++i)
    {
       const auto metadataPacket = metadataPacketList->at(i);

                        const auto objectDetectedEventMetadataPacket = makePtr<EventMetadataPacket>();
                        const auto eventPacket = objectDetectedEventMetadataPacket->queryInterface < IEventMetadataPacket>();
                        if (eventPacket)
                        {
                            PLOG_INFO << "eventPacket Received";
                            return true;
                        }
    }
    Is this the correct approach to receive custom intercom events in the plugin DLL? Should I be listening for a specific metadata type?

    0
  • Subramanian

    Will this method emits the event that i am expecting
    DeviceAgent::MetadataPacketList DeviceAgent::eventsToEventMetadataPacketList(
       const EventList& events,
       int64_t timestampUs)
    {
       if (events.empty())
           return {};

       MetadataPacketList result;

       const auto objectDetectedEventMetadataPacket = makePtr<EventMetadataPacket>();

       for (const std::shared_ptr<Event>& event: events)
       {
           const auto eventMetadata = makePtr<EventMetadata>();

           if (event->eventType == EventType::detection_started ||
               event->eventType == EventType::detection_finished)
           {
               static const std::string kStartedSuffix = " STARTED";
               static const std::string kFinishedSuffix = " FINISHED";

               const std::string suffix = (event->eventType == EventType::detection_started) ?
                   kStartedSuffix : kFinishedSuffix;
               const std::string caption = kClassesToDetectPluralCapitalized.at(event->classLabel) +
                   " detection" + suffix;
               const std::string description = caption;

               eventMetadata->setCaption(caption);
               eventMetadata->setDescription(description);
               eventMetadata->setIsActive(event->eventType == EventType::detection_started);
               eventMetadata->setTypeId(kProlongedDetectionEventType);

               const auto eventMetadataPacket = makePtr<EventMetadataPacket>();
               eventMetadataPacket->addItem(eventMetadata.get());
               eventMetadataPacket->setTimestampUs(event->timestampUs);
               result.push_back(eventMetadataPacket);
           }
           else if (event->eventType == EventType::object_detected)
           {
               std::string caption = event->classLabel + kDetectionEventCaptionSuffix;
               caption[0] = (char) toupper(caption[0]);
               std::string description = event->classLabel + kDetectionEventDescriptionSuffix;
               description[0] = (char) toupper(description[0]);

               eventMetadata->setCaption(caption);
               eventMetadata->setDescription(description);
               eventMetadata->setIsActive(true);
               eventMetadata->setTypeId(kDetectionEventType);

               objectDetectedEventMetadataPacket->addItem(eventMetadata.get());
           }
       }

       objectDetectedEventMetadataPacket->setTimestampUs(timestampUs);
       result.push_back(objectDetectedEventMetadataPacket);

       return result;
    }

    0
  • Ichiro
    • Network Optix team

    Hi Subramanian,

    Based on what you’ve described, the overall logic and steps appear sound and should generally work as expected:

    • Implemented a device_agent to listen for device signals.
    • Injected EventMetadataPacket with a custom eventType.
    • Queried IEventMetadataPacket within the plugin DLL.

     

    However, please note that we’re unable to troubleshoot or debug any external code or implementation directly. If you encounter error messages or unexpected behavior, please provide detailed information along with relevant code snippets with comments and details..

    We won’t be able to trace or analyze your code otherwise — we can only offer suggestions based on the reported errors, observed behavior, and described use cases.

    Thank you for your understanding.

    0
  • Subramanian

    I would like to create an event that triggers an HTTP request—similar to what can be configured via the Rules Engine UI—but entirely from code.

    Specifically, I want to:

    • Define a custom event from my plugin (e.g. MyPlugin.dll)
    • Automatically associate it with an action like Do HTTP Request
    • Configure the HTTP method, URL, headers, and payload
    • Ensure this setup is applied without requiring manual UI configuration
       

    Is there a supported way to do this via the SDK or any internal APIs? If not, is there a recommended approach to simulate or inject such rule-based behavior programmatically?

    i have used the following
    Step 1 
    /ec2/getevents to get event id and details
    Step 2
    /ec2/saveEventRule:

    {
       "id": "c4259d8d-8fe6-43e9-b3ac-02a5ef4e1c55",
       "eventType": "analyticsSdkEvent",
       "eventResourceIds": [
           "a4870f7a-d106-2ed5--9d62ec10adda"
       ],
       "eventCondition": "{\"analyticsEngineId\":\"{d018384f-8f08-6a40-70a8-1405ba18b455}\",\"eventTimestampUsec\":\"0\",\"eventType\":\"undefinedEvent\",\"inputPortId\":\"nx.sys.CallRequest\",\"metadata\":{\"allUsers\":false,\"level\":\"\"},\"omitDbLogging\":false,\"progress\":0,\"reasonCode\":\"none\"}",
       "eventState": "Active",
       "actionType": "execHttpRequestAction",
       "actionResourceIds": [
           "c4259d8d-8fe6-43e9-b3ac-02a5ef4e1c55"
       ],
       "actionParams": "{\"allUsers\":false,\"authType\":\"authBasic\",\"contentType\":\"application/json\",\"durationMs\":5000,\"forced\":true,\"fps\":10,\"httpMethod\":\"POST\",\"needConfirmation\":false,\"playToClient\":true,\"recordAfter\":0,\"recordBeforeMs\":1000,\"streamQuality\":\"highest\",\"text\":\"{\n\\\"CameraId\\\":\\\"{event.cameraId}\\\",\n\\\"CameraName\\\":\\\"{event.cameraName}\\\",\n\\\"EventType\\\":\\\"{event.eventType}\\\",\n\\\"EventName\\\":\\\"{event.eventName}\\\"\n}\n\",\"url\":\"http://:@localhost:9000\",\"useSource\":false}",
       "aggregationPeriod": 10,
       "disabled": false,
       "comment": "",
       "schedule": "",
       "system": false,
       "EventState": "string"
    }


    i get the following result

    {
     "error": "2",
     "errorId": "invalidParameter",
     "errorString": "Can't deserialize input Json data to destination object."
    }

    but my jon is valid and i am using GUID generator for "id": and  "actionResourceIds":

    Thanks in advance!

    0
  • Norman
    • Network Optix team

    Hi Subramanian,

    If you only update the “id”, the rule will work correctly. The “actionResourceIds” field is fixed for that specific device and shouldn’t be modified, unless it applies to another device. 

    For future troubleshooting, a helpful approach is to create two identical rules through the GUI and then compare the results of the GET /ec2/getEventRules request using a tool like DiffChecker (or any similar comparison tool).

    As shown below, the only difference is the “id” value. I also added a “comment” field to make it easier to locate the rule in the JSON output.

    With kind regards. 

    0
  • Subramanian
    {
        "id": "6a361330-d7d9-46a8-8a43-498e253eefa6",
        "eventType": "analyticsSdkEvent",
        "eventResourceIds": [
            "a4870f7a-d106-2ed5--9d62ec10adda"
        ],
        "eventCondition": "{\"analyticsEngineId\":\"{d018384f-8f08-6a40-70a8-1405ba18b455}\",\"eventTimestampUsec\":\"0\",\"eventType\":\"undefinedEvent\",\"inputPortId\":\"nx.sys.CallRequest\",\"metadata\":{\"allUsers\":false,\"level\":\"\"},\"omitDbLogging\":false,\"progress\":0,\"reasonCode\":\"none\"}",
        "eventState": "Active",
        "actionType": "execHttpRequestAction",
        "actionResourceIds": [],
        "actionParams": "{\"allUsers\":false,\"authType\":\"authBasic\",\"contentType\":\"application/json\",\"durationMs\":5000,\"forced\":true,\"fps\":10,\"httpMethod\":\"POST\",\"needConfirmation\":false,\"playToClient\":true,\"recordAfter\":0,\"recordBeforeMs\":1000,\"streamQuality\":\"highest\",\"text\":\"{\n\\\"CameraId\\\":\\\"{event.cameraId}\\\",\n\\\"CameraName\\\":\\\"{event.cameraName}\\\",\n\\\"EventType\\\":\\\"{event.eventType}\\\",\n\\\"EventName\\\":\\\"{event.eventName}\\\"\n}\n\",\"url\":\"http://:@localhost:9000\",\"useSource\":false}",
        "aggregationPeriod": 10,
        "disabled": false,
        "comment": "TESTING1",
        "schedule": "",
        "system": false,
        "EventState": "string"
    }

     

    the ID value is guid generated value is that correct still
    if so i am still getting error
    one more question can this saverule works under liveuser login

    i need to create new one insted of updating to evey system 
    so need to know
    {\"analyticsEngineId\":\"{d018384f-8f08-6a40-70a8-1405ba18b455} where this is coming from because i need to put inside the plugin code to call this api if engine id is diffrent then how to get that
    can u provide the api steps and procedure which i can use to dynamically generate on every system to create a new rule on starting the engine 

    0
  • Norman
    • Network Optix team

    Hi Subramanian,

    I updated my previous comment, since I created some confusion. 
    You want a generic rule, not a specific rule. 

    {
        "actionParams": "{\"allUsers\":false,\"authType\":\"authBasic\",\"contentType\":\"application/json\",\"durationMs\":5000,\"forced\":true,\"fps\":10,\"httpMethod\":\"POST\",\"needConfirmation\":false,\"playToClient\":true,\"recordAfter\":0,\"recordBeforeMs\":1000,\"streamQuality\":\"highest\",\"text\":\"{\n    \\\"body\\\"\n}\",\"url\":\"https://:@localhost:5000\",\"useSource\":false}",
        "actionResourceIds": [],
        "actionType": "execHttpRequestAction",
        "aggregationPeriod": 60,
        "comment": "TEST",
        "disabled": false,
        "eventCondition": "{\"analyticsEngineId\":\"{0effea07-d494-aed7-bc53-beab1f45ce9d}\",\"eventTimestampUsec\":\"0\",\"eventType\":\"undefinedEvent\",\"inputPortId\":\"nx.dahua.ManNumDetection\",\"metadata\":{\"allUsers\":false,\"level\":\"\"},\"omitDbLogging\":false,\"progress\":0,\"reasonCode\":\"none\"}",
        "eventResourceIds": [
            "{30c35075-4dbb-bf75-0f93-11700c76bd4f}"
        ],
        "eventState": "Active",
        "eventType": "analyticsSdkEvent",
        "id": "{53aaad7a-b38c-4656-8bf4-3553692128a3}",
        "schedule": "",
        "system": false
    }

    In this rule there are three UUID: 

    1. analyticsEngineId - this ID determines which Event should be set. This UUID can be reused in any system, however, it specific for a certain plugin + Event Type. If the plugin or Event Type don't exist, the rule will be created with blank value.
    2. eventResourceIds - this ID determines to which device it applies. It is identical to the Camera ID, you collect with GET /rest/v3/devices.
    3. id - This is the unique ID for this rule, and this rule only
    0
  • Subramanian

      {
       "actionParams": "{\"allUsers\":false,\"authType\":\"authBasic\",\"contentType\":\"application/json\",\"durationMs\":5000,\"forced\":true,\"fps\":10,\"httpMethod\":\"POST\",\"needConfirmation\":false,\"playToClient\":true,\"recordAfter\":0,\"recordBeforeMs\":1000,\"streamQuality\":\"highest\",\"text\":\"{\\n\\\"CameraId\\\":\\\"{event.cameraId}\\\",\\n\\\"CameraName\\\":\\\"{event.cameraName}\\\",\\n\\\"EventType\\\":\\\"{event.eventType}\\\",\\n\\\"EventName\\\":\\\"{event.eventName}\\\"\\n}\\n\",\"url\":\"http://:@localhost:9000\",\"useSource\":false}",
       "actionResourceIds": [],
       "actionType": "execHttpRequestAction",
       "aggregationPeriod": 5,
       "comment": "",
       "disabled": false,
       "eventCondition": "{\"analyticsEngineId\":\"{d018384f-8f08-6a40-70a8-1405ba18b455}\",\"eventTimestampUsec\":\"0\",\"eventType\":\"undefinedEvent\",\"inputPortId\":\"nx.sys.CallRequest\",\"metadata\":{\"allUsers\":false,\"level\":\"\"},\"omitDbLogging\":false,\"progress\":0,\"reasonCode\":\"none\"}",
       "eventResourceIds": [
         "{a4870f7a-d106-2ed5-0d68-9d62ec10adda}"
       ],
       "eventState": "Active",
       "eventType": "analyticsSdkEvent",
       "id": "{86754159-bf73-a590-6919-4ed5805eb85a}",
       "schedule": "",
       "system": false
     },

    this is the output of the event from /ec2/getevents
    so i entererd 

    eventResourceIds": [
        "{a4870f7a-d106-2ed5-0d68-9d62ec10adda}"
      ],  → camera id 

    \"analyticsEngineId\":\"{d018384f-8f08-6a40-70a8-1405ba18b455}  → event id

      "id": "{86754159-bf73-a590-6919-4ed5805eb85a}", → i generated using guid generator
    so i think i got what u trying to explain 
    but still getting the error

     

    0
  • Norman
    • Network Optix team

    Hi Subramanian,

    I see the mistake you made, and could reproduce it: 

    Please, when using JSON formatted text, validate it; for example with https://jsonlint.com/:  

    So, I fixed the issue (removing the , in the end, then it is valid: 

    Then when I I took the body you shared - without the , - and used Postman to add the rule to my system, and I could do it without any issues. See below: 

    And there is the rule: 

    Without the proper Camera assigned, since your camera ID, doesn't exist in my system, and the same applies to the Event Type, since I don't have your Plugin. Both are expected. 

    0
  • Subramanian
    curl --location 'https://127.0.0.1:7001/ec2/saveEventRule' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Basic ZXZvbG9uOkV2b2xvbkluc2l0ZXM=' \
    --data-raw '{
      "actionParams": "{\"allUsers\":false,\"authType\":\"authBasic\",\"contentType\":\"application/json\",\"durationMs\":5000,\"forced\":true,\"fps\":10,\"httpMethod\":\"POST\",\"needConfirmation\":false,\"playToClient\":true,\"recordAfter\":0,\"recordBeforeMs\":1000,\"streamQuality\":\"highest\",\"text\":\"{\\n\\\"CameraId\\\":\\\"{event.cameraId}\\\",\\n\\\"CameraName\\\":\\\"{event.cameraName}\\\",\\n\\\"EventType\\\":\\\"{event.eventType}\\\",\\n\\\"EventName\\\":\\\"{event.eventName}\\\"\\n}\\n\",\"url\":\"http://:@localhost:9000\",\"useSource\":false}",
      "actionResourceIds": [],
      "actionType": "execHttpRequestAction",
      "aggregationPeriod": 5,
      "comment": "",
      "disabled": false,
      "eventCondition": "{\"analyticsEngineId\":\"{d018384f-8f08-6a40-70a8-1405ba18b455}\",\"eventTimestampUsec\":\"0\",\"eventType\":\"undefinedEvent\",\"inputPortId\":\"nx.sys.CallRequest\",\"metadata\":{\"allUsers\":false,\"level\":\"\"},\"omitDbLogging\":false,\"progress\":0,\"reasonCode\":\"none\"}",
      "eventResourceIds": [
        "{a4870f7a-d106-2ed5-0d68-9d62ec10adda}"
      ],
      "eventState": "Active",
      "eventType": "analyticsSdkEvent",
      "id": "{86754159-bf73-a590-6919-4ed5805eb85a}",
      "schedule": "",
      "system": false
    }'

    still no luck 
     

    FYI the “},” after the parameters is just a copy past from /ec2/getevents  output with multiple camera details so it just a copy mistake

    i am using 5.1.3 version of client and server

    0
  • Norman
    • Network Optix team

    Hi Subramanian,

    In the cUrl command, you use basic authentication, which isn't supported by the VMS. The default method is the use of a Bearer token, like so: 

    curl --location 'https://127.0.0.1:7001/ec2/saveEventRule' \
      --header 'Content-Type: application/json' \
      --header 'Authorization: Bearer <YOUR_TOKEN>' \
      --data-raw '{
        "actionParams": "{\"allUsers\":false,\"authType\":\"authBasic\",\"contentType\":\"application/json\",\"durationMs\":5000,\"forced\":true,\"fps\":10,\"httpMethod\":\"POST\",\"needConfirmation\":false,\"playToClient\":true,\"recordAfter\":0,\"recordBeforeMs\":1000,\"streamQuality\":\"highest\",\"text\":\"{\\n\\\"CameraId\\\":\\\"{event.cameraId}\\\",\\n\\\"CameraName\\\":\\\"{event.cameraName}\\\",\\n\\\"EventType\\\":\\\"{event.eventType}\\\",\\n\\\"EventName\\\":\\\"{event.eventName}\\\"\\n}\\n\",\"url\":\"http://:@localhost:9000\",\"useSource\":false}",
        "actionResourceIds": [],
        "actionType": "execHttpRequestAction",
        "aggregationPeriod": 5,
        "comment": "",
        "disabled": false,
        "eventCondition": "{\"analyticsEngineId\":\"{d018384f-8f08-6a40-70a8-1405ba18b455}\",\"eventTimestampUsec\":\"0\",\"eventType\":\"undefinedEvent\",\"inputPortId\":\"nx.sys.CallRequest\",\"metadata\":{\"allUsers\":false,\"level\":\"\"},\"omitDbLogging\":false,\"progress\":0,\"reasonCode\":\"none\"}",
        "eventResourceIds": [
          "{a4870f7a-d106-2ed5-0d68-9d62ec10adda}"
        ],
        "eventState": "Active",
        "eventType": "analyticsSdkEvent",
        "id": "{86754159-bf73-a590-6919-4ed5805eb85a}",
        "schedule": "",
        "system": false
      }'

    Alternatively, you could create a dedicated Digest User, and use Digest Authentication on the cUrl command: 

    curl --location 'https://127.0.0.1:7001/ec2/saveEventRule' \
      --header 'Content-Type: application/json' \
      --digest \
      --user '<user>:<password>' \
      --data-raw '{
        "actionParams": "{\"allUsers\":false,\"authType\":\"authBasic\",\"contentType\":\"application/json\",\"durationMs\":5000,\"forced\":true,\"fps\":10,\"httpMethod\":\"POST\",\"needConfirmation\":false,\"playToClient\":true,\"recordAfter\":0,\"recordBeforeMs\":1000,\"streamQuality\":\"highest\",\"text\":\"{\\n\\\"CameraId\\\":\\\"{event.cameraId}\\\",\\n\\\"CameraName\\\":\\\"{event.cameraName}\\\",\\n\\\"EventType\\\":\\\"{event.eventType}\\\",\\n\\\"EventName\\\":\\\"{event.eventName}\\\"\\n}\\n\",\"url\":\"http://:@localhost:9000\",\"useSource\":false}",
        "actionResourceIds": [],
        "actionType": "execHttpRequestAction",
        "aggregationPeriod": 5,
        "comment": "",
        "disabled": false,
        "eventCondition": "{\"analyticsEngineId\":\"{d018384f-8f08-6a40-70a8-1405ba18b455}\",\"eventTimestampUsec\":\"0\",\"eventType\":\"undefinedEvent\",\"inputPortId\":\"nx.sys.CallRequest\",\"metadata\":{\"allUsers\":false,\"level\":\"\"},\"omitDbLogging\":false,\"progress\":0,\"reasonCode\":\"none\"}",
        "eventResourceIds": [
          "{a4870f7a-d106-2ed5-0d68-9d62ec10adda}"
        ],
        "eventState": "Active",
        "eventType": "analyticsSdkEvent",
        "id": "{86754159-bf73-a590-6919-4ed5805eb85a}",
        "schedule": "",
        "system": false
      }'

    That being said, Bearer Authentication is the preferred and more secure method to authenticate. 

    In the Postman screenshot, there is a 403 Forbidden status code, which means that the client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike a 401 Unauthorized status code, the users identity is known to the server. In this case, you used the correct authorization method, however the user didn't have sufficient user rights. To process such requests, the user should have access level right of a Power User or administrator. 

    With kind regards.

    0
  • Norman
    • Network Optix team

    Hi Subramanian 

    You wrote: 

    i am using 5.1.3 version of client and server

    Please update your system to version 6.0.6 since version 5.1.3 of March 2024, isn't supported anymore, and we might be trying to solve something that have been solved already. 

    With kind regards.

     

    0
  • Subramanian

    Thanks a lot for the immediate response and your invaluable help—it’s much appreciated!

    I’ve updated to version 6.0.6 as suggested, and the API works perfectly when logged in as an admin user. However, when I try the same API call using a live user login, it doesn’t seem to work.

    Is it possible to create event rules via API using a live user account? Or is admin access strictly required for this operation?

    0
  • Norman
    • Network Optix team

    Hi Subramanian,

    Glad to see it works! 

    The creation of rule is restricted to administrators, and Power Users. Other user levels, in general, cannot modify the configuration of the VMS. 

    With kind regards.

    0
  • Subramanian

    one more think, I don't see settings for specific camera instead  i see a common entry I need to do for specific camera and need to set Event type also like the following

     

    Expected:

    I need to pass or select which camera the rule should apply and for which event type i thought giving event resource id will set this camera 

    0

Please sign in to leave a comment.