@camstack/types 1.2.148 → 1.2.149

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.
@@ -11,6 +11,7 @@ import { DeviceType } from '../device/device-type.js';
11
11
  export declare const BatteryStatusSchema: z.ZodObject<{
12
12
  percentage: z.ZodNullable<z.ZodNumber>;
13
13
  charging: z.ZodEnum<{
14
+ unknown: "unknown";
14
15
  none: "none";
15
16
  dc: "dc";
16
17
  solar: "solar";
@@ -65,6 +66,7 @@ export declare const batteryCapability: {
65
66
  status: z.ZodObject<{
66
67
  percentage: z.ZodNullable<z.ZodNumber>;
67
68
  charging: z.ZodEnum<{
69
+ unknown: "unknown";
68
70
  none: "none";
69
71
  dc: "dc";
70
72
  solar: "solar";
@@ -81,6 +83,7 @@ export declare const batteryCapability: {
81
83
  readonly schema: z.ZodObject<{
82
84
  percentage: z.ZodNullable<z.ZodNumber>;
83
85
  charging: z.ZodEnum<{
86
+ unknown: "unknown";
84
87
  none: "none";
85
88
  dc: "dc";
86
89
  solar: "solar";
@@ -93,7 +96,7 @@ export declare const batteryCapability: {
93
96
  readonly kind: "push";
94
97
  readonly empty: {
95
98
  readonly percentage: 0;
96
- readonly charging: "none";
99
+ readonly charging: "unknown";
97
100
  readonly sleeping: false;
98
101
  readonly lastUpdated: 0;
99
102
  };
@@ -110,6 +113,7 @@ export declare const batteryCapability: {
110
113
  readonly runtimeState: z.ZodObject<{
111
114
  percentage: z.ZodNullable<z.ZodNumber>;
112
115
  charging: z.ZodEnum<{
116
+ unknown: "unknown";
113
117
  none: "none";
114
118
  dc: "dc";
115
119
  solar: "solar";
@@ -1250,6 +1250,7 @@ export declare const pipelineOrchestratorCapability: {
1250
1250
  "no-provider": "no-provider";
1251
1251
  "source-unreachable": "source-unreachable";
1252
1252
  "not-configured": "not-configured";
1253
+ "device-disabled": "device-disabled";
1253
1254
  }>>;
1254
1255
  enabled: z.ZodBoolean;
1255
1256
  authority: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -1323,6 +1324,7 @@ export declare const pipelineOrchestratorCapability: {
1323
1324
  "no-provider": "no-provider";
1324
1325
  "source-unreachable": "source-unreachable";
1325
1326
  "not-configured": "not-configured";
1327
+ "device-disabled": "device-disabled";
1326
1328
  }>>;
1327
1329
  enabled: z.ZodBoolean;
1328
1330
  authority: z.ZodDiscriminatedUnion<[z.ZodObject<{
package/dist/index.js CHANGED
@@ -887,7 +887,8 @@ var CameraSwitchAuthoritySchema = zod.z.discriminatedUnion("kind", [
887
887
  var CameraSwitchUnavailableReasonSchema = zod.z.enum([
888
888
  "no-provider",
889
889
  "source-unreachable",
890
- "not-configured"
890
+ "not-configured",
891
+ "device-disabled"
891
892
  ]);
892
893
  /**
893
894
  * One switch, resolved for one camera.
@@ -1057,7 +1058,7 @@ function resolveState(descriptor, input) {
1057
1058
  if (audio === null) return {
1058
1059
  available: false,
1059
1060
  enabled: true,
1060
- unavailableReason: "source-unreachable"
1061
+ unavailableReason: input.deviceDisabled ? "device-disabled" : "source-unreachable"
1061
1062
  };
1062
1063
  if (!audio.supported) return {
1063
1064
  available: false,
@@ -1079,7 +1080,7 @@ function resolveState(descriptor, input) {
1079
1080
  if (mask === null) return {
1080
1081
  available: false,
1081
1082
  enabled: false,
1082
- unavailableReason: "source-unreachable"
1083
+ unavailableReason: input.deviceDisabled ? "device-disabled" : "source-unreachable"
1083
1084
  };
1084
1085
  if (!mask.supported) return {
1085
1086
  available: false,
@@ -25382,12 +25383,20 @@ var BatteryStatusSchema = zod.z.object({
25382
25383
  * Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
25383
25384
  * Reolink-specific for the Solar Panel 2 accessory (will become
25384
25385
  * common on other battery cams). `'none'` means running on battery
25385
- * alone.
25386
+ * alone — a NEGATIVE the firmware actually reported.
25387
+ *
25388
+ * `'unknown'` is the absence of an answer: the provider has not read the
25389
+ * power fields yet, or the firmware reported neither. Before it existed,
25390
+ * two unreadable fields produced `'none'`, and a camera nobody had reached
25391
+ * was drawn "on battery alone" — the same D315 defect `percentage` closed
25392
+ * by going nullable. Consumers SKIP it (no charger state published, no
25393
+ * glyph, no HomeKit ChargingState) rather than coerce it either way.
25386
25394
  */
25387
25395
  charging: zod.z.enum([
25388
25396
  "dc",
25389
25397
  "solar",
25390
- "none"
25398
+ "none",
25399
+ "unknown"
25391
25400
  ]),
25392
25401
  /**
25393
25402
  * True when the camera firmware has gone into low-power mode. Battery
@@ -25477,7 +25486,7 @@ onStatusChanged: { data: zod.z.object({
25477
25486
  kind: "push",
25478
25487
  empty: {
25479
25488
  percentage: 0,
25480
- charging: "none",
25489
+ charging: "unknown",
25481
25490
  sleeping: false,
25482
25491
  lastUpdated: 0
25483
25492
  }
@@ -37010,8 +37019,17 @@ var BaseDeviceProvider = class extends require_sleep.BaseAddon {
37010
37019
  async onRestoreDevices(savedDevices) {
37011
37020
  const restored = /* @__PURE__ */ new Set();
37012
37021
  const failures = [];
37022
+ const liveStableIds = new Set((await this.ctx.kernel.devices.getAll()).map((device) => device.stableId));
37013
37023
  const attemptRestore = async (saved) => {
37014
37024
  if (restored.has(saved.id)) return;
37025
+ if (liveStableIds.has(saved.stableId)) {
37026
+ this.ctx.logger.debug("Restore row already live — not dialled again", { tags: {
37027
+ deviceId: saved.id,
37028
+ stableId: saved.stableId
37029
+ } });
37030
+ restored.add(saved.id);
37031
+ return;
37032
+ }
37015
37033
  const Class = this.deviceClasses[saved.type];
37016
37034
  if (!Class) throw new Error(`no device class registered for type "${saved.type}"`);
37017
37035
  if (saved.parentDeviceId !== null && !restored.has(saved.parentDeviceId)) throw new Error(`parent device ${saved.parentDeviceId} not restored`);
package/dist/index.mjs CHANGED
@@ -886,7 +886,8 @@ var CameraSwitchAuthoritySchema = z.discriminatedUnion("kind", [
886
886
  var CameraSwitchUnavailableReasonSchema = z.enum([
887
887
  "no-provider",
888
888
  "source-unreachable",
889
- "not-configured"
889
+ "not-configured",
890
+ "device-disabled"
890
891
  ]);
891
892
  /**
892
893
  * One switch, resolved for one camera.
@@ -1056,7 +1057,7 @@ function resolveState(descriptor, input) {
1056
1057
  if (audio === null) return {
1057
1058
  available: false,
1058
1059
  enabled: true,
1059
- unavailableReason: "source-unreachable"
1060
+ unavailableReason: input.deviceDisabled ? "device-disabled" : "source-unreachable"
1060
1061
  };
1061
1062
  if (!audio.supported) return {
1062
1063
  available: false,
@@ -1078,7 +1079,7 @@ function resolveState(descriptor, input) {
1078
1079
  if (mask === null) return {
1079
1080
  available: false,
1080
1081
  enabled: false,
1081
- unavailableReason: "source-unreachable"
1082
+ unavailableReason: input.deviceDisabled ? "device-disabled" : "source-unreachable"
1082
1083
  };
1083
1084
  if (!mask.supported) return {
1084
1085
  available: false,
@@ -25381,12 +25382,20 @@ var BatteryStatusSchema = z.object({
25381
25382
  * Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
25382
25383
  * Reolink-specific for the Solar Panel 2 accessory (will become
25383
25384
  * common on other battery cams). `'none'` means running on battery
25384
- * alone.
25385
+ * alone — a NEGATIVE the firmware actually reported.
25386
+ *
25387
+ * `'unknown'` is the absence of an answer: the provider has not read the
25388
+ * power fields yet, or the firmware reported neither. Before it existed,
25389
+ * two unreadable fields produced `'none'`, and a camera nobody had reached
25390
+ * was drawn "on battery alone" — the same D315 defect `percentage` closed
25391
+ * by going nullable. Consumers SKIP it (no charger state published, no
25392
+ * glyph, no HomeKit ChargingState) rather than coerce it either way.
25385
25393
  */
25386
25394
  charging: z.enum([
25387
25395
  "dc",
25388
25396
  "solar",
25389
- "none"
25397
+ "none",
25398
+ "unknown"
25390
25399
  ]),
25391
25400
  /**
25392
25401
  * True when the camera firmware has gone into low-power mode. Battery
@@ -25476,7 +25485,7 @@ onStatusChanged: { data: z.object({
25476
25485
  kind: "push",
25477
25486
  empty: {
25478
25487
  percentage: 0,
25479
- charging: "none",
25488
+ charging: "unknown",
25480
25489
  sleeping: false,
25481
25490
  lastUpdated: 0
25482
25491
  }
@@ -37002,8 +37011,17 @@ var BaseDeviceProvider = class extends BaseAddon {
37002
37011
  async onRestoreDevices(savedDevices) {
37003
37012
  const restored = /* @__PURE__ */ new Set();
37004
37013
  const failures = [];
37014
+ const liveStableIds = new Set((await this.ctx.kernel.devices.getAll()).map((device) => device.stableId));
37005
37015
  const attemptRestore = async (saved) => {
37006
37016
  if (restored.has(saved.id)) return;
37017
+ if (liveStableIds.has(saved.stableId)) {
37018
+ this.ctx.logger.debug("Restore row already live — not dialled again", { tags: {
37019
+ deviceId: saved.id,
37020
+ stableId: saved.stableId
37021
+ } });
37022
+ restored.add(saved.id);
37023
+ return;
37024
+ }
37007
37025
  const Class = this.deviceClasses[saved.type];
37008
37026
  if (!Class) throw new Error(`no device class registered for type "${saved.type}"`);
37009
37027
  if (saved.parentDeviceId !== null && !restored.has(saved.parentDeviceId)) throw new Error(`parent device ${saved.parentDeviceId} not restored`);
@@ -173,6 +173,7 @@ export declare const CameraSwitchUnavailableReasonSchema: z.ZodEnum<{
173
173
  "no-provider": "no-provider";
174
174
  "source-unreachable": "source-unreachable";
175
175
  "not-configured": "not-configured";
176
+ "device-disabled": "device-disabled";
176
177
  }>;
177
178
  export type CameraSwitchUnavailableReason = z.infer<typeof CameraSwitchUnavailableReasonSchema>;
178
179
  /**
@@ -201,6 +202,7 @@ export declare const CameraSwitchSchema: z.ZodObject<{
201
202
  "no-provider": "no-provider";
202
203
  "source-unreachable": "source-unreachable";
203
204
  "not-configured": "not-configured";
205
+ "device-disabled": "device-disabled";
204
206
  }>>;
205
207
  enabled: z.ZodBoolean;
206
208
  authority: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -244,6 +246,7 @@ export declare const CameraSwitchGroupSchema: z.ZodObject<{
244
246
  "no-provider": "no-provider";
245
247
  "source-unreachable": "source-unreachable";
246
248
  "not-configured": "not-configured";
249
+ "device-disabled": "device-disabled";
247
250
  }>>;
248
251
  enabled: z.ZodBoolean;
249
252
  authority: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -1095,7 +1095,8 @@ export interface EventCatalog {
1095
1095
  readonly status: {
1096
1096
  /** `null` = NOT YET KNOWN. See `BatteryStatusSchema.percentage`. */
1097
1097
  readonly percentage: number | null;
1098
- readonly charging: 'dc' | 'solar' | 'none';
1098
+ /** `'unknown'` = the power source was never read. See `BatteryStatusSchema.charging`. */
1099
+ readonly charging: 'dc' | 'solar' | 'none' | 'unknown';
1099
1100
  readonly sleeping: boolean;
1100
1101
  readonly lastUpdated: number;
1101
1102
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/types",
3
- "version": "1.2.148",
3
+ "version": "1.2.149",
4
4
  "description": "Shared types, interfaces, and model catalogs for the CamStack detection ecosystem",
5
5
  "keywords": [
6
6
  "camstack",