#include "autocook.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(Oven::CombinationMode); 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(Oven::CombinationMode); oven->setHumidity(currentStep.humidity); oven->setTemp(currentStep.temp); oven->setFan(currentStep.fan); oven->setTime(remainingTime() + 300); if (cook.isCoreTempValid()) { oven->setInterTemp(cook.coreTemp()); oven->setInterTempEnabled(true); } else oven->setInterTempEnabled(false); 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; } advance(); } void AutoCook::nextStep() { qDebug() << "Next Step Before" << remainingTime(); Oven *oven = Oven::getInstance(); CookStep ¤tStep = cook.steps[currentStepIndex]; CookStep &nextStep = cook.steps[currentStepIndex + 1]; 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->setHumidity(nextStep.humidity); oven->setTemp(nextStep.temp); oven->setFan(nextStep.fan); oven->setTime(remainingTime() + 300); if (cook.isCoreTempValid()) { oven->setInterTemp(cook.coreTemp()); oven->setInterTempEnabled(true); } else oven->setInterTempEnabled(false); 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->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->stopCooking(); isWaitingDoorOpened_ = true; } currentStepIndex++; advance(); qDebug() << "Next Step After" << remainingTime(); } bool AutoCook::advance() { Oven *oven = Oven::getInstance(); CookStep ¤tStep = cook.steps[currentStepIndex]; switch (Define::classify(currentStep.type)) { case Define::PreheatClass: if (oven->currentHumidity() >= currentStep.humidity && 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; 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(); } int currentCoreTemp = oven->currentInterTemp(); if (currentCoreTemp >= cook.coreTemp()) { done_ = true; 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); qDebug() << "cook.coreTemp()" << cook.coreTemp(); qDebug() << "currentCoreTemp" << currentCoreTemp; qDebug() << "lastCoreTemp" << lastCoreTemp; qDebug() << "lastCoreTempChangedTime.elapsed()" << lastCoreTempChangedTime.elapsed(); qDebug() << "expectedRemainingTime" << expectedRemainingTime; if (expectedRemainingTime > 30000) { lastStep.time = expectedRemainingTime; lastCoreTempIncreasedTime.start(); } else { int currentRemainingTime = lastStep.time - lastCoreTempIncreasedTime.elapsed(); qDebug() << "lastCoreTempIncreasedTime" << lastCoreTempIncreasedTime; qDebug() << "currentRemainingTime" << currentRemainingTime; if (currentRemainingTime > 30000) { lastStep.time = 30000; lastCoreTempIncreasedTime.start(); } else if (expectedRemainingTime > currentRemainingTime) { lastStep.time = expectedRemainingTime; lastCoreTempIncreasedTime.start(); } } } } lastCoreTemp = currentCoreTemp; lastCoreTempChangedTime.start(); } // int currentCoreTemp = oven->currentInterTemp(); // if (currentCoreTemp != lastCoreTemp) // { // int remainingStepsTime = 0; // for (int idx = currentStepIndex + 1; idx < cook.steps.size(); idx++) // remainingStepsTime += cook.steps[idx].time; // int currentRemainingTime = currentStep.time - lastCoreTempTime.elapsed() + remainingStepsTime; // int expectedTime = (cook.coreTemp() - currentCoreTemp) * qAbs(lastCoreTempTime.elapsed() / (currentCoreTemp - lastCoreTemp)); // int expectedCurrentStepTime = expectedTime - remainingStepsTime; // for (int idx = currentStepIndex; idx < cook.steps.size(); idx++) // { // CookStep &step = cook.steps[idx]; // if (expectedCurrentStepTime > 0) // { // step.time = expectedCurrentStepTime; // break; // } // else // { // expectedCurrentStepTime += step.time; // step.time = 0; // } // } // lastCoreTemp = oven->currentInterTemp(); // lastCoreTempTime.start(); // stepStartTime.start(); // advance(); // return true; // } } } 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; } }