nx_iot_dashboard.nx source
↩ module page · 66 lines · 3561 B
1// nx_iot_dashboard.nx -- the sovereign Nishi-browser IoT DASHBOARD (killer-feature rung 1).
2//
3// Operator 2026-06-23 vision: devices stable + non-blinking + auto-connected + AVAILABLE even when
4// the INTERNET is OUT (LAN up); managed entirely from the first-party Nishi browser; sharded per
5// house. This page is the management surface: per device a STATUS line (on-LAN / available with
6// internet down / last-seen) + the capability controls -- so you SEE they're connected and can act,
7// all local. Reuses the proven zero-JS nx_iot_control_page (cp_head/cp_foot/cp_widgets/cp_cat) so it
8// works in any browser with no app, no cloud, no JavaScript. The hub feeds it live device records;
9// this organ is the renderer (multi-tenant: one page per house). license_tier: ORIGINAL
10import "nx_iot_control_page.nx"
11
12const DB_OUT: *u8 = "web_assets/iot_dashboard.html"
13const DB_CAP: i64 = 262144
14
15// online/offline status dot (inline-styled so we reuse cp_head's CSS unchanged)
16func db_badge(h: *u8, off: i64, online: i64) -> i64 {
17 var w: i64 = off
18 w = cp_cat(h, w, "<span style=\"display:inline-block;width:9px;height:9px;border-radius:50%;margin-right:7px;vertical-align:middle;background:" as *u8)
19 if online == 1 { w = cp_cat(h, w, "#3fb950" as *u8) } else { w = cp_cat(h, w, "#f85149" as *u8) }
20 w = cp_cat(h, w, "\"></span>" as *u8)
21 return w
22}
23
24// one device row: badge + name + (room . type . ip) + LAN-status line + capability controls
25func db_card(h: *u8, off: i64, id: *u8, name: *u8, room: *u8, vlabel: *u8, ip: *u8,
26 dev_class: i64, is_on: i64, online: i64, seen_s: i64) -> i64 {
27 var w: i64 = off
28 let caps: i64 = nx_iot_cap_for_class(0, dev_class)
29 w = cp_cat(h, w, "<div class=\"card\"><div class=\"cn\">" as *u8)
30 w = db_badge(h, w, online)
31 w = cp_cat(h, w, name)
32 w = cp_cat(h, w, "</div><div class=\"cr\">" as *u8)
33 w = cp_cat(h, w, room); w = cp_cat(h, w, " · " as *u8); w = cp_cat(h, w, vlabel)
34 w = cp_cat(h, w, " · " as *u8); w = cp_cat(h, w, ip)
35 w = cp_cat(h, w, "</div><div style=\"color:#8aa0b4;font-size:12px;margin:0 0 .6em\">" as *u8)
36 if online == 1 { w = cp_cat(h, w, "On LAN · available with internet down · seen " as *u8) }
37 else { w = cp_cat(h, w, "Offline · last seen " as *u8) }
38 w = cp_catn(h, w, seen_s); w = cp_cat(h, w, "s ago</div>" as *u8)
39 w = cp_cat(h, w, "<div class=\"row\">" as *u8)
40 w = cp_widgets(h, w, id, caps, is_on)
41 w = cp_cat(h, w, "</div></div>\n" as *u8)
42 return w
43}
44
45// render the whole dashboard into h (returns length). Devices passed as parallel intent here;
46// the hub will drive this from the live discovery/lease store (one render per tenant/house).
47func db_render(h: *u8) -> i64 {
48 var w: i64 = 0
49 w = cp_head(h, w)
50 w = db_card(h, w, "38:1f:8d:43:9b:22" as *u8, "IoT Plug 1" as *u8, "House" as *u8, "Tuya/ESP" as *u8, "192.168.10.166" as *u8, NX_IOT_CLASS_SWITCH, 1, 1, 1)
51 w = db_card(h, w, "38:1f:8d:43:a3:c2" as *u8, "IoT Plug 2" as *u8, "House" as *u8, "Tuya/ESP" as *u8, "192.168.10.242" as *u8, NX_IOT_CLASS_SWITCH, 0, 1, 3)
52 w = cp_foot(h, w)
53 return w
54}
55
56func main() -> i64 {
57 let h: *u8 = sys_mmap(DB_CAP)
58 let w: i64 = db_render(h)
59 let fd: i64 = sys_openat_wr(DB_OUT, 0x1a4)
60 if fd < 0 { sys_write(2, "FATAL: cannot open web_assets/iot_dashboard.html\n" as *u8, 49); sys_exit(2); return 2 }
61 sys_write(fd, h, w)
62 sys_close(fd)
63 sys_write(1, "[nx_iot_dashboard] wrote iot_dashboard.html\n" as *u8, 44)
64 sys_exit(0)
65 return 0
66}