Files
geutebruck/gevisoft-sdk-reference.md
Administrator 14893e62a5 feat: Geutebruck GeViScope/GeViSoft Action Mapping System - MVP
This MVP release provides a complete full-stack solution for managing action mappings
in Geutebruck's GeViScope and GeViSoft video surveillance systems.

## Features

### Flutter Web Application (Port 8081)
- Modern, responsive UI for managing action mappings
- Action picker dialog with full parameter configuration
- Support for both GSC (GeViScope) and G-Core server actions
- Consistent UI for input and output actions with edit/delete capabilities
- Real-time action mapping creation, editing, and deletion
- Server categorization (GSC: prefix for GeViScope, G-Core: prefix for G-Core servers)

### FastAPI REST Backend (Port 8000)
- RESTful API for action mapping CRUD operations
- Action template service with comprehensive action catalog (247 actions)
- Server management (G-Core and GeViScope servers)
- Configuration tree reading and writing
- JWT authentication with role-based access control
- PostgreSQL database integration

### C# SDK Bridge (gRPC, Port 50051)
- Native integration with GeViSoft SDK (GeViProcAPINET_4_0.dll)
- Action mapping creation with correct binary format
- Support for GSC and G-Core action types
- Proper Camera parameter inclusion in action strings (fixes CrossSwitch bug)
- Action ID lookup table with server-specific action IDs
- Configuration reading/writing via SetupClient

## Bug Fixes
- **CrossSwitch Bug**: GSC and G-Core actions now correctly display camera/PTZ head parameters in GeViSet
- Action strings now include Camera parameter: `@ PanLeft (Comment: "", Camera: 101028)`
- Proper filter flags and VideoInput=0 for action mappings
- Correct action ID assignment (4198 for GSC, 9294 for G-Core PanLeft)

## Technical Stack
- **Frontend**: Flutter Web, Dart, Dio HTTP client
- **Backend**: Python FastAPI, PostgreSQL, Redis
- **SDK Bridge**: C# .NET 8.0, gRPC, GeViSoft SDK
- **Authentication**: JWT tokens
- **Configuration**: GeViSoft .set files (binary format)

## Credentials
- GeViSoft/GeViScope: username=sysadmin, password=masterkey
- Default admin: username=admin, password=admin123

## Deployment
All services run on localhost:
- Flutter Web: http://localhost:8081
- FastAPI: http://localhost:8000
- SDK Bridge gRPC: localhost:50051
- GeViServer: localhost (default port)

Generated with Claude Code (https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-31 18:10:54 +01:00

22 KiB

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
  2. GeViSoft Architecture
  3. Core SDK Components
  4. Action Mapping Concepts
  5. API Classes and Methods
  6. Working with Action Mappings
  7. State Queries
  8. Database Queries
  9. 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

// 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

// 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.

// 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.

// 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)

// 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:

// 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<CSAActionMappingTable*>(answer);

    // Work with mappingTable data structure
    // ... process action mappings ...

    answer->DeleteObject();
}

Modifying Action Mapping Configuration

To send updated action mapping configuration back to GeViServer:

// 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

// 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<CSAVideoInputInfo*>(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

// 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<CDBAQueryHandle*>(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<CDBAActionEntry*>(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

#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<TMessageEntry*>(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<CAction*>(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

// 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:

#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:

// 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<CSAActionMappingTable*>(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:

// 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

#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!