@camstack/addon-provider-homeassistant 1.1.0 → 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
@@ -4629,7 +4629,7 @@ function _instanceof(cls, params = {}) {
4629
4629
  return inst;
4630
4630
  }
4631
4631
  //#endregion
4632
- //#region ../types/dist/sleep-B1dKJAMJ.mjs
4632
+ //#region ../types/dist/sleep-BV7rLc6Y.mjs
4633
4633
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4634
4634
  EventCategory["SystemBoot"] = "system.boot";
4635
4635
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -5108,6 +5108,12 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
5108
5108
  * Payload: `{ deviceId, childDeviceIds, hiddenChildIds }`.
5109
5109
  */
5110
5110
  EventCategory["AccessoriesChanged"] = "accessories.onAccessoriesChanged";
5111
+ /**
5112
+ * Progress update from a running model conversion job.
5113
+ * Payload: `{ kind: 'model-convert', phase, sessionId?, pct?, detail? }`.
5114
+ * Emitted by `addon-model-studio` on the converting node.
5115
+ */
5116
+ EventCategory["ModelConvertProgress"] = "model-convert.progress";
5111
5117
  return EventCategory;
5112
5118
  }({});
5113
5119
  Object.fromEntries([
@@ -6645,6 +6651,13 @@ object({
6645
6651
  unreachable: number()
6646
6652
  })
6647
6653
  });
6654
+ var LabelDefinitionSchema = object({
6655
+ id: string(),
6656
+ name: string(),
6657
+ category: string().optional(),
6658
+ description: string().optional(),
6659
+ icon: string().optional()
6660
+ });
6648
6661
  var MODEL_FORMATS = [
6649
6662
  "onnx",
6650
6663
  "coreml",
@@ -6653,6 +6666,120 @@ var MODEL_FORMATS = [
6653
6666
  "pt"
6654
6667
  ];
6655
6668
  /**
6669
+ * Multi-file format payload.
6670
+ *
6671
+ * - Directory formats (`isDirectory: true`, e.g. `.mlpackage`): files
6672
+ * relative to the directory root — the downloader fetches each from
6673
+ * `{url}/{file}` into `{modelDir}/{file}`. If omitted, it probes the
6674
+ * HuggingFace API (slower).
6675
+ * - Single-file formats (no `isDirectory`, e.g. OpenVINO IR): sibling
6676
+ * files fetched from the SAME remote directory as `url` and stored flat
6677
+ * alongside the main file — e.g. `['camstack-yolov9t.bin']` for the IR
6678
+ * weights next to `camstack-yolov9t.xml`.
6679
+ */
6680
+ var ModelFormatEntrySchema = object({
6681
+ url: string(),
6682
+ sizeMB: number(),
6683
+ /** Whether this format is a directory bundle (e.g., .mlpackage) rather than a single file */
6684
+ isDirectory: boolean().optional(),
6685
+ /** Multi-file payload (directory members or sibling files). */
6686
+ files: array(string()).readonly().optional(),
6687
+ /** Runtime(s) that can use this format. If omitted, inferred from ModelFormat key */
6688
+ runtimes: array(_enum(["node", "python"])).readonly().optional()
6689
+ });
6690
+ /**
6691
+ * Extra file that must be downloaded alongside the model (e.g., labels JSON, dict.txt).
6692
+ * The downloader fetches from `url` and saves to `{modelsDir}/{filename}`.
6693
+ */
6694
+ var ModelExtraFileSchema = object({
6695
+ url: string(),
6696
+ filename: string(),
6697
+ sizeMB: number()
6698
+ });
6699
+ /**
6700
+ * Per-format payload map. Modelled as an explicit object (one optional key
6701
+ * per `ModelFormat`) rather than `z.record(enum, …)` — zod v4's enum-keyed
6702
+ * record requires every key, but a catalog entry only ships a subset of
6703
+ * formats.
6704
+ */
6705
+ var ModelFormatsSchema = object({
6706
+ onnx: ModelFormatEntrySchema.optional(),
6707
+ coreml: ModelFormatEntrySchema.optional(),
6708
+ openvino: ModelFormatEntrySchema.optional(),
6709
+ tflite: ModelFormatEntrySchema.optional(),
6710
+ pt: ModelFormatEntrySchema.optional()
6711
+ });
6712
+ var ModelCatalogEntrySchema = object({
6713
+ id: string(),
6714
+ name: string(),
6715
+ description: string(),
6716
+ formats: ModelFormatsSchema,
6717
+ inputSize: object({
6718
+ width: number(),
6719
+ height: number()
6720
+ }),
6721
+ labels: array(LabelDefinitionSchema).readonly(),
6722
+ inputLayout: _enum(["nchw", "nhwc"]).optional(),
6723
+ inputNormalization: _enum([
6724
+ "zero-one",
6725
+ "imagenet",
6726
+ "none"
6727
+ ]).optional(),
6728
+ preprocessMode: _enum(["letterbox", "resize"]).optional(),
6729
+ /**
6730
+ * When true, the executor produces a landmark-aligned crop (similarity warp
6731
+ * onto the canonical template) before this step runs, instead of a plain
6732
+ * axis-aligned bbox crop. Required for face-recognition embedders (ArcFace):
6733
+ * their embeddings are only discriminative on an aligned input. The face
6734
+ * detector that produced the parent detail must emit 5 landmarks.
6735
+ */
6736
+ faceAlignment: boolean().optional(),
6737
+ /**
6738
+ * Auxiliary files required at runtime (labels JSON, charset dict, etc.).
6739
+ * Downloaded into the same modelsDir alongside the model file.
6740
+ */
6741
+ extraFiles: array(ModelExtraFileSchema).readonly().optional()
6742
+ });
6743
+ var ConvertTargetSchema = discriminatedUnion("format", [object({
6744
+ format: literal("openvino"),
6745
+ precisions: array(_enum(["fp16", "int8"])).min(1).readonly()
6746
+ }), object({ format: literal("coreml") })]);
6747
+ var ModelConvertMetadataSchema = object({
6748
+ id: string().regex(/^[a-zA-Z0-9._-]+$/),
6749
+ name: string(),
6750
+ labels: array(LabelDefinitionSchema).readonly(),
6751
+ inputSize: object({
6752
+ width: number(),
6753
+ height: number()
6754
+ }),
6755
+ inputLayout: _enum(["nchw", "nhwc"]).optional(),
6756
+ inputNormalization: _enum([
6757
+ "zero-one",
6758
+ "imagenet",
6759
+ "none"
6760
+ ]).optional(),
6761
+ preprocessMode: _enum(["letterbox", "resize"]).optional(),
6762
+ outputFormat: _enum([
6763
+ "yolo",
6764
+ "ssd",
6765
+ "embedding",
6766
+ "classification",
6767
+ "ocr",
6768
+ "segmentation"
6769
+ ]),
6770
+ faceAlignment: boolean().optional()
6771
+ });
6772
+ var ConvertResultSchema = object({
6773
+ entry: ModelCatalogEntrySchema,
6774
+ artifacts: array(object({
6775
+ format: _enum(MODEL_FORMATS),
6776
+ precision: _enum(["fp16", "int8"]).optional(),
6777
+ sizeMB: number(),
6778
+ validated: boolean(),
6779
+ files: array(string()).readonly()
6780
+ })).readonly()
6781
+ });
6782
+ /**
6656
6783
  * Numeric day-of-week: 0 = Sunday … 6 = Saturday (matches `Date.getDay`).
6657
6784
  * Named `RecordingWeekday` to avoid collision with the string-union
6658
6785
  * `Weekday` exported from `interfaces/timezones.ts`.
@@ -15366,6 +15493,54 @@ var EnrichedWidgetMetadataSchema = WidgetMetadataSchema.extend({
15366
15493
  bundleUrl: string()
15367
15494
  });
15368
15495
  method(_void(), array(EnrichedWidgetMetadataSchema).readonly());
15496
+ /**
15497
+ * `custom-model-registry` — collection cap exposing operator-registered
15498
+ * custom detection models. Each provider (today: `addon-model-studio`)
15499
+ * contributes a list of `CustomModelDescriptor`s; the hub auto-concatenates
15500
+ * them across providers (`concatCollection`).
15501
+ *
15502
+ * The detection-pipeline is *aware* of this cap: when at least one provider
15503
+ * exists it unions these descriptors into the per-step model picker and the
15504
+ * runtime model-resolution path, alongside the static catalog. When no
15505
+ * provider exists the consumer no-ops entirely (identical to the catalog-only
15506
+ * behaviour).
15507
+ *
15508
+ * A descriptor carries a full `ModelCatalogEntry` directly — the same shape
15509
+ * the static catalog uses — so the existing download/resolution code consumes
15510
+ * it unchanged. `stepId` is the detection step the model targets
15511
+ * (e.g. `'object-detection'`).
15512
+ */
15513
+ var CustomModelDescriptorSchema = object({
15514
+ stepId: string(),
15515
+ entry: ModelCatalogEntrySchema
15516
+ });
15517
+ method(_void(), array(CustomModelDescriptorSchema).readonly());
15518
+ method(object({
15519
+ nodeId: string(),
15520
+ modelId: string(),
15521
+ format: _enum(MODEL_FORMATS),
15522
+ entry: ModelCatalogEntrySchema
15523
+ }), object({
15524
+ ok: boolean(),
15525
+ /** sha256 of the staged tarball (empty for a hub-local no-op). */
15526
+ sha256: string(),
15527
+ bytes: number(),
15528
+ /** The target node's modelsDir the artifact landed in. */
15529
+ path: string()
15530
+ }), {
15531
+ kind: "mutation",
15532
+ auth: "admin"
15533
+ });
15534
+ method(object({
15535
+ sourceUrl: string(),
15536
+ metadata: ModelConvertMetadataSchema,
15537
+ targets: array(ConvertTargetSchema).min(1).readonly(),
15538
+ calibrationRef: string().optional(),
15539
+ sessionId: string().optional()
15540
+ }), ConvertResultSchema, {
15541
+ kind: "mutation",
15542
+ auth: "admin"
15543
+ });
15369
15544
  var AddonHttpRouteSchema = object({
15370
15545
  method: _enum([
15371
15546
  "GET",
@@ -20349,6 +20524,12 @@ Object.freeze({
20349
20524
  addonId: null,
20350
20525
  access: "create"
20351
20526
  },
20527
+ "customModelRegistry.listModels": {
20528
+ capName: "custom-model-registry",
20529
+ capScope: "system",
20530
+ addonId: null,
20531
+ access: "view"
20532
+ },
20352
20533
  "decoder.createSession": {
20353
20534
  capName: "decoder",
20354
20535
  capScope: "system",
@@ -21573,6 +21754,18 @@ Object.freeze({
21573
21754
  addonId: null,
21574
21755
  access: "view"
21575
21756
  },
21757
+ "modelConvert.convert": {
21758
+ capName: "model-convert",
21759
+ capScope: "system",
21760
+ addonId: null,
21761
+ access: "create"
21762
+ },
21763
+ "modelDistributor.distributeModel": {
21764
+ capName: "model-distributor",
21765
+ capScope: "system",
21766
+ addonId: null,
21767
+ access: "create"
21768
+ },
21576
21769
  "motion.isDetected": {
21577
21770
  capName: "motion",
21578
21771
  capScope: "device",
package/dist/addon.mjs CHANGED
@@ -4628,7 +4628,7 @@ function _instanceof(cls, params = {}) {
4628
4628
  return inst;
4629
4629
  }
4630
4630
  //#endregion
4631
- //#region ../types/dist/sleep-B1dKJAMJ.mjs
4631
+ //#region ../types/dist/sleep-BV7rLc6Y.mjs
4632
4632
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4633
4633
  EventCategory["SystemBoot"] = "system.boot";
4634
4634
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -5107,6 +5107,12 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
5107
5107
  * Payload: `{ deviceId, childDeviceIds, hiddenChildIds }`.
5108
5108
  */
5109
5109
  EventCategory["AccessoriesChanged"] = "accessories.onAccessoriesChanged";
5110
+ /**
5111
+ * Progress update from a running model conversion job.
5112
+ * Payload: `{ kind: 'model-convert', phase, sessionId?, pct?, detail? }`.
5113
+ * Emitted by `addon-model-studio` on the converting node.
5114
+ */
5115
+ EventCategory["ModelConvertProgress"] = "model-convert.progress";
5110
5116
  return EventCategory;
5111
5117
  }({});
5112
5118
  Object.fromEntries([
@@ -6644,6 +6650,13 @@ object({
6644
6650
  unreachable: number()
6645
6651
  })
6646
6652
  });
6653
+ var LabelDefinitionSchema = object({
6654
+ id: string(),
6655
+ name: string(),
6656
+ category: string().optional(),
6657
+ description: string().optional(),
6658
+ icon: string().optional()
6659
+ });
6647
6660
  var MODEL_FORMATS = [
6648
6661
  "onnx",
6649
6662
  "coreml",
@@ -6652,6 +6665,120 @@ var MODEL_FORMATS = [
6652
6665
  "pt"
6653
6666
  ];
6654
6667
  /**
6668
+ * Multi-file format payload.
6669
+ *
6670
+ * - Directory formats (`isDirectory: true`, e.g. `.mlpackage`): files
6671
+ * relative to the directory root — the downloader fetches each from
6672
+ * `{url}/{file}` into `{modelDir}/{file}`. If omitted, it probes the
6673
+ * HuggingFace API (slower).
6674
+ * - Single-file formats (no `isDirectory`, e.g. OpenVINO IR): sibling
6675
+ * files fetched from the SAME remote directory as `url` and stored flat
6676
+ * alongside the main file — e.g. `['camstack-yolov9t.bin']` for the IR
6677
+ * weights next to `camstack-yolov9t.xml`.
6678
+ */
6679
+ var ModelFormatEntrySchema = object({
6680
+ url: string(),
6681
+ sizeMB: number(),
6682
+ /** Whether this format is a directory bundle (e.g., .mlpackage) rather than a single file */
6683
+ isDirectory: boolean().optional(),
6684
+ /** Multi-file payload (directory members or sibling files). */
6685
+ files: array(string()).readonly().optional(),
6686
+ /** Runtime(s) that can use this format. If omitted, inferred from ModelFormat key */
6687
+ runtimes: array(_enum(["node", "python"])).readonly().optional()
6688
+ });
6689
+ /**
6690
+ * Extra file that must be downloaded alongside the model (e.g., labels JSON, dict.txt).
6691
+ * The downloader fetches from `url` and saves to `{modelsDir}/{filename}`.
6692
+ */
6693
+ var ModelExtraFileSchema = object({
6694
+ url: string(),
6695
+ filename: string(),
6696
+ sizeMB: number()
6697
+ });
6698
+ /**
6699
+ * Per-format payload map. Modelled as an explicit object (one optional key
6700
+ * per `ModelFormat`) rather than `z.record(enum, …)` — zod v4's enum-keyed
6701
+ * record requires every key, but a catalog entry only ships a subset of
6702
+ * formats.
6703
+ */
6704
+ var ModelFormatsSchema = object({
6705
+ onnx: ModelFormatEntrySchema.optional(),
6706
+ coreml: ModelFormatEntrySchema.optional(),
6707
+ openvino: ModelFormatEntrySchema.optional(),
6708
+ tflite: ModelFormatEntrySchema.optional(),
6709
+ pt: ModelFormatEntrySchema.optional()
6710
+ });
6711
+ var ModelCatalogEntrySchema = object({
6712
+ id: string(),
6713
+ name: string(),
6714
+ description: string(),
6715
+ formats: ModelFormatsSchema,
6716
+ inputSize: object({
6717
+ width: number(),
6718
+ height: number()
6719
+ }),
6720
+ labels: array(LabelDefinitionSchema).readonly(),
6721
+ inputLayout: _enum(["nchw", "nhwc"]).optional(),
6722
+ inputNormalization: _enum([
6723
+ "zero-one",
6724
+ "imagenet",
6725
+ "none"
6726
+ ]).optional(),
6727
+ preprocessMode: _enum(["letterbox", "resize"]).optional(),
6728
+ /**
6729
+ * When true, the executor produces a landmark-aligned crop (similarity warp
6730
+ * onto the canonical template) before this step runs, instead of a plain
6731
+ * axis-aligned bbox crop. Required for face-recognition embedders (ArcFace):
6732
+ * their embeddings are only discriminative on an aligned input. The face
6733
+ * detector that produced the parent detail must emit 5 landmarks.
6734
+ */
6735
+ faceAlignment: boolean().optional(),
6736
+ /**
6737
+ * Auxiliary files required at runtime (labels JSON, charset dict, etc.).
6738
+ * Downloaded into the same modelsDir alongside the model file.
6739
+ */
6740
+ extraFiles: array(ModelExtraFileSchema).readonly().optional()
6741
+ });
6742
+ var ConvertTargetSchema = discriminatedUnion("format", [object({
6743
+ format: literal("openvino"),
6744
+ precisions: array(_enum(["fp16", "int8"])).min(1).readonly()
6745
+ }), object({ format: literal("coreml") })]);
6746
+ var ModelConvertMetadataSchema = object({
6747
+ id: string().regex(/^[a-zA-Z0-9._-]+$/),
6748
+ name: string(),
6749
+ labels: array(LabelDefinitionSchema).readonly(),
6750
+ inputSize: object({
6751
+ width: number(),
6752
+ height: number()
6753
+ }),
6754
+ inputLayout: _enum(["nchw", "nhwc"]).optional(),
6755
+ inputNormalization: _enum([
6756
+ "zero-one",
6757
+ "imagenet",
6758
+ "none"
6759
+ ]).optional(),
6760
+ preprocessMode: _enum(["letterbox", "resize"]).optional(),
6761
+ outputFormat: _enum([
6762
+ "yolo",
6763
+ "ssd",
6764
+ "embedding",
6765
+ "classification",
6766
+ "ocr",
6767
+ "segmentation"
6768
+ ]),
6769
+ faceAlignment: boolean().optional()
6770
+ });
6771
+ var ConvertResultSchema = object({
6772
+ entry: ModelCatalogEntrySchema,
6773
+ artifacts: array(object({
6774
+ format: _enum(MODEL_FORMATS),
6775
+ precision: _enum(["fp16", "int8"]).optional(),
6776
+ sizeMB: number(),
6777
+ validated: boolean(),
6778
+ files: array(string()).readonly()
6779
+ })).readonly()
6780
+ });
6781
+ /**
6655
6782
  * Numeric day-of-week: 0 = Sunday … 6 = Saturday (matches `Date.getDay`).
6656
6783
  * Named `RecordingWeekday` to avoid collision with the string-union
6657
6784
  * `Weekday` exported from `interfaces/timezones.ts`.
@@ -15365,6 +15492,54 @@ var EnrichedWidgetMetadataSchema = WidgetMetadataSchema.extend({
15365
15492
  bundleUrl: string()
15366
15493
  });
15367
15494
  method(_void(), array(EnrichedWidgetMetadataSchema).readonly());
15495
+ /**
15496
+ * `custom-model-registry` — collection cap exposing operator-registered
15497
+ * custom detection models. Each provider (today: `addon-model-studio`)
15498
+ * contributes a list of `CustomModelDescriptor`s; the hub auto-concatenates
15499
+ * them across providers (`concatCollection`).
15500
+ *
15501
+ * The detection-pipeline is *aware* of this cap: when at least one provider
15502
+ * exists it unions these descriptors into the per-step model picker and the
15503
+ * runtime model-resolution path, alongside the static catalog. When no
15504
+ * provider exists the consumer no-ops entirely (identical to the catalog-only
15505
+ * behaviour).
15506
+ *
15507
+ * A descriptor carries a full `ModelCatalogEntry` directly — the same shape
15508
+ * the static catalog uses — so the existing download/resolution code consumes
15509
+ * it unchanged. `stepId` is the detection step the model targets
15510
+ * (e.g. `'object-detection'`).
15511
+ */
15512
+ var CustomModelDescriptorSchema = object({
15513
+ stepId: string(),
15514
+ entry: ModelCatalogEntrySchema
15515
+ });
15516
+ method(_void(), array(CustomModelDescriptorSchema).readonly());
15517
+ method(object({
15518
+ nodeId: string(),
15519
+ modelId: string(),
15520
+ format: _enum(MODEL_FORMATS),
15521
+ entry: ModelCatalogEntrySchema
15522
+ }), object({
15523
+ ok: boolean(),
15524
+ /** sha256 of the staged tarball (empty for a hub-local no-op). */
15525
+ sha256: string(),
15526
+ bytes: number(),
15527
+ /** The target node's modelsDir the artifact landed in. */
15528
+ path: string()
15529
+ }), {
15530
+ kind: "mutation",
15531
+ auth: "admin"
15532
+ });
15533
+ method(object({
15534
+ sourceUrl: string(),
15535
+ metadata: ModelConvertMetadataSchema,
15536
+ targets: array(ConvertTargetSchema).min(1).readonly(),
15537
+ calibrationRef: string().optional(),
15538
+ sessionId: string().optional()
15539
+ }), ConvertResultSchema, {
15540
+ kind: "mutation",
15541
+ auth: "admin"
15542
+ });
15368
15543
  var AddonHttpRouteSchema = object({
15369
15544
  method: _enum([
15370
15545
  "GET",
@@ -20348,6 +20523,12 @@ Object.freeze({
20348
20523
  addonId: null,
20349
20524
  access: "create"
20350
20525
  },
20526
+ "customModelRegistry.listModels": {
20527
+ capName: "custom-model-registry",
20528
+ capScope: "system",
20529
+ addonId: null,
20530
+ access: "view"
20531
+ },
20351
20532
  "decoder.createSession": {
20352
20533
  capName: "decoder",
20353
20534
  capScope: "system",
@@ -21572,6 +21753,18 @@ Object.freeze({
21572
21753
  addonId: null,
21573
21754
  access: "view"
21574
21755
  },
21756
+ "modelConvert.convert": {
21757
+ capName: "model-convert",
21758
+ capScope: "system",
21759
+ addonId: null,
21760
+ access: "create"
21761
+ },
21762
+ "modelDistributor.distributeModel": {
21763
+ capName: "model-distributor",
21764
+ capScope: "system",
21765
+ addonId: null,
21766
+ access: "create"
21767
+ },
21575
21768
  "motion.isDetected": {
21576
21769
  capName: "motion",
21577
21770
  capScope: "device",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-homeassistant",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Home Assistant device provider addon for CamStack",
5
5
  "keywords": [
6
6
  "camstack",