@camstack/addon-pipeline-orchestrator 1.2.263 → 1.2.265
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/_stub.js +2 -2
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-GwChQ1tx.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-DcObJv8j.mjs} +2 -2
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-4LsLRtwM.mjs +26 -0
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-BM06SN3k.mjs +26 -0
- package/dist/{hostInit-CO8YQvNz.mjs → hostInit-veHYbLfI.mjs} +2 -2
- package/dist/index.js +249 -43
- package/dist/index.mjs +249 -43
- package/dist/remoteEntry.js +1 -1
- package/package.json +1 -1
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-ChLAIKue.mjs +0 -26
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-tzKjeTfv.mjs +0 -26
package/dist/index.js
CHANGED
|
@@ -8036,7 +8036,59 @@ function errMsg$1(err) {
|
|
|
8036
8036
|
return String(err);
|
|
8037
8037
|
}
|
|
8038
8038
|
//#endregion
|
|
8039
|
-
//#region ../types/dist/composition-
|
|
8039
|
+
//#region ../types/dist/composition-Dq42XWp0.mjs
|
|
8040
|
+
/**
|
|
8041
|
+
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
8042
|
+
*
|
|
8043
|
+
* ## Why a download, on every node, including the container
|
|
8044
|
+
*
|
|
8045
|
+
* The version of ffmpeg used to be CODE: baked into the image, changeable only
|
|
8046
|
+
* by rebuilding and rolling it. Now it is DATA — this file states the release,
|
|
8047
|
+
* and a node that boots with a different one downloads it. Changing ffmpeg is a
|
|
8048
|
+
* framework bump, not an image rebuild.
|
|
8049
|
+
*
|
|
8050
|
+
* It also settles the licence question by removing it. FFmpeg's licence is
|
|
8051
|
+
* chosen at compile time: the core is LGPL 2.1+, `--enable-gpl` makes it GPL
|
|
8052
|
+
* (for x264/x265), `--enable-version3` makes that v3, and `--enable-nonfree`
|
|
8053
|
+
* makes the result undistributable. These are GPL v3 builds, and we do not
|
|
8054
|
+
* distribute them: the user's own node fetches the archive from the project
|
|
8055
|
+
* that publishes it, so we convey no GPL work and inherit none of the
|
|
8056
|
+
* obligations that come with conveying one. That is the whole reason the image
|
|
8057
|
+
* no longer installs ffmpeg at all — not a technical preference.
|
|
8058
|
+
*
|
|
8059
|
+
* ## Why jellyfin-ffmpeg
|
|
8060
|
+
*
|
|
8061
|
+
* One vendor covering linux-amd64, linux-arm64, darwin-arm64 and darwin-x64
|
|
8062
|
+
* from one release, with the widest hardware surface of anything maintained:
|
|
8063
|
+
* VAAPI, QSV, NVENC/NVDEC, AMF, Vulkan, OpenCL and DRM on amd64, plus Rockchip
|
|
8064
|
+
* MPP on arm64. It reaches the vendor libraries through dlopen trampolines,
|
|
8065
|
+
* so the binary is not linked against a driver stack it may not find.
|
|
8066
|
+
*
|
|
8067
|
+
* **What it still needs from the host, measured 2026-09-19.** On the Unraid
|
|
8068
|
+
* HOST, which has no libva, `-vaapi_device` aborts the process outright —
|
|
8069
|
+
* `implib-gen: libva-drm.so.2: failed to load library ... Assertion '0 &&
|
|
8070
|
+
* "Assertion in generated code"' failed`. Inside our container, which installs
|
|
8071
|
+
* libva plus the iHD driver, the same command encodes: verified end to end with
|
|
8072
|
+
* `testsrc → format=nv12,hwupload → h264_vaapi`. So the image drops ffmpeg and
|
|
8073
|
+
* KEEPS the Intel media stack; the drivers are the part a binary cannot bring.
|
|
8074
|
+
*
|
|
8075
|
+
* ## Why each artifact carries a checksum and a claim
|
|
8076
|
+
*
|
|
8077
|
+
* The download is now the only source, so `sha256` is verified before anything
|
|
8078
|
+
* is extracted — jellyfin publishes no checksums on its release assets, so
|
|
8079
|
+
* these are ours, taken at the version bump. And `expectedHwaccels` is what the
|
|
8080
|
+
* build is supposed to be able to do: a binary that probes short of its own
|
|
8081
|
+
* claim is a source that changed under us, which is precisely what went
|
|
8082
|
+
* unnoticed for months when a static build turned out to carry no VAAPI at all
|
|
8083
|
+
* (D536).
|
|
8084
|
+
*/
|
|
8085
|
+
/** The pinned jellyfin-ffmpeg release. Changing this is the version change. */
|
|
8086
|
+
var FFMPEG_RELEASE = "8.1.2-5";
|
|
8087
|
+
var BASE = `https://github.com/jellyfin/jellyfin-ffmpeg/releases/download/v${FFMPEG_RELEASE}`;
|
|
8088
|
+
function portable(target) {
|
|
8089
|
+
return `${BASE}/jellyfin-ffmpeg_${FFMPEG_RELEASE}_portable_${target}-gpl.tar.xz`;
|
|
8090
|
+
}
|
|
8091
|
+
portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac64");
|
|
8040
8092
|
/**
|
|
8041
8093
|
* LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
|
|
8042
8094
|
* valutatore puro del suo FRONTE.
|
|
@@ -14076,6 +14128,70 @@ var CompositionBlockStateSchema = object({
|
|
|
14076
14128
|
reason: string().optional(),
|
|
14077
14129
|
fields: array(CompositionFieldStateSchema)
|
|
14078
14130
|
});
|
|
14131
|
+
var NUMBER = {
|
|
14132
|
+
kind: "fixed",
|
|
14133
|
+
result: ["number"]
|
|
14134
|
+
};
|
|
14135
|
+
var BOOLEAN = {
|
|
14136
|
+
kind: "fixed",
|
|
14137
|
+
result: ["boolean"]
|
|
14138
|
+
};
|
|
14139
|
+
Object.freeze({
|
|
14140
|
+
min: NUMBER,
|
|
14141
|
+
max: NUMBER,
|
|
14142
|
+
abs: NUMBER,
|
|
14143
|
+
floor: NUMBER,
|
|
14144
|
+
ceil: NUMBER,
|
|
14145
|
+
sqrt: NUMBER,
|
|
14146
|
+
round: NUMBER,
|
|
14147
|
+
pow: NUMBER,
|
|
14148
|
+
clamp: NUMBER,
|
|
14149
|
+
avg: NUMBER,
|
|
14150
|
+
sum: NUMBER,
|
|
14151
|
+
age: NUMBER,
|
|
14152
|
+
convert: NUMBER,
|
|
14153
|
+
coalesce: { kind: "coalesce" },
|
|
14154
|
+
any: BOOLEAN,
|
|
14155
|
+
all: BOOLEAN,
|
|
14156
|
+
within: BOOLEAN,
|
|
14157
|
+
latest: {
|
|
14158
|
+
kind: "fixed",
|
|
14159
|
+
result: ["number", "null"]
|
|
14160
|
+
},
|
|
14161
|
+
number: {
|
|
14162
|
+
kind: "fixed",
|
|
14163
|
+
result: ["number", "null"]
|
|
14164
|
+
},
|
|
14165
|
+
rose: {
|
|
14166
|
+
kind: "fixed",
|
|
14167
|
+
result: ["number", "null"]
|
|
14168
|
+
},
|
|
14169
|
+
count: NUMBER
|
|
14170
|
+
});
|
|
14171
|
+
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
14172
|
+
/**
|
|
14173
|
+
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
14174
|
+
* device of that type, or an existing one that lacks them, can be given. The
|
|
14175
|
+
* blockers are the validator's own refusal codes, and a spec compares this
|
|
14176
|
+
* listing with `planComposition` for every capability — the editor can never
|
|
14177
|
+
* offer a feature the save would refuse for the same reason.
|
|
14178
|
+
*/
|
|
14179
|
+
var ComposableFieldSchema = object({
|
|
14180
|
+
path: string(),
|
|
14181
|
+
kind: CompositionFieldKindSchema,
|
|
14182
|
+
nullable: boolean(),
|
|
14183
|
+
required: boolean(),
|
|
14184
|
+
enumValues: array(string()).optional()
|
|
14185
|
+
});
|
|
14186
|
+
var ComposableCapabilitiesSchema = object({ caps: array(object({
|
|
14187
|
+
cap: string(),
|
|
14188
|
+
fields: array(ComposableFieldSchema),
|
|
14189
|
+
/** Present for an item-array cap (`consumables.items`). */
|
|
14190
|
+
itemArray: object({
|
|
14191
|
+
path: string(),
|
|
14192
|
+
keyField: string()
|
|
14193
|
+
}).optional()
|
|
14194
|
+
})) });
|
|
14079
14195
|
/** Where a block runs. The operator chooses — a block driving a device on an
|
|
14080
14196
|
* agent is the reason placement is not fixed to the hub. */
|
|
14081
14197
|
var CoreBlockPlacementSchema = union([literal("hub"), string().min(1)]);
|
|
@@ -14240,7 +14356,7 @@ method(object({}), object({ blocks: array(CoreBlockSchema) }), { auth: "admin" }
|
|
|
14240
14356
|
}), method(object({ blockId: string() }), CompositionGetReadSchema, { auth: "admin" }), method(object({}), CompositionListReadSchema, { auth: "admin" }), method(object({
|
|
14241
14357
|
addonId: string().min(1),
|
|
14242
14358
|
stableId: string().min(1)
|
|
14243
|
-
}), CompositionCustomizationReadSchema, { auth: "admin" }), method(object({
|
|
14359
|
+
}), CompositionCustomizationReadSchema, { auth: "admin" }), method(object({ deviceType: _enum(DeviceType) }), ComposableCapabilitiesSchema, { auth: "admin" }), method(object({
|
|
14244
14360
|
composition: CompositionSchema,
|
|
14245
14361
|
blockId: string().optional()
|
|
14246
14362
|
}), CompositionValidationSchema, {
|
|
@@ -22180,6 +22296,21 @@ var ObjectEventSchema = object({
|
|
|
22180
22296
|
keyFrameMediaId: number().int().optional(),
|
|
22181
22297
|
/** Populated by B5 (recording playback URL for this event). */
|
|
22182
22298
|
mediaUrl: string().optional(),
|
|
22299
|
+
/**
|
|
22300
|
+
* When the change this row records HAPPENED, epoch ms, when that is earlier
|
|
22301
|
+
* than {@link timestamp} and the producer could date it (D684).
|
|
22302
|
+
*
|
|
22303
|
+
* Set on a package PICK-UP row only: its `timestamp` is when the departure
|
|
22304
|
+
* was CONCLUDED — five minutes of unseen observed time after the parcel went
|
|
22305
|
+
* — and a notification's footage has to be cut around the pick-up, not the
|
|
22306
|
+
* empty doormat after it (D682). Stored so every path that rebuilds a
|
|
22307
|
+
* notification subject from the row (the boot reconcile, a dry-run) anchors
|
|
22308
|
+
* on the same instant the live hook did.
|
|
22309
|
+
*
|
|
22310
|
+
* `timestamp` keeps its meaning. Absent on every other row and on every
|
|
22311
|
+
* pick-up written before D684 — UNKNOWN, never 0 and never `timestamp`.
|
|
22312
|
+
*/
|
|
22313
|
+
observedAt: number().optional(),
|
|
22183
22314
|
/** The parent track's key-event importance [0,1], propagated to every object
|
|
22184
22315
|
* event of the track (so an event row can be sorted by importance without a
|
|
22185
22316
|
* track join). Absent on legacy rows / before the track was scored. */
|
|
@@ -25683,6 +25814,16 @@ var NodeInferenceDevicesSchema = object({
|
|
|
25683
25814
|
* Strictly the control plane: never sees a frame, never calls inference,
|
|
25684
25815
|
* never drains queues. The runner does that work locally on each agent.
|
|
25685
25816
|
*/
|
|
25817
|
+
/**
|
|
25818
|
+
* The input of `setCameraSensors` (G5, D676): the ONE typed write path of a
|
|
25819
|
+
* camera's attached sensors (D672). `config: null` removes the attachment —
|
|
25820
|
+
* the camera reads `not-configured` again, never `unreadable`.
|
|
25821
|
+
*/
|
|
25822
|
+
var SetCameraSensorsInputSchema = object({
|
|
25823
|
+
deviceId: number().int().nonnegative(),
|
|
25824
|
+
/** `null` removes the attachment: the camera goes back to `not-configured`. */
|
|
25825
|
+
config: CameraSensorsConfigSchema.nullable()
|
|
25826
|
+
});
|
|
25686
25827
|
var pipelineOrchestratorCapability = {
|
|
25687
25828
|
name: "pipeline-orchestrator",
|
|
25688
25829
|
scope: "system",
|
|
@@ -26148,6 +26289,18 @@ var pipelineOrchestratorCapability = {
|
|
|
26148
26289
|
*/
|
|
26149
26290
|
getCameraStatuses: method(object({ deviceIds: array(number()).optional() }), array(CameraStatusSchema).readonly()),
|
|
26150
26291
|
/**
|
|
26292
|
+
* Attach sensors to a camera, or detach them with `config: null` (D672
|
|
26293
|
+
* configuration, G5/D676). Written to the orchestrator's per-device store
|
|
26294
|
+
* under the same key `applyDeviceSettingsPatch` writes, and announced as a
|
|
26295
|
+
* settings change so the camera-sensors bridge refreshes. Refused by name
|
|
26296
|
+
* — nothing written — for a device that cannot be read, does not exist,
|
|
26297
|
+
* is not a camera, or names itself as its own sensor.
|
|
26298
|
+
*/
|
|
26299
|
+
setCameraSensors: method(SetCameraSensorsInputSchema, object({ success: literal(true) }), {
|
|
26300
|
+
kind: "mutation",
|
|
26301
|
+
auth: "admin"
|
|
26302
|
+
}),
|
|
26303
|
+
/**
|
|
26151
26304
|
* Disk-wins fleet reconcile after a recordings wipe. Starts the walk in
|
|
26152
26305
|
* the addon process and returns immediately with the job snapshot — the
|
|
26153
26306
|
* work outlives the tRPC/UDS 60s timeout. Poll `getReconcileFromDiskStatus`.
|
|
@@ -37177,47 +37330,6 @@ var zoneRulesCapability = {
|
|
|
37177
37330
|
*/
|
|
37178
37331
|
durability: "restored"
|
|
37179
37332
|
};
|
|
37180
|
-
var NUMBER = {
|
|
37181
|
-
kind: "fixed",
|
|
37182
|
-
result: ["number"]
|
|
37183
|
-
};
|
|
37184
|
-
var BOOLEAN = {
|
|
37185
|
-
kind: "fixed",
|
|
37186
|
-
result: ["boolean"]
|
|
37187
|
-
};
|
|
37188
|
-
Object.freeze({
|
|
37189
|
-
min: NUMBER,
|
|
37190
|
-
max: NUMBER,
|
|
37191
|
-
abs: NUMBER,
|
|
37192
|
-
floor: NUMBER,
|
|
37193
|
-
ceil: NUMBER,
|
|
37194
|
-
sqrt: NUMBER,
|
|
37195
|
-
round: NUMBER,
|
|
37196
|
-
pow: NUMBER,
|
|
37197
|
-
clamp: NUMBER,
|
|
37198
|
-
avg: NUMBER,
|
|
37199
|
-
sum: NUMBER,
|
|
37200
|
-
age: NUMBER,
|
|
37201
|
-
convert: NUMBER,
|
|
37202
|
-
coalesce: { kind: "coalesce" },
|
|
37203
|
-
any: BOOLEAN,
|
|
37204
|
-
all: BOOLEAN,
|
|
37205
|
-
within: BOOLEAN,
|
|
37206
|
-
latest: {
|
|
37207
|
-
kind: "fixed",
|
|
37208
|
-
result: ["number", "null"]
|
|
37209
|
-
},
|
|
37210
|
-
number: {
|
|
37211
|
-
kind: "fixed",
|
|
37212
|
-
result: ["number", "null"]
|
|
37213
|
-
},
|
|
37214
|
-
rose: {
|
|
37215
|
-
kind: "fixed",
|
|
37216
|
-
result: ["number", "null"]
|
|
37217
|
-
},
|
|
37218
|
-
count: NUMBER
|
|
37219
|
-
});
|
|
37220
|
-
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
37221
37333
|
/**
|
|
37222
37334
|
* Accessory device helpers — shared across drivers.
|
|
37223
37335
|
*
|
|
@@ -39668,6 +39780,12 @@ Object.freeze({
|
|
|
39668
39780
|
addonId: null,
|
|
39669
39781
|
access: "view"
|
|
39670
39782
|
},
|
|
39783
|
+
"coreBlocks.listComposableCaps": {
|
|
39784
|
+
capName: "core-blocks",
|
|
39785
|
+
capScope: "system",
|
|
39786
|
+
addonId: null,
|
|
39787
|
+
access: "view"
|
|
39788
|
+
},
|
|
39671
39789
|
"coreBlocks.listCompositions": {
|
|
39672
39790
|
capName: "core-blocks",
|
|
39673
39791
|
capScope: "system",
|
|
@@ -43352,6 +43470,12 @@ Object.freeze({
|
|
|
43352
43470
|
addonId: null,
|
|
43353
43471
|
access: "create"
|
|
43354
43472
|
},
|
|
43473
|
+
"pipelineOrchestrator.setCameraSensors": {
|
|
43474
|
+
capName: "pipeline-orchestrator",
|
|
43475
|
+
capScope: "system",
|
|
43476
|
+
addonId: null,
|
|
43477
|
+
access: "create"
|
|
43478
|
+
},
|
|
43355
43479
|
"pipelineOrchestrator.setCameraStepOverride": {
|
|
43356
43480
|
capName: "pipeline-orchestrator",
|
|
43357
43481
|
capScope: "system",
|
|
@@ -47062,6 +47186,11 @@ Object.freeze({
|
|
|
47062
47186
|
form: "single",
|
|
47063
47187
|
optional: false
|
|
47064
47188
|
}],
|
|
47189
|
+
"pipelineOrchestrator.setCameraSensors": [{
|
|
47190
|
+
name: "deviceId",
|
|
47191
|
+
form: "single",
|
|
47192
|
+
optional: false
|
|
47193
|
+
}],
|
|
47065
47194
|
"pipelineOrchestrator.setCameraStepOverride": [{
|
|
47066
47195
|
name: "deviceId",
|
|
47067
47196
|
form: "single",
|
|
@@ -49683,6 +49812,52 @@ var AudioSubscriptionController = class {
|
|
|
49683
49812
|
}
|
|
49684
49813
|
};
|
|
49685
49814
|
//#endregion
|
|
49815
|
+
//#region src/camera-sensors/write.ts
|
|
49816
|
+
/**
|
|
49817
|
+
* The ONE typed write path of a camera's attached sensors (D672 config,
|
|
49818
|
+
* G5/D676) — `pipelineOrchestrator.setCameraSensors`.
|
|
49819
|
+
*
|
|
49820
|
+
* The input is already validated by the cap schema at the router. Here it is
|
|
49821
|
+
* refused BY NAME, and logged with the device tag, before anything is written
|
|
49822
|
+
* (D391): a device that could not be read (a failed read changes nothing,
|
|
49823
|
+
* D49), an unknown device, a non-camera, a camera named as its own sensor.
|
|
49824
|
+
* The value is then handed to `writeDeviceStore` under the CS-1 key, which the
|
|
49825
|
+
* addon binds to `applyDeviceSettingsPatch` — so the D672 patch gate, the
|
|
49826
|
+
* PARSED value, the store and the settings-updated event that refreshes the
|
|
49827
|
+
* bridge's resolver are ONE path, never a copy of it. `null` clears: the
|
|
49828
|
+
* device store keeps a null key, and `parseCameraSensorsSetting` reads it as
|
|
49829
|
+
* not-configured.
|
|
49830
|
+
*/
|
|
49831
|
+
function refuse(deps, deviceId, reason) {
|
|
49832
|
+
deps.logger.warn("camera sensors write refused", {
|
|
49833
|
+
tags: { deviceId },
|
|
49834
|
+
meta: { reason }
|
|
49835
|
+
});
|
|
49836
|
+
throw new Error(`pipeline-orchestrator: camera sensors of ${deviceId} not saved — ${reason}`);
|
|
49837
|
+
}
|
|
49838
|
+
async function readOrRefuse(deps, deviceId) {
|
|
49839
|
+
let device;
|
|
49840
|
+
try {
|
|
49841
|
+
device = await deps.readDevice(deviceId);
|
|
49842
|
+
} catch (err) {
|
|
49843
|
+
return refuse(deps, deviceId, `could not read device ${deviceId}: ${errMsg$1(err)}`);
|
|
49844
|
+
}
|
|
49845
|
+
if (device === null) return refuse(deps, deviceId, `no device ${deviceId}`);
|
|
49846
|
+
return device;
|
|
49847
|
+
}
|
|
49848
|
+
async function writeCameraSensors(deps, input) {
|
|
49849
|
+
const { deviceId, config } = input;
|
|
49850
|
+
const device = await readOrRefuse(deps, deviceId);
|
|
49851
|
+
if (device.type !== DeviceType.Camera) return refuse(deps, deviceId, `device ${deviceId} is not a camera`);
|
|
49852
|
+
if (config !== null && config.sensors.some((s) => s.addonId === device.addonId && s.stableId === device.stableId)) return refuse(deps, deviceId, "a camera cannot be its own sensor");
|
|
49853
|
+
await deps.writeDeviceStore(deviceId, { [CAMERA_SENSORS_SETTINGS_KEY]: config });
|
|
49854
|
+
deps.logger.info("camera sensors saved", {
|
|
49855
|
+
tags: { deviceId },
|
|
49856
|
+
meta: { sensors: config === null ? 0 : config.sensors.length }
|
|
49857
|
+
});
|
|
49858
|
+
return { success: true };
|
|
49859
|
+
}
|
|
49860
|
+
//#endregion
|
|
49686
49861
|
//#region src/disk-reconcile-fleet.ts
|
|
49687
49862
|
async function reconcileFleetFromDisk(deps) {
|
|
49688
49863
|
const deviceIds = await deps.listDeviceIds();
|
|
@@ -66200,6 +66375,37 @@ var PipelineOrchestratorAddon = class PipelineOrchestratorAddon extends BaseAddo
|
|
|
66200
66375
|
return this.deviceConfig.applyDeviceSettingsPatch(input);
|
|
66201
66376
|
}
|
|
66202
66377
|
/**
|
|
66378
|
+
* The one typed write path of a camera's attached sensors (G5, D676) — see
|
|
66379
|
+
* `camera-sensors/write.ts`. Its refusals run first; the store write then
|
|
66380
|
+
* goes THROUGH `applyDeviceSettingsPatch`, so the D672 patch gate, the
|
|
66381
|
+
* parsed value, the key and the `OrchestrationSettingsUpdated` event are the
|
|
66382
|
+
* one path a camera configured through the device page already takes.
|
|
66383
|
+
*/
|
|
66384
|
+
async setCameraSensors(input) {
|
|
66385
|
+
const ctx = this.ctx;
|
|
66386
|
+
const deviceConfig = this.deviceConfig;
|
|
66387
|
+
if (deviceConfig === null) throw new Error("pipeline-orchestrator: not initialised — camera sensors not saved");
|
|
66388
|
+
const api = ctx.api;
|
|
66389
|
+
return writeCameraSensors({
|
|
66390
|
+
readDevice: async (deviceId) => {
|
|
66391
|
+
if (!api) throw new Error("the device registry is not reachable");
|
|
66392
|
+
const dev = await api.deviceManager.getDevice.query({ deviceId });
|
|
66393
|
+
return dev === null || dev === void 0 ? null : {
|
|
66394
|
+
type: dev.type,
|
|
66395
|
+
addonId: dev.addonId,
|
|
66396
|
+
stableId: dev.stableId
|
|
66397
|
+
};
|
|
66398
|
+
},
|
|
66399
|
+
writeDeviceStore: async (deviceId, patch) => {
|
|
66400
|
+
await deviceConfig.applyDeviceSettingsPatch({
|
|
66401
|
+
deviceId,
|
|
66402
|
+
patch
|
|
66403
|
+
});
|
|
66404
|
+
},
|
|
66405
|
+
logger: ctx.logger.child("camera-sensors")
|
|
66406
|
+
}, input);
|
|
66407
|
+
}
|
|
66408
|
+
/**
|
|
66203
66409
|
* Apply the subset of global settings that affect runtime behaviour
|
|
66204
66410
|
* (balancer thresholds, broker timeout, failover policy) into the
|
|
66205
66411
|
* in-memory state so subsequent `balance()` / `handleNodeDisconnect`
|