Fotobot
Get data from your photovoltaic plant
Public Slots | Signals | Public Member Functions | Private Member Functions | Private Attributes | List of all members
DATABASE Class Reference

Class for communication with database. More...

#include <database.h>

Inheritance diagram for DATABASE:

Public Slots

void insertData (DBT_DATA)
 Writes data to database table DATA. More...
 
void execMaintenance ()
 Database maintenance. More...
 
void deleteLine (QSqlDatabase &, int)
 Delete line in database.
 
void deleteLine (int)
 
void deleteInvertor (QSqlDatabase &, int)
 Delete invertor in database.
 
void deleteInvertor (int)
 
void deleteInterfacebox (QSqlDatabase &, int)
 Delete interfacebox in database.
 
void deleteInterfacebox (int)
 
void deleteUser (QSqlDatabase &, QString userid)
 
void deleteUser (QString userid)
 
QString changePassword (QSqlDatabase &, DBT_USERS)
 Updates user's info (actually only password is changed) More...
 
QString changePassword (DBT_USERS)
 
void saveUser (QSqlDatabase &, DBT_USERS)
 Updates user's info.
 
void saveUser (DBT_USERS)
 
int saveLine (QSqlDatabase &, DBT_LINES)
 Insert or update LINE. More...
 
int saveLine (DBT_LINES)
 
int saveInvertor (QSqlDatabase &, DBT_INVERTORS)
 Insert or update INVERTOR. More...
 
int saveInvertor (DBT_INVERTORS)
 
int saveInterfacebox (QSqlDatabase &, DBT_INTERFACEBOXES)
 Insert or update Interfacebox. More...
 
int saveInterfacebox (DBT_INTERFACEBOXES)
 
void saveMaintenance (QSqlDatabase &, DBT_MAINTENANCE)
 Updates maintenace record in database.
 
void saveMaintenance (DBT_MAINTENANCE)
 
void setGeocoordinates (QSqlDatabase &, DBT_GEOCOORDINATES)
 update geocoordinates
 
void setGeocoordinates (DBT_GEOCOORDINATES)
 
void commit ()
 Commit transactions. More...
 

Signals

void databaseChanged ()
 Signals when information about lines or invertors changed. More...
 

Public Member Functions

 DATABASE (QSettings *settings, QObject *parent=NULL)
 
QList< DBT_LINESlines (int line=0)
 Returns list of communications lines. More...
 
QList< DBT_INVERTORSinvertors (int line=0)
 Returns list of invertors filtered by line number.
 
QList< DBT_INVERTORSinvertors (const QList< int > &invertors)
 Returns list of invertors filtered by invertors numbers. More...
 
QList< DBT_INTERFACEBOXESinterfaceboxes (int line=0)
 Returns list of interfaceboxes filtered by line number.
 
QList< DBT_INTERFACEBOXESinterfaceboxes (const QList< int > &interfaceboxes)
 Returns list of interfaceboxes filtered by interfaceboxes numbers. More...
 
DBT_GEOCOORDINATES geocoordinates ()
 Returns geocoordinates.
 
QList< DBT_DATA_VWdata (const QDateTime &from=QDateTime(), const QDateTime &to=QDateTime(), bool limit=true)
 Returns data for all invertors. More...
 
QList< DBT_USERSusers (const QString &user=QString())
 Returs list of users or selected user.
 
QList< DBT_MAINTENANCEmaintenance ()
 Returns list of DBT_MAINTENANCE.
 
QList< DBT_LINES_STATUSlinesStatus ()
 Returns status of lines. More...
 

Private Member Functions

void create (QSqlDatabase &db)
 Creates new database structure in opened file.
 
void upgrade (QSqlDatabase &db)
 
QSqlDatabase open (const QString &dbname)
 Opens or creates new database file.
 
QString nulld (const QDateTime &x)
 Formats QDateTime for database store. More...
 
QString nulli (const QVariant &x)
 Formats QVariant - integer for database store. More...
 
QString nullf (const QVariant &x)
 Formats QVariant - double for database store. More...
 
QString nulls (const QString &x)
 Formats QString for database store. More...
 
QString nullb (bool x)
 Formats bool for database store. More...
 

Private Attributes

bool m_in_transaction
 
QTimer * m_timerCommit
 
QSqlDatabase m_db
 
QSqlDatabase m_dbc
 
QMutex m_mutex
 Mutex for locking between threads.
 
QString m_synchronous
 

Detailed Description

Class for communication with database.

The only object that can read and write to the database files. Contains all access methods needed for data storing in the rest of application.

Database engine SQLite is single-thread only. When using in multi-thread application there must be only single thread accessing object DATABASE at the same time and only one object can exist in application.

All functions in the DATABASE object are locked using QMutex.

Reading from database:
You can freely read data from database since the mutex locks object and no other thread can access the database at the same time.

Writing to database:
You can freely write data to your database since the mutex locks object and no other thread can acces the database at the same time. All insert/update functions are implemented as slots so if your thread cannot wait for database, you can use queued SIGNAL/SLOT mechanism from different threads:

connect(writer, SIGNAL(data(DBT_DATA)),
db, SLOT(insertData(DBT_DATA)),
Qt::QueuedConnection);

Definition at line 47 of file database.h.

Member Function Documentation

QString DATABASE::changePassword ( QSqlDatabase &  db,
DBT_USERS  user 
)
slot

Updates user's info (actually only password is changed)

This method can only change existing record, no insert is possible.

Definition at line 308 of file database.cpp.

308  {
309  QMutexLocker locker(&m_mutex);
310  MSqlQuery q(db);
311  if (user.password.isEmpty() || user.password == "") {
312  return user.user;
313  }
314  QString passsha1 = QCryptographicHash::hash(user.password.toAscii(), QCryptographicHash::Sha1).toHex();
315  q.exec(QString("update users set password='%1' where user='%2'")
316  .arg(passsha1)
317  .arg(user.user)
318  );
319  return user.user;
320 }
Extends class QSqlQuery - adds a diagnostics and logging.
Definition: msqlquery.h:22
QMutex m_mutex
Mutex for locking between threads.
Definition: database.h:114
void DATABASE::commit ( )
slot

Commit transactions.

Since the database is as a default in "autocommit" state, when every standalone query is commited, then the database can be very slow when more lines are connected. For this reason are all inserts grouped in 5 secs block and the commit is requested every 5 secons by the m_timerCommit timer.

Definition at line 101 of file database.cpp.

101  {
102  QMutexLocker locker(&m_mutex);
103  QSqlQuery q(m_db);
104  if (m_in_transaction) {
105  q.exec("commit;");
106  }
107  q.exec("begin;");
108  m_in_transaction = true;
109  m_timerCommit->start(); // restart timer
110 }
QMutex m_mutex
Mutex for locking between threads.
Definition: database.h:114
QList< DBT_DATA_VW > DATABASE::data ( const QDateTime &  from = QDateTime(),
const QDateTime &  to = QDateTime(),
bool  limit = true 
)

Returns data for all invertors.

Parameters
from- Date & Time from
to- Date & Time to
limit- Limit number of records

When no parameter was given then last known state of all invertors is returned. When just one parameter was given then all records from this time till last know state is returned. Parameter limit is used to limit the number of records. There is a problem to compress big ammount of data (fbhw is low memory device).

Returns
Returns list of DBT_DATA_VW structures. Values are stored in QVariant and null values in database should correspond to null values in QVariant variables in the returned structure.

Definition at line 611 of file database.cpp.

611  {
612  QMutexLocker locker(&m_mutex);
613  QList<DBT_DATA_VW> list;
614  MSqlQuery q(m_db);
615 
616  QString dotaz;
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, "
626  "l.sn_format "
627  "from data d, "
628  " (select invertor,max(date) as date from data group by invertor) x, "
629  " invertors i, "
630  " lines l "
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; ");
635  } else {
636  QDateTime lto = QDateTime::currentDateTime();
637  if (to.isValid() && !limit) {
638  lto = to;
639  }
640  if (to.isValid() && limit) {
641  lto = from.addSecs(10800);
642  if (lto > QDateTime::currentDateTime()) {
643  lto = QDateTime::currentDateTime();
644  }
645  if (lto > to) {
646  lto = to;
647  }
648  }
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, "
657  "l.sn_format "
658  "from data d, "
659  " invertors i, "
660  " lines l "
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"))
667  ;
668  }
669 
670  qDebug() << dotaz;
671 
672  q.exec(dotaz);
673  while (q.next()) {
674  DBT_DATA_VW x;
675  int i=0;
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);
705  } else {
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')))
718  ;
719  }
720  list.append(x);
721  }
722 
723  return list;
724 }
Extends class QSqlQuery - adds a diagnostics and logging.
Definition: msqlquery.h:22
Class describing database table DATA + INVERTORS.
QMutex m_mutex
Mutex for locking between threads.
Definition: database.h:114
void DATABASE::databaseChanged ( )
signal

Signals when information about lines or invertors changed.

This signal is be connected to INVERTORS object where list of lines and invertors is stored. When the signal is received then all invertors should be re-read from database and recreated.

void DATABASE::execMaintenance ( )
slot

Database maintenance.

Deletes old records from "data" database table The age for deleting is taken from database table "maintenance".

Definition at line 1158 of file database.cpp.

1158  {
1159  QMutexLocker locker(&m_mutex);
1160  qWarning() << "DATABASE::execMaintenance();";
1161  MSqlQuery q(m_db);
1162  q.exec(QString("select days from maintenance;"));
1163  if (!q.next()) return;
1164  QDateTime date;
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"))
1169  );
1170  q.exec(QString("vacuum full;"));
1171 }
Extends class QSqlQuery - adds a diagnostics and logging.
Definition: msqlquery.h:22
QMutex m_mutex
Mutex for locking between threads.
Definition: database.h:114
void DATABASE::insertData ( DBT_DATA  x)
slot

Writes data to database table DATA.

This slot should be connected to signal INVERTOR::data(DBT_DATA); Data are passed by value let the queueing is possible - this is because data source and DATABASE object run in different thread.

Definition at line 734 of file database.cpp.

734  {
735  QMutexLocker locker(&m_mutex);
736  if (x.invertor <= 0) return;
737  MSqlQuery q(m_db);
738 
739  q.exec(QString("select 1 from data where invertor=%1 and date=%2;")
740  .arg(x.invertor)
741  .arg(nulld(x.date))
742  );
743  if (q.next()) return;
744 
745  if (x.error.isEmpty()) {
746  q.exec(QString("insert into data ( "
747  "invertor, " // 1
748  "date, " // 2
749  "error, " // 3
750  "now_power, " // 4
751  "now_ac_current, " // 5
752  "now_ac_voltage, " // 6
753  "now_ac_frequency, " // 7
754  "now_dc_current, " // 8
755  "now_dc_voltage, " // 9
756  "day_energy, " // 10
757  "day_power_maximum, " // 11
758  "day_ac_voltage_maximum, " // 12
759  "day_ac_voltage_minimum, " // 13
760  "day_dc_voltage_maximum, " // 14
761  "day_operating_hours, " // 15
762  "total_energy, " // 16
763  "total_power_maximum, " // 17
764  "total_ac_voltage_maximum, " // 18
765  "total_ac_voltage_minimum, " // 19
766  "total_dc_voltage_maximum, " // 20
767  "total_operating_hours, " // 21
768  "temperature_1, " // 22
769  "temperature_2, " // 23
770  "irradiance," // 24
771  "status" // 25
772  ") values ("
773  "%1," // invertor
774  "%2," // date
775  "%3," // error
776  "%4," // now_power
777  "%5," // now_ac_current
778  "%6," // now_ac_voltage
779  "%7," // now_ac_frequency
780  "%8," // now_dc_current
781  "%9," // nod_dc_voltage
782  "%10," // day_energy
783  "%11," // day_power_maximum
784  "%12," // day_ac_voltage_maximum
785  "%13," // day_ac_voltage_minimum
786  "%14," // day_dc_voltage_maximum
787  "%15," // day_operating_hours
788  "%16," // total_energy
789  "%17," // total_power_maximum
790  "%18," // total_ac_voltage_maximum
791  "%19," // total_ac_voltage_minimum
792  "%20," // total_dc_voltage_maximum
793  "%21," // total_operating_hours
794  "%22," // temperature_1
795  "%23," // temperature_2
796  "%24," // irradiance
797  "%25" // status
798  ")" )
799  .arg( x.invertor) // 1
800  .arg(nulld(x.date)) // 2
801  .arg( "null") // 3
802  .arg(nulli(x.now_power)) // 4
803  .arg(nullf(x.now_ac_current)) // 5
804  .arg(nulli(x.now_ac_voltage)) // 6
805  .arg(nullf(x.now_ac_frequency)) // 7
806  .arg(nullf(x.now_dc_current)) // 8
807  .arg(nulli(x.now_dc_voltage)) // 9
808  .arg(nulli(x.day_energy)) // 10
809  .arg(nulli(x.day_power_maximum)) // 11
810  .arg(nulli(x.day_ac_voltage_maximum)) // 12
811  .arg(nulli(x.day_ac_voltage_minimum)) // 13
812  .arg(nulli(x.day_dc_voltage_maximum)) // 14
813  .arg(nullf(x.day_operating_hours)) // 15
814  .arg(nulli(x.total_energy)) // 16
815  .arg(nulli(x.total_power_maximum)) // 17
816  .arg(nulli(x.total_ac_voltage_maximum)) // 18
817  .arg(nulli(x.total_ac_voltage_minimum)) // 19
818  .arg(nulli(x.total_dc_voltage_maximum)) // 20
819  .arg(nullf(x.total_operating_hours)) // 21
820  .arg(nullf(x.temperature_1)) // 22
821  .arg(nullf(x.temperature_2)) // 23
822  .arg(nullf(x.irradiance)) // 24
823  .arg(nulls(x.status)) // 25
824  );
825  } else {
826  // Error, write only error messsage
827  q.exec(QString("insert into data ("
828  "invertor,"
829  "date,"
830  "error"
831  ") values ("
832  "%1,"
833  "%2,"
834  "%3"
835  ")" )
836  .arg( x.invertor)
837  .arg(nulld(x.date))
838  .arg(nulls(x.error))
839  );
840  }
841 
842 }
Extends class QSqlQuery - adds a diagnostics and logging.
Definition: msqlquery.h:22
QString nulls(const QString &x)
Formats QString for database store.
Definition: database.cpp:1312
QString nulli(const QVariant &x)
Formats QVariant - integer for database store.
Definition: database.cpp:1276
QString nullf(const QVariant &x)
Formats QVariant - double for database store.
Definition: database.cpp:1294
QMutex m_mutex
Mutex for locking between threads.
Definition: database.h:114
QString nulld(const QDateTime &x)
Formats QDateTime for database store.
Definition: database.cpp:1262
QList< DBT_INTERFACEBOXES > DATABASE::interfaceboxes ( const QList< int > &  interfaceboxes)

Returns list of interfaceboxes filtered by interfaceboxes numbers.

Parameters
interfaceboxes- list of interfaceboxes to select

Using:

db->interfaceboxes( QList<int>() << 1 << 2 << 3 );

Definition at line 554 of file database.cpp.

554  {
555  QMutexLocker locker(&m_mutex);
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));
560  }
561  MSqlQuery q(m_db);
562  q.exec(QString("select interfacebox, line, description "
563  " from interfaceboxes where %1 order by interfacebox; ")
564  .arg(cond)
565  );
566  while (q.next()) {
568  int i=0;
569  x.interfacebox = q.value(i++).toInt();
570  x.line = q.value(i++).toInt();
571  x.description = q.value(i++).toString();
572  list.append(x);
573  }
574  return list;
575 }
QList< DBT_INTERFACEBOXES > interfaceboxes(int line=0)
Returns list of interfaceboxes filtered by line number.
Definition: database.cpp:524
Extends class QSqlQuery - adds a diagnostics and logging.
Definition: msqlquery.h:22
QMutex m_mutex
Mutex for locking between threads.
Definition: database.h:114
QList< DBT_INVERTORS > DATABASE::invertors ( const QList< int > &  invertors)

Returns list of invertors filtered by invertors numbers.

Parameters
invertors- list of invertors to select

Using:

db->invertors( QList<int>() << 1 << 2 << 3 );

Definition at line 470 of file database.cpp.

470  {
471  QMutexLocker locker(&m_mutex);
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));
476  }
477  MSqlQuery q(m_db);
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; ")
486  .arg(cond)
487  );
488  while (q.next()) {
489  DBT_INVERTORS x;
490  int i=0;
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();
516  list.append(x);
517  }
518  return list;
519 }
Extends class QSqlQuery - adds a diagnostics and logging.
Definition: msqlquery.h:22
QList< DBT_INVERTORS > invertors(int line=0)
Returns list of invertors filtered by line number.
Definition: database.cpp:411
QMutex m_mutex
Mutex for locking between threads.
Definition: database.h:114
Class describing database table INVERTORS.
QList< DBT_LINES > DATABASE::lines ( int  line = 0)

Returns list of communications lines.

Parameters
line- number of requested line or 0 for all lines in database
Returns
Called without parameters or with line==0 returns list of all lines and called with line>0 returns empty list (requested line was not found in database) or list with exactly one record (requested line was found).

Definition at line 380 of file database.cpp.

380  {
381  QMutexLocker locker(&m_mutex);
382  QList<DBT_LINES> x;
383  MSqlQuery q(m_db);
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));
386  while (q.next()) {
387  DBT_LINES p;
388  int i=0;
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();
403  x.append(p);
404  }
405  return x;
406 }
Extends class QSqlQuery - adds a diagnostics and logging.
Definition: msqlquery.h:22
QMutex m_mutex
Mutex for locking between threads.
Definition: database.h:114
Class describing database table LINES.
QList< DBT_LINES_STATUS > DATABASE::linesStatus ( )

Returns status of lines.

Status consists from two basic information:

  • number of invertors connected to the line
  • number of working invertors.

Working invertor is invertor which int last 10 minutes has at least one record in database without error.

Status is returned as a list of DBT_LINES_STATUS structures.

Definition at line 1186 of file database.cpp.

1186  {
1187  QMutexLocker locker(&m_mutex);
1188  MSqlQuery q(m_db);
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 "
1198  " and date>'%1' "
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")
1204  );
1205  q.exec(dotaz);
1206 // qDebug() << dotaz.replace(QRegExp("\\s+"), QString(" "));
1207  while (q.next()) {
1208  DBT_LINES_STATUS p;
1209  int i=0;
1210  p.line = q.value(i++).toInt();
1211  p.working = q.value(i++).toInt();
1212  p.invertors = q.value(i++).toInt();
1213  list.append(p);
1214  }
1215  return list;
1216 }
Extends class QSqlQuery - adds a diagnostics and logging.
Definition: msqlquery.h:22
Class describing lines status.
QMutex m_mutex
Mutex for locking between threads.
Definition: database.h:114
QString DATABASE::nullb ( bool  x)
private

Formats bool for database store.

Returns string "null" when string is not valid else returns string include apostrophs.

Definition at line 1327 of file database.cpp.

1327  {
1328  return QString("%1").arg((x)?1:0);
1329 }
QString DATABASE::nulld ( const QDateTime &  x)
private

Formats QDateTime for database store.

Returns string "null" when date is not valid. Returns datetime formated in: 'yyyy-MM-dd hh:mm:ss' include apostrophs.

Definition at line 1262 of file database.cpp.

1262  {
1263  if (!x.isValid()) {
1264  return "null";
1265  }
1266  return QString("'%1'").arg(x.toString("yyyy-MM-dd hh:mm:ss"));
1267 }
QString DATABASE::nullf ( const QVariant &  x)
private

Formats QVariant - double for database store.

Returns string "null" when QVariant is not valid else returns double as a string.

Definition at line 1294 of file database.cpp.

1294  {
1295  if (!x.isValid()) {
1296  return "null";
1297  }
1298  double val = x.toInt();
1299  if (isnan(val)) {
1300  return "null";
1301  }
1302  return QString("%1").arg(val).replace(",",".");
1303 }
QString DATABASE::nulli ( const QVariant &  x)
private

Formats QVariant - integer for database store.

Returns string "null" when QVariant is not valid else returns integer as a string.

Definition at line 1276 of file database.cpp.

1276  {
1277  if (!x.isValid()) {
1278  return "null";
1279  }
1280  int val = x.toInt();
1281  if (isnan(val)) {
1282  return "null";
1283  }
1284  return QString("%1").arg(val);
1285 }
QString DATABASE::nulls ( const QString &  x)
private

Formats QString for database store.

Returns string "null" when string is not valid else returns string include apostrophs.

Definition at line 1312 of file database.cpp.

1312  {
1313  if (x.isEmpty()) {
1314  return "null";
1315  }
1316  QString xx = x;
1317  return QString("'%1'").arg(xx.replace('\'',"''"));
1318 }
int DATABASE::saveInterfacebox ( QSqlDatabase &  db,
DBT_INTERFACEBOXES  x 
)
slot

Insert or update Interfacebox.

Returns
Number of interfaceboxes in database (primary key)

Definition at line 1038 of file database.cpp.

1038  {
1039  QMutexLocker locker(&m_mutex);
1040  MSqlQuery q(db);
1041  q.exec(QString("select line from interfaceboxes where interfacebox=%1;").arg(x.interfacebox));
1042  if (q.next()) {
1043  // record exists
1044  q.exec(QString("update interfaceboxes set "
1045  "description = %1, "
1046  "line = %2 "
1047  "where interfacebox = %3; ")
1048  .arg(nulls(x.description))
1049  .arg(nulli(x.line))
1050  .arg(nulli(x.interfacebox))
1051  );
1052  } else {
1053  q.exec(QString("insert into interfaceboxes ("
1054  "description, line) values ("
1055  "%1, %2);")
1056  .arg(nulls(x.description))
1057  .arg(nulli(x.line))
1058  );
1059  q.exec(QString("select last_insert_rowid();"));
1060  q.next();
1061  emit databaseChanged();
1062  return q.value(0).toInt();
1063  }
1064  return x.interfacebox;
1065 }
Extends class QSqlQuery - adds a diagnostics and logging.
Definition: msqlquery.h:22
QString nulls(const QString &x)
Formats QString for database store.
Definition: database.cpp:1312
QString nulli(const QVariant &x)
Formats QVariant - integer for database store.
Definition: database.cpp:1276
void databaseChanged()
Signals when information about lines or invertors changed.
QMutex m_mutex
Mutex for locking between threads.
Definition: database.h:114
int DATABASE::saveInvertor ( QSqlDatabase &  db,
DBT_INVERTORS  x 
)
slot

Insert or update INVERTOR.

Returns
Number of invertor in database (primary key)

Definition at line 922 of file database.cpp.

922  {
923  QMutexLocker locker(&m_mutex);
924  MSqlQuery q(db);
925  q.exec(QString("select line from invertors where invertor=%1;").arg(x.invertor));
926  if (q.next()) {
927  // record exists
928  q.exec(QString("update invertors set "
929  "description = %1, "
930  "line = %2, "
931  "address = %3, "
932  "now_power = %4, "
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, "
938  "day_energy = %10, "
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, "
952  "irradiance = %24 "
953  "where invertor = %25; ")
954  .arg(nulls(x.description))
955  .arg(nulli(x.line))
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))
979 
980  );
981  } else {
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))
992  .arg(nulli(x.line))
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))
1015  );
1016  q.exec(QString("select last_insert_rowid();"));
1017  q.next();
1018  emit databaseChanged();
1019  return q.value(0).toInt();
1020  }
1021  return x.invertor;
1022 }
QString nullb(bool x)
Formats bool for database store.
Definition: database.cpp:1327
Extends class QSqlQuery - adds a diagnostics and logging.
Definition: msqlquery.h:22
QString nulls(const QString &x)
Formats QString for database store.
Definition: database.cpp:1312
QString nulli(const QVariant &x)
Formats QVariant - integer for database store.
Definition: database.cpp:1276
void databaseChanged()
Signals when information about lines or invertors changed.
QMutex m_mutex
Mutex for locking between threads.
Definition: database.h:114
int DATABASE::saveLine ( QSqlDatabase &  db,
DBT_LINES  x 
)
slot

Insert or update LINE.

Returns
Number of line in database (primary key)

Definition at line 857 of file database.cpp.

857  {
858  QMutexLocker locker(&m_mutex);
859  MSqlQuery q(db);
860  q.exec(QString("select line from lines where line=%1;").arg(x.line));
861  if (q.next()) {
862  // record exists
863  q.exec(QString("update lines set "
864  " device='%1', "
865  " description='%2', "
866  " speed=%3, "
867  " retries=%4, "
868  " timeout=%5, "
869  " sn_format='%6', "
870  " type = %7, "
871  " hostname = '%8', "
872  " portnumber = %9 "
873  " where line=%10;")
874  .arg(x.device)
875  .arg(x.description)
876  .arg(x.speed)
877  .arg(x.retries)
878  .arg(x.timeout)
879  .arg(x.sn_format)
880  .arg(x.type)
881  .arg(x.hostname)
882  .arg(x.portnumber)
883  .arg(x.line)
884  );
885  } else {
886  q.exec(QString("insert into lines "
887  "(device, description, speed, retries, timeout, sn_format, type, hostname, portnumber) "
888  "values "
889  "('%1', '%2', %3, %4, %5, '%6', %7, '%8', %9);")
890  .arg(x.device)
891  .arg(x.description)
892  .arg(x.speed)
893  .arg(x.retries)
894  .arg(x.timeout)
895  .arg(x.sn_format)
896  .arg(x.type)
897  .arg(x.hostname)
898  .arg(x.portnumber)
899  );
900  q.exec(QString("select last_insert_rowid();"));
901  q.next();
902  emit databaseChanged();
903  return q.value(0).toInt();
904  }
905  return x.line;
906 }
Extends class QSqlQuery - adds a diagnostics and logging.
Definition: msqlquery.h:22
void databaseChanged()
Signals when information about lines or invertors changed.
QMutex m_mutex
Mutex for locking between threads.
Definition: database.h:114

The documentation for this class was generated from the following files: