293 lines
8.8 KiB
C++
293 lines
8.8 KiB
C++
#include "MainWindow.h"
|
|
#include "ui_MainWindow.h"
|
|
|
|
#include "rt8016AdcDgr.h"
|
|
|
|
#include <core/MeasurementSetup.h>
|
|
#include <core/CanTrace.h>
|
|
#include <core/Log.h>
|
|
|
|
#include <driver/CanInterface.h>
|
|
#include <driver/SLCANDriver/SLCANDriver.h>
|
|
#include <driver/CANBlastDriver/CANBlasterDriver.h>
|
|
|
|
#if defined(__linux__)
|
|
#include <driver/SocketCanDriver/SocketCanDriver.h>
|
|
#else
|
|
#include <driver/CandleApiDriver/CandleApiDriver.h>
|
|
#endif
|
|
|
|
#include <window/SetupDialog/SetupDialog.h>
|
|
|
|
#include <QTimer>
|
|
#include <QDebug>
|
|
|
|
MainWindow::MainWindow(QWidget* parent)
|
|
: QMainWindow(parent)
|
|
, ui(new Ui::MainWindow)
|
|
, dateTimeTimer_(new QTimer(this))
|
|
, canStatusTimer_(new QTimer(this))
|
|
, lastPackageDateTime_(QDateTime::fromMSecsSinceEpoch(0))
|
|
{
|
|
ui->setupUi(this);
|
|
|
|
setupDrivers();
|
|
setupTables();
|
|
|
|
auto& backend = Backend::instance();
|
|
connect(backend.getTrace(), &CanTrace::messageEnqueued, this, &MainWindow::handlePackage);
|
|
|
|
dateTimeTimer_->start(1000);
|
|
connect(dateTimeTimer_, &QTimer::timeout, this, &MainWindow::updateDateTime);
|
|
|
|
canStatusTimer_->start(1000);
|
|
connect(canStatusTimer_, &QTimer::timeout, this, &MainWindow::updateCanStatus);
|
|
|
|
updateDateTime();
|
|
connectCan();
|
|
}
|
|
|
|
MainWindow::~MainWindow()
|
|
{
|
|
disconnectCan();
|
|
delete ui;
|
|
}
|
|
|
|
void MainWindow::connectCan()
|
|
{
|
|
auto& backend = Backend::instance();
|
|
|
|
backend.clearTrace();
|
|
backend.startMeasurement();
|
|
|
|
QTimer::singleShot(100, this, [this]{ updateCanStatus(); });
|
|
|
|
// for (const auto interfaceId: backend.getInterfaceList())
|
|
// {
|
|
// log_info(backend.getInterfaceById(interfaceId)->getName());
|
|
// }
|
|
|
|
// MeasurementSetup new_setup(&backend);
|
|
// new_setup.cloneFrom(backend.getSetup());
|
|
|
|
// auto setupDlg = new SetupDialog(Backend::instance(), 0);
|
|
// if (setupDlg->showSetupDialog(new_setup)) {
|
|
// auto& backend = Backend::instance();
|
|
// for (const auto interfaceId: backend.getInterfaceList())
|
|
// {
|
|
// log_info(backend.getInterfaceById(interfaceId)->getName());
|
|
// }
|
|
|
|
// backend.setSetup(new_setup);
|
|
// backend.clearTrace();
|
|
// backend.startMeasurement();
|
|
// }
|
|
}
|
|
|
|
void MainWindow::disconnectCan()
|
|
{
|
|
Backend::instance().stopMeasurement();
|
|
}
|
|
|
|
void MainWindow::handlePackage(int index)
|
|
{
|
|
log_info("Received message: " + QString::number(index));
|
|
lastPackageDateTime_ = QDateTime::currentDateTime();
|
|
|
|
auto& backend = Backend::instance();
|
|
auto message = backend.getTrace()->getMessage(index);
|
|
if (!message)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (message->getId() != 0x60)
|
|
{
|
|
return;
|
|
}
|
|
|
|
quint16 frequency = ((message->getByte(1) << 8) + message->getByte(0)) & 0x7FFF;
|
|
quint8 sign = ((message->getByte(1) & 0x80) >> 7);
|
|
|
|
double frequencyValue = (sign ? -1 : 1) * frequency;
|
|
frequencyValue /= 128;
|
|
parameterModel_->setItem(1, 1, new QStandardItem(QString::number(frequencyValue, 'f', 2)));
|
|
|
|
quint16 inputVoltage = (message->getByte(2) << 2) + ((message->getByte(7) & 0x03) >> 0);
|
|
inputVoltage /= 1.137;
|
|
parameterModel_->setItem(0, 1, new QStandardItem(QString::number(inputVoltage)));
|
|
|
|
quint16 coolantTemperatureIndex = (message->getByte(4) << 2) + ((message->getByte(7) & 0x30) >> 4);
|
|
if (coolantTemperatureIndex > 1023)
|
|
{
|
|
coolantTemperatureIndex = 0;
|
|
}
|
|
|
|
qint16 coolantTemperature = FlashTdegr[coolantTemperatureIndex << 2] - 55;
|
|
parameterModel_->setItem(5, 1, new QStandardItem(QString::number(coolantTemperature)));
|
|
|
|
quint16 outputPhaseCurrent = (message->getByte(3) << 2) + ((message->getByte(7) & 0x0C) >> 2);
|
|
outputPhaseCurrent /= 3.1;
|
|
|
|
quint8 phaseNumber = ((message->getByte(7) & 0xC0) >> 6);
|
|
switch (phaseNumber)
|
|
{
|
|
case 0x00:
|
|
parameterModel_->setItem(2, 1, new QStandardItem(QString::number(outputPhaseCurrent)));
|
|
break;
|
|
case 0x01:
|
|
parameterModel_->setItem(3, 1, new QStandardItem(QString::number(outputPhaseCurrent)));
|
|
break;
|
|
case 0x02:
|
|
parameterModel_->setItem(4, 1, new QStandardItem(QString::number(outputPhaseCurrent)));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
auto status = message->getByte(5);
|
|
if (status != lastStatus_)
|
|
{
|
|
lastStatus_ = status;
|
|
statusModel_->appendRow({new QStandardItem(message->getDateTime().toString("dd.MM.yyyy hh:mm:ss")),
|
|
new QStandardItem(statusToString(status)),
|
|
new QStandardItem(statusToDescription(status))});
|
|
}
|
|
}
|
|
|
|
void MainWindow::updateDateTime()
|
|
{
|
|
const auto currentDateTime = QDateTime::currentDateTime();
|
|
ui->dateLabel->setText(currentDateTime.toString("dd.MM.yyyy"));
|
|
ui->timeLabel->setText(currentDateTime.toString("hh:mm:ss"));
|
|
}
|
|
|
|
void MainWindow::updateCanStatus()
|
|
{
|
|
// auto isConnected = false;
|
|
// auto& backend = Backend::instance();
|
|
// for (const auto interfaceId: backend.getInterfaceList())
|
|
// {
|
|
// isConnected |= backend.getInterfaceById(interfaceId)->isOpen();
|
|
// }
|
|
|
|
auto isConnected = lastPackageDateTime_.msecsTo(QDateTime::currentDateTime()) < 5000;
|
|
auto pallette = QPalette();
|
|
auto color = QColor(isConnected ? Qt::darkGreen : Qt::darkRed);
|
|
color.setAlphaF(0.7);
|
|
pallette.setColor(QPalette::Window, color);
|
|
|
|
ui->titleLabel->setAutoFillBackground(true);
|
|
ui->titleLabel->setPalette(pallette);
|
|
}
|
|
|
|
void MainWindow::setupDrivers()
|
|
{
|
|
auto& backend = Backend::instance();
|
|
|
|
#if defined(__linux__)
|
|
backend.addCanDriver(*(new SocketCanDriver(backend)));
|
|
#else
|
|
backend.addCanDriver(*(new CandleApiDriver(backend)));
|
|
#endif
|
|
// backend.addCanDriver(*(new SLCANDriver(backend)));
|
|
// backend.addCanDriver(*(new CANBlasterDriver(backend)));
|
|
|
|
backend.setDefaultSetup();
|
|
}
|
|
|
|
void MainWindow::setupTables()
|
|
{
|
|
parameterModel_ = new QStandardItemModel(6, 2, this);
|
|
statusModel_ = new QStandardItemModel(0, 3, this);
|
|
|
|
parameterModel_->setHorizontalHeaderLabels({tr("Parameter"), tr("Value")});
|
|
statusModel_->setHorizontalHeaderLabels({tr("Time"), tr("Module status"), tr("Module status description")});
|
|
|
|
parameterModel_->setItem(0, 0, new QStandardItem(tr("Input voltage, V")));
|
|
parameterModel_->setItem(1, 0, new QStandardItem(tr("Input voltage frequency, Hz")));
|
|
parameterModel_->setItem(2, 0, new QStandardItem(tr("Phase A input current, A")));
|
|
parameterModel_->setItem(3, 0, new QStandardItem(tr("Phase B input current, A")));
|
|
parameterModel_->setItem(4, 0, new QStandardItem(tr("Phase C input current, A")));
|
|
parameterModel_->setItem(5, 0, new QStandardItem(tr("Coolant temperature, °C")));
|
|
|
|
ui->parameterTableView->setModel(parameterModel_);
|
|
ui->statusTableView->setModel(statusModel_);
|
|
|
|
ui->parameterTableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
|
ui->statusTableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
|
|
|
ui->parameterTableView->horizontalHeader()->setStretchLastSection(true);
|
|
ui->statusTableView->horizontalHeader()->setStretchLastSection(true);
|
|
|
|
ui->parameterTableView->verticalHeader()->hide();
|
|
|
|
ui->parameterTableView->setColumnWidth(0, 280);
|
|
ui->statusTableView->setColumnWidth(0, 150);
|
|
}
|
|
|
|
QString MainWindow::statusToString(quint8 status)
|
|
{
|
|
return "0x" + QString::number(status, 16).rightJustified(2, '0');
|
|
}
|
|
|
|
QString MainWindow::statusToDescription(quint8 status)
|
|
{
|
|
QString description;
|
|
status &= 0x7F;
|
|
|
|
switch (status)
|
|
{
|
|
case 0x00:
|
|
description = tr("Supply voltage 110[V] to the control circuit");
|
|
break;
|
|
case 0x01:
|
|
description = tr("Pause after blocking");
|
|
break;
|
|
case 0x03:
|
|
description = tr("Waiting for the required DC link voltage level. 670[V]. Input voltage");
|
|
break;
|
|
case 0x04:
|
|
description = tr("Waiting for a CAN command to start work");
|
|
break;
|
|
case 0x07:
|
|
description = tr("Normal operation");
|
|
break;
|
|
case 0x08:
|
|
description = tr("Normal operation with output current limitation");
|
|
break;
|
|
case 0x10:
|
|
description = tr("DC link overvoltage. Input voltage");
|
|
break;
|
|
case 0x11:
|
|
description = tr("Fault half bridge 1");
|
|
break;
|
|
case 0x12:
|
|
description = tr("Fault half bridge 2");
|
|
break;
|
|
case 0x14:
|
|
description = tr("Fault half bridge 3");
|
|
break;
|
|
case 0x18:
|
|
description = tr("Cooler overheating");
|
|
break;
|
|
case 0x21:
|
|
description = tr("Instantaneous total current fault (270 A)");
|
|
break;
|
|
case 0x22:
|
|
description = tr("Large total current for 15 seconds (200 A)");
|
|
break;
|
|
case 0x27:
|
|
description = tr("Instant current fault in one of the phases (396 A)");
|
|
break;
|
|
case 0x25:
|
|
description = tr("No incoming messages via CAN");
|
|
break;
|
|
default:
|
|
description = tr("Unknown status");
|
|
break;
|
|
}
|
|
|
|
return description;
|
|
}
|