UNPKG

ts-onvif

Version:

Client to ONVIF devices

240 lines (239 loc) 10.6 kB
/** * Events ver10 module * @author Andrew D.Laptev <a.d.laptev@gmail.com> * @see https://www.onvif.org/specs/core/ONVIF-Core-Specification.pdf * @see https://www.onvif.org/ver10/events/wsdl/event.wsdl */ import { Onvif } from './onvif'; import { AddEventBroker, Capabilities, CreatePullPointSubscription, DeleteEventBroker, EventBrokerConfig, GetEventBrokers, GetEventPropertiesResponse, PullMessages } from './interfaces/event'; import { CommonDuration } from './utils'; import { AnyURI } from './interfaces/basics'; import { ItemList } from './interfaces/onvif'; import { EventEmitter } from 'events'; import { Agent as HttpsAgent } from 'https'; import { Agent as HttpAgent } from 'http'; interface TerminationTimeResponse { currentTime: Date; terminationTime: Date; } /** ONVIF topic expression dialects from WS-Topics and [event.wsdl](https://www.onvif.org/ver10/events/wsdl/event.wsdl). */ export type TopicExpressionDialect = 'http://www.onvif.org/ver10/tev/topicExpression/ConcreteSet' | 'http://docs.oasis-open.org/wsn/t-1/TopicExpression/Concrete' | 'http://docs.oasis-open.org/wsn/t-1/TopicExpression/Full' | 'http://docs.oasis-open.org/wsn/t-1/TopicExpression/Simple'; /** * Popular ONVIF topic expressions (`tns1` = `http://www.onvif.org/ver10/topics`). * Subtree patterns ending with `//.` are defined in ONVIF Core 9.6.3. */ export type OnvifTopicExpression = 'tns1:RuleEngine/CellMotionDetector/Motion' | 'tns1:RuleEngine/LineDetector/Crossed' | 'tns1:RuleEngine/FieldDetector/ObjectsInside' | 'tns1:RuleEngine/TamperDetector/Tamper' | 'tns1:RuleEngine/LineDetector//.' | 'tns1:RuleEngine/FieldDetector//.' | 'tns1:RuleEngine//.' | 'tns1:VideoSource/MotionAlarm' | 'tns1:VideoSource/GlobalSceneChange' | 'tns1:VideoSource/ImageTooDark/ImagingService' | 'tns1:VideoSource/ImageTooBright/ImagingService' | 'tns1:VideoSource/ImageTooBlurry/ImagingService' | 'tns1:VideoSource/ImageTooNoisy/ImagingService' | 'tns1:VideoAnalytics//.' | 'tns1:VideoAnalytics/tnsanalytics:CellMotionDetector' | 'tns1:Device/Trigger/DigitalInput' | 'tns1:Device/Trigger/Relay' | 'tns1:Device/HardwareFailure/StorageFailure' | 'tns1:Device/HardwareFailure/FanFailure' | 'tns1:Device/HardwareFailure/PowerSupplyFailure' | 'tns1:Device/HardwareFailure/TemperatureCritical' | 'tns1:Monitoring/ProcessorUsage' | 'tns1:Monitoring/OperatingTime/LastReset' | 'tns1:Monitoring/OperatingTime/LastReboot' | 'tns1:Monitoring/OperatingTime/LastClockSynchronization' | 'tns1:RecordingConfig/RecordingJobState' | 'tns1:RecordingConfig/TrackConfiguration' | 'tns1:Media/ConfigurationChanged' | 'tns1:Media/ProfileChanged' /** Vendor-specific topics, e.g. `tns1:RuleEngine/MyRuleDetector/FaceDetect` */ | 'tns1:RuleEngine/PeopleDetector/People' | (string & {}); export interface TopicExpression { dialect: TopicExpressionDialect; expression: OnvifTopicExpression; } export interface PullPointSubscriptionFilter { topicExpression?: TopicExpression[]; /** XPath for message content filtering (ItemFilter dialect). */ messageContent?: string; } export interface CreatePullPointSubscriptionExtended extends Omit<CreatePullPointSubscription, 'filter' | 'initialTerminationTime'> { filter?: PullPointSubscriptionFilter; /** Initial termination time. */ initialTerminationTime?: CommonDuration; } export interface PullMessagesResponse { /** The date and time when the messages have been delivered by the web server to the client. */ currentTime: Date; /** Date time when the PullPoint will be shut down without further pull requests. */ terminationTime: Date; /** List of messages. This list shall be empty in case of a timeout. */ notificationMessage: NotificationMessage[]; } export interface NotificationMessage { topic: Topic; subscriptionReference?: { address?: any; }; producerReference?: { address?: any; }; message: { message: EventMessage; }; } export interface Topic { _: OnvifTopicExpression; dialect?: TopicExpressionDialect; } export interface EventMessage { utcTime: Date; propertyOperation?: PropertyOperation; source?: ItemList; key?: ItemList; data?: ItemList; } export type PropertyOperation = 'Initialized' | 'Changed' | 'Deleted'; export interface PullPointSubscription { subscriptionReference: { address: AnyURI; referenceParameters?: { subscriptionId: string; }; }; currentTime: Date; terminationTime: Date; } interface StatusResponse { currentTime: Date; terminationTime: Date; } interface SubscribeOptions { /** URL of the event service */ url: string; /** Subscription duration in milliseconds */ terminationTime?: CommonDuration; /** Renew subscription after the termination time */ renew?: boolean; /** Filter */ filter?: PullPointSubscriptionFilter; } /** * Events service */ export default class Events { private readonly onvif; agent: HttpsAgent | HttpAgent; globalSubscription: Subscription; constructor(onvif: Onvif); private createAgent; /** * Drop in-flight PullMessages sockets (long-poll up to PULL_TIMEOUT) so unsubscribe * does not leave Happytime / cameras stuck with an open request. */ resetAgent(): void; /** * The WS-BaseNotification specification defines a set of OPTIONAL WS-ResouceProperties. This specification does not * require the implementation of the WS-ResourceProperty interface. Instead, the subsequent direct interface shall be * implemented by an ONVIF compliant device in order to provide information about the FilterDialects, Schema files * and topics supported by the device. */ getEventProperties(): Promise<GetEventPropertiesResponse>; getServiceCapabilities(): Promise<Capabilities>; static filterToBuild(filter?: PullPointSubscriptionFilter): Record<string, unknown> | undefined; /** * This method returns a PullPointSubscription that can be polled using PullMessages. This message contains the same * elements as the SubscriptionRequest of the WS-BaseNotification without the ConsumerReference. * If no Filter is specified the pullpoint notifies all occurring events to the client. * This method is mandatory. */ createPullPointSubscription(options?: CreatePullPointSubscriptionExtended): Promise<PullPointSubscription>; private static eventBrokerToBuild; addEventBroker({ eventBroker }: AddEventBroker): Promise<void>; deleteEventBroker({ address }: DeleteEventBroker): Promise<void>; getEventBrokers({ address }?: GetEventBrokers): Promise<EventBrokerConfig[]>; /** * Subscribe to events using WS-BaseNotification producer * @param options */ subscribe(options: SubscribeOptions): Promise<PullPointSubscription>; /** * Unsubscribe from WS-BaseNotification push events */ unsubscribe(subscription: PullPointSubscription): Promise<void>; /** * Renew for WS-BaseNotification push event * @param subscription * @param terminationTime time in milliseconds */ renew(subscription: PullPointSubscription, terminationTime: CommonDuration): Promise<StatusResponse>; /** * Get status for WS-BaseNotification push events */ getStatus(subscription: PullPointSubscription): Promise<StatusResponse>; } interface SubscriptionEvents { data: [msg: NotificationMessage]; error: [error: NodeJS.ErrnoException]; connectionError: [error: NodeJS.ErrnoException]; } /** * Subscription to events class * @event data - emitted when event is received * @event error - emitted when error occurs * @example * ```ts * const sub = new Subscription(cam, 'pullPoint', { * filter: { * topicExpression: [ * { * expression: 'tns1:RuleEngine/PeopleDetector/People', * dialect: 'http://www.onvif.org/ver10/tev/topicExpression/ConcreteSet', * }, * ], * }, * }); * sub.on('data', console.log); * await sub.subscribe(); * ``` */ export declare class Subscription extends EventEmitter<SubscriptionEvents> { private readonly onvif; subscription?: PullPointSubscription; private readonly messageLimit; eventReconnectMs: number; private readonly options; /** * Event received from subscription * @event * @param msg Notification message */ data: (msg: NotificationMessage) => void; /** * Any subscription error * @event * @param error Error object */ error: (error: NodeJS.ErrnoException) => void; connectionError: (error: NodeJS.ErrnoException) => void; constructor(onvif: Onvif, options?: CreatePullPointSubscriptionExtended); /** When false, in-flight pull loops must not renew or auto-resubscribe. */ private pulling; subscribe(): Promise<void>; /** * Loop events from the subscription */ eventPull(): Promise<void>; /** * Pull messages from the subscription * @param options */ pullMessages(options?: PullMessages): Promise<PullMessagesResponse>; /** * Properties inform a client about property creation, changes and deletion in a uniform way. When a client wants to * synchronize its properties with the properties of the device, it can request a synchronization point which repeats * the current status of all properties to which a client has subscribed. The PropertyOperation of all produced * notifications is set to “Initialized”. The Synchronization Point is requested directly from the SubscriptionManager * which was returned in either the SubscriptionResponse or in the CreatePullPointSubscriptionResponse. The property * update is transmitted via the notification transportation of the notification interface. This method is mandatory. */ setSynchronizationPoint(): Promise<void>; /** * Renew the subscription */ renew(): Promise<TerminationTimeResponse>; /** * The device shall provide the following Unsubscribe command for all SubscriptionManager endpoints returned * by the CreatePullPointSubscription command. * This command shall terminate the lifetime of a pull point. */ unsubscribe(): Promise<void>; /** * Restart the event request with an increasing interval when the connection to the device is refused * @private */ private restartEventRequest; /** * Get params for concrete subscription * @private */ private getSubscriptionUrlAndHeaders; } export {};