Generic Events
Introduction
If you have a software package or a hardware device, from now on called a unit, which is capable of sending packages via IP, you may configure the XProtect Generic Events feature to analyze such packets and trigger events based on criteria you define. If you do not have such a unit, you may want to write a new program or a new function in your existing application, which sends generic events to XProtect. This paper is an introduction how to accomplish either of these tasks.
You will always need to instruct the XProtect server what to do when data arrives. You do that by defining types of generic events in the management client application. Each type has an expression string. When the expression has a match on the arriving data, the event type is triggered. If you define a rule for the event in the Rules section, this triggering will cause an action, exactly as with user-defined events.
Interfacing to XProtect
If you have the option of writing new software to send generic events, you should write code which sends a string of ASCII characters per event to TCP port 1234, then closes the TCP session. Code to do this needs not be complex, the MIP SDK contains a sample named TriggerGenericEvent. It all boils down to something like:
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(IPAddress.Parse(hostname), 1234);
byte[] bytes = Encoding.ASCII.GetBytes("RecordCamera1");
socket.Send(bytes, bytes.length, 0);
socket.Close();
To process streaming data, turn to the "International" data source, which is listening at TCP port 1235.
This data source provides a useful echo to your application. Below is non-compilable pseudo code which sends 10 events to the server separated by pairs of carriage return and linefeed ("\r\n"). You could now receive the answers, testing if the third number in each answer is N>0 then you know there was a match on the N generic events types listed after the number N.
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(IPAddress.Parse(hostname), 1235);
byte[] rb = new byte[256];
byte[] bytes;
for (int i = 1; i < 11; i++) {
bytes = Encoding.UTF8.GetBytes(string.Format("RecordCamera{0}\r\n", i));
socket.Send(bytes, bytes.length, 0);
}
The host address shall be the address of the XProtect event server.
Configuring XProtect to interface to existing hard- or software
Above, we assumed that it's possible for you to modify existing code or write new. In many cases, that probably isn't the case. You have an existing unit which you really can't influence how works. But you can create a new data source which matches how your unit sends data.
In the XProtect Management Client's Tools > Options dialog, select the Generic Events tab. Create a new data source and give it a name so you know it belongs with your unit. Select IP version 4 or 6, and select TCP or UDP as appropriate. Enter the IP port number which your unit sends data to. Consult the maker of your unit if you need information to make these choices. If the data from your unit will arrive from a computer with another IP address than the XProtect event server, add this IP address to the list of allowed IPv4 or IPv6 addresses. Now click OK.
You may monitor the data received by the generic events feature if you download the free tool, Sysinternals DebugView. You should run this tool with administrator rights on the event server computer. Select the option Capture Global Win32, and in the Edit menu you should set the filter to MiGV*. You should now see a log like:
12:04:46 [8016] MiGV: Connect from 10.10.16.193
12:04:46 [8016] MiGV: Local connection. Always allowed.
12:04:46 [8016] MiGV: 47 International. Session started.
12:04:46 [8016] Please RecordCamera1 that would be nice: MiGV: 47 International:
12:04:46 [8016] MiGV:*47 International. Match on RecordCamera1 (1)
12:05:08 [8016] MiGV: Echoed: 5,39,1,RecCam1
12:05:33 [8016] MiGV: 47 International. Session ended.
If you did not make contact, you should reinvestigate the IP port number and the choices of UDP/TCP and IPv4/IPv6. You should also double-check if a firewall is preventing the connection. Wireshark is an excellent, easy to use, and free tool to monitor your network traffic.
Configuring data sources
In principle, the stream of bytes you receive may be endless. You must instruct XProtect how
to cut the stream into records. You do that by defining a sequence of one or more bytes.
Whenever that sequence of bytes is detected, the bytes before it are processed as a record to
see if there are any matches. The default separator sequence is 13,10
: a
"carriage return" (ASCII decimal 13) followed immediately by a "line feed" (ASCII decimal 10).
Consult the maker of your unit and ask what they are using to separate records and enter that
choice in the field Separator bytes.
The record separator bytes should arrive with intervals of no less than 16K bytes. After 16K bytes without separator bytes, the record is processed as if there were a set of separator bytes. The same is true if you close the TCP session without a final set of separator bytes. If you have not defined any separator bytes, that is, if the input field Separator bytes is left blank, the session will be shut down and the record will be processed when 1024 bytes have arrived. This is to be compatible with the older implementation.
The record received consists of 8 bit bytes. The generic events feature searches for matches on strings of characters. When turning bytes into characters an encoding is applied. If the encoding used by your unit to send the bytes is different from the encoding defined with your data source, characters other than A-z and 0-9 may appear to be wrong. You should consult the maker of the unit and choose the appropriate encoding based on that advice.
Matching events with records
Each generic event type defines an expression and an expression type. The expression is a string and the type can be either of Search, Match or Regular expression. The expression type defines how it is decided whether the expression matches the record. Please note that there might be a delay of 20-60 seconds before a newly created generic event is actually known by the event server.
Search and Match
In the two older modes you enter an expression like "John" AND ("Smith" OR
"Jones")
. In Search mode, that will give match on Hello, John
Smith I presume
. In Match mode there will be no match here, you will
have to reduce the record to contain only John Smith
. This is rather simple to
understand, but gives you limited possibilities. You need not use the AND-OR operators and the
parentheses, a single operand like "door23"
may do, but there must always be
double quotes around every operand in your expression.
Regular expression
Regular expressions give you almost unlimited expressions, at the cost of requiring more from you. We will not teach regular expressions here, only give you a glimpse of what they can do for you. To lean more, you may Google the subject, there are millions of articles. If you already entered an AND-OR expression, you may now shift to regular expressions using the combo box. The expression you entered will automatically convert to the corresponding regular expression.
The simplest regular expression is the bare operand, like door23
without quotes
of any kind. That works like "door23"
in Search mode and will match for example
please close door23
. From Match mode, "door23"
would be converted to
^door23$
as a regular expression, which will only match door23
with no
characters before or after it.
You could make that case insensitive using |
as or-operator:
^(D|d)(O|o)(O|o)(R|r)23$
.
If you want an expression which triggers the event no matter which number the door has, you
could use door[0-9]+
. [0-9]
means any single digit, +
means 1 or more instances of such a digit. There will be a match if any of door1, door12,
door319
are present somewhere in the record, but door
only without any numbers
after it would not give a match.
Wikipedia has an excellent introduction to regular expressions.
Priority
You may assign an individual priority to each type of generic event you define. When a record is processed, it is matched against all generic event types which belong to the data source which received the record. The events with the highest priorities (lowest numbers) are tested for match first. When there is a match on an event type with a given priority, event types with lower priorities are ignored until the next record is processed