![]() |
AXEvent
|
This is the main include file to be used for all applications that want to use the AXEvent library. More...
Go to the source code of this file.
This is the main include file to be used for all applications that want to use the AXEvent library.
The axevent library provides an interface to the event system found in Axis devices.
The purpose of the AXEvents library is to provide applications with a mechanism for sending and receiving events. There are two different roles an application can assume when interacting with the event system.
An application may assume one or both roles simultaneously.
The axevent library is designed to be used with the GLib library. An application using the axevent library must have a running GMainLoop.
As in event system, event producers declare and send events while event event consumers subscribe to and consume events. The axevent library provides a loose coupling between producers and consumers. This loose coupling allows producers to send events that no one is subscribing to and allows consumers to subscribe to events that no producer has declared or is sending. Of course it would be pointless for a consumer to subscribe to an event that can never be sent, but it may well be interesting to subscribe to an event that may be sent in the future depending on whether a specific product feature is switched on or of. Eg. an event consumer may want to subscribe to motion detection events and is free to do so even when motion detection isn't enabled. When motion detection is enabled, any motion detection event sent will automatically be delivered to the consumer without the consumer having to reinitialize its subscription.
The axevent library operates on three different aspects of events
An event is an instance of an event declaration (see below) and may not contain any unset values. Events with unset values are invalid and are undeliverable. The event's type must be declared before the producer can send the event, see Event declarations below. An undeclared event is undeliverable. Each event contains a AXEventKeyValueSet key/value set and a settable timestamp. The key/value set describes the keys and values that constitute the event. The timestamp will be interpreted by the consumer as the time at which the event occured.
All events are expressed as a set of key/value pairs, where the key should be assigned to a namespace. For example, the event describing that the first I/O port is active is described by the following key/value pairs.
tns1:topic0=Device
tnsaxis:topic1=IO
tnsaxis:topic2=Port
port=0
state=1
Where
The general form of a key/value pair can be described as
[name space:]<key>=<value>
The namespace's primary purpose is to avoid name clashes but is also used to distinguish between events declared by different vendors. Each vendor should define their own namespace. In the I/O port example, the namespace tns1 is defined by Onvif and tnxaxis is defined by Axis. The keys "port" and "state" are not assigned to a namespace.
Events are managed by the AXEvents type and its associated functions located in ax_event.h.
An event declaration specifies the AXEventKeyValueSet key/value set that contains all the keys that constitute the event. The axevent library provides two kinds of events:
Stateless events are events that do not have any persistent state. A stateless event is similar to a signal or a pulse; it has no state and exists only when it is sent. A stateless event can for example be "a point crossed a line".
When declaring a stateless event, the producer must specify all keys that consitute the event. If a key has a fixed value, the value must be specified. If a key has variable values, the value should be set to NULL in the declaration.
The example in the link below shows how to declare a stateless event with the following key/value set
tnsaxis:topic0=CameraApplicationPlatform
tnsaxis:topic1=MyApplication
event=* <-- "event" key has a variable value
ax_event_stateless_declaration_example.c
Property states, or stateful events, are events that have a persistent state. The event is always in one of its states. A property state can for example be the state of an I/O port: active or inactive.
When declaring a property state, the producer must specify all keys that consitute the event. If a key has a fixed value, the value must be specified. If a key has variable values, the value in the declaration should be set to the initial value.
The example in the link below shows hos to declare a property state with the following key/value set
tnsaxis:topic0=CameraApplicationPaltform
tnsaxis:topic1=MyApplication
feature=myfeature
enabled=* <-- "enabled" key has a variable value
ax_event_property_state_declaration_example.c
Event declarations describing events that can be emitted from different sources should contain a source key. The source key is used to identify the source. In the I/O event example above, source key is the port key.
All event declarations should contain a data key that describe the state of the source emitting the event. In the I/O event example above, the data key is the state key.
The source key can be omitted, for example if source information is of no use for the consumer. The data key can also be omitted, although most event will have data of some kind. See ax_event_handler_declare_event for a detailed description about how to declare an event.
N.b. from AXIS OS 12.0, templates for events are deprecated and are planned for removal.
An event declaration template is an XML representation of the declaration's key/value set. The template is then referenced when declaring a new event.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFromDefault="qualified" attributeFormDefault="unqualified">
<xs:complexType name="KeyType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="NameSpace" type="xs:string" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:simpleType name="StringType">
<xs:restriction base="xs:string" />
</xs:simpleType>
<xs:simpleType name="DoubleType">
<xs:restriction base="xs:double" />
</xs:simpleType>
<xs:simpleType name="BooleanType">
<xs:restriction base="xs:boolean" />
</xs:simpleType>
<xs:simpleType name="IntegerType">
<xs:restriction base="xs:int" />
</xs:simpleType>
<xs:complexType name="ItemType">
<xs:sequence>
<xs:element name="Key" type="KeyType" />
<xs:choice maxOccurs="1">
<xs:element name="Integer" type="IntegerType" />
<xs:element name="Double" type="DoubleType" />
<xs:element name="Boolean" type="BooleanType" />
<xs:element name="String" type="StringType" />
</xs:choice>
<xs:element name="Tag" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="DeclarationType">
<xs:sequence>
<xs:element name="Item" type="ItemType" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:element name="Declaration" type="DeclarationType">
<xs:annotation>
<xs:documentation>Comment describing your root element</xs:documentation>
</xs:annotation>
</xs:element>
</xs:schema>
The next example lists a template that could be used to declare the same event as declared in:ax_event_stateless_declaration_example.c
<Declaration>
<Item>
<Key NameSpace="tnsaxis">topic0</Key>
<String>CameraApplicationPlatform</String>
</Item>
<Item>
<Key NameSpace="tnsaxis">topic1</Key>
<String>MyApplication</String>
</Item>
<Item>
<Key>event</Key>
<Boolean />
<Tag>onvif-data</Tag>
</Item>
</Declaration>
See this example for how to use the template to declare the event
ax_event_stateless_declaration_from_template_example.c
The next example lists a template that could be used to declare the same event as declared in:
ax_event_property_state_declaration_example.c
<Declaration>
<Item>
<Key NameSpace="tnsaxis">topic0</Key>
<String>CameraApplicationPlatform</String>
</Item>
<Item>
<Key NameSpace="tnsaxis">topic1</Key>
<String>MyApplication</String>
</Item>
<Item>
<Key>feature</Key>
<String>myfeature</String>
</Item>
<Item>
<Key>event</Key>
<Boolean />
<Tag>onvif-data</Tag>
<Tag>property-state</Tag>
</Item>
</Declaration>
See this example for how to use the template to declare the event:
ax_event_property_state_declaration_from_template_example.c
When an event declaration is no longer needed it should be undeclared.
An application can subscribe to a single event or to a set of events. In both cases, the application should create a AXEventKeyValueSet key/value set that matches the desired subscription.
To subscribe to a single event, for example to the I/O event above, the application should create a AXEventKeyValueSet key/value set that matches all the keys and values in the event.
tns1:topic0=Device
tnsaxis:topic1=IO
tnsaxis:topic2=Port
port=0
state=1
An application subscribing to this key/value set will receive an event each time the value of the key state equals 1 on I/O port 0.
To subscribe to a set of events, the application should create a AXEventKeyValueSet key/value set where some keys, values or event namesspaces are omitted. ax_event_key_value_set_example1.c ax_event_key_value_set_example2.c
tns1:topic0=Device tnsaxis:topic1=IO tnsaxis:topic2=Port
An application subscribing to the key/value set above will receive events from all I/O ports whenever their respective states change.
Subscriptions to stateless events and to property states are created in the same way but there is a difference in how the events are delivered to the subscription callback. As stateless events only exist when they are sent, a subscription callback associated with a stateless event will not be called until the event is sent. A subscription callback associated with a property state, which always has a well-defined state, will be called immediately after the subscription so that the subscriber always has the current state of the event. Each time the property state is updated, a new call will be performed.
If an application subscribes to an event that is not yet declared, the associated subscription callback will not be called until a producer declares the event.
The following example shows how to subscribe to an event:
ax_event_subscription_example.c
The callback functions registered with the AXEventHandler will be called from the GMainLoop thread in the default context. This means that the client may not prevent callback functions from returning, nor should any lengthy processing be made in the callback functions. Failure to comply with this convention will prevent the event system from, or delay it in, sending or delivering any more events to the calling application.