cook.cpp 9.55 KB
#include "cook.h"

#include <QErrorMessage>

static QErrorMessage *errorDialog = NULL;
static void showError(QString errorMessage)
{
    if (errorDialog == NULL)
    {
        errorDialog = new QErrorMessage;
        errorDialog->setWindowModality(Qt::ApplicationModal);
        errorDialog->setGeometry(QRect(0, 511, 1080, 511));
    }

    errorDialog->showMessage(errorMessage);
    errorDialog->exec();
}

Cook::Cook()
    : type(Define::InvalidCookType),
      isInitialized_(false), isLoaded_(false), isCoreTempValid_(false),
      time_(0), coreTemp_(0)
{
    for (int i = 0; i < 5; i++)
        configs[i].type = Define::InvalidConfig;
}

Cook::Cook(Define::CookType type, QString root, QString name)
    : Cook()
{
    if (!root.endsWith("/"))
        root += "/";

    this->type = type;
    this->root = root;
    this->name = name;

    initialize();
}

void Cook::initialize()
{
    if (type == Define::InvalidCookType || root.isEmpty() || name.isEmpty())
        return;

    QFile file(root + "config.csv");
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        showError("File not found: " + file.fileName());
        return;
    }

    int lineCount = 0;
    int configIndex = 0;
    while (!file.atEnd())
    {
        if (configIndex == 5)
            break;

        lineCount++;

        QString line = QString::fromUtf8(file.readLine()).trimmed();
        if (line.isEmpty())
            continue;

        if (line.startsWith("use"))
            continue;

        QString errorMessage = QString("%3: %1, line %2").arg(file.fileName()).arg(lineCount);

        QString use = line.section(',', 0, 0).trimmed();
        if (use.isEmpty())
        {
            showError(errorMessage.arg("Use column must be filled"));
            file.close();
            return;
        }

        if (use == "yes")
        {
            CookConfig config;

            config.type = Define::identifyConfigType(line.section(',', 1, 1).trimmed());
            if (config.type == Define::InvalidConfig)
            {
                showError(errorMessage.arg("Invalid configuration type"));
                file.close();
                return;
            }

            bool ok;
            config.maximum = line.section(',', 2, 2).trimmed().toInt(&ok);
            if (!ok)
            {
                showError(errorMessage.arg("Invalid count"));
                file.close();
                return;
            }

            config.current = line.section(',', 3, 3).trimmed().toInt(&ok);
            if (!ok)
            {
                showError(errorMessage.arg("Invalid default"));
                file.close();
                return;
            }

            configs[configIndex++] = config;
        }
        else
            configs[configIndex++] = CookConfig { Define::ConfigNotUsed, 0, 0 };
    }

    file.close();

    for (int i = configIndex; i < 5; i++)
        configs[configIndex++] = CookConfig { Define::ConfigNotUsed, 0, 0 };

    isInitialized_ = true;
}

void Cook::setConfig(int first, int second, int third, int fourth, int fifth)
{
    if (!isInitialized())
        return;

    int currents[5] = { first, second, third, fourth, fifth };
    for (int i = 0; i < 5; i++)
    {
        if (configs[i].type == Define::ConfigNotUsed)
            continue;

        if (configs[i].current != currents[i])
        {
            configs[i].current = currents[i];
            isLoaded_ = false;
        }
    }
}

void Cook::load()
{
    if (!isInitialized())
        return;

    QString selection;
    for (int i = 0; i < 5; i++)
    {
        if (configs[i].type == Define::ConfigNotUsed)
            continue;

        selection += QString::number(configs[i].current);
    }

    QFile dataFile(root + "data." + selection + ".csv");
    if (!dataFile.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        showError("File not found: " + dataFile.fileName());
        return;
    }

    steps.clear();

    int lineCount = 0;
    while (!dataFile.atEnd())
    {
        lineCount++;

        QString line = QString::fromUtf8(dataFile.readLine()).trimmed();
        if (line.isEmpty())
            continue;

        if (line.startsWith("type"))
            continue;

        QString errorMessage = QString("%3: %1, line %2").arg(dataFile.fileName()).arg(lineCount);

        CookStep step;
        bzero(&step, sizeof(step));

        step.type = Define::identifyStepType(line.section(',', 0, 0).trimmed());
        switch (Define::classify(step.type))
        {
        case Define::InvalidClass:
            showError(errorMessage.arg("Invalid type"));
            continue;
        case Define::DoorClass:
            steps.append(step);
            continue;
        default:
            break;
        }

        step.mode = Define::identifyMode(line.section(',', 1, 1).trimmed());
        if (step.mode == Define::InvalidMode)
        {
            showError(errorMessage.arg("Invalid mode"));
            continue;
        }

        bool ok;

        step.humidity = line.section(',', 3, 3).trimmed().toInt(&ok);
        if (!ok || step.humidity < 0 || step.humidity > 100)
        {
            showError(errorMessage.arg("Invalid humidity"));
            continue;
        }

        step.temp = line.section(',', 4, 4).trimmed().toInt(&ok);
        if (!ok || step.temp < 30 || step.temp > 300)
        {
            showError(errorMessage.arg("Invalid temperature"));
            continue;
        }

        step.fan = line.section(',', 6, 6).trimmed().toInt(&ok);
        if (!ok || step.fan < 1 || step.fan > 5)
        {
            showError(errorMessage.arg("Invalid fan level"));
            continue;
        }

        if (step.type == Define::Preheat)
        {
            steps.append(step);
            continue;
        }

        step.time = line.section(',', 2, 2).trimmed().toInt(&ok);
        if (!ok || step.time <= 0)
        {
            showError(errorMessage.arg("Invalid time"));
            continue;
        }

        int tInt = line.section(',', 5, 5).trimmed().toInt(&ok);
        if (ok)
        {
            if (tInt < 0 || tInt > 100)
            {
                showError(errorMessage.arg("Invalid coreTemperature"));
                continue;
            }

            step.coreTemp = tInt;
        }

        tInt = line.section(',', 7, 7).trimmed().toInt(&ok);
        if (ok)
        {
            if (tInt < 0)
            {
                showError(errorMessage.arg("Invalid damper"));
                continue;
            }

            step.dehumidification = tInt;

            tInt = line.section(',', 9, 9).trimmed().toInt(&ok);
            if (ok)
            {
                if (tInt < 0)
                {
                    showError(errorMessage.arg("Invalid damperRepeat"));
                    continue;
                }

                step.dehumidificationRepeatDelay = tInt;

                tInt = line.section(',', 11, 11).trimmed().toInt(&ok);
                if (ok)
                {
                    if (tInt < 0)
                    {
                        showError(errorMessage.arg("Invalid damperRepeatCount"));
                        continue;
                    }

                    step.dehumidificationRepeatCount = tInt;
                }
            }
        }

        tInt = line.section(',', 8, 8).trimmed().toInt(&ok);
        if (ok)
        {
            if (tInt < 0)
            {
                showError(errorMessage.arg("Invalid sideNozzle"));
                continue;
            }

            step.humidification = tInt;

            tInt = line.section(',', 10, 10).trimmed().toInt(&ok);
            if (ok)
            {
                if (tInt < 0)
                {
                    showError(errorMessage.arg("Invalid sideNozzleRepeat"));
                    continue;
                }

                step.humidificationRepeatDelay = tInt;

                tInt = line.section(',', 12, 12).trimmed().toInt(&ok);
                if (ok)
                {
                    if (tInt < 0)
                    {
                        showError(errorMessage.arg("Invalid sideNozzleRepeatCount"));
                        continue;
                    }

                    step.humidificationRepeatCount = tInt;
                }
            }
        }

        steps.append(step);
    }

    dataFile.close();

    QFile processFile(root + "process.csv");
    if (!processFile.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        showError("File not found: " + processFile.fileName());
        return;
    }

    lineCount = 0;
    while (!processFile.atEnd())
    {
        lineCount++;

        QString line = QString::fromUtf8(processFile.readLine()).trimmed();
        if (line.isEmpty())
            continue;

        if (line.startsWith("type"))
            continue;

        QString errorMessage = QString("%3: %1, line %2").arg(processFile.fileName()).arg(lineCount);

        Define::Process process = Define::identifyProcess(line);
        if (process == Define::InvalidProcess)
        {
            showError(errorMessage.arg("Invalid type"));
            continue;
        }

        processes.append(process);
    }

    isLoaded_ = true;

    isCoreTempValid_ = false;
    time_ = 0;
    coreTemp_ = 0;
    foreach (CookStep s, steps)
    {
        if (s.coreTemp)
        {
            isCoreTempValid_ = true;
            coreTemp_ = s.coreTemp;
        }

        time_ += s.time;
    }
}

bool Cook::isCoreTempValid()
{
    if (!isLoaded())
        load();

    return isCoreTempValid_;
}

int Cook::time()
{
    if (!isLoaded())
        load();

    return time_;
}

int Cook::coreTemp()
{
    if (!isLoaded())
        load();

    return coreTemp_;
}