diff --git a/commands.cpp b/commands.cpp index 7988b75..1d5a026 100644 --- a/commands.cpp +++ b/commands.cpp @@ -161,7 +161,7 @@ void Commands::processPacket(QByteArray data) values.opState = opStateToStr((OperationalStateTypedef)vb.vbPopFrontUint8()); values.balanceActive = vb.vbPopFrontUint8(); - values.faultState = faultStateToStr((bms_fault_code)vb.vbPopFrontUint8()); + values.faultState = faultStateToString((bms_fault_code)vb.vbPopFrontUint8()); emit valuesReceived(values); } break; @@ -271,6 +271,12 @@ void Commands::processPacket(QByteArray data) emit ackReceived(tr("Network settings applied successfully")); break; } + case COMM_GET_FAULT_STATE: + { + const auto state = static_cast(vb.vbPopFrontUint16()); + emit faultStateReceived(faultStateToType(state), faultStateToString(state)); + break; + } default: break; } @@ -367,6 +373,13 @@ void Commands::setNetSettings(QStringList settings) emitData(vb); } +void Commands::getFaultState() +{ + VByteArray vb; + vb.vbAppendInt8(COMM_GET_FAULT_STATE); + emitData(vb); +} + void Commands::sendTerminalCmd(QString cmd) { VByteArray vb; @@ -615,34 +628,67 @@ QString Commands::opStateToStr(OperationalStateTypedef fault) } } -QString Commands::faultStateToStr(bms_fault_code fault) +QString Commands::faultStateToString(bms_fault_code fault) { - switch (fault) { - case FAULT_CODE_NONE: return "System OK"; - case FAULT_CODE_PACK_OVER_VOLTAGE: return "Pack overvoltage"; - case FAULT_CODE_PACK_UNDER_VOLTAGE: return "Pack undervoltage"; - case FAULT_CODE_LOAD_OVER_VOLTAGE: return "Load overvoltage"; - case FAULT_CODE_LOAD_UNDER_VOLTAGE: return "Load undervoltage"; - case FAULT_CODE_CHARGER_OVER_VOLTAGE: return "Charger overvoltage"; - case FAULT_CODE_CHARGER_UNDER_VOLTAGE: return "Charger undervoltgae"; - case FAULT_CODE_CELL_HARD_OVER_VOLTAGE: return "Cell hard overvoltage"; - case FAULT_CODE_CELL_HARD_UNDER_VOLTAGE: return "Cell hard undervoltage"; - case FAULT_CODE_CELL_SOFT_OVER_VOLTAGE: return "Cell soft overvoltage"; - case FAULT_CODE_CELL_SOFT_UNDER_VOLTAGE: return "Cell soft undervoltage"; - case FAULT_CODE_MAX_UVP_OVP_ERRORS: return "MAX OVP/UVP errors"; - case FAULT_CODE_MAX_UVT_OVT_ERRORS: return "MAX OVT/UVT errors"; - case FAULT_CODE_OVER_CURRENT: return "Over current"; - case FAULT_CODE_OVER_TEMP_BMS: return "Over temp BMS"; - case FAULT_CODE_UNDER_TEMP_BMS: return "Under temp BMS"; - case FAULT_CODE_DISCHARGE_OVER_TEMP_CELLS: return "Discharge over temp cell"; - case FAULT_CODE_DISCHARGE_UNDER_TEMP_CELLS: return "Discharge under temp cell"; - case FAULT_CODE_CHARGE_OVER_TEMP_CELLS: return "Charge over temp cell"; - case FAULT_CODE_CHARGE_UNDER_TEMP_CELLS: return "Charge under temp cell"; - case FAULT_CODE_PRECHARGE_TIMEOUT: return "Precharge timeout"; - case FAULT_CODE_DISCHARGE_RETRY: return "Discharge retry"; - case FAULT_CODE_CHARGE_RETRY: return "Charge retry"; - case FAULT_CODE_CHARGER_DISCONNECT: return "Charge retry"; - default: return "Unknown fault"; + switch (fault) + { + case FAULT_CODE_NONE: return tr("System ok"); + case FAULT_CODE_PACK_OVER_VOLTAGE: return tr("Pack overvoltage"); + case FAULT_CODE_PACK_UNDER_VOLTAGE: return tr("Pack undervoltage"); + case FAULT_CODE_LOAD_OVER_VOLTAGE: return tr("Load overvoltage"); + case FAULT_CODE_LOAD_UNDER_VOLTAGE: return tr("Load undervoltage"); + case FAULT_CODE_CHARGER_OVER_VOLTAGE: return tr("Charger overvoltage"); + case FAULT_CODE_CHARGER_UNDER_VOLTAGE: return tr("Charger undervoltgae"); + case FAULT_CODE_CELL_HARD_OVER_VOLTAGE: return tr("Cell hard overvoltage"); + case FAULT_CODE_CELL_HARD_UNDER_VOLTAGE: return tr("Cell hard undervoltage"); + case FAULT_CODE_CELL_SOFT_OVER_VOLTAGE: return tr("Cell soft overvoltage"); + case FAULT_CODE_CELL_SOFT_UNDER_VOLTAGE: return tr("Cell soft undervoltage"); + case FAULT_CODE_MAX_UVP_OVP_ERRORS: return tr("Too high or too low voltage"); + case FAULT_CODE_MAX_UVT_OVT_ERRORS: return tr("Too high or too low temperature"); + case FAULT_CODE_OVER_CURRENT: return tr("Over current"); + case FAULT_CODE_OVER_TEMP_BMS: return tr("Over temperature BMS"); + case FAULT_CODE_UNDER_TEMP_BMS: return tr("Under temperature BMS"); + case FAULT_CODE_DISCHARGE_OVER_TEMP_CELLS: return tr("Discharge over temperature cell"); + case FAULT_CODE_DISCHARGE_UNDER_TEMP_CELLS: return tr("Discharge under temperature cell"); + case FAULT_CODE_CHARGE_OVER_TEMP_CELLS: return tr("Charge over temperature cell"); + case FAULT_CODE_CHARGE_UNDER_TEMP_CELLS: return tr("Charge under temperature cell"); + case FAULT_CODE_PRECHARGE_TIMEOUT: return tr("Precharge timeout"); + case FAULT_CODE_DISCHARGE_RETRY: return tr("Discharge retry"); + case FAULT_CODE_CHARGE_RETRY: return tr("Charge retry"); + case FAULT_CODE_CHARGER_DISCONNECT: return tr("Charge retry"); + default: return tr("Unknown state"); + } +} + +DataTypes::StateType Commands::faultStateToType(bms_fault_code fault) +{ + switch (fault) + { + case FAULT_CODE_NONE: return DataTypes::StateType::Good; + case FAULT_CODE_PACK_OVER_VOLTAGE: return DataTypes::StateType::Error; + case FAULT_CODE_PACK_UNDER_VOLTAGE: return DataTypes::StateType::Error; + case FAULT_CODE_LOAD_OVER_VOLTAGE: return DataTypes::StateType::Error; + case FAULT_CODE_LOAD_UNDER_VOLTAGE: return DataTypes::StateType::Error; + case FAULT_CODE_CHARGER_OVER_VOLTAGE: return DataTypes::StateType::Error; + case FAULT_CODE_CHARGER_UNDER_VOLTAGE: return DataTypes::StateType::Error; + case FAULT_CODE_CELL_HARD_OVER_VOLTAGE: return DataTypes::StateType::Error; + case FAULT_CODE_CELL_HARD_UNDER_VOLTAGE: return DataTypes::StateType::Error; + case FAULT_CODE_CELL_SOFT_OVER_VOLTAGE: return DataTypes::StateType::Error; + case FAULT_CODE_CELL_SOFT_UNDER_VOLTAGE: return DataTypes::StateType::Error; + case FAULT_CODE_MAX_UVP_OVP_ERRORS: return DataTypes::StateType::Error; + case FAULT_CODE_MAX_UVT_OVT_ERRORS: return DataTypes::StateType::Error; + case FAULT_CODE_OVER_CURRENT: return DataTypes::StateType::Error; + case FAULT_CODE_OVER_TEMP_BMS: return DataTypes::StateType::Error; + case FAULT_CODE_UNDER_TEMP_BMS: return DataTypes::StateType::Error; + case FAULT_CODE_DISCHARGE_OVER_TEMP_CELLS: return DataTypes::StateType::Error; + case FAULT_CODE_DISCHARGE_UNDER_TEMP_CELLS: return DataTypes::StateType::Error; + case FAULT_CODE_CHARGE_OVER_TEMP_CELLS: return DataTypes::StateType::Error; + case FAULT_CODE_CHARGE_UNDER_TEMP_CELLS: return DataTypes::StateType::Error; + case FAULT_CODE_PRECHARGE_TIMEOUT: return DataTypes::StateType::Warning; + case FAULT_CODE_DISCHARGE_RETRY: return DataTypes::StateType::Info; + case FAULT_CODE_CHARGE_RETRY: return DataTypes::StateType::Info; + case FAULT_CODE_CHARGER_DISCONNECT: return DataTypes::StateType::Info; + default: return DataTypes::StateType::Info; } } diff --git a/commands.h b/commands.h index bc8a7b9..5818e7a 100644 --- a/commands.h +++ b/commands.h @@ -72,6 +72,7 @@ signals: void valuesSetupReceived(BMS_VALUES values); void pingCanRx(QVector devs, bool isTimeout); void netSettingsReceived(QStringList settings); + void faultStateReceived(DataTypes::StateType faultType, QString faultString); public slots: void processPacket(QByteArray data); @@ -84,6 +85,7 @@ public slots: void getNetSettings(); void getNetDefaultSettings(); void setNetSettings(QStringList settings); + void getFaultState(); void sendTerminalCmd(QString cmd); void setDetect(disp_pos_mode mode); void samplePrint(debug_sampling_mode mode, int sample_len, int dec); @@ -102,7 +104,8 @@ private: void emitData(QByteArray data); void firmwareUploadUpdate(bool isTimeout); QString opStateToStr(OperationalStateTypedef fault); - QString faultStateToStr(bms_fault_code fault); + QString faultStateToString(bms_fault_code fault); + DataTypes::StateType faultStateToType(bms_fault_code fault); QTimer *mTimer; bool mSendCan; diff --git a/datatypes.h b/datatypes.h index 24f9de8..16aad99 100644 --- a/datatypes.h +++ b/datatypes.h @@ -84,6 +84,8 @@ typedef enum { FAULT_CODE_PRECHARGE_TIMEOUT, FAULT_CODE_DISCHARGE_RETRY, FAULT_CODE_CHARGE_RETRY, + FAULT_CODE_CAN_DELAYED_POWER_DOWN, + FAULT_CODE_NOT_USED_TIMEOUT, FAULT_CODE_CHARGER_DISCONNECT } bms_fault_code; @@ -419,6 +421,7 @@ typedef enum { COMM_GET_BMS_NET_SETTINGS, COMM_GET_BMS_NET_DEFAULT_SETTINGS, COMM_SET_BMS_NET_SETTINGS, + COMM_GET_FAULT_STATE, } COMM_PACKET_ID; typedef struct { @@ -469,4 +472,19 @@ typedef enum { OP_STATE_FORCEON, // 11 } OperationalStateTypedef; +namespace DataTypes +{ + Q_NAMESPACE + + enum class StateType + { + Neutral, + Info, + Good, + Warning, + Error + }; + Q_ENUM_NS(StateType); +} + #endif // DATATYPES_H diff --git a/main.cpp b/main.cpp index 625ae49..76ea02d 100644 --- a/main.cpp +++ b/main.cpp @@ -79,6 +79,9 @@ int main(int argc, char *argv[]) qmlRegisterType("Cubo", 1, 0, "FirmwareUpdateHelper"); qmlRegisterType("Cubo", 1, 0, "CurrentTableModel"); + qmlRegisterUncreatableMetaObject(DataTypes::staticMetaObject, "Cubo", 1, 0, "DataTypes", "Error: only enums"); + qRegisterMetaType("DataTypes::StateType"); + engine.addImportPath(QStringLiteral("qrc:/")); engine.load(QUrl(QStringLiteral("qrc:/MainWindow.qml"))); diff --git a/qml/Icons/error-state.svg b/qml/Icons/error-state.svg new file mode 100644 index 0000000..4102a6c --- /dev/null +++ b/qml/Icons/error-state.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/qml/Icons/good-state.svg b/qml/Icons/good-state.svg new file mode 100644 index 0000000..9634ce2 --- /dev/null +++ b/qml/Icons/good-state.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/qml/Icons/info-state.svg b/qml/Icons/info-state.svg new file mode 100644 index 0000000..cf7a785 --- /dev/null +++ b/qml/Icons/info-state.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/qml/Icons/neutral-state.svg b/qml/Icons/neutral-state.svg new file mode 100644 index 0000000..7bddb43 --- /dev/null +++ b/qml/Icons/neutral-state.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/qml/Icons/warning-state.svg b/qml/Icons/warning-state.svg new file mode 100644 index 0000000..1a30dc4 --- /dev/null +++ b/qml/Icons/warning-state.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/qml/MainWindow.qml b/qml/MainWindow.qml index 918b46d..bba6b59 100644 --- a/qml/MainWindow.qml +++ b/qml/MainWindow.qml @@ -353,11 +353,16 @@ ApplicationWindow { onPortConnectedChanged: { connectionStatusLabel.text = Qt.binding(function(){ return BmsInterface.isPortConnected() ? qsTr("Connected") : qsTr("Disconnected") }) connectionStatusIndicator.enabled = BmsInterface.isPortConnected() + faultStateTimer.running = BmsInterface.isPortConnected() + if (BmsInterface.isPortConnected()) { BmsInterface.commands().getBMSconf() + BmsInterface.commands().getFaultState() } else { serialLabel.text = "-" firmwareLabel.text = "-" + statusPopup.queue = [] + faultStatePopup.lastState = "" } } @@ -419,6 +424,17 @@ ApplicationWindow { onFwVersionReceived: { firmwareLabel.text = major + "." + minor } + onFaultStateReceived: { + if (faultStatePopup.lastState != faultString) { + faultStatePopup.close() + faultStatePopup.lastState = faultString + faultStatePopup.text = faultString + faultStatePopup.type = faultType + faultStatePopup.open() + + Qt.callLater(debugScreen.printMessage, faultString, faultStatePopup.color) + } + } } Screens.ConnectionDialog { @@ -457,12 +473,12 @@ ApplicationWindow { onOpened: { hideStatusTimer.start() } - } - Timer { - id: hideStatusTimer - interval: 3000 - onTriggered: statusPopup.close() + Timer { + id: hideStatusTimer + interval: 3000 + onTriggered: statusPopup.close() + } } Popup { @@ -505,6 +521,12 @@ ApplicationWindow { onOpened: hideBusyTimer.start() onClosed: hideBusyTimer.stop() + + Timer { + id: hideBusyTimer + interval: 30000 + onTriggered: busyPopup.close() + } } Popup { @@ -549,10 +571,29 @@ ApplicationWindow { } } - Timer { - id: hideBusyTimer - interval: 30000 - onTriggered: busyPopup.close() + Screens.StatePopup { + id: faultStatePopup + x: parent.width - width - 45 + y: 18 + + property var lastState: "" + + onOpened: { + hideStateTimer.start() + } + + Timer { + id: hideStateTimer + interval: 3000 + onTriggered: faultStatePopup.close() + } + + Timer { + id: faultStateTimer + interval: 50000 + repeat: true + onTriggered: BmsInterface.commands().getFaultState() + } } background: Rectangle { @@ -561,6 +602,6 @@ ApplicationWindow { Component.onCompleted: { connectionDialog.open() - Qt.callLater(debugScreen.printMessage, qsTr("Tool started"), true) + Qt.callLater(debugScreen.printMessage, qsTr("Tool started")) } } diff --git a/qml/Screens/DebugInformationScreen.qml b/qml/Screens/DebugInformationScreen.qml index 381653b..e954190 100644 --- a/qml/Screens/DebugInformationScreen.qml +++ b/qml/Screens/DebugInformationScreen.qml @@ -37,23 +37,15 @@ ColumnLayout { Connections { target: BmsInterface - onStatusMessage: printMessage(msg, isGood) - onPortConnectedChanged: printMessage(BmsInterface.getConnectedPortName(), true) + onStatusMessage: printMessage(msg, isGood ? Palette.textColor : Palette.invalidColor) + onPortConnectedChanged: printMessage(BmsInterface.getConnectedPortName()) } - function printMessage(msg, isGood) { - var message = "" - - if (!isGood) { - message += "" - } + function printMessage(msg, color = Palette.textColor) { + var message = "" message += new Date().toLocaleString(Qt.locale("en-US"), "dd.MM.yyyy hh:mm:ss") + ": " + msg - - if (!isGood) { - message += "" - } - + message += "" message += "
" outputArea.insert(outputArea.length, message) diff --git a/qml/Screens/StatePopup.qml b/qml/Screens/StatePopup.qml new file mode 100644 index 0000000..3267469 --- /dev/null +++ b/qml/Screens/StatePopup.qml @@ -0,0 +1,97 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.12 + +import Controls 1.0 as Controls +import Cubo 1.0 +import Utils 1.0 + +Popup { + id: root + closePolicy: Popup.NoAutoClose + + property string text: "" + property var type: DataTypes.StateType.Info + property color color: switch (type) { + case DataTypes.StateType.Info: + return "#0A72BA" + case DataTypes.StateType.Good: + return "#009352" + case DataTypes.StateType.Warning: + return "#E5C207" + case DataTypes.StateType.Error: + return "#CF3200" + case DataTypes.StateType.Neutral: + default: + return "#838D97" + } + + property var icon: switch (type) { + case DataTypes.StateType.Info: + return "qrc:/Icons/info-state.svg" + case DataTypes.StateType.Good: + return "qrc:/Icons/good-state.svg" + case DataTypes.StateType.Warning: + return "qrc:/Icons/warning-state.svg" + case DataTypes.StateType.Error: + return "qrc:/Icons/error-state.svg" + case DataTypes.StateType.Neutral: + default: + return "qrc:/Icons/neutral-state.svg" + } + + + + RowLayout { + spacing: 15 + + Image { + source: root.icon + Layout.leftMargin: 5 + } + + Controls.SubtitleLabel { + id: label + text: root.text + maximumLineCount: 10 + wrapMode: Text.Wrap + } + } + + background: Rectangle { + radius: 6 + color: "#F7F8FC" + + Rectangle { + radius: 6 + anchors.fill: parent + color: Qt.rgba(root.color.r, root.color.g, root.color.b, 0.1) + } + + Rectangle { + radius: 6 + width: 4 + height: parent.height + anchors.left: parent.left + color: root.color + } + } + + enter: Transition { + NumberAnimation { + property: "opacity" + from: 0.0 + to: 1.0 + duration: 300 + } + } + + exit: Transition { + NumberAnimation { + property: "opacity" + from: 1.0 + to: 0.0 + duration: 2500 + } + } +} diff --git a/qml/Screens/qmldir b/qml/Screens/qmldir index 1b900e3..621f21a 100644 --- a/qml/Screens/qmldir +++ b/qml/Screens/qmldir @@ -14,3 +14,4 @@ NetworkSettingsScreen 1.0 NetworkSettingsScreen.qml TimeSettingsScreen 1.0 TimeSettingsScreen.qml CanSettingsScreen 1.0 CanSettingsScreen.qml TemperatureMonitorScreen 1.0 TemperatureMonitorScreen.qml +StatePopup 1.0 StatePopup.qml diff --git a/qml/qml_icons.qrc b/qml/qml_icons.qrc index dfffef1..f161628 100644 --- a/qml/qml_icons.qrc +++ b/qml/qml_icons.qrc @@ -19,5 +19,10 @@ Icons/russian-flag.svg Icons/refresh.svg Icons/temperature.svg + Icons/error-state.svg + Icons/good-state.svg + Icons/info-state.svg + Icons/neutral-state.svg + Icons/warning-state.svg diff --git a/qml/qml_items.qrc b/qml/qml_items.qrc index 6f5045f..95df15e 100644 --- a/qml/qml_items.qrc +++ b/qml/qml_items.qrc @@ -49,5 +49,6 @@ Controls/RadioButton.qml Screens/TemperatureMonitorScreen.qml Screens/CanSettingsScreen.qml + Screens/StatePopup.qml diff --git a/translations/cubo_en.ts b/translations/cubo_en.ts index dc09868..3eaaa01 100644 --- a/translations/cubo_en.ts +++ b/translations/cubo_en.ts @@ -588,45 +588,166 @@ Wait, please. - - + + Buffer erase - + Buffer erase timeout - + CRC/Size write - + CRC/Size write timeout - + Firmware data write - + Firmware data write timeout - + Firmware update completed! Reconnect to the board if you want to continue working with it. - + + System ok + + + + + Pack overvoltage + + + + + Pack undervoltage + + + + + Load overvoltage + + + + + Load undervoltage + + + + + Charger overvoltage + + + + + Charger undervoltgae + + + + + Cell hard overvoltage + + + + + Cell hard undervoltage + + + + + Cell soft overvoltage + + + + + Cell soft undervoltage + + + + + Too high or too low voltage + + + + + Too high or too low temperature + + + + + Over current + + + + + Over temperature BMS + + + + + Under temperature BMS + + + + + Discharge over temperature cell + + + + + Discharge under temperature cell + + + + + Charge over temperature cell + + + + + Charge under temperature cell + + + + + Precharge timeout + + + + + Discharge retry + + + + + + Charge retry + + + + + Unknown state + + + + Cancelled @@ -833,12 +954,12 @@ Reconnect to the board if you want to continue working with it. - + Firmware update - + Tool started diff --git a/translations/cubo_it.ts b/translations/cubo_it.ts index ba08213..55e4344 100644 --- a/translations/cubo_it.ts +++ b/translations/cubo_it.ts @@ -588,45 +588,166 @@ Wait, please. - - + + Buffer erase - + Buffer erase timeout - + CRC/Size write - + CRC/Size write timeout - + Firmware data write - + Firmware data write timeout - + Firmware update completed! Reconnect to the board if you want to continue working with it. - + + System ok + + + + + Pack overvoltage + + + + + Pack undervoltage + + + + + Load overvoltage + + + + + Load undervoltage + + + + + Charger overvoltage + + + + + Charger undervoltgae + + + + + Cell hard overvoltage + + + + + Cell hard undervoltage + + + + + Cell soft overvoltage + + + + + Cell soft undervoltage + + + + + Too high or too low voltage + + + + + Too high or too low temperature + + + + + Over current + + + + + Over temperature BMS + + + + + Under temperature BMS + + + + + Discharge over temperature cell + + + + + Discharge under temperature cell + + + + + Charge over temperature cell + + + + + Charge under temperature cell + + + + + Precharge timeout + + + + + Discharge retry + + + + + + Charge retry + + + + + Unknown state + + + + Cancelled @@ -833,12 +954,12 @@ Reconnect to the board if you want to continue working with it. - + Firmware update - + Tool started diff --git a/translations/cubo_ru.qm b/translations/cubo_ru.qm index fc9b69c..8bd9399 100644 Binary files a/translations/cubo_ru.qm and b/translations/cubo_ru.qm differ diff --git a/translations/cubo_ru.ts b/translations/cubo_ru.ts index 341fa78..11fd8de 100644 --- a/translations/cubo_ru.ts +++ b/translations/cubo_ru.ts @@ -637,38 +637,38 @@ Wait, please. Настройки сети успешно применены - - + + Buffer erase Стирание буфера - + Buffer erase timeout Таймаут стирания буфера - + CRC/Size write Запись контрольной суммы - + CRC/Size write timeout Таймаут записи контрольной суммы - + Firmware data write Запись данных прошивки - + Firmware data write timeout Таймаут записи данных прошивки - + Firmware update completed! Reconnect to the board if you want to continue working with it. @@ -676,12 +676,133 @@ Reconnect to the board if you want to continue working with it. Выполните повторное подключение к плате, если хотите продолжить работу с ней. + + + System ok + Система в порядке + + + + Pack overvoltage + Напряжение пакета превышено + + + + Pack undervoltage + Напряжение пакета занижено + + + + Load overvoltage + Напряжение загрузки превышено + + + + Load undervoltage + Напряжение загрузки занижено + + + + Charger overvoltage + Напряжение зарядки завышено + + + + Charger undervoltgae + Напряжение зарядки занижено + + + + Cell hard overvoltage + Напряжение ячейки сильно завышено + + + + Cell hard undervoltage + Напряжение ячейки сильно занижено + + + + Cell soft overvoltage + Напряжение ячейки завышено + + + + Cell soft undervoltage + Напряжение ячейки занижено + + + + Too high or too low voltage + Слишком высокий или низкий вольтаж + + + + Too high or too low temperature + Слишком высокая или низкая температура + + + + Over current + Превышен ток + + + + Over temperature BMS + Превышена температура BMS + + + + Under temperature BMS + Занижена температура BMS + + + + Discharge over temperature cell + Превышена температура разряда ячейки + + + + Discharge under temperature cell + Занижена температура разряда ячейки + + + + Charge over temperature cell + Превышена температура заряда ячейки + + + + Charge under temperature cell + Занижена температура заряда ячейки + + + + Precharge timeout + Тайм-аут предварительной зарядки + + + + Discharge retry + Попытка рязряда + + + + + Charge retry + Попытка заряда + + + + Unknown state + Неизвестное состояние + Firmware update completed Обновление прошивки завершено - + Cancelled Отменено @@ -876,7 +997,7 @@ Reconnect to the board if you want to continue working with it. Вывод информации - + Firmware update Обновление прошивки @@ -885,7 +1006,7 @@ Reconnect to the board if you want to continue working with it. Терминал - + Tool started Утилита запущена