Commit af27778be6b51d9a7a478432de1b155526dec1fb
1 parent
93eb4676f3
Exists in
master
and in
2 other branches
HACCP 구현
Showing
15 changed files
with
788 additions
and
8 deletions
Show diff stats
app/gui/oven_control/autocook.cpp
1 | 1 | #include "autocook.h" |
2 | 2 | #include "soundplayer.h" |
3 | +#include "haccp.h" | |
3 | 4 | |
4 | 5 | AutoCook::AutoCook() : currentStepIndex(0), done_(false), doorOpened(false), checkingCoreTemp(false) |
5 | 6 | { |
... | ... | @@ -12,7 +13,6 @@ AutoCook::AutoCook(Cook cook) : AutoCook() |
12 | 13 | for (int idx = 0; idx < this->cook.steps.size(); idx++) |
13 | 14 | this->cook.steps[idx].time *= 1000; |
14 | 15 | |
15 | - | |
16 | 16 | startStep(); |
17 | 17 | } |
18 | 18 | |
... | ... | @@ -71,6 +71,19 @@ void AutoCook::startStep() |
71 | 71 | break; |
72 | 72 | } |
73 | 73 | |
74 | + HACCP::autoStart(cook.root); | |
75 | + | |
76 | + for (int i = 0; i < 5; i++) | |
77 | + { | |
78 | + Define::CookConfigType type = cook.configs[i].type; | |
79 | + if (type == Define::ConfigNotUsed) | |
80 | + continue; | |
81 | + | |
82 | + HACCP::setConfig(type, cook.configs[i].current); | |
83 | + } | |
84 | + | |
85 | + HACCP::setStep(currentStep.type); | |
86 | + | |
74 | 87 | advance(); |
75 | 88 | } |
76 | 89 | |
... | ... | @@ -81,6 +94,8 @@ void AutoCook::nextStep() |
81 | 94 | CookStep ¤tStep = cook.steps[currentStepIndex]; |
82 | 95 | CookStep &nextStep = cook.steps[currentStepIndex + 1]; |
83 | 96 | |
97 | + HACCP::setStep(nextStep.type); | |
98 | + | |
84 | 99 | Define::StepClass currentClass = Define::classify(currentStep.type); |
85 | 100 | Define::StepClass nextClass = Define::classify(nextStep.type); |
86 | 101 | |
... | ... | @@ -315,6 +330,7 @@ bool AutoCook::advance() |
315 | 330 | { |
316 | 331 | done_ = true; |
317 | 332 | |
333 | + HACCP::done(); | |
318 | 334 | SoundPlayer::playStop(); |
319 | 335 | |
320 | 336 | if (currentStep.dehumidification) |
... | ... | @@ -360,6 +376,7 @@ bool AutoCook::advance() |
360 | 376 | { |
361 | 377 | done_ = true; |
362 | 378 | |
379 | + HACCP::done(); | |
363 | 380 | SoundPlayer::playStop(); |
364 | 381 | |
365 | 382 | if (currentStep.dehumidification) | ... | ... |
app/gui/oven_control/autocookwindow.cpp
... | ... | @@ -17,6 +17,7 @@ |
17 | 17 | #include "autocookselectionpopup.h" |
18 | 18 | #include "autocookcheckconfigwindow.h" |
19 | 19 | #include "manualviewerdlg.h" |
20 | +#include "haccp.h" | |
20 | 21 | |
21 | 22 | AutoCookWindow::AutoCookWindow(QWidget *parent, Cook cook) : |
22 | 23 | QMainWindow(parent), |
... | ... | @@ -110,6 +111,7 @@ AutoCookWindow::AutoCookWindow(QWidget *parent, Cook cook) : |
110 | 111 | AutoCookWindow::~AutoCookWindow() |
111 | 112 | { |
112 | 113 | Oven::getInstance()->stop(); |
114 | + HACCP::done(); | |
113 | 115 | |
114 | 116 | delete ui; |
115 | 117 | } |
... | ... | @@ -749,6 +751,9 @@ void AutoCookWindow::startProcess(int process) |
749 | 751 | |
750 | 752 | SoundPlayer::playStart(); |
751 | 753 | |
754 | + HACCP::autoStart(cook.root); | |
755 | + HACCP::setProcess(Define::MakeCrisper); | |
756 | + | |
752 | 757 | break; |
753 | 758 | } |
754 | 759 | case Define::KeepWarm: |
... | ... | @@ -756,6 +761,9 @@ void AutoCookWindow::startProcess(int process) |
756 | 761 | processSelected = false; |
757 | 762 | selectedProcess = (Define::Process) process; |
758 | 763 | |
764 | + HACCP::autoStart(cook.root); | |
765 | + HACCP::setProcess(Define::KeepWarm); | |
766 | + | |
759 | 767 | KeepWarmPopup *p = new KeepWarmPopup(this); |
760 | 768 | p->showFullScreen(); |
761 | 769 | p->raise(); |
... | ... | @@ -778,6 +786,7 @@ void AutoCookWindow::checkProcess() |
778 | 786 | Oven *oven = Oven::getInstance(); |
779 | 787 | if (oven->currentTemp() >= oven->temp()) |
780 | 788 | { |
789 | + HACCP::done(); | |
781 | 790 | SoundPlayer::playStop(); |
782 | 791 | oven->stopCooking(); |
783 | 792 | checkProcessTimer.stop(); | ... | ... |
app/gui/oven_control/define.cpp
... | ... | @@ -566,3 +566,36 @@ QString Define::name(Define::Mode mode) |
566 | 566 | return ""; |
567 | 567 | } |
568 | 568 | } |
569 | + | |
570 | +QString Define::name(Define::CookConfigType type) | |
571 | +{ | |
572 | + switch (type) | |
573 | + { | |
574 | + case Brightness: | |
575 | + return "brightness"; | |
576 | + case BurnDegree: | |
577 | + return "cookinglevel"; | |
578 | + case SoftBoilDegree: | |
579 | + return "boiledlevel"; | |
580 | + case PieceSize: | |
581 | + return "size"; | |
582 | + case CrispyDegree: | |
583 | + return "crispy1"; | |
584 | + case MoistDegree: | |
585 | + return "moisten1"; | |
586 | + case Thickness: | |
587 | + return "thickness"; | |
588 | + case Humidity: | |
589 | + return "humidity"; | |
590 | + case Temperature: | |
591 | + return "temperature"; | |
592 | + case Time: | |
593 | + return "cookingtime"; | |
594 | + case CoreTemperature: | |
595 | + return "coretemperature"; | |
596 | + case Thermometer: | |
597 | + return "coretemperaturesensor"; | |
598 | + default: | |
599 | + return "unknownconfig"; | |
600 | + } | |
601 | +} | ... | ... |
app/gui/oven_control/define.h
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | |
10 | 10 | // 0 for normal |
11 | 11 | // 1 for premium |
12 | -#define MODEL_GRADE 0 | |
12 | +#define MODEL_GRADE 1 | |
13 | 13 | |
14 | 14 | namespace Define |
15 | 15 | { |
... | ... | @@ -52,6 +52,7 @@ namespace Define |
52 | 52 | QString iconActiveted(CookConfigType type); |
53 | 53 | QString minimum(CookConfigType type); |
54 | 54 | QString maximum(CookConfigType type); |
55 | + QString name(CookConfigType type); | |
55 | 56 | |
56 | 57 | enum StepClass |
57 | 58 | { | ... | ... |
app/gui/oven_control/engineermenuwindow.cpp
... | ... | @@ -11,6 +11,7 @@ |
11 | 11 | #include "fileprocessor.h" |
12 | 12 | #include "fileprocessdlg.h" |
13 | 13 | #include "usbcheckpopupdlg.h" |
14 | +#include "haccp.h" | |
14 | 15 | |
15 | 16 | #include <QKeyEvent> |
16 | 17 | |
... | ... | @@ -28,10 +29,14 @@ EngineerMenuWindow::EngineerMenuWindow(QWidget *parent) : |
28 | 29 | |
29 | 30 | foreach (QPushButton *button, findChildren<QPushButton *>()) |
30 | 31 | connect(button, &QPushButton::pressed, SoundPlayer::playClick); |
32 | + | |
33 | + HACCP::engineeringStart(); | |
31 | 34 | } |
32 | 35 | |
33 | 36 | EngineerMenuWindow::~EngineerMenuWindow() |
34 | 37 | { |
38 | + HACCP::done(); | |
39 | + | |
35 | 40 | delete ui; |
36 | 41 | } |
37 | 42 | ... | ... |
app/gui/oven_control/haccp.cpp
... | ... | @@ -0,0 +1,651 @@ |
1 | +#include "haccp.h" | |
2 | + | |
3 | +#include <QDateTime> | |
4 | +#include <QDir> | |
5 | +#include <QTextStream> | |
6 | +#include <QTimer> | |
7 | + | |
8 | +#include "unistd.h" | |
9 | + | |
10 | +#include "stringer.h" | |
11 | +#include "oven.h" | |
12 | + | |
13 | +namespace | |
14 | +{ | |
15 | + | |
16 | +enum Type { Invalid, Manual, Auto, Multi, Wash, Engineering }; | |
17 | + | |
18 | +struct Stamp | |
19 | +{ | |
20 | + QDateTime time; | |
21 | + int temp; | |
22 | + int targetCoreTemp; | |
23 | + int curCoreTemp; | |
24 | + bool door; | |
25 | + QString caption; | |
26 | +}; | |
27 | + | |
28 | +struct Config | |
29 | +{ | |
30 | + Define::CookConfigType type; | |
31 | + int level; | |
32 | +}; | |
33 | + | |
34 | +struct Data | |
35 | +{ | |
36 | + QDateTime startedAt; | |
37 | + Type type; | |
38 | + QString autoRoot; | |
39 | + QList<Config> autoConfig; | |
40 | + int washType; | |
41 | + QList<Stamp> records; | |
42 | +} data; | |
43 | + | |
44 | +QDateTime initializedTime; | |
45 | +int processCount; | |
46 | +QTimer checkTimer; | |
47 | +QTime lastStampedTime; | |
48 | + | |
49 | +Define::Mode lastMode; | |
50 | +int lastFan; | |
51 | +bool lastDoor; | |
52 | +bool lastDamper; | |
53 | +bool lastSideNozzle; | |
54 | +bool lastCoreTempEnabled; | |
55 | + | |
56 | +int figureProcessCount(); | |
57 | +void initData(Type type); | |
58 | +void start(); | |
59 | +void stamp(QString caption = ""); | |
60 | +void stampStart(); | |
61 | +void stampMode(Define::Mode mode); | |
62 | +void stampDamper(); | |
63 | +void stampSideNozzle(); | |
64 | +void stampEnd(); | |
65 | +void stampError(QString error); | |
66 | +void saveData(); | |
67 | +void check(); | |
68 | +} | |
69 | + | |
70 | +namespace HACCP | |
71 | +{ | |
72 | + | |
73 | +void init() | |
74 | +{ | |
75 | + // make the directory if it doesn't exist | |
76 | + QDir().mkpath("/prime/haccp"); | |
77 | + | |
78 | + initializedTime = QDateTime::currentDateTime(); | |
79 | + processCount = figureProcessCount() + 1; | |
80 | + | |
81 | + checkTimer.setInterval(100); | |
82 | + QObject::connect(&checkTimer, &QTimer::timeout, check); | |
83 | + | |
84 | + Oven *oven = Oven::getInstance(); | |
85 | + QObject::connect(oven, &Oven::changed, check); | |
86 | +} | |
87 | + | |
88 | +void autoStart(const QString &path) | |
89 | +{ | |
90 | + initData(Auto); | |
91 | + data.autoRoot = path; | |
92 | + | |
93 | + start(); | |
94 | +} | |
95 | + | |
96 | +void manualStart() | |
97 | +{ | |
98 | + qDebug() << __FUNCTION__; | |
99 | + | |
100 | + initData(Manual); | |
101 | + start(); | |
102 | +} | |
103 | + | |
104 | +void multiStart() | |
105 | +{ | |
106 | + initData(Multi); | |
107 | + start(); | |
108 | +} | |
109 | + | |
110 | +void washStart(int type) | |
111 | +{ | |
112 | + initData(Wash); | |
113 | + data.washType = type; | |
114 | +} | |
115 | + | |
116 | +void engineeringStart() | |
117 | +{ | |
118 | + initData(Engineering); | |
119 | +} | |
120 | + | |
121 | +void done() | |
122 | +{ | |
123 | + qDebug() << __FUNCTION__; | |
124 | + if (data.type == Invalid) | |
125 | + return; | |
126 | + | |
127 | + stampEnd(); | |
128 | + saveData(); | |
129 | +} | |
130 | + | |
131 | +void error(QString code) | |
132 | +{ | |
133 | + if (data.type == Invalid) | |
134 | + return; | |
135 | + | |
136 | + stampError(code); | |
137 | + saveData(); | |
138 | +} | |
139 | + | |
140 | +void setConfig(Define::CookConfigType type, int level) | |
141 | +{ | |
142 | + data.autoConfig.append(Config{type, level}); | |
143 | +} | |
144 | + | |
145 | +void setStep(Define::StepType type) | |
146 | +{ | |
147 | + switch (type) | |
148 | + { | |
149 | + case Define::Preheat: | |
150 | + stamp("preheat"); | |
151 | + break; | |
152 | + case Define::Load: | |
153 | + stamp("load"); | |
154 | + break; | |
155 | + case Define::PutThermometer: | |
156 | + stamp("therometer"); | |
157 | + break; | |
158 | + case Define::Cut: | |
159 | + stamp("cut"); | |
160 | + break; | |
161 | + case Define::Pour: | |
162 | + stamp("pour"); | |
163 | + break; | |
164 | + case Define::Bake: | |
165 | + stamp("bake"); | |
166 | + break; | |
167 | + case Define::Dry: | |
168 | + stamp("dry"); | |
169 | + break; | |
170 | + case Define::Ferment: | |
171 | + stamp("ferment"); | |
172 | + break; | |
173 | + case Define::BlowSteam: | |
174 | + stamp("steaming"); | |
175 | + break; | |
176 | + case Define::CoolDown: | |
177 | + stamp("cooldown"); | |
178 | + break; | |
179 | + case Define::Steam: | |
180 | + stamp("steam"); | |
181 | + break; | |
182 | + case Define::Roast: | |
183 | + stamp("roasting"); | |
184 | + break; | |
185 | + case Define::Boil: | |
186 | + stamp("boil"); | |
187 | + break; | |
188 | + case Define::Thicken: | |
189 | + stamp("thicken"); | |
190 | + break; | |
191 | + case Define::WarmUp: | |
192 | + stamp("warmup"); | |
193 | + break; | |
194 | + case Define::MakeCrispy: | |
195 | + stamp("crispy2"); | |
196 | + break; | |
197 | + case Define::Finish: | |
198 | + stamp("finish"); | |
199 | + break; | |
200 | + case Define::Damp: | |
201 | + stamp("damp"); | |
202 | + break; | |
203 | + case Define::Defer: | |
204 | + stamp("defer"); | |
205 | + break; | |
206 | + case Define::Grill: | |
207 | + stamp("grill"); | |
208 | + break; | |
209 | + case Define::End: | |
210 | + stamp("end"); | |
211 | + break; | |
212 | + case Define::Burn: | |
213 | + stamp("burn"); | |
214 | + break; | |
215 | + case Define::Fry: | |
216 | + stamp("fry"); | |
217 | + break; | |
218 | + case Define::HeatUp: | |
219 | + stamp("heatup"); | |
220 | + break; | |
221 | + case Define::Ripen: | |
222 | + stamp("ripen"); | |
223 | + break; | |
224 | + case Define::RipenKeep: | |
225 | + stamp("ripenkeep"); | |
226 | + break; | |
227 | + case Define::BoilSteadily: | |
228 | + stamp("boilsteadily"); | |
229 | + break; | |
230 | + case Define::CookGratin: | |
231 | + stamp("cookgratin"); | |
232 | + break; | |
233 | + case Define::Brown: | |
234 | + stamp("brown"); | |
235 | + break; | |
236 | + case Define::Simmer: | |
237 | + stamp("simmer"); | |
238 | + break; | |
239 | + case Define::Moisten: | |
240 | + stamp("moisten2"); | |
241 | + break; | |
242 | + } | |
243 | +} | |
244 | + | |
245 | +void setProcess(Define::Process type) | |
246 | +{ | |
247 | + switch (type) | |
248 | + { | |
249 | + case Define::CookAgain: | |
250 | + stamp("again"); | |
251 | + break; | |
252 | + case Define::MakeCrisper: | |
253 | + stamp("crispy3"); | |
254 | + break; | |
255 | + case Define::KeepWarm: | |
256 | + stamp("heatreserve"); | |
257 | + break; | |
258 | + } | |
259 | +} | |
260 | + | |
261 | +} | |
262 | + | |
263 | + | |
264 | +namespace | |
265 | +{ | |
266 | + | |
267 | +QString path() | |
268 | +{ | |
269 | + return "/prime/haccp"; | |
270 | +} | |
271 | + | |
272 | +QString path(int year) | |
273 | +{ | |
274 | + return QString("/prime/haccp/%1").arg(year, 4, 10, QLatin1Char('0')); | |
275 | +} | |
276 | + | |
277 | +QString path(int year, int month) | |
278 | +{ | |
279 | + return QString("/prime/haccp/%1/%2") | |
280 | + .arg(year, 4, 10, QLatin1Char('0')) | |
281 | + .arg(month, 2, 10, QLatin1Char('0')); | |
282 | +} | |
283 | + | |
284 | +QString path(int year, int month, int day) | |
285 | +{ | |
286 | + return QString("/prime/haccp/%1/%2/%3") | |
287 | + .arg(year, 4, 10, QLatin1Char('0')) | |
288 | + .arg(month, 2, 10, QLatin1Char('0')) | |
289 | + .arg(day, 2, 10, QLatin1Char('0')); | |
290 | +} | |
291 | + | |
292 | +QString path(int year, int month, int day, int proc) | |
293 | +{ | |
294 | + return QString("/prime/haccp/%1/%2/%3/%4") | |
295 | + .arg(year, 4, 10, QLatin1Char('0')) | |
296 | + .arg(month, 2, 10, QLatin1Char('0')) | |
297 | + .arg(day, 2, 10, QLatin1Char('0')) | |
298 | + .arg(proc); | |
299 | +} | |
300 | + | |
301 | +int figureLatest(const QString &path, QDir::Filter filter) | |
302 | +{ | |
303 | + QDir root(path); | |
304 | + if (!root.exists()) | |
305 | + return -1; | |
306 | + | |
307 | + QStringList list = root.entryList(filter); | |
308 | + if (list.empty()) | |
309 | + return -1; | |
310 | + | |
311 | + int latest = -1; | |
312 | + foreach (QString e, list) | |
313 | + { | |
314 | + bool ok; | |
315 | + int num = e.toInt(&ok); | |
316 | + if (!ok) | |
317 | + continue; | |
318 | + | |
319 | + if (num > latest) | |
320 | + latest = num; | |
321 | + } | |
322 | + | |
323 | + return latest; | |
324 | +} | |
325 | + | |
326 | +int figureLatestDir(const QString &path) | |
327 | +{ | |
328 | + return figureLatest(path, QDir::AllDirs); | |
329 | +} | |
330 | + | |
331 | +int figureLatestFile(const QString &path) | |
332 | +{ | |
333 | + return figureLatest(path, QDir::Files); | |
334 | +} | |
335 | + | |
336 | +int figureProcessCount() | |
337 | +{ | |
338 | + int year = figureLatestDir(path()); | |
339 | + if (year < 0) | |
340 | + return 0; | |
341 | + | |
342 | + int month = figureLatestDir(path(year)); | |
343 | + if (month < 0) | |
344 | + return 0; | |
345 | + | |
346 | + int day = figureLatestDir(path(year, month)); | |
347 | + if (day < 0) | |
348 | + return 0; | |
349 | + | |
350 | + int proc = figureLatestFile(path(year, month, day)); | |
351 | + if (proc < 0) | |
352 | + return 0; | |
353 | + | |
354 | + return proc; | |
355 | +} | |
356 | + | |
357 | +void initData(Type type) | |
358 | +{ | |
359 | + data.type = type; | |
360 | + data.autoRoot = QString(); | |
361 | + data.autoConfig.clear(); | |
362 | + data.washType = 0; | |
363 | + data.records.clear(); | |
364 | + | |
365 | + if (initializedTime.isValid()) | |
366 | + { | |
367 | + data.startedAt = initializedTime; | |
368 | + stampStart(); | |
369 | + } | |
370 | + else | |
371 | + data.startedAt = QDateTime::currentDateTime(); | |
372 | + | |
373 | +} | |
374 | + | |
375 | +void start() | |
376 | +{ | |
377 | + qDebug() << __FUNCTION__; | |
378 | + | |
379 | + lastMode = Define::InvalidMode; | |
380 | + lastFan = -1; | |
381 | + lastDoor = false; | |
382 | + lastDamper = false; | |
383 | + lastSideNozzle = false; | |
384 | + lastCoreTempEnabled = false; | |
385 | + | |
386 | + Oven *oven = Oven::getInstance(); | |
387 | + stampMode(oven->mode()); | |
388 | + | |
389 | + checkTimer.start(); | |
390 | +} | |
391 | + | |
392 | +void stamp(QString caption) | |
393 | +{ | |
394 | + qDebug() << __FUNCTION__; | |
395 | + | |
396 | + if (data.type == Invalid) | |
397 | + return; | |
398 | + | |
399 | + Oven *oven = Oven::getInstance(); | |
400 | + | |
401 | + Stamp s; | |
402 | + s.time = QDateTime::currentDateTime(); | |
403 | + s.temp = oven->currentTemp(); | |
404 | + | |
405 | + if (oven->interTempEnabled()) | |
406 | + { | |
407 | + s.targetCoreTemp = oven->interTemp(); | |
408 | + s.curCoreTemp = oven->currentInterTemp(); | |
409 | + } | |
410 | + else | |
411 | + { | |
412 | + s.targetCoreTemp = 0; | |
413 | + s.curCoreTemp = 0; | |
414 | + } | |
415 | + | |
416 | + s.door = oven->door(); | |
417 | + s.caption = caption; | |
418 | + | |
419 | + data.records.append(s); | |
420 | + | |
421 | + lastDoor = oven->door(); | |
422 | + lastStampedTime.start(); | |
423 | +} | |
424 | + | |
425 | +void stampStart() | |
426 | +{ | |
427 | + qDebug() << __FUNCTION__; | |
428 | + | |
429 | + stamp("START (POWER ON)"); | |
430 | +} | |
431 | + | |
432 | +void stampMode(Define::Mode mode) | |
433 | +{ | |
434 | + qDebug() << __FUNCTION__; | |
435 | + | |
436 | + switch (mode) | |
437 | + { | |
438 | + case Define::SteamMode: | |
439 | + stamp("Mode STEAM"); | |
440 | + break; | |
441 | + case Define::CombiMode: | |
442 | + stamp("Mode COMBI"); | |
443 | + break; | |
444 | + case Define::DryMode: | |
445 | + stamp("Mode DRY"); | |
446 | + break; | |
447 | + } | |
448 | + | |
449 | + lastMode = mode; | |
450 | +} | |
451 | + | |
452 | +void stampFan(int fan) | |
453 | +{ | |
454 | + qDebug() << __FUNCTION__; | |
455 | + | |
456 | + lastFan = fan; | |
457 | + stamp(QString("FAN = %1").arg(fan)); | |
458 | +} | |
459 | + | |
460 | +void stampDamper() | |
461 | +{ | |
462 | + qDebug() << __FUNCTION__; | |
463 | + | |
464 | + stamp("DAMPER"); | |
465 | +} | |
466 | + | |
467 | +void stampSideNozzle() | |
468 | +{ | |
469 | + qDebug() << __FUNCTION__; | |
470 | + | |
471 | + stamp("SIDE NOZZLE"); | |
472 | +} | |
473 | + | |
474 | +void stampEnd() | |
475 | +{ | |
476 | + qDebug() << __FUNCTION__; | |
477 | + | |
478 | + stamp("END"); | |
479 | +} | |
480 | + | |
481 | +void stampError(QString error) | |
482 | +{ | |
483 | + stamp(QString("END (%1)").arg(error)); | |
484 | +} | |
485 | + | |
486 | +void saveData() | |
487 | +{ | |
488 | + qDebug() << __FUNCTION__; | |
489 | + | |
490 | + if (data.records.isEmpty()) | |
491 | + { | |
492 | + data.type = Invalid; | |
493 | + return; | |
494 | + } | |
495 | + | |
496 | + QDate date = data.startedAt.date(); | |
497 | + | |
498 | + QDir().mkpath(path(date.year(), date.month(), date.day())); | |
499 | + | |
500 | + QString p = path(date.year(), date.month(), date.day(), processCount); | |
501 | + | |
502 | + QFile file(p); | |
503 | + if (!file.open(QIODevice::Truncate | QIODevice::WriteOnly)) | |
504 | + { | |
505 | + qDebug() << "Failed to open"; | |
506 | + return; | |
507 | + } | |
508 | + | |
509 | + QTextStream stream(&file); | |
510 | + stream.setCodec("UTF-8"); | |
511 | + | |
512 | + // TODO: fill them | |
513 | + stream << "No.," << processCount << "\n"; | |
514 | + stream << "Typ," << "\n"; | |
515 | + stream << "Serial No.," << "\n"; | |
516 | + stream << "Version," << "\n"; | |
517 | + stream << "Time," << data.startedAt.toString("yyyy.MM.dd HH:mm:ss") << "\n"; | |
518 | + | |
519 | + stream << "Progr,"; | |
520 | + switch (data.type) | |
521 | + { | |
522 | + case Manual: | |
523 | + stream << 1; | |
524 | + break; | |
525 | + case Auto: | |
526 | + stream << data.autoRoot; | |
527 | + break; | |
528 | + case Multi: | |
529 | + stream << 4; | |
530 | + break; | |
531 | + case Wash: | |
532 | + stream << 6 << "-" << data.washType; | |
533 | + break; | |
534 | + case Engineering: | |
535 | + stream << 999; | |
536 | + break; | |
537 | + } | |
538 | + stream << "\n"; | |
539 | + | |
540 | + stream << "\n" | |
541 | + << "#1,Time\n" | |
542 | + << "#2,Inner Tank Temp\n" | |
543 | + << "#3,Food Temp (Target)\n" | |
544 | + << "#4,Food Temp\n" | |
545 | + << "#5,Door Open / Closed\n"; | |
546 | + | |
547 | + stream << "\n"; | |
548 | + | |
549 | + stream << "#1,#2,#3,#4,#5\n"; | |
550 | + for (int i = 0; i < data.records.size(); i++) | |
551 | + { | |
552 | + const Stamp &s = data.records.at(i); | |
553 | + if (!s.caption.isEmpty() && i+1 < data.records.size()) | |
554 | + { | |
555 | + Stamp &n = data.records[i+1]; | |
556 | + | |
557 | + int secs = data.startedAt.secsTo(s.time); | |
558 | + int nextSecs = data.startedAt.secsTo(n.time); | |
559 | + if (secs == nextSecs | |
560 | + && s.temp == n.temp | |
561 | + && s.targetCoreTemp == n.targetCoreTemp | |
562 | + && s.curCoreTemp == n.curCoreTemp | |
563 | + && s.door == n.door) | |
564 | + { | |
565 | + if (n.caption.isEmpty()) | |
566 | + n.caption = s.caption; | |
567 | + else | |
568 | + n.caption = QString("%1\n%2").arg(s.caption).arg(n.caption); | |
569 | + | |
570 | + continue; | |
571 | + } | |
572 | + } | |
573 | + | |
574 | + if (!s.caption.isEmpty()) | |
575 | + stream << s.caption << "\n"; | |
576 | + | |
577 | + stream << Stringer::timeSecs(data.startedAt.secsTo(s.time)) << "," | |
578 | + << s.temp << "," | |
579 | + << s.targetCoreTemp << "," | |
580 | + << s.curCoreTemp << "," | |
581 | + << (s.door ? "O\n" : "C\n"); | |
582 | + } | |
583 | + | |
584 | + if (!data.autoConfig.isEmpty()) | |
585 | + { | |
586 | + foreach (Config c, data.autoConfig) | |
587 | + stream << Define::name(c.type) | |
588 | + << " = " | |
589 | + << c.level << "\n"; | |
590 | + } | |
591 | + | |
592 | + stream.flush(); | |
593 | + file.close(); | |
594 | + sync(); | |
595 | + | |
596 | + initializedTime = QDateTime(); | |
597 | + processCount++; | |
598 | + | |
599 | + data.type = Invalid; | |
600 | + | |
601 | + checkTimer.stop(); | |
602 | +} | |
603 | + | |
604 | +void check() | |
605 | +{ | |
606 | + switch (data.type) | |
607 | + { | |
608 | + case Invalid: | |
609 | + case Wash: | |
610 | + case Engineering: | |
611 | + return; | |
612 | + default: | |
613 | + break; | |
614 | + } | |
615 | + | |
616 | + Oven *oven = Oven::getInstance(); | |
617 | + | |
618 | + if (oven->mode() != lastMode) | |
619 | + stampMode(oven->mode()); | |
620 | + | |
621 | + if (oven->fan() != lastFan) | |
622 | + stampFan(oven->fan()); | |
623 | + | |
624 | + if (oven->damper() != lastDamper) | |
625 | + { | |
626 | + lastDamper = oven->damper(); | |
627 | + if (lastDamper) | |
628 | + stampDamper(); | |
629 | + } | |
630 | + | |
631 | + if (oven->humidification() != lastSideNozzle) | |
632 | + { | |
633 | + lastSideNozzle = oven->humidification(); | |
634 | + if (lastSideNozzle) | |
635 | + stampSideNozzle(); | |
636 | + } | |
637 | + | |
638 | + if (oven->interTempEnabled() != lastCoreTempEnabled) | |
639 | + { | |
640 | + lastCoreTempEnabled = oven->interTempEnabled(); | |
641 | + stamp(); | |
642 | + } | |
643 | + | |
644 | + if (oven->door() != lastDoor) | |
645 | + stamp(); | |
646 | + | |
647 | + if (lastStampedTime.elapsed() > 60 * 1000 - 100) | |
648 | + stamp(); | |
649 | +} | |
650 | + | |
651 | +} | ... | ... |
app/gui/oven_control/haccp.h
... | ... | @@ -0,0 +1,29 @@ |
1 | +#ifndef HACCP_H | |
2 | +#define HACCP_H | |
3 | + | |
4 | +#include <QString> | |
5 | + | |
6 | +#include "define.h" | |
7 | + | |
8 | +namespace HACCP | |
9 | +{ | |
10 | + | |
11 | +void init(); | |
12 | + | |
13 | +void autoStart(const QString &path); | |
14 | +void manualStart(); | |
15 | +void multiStart(); | |
16 | +void washStart(int type); | |
17 | +void engineeringStart(); | |
18 | + | |
19 | +void done(); | |
20 | +void error(QString code); | |
21 | + | |
22 | +// For auto cook | |
23 | +void setConfig(Define::CookConfigType type, int level); | |
24 | +void setStep(Define::StepType type); | |
25 | +void setProcess(Define::Process type); | |
26 | + | |
27 | +} | |
28 | + | |
29 | +#endif // HACCP_H | ... | ... |
app/gui/oven_control/keepwarmpopup.cpp
... | ... | @@ -3,6 +3,8 @@ |
3 | 3 | |
4 | 4 | #include <QKeyEvent> |
5 | 5 | |
6 | +#include "haccp.h" | |
7 | + | |
6 | 8 | KeepWarmPopup::KeepWarmPopup(QWidget *parent) : |
7 | 9 | QWidget(parent), |
8 | 10 | ui(new Ui::KeepWarmPopup) |
... | ... | @@ -19,6 +21,8 @@ KeepWarmPopup::KeepWarmPopup(QWidget *parent) : |
19 | 21 | |
20 | 22 | KeepWarmPopup::~KeepWarmPopup() |
21 | 23 | { |
24 | + HACCP::done(); | |
25 | + | |
22 | 26 | delete ui; |
23 | 27 | } |
24 | 28 | ... | ... |
app/gui/oven_control/main.cpp
... | ... | @@ -5,6 +5,8 @@ |
5 | 5 | #include "ovenstatics.h" |
6 | 6 | #include "config.h" |
7 | 7 | #include "inputoverwatcher.h" |
8 | +#include "haccp.h" | |
9 | + | |
8 | 10 | #include <QApplication> |
9 | 11 | |
10 | 12 | int main(int argc, char *argv[]) |
... | ... | @@ -32,6 +34,8 @@ int main(int argc, char *argv[]) |
32 | 34 | pal.setColor(QPalette::Disabled, QPalette::Light, QColor(0, 0, 0, 0)); |
33 | 35 | QApplication::setPalette(pal); |
34 | 36 | |
37 | + HACCP::init(); | |
38 | + | |
35 | 39 | MainWindow w; |
36 | 40 | w.showFullScreen(); |
37 | 41 | ... | ... |
app/gui/oven_control/manualcookwindow.cpp
... | ... | @@ -22,6 +22,7 @@ |
22 | 22 | #include "washwindow.h" |
23 | 23 | #include "errorpopupdlg.h" |
24 | 24 | #include "manualviewerdlg.h" |
25 | +#include "haccp.h" | |
25 | 26 | |
26 | 27 | #include <QTime> |
27 | 28 | |
... | ... | @@ -559,6 +560,8 @@ void ManualCookWindow::onOvenUpdated(Oven *oven) |
559 | 560 | lastCheckedCooking = oven->cooking(); |
560 | 561 | cookDone = true; |
561 | 562 | |
563 | + HACCP::done(); | |
564 | + | |
562 | 565 | emit done(); |
563 | 566 | } |
564 | 567 | } |
... | ... | @@ -619,6 +622,7 @@ void ManualCookWindow::start() |
619 | 622 | s.coreTemp = oven->interTemp(); |
620 | 623 | |
621 | 624 | CookHistory::record(s); |
625 | + HACCP::manualStart(); | |
622 | 626 | |
623 | 627 | if (monitorLevel > 0 && oven->door()) |
624 | 628 | { |
... | ... | @@ -637,6 +641,7 @@ void ManualCookWindow::stop() |
637 | 641 | |
638 | 642 | oven->stop(); |
639 | 643 | startCookingTimer.stop(); |
644 | + HACCP::done(); | |
640 | 645 | } |
641 | 646 | |
642 | 647 | void ManualCookWindow::addFavorite() | ... | ... |
app/gui/oven_control/multicookcontroller.cpp
1 | 1 | #include "multicookcontroller.h" |
2 | 2 | |
3 | 3 | #include "oven.h" |
4 | +#include "haccp.h" | |
4 | 5 | |
5 | 6 | MultiCookController::MultiCookController(QObject *parent) : QObject(parent) |
6 | 7 | { |
... | ... | @@ -47,7 +48,11 @@ void MultiCookController::check() |
47 | 48 | { |
48 | 49 | case Idle: |
49 | 50 | if (!container->isEmpty()) |
51 | + { | |
50 | 52 | state = Preheating; |
53 | + | |
54 | + HACCP::multiStart(); | |
55 | + } | |
51 | 56 | break; |
52 | 57 | case Preheating: |
53 | 58 | checkPreheating(); |
... | ... | @@ -81,6 +86,7 @@ void MultiCookController::checkPreheating() |
81 | 86 | if (container->isEmpty()) |
82 | 87 | { |
83 | 88 | state = Idle; |
89 | + HACCP::done(); | |
84 | 90 | oven->stop(); |
85 | 91 | return; |
86 | 92 | } |
... | ... | @@ -110,6 +116,7 @@ void MultiCookController::checkRunning() |
110 | 116 | if (container->isEmpty()) |
111 | 117 | { |
112 | 118 | state = Idle; |
119 | + HACCP::done(); | |
113 | 120 | oven->stop(); |
114 | 121 | return; |
115 | 122 | } |
... | ... | @@ -117,6 +124,7 @@ void MultiCookController::checkRunning() |
117 | 124 | if (container->isFinished()) |
118 | 125 | { |
119 | 126 | state = Finished; |
127 | + HACCP::done(); | |
120 | 128 | oven->stop(); |
121 | 129 | container->stop(); |
122 | 130 | return; |
... | ... | @@ -188,6 +196,7 @@ void MultiCookController::checkFinished() |
188 | 196 | if (oven->door()) |
189 | 197 | { |
190 | 198 | state = Idle; |
199 | + HACCP::done(); | |
191 | 200 | |
192 | 201 | for (int i = 0; i < 10; i++) |
193 | 202 | { | ... | ... |
app/gui/oven_control/oven_control.pro
... | ... | @@ -141,7 +141,8 @@ SOURCES += main.cpp\ |
141 | 141 | multicookselectionwindow.cpp \ |
142 | 142 | multicookmanualwindow.cpp \ |
143 | 143 | multicookautowindow.cpp \ |
144 | - multicookbook.cpp | |
144 | + multicookbook.cpp \ | |
145 | + haccp.cpp | |
145 | 146 | |
146 | 147 | |
147 | 148 | HEADERS += mainwindow.h \ |
... | ... | @@ -273,7 +274,8 @@ HEADERS += mainwindow.h \ |
273 | 274 | multicookselectionwindow.h \ |
274 | 275 | multicookmanualwindow.h \ |
275 | 276 | multicookautowindow.h \ |
276 | - multicookbook.h | |
277 | + multicookbook.h \ | |
278 | + haccp.h | |
277 | 279 | |
278 | 280 | FORMS += mainwindow.ui \ |
279 | 281 | manualcookwindow.ui \ | ... | ... |
app/gui/oven_control/stringer.cpp
... | ... | @@ -237,11 +237,14 @@ QString Stringer::dateTime(const QDateTime &dateTime, DateTimeType type) |
237 | 237 | |
238 | 238 | QString Stringer::time(int msecs) |
239 | 239 | { |
240 | - int t = qCeil(msecs / 1000.0); | |
240 | + return timeSecs(qCeil(msecs / 1000.0)); | |
241 | +} | |
241 | 242 | |
242 | - int h = t / (60*60); | |
243 | - int m = (t/60) % 60; | |
244 | - int s = t % 60; | |
243 | +QString Stringer::timeSecs(int secs) | |
244 | +{ | |
245 | + int h = secs / (60*60); | |
246 | + int m = (secs/60) % 60; | |
247 | + int s = secs % 60; | |
245 | 248 | |
246 | 249 | return QString("%1:%2:%3") |
247 | 250 | .arg(h, 2, 10, QLatin1Char('0')) | ... | ... |
app/gui/oven_control/stringer.h
app/gui/oven_control/washwindow.cpp
... | ... | @@ -11,6 +11,7 @@ |
11 | 11 | #include "ovenstatics.h" |
12 | 12 | #include "cooldownpopup.h" |
13 | 13 | #include "manualviewerdlg.h" |
14 | +#include "haccp.h" | |
14 | 15 | |
15 | 16 | WashWindow::WashWindow(QWidget *parent) : |
16 | 17 | QMainWindow(parent), |
... | ... | @@ -389,6 +390,7 @@ void WashWindow::onChanged() |
389 | 390 | { |
390 | 391 | state = Running; |
391 | 392 | |
393 | + HACCP::washStart(type); | |
392 | 394 | updateView(); |
393 | 395 | } |
394 | 396 | else |
... | ... | @@ -403,6 +405,7 @@ void WashWindow::onChanged() |
403 | 405 | { |
404 | 406 | state = Idle; |
405 | 407 | |
408 | + HACCP::done(); | |
406 | 409 | SoundPlayer::playStop(); |
407 | 410 | DirtyLevel::wash(type); |
408 | 411 | OvenStatistics::getInstance()->setWashState(false); |
... | ... | @@ -424,6 +427,7 @@ void WashWindow::onChanged() |
424 | 427 | case Stopping: |
425 | 428 | if (!udp->getData().cleaning_sate) |
426 | 429 | { |
430 | + HACCP::done(); | |
427 | 431 | SoundPlayer::playStop(); |
428 | 432 | OvenStatistics::getInstance()->setWashState(false); |
429 | 433 | |
... | ... | @@ -437,6 +441,7 @@ void WashWindow::onChanged() |
437 | 441 | { |
438 | 442 | state = RunningClean; |
439 | 443 | |
444 | + HACCP::washStart(6); | |
440 | 445 | updateView(); |
441 | 446 | } |
442 | 447 | else |
... | ... | @@ -450,6 +455,8 @@ void WashWindow::onChanged() |
450 | 455 | else |
451 | 456 | { |
452 | 457 | state = Idle; |
458 | + | |
459 | + HACCP::done(); | |
453 | 460 | SoundPlayer::playStop(); |
454 | 461 | OvenStatistics::getInstance()->setWashState(false); |
455 | 462 | ... | ... |