code wiki / (root) / nx_iot_scene_sync.nx

nx_iot_scene_sync.nx

buildroot/runtime/nx_iot_scene_sync.nx

12480 B300 linesdepth 0pulls 0 transitivereach 1 importersview sourcekind librarytopic iot
docsdependenciesstructsconstsfunctions

about

nx_iot_scene_sync.nx -- the "lights stay in sync, self-fixing" organ. Roadmap: NISHI_IOT_HUB_ROADMAP.md Epoch 4 (SYNCHRONIZE). Closes the operator's ORIGINAL complaint -- "the lights blink and desync all the time" -- as a REPEATABLE, SELF-FIXING loop, not a one-off. THE DESYNC PROBLEM (operator, 2026-05-16 + 2026-06-20 "i still want the lights to sync that are blinking as a repeatable self fixing thing"): A scene (all lights = same colour/brightness/on) drifts apart because (a) lights get the command at slightly different times (skew), and (b) a light that drops WiFi + re-pairs comes back at its DEFAULT state -- out of sync with the rest -- and stays wrong until a human re-sets it. THE FIX (two layers, both already in the hub): 1. PREVENT skew: apply a scene ATOMICALLY -- all lights at the same tick (nx_iot_clock_master drains a scene all-or-nothing). The daemon wires that; this organ holds the SINGLE SOURCE OF TRUTH for what the scene SHOULD be. 2. SELF-FIX drift: this organ tracks, per device, which scene EPOCH it last applied. A device that dropped + healed (nx_iot_watchdog -> re-provision -> nx_iot_anchor re-adopt) is marked desynced; the loop re-applies the current desired scene to it -> back in sync. Every heal -> auto re-sync. REPEATABLE: each drop is fixed the same way, and the MEASURED `syncs_restored` counts the manual re-sets spared. WHAT THIS ORGAN IS: the pure SYNC-STATE machine. desired scene + per device applied-epoch + convergence (all_in_sync / needs_resync / resync). No network, no device writes -- the driver (kasa pt_light etc., already brick-safe) applies the computed scene; the clock master makes it atomic; the watchdog triggers the heal. Pure-buffer, so it gate-proves offline + is portable. Single-responsibility (#9): it owns "are the lights in sync, and what brings a stray one back". MEASURED-EXCEED (feedback-no-wave-measured-exceed; mirrors anchor's duplicates_prevented + watchdog's recover_count): `syncs_restored` is the count of times a drifted light was auto-pulled back to the scene -- the manual re-sets the operator did NOT have to do. The gate asserts it. genealogy_id: NISHI_IOT_HUB_ROADMAP.md Epoch 4 + project-iot-hub-multi-vendor-kickoff-2026-05-16 license_tier: ORIGINAL

dependencies 0 imports · 1 importers

nx_iot_scene_sync.nx nx_iot_scene_sync_test.nx

imports: none

imported by: nx_iot_scene_sync_test.nx

structs

83struct IotSceneReg

consts

60const NX_IOT_SYNC_UNKNOWN: i64 = 0
61const NX_IOT_SYNC_OK: i64 = 1 // device matches the desired scene
62const NX_IOT_SYNC_NEEDS_RESYNC: i64 = 2 // device drifted -> re-apply needed
63const NX_IOT_SYNC_FULL: i64 = 3 // registry at capacity
64const NX_IOT_SYNC_NOT_FOUND: i64 = 4
65const NX_IOT_SYNC_BAD_ARG: i64 = 5
66const NX_IOT_SYNC_N: i64 = 6
75const NX_IOT_SYNC_EPOCH_NONE: i64 = -1
101const NX_IOT_SYNC_DEV_STRIDE: i64 = 2

functions

68func nx_iot_sync_verdict_is_valid(v: i64) -> i64
called by 1: main
103func nx_iot_sync_dev_lid(devs: *i64, slot: i64) -> i64
called by 1: nx_iot_sync_find
106func nx_iot_sync_dev_epoch(devs: *i64, slot: i64) -> i64
110func nx_iot_sync_find(reg: *IotSceneReg, devs: *i64, logical_id: i64) -> i64
124func nx_iot_scene_init(reg: *IotSceneReg, cap: i64) -> i64
called by 1: main
147func nx_iot_scene_set(reg: *IotSceneReg, on: i64, bri: i64,
called by 1: main
164func nx_iot_scene_add_device(reg: *IotSceneReg, devs: *i64,
called by 1: main calls 1: nx_iot_sync_find
180func nx_iot_scene_in_sync(reg: *IotSceneReg, devs: *i64, logical_id: i64) -> i64
188func nx_iot_scene_needs_resync(reg: *IotSceneReg, devs: *i64, logical_id: i64) -> i64
198func nx_iot_scene_mark_applied(reg: *IotSceneReg, devs: *i64, logical_id: i64) -> i64
called by 1: main calls 1: nx_iot_sync_find
208func nx_iot_scene_mark_desynced(reg: *IotSceneReg, devs: *i64, logical_id: i64) -> i64
called by 1: main calls 1: nx_iot_sync_find
223func nx_iot_scene_resync(reg: *IotSceneReg, devs: *i64, logical_id: i64) -> i64
236func nx_iot_scene_all_in_sync(reg: *IotSceneReg, devs: *i64) -> i64
called by 1: main calls 1: nx_iot_sync_dev_epoch
246func nx_iot_scene_count_desynced(reg: *IotSceneReg, devs: *i64) -> i64
called by 1: main calls 1: nx_iot_sync_dev_epoch
260func nx_iot_scene_resync_all(reg: *IotSceneReg, devs: *i64) -> i64
called by 1: main calls 1: nx_iot_sync_dev_epoch
277func nx_iot_scene_epoch(reg: *IotSceneReg) -> i64
called by 1: main
281func nx_iot_scene_count(reg: *IotSceneReg) -> i64
called by 1: main
285func nx_iot_scene_syncs_restored(reg: *IotSceneReg) -> i64
called by 1: main
289func nx_iot_scene_desyncs_seen(reg: *IotSceneReg) -> i64
called by 1: main
293func nx_iot_scene_get_brightness(reg: *IotSceneReg) -> i64
called by 1: main
297func nx_iot_scene_get_on(reg: *IotSceneReg) -> i64
called by 1: main