nx_printer_waste.nx source
↩ module page · 96 lines · 4583 B
1// nx_printer_waste.nx -- honest supply + waste auditor (R4). Targets the operator's "wasteful as shit".
2//
3// Two concrete, evidence-grounded wastes (from the live Brother dump):
4// (1) SUPPLY waste/awareness: marker-levels/marker-low-levels/marker-high-levels (parallel 1setOf
5// integer arrays, one entry per ink/toner supply). We compute each supply's true % and an honest
6// status (OK/LOW/EMPTY/UNKNOWN) so you neither run dry mid-job nor toss a cartridge early on a
7// vendor "low" scare. Negative levels (-1/-2/-3) mean "unknown" (RFC 3805 Printer MIB) -> not a
8// false 0%.
9// (2) PAPER waste: a printer that SUPPORTS duplex but DEFAULTS to one-sided (the Brother does exactly
10// this: sides-supported includes two-sided-long/short-edge, sides-default=one-sided) wastes paper
11// on every default job. We flag it.
12//
13// NEVER-BRICK (#26): pure read-only model; no syscalls. Sovereign (imports only nx_ipp_codec.nx).
14// genealogy_id: project-printer-management-ipp-sclass-2026-06-20 ; license_tier: ORIGINAL
15
16import "nx_ipp_codec.nx"
17const NX_MAGIC_1000000: i64 = 1000000
18
19// ---- sealed supply status ----
20const NX_SUP_OK: i64 = 1
21const NX_SUP_LOW: i64 = 2
22const NX_SUP_EMPTY: i64 = 3
23const NX_SUP_UNKNOWN: i64 = 4
24const NX_SUP_N: i64 = 5
25
26// ---- sealed duplex/paper-waste verdict ----
27const NX_DUP_OK: i64 = 1 // duplex is the default -> not wasting paper
28const NX_DUP_WASTE: i64 = 2 // duplex supported but defaults to one-sided -> paper waste
29const NX_DUP_UNSUPPORTED: i64 = 3 // no duplex hardware
30const NX_DUP_UNKNOWN: i64 = 4 // sides attributes not reported
31
32// status of one supply: level/low/high are in high-relative units. Writes % via out_pct (-1 = unknown).
33func nx_pw_supply_status(lvl: i64, lo: i64, hi: i64, out_pct: *i64) -> i64 {
34 if lvl < 0 { out_pct[0] = 0 - 1; return NX_SUP_UNKNOWN }
35 var pct: i64 = lvl
36 if hi > 0 { pct = lvl * 100 / hi }
37 out_pct[0] = pct
38 if lvl <= 0 { return NX_SUP_EMPTY }
39 if lvl <= lo { return NX_SUP_LOW }
40 return NX_SUP_OK
41}
42
43// paper-waste verdict from sides-supported / sides-default.
44func nx_pw_duplex(body: *u8, n: i64) -> i64 {
45 var has_duplex: i64 = 0
46 if nx_ipp_set_contains(body, n, "sides-supported", "two-sided-long-edge") == 1 { has_duplex = 1 }
47 if nx_ipp_set_contains(body, n, "sides-supported", "two-sided-short-edge") == 1 { has_duplex = 1 }
48 let has_supp: i64 = nx_ipp_set_contains(body, n, "sides-supported", "one-sided")
49 if has_duplex == 0 {
50 if has_supp == 1 { return NX_DUP_UNSUPPORTED }
51 return NX_DUP_UNKNOWN
52 }
53 if nx_ipp_set_contains(body, n, "sides-default", "one-sided") == 1 { return NX_DUP_WASTE }
54 return NX_DUP_OK
55}
56
57// Audit all supplies. scratch = caller i64[4] work area. Writes out_count (#supplies),
58// out_min_pct (lowest known %, -1 if none known), out_dup (paper-waste verdict). Returns worst supply status.
59func nx_printer_waste(body: *u8, n: i64, scratch: *i64,
60 out_count: *i64, out_min_pct: *i64, out_dup: *i64) -> i64 {
61 let c_lvl: *i64 = scratch
62 let c_lo: *i64 = ((scratch as i64) + 8) as *i64
63 let c_hi: *i64 = ((scratch as i64) + 16) as *i64
64 let c_pct: *i64 = ((scratch as i64) + 24) as *i64
65 var idx: i64 = 0
66 var count: i64 = 0
67 var any_empty: i64 = 0
68 var any_low: i64 = 0
69 var any_ok: i64 = 0
70 var min_pct: i64 = NX_MAGIC_1000000
71 var keep: i64 = 1
72 while keep == 1 {
73 if nx_ipp_set_int_at(body, n, "marker-levels", idx, c_lvl) != NX_IPP_OK { keep = 0 }
74 else {
75 count = count + 1
76 var lo: i64 = 0
77 var hi: i64 = 100
78 if nx_ipp_set_int_at(body, n, "marker-low-levels", idx, c_lo) == NX_IPP_OK { lo = c_lo[0] }
79 if nx_ipp_set_int_at(body, n, "marker-high-levels", idx, c_hi) == NX_IPP_OK { hi = c_hi[0] }
80 let st: i64 = nx_pw_supply_status(c_lvl[0], lo, hi, c_pct)
81 if st == NX_SUP_EMPTY { any_empty = 1 }
82 if st == NX_SUP_LOW { any_low = 1 }
83 if st == NX_SUP_OK { any_ok = 1 }
84 if c_pct[0] >= 0 { if c_pct[0] < min_pct { min_pct = c_pct[0] } }
85 idx = idx + 1
86 }
87 }
88 out_count[0] = count
89 out_dup[0] = nx_pw_duplex(body, n)
90 if min_pct == NX_MAGIC_1000000 { out_min_pct[0] = 0 - 1 } else { out_min_pct[0] = min_pct }
91 if count == 0 { return NX_SUP_UNKNOWN }
92 if any_empty == 1 { return NX_SUP_EMPTY }
93 if any_low == 1 { return NX_SUP_LOW }
94 if any_ok == 1 { return NX_SUP_OK }
95 return NX_SUP_UNKNOWN
96}