#include "oven.h" #include #include #include Oven *Oven::instance = 0; Oven::Oven(QObject *parent) : QObject(parent) { interface = NULL; currentHumidity_ = 0; currentTemp_ = 0; currentInterTemp_ = 0; cookingTimer.setSingleShot(true); connect(&cookingTimer, SIGNAL(timeout()), SLOT(stopCooking())); damperTimer.setSingleShot(true); connect(&damperTimer, SIGNAL(timeout()), SLOT(closeDamper())); humidificationTimer.setSingleShot(true); connect(&humidificationTimer, SIGNAL(timeout()), SLOT(stopHumidification())); damperRepeatRuntimeTimer.setSingleShot(true); connect(&damperRepeatRuntimeTimer, SIGNAL(timeout()), SLOT(idleRepeatDamper())); damperRepeatDelayTimer.setSingleShot(true); connect(&damperRepeatDelayTimer, SIGNAL(timeout()), SLOT(runRepeatDamper())); humidificationRepeatRuntimeTimer.setSingleShot(true); connect(&humidificationRepeatRuntimeTimer, SIGNAL(timeout()), SLOT(idleRepeatHumidification())); humidificationRepeatDelayTimer.setSingleShot(true); connect(&humidificationRepeatDelayTimer, SIGNAL(timeout()), SLOT(runRepeatHumidification())); isInterTempValid_ = false; humidificationRepeat = false; damperRepeat = false; } void Oven::setInterface(OvenInterface *interface) { if (this->interface) this->interface->disconnect(); this->interface = interface; connect(interface, SIGNAL(doorOpened()), this, SLOT(onDoorOpened())); connect(interface, SIGNAL(doorClosed()), this, SLOT(onDoorClosed())); } void Oven::setMode(Mode mode) { if (setMode_(mode)) emit changed(this); } bool Oven::setMode_(Mode mode) { switch (mode) { case HeatMode: case SteamMode: case CombinationMode: break; default: return false; } if (mode != mode_) { mode_ = mode; return true; } return false; } void Oven::setDefault(Mode mode) { setMode_(mode); switch (mode) { case HeatMode: setHumidity_(0); setTemp_(160); break; case SteamMode: setHumidity_(100); setTemp_(100); break; case CombinationMode: setHumidity_(50); setTemp_(100); break; } setTime(0); setInterTempEnabled_(false); setInterTemp_(minInterTemp()); setFan_(4); cooking_ = false; preheating_ = false; cooldown_ = false; damper_ = false; humidification_ = false; door_ = interface->door(); paused_ = false; emit changed(this); } void Oven::setHumidity(int percentage) { if (setHumidity_(percentage)) emit changed(this); } bool Oven::setHumidity_(int percentage) { if (percentage < 0 || percentage > 100) return false; if (percentage != humidity_) { humidity_ = percentage; interface->setHumidity(percentage); return true; } return false; } void Oven::setTemp(int celsius) { if (setTemp_(celsius)) emit changed(this); } bool Oven::setTemp_(int celsius) { if (celsius < minTemp() || celsius > maxTemp()) return false; if (celsius != temp_) { temp_ = celsius; interface->setTemp(celsius); return true; } return false; } int Oven::time() { int left = cookingTimer.remainingTime(); int interval = cookingTimer.interval(); if (left > interval) left = interval; if (cooking()) return ceil(left / 1000.0); return time_; } void Oven::setTime(int secs) { time_ = secs; cookingTimer.setInterval(secs * 1000); } void Oven::setInterTempEnabled(bool enabled) { if (setInterTempEnabled_(enabled)) emit changed(this); } bool Oven::setInterTempEnabled_(bool enabled) { if (interTempEnabled_ != enabled) { interTempEnabled_ = enabled; if (interTempEnabled_) interface->setInterTemp(interTemp_); else interface->setInterTemp(0); return true; } return false; } void Oven::setInterTemp(int celsius) { if (setInterTemp_(celsius)) emit changed(this); } bool Oven::setInterTemp_(int celsius) { if (celsius < minInterTemp() || celsius > maxInterTemp()) return false; if (celsius != interTemp_) { interTemp_ = celsius; if (interTempEnabled_) interface->setInterTemp(celsius); return true; } return false; } void Oven::setFan(int speed) { if (setFan_(speed)) emit changed(this); } bool Oven::setFan_(int speed) { if (speed < minFan() || speed > maxFan()) return false; if (speed == fan_) return false; int rpm = 0; switch (speed) { case 1: rpm = 500; break; case 2: rpm = 725; break; case 3: rpm = 950; break; case 4: rpm = 1175; break; case 5: rpm = 1400; break; } fan_ = speed; interface->setFan(rpm); return true; } bool Oven::isInterTempValid() { return isInterTempValid_ && interTempValidTime.elapsed() > 3000; } bool Oven::cookingStartable() { if (/*door() || */cooking() || time() <= 0) return false; return true; } bool Oven::preheatingStartable() { if (door()) return false; return true; } bool Oven::cooldownStartable() { return true; } bool Oven::damperOpenable() { return true; } bool Oven::humidificationStartable() { return true; } void Oven::stop() { if (cooking()) stopCooking(); if (preheating()) stopPreheating(); if (damper()) closeDamper(); if (cooldown()) stopCooldown(); if (humidification()) stopHumidification(); } void Oven::startCooking() { if (!cooking()) { if (door()) { paused_ = true; } else { paused_ = false; if (preheating()) stopPreheating(); if (cooldown()) stopCooldown(); cooking_ = true; cookingTimer.start(); interface->startCooking(); } emit changed(this); } } void Oven::stopCooking() { if (cooking()) { if (time() > 0) { paused_ = true; setTime(time()); cookingTimer.stop(); } else setTime(0); cooking_ = false; interface->stopCooking(); emit changed(this); } } void Oven::startPreheating() { if (preheatingStartable()) { if (cooking()) stopCooking(); preheating_ = true; interface->startPreheating(); emit changed(this); } } void Oven::stopPreheating() { if (preheating()) { preheating_ = false; interface->stopPreheating(); emit changed(this); if (paused()) startCooking(); } } void Oven::startCooldown() { if (cooldownStartable()) { if (cooking()) stopCooking(); cooldown_ = true; interface->startCooldown(); emit changed(this); } } void Oven::stopCooldown() { if (cooldown()) { cooldown_ = false; interface->stopCooldown(); emit changed(this); if (paused()) startCooking(); } } void Oven::startHumidification(int secs) { if (humidificationStartable()) { if (humidificationRepeat) { } else { humidification_ = true; humidificationTimer.start(secs * 1000); interface->startHumidification(); emit changed(this); } } } void Oven::stopHumidification() { if (humidification()) { humidification_ = false; if (humidificationTimer.isActive()) humidificationTimer.stop(); interface->stopHumidification(); emit changed(this); } } void Oven::repeatHumidification(int runtime, int delay, int count) { humidificationRepeatInfinitely = count == 0; humidificationRepeatRuntime = runtime * 1000; humidificationRepeatDelay = delay * 1000; humidificationRepeatCount = count; if (humidificationRepeat) { if (humidificationRepeatPaused) { if (humidificationRepeatPausedOnRuntime) humidificationRepeatRemainingTime = humidificationRepeatRuntime; else humidificationRepeatRemainingTime = humidificationRepeatDelay; } else { runRepeatHumidification(); } } else { humidificationRepeat = true; if (humidification()) { humidificationRepeatPaused = true; humidificationRepeatPausedOnRuntime = false; humidificationRepeatRemainingTime = humidificationRepeatDelay; } else { humidificationRepeatPaused = false; humidificationRepeatRemainingTime = 0; runRepeatHumidification(); } } } void Oven::stopRepeatHumidification() { if (!humidificationRepeat) return; humidificationRepeat = false; humidificationRepeatRuntimeTimer.stop(); humidificationRepeatDelayTimer.stop(); if (humidification()) stopHumidification(); } void Oven::pauseRepeatHumidification() { if (!humidificationRepeat) return; humidificationRepeatPaused = true; if (humidificationRepeatRuntimeTimer.isActive()) { humidificationRepeatPausedOnRuntime = true; humidificationRepeatRemainingTime = humidificationRepeatRuntimeTimer.remainingTime(); humidificationRepeatRuntimeTimer.stop(); } else { humidificationRepeatPausedOnRuntime = false; humidificationRepeatRemainingTime = humidificationRepeatDelayTimer.remainingTime(); humidificationRepeatDelayTimer.stop(); } } void Oven::resumeRepeatHumidification() { if (!humidificationRepeat || !humidificationRepeatPaused) return; humidificationRepeatPaused = false; if (humidificationRepeatPausedOnRuntime) { humidificationRepeatRuntimeTimer.start(humidificationRepeatRemainingTime); humidification_ = true; interface->startHumidification(); emit changed(this); } else { humidificationRepeatDelayTimer.start(humidificationRepeatRemainingTime); } } void Oven::runRepeatHumidification() { if (humidificationRepeatInfinitely || humidificationRepeatCount-- > 0) { humidificationRepeatRuntimeTimer.start(humidificationRepeatRuntime); humidification_ = true; interface->startHumidification(); emit changed(this); } } void Oven::idleRepeatHumidification() { humidificationRepeatDelayTimer.start(humidificationRepeatDelay); humidification_ = false; interface->stopHumidification(); emit changed(this); } void Oven::openDamper(int secs) { if (!damper()) { damper_ = true; interface->openDamper(); emit changed(this); } damperTimer.start(secs * 1000); } void Oven::closeDamper() { if (damper()) { damper_ = false; if (damperTimer.isActive()) damperTimer.stop(); interface->closeDamper(); emit changed(this); } } void Oven::repeatDamper(int runtime, int delay, int count) { damperRepeatInfinitely = count == 0; damperRepeatRuntime = runtime * 1000; damperRepeatDelay = delay * 1000; damperRepeatCount = count; if (damperRepeat) { if (damperRepeatPaused) { if (damperRepeatPausedOnRuntime) damperRepeatRemainingTime = damperRepeatRuntime; else damperRepeatRemainingTime = damperRepeatDelay; } else { runRepeatDamper(); } } else { damperRepeat = true; if (damper()) { damperRepeatPaused = true; damperRepeatPausedOnRuntime = false; damperRepeatRemainingTime = damperRepeatDelay; } else { damperRepeatPaused = false; damperRepeatRemainingTime = 0; runRepeatDamper(); } } } void Oven::stopRepeatDamper() { if (!damperRepeat) return; damperRepeat = false; damperRepeatRuntimeTimer.stop(); damperRepeatDelayTimer.stop(); if (damper()) closeDamper(); } void Oven::pauseRepeatDamper() { if (!damperRepeat) return; damperRepeatPaused = true; if (damperRepeatRuntimeTimer.isActive()) { damperRepeatPausedOnRuntime = true; damperRepeatRemainingTime = damperRepeatRuntimeTimer.remainingTime(); damperRepeatRuntimeTimer.stop(); } else { damperRepeatPausedOnRuntime = false; damperRepeatRemainingTime = damperRepeatDelayTimer.remainingTime(); damperRepeatDelayTimer.stop(); } } void Oven::resumeRepeatDamper() { if (!damperRepeat || !damperRepeatPaused) return; damperRepeatPaused = false; if (damperRepeatPausedOnRuntime) { damperRepeatRuntimeTimer.start(damperRepeatRemainingTime); damper_ = true; interface->closeDamper(); emit changed(this); } else { damperRepeatDelayTimer.start(damperRepeatRemainingTime); } } void Oven::runRepeatDamper() { if (damperRepeatInfinitely || damperRepeatCount-- > 0) { damperRepeatRuntimeTimer.start(damperRepeatRuntime); damper_ = true; interface->openDamper(); emit changed(this); } } void Oven::idleRepeatDamper() { damperRepeatDelayTimer.start(damperRepeatDelay); damper_ = false; interface->closeDamper(); emit changed(this); } void Oven::setCurrentHumidity(int percentage) { if (currentHumidity() != percentage) { currentHumidity_ = percentage; emit changed(this); } } void Oven::setCurrentTemp(int celsius) { if (currentTemp() != celsius) { currentTemp_ = celsius; emit changed(this); } } void Oven::setCurrentInterTemp(int celsius) { if (currentInterTemp() != celsius) { currentInterTemp_ = celsius; if (isInterTempValid_) { if (currentInterTemp_ == currentTemp_) isInterTempValid_ = false; } else { if (currentInterTemp_ + 20 < currentTemp_) { isInterTempValid_ = true; interTempValidTime = QTime::currentTime(); } } emit changed(this); } } int Oven::maxTemp() { switch (mode()) { case HeatMode: return 300; case SteamMode: return 130; case CombinationMode: return 300; default: return 0; } } int Oven::minTemp() { switch (mode()) { case HeatMode: return 30; case SteamMode: return 30; case CombinationMode: return 30; default: return 0; } } int Oven::maxInterTemp() { switch (mode()) { case HeatMode: return 99; case SteamMode: return 99; case CombinationMode: return 99; default: return 0; } } int Oven::minInterTemp() { switch (mode()) { case HeatMode: return 30; case SteamMode: return 30; case CombinationMode: return 30; default: return 0; } } int Oven::maxFan() { return 5; } int Oven::minFan() { return 1; } void Oven::onDoorOpened() { door_ = true; emit changed(this); if (cooking()) { stopCooking(); if (damperRepeat) pauseRepeatDamper(); openDamper(7); } } void Oven::onDoorClosed() { door_ = false; emit changed(this); if (!cooldown() && paused()) startCooking(); if (damper()) closeDamper(); if (damperRepeat) resumeRepeatDamper(); }