# HG changeset patch # User Michiel Broek # Date 1676126882 -3600 # Node ID 520306773450d16d57aa729a28e1d43652bc6e44 # Parent c3a781b4d35bc61ccbe34a6b999a4414967da472 Monitor iSpindels: use global variables instead of repeated expensive MySQL calls. Use the yeast temperature ranges for the colors on the thermometer scale. Don't show SVG and ABV if the OG is not yet known. Turn statusfield red if offline. Extra mon_ispindles fields yeast_lo and yeast_hi. Need at least bmsd version 0.3.42. If a websocket message is received that cannot be parsed, show the whole received message. diff -r c3a781b4d35b -r 520306773450 src/DetailiSpindel.cpp --- a/src/DetailiSpindel.cpp Fri Feb 10 17:28:46 2023 +0100 +++ b/src/DetailiSpindel.cpp Sat Feb 11 15:48:02 2023 +0100 @@ -32,7 +32,9 @@ { QSqlQuery query; +#ifdef DEBUG_MONITOR qDebug() << "DetailiSpindel record:" << id; +#endif ui->setupUi(this); this->recno = id; setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint); @@ -54,7 +56,6 @@ connect(ui->codePick, QOverload::of(&QComboBox::currentIndexChanged), this, &DetailiSpindel::code_changed); connect(ui->modeEdit, QOverload::of(&QComboBox::currentIndexChanged), this, &DetailiSpindel::mode_changed); - connect(ui->logButton, SIGNAL(clicked()), this, SLOT(on_ChartButton_clicked())); connect(parent, SIGNAL(updateiSpindel(QString)), this, SLOT(refreshiSpindel(QString))); emit refreshTable(); } @@ -64,7 +65,7 @@ { QSqlQuery query; - qDebug() << "refreshTable ispindel rec:" << this->recno; + qDebug() << "DetailiSpindel::refreshTable()"; query.prepare("SELECT * FROM mon_ispindels WHERE record = :recno"); query.bindValue(":recno", this->recno); @@ -80,24 +81,31 @@ _beercode = query.value("beercode").toString(); _beername = query.value("beername").toString(); + bool alarm = (query.value("alarm").toInt() != 0) ? true:false; + bool online = (query.value("online").toInt() != 0) ? true:false; + bool mode = (query.value("mode").toString() == "ON") ? true:false; + ui->uuidEdit->setText(_uuid); ui->systemEdit->setText(_node+"/"+_alias); ui->codePick->setItemText(0, _alias.toUpper()+" - "+_alias); + ui->alarmLED->setChecked(alarm); - if (query.value("online").toInt()) { + if (online) { ui->statusEdit->setText(tr("Online")); + ui->statusEdit->setStyleSheet(""); ui->codeEdit->setText(_beercode+" - "+_beername); + ui->thermoMeter->setNominal(query.value("yeast_lo").toDouble()); + ui->thermoMeter->setCritical(query.value("yeast_hi").toDouble()); + + ui->powerLED->setChecked(mode); ui->modeEdit->show(); - if (query.value("mode").toString() == "OFF") { - ui->powerLED->setChecked(false); + if (mode) { + ui->modeEdit->setCurrentIndex(1); + ui->codePick->hide(); + } else { ui->modeEdit->setCurrentIndex(0); ui->codePick->show(); - } else { - ui->powerLED->setChecked(true); - ui->modeEdit->setCurrentIndex(1); - ui->codePick->hide(); } - ui->alarmLED->setChecked((query.value("alarm").toInt() != 0) ? true:false); ui->voltEdit->setText(QString("%1").arg(query.value("battery").toDouble(), 4, 'f', 3, '0')); ui->tiltEdit->setText(QString("%1").arg(query.value("angle").toDouble(), 6, 'f', 5, '0')); @@ -106,16 +114,24 @@ ui->sgEdit->setText(QString("%1").arg(sg, 5, 'f', 4, '0')); if (query.value("gravity").toDouble()) { - double og = Utils::plato_to_sg(query.value("og_gravity").toDouble()); + double o_plato = query.value("og_gravity").toDouble(); + double og = Utils::plato_to_sg(o_plato); double svg = Utils::calc_svg(og, sg); ui->ogVal->setText(QString("%1").arg(og, 5, 'f', 4, '0')); - ui->ogVal2->setText(QString("%1°P").arg(query.value("og_gravity").toDouble(), 4, 'f', 3, '0')); + ui->ogVal2->setText(QString("%1°P").arg(o_plato, 4, 'f', 3, '0')); ui->sgVal->setText(QString("%1").arg(sg, 5, 'f', 4, '0')); ui->sgVal2->setText(QString("%1°P").arg(query.value("gravity").toDouble(), 4, 'f', 3, '0')); - ui->svgVal->setText(QString("%1%").arg(svg, 2, 'f', 1, '0')); - ui->svgBar->setValue(svg); - ui->abvVal->setText(QString("%1%").arg(Utils::abvol(og, sg), 3, 'f', 2, '0')); + if (o_plato > 0.1) { + ui->svgVal->setText(QString("%1%").arg(svg, 2, 'f', 1, '0')); + ui->svgBar->setValue(svg); + ui->abvVal->setText(QString("%1%").arg(Utils::abvol(og, sg), 3, 'f', 2, '0')); + } else { + /* o_plato is 0 if a new beer is selected. */ + ui->svgVal->setText(""); + ui->svgBar->setValue(0); + ui->abvVal->setText(""); + } } else { ui->ogVal->setText(""); ui->ogVal2->setText(""); @@ -140,6 +156,7 @@ } else { /* Offline */ ui->statusEdit->setText(tr("Offline")); + ui->statusEdit->setStyleSheet("background-color: red"); ui->powerLED->setChecked(false); ui->alarmLED->setChecked(true); ui->codePick->hide(); @@ -154,7 +171,6 @@ DetailiSpindel::~DetailiSpindel() { - qDebug() << "DetailiSpindel done"; delete ui; emit entry_changed(); } @@ -172,7 +188,7 @@ } -void DetailiSpindel::on_ChartButton_clicked() +void DetailiSpindel::on_logButton_clicked() { ChartiSpindel dialog(_beercode, _beername, this); } @@ -189,7 +205,9 @@ { QStringList mode ({ "OFF", "ON" }); QString msg = QString("{\"device\":\"ispindels\",\"node\":\"" + _node + "\",\"unit\":\"" + _alias + "\",\"mode\":\"" + mode[val] + "\"}"); +#ifdef DEBUG_MONITOR qDebug() << "mode_changed" << val << msg; +#endif webSocket->sendTextMessage(msg); } @@ -203,18 +221,44 @@ if (val == 0) { msg.append(QString("\"beeruuid\":\"") + _uuid + "\","); msg.append(QString("\"beercode\":\"") + _alias.toUpper() + "\","); - msg.append(QString("\"beername\":\"") + _alias + "\"}"); + msg.append(QString("\"beername\":\"") + _alias + "\","); + msg.append(QString("\"yeast_lo\":20.0,")); + msg.append(QString("\"yeast_hi\":25.0}")); } else { query.exec("SELECT code,name,uuid,stage,json_yeasts FROM products WHERE stage='1' OR stage='2' OR stage='3' OR stage='4' OR stage='5' OR stage='6' OR stage='7' ORDER BY code"); for (int i = 0; i < val; i++) { query.next(); } + double yl = 0; + double yh = 40; + const auto& y_json = query.value("json_yeasts").toString(); + if (! y_json.trimmed().isEmpty()) { + const auto& formattedJson = QString("%1").arg(y_json); + QJsonDocument yeasts = QJsonDocument::fromJson(formattedJson.toUtf8(), &parseError); + if (parseError.error != QJsonParseError::NoError) { + qWarning() << "Parse error: " << parseError.errorString() << "at" << parseError.offset ; + } else if (yeasts.isArray()) { + for (int i = 0; i < yeasts.array().size(); i++) { + QJsonObject obj = yeasts.array().at(i).toObject(); + if (obj["y_use"].toInt() == 0) { // Primary yeast + if (obj["y_min_temperature"].toDouble() > yl) + yl = obj["y_min_temperature"].toDouble(); + if (obj["y_max_temperature"].toDouble() < yh) + yh = obj["y_max_temperature"].toDouble(); + } + } + } + } msg.append(QString("\"beeruuid\":\"") + query.value("uuid").toString() + "\","); msg.append(QString("\"beercode\":\"") + query.value("code").toString() + "\","); - msg.append(QString("\"beername\":\"") + query.value("name").toString() + "\"}"); + msg.append(QString("\"beername\":\"") + query.value("name").toString() + "\","); + msg.append(QString("\"yeast_lo\":%1,").arg(yl)); + msg.append(QString("\"yeast_hi\":%1}").arg(yh)); } +#ifdef DEBUG_MONITOR qDebug() << "code_changed" << val << msg; +#endif webSocket->sendTextMessage(msg); } diff -r c3a781b4d35b -r 520306773450 src/DetailiSpindel.h --- a/src/DetailiSpindel.h Fri Feb 10 17:28:46 2023 +0100 +++ b/src/DetailiSpindel.h Sat Feb 11 15:48:02 2023 +0100 @@ -30,7 +30,7 @@ void refreshTable(void); void mode_changed(int val); void code_changed(int val); - void on_ChartButton_clicked(); + void on_logButton_clicked(); public slots: void refreshiSpindel(QString); diff -r c3a781b4d35b -r 520306773450 src/MainWindow.cpp --- a/src/MainWindow.cpp Fri Feb 10 17:28:46 2023 +0100 +++ b/src/MainWindow.cpp Sat Feb 11 15:48:02 2023 +0100 @@ -344,6 +344,7 @@ if (parseError.error != QJsonParseError::NoError) { qWarning() << "wsTextMessageReceived error:" << parseError.errorString() << "at" << parseError.offset ; + qWarning() << message; return; } diff -r c3a781b4d35b -r 520306773450 translations/bmsapp_en.ts --- a/translations/bmsapp_en.ts Fri Feb 10 17:28:46 2023 +0100 +++ b/translations/bmsapp_en.ts Sat Feb 11 15:48:02 2023 +0100 @@ -996,17 +996,17 @@ - + BMSapp - Details iSpindel - + Online - + Offline diff -r c3a781b4d35b -r 520306773450 translations/bmsapp_nl.ts --- a/translations/bmsapp_nl.ts Fri Feb 10 17:28:46 2023 +0100 +++ b/translations/bmsapp_nl.ts Sat Feb 11 15:48:02 2023 +0100 @@ -1073,17 +1073,17 @@ Log - + BMSapp - Details iSpindel BMSapp - Detail iSpindel - + Online Online - + Offline Offline