-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtoaster.e
236 lines (170 loc) · 8.94 KB
/
toaster.e
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
decl_name "Toaster Oven"
decl_version 2
/* Load the registry with some default values. */
decl_startup {
"regadd timer.short 5 &"
"regadd timer.default 10 &"
"regadd timer.long 30 &"
"regadd toaster.name 'My Toaster'"
}
decl_variables {
Timer = 10 /* Reload value for timer. */
}
/* Actions can dispatch evets into their own state machines. We
declare a few events here for use by the state machines. */
decl_events {
_evt_Door
_evt_OnOff
}
statemachine Toaster_oven {
/* On startup, transition to Toaster_off. It is
assumed the door is closed for the example. */
startstate Toaster_off
state Door_closed {
/* Transtioning from Door_open to any of the Door_closed
substates will call the entry actions defined here. */
enter (toaster_lamp, OFF)
/* For any of the Door_closed substates the Door event
will transition to the Door_open state. */
event (_evt_Door, Door_opened)
/* When the door is opened the lamp is turned on. */
exit (toaster_lamp, ON)
}
super Door_closed {
/* All states in this scope takes Door_closed as
super state. Entry and Exit actions during state
state transitions will happen according to the UML
specification. Super states can be nested. */
state Toaster_off {
/* Reset the timer. */
enter (state_timer1_sec, 0)
/* Set the timer. */
action (_evt_OnOff, state_timer1_sec, [Timer])
/* Transition to Toaster_on. */
event (_evt_OnOff, Toaster_on)
}
state Toaster_on {
/* On entry, turn the heater on. */
enter (toaster_heater, ON)
/* When the timer expires, transition to Toaster_off. */
event (_state_timer1, Toaster_off)
/* On the OnOff event, transition to Toaster_off. */
event (_evt_OnOff, Toaster_off)
/* On exit, turn the heater off. */
exit (toaster_heater, OFF)
}
}
state Door_opened {
/* When the door is closed, check if the timer is active
and load the result into the accumulator. */
action_ld (_evt_Door, [a], state_timer1_active)
/* If the accumulator is set, transition to Toaster_on. */
event_if (_evt_Door, Toaster_on)
/* If the accumulator is clear, transition to Toaster_off. */
event_nt (_evt_Door, Toaster_off)
}
}
/* more variable declarations to be appended to the global variables */
decl_variables {
LogLevel = LOG_ALL /* Debug log level */
LogOutput = ENABLE /* Toaster output ENABLED/DISABLED */
}
/* more event declarations to be appended to the global events */
decl_events {
_evt_WriteSettings
_evt_WriteMenu
_evt_Misc
}
statemachine Toaster_controller {
startstate start
state start {
enter (console_events_register, TRUE)
enter (debug_log_statemachine, "Toaster_oven")
enter (debug_log_level, [LogLevel])
enter (debug_log_output, [LogOutput])
event (_state_start, menu_ctrl)
}
state menu {
action (_evt_WriteSettings, console_writeln, "")
action (_evt_WriteSettings, console_writeln, "'[toaster.name]' settings:")
action (_evt_WriteSettings, console_writeln, " - Timer: [Timer]s")
action (_evt_WriteSettings, a_load, [LogLevel])
action_eq (_evt_WriteSettings, LOG_ALL, console_writeln, " - Log Level: ALL")
action_eq (_evt_WriteSettings, LOG_TRANSITIONS, console_writeln, " - Log Level: TRANSITIONS")
action_eq (_evt_WriteSettings, LOG_REPORT, console_writeln, " - Log Level: REPORT")
action (_evt_WriteSettings, a_load, [LogOutput])
action_eq (_evt_WriteSettings, DISABLE, console_writeln, " - Log Output: DISABLE")
action_ne (_evt_WriteSettings, DISABLE, console_writeln, " - Log Output: ENABLE")
action_eq_e (_console_char, 'D', debug_dump)
}
super menu {
state menu_ctrl {
action (_state_start, state_event_local, _evt_WriteSettings)
action (_state_start, state_event_local, _evt_WriteMenu)
action (_evt_WriteMenu, console_writeln, "Control menu:")
action (_evt_WriteMenu, console_writeln, " \\[t] Toaster On/Off.")
action (_evt_WriteMenu, console_writeln, " \\[d] Door Open/Close.")
action (_evt_WriteMenu, console_writeln, " \\[s] Settings.")
action (_evt_WriteMenu, console_writeln, " \\[h] Help.")
action (_evt_WriteMenu, console_writeln, " \\[q] Quit.")
action (_console_char, a_load, 0)
action_eq_e (_console_char, 't', state_event, _evt_OnOff)
action_eq_e (_console_char, 'd', state_event, _evt_Door)
action_eq_e (_console_char, 's', a_load, TRUE)
action_eq_e (_console_char, 'h', state_event_local, _evt_WriteMenu)
action_eq_e (_console_char, '?', state_event_local, _evt_WriteMenu)
event_if (_console_char, menu_settings)
}
state menu_settings {
action (_state_start, state_event_local, _evt_WriteSettings)
action (_state_start, state_event_local, _evt_WriteMenu)
action (_evt_WriteMenu, console_writeln, "Settings menu:")
action (_evt_WriteMenu, console_writeln, " \\[1] Set [timer.short] second timer.")
action (_evt_WriteMenu, console_writeln, " \\[2] Set [timer.default] second timer.")
action (_evt_WriteMenu, console_writeln, " \\[3] Set [timer.long] second timer.")
action (_evt_WriteMenu, console_writeln, " \\[4] Log REPORT.")
action (_evt_WriteMenu, console_writeln, " \\[5] Log TRANSITIONS.")
action (_evt_WriteMenu, console_writeln, " \\[6] Log ALL.")
action (_evt_WriteMenu, console_writeln, " \\[7] Output ENABLE/DISABLE.")
action (_evt_WriteMenu, console_writeln, " \\[8] Start tress test.")
action (_evt_WriteMenu, console_writeln, " \\[x] Exit setting menu.")
action (_evt_WriteMenu, console_writeln, " \\[q] Quit.")
action_ld (_console_char, [a], get, [Timer])
action_eq_e (_console_char, '1', a_load, [timer.short])
action_eq_e (_console_char, '2', a_load, [timer.default])
action_eq_e (_console_char, '3', a_load, [timer.long])
action_ld (_console_char, [Timer], get, [a])
action_ld (_console_char, [a], get, [LogLevel])
action_eq_e (_console_char, '4', a_load, LOG_REPORT)
action_eq_e (_console_char, '5', a_load, LOG_TRANSITIONS)
action_eq_e (_console_char, '6', a_load, LOG_ALL)
action_ld (_console_char, [LogLevel], get, [a])
action (_console_char, debug_log_level, [LogLevel])
action_ld (_console_char, [a], get, [LogOutput])
action_eq_e (_console_char, '7', a_not, DISABLE)
action_ld (_console_char, [LogOutput], get, [a])
action (_console_char, debug_log_output, [LogOutput])
action_eq_e (_console_char, '8', state_event_local, _evt_Misc)
action (_console_char, a_load, 0)
action_eq_e (_console_char, 'x', a_load, 1)
event_if (_console_char, menu_ctrl)
event_nt (_console_char, menu_settings)
event (_evt_Misc, stress_test)
}
}
state stress_test {
enter (console_writeln, ">> test")
enter (state_timer1, 1000)
action (_state_timer1, rand+, 10)
action_gt (_state_timer1, 5, console_writeln, ">> test Door")
action_gt (_state_timer1, 5, state_event, _evt_Door)
action_lt (_state_timer1, 5, console_writeln, ">> test OnOff")
action_lt (_state_timer1, 5, state_event, _evt_OnOff)
action (_state_timer1, rand, 4)
action (_state_timer1, a_inc, 5)
action (_state_timer1, state_timer1_sec, [a])
action_eq_e (_console_char!, 'D', debug_dump)
event (_console_char, PREVIOUS)
exit (console_writeln, "<< test")
}
}