@camstack/addon-provider-amcrest 0.2.113 → 0.2.115
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/addon.js +125 -1
- package/dist/addon.mjs +125 -1
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -5367,7 +5367,7 @@ var ZodIssueCode = {
|
|
|
5367
5367
|
var ZodFirstPartyTypeKind;
|
|
5368
5368
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5369
5369
|
//#endregion
|
|
5370
|
-
//#region ../types/dist/sleep-
|
|
5370
|
+
//#region ../types/dist/sleep-Dk-BdnBf.mjs
|
|
5371
5371
|
/**
|
|
5372
5372
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5373
5373
|
* window to float samples (D455).
|
|
@@ -31222,6 +31222,26 @@ var PtzHomePresetSchema = object({
|
|
|
31222
31222
|
"none"
|
|
31223
31223
|
])
|
|
31224
31224
|
});
|
|
31225
|
+
/**
|
|
31226
|
+
* The camera's own idle-return behaviour: whether it goes home by itself, and
|
|
31227
|
+
* after how long.
|
|
31228
|
+
*
|
|
31229
|
+
* ONE shape, not two scalars, because on the camera they are ONE fact —
|
|
31230
|
+
* Reolink's guard point carries `benable` and `timeout` in the same element,
|
|
31231
|
+
* written by the same command. Reading them apart means two round-trips that
|
|
31232
|
+
* can disagree.
|
|
31233
|
+
*
|
|
31234
|
+
* `enabled` and `seconds` are INDEPENDENT: a camera can hold a 68 s delay with
|
|
31235
|
+
* the behaviour switched off, which is exactly what the vendor app leaves when
|
|
31236
|
+
* you turn the guard point off without clearing it. The first version of this
|
|
31237
|
+
* cap reported only the delay, so that state was invisible — a camera could be
|
|
31238
|
+
* configured to return after 68 seconds with no way to say whether it should
|
|
31239
|
+
* return at all.
|
|
31240
|
+
*/
|
|
31241
|
+
var PtzHomeReturnSchema = object({
|
|
31242
|
+
enabled: boolean(),
|
|
31243
|
+
seconds: number().int()
|
|
31244
|
+
});
|
|
31225
31245
|
var ptzCapability = {
|
|
31226
31246
|
name: "ptz",
|
|
31227
31247
|
scope: "device",
|
|
@@ -31281,6 +31301,54 @@ var ptzCapability = {
|
|
|
31281
31301
|
auth: "admin"
|
|
31282
31302
|
}),
|
|
31283
31303
|
/**
|
|
31304
|
+
* Make WHERE THE HEAD IS POINTING RIGHT NOW this camera's home.
|
|
31305
|
+
*
|
|
31306
|
+
* `setHomePreset` takes a preset id, and a preset id is the wrong shape for
|
|
31307
|
+
* the most natural thing an operator does: aim the camera, then say "here".
|
|
31308
|
+
* It is also the only shape a camera whose home is NOT a preset can accept
|
|
31309
|
+
* -- Reolink's home is a guard point, a stored position with no id at all,
|
|
31310
|
+
* and hiding the control for that case (as the UI briefly did) left the one
|
|
31311
|
+
* vendor with a native home unable to set it.
|
|
31312
|
+
*
|
|
31313
|
+
* Each provider does it its own way:
|
|
31314
|
+
* reolink `setGrd` with `needSetPos`, pinning the guard point here
|
|
31315
|
+
* hikvision / amcrest save a preset, then pin it as home
|
|
31316
|
+
* onvif REFUSES -- its home is the PTZ origin and cannot be moved
|
|
31317
|
+
*
|
|
31318
|
+
* A provider that cannot honour it throws rather than silently doing
|
|
31319
|
+
* nothing: an operator who pressed "set home here" and saw no error would
|
|
31320
|
+
* believe it took.
|
|
31321
|
+
*/
|
|
31322
|
+
captureHomeHere: method(object({ deviceId: number() }), _void(), {
|
|
31323
|
+
kind: "mutation",
|
|
31324
|
+
auth: "admin"
|
|
31325
|
+
}),
|
|
31326
|
+
/**
|
|
31327
|
+
* Whether the camera returns home on its own when left idle, and after how
|
|
31328
|
+
* long. `null` when it has no such behaviour at all.
|
|
31329
|
+
*
|
|
31330
|
+
* Reolink's guard point carries one (`timeout`, freely settable in
|
|
31331
|
+
* seconds). It is a real function of the camera that we did not expose at
|
|
31332
|
+
* all, and it belongs next to the home it governs rather than in a vendor
|
|
31333
|
+
* settings page nobody associates with Home.
|
|
31334
|
+
*/
|
|
31335
|
+
getHomeReturn: method(object({ deviceId: number() }), PtzHomeReturnSchema.nullable()),
|
|
31336
|
+
/**
|
|
31337
|
+
* Set both together. Refused by a camera with no idle-return behaviour.
|
|
31338
|
+
*
|
|
31339
|
+
* They travel together for the same reason they are read together: the
|
|
31340
|
+
* underlying write carries both, so setting one alone means reading the
|
|
31341
|
+
* other back first and racing whoever else is writing.
|
|
31342
|
+
*/
|
|
31343
|
+
setHomeReturn: method(object({
|
|
31344
|
+
deviceId: number(),
|
|
31345
|
+
enabled: boolean(),
|
|
31346
|
+
seconds: number().int().min(0).max(3600)
|
|
31347
|
+
}), _void(), {
|
|
31348
|
+
kind: "mutation",
|
|
31349
|
+
auth: "admin"
|
|
31350
|
+
}),
|
|
31351
|
+
/**
|
|
31284
31352
|
* Pull the current PTZ position. Redundant with the auto-injected
|
|
31285
31353
|
* `getStatus` method (see `status` below); kept for callers that
|
|
31286
31354
|
* haven't migrated. Will be folded into `getStatus` in a future
|
|
@@ -40941,6 +41009,12 @@ Object.freeze({
|
|
|
40941
41009
|
addonId: null,
|
|
40942
41010
|
access: "create"
|
|
40943
41011
|
},
|
|
41012
|
+
"ptz.captureHomeHere": {
|
|
41013
|
+
capName: "ptz",
|
|
41014
|
+
capScope: "device",
|
|
41015
|
+
addonId: null,
|
|
41016
|
+
access: "create"
|
|
41017
|
+
},
|
|
40944
41018
|
"ptz.continuousMove": {
|
|
40945
41019
|
capName: "ptz",
|
|
40946
41020
|
capScope: "device",
|
|
@@ -40959,6 +41033,12 @@ Object.freeze({
|
|
|
40959
41033
|
addonId: null,
|
|
40960
41034
|
access: "view"
|
|
40961
41035
|
},
|
|
41036
|
+
"ptz.getHomeReturn": {
|
|
41037
|
+
capName: "ptz",
|
|
41038
|
+
capScope: "device",
|
|
41039
|
+
addonId: null,
|
|
41040
|
+
access: "view"
|
|
41041
|
+
},
|
|
40962
41042
|
"ptz.getOptions": {
|
|
40963
41043
|
capName: "ptz",
|
|
40964
41044
|
capScope: "device",
|
|
@@ -41013,6 +41093,12 @@ Object.freeze({
|
|
|
41013
41093
|
addonId: null,
|
|
41014
41094
|
access: "create"
|
|
41015
41095
|
},
|
|
41096
|
+
"ptz.setHomeReturn": {
|
|
41097
|
+
capName: "ptz",
|
|
41098
|
+
capScope: "device",
|
|
41099
|
+
addonId: null,
|
|
41100
|
+
access: "create"
|
|
41101
|
+
},
|
|
41016
41102
|
"ptz.stop": {
|
|
41017
41103
|
capName: "ptz",
|
|
41018
41104
|
capScope: "device",
|
|
@@ -44176,6 +44262,11 @@ Object.freeze({
|
|
|
44176
44262
|
form: "single",
|
|
44177
44263
|
optional: false
|
|
44178
44264
|
}],
|
|
44265
|
+
"ptz.captureHomeHere": [{
|
|
44266
|
+
name: "deviceId",
|
|
44267
|
+
form: "single",
|
|
44268
|
+
optional: false
|
|
44269
|
+
}],
|
|
44179
44270
|
"ptz.continuousMove": [{
|
|
44180
44271
|
name: "deviceId",
|
|
44181
44272
|
form: "single",
|
|
@@ -44191,6 +44282,11 @@ Object.freeze({
|
|
|
44191
44282
|
form: "single",
|
|
44192
44283
|
optional: false
|
|
44193
44284
|
}],
|
|
44285
|
+
"ptz.getHomeReturn": [{
|
|
44286
|
+
name: "deviceId",
|
|
44287
|
+
form: "single",
|
|
44288
|
+
optional: false
|
|
44289
|
+
}],
|
|
44194
44290
|
"ptz.getOptions": [{
|
|
44195
44291
|
name: "deviceId",
|
|
44196
44292
|
form: "single",
|
|
@@ -44236,6 +44332,11 @@ Object.freeze({
|
|
|
44236
44332
|
form: "single",
|
|
44237
44333
|
optional: false
|
|
44238
44334
|
}],
|
|
44335
|
+
"ptz.setHomeReturn": [{
|
|
44336
|
+
name: "deviceId",
|
|
44337
|
+
form: "single",
|
|
44338
|
+
optional: false
|
|
44339
|
+
}],
|
|
44239
44340
|
"ptz.stop": [{
|
|
44240
44341
|
name: "deviceId",
|
|
44241
44342
|
form: "single",
|
|
@@ -46959,6 +47060,8 @@ var AmcrestCamera = class AmcrestCamera extends BaseDevice {
|
|
|
46959
47060
|
* granularity is reported through `getOptions` instead of being hidden
|
|
46960
47061
|
* behind a 0..1 float.
|
|
46961
47062
|
*/
|
|
47063
|
+
/** Dahua exposes 25 fixed preset slots, 1-based. */
|
|
47064
|
+
static DAHUA_MAX_PRESETS = 25;
|
|
46962
47065
|
static DAHUA_SPEED_STEPS = 8;
|
|
46963
47066
|
/**
|
|
46964
47067
|
* How long one `ptz.move` pulse runs, ms. The DENOMINATOR of "how far did
|
|
@@ -47162,6 +47265,27 @@ var AmcrestCamera = class AmcrestCamera extends BaseDevice {
|
|
|
47162
47265
|
};
|
|
47163
47266
|
return this.resolveHomePreset();
|
|
47164
47267
|
},
|
|
47268
|
+
captureHomeHere: async ({ deviceId }) => {
|
|
47269
|
+
if (deviceId !== this.id) return;
|
|
47270
|
+
const client = this.ensureClient();
|
|
47271
|
+
const ceiling = (await client.getPtzCaps(this.channel))?.maxPresets ?? AmcrestCamera.DAHUA_MAX_PRESETS;
|
|
47272
|
+
const used = new Set((await client.getPtzPresets(this.channel)).map((p) => p.id));
|
|
47273
|
+
let slot = 1;
|
|
47274
|
+
while (used.has(slot) && slot <= ceiling) slot += 1;
|
|
47275
|
+
if (slot > ceiling) throw new Error("No free preset slot on this camera to store a home position — free one first");
|
|
47276
|
+
await client.ptzSetPreset(this.channel, slot, AmcrestCamera.PTZ_CGI_TIMEOUT_MS);
|
|
47277
|
+
await this.config.setAll({ homePresetId: String(slot) });
|
|
47278
|
+
this.ctx.logger.info("amcrest: home pinned to the current position", {
|
|
47279
|
+
tags: { deviceId: this.id },
|
|
47280
|
+
meta: { presetId: slot }
|
|
47281
|
+
});
|
|
47282
|
+
},
|
|
47283
|
+
getHomeReturn: async () => {
|
|
47284
|
+
return null;
|
|
47285
|
+
},
|
|
47286
|
+
setHomeReturn: async () => {
|
|
47287
|
+
throw new Error("Amcrest: the idle-return timer is not wired on this driver");
|
|
47288
|
+
},
|
|
47165
47289
|
setHomePreset: async ({ deviceId, presetId }) => {
|
|
47166
47290
|
if (deviceId !== this.id) return;
|
|
47167
47291
|
await this.config.setAll({ homePresetId: presetId ?? "" });
|
package/dist/addon.mjs
CHANGED
|
@@ -5368,7 +5368,7 @@ var ZodIssueCode = {
|
|
|
5368
5368
|
var ZodFirstPartyTypeKind;
|
|
5369
5369
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5370
5370
|
//#endregion
|
|
5371
|
-
//#region ../types/dist/sleep-
|
|
5371
|
+
//#region ../types/dist/sleep-Dk-BdnBf.mjs
|
|
5372
5372
|
/**
|
|
5373
5373
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5374
5374
|
* window to float samples (D455).
|
|
@@ -31223,6 +31223,26 @@ var PtzHomePresetSchema = object({
|
|
|
31223
31223
|
"none"
|
|
31224
31224
|
])
|
|
31225
31225
|
});
|
|
31226
|
+
/**
|
|
31227
|
+
* The camera's own idle-return behaviour: whether it goes home by itself, and
|
|
31228
|
+
* after how long.
|
|
31229
|
+
*
|
|
31230
|
+
* ONE shape, not two scalars, because on the camera they are ONE fact —
|
|
31231
|
+
* Reolink's guard point carries `benable` and `timeout` in the same element,
|
|
31232
|
+
* written by the same command. Reading them apart means two round-trips that
|
|
31233
|
+
* can disagree.
|
|
31234
|
+
*
|
|
31235
|
+
* `enabled` and `seconds` are INDEPENDENT: a camera can hold a 68 s delay with
|
|
31236
|
+
* the behaviour switched off, which is exactly what the vendor app leaves when
|
|
31237
|
+
* you turn the guard point off without clearing it. The first version of this
|
|
31238
|
+
* cap reported only the delay, so that state was invisible — a camera could be
|
|
31239
|
+
* configured to return after 68 seconds with no way to say whether it should
|
|
31240
|
+
* return at all.
|
|
31241
|
+
*/
|
|
31242
|
+
var PtzHomeReturnSchema = object({
|
|
31243
|
+
enabled: boolean(),
|
|
31244
|
+
seconds: number().int()
|
|
31245
|
+
});
|
|
31226
31246
|
var ptzCapability = {
|
|
31227
31247
|
name: "ptz",
|
|
31228
31248
|
scope: "device",
|
|
@@ -31282,6 +31302,54 @@ var ptzCapability = {
|
|
|
31282
31302
|
auth: "admin"
|
|
31283
31303
|
}),
|
|
31284
31304
|
/**
|
|
31305
|
+
* Make WHERE THE HEAD IS POINTING RIGHT NOW this camera's home.
|
|
31306
|
+
*
|
|
31307
|
+
* `setHomePreset` takes a preset id, and a preset id is the wrong shape for
|
|
31308
|
+
* the most natural thing an operator does: aim the camera, then say "here".
|
|
31309
|
+
* It is also the only shape a camera whose home is NOT a preset can accept
|
|
31310
|
+
* -- Reolink's home is a guard point, a stored position with no id at all,
|
|
31311
|
+
* and hiding the control for that case (as the UI briefly did) left the one
|
|
31312
|
+
* vendor with a native home unable to set it.
|
|
31313
|
+
*
|
|
31314
|
+
* Each provider does it its own way:
|
|
31315
|
+
* reolink `setGrd` with `needSetPos`, pinning the guard point here
|
|
31316
|
+
* hikvision / amcrest save a preset, then pin it as home
|
|
31317
|
+
* onvif REFUSES -- its home is the PTZ origin and cannot be moved
|
|
31318
|
+
*
|
|
31319
|
+
* A provider that cannot honour it throws rather than silently doing
|
|
31320
|
+
* nothing: an operator who pressed "set home here" and saw no error would
|
|
31321
|
+
* believe it took.
|
|
31322
|
+
*/
|
|
31323
|
+
captureHomeHere: method(object({ deviceId: number() }), _void(), {
|
|
31324
|
+
kind: "mutation",
|
|
31325
|
+
auth: "admin"
|
|
31326
|
+
}),
|
|
31327
|
+
/**
|
|
31328
|
+
* Whether the camera returns home on its own when left idle, and after how
|
|
31329
|
+
* long. `null` when it has no such behaviour at all.
|
|
31330
|
+
*
|
|
31331
|
+
* Reolink's guard point carries one (`timeout`, freely settable in
|
|
31332
|
+
* seconds). It is a real function of the camera that we did not expose at
|
|
31333
|
+
* all, and it belongs next to the home it governs rather than in a vendor
|
|
31334
|
+
* settings page nobody associates with Home.
|
|
31335
|
+
*/
|
|
31336
|
+
getHomeReturn: method(object({ deviceId: number() }), PtzHomeReturnSchema.nullable()),
|
|
31337
|
+
/**
|
|
31338
|
+
* Set both together. Refused by a camera with no idle-return behaviour.
|
|
31339
|
+
*
|
|
31340
|
+
* They travel together for the same reason they are read together: the
|
|
31341
|
+
* underlying write carries both, so setting one alone means reading the
|
|
31342
|
+
* other back first and racing whoever else is writing.
|
|
31343
|
+
*/
|
|
31344
|
+
setHomeReturn: method(object({
|
|
31345
|
+
deviceId: number(),
|
|
31346
|
+
enabled: boolean(),
|
|
31347
|
+
seconds: number().int().min(0).max(3600)
|
|
31348
|
+
}), _void(), {
|
|
31349
|
+
kind: "mutation",
|
|
31350
|
+
auth: "admin"
|
|
31351
|
+
}),
|
|
31352
|
+
/**
|
|
31285
31353
|
* Pull the current PTZ position. Redundant with the auto-injected
|
|
31286
31354
|
* `getStatus` method (see `status` below); kept for callers that
|
|
31287
31355
|
* haven't migrated. Will be folded into `getStatus` in a future
|
|
@@ -40942,6 +41010,12 @@ Object.freeze({
|
|
|
40942
41010
|
addonId: null,
|
|
40943
41011
|
access: "create"
|
|
40944
41012
|
},
|
|
41013
|
+
"ptz.captureHomeHere": {
|
|
41014
|
+
capName: "ptz",
|
|
41015
|
+
capScope: "device",
|
|
41016
|
+
addonId: null,
|
|
41017
|
+
access: "create"
|
|
41018
|
+
},
|
|
40945
41019
|
"ptz.continuousMove": {
|
|
40946
41020
|
capName: "ptz",
|
|
40947
41021
|
capScope: "device",
|
|
@@ -40960,6 +41034,12 @@ Object.freeze({
|
|
|
40960
41034
|
addonId: null,
|
|
40961
41035
|
access: "view"
|
|
40962
41036
|
},
|
|
41037
|
+
"ptz.getHomeReturn": {
|
|
41038
|
+
capName: "ptz",
|
|
41039
|
+
capScope: "device",
|
|
41040
|
+
addonId: null,
|
|
41041
|
+
access: "view"
|
|
41042
|
+
},
|
|
40963
41043
|
"ptz.getOptions": {
|
|
40964
41044
|
capName: "ptz",
|
|
40965
41045
|
capScope: "device",
|
|
@@ -41014,6 +41094,12 @@ Object.freeze({
|
|
|
41014
41094
|
addonId: null,
|
|
41015
41095
|
access: "create"
|
|
41016
41096
|
},
|
|
41097
|
+
"ptz.setHomeReturn": {
|
|
41098
|
+
capName: "ptz",
|
|
41099
|
+
capScope: "device",
|
|
41100
|
+
addonId: null,
|
|
41101
|
+
access: "create"
|
|
41102
|
+
},
|
|
41017
41103
|
"ptz.stop": {
|
|
41018
41104
|
capName: "ptz",
|
|
41019
41105
|
capScope: "device",
|
|
@@ -44177,6 +44263,11 @@ Object.freeze({
|
|
|
44177
44263
|
form: "single",
|
|
44178
44264
|
optional: false
|
|
44179
44265
|
}],
|
|
44266
|
+
"ptz.captureHomeHere": [{
|
|
44267
|
+
name: "deviceId",
|
|
44268
|
+
form: "single",
|
|
44269
|
+
optional: false
|
|
44270
|
+
}],
|
|
44180
44271
|
"ptz.continuousMove": [{
|
|
44181
44272
|
name: "deviceId",
|
|
44182
44273
|
form: "single",
|
|
@@ -44192,6 +44283,11 @@ Object.freeze({
|
|
|
44192
44283
|
form: "single",
|
|
44193
44284
|
optional: false
|
|
44194
44285
|
}],
|
|
44286
|
+
"ptz.getHomeReturn": [{
|
|
44287
|
+
name: "deviceId",
|
|
44288
|
+
form: "single",
|
|
44289
|
+
optional: false
|
|
44290
|
+
}],
|
|
44195
44291
|
"ptz.getOptions": [{
|
|
44196
44292
|
name: "deviceId",
|
|
44197
44293
|
form: "single",
|
|
@@ -44237,6 +44333,11 @@ Object.freeze({
|
|
|
44237
44333
|
form: "single",
|
|
44238
44334
|
optional: false
|
|
44239
44335
|
}],
|
|
44336
|
+
"ptz.setHomeReturn": [{
|
|
44337
|
+
name: "deviceId",
|
|
44338
|
+
form: "single",
|
|
44339
|
+
optional: false
|
|
44340
|
+
}],
|
|
44240
44341
|
"ptz.stop": [{
|
|
44241
44342
|
name: "deviceId",
|
|
44242
44343
|
form: "single",
|
|
@@ -46960,6 +47061,8 @@ var AmcrestCamera = class AmcrestCamera extends BaseDevice {
|
|
|
46960
47061
|
* granularity is reported through `getOptions` instead of being hidden
|
|
46961
47062
|
* behind a 0..1 float.
|
|
46962
47063
|
*/
|
|
47064
|
+
/** Dahua exposes 25 fixed preset slots, 1-based. */
|
|
47065
|
+
static DAHUA_MAX_PRESETS = 25;
|
|
46963
47066
|
static DAHUA_SPEED_STEPS = 8;
|
|
46964
47067
|
/**
|
|
46965
47068
|
* How long one `ptz.move` pulse runs, ms. The DENOMINATOR of "how far did
|
|
@@ -47163,6 +47266,27 @@ var AmcrestCamera = class AmcrestCamera extends BaseDevice {
|
|
|
47163
47266
|
};
|
|
47164
47267
|
return this.resolveHomePreset();
|
|
47165
47268
|
},
|
|
47269
|
+
captureHomeHere: async ({ deviceId }) => {
|
|
47270
|
+
if (deviceId !== this.id) return;
|
|
47271
|
+
const client = this.ensureClient();
|
|
47272
|
+
const ceiling = (await client.getPtzCaps(this.channel))?.maxPresets ?? AmcrestCamera.DAHUA_MAX_PRESETS;
|
|
47273
|
+
const used = new Set((await client.getPtzPresets(this.channel)).map((p) => p.id));
|
|
47274
|
+
let slot = 1;
|
|
47275
|
+
while (used.has(slot) && slot <= ceiling) slot += 1;
|
|
47276
|
+
if (slot > ceiling) throw new Error("No free preset slot on this camera to store a home position — free one first");
|
|
47277
|
+
await client.ptzSetPreset(this.channel, slot, AmcrestCamera.PTZ_CGI_TIMEOUT_MS);
|
|
47278
|
+
await this.config.setAll({ homePresetId: String(slot) });
|
|
47279
|
+
this.ctx.logger.info("amcrest: home pinned to the current position", {
|
|
47280
|
+
tags: { deviceId: this.id },
|
|
47281
|
+
meta: { presetId: slot }
|
|
47282
|
+
});
|
|
47283
|
+
},
|
|
47284
|
+
getHomeReturn: async () => {
|
|
47285
|
+
return null;
|
|
47286
|
+
},
|
|
47287
|
+
setHomeReturn: async () => {
|
|
47288
|
+
throw new Error("Amcrest: the idle-return timer is not wired on this driver");
|
|
47289
|
+
},
|
|
47166
47290
|
setHomePreset: async ({ deviceId, presetId }) => {
|
|
47167
47291
|
if (deviceId !== this.id) return;
|
|
47168
47292
|
await this.config.setAll({ homePresetId: presetId ?? "" });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-provider-amcrest",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.115",
|
|
4
4
|
"description": "Amcrest/Dahua camera device provider addon for CamStack — Dahua CGI over HTTP(S) with digest auth (snapshot, RTSP catalog, PTZ, image/day-night config)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|