diff --git a/app/gui/oven_control/mainwindow.cpp b/app/gui/oven_control/mainwindow.cpp
index 7d4a4fe..ee5059a 100644
--- a/app/gui/oven_control/mainwindow.cpp
+++ b/app/gui/oven_control/mainwindow.cpp
@@ -11,6 +11,8 @@
 #include "programmingwindow.h"
 #include "washwindow.h"
 #include "configwindow.h"
+#include "ovenstatics.h"
+#include "notipopupdlg.h"
 
 MainWindow *MainWindow::instance = NULL;
 
@@ -31,6 +33,8 @@ MainWindow::MainWindow(QWidget *parent) :
         connect(button, &QPushButton::pressed, SoundPlayer::playClick);
         connect(button, SIGNAL(clicked()), SLOT(setFocus()));
     }
+
+    QTimer::singleShot(0, this, SLOT(checkPrevWash()));
 }
 
 MainWindow::~MainWindow()
@@ -117,6 +121,18 @@ void MainWindow::onEncoderClicked(QWidget *clicked)
         b->click();
 }
 
+void MainWindow::checkPrevWash()
+{
+    if (OvenStatistics::getInstance()->loadWashState())
+    {
+        NotiPopupDlg *d = new NotiPopupDlg(this, tr("세척이 정상적으로 종료되지 않아\n반드시 세척통을 자동 세척해야 합니다.\n내부를 비워주세요"));
+        d->setWindowModality(Qt::WindowModal);
+        d->show();
+
+        connect(d, SIGNAL(accepted()), SLOT(on_washButton_clicked()));
+    }
+}
+
 void MainWindow::showManualCookWindow(Define::Mode mode)
 {
     ManualCookWindow *w = new ManualCookWindow(this, mode);
diff --git a/app/gui/oven_control/mainwindow.h b/app/gui/oven_control/mainwindow.h
index 642f040..2f0d407 100644
--- a/app/gui/oven_control/mainwindow.h
+++ b/app/gui/oven_control/mainwindow.h
@@ -38,6 +38,8 @@ private:
     void onEncoderClicked(QWidget *clicked);
 
 private slots:
+    void checkPrevWash();
+
     void showManualCookWindow(Define::Mode mode);
     void showAutoCookSelectionWindow(Define::CookType type);
 
diff --git a/app/gui/oven_control/washwindow.cpp b/app/gui/oven_control/washwindow.cpp
index 564265e..43f3c1b 100644
--- a/app/gui/oven_control/washwindow.cpp
+++ b/app/gui/oven_control/washwindow.cpp
@@ -8,6 +8,7 @@
 #include "dirtylevel.h"
 #include "configwindow.h"
 #include "mainwindow.h"
+#include "ovenstatics.h"
 
 WashWindow::WashWindow(QWidget *parent) :
     QMainWindow(parent),
@@ -56,6 +57,30 @@ WashWindow::WashWindow(QWidget *parent) :
     updateGauge();
 
     setFocus();
+
+    if (OvenStatistics::getInstance()->loadWashState())
+    {
+        // Start Cleaning Steam Generator
+        state = RequestClean;
+
+        udp->set(TG_OVEN_MODE, 2);
+        udp->set(TG_CLEAN_TYPE, 6);
+        udp->turnOn(TG_CLEANING);
+
+        ui->animation->clear();
+
+        ui->animation->load(":/images/animation/wash_01.png");
+        ui->animation->load(":/images/animation/wash_02.png");
+        ui->animation->load(":/images/animation/wash_03.png");
+        ui->animation->load(":/images/animation/wash_04.png");
+        ui->washStepGauge->setValue(0);
+        ui->titleLabel->setText(tr("스팀통헹굼 진행 중입니다."));
+        ui->descLabel->setText(tr("완료될 때까지 문을 열지 마세요."));
+        ui->washStepTypeLabel->setText("");
+        ui->washStepCountLabel->setText("");
+
+        ui->upperStack->setCurrentIndex(1);
+    }
 }
 
 WashWindow::~WashWindow()
@@ -100,13 +125,13 @@ void WashWindow::keyReleaseEvent(QKeyEvent *event)
 
 void WashWindow::start(int type)
 {
-    if (selected)
+    if (state != Idle)
         return;
 
     if (type < 1 || type > 5)
         return;
 
-    selected = true;
+    state = OpenDoor;
 
     this->type = type;
 
@@ -125,13 +150,11 @@ void WashWindow::start(int type)
 
 void WashWindow::stop()
 {
-    if (!started)
+    if (state != Request && state != Running)
         return;
 
-    if (canceled)
-        return;
+    state = Stopping;
 
-    canceled = true;
     udp->turnOff(TG_CLEANING);
 }
 
@@ -146,22 +169,69 @@ void WashWindow::updateGauge()
     ui->stateSlider->setValue(DirtyLevel::state());
 }
 
+void WashWindow::updateView()
+{
+    const oven_control_t &control = udp->getControl();
+    if (control.clean_total != 0 && control.clean_step != 0 && control.clean_step_type != 0)
+    {
+        ui->washStepGauge->setMaximum(control.clean_total);
+        ui->washStepGauge->setValue(control.clean_step);
+        ui->washStepCountLabel->setText(QString().sprintf("%d/%d", control.clean_step, control.clean_total));
+
+        switch (control.clean_step_type)
+        {
+        case 1:
+            ui->washStepTypeLabel->setText(tr("내부 헹굼 진행 중입니다."));
+            break;
+        case 2:
+            ui->washStepTypeLabel->setText(tr("스팀 급수 진행 중입니다."));
+            break;
+        case 3:
+            ui->washStepTypeLabel->setText(tr("내부 팬 세척 진행 중입니다."));
+            break;
+        case 4:
+            ui->washStepTypeLabel->setText(tr("내부 스팀 불림 진행 중입니다."));
+            break;
+        case 5:
+            ui->washStepTypeLabel->setText(tr("내부 강 세척 진행 중입니다."));
+            break;
+        case 6:
+            ui->washStepTypeLabel->setText(tr("내부 상부 세척 진행 중입니다."));
+            break;
+        case 7:
+            ui->washStepTypeLabel->setText(tr("내부 스팀 세척 진행 중입니다."));
+            break;
+        case 8:
+            ui->washStepTypeLabel->setText(tr("세척 종료 진행 중입니다."));
+            break;
+        case 9:
+            ui->washStepTypeLabel->setText(tr("세제 세척수 만들기 진행 중입니다."));
+            break;
+        case 10:
+            ui->washStepTypeLabel->setText(tr("세제 세척수 헹굼 진행 중입니다."));
+            break;
+        case 11:
+            ui->washStepTypeLabel->setText(tr("하부 탱크 세척수 만들기 진행 중입니다."));
+            break;
+        }
+    }
+}
+
 void WashWindow::onChanged()
 {
-    if (!selected)
+    if (state == Idle)
         return;
 
-    oven_state_t state;
-    udp->fillData(state);
-
-    if (!opened)
+    switch (state)
     {
-        if (state.door_state)
+    case Idle:
+        return;
+    case OpenDoor:
+        if (udp->getData().door_state)
         {
-            opened = true;
+            state = CloseDoor;
 
             ui->animation->clear();
-
             ui->animation->load(":/images/animation/door_big_09.png");
             ui->animation->load(":/images/animation/door_big_08.png");
             ui->animation->load(":/images/animation/door_big_07.png");
@@ -173,12 +243,11 @@ void WashWindow::onChanged()
             ui->animation->load(":/images/animation/door_big_01.png");
             ui->closeDoorArrow->show();
         }
-    }
-    else if (!started)
-    {
-        if (!state.door_state)
+        break;
+    case CloseDoor:
+        if (!udp->getData().door_state)
         {
-            started = true;
+            state = Request;
 
             SoundPlayer::playStart();
 
@@ -199,104 +268,118 @@ void WashWindow::onChanged()
 
             udp->set(TG_CLEAN_TYPE, type);
             udp->turnOn(TG_CLEANING);
-        }
-    }
-    else if (state.cleaning_sate)
-    {
-        if (!run)
-            run = true;
 
-        oven_control_t control;
-        udp->fillControl(control);
+            OvenStatistics::getInstance()->setWashState(true);
+        }
+        break;
+    case Request:
+        if (udp->getData().cleaning_sate)
+        {
+            state = Running;
 
-        if (control.clean_total != 0 && control.clean_step != 0 && control.clean_step_type != 0)
+            updateView();
+        }
+        else
+            updateView();
+        break;
+    case Running:
+        if (udp->getData().cleaning_sate)
         {
-            ui->washStepGauge->setMaximum(control.clean_total);
-            ui->washStepGauge->setValue(control.clean_step);
-            ui->washStepCountLabel->setText(QString().sprintf("%d/%d", control.clean_step, control.clean_total));
-
-            switch (control.clean_step_type)
-            {
-            case 1:
-                ui->washStepTypeLabel->setText(tr("내부 헹굼 진행 중입니다."));
-                break;
-            case 2:
-                ui->washStepTypeLabel->setText(tr("스팀 급수 진행 중입니다."));
-                break;
-            case 3:
-                ui->washStepTypeLabel->setText(tr("내부 팬 세척 진행 중입니다."));
-                break;
-            case 4:
-                ui->washStepTypeLabel->setText(tr("내부 스팀 불림 진행 중입니다."));
-                break;
-            case 5:
-                ui->washStepTypeLabel->setText(tr("내부 강 세척 진행 중입니다."));
-                break;
-            case 6:
-                ui->washStepTypeLabel->setText(tr("내부 상부 세척 진행 중입니다."));
-                break;
-            case 7:
-                ui->washStepTypeLabel->setText(tr("내부 스팀 세척 진행 중입니다."));
-                break;
-            case 8:
-                ui->washStepTypeLabel->setText(tr("세척 종료 진행 중입니다."));
-                break;
-            case 9:
-                ui->washStepTypeLabel->setText(tr("세제 세척수 만들기 진행 중입니다."));
-                break;
-            case 10:
-                ui->washStepTypeLabel->setText(tr("세제 세척수 헹굼 진행 중입니다."));
-                break;
-            case 11:
-                ui->washStepTypeLabel->setText(tr("하부 탱크 세척수 만들기 진행 중입니다."));
-                break;
-            }
+            updateView();
         }
-    }
-    else if (canceled)
-    {
-        SoundPlayer::playStop();
+        else
+        {
+            state = Idle;
 
-        close();
-    }
-    else if (run)
-    {
-        SoundPlayer::playStop();
-        DirtyLevel::wash(type);
+            SoundPlayer::playStop();
+            DirtyLevel::wash(type);
+            OvenStatistics::getInstance()->setWashState(false);
 
-        ui->titleLabel->setText(tr("세척이 종료되었습니다"));
-        ui->descLabel->setText("");
-        ui->washStepTypeLabel->setText("");
-        ui->washStepCountLabel->setText("");
+            ui->titleLabel->setText(tr("세척이 종료되었습니다"));
+            ui->descLabel->setText("");
+            ui->washStepTypeLabel->setText("");
+            ui->washStepCountLabel->setText("");
 
-        ui->animation->stop();
-        ui->animation->clear();
-        ui->animation->load(":/images/animation/wash_04.png");
+            ui->animation->stop();
+            ui->animation->clear();
+            ui->animation->load(":/images/animation/wash_04.png");
 
-        returnToClockTimer.start();
+            returnToClockTimer.start();
 
-        selected = false;
-        opened = false;
-        started = false;
-        run = false;
+            updateGauge();
+        }
+        break;
+    case Stopping:
+        if (!udp->getData().cleaning_sate)
+        {
+            SoundPlayer::playStop();
+            OvenStatistics::getInstance()->setWashState(false);
 
-        updateGauge();
+            close();
+        }
+        else
+            updateView();
+        break;
+    case RequestClean:
+        if (udp->getData().cleaning_sate)
+        {
+            state = RunningClean;
+
+            updateView();
+        }
+        else
+            updateView();
+        break;
+    case RunningClean:
+        if (udp->getData().cleaning_sate)
+        {
+            updateView();
+        }
+        else
+        {
+            OvenStatistics::getInstance()->setWashState(false);
+
+            ui->titleLabel->setText(tr("세척이 종료되었습니다"));
+            ui->descLabel->setText("");
+            ui->washStepTypeLabel->setText("");
+            ui->washStepCountLabel->setText("");
+
+            ui->animation->stop();
+            ui->animation->clear();
+            ui->animation->load(":/images/animation/wash_04.png");
+
+            returnToClockTimer.start();
+        }
     }
 }
 
 void WashWindow::on_backButton_clicked()
 {
-    if (started)
-        stop();
-    else
+    switch (state)
+    {
+    case Idle:
+    case OpenDoor:
+    case CloseDoor:
         close();
+        break;
+    case Request:
+    case Running:
+        stop();
+        break;
+    case Stopping:
+    case RequestClean:
+    case RunningClean:
+        return;
+    }
 }
 
 void WashWindow::on_configButton_clicked()
 {
-    if (started)
-        stop();
-    else
+    switch (state)
+    {
+    case Idle:
+    case OpenDoor:
+    case CloseDoor:
     {
         ConfigWindow *w = new ConfigWindow(MainWindow::getInstance());
         w->setWindowModality(Qt::WindowModal);
@@ -304,6 +387,16 @@ void WashWindow::on_configButton_clicked()
         w->raise();
 
         MainWindow::jump(w);
+        break;
+    }
+    case Request:
+    case Running:
+        stop();
+        break;
+    case Stopping:
+    case RequestClean:
+    case RunningClean:
+        return;
     }
 }
 
diff --git a/app/gui/oven_control/washwindow.h b/app/gui/oven_control/washwindow.h
index d9154ad..4b7a667 100644
--- a/app/gui/oven_control/washwindow.h
+++ b/app/gui/oven_control/washwindow.h
@@ -27,6 +27,7 @@ private slots:
     void stop();
     void returnToClock();
     void updateGauge();
+    void updateView();
 
     void onChanged();
 
@@ -38,6 +39,11 @@ private:
     Ui::WashWindow *ui;
     UdpHandler *udp;
 
+    enum State {
+        Idle, OpenDoor, CloseDoor, Request, Running, Stopping,
+        RequestClean, RunningClean
+    } state = Idle;
+
     bool selected;
     bool opened;
     bool started;