9 #include <QCryptographicHash>
16 #define ADMINPASSWORD "e5a66b96415488a8df63d229d1a3048b29ef757f"
19 #ifndef FOTOMONPASSWORD
20 #define FOTOMONPASSWORD "ff5bcc26bc440020b177abff256652991c3dd0ef"
23 DATABASE::~DATABASE() {
29 #define COMMITINTERVAL 60000
30 #define SYNCHRONOUS "OFF"
31 #define DEFAULTDEVICE "/dev/ttyA"
33 #define COMMITINTERVAL 5000
34 #define SYNCHRONOUS "FULL"
35 #define DEFAULTDEVICE "/dev/ttyS0"
39 DATABASE::DATABASE(QSettings *settings, QObject *parent) : QObject(parent) {
40 m_in_transaction =
false;
41 m_timerCommit =
new QTimer(
this);
42 m_timerCommit->setInterval(settings->value(
"commitinterval", COMMITINTERVAL).toInt());
43 m_timerCommit->setSingleShot(
false);
44 connect(m_timerCommit, SIGNAL(timeout()),
45 this, SLOT(commit()));
46 m_timerCommit->start();
48 m_synchronous = settings->value(
"synchronous", SYNCHRONOUS).toString();
49 if (m_synchronous !=
"OFF" &&
50 m_synchronous !=
"NORMAL" &&
51 m_synchronous !=
"FULL" ) {
52 m_synchronous = SYNCHRONOUS;
55 QString dbdata = settings->value(
"dbname",
"fotobot.sqlite3").toString();
56 QString dbcopy = settings->value(
"dbname-copy",
"fotobot-copy.sqlite3").toString();
58 QFile filedbdata(dbdata);
59 QFile filedbcopy(dbcopy);
60 if (filedbcopy.exists() && !filedbdata.exists()) {
61 filedbcopy.copy(dbdata);
64 m_db = open( settings->value(
"dbname",
"fotobot.sqlite3").toString() );
65 m_dbc = open( settings->value(
"dbname-copy",
"fotobot-copy.sqlite3").toString() );
74 qDebug() << QString(
"DATABASE::open(%1)").arg(name) <<
"current path" << QDir::currentPath();
76 QSqlDatabase db = QSqlDatabase::addDatabase(
"QSQLITE", QUuid::createUuid().toString().toAscii());
77 db.setDatabaseName( name );
81 q.exec(QString(
"pragma synchronous=%1;").arg(m_synchronous));
82 q.exec(
"select * from version;");
104 if (m_in_transaction) {
108 m_in_transaction =
true;
109 m_timerCommit->start();
117 qWarning() <<
"DATABASE::create()";
119 q.exec(
"create table version (version integer);");
120 q.exec(
"insert into version (version) values (1);");
121 q.exec(
"create table lines ("
122 " line integer primary key, "
123 " description text, "
126 " retries integer not null default 5, "
127 " timeout integer not null default 3000, "
130 q.exec(
"create table invertors ("
132 " invertor integer primary key, "
133 " description text, "
138 " now_power integer, "
139 " now_ac_current integer, "
140 " now_ac_voltage integer, "
141 " now_ac_frequency integer, "
142 " now_dc_current integer, "
143 " now_dc_voltage integer, "
144 " day_energy integer, "
145 " day_power_maximum integer, "
146 " day_ac_voltage_maximum integer, "
147 " day_ac_voltage_minimum integer, "
148 " day_dc_voltage_maximum integer, "
149 " day_operating_hours integer, "
150 " total_energy integer, "
151 " total_power_maximum integer, "
152 " total_ac_voltage_maximum integer, "
153 " total_ac_voltage_minimum integer, "
154 " total_dc_voltage_maximum integer, "
155 " total_operating_hours integer, "
156 " unique (line, address) "
158 q.exec(
"create table data ("
160 " not null references invertors(invertor) "
161 " on update cascade on delete cascade, "
164 " now_power numeric, "
165 " now_ac_current numeric, "
166 " now_ac_voltage numeric, "
167 " now_ac_frequency numeric, "
168 " now_dc_current numeric, "
169 " now_dc_voltage numeric, "
170 " day_energy numeric, "
171 " day_power_maximum numeric, "
172 " day_ac_voltage_maximum numeric, "
173 " day_ac_voltage_minimum numeric, "
174 " day_dc_voltage_maximum numeric, "
175 " day_operating_hours numeric, "
176 " total_energy numeric, "
177 " total_power_maximum numeric, "
178 " total_ac_voltage_maximum numeric, "
179 " total_ac_voltage_minimum numeric, "
180 " total_dc_voltage_maximum numeric, "
181 " total_operating_hours numeric "
183 q.exec(
"create index data_idx_invertor_date on data(invertor,date);");
185 q.exec(
"create table users ("
186 " user text primary key, "
187 " password text not null "
189 q.exec(QString(
"insert into users (user, password) values ('admin', '%1');").arg(ADMINPASSWORD));
191 q.exec(
"create table maintenance ("
194 q.exec(
"insert into maintenance (days) values (5);");
198 q.exec(QString(
" insert into lines (line, device, description, retries, timeout, speed) values "
199 " (1, '%1', 'Line 1', 5, 3000, 9600);").arg(DEFAULTDEVICE));
201 for (
int i=1; i<=73; i++) {
202 q.exec(QString(
"insert into invertors (invertor, line, address, now_power) values (%1, 1, %1, 1);").arg(i));
209 void DATABASE::upgrade(QSqlDatabase& db) {
211 q.exec(
"select version from version;");
213 int version = q.value(0).toInt();
215 q.exec(
"create table interfaceboxes ("
216 " interfacebox integer primary key, "
217 " line integer not null references lines(line) on update cascade on delete cascade, "
220 qDebug() <<
"DATABASE::upgrade() 1 -> 2";
224 q.exec(
"create table geocoordinates ("
225 " longitude numeric not null, "
226 " latitude numeric not null "
228 qDebug() <<
"DATABASE::upgrade() 2 -> 3";
232 q.exec(
"alter table users add column can_access_data integer;");
233 q.exec(
"alter table users add column can_change_settings integer;");
234 q.exec(
"delete from users;");
235 q.exec(QString(
"insert into users (user, password, can_access_data, can_change_settings) values ('admin', '%1', 1, 1); ").arg(ADMINPASSWORD));
236 q.exec(QString(
"insert into users (user, password, can_access_data, can_change_settings) values ('fotomon', '%1', 1, 0); ").arg(FOTOMONPASSWORD));
237 qDebug() <<
"DATABASE::upgrade() 3 -> 4";
242 q.exec(
"alter table lines add column type integer;");
243 q.exec(
"alter table lines add column hostname text;");
244 q.exec(
"alter table lines add column portnumber integer;");
245 q.exec(QString(
"update lines set type = %1;").arg(DBT_LINES::Fronius));
246 qDebug() <<
"DATABASE::upgrade() 4 -> 5";
251 q.exec(
"alter table invertors add column temperature_1 integer;");
252 q.exec(
"alter table invertors add column temperature_2 integer;");
253 q.exec(
"alter table invertors add column irradiance integer;");
254 q.exec(
"alter table data add column temperature_1 numeric;");
255 q.exec(
"alter table data add column temperature_2 numeric;");
256 q.exec(
"alter table data add column irradiance numeric;");
257 qDebug() <<
"DATABASE::upgrade() 4 -> 5";
262 q.exec(
"alter table data add column status text;");
263 qDebug() <<
"DATABASE::upgrade() 5 -> 6";
267 q.exec(QString(
"update version set version=%1;").arg(version));
276 QList<DBT_USERS> list;
278 if (user.isEmpty()) {
279 q.exec(QString(
"select user, password, can_access_data, can_change_settings from users;"));
281 q.exec(QString(
"select user, password, can_access_data, can_change_settings from users where user='%1';").arg(user));
286 p.user = q.value(i++).toString();
287 p.password = q.value(i++).toString();
288 p.can_access_data = q.value(i++).toBool();
289 p.can_change_settings = q.value(i++).toBool();
311 if (user.password.isEmpty() || user.password ==
"") {
314 QString passsha1 = QCryptographicHash::hash(user.password.toAscii(), QCryptographicHash::Sha1).toHex();
315 q.exec(QString(
"update users set password='%1' where user='%2'")
336 q.exec(QString(
"select * from users where user='%1'").arg(user.id));
338 q.exec(QString(
"update users set user='%1', can_access_data=%2, can_change_settings=%3 where user='%4'")
340 .arg(
nullb(user.can_access_data))
341 .arg(
nullb(user.can_change_settings))
345 q.exec(QString(
"insert into users (user, password, can_access_data, can_change_settings) values ('%1', '!!', %2, %3);")
347 .arg(user.can_access_data)
348 .arg(user.can_change_settings)
357 void DATABASE::deleteUser(QString userid) {
358 deleteUser(m_db, userid);
359 deleteUser(m_dbc, userid);
363 void DATABASE::deleteUser(QSqlDatabase& db, QString userid) {
366 q.exec(QString(
"delete from users where user='%1'").arg(userid));
384 q.exec(QString(
"select line, device, description, speed, retries, timeout, sn_format, type, hostname, portnumber from lines "
385 " where %1 <= 0 or line = %1; ").arg(line));
389 p.line = q.value(i++).toInt();
390 p.device = q.value(i++).toString();
391 p.description = q.value(i++).toString();
392 p.speed = q.value(i++).toInt();
393 p.retries = q.value(i++).toInt();
394 p.timeout = q.value(i++).toInt();
395 p.sn_format = q.value(i++).toString();
396 int type = q.value(i++).toInt();
397 p.type = (type == DBT_LINES::Fronius) ? DBT_LINES::Fronius
398 : (type == DBT_LINES::ModbusTCP) ? DBT_LINES::ModbusTCP
399 : (type == DBT_LINES::ModbusRTU) ? DBT_LINES::ModbusRTU
400 : DBT_LINES::Unknown;
401 p.hostname = q.value(i++).toString();
402 p.portnumber = q.value(i++).toInt();
413 QList<DBT_INVERTORS> list;
415 q.exec(QString(
"select invertor, description, line, address, "
416 " now_power, now_ac_current, now_ac_voltage, now_ac_frequency, now_dc_current,"
417 " now_dc_voltage, day_energy, day_power_maximum, day_ac_voltage_maximum, "
418 " day_ac_voltage_minimum, day_dc_voltage_maximum, day_operating_hours, "
419 " total_energy, total_power_maximum, total_ac_voltage_maximum, "
420 " total_ac_voltage_minimum, total_dc_voltage_maximum, total_operating_hours, "
421 " temperature_1, temperature_2, irradiance "
422 " from invertors where 0 = %1 or line = %1 order by invertor; ")
428 x.invertor = q.value(i++).toInt();
429 x.description = q.value(i++).toString();
430 x.line = q.value(i++).toInt();
431 x.address = q.value(i++).toInt();
432 x.now_power = q.value(i++).toBool();
433 x.now_ac_current = q.value(i++).toBool();
434 x.now_ac_voltage = q.value(i++).toBool();
435 x.now_ac_frequency = q.value(i++).toBool();
436 x.now_dc_current = q.value(i++).toBool();
437 x.now_dc_voltage = q.value(i++).toBool();
438 x.day_energy = q.value(i++).toBool();
439 x.day_power_maximum = q.value(i++).toBool();
440 x.day_ac_voltage_maximum = q.value(i++).toBool();
441 x.day_ac_voltage_minimum = q.value(i++).toBool();
442 x.day_dc_voltage_maximum = q.value(i++).toBool();
443 x.day_operating_hours = q.value(i++).toBool();
444 x.total_energy = q.value(i++).toBool();
445 x.total_power_maximum = q.value(i++).toBool();
446 x.total_ac_voltage_maximum = q.value(i++).toBool();
447 x.total_ac_voltage_minimum = q.value(i++).toBool();
448 x.total_dc_voltage_maximum = q.value(i++).toBool();
449 x.total_operating_hours = q.value(i++).toBool();
450 x.temperature_1 = q.value(i++).toBool();
451 x.temperature_2 = q.value(i++).toBool();
452 x.irradiance = q.value(i++).toBool();
472 QList<DBT_INVERTORS> list;
473 QString cond =
"0=1 ";
474 for (
int i=0; i<invertors.size(); i++) {
475 cond = cond + QString(
" or invertor=%1").arg(invertors.at(i));
478 q.exec(QString(
"select invertor, description, line, address, "
479 " now_power, now_ac_current, now_ac_voltage, now_ac_frequency, now_dc_current,"
480 " now_dc_voltage, day_energy, day_power_maximum, day_ac_voltage_maximum, "
481 " day_ac_voltage_minimum, day_dc_voltage_maximum, day_operating_hours, "
482 " total_energy, total_power_maximum, total_ac_voltage_maximum, "
483 " total_ac_voltage_minimum, total_dc_voltage_maximum, total_operating_hours, "
484 " temperature_1, temperature_2, irradiance "
485 " from invertors where %1 order by invertor; ")
491 x.invertor = q.value(i++).toInt();
492 x.description = q.value(i++).toString();
493 x.line = q.value(i++).toInt();
494 x.address = q.value(i++).toInt();
495 x.now_power = q.value(i++).toBool();
496 x.now_ac_current = q.value(i++).toBool();
497 x.now_ac_voltage = q.value(i++).toBool();
498 x.now_ac_frequency = q.value(i++).toBool();
499 x.now_dc_current = q.value(i++).toBool();
500 x.now_dc_voltage = q.value(i++).toBool();
501 x.day_energy = q.value(i++).toBool();
502 x.day_power_maximum = q.value(i++).toBool();
503 x.day_ac_voltage_maximum = q.value(i++).toBool();
504 x.day_ac_voltage_minimum = q.value(i++).toBool();
505 x.day_dc_voltage_maximum = q.value(i++).toBool();
506 x.day_operating_hours = q.value(i++).toBool();
507 x.total_energy = q.value(i++).toBool();
508 x.total_power_maximum = q.value(i++).toBool();
509 x.total_ac_voltage_maximum = q.value(i++).toBool();
510 x.total_ac_voltage_minimum = q.value(i++).toBool();
511 x.total_dc_voltage_maximum = q.value(i++).toBool();
512 x.total_operating_hours = q.value(i++).toBool();
513 x.temperature_1 = q.value(i++).toBool();
514 x.temperature_2 = q.value(i++).toBool();
515 x.irradiance = q.value(i++).toBool();
526 QList<DBT_INTERFACEBOXES> list;
528 q.exec(QString(
"select interfacebox, line, description "
529 " from interfaceboxes where 0 = %1 or line = %1 order by interfacebox; ")
535 x.interfacebox = q.value(i++).toInt();
536 x.line = q.value(i++).toInt();
537 x.description = q.value(i++).toString();
556 QList<DBT_INTERFACEBOXES> list;
557 QString cond =
"0=1 ";
558 for (
int i=0; i<interfaceboxes.size(); i++) {
559 cond = cond + QString(
" or interfacebox=%1").arg(interfaceboxes.at(i));
562 q.exec(QString(
"select interfacebox, line, description "
563 " from interfaceboxes where %1 order by interfacebox; ")
569 x.interfacebox = q.value(i++).toInt();
570 x.line = q.value(i++).toInt();
571 x.description = q.value(i++).toString();
584 q.exec(QString(
"select longitude, latitude "
585 " from geocoordinates; ")
590 g.longitude = q.value(i++);
591 g.latitude = q.value(i++);
611 QList<DBT_DATA_VW>
DATABASE::data(
const QDateTime& from,
const QDateTime& to,
bool limit) {
613 QList<DBT_DATA_VW> list;
617 if (!from.isValid()) {
618 dotaz = QString(
"select i.line, i.address, "
619 "d.date, d.error, d.now_power, d.now_ac_current, d.now_ac_voltage, "
620 "d.now_ac_frequency, d.now_dc_current, d.now_dc_voltage, d.day_energy, "
621 "d.day_power_maximum, d.day_ac_voltage_maximum, d.day_ac_voltage_minimum, "
622 "d.day_dc_voltage_maximum, d.day_operating_hours, d.total_energy, "
623 "d.total_power_maximum, d.total_ac_voltage_maximum, d.total_ac_voltage_minimum, "
624 "d.total_dc_voltage_maximum, d.total_operating_hours, "
625 "d.temperature_1, d.temperature_2, d.irradiance, d.status, "
628 " (select invertor,max(date) as date from data group by invertor) x, "
631 "where d.invertor=x.invertor and d.date=x.date "
632 " and d.invertor=i.invertor "
633 " and l.line=i.line "
634 "order by i.line, i.address; ");
636 QDateTime lto = QDateTime::currentDateTime();
637 if (to.isValid() && !limit) {
640 if (to.isValid() && limit) {
641 lto = from.addSecs(10800);
642 if (lto > QDateTime::currentDateTime()) {
643 lto = QDateTime::currentDateTime();
649 dotaz = QString(
"select i.line, i.address, "
650 "d.date, d.error, d.now_power, d.now_ac_current, d.now_ac_voltage, "
651 "d.now_ac_frequency, d.now_dc_current, d.now_dc_voltage, d.day_energy, "
652 "d.day_power_maximum, d.day_ac_voltage_maximum, d.day_ac_voltage_minimum, "
653 "d.day_dc_voltage_maximum, d.day_operating_hours, d.total_energy, "
654 "d.total_power_maximum, d.total_ac_voltage_maximum, d.total_ac_voltage_minimum, "
655 "d.total_dc_voltage_maximum, d.total_operating_hours, "
656 "d.temperature_1, d.temperature_2, d.irradiance, d.status, "
661 "where d.invertor=i.invertor "
662 " and l.line=i.line "
663 " and d.date >= '%1' and d.date <= '%2' "
664 "order by i.line, d.date, i.address ; ")
665 .arg(from.toString(
"yyyy-MM-dd hh:mm:ss"))
666 .arg( lto.toString(
"yyyy-MM-dd hh:mm:ss"))
676 x.line = q.value(i++).toInt();
677 x.address = q.value(i++).toInt();
678 x.date = QDateTime::fromString(q.value(i++).toString(),
"yyyy-MM-dd hh:mm:ss");
679 x.error = q.value(i++).toString();
680 x.now_power = q.value(i++);
681 x.now_ac_current = q.value(i++);
682 x.now_ac_voltage = q.value(i++);
683 x.now_ac_frequency = q.value(i++);
684 x.now_dc_current = q.value(i++);
685 x.now_dc_voltage = q.value(i++);
686 x.day_energy = q.value(i++);
687 x.day_power_maximum = q.value(i++);
688 x.day_ac_voltage_maximum = q.value(i++);
689 x.day_ac_voltage_minimum = q.value(i++);
690 x.day_dc_voltage_maximum = q.value(i++);
691 x.day_operating_hours = q.value(i++);
692 x.total_energy = q.value(i++);
693 x.total_power_maximum = q.value(i++);
694 x.total_ac_voltage_maximum = q.value(i++);
695 x.total_ac_voltage_minimum = q.value(i++);
696 x.total_dc_voltage_maximum = q.value(i++);
697 x.total_operating_hours = q.value(i++);
698 x.temperature_1 = q.value(i++);
699 x.temperature_2 = q.value(i++);
700 x.irradiance = q.value(i++);
701 x.status = q.value(i++).toString();
702 x.serial_number = q.value(i++).toString();
703 if (x.serial_number.isEmpty() || x.serial_number==
"") {
704 x.serial_number = QString(
"%1").arg(x.address);
706 x.serial_number = x.serial_number
707 .replace(
"$L",QString(
"%1").arg(x.line))
708 .replace(
"$A",QString(
"%1").arg(x.address))
709 .replace(
"$1A",QString(
"%1").arg(x.address,1,10,QChar(
'0')))
710 .replace(
"$2A",QString(
"%1").arg(x.address,2,10,QChar(
'0')))
711 .replace(
"$3A",QString(
"%1").arg(x.address,3,10,QChar(
'0')))
712 .replace(
"$4A",QString(
"%1").arg(x.address,4,10,QChar(
'0')))
713 .replace(
"$5A",QString(
"%1").arg(x.address,5,10,QChar(
'0')))
714 .replace(
"$6A",QString(
"%1").arg(x.address,6,10,QChar(
'0')))
715 .replace(
"$7A",QString(
"%1").arg(x.address,7,10,QChar(
'0')))
716 .replace(
"$8A",QString(
"%1").arg(x.address,8,10,QChar(
'0')))
717 .replace(
"$9A",QString(
"%1").arg(x.address,9,10,QChar(
'0')))
736 if (x.invertor <= 0)
return;
739 q.exec(QString(
"select 1 from data where invertor=%1 and date=%2;")
743 if (q.next())
return;
745 if (x.error.isEmpty()) {
746 q.exec(QString(
"insert into data ( "
757 "day_power_maximum, "
758 "day_ac_voltage_maximum, "
759 "day_ac_voltage_minimum, "
760 "day_dc_voltage_maximum, "
761 "day_operating_hours, "
763 "total_power_maximum, "
764 "total_ac_voltage_maximum, "
765 "total_ac_voltage_minimum, "
766 "total_dc_voltage_maximum, "
767 "total_operating_hours, "
802 .arg(
nulli(x.now_power))
803 .arg(
nullf(x.now_ac_current))
804 .arg(
nulli(x.now_ac_voltage))
805 .arg(
nullf(x.now_ac_frequency))
806 .arg(
nullf(x.now_dc_current))
807 .arg(
nulli(x.now_dc_voltage))
808 .arg(
nulli(x.day_energy))
809 .arg(
nulli(x.day_power_maximum))
810 .arg(
nulli(x.day_ac_voltage_maximum))
811 .arg(
nulli(x.day_ac_voltage_minimum))
812 .arg(
nulli(x.day_dc_voltage_maximum))
813 .arg(
nullf(x.day_operating_hours))
814 .arg(
nulli(x.total_energy))
815 .arg(
nulli(x.total_power_maximum))
816 .arg(
nulli(x.total_ac_voltage_maximum))
817 .arg(
nulli(x.total_ac_voltage_minimum))
818 .arg(
nulli(x.total_dc_voltage_maximum))
819 .arg(
nullf(x.total_operating_hours))
820 .arg(
nullf(x.temperature_1))
821 .arg(
nullf(x.temperature_2))
822 .arg(
nullf(x.irradiance))
823 .arg(
nulls(x.status))
827 q.exec(QString(
"insert into data ("
860 q.exec(QString(
"select line from lines where line=%1;").arg(x.line));
863 q.exec(QString(
"update lines set "
865 " description='%2', "
886 q.exec(QString(
"insert into lines "
887 "(device, description, speed, retries, timeout, sn_format, type, hostname, portnumber) "
889 "('%1', '%2', %3, %4, %5, '%6', %7, '%8', %9);")
900 q.exec(QString(
"select last_insert_rowid();"));
903 return q.value(0).toInt();
925 q.exec(QString(
"select line from invertors where invertor=%1;").arg(x.invertor));
928 q.exec(QString(
"update invertors set "
933 "now_ac_current = %5, "
934 "now_ac_voltage = %6, "
935 "now_ac_frequency = %7, "
936 "now_dc_current = %8, "
937 "now_dc_voltage = %9, "
939 "day_power_maximum = %11, "
940 "day_ac_voltage_maximum = %12, "
941 "day_ac_voltage_minimum = %13, "
942 "day_dc_voltage_maximum = %14, "
943 "day_operating_hours = %15, "
944 "total_energy = %16, "
945 "total_power_maximum = %17, "
946 "total_ac_voltage_maximum = %18, "
947 "total_ac_voltage_minimum = %19, "
948 "total_dc_voltage_maximum = %20, "
949 "total_operating_hours = %21, "
950 "temperature_1 = %22, "
951 "temperature_2 = %23, "
953 "where invertor = %25; ")
954 .arg(
nulls(x.description))
956 .arg(
nulli(x.address))
957 .arg(
nullb(x.now_power))
958 .arg(
nullb(x.now_ac_current))
959 .arg(
nullb(x.now_ac_voltage))
960 .arg(
nullb(x.now_ac_frequency))
961 .arg(
nullb(x.now_dc_current))
962 .arg(
nullb(x.now_dc_voltage))
963 .arg(
nullb(x.day_energy))
964 .arg(
nullb(x.day_power_maximum))
965 .arg(
nullb(x.day_ac_voltage_maximum))
966 .arg(
nullb(x.day_ac_voltage_minimum))
967 .arg(
nullb(x.day_dc_voltage_maximum))
968 .arg(
nullb(x.day_operating_hours))
969 .arg(
nullb(x.total_energy))
970 .arg(
nullb(x.total_power_maximum))
971 .arg(
nullb(x.total_ac_voltage_maximum))
972 .arg(
nullb(x.total_ac_voltage_minimum))
973 .arg(
nullb(x.total_dc_voltage_maximum))
974 .arg(
nullb(x.total_operating_hours))
975 .arg(
nulli(x.temperature_1))
976 .arg(
nulli(x.temperature_2))
977 .arg(
nulli(x.irradiance))
978 .arg(
nulli(x.invertor))
982 q.exec(QString(
"insert into invertors ("
983 "description, line, address, now_power, now_ac_current, now_ac_voltage, "
984 "now_ac_frequency, now_dc_current, now_dc_voltage, day_energy, "
985 "day_power_maximum, day_ac_voltage_maximum, day_ac_voltage_minimum, "
986 "day_dc_voltage_maximum, day_operating_hours, total_energy, "
987 "total_power_maximum, total_ac_voltage_maximum, total_ac_voltage_minimum, "
988 "total_dc_voltage_maximum, total_operating_hours, temperature_1, temperature_2, irradiance) values ("
989 "%1, %2, %3, %4, %5, %6, %7, %8, %9, %10, "
990 "%11, %12, %13, %14, %15, %16, %17, %18, %19, %20, %21, %22, %23, %24);")
991 .arg(
nulls(x.description))
993 .arg(
nulli(x.address))
994 .arg(
nullb(x.now_power))
995 .arg(
nullb(x.now_ac_current))
996 .arg(
nullb(x.now_ac_voltage))
997 .arg(
nullb(x.now_ac_frequency))
998 .arg(
nullb(x.now_dc_current))
999 .arg(
nullb(x.now_dc_voltage))
1000 .arg(
nullb(x.day_energy))
1001 .arg(
nullb(x.day_power_maximum))
1002 .arg(
nullb(x.day_ac_voltage_maximum))
1003 .arg(
nullb(x.day_ac_voltage_minimum))
1004 .arg(
nullb(x.day_dc_voltage_maximum))
1005 .arg(
nullb(x.day_operating_hours))
1006 .arg(
nullb(x.total_energy))
1007 .arg(
nullb(x.total_power_maximum))
1008 .arg(
nullb(x.total_ac_voltage_maximum))
1009 .arg(
nullb(x.total_ac_voltage_minimum))
1010 .arg(
nullb(x.total_dc_voltage_maximum))
1011 .arg(
nullb(x.total_operating_hours))
1012 .arg(
nulli(x.temperature_1))
1013 .arg(
nulli(x.temperature_2))
1014 .arg(
nulli(x.irradiance))
1016 q.exec(QString(
"select last_insert_rowid();"));
1019 return q.value(0).toInt();
1039 QMutexLocker locker(&
m_mutex);
1041 q.exec(QString(
"select line from interfaceboxes where interfacebox=%1;").arg(x.interfacebox));
1044 q.exec(QString(
"update interfaceboxes set "
1045 "description = %1, "
1047 "where interfacebox = %3; ")
1048 .arg(
nulls(x.description))
1050 .arg(
nulli(x.interfacebox))
1053 q.exec(QString(
"insert into interfaceboxes ("
1054 "description, line) values ("
1056 .arg(
nulls(x.description))
1059 q.exec(QString(
"select last_insert_rowid();"));
1062 return q.value(0).toInt();
1064 return x.interfacebox;
1078 QMutexLocker locker(&
m_mutex);
1080 q.exec(QString(
"select longitude, latitude from geocoordinates;"));
1083 q.exec(QString(
"update geocoordinates set "
1086 .arg(
nullf(x.longitude))
1087 .arg(
nullf(x.latitude))
1090 q.exec(QString(
"insert into geocoordinates ("
1091 "longitude, latitude) values ("
1093 .arg(
nullf(x.longitude))
1094 .arg(
nullf(x.latitude))
1110 QMutexLocker locker(&
m_mutex);
1112 q.exec(QString(
"begin;"));
1113 q.exec(QString(
"delete from invertors where line=%1;").arg(line));
1114 q.exec(QString(
"delete from lines where line=%1;").arg(line));
1115 q.exec(QString(
"commit;"));
1130 QMutexLocker locker(&
m_mutex);
1132 q.exec(QString(
"delete from invertors where invertor=%1;").arg(invertor));
1146 QMutexLocker locker(&
m_mutex);
1148 q.exec(QString(
"delete from interfaceboxes where interfacebox=%1;").arg(interfacebox));
1159 QMutexLocker locker(&
m_mutex);
1160 qWarning() <<
"DATABASE::execMaintenance();";
1162 q.exec(QString(
"select days from maintenance;"));
1163 if (!q.next())
return;
1165 date = QDateTime::currentDateTime();
1166 date = date.addDays(-q.value(0).toInt());
1167 q.exec(QString(
"delete from data where date < '%1';")
1168 .arg(date.toString(
"yyyy-MM-dd hh:mm:ss"))
1170 q.exec(QString(
"vacuum full;"));
1187 QMutexLocker locker(&
m_mutex);
1189 QDateTime date = QDateTime::currentDateTime().addSecs(-600);
1190 QList<DBT_LINES_STATUS> list;
1191 QString dotaz = QString(
"select n.line, w.working, n.number "
1192 " from (select line, count(0) as number "
1193 " from invertors group by line) n "
1194 " left join (select line, coalesce(sum(jedna),0) as working "
1195 " from (select i.line, 1 as jedna "
1196 " from data d, invertors i "
1197 " where d.invertor=i.invertor "
1199 " and error is null "
1200 " group by i.line, i.invertor "
1201 " having count(1) > 0) "
1202 " group by line) w using(line);")
1203 .arg(date.toString(
"yyyy-MM-dd hh:mm:ss")
1210 p.line = q.value(i++).toInt();
1211 p.working = q.value(i++).toInt();
1212 p.invertors = q.value(i++).toInt();
1223 QMutexLocker locker(&
m_mutex);
1225 QList<DBT_MAINTENANCE> list;
1226 q.exec(QString(
"select days from maintenance;"));
1230 p.days = q.value(i++).toInt();
1247 QMutexLocker locker(&
m_mutex);
1249 q.exec(QString(
"update maintenance set days=%1;")
1266 return QString(
"'%1'").arg(x.toString(
"yyyy-MM-dd hh:mm:ss"));
1280 int val = x.toInt();
1284 return QString(
"%1").arg(val);
1298 double val = x.toInt();
1302 return QString(
"%1").arg(val).replace(
",",
".");
1317 return QString(
"'%1'").arg(xx.replace(
'\'',
"''"));
1328 return QString(
"%1").arg((x)?1:0);
QList< DBT_USERS > users(const QString &user=QString())
Returs list of users or selected user.
QList< DBT_INTERFACEBOXES > interfaceboxes(int line=0)
Returns list of interfaceboxes filtered by line number.
QString changePassword(QSqlDatabase &, DBT_USERS)
Updates user's info (actually only password is changed)
Class describing database table GEOCOORDINATES.
QString nullb(bool x)
Formats bool for database store.
Class describing database table MAINTENANCE.
QList< DBT_LINES > lines(int line=0)
Returns list of communications lines.
Extends class QSqlQuery - adds a diagnostics and logging.
int saveInvertor(QSqlDatabase &, DBT_INVERTORS)
Insert or update INVERTOR.
void commit()
Commit transactions.
QString nulls(const QString &x)
Formats QString for database store.
Class describing database table DATA.
QList< DBT_DATA_VW > data(const QDateTime &from=QDateTime(), const QDateTime &to=QDateTime(), bool limit=true)
Returns data for all invertors.
QList< DBT_INVERTORS > invertors(int line=0)
Returns list of invertors filtered by line number.
void execMaintenance()
Database maintenance.
QString nulli(const QVariant &x)
Formats QVariant - integer for database store.
int saveInterfacebox(QSqlDatabase &, DBT_INTERFACEBOXES)
Insert or update Interfacebox.
void deleteLine(QSqlDatabase &, int)
Delete line in database.
void databaseChanged()
Signals when information about lines or invertors changed.
void saveUser(QSqlDatabase &, DBT_USERS)
Updates user's info.
void create(QSqlDatabase &db)
Creates new database structure in opened file.
QList< DBT_MAINTENANCE > maintenance()
Returns list of DBT_MAINTENANCE.
void deleteInterfacebox(QSqlDatabase &, int)
Delete interfacebox in database.
Class describing lines status.
QString nullf(const QVariant &x)
Formats QVariant - double for database store.
Class describing database table USERS.
void insertData(DBT_DATA)
Writes data to database table DATA.
Class describing database table DATA + INVERTORS.
int saveLine(QSqlDatabase &, DBT_LINES)
Insert or update LINE.
QMutex m_mutex
Mutex for locking between threads.
void deleteInvertor(QSqlDatabase &, int)
Delete invertor in database.
DBT_GEOCOORDINATES geocoordinates()
Returns geocoordinates.
void saveMaintenance(QSqlDatabase &, DBT_MAINTENANCE)
Updates maintenace record in database.
void setGeocoordinates(QSqlDatabase &, DBT_GEOCOORDINATES)
update geocoordinates
QList< DBT_LINES_STATUS > linesStatus()
Returns status of lines.
Class describing database table LINES.
QString nulld(const QDateTime &x)
Formats QDateTime for database store.
Class describing database table INVERTORS.
QSqlDatabase open(const QString &dbname)
Opens or creates new database file.