# GeViSoft .NET SDK Reference - Action Mapping Guide **Generated**: 2025-12-11 **SDK Version**: GeViSoft SDK 6.0.1.5 **CHM Files Extracted to**: C:\Gevisoft\Documentation\extracted_html\ --- ## Table of Contents 1. [Overview](#overview) 2. [GeViSoft Architecture](#gevisoft-architecture) 3. [Core SDK Components](#core-sdk-components) 4. [Action Mapping Concepts](#action-mapping-concepts) 5. [API Classes and Methods](#api-classes-and-methods) 6. [Working with Action Mappings](#working-with-action-mappings) 7. [State Queries](#state-queries) 8. [Database Queries](#database-queries) 9. [Code Examples](#code-examples) --- ## Overview GeViSoft is a management platform (control layer) that coordinates multiple GeViScope instances (video servers). This SDK allows programmatic control of GeViSoft/GeViScope systems through a .NET API. **Key Concepts:** - **GeViSoft**: Management platform controlling multiple GeViScope instances - **GeViScope**: Video server instances handling cameras, monitors, and video routing - **GeViServer**: The GeViSoft server process that clients connect to - **Actions**: Commands or notifications in the system - **Action Mapping**: Automation rules that trigger output actions in response to input actions --- ## GeViSoft Architecture ``` ┌────────────────────────────────────────────────┐ │ GeViSoft (Management Layer) │ │ GeViServer Process │ │ │ │ ┌──────────────────────────────────────────┐ │ │ │ Action Mapping Engine │ │ │ │ Input Action → Output Action(s) │ │ │ └──────────────────────────────────────────┘ │ │ │ │ ┌──────────────────────────────────────────┐ │ │ │ Activity Database │ │ │ │ - Action logs │ │ │ │ - Alarm events │ │ │ │ - Configuration tables │ │ │ └──────────────────────────────────────────┘ │ └────────────────────────────────────────────────┘ │ ┌─────────┴─────────┐ │ │ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ │ GeViScope │ │ GeViScope │ │ Instance 1 │ │ Instance 2 │ │ (GSCServer) │ │ (GSCServer) │ │ │ │ │ │ Cameras │ │ Cameras │ │ Monitors │ │ Monitors │ │ Video Routing │ │ Video Routing │ └─────────────────┘ └─────────────────┘ ``` --- ## Core SDK Components ### 1. GeViAPIClient **Primary SDK wrapper class** for communicating with GeViServer. **Header**: `GeViAPIClient.h` **DLL**: `GeViProcAPI.dll` **Key Methods:** - `Connect()` - Establishes connection to GeViServer - `Disconnect()` - Disconnects from GeViServer - `SendMessage()` - Sends action messages to the server - `SendStateQuery()` - Queries system state (e.g., list of cameras, action mappings) - `SendDatabaseQuery()` - Queries activity database - `SetCBNotification()` - Registers callback for receiving server notifications - `SendPing()` - Heartbeat check - `EncodePassword()` - Encodes plaintext passwords for authentication ### 2. CGeViMessage **Base class for all messages** (actions, queries, answers). **Types of Messages:** - **Actions (CAction)**: Commands or notifications (e.g., `CrossSwitch`, `InputContact`) - **State Queries (CStateQuery)**: Request system state information - **State Answers (CStateAnswer)**: Responses to state queries - **Database Queries (CDataBaseQuery)**: Query action/alarm logs - **Database Answers (CDataBaseAnswer)**: Responses to database queries ### 3. CAction **Base class for action messages**. **Properties:** - `m_ActionKind` - Action category (TActionKind) - `m_ActionCode` - Specific action type code (TActionCode) **Methods:** - `GetActionName()` - Returns action name as string - `GetActionCodeByName(name)` - Converts action name to code - `ReadASCIIMessage()` - Parses action from ASCII string - `WriteASCIIMessage()` - Serializes action to ASCII string --- ## Action Mapping Concepts ### What is Action Mapping? Action mapping allows you to trigger one or more actions automatically when another action occurs. **Example Use Case:** - **Input Action**: `InputContact(3, false)` - Door contact opened - **Output Actions**: `AlternateContact(2, 1000, 500)` - Flash beacon on digital output 2 ### Action Mapping Components ``` ┌──────────────────────────────────────────┐ │ Action Mapping Entry │ ├──────────────────────────────────────────┤ │ Input Action: │ │ - Action name (e.g., InputContact) │ │ - Parameters (e.g., ContactID=3) │ │ │ │ Output Actions (List): │ │ - Action 1: AlternateContact(...) │ │ - Action 2: SendMail(...) │ │ - Action 3: CrossSwitch(...) │ └──────────────────────────────────────────┘ ``` ### Action Categories Actions are organized into logical categories: 1. **System Actions**: System lifecycle, authentication, database operations 2. **Video Actions**: Video control, camera management, VCA (Video Content Analysis) 3. **Device Actions**: Hardware device integration 4. **Audio Actions**: Audio stream management 5. **Camera Control Actions**: PTZ and camera parameter control 6. **Digital Contacts Actions**: Digital I/O operations (e.g., `InputContact`, `AlternateContact`, `CloseContact`) 7. **ATM Actions**: ATM integration 8. **POS Actions**: Point-of-Sale integration 9. **Backup Actions**: Data backup and export 10. **Remote Export Actions**: Remote video export capabilities --- ## API Classes and Methods ### Connection Management ```cpp // Constructor GeViAPIClient::GeViAPIClient( const char* Aliasname, // Connection alias (can be empty "") const char* Address, // GeViServer IP or hostname const char* Username, // Username const char* Password, // Encrypted password (use EncodePassword) const char* Username2, // Second username (dual control, optional "") const char* Password2 // Second password (optional "") ) // Connect to server TConnectResult Connect( TGeViConnectProgress ACallback, // Progress callback void* AInstance // Pointer to calling instance ("this") ) // Disconnect void Disconnect() // Encode password static void EncodePassword( char* Dest, // Output buffer (33 bytes) const char* Source, // Plaintext password int DestSize // Size of destination buffer (33) ) ``` ### Sending Actions ```cpp // Send action message (fire-and-forget, no response) void SendMessage(CGeViMessage* GeViMessage) // Example: Send CustomAction CGeViMessage* gevimessage = new CActCustomAction(123, "Hello GeViSoft!"); m_APIClient->SendMessage(gevimessage); gevimessage->DeleteObject(); // Always delete objects created in DLL ``` ### State Queries (Reading Configuration) State queries retrieve system configuration and state information. ```cpp // Send state query (blocking call, returns answer) CStateAnswer* SendStateQuery( CStateQuery* GeViQuery, const int timeout_ms // Use INFINITE to prevent timeout ) ``` **Common State Queries:** - `CSQGetFirstVideoInput()` - Get first video input (camera) - `CSQGetNextVideoInput()` - Get next video input - `CSQGetFirstMonitor()` - Get first monitor - **`CSQGetActionMappingTable()`** - **Retrieve action mapping configuration** - **`CSQSetActionMappingTable()`** - **Send updated action mapping configuration** ### Database Queries (Reading Logs) Database queries retrieve historical action and alarm data. ```cpp // Send database query (blocking call, returns answer) CDataBaseAnswer* SendDatabaseQuery( CDataBaseQuery* GeViMessage, const int timeout_ms ) ``` **Database Query Workflow:** 1. Create query session: `CDBQCreateActionQuery(0)` 2. Extract query handle from answer 3. Set filters (optional): `CDBFTypeName`, `CDBFPK_GrtEqu`, etc. 4. Fetch records: `CDBQGetLast`, `CDBQGetNext`, `CDBQGetPrev` 5. Close session when done ### Receiving Notifications (Server Push) ```cpp // Register notification callback void SetCBNotification( TGeViDatabaseNotification ACallback, void* AInstance ) // Callback signature void __stdcall GeViDatabaseNotificationCB( void* Instance, TServerNotification Notification, void* Params ) ``` **Notification Types:** - `NFServer_NewMessage` - New action message received - `NFServer_SetupChanged` - Configuration changed - `NFServer_Shutdown` - Server shutting down --- ## Working with Action Mappings ### Reading Action Mapping Configuration To read the current action mapping configuration from GeViServer: ```cpp // 1. Create state query to get action mapping table CStateQuery* getActionMappingQuery = new CSQGetActionMappingTable(); // 2. Send query to server CStateAnswer* answer = m_APIClient->SendStateQuery( getActionMappingQuery, INFINITE // No timeout ); // 3. Clean up query getActionMappingQuery->DeleteObject(); // 4. Process answer if (answer && answer->m_AnswerKind == sak_ActionMappingTable) { CSAActionMappingTable* mappingTable = reinterpret_cast(answer); // Work with mappingTable data structure // ... process action mappings ... answer->DeleteObject(); } ``` ### Modifying Action Mapping Configuration To send updated action mapping configuration back to GeViServer: ```cpp // 1. Read current configuration CSAActionMappingTable* mappingTable = /* get from server */; // 2. Modify mappingTable data structure // ... add/remove/modify action mappings ... // 3. Create state query to set action mapping table CStateQuery* setActionMappingQuery = new CSQSetActionMappingTable(mappingTable); // 4. Send updated configuration to server CStateAnswer* answer = m_APIClient->SendStateQuery( setActionMappingQuery, INFINITE ); // 5. Check if successful if (answer && answer->m_AnswerKind == sak_OK) { // Success! } else { // Handle error } // 6. Clean up setActionMappingQuery->DeleteObject(); answer->DeleteObject(); ``` ### Action Mapping Table Structure The `CSAActionMappingTable` structure contains: - **Mapping Entries**: List of input→output action pairs - **Each Entry Contains**: - Input action definition (action name, parameters) - List of output actions (multiple actions can be triggered) - Caption/description - Enable/disable state --- ## State Queries ### Video Input Enumeration Example ```cpp // Get first video input CStateQuery* getFirstVideoInputQuery = new CSQGetFirstVideoInput( true, // Show only active channels true // Show only enabled channels ); CStateAnswer* stateAnswer = m_APIClient->SendStateQuery( getFirstVideoInputQuery, INFINITE ); getFirstVideoInputQuery->DeleteObject(); // Iterate through all video inputs while (stateAnswer && stateAnswer->m_AnswerKind != sak_Nothing) { // Get channel info CSAVideoInputInfo* videoInputInfo = reinterpret_cast(stateAnswer); // Access properties: // - videoInputInfo->m_GlobalID // - videoInputInfo->m_Name // - videoInputInfo->m_Description // - videoInputInfo->m_HasPTZHead // - videoInputInfo->m_HasVideoSensor // Get next video input CStateQuery* getNextVideoInputQuery = new CSQGetNextVideoInput( true, true, videoInputInfo->m_GlobalID ); stateAnswer->DeleteObject(); stateAnswer = m_APIClient->SendStateQuery( getNextVideoInputQuery, INFINITE ); getNextVideoInputQuery->DeleteObject(); } if (stateAnswer) stateAnswer->DeleteObject(); ``` --- ## Database Queries ### Querying Action History ```cpp // 1. Create action query session CDataBaseQuery* geviquery = new CDBQCreateActionQuery(0); CDataBaseAnswer* dbanswer = m_APIClient->SendDatabaseQuery( geviquery, INFINITE ); geviquery->DeleteObject(); // 2. Extract query handle CDBAQueryHandle* handle = nullptr; if (dbanswer->m_AnswerCode == dbac_QueryHandle) { handle = reinterpret_cast(dbanswer); } // 3. Optional: Set filters CDataBaseFilter* filter = new CDBFTypeName( handle->m_Handle, "CrossSwitch", // Filter for CrossSwitch actions dbc_LIKE ); dbanswer = m_APIClient->SendDatabaseQuery(filter, INFINITE); filter->DeleteObject(); // 4. Get latest action entry CDataBaseQuery* getEntry = new CDBQGetLast(handle->m_Handle); dbanswer = m_APIClient->SendDatabaseQuery(getEntry, INFINITE); getEntry->DeleteObject(); // 5. Process action entry if (dbanswer->m_AnswerCode == dbac_ActionEntry) { CDBAActionEntry* actionEntry = reinterpret_cast(dbanswer); // Access: // - actionEntry->m_PK (primary key) // - actionEntry->m_TimeStamp // - actionEntry->m_Action (CAction object) __int64 primaryKey = actionEntry->m_PK; } dbanswer->DeleteObject(); ``` ### Available Database Filters - `CDBFTypeName` - Filter by action type name - `CDBFPK_GrtEqu` - Primary key >= value - `CDBFPK_LowEqu` - Primary key <= value - `CDBFTimestamp_GrtEqu` - Timestamp >= value - `CDBFTimestamp_LowEqu` - Timestamp <= value - `CDBFSender` - Filter by sender - Many more in DatabaseQueries.h --- ## Code Examples ### Complete Connection Example ```cpp #include "GeViAPIClient.h" // Connection progress callback void __stdcall ConnectProgressCB( void* Instance, TConnectProgress Progress ) { // Update UI with connection progress printf("Connection progress: %d\n", Progress); } // Database notification callback void __stdcall GeViDatabaseNotificationCB( void* Instance, TServerNotification Notification, void* Params ) { if (Notification == NFServer_NewMessage) { TMessageEntry* messageEntry = reinterpret_cast(Params); int noOfBytesRead = 0; CGeViMessage* gevimessage = CGeViMessage::ReadBinMessage( messageEntry->Buffer, messageEntry->Length, noOfBytesRead ); if (gevimessage) { // Process received message printf("Received action: %s\n", static_cast(gevimessage)->GetActionName()); gevimessage->DeleteObject(); } } } // Main application int main() { // Encode password char encodedPassword[33]; GeViAPIClient::EncodePassword( encodedPassword, "myPlaintextPassword", 33 ); // Create client GeViAPIClient* apiClient = new GeViAPIClient( "", // Alias "192.168.1.100", // GeViServer address "admin", // Username encodedPassword, // Encrypted password "", // Username2 (optional) "" // Password2 (optional) ); // Connect to server TConnectResult result = apiClient->Connect( ConnectProgressCB, nullptr // or "this" if in class ); if (result == connectOk) { printf("Connected to GeViServer!\n"); // Register notification callback apiClient->SetCBNotification( GeViDatabaseNotificationCB, nullptr ); // Send a test action CGeViMessage* testAction = new CActCustomAction( 123, "Test message" ); apiClient->SendMessage(testAction); testAction->DeleteObject(); // Keep connection alive while (true) { if (!apiClient->SendPing()) { printf("Connection lost!\n"); break; } Sleep(5000); // Wait 5 seconds } // Disconnect apiClient->Disconnect(); } else { printf("Connection failed: %d\n", result); } delete apiClient; return 0; } ``` ### Creating Actions from Strings ```cpp // Parse action from ASCII string std::string buffer("CrossSwitch(101038, 1, 0)"); int bytesRead = 0; CGeViMessage* gevimessage = CGeViMessage::ReadASCIIMessage( buffer.c_str(), buffer.size(), bytesRead ); if (gevimessage) { // Send parsed action m_APIClient->SendMessage(gevimessage); gevimessage->DeleteObject(); } // Convert action to ASCII string CGeViMessage* action = new CActCrossSwitch(101038, 1, 0); char buffer[GEVI_MAXACTIONLENGTH]; int numBytesReceived = 0; action->WriteASCIIMessage( buffer, GEVI_MAXACTIONLENGTH, numBytesReceived ); printf("Action: %s\n", buffer); // Output: CrossSwitch(101038, 1, 0) action->DeleteObject(); ``` ### Working with GeViScope Actions GeViScope actions can be sent through GeViSoft: ```cpp #include "GscActions.h" // GeViScope action constructors // Create GeViScope action CGeViMessage* gscAction = new CActGscAction( "YourGscServerName", // GeViScope server alias from GeViSet GscAct_CreateCustomAction(1, L"Hello GeViScope!") ); m_APIClient->SendMessage(gscAction); gscAction->DeleteObject(); ``` --- ## Key Takeaways for Your API Project Based on your geutebruck-api project specs, here's how to integrate action mapping: ### 1. Reading Action Mapping Configuration For your API endpoint `GET /api/v1/gevisoft/action-mappings`: ```cpp // In your GeViSoft SDK bridge CStateQuery* query = new CSQGetActionMappingTable(); CStateAnswer* answer = m_APIClient->SendStateQuery(query, INFINITE); query->DeleteObject(); if (answer && answer->m_AnswerKind == sak_ActionMappingTable) { CSAActionMappingTable* mappings = reinterpret_cast(answer); // Convert to JSON for your REST API json result = convertActionMappingsToJson(mappings); answer->DeleteObject(); return result; } ``` ### 2. Modifying Action Mapping Configuration For your API endpoint `PUT /api/v1/gevisoft/action-mappings`: ```cpp // Receive JSON from REST API json actionMappingsJson = /* from HTTP request */; // Convert JSON to CSAActionMappingTable structure CSAActionMappingTable* mappings = convertJsonToActionMappings(actionMappingsJson); // Send to GeViServer CStateQuery* setQuery = new CSQSetActionMappingTable(mappings); CStateAnswer* answer = m_APIClient->SendStateQuery(setQuery, INFINITE); setQuery->DeleteObject(); if (answer && answer->m_AnswerKind == sak_OK) { // Success - action mappings updated answer->DeleteObject(); return {{"success": true}}; } else { // Error handling answer->DeleteObject(); return {{"success": false, "error": "Failed to update"}}; } ``` ### 3. Important Implementation Notes 1. **Thread Safety**: GeViAPIClient operations are blocking. Use a separate thread or async handling in your REST API to avoid blocking HTTP requests. 2. **Connection Management**: Maintain a persistent GeViAPIClient connection. Don't connect/disconnect for each API request. 3. **Memory Management**: Always call `DeleteObject()` on objects created by the SDK DLL. 4. **Error Handling**: Check answer codes and types before casting pointers. 5. **Data Conversion**: You'll need helper functions to convert between SDK structures and JSON for your REST API. --- ## Documentation Locations ### Extracted CHM Files All CHM documentation has been extracted to: ``` C:\Gevisoft\Documentation\extracted_html\ ├── GeViSoft_API_Documentation\ # API class reference (Doxygen) ├── GeViSoft_SDK_Documentation\ # SDK usage guide and tutorials └── GeViSoft_NET_SDK_API\ # .NET specific API docs ``` ### Key Files to Reference - **GeViAPIClient Reference**: `GeViSoft_API_Documentation/class_ge_vi_a_p_i_client.html` - **Action Mapping Guide**: `GeViSoft_SDK_Documentation/313Action Mapping.htm` - **State Queries Guide**: `GeViSoft_SDK_Documentation/414StateQueries.htm` - **Database Queries Guide**: `GeViSoft_SDK_Documentation/415DatabaseQueries.htm` - **Action Messages Guide**: `GeViSoft_SDK_Documentation/413_4ActionMessages.htm` ### Headers to Include ```cpp #include "GeViAPIClient.h" // Main API client #include "Actions.h" // GeViSoft action constructors #include "GscActions.h" // GeViScope action constructors #include "StateQueries.h" // State query classes #include "DatabaseQueries.h" // Database query classes #include "GeViProcAPI.h" // Low-level API types ``` --- ## Next Steps for Your Project 1. **Set up GeViAPIClient connection** in your C++ SDK bridge 2. **Implement state query wrappers** for GetActionMappingTable and SetActionMappingTable 3. **Create JSON converters** for action mapping structures 4. **Build REST API endpoints** that call your SDK bridge functions 5. **Test with GeViAPI Test Client** to verify action mappings work correctly Good luck with your Geutebruck API implementation!