21 |
21 |
22 ChartFermenter::ChartFermenter(QString code, QString name, QWidget *parent) : QDialog(parent) |
22 ChartFermenter::ChartFermenter(QString code, QString name, QWidget *parent) : QDialog(parent) |
23 { |
23 { |
24 QSqlQuery query; |
24 QSqlQuery query; |
25 double timestamp; |
25 double timestamp; |
|
26 bool use_air = false, use_beer=false, use_chiller = false, use_room = false; |
|
27 bool use_sp_low = false, use_sp_high = false, use_heater = false, use_cooler = false; |
|
28 QAreaSeries *pwr_cool, *pwr_heat; |
|
29 QLineSeries *pv_air, *pv_beer, *pv_chiller; |
|
30 QLineSeries *pwr_cool1, *pwr_cool0, *pwr_heat1, *pwr_heat0; |
|
31 int min = 100, max = 0; |
26 |
32 |
27 qDebug() << "ChartFermenter:" << code << name; |
33 qDebug() << "ChartFermenter:" << code << name; |
|
34 |
|
35 /* |
|
36 * First see which values are really used in the logfile. |
|
37 */ |
|
38 query.prepare("SELECT * FROM log_fermenter WHERE code=:code ORDER BY datetime"); |
|
39 query.bindValue(":code", code); |
|
40 query.exec(); |
|
41 while (query.next()) { |
|
42 if (query.value("temp_air").toDouble() > 0) |
|
43 use_air = true; |
|
44 if (query.value("temp_beer").toDouble() > 0) |
|
45 use_beer = true; |
|
46 if (query.value("temp_chiller").toDouble() > 0) |
|
47 use_chiller = true; |
|
48 if (query.value("temp_room").toDouble() > 0) |
|
49 use_room = true; |
|
50 if (query.value("sp_low").toDouble() > 0) |
|
51 use_sp_low = true; |
|
52 if (query.value("sp_high").toDouble() > 0) |
|
53 use_sp_high = true; |
|
54 if (query.value("heater_power").toDouble() > 0) |
|
55 use_heater = true; |
|
56 if (query.value("cooler_power").toDouble() > 0) |
|
57 use_cooler = true; |
|
58 if (use_air && use_beer && use_chiller && use_room && use_sp_low && use_sp_high && use_heater && use_cooler) |
|
59 break; |
|
60 } |
|
61 // qDebug() << "use" << use_air << use_beer << use_chiller << use_room << use_sp_low << use_sp_high << use_heater << use_cooler; |
28 |
62 |
29 QDialog* dialog = new QDialog(parent); |
63 QDialog* dialog = new QDialog(parent); |
30 dialog->setWindowTitle(tr("BMSapp - Fermenter log ") + "\"" + name + "\""); |
64 dialog->setWindowTitle(tr("BMSapp - Fermenter log ") + "\"" + name + "\""); |
31 dialog->setObjectName(QString::fromUtf8("ChartFermenter")); |
65 dialog->setObjectName(QString::fromUtf8("ChartFermenter")); |
32 dialog->setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint); |
66 dialog->setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint); |
42 buttonBox->setObjectName(QString::fromUtf8("buttonBox")); |
76 buttonBox->setObjectName(QString::fromUtf8("buttonBox")); |
43 buttonBox->setOrientation(Qt::Vertical); |
77 buttonBox->setOrientation(Qt::Vertical); |
44 buttonBox->setStandardButtons(QDialogButtonBox::Ok); |
78 buttonBox->setStandardButtons(QDialogButtonBox::Ok); |
45 buttonBox->addButton(saveButton,QDialogButtonBox::ActionRole); |
79 buttonBox->addButton(saveButton,QDialogButtonBox::ActionRole); |
46 |
80 |
47 QLineSeries *pv_air = new QLineSeries(); |
81 if (use_air) |
48 QLineSeries *pv_beer = new QLineSeries(); |
82 pv_air = new QLineSeries(); |
49 QLineSeries *pv_chiller = new QLineSeries(); |
83 if (use_beer) |
50 QLineSeries *pwr_cool1 = new QLineSeries(); |
84 pv_beer = new QLineSeries(); |
51 QLineSeries *pwr_cool0 = new QLineSeries(); |
85 if (use_chiller) |
52 QLineSeries *pwr_heat1 = new QLineSeries(); // Top side of area |
86 pv_chiller = new QLineSeries(); |
53 QLineSeries *pwr_heat0 = new QLineSeries(); // Bottom side of area |
87 if (use_cooler) { |
|
88 pwr_cool1 = new QLineSeries(); |
|
89 pwr_cool0 = new QLineSeries(); |
|
90 } |
|
91 if (use_heater) { |
|
92 pwr_heat1 = new QLineSeries(); // Top side of area |
|
93 pwr_heat0 = new QLineSeries(); // Bottom side of area |
|
94 } |
54 |
95 |
55 query.prepare("SELECT * FROM log_fermenter WHERE code=:code ORDER BY datetime"); |
96 query.prepare("SELECT * FROM log_fermenter WHERE code=:code ORDER BY datetime"); |
56 query.bindValue(":code", code); |
97 query.bindValue(":code", code); |
57 query.exec(); |
98 query.exec(); |
58 while (query.next()) { |
99 while (query.next()) { |
59 timestamp = query.value("datetime").toDateTime().toSecsSinceEpoch() * 1000; |
100 timestamp = query.value("datetime").toDateTime().toSecsSinceEpoch() * 1000; |
60 pv_air->append(timestamp, query.value("temp_air").toDouble()); |
101 if (use_air) { |
61 pv_beer->append(timestamp, query.value("temp_beer").toDouble()); |
102 pv_air->append(timestamp, query.value("temp_air").toDouble()); |
62 if (query.value("temp_chiller").toDouble() > 0) |
103 if (ceil(query.value("temp_air").toDouble()) > max) |
|
104 max = ceil(query.value("temp_air").toDouble()); |
|
105 if (floor(query.value("temp_air").toDouble()) < min) |
|
106 min = floor(query.value("temp_air").toDouble()); |
|
107 } |
|
108 if (use_beer) { |
|
109 pv_beer->append(timestamp, query.value("temp_beer").toDouble()); |
|
110 if (ceil(query.value("temp_beer").toDouble()) > max) |
|
111 max = ceil(query.value("temp_beer").toDouble()); |
|
112 if (floor(query.value("temp_beer").toDouble()) < min) |
|
113 min = floor(query.value("temp_beer").toDouble()); |
|
114 } |
|
115 if (use_chiller && query.value("temp_chiller").toDouble() > 0) { |
63 pv_chiller->append(timestamp, query.value("temp_chiller").toDouble()); |
116 pv_chiller->append(timestamp, query.value("temp_chiller").toDouble()); |
64 pwr_cool0->append(timestamp, 0); |
117 // if (ceil(query.value("temp_chiller").toDouble()) > max) |
65 pwr_cool1->append(timestamp, query.value("cooler_power").toInt()); |
118 // max = ceil(query.value("temp_chiller").toDouble()); |
66 pwr_heat0->append(timestamp, 0); |
119 // if (floor(query.value("temp_chiller").toDouble()) < min) |
67 pwr_heat1->append(timestamp, query.value("heater_power").toInt()); |
120 // min = floor(query.value("temp_chiller").toDouble()); |
68 } |
121 } |
69 |
122 if (use_cooler) { |
70 pv_air->setName(tr("Air")); |
123 pwr_cool0->append(timestamp, 0); |
71 pv_air->setColor(QColorConstants::Svg::lightgreen); |
124 pwr_cool1->append(timestamp, query.value("cooler_power").toInt()); |
72 pv_beer->setName(tr("Beer")); |
125 } |
73 QPen pen(QColorConstants::Svg::navy); |
126 if (use_heater) { |
74 pen.setWidth(2); |
127 pwr_heat0->append(timestamp, 0); |
75 pv_beer->setPen(pen); |
128 pwr_heat1->append(timestamp, query.value("heater_power").toInt()); |
76 pv_chiller->setName(tr("Chiller")); |
129 } |
77 pv_chiller->setColor(QColorConstants::Svg::lightsalmon); |
130 } |
78 pv_chiller->setOpacity(0.75); |
131 // qDebug() << "min" << min << "max" << max << "ticks" << max-min+1; |
79 |
132 |
80 QAreaSeries *pwr_cool = new QAreaSeries(pwr_cool0, pwr_cool1); |
133 /* |
81 pwr_cool->setName("Cool %"); |
134 * If the range is small, increase it. |
82 pwr_cool->setOpacity(0.50); |
135 */ |
83 pwr_cool->setColor(QColorConstants::Blue); |
136 if ((max - min) < 5) { |
84 QAreaSeries *pwr_heat = new QAreaSeries(pwr_heat0, pwr_heat1); |
137 min = max - 5; |
85 pwr_heat->setName("Heat %"); |
138 } else if ((max - min) < 10) { |
86 pwr_heat->setOpacity(0.50); |
139 min = max - 10; |
87 pwr_heat->setColor(QColorConstants::Red); |
140 } |
|
141 |
|
142 if (use_air) { |
|
143 pv_air->setName(tr("Air")); |
|
144 if (use_beer) { |
|
145 pv_air->setColor(QColorConstants::Svg::lightgreen); |
|
146 } else { |
|
147 /* |
|
148 * If there is no beer line, then make this one fat. |
|
149 */ |
|
150 QPen pen(QColorConstants::Svg::lightgreen); |
|
151 pen.setWidth(2); |
|
152 pv_air->setPen(pen); |
|
153 } |
|
154 } |
|
155 if (use_beer) { |
|
156 pv_beer->setName(tr("Beer")); |
|
157 QPen pen(QColorConstants::Svg::navy); |
|
158 pen.setWidth(2); |
|
159 pv_beer->setPen(pen); |
|
160 } |
|
161 if (use_chiller) { |
|
162 pv_chiller->setName(tr("Chiller")); |
|
163 pv_chiller->setColor(QColorConstants::Svg::lightsalmon); |
|
164 pv_chiller->setOpacity(0.75); |
|
165 } |
|
166 |
|
167 if (use_cooler) { |
|
168 pwr_cool = new QAreaSeries(pwr_cool0, pwr_cool1); |
|
169 pwr_cool->setName("Cool %"); |
|
170 pwr_cool->setOpacity(0.50); |
|
171 pwr_cool->setColor(QColorConstants::Blue); |
|
172 } |
|
173 if (use_heater) { |
|
174 pwr_heat = new QAreaSeries(pwr_heat0, pwr_heat1); |
|
175 pwr_heat->setName("Heat %"); |
|
176 pwr_heat->setOpacity(0.50); |
|
177 pwr_heat->setColor(QColorConstants::Red); |
|
178 } |
88 |
179 |
89 chart = new QChart(); |
180 chart = new QChart(); |
90 chart->setTitle(QString("%1 \"%2\"").arg(code).arg(name)); |
181 chart->setTitle(QString("%1 \"%2\"").arg(code).arg(name)); |
91 chart->addSeries(pwr_cool); // Order is important, first drawn is lowest layer. |
182 if (use_cooler) |
92 chart->addSeries(pwr_heat); |
183 chart->addSeries(pwr_cool); // Order is important, first drawn is lowest layer. |
93 chart->addSeries(pv_chiller); |
184 if (use_heater) |
94 chart->addSeries(pv_air); |
185 chart->addSeries(pwr_heat); |
95 chart->addSeries(pv_beer); // Top layer |
186 if (use_chiller) |
|
187 chart->addSeries(pv_chiller); |
|
188 if (use_air) |
|
189 chart->addSeries(pv_air); |
|
190 if (use_beer) |
|
191 chart->addSeries(pv_beer); // Top layer |
96 |
192 |
97 QDateTimeAxis *axisX = new QDateTimeAxis; |
193 QDateTimeAxis *axisX = new QDateTimeAxis; |
98 axisX->setTickCount(10); |
194 axisX->setTickCount(10); |
99 axisX->setFormat("dd MMM"); |
195 axisX->setFormat("dd MMM"); |
100 axisX->setTitleText(tr("Date")); |
196 axisX->setTitleText(tr("Date")); |
101 axisX->setLabelsFont(QFont("Helvetica", 8, QFont::Normal)); |
197 axisX->setLabelsFont(QFont("Helvetica", 8, QFont::Normal)); |
102 chart->addAxis(axisX, Qt::AlignBottom); |
198 chart->addAxis(axisX, Qt::AlignBottom); |
103 pv_air->attachAxis(axisX); |
199 if (use_air) |
104 pv_beer->attachAxis(axisX); |
200 pv_air->attachAxis(axisX); |
105 pv_chiller->attachAxis(axisX); |
201 if (use_beer) |
|
202 pv_beer->attachAxis(axisX); |
|
203 if (use_chiller) |
|
204 pv_chiller->attachAxis(axisX); |
106 |
205 |
107 QValueAxis *axisY = new QValueAxis; |
206 QValueAxis *axisY = new QValueAxis; |
108 axisY->setTickCount(11); |
207 axisY->setRange(min, max); |
|
208 axisY->setTickCount(max-min+1); |
109 axisY->setMinorTickCount(1); |
209 axisY->setMinorTickCount(1); |
110 axisY->setLabelFormat("%i"); |
210 axisY->setLabelFormat("%.1f"); |
111 axisY->setTitleText(tr("Temp °C")); |
211 axisY->setTitleText(tr("Temp °C")); |
112 axisY->setLabelsFont(QFont("Helvetica", 8, QFont::Normal)); |
212 axisY->setLabelsFont(QFont("Helvetica", 8, QFont::Normal)); |
113 chart->addAxis(axisY, Qt::AlignLeft); |
213 chart->addAxis(axisY, Qt::AlignLeft); |
114 pv_air->attachAxis(axisY); |
214 if (use_air) |
115 pv_beer->attachAxis(axisY); |
215 pv_air->attachAxis(axisY); |
116 pv_chiller->attachAxis(axisY); |
216 if (use_beer) |
117 |
217 pv_beer->attachAxis(axisY); |
118 QValueAxis *axisYR = new QValueAxis; |
218 if (use_chiller) |
119 axisYR->setRange(0, 100); |
219 pv_chiller->attachAxis(axisY); |
120 axisYR->setTickCount(11); |
220 |
121 axisYR->setLabelFormat("%i"); |
221 if (use_heater || use_cooler) { |
122 axisYR->setTitleText(tr("Power %")); |
222 QValueAxis *axisYR = new QValueAxis; |
123 axisYR->setLabelsFont(QFont("Helvetica", 8, QFont::Normal)); |
223 axisYR->setRange(0, 100); |
124 chart->addAxis(axisYR, Qt::AlignRight); |
224 axisYR->setTickCount(11); |
125 pwr_cool->attachAxis(axisYR); |
225 axisYR->setLabelFormat("%i"); |
126 pwr_heat->attachAxis(axisYR); |
226 axisYR->setTitleText(tr("Power %")); |
127 |
227 axisYR->setLabelsFont(QFont("Helvetica", 8, QFont::Normal)); |
128 connect(pv_air, &QLineSeries::hovered, this, &ChartFermenter::tooltip); |
228 chart->addAxis(axisYR, Qt::AlignRight); |
129 connect(pv_beer, &QLineSeries::hovered, this, &ChartFermenter::tooltip); |
229 if (use_cooler) |
130 connect(pv_chiller, &QLineSeries::hovered, this, &ChartFermenter::tooltip); |
230 pwr_cool->attachAxis(axisYR); |
|
231 if (use_heater) |
|
232 pwr_heat->attachAxis(axisYR); |
|
233 } |
|
234 |
|
235 if (use_air) |
|
236 connect(pv_air, &QLineSeries::hovered, this, &ChartFermenter::tooltip); |
|
237 if (use_beer) |
|
238 connect(pv_beer, &QLineSeries::hovered, this, &ChartFermenter::tooltip); |
|
239 if (use_chiller) |
|
240 connect(pv_chiller, &QLineSeries::hovered, this, &ChartFermenter::tooltip); |
131 |
241 |
132 chartView = new QChartView(chart); |
242 chartView = new QChartView(chart); |
133 chartView->setRenderHint(QPainter::Antialiasing); |
243 chartView->setRenderHint(QPainter::Antialiasing); |
134 dialog->setLayout(new QHBoxLayout); |
244 dialog->setLayout(new QHBoxLayout); |
135 dialog->layout()->addWidget(chartView); |
245 dialog->layout()->addWidget(chartView); |