UNPKG

camstreamerlib

Version:

Helper library for CamStreamer ACAP applications.

120 lines (119 loc) 4.64 kB
import { z } from 'zod'; import { responseStringify, pad } from '../internal/utils'; const ACTION = 'AddCameraBookmark'; const GET_CAMERAS_URL = 'report/EntityConfiguration?q=EntityTypes@Camera'; const GET_CAMERAS_DETAILS_URL = '/entity?q='; const cameraGuidsResponseSchema = z.object({ Rsp: z.object({ Status: z.string(), Result: z.array(z.object({ Guid: z.string() })), }), }); const connectionResponseSchema = z.object({ Rsp: z.object({ Status: z.string(), }), }); export const cameraDetailSchema = z.object({ Guid: z.string().optional(), Name: z.string().optional(), EntityType: z.string().optional(), }); export const cameraDetailsResponseSchema = z.object({ Rsp: z.object({ Status: z.string(), Result: z.union([z.array(cameraDetailSchema), cameraDetailSchema]), }), }); export class GenetecAgent { settings; baseUrl; credentials; constructor(options = {}) { this.settings = { protocol: options.protocol ?? 'http', ip: options.ip ?? '127.0.0.1', port: options.port ?? 80, base_uri: options.base_uri ?? 'WebSdk', user: options.user ?? 'root', pass: options.pass ?? '', app_id: options.app_id ?? '', }; this.baseUrl = `${this.settings.protocol}://${this.settings.ip}:${this.settings.port}/${this.settings.base_uri}`; this.credentials = btoa(`${this.settings.user};${this.settings.app_id}:${this.settings.pass}`); } async checkConnection() { const requestOptions = this.getRequestOptions('GET'); const res = await fetch(`${this.baseUrl}/`, requestOptions); if (!res.ok) { throw new Error(await responseStringify(res)); } return connectionResponseSchema.parse(await res.json()); } async getAllCameraGuids() { const requestOptions = this.getRequestOptions('GET'); const res = await fetch(`${this.baseUrl}/${GET_CAMERAS_URL}`, requestOptions); if (!res.ok) { throw new Error(await responseStringify(res)); } return cameraGuidsResponseSchema.parse(await res.json()); } async getCameraDetails(guids, parameters) { const params = parameters.join(','); let camerasGuids = []; const requestOptions = this.getRequestOptions('GET'); const allCameras = []; const chunkSize = 10; while (guids.length > 0) { const chunk = guids.slice(0, chunkSize); guids.splice(0, chunkSize); camerasGuids = chunk.map((item) => item.Guid); const camerasDetailsUrl = []; for (const guid of camerasGuids) { camerasDetailsUrl.push(`entity=${guid},${params}`); } const res = await fetch(`${this.baseUrl}/${GET_CAMERAS_DETAILS_URL}${camerasDetailsUrl.join(',')}`, requestOptions); if (!res.ok) { throw new Error(await responseStringify(res)); } const data = cameraDetailsResponseSchema.parse(await res.json()); const resultArray = Array.isArray(data.Rsp.Result) ? data.Rsp.Result : [data.Rsp.Result]; allCameras.push(...resultArray); } return allCameras; } async sendBookmark(guids, bookmarkText) { const cameraEntitiesUrl = []; const timeStamp = this.getTimeStamp(); const requestOptions = this.getRequestOptions('POST'); for (const guid of guids) { cameraEntitiesUrl.push(`${ACTION}(${guid},${timeStamp},${bookmarkText})`); } const res = await fetch(`${this.baseUrl}/action?q=${cameraEntitiesUrl.join(',')}`, requestOptions); if (!res.ok) { throw new Error(await responseStringify(res)); } return res; } getRequestOptions(method) { return { method, headers: new Headers({ Authorization: `Basic ${this.credentials}`, Accept: 'text/json', }), redirect: 'follow', }; } getTimeStamp() { const date = new Date(); const year = date.getUTCFullYear(); const month = pad(date.getUTCMonth() + 1, 2); const day = pad(date.getUTCDate(), 2); const hours = pad(date.getUTCHours(), 2); const minutes = pad(date.getUTCMinutes(), 2); const seconds = pad(date.getUTCSeconds(), 2); const miliSeconds = pad(date.getUTCMilliseconds(), 2); return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.${miliSeconds}Z`; } }