Now statuses have different colors. Various minor fixes
This commit is contained in:
@@ -2,13 +2,14 @@
|
|||||||
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
|
||||||
BatteryController::BatteryController(
|
BatteryController::BatteryController(QObject *parent)
|
||||||
QObject *parent)
|
|
||||||
: QObject{parent}
|
: QObject{parent}
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
BatteryController::~BatteryController()
|
BatteryController::~BatteryController()
|
||||||
{
|
{
|
||||||
@@ -182,105 +183,71 @@ void BatteryController::setStatuses(const QVariantList& statuses)
|
|||||||
emit statusesChanged();
|
emit statusesChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BatteryController::addStatus(const quint16 status)
|
void BatteryController::addStatus(const quint32 status)
|
||||||
{
|
{
|
||||||
// QString description;
|
QVariantList statusList;
|
||||||
// auto appendDescription = [&description](const QString& subStatus)
|
auto appendStatus = [&statusList](const QVariant& subStatus)
|
||||||
// {
|
|
||||||
// if (!description.isEmpty())
|
|
||||||
// {
|
|
||||||
// description += ", ";
|
|
||||||
// }
|
|
||||||
// description += subStatus;
|
|
||||||
// };
|
|
||||||
|
|
||||||
QStringList descriptionList;
|
|
||||||
auto appendDescription = [&descriptionList](const QString& subStatus)
|
|
||||||
{
|
{
|
||||||
descriptionList.append(subStatus);
|
statusList.append(subStatus);
|
||||||
};
|
};
|
||||||
|
|
||||||
std::bitset<16> descriptionBitset(status);
|
QMap<qsizetype, QVariantList> statusBitDescriptions =
|
||||||
if (descriptionBitset.test(0))
|
|
||||||
{
|
{
|
||||||
appendDescription("Ошибка Т датчика КП");
|
{0, {"Ошибка Т датчика КП", StatusSeverity::Error}},
|
||||||
|
{1, {"Глубокий разряд АКБ", StatusSeverity::Error}},
|
||||||
|
{2, {"Заряд выполнен", StatusSeverity::Info}},
|
||||||
|
{3, {"Ошибка Т датчика УКПБ", StatusSeverity::Info}},
|
||||||
|
|
||||||
|
{4, {"Ток долго не снижается", StatusSeverity::Error}},
|
||||||
|
{5, {"Ошибка БПС3000", StatusSeverity::Error}},
|
||||||
|
{6, {"U менее 61.25 В", StatusSeverity::Error}},
|
||||||
|
{7, {"U выше нормы по КП", StatusSeverity::Error}},
|
||||||
|
|
||||||
|
{8, {"Останов первого заряда", StatusSeverity::Info}},
|
||||||
|
{9, {"Останов разряда", StatusSeverity::Info}},
|
||||||
|
{10, {"Останов повторного заряда", StatusSeverity::Info}},
|
||||||
|
{11, {"Более 45 градусов", StatusSeverity::Warning}},
|
||||||
|
|
||||||
|
{12, {"Разночтение в токах", StatusSeverity::Error}},
|
||||||
|
{13, {"Разночтение в напряжениях", StatusSeverity::Error}},
|
||||||
|
{14, {"Разночтение в температурах", StatusSeverity::Error}},
|
||||||
|
{15, {"Разночтение в емкости АКБ", StatusSeverity::Info}},
|
||||||
|
|
||||||
|
{16, {"Низкий разряд АКБ", StatusSeverity::Info}},
|
||||||
|
{17, {"Ошибка контрольного заряда", StatusSeverity::Error}},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto it = statusBitDescriptions.constBegin(); it != statusBitDescriptions.constEnd(); ++it)
|
||||||
|
{
|
||||||
|
if (status & (1 << it.key()))
|
||||||
|
{
|
||||||
|
appendStatus(it.value());
|
||||||
}
|
}
|
||||||
if (descriptionBitset.test(1))
|
|
||||||
{
|
|
||||||
appendDescription("Низкий разряд АКБ");
|
|
||||||
}
|
|
||||||
if (descriptionBitset.test(2))
|
|
||||||
{
|
|
||||||
appendDescription("Заряд завершен");
|
|
||||||
}
|
|
||||||
if (descriptionBitset.test(3))
|
|
||||||
{
|
|
||||||
appendDescription("Ошибка Т датчика УКПБ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (descriptionBitset.test(4))
|
if (statusList.isEmpty())
|
||||||
{
|
{
|
||||||
appendDescription("Ток долго не снижается");
|
appendStatus(QVariantList{"Штатный режим", StatusSeverity::Info});
|
||||||
}
|
|
||||||
if (descriptionBitset.test(5))
|
|
||||||
{
|
|
||||||
appendDescription("Ошибка БПС3000");
|
|
||||||
}
|
|
||||||
if (descriptionBitset.test(6))
|
|
||||||
{
|
|
||||||
appendDescription("U менее 61.25 В");
|
|
||||||
}
|
|
||||||
if (descriptionBitset.test(7))
|
|
||||||
{
|
|
||||||
appendDescription("U выше нормы по КП");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (descriptionBitset.test(8))
|
|
||||||
{
|
|
||||||
appendDescription("Останов первого заряда");
|
|
||||||
}
|
|
||||||
if (descriptionBitset.test(9))
|
|
||||||
{
|
|
||||||
appendDescription("Останов разряда");
|
|
||||||
}
|
|
||||||
if (descriptionBitset.test(10))
|
|
||||||
{
|
|
||||||
appendDescription("Останов второго заряда");
|
|
||||||
}
|
|
||||||
if (descriptionBitset.test(11))
|
|
||||||
{
|
|
||||||
appendDescription("Более 45 гр. С");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (descriptionBitset.test(12))
|
|
||||||
{
|
|
||||||
appendDescription("Разночтение в токах");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (descriptionList.isEmpty())
|
|
||||||
{
|
|
||||||
appendDescription("Штатный режим");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
statuses_.clear();
|
statuses_.clear();
|
||||||
|
|
||||||
for (const auto& description: descriptionList)
|
for (const auto& statusVariant: statusList)
|
||||||
{
|
{
|
||||||
|
const auto statusDescription = statusVariant.toList();
|
||||||
|
if (statusDescription.size() < 2)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
QVariantMap statusMap;
|
QVariantMap statusMap;
|
||||||
statusMap.insert("time", QDateTime::currentDateTime().toString("hh:mm:ss dd-MM-yyyy"));
|
statusMap.insert("time", QDateTime::currentDateTime().toString("hh:mm:ss dd-MM-yyyy"));
|
||||||
statusMap.insert("status", "0x" + QString::number(status, 16).toUpper().rightJustified(2, '0'));
|
statusMap.insert("status", "0x" + QString::number(status, 16).toUpper().rightJustified(2, '0'));
|
||||||
statusMap.insert("description", description);
|
statusMap.insert("description", statusDescription.at(0));
|
||||||
|
statusMap.insert("severity", statusDescription.at(1));
|
||||||
|
|
||||||
statuses_.append(statusMap);
|
statuses_.append(statusMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
emit statusesChanged();
|
emit statusesChanged();
|
||||||
|
|
||||||
// if (statuses_.isEmpty() || statuses_.first().toMap()["status"] != statusMap["status"])
|
|
||||||
// {
|
|
||||||
// qDebug() << "Status:" << statusMap["status"].toString() << statusMap["description"].toString();
|
|
||||||
// statuses_.prepend(statusMap);
|
|
||||||
// emit statusesChanged();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,15 @@ class BatteryController : public QObject
|
|||||||
Q_PROPERTY(QVariantList statues READ statuses WRITE setStatuses NOTIFY statusesChanged)
|
Q_PROPERTY(QVariantList statues READ statuses WRITE setStatuses NOTIFY statusesChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum StatusSeverity
|
||||||
|
{
|
||||||
|
Info = 0,
|
||||||
|
Good = 1,
|
||||||
|
Warning = 2,
|
||||||
|
Error = 3
|
||||||
|
};
|
||||||
|
Q_ENUM(StatusSeverity)
|
||||||
|
|
||||||
explicit BatteryController(QObject *parent = nullptr);
|
explicit BatteryController(QObject *parent = nullptr);
|
||||||
~BatteryController();
|
~BatteryController();
|
||||||
|
|
||||||
@@ -64,7 +73,7 @@ public:
|
|||||||
|
|
||||||
QVariantList statuses() const;
|
QVariantList statuses() const;
|
||||||
void setStatuses(const QVariantList &statuses);
|
void setStatuses(const QVariantList &statuses);
|
||||||
void addStatus(const quint16 status);
|
void addStatus(const quint32 status);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void batteryIndexChanged();
|
void batteryIndexChanged();
|
||||||
|
|||||||
@@ -238,19 +238,19 @@ void CanController::handleControlParameters(const CanMessage* message, qsizetype
|
|||||||
|
|
||||||
quint16 capacity = 0;
|
quint16 capacity = 0;
|
||||||
stream >> capacity;
|
stream >> capacity;
|
||||||
batteries_.at(batteryIndex)->setControlCapacity(parameterToVariant(capacity));
|
batteries_.at(batteryIndex)->setControlCapacity(doubleParameterToVariant(capacity));
|
||||||
|
|
||||||
quint16 temperature = 0;
|
quint16 temperature = 0;
|
||||||
stream >> temperature;
|
stream >> temperature;
|
||||||
batteries_.at(batteryIndex)->setControlTemperature(parameterToVariant(temperature));
|
batteries_.at(batteryIndex)->setControlTemperature(intParameterToVariant(temperature));
|
||||||
|
|
||||||
quint16 current = 0;
|
qint16 current = 0;
|
||||||
stream >> current;
|
stream >> current;
|
||||||
batteries_.at(batteryIndex)->setControlCurrent(parameterToVariant(current));
|
batteries_.at(batteryIndex)->setControlCurrent(intParameterToVariant(current));
|
||||||
|
|
||||||
quint16 voltage = 0;
|
quint16 voltage = 0;
|
||||||
stream >> voltage;
|
stream >> voltage;
|
||||||
batteries_.at(batteryIndex)->setControlVoltage(parameterToVariant(voltage));
|
batteries_.at(batteryIndex)->setControlVoltage(doubleParameterToVariant(voltage));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanController::handleMeasuredParameters(const CanMessage* message, qsizetype batteryIndex)
|
void CanController::handleMeasuredParameters(const CanMessage* message, qsizetype batteryIndex)
|
||||||
@@ -260,19 +260,19 @@ void CanController::handleMeasuredParameters(const CanMessage* message, qsizetyp
|
|||||||
|
|
||||||
quint16 capacity = 0;
|
quint16 capacity = 0;
|
||||||
stream >> capacity;
|
stream >> capacity;
|
||||||
batteries_.at(batteryIndex)->setMeasuredCapacity(parameterToVariant(capacity));
|
batteries_.at(batteryIndex)->setMeasuredCapacity(doubleParameterToVariant(capacity));
|
||||||
|
|
||||||
quint16 temperature = 0;
|
quint16 temperature = 0;
|
||||||
stream >> temperature;
|
stream >> temperature;
|
||||||
batteries_.at(batteryIndex)->setMeasuredTemperature(parameterToVariant(temperature));
|
batteries_.at(batteryIndex)->setMeasuredTemperature(intParameterToVariant(temperature));
|
||||||
|
|
||||||
quint16 current = 0;
|
qint16 current = 0;
|
||||||
stream >> current;
|
stream >> current;
|
||||||
batteries_.at(batteryIndex)->setMeasuredCurrent(parameterToVariant(current));
|
batteries_.at(batteryIndex)->setMeasuredCurrent(intParameterToVariant(current));
|
||||||
|
|
||||||
quint16 voltage = 0;
|
quint16 voltage = 0;
|
||||||
stream >> voltage;
|
stream >> voltage;
|
||||||
batteries_.at(batteryIndex)->setMeasuredVoltage(parameterToVariant(voltage));
|
batteries_.at(batteryIndex)->setMeasuredVoltage(doubleParameterToVariant(voltage));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanController::handleStatusParameters(const CanMessage* message, qsizetype batteryIndex)
|
void CanController::handleStatusParameters(const CanMessage* message, qsizetype batteryIndex)
|
||||||
@@ -290,7 +290,7 @@ void CanController::handleStatusParameters(const CanMessage* message, qsizetype
|
|||||||
|
|
||||||
stream.skipRawData(1);
|
stream.skipRawData(1);
|
||||||
|
|
||||||
quint16 status = 0;
|
quint32 status = 0;
|
||||||
stream >> status;
|
stream >> status;
|
||||||
batteries_.at(batteryIndex)->addStatus(status);
|
batteries_.at(batteryIndex)->addStatus(status);
|
||||||
}
|
}
|
||||||
@@ -350,7 +350,3 @@ QList<quint16> CanController::registerAddresses() const
|
|||||||
return {0x200, 0x280, 0x300, 0x380, 0x400, 0x480, 0x500, 0x580};
|
return {0x200, 0x280, 0x300, 0x380, 0x400, 0x480, 0x500, 0x580};
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant CanController::parameterToVariant(quint16 parameter) const
|
|
||||||
{
|
|
||||||
return parameter == 0xFFFF ? QVariant() : QVariant::fromValue(parameter / 10.0);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#ifndef CANCONTROLLER_H
|
#ifndef CANCONTROLLER_H
|
||||||
#define CANCONTROLLER_H
|
#define CANCONTROLLER_H
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
@@ -57,7 +59,24 @@ private:
|
|||||||
void initializeBatteries();
|
void initializeBatteries();
|
||||||
|
|
||||||
QList<quint16> registerAddresses() const;
|
QList<quint16> registerAddresses() const;
|
||||||
QVariant parameterToVariant(quint16 parameter) const;
|
|
||||||
|
template<typename T>
|
||||||
|
static QVariant doubleParameterToVariant(T parameter)
|
||||||
|
{
|
||||||
|
return isParameterEmpty(parameter) ? QVariant() : QVariant::fromValue(parameter / 10.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static QVariant intParameterToVariant(T parameter)
|
||||||
|
{
|
||||||
|
return isParameterEmpty(parameter) ? QVariant() : QVariant::fromValue(parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static bool isParameterEmpty(T /*parameter*/)
|
||||||
|
{
|
||||||
|
return std::numeric_limits<T>::max();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isConnected_ = false;
|
bool isConnected_ = false;
|
||||||
|
|||||||
@@ -62,14 +62,14 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CustomControls.TextField {
|
CustomControls.TextField {
|
||||||
text: battery ? convertDoubleToString(battery.controlCurrent) : "—"
|
text: battery ? convertIntToString(battery.controlCurrent) : "—"
|
||||||
indicatorText: "А"
|
indicatorText: "А"
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredWidth: 1
|
Layout.preferredWidth: 1
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomControls.TextField {
|
CustomControls.TextField {
|
||||||
text: battery ? convertDoubleToString(battery.measuredCurrent) : "—"
|
text: battery ? convertIntToString(battery.measuredCurrent) : "—"
|
||||||
indicatorText: "А"
|
indicatorText: "А"
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredWidth: 1
|
Layout.preferredWidth: 1
|
||||||
@@ -90,14 +90,14 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CustomControls.TextField {
|
CustomControls.TextField {
|
||||||
text: battery ? convertDoubleToString(battery.controlTemperature) : "—"
|
text: battery ? convertIntToString(battery.controlTemperature) : "—"
|
||||||
indicatorText: "°C"
|
indicatorText: "°C"
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredWidth: 1
|
Layout.preferredWidth: 1
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomControls.TextField {
|
CustomControls.TextField {
|
||||||
text: battery ? convertDoubleToString(battery.measuredTemperature) : "—"
|
text: battery ? convertIntToString(battery.measuredTemperature) : "—"
|
||||||
indicatorText: "°C"
|
indicatorText: "°C"
|
||||||
implicitWidth: 1
|
implicitWidth: 1
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
@@ -130,7 +130,7 @@ Rectangle {
|
|||||||
|
|
||||||
delegate: CustomControls.ColoredLabel {
|
delegate: CustomControls.ColoredLabel {
|
||||||
text: modelData.description
|
text: modelData.description
|
||||||
backgroundColor: Palette.neutralColor
|
backgroundColor: statusSeverityToColor(modelData.severity)
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
width: parent.width
|
width: parent.width
|
||||||
}
|
}
|
||||||
@@ -183,4 +183,18 @@ Rectangle {
|
|||||||
return Palette.blueButtonColor
|
return Palette.blueButtonColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function statusSeverityToColor(severity) {
|
||||||
|
switch (severity) {
|
||||||
|
case BatteryController.Good:
|
||||||
|
return Palette.goodColor
|
||||||
|
case BatteryController.Warning:
|
||||||
|
return Palette.warningColor
|
||||||
|
case BatteryController.Error:
|
||||||
|
return Palette.errorColor
|
||||||
|
case BatteryController.Info:
|
||||||
|
default:
|
||||||
|
return Palette.infoColor
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ Controls.Button {
|
|||||||
topPadding: 8
|
topPadding: 8
|
||||||
bottomPadding: 8
|
bottomPadding: 8
|
||||||
|
|
||||||
|
font.family: "Roboto"
|
||||||
|
font.pixelSize: 14
|
||||||
|
font.weight: Font.Normal
|
||||||
|
|
||||||
property color backgroundColor: Palette.blueButtonColor
|
property color backgroundColor: Palette.blueButtonColor
|
||||||
|
|
||||||
contentItem: Text {
|
contentItem: Text {
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ Controls.TextField {
|
|||||||
id: control
|
id: control
|
||||||
|
|
||||||
readOnly: true
|
readOnly: true
|
||||||
selectByMouse: true
|
|
||||||
implicitHeight: 34
|
implicitHeight: 34
|
||||||
|
|
||||||
horizontalAlignment: Text.AlignRight
|
horizontalAlignment: Text.AlignRight
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ ApplicationWindow {
|
|||||||
|
|
||||||
CustomControls.ColoredLabel {
|
CustomControls.ColoredLabel {
|
||||||
text: CanController.isConnected ? "Штатный режим" : "Отсутствует связь с БМФ2"
|
text: CanController.isConnected ? "Штатный режим" : "Отсутствует связь с БМФ2"
|
||||||
backgroundColor: CanController.isConnected ? Palette.goodColor : Palette.invalidColor
|
backgroundColor: CanController.isConnected ? Palette.goodColor : Palette.errorColor
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ QtObject {
|
|||||||
property color redButtonColor: "#E74245"
|
property color redButtonColor: "#E74245"
|
||||||
property color yellowButtonColor: "#F4BB44"
|
property color yellowButtonColor: "#F4BB44"
|
||||||
|
|
||||||
property color informationColor: "#E2EAFF"
|
property color infoColor: "#E2EAFF"
|
||||||
property color invalidColor: "#FFEDE3"
|
|
||||||
property color goodColor: "#C4FFCA"
|
property color goodColor: "#C4FFCA"
|
||||||
property color neutralColor: "#FEFBC6"
|
property color warningColor: "#FEFBC6"
|
||||||
|
property color errorColor: "#FFEDE3"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
QT += quickcontrols2 quick
|
QT += quickcontrols2 quick
|
||||||
|
|
||||||
|
CONFIG += c++17
|
||||||
|
|
||||||
# You can make your code fail to compile if it uses deprecated APIs.
|
# You can make your code fail to compile if it uses deprecated APIs.
|
||||||
# In order to do so, uncomment the following line.
|
# In order to do so, uncomment the following line.
|
||||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
|
|||||||
5
main.cpp
5
main.cpp
@@ -1,6 +1,7 @@
|
|||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QQmlApplicationEngine>
|
#include <QQmlApplicationEngine>
|
||||||
|
|
||||||
|
#include <QCursor>
|
||||||
#include <QLocale>
|
#include <QLocale>
|
||||||
#include <QTextCodec>
|
#include <QTextCodec>
|
||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
@@ -22,6 +23,10 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
QGuiApplication app(argc, argv);
|
QGuiApplication app(argc, argv);
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
QGuiApplication::setOverrideCursor(QCursor(Qt::BlankCursor));
|
||||||
|
#endif
|
||||||
|
|
||||||
QCoreApplication::setOrganizationName("Tksi");
|
QCoreApplication::setOrganizationName("Tksi");
|
||||||
QCoreApplication::setOrganizationDomain("Tksi.rus");
|
QCoreApplication::setOrganizationDomain("Tksi.rus");
|
||||||
QCoreApplication::setApplicationName("Tksi monitor");
|
QCoreApplication::setApplicationName("Tksi monitor");
|
||||||
|
|||||||
Reference in New Issue
Block a user