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.

Sat, 11 Feb 2023 15:48:02 +0100

author
Michiel Broek <mbroek@mbse.eu>
date
Sat, 11 Feb 2023 15:48:02 +0100
changeset 493
520306773450
parent 492
c3a781b4d35b
child 494
49ac23d25f61

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.

src/DetailiSpindel.cpp file | annotate | diff | comparison | revisions
src/DetailiSpindel.h file | annotate | diff | comparison | revisions
src/MainWindow.cpp file | annotate | diff | comparison | revisions
translations/bmsapp_en.ts file | annotate | diff | comparison | revisions
translations/bmsapp_nl.ts file | annotate | diff | comparison | revisions
--- 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<int>::of(&QComboBox::currentIndexChanged), this, &DetailiSpindel::code_changed);
     connect(ui->modeEdit, QOverload<int>::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);
 }
 
--- 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);
--- 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;
     }
 
--- 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 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../src/DetailiSpindel.cpp" line="39"/>
+        <location filename="../src/DetailiSpindel.cpp" line="41"/>
         <source>BMSapp - Details iSpindel</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../src/DetailiSpindel.cpp" line="88"/>
+        <location filename="../src/DetailiSpindel.cpp" line="96"/>
         <source>Online</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../src/DetailiSpindel.cpp" line="142"/>
+        <location filename="../src/DetailiSpindel.cpp" line="160"/>
         <source>Offline</source>
         <translation type="unfinished"></translation>
     </message>
--- 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 @@
         <translation>Log</translation>
     </message>
     <message>
-        <location filename="../src/DetailiSpindel.cpp" line="39"/>
+        <location filename="../src/DetailiSpindel.cpp" line="41"/>
         <source>BMSapp - Details iSpindel</source>
         <translation>BMSapp - Detail iSpindel</translation>
     </message>
     <message>
-        <location filename="../src/DetailiSpindel.cpp" line="88"/>
+        <location filename="../src/DetailiSpindel.cpp" line="96"/>
         <source>Online</source>
         <translation>Online</translation>
     </message>
     <message>
-        <location filename="../src/DetailiSpindel.cpp" line="142"/>
+        <location filename="../src/DetailiSpindel.cpp" line="160"/>
         <source>Offline</source>
         <translation>Offline</translation>
     </message>

mercurial