@camstack/addon-provider-homematic 1.0.7 → 1.1.1

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 CHANGED
@@ -4651,7 +4651,7 @@ function preprocess(fn, schema) {
4651
4651
  });
4652
4652
  }
4653
4653
  //#endregion
4654
- //#region ../types/dist/sleep-B1dKJAMJ.mjs
4654
+ //#region ../types/dist/sleep-BV7rLc6Y.mjs
4655
4655
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4656
4656
  EventCategory["SystemBoot"] = "system.boot";
4657
4657
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -5130,6 +5130,12 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
5130
5130
  * Payload: `{ deviceId, childDeviceIds, hiddenChildIds }`.
5131
5131
  */
5132
5132
  EventCategory["AccessoriesChanged"] = "accessories.onAccessoriesChanged";
5133
+ /**
5134
+ * Progress update from a running model conversion job.
5135
+ * Payload: `{ kind: 'model-convert', phase, sessionId?, pct?, detail? }`.
5136
+ * Emitted by `addon-model-studio` on the converting node.
5137
+ */
5138
+ EventCategory["ModelConvertProgress"] = "model-convert.progress";
5133
5139
  return EventCategory;
5134
5140
  }({});
5135
5141
  Object.fromEntries([
@@ -6667,6 +6673,13 @@ object({
6667
6673
  unreachable: number()
6668
6674
  })
6669
6675
  });
6676
+ var LabelDefinitionSchema = object({
6677
+ id: string(),
6678
+ name: string(),
6679
+ category: string().optional(),
6680
+ description: string().optional(),
6681
+ icon: string().optional()
6682
+ });
6670
6683
  var MODEL_FORMATS = [
6671
6684
  "onnx",
6672
6685
  "coreml",
@@ -6675,6 +6688,120 @@ var MODEL_FORMATS = [
6675
6688
  "pt"
6676
6689
  ];
6677
6690
  /**
6691
+ * Multi-file format payload.
6692
+ *
6693
+ * - Directory formats (`isDirectory: true`, e.g. `.mlpackage`): files
6694
+ * relative to the directory root — the downloader fetches each from
6695
+ * `{url}/{file}` into `{modelDir}/{file}`. If omitted, it probes the
6696
+ * HuggingFace API (slower).
6697
+ * - Single-file formats (no `isDirectory`, e.g. OpenVINO IR): sibling
6698
+ * files fetched from the SAME remote directory as `url` and stored flat
6699
+ * alongside the main file — e.g. `['camstack-yolov9t.bin']` for the IR
6700
+ * weights next to `camstack-yolov9t.xml`.
6701
+ */
6702
+ var ModelFormatEntrySchema = object({
6703
+ url: string(),
6704
+ sizeMB: number(),
6705
+ /** Whether this format is a directory bundle (e.g., .mlpackage) rather than a single file */
6706
+ isDirectory: boolean().optional(),
6707
+ /** Multi-file payload (directory members or sibling files). */
6708
+ files: array(string()).readonly().optional(),
6709
+ /** Runtime(s) that can use this format. If omitted, inferred from ModelFormat key */
6710
+ runtimes: array(_enum(["node", "python"])).readonly().optional()
6711
+ });
6712
+ /**
6713
+ * Extra file that must be downloaded alongside the model (e.g., labels JSON, dict.txt).
6714
+ * The downloader fetches from `url` and saves to `{modelsDir}/{filename}`.
6715
+ */
6716
+ var ModelExtraFileSchema = object({
6717
+ url: string(),
6718
+ filename: string(),
6719
+ sizeMB: number()
6720
+ });
6721
+ /**
6722
+ * Per-format payload map. Modelled as an explicit object (one optional key
6723
+ * per `ModelFormat`) rather than `z.record(enum, …)` — zod v4's enum-keyed
6724
+ * record requires every key, but a catalog entry only ships a subset of
6725
+ * formats.
6726
+ */
6727
+ var ModelFormatsSchema = object({
6728
+ onnx: ModelFormatEntrySchema.optional(),
6729
+ coreml: ModelFormatEntrySchema.optional(),
6730
+ openvino: ModelFormatEntrySchema.optional(),
6731
+ tflite: ModelFormatEntrySchema.optional(),
6732
+ pt: ModelFormatEntrySchema.optional()
6733
+ });
6734
+ var ModelCatalogEntrySchema = object({
6735
+ id: string(),
6736
+ name: string(),
6737
+ description: string(),
6738
+ formats: ModelFormatsSchema,
6739
+ inputSize: object({
6740
+ width: number(),
6741
+ height: number()
6742
+ }),
6743
+ labels: array(LabelDefinitionSchema).readonly(),
6744
+ inputLayout: _enum(["nchw", "nhwc"]).optional(),
6745
+ inputNormalization: _enum([
6746
+ "zero-one",
6747
+ "imagenet",
6748
+ "none"
6749
+ ]).optional(),
6750
+ preprocessMode: _enum(["letterbox", "resize"]).optional(),
6751
+ /**
6752
+ * When true, the executor produces a landmark-aligned crop (similarity warp
6753
+ * onto the canonical template) before this step runs, instead of a plain
6754
+ * axis-aligned bbox crop. Required for face-recognition embedders (ArcFace):
6755
+ * their embeddings are only discriminative on an aligned input. The face
6756
+ * detector that produced the parent detail must emit 5 landmarks.
6757
+ */
6758
+ faceAlignment: boolean().optional(),
6759
+ /**
6760
+ * Auxiliary files required at runtime (labels JSON, charset dict, etc.).
6761
+ * Downloaded into the same modelsDir alongside the model file.
6762
+ */
6763
+ extraFiles: array(ModelExtraFileSchema).readonly().optional()
6764
+ });
6765
+ var ConvertTargetSchema = discriminatedUnion("format", [object({
6766
+ format: literal("openvino"),
6767
+ precisions: array(_enum(["fp16", "int8"])).min(1).readonly()
6768
+ }), object({ format: literal("coreml") })]);
6769
+ var ModelConvertMetadataSchema = object({
6770
+ id: string().regex(/^[a-zA-Z0-9._-]+$/),
6771
+ name: string(),
6772
+ labels: array(LabelDefinitionSchema).readonly(),
6773
+ inputSize: object({
6774
+ width: number(),
6775
+ height: number()
6776
+ }),
6777
+ inputLayout: _enum(["nchw", "nhwc"]).optional(),
6778
+ inputNormalization: _enum([
6779
+ "zero-one",
6780
+ "imagenet",
6781
+ "none"
6782
+ ]).optional(),
6783
+ preprocessMode: _enum(["letterbox", "resize"]).optional(),
6784
+ outputFormat: _enum([
6785
+ "yolo",
6786
+ "ssd",
6787
+ "embedding",
6788
+ "classification",
6789
+ "ocr",
6790
+ "segmentation"
6791
+ ]),
6792
+ faceAlignment: boolean().optional()
6793
+ });
6794
+ var ConvertResultSchema = object({
6795
+ entry: ModelCatalogEntrySchema,
6796
+ artifacts: array(object({
6797
+ format: _enum(MODEL_FORMATS),
6798
+ precision: _enum(["fp16", "int8"]).optional(),
6799
+ sizeMB: number(),
6800
+ validated: boolean(),
6801
+ files: array(string()).readonly()
6802
+ })).readonly()
6803
+ });
6804
+ /**
6678
6805
  * Numeric day-of-week: 0 = Sunday … 6 = Saturday (matches `Date.getDay`).
6679
6806
  * Named `RecordingWeekday` to avoid collision with the string-union
6680
6807
  * `Weekday` exported from `interfaces/timezones.ts`.
@@ -15343,6 +15470,54 @@ var EnrichedWidgetMetadataSchema = WidgetMetadataSchema.extend({
15343
15470
  bundleUrl: string()
15344
15471
  });
15345
15472
  method(_void(), array(EnrichedWidgetMetadataSchema).readonly());
15473
+ /**
15474
+ * `custom-model-registry` — collection cap exposing operator-registered
15475
+ * custom detection models. Each provider (today: `addon-model-studio`)
15476
+ * contributes a list of `CustomModelDescriptor`s; the hub auto-concatenates
15477
+ * them across providers (`concatCollection`).
15478
+ *
15479
+ * The detection-pipeline is *aware* of this cap: when at least one provider
15480
+ * exists it unions these descriptors into the per-step model picker and the
15481
+ * runtime model-resolution path, alongside the static catalog. When no
15482
+ * provider exists the consumer no-ops entirely (identical to the catalog-only
15483
+ * behaviour).
15484
+ *
15485
+ * A descriptor carries a full `ModelCatalogEntry` directly — the same shape
15486
+ * the static catalog uses — so the existing download/resolution code consumes
15487
+ * it unchanged. `stepId` is the detection step the model targets
15488
+ * (e.g. `'object-detection'`).
15489
+ */
15490
+ var CustomModelDescriptorSchema = object({
15491
+ stepId: string(),
15492
+ entry: ModelCatalogEntrySchema
15493
+ });
15494
+ method(_void(), array(CustomModelDescriptorSchema).readonly());
15495
+ method(object({
15496
+ nodeId: string(),
15497
+ modelId: string(),
15498
+ format: _enum(MODEL_FORMATS),
15499
+ entry: ModelCatalogEntrySchema
15500
+ }), object({
15501
+ ok: boolean(),
15502
+ /** sha256 of the staged tarball (empty for a hub-local no-op). */
15503
+ sha256: string(),
15504
+ bytes: number(),
15505
+ /** The target node's modelsDir the artifact landed in. */
15506
+ path: string()
15507
+ }), {
15508
+ kind: "mutation",
15509
+ auth: "admin"
15510
+ });
15511
+ method(object({
15512
+ sourceUrl: string(),
15513
+ metadata: ModelConvertMetadataSchema,
15514
+ targets: array(ConvertTargetSchema).min(1).readonly(),
15515
+ calibrationRef: string().optional(),
15516
+ sessionId: string().optional()
15517
+ }), ConvertResultSchema, {
15518
+ kind: "mutation",
15519
+ auth: "admin"
15520
+ });
15346
15521
  var AddonHttpRouteSchema = object({
15347
15522
  method: _enum([
15348
15523
  "GET",
@@ -20237,6 +20412,12 @@ Object.freeze({
20237
20412
  addonId: null,
20238
20413
  access: "create"
20239
20414
  },
20415
+ "customModelRegistry.listModels": {
20416
+ capName: "custom-model-registry",
20417
+ capScope: "system",
20418
+ addonId: null,
20419
+ access: "view"
20420
+ },
20240
20421
  "decoder.createSession": {
20241
20422
  capName: "decoder",
20242
20423
  capScope: "system",
@@ -21461,6 +21642,18 @@ Object.freeze({
21461
21642
  addonId: null,
21462
21643
  access: "view"
21463
21644
  },
21645
+ "modelConvert.convert": {
21646
+ capName: "model-convert",
21647
+ capScope: "system",
21648
+ addonId: null,
21649
+ access: "create"
21650
+ },
21651
+ "modelDistributor.distributeModel": {
21652
+ capName: "model-distributor",
21653
+ capScope: "system",
21654
+ addonId: null,
21655
+ access: "create"
21656
+ },
21464
21657
  "motion.isDetected": {
21465
21658
  capName: "motion",
21466
21659
  capScope: "device",
package/dist/addon.mjs CHANGED
@@ -4652,7 +4652,7 @@ function preprocess(fn, schema) {
4652
4652
  });
4653
4653
  }
4654
4654
  //#endregion
4655
- //#region ../types/dist/sleep-B1dKJAMJ.mjs
4655
+ //#region ../types/dist/sleep-BV7rLc6Y.mjs
4656
4656
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4657
4657
  EventCategory["SystemBoot"] = "system.boot";
4658
4658
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -5131,6 +5131,12 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
5131
5131
  * Payload: `{ deviceId, childDeviceIds, hiddenChildIds }`.
5132
5132
  */
5133
5133
  EventCategory["AccessoriesChanged"] = "accessories.onAccessoriesChanged";
5134
+ /**
5135
+ * Progress update from a running model conversion job.
5136
+ * Payload: `{ kind: 'model-convert', phase, sessionId?, pct?, detail? }`.
5137
+ * Emitted by `addon-model-studio` on the converting node.
5138
+ */
5139
+ EventCategory["ModelConvertProgress"] = "model-convert.progress";
5134
5140
  return EventCategory;
5135
5141
  }({});
5136
5142
  Object.fromEntries([
@@ -6668,6 +6674,13 @@ object({
6668
6674
  unreachable: number()
6669
6675
  })
6670
6676
  });
6677
+ var LabelDefinitionSchema = object({
6678
+ id: string(),
6679
+ name: string(),
6680
+ category: string().optional(),
6681
+ description: string().optional(),
6682
+ icon: string().optional()
6683
+ });
6671
6684
  var MODEL_FORMATS = [
6672
6685
  "onnx",
6673
6686
  "coreml",
@@ -6676,6 +6689,120 @@ var MODEL_FORMATS = [
6676
6689
  "pt"
6677
6690
  ];
6678
6691
  /**
6692
+ * Multi-file format payload.
6693
+ *
6694
+ * - Directory formats (`isDirectory: true`, e.g. `.mlpackage`): files
6695
+ * relative to the directory root — the downloader fetches each from
6696
+ * `{url}/{file}` into `{modelDir}/{file}`. If omitted, it probes the
6697
+ * HuggingFace API (slower).
6698
+ * - Single-file formats (no `isDirectory`, e.g. OpenVINO IR): sibling
6699
+ * files fetched from the SAME remote directory as `url` and stored flat
6700
+ * alongside the main file — e.g. `['camstack-yolov9t.bin']` for the IR
6701
+ * weights next to `camstack-yolov9t.xml`.
6702
+ */
6703
+ var ModelFormatEntrySchema = object({
6704
+ url: string(),
6705
+ sizeMB: number(),
6706
+ /** Whether this format is a directory bundle (e.g., .mlpackage) rather than a single file */
6707
+ isDirectory: boolean().optional(),
6708
+ /** Multi-file payload (directory members or sibling files). */
6709
+ files: array(string()).readonly().optional(),
6710
+ /** Runtime(s) that can use this format. If omitted, inferred from ModelFormat key */
6711
+ runtimes: array(_enum(["node", "python"])).readonly().optional()
6712
+ });
6713
+ /**
6714
+ * Extra file that must be downloaded alongside the model (e.g., labels JSON, dict.txt).
6715
+ * The downloader fetches from `url` and saves to `{modelsDir}/{filename}`.
6716
+ */
6717
+ var ModelExtraFileSchema = object({
6718
+ url: string(),
6719
+ filename: string(),
6720
+ sizeMB: number()
6721
+ });
6722
+ /**
6723
+ * Per-format payload map. Modelled as an explicit object (one optional key
6724
+ * per `ModelFormat`) rather than `z.record(enum, …)` — zod v4's enum-keyed
6725
+ * record requires every key, but a catalog entry only ships a subset of
6726
+ * formats.
6727
+ */
6728
+ var ModelFormatsSchema = object({
6729
+ onnx: ModelFormatEntrySchema.optional(),
6730
+ coreml: ModelFormatEntrySchema.optional(),
6731
+ openvino: ModelFormatEntrySchema.optional(),
6732
+ tflite: ModelFormatEntrySchema.optional(),
6733
+ pt: ModelFormatEntrySchema.optional()
6734
+ });
6735
+ var ModelCatalogEntrySchema = object({
6736
+ id: string(),
6737
+ name: string(),
6738
+ description: string(),
6739
+ formats: ModelFormatsSchema,
6740
+ inputSize: object({
6741
+ width: number(),
6742
+ height: number()
6743
+ }),
6744
+ labels: array(LabelDefinitionSchema).readonly(),
6745
+ inputLayout: _enum(["nchw", "nhwc"]).optional(),
6746
+ inputNormalization: _enum([
6747
+ "zero-one",
6748
+ "imagenet",
6749
+ "none"
6750
+ ]).optional(),
6751
+ preprocessMode: _enum(["letterbox", "resize"]).optional(),
6752
+ /**
6753
+ * When true, the executor produces a landmark-aligned crop (similarity warp
6754
+ * onto the canonical template) before this step runs, instead of a plain
6755
+ * axis-aligned bbox crop. Required for face-recognition embedders (ArcFace):
6756
+ * their embeddings are only discriminative on an aligned input. The face
6757
+ * detector that produced the parent detail must emit 5 landmarks.
6758
+ */
6759
+ faceAlignment: boolean().optional(),
6760
+ /**
6761
+ * Auxiliary files required at runtime (labels JSON, charset dict, etc.).
6762
+ * Downloaded into the same modelsDir alongside the model file.
6763
+ */
6764
+ extraFiles: array(ModelExtraFileSchema).readonly().optional()
6765
+ });
6766
+ var ConvertTargetSchema = discriminatedUnion("format", [object({
6767
+ format: literal("openvino"),
6768
+ precisions: array(_enum(["fp16", "int8"])).min(1).readonly()
6769
+ }), object({ format: literal("coreml") })]);
6770
+ var ModelConvertMetadataSchema = object({
6771
+ id: string().regex(/^[a-zA-Z0-9._-]+$/),
6772
+ name: string(),
6773
+ labels: array(LabelDefinitionSchema).readonly(),
6774
+ inputSize: object({
6775
+ width: number(),
6776
+ height: number()
6777
+ }),
6778
+ inputLayout: _enum(["nchw", "nhwc"]).optional(),
6779
+ inputNormalization: _enum([
6780
+ "zero-one",
6781
+ "imagenet",
6782
+ "none"
6783
+ ]).optional(),
6784
+ preprocessMode: _enum(["letterbox", "resize"]).optional(),
6785
+ outputFormat: _enum([
6786
+ "yolo",
6787
+ "ssd",
6788
+ "embedding",
6789
+ "classification",
6790
+ "ocr",
6791
+ "segmentation"
6792
+ ]),
6793
+ faceAlignment: boolean().optional()
6794
+ });
6795
+ var ConvertResultSchema = object({
6796
+ entry: ModelCatalogEntrySchema,
6797
+ artifacts: array(object({
6798
+ format: _enum(MODEL_FORMATS),
6799
+ precision: _enum(["fp16", "int8"]).optional(),
6800
+ sizeMB: number(),
6801
+ validated: boolean(),
6802
+ files: array(string()).readonly()
6803
+ })).readonly()
6804
+ });
6805
+ /**
6679
6806
  * Numeric day-of-week: 0 = Sunday … 6 = Saturday (matches `Date.getDay`).
6680
6807
  * Named `RecordingWeekday` to avoid collision with the string-union
6681
6808
  * `Weekday` exported from `interfaces/timezones.ts`.
@@ -15344,6 +15471,54 @@ var EnrichedWidgetMetadataSchema = WidgetMetadataSchema.extend({
15344
15471
  bundleUrl: string()
15345
15472
  });
15346
15473
  method(_void(), array(EnrichedWidgetMetadataSchema).readonly());
15474
+ /**
15475
+ * `custom-model-registry` — collection cap exposing operator-registered
15476
+ * custom detection models. Each provider (today: `addon-model-studio`)
15477
+ * contributes a list of `CustomModelDescriptor`s; the hub auto-concatenates
15478
+ * them across providers (`concatCollection`).
15479
+ *
15480
+ * The detection-pipeline is *aware* of this cap: when at least one provider
15481
+ * exists it unions these descriptors into the per-step model picker and the
15482
+ * runtime model-resolution path, alongside the static catalog. When no
15483
+ * provider exists the consumer no-ops entirely (identical to the catalog-only
15484
+ * behaviour).
15485
+ *
15486
+ * A descriptor carries a full `ModelCatalogEntry` directly — the same shape
15487
+ * the static catalog uses — so the existing download/resolution code consumes
15488
+ * it unchanged. `stepId` is the detection step the model targets
15489
+ * (e.g. `'object-detection'`).
15490
+ */
15491
+ var CustomModelDescriptorSchema = object({
15492
+ stepId: string(),
15493
+ entry: ModelCatalogEntrySchema
15494
+ });
15495
+ method(_void(), array(CustomModelDescriptorSchema).readonly());
15496
+ method(object({
15497
+ nodeId: string(),
15498
+ modelId: string(),
15499
+ format: _enum(MODEL_FORMATS),
15500
+ entry: ModelCatalogEntrySchema
15501
+ }), object({
15502
+ ok: boolean(),
15503
+ /** sha256 of the staged tarball (empty for a hub-local no-op). */
15504
+ sha256: string(),
15505
+ bytes: number(),
15506
+ /** The target node's modelsDir the artifact landed in. */
15507
+ path: string()
15508
+ }), {
15509
+ kind: "mutation",
15510
+ auth: "admin"
15511
+ });
15512
+ method(object({
15513
+ sourceUrl: string(),
15514
+ metadata: ModelConvertMetadataSchema,
15515
+ targets: array(ConvertTargetSchema).min(1).readonly(),
15516
+ calibrationRef: string().optional(),
15517
+ sessionId: string().optional()
15518
+ }), ConvertResultSchema, {
15519
+ kind: "mutation",
15520
+ auth: "admin"
15521
+ });
15347
15522
  var AddonHttpRouteSchema = object({
15348
15523
  method: _enum([
15349
15524
  "GET",
@@ -20238,6 +20413,12 @@ Object.freeze({
20238
20413
  addonId: null,
20239
20414
  access: "create"
20240
20415
  },
20416
+ "customModelRegistry.listModels": {
20417
+ capName: "custom-model-registry",
20418
+ capScope: "system",
20419
+ addonId: null,
20420
+ access: "view"
20421
+ },
20241
20422
  "decoder.createSession": {
20242
20423
  capName: "decoder",
20243
20424
  capScope: "system",
@@ -21462,6 +21643,18 @@ Object.freeze({
21462
21643
  addonId: null,
21463
21644
  access: "view"
21464
21645
  },
21646
+ "modelConvert.convert": {
21647
+ capName: "model-convert",
21648
+ capScope: "system",
21649
+ addonId: null,
21650
+ access: "create"
21651
+ },
21652
+ "modelDistributor.distributeModel": {
21653
+ capName: "model-distributor",
21654
+ capScope: "system",
21655
+ addonId: null,
21656
+ access: "create"
21657
+ },
21465
21658
  "motion.isDetected": {
21466
21659
  capName: "motion",
21467
21660
  capScope: "device",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-homematic",
3
- "version": "1.0.7",
3
+ "version": "1.1.1",
4
4
  "description": "Homematic / HomematicIP (CCU3 / RaspberryMatic) device-provider addon for CamStack — wraps the nodehomematic library",
5
5
  "keywords": [
6
6
  "camstack",