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>
This commit is contained in:
747
gevisoft-sdk-reference.md
Normal file
747
gevisoft-sdk-reference.md
Normal file
@@ -0,0 +1,747 @@
|
||||
# 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!
|
||||
Reference in New Issue
Block a user