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

748 lines
22 KiB
Markdown

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