nx_print_runtime_thermal_test.nx source
↩ module page · 105 lines · 3839 B
1// nx_print_runtime_thermal_test.nx -- thermal-dropout detection
2// extension of the runtime spaghetti monitor.
3//
4// Closed-form invariants:
5// (a) All temps at setpoint -> no issue
6// (b) Brief dropout (< duration) -> no issue
7// (c) Bed below for > duration -> BED_TEMP_DROP fires
8// (d) Recovery: temp returns to setpoint -> next event no issue
9// (e) Hotend below -> HOTEND_TEMP_DROP fires
10// (f) Chamber below -> CHAMBER_TEMP_DROP fires
11// (g) Setpoint = -1 skips axis (no spurious alarm even at -100°C)
12// (h) n_issues_total tracks fires
13//
14// expect_exit: 0
15// license_tier: ORIGINAL
16
17import "nx_syscalls.nx"
18import "nx_print_runtime_monitor.nx"
19
20func main() -> i64 {
21 let m: *NxRuntimeMonitor = nx_runtime_monitor_new(
22 5000, 3, 16384, 16384)
23 if (m as i64) == 0 { return 5 }
24 // 3°C tolerance, 2s alarm duration
25 nx_runtime_monitor_set_thermal(m, 3, 2000)
26
27 // ===== (a) All temps at setpoint, no issue =====
28 let v0: i64 = nx_runtime_monitor_step_thermal(m,
29 60, 60, // bed
30 210, 210, // hotend
31 30, 30, // chamber
32 0)
33 if v0 != NX_RT_ISSUE_NONE { return 10 }
34
35 // ===== (b) Bed briefly below (1s; < 2s duration) -> no alarm =====
36 let v1: i64 = nx_runtime_monitor_step_thermal(m,
37 55, 60, // 5°C below setpoint, > 3°C tolerance
38 210, 210,
39 30, 30,
40 500)
41 if v1 != NX_RT_ISSUE_NONE { return 20 } // started but not yet alarm
42
43 let v2: i64 = nx_runtime_monitor_step_thermal(m,
44 55, 60,
45 210, 210,
46 30, 30,
47 1500) // 1.5s below; still under 2s
48 if v2 != NX_RT_ISSUE_NONE { return 21 }
49
50 // ===== (c) Bed below for > 2s -> BED_TEMP_DROP =====
51 let v3: i64 = nx_runtime_monitor_step_thermal(m,
52 55, 60,
53 210, 210,
54 30, 30,
55 2600) // 2.1s below since 500; now alarm fires (>2000ms threshold)
56 if v3 != NX_RT_ISSUE_BED_TEMP_DROP { return 30 }
57 if m.n_issues_total != 1 { return 31 }
58
59 // ===== (d) Recovery: bed back at setpoint -> no issue =====
60 let v4: i64 = nx_runtime_monitor_step_thermal(m,
61 60, 60,
62 210, 210,
63 30, 30,
64 3000)
65 if v4 != NX_RT_ISSUE_NONE { return 40 }
66
67 // ===== (e) Hotend below for > duration -> HOTEND_TEMP_DROP =====
68 nx_runtime_monitor_step_thermal(m, 60, 60, 200, 210, 30, 30, 4000)
69 nx_runtime_monitor_step_thermal(m, 60, 60, 200, 210, 30, 30, 5000)
70 let v5: i64 = nx_runtime_monitor_step_thermal(m,
71 60, 60,
72 200, 210, // 10°C below > 3°C tolerance
73 30, 30,
74 6500) // > 2s since first below
75 if v5 != NX_RT_ISSUE_HOTEND_TEMP_DROP { return 50 }
76
77 // ===== (f) Chamber below for > duration -> CHAMBER_TEMP_DROP =====
78 // (Reset chamber timer by going back to setpoint first)
79 nx_runtime_monitor_step_thermal(m, 60, 60, 210, 210, 30, 30, 7000)
80 nx_runtime_monitor_step_thermal(m, 60, 60, 210, 210, 25, 30, 8000)
81 let v6: i64 = nx_runtime_monitor_step_thermal(m,
82 60, 60,
83 210, 210,
84 25, 30,
85 10500) // > 2s below
86 if v6 != NX_RT_ISSUE_CHAMBER_TEMP_DROP { return 60 }
87
88 // ===== (g) Setpoint = -1 skips axis =====
89 let m2: *NxRuntimeMonitor = nx_runtime_monitor_new(5000, 3, 16384, 16384)
90 nx_runtime_monitor_set_thermal(m2, 3, 2000)
91 // bed at -100°C but setpoint=-1 -> skip; no alarm
92 nx_runtime_monitor_step_thermal(m2, 0 - 100, -1, 210, 210, 30, 30, 0)
93 let v7: i64 = nx_runtime_monitor_step_thermal(m2,
94 0 - 100, -1,
95 210, 210,
96 30, 30,
97 5000) // bed cold but skipped
98 if v7 != NX_RT_ISSUE_NONE { return 70 }
99 if m2.n_issues_total != 0 { return 71 }
100
101 // ===== (h) Issue count tracking =====
102 if m.n_issues_total != 3 { return 80 } // bed + hotend + chamber
103
104 return 0
105}