@camstack/types 1.2.152 → 1.2.154

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/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_event_category = require("./event-category-BaEgqJNv.js");
3
- const require_sleep = require("./sleep-DVTaZZHP.js");
2
+ const require_event_category = require("./event-category-b8kBSOTT.js");
3
+ const require_sleep = require("./sleep-Dp0uukHR.js");
4
4
  const require_canonical_hash = require("./canonical-hash-DNV8S5ET.js");
5
5
  const require_enums = require("./enums.js");
6
6
  const require_err_msg = require("./err-msg-COpsHMw2.js");
@@ -25568,6 +25568,125 @@ onStatusChanged: { data: zod.z.object({
25568
25568
  volatileStateFields: ["lastUpdated"]
25569
25569
  };
25570
25570
  //#endregion
25571
+ //#region src/capabilities/network-link.cap.ts
25572
+ /**
25573
+ * How a device reaches the network, and how well.
25574
+ *
25575
+ * NOT `connectivity`: that cap is an UPSTREAM system's binary view of whether
25576
+ * an entity is reachable (a Home Assistant `binary_sensor` with
25577
+ * `device_class: connectivity`). This one is the device's OWN link — the
25578
+ * medium it is on and the signal it sees — the way `battery` is the device's
25579
+ * own charge.
25580
+ *
25581
+ * `'wifi'`, `'ethernet'` and `'cellular'` are links the firmware actually
25582
+ * reported. `'unknown'` is the ABSENCE of an answer — the provider has
25583
+ * registered the capability but has not read the link yet (D315: unknown is
25584
+ * not empty). Consumers skip it rather than draw a wire or a bar.
25585
+ */
25586
+ var NETWORK_LINK_TYPES = [
25587
+ "wifi",
25588
+ "ethernet",
25589
+ "cellular",
25590
+ "unknown"
25591
+ ];
25592
+ /**
25593
+ * Network-link snapshot. Same shape for every provider (a Reolink wifi
25594
+ * camera, a Home Assistant device with a signal-strength sensor, a Tapo
25595
+ * plug): one slice under `device.runtimeState['network-link']`, one badge,
25596
+ * one Home Assistant projection.
25597
+ */
25598
+ var NetworkLinkStatusSchema = zod.z.object({
25599
+ /** The link the device is on. `'unknown'` = not read yet, not "no link". */
25600
+ type: zod.z.enum(NETWORK_LINK_TYPES),
25601
+ /**
25602
+ * Link quality, 0..100 inclusive, normalised by the provider from whatever
25603
+ * the firmware reports (bars, RSSI, a vendor scale). **`null` means NOT
25604
+ * KNOWN or NOT APPLICABLE** — a wired link has no signal, and a wireless
25605
+ * one whose reading has not landed must not be drawn at 0 %. Consumers
25606
+ * SKIP a null rather than coerce it.
25607
+ */
25608
+ signalPercent: zod.z.number().min(0).max(100).nullable(),
25609
+ /** Raw received signal strength in dBm, when the firmware reports one. */
25610
+ rssiDbm: zod.z.number().optional(),
25611
+ /** Network name of a wireless link, when the firmware reports it. */
25612
+ ssid: zod.z.string().optional(),
25613
+ /** Ms epoch of the last observation. Lets consumers reason about freshness. */
25614
+ lastUpdated: zod.z.number()
25615
+ });
25616
+ /** The slice a provider seeds before its first read: nothing is known yet. */
25617
+ var NETWORK_LINK_UNKNOWN = {
25618
+ type: "unknown",
25619
+ signalPercent: null,
25620
+ lastUpdated: 0
25621
+ };
25622
+ /**
25623
+ * Normalise a signal the firmware reports as BARS (0..`maxBars`) to 0..100.
25624
+ * Out-of-range or non-finite input is not a reading: `null`.
25625
+ */
25626
+ function signalPercentFromBars(bars, maxBars) {
25627
+ if (bars === void 0 || !Number.isFinite(bars) || maxBars <= 0) return null;
25628
+ if (bars < 0 || bars > maxBars) return null;
25629
+ return Math.round(bars / maxBars * 100);
25630
+ }
25631
+ /**
25632
+ * Normalise an RSSI in dBm to 0..100 on the usual wifi scale: -100 dBm and
25633
+ * below is 0 %, -50 dBm and above is 100 %, linear between. Non-finite or
25634
+ * positive input is not an RSSI: `null`.
25635
+ */
25636
+ function signalPercentFromRssi(rssiDbm) {
25637
+ if (rssiDbm === void 0 || !Number.isFinite(rssiDbm) || rssiDbm > 0) return null;
25638
+ return Math.round((Math.min(-50, Math.max(-100, rssiDbm)) + 100) * 2);
25639
+ }
25640
+ var networkLinkCapability = {
25641
+ name: "network-link",
25642
+ scope: "device",
25643
+ deviceNative: true,
25644
+ mode: "singleton",
25645
+ deviceTypes: [
25646
+ require_sleep.DeviceType.Camera,
25647
+ require_sleep.DeviceType.Sensor,
25648
+ require_sleep.DeviceType.Button,
25649
+ require_sleep.DeviceType.Switch,
25650
+ require_sleep.DeviceType.Light,
25651
+ require_sleep.DeviceType.Lock,
25652
+ require_sleep.DeviceType.Siren
25653
+ ],
25654
+ methods: {},
25655
+ events: {
25656
+ /**
25657
+ * Emitted whenever the cached status changes (a link switch, a signal
25658
+ * reading that moved). Mirrored on the parent chain by the
25659
+ * DeviceEventPropagator like `battery.onStatusChanged`.
25660
+ */
25661
+ onStatusChanged: { data: zod.z.object({
25662
+ deviceId: zod.z.number(),
25663
+ status: NetworkLinkStatusSchema
25664
+ }) } },
25665
+ status: {
25666
+ schema: NetworkLinkStatusSchema,
25667
+ kind: "push",
25668
+ empty: NETWORK_LINK_UNKNOWN
25669
+ },
25670
+ /**
25671
+ * Runtime-state slice — every provider stores the same shape under
25672
+ * `device.runtimeState['network-link']`, read once by the badge and the
25673
+ * Home Assistant projector regardless of the driver.
25674
+ */
25675
+ runtimeState: NetworkLinkStatusSchema,
25676
+ /**
25677
+ * Runtime-state durability: **restored** — a link reading is slow to
25678
+ * change and a sleeping battery camera may not report for hours; the
25679
+ * restored slice is what the badge shows until the next read.
25680
+ *
25681
+ * See `RuntimeStateDurability`. Enforced by
25682
+ * `scripts/check-runtime-state-durability.ts`.
25683
+ */
25684
+ durability: "restored",
25685
+ /** Clock fields: written, but excluded from the compare that decides
25686
+ * whether persisting is worth a SQLite commit. */
25687
+ volatileStateFields: ["lastUpdated"]
25688
+ };
25689
+ //#endregion
25571
25690
  //#region src/capabilities/binary.cap.ts
25572
25691
  /**
25573
25692
  * Generic boolean sensor — last-resort fallback when no domain-
@@ -31509,6 +31628,431 @@ var ptzAutotrackCapability = {
31509
31628
  durability: "session"
31510
31629
  };
31511
31630
  //#endregion
31631
+ //#region src/capabilities/navigation.cap.ts
31632
+ /**
31633
+ * `navigation` — a device-scoped capability that natively expresses the FULL
31634
+ * navigation / action surface of a robot that DRIVES ITSELF and carries an
31635
+ * on-board camera (the Dreame robot-vacuum camera is the first provider).
31636
+ *
31637
+ * Why a NEW cap rather than overloading `ptz`:
31638
+ * - `ptz` moves a *gimbal* on a fixed camera (pan/tilt/zoom of the lens). A
31639
+ * robot vacuum has no gimbal — the whole chassis drives, turns and spins.
31640
+ * The two are different physical models: PTZ is absolute-position + presets,
31641
+ * navigation is momentary drive nudges + discrete robot ACTIONS
31642
+ * (dock / spot-clean / follow-pet / go-to-point / …).
31643
+ * - This cap is the SOURCE OF TRUTH. Two consumers adapt from it rather than
31644
+ * the reverse:
31645
+ * 1. a native CamStack navigation panel (data-driven from `listActions`
31646
+ * / `getOptions`), and
31647
+ * 2. the PTZ surface — a thin adapter mimics `ptz` from `navigation` so a
31648
+ * robot camera shows up in the existing PTZ control path without every
31649
+ * PTZ provider learning about robots. The mapping lives in the adapter,
31650
+ * not here (see the addon design note):
31651
+ * ptz.continuousMove({pan,tilt}) → navigation.move({pan,tilt})
31652
+ * ptz.stop() → navigation.stop()
31653
+ * ptz.goHome() → navigation.runAction('goHome')
31654
+ * ptz.getPresets() → navigation.listActions() (id→preset)
31655
+ * ptz.goToPreset(id) → navigation.runAction(id)
31656
+ *
31657
+ * ## Continuous drive
31658
+ *
31659
+ * `move` is MOMENTARY. Fluid navigation comes from the UI (or the PTZ adapter)
31660
+ * sending `move({pan,tilt})` REPEATEDLY at ~1 Hz while a direction is held, and
31661
+ * one `stop()` on release — exactly like the robot app's remote-drive joystick.
31662
+ * The provider forwards EACH `move` to one drive write; it must NOT debounce or
31663
+ * coalesce them. The UI owns the cadence.
31664
+ *
31665
+ * ## The action dictionary
31666
+ *
31667
+ * The discrete controls (dock / locate / spot-clean / follow / flash / sounds)
31668
+ * are a DATA-DRIVEN dictionary the cap exposes via `listActions()`. Each entry
31669
+ * carries `{ id, kind, label, icon }` (plus `soundId` for sound entries) so the
31670
+ * native panel AND the PTZ mimic render buttons WITHOUT hardcoding a
31671
+ * vendor-specific list. `kind: 'action'` entries are triggered with
31672
+ * `runAction({ actionId })`; `kind: 'sound'` entries with `playSound({ soundId })`
31673
+ * (the entry carries the `soundId` to pass). The general primitives — `move`,
31674
+ * `stop`, `goToPoint` — stay as first-class methods, not dictionary entries.
31675
+ *
31676
+ * NOTE (provider wiring): the first provider (Dreame) drives this with the RAW
31677
+ * `callAction(siid,aiid,in)` / `setProperty({siid,piid,value})` MIoT primitives
31678
+ * that the currently-published `@apocaliss92/nodedreame` already exposes on
31679
+ * every device handle. A future nodedreame publish adds a typed
31680
+ * `DreameCameraController` (drive / playPetSound / spotClean / findPet / …); the
31681
+ * provider can then swap the raw calls for the typed methods with no change to
31682
+ * THIS contract.
31683
+ */
31684
+ /**
31685
+ * A momentary drive nudge. The robot MOVES (no gimbal) for as long as the caller
31686
+ * keeps sending nudges (~1 Hz); an explicit `stop` (or letting the nudges lapse)
31687
+ * halts it.
31688
+ *
31689
+ * - `pan` — turn: negative = left, positive = right, 0 = straight.
31690
+ * - `tilt` — throttle: positive = forward, negative = spin / turn-around.
31691
+ * - `speed` — optional intensity hint [0, 1]; the provider may scale the drive
31692
+ * vector by it (drivers without proportional drive ignore it).
31693
+ *
31694
+ * `pan` / `tilt` are normalized [-1, 1]. Both optional so a caller can nudge one
31695
+ * axis alone; an all-undefined nudge is a no-op.
31696
+ */
31697
+ var NavigationMoveCommandSchema = zod.z.object({
31698
+ pan: zod.z.number().min(-1).max(1).optional(),
31699
+ tilt: zod.z.number().min(-1).max(1).optional(),
31700
+ speed: zod.z.number().min(0).max(1).optional()
31701
+ });
31702
+ /**
31703
+ * The enumerated discrete actions a navigation-capable robot can perform via
31704
+ * `runAction`. This is the CLOSED vocabulary; a given device advertises the
31705
+ * subset it supports through `listActions`. Sounds are NOT here — they go through
31706
+ * `playSound` (see the `sound` dictionary entries).
31707
+ */
31708
+ var NavigationActionIdSchema = zod.z.enum([
31709
+ "goHome",
31710
+ "locate",
31711
+ "spotClean",
31712
+ "findPet",
31713
+ "personFollow",
31714
+ "stop",
31715
+ "startClean",
31716
+ "pauseClean",
31717
+ "dockWash",
31718
+ "autoEmpty",
31719
+ "flashOn",
31720
+ "flashOff"
31721
+ ]);
31722
+ /** Whether a dictionary entry is a `runAction` action or a `playSound` sound. */
31723
+ var NavigationEntryKindSchema = zod.z.enum(["action", "sound"]);
31724
+ /**
31725
+ * One entry in the navigation action dictionary — the DATA-DRIVEN unit both the
31726
+ * native panel and the PTZ mimic render as a button.
31727
+ *
31728
+ * - `id` — stable id. For `kind:'action'` it is a {@link NavigationActionId}
31729
+ * (pass to `runAction`); for `kind:'sound'` it is a namespaced id
31730
+ * (`sound:meow`) whose `soundId` is passed to `playSound`.
31731
+ * - `icon` — icon HINT (lucide-style name; the UI maps it to its own set).
31732
+ * - `label` — operator-facing English label.
31733
+ * - `soundId` — wire sound id, present only on `kind:'sound'` entries.
31734
+ * - `enabled` — per-device FEATURE FLAG. `listActions` reports it so the UI /
31735
+ * PTZ render ONLY enabled entries. Data-driven: the provider
31736
+ * flips it from config, never by editing code.
31737
+ */
31738
+ var NavigationActionEntrySchema = zod.z.object({
31739
+ id: zod.z.string(),
31740
+ kind: NavigationEntryKindSchema,
31741
+ label: zod.z.string(),
31742
+ icon: zod.z.string(),
31743
+ /** Present only on `kind:'sound'` entries — the id to pass to `playSound`. */
31744
+ soundId: zod.z.number().int().optional(),
31745
+ /** Per-device feature flag — render this entry only when true. */
31746
+ enabled: zod.z.boolean()
31747
+ });
31748
+ /**
31749
+ * Canonical dictionary of every navigation control (discrete actions + sounds)
31750
+ * with its default label + icon hint. A provider filters this to the subset a
31751
+ * device supports (and may override a label). Exported so the provider AND the
31752
+ * UI share ONE list instead of re-deriving labels / ids independently.
31753
+ *
31754
+ * Icons are lucide-style hints; the viewer maps them to its own icon set. Every
31755
+ * catalog default is `enabled: true`; a provider overrides per-device from
31756
+ * config (data-driven — enabling / disabling one later is a config change, not a
31757
+ * code change).
31758
+ */
31759
+ var NAVIGATION_ACTION_CATALOG = [
31760
+ {
31761
+ id: "startClean",
31762
+ kind: "action",
31763
+ label: "Start cleaning",
31764
+ icon: "play",
31765
+ enabled: true
31766
+ },
31767
+ {
31768
+ id: "pauseClean",
31769
+ kind: "action",
31770
+ label: "Pause cleaning",
31771
+ icon: "pause",
31772
+ enabled: true
31773
+ },
31774
+ {
31775
+ id: "stop",
31776
+ kind: "action",
31777
+ label: "Stop",
31778
+ icon: "hand",
31779
+ enabled: true
31780
+ },
31781
+ {
31782
+ id: "goHome",
31783
+ kind: "action",
31784
+ label: "Return to dock",
31785
+ icon: "home",
31786
+ enabled: true
31787
+ },
31788
+ {
31789
+ id: "locate",
31790
+ kind: "action",
31791
+ label: "Locate",
31792
+ icon: "bell",
31793
+ enabled: true
31794
+ },
31795
+ {
31796
+ id: "spotClean",
31797
+ kind: "action",
31798
+ label: "Spot clean here",
31799
+ icon: "crosshair",
31800
+ enabled: true
31801
+ },
31802
+ {
31803
+ id: "findPet",
31804
+ kind: "action",
31805
+ label: "Find pet",
31806
+ icon: "paw-print",
31807
+ enabled: true
31808
+ },
31809
+ {
31810
+ id: "personFollow",
31811
+ kind: "action",
31812
+ label: "Follow me",
31813
+ icon: "footprints",
31814
+ enabled: true
31815
+ },
31816
+ {
31817
+ id: "dockWash",
31818
+ kind: "action",
31819
+ label: "Wash mop",
31820
+ icon: "droplets",
31821
+ enabled: true
31822
+ },
31823
+ {
31824
+ id: "autoEmpty",
31825
+ kind: "action",
31826
+ label: "Empty dustbin",
31827
+ icon: "trash-2",
31828
+ enabled: true
31829
+ },
31830
+ {
31831
+ id: "flashOn",
31832
+ kind: "action",
31833
+ label: "Flash on",
31834
+ icon: "flashlight",
31835
+ enabled: true
31836
+ },
31837
+ {
31838
+ id: "flashOff",
31839
+ kind: "action",
31840
+ label: "Flash off",
31841
+ icon: "flashlight-off",
31842
+ enabled: true
31843
+ },
31844
+ {
31845
+ id: "sound:meow",
31846
+ kind: "sound",
31847
+ label: "Meow",
31848
+ icon: "cat",
31849
+ soundId: 684,
31850
+ enabled: true
31851
+ },
31852
+ {
31853
+ id: "sound:bark",
31854
+ kind: "sound",
31855
+ label: "Woof",
31856
+ icon: "dog",
31857
+ soundId: 685,
31858
+ enabled: true
31859
+ },
31860
+ {
31861
+ id: "sound:footsteps",
31862
+ kind: "sound",
31863
+ label: "Footsteps",
31864
+ icon: "footprints",
31865
+ soundId: 686,
31866
+ enabled: true
31867
+ },
31868
+ {
31869
+ id: "sound:purring",
31870
+ kind: "sound",
31871
+ label: "Purring",
31872
+ icon: "cat",
31873
+ soundId: 687,
31874
+ enabled: true
31875
+ },
31876
+ {
31877
+ id: "sound:tickTock",
31878
+ kind: "sound",
31879
+ label: "Tick-tock",
31880
+ icon: "clock",
31881
+ soundId: 688,
31882
+ enabled: true
31883
+ }
31884
+ ];
31885
+ /** Coordinates for `goToPoint` — a point on the robot's live map. */
31886
+ var NavigationPointSchema = zod.z.object({
31887
+ x: zod.z.number(),
31888
+ y: zod.z.number()
31889
+ });
31890
+ /**
31891
+ * Per-device FEATURE-FLAG report for the general (non-dictionary) primitives.
31892
+ * The cap reports which are enabled so the UI / PTZ render only the controls
31893
+ * that are turned on for THIS device. Data-driven: the provider derives these
31894
+ * from config + probe, never hardcoded in the UI. The per-DICTIONARY-entry flags
31895
+ * live on {@link NavigationActionEntrySchema.enabled}; these gate the primitives
31896
+ * that are not dictionary entries.
31897
+ *
31898
+ * - `move` / `stop` — the momentary drive joystick.
31899
+ * - `goToPoint` — send-to-map-coordinate. Ships OFF on Dreame until the
31900
+ * map-coordinate plumbing is wired.
31901
+ * - `runAction` — the discrete action buttons (dictionary `kind:'action'`).
31902
+ * - `playSound` — the sound buttons (dictionary `kind:'sound'`).
31903
+ * - `light` — the on/off fill-light toggle (works anytime).
31904
+ * - `lightMode` — the auto/manual selector + manual level slider (a
31905
+ * camera-service control; needs an active stream).
31906
+ */
31907
+ var NavigationFeaturesSchema = zod.z.object({
31908
+ move: zod.z.boolean(),
31909
+ stop: zod.z.boolean(),
31910
+ goToPoint: zod.z.boolean(),
31911
+ runAction: zod.z.boolean(),
31912
+ playSound: zod.z.boolean(),
31913
+ light: zod.z.boolean(),
31914
+ lightMode: zod.z.boolean()
31915
+ });
31916
+ /** Light mode: `auto` lets the camera choose brightness; `manual` uses `level`. */
31917
+ var NavigationLightModeSchema = zod.z.enum(["auto", "manual"]);
31918
+ /** Manual fill-light level bounds (the camera-service accepts 40..100). */
31919
+ var NAVIGATION_LIGHT_LEVEL_MIN = 40;
31920
+ var NAVIGATION_LIGHT_LEVEL_MAX = 100;
31921
+ /** Coarse work mode the robot reports — drives the UI's active-state chips. */
31922
+ var NavigationModeSchema = zod.z.enum([
31923
+ "idle",
31924
+ "cleaning",
31925
+ "spot",
31926
+ "following",
31927
+ "goto",
31928
+ "returning",
31929
+ "paused",
31930
+ "unknown"
31931
+ ]);
31932
+ /**
31933
+ * Live navigation state so the UI can reflect what the robot is doing:
31934
+ * - `mode` — coarse activity (idle / cleaning / following / …).
31935
+ * - `following` — person/pet follow is currently armed.
31936
+ * - `flash` — the on-camera fill light is on.
31937
+ * - `lightMode` — auto vs manual fill-light mode.
31938
+ * - `lightLevel` — manual fill-light level (40..100); meaningful when
31939
+ * `lightMode === 'manual'`.
31940
+ */
31941
+ var NavigationStatusSchema = zod.z.object({
31942
+ mode: NavigationModeSchema,
31943
+ following: zod.z.boolean(),
31944
+ flash: zod.z.boolean(),
31945
+ lightMode: NavigationLightModeSchema,
31946
+ lightLevel: zod.z.number().min(40).max(100),
31947
+ /** Ms epoch when the slice was last updated. */
31948
+ lastChangedAt: zod.z.number()
31949
+ });
31950
+ /**
31951
+ * Runtime-state slice owned by this cap (kernel-managed: validated, mirrored,
31952
+ * observable). Adds `lastFetchedAt` on top of the status shape per the
31953
+ * convention.
31954
+ */
31955
+ var NavigationRuntimeStateSchema = NavigationStatusSchema.extend({ lastFetchedAt: zod.z.number() });
31956
+ var navigationCapability = {
31957
+ name: "navigation",
31958
+ scope: "device",
31959
+ deviceNative: true,
31960
+ mode: "singleton",
31961
+ deviceTypes: [require_sleep.DeviceType.Camera],
31962
+ deviceConfig: { ui: {
31963
+ kind: "widget",
31964
+ widgetId: "host/navigation-panel",
31965
+ tab: "navigation",
31966
+ topTab: true,
31967
+ label: "Navigation",
31968
+ order: 0
31969
+ } },
31970
+ methods: {
31971
+ /**
31972
+ * Momentary drive nudge (the robot moves). `protected` — mirrors
31973
+ * `ptz.continuousMove` so the Viewer navigation panel (and the PTZ-mimic
31974
+ * path) works for any authenticated user, not admin-only. The UI sends
31975
+ * these at ~1 Hz while a control is held; the provider forwards each one to
31976
+ * a single drive write WITHOUT debouncing.
31977
+ */
31978
+ move: require_sleep.method(NavigationMoveCommandSchema.extend({ deviceId: zod.z.number() }), zod.z.void(), { kind: "mutation" }),
31979
+ /** Halt all motion immediately (zero drive vector). */
31980
+ stop: require_sleep.method(zod.z.object({ deviceId: zod.z.number() }), zod.z.void(), { kind: "mutation" }),
31981
+ /** Send the robot to a point on its live map. */
31982
+ goToPoint: require_sleep.method(NavigationPointSchema.extend({ deviceId: zod.z.number() }), zod.z.void(), { kind: "mutation" }),
31983
+ /**
31984
+ * Enumerate the discrete controls THIS device supports (data-driven UI +
31985
+ * PTZ mimic). Camera-probed subset of {@link NAVIGATION_ACTION_CATALOG}.
31986
+ */
31987
+ listActions: require_sleep.method(zod.z.object({ deviceId: zod.z.number() }), zod.z.array(NavigationActionEntrySchema)),
31988
+ /**
31989
+ * Run one discrete action (a `kind:'action'` dictionary entry). Invalid /
31990
+ * unsupported action ids are rejected by the provider.
31991
+ */
31992
+ runAction: require_sleep.method(zod.z.object({
31993
+ deviceId: zod.z.number(),
31994
+ actionId: NavigationActionIdSchema
31995
+ }), zod.z.void(), { kind: "mutation" }),
31996
+ /** Play a sound by its wire id (the `soundId` of a `kind:'sound'` entry). */
31997
+ playSound: require_sleep.method(zod.z.object({
31998
+ deviceId: zod.z.number(),
31999
+ soundId: zod.z.number().int()
32000
+ }), zod.z.void(), { kind: "mutation" }),
32001
+ /**
32002
+ * Turn the on-camera fill light on / off (the `OpenFullLight` control —
32003
+ * works anytime, no active stream required).
32004
+ */
32005
+ setLightOn: require_sleep.method(zod.z.object({
32006
+ deviceId: zod.z.number(),
32007
+ on: zod.z.boolean()
32008
+ }), zod.z.void(), { kind: "mutation" }),
32009
+ /**
32010
+ * Set the fill-light mode (auto vs manual). `manual` optionally carries the
32011
+ * initial `level`. The auto/manual + level control is a CAMERA-service
32012
+ * action that generally needs an active camera stream/monitor session — the
32013
+ * UI shows the manual level slider ONLY when `mode === 'manual'`.
32014
+ */
32015
+ setLightMode: require_sleep.method(zod.z.object({
32016
+ deviceId: zod.z.number(),
32017
+ mode: NavigationLightModeSchema,
32018
+ level: zod.z.number().min(40).max(100).optional()
32019
+ }), zod.z.void(), { kind: "mutation" }),
32020
+ /** Set the MANUAL fill-light level (40..100). Implies `manual` mode. */
32021
+ setLightLevel: require_sleep.method(zod.z.object({
32022
+ deviceId: zod.z.number(),
32023
+ level: zod.z.number().min(40).max(100)
32024
+ }), zod.z.void(), { kind: "mutation" }),
32025
+ /**
32026
+ * Per-device FEATURE-FLAG report for the general primitives — drives which
32027
+ * controls the UI shows (the per-entry flags for the dictionary come back on
32028
+ * `listActions`).
32029
+ */
32030
+ getFeatures: require_sleep.method(zod.z.object({ deviceId: zod.z.number() }), NavigationFeaturesSchema)
32031
+ },
32032
+ events: { onStatusChanged: { data: zod.z.object({
32033
+ deviceId: zod.z.number(),
32034
+ status: NavigationStatusSchema
32035
+ }) } },
32036
+ status: {
32037
+ schema: NavigationStatusSchema,
32038
+ kind: "push"
32039
+ },
32040
+ /**
32041
+ * Runtime-state slice mirrored by the kernel. The navigation panel watches it
32042
+ * for live mode / follow / flash changes.
32043
+ */
32044
+ runtimeState: NavigationRuntimeStateSchema,
32045
+ /**
32046
+ * Runtime-state durability: **session** — like `vacuum-control`, a restored
32047
+ * `mode: cleaning` / `following: true` is a robot that is not actually doing
32048
+ * that. The live handle re-publishes on connect.
32049
+ *
32050
+ * See `RuntimeStateDurability`. Enforced by
32051
+ * `scripts/check-runtime-state-durability.ts`.
32052
+ */
32053
+ durability: "session"
32054
+ };
32055
+ //#endregion
31512
32056
  //#region src/capabilities/reboot.cap.ts
31513
32057
  /**
31514
32058
  * reboot — device-scoped capability for "soft" device reboots (firmware
@@ -36068,6 +36612,8 @@ var DEVICE_LOCAL_STATE_CAPS = {
36068
36612
  motionTrigger: motionTriggerCapability,
36069
36613
  motionZones: motionZonesCapability,
36070
36614
  nativeObjectDetection: nativeObjectDetectionCapability,
36615
+ navigation: navigationCapability,
36616
+ networkLink: networkLinkCapability,
36071
36617
  notifier: notifierCapability,
36072
36618
  numericSensor: numericSensorCapability,
36073
36619
  petFeeder: petFeederCapability,
@@ -38880,6 +39426,8 @@ var CAP_NAMES_WITH_STATUS = [
38880
39426
  "motion-zones",
38881
39427
  "mqtt-broker",
38882
39428
  "native-object-detection",
39429
+ "navigation",
39430
+ "network-link",
38883
39431
  "notifier",
38884
39432
  "numeric-sensor",
38885
39433
  "osd",
@@ -38998,7 +39546,9 @@ var CAPABILITY_NAMES = {
38998
39546
  motionZones: "motion-zones",
38999
39547
  mqttBroker: "mqtt-broker",
39000
39548
  nativeObjectDetection: "native-object-detection",
39549
+ navigation: "navigation",
39001
39550
  networkAccess: "network-access",
39551
+ networkLink: "network-link",
39002
39552
  networkQuality: "network-quality",
39003
39553
  nodes: "nodes",
39004
39554
  notificationOutput: "notification-output",
@@ -39420,10 +39970,18 @@ var CAPABILITY_ROUTER_KEYS = [
39420
39970
  key: "nativeObjectDetection",
39421
39971
  name: "native-object-detection"
39422
39972
  },
39973
+ {
39974
+ key: "navigation",
39975
+ name: "navigation"
39976
+ },
39423
39977
  {
39424
39978
  key: "networkAccess",
39425
39979
  name: "network-access"
39426
39980
  },
39981
+ {
39982
+ key: "networkLink",
39983
+ name: "network-link"
39984
+ },
39427
39985
  {
39428
39986
  key: "networkQuality",
39429
39987
  name: "network-quality"
@@ -39772,7 +40330,9 @@ var ALL_CAPABILITY_DEFINITIONS = [
39772
40330
  motionZonesCapability,
39773
40331
  mqttBrokerCapability,
39774
40332
  nativeObjectDetectionCapability,
40333
+ navigationCapability,
39775
40334
  networkAccessCapability,
40335
+ networkLinkCapability,
39776
40336
  networkQualityCapability,
39777
40337
  nodesCapability,
39778
40338
  notificationOutputCapability,
@@ -42575,6 +43135,66 @@ var METHOD_ACCESS_MAP = Object.freeze({
42575
43135
  addonId: null,
42576
43136
  access: "create"
42577
43137
  },
43138
+ "navigation.getFeatures": {
43139
+ capName: "navigation",
43140
+ capScope: "device",
43141
+ addonId: null,
43142
+ access: "view"
43143
+ },
43144
+ "navigation.goToPoint": {
43145
+ capName: "navigation",
43146
+ capScope: "device",
43147
+ addonId: null,
43148
+ access: "create"
43149
+ },
43150
+ "navigation.listActions": {
43151
+ capName: "navigation",
43152
+ capScope: "device",
43153
+ addonId: null,
43154
+ access: "view"
43155
+ },
43156
+ "navigation.move": {
43157
+ capName: "navigation",
43158
+ capScope: "device",
43159
+ addonId: null,
43160
+ access: "create"
43161
+ },
43162
+ "navigation.playSound": {
43163
+ capName: "navigation",
43164
+ capScope: "device",
43165
+ addonId: null,
43166
+ access: "create"
43167
+ },
43168
+ "navigation.runAction": {
43169
+ capName: "navigation",
43170
+ capScope: "device",
43171
+ addonId: null,
43172
+ access: "create"
43173
+ },
43174
+ "navigation.setLightLevel": {
43175
+ capName: "navigation",
43176
+ capScope: "device",
43177
+ addonId: null,
43178
+ access: "create"
43179
+ },
43180
+ "navigation.setLightMode": {
43181
+ capName: "navigation",
43182
+ capScope: "device",
43183
+ addonId: null,
43184
+ access: "create"
43185
+ },
43186
+ "navigation.setLightOn": {
43187
+ capName: "navigation",
43188
+ capScope: "device",
43189
+ addonId: null,
43190
+ access: "create"
43191
+ },
43192
+ "navigation.stop": {
43193
+ capName: "navigation",
43194
+ capScope: "device",
43195
+ addonId: null,
43196
+ access: "create"
43197
+ },
42578
43198
  "networkAccess.getEndpoint": {
42579
43199
  capName: "network-access",
42580
43200
  capScope: "system",
@@ -45968,6 +46588,7 @@ var KNOWN_CAP_NAMES = [
45968
46588
  "motion-zones",
45969
46589
  "mqtt-broker",
45970
46590
  "native-object-detection",
46591
+ "navigation",
45971
46592
  "network-access",
45972
46593
  "network-quality",
45973
46594
  "nodes",
@@ -46056,6 +46677,7 @@ var DEVICE_CAP_NAMES = [
46056
46677
  "motion-trigger",
46057
46678
  "motion-zones",
46058
46679
  "native-object-detection",
46680
+ "navigation",
46059
46681
  "notifier",
46060
46682
  "osd",
46061
46683
  "pet-feeder",
@@ -46933,6 +47555,56 @@ var METHOD_DEVICE_SELECTORS = Object.freeze({
46933
47555
  form: "single",
46934
47556
  optional: false
46935
47557
  }],
47558
+ "navigation.getFeatures": [{
47559
+ name: "deviceId",
47560
+ form: "single",
47561
+ optional: false
47562
+ }],
47563
+ "navigation.goToPoint": [{
47564
+ name: "deviceId",
47565
+ form: "single",
47566
+ optional: false
47567
+ }],
47568
+ "navigation.listActions": [{
47569
+ name: "deviceId",
47570
+ form: "single",
47571
+ optional: false
47572
+ }],
47573
+ "navigation.move": [{
47574
+ name: "deviceId",
47575
+ form: "single",
47576
+ optional: false
47577
+ }],
47578
+ "navigation.playSound": [{
47579
+ name: "deviceId",
47580
+ form: "single",
47581
+ optional: false
47582
+ }],
47583
+ "navigation.runAction": [{
47584
+ name: "deviceId",
47585
+ form: "single",
47586
+ optional: false
47587
+ }],
47588
+ "navigation.setLightLevel": [{
47589
+ name: "deviceId",
47590
+ form: "single",
47591
+ optional: false
47592
+ }],
47593
+ "navigation.setLightMode": [{
47594
+ name: "deviceId",
47595
+ form: "single",
47596
+ optional: false
47597
+ }],
47598
+ "navigation.setLightOn": [{
47599
+ name: "deviceId",
47600
+ form: "single",
47601
+ optional: false
47602
+ }],
47603
+ "navigation.stop": [{
47604
+ name: "deviceId",
47605
+ form: "single",
47606
+ optional: false
47607
+ }],
46936
47608
  "networkQuality.getDeviceStats": [{
46937
47609
  name: "deviceId",
46938
47610
  form: "single",
@@ -48136,7 +48808,7 @@ function getCapsByProviderKind(kind) {
48136
48808
  //#region src/generated/runtime-state-durability.ts
48137
48809
  /**
48138
48810
  * Per-cap runtime-state policy, projected from every `*.cap.ts` that declares
48139
- * `runtimeState`. 64 caps: 34 `restored`, 30 `session`.
48811
+ * `runtimeState`. 66 caps: 35 `restored`, 31 `session`.
48140
48812
  *
48141
48813
  * A cap absent from this map has no runtime-state slice at all. A cap PRESENT
48142
48814
  * with `durability: 'session'` has one and has decided not to keep it.
@@ -48298,6 +48970,14 @@ var RUNTIME_STATE_POLICY = {
48298
48970
  durability: "restored",
48299
48971
  volatileFields: ["lastFetchedAt"]
48300
48972
  },
48973
+ "navigation": {
48974
+ durability: "session",
48975
+ volatileFields: []
48976
+ },
48977
+ "network-link": {
48978
+ durability: "restored",
48979
+ volatileFields: ["lastUpdated"]
48980
+ },
48301
48981
  "notifier": {
48302
48982
  durability: "session",
48303
48983
  volatileFields: []
@@ -48440,6 +49120,7 @@ var RESTORED_CAP_NAMES = [
48440
49120
  "lock-control",
48441
49121
  "motion-zones",
48442
49122
  "native-object-detection",
49123
+ "network-link",
48443
49124
  "numeric-sensor",
48444
49125
  "power-meter",
48445
49126
  "presence",
@@ -53673,6 +54354,9 @@ exports.NATIVE_LEASE_SCENE_BUDGET_KEY = NATIVE_LEASE_SCENE_BUDGET_KEY;
53673
54354
  exports.NATIVE_LEASE_SECTION_ID = NATIVE_LEASE_SECTION_ID;
53674
54355
  exports.NATIVE_LEASE_TILE_BUDGET_FIELD = NATIVE_LEASE_TILE_BUDGET_FIELD;
53675
54356
  exports.NATIVE_LEASE_TILE_BUDGET_KEY = NATIVE_LEASE_TILE_BUDGET_KEY;
54357
+ exports.NAVIGATION_ACTION_CATALOG = NAVIGATION_ACTION_CATALOG;
54358
+ exports.NAVIGATION_LIGHT_LEVEL_MAX = NAVIGATION_LIGHT_LEVEL_MAX;
54359
+ exports.NAVIGATION_LIGHT_LEVEL_MIN = NAVIGATION_LIGHT_LEVEL_MIN;
53676
54360
  exports.NC_ALARM_SYSTEM_EVENT_KINDS = NC_ALARM_SYSTEM_EVENT_KINDS;
53677
54361
  exports.NC_AUDIO_CONFIRM_HITS_DEFAULT = NC_AUDIO_CONFIRM_HITS_DEFAULT;
53678
54362
  exports.NC_AUDIO_CONFIRM_HITS_MAX = NC_AUDIO_CONFIRM_HITS_MAX;
@@ -53710,6 +54394,8 @@ exports.NC_SNOOZE_MAX_MINUTES = NC_SNOOZE_MAX_MINUTES;
53710
54394
  exports.NC_SYSTEM_DELIVERY = NC_SYSTEM_DELIVERY;
53711
54395
  exports.NC_SYSTEM_EVENT_FILTER_KEYS = NC_SYSTEM_EVENT_FILTER_KEYS;
53712
54396
  exports.NC_TAXONOMY = NC_TAXONOMY;
54397
+ exports.NETWORK_LINK_TYPES = NETWORK_LINK_TYPES;
54398
+ exports.NETWORK_LINK_UNKNOWN = NETWORK_LINK_UNKNOWN;
53713
54399
  exports.NativeCropBboxSchema = NativeCropBboxSchema;
53714
54400
  exports.NativeCropRefSchema = NativeCropRefSchema;
53715
54401
  exports.NativeCropResultSchema = NativeCropResultSchema;
@@ -53719,6 +54405,16 @@ exports.NativeLeaseSettingsSchema = NativeLeaseSettingsSchema;
53719
54405
  exports.NativeObjectClassEnum = NativeObjectClassEnum;
53720
54406
  exports.NativeObjectDetectionRuntimeStateSchema = NativeObjectDetectionRuntimeStateSchema;
53721
54407
  exports.NativeObjectDetectionStatusSchema = NativeObjectDetectionStatusSchema;
54408
+ exports.NavigationActionEntrySchema = NavigationActionEntrySchema;
54409
+ exports.NavigationActionIdSchema = NavigationActionIdSchema;
54410
+ exports.NavigationEntryKindSchema = NavigationEntryKindSchema;
54411
+ exports.NavigationFeaturesSchema = NavigationFeaturesSchema;
54412
+ exports.NavigationLightModeSchema = NavigationLightModeSchema;
54413
+ exports.NavigationModeSchema = NavigationModeSchema;
54414
+ exports.NavigationMoveCommandSchema = NavigationMoveCommandSchema;
54415
+ exports.NavigationPointSchema = NavigationPointSchema;
54416
+ exports.NavigationRuntimeStateSchema = NavigationRuntimeStateSchema;
54417
+ exports.NavigationStatusSchema = NavigationStatusSchema;
53722
54418
  exports.NcAlarmConfigSchema = NcAlarmConfigSchema;
53723
54419
  exports.NcAlarmModeCoverageSchema = NcAlarmModeCoverageSchema;
53724
54420
  exports.NcAlarmSettingsPatchSchema = NcAlarmSettingsPatchSchema;
@@ -53768,6 +54464,7 @@ exports.NcZoneConditionSchema = NcZoneConditionSchema;
53768
54464
  exports.NetworkAccessStatusSchema = NetworkAccessStatusSchema;
53769
54465
  exports.NetworkAddressSchema = NetworkAddressSchema;
53770
54466
  exports.NetworkEndpointSchema = NetworkEndpointSchema;
54467
+ exports.NetworkLinkStatusSchema = NetworkLinkStatusSchema;
53771
54468
  exports.NotificationActionIconSchema = NotificationActionIconSchema;
53772
54469
  exports.NotificationActionSchema = NotificationActionSchema;
53773
54470
  exports.NotificationFormatSchema = NotificationFormatSchema;
@@ -54426,7 +55123,9 @@ exports.motionTriggerCapability = motionTriggerCapability;
54426
55123
  exports.motionZonesCapability = motionZonesCapability;
54427
55124
  exports.mqttBrokerCapability = mqttBrokerCapability;
54428
55125
  exports.nativeObjectDetectionCapability = nativeObjectDetectionCapability;
55126
+ exports.navigationCapability = navigationCapability;
54429
55127
  exports.networkAccessCapability = networkAccessCapability;
55128
+ exports.networkLinkCapability = networkLinkCapability;
54430
55129
  exports.networkQualityCapability = networkQualityCapability;
54431
55130
  exports.nodePin = require_sleep.nodePin;
54432
55131
  exports.nodesCapability = nodesCapability;
@@ -54540,6 +55239,8 @@ exports.selectAssignedProfileSlots = require_sleep.selectAssignedProfileSlots;
54540
55239
  exports.serverManagementCapability = serverManagementCapability;
54541
55240
  exports.setByPath = setByPath;
54542
55241
  exports.settingsStoreCapability = settingsStoreCapability;
55242
+ exports.signalPercentFromBars = signalPercentFromBars;
55243
+ exports.signalPercentFromRssi = signalPercentFromRssi;
54543
55244
  exports.sleep = require_sleep.sleep;
54544
55245
  exports.sleepCancellable = require_sleep.sleepCancellable;
54545
55246
  exports.sliceActiveValue = sliceActiveValue;