#include "autocook.h" #include "soundplayer.h" #include "haccp.h" AutoCook::AutoCook() : currentStepIndex(0), done_(false), doorOpened(false), checkingCoreTemp(false) { } AutoCook::AutoCook(Cook cook) : AutoCook() { this->cook = cook; for (int idx = 0; idx < this->cook.steps.size(); idx++) this->cook.steps[idx].time *= 1000; startStep(); } void AutoCook::startStep() { Oven *oven = Oven::getInstance(); CookStep ¤tStep = cook.steps[currentStepIndex]; switch (Define::classify(currentStep.type)) { case Define::PreheatClass: startHumidity = oven->currentHumidity(); startTemp = oven->currentTemp(); isWaitingDoorOpened_ = false; oven->setMode(currentStep.mode); oven->setHumidity(currentStep.humidity); oven->setTemp(currentStep.temp); oven->setFan(currentStep.fan); oven->startPreheating(); break; case Define::DoorClass: isWaitingDoorOpened_ = true; break; case Define::CookClass: startHumidity = oven->currentHumidity(); startTemp = oven->currentTemp(); isWaitingDoorOpened_ = false; oven->setMode(currentStep.mode); oven->setHumidity(currentStep.humidity); oven->setTemp(currentStep.temp); oven->setFan(currentStep.fan); oven->setTime(remainingTime() + 300); oven->setInterTempEnabled(false); if (cook.isCoreTempValid()) oven->setInterTemp(cook.coreTemp()); if (currentStep.dehumidification) { if (currentStep.dehumidificationRepeatDelay) oven->repeatDamper(currentStep.dehumidification, currentStep.dehumidificationRepeatDelay, currentStep.dehumidificationRepeatCount); else oven->openDamper(currentStep.dehumidification); } if (currentStep.humidification) { if (currentStep.humidificationRepeatDelay) oven->repeatHumidification(currentStep.humidification, currentStep.humidificationRepeatDelay, currentStep.humidificationRepeatCount); else oven->startHumidification(currentStep.humidification); } stepStartTime.start(); oven->startCooking(); case Define::InvalidClass: break; } HACCP::autoStart(cook.root); for (int i = 0; i < 5; i++) { Define::CookConfigType type = cook.configs[i].type; if (type == Define::ConfigNotUsed) continue; HACCP::setConfig(type, cook.configs[i].current); } HACCP::setStep(currentStep.type); advance(); } void AutoCook::nextStep() { Oven *oven = Oven::getInstance(); CookStep ¤tStep = cook.steps[currentStepIndex]; CookStep &nextStep = cook.steps[currentStepIndex + 1]; HACCP::setStep(nextStep.type); Define::StepClass currentClass = Define::classify(currentStep.type); Define::StepClass nextClass = Define::classify(nextStep.type); if (currentClass == Define::PreheatClass && nextClass == Define::DoorClass) { oven->stopPreheating(); isWaitingDoorOpened_ = true; } else if (currentClass == Define::DoorClass && nextClass == Define::CookClass) { startHumidity = oven->currentHumidity(); startTemp = oven->currentTemp(); oven->setMode(nextStep.mode); oven->setHumidity(nextStep.humidity); oven->setTemp(nextStep.temp); oven->setFan(nextStep.fan); oven->setTime(remainingTime() + 300); if (cook.isCoreTempValid()) oven->setInterTemp(cook.coreTemp()); stepStartTime.start(); oven->startCooking(); if (nextStep.dehumidification) { if (nextStep.dehumidificationRepeatDelay) oven->repeatDamper(nextStep.dehumidification, nextStep.dehumidificationRepeatDelay, nextStep.dehumidificationRepeatCount); else oven->openDamper(nextStep.dehumidification); } if (nextStep.humidification) { if (nextStep.humidificationRepeatDelay) oven->repeatHumidification(nextStep.humidification, nextStep.humidificationRepeatDelay, nextStep.humidificationRepeatCount); else oven->startHumidification(nextStep.humidification); } if (checkingCoreTemp && currentStepIndex + 2 >= cook.steps.size()) { lastCoreTempIncreasedTime.start(); } } else if (currentClass == Define::CookClass && nextClass == Define::CookClass) { startHumidity = oven->currentHumidity(); startTemp = oven->currentTemp(); oven->setMode(nextStep.mode); oven->setHumidity(nextStep.humidity); oven->setTemp(nextStep.temp); oven->setFan(nextStep.fan); stepStartTime.start(); if (currentStep.dehumidification) { if (nextStep.dehumidification) { if (currentStep.dehumidificationRepeatDelay) { if (nextStep.dehumidificationRepeatDelay) oven->repeatDamper(nextStep.dehumidification, nextStep.dehumidificationRepeatDelay, nextStep.dehumidificationRepeatCount); else { oven->stopRepeatDamper(); oven->openDamper(nextStep.dehumidification); } } else { if (nextStep.dehumidificationRepeatDelay) oven->repeatDamper(nextStep.dehumidification, nextStep.dehumidificationRepeatDelay, nextStep.dehumidificationRepeatCount); else oven->openDamper(nextStep.dehumidification); } } else { if (currentStep.dehumidificationRepeatDelay) oven->stopRepeatDamper(); } } else { if (nextStep.dehumidification) { if (nextStep.dehumidificationRepeatDelay) oven->repeatDamper(nextStep.dehumidification, nextStep.dehumidificationRepeatDelay, nextStep.dehumidificationRepeatCount); else oven->openDamper(nextStep.dehumidification); } } if (nextStep.humidification != currentStep.humidification || nextStep.humidificationRepeatDelay != currentStep.humidificationRepeatDelay || nextStep.humidificationRepeatCount != currentStep.humidificationRepeatCount) { if (nextStep.humidificationRepeatDelay) { if (currentStep.humidificationRepeatDelay) oven->repeatHumidification(nextStep.humidification, nextStep.humidificationRepeatDelay, nextStep.humidificationRepeatCount); else { oven->stopHumidification(); oven->repeatHumidification(nextStep.humidification, nextStep.humidificationRepeatDelay, nextStep.humidificationRepeatCount); } } else { if (currentStep.humidificationRepeatDelay) { oven->stopRepeatHumidification(); oven->startHumidification(nextStep.humidification); } else oven->startHumidification(nextStep.humidification); } } if (checkingCoreTemp && currentStepIndex + 2 >= cook.steps.size()) { lastCoreTempIncreasedTime.start(); } } else if (currentClass == Define::CookClass && nextClass == Define::DoorClass) { if (currentStep.dehumidification) { if (currentStep.dehumidificationRepeatDelay) oven->stopRepeatDamper(); else oven->closeDamper(); } if (currentStep.humidification) { if (currentStep.humidificationRepeatDelay) oven->stopRepeatHumidification(); else oven->stopHumidification(); } oven->setInterTempEnabled(false); oven->stopCooking(); isWaitingDoorOpened_ = true; } currentStepIndex++; advance(); } bool AutoCook::advance() { Oven *oven = Oven::getInstance(); CookStep ¤tStep = cook.steps[currentStepIndex]; switch (Define::classify(currentStep.type)) { case Define::PreheatClass: if (oven->currentTemp() >= currentStep.temp) { nextStep(); return true; } break; case Define::DoorClass: if (isWaitingDoorOpened_) { if (oven->door()) { isWaitingDoorOpened_ = false; return true; } } else { if (!oven->door()) { nextStep(); return true; } } break; case Define::CookClass: { if (oven->door()) { if (!doorOpened) { doorOpened = true; if (checkingCoreTemp && currentStepIndex + 1 >= cook.steps.size()) { currentStep.time -= lastCoreTempIncreasedTime.elapsed(); } else { currentStep.time -= stepStartTime.elapsed(); } } return false; } else if (doorOpened) { doorOpened = false; stepStartTime.start(); lastCoreTempIncreasedTime.start(); lastCoreTempChangedTime.start(); } int remainingCurrentStepTime = currentStep.time; if (checkingCoreTemp && currentStepIndex + 1 >= cook.steps.size()) remainingCurrentStepTime -= lastCoreTempIncreasedTime.elapsed(); else remainingCurrentStepTime -= stepStartTime.elapsed(); if (remainingCurrentStepTime <= 0) { if (currentStepIndex + 1 < cook.steps.size()) { nextStep(); return true; } else { done_ = true; HACCP::done(); SoundPlayer::playStop(); if (currentStep.dehumidification) { if (currentStep.dehumidificationRepeatDelay) oven->stopRepeatDamper(); else oven->closeDamper(); } if (currentStep.humidification) { if (currentStep.humidificationRepeatDelay) oven->stopRepeatHumidification(); else oven->stopHumidification(); } oven->stopCooking(); return true; } } else if (cook.isCoreTempValid() && oven->isInterTempValid()) { if (!checkingCoreTemp) { checkingCoreTemp = true; lastCoreTemp = oven->currentInterTemp(); lastIncreasedCoreTemp = lastCoreTemp; lastCoreTempChangedTime.start(); lastCoreTempIncreasedTime.start(); } if (cook.coreTemp() != oven->interTemp()) oven->setInterTemp(cook.coreTemp()); if (!oven->interTempEnabled()) oven->setInterTempEnabled(true); int currentCoreTemp = oven->currentInterTemp(); if (currentCoreTemp >= cook.coreTemp()) { done_ = true; HACCP::done(); SoundPlayer::playStop(); if (currentStep.dehumidification) { if (currentStep.dehumidificationRepeatDelay) oven->stopRepeatDamper(); else oven->closeDamper(); } if (currentStep.humidification) { if (currentStep.humidificationRepeatDelay) oven->stopRepeatHumidification(); else oven->stopHumidification(); } oven->stopCooking(); currentStepIndex = cook.steps.size() - 1; return true; } else if (currentCoreTemp != lastCoreTemp) { if (currentCoreTemp > lastIncreasedCoreTemp) { if (currentStepIndex + 1 < cook.steps.size()) { int otherStepsTime = 0; for (int idx = currentStepIndex; idx + 1 < cook.steps.size(); idx++) otherStepsTime += cook.steps[idx].time; otherStepsTime -= stepStartTime.elapsed(); int expectedRemainingTime = (cook.coreTemp() - currentCoreTemp) * lastCoreTempChangedTime.elapsed() / (currentCoreTemp - lastCoreTemp); int expectedLastStepRemainingTime = expectedRemainingTime - otherStepsTime; CookStep &lastStep = cook.steps[cook.steps.size() - 1]; lastStep.time = qMax(expectedLastStepRemainingTime, 30000); lastIncreasedCoreTemp = currentCoreTemp; lastCoreTempIncreasedTime.start(); } else { CookStep &lastStep = cook.steps[cook.steps.size() - 1]; int expectedRemainingTime = (cook.coreTemp() - currentCoreTemp) * lastCoreTempChangedTime.elapsed() / (currentCoreTemp - lastCoreTemp); if (expectedRemainingTime > 30000) { lastStep.time = expectedRemainingTime; lastCoreTempIncreasedTime.start(); } else { int currentRemainingTime = lastStep.time - lastCoreTempIncreasedTime.elapsed(); if (currentRemainingTime > 30000) { lastStep.time = 30000; lastCoreTempIncreasedTime.start(); } else if (expectedRemainingTime > currentRemainingTime) { lastStep.time = expectedRemainingTime; lastCoreTempIncreasedTime.start(); } } } } lastCoreTemp = currentCoreTemp; lastCoreTempChangedTime.start(); } } else if (oven->interTempEnabled()) { oven->setInterTempEnabled(false); } } case Define::InvalidClass: break; } return false; } int AutoCook::remainingTime() { if (done_) { return 0; } else if (checkingCoreTemp && currentStepIndex + 1 >= cook.steps.size()) { CookStep &step = cook.steps[cook.steps.size() - 1]; int t = step.time; if (!doorOpened) t -= lastCoreTempIncreasedTime.elapsed(); return t / 1000; } else { int t = 0; for (int i = currentStepIndex; i < cook.steps.size(); i++) t += cook.steps[i].time; if (!doorOpened && Define::classify(cook.steps[currentStepIndex].type) == Define::CookClass) t -= stepStartTime.elapsed(); return t / 1000; } } bool AutoCook::isCoreTempActivated() { return checkingCoreTemp; } int AutoCook::msecs() { if (done_) { return 0; } else if (checkingCoreTemp && currentStepIndex + 1 >= cook.steps.size()) { CookStep &step = cook.steps[cook.steps.size() - 1]; int t = step.time; if (!doorOpened) t -= lastCoreTempIncreasedTime.elapsed(); return t; } else { int t = 0; for (int i = currentStepIndex; i < cook.steps.size(); i++) t += cook.steps[i].time; if (!doorOpened && Define::classify(cook.steps[currentStepIndex].type) == Define::CookClass) t -= stepStartTime.elapsed(); return t; } }