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>
806 lines
39 KiB
HTML
806 lines
39 KiB
HTML
<!DOCTYPE html>
|
||
<html xmlns:MadCap="http://www.madcapsoftware.com/Schemas/MadCap.xsd" lang="en" xml:lang="en" data-mc-search-type="Stem" data-mc-help-system-file-name="index.xml" data-mc-path-to-help-system="../" data-mc-target-type="WebHelp2" data-mc-runtime-file-type="Topic" data-mc-preload-images="false" data-mc-in-preview-mode="false" data-mc-toc-path="GeViScope SDK|GeViScope Software Development Kit (SDK)">
|
||
<!-- saved from url=(0014)about:internet -->
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>Guidelines and hints
|
||
</title>
|
||
<link href="Resources/TableStyles/Rows.css" rel="stylesheet" />
|
||
<link href="../Skins/Default/Stylesheets/TextEffects.css" rel="stylesheet" />
|
||
<link href="../Skins/Default/Stylesheets/Topic.css" rel="stylesheet" />
|
||
<link href="Resources/Stylesheets/Styles.css" rel="stylesheet" />
|
||
<script src="../Resources/Scripts/jquery.min.js">
|
||
</script>
|
||
<script src="../Resources/Scripts/plugins.min.js">
|
||
</script>
|
||
<script src="../Resources/Scripts/require.min.js">
|
||
</script>
|
||
<script src="../Resources/Scripts/require.config.js">
|
||
</script>
|
||
<script src="../Resources/Scripts/MadCapAll.js">
|
||
</script>
|
||
</head>
|
||
<body>
|
||
<div class="MCBreadcrumbsBox_0"><span class="MCBreadcrumbsPrefix">| </span><a class="MCBreadcrumbsLink" href="Titel.htm">GeViScope SDK</a><span class="MCBreadcrumbsDivider"> > </span><a class="MCBreadcrumbsLink" href="010GeViScope_SDK.htm">GeViScope Software Development Kit (SDK)</a><span class="MCBreadcrumbsDivider"> > </span><span class="MCBreadcrumbs">Guidelines and hints</span>
|
||
</div>
|
||
<h2>Guidelines and hints
|
||
</h2>
|
||
<h3>Introduction
|
||
</h3>
|
||
<p>It is recommended to be familiar with the GeViScope system and the possibilities of modern video
|
||
surveillance systems and video management systems. Before starting programming
|
||
your custom GeViScope client you should know basics
|
||
of video formats, video compression, GeViScope
|
||
events, GeViScope actions and the principles of a
|
||
client - server network communication.
|
||
</p>
|
||
<p>  </p>
|
||
<p>The following sections support you with
|
||
some suggestions and hints about using the SDK interfaces.
|
||
</p>
|
||
<h3>General hints
|
||
</h3>
|
||
<p>If your application needs to listen to
|
||
events and actions please use the application PLCSimulator.exe that you can
|
||
find on Your GeViScope device. This software allows
|
||
you to start actions and events which might be used by your program.
|
||
</p>
|
||
<p>  </p>
|
||
<p>You should work and do some tests with a
|
||
real GeViScope device or with the virtual test
|
||
environment belonging to the SDK. Create some events and actions, start them
|
||
with PLCSimulator.exe.
|
||
</p>
|
||
<p>  </p>
|
||
<p>Starting the setup software GSCSetup.exe
|
||
with the command line parameter /utilities will offer you the possibility to
|
||
open DBITest to discover the database structure and
|
||
to evaluate and test select statements against the database. Additionally this
|
||
tool offers you the possibility to start the registry editor to evaluate the
|
||
internal structure of the GeViScope setup.
|
||
</p>
|
||
<p>  </p>
|
||
<p class="GutZuWissen">Make
|
||
sure to delete all objects that are created inside of DLLs. The objects
|
||
themselves should always offer a Destroy() or Free()
|
||
method for that.</p>
|
||
<p> </p>
|
||
<p>Callback functions, which are called out of
|
||
the SDK DLLs, are called from threads, which were created inside the DLLs.
|
||
Variables and pointers that are passed as arguments of the callback may not be
|
||
used outside the callback context. They are only valid for the duration of the
|
||
callback call.
|
||
</p>
|
||
<p>  </p>
|
||
<p>Structures that are used as arguments for
|
||
SDK functions should always be initialized by the function memset(). After setting all
|
||
the structure elements to zero, the size or structsize
|
||
element has to be initialized with the sizeof() function.
|
||
</p>
|
||
<p>  </p>
|
||
<p>MPEG-2 files that were created by SDK
|
||
functions can possibly not be played with the windows media player. The reason
|
||
is a missing MPEG-2 decoder. We recommend using DVD player software like PowerDVD or the VCL Media Player software.
|
||
</p>
|
||
<h3>Working with handles and instances
|
||
</h3>
|
||
<p>Integral part of the SDK
|
||
are units that give the user a comfortable access to the plain functions
|
||
of the DLL, e.g. GSCDBI.h/.cpp/.pas.
|
||
In these units classes encapsulate access to instances of objects which are
|
||
created inside the DLL. To have access from outside the DLL (custom
|
||
application) to the inside residing instances, handles are used. The units have
|
||
to be added to the project respectively to the solution to avoid linker errors.
|
||
</p>
|
||
<p>  </p>
|
||
<p>After work with instances is finished, the
|
||
instances have to be deleted by calling their destroy()
|
||
or free() method. Otherwise there will be memory leaks left.
|
||
</p>
|
||
<p>  </p>
|
||
<p>Using the plain exported functions of the
|
||
DLL is not recommended. To get access to full functionality you should use the
|
||
units instead (pas files or h/cpp files).
|
||
</p>
|
||
<p>  </p>
|
||
<p>The following example (in pseudo code)
|
||
should illustrate the above facts:
|
||
</p>
|
||
<p>  </p>
|
||
<p><span style="color: #008000;"> // define a handle to a server object</span>
|
||
</p>
|
||
<p> HGscServer
|
||
MyServer;
|
||
</p>
|
||
<p> </p>
|
||
<p> <span style="color: #008000;">// create a server object instance inside the DLL and</span><br /><span style="color: #008000;"> // get a handle to it</span></p>
|
||
<p> MyServer =
|
||
DBICreateRemoteserver();
|
||
</p>
|
||
<p> 
|
||
</p>
|
||
<p> ...
|
||
</p>
|
||
<p> </p>
|
||
<p> <span style="color: #008000;">// work with the object instance with the help of the
|
||
handle</span></p>
|
||
<p> MyServer->Connect();
|
||
</p>
|
||
<p> 
|
||
</p>
|
||
<p> ...
|
||
</p>
|
||
<p> 
|
||
</p>
|
||
<p><span style="color: #008000;"> // define a handle to a PLC object
|
||
</span>
|
||
</p>
|
||
<p> HGscPLC
|
||
PLC;
|
||
</p>
|
||
<p> 
|
||
</p>
|
||
<p style="color: #008000;">  // create a
|
||
PLC object instance inside the DLL and
|
||
</p>
|
||
<p style="color: #008000;"> // get a handle to it
|
||
</p>
|
||
<p> PLC =
|
||
MyServer.CreatePLC();
|
||
</p>
|
||
<p> 
|
||
</p>
|
||
<p> ...
|
||
</p>
|
||
<p> 
|
||
</p>
|
||
<p> <span style="color: #008000;">// work with the object instance with the help of the
|
||
handle</span></p>
|
||
<p> PLC->OpenPushCallback(...);
|
||
</p>
|
||
<p> </p>
|
||
<p> ...
|
||
</p>
|
||
<p> </p>
|
||
<p> <span style="color: #008000;">// destroy PLC object</span> <![CDATA[ ]]></p>
|
||
<p> PLC->Destroy();
|
||
</p>
|
||
<p> 
|
||
</p>
|
||
<p> ...
|
||
</p>
|
||
<p> 
|
||
</p>
|
||
<p><span style="color: #008000;"> // destroy server object
|
||
</span>
|
||
</p>
|
||
<p> MyServer->Destroy();
|
||
</p>
|
||
<h3>Interaction between DBI and MediaPlayer
|
||
</h3>
|
||
<p>The DBI interface gives access to GeViScope server functionality. After creating an instance
|
||
with the function DBICreateRemoteserver() a connection to the server can be established by calling
|
||
the method Connect() of the server object instance.
|
||
</p>
|
||
<p> </p>
|
||
<p>The following methods of a server object
|
||
instance can be called to get access to different kinds of functions (not a
|
||
complete list):
|
||
</p>
|
||
<p> </p>
|
||
<table style="caption-side: top;mc-table-style: url('Resources/TableStyles/Rows.css');" class="TableStyle_Rows" cellspacing="0">
|
||
<col />
|
||
<col />
|
||
<thead>
|
||
<tr>
|
||
<th class="TableStyle_Rows_Head_0_0_RowSep_ColSep">Method
|
||
</th>
|
||
<th class="TableStyle_Rows_Head_0_0_RowSep_ColEnd">Function</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td width="307" valign="top" class="TableStyle_Rows_Body_0_0_RowSep_ColSep">CreateDataSet(), CreateDataPacket() </td>
|
||
<td width="307" valign="top" class="TableStyle_Rows_Body_0_0_RowSep_ColEnd">Fetch data from server database</td>
|
||
</tr>
|
||
<tr>
|
||
<td width="307" valign="top" class="TableStyle_Rows_Body_1_0_RowSep_ColSep">CreateLiveStream()</td>
|
||
<td width="307" valign="top" class="TableStyle_Rows_Body_1_0_RowSep_ColEnd">Fetch live data from server</td>
|
||
</tr>
|
||
<tr>
|
||
<td width="307" valign="top" class="TableStyle_Rows_Body_0_0_RowSep_ColSep">CreateRegistry() </td>
|
||
<td class="TableStyle_Rows_Body_0_0_RowSep_ColEnd">Fetch setup data from server (media
|
||
channel information, event information, …)</td>
|
||
</tr>
|
||
<tr>
|
||
<td width="307" valign="top" class="TableStyle_Rows_Body_1_0_RowEnd_ColSep">CreatePLC()</td>
|
||
<td width="307" valign="top" class="TableStyle_Rows_Body_1_0_RowEnd_ColEnd">Listen to, create and send actions </td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p> </p>
|
||
<p>The example (in pseudo code) of the
|
||
previous chapter should illustrate the above facts.
|
||
</p>
|
||
<p> </p>
|
||
<p>The MediaPlayer
|
||
interface offers simple to use objects to display live and recorded video in
|
||
windows controls. A viewer object instance needs to be created by calling GMPCreateViewer().
|
||
The viewer needs a handle to a windows control and a handle to a server object
|
||
instance. It handles fetching data, decompressing data and displaying video in
|
||
the linked windows control by itself.
|
||
</p>
|
||
<p> </p>
|
||
<p>The following methods of a viewer object
|
||
instance can be called to get access to different kinds of functions (not a
|
||
complete list):
|
||
</p>
|
||
<p> </p>
|
||
<table style="caption-side: top;mc-table-style: url('Resources/TableStyles/Rows.css');" class="TableStyle_Rows" cellspacing="0">
|
||
<col />
|
||
<col />
|
||
<thead>
|
||
<tr>
|
||
<th class="TableStyle_Rows_Head_0_0_RowSep_ColSep">Method</th>
|
||
<th class="TableStyle_Rows_Head_0_0_RowSep_ColEnd">Function </th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td width="307" valign="top" class="TableStyle_Rows_Body_0_0_RowSep_ColSep">ConnectDB() </td>
|
||
<td width="307" valign="top" class="TableStyle_Rows_Body_0_0_RowSep_ColEnd">Fetch video data from the database and
|
||
display it in any play mode required. Filter and search criteria can
|
||
optionally be defined. </td>
|
||
</tr>
|
||
<tr>
|
||
<td width="307" valign="top" class="TableStyle_Rows_Body_1_0_RowEnd_ColSep">SetPlayMode(pmPlayNextEvent)</td>
|
||
<td width="307" valign="top" class="TableStyle_Rows_Body_1_0_RowEnd_ColEnd">Display the next available event pictures</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p> 
|
||
</p>
|
||
<p>The following example (in pseudo code)
|
||
shows how to create a viewer and use it afterwards:</p>
|
||
<p> </p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> <span style="color: #008000;">// define a handle to a viewer object</span></p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> HGscViewer
|
||
MyViewer;
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> <span style="color: #008000;">// create a viewer object instance inside the DLL and</span></p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> <span style="color: #008000;">// get a handle to it</span></p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> MyViewer =
|
||
GMPCreateViewer(WindowHandle, ...);
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> <span style="color: #008000;">// define a structure with data needed to link</span></p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> <span style="color: #008000;">// the viewer to a media channel in the server</span></p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> TMPConnectData MyViewerConnectData;
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"><span style="color: #008000;">  // handle to the server object instance </span>
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> MyViewerConnectData.Connection = MyServer; </p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> MyViewerConnectData.ServerType = ctGSCServer; </p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> MyViewerConnectData.MediaType = mtServer; </p>
|
||
<p class="CODEetc" style="margin-left: 25px;"><span style="color: #008000;"> // ID of the media channel that should be displayed</span>
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> MyViewerConnectData.MediaChID = ...
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> <span style="color: #008000;">// link the viewer to a media channel and display live data</span></p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> MyViewer->ConnectDB(MyViewerConnectData, pmPlayStream, ...); </p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> </p>
|
||
<p class="CODEetc" style="margin-left: 25px;"><span style="color: #008000;"> // destroy viewer object</span>
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;">  MyViewer->Destroy(); </p>
|
||
<p> 
|
||
</p>
|
||
<p>Beside the viewer object class there is
|
||
another class in the MediaPlayer interface: The offscreen viewer object class. If you want to decompress
|
||
media, which should not be displayed with the help of the viewer object, you
|
||
can use the offscreen viewer object. An instance can
|
||
be created with the function GMPCreateOffscreenViewer(). The offscreen viewer object
|
||
instance provides nearly the same functionality as the viewer object class
|
||
does. The video footage is not rendered in a window,
|
||
it is decompressed in a special DecompBuffer object
|
||
instance. After the decompression is done inside the offscreen
|
||
viewer, the hosting application can be notified with the help of a callback
|
||
function. Inside the callback the decompressed image can be accessed.
|
||
</p>
|
||
<p> </p>
|
||
<p>The DecompBuffer
|
||
class encapsulates special functions for effective decompressing. So it is
|
||
recommend to use it. Creating an instance of the
|
||
buffer can be reached by calling the function GMPCreateDecompBuffer(). The
|
||
instance can be used for as many decompressions as needed. The method GetBufPointer()
|
||
gives access to the raw picture data inside the buffer.
|
||
</p>
|
||
<p> 
|
||
</p>
|
||
<p>Here is a short example (in pseudo code)
|
||
how to work with an offscreen viewer object:
|
||
</p>
|
||
<p> </p>
|
||
<p class="CODEetc" style="margin-left: 25px;color: #008000;"> // define a handle to a DecompBuffer object
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> HGscDecompBuffer
|
||
MyDecompBuffer;
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> </p>
|
||
<p class="CODEetc" style="margin-left: 25px;color: #008000;"> // create a DecompBuffer object instance inside the DLL and
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;color: #008000;"> // get a handle to it
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> MyDecompBuffer
|
||
= GMPCreateDecompBuffer();
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;color: #008000;"> // define a handle to a offscreen viewer object
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> HGscViewer
|
||
MyOffscreenViewer;
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;color: #008000;"> // create an offscreen viewer object instance inside the
|
||
DLL and
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;color: #008000;"> // get a handle to it
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> MyOffscreenViewer
|
||
= GMPCreateOffscreenViewer(MyDecompBuffer);
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"><span style="color: #008000;"> // set callback of the offscreen viewer object
|
||
</span> <![CDATA[ ]]></p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> MyOffscreenViewer.SetNewOffscreenImageCallBack(NewOffscreenImageCallback);
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;color: #008000;"> // define a structure with data needed to link
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;color: #008000;"> // the offscreen viewer to a media channel in the server
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> TMPConnectData
|
||
MyOffscreenViewerConnectData;
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> <span style="color: #008000;">// handle to the server object instance
|
||
</span> <![CDATA[ ]]></p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> MyOffscreenViewerConnectData.Connection
|
||
= MyServer;
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> MyOffscreenViewerConnectData.ServerType
|
||
= ctGSCServer;
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> MyOffscreenViewerConnectData.MediaType
|
||
= mtServer;
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"><span style="color: #008000;"> // ID of the media channel that should be decompressed
|
||
</span> <![CDATA[ ]]></p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> MyOffscreenViewerConnectData.MediaChID
|
||
= ...
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> <span style="color: #008000;">// link the offscreen viewer to a media channel and
|
||
decompress live data
|
||
</span> <![CDATA[ ]]></p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> MyOffscreenViewer->ConnectDB(MyOffscreenViewerConnectData,
|
||
pmPlayStream, ...);
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> ...
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"><span style="color: #008000;"> // destroy offscreen viewer object
|
||
</span> <![CDATA[ ]]></p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> MyOffscreenViewer->Destroy();
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> </p>
|
||
<p class="CODEetc" style="margin-left: 25px;"><span style="color: #008000;"> // destroy DecompBuffer object
|
||
</span> <![CDATA[ ]]></p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> MyDecompBuffer->Destroy();
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> ...
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;color: #008000;"> // callback function, that is called after images have been
|
||
decompressed
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> ...
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;">  
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;color: #008000;"> // get a raw pointer to the picture in the DecompBuffer
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;color: #008000;"> // object
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> MyDecompBuffer->GetBufPointer(BufferPointer,
|
||
...);
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;color: #008000;"> // copy the picture into a windows bitmap resource
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;color: #008000;"> // for example
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> SetDIBits(...,
|
||
BitmapHandle, ..., BufferPointer, ..., DIB_RGB_COLORS);
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> ...
|
||
</p>
|
||
<h3>Enumeration of setup data
|
||
</h3>
|
||
<p>GeViScope Server resources can be enumerated by custom applications. The
|
||
setup object, which can be instantiated by calling the server method CreateRegistry(),
|
||
offers functionality for this.
|
||
</p>
|
||
<p> </p>
|
||
<p>Enumeration of resources normally is done
|
||
in four steps:
|
||
</p>
|
||
<p> </p>
|
||
<ol>
|
||
<li value="1">Define an
|
||
array of type GSCSetupReadRequest with the only
|
||
element “/”. This causes the method ReadNodes() to transfer the whole setup from the server to the
|
||
custom application.
|
||
</li>
|
||
<li value="2">Call the
|
||
method ReadNodes() of the setup object to get the whole setup from the
|
||
server.
|
||
</li>
|
||
<li value="3">Call one of
|
||
the Get…() methods of the setup object to get an
|
||
array of GUIDs representing the list of resources. There are different Get…() methods, e. g. GetMediaChannels()
|
||
or GetEvents().
|
||
</li>
|
||
<li value="4">Use the
|
||
GUID array to receive the resources data by calling Get…Settings()
|
||
methods, e. g. GetMediaChannelSettings() or GetEventSettings().
|
||
</li>
|
||
</ol>
|
||
<p> </p>
|
||
<p>Here is an example (in pseudo code), that
|
||
shows how to enumerate the media channels:
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> ...
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> <span style="color: #008000;">// connect to the server</span> <![CDATA[ ]]></p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> MyServer->Connect();
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> ...
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> <span style="color: #008000;">// define a
|
||
handle to a setup object
|
||
</span> <![CDATA[ ]]></p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> HGscRegistry MySetup;
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;color: #008000;"> // create a setup object instance inside the DLL and
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;color: #008000;"> // get a handle to it
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> MySetup =
|
||
MyServer->CreateRegistry();
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> <span style="color: #008000;">// define a array for the setup read request
|
||
</span> <![CDATA[ ]]></p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> GscSetupReadRequest SetupReadRequest[1];
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> SetupReadRequest[0].NodeName = "/";
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> <span style="color: #008000;">// read the setup data from the server
|
||
</span> <![CDATA[ ]]></p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> MySetup->ReadNodes(&SetupReadRequest, ...);
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> </p>
|
||
<p class="CODEetc" style="margin-left: 25px;color: #008000;"> // define
|
||
a GUID array for the GUIDs of the
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;color: #008000;"> // existing media channels
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> GuidDynArray MediaChannels;
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> </p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> <span style="color: #008000;">// get the GUID array out of the setup data
|
||
</span> <![CDATA[ ]]></p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> MySetup->GetMediaChannels(MediaChannels);
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"><span style="color: #008000;">// get the data of
|
||
each single media channel
|
||
</span> <![CDATA[ ]]></p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> <span style="color: #4169e1;">for </span>each MediaChannelGUID <span style="color: #4169e1;">in
|
||
</span>MediaChannels
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> MySetup->GetMediaChannelSettings(MediaChannelGUID,
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 200px;"> MediaChannelID,
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 200px;">  GlobalNumber,
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 200px;"> ...);
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> ...
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> <span style="color: #008000;">// destroy setup object</span> <![CDATA[ ]]></p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> MySetup->Destroy();
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> <span style="color: #008000;">// destroy server object
|
||
</span> <![CDATA[ ]]></p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> MyServer->Destroy();
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;">  ...
|
||
</p>
|
||
<p> 
|
||
</p>
|
||
<p>Please note that especially the media
|
||
channels can be enumerated by using the global function GMPQueryMediaChannelList()
|
||
of the MediaPlayer interface as well.
|
||
</p>
|
||
<p> 
|
||
</p>
|
||
<h3>PLC, actions and events
|
||
</h3>
|
||
<p>The PLC (Prcess
|
||
Logic Control) object supports you with functionality for handling
|
||
notifications, actions and events. The method CreatePLC() of the server
|
||
object class creates a handle to a PLC object inside the DBI DLL.
|
||
</p>
|
||
<p> </p>
|
||
<p>The following methods of a PLC object
|
||
instance can be called to get access to different kinds of functions (not a
|
||
complete list):
|
||
</p>
|
||
<p> </p>
|
||
<table style="caption-side: top;mc-table-style: url('Resources/TableStyles/Rows.css');" class="TableStyle_Rows" cellspacing="0">
|
||
<col />
|
||
<col />
|
||
<thead>
|
||
<tr>
|
||
<th class="TableStyle_Rows_Head_0_0_RowSep_ColSep">Method </th>
|
||
<th class="TableStyle_Rows_Head_0_0_RowSep_ColEnd">Function
|
||
</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td width="307" valign="top" class="TableStyle_Rows_Body_0_0_RowSep_ColSep">SendAction() </td>
|
||
<td width="307" valign="top" class="TableStyle_Rows_Body_0_0_RowSep_ColEnd">Send an action to the connected server </td>
|
||
</tr>
|
||
<tr>
|
||
<td width="307" valign="top" class="TableStyle_Rows_Body_1_0_RowSep_ColSep">StartEvent() </td>
|
||
<td width="307" valign="top" class="TableStyle_Rows_Body_1_0_RowSep_ColEnd">Start an event of the connected server </td>
|
||
</tr>
|
||
<tr>
|
||
<td width="307" valign="top" class="TableStyle_Rows_Body_0_0_RowSep_ColSep">SubscribeActions()</td>
|
||
<td width="307" valign="top" class="TableStyle_Rows_Body_0_0_RowSep_ColEnd">Subscribe a list of actions that should
|
||
be notified by a registered callback function </td>
|
||
</tr>
|
||
<tr>
|
||
<td width="307" valign="top" class="TableStyle_Rows_Body_1_0_RowEnd_ColSep">
|
||
<p>OpenPushCallback()
|
||
</p>
|
||
</td>
|
||
<td width="307" valign="top" class="TableStyle_Rows_Body_1_0_RowEnd_ColEnd">Register a callback function, that is
|
||
called if an notification arrives or a event starts/stops or if one of the
|
||
subscribed actions arrives </td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p> 
|
||
</p>
|
||
<p>To receive Notifications and actions a
|
||
callback function can be registered with the method OpenPushCallback(). After
|
||
receiving an action, the action should be decoded and dispatched by the an instance of the class GSCActionDispatcher.
|
||
The action dispatcher gives you a simple way to react on specific actions. Here
|
||
is a short example (in pseudo code):
|
||
</p>
|
||
<p> </p>
|
||
<p class="CODEetc" style="color: #008000;margin-left: 25px;"> // initialization code:
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> ...
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="color: #008000;margin-left: 50px;"> // connect to the server
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> MyServer->Connect();
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> ...
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> <span style="color: #008000;">// define a handle to a PLC object
|
||
</span> <![CDATA[ ]]></p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> HGSCPLC
|
||
PLC;
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="color: #008000;margin-left: 50px;"> // create a PLC object instance inside the DLL and
|
||
</p>
|
||
<p class="CODEetc" style="color: #008000;margin-left: 50px;"> // get a handle to it
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> PLC =
|
||
MyServer.CreatePLC();
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;">  ...
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="color: #008000;margin-left: 50px;"> // link your callback function for a custom action
|
||
</p>
|
||
<p class="CODEetc" style="color: #008000;margin-left: 50px;"> // to the action dispatcher, so that the callback function
|
||
</p>
|
||
<p class="CODEetc" style="color: #008000;margin-left: 50px;"> // is called automatically if a cutsom action arrives
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> ActionDispatcher->OnCustomAction = this->MyCustomActionHandler;
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="color: #008000;margin-left: 50px;"> // register a callback function for notifications,
|
||
</p>
|
||
<p class="CODEetc" style="color: #008000;margin-left: 50px;"> // events and actions (this callback function dispatches
|
||
</p>
|
||
<p class="CODEetc" style="color: #008000;margin-left: 50px;"> // all received actions with the help of the
|
||
</p>
|
||
<p class="CODEetc" style="color: #008000;margin-left: 50px;"> // GSCActionDispatcher)
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> PLC->OpenPushCallback(...);
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> ...
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> <span style="color: #008000;">// destroy PLC object
|
||
</span> <![CDATA[ ]]></p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> PLC->Destroy();
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> ...
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> <span style="color: #008000;">// destroy server object</span> <![CDATA[ ]]></p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> MyServer->Destroy();
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="color: #008000;margin-left: 25px;"> // callback function for all notifications, events and
|
||
</p>
|
||
<p class="CODEetc" style="color: #008000;margin-left: 25px;"> // subscribed actions:
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 25px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> ...
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> 
|
||
</p>
|
||
<p class="CODEetc" style="color: #008000;margin-left: 50px;"> // dispatch the received action to the linked
|
||
</p>
|
||
<p class="CODEetc" style="color: #008000;margin-left: 50px;"> // callback functions
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> ActionDispatcher->Dispatch(ActionHandle);
|
||
</p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> </p>
|
||
<p class="CODEetc" style="margin-left: 50px;"> ...
|
||
</p>
|
||
<p> 
|
||
 
|
||
</p>
|
||
<h3>Media channel IDs
|
||
</h3>
|
||
<p>The existing media channels can be
|
||
displayed by the viewer objects of the MediaPlayer interface.
|
||
Normally this is done with the method ConnectDB(). This method needs the media channel ID to identify the
|
||
media channel (camera) that should be displayed.
|
||
</p>
|
||
<p> </p>
|
||
<p>The media channel IDs are generated
|
||
automatically by the GeViScope server. Every created
|
||
media channel gets an ID that is always unique. So if you remove media channels
|
||
from the setup and add them again, they will sure receive some new IDs.
|
||
</p>
|
||
<p> </p>
|
||
<p>For that reason media channels should not
|
||
be accessed by constant IDs. It is recommend using global numbers instead,
|
||
because they can be changed in the setup. To find the fitting media channel ID
|
||
for a given global number, the media channels should be enumerated from the
|
||
server setup. Please refer to chapter “Enumeration of setup data” in this
|
||
document to see how this is done. </p>
|
||
<p> </p>
|
||
<p>There is a similar difficulty with events,
|
||
digital inputs and outputs. Events don’t have global numbers. Here the event
|
||
name should be used instead.
|
||
</p>
|
||
<p> 
|
||
</p>
|
||
<h3>Handling connection collapses
|
||
</h3>
|
||
<p>The callback OpenPushCallback() of the
|
||
PLC object enables to listen to different kinds of notifications from the PLC
|
||
object. One is the “plcnPushCallbackLost”
|
||
notification. It is fired if a connection is internally detected as collapsed.
|
||
As a reaction on this event you should destroy or free all objects that were
|
||
created inside the DLLs and start a phase of reconnect tries. The reconnect
|
||
tries should start every 30 seconds for example. Additionally your application
|
||
can listen to UDP broadcasts that are sent by the GeViScope
|
||
server. After your application received this broadcast it can directly try to
|
||
reconnect to the server. Please be aware of the fact, that broadcasts only work
|
||
in LAN – routers normally block broadcasts.
|
||
</p>
|
||
<p> 
|
||
</p>
|
||
<h3>Using MediaPlayer with GeViScope and MULTISCOPE III servers
|
||
</h3>
|
||
<p>Generally the MediaPlayer
|
||
interface can be used with GeViScope as well as
|
||
MULTISCOPE III servers. To link the server connection to the viewer object, the
|
||
connection data structure has to be defined. The type of the structure is “TMPConnectData”. The element “ServerType”
|
||
identifies the kind of server whose media should be displayed in the viewer.
|
||
</p>
|
||
<p> </p>
|
||
<p>Please have a look on the example (in
|
||
pseudo code) in the chapter “Interaction between DBI and MediaPlayer”
|
||
in this document.
|
||
</p>
|
||
<p> </p>
|
||
<p>For creating different kind of connections,
|
||
different DLLs have to be used. For GeViScope the DLL
|
||
“GSCDBI.DLL” and for MULTISCOPE III the DLL “MscDBI.DLL” has to be included in
|
||
the project or solution of the custom application. They can coexist. </p>
|
||
<p> </p>
|
||
<p>Handling a connection to a MULTISCOPE III
|
||
server is similar to GeViScope. Details can be found
|
||
in the MULTISCOPE III SDK documentation.
|
||
</p>
|
||
<p> 
|
||
</p>
|
||
</body>
|
||
</html> |