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:
311
geutebruck-api/SDK_INTEGRATION_LESSONS.md
Normal file
311
geutebruck-api/SDK_INTEGRATION_LESSONS.md
Normal file
@@ -0,0 +1,311 @@
|
||||
# GeViSoft SDK Integration - Critical Lessons Learned
|
||||
|
||||
**Date**: 2025-12-08
|
||||
**Source**: GeViSoftConfigReader development session
|
||||
**Applies to**: geutebruck-api (001-surveillance-api)
|
||||
|
||||
---
|
||||
|
||||
## 🚨 Critical Requirements
|
||||
|
||||
### 1. **Full GeViSoft Installation Required**
|
||||
|
||||
❌ **Installing only SDK is NOT sufficient**
|
||||
✅ **Must install GeViSoft FULL application first, then SDK**
|
||||
|
||||
**Why**: The SDK libraries depend on runtime components from the full GeViSoft installation.
|
||||
|
||||
### 2. **Visual C++ 2010 Redistributable (x86) REQUIRED**
|
||||
|
||||
**Critical Dependency**: `vcredist_x86_2010.exe`
|
||||
|
||||
**Error without it**:
|
||||
```
|
||||
FileNotFoundException: Could not load file or assembly 'GeViProcAPINET_4_0.dll'
|
||||
or one of its dependencies. The specified module could not be found.
|
||||
```
|
||||
|
||||
**Installation**:
|
||||
```powershell
|
||||
# Download and install
|
||||
Invoke-WebRequest -Uri 'https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x86.exe' -OutFile 'vcredist_x86_2010.exe'
|
||||
Start-Process -FilePath 'vcredist_x86_2010.exe' -ArgumentList '/install', '/quiet', '/norestart' -Wait
|
||||
```
|
||||
|
||||
**Documentation Reference**: GeViScope_SDK.txt lines 689-697
|
||||
> "For applications using the .NET-Framework 2.0 the Visual C++ 2008 Redistributable Package...
|
||||
> need to install the Visual C++ 2010 Redistributable Package."
|
||||
|
||||
### 3. **Platform Requirements**
|
||||
|
||||
- **Architecture**: x86 (32-bit) REQUIRED
|
||||
- **.NET Framework**: 4.0+ (tested with 4.8)
|
||||
- **Windows**: Windows 10/11 or Windows Server 2016+
|
||||
|
||||
---
|
||||
|
||||
## 📚 SDK Architecture
|
||||
|
||||
### DLL Dependencies
|
||||
|
||||
**GeViProcAPINET_4_0.dll** (Managed .NET wrapper) requires:
|
||||
- `GeViProcAPI.dll` (Native C++ core)
|
||||
- `GscDBI.dll` (Database interface)
|
||||
- `GscActions.dll` (Action system)
|
||||
|
||||
**All DLLs must be in application output directory**: `C:\GEVISOFT\`
|
||||
|
||||
### Connection Workflow
|
||||
|
||||
```csharp
|
||||
// 1. Create database object
|
||||
var database = new GeViDatabase();
|
||||
|
||||
// 2. Initialize connection
|
||||
database.Create(hostname, username, password);
|
||||
|
||||
// 3. Register callbacks BEFORE connecting
|
||||
database.RegisterCallback();
|
||||
|
||||
// 4. Connect
|
||||
GeViConnectResult result = database.Connect();
|
||||
|
||||
// 5. Check result
|
||||
if (result != GeViConnectResult.connectOk) {
|
||||
// Handle connection failure
|
||||
}
|
||||
|
||||
// 6. Perform operations
|
||||
// ...
|
||||
|
||||
// 7. Cleanup
|
||||
database.Disconnect();
|
||||
database.Dispose();
|
||||
```
|
||||
|
||||
**Order matters!** `RegisterCallback()` must be called BEFORE `Connect()`.
|
||||
|
||||
---
|
||||
|
||||
## 🔌 GeViServer
|
||||
|
||||
### Server Must Be Running
|
||||
|
||||
**Start server**:
|
||||
```cmd
|
||||
cd C:\GEVISOFT
|
||||
GeViServer.exe console
|
||||
```
|
||||
|
||||
Or via batch file:
|
||||
```cmd
|
||||
startserver.bat
|
||||
```
|
||||
|
||||
### Network Ports
|
||||
|
||||
GeViServer listens on:
|
||||
- **7700, 7701, 7703** (TCP) - API communication
|
||||
- **7777, 7800, 7801, 7803** (TCP) - Additional services
|
||||
- **7704** (UDP)
|
||||
|
||||
**NOT on port 7707** (common misconception)
|
||||
|
||||
### Connection String
|
||||
|
||||
Default connection:
|
||||
- **Hostname**: `localhost`
|
||||
- **Username**: `sysadmin`
|
||||
- **Password**: `masterkey` (default, should be changed)
|
||||
|
||||
---
|
||||
|
||||
## 📊 Query Patterns
|
||||
|
||||
### State Queries (Current Configuration)
|
||||
|
||||
**Pattern**: GetFirst → GetNext iteration
|
||||
|
||||
```csharp
|
||||
// Example: Enumerate all video inputs (cameras)
|
||||
var query = new CSQGetFirstVideoInput(true, true);
|
||||
var answer = database.SendStateQuery(query);
|
||||
|
||||
while (answer.AnswerKind != AnswerKind.Nothing) {
|
||||
var videoInput = (CSAVideoInputInfo)answer;
|
||||
|
||||
// Process videoInput
|
||||
// - videoInput.GlobalID
|
||||
// - videoInput.Name
|
||||
// - videoInput.Description
|
||||
// - videoInput.HasPTZHead
|
||||
// - videoInput.HasVideoSensor
|
||||
|
||||
// Get next
|
||||
query = new CSQGetNextVideoInput(true, true, videoInput.GlobalID);
|
||||
answer = database.SendStateQuery(query);
|
||||
}
|
||||
```
|
||||
|
||||
**Queryable Entities**:
|
||||
- Video Inputs (cameras)
|
||||
- Video Outputs (monitors)
|
||||
- Digital Contacts (I/O)
|
||||
|
||||
### Database Queries (Historical Data)
|
||||
|
||||
```csharp
|
||||
// Create query session
|
||||
var createQuery = new CDBQCreateActionQuery(0);
|
||||
var createAnswer = database.SendDatabaseQuery(createQuery);
|
||||
var handle = (CDBAQueryHandle)createAnswer;
|
||||
|
||||
// Get records
|
||||
var getQuery = new CDBQGetLast(handle.Handle);
|
||||
var getAnswer = database.SendDatabaseQuery(getQuery);
|
||||
```
|
||||
|
||||
**Available**:
|
||||
- Action logs
|
||||
- Alarm logs
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Common Pitfalls
|
||||
|
||||
### 1. **Console Apps vs Windows Forms**
|
||||
|
||||
❌ **Console applications** (OutputType=Exe) fail to load mixed-mode C++/CLI DLLs
|
||||
✅ **Windows Forms applications** (OutputType=WinExe) load successfully
|
||||
|
||||
**Workaround**: Use hidden Windows Form:
|
||||
```csharp
|
||||
public class MainForm : Form {
|
||||
public MainForm() {
|
||||
this.WindowState = FormWindowState.Minimized;
|
||||
this.ShowInTaskbar = false;
|
||||
this.Size = new Size(1, 1);
|
||||
this.Shown += MainForm_Shown;
|
||||
}
|
||||
|
||||
private void MainForm_Shown(object sender, EventArgs e) {
|
||||
this.Hide();
|
||||
// Do actual work here
|
||||
Application.Exit();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. **Output Directory**
|
||||
|
||||
SDK documentation states applications should output to `C:\GEVISOFT\` to ensure DLL dependencies are found.
|
||||
|
||||
### 3. **Application Lifecycle**
|
||||
|
||||
Give file operations time to complete before exit:
|
||||
```csharp
|
||||
finally {
|
||||
System.Threading.Thread.Sleep(2000);
|
||||
Application.Exit();
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🐍 Python Integration Considerations
|
||||
|
||||
### For Python FastAPI SDK Bridge
|
||||
|
||||
**Challenge**: GeViSoft SDK is .NET/COM, Python needs to interface with it.
|
||||
|
||||
**Options**:
|
||||
|
||||
1. **Subprocess Calls** (Simplest)
|
||||
```python
|
||||
result = subprocess.run([
|
||||
"GeViSoftConfigReader.exe",
|
||||
"localhost", "admin", "password", "output.json"
|
||||
], capture_output=True)
|
||||
```
|
||||
|
||||
2. **pythonnet** (Direct .NET interop)
|
||||
```python
|
||||
import clr
|
||||
clr.AddReference("GeViProcAPINET_4_0")
|
||||
from GEUTEBRUECK.GeViSoftSDKNET.ActionsWrapper import GeViDatabase
|
||||
```
|
||||
|
||||
3. **comtypes** (COM interface)
|
||||
```python
|
||||
from comtypes.client import CreateObject
|
||||
# If SDK exposes COM interface
|
||||
```
|
||||
|
||||
4. **C# Service Bridge** (Recommended for production)
|
||||
- Build C# Windows Service that wraps SDK
|
||||
- Exposes gRPC/REST interface
|
||||
- Python API calls the C# service
|
||||
- Isolates SDK complexity
|
||||
|
||||
### Recommended Approach
|
||||
|
||||
**For geutebruck-api project**:
|
||||
|
||||
1. **Phase 0 Research**: Test all Python integration methods
|
||||
2. **Phase 1**: Implement C# SDK bridge service (like GeViSoftConfigReader but as a service)
|
||||
3. **Phase 2**: Python API communicates with C# bridge via localhost HTTP/gRPC
|
||||
|
||||
**Why**:
|
||||
- SDK stability (crashes don't kill Python API)
|
||||
- Clear separation of concerns
|
||||
- Easier testing (mock the bridge)
|
||||
- Leverage existing GeViSoftConfigReader code
|
||||
|
||||
---
|
||||
|
||||
## 📖 Documentation
|
||||
|
||||
**Extracted PDF Documentation Location**:
|
||||
```
|
||||
C:\DEV\COPILOT\SOURCES\EXTRACTED_TEXT\
|
||||
├── GeViSoft\GeViSoft\GeViSoft_SDK_Documentation.txt
|
||||
└── GeViScope\GeViScope_SDK.txt
|
||||
```
|
||||
|
||||
**Key Sections**:
|
||||
- Lines 1298-1616: Database queries and state queries
|
||||
- Lines 689-697: VC++ redistributable requirements
|
||||
- Lines 1822-1824: Application output directory requirements
|
||||
|
||||
---
|
||||
|
||||
## ✅ Working Example
|
||||
|
||||
**GeViSoftConfigReader** (`C:\DEV\COPILOT\geutebruck-api\GeViSoftConfigReader\`)
|
||||
- ✅ Successfully connects to GeViServer
|
||||
- ✅ Queries configuration data
|
||||
- ✅ Exports to JSON
|
||||
- ✅ Proper error handling
|
||||
- ✅ All dependencies resolved
|
||||
|
||||
**Use as reference implementation for API SDK bridge.**
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Deployment Checklist
|
||||
|
||||
For any application using GeViSoft SDK:
|
||||
|
||||
- [ ] GeViSoft FULL application installed
|
||||
- [ ] GeViSoft SDK installed
|
||||
- [ ] Visual C++ 2010 Redistributable (x86) installed
|
||||
- [ ] Application targets x86 (32-bit)
|
||||
- [ ] Application outputs to `C:\GEVISOFT\` OR all DLLs copied to app directory
|
||||
- [ ] .NET Framework 4.0+ installed
|
||||
- [ ] GeViServer running and accessible
|
||||
- [ ] Correct credentials available
|
||||
- [ ] Windows Forms pattern used (not console app) for .NET applications
|
||||
|
||||
---
|
||||
|
||||
**End of Document**
|
||||
Reference in New Issue
Block a user