- Add GeViScope Bridge (C# .NET 8.0) on port 7720 - Full SDK wrapper for camera control, PTZ, actions/events - 17 REST API endpoints for GeViScope server interaction - Support for MCS (Media Channel Simulator) with 16 test channels - Real-time action/event streaming via PLC callbacks - Add GeViServer Bridge (C# .NET 8.0) on port 7710 - Integration with GeViSoft orchestration layer - Input/output control and event management - Update Python API with new routers - /api/geviscope/* - Proxy to GeViScope Bridge - /api/geviserver/* - Proxy to GeViServer Bridge - /api/excel/* - Excel import functionality - Add Flutter app GeViScope integration - GeViScopeRemoteDataSource with 17 API methods - GeViScopeBloc for state management - GeViScopeScreen with PTZ controls - App drawer navigation to GeViScope - Add SDK documentation (extracted from PDFs) - GeViScope SDK docs (7 parts + action reference) - GeViSoft SDK docs (12 chunks) - Add .mcp.json for Claude Code MCP server config Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
233 lines
6.1 KiB
C#
233 lines
6.1 KiB
C#
using GEUTEBRUECK.GeViSoftSDKNET.ActionsWrapper;
|
|
using GEUTEBRUECK.GeViSoftSDKNET.ActionsWrapper.ActionDispatcher;
|
|
using GEUTEBRUECK.GeViSoftSDKNET.ActionsWrapper.SystemActions;
|
|
using GEUTEBRUECK.GeViSoftSDKNET.ActionsWrapper.SwitchControlActions;
|
|
|
|
var builder = WebApplication.CreateBuilder(args);
|
|
|
|
// GeViServer connection state
|
|
GeViDatabase? database = null;
|
|
string? currentAddress = null;
|
|
string? currentUsername = null;
|
|
List<string> receivedMessages = new List<string>();
|
|
|
|
var app = builder.Build();
|
|
|
|
// Event handler for received messages
|
|
void OnDatabaseNotification(object? sender, GeViSoftDatabaseNotificationEventArgs e)
|
|
{
|
|
var msg = $"[{DateTime.Now:HH:mm:ss}] Notification: {e.ServerNotificationType}";
|
|
Console.WriteLine(msg);
|
|
receivedMessages.Add(msg);
|
|
}
|
|
|
|
void OnReceivedCustomAction(object? sender, GeViAct_CustomActionEventArgs e)
|
|
{
|
|
var msg = $"[{DateTime.Now:HH:mm:ss}] CustomAction({e.aCustomInt}, \"{e.aCustomText}\")";
|
|
Console.WriteLine(msg);
|
|
receivedMessages.Add(msg);
|
|
}
|
|
|
|
void OnReceivedCrossSwitch(object? sender, GeViAct_CrossSwitchEventArgs e)
|
|
{
|
|
var msg = $"[{DateTime.Now:HH:mm:ss}] CrossSwitch({e.aVideoInput}, {e.aVideoOutput}, {e.aSwitchMode})";
|
|
Console.WriteLine(msg);
|
|
receivedMessages.Add(msg);
|
|
}
|
|
|
|
// Connection endpoint
|
|
app.MapPost("/connect", (ConnectRequest request) =>
|
|
{
|
|
try
|
|
{
|
|
// Create and configure database connection
|
|
database = new GeViDatabase();
|
|
database.Create(
|
|
request.Address,
|
|
request.Username,
|
|
request.Password
|
|
);
|
|
|
|
// Register event handlers BEFORE connecting
|
|
database.DatabaseNotification += OnDatabaseNotification;
|
|
database.ReceivedCustomAction += OnReceivedCustomAction;
|
|
database.ReceivedCrossSwitch += OnReceivedCrossSwitch;
|
|
database.RegisterCallback();
|
|
|
|
// Connect to GeViServer
|
|
var connectResult = database.Connect();
|
|
|
|
if (connectResult == GeViConnectResult.connectOk)
|
|
{
|
|
currentAddress = request.Address;
|
|
currentUsername = request.Username;
|
|
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] Connected to GeViServer at {request.Address}");
|
|
|
|
return Results.Ok(new
|
|
{
|
|
success = true,
|
|
message = "Connected to GeViServer",
|
|
address = request.Address,
|
|
username = request.Username,
|
|
connected_at = DateTime.UtcNow
|
|
});
|
|
}
|
|
else
|
|
{
|
|
return Results.BadRequest(new
|
|
{
|
|
error = "Connection failed",
|
|
message = connectResult.ToString()
|
|
});
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return Results.BadRequest(new
|
|
{
|
|
error = "Internal Server Error",
|
|
message = ex.Message,
|
|
stack_trace = ex.StackTrace
|
|
});
|
|
}
|
|
});
|
|
|
|
// Disconnect endpoint
|
|
app.MapPost("/disconnect", () =>
|
|
{
|
|
try
|
|
{
|
|
if (database != null)
|
|
{
|
|
database.Disconnect();
|
|
database.Dispose();
|
|
database = null;
|
|
}
|
|
|
|
currentAddress = null;
|
|
currentUsername = null;
|
|
|
|
return Results.Ok(new
|
|
{
|
|
success = true,
|
|
message = "Disconnected successfully"
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return Results.BadRequest(new
|
|
{
|
|
error = "Internal Server Error",
|
|
message = ex.Message
|
|
});
|
|
}
|
|
});
|
|
|
|
// Status endpoint
|
|
app.MapGet("/status", () =>
|
|
{
|
|
return Results.Ok(new
|
|
{
|
|
is_connected = database != null,
|
|
address = currentAddress,
|
|
username = currentUsername
|
|
});
|
|
});
|
|
|
|
// Ping endpoint
|
|
app.MapPost("/ping", () =>
|
|
{
|
|
try
|
|
{
|
|
if (database == null)
|
|
{
|
|
return Results.BadRequest(new { error = "Not connected" });
|
|
}
|
|
|
|
var result = database.SendPing();
|
|
|
|
return Results.Ok(new
|
|
{
|
|
success = result,
|
|
message = result ? "Ping successful" : "Ping failed"
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return Results.BadRequest(new
|
|
{
|
|
error = "Internal Server Error",
|
|
message = ex.Message
|
|
});
|
|
}
|
|
});
|
|
|
|
// Send message endpoint
|
|
app.MapPost("/send-message", (SendMessageRequest request) =>
|
|
{
|
|
try
|
|
{
|
|
if (database == null)
|
|
{
|
|
return Results.BadRequest(new { error = "Not connected" });
|
|
}
|
|
|
|
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] SENDING: {request.Message}");
|
|
|
|
// Send action message
|
|
database.SendMessage(request.Message);
|
|
|
|
var logMsg = $"[{DateTime.Now:HH:mm:ss}] SENT: {request.Message}";
|
|
receivedMessages.Add(logMsg);
|
|
|
|
return Results.Ok(new
|
|
{
|
|
success = true,
|
|
message = "Message sent successfully",
|
|
sent_message = request.Message
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] ERROR: {ex.Message}");
|
|
return Results.BadRequest(new
|
|
{
|
|
error = "Internal Server Error",
|
|
message = ex.Message
|
|
});
|
|
}
|
|
});
|
|
|
|
// Get message log endpoint
|
|
app.MapGet("/messages", () =>
|
|
{
|
|
return Results.Ok(new
|
|
{
|
|
count = receivedMessages.Count,
|
|
messages = receivedMessages.TakeLast(50).ToList()
|
|
});
|
|
});
|
|
|
|
// Clear message log endpoint
|
|
app.MapPost("/messages/clear", () =>
|
|
{
|
|
receivedMessages.Clear();
|
|
return Results.Ok(new { message = "Message log cleared" });
|
|
});
|
|
|
|
Console.WriteLine("========================================");
|
|
Console.WriteLine("GeViServer Bridge starting on port 7710");
|
|
Console.WriteLine("========================================");
|
|
|
|
// Run on port 7710 (avoiding conflict with GeViServer DevicePort 7701)
|
|
app.Run("http://localhost:7710");
|
|
|
|
// Request models
|
|
record ConnectRequest(
|
|
string Address,
|
|
string Username,
|
|
string Password
|
|
);
|
|
|
|
record SendMessageRequest(string Message);
|