code wiki / _hdl_build / nx_household.nx

nx_household.nx source

↩ module page · 91 lines · 5371 B

1// nx_household.nx -- LIB: the HOUSEHOLD COMMAND CENTER. One sovereign no-JS dashboard tying the whole 2// ecosystem together: tonight's dinner (what you can cook from the pantry), what's expiring, the shopping list 3// (low stock), grow-your-own savings, and the estate net worth -- each pulled LIVE from the food + inventory 4// engines. The single "it all works together" surface. Boundary-escaped. (Named nx_household to avoid the 5// existing IoT nx_home.nx.) license_tier: ORIGINAL 6import "nx_pantry.nx" 7import "nx_garden.nx" 8import "nx_inventory.nx" 9import "nx_food_science.nx" 10import "nx_syscalls.nx" 11 12func hh_money(dst: *u8, off: i64, cents: i64) -> i64 { 13 var o: i64 = off 14 dst[o] = 36 as u8; o = o + 1 15 o = fd_apnum(dst, o, cents / 100) 16 dst[o] = 46 as u8; o = o + 1 17 let r: i64 = cents % 100 18 dst[o] = (48 + (r / 10)) as u8; o = o + 1 19 dst[o] = (48 + (r % 10)) as u8; o = o + 1 20 return o 21} 22 23// append display names of inventory ids[0..n) (", " joined, escaped); "(none)" if empty 24func hh_inv_names(inv_prefix: *u8, domain: *u8, ids: *i64, n: i64, out: *u8, off: i64) -> i64 { 25 var o: i64 = off 26 if n == 0 { return as_append(out, o, "(none)" as *u8) } 27 var i: i64 = 0 28 while i < n { 29 if i > 0 { o = as_append(out, o, ", " as *u8) } 30 let nm: *u8 = sys_mmap(64) 31 iv_field_of(inv_prefix, domain, ids[i] as *u8, 0, nm) 32 o = as_append_escaped(out, o, nm, as_len(nm)) 33 i = i + 1 34 } 35 return o 36} 37 38func hh_render_dashboard(food_prefix: *u8, inv_prefix: *u8, pantry_dom: *u8, estate_dom: *u8, household: *u8, out: *u8) -> i64 { 39 let world: *i64 = fd_world_open(food_prefix) 40 let names: *i64 = world[4] as *i64 41 42 // tonight's dinner: choose from what's in stock 43 let avail: *i64 = sys_mmap(8 * 64) as *i64 44 fp_pantry_avail(world, inv_prefix, pantry_dom, avail) 45 let build: *i64 = sys_mmap(8 * 16) as *i64 46 let roles: *i64 = sys_mmap(8 * 16) as *i64 47 let nb: i64 = fp_choose(food_prefix, world, avail, build, roles) 48 49 var o: i64 = 0 50 o = as_append(out, o, "<!doctype html><html lang='en'><head><meta charset='utf-8'><meta name='viewport' content='width=device-width,initial-scale=1'><title>Your Nishi Home</title><style>body{margin:0;font-family:system-ui,sans-serif;color:#1b232c;background:#eef2f5;line-height:1.5}header{background:#0b2545;color:#fff;padding:26px 22px}header h1{margin:0;font-size:1.5rem}header p{margin:4px 0 0;color:#bcd2ea}main{max-width:680px;margin:0 auto;padding:18px 16px 40px;display:grid;gap:14px}.tile{background:#fff;border-radius:12px;padding:16px 18px;box-shadow:0 1px 0 #dde5ec}.tile h2{margin:0 0 6px;font-size:1rem;color:#0b2545;display:flex;justify-content:space-between;align-items:baseline}.tile .big{font-size:1.15rem;font-weight:700}.muted{color:#5b6b7a}.save{color:#1f7a44}.expire{color:#a85b00;font-weight:600}</style></head><body><header><h1>Your Nishi Home</h1><p>" as *u8) 51 o = as_append_escaped(out, o, household, as_len(household)) 52 o = as_append(out, o, "</p></header><main>" as *u8) 53 54 o = as_append(out, o, "<div class='tile'><h2>Tonight you can make</h2><div class='big'>" as *u8) 55 if nb == 5 { 56 var i: i64 = 0 57 while i < nb { if i > 0 { o = as_append(out, o, " &middot; " as *u8) } o = as_append_escaped(out, o, names[build[i]] as *u8, as_len(names[build[i]] as *u8)); i = i + 1 } 58 } else { o = as_append(out, o, "Not enough on hand for a full stir-fry &mdash; see the shopping list." as *u8) } 59 o = as_append(out, o, "</div><p class='muted'>balanced by food science, from what's in your kitchen.</p></div>" as *u8) 60 61 let exp: *i64 = sys_mmap(8 * 256) as *i64 62 let nexp: i64 = iv_expiring(inv_prefix, pantry_dom, 0, 3, exp) 63 o = as_append(out, o, "<div class='tile'><h2>Use these soon <span class='expire'>" as *u8) 64 o = fd_apnum(out, o, nexp); o = as_append(out, o, " expiring</span></h2><div class='expire'>" as *u8) 65 o = hh_inv_names(inv_prefix, pantry_dom, exp, nexp, out, o) 66 o = as_append(out, o, "</div></div>" as *u8) 67 68 let lid: *i64 = sys_mmap(8 * 256) as *i64 69 let lneed: *i64 = sys_mmap(8 * 256) as *i64 70 let nlo: i64 = iv_low_stock(inv_prefix, pantry_dom, lid, lneed) 71 o = as_append(out, o, "<div class='tile'><h2>Shopping list <span class='muted'>" as *u8) 72 o = fd_apnum(out, o, nlo); o = as_append(out, o, " to buy</span></h2><div>" as *u8) 73 o = hh_inv_names(inv_prefix, pantry_dom, lid, nlo, out, o) 74 o = as_append(out, o, "</div></div>" as *u8) 75 76 let og: *i64 = sys_mmap(16) as *i64 77 let mealsav: i64 = gd_meal_savings(food_prefix, world, build, nb, og) 78 o = as_append(out, o, "<div class='tile'><h2>Grow &amp; save</h2><div class='big save'>" as *u8) 79 o = hh_money(out, o, mealsav * 3 * 52) 80 o = as_append(out, o, " / year</div><p class='muted'>grow " as *u8) 81 o = fd_apnum(out, o, og[0]); o = as_append(out, o, " of tonight's ingredients yourself (cooked 3&times;/week).</p></div>" as *u8) 82 83 let netw: i64 = iv_value_total(inv_prefix, estate_dom) 84 o = as_append(out, o, "<div class='tile'><h2>Estate <span class='muted'>cataloged for your will</span></h2><div class='big'>" as *u8) 85 o = hh_money(out, o, netw) 86 o = as_append(out, o, "</div><p class='muted'>total catalogued net worth.</p></div>" as *u8) 87 88 o = as_append(out, o, "</main></body></html>" as *u8) 89 out[o] = 0 as u8 90 return o 91}