1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
//! Elevator Finite State Machine (FSM) Module
//!
//! This module contains the core logic for the elevator's finite state machine (FSM).
//! It is responsible for reacting to sensor inputs, handling requests, updating the internal
//! elevator state, and controlling motor and lights accordingly.
//!
//! The FSM implements transitions between key elevator states, such as:
//! - Moving
//! - DoorOpen
//! - Idle
//! - Error
//!
//! # Main Responsibilities
//! - Handling initialization from unknown position (`on_init`)
//! - Managing floor arrivals and door timeout logic (`on_floor_arrival`, `on_door_timeout`)
//! - Monitoring inactivity or fault conditions (`handle_error_timeout`)
//! - Executing transitions from Idle state (`handle_idle_state`)
//!
//! # Timers
//! The FSM relies on three coordinated timers:
//! - `door`: Tracks how long the door has been open.
//! - `cab_priority`: Gives passengers time to press cab buttons after door opens.
//! - `error`: Tracks how long the system has been inactive or blocked.
//!
//! These timers are grouped into the [`ElevatorTimers`] struct and passed where needed.
//!
//! # Integration
//! This module is called from the elevator runtime loop and reacts to:
//! - New floor sensor values
//! - Cab and hall call requests
//! - Timer expirations
//!
//!
//! # Related Modules
//! - [`request`]: Direction and behaviour decision logic.
//! - [`self_elevator`]: Local state updates from hardware events.
//! - [`lights`]: Door and button light controls.
//!
//! # Note
//! All function names follow snake_case naming for consistency.
use self_elevator;
use request;
use lights;
use ;
use crateprint;
use crateconfig;
use crate;
use crate;
use sleep;
use mpsc;
/// Initializes the elevator by moving downward until a valid floor is reached.
///
/// This function sets the elevator in motion and waits until the floor sensor detects
/// a valid floor. During this process, it updates the local elevator state with incoming messages,
/// while tracking timeout conditions through the shared timer structure.
///
/// # Parameters
/// - `self_container`: Mutable reference to the elevator's internal state.
/// - `e`: The hardware-facing elevator handle (for motor control).
/// - `local_elev_rx`: Channel receiver for elevator sensor and button messages.
/// - `timers`: Mutable reference to the shared `ElevatorTimers` instance.
pub async
/// Handles floor arrival updates when a new floor sensor reading is detected.
///
/// If the current floor (`last_floor_sensor`) is different from the previously known floor,
/// this function triggers arrival-handling logic, restarts the error timer,
/// and optionally releases the cab call timer if the stop was due to an inside request.
///
/// # Parameters
/// - `self_container`: Mutable reference to the local elevator state.
/// - `e`: Elevator hardware interface for controlling motor and lights.
/// - `prev_floor`: Mutable reference to the previous floor value (used for change detection).
/// - `timers`: Mutable reference to the shared `ElevatorTimers` instance.
///
/// # Behavior
/// - Calls `on_floor_arrival()` if floor changed.
/// - Starts the error timer on valid floor detection.
/// - Releases the cab call timer if the stop was due to an inside (cab) request.
pub async
/// Function to handle stop button event
///
/// # Note
/// Stop button is not properly implemented. Pressing stop button will only put the elevator in `CosmicError`-state
pub async
/// Handles door timeout logic when appropriate.
///
/// If the door timer has expired and no obstruction is detected.
/// If the elevator is moving toward a cab call, the cab call timer
/// is released. If the cab call timer has also expired, the system proceeds to handle
/// the door timeout state transition.
///
/// # Parameters
/// - `self_container`: Mutable reference to the elevator's internal state.
/// - `e`: Elevator identifier or hardware handle used to control lights and motors.
/// - `door_timer`: Timer that tracks how long the door has been open.
///
/// # Behavior
/// - Handles door-close logic via finite state machine if cab call timer is also expired.
pub async
/// Monitors elevator activity and triggers error behavior after a timeout period.
///
/// If no cab call has timed out or the elevator is idle, the error timer is restarted.
/// If the error timer itself has expired and a cab call was previously active,
/// the elevator enters an error state and logs a critical error message.
///
/// # Parameters
/// - `self_container`: Reference to the elevator state being monitored.
/// - `cab_priority_timer`: Timer tracking how long a cab call has been pending.
/// - `error_timer`: Mutable timer for detecting inactivity or system faults.
/// - `prev_cab_priority_timer_stat`: Whether the cab call timer had previously expired.
///
/// # Behavior
/// - Triggers an error state if prolonged inactivity or failure is detected.
/// Attempts to transition the elevator from idle to active movement if a request is pending.
///
/// If the elevator is currently idle, the system chooses a new direction and behavior
/// using the request logic. If a non-idle state is chosen, the elevator's direction
/// and behavior are updated, the door timer is started, and the motor is stopped
/// in preparation for movement or door logic.
///
/// # Parameters
/// - `self_container`: Mutable reference to the elevator's current state.
/// - `e`: Elevator handle or control interface.
/// - `door_timer`: Timer used to delay transitions or prepare door actions.
///
/// # Behavior
/// - Only operates when the elevator is in an idle state.
/// - Initializes direction and behavior when transitioning out of idle.
/// - Starts door timer and stops the motor to stabilize before further action.
/// Handles elevator behavior upon arrival at a new floor.
///
/// If the elevator is currently moving or in an error state, this function checks
/// whether it should stop at the current floor (e.g., due to a hall or cab request).
/// If a stop is needed, it performs the following actions:
/// - Stops the motor
/// - Clears cab requests at the current floor
/// - Starts both the door timer and the cab call priority timer
/// - Sets the elevator's behavior to `DoorOpen`
///
///
/// # Parameters
/// - `elevator`: Mutable reference to the elevator's internal state.
/// - `e`: Elevator hardware interface, used to control motor and lights.
/// - `door_timer`: Timer tracking how long the door should stay open.
/// - `cab_priority_timer`: Timer giving priority to inside cab requests after door opens.
async
/// Handles the event when the door timeout has expired.
///
/// This function is called after the door has been open for a certain time.
/// It decides what the elevator should do next by:
/// - Choosing a new direction and behaviour using the request logic
/// - Updating the elevator's direction and behaviour accordingly
///
/// If the elevator decides to stay in `DoorOpen`, it means there is still
/// a request at the current floor and the door should remain open.
/// Otherwise, the elevator starts moving in the chosen direction.
///
/// # Parameters
/// - `elevator`: Mutable reference to the elevator's internal state.
/// - `e`: Elevator hardware interface, used to control lights and motor.
async