Développement cloud.

This commit is contained in:
2023-02-19 17:03:43 -05:00
parent 3ec5677dca
commit daa887d67b
33 changed files with 2122 additions and 100 deletions
@@ -90,6 +90,7 @@ void CCANAnalyzer::CANTimerExpired()
if(NewMessagesList.at(i)->mCANMsgID == mDeviceMessagesList->at(j)->mCANMsgID)
{
mDeviceMessagesList->at(j)->UpdateValue(NewMessagesList.at(i));
mDeviceMessagesList->at(j)->mPendingData = true;
}
}
}
@@ -100,6 +101,7 @@ void CCANAnalyzer::CANTimerExpired()
delete NewMessagesList.takeFirst();
}
mDevicePtr->NewMessageParsed();
+69 -1
View File
@@ -1,6 +1,74 @@
#include "CANDataLogger.h"
#include "defines.h"
CCANDataLogger::CCANDataLogger()
CCANDataLogger::CCANDataLogger():
mTopicDeviceString("")
{
}
int CCANDataLogger::LogNewData(const QList<CCANMessage *> *MsgList)
{
//MQTT
//For each message in the list, we create a CCANMessage
//First, clear the current list
mMQTTMsgList.clear();
qDebug("\n\n\n");
for(int i = 0; i < MsgList->size(); i++)
{
if(MsgList->at(i)->mPendingData == true)
{
CCANMessage *Msg = MsgList->at(i);
QString MsgPayload = "{";
QString MsgTopic = mTopicDeviceString;
MsgTopic.append(Msg->mCANMsgName);
MsgTopic.append("/");
//For each signal with new data, insert an entry in the JSon payload string
for(int signal = 0; signal < Msg->mSignalsList.size(); signal++)
{
QString SignalData;
CCANSignal *Signal = Msg->mSignalsList.at(signal);
if(Signal->mValueType == CCANSignal::CAN_SIGNAL_TYPE_UNSIGNED_INT)
{
SignalData = QString("\"%1\":%2").arg(Signal->mSignalName).arg((quint64)Signal->mPhysicalValue);
}
else if(Signal->mValueType == CCANSignal::CAN_SIGNAL_TYPE_SIGNED_INT)
{
SignalData = QString("\"%1\":%2").arg(Signal->mSignalName).arg((qint64)Signal->mPhysicalValue);
}
else if(Signal->mValueType == CCANSignal::CAN_SIGNAL_TYPE_32_BIT_FLOAT ||
Signal->mValueType == CCANSignal::CAN_SIGNAL_TYPE_64_BIT_DOUBLE)
{
SignalData = QString("\"%1\":%2").arg(Signal->mSignalName).arg(Signal->mPhysicalValue,0,'f',1);
}
MsgPayload.append(SignalData);
if(signal < Msg->mSignalsList.size()-1)
{
MsgPayload.append(",");
}
}
MsgPayload.append("}");
qDebug("%s",qPrintable(MsgPayload));
CMQTTMessage NewMessage(MsgTopic, MsgPayload);
mMQTTMsgList.append(NewMessage);
} //if(MsgList->at(i)->mPendingData == true)
}
return RET_OK;
}
int CCANDataLogger::SetMQTTTopicDevice(QString DeviceString)
{
mTopicDeviceString = DeviceString;
return RET_OK;
}
+16 -2
View File
@@ -1,11 +1,25 @@
#ifndef CANDATALOGGER_H
#define CANDATALOGGER_H
#include <QString>
#include "MQTTMessage.h"
#include <QList>
#include "CANMessage.h"
class CCANDataLogger
{
public:
CCANDataLogger();
int LogNewData(const QList<CCANMessage*> *MsgList);
//MQTT logging
QString mTopicDeviceString;
QList<CMQTTMessage> mMQTTMsgList;
int SetMQTTTopicDevice(QString DeviceString);
};
#endif // CANDATALOGGER_H
#endif // CANDATALOGGER_H
+9 -1
View File
@@ -72,6 +72,8 @@ int CCANDevice::Init()
return RET_GENERAL_ERROR;
}
mCANDataLogger.SetMQTTTopicDevice(QString("CANBus/%1/").arg(mDeviceConfigInfo.mDeviceName));
CGeneralMessagesLogDispatcher::instance()->AddLogMessage(QString("Dispositif [%1] initialisé avec succès!").arg(mDeviceConfigInfo.mDeviceName),true,CGeneralMessagesLogDispatcher::GEN_MSG_TXT_SUCCESS_STATUS);
return RET_OK;
}
@@ -92,7 +94,13 @@ int CCANDevice::Init(QString DatabaseFileName, TPCANHandle CANDeviceID, TPCANBau
int CCANDevice::NewMessageParsed()
{
return mProgramPtr->UpdateCANViewerDataRequest(&mMessageList);
mCANDataLogger.LogNewData(&mMessageList);
mProgramPtr->UpdateCANViewerDataRequest(&mMessageList);
for(int i = 0; i < mMessageList.size(); i++)
mMessageList.at(i)->mPendingData = false;
return RET_OK;
}
+3
View File
@@ -10,6 +10,7 @@
#include <QList>
#include "PCANBasic.h"
#include "CANDeviceConfig.h"
#include "CANDataLogger.h"
class COtarcikCan;
@@ -31,6 +32,7 @@ public:
bool mMessagesListLoaded;
CCANAnalyzer mCANAnalyzer; //The module that handles the USB puck and decodes the data
CCANDatabase mCANDatabase; //The device's database loaded from dbc file
CCANDataLogger mCANDataLogger;
QList<CCANMessage*> mMessageList;
@@ -41,6 +43,7 @@ public:
private:
bool mConfigSet;
signals:
public slots:
+4 -2
View File
@@ -1,12 +1,14 @@
#include "CANMessage.h"
#include "defines.h"
CCANMessage::CCANMessage()
CCANMessage::CCANMessage():
mPendingData(false)
{
mSignalsList.clear();
}
CCANMessage::CCANMessage(const CCANMessage &Src)
CCANMessage::CCANMessage(const CCANMessage &Src):
mPendingData(false)
{
*this = Src;
}
+1
View File
@@ -18,6 +18,7 @@ public:
unsigned int mCANMsgType; // Type of the message, using the PCAN interface driver encoding defined in PCANbasic.h
QByteArray mCANMsgData; // Raw data structure of the message, max size = 8 bytes
quint64 mCANRawDataMotorola, mCANRawDataIntel;
bool mPendingData;
//Database generated message structure
+5 -1
View File
@@ -2,7 +2,9 @@
#include "defines.h"
CCANSignal::CCANSignal()
CCANSignal::CCANSignal():
mRawValue(0),
mPhysicalValue(0.0)
{
mEncoding = CAN_SIGNAL_ENCODING_INVALID;
@@ -35,6 +37,8 @@ int CCANSignal::ComputeNewSignalValue(quint64 NewValue, quint16 MessageSize)
mPhysicalValue = ((signed) mRawValue * mValueFactor) + mValueOffset;
// mPhysicalValueUINT = ((quint64)((quint64) mRawValue * mValueFactor)) + (quint64)mValueOffset;
// mPhysicalValue = (qint64)((qint64) mRawValue * mValueFactor) + (qint64)mValueOffset;
return RET_OK;
+2
View File
@@ -58,6 +58,8 @@ public:
quint64 mRawValue;
double mPhysicalValue;
// quint64 mPhysicalValueUINT;
// qint64 mPhysicalValueINT;
};
@@ -297,14 +297,14 @@ int CCANDatabase::BuildMessageList(QList<CCANMessage *> *MsgListPtr)
NewSignal->mStartBit = startbit;
NewSignal->mSignalSize = length;
qDebug(" Signal: name='%s', unit='%s'\n", signal_name, signal_unit);
qDebug(" qname='%s'\n", signal_qname);
qDebug(" comment='%s'\n", signal_comment);
qDebug(" encoding='%s'\n", sigEncToStr(sigEnc));
qDebug(" representation='%s'\n", sigRepToStr(sigType));
qDebug(" value min=%.02f, value max=%.02f\n", minval, maxval);
qDebug(" scale faktor=%.02f, offset=%.02f\n", factor, offset);
qDebug(" startbit=%d, length=%d\n", startbit, length);
// qDebug(" Signal: name='%s', unit='%s'\n", signal_name, signal_unit);
// qDebug(" qname='%s'\n", signal_qname);
// qDebug(" comment='%s'\n", signal_comment);
// qDebug(" encoding='%s'\n", sigEncToStr(sigEnc));
// qDebug(" representation='%s'\n", sigRepToStr(sigType));
// qDebug(" value min=%.02f, value max=%.02f\n", minval, maxval);
// qDebug(" scale faktor=%.02f, offset=%.02f\n", factor, offset);
// qDebug(" startbit=%d, length=%d\n", startbit, length);
NewMsg->AddSignal(NewSignal);
status = kvaDbGetNextSignal (mh, &sh);
@@ -0,0 +1,43 @@
#include "CloudParams.h"
#include <QDataStream>
CCloudParams::CCloudParams()
{
}
QDataStream &operator>>(QDataStream &in, CCloudParams &dest)
{
in >> dest.mMQTTBrokerHostName
>> dest.mMQTTBrokerPassword
>> dest.mMQTTBrokerPort
>> dest.mMQTTBrokerUserName
>> dest.mMQTTTopicPrefix;
return in;
}
QDataStream &operator<<(QDataStream &out, const CCloudParams &source)
{
out << source.mMQTTBrokerHostName
<< source.mMQTTBrokerPassword
<< source.mMQTTBrokerPort
<< source.mMQTTBrokerUserName
<< source.mMQTTTopicPrefix;
return out;
}
CCloudParams& CCloudParams::operator=(const CCloudParams *source)
{
if(source == this)
{
return *this;
}
this->mMQTTBrokerHostName = source->mMQTTBrokerHostName;
this->mMQTTBrokerPassword = source->mMQTTBrokerPassword;
this->mMQTTBrokerPort = source->mMQTTBrokerPort;
this->mMQTTBrokerUserName = source->mMQTTBrokerUserName;
this->mMQTTTopicPrefix = source->mMQTTTopicPrefix;
return *this;
}
@@ -0,0 +1,22 @@
#ifndef CLOUDPARAMS_H
#define CLOUDPARAMS_H
#include <QString>
class CCloudParams
{
public:
CCloudParams();
QString mMQTTBrokerHostName;
QString mMQTTBrokerUserName;
QString mMQTTBrokerPassword;
QString mMQTTTopicPrefix;
quint32 mMQTTBrokerPort;
CCloudParams &operator=(const CCloudParams *source);
};
QDataStream &operator<<(QDataStream &out, const CCloudParams &source);
QDataStream &operator>>(QDataStream &in, CCloudParams &dest);
#endif // CLOUDPARAMS_H
@@ -0,0 +1,12 @@
#include "MQTTMessage.h"
CMQTTMessage::CMQTTMessage()
{
}
CMQTTMessage::CMQTTMessage(QString Topic, QString Payload)
{
mMessageTopic = Topic;
mMessagePayload = Payload;
}
@@ -0,0 +1,15 @@
#ifndef MQTTMESSAGE_H
#define MQTTMESSAGE_H
#include <QString>
class CMQTTMessage
{
public:
CMQTTMessage();
CMQTTMessage(QString Topic, QString Payload);
QString mMessageTopic;
QString mMessagePayload;
};
#endif // MQTTMESSAGE_H
+28 -2
View File
@@ -149,7 +149,21 @@ void CCANViewerPage::MessageSelectionChanged()
ui->mCANSignalTableWidget->setItem(signal,0,NewItem);
//Phys value
NewItem = new QTableWidgetItem(QString("%1").arg(Msg->mSignalsList.at(signal)->mPhysicalValue,0,'f',1));
if(Msg->mSignalsList.at(signal)->mValueType == CCANSignal::CAN_SIGNAL_TYPE_UNSIGNED_INT)
{
NewItem = new QTableWidgetItem(QString("%1").arg((quint64)Msg->mSignalsList.at(signal)->mPhysicalValue));
}
else if(Msg->mSignalsList.at(signal)->mValueType == CCANSignal::CAN_SIGNAL_TYPE_SIGNED_INT)
{
NewItem = new QTableWidgetItem(QString("%1").arg((qint64)Msg->mSignalsList.at(signal)->mPhysicalValue));
}
else if(Msg->mSignalsList.at(signal)->mValueType == CCANSignal::CAN_SIGNAL_TYPE_32_BIT_FLOAT ||
Msg->mSignalsList.at(signal)->mValueType == CCANSignal::CAN_SIGNAL_TYPE_64_BIT_DOUBLE)
{
NewItem = new QTableWidgetItem(QString("%1").arg(Msg->mSignalsList.at(signal)->mPhysicalValue,0,'f',1));
}
ui->mCANSignalTableWidget->setItem(signal,1,NewItem);
//Raw value
@@ -184,7 +198,19 @@ int CCANViewerPage::UpdateSignalsTable()
ui->mCANSignalTableWidget->item(row,0)->setText(Msg->mSignalsList.at(signal)->mSignalName);
//Phys value
ui->mCANSignalTableWidget->item(row,0)->setText(QString("%1").arg(Msg->mSignalsList.at(signal)->mPhysicalValue,0,'f',1));
if(Msg->mSignalsList.at(signal)->mValueType == CCANSignal::CAN_SIGNAL_TYPE_UNSIGNED_INT)
{
ui->mCANSignalTableWidget->item(row,0)->setText(QString("%1").arg((quint64)Msg->mSignalsList.at(signal)->mPhysicalValue));
}
else if(Msg->mSignalsList.at(signal)->mValueType == CCANSignal::CAN_SIGNAL_TYPE_SIGNED_INT)
{
ui->mCANSignalTableWidget->item(row,0)->setText(QString("%1").arg((qint64)Msg->mSignalsList.at(signal)->mPhysicalValue));
}
else if(Msg->mSignalsList.at(signal)->mValueType == CCANSignal::CAN_SIGNAL_TYPE_32_BIT_FLOAT ||
Msg->mSignalsList.at(signal)->mValueType == CCANSignal::CAN_SIGNAL_TYPE_64_BIT_DOUBLE)
{
ui->mCANSignalTableWidget->item(row,0)->setText(QString("%1").arg(Msg->mSignalsList.at(signal)->mPhysicalValue,0,'f',1));
}
//Raw value
ui->mCANSignalTableWidget->item(row,0)->setText(QString("0x%1").arg(Msg->mSignalsList.at(signal)->mRawValue,0,16));
@@ -1,14 +1,103 @@
#include "LoggingSettingsPage.h"
#include "ui_LoggingSettingsPage.h"
#include "defines.h"
#include "OtarcikCan.h"
CLoggingSettingsPage::CLoggingSettingsPage(QWidget *parent) :
QWidget(parent),
ui(new Ui::CLoggingSettingsPage)
ui(new Ui::CLoggingSettingsPage),
EditMode(false)
{
ui->setupUi(this);
ui->mCancelBtn->hide();
ui->mChangeParamsBtn->setText("Modifier");
ui->mCloudMQTTHostNameEdit->setEnabled(false);
ui->mCloudMQTTPasswordEdit->setEnabled(false);
ui->mCloudMQTTPortSpinBx->setEnabled(false);
ui->mCloudMQTTTopicPrefixEdit->setEnabled(false);
ui->mCloudMQTTUserNameEdit->setEnabled(false);
connect(ui->mCancelBtn,&QPushButton::clicked,this,&CLoggingSettingsPage::CancelBtnPressed);
connect(ui->mChangeParamsBtn,&QPushButton::clicked,this,&CLoggingSettingsPage::ModifyParamsBtnPressed);
}
CLoggingSettingsPage::~CLoggingSettingsPage()
{
delete ui;
}
int CLoggingSettingsPage::SetCloudParams(const CCloudParams *CloudParams)
{
if(CloudParams == 0)
{
return RET_GENERAL_ERROR;
}
mCloudParams = *CloudParams;
UpdateConfigPage();
return RET_OK;
}
void CLoggingSettingsPage::ModifyParamsBtnPressed()
{
if(EditMode == false)
{
EditMode = true;
ui->mCancelBtn->show();
ui->mCloudMQTTHostNameEdit->setEnabled(true);
ui->mCloudMQTTPasswordEdit->setEnabled(true);
ui->mCloudMQTTPortSpinBx->setEnabled(true);
ui->mCloudMQTTTopicPrefixEdit->setEnabled(true);
ui->mCloudMQTTUserNameEdit->setEnabled(true);
ui->mChangeParamsBtn->setText("Appliquer");
}
else
{
EditMode = false;
ui->mChangeParamsBtn->setText("Modifier");
ui->mCancelBtn->hide();
ui->mCloudMQTTHostNameEdit->setEnabled(false);
ui->mCloudMQTTPasswordEdit->setEnabled(false);
ui->mCloudMQTTPortSpinBx->setEnabled(false);
ui->mCloudMQTTTopicPrefixEdit->setEnabled(false);
ui->mCloudMQTTUserNameEdit->setEnabled(false);
mCloudParams.mMQTTBrokerHostName = ui->mCloudMQTTHostNameEdit->text();
mCloudParams.mMQTTBrokerPassword = ui->mCloudMQTTPasswordEdit->text();
mCloudParams.mMQTTBrokerPort = (quint32)ui->mCloudMQTTPortSpinBx->value();
mCloudParams.mMQTTTopicPrefix = ui->mCloudMQTTTopicPrefixEdit->text();
mCloudParams.mMQTTBrokerUserName = ui->mCloudMQTTUserNameEdit->text();
mProgramHandle->SaveCloudLoggingConfigRequest(&mCloudParams);
}
}
void CLoggingSettingsPage::CancelBtnPressed()
{
EditMode = false;
ui->mCancelBtn->hide();
ui->mCloudMQTTHostNameEdit->setEnabled(false);
ui->mCloudMQTTPasswordEdit->setEnabled(false);
ui->mCloudMQTTPortSpinBx->setEnabled(false);
ui->mCloudMQTTTopicPrefixEdit->setEnabled(false);
ui->mCloudMQTTUserNameEdit->setEnabled(false);
UpdateConfigPage();
}
int CLoggingSettingsPage::UpdateConfigPage()
{
ui->mCloudMQTTHostNameEdit->setText(mCloudParams.mMQTTBrokerHostName);
ui->mCloudMQTTPasswordEdit->setText(mCloudParams.mMQTTBrokerPassword);
ui->mCloudMQTTPortSpinBx->setValue(mCloudParams.mMQTTBrokerPort);
ui->mCloudMQTTTopicPrefixEdit->setText(mCloudParams.mMQTTTopicPrefix);
ui->mCloudMQTTUserNameEdit->setText(mCloudParams.mMQTTBrokerUserName);
return RET_OK;
}
@@ -2,6 +2,10 @@
#define LOGGINGSETTINGSPAGE_H
#include <QWidget>
#include "CloudParams.h"
class COtarcikCan;
namespace Ui {
class CLoggingSettingsPage;
@@ -15,8 +19,27 @@ public:
explicit CLoggingSettingsPage(QWidget *parent = 0);
~CLoggingSettingsPage();
int SetCloudParams(const CCloudParams *CloudParams);
COtarcikCan *mProgramHandle;
private:
int UpdateConfigPage();
Ui::CLoggingSettingsPage *ui;
bool EditMode;
CCloudParams mCloudParams;
public slots:
void ModifyParamsBtnPressed();
void CancelBtnPressed();
};
#endif // LOGGINGSETTINGSPAGE_H
+30 -4
View File
@@ -208,8 +208,8 @@
<widget class="QLabel" name="mGeneralLogParamsLbl">
<property name="geometry">
<rect>
<x>20</x>
<y>370</y>
<x>740</x>
<y>40</y>
<width>181</width>
<height>31</height>
</rect>
@@ -226,8 +226,8 @@
<widget class="QCheckBox" name="mSaveLocalLogFileChkBx">
<property name="geometry">
<rect>
<x>20</x>
<y>410</y>
<x>740</x>
<y>80</y>
<width>261</width>
<height>20</height>
</rect>
@@ -236,6 +236,32 @@
<string>Sauvegarder fichier log local</string>
</property>
</widget>
<widget class="QPushButton" name="mChangeParamsBtn">
<property name="geometry">
<rect>
<x>370</x>
<y>340</y>
<width>80</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>Modifier</string>
</property>
</widget>
<widget class="QPushButton" name="mCancelBtn">
<property name="geometry">
<rect>
<x>260</x>
<y>340</y>
<width>80</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>Annuler</string>
</property>
</widget>
</widget>
<resources/>
<connections/>
+30 -1
View File
@@ -39,6 +39,7 @@ int COtarcikCan::Start()
mMainWindow.mCANbusSettingsPage->mProgramPtr = this;
mMainWindow.mDataLoggingSettingsPage->mProgramHandle = this;
mMainWindow.show();
@@ -57,8 +58,11 @@ int COtarcikCan::Start()
PopulateCANDevicesList(CANDeviceConfigList);
}
mMainWindow.mCANbusSettingsPage->SetDevicesList(&mCANDevicesList);
mCloudLoggingParams = *mSystemConfig.GetCloudParams();
mMainWindow.mDataLoggingSettingsPage->SetCloudParams(&mCloudLoggingParams);
}
// CCANDevice *NewCANDevice = new CCANDevice();
// mCANDevicesList.append(NewCANDevice);
@@ -124,6 +128,7 @@ int COtarcikCan::SaveCANDevicesConfigRequest(QList<CCANDeviceConfig *> *DevicesC
return RET_OK;
}
int COtarcikCan::PopulateCANDevicesList(QList<CCANDeviceConfig *> *CANDeviceConfigList)
{
if(CANDeviceConfigList == 0)
@@ -146,3 +151,27 @@ int COtarcikCan::PopulateCANDevicesList(QList<CCANDeviceConfig *> *CANDeviceConf
return RET_OK;
}
int COtarcikCan::SaveCloudLoggingConfigRequest(CCloudParams *CloudParams)
{
if(CloudParams == 0)
{
return RET_GENERAL_ERROR;
}
mCloudLoggingParams = *CloudParams;
mSystemConfig.SetCloudParams(&mCloudLoggingParams);
if(mSystemConfig.SaveConfig() == RET_OK)
{
//TODO: Reset the MQTT driver with new parameters.
}
else
{
return RET_GENERAL_ERROR;
}
return RET_OK;
}
+2
View File
@@ -29,9 +29,11 @@ public:
int SaveCANDevicesConfigRequest(QList<CCANDeviceConfig*> *DevicesConfigList);
int SaveCloudLoggingConfigRequest(CCloudParams *CloudParams);
private:
QList<CCANDevice*> mCANDevicesList;
CCloudParams mCloudLoggingParams;
int PopulateCANDevicesList(QList<CCANDeviceConfig*> *DevicesConfigsList);
+27
View File
@@ -56,6 +56,7 @@ int CSystemConfig::LoadConfig()
*InputStream >> FileVersion;
//Load CAN devices configs
int NbDevices;
*InputStream >> NbDevices;
for(int i = 0; i < NbDevices; i++)
@@ -66,6 +67,12 @@ int CSystemConfig::LoadConfig()
mCANDeviceConfigList.append(NewDeviceConfig);
}
//Load Cloud logging settings
*InputStream >> mCloudLoggingParams;
//Load general program settings
*InputStream >> mSaveLocalLogFile;
ConfigFile->close();
delete ConfigFile;
@@ -111,6 +118,12 @@ int CSystemConfig::SaveConfig()
*OutputStream << *mCANDeviceConfigList.at(i); //Add each device info to config file
}
//Save the Cloud logging settings
*OutputStream << mCloudLoggingParams;
//Save the general system parameters
*OutputStream << mSaveLocalLogFile;
ConfigFile->flush();
ConfigFile->close();
@@ -147,3 +160,17 @@ int CSystemConfig::SetCANDevicesConfigList(QList<CCANDeviceConfig *> *DevicesCon
return RET_OK;
}
CCloudParams *CSystemConfig::GetCloudParams()
{
return &mCloudLoggingParams;
}
int CSystemConfig::SetCloudParams(CCloudParams *CloudParams)
{
if(CloudParams == 0)
return RET_GENERAL_ERROR;
mCloudLoggingParams = *CloudParams;
return RET_OK;
}
+5
View File
@@ -6,6 +6,7 @@
#include <QFile>
#include <QDataStream>
#include "CANDeviceConfig.h"
#include "CloudParams.h"
#define OTARCIK_CURRENT_CONFIG_FILE_VERSION 0x01
#define OTARCIK_CONFIG_FILE_MAGIC_NBR 0xDEADBEEF
@@ -24,12 +25,16 @@ public:
int SetCANDevicesConfigList(QList<CCANDeviceConfig*> *DevicesConfigList);
QList<CCANDeviceConfig*> *GetCANDevicesConfigList();
CCloudParams *GetCloudParams();
int SetCloudParams(CCloudParams *CloudParams);
//Can devices configs
QList<CCANDeviceConfig*> mCANDeviceConfigList;
//Cloud interface config
CCloudParams mCloudLoggingParams;
//Misc general system settings
bool mSaveLocalLogFile;