code wiki / (root) / nx_electrical_test.nx

nx_electrical_test.nx source

↩ module page · 99 lines · 4391 B

1// nx_electrical_test.nx -- gate for the electrical-health kernel (#5). 2// 3// Proves the safety verdicts (ground-fault / overload / voltage sag+swell / 4// high-load), sovereign energy metering (10A x 120V x 1h = 1200 Wh), and the 5// liar-kill: load_permille tracks current (NOMINAL @ 500 vs OVERLOAD @ 1100 at 6// identical voltage). 7// 8// expect_exit: 0 9// 10// license_tier: ORIGINAL 11 12import "nx_syscalls_x86_64.nx" 13import "nx_electrical.nx" 14 15func main() -> i64 { 16 if nx_elec_verdict_is_valid(NX_ELEC_GROUND_FAULT) != 1 { return 1 } 17 if nx_elec_verdict_is_valid(NX_ELEC_N) != 0 { return 2 } 18 if nx_elec_verdict_is_valid(-1) != 0 { return 3 } 19 20 let cur: *i64 = sys_mmap(128) as *i64 21 let volt: *i64 = sys_mmap(128) as *i64 22 let out: *ElecEff = sys_mmap(128) as *ElecEff 23 let spec: *ElecSpec = sys_mmap(64) as *ElecSpec 24 spec.breaker_rating_ca = 2000 // 20A breaker 25 spec.high_load_permille = 800 // warn at 80% (16A) 26 spec.nominal_voltage_cv = 12000 // 120V 27 spec.voltage_band_permille = 50 // +/-5% -> 114..126V 28 spec.ground_fault_ma = 5 // GFCI 5mA 29 spec.idle_current_ca = 50 // 0.5A 30 31 // ===== NOMINAL + energy metering ================================ 32 cur[0]=1000; cur[1]=1000; cur[2]=1000; cur[3]=1000 33 volt[0]=12000; volt[1]=12000; volt[2]=12000; volt[3]=12000 34 nx_elec_analyze(cur, volt, 4, 3600, 0, spec, out) 35 if out.verdict != NX_ELEC_NOMINAL { return 10 } 36 if out.load_permille != 500 { return 11 } 37 if out.mean_power_w != 1200 { return 12 } 38 if out.energy_wh != 1200 { return 13 } // 10A x 120V x 1h 39 40 // ===== HIGH_LOAD: 85% of rating ================================ 41 cur[0]=1700; cur[1]=1700; cur[2]=1700; cur[3]=1700 42 volt[0]=12000; volt[1]=12000; volt[2]=12000; volt[3]=12000 43 nx_elec_analyze(cur, volt, 4, 3600, 0, spec, out) 44 if out.verdict != NX_ELEC_HIGH_LOAD { return 20 } 45 46 // ===== OVERLOAD: 110% of rating -> fire/trip =================== 47 cur[0]=2200; cur[1]=2200; cur[2]=2200; cur[3]=2200 48 nx_elec_analyze(cur, volt, 4, 3600, 0, spec, out) 49 if out.verdict != NX_ELEC_OVERLOAD { return 30 } 50 51 // ===== VOLTAGE_SAG: brownout (110V < 114V) ===================== 52 cur[0]=1000; cur[1]=1000; cur[2]=1000; cur[3]=1000 53 volt[0]=11000; volt[1]=11000; volt[2]=11000; volt[3]=11000 54 nx_elec_analyze(cur, volt, 4, 3600, 0, spec, out) 55 if out.verdict != NX_ELEC_VOLTAGE_SAG { return 40 } 56 57 // ===== VOLTAGE_SWELL: overvoltage (130V > 126V) ================ 58 volt[0]=13000; volt[1]=13000; volt[2]=13000; volt[3]=13000 59 nx_elec_analyze(cur, volt, 4, 3600, 0, spec, out) 60 if out.verdict != NX_ELEC_VOLTAGE_SWELL { return 50 } 61 62 // ===== GROUND_FAULT: leakage 8mA > 5mA (safety, checked first) == 63 volt[0]=12000; volt[1]=12000; volt[2]=12000; volt[3]=12000 64 nx_elec_analyze(cur, volt, 4, 3600, 8, spec, out) 65 if out.verdict != NX_ELEC_GROUND_FAULT { return 60 } 66 67 // ===== IDLE: no load ============================================ 68 cur[0]=20; cur[1]=20; cur[2]=20; cur[3]=20 69 nx_elec_analyze(cur, volt, 4, 3600, 0, spec, out) 70 if out.verdict != NX_ELEC_IDLE { return 70 } 71 72 // ===== INSUFFICIENT_DATA: empty window ========================= 73 nx_elec_analyze(cur, volt, 0, 3600, 0, spec, out) 74 if out.verdict != NX_ELEC_INSUFFICIENT_DATA { return 80 } 75 76 // ===== BAD_ARG: negative leakage =============================== 77 cur[0]=1000; cur[1]=1000; cur[2]=1000; cur[3]=1000 78 nx_elec_analyze(cur, volt, 4, 3600, 0 - 1, spec, out) 79 if out.verdict != NX_ELEC_BAD_ARG { return 90 } 80 81 // ===== LIAR-KILL: load tracks current ========================== 82 cur[0]=1000; cur[1]=1000; cur[2]=1000; cur[3]=1000 83 nx_elec_analyze(cur, volt, 4, 3600, 0, spec, out) 84 if out.verdict != NX_ELEC_NOMINAL { return 92 } 85 let nom_load: i64 = out.load_permille 86 let nom_verdict: i64 = out.verdict 87 cur[0]=2200; cur[1]=2200; cur[2]=2200; cur[3]=2200 88 nx_elec_analyze(cur, volt, 4, 3600, 0, spec, out) 89 if out.verdict != NX_ELEC_OVERLOAD { return 93 } 90 if out.load_permille == nom_load { return 94 } 91 if out.verdict == nom_verdict { return 95 } 92 93 // ===== BAD_ARG: invalid rating ================================= 94 spec.breaker_rating_ca = 0 95 nx_elec_analyze(cur, volt, 4, 3600, 0, spec, out) 96 if out.verdict != NX_ELEC_BAD_ARG { return 96 } 97 98 return 0 99}