@camstack/addon-provider-homematic 1.2.43 → 1.2.44

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.
Files changed (3) hide show
  1. package/dist/addon.js +121 -13
  2. package/dist/addon.mjs +121 -13
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -8048,18 +8048,61 @@ var RelocateFootageInputSchema = object({
8048
8048
  * `RecordingConfig.enabled` or camera wrapper bindings. */
8049
8049
  var StorageMigrationLeaseInputSchema = object({ leaseId: string().min(1) });
8050
8050
  var StorageMigrationFootageMoveInputSchema = RelocateFootageInputSchema.extend({ leaseId: string().min(1) });
8051
+ /**
8052
+ * What a `relocateMedia` pass DOES. One engine, three passes — never a second
8053
+ * mover (the engine already walks both collections with a timestamp cursor and
8054
+ * already has a stamp-without-copy path).
8055
+ *
8056
+ * - `move` — the default and the historical behaviour: event-media and
8057
+ * retrain blobs move to `toLocationId` and their rows are
8058
+ * stamped. The enrolled gallery is skipped (D197).
8059
+ * - `seal` — ROWS ONLY, no bytes. Every row whose `locationId` is NULL is
8060
+ * stamped with `toLocationId`. `toLocationId` here is the id the
8061
+ * bytes ALREADY sit on — today's `eventMedia` default — because
8062
+ * a NULL row means "wherever `eventMedia` points *now*", and the
8063
+ * instant a repoint moves that pointer the row reads from the
8064
+ * new disk while its bytes are on the old one.
8065
+ * - `gallery` — the inverse selection of `move`: ONLY the retention-exempt
8066
+ * (enrolled-gallery) rows, which `move` deliberately skips.
8067
+ * `galleryMedia` is `cardinality: 'single'`, so this pass can
8068
+ * never run beside a live second location: it is stop-the-world
8069
+ * by construction, which is acceptable only because the gallery
8070
+ * is a few KB per enrolled sample.
8071
+ */
8072
+ var MediaRelocateModeSchema = _enum([
8073
+ "move",
8074
+ "seal",
8075
+ "gallery"
8076
+ ]);
8051
8077
  var RelocateMediaInputSchema = object({
8052
8078
  toLocationId: string(),
8053
- throttleMbps: number().min(1).max(1e3).optional()
8079
+ throttleMbps: number().min(1).max(1e3).optional(),
8080
+ /** Omitted = `move`, the pre-existing behaviour. */
8081
+ mode: MediaRelocateModeSchema.optional()
8082
+ });
8083
+ /** How many rows still carry NO `locationId` — the population a repoint would
8084
+ * silently re-aim at a disk that does not hold their bytes. Zero is the only
8085
+ * value that permits a non-blocking `eventMedia` cutover. */
8086
+ var UnstampedEventMediaCountSchema = object({
8087
+ media: number().int().nonnegative(),
8088
+ retrainFrames: number().int().nonnegative(),
8089
+ total: number().int().nonnegative()
8054
8090
  });
8055
8091
  var StorageMigrationMediaMoveInputSchema = RelocateMediaInputSchema.extend({ leaseId: string().min(1) });
8056
- /** The independently selectable logical storage classes. `recordings`
8057
- * encompasses the high and mid segment profiles; `recordingsLow` is low
8058
- * segments; `eventMedia` is post-analysis blobs. */
8092
+ /** The independently selectable logical storage classes — every class
8093
+ * `storage.listLocationDeclarations` reports, so an operator never meets a
8094
+ * Zod enum error where they should meet an explanation.
8095
+ *
8096
+ * `recordings` encompasses the high and mid segment profiles; `recordingsLow`
8097
+ * is low segments; `eventMedia` is post-analysis blobs; `galleryMedia` is the
8098
+ * enrolled gallery; `backups` is the system backup archive. The last two have
8099
+ * their own rules — see {@link StorageMigrationFindingCodeSchema}. */
8059
8100
  var StorageMigrationClassSchema = _enum([
8060
8101
  "recordings",
8061
8102
  "recordingsLow",
8062
- "eventMedia"
8103
+ "eventMedia",
8104
+ "backups",
8105
+ "galleryMedia"
8063
8106
  ]);
8064
8107
  /** A destination is always an existing, fully-qualified location id. The
8065
8108
  * migration API intentionally never changes a source location's `basePath`:
@@ -8067,20 +8110,56 @@ var StorageMigrationClassSchema = _enum([
8067
8110
  var StorageMigrationDestinationsSchema = object({
8068
8111
  recordings: string().min(1).optional(),
8069
8112
  recordingsLow: string().min(1).optional(),
8070
- eventMedia: string().min(1).optional()
8113
+ eventMedia: string().min(1).optional(),
8114
+ backups: string().min(1).optional(),
8115
+ galleryMedia: string().min(1).optional()
8071
8116
  }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
8117
+ /**
8118
+ * How a migration sequences the cutover against the byte move.
8119
+ *
8120
+ * - `blocking` — the historical order: pause, move every byte, repoint,
8121
+ * resume. Recording is stopped for the whole move. Right
8122
+ * for a small or a cold class, and the only legal mode for
8123
+ * a `cardinality: 'single'` class.
8124
+ * - `nonBlocking` — repoint FIRST, drain behind: seal, pause, repoint,
8125
+ * refresh, resume, then move the past with everything
8126
+ * running. The pause is three bounded instants (a detach +
8127
+ * attach round, a write-gate drain, a lease) instead of one
8128
+ * bounded by bytes. 1.09 TB at 7–14 MB/s is thirty hours of
8129
+ * stopped recording under `blocking`; the same move is
8130
+ * seconds of stopped recording under `nonBlocking`.
8131
+ *
8132
+ * The mode is on the JOB, not only on the input, because `status` is where an
8133
+ * operator finds out which one is running.
8134
+ */
8135
+ var StorageMigrationModeSchema = _enum(["blocking", "nonBlocking"]);
8072
8136
  /** Shared input for planning and starting an orchestrated storage migration. */
8073
8137
  var StorageMigrationInputSchema = object({
8074
8138
  destinations: StorageMigrationDestinationsSchema,
8075
- throttleMbps: number().min(1).max(1e3).optional()
8139
+ throttleMbps: number().min(1).max(1e3).optional(),
8140
+ /** Omitted = `blocking`, which stays the default. */
8141
+ mode: StorageMigrationModeSchema.optional()
8076
8142
  });
8077
- /** The durable coordinator state machine. The only phase that changes default
8078
- * locations is `repointing`, after every selected mover has completed and been
8079
- * verified. */
8143
+ /**
8144
+ * The durable coordinator state machine.
8145
+ *
8146
+ * `blocking`:
8147
+ * planning → pausing → moving → verifying → repointing → refreshing → resuming → done
8148
+ *
8149
+ * `nonBlocking`:
8150
+ * planning → sealing → pausing → repointing → refreshing → resuming → draining → verifying → done
8151
+ *
8152
+ * Same phases, different order plus two new ones — not a second mover.
8153
+ * `sealing` closes the `eventMedia` NULL-row hole BEFORE anything is paused;
8154
+ * `draining` runs the same movers UNLEASED, after every writer is back up.
8155
+ * `repointing` is still the only phase that changes a default location.
8156
+ */
8080
8157
  var StorageMigrationPhaseSchema = _enum([
8081
8158
  "planning",
8159
+ "sealing",
8082
8160
  "pausing",
8083
8161
  "moving",
8162
+ "draining",
8084
8163
  "verifying",
8085
8164
  "repointing",
8086
8165
  "refreshing",
@@ -8105,6 +8184,9 @@ var StorageMigrationMoveSchema = object({
8105
8184
  var StorageMigrationJobSchema = object({
8106
8185
  jobId: string(),
8107
8186
  phase: StorageMigrationPhaseSchema,
8187
+ /** Which order this job is running. `status` is the only place an operator
8188
+ * can tell a seconds-long cutover from a thirty-hour one. */
8189
+ mode: StorageMigrationModeSchema,
8108
8190
  destinations: StorageMigrationDestinationsSchema,
8109
8191
  throttleMbps: number(),
8110
8192
  moves: array(StorageMigrationMoveSchema),
@@ -8117,13 +8199,30 @@ var StorageMigrationJobSchema = object({
8117
8199
  finishedAt: number().nullable(),
8118
8200
  error: string().nullable()
8119
8201
  });
8202
+ var StorageMigrationFindingSchema = object({
8203
+ code: _enum([
8204
+ "sharesDeviceWithSource",
8205
+ "deviceIdentityUnknown",
8206
+ "unstampedEventMediaRows",
8207
+ "blockingOnly",
8208
+ "noMover"
8209
+ ]),
8210
+ storageClass: StorageMigrationClassSchema,
8211
+ /** Human-readable, already carrying the ids and counts. */
8212
+ message: string()
8213
+ });
8120
8214
  var StorageMigrationPlanSchema = object({
8121
8215
  destinations: StorageMigrationDestinationsSchema,
8216
+ /** The mode this plan was built for. A plan is only valid for its mode: the
8217
+ * `eventMedia` seal gate and the single-cardinality refusal both depend on
8218
+ * it. */
8219
+ mode: StorageMigrationModeSchema,
8122
8220
  moves: array(object({
8123
8221
  storageClass: StorageMigrationClassSchema,
8124
8222
  fromLocationId: string(),
8125
8223
  toLocationId: string()
8126
- }))
8224
+ })),
8225
+ findings: array(StorageMigrationFindingSchema)
8127
8226
  });
8128
8227
  /**
8129
8228
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
@@ -19042,7 +19141,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19042
19141
  }), method(RelocateMediaInputSchema, object({ jobId: string() }), {
19043
19142
  kind: "mutation",
19044
19143
  auth: "admin"
19045
- }), method(object({}), array(RelocateJobSchema).readonly(), {
19144
+ }), method(object({}), UnstampedEventMediaCountSchema, { auth: "admin" }), method(object({}), array(RelocateJobSchema).readonly(), {
19046
19145
  kind: "query",
19047
19146
  auth: "admin"
19048
19147
  }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
@@ -20949,7 +21048,10 @@ method(object({
20949
21048
  }), StorageLocationSchema, {
20950
21049
  kind: "mutation",
20951
21050
  auth: "admin"
20952
- }), method(object({ id: string() }), _void(), {
21051
+ }), method(object({
21052
+ id: string(),
21053
+ force: boolean().optional()
21054
+ }), _void(), {
20953
21055
  kind: "mutation",
20954
21056
  auth: "admin"
20955
21057
  }), method(object({ id: string() }), object({
@@ -34806,6 +34908,12 @@ Object.freeze({
34806
34908
  addonId: null,
34807
34909
  access: "create"
34808
34910
  },
34911
+ "pipelineAnalytics.countUnstampedEventMedia": {
34912
+ capName: "pipeline-analytics",
34913
+ capScope: "device",
34914
+ addonId: null,
34915
+ access: "view"
34916
+ },
34809
34917
  "pipelineAnalytics.deleteDeviceEvents": {
34810
34918
  capName: "pipeline-analytics",
34811
34919
  capScope: "device",
package/dist/addon.mjs CHANGED
@@ -8049,18 +8049,61 @@ var RelocateFootageInputSchema = object({
8049
8049
  * `RecordingConfig.enabled` or camera wrapper bindings. */
8050
8050
  var StorageMigrationLeaseInputSchema = object({ leaseId: string().min(1) });
8051
8051
  var StorageMigrationFootageMoveInputSchema = RelocateFootageInputSchema.extend({ leaseId: string().min(1) });
8052
+ /**
8053
+ * What a `relocateMedia` pass DOES. One engine, three passes — never a second
8054
+ * mover (the engine already walks both collections with a timestamp cursor and
8055
+ * already has a stamp-without-copy path).
8056
+ *
8057
+ * - `move` — the default and the historical behaviour: event-media and
8058
+ * retrain blobs move to `toLocationId` and their rows are
8059
+ * stamped. The enrolled gallery is skipped (D197).
8060
+ * - `seal` — ROWS ONLY, no bytes. Every row whose `locationId` is NULL is
8061
+ * stamped with `toLocationId`. `toLocationId` here is the id the
8062
+ * bytes ALREADY sit on — today's `eventMedia` default — because
8063
+ * a NULL row means "wherever `eventMedia` points *now*", and the
8064
+ * instant a repoint moves that pointer the row reads from the
8065
+ * new disk while its bytes are on the old one.
8066
+ * - `gallery` — the inverse selection of `move`: ONLY the retention-exempt
8067
+ * (enrolled-gallery) rows, which `move` deliberately skips.
8068
+ * `galleryMedia` is `cardinality: 'single'`, so this pass can
8069
+ * never run beside a live second location: it is stop-the-world
8070
+ * by construction, which is acceptable only because the gallery
8071
+ * is a few KB per enrolled sample.
8072
+ */
8073
+ var MediaRelocateModeSchema = _enum([
8074
+ "move",
8075
+ "seal",
8076
+ "gallery"
8077
+ ]);
8052
8078
  var RelocateMediaInputSchema = object({
8053
8079
  toLocationId: string(),
8054
- throttleMbps: number().min(1).max(1e3).optional()
8080
+ throttleMbps: number().min(1).max(1e3).optional(),
8081
+ /** Omitted = `move`, the pre-existing behaviour. */
8082
+ mode: MediaRelocateModeSchema.optional()
8083
+ });
8084
+ /** How many rows still carry NO `locationId` — the population a repoint would
8085
+ * silently re-aim at a disk that does not hold their bytes. Zero is the only
8086
+ * value that permits a non-blocking `eventMedia` cutover. */
8087
+ var UnstampedEventMediaCountSchema = object({
8088
+ media: number().int().nonnegative(),
8089
+ retrainFrames: number().int().nonnegative(),
8090
+ total: number().int().nonnegative()
8055
8091
  });
8056
8092
  var StorageMigrationMediaMoveInputSchema = RelocateMediaInputSchema.extend({ leaseId: string().min(1) });
8057
- /** The independently selectable logical storage classes. `recordings`
8058
- * encompasses the high and mid segment profiles; `recordingsLow` is low
8059
- * segments; `eventMedia` is post-analysis blobs. */
8093
+ /** The independently selectable logical storage classes — every class
8094
+ * `storage.listLocationDeclarations` reports, so an operator never meets a
8095
+ * Zod enum error where they should meet an explanation.
8096
+ *
8097
+ * `recordings` encompasses the high and mid segment profiles; `recordingsLow`
8098
+ * is low segments; `eventMedia` is post-analysis blobs; `galleryMedia` is the
8099
+ * enrolled gallery; `backups` is the system backup archive. The last two have
8100
+ * their own rules — see {@link StorageMigrationFindingCodeSchema}. */
8060
8101
  var StorageMigrationClassSchema = _enum([
8061
8102
  "recordings",
8062
8103
  "recordingsLow",
8063
- "eventMedia"
8104
+ "eventMedia",
8105
+ "backups",
8106
+ "galleryMedia"
8064
8107
  ]);
8065
8108
  /** A destination is always an existing, fully-qualified location id. The
8066
8109
  * migration API intentionally never changes a source location's `basePath`:
@@ -8068,20 +8111,56 @@ var StorageMigrationClassSchema = _enum([
8068
8111
  var StorageMigrationDestinationsSchema = object({
8069
8112
  recordings: string().min(1).optional(),
8070
8113
  recordingsLow: string().min(1).optional(),
8071
- eventMedia: string().min(1).optional()
8114
+ eventMedia: string().min(1).optional(),
8115
+ backups: string().min(1).optional(),
8116
+ galleryMedia: string().min(1).optional()
8072
8117
  }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
8118
+ /**
8119
+ * How a migration sequences the cutover against the byte move.
8120
+ *
8121
+ * - `blocking` — the historical order: pause, move every byte, repoint,
8122
+ * resume. Recording is stopped for the whole move. Right
8123
+ * for a small or a cold class, and the only legal mode for
8124
+ * a `cardinality: 'single'` class.
8125
+ * - `nonBlocking` — repoint FIRST, drain behind: seal, pause, repoint,
8126
+ * refresh, resume, then move the past with everything
8127
+ * running. The pause is three bounded instants (a detach +
8128
+ * attach round, a write-gate drain, a lease) instead of one
8129
+ * bounded by bytes. 1.09 TB at 7–14 MB/s is thirty hours of
8130
+ * stopped recording under `blocking`; the same move is
8131
+ * seconds of stopped recording under `nonBlocking`.
8132
+ *
8133
+ * The mode is on the JOB, not only on the input, because `status` is where an
8134
+ * operator finds out which one is running.
8135
+ */
8136
+ var StorageMigrationModeSchema = _enum(["blocking", "nonBlocking"]);
8073
8137
  /** Shared input for planning and starting an orchestrated storage migration. */
8074
8138
  var StorageMigrationInputSchema = object({
8075
8139
  destinations: StorageMigrationDestinationsSchema,
8076
- throttleMbps: number().min(1).max(1e3).optional()
8140
+ throttleMbps: number().min(1).max(1e3).optional(),
8141
+ /** Omitted = `blocking`, which stays the default. */
8142
+ mode: StorageMigrationModeSchema.optional()
8077
8143
  });
8078
- /** The durable coordinator state machine. The only phase that changes default
8079
- * locations is `repointing`, after every selected mover has completed and been
8080
- * verified. */
8144
+ /**
8145
+ * The durable coordinator state machine.
8146
+ *
8147
+ * `blocking`:
8148
+ * planning → pausing → moving → verifying → repointing → refreshing → resuming → done
8149
+ *
8150
+ * `nonBlocking`:
8151
+ * planning → sealing → pausing → repointing → refreshing → resuming → draining → verifying → done
8152
+ *
8153
+ * Same phases, different order plus two new ones — not a second mover.
8154
+ * `sealing` closes the `eventMedia` NULL-row hole BEFORE anything is paused;
8155
+ * `draining` runs the same movers UNLEASED, after every writer is back up.
8156
+ * `repointing` is still the only phase that changes a default location.
8157
+ */
8081
8158
  var StorageMigrationPhaseSchema = _enum([
8082
8159
  "planning",
8160
+ "sealing",
8083
8161
  "pausing",
8084
8162
  "moving",
8163
+ "draining",
8085
8164
  "verifying",
8086
8165
  "repointing",
8087
8166
  "refreshing",
@@ -8106,6 +8185,9 @@ var StorageMigrationMoveSchema = object({
8106
8185
  var StorageMigrationJobSchema = object({
8107
8186
  jobId: string(),
8108
8187
  phase: StorageMigrationPhaseSchema,
8188
+ /** Which order this job is running. `status` is the only place an operator
8189
+ * can tell a seconds-long cutover from a thirty-hour one. */
8190
+ mode: StorageMigrationModeSchema,
8109
8191
  destinations: StorageMigrationDestinationsSchema,
8110
8192
  throttleMbps: number(),
8111
8193
  moves: array(StorageMigrationMoveSchema),
@@ -8118,13 +8200,30 @@ var StorageMigrationJobSchema = object({
8118
8200
  finishedAt: number().nullable(),
8119
8201
  error: string().nullable()
8120
8202
  });
8203
+ var StorageMigrationFindingSchema = object({
8204
+ code: _enum([
8205
+ "sharesDeviceWithSource",
8206
+ "deviceIdentityUnknown",
8207
+ "unstampedEventMediaRows",
8208
+ "blockingOnly",
8209
+ "noMover"
8210
+ ]),
8211
+ storageClass: StorageMigrationClassSchema,
8212
+ /** Human-readable, already carrying the ids and counts. */
8213
+ message: string()
8214
+ });
8121
8215
  var StorageMigrationPlanSchema = object({
8122
8216
  destinations: StorageMigrationDestinationsSchema,
8217
+ /** The mode this plan was built for. A plan is only valid for its mode: the
8218
+ * `eventMedia` seal gate and the single-cardinality refusal both depend on
8219
+ * it. */
8220
+ mode: StorageMigrationModeSchema,
8123
8221
  moves: array(object({
8124
8222
  storageClass: StorageMigrationClassSchema,
8125
8223
  fromLocationId: string(),
8126
8224
  toLocationId: string()
8127
- }))
8225
+ })),
8226
+ findings: array(StorageMigrationFindingSchema)
8128
8227
  });
8129
8228
  /**
8130
8229
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
@@ -19043,7 +19142,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19043
19142
  }), method(RelocateMediaInputSchema, object({ jobId: string() }), {
19044
19143
  kind: "mutation",
19045
19144
  auth: "admin"
19046
- }), method(object({}), array(RelocateJobSchema).readonly(), {
19145
+ }), method(object({}), UnstampedEventMediaCountSchema, { auth: "admin" }), method(object({}), array(RelocateJobSchema).readonly(), {
19047
19146
  kind: "query",
19048
19147
  auth: "admin"
19049
19148
  }), method(object({ jobId: string() }), object({ cancelled: boolean() }), {
@@ -20950,7 +21049,10 @@ method(object({
20950
21049
  }), StorageLocationSchema, {
20951
21050
  kind: "mutation",
20952
21051
  auth: "admin"
20953
- }), method(object({ id: string() }), _void(), {
21052
+ }), method(object({
21053
+ id: string(),
21054
+ force: boolean().optional()
21055
+ }), _void(), {
20954
21056
  kind: "mutation",
20955
21057
  auth: "admin"
20956
21058
  }), method(object({ id: string() }), object({
@@ -34807,6 +34909,12 @@ Object.freeze({
34807
34909
  addonId: null,
34808
34910
  access: "create"
34809
34911
  },
34912
+ "pipelineAnalytics.countUnstampedEventMedia": {
34913
+ capName: "pipeline-analytics",
34914
+ capScope: "device",
34915
+ addonId: null,
34916
+ access: "view"
34917
+ },
34810
34918
  "pipelineAnalytics.deleteDeviceEvents": {
34811
34919
  capName: "pipeline-analytics",
34812
34920
  capScope: "device",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-homematic",
3
- "version": "1.2.43",
3
+ "version": "1.2.44",
4
4
  "description": "Homematic / HomematicIP (CCU3 / RaspberryMatic) device-provider addon for CamStack — wraps the nodehomematic library",
5
5
  "keywords": [
6
6
  "camstack",