Files
geutebruck/SOURCES/CODEX/GeViScope/GeViScopeSDK_HTML5/Content/016Guidelines_And_Hints.htm
Administrator 14893e62a5 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>
2025-12-31 18:10:54 +01:00

806 lines
39 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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"> &gt; </span><a class="MCBreadcrumbsLink" href="010GeViScope_SDK.htm">GeViScope Software Development Kit (SDK)</a><span class="MCBreadcrumbsDivider"> &gt; </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>&#160; </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>&#160; </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>&#160; </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>&#160; </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>&#160;</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>&#160; </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>&#160; </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>&#160; </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>&#160; </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>&#160; </p>
<p>The following example (in pseudo code)
should illustrate the above facts:
</p>
<p>&#160; </p>
<p><span style="color: #008000;">&#160;// define a handle to a server object</span>
</p>
<p>&#160;HGscServer
MyServer;
</p>
<p>&#160;</p>
<p>&#160;<span style="color: #008000;">// create a server object instance inside the DLL and</span><br /><span style="color: #008000;">&#160;// get a handle to it</span></p>
<p>&#160;MyServer =
DBICreateRemoteserver();
</p>
<p>&#160;
</p>
<p>&#160;...
</p>
<p>&#160;</p>
<p>&#160;<span style="color: #008000;">// work with the object instance with the help of the
handle</span></p>
<p>&#160;MyServer-&gt;Connect();
</p>
<p>&#160;
</p>
<p>&#160;...
</p>
<p>&#160;
</p>
<p><span style="color: #008000;">&#160;// define a handle to a PLC object
</span>
</p>
<p>&#160;HGscPLC
PLC;
</p>
<p>&#160;
</p>
<p style="color: #008000;">&#160;&#160;// create a
PLC object instance inside the DLL and
</p>
<p style="color: #008000;">&#160;// get a handle to it
</p>
<p>&#160;PLC =
MyServer.CreatePLC();
</p>
<p>&#160;
</p>
<p>&#160;...
</p>
<p>&#160;
</p>
<p>&#160;<span style="color: #008000;">// work with the object instance with the help of the
handle</span></p>
<p>&#160;PLC-&gt;OpenPushCallback(...);
</p>
<p>&#160;</p>
<p>&#160;...
</p>
<p>&#160;</p>
<p>&#160;<span style="color: #008000;">// destroy PLC object</span> <![CDATA[ ]]></p>
<p>&#160;PLC-&gt;Destroy();
</p>
<p>&#160;
</p>
<p>&#160;...
</p>
<p>&#160;
</p>
<p><span style="color: #008000;">&#160;// destroy server object
</span>
</p>
<p>&#160;MyServer-&gt;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>&#160;</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>&#160;</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>&#160;</p>
<p>The example (in pseudo code) of the
previous chapter should illustrate the above facts.
</p>
<p>&#160;</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>&#160;</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>&#160;</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>&#160;
</p>
<p>The following example (in pseudo code)
shows how to create a viewer and use it afterwards:</p>
<p>&#160;</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;<span style="color: #008000;">// define a handle to a viewer object</span></p>
<p class="CODEetc" style="margin-left: 25px;">&#160;HGscViewer
MyViewer;
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;<span style="color: #008000;">// create a viewer object instance inside the DLL and</span></p>
<p class="CODEetc" style="margin-left: 25px;">&#160;<span style="color: #008000;">// get a handle to it</span></p>
<p class="CODEetc" style="margin-left: 25px;">&#160;MyViewer =
GMPCreateViewer(WindowHandle, ...);
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;<span style="color: #008000;">// define a structure with data needed to link</span></p>
<p class="CODEetc" style="margin-left: 25px;">&#160;<span style="color: #008000;">// the viewer to a media channel in the server</span></p>
<p class="CODEetc" style="margin-left: 25px;">&#160;TMPConnectData MyViewerConnectData;
</p>
<p class="CODEetc" style="margin-left: 25px;"><span style="color: #008000;">&#160;&#160;// handle to the server object instance </span>
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;MyViewerConnectData.Connection = MyServer; </p>
<p class="CODEetc" style="margin-left: 25px;">&#160;MyViewerConnectData.ServerType = ctGSCServer; </p>
<p class="CODEetc" style="margin-left: 25px;">&#160;MyViewerConnectData.MediaType = mtServer; </p>
<p class="CODEetc" style="margin-left: 25px;"><span style="color: #008000;">&#160;// ID of the media channel that should be displayed</span>
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;MyViewerConnectData.MediaChID = ...
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;<span style="color: #008000;">// link the viewer to a media channel and display live data</span></p>
<p class="CODEetc" style="margin-left: 25px;">&#160;MyViewer-&gt;ConnectDB(MyViewerConnectData, pmPlayStream, ...); </p>
<p class="CODEetc" style="margin-left: 25px;">&#160;</p>
<p class="CODEetc" style="margin-left: 25px;"><span style="color: #008000;">&#160;// destroy viewer object</span>
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;&#160;MyViewer-&gt;Destroy(); </p>
<p>&#160;
</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>&#160;</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>&#160;
</p>
<p>Here is a short example (in pseudo code)
how to work with an offscreen viewer object:
</p>
<p>&#160;</p>
<p class="CODEetc" style="margin-left: 25px;color: #008000;">&#160;// define a handle to a DecompBuffer object
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;HGscDecompBuffer
MyDecompBuffer;
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;</p>
<p class="CODEetc" style="margin-left: 25px;color: #008000;">&#160;// create a DecompBuffer object instance inside the DLL and
</p>
<p class="CODEetc" style="margin-left: 25px;color: #008000;">&#160;// get a handle to it
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;MyDecompBuffer
= GMPCreateDecompBuffer();
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;color: #008000;">&#160;// define a handle to a offscreen viewer object
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;HGscViewer
MyOffscreenViewer;
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;color: #008000;">&#160;// create an offscreen viewer object instance inside the
DLL and
</p>
<p class="CODEetc" style="margin-left: 25px;color: #008000;">&#160;// get a handle to it
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;MyOffscreenViewer
= GMPCreateOffscreenViewer(MyDecompBuffer);
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;"><span style="color: #008000;">&#160;// set callback of the offscreen viewer object
</span> <![CDATA[ ]]></p>
<p class="CODEetc" style="margin-left: 25px;">&#160;MyOffscreenViewer.SetNewOffscreenImageCallBack(NewOffscreenImageCallback);
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;color: #008000;">&#160;// define a structure with data needed to link
</p>
<p class="CODEetc" style="margin-left: 25px;color: #008000;">&#160;// the offscreen viewer to a media channel in the server
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;TMPConnectData
MyOffscreenViewerConnectData;
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;<span style="color: #008000;">// handle to the server object instance
</span> <![CDATA[ ]]></p>
<p class="CODEetc" style="margin-left: 25px;">&#160;MyOffscreenViewerConnectData.Connection
= MyServer;
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;MyOffscreenViewerConnectData.ServerType
= ctGSCServer;
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;MyOffscreenViewerConnectData.MediaType
= mtServer;
</p>
<p class="CODEetc" style="margin-left: 25px;"><span style="color: #008000;">&#160;// ID of the media channel that should be decompressed
</span> <![CDATA[ ]]></p>
<p class="CODEetc" style="margin-left: 25px;">&#160;MyOffscreenViewerConnectData.MediaChID
= ...
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;<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;">&#160;MyOffscreenViewer-&gt;ConnectDB(MyOffscreenViewerConnectData,
pmPlayStream, ...);
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;...
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;"><span style="color: #008000;">&#160;// destroy offscreen viewer object
</span> <![CDATA[ ]]></p>
<p class="CODEetc" style="margin-left: 25px;">&#160;MyOffscreenViewer-&gt;Destroy();
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;</p>
<p class="CODEetc" style="margin-left: 25px;"><span style="color: #008000;">&#160;// destroy DecompBuffer object
</span> <![CDATA[ ]]></p>
<p class="CODEetc" style="margin-left: 25px;">&#160;MyDecompBuffer-&gt;Destroy();
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;...
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;color: #008000;">&#160;// callback function, that is called after images have been
decompressed
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;...
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;color: #008000;">&#160;// get a raw pointer to the picture in the DecompBuffer
</p>
<p class="CODEetc" style="margin-left: 25px;color: #008000;">&#160;// object
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;MyDecompBuffer-&gt;GetBufPointer(BufferPointer,
...);
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;color: #008000;">&#160;// copy the picture into a windows bitmap resource
</p>
<p class="CODEetc" style="margin-left: 25px;color: #008000;">&#160;// for example
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;SetDIBits(...,
BitmapHandle, ..., BufferPointer, ..., DIB_RGB_COLORS);
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;...
</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>&#160;</p>
<p>Enumeration of resources normally is done
in four steps:
</p>
<p>&#160;</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>&#160;</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;">&#160;...
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;<span style="color: #008000;">// connect to the server</span> <![CDATA[ ]]></p>
<p class="CODEetc" style="margin-left: 25px;">&#160;MyServer-&gt;Connect();
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;...
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;<span style="color: #008000;">// define a
handle to a setup object
</span> <![CDATA[ ]]></p>
<p class="CODEetc" style="margin-left: 25px;">&#160;HGscRegistry MySetup;
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;color: #008000;">&#160;// create a setup object instance inside the DLL and
</p>
<p class="CODEetc" style="margin-left: 25px;color: #008000;">&#160;// get a handle to it
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;MySetup =
MyServer-&gt;CreateRegistry();
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;<span style="color: #008000;">// define a array for the setup read request
</span> <![CDATA[ ]]></p>
<p class="CODEetc" style="margin-left: 25px;">&#160;GscSetupReadRequest SetupReadRequest[1];
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;SetupReadRequest[0].NodeName = "/";
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;<span style="color: #008000;">// read the setup data from the server
</span> <![CDATA[ ]]></p>
<p class="CODEetc" style="margin-left: 25px;">&#160;MySetup-&gt;ReadNodes(&amp;SetupReadRequest, ...);
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;</p>
<p class="CODEetc" style="margin-left: 25px;color: #008000;">&#160;// define
a GUID array for the GUIDs of the
</p>
<p class="CODEetc" style="margin-left: 25px;color: #008000;">&#160;// existing media channels
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;GuidDynArray MediaChannels;
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;<span style="color: #008000;">// get the GUID array out of the setup data
</span> <![CDATA[ ]]></p>
<p class="CODEetc" style="margin-left: 25px;">&#160;MySetup-&gt;GetMediaChannels(MediaChannels);
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</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;">&#160;<span style="color: #4169e1;">for </span>each MediaChannelGUID <span style="color: #4169e1;">in
</span>MediaChannels
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;MySetup-&gt;GetMediaChannelSettings(MediaChannelGUID,
</p>
<p class="CODEetc" style="margin-left: 200px;">&#160;MediaChannelID,
</p>
<p class="CODEetc" style="margin-left: 200px;">&#160;&#160;GlobalNumber,
</p>
<p class="CODEetc" style="margin-left: 200px;">&#160;...);
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;...
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;<span style="color: #008000;">// destroy setup object</span> <![CDATA[ ]]></p>
<p class="CODEetc" style="margin-left: 25px;">&#160;MySetup-&gt;Destroy();
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;<span style="color: #008000;">// destroy server object
</span> <![CDATA[ ]]></p>
<p class="CODEetc" style="margin-left: 25px;">&#160;MyServer-&gt;Destroy();
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;&#160;...
</p>
<p>&#160;
</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>&#160;
</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>&#160;</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>&#160;</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>&#160;
</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>&#160;</p>
<p class="CODEetc" style="color: #008000;margin-left: 25px;">&#160;// initialization code:
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;...
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;
</p>
<p class="CODEetc" style="color: #008000;margin-left: 50px;">&#160;// connect to the server
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;MyServer-&gt;Connect();
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;...
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;<span style="color: #008000;">// define a handle to a PLC object
</span> <![CDATA[ ]]></p>
<p class="CODEetc" style="margin-left: 50px;">&#160;HGSCPLC
PLC;
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;
</p>
<p class="CODEetc" style="color: #008000;margin-left: 50px;">&#160;// create a PLC object instance inside the DLL and
</p>
<p class="CODEetc" style="color: #008000;margin-left: 50px;">&#160;// get a handle to it
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;PLC =
MyServer.CreatePLC();
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;&#160;...
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;
</p>
<p class="CODEetc" style="color: #008000;margin-left: 50px;">&#160;// link your callback function for a custom action
</p>
<p class="CODEetc" style="color: #008000;margin-left: 50px;">&#160;// to the action dispatcher, so that the callback function
</p>
<p class="CODEetc" style="color: #008000;margin-left: 50px;">&#160;// is called automatically if a cutsom action arrives
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;ActionDispatcher-&gt;OnCustomAction = this-&gt;MyCustomActionHandler;
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;
</p>
<p class="CODEetc" style="color: #008000;margin-left: 50px;">&#160;// register a callback function for notifications,
</p>
<p class="CODEetc" style="color: #008000;margin-left: 50px;">&#160;// events and actions (this callback function dispatches
</p>
<p class="CODEetc" style="color: #008000;margin-left: 50px;">&#160;// all received actions with the help of the
</p>
<p class="CODEetc" style="color: #008000;margin-left: 50px;">&#160;// GSCActionDispatcher)
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;PLC-&gt;OpenPushCallback(...);
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;...
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;<span style="color: #008000;">// destroy PLC object
</span> <![CDATA[ ]]></p>
<p class="CODEetc" style="margin-left: 50px;">&#160;PLC-&gt;Destroy();
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;...
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;<span style="color: #008000;">// destroy server object</span> <![CDATA[ ]]></p>
<p class="CODEetc" style="margin-left: 50px;">&#160;MyServer-&gt;Destroy();
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="color: #008000;margin-left: 25px;">&#160;// callback function for all notifications, events and
</p>
<p class="CODEetc" style="color: #008000;margin-left: 25px;">&#160;// subscribed actions:
</p>
<p class="CODEetc" style="margin-left: 25px;">&#160;
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;...
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;
</p>
<p class="CODEetc" style="color: #008000;margin-left: 50px;">&#160;// dispatch the received action to the linked
</p>
<p class="CODEetc" style="color: #008000;margin-left: 50px;">&#160;// callback functions
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;ActionDispatcher-&gt;Dispatch(ActionHandle);
</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;</p>
<p class="CODEetc" style="margin-left: 50px;">&#160;...
</p>
<p>&#160;
&#160;
</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>&#160;</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>&#160;</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>&#160;</p>
<p>There is a similar difficulty with events,
digital inputs and outputs. Events dont have global numbers. Here the event
name should be used instead.
</p>
<p>&#160;
</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>&#160;
</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>&#160;</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>&#160;</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>&#160;</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>&#160;
</p>
</body>
</html>