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