787 lines
32 KiB
QML
787 lines
32 KiB
QML
import QtQuick 2.12
|
|
import QtQuick.Controls 2.12
|
|
import QtQuick.Layouts 1.12
|
|
import QtQuick.Dialogs 1.2
|
|
import Qt.labs.settings 1.1
|
|
|
|
import Controls 1.0 as Controls
|
|
import Cubo 1.0
|
|
import Utils 1.0
|
|
|
|
RowLayout {
|
|
property real contentPadding: 35
|
|
property real contentRowSpacing: 20
|
|
property real contentColumnSpacing: 35
|
|
|
|
signal needWait(bool active, string text)
|
|
|
|
spacing: contentColumnSpacing
|
|
|
|
Flickable {
|
|
id: settingsFlickable
|
|
clip: true
|
|
contentHeight: configLayout.height
|
|
boundsBehavior: Flickable.StopAtBounds
|
|
|
|
ColumnLayout {
|
|
id: configLayout
|
|
width: parent.width
|
|
spacing: 15
|
|
|
|
Controls.Frame {
|
|
id: serialNumberSettingsFrame
|
|
padding: contentPadding
|
|
implicitWidth: parent.width
|
|
Layout.fillWidth: true
|
|
|
|
RowLayout {
|
|
spacing: contentColumnSpacing
|
|
anchors.fill: parent
|
|
|
|
Controls.TitleLabel {
|
|
text: qsTr("Serial number")
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.spacing) / 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: serialNumberField
|
|
validator: RegExpValidator { regExp: /[1-9][0-9]*/ }
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.spacing) / 2
|
|
}
|
|
}
|
|
}
|
|
|
|
Controls.Frame {
|
|
id: configurationSettingsFrame
|
|
padding: contentPadding
|
|
implicitWidth: parent.width
|
|
Layout.fillWidth: true
|
|
|
|
GridLayout {
|
|
columns: 2
|
|
rowSpacing: contentRowSpacing
|
|
columnSpacing: contentColumnSpacing
|
|
anchors.fill: parent
|
|
|
|
Controls.TitleLabel {
|
|
text: qsTr("Configuration")
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 2
|
|
}
|
|
|
|
Controls.SubtitleLabel {
|
|
text: qsTr("Number of boards")
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.SubtitleLabel {
|
|
text: qsTr("Number of cells")
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: numberOfBoardsField
|
|
validator: IntValidator {}
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: numberOfCellsField
|
|
validator: IntValidator {}
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
}
|
|
}
|
|
|
|
Controls.Frame {
|
|
id: socSettingsFrame
|
|
padding: contentPadding
|
|
implicitWidth: parent.width
|
|
Layout.fillWidth: true
|
|
|
|
GridLayout {
|
|
columns: 2
|
|
rowSpacing: contentRowSpacing
|
|
columnSpacing: contentColumnSpacing
|
|
anchors.fill: parent
|
|
|
|
Controls.TitleLabel {
|
|
text: qsTr("SOC")
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 2
|
|
}
|
|
|
|
Controls.SubtitleLabel {
|
|
text: qsTr("Number of cells connected in parallel")
|
|
maximumLineCount: 2
|
|
wrapMode: Text.WordWrap
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.SubtitleLabel {
|
|
text: qsTr("Battery capacity")
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: numberOfParallelCellsField
|
|
validator: IntValidator {}
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: batteryCapacityField
|
|
validator: DoubleValidator { decimals: 2; locale: "en-US"; notation: DoubleValidator.StandardNotation }
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
}
|
|
}
|
|
|
|
Controls.Frame {
|
|
id: limitSettingsFrame
|
|
padding: contentPadding
|
|
implicitWidth: parent.width
|
|
Layout.fillWidth: true
|
|
|
|
GridLayout {
|
|
columns: 2
|
|
rowSpacing: contentRowSpacing
|
|
columnSpacing: contentColumnSpacing
|
|
anchors.fill: parent
|
|
|
|
Controls.TitleLabel {
|
|
text: qsTr("Limits")
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 2
|
|
}
|
|
|
|
Controls.SubtitleLabel {
|
|
text: qsTr("Maximum charge current, A")
|
|
maximumLineCount: 2
|
|
wrapMode: Text.WordWrap
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.SubtitleLabel {
|
|
text: qsTr("Maximum load current, A")
|
|
maximumLineCount: 2
|
|
wrapMode: Text.WordWrap
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: maximumChargeCurrentField
|
|
validator: DoubleValidator { decimals: 2; locale: "en-US"; notation: DoubleValidator.StandardNotation }
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: maximumLoadCurrentField
|
|
validator: DoubleValidator { decimals: 2; locale: "en-US"; notation: DoubleValidator.StandardNotation }
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.SubtitleLabel {
|
|
text: qsTr("Maximum temperature, °C")
|
|
maximumLineCount: 2
|
|
wrapMode: Text.WordWrap
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
Layout.columnSpan: 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: maximumTemperatureField
|
|
validator: DoubleValidator { decimals: 2; locale: "en-US"; notation: DoubleValidator.StandardNotation }
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
Layout.columnSpan: 2
|
|
}
|
|
}
|
|
}
|
|
|
|
Controls.Frame {
|
|
id: cellSettingsFrame
|
|
padding: contentPadding
|
|
implicitWidth: parent.width
|
|
Layout.fillWidth: true
|
|
|
|
GridLayout {
|
|
columns: 2
|
|
rowSpacing: contentRowSpacing
|
|
columnSpacing: contentColumnSpacing
|
|
anchors.fill: parent
|
|
|
|
Controls.TitleLabel {
|
|
text: qsTr("Cell configuration")
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 2
|
|
}
|
|
|
|
Controls.SubtitleLabel {
|
|
text: qsTr("Lower disable threshold, V")
|
|
maximumLineCount: 2
|
|
wrapMode: Text.WordWrap
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.SubtitleLabel {
|
|
text: qsTr("Upper disable threshold, V")
|
|
maximumLineCount: 2
|
|
wrapMode: Text.WordWrap
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: lowerDisableThresholdField
|
|
validator: DoubleValidator { decimals: 2; locale: "en-US"; notation: DoubleValidator.StandardNotation }
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: upperDisableThresholdField
|
|
validator: DoubleValidator { decimals: 2; locale: "en-US"; notation: DoubleValidator.StandardNotation }
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.SubtitleLabel {
|
|
text: qsTr("Lower enable threshold (should be higher than disable), V")
|
|
maximumLineCount: 3
|
|
wrapMode: Text.WordWrap
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.SubtitleLabel {
|
|
text: qsTr("Upper enable threshold (should be higher than disable), V")
|
|
maximumLineCount: 3
|
|
wrapMode: Text.WordWrap
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: lowerEnableThresholdField
|
|
validator: DoubleValidator { decimals: 2; locale: "en-US"; notation: DoubleValidator.StandardNotation }
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: upperEnableThresholdField
|
|
validator: DoubleValidator { decimals: 2; locale: "en-US"; notation: DoubleValidator.StandardNotation }
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
}
|
|
}
|
|
|
|
Controls.Frame {
|
|
id: balancingSettingsFrame
|
|
padding: contentPadding
|
|
implicitWidth: parent.width
|
|
Layout.fillWidth: true
|
|
|
|
GridLayout {
|
|
columns: 2
|
|
rowSpacing: contentRowSpacing
|
|
columnSpacing: contentColumnSpacing
|
|
anchors.fill: parent
|
|
|
|
Controls.TitleLabel {
|
|
text: qsTr("Balancing configuration")
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 2
|
|
}
|
|
|
|
Controls.SubtitleLabel {
|
|
text: qsTr("Balancing start voltage, V")
|
|
maximumLineCount: 2
|
|
wrapMode: Text.WordWrap
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.SubtitleLabel {
|
|
text: qsTr("Cell voltage delta to start balancing, V")
|
|
maximumLineCount: 2
|
|
wrapMode: Text.WordWrap
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: balancingStartVoltageField
|
|
validator: DoubleValidator { decimals: 2; locale: "en-US"; notation: DoubleValidator.StandardNotation }
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: balancingStartDeltaVoltageField
|
|
validator: DoubleValidator { decimals: 2; locale: "en-US"; notation: DoubleValidator.StandardNotation }
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.SubtitleLabel {
|
|
text: qsTr("Cell balancing interval, ms")
|
|
maximumLineCount: 2
|
|
wrapMode: Text.WordWrap
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
Layout.columnSpan: 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: balancingCellIntervalField
|
|
validator: IntValidator {}
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
Layout.columnSpan: 2
|
|
}
|
|
}
|
|
}
|
|
|
|
Controls.Frame {
|
|
id: outputSettingsFrame
|
|
padding: contentPadding
|
|
implicitWidth: parent.width
|
|
Layout.fillWidth: true
|
|
|
|
property real outputNumberSize: 60
|
|
|
|
GridLayout {
|
|
columns: 2
|
|
rowSpacing: contentRowSpacing
|
|
columnSpacing: contentColumnSpacing
|
|
anchors.fill: parent
|
|
|
|
Controls.TitleLabel {
|
|
text: qsTr("Output settings")
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 2
|
|
}
|
|
|
|
RowLayout {
|
|
spacing: 20
|
|
|
|
Controls.LabelWithBackground {
|
|
text: qsTr("# 1")
|
|
Layout.preferredWidth: outputSettingsFrame.outputNumberSize
|
|
Layout.preferredHeight: outputSettingsFrame.outputNumberSize
|
|
}
|
|
|
|
Controls.CheckBox {
|
|
text: qsTr("Use for storage management")
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: outputSettingsFrame.outputNumberSize
|
|
}
|
|
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 2
|
|
}
|
|
|
|
Controls.LineSeparator {
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 2
|
|
}
|
|
|
|
RowLayout {
|
|
spacing: 20
|
|
|
|
Controls.LabelWithBackground {
|
|
text: qsTr("# 2")
|
|
Layout.preferredWidth: outputSettingsFrame.outputNumberSize
|
|
Layout.preferredHeight: outputSettingsFrame.outputNumberSize
|
|
}
|
|
|
|
Controls.CheckBox {
|
|
text: qsTr("Normally closed")
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: outputSettingsFrame.outputNumberSize
|
|
}
|
|
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 2
|
|
}
|
|
|
|
Controls.SubtitleLabel {
|
|
text: qsTr("Change in value during SOC")
|
|
maximumLineCount: 2
|
|
wrapMode: Text.WordWrap
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
Layout.columnSpan: 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: changeValueSocField
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
Layout.columnSpan: 2
|
|
}
|
|
|
|
Controls.LineSeparator {
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 2
|
|
}
|
|
|
|
RowLayout {
|
|
spacing: 20
|
|
|
|
Controls.LabelWithBackground {
|
|
text: qsTr("# 3")
|
|
Layout.preferredWidth: outputSettingsFrame.outputNumberSize
|
|
Layout.preferredHeight: outputSettingsFrame.outputNumberSize
|
|
}
|
|
|
|
Controls.CheckBox {
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: outputSettingsFrame.outputNumberSize
|
|
}
|
|
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 2
|
|
}
|
|
|
|
Controls.SubtitleLabel {
|
|
text: qsTr("Closes at t<, °C")
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.SubtitleLabel {
|
|
text: qsTr("Opens at t>, °C")
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: closesBelowTemperatureThirdField
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: opensGreaterTemperatureThirdField
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.LineSeparator {
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 2
|
|
}
|
|
|
|
RowLayout {
|
|
spacing: 20
|
|
|
|
Controls.LabelWithBackground {
|
|
text: qsTr("# 4")
|
|
Layout.preferredWidth: outputSettingsFrame.outputNumberSize
|
|
Layout.preferredHeight: outputSettingsFrame.outputNumberSize
|
|
}
|
|
|
|
Controls.CheckBox {
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: outputSettingsFrame.outputNumberSize
|
|
}
|
|
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 2
|
|
}
|
|
|
|
Controls.SubtitleLabel {
|
|
text: qsTr("Closes at t<, °C")
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.SubtitleLabel {
|
|
text: qsTr("Opens at t>, °C")
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: closesBelowTemperatureFourthField
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: opensGreaterTemperatureFourthField
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.LineSeparator {
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 2
|
|
}
|
|
}
|
|
}
|
|
|
|
Controls.Frame {
|
|
id: zeroSensorSettingsFrame
|
|
padding: contentPadding
|
|
implicitWidth: parent.width
|
|
Layout.fillWidth: true
|
|
|
|
GridLayout {
|
|
columns: 2
|
|
rowSpacing: contentRowSpacing
|
|
columnSpacing: contentColumnSpacing
|
|
anchors.fill: parent
|
|
|
|
Controls.SubtitleLabel {
|
|
text: qsTr("Current sensor value \"0\"")
|
|
Layout.fillWidth: true
|
|
Layout.columnSpan: 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: zeroSensorValueField
|
|
validator: DoubleValidator { decimals: 2; locale: "en-US"; notation: DoubleValidator.StandardNotation }
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
Layout.columnSpan: 2
|
|
}
|
|
|
|
Controls.Button {
|
|
id: zeroSensorValueCalibrationButton
|
|
text: qsTr("Calibrate \"0\"")
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
Layout.columnSpan: 2
|
|
onClicked: BmsInterface.commands().sendTerminalCmd("setZeroCurrent")
|
|
}
|
|
}
|
|
}
|
|
|
|
Controls.OutlineButton {
|
|
text: qsTr("Load settings from file")
|
|
onClicked: loadFileDialog.open()
|
|
Layout.preferredWidth: 270
|
|
|
|
FileDialog {
|
|
id: loadFileDialog
|
|
title: qsTr("Select configuration file")
|
|
folder: shortcuts.documents
|
|
nameFilters: [ qsTr("Configuration files (*.xml)"), qsTr("All files (*)") ]
|
|
onAccepted: {
|
|
let result = BmsInterface.bmsConfig().loadXml(loadFileDialog.fileUrl.toString().replace(/^(file:\/{3})/, ""), "bmsConfiguration")
|
|
if (!result) {
|
|
BmsInterface.emitStatusMessage(BmsInterface.bmsConfig().xmlStatus(), false)
|
|
}
|
|
}
|
|
}
|
|
|
|
Settings {
|
|
category: "loadConfiguration"
|
|
property alias folder: loadFileDialog.folder
|
|
}
|
|
}
|
|
|
|
Controls.OutlineButton {
|
|
text: qsTr("Save settings to file")
|
|
onClicked: saveFileDialog.open()
|
|
Layout.preferredWidth: 270
|
|
|
|
FileDialog {
|
|
id: saveFileDialog
|
|
title: qsTr("Select configuration file")
|
|
selectExisting: false
|
|
folder: shortcuts.documents
|
|
nameFilters: [ qsTr("Configuration files (*.xml)"), qsTr("All files (*)") ]
|
|
onAccepted: {
|
|
let result = BmsInterface.bmsConfig().saveXml(saveFileDialog.fileUrl.toString().replace(/^(file:\/{3})/, ""), "bmsConfiguration")
|
|
if (!result) {
|
|
BmsInterface.emitStatusMessage(BmsInterface.bmsConfig().xmlStatus(), false)
|
|
} else {
|
|
BmsInterface.emitStatusMessage(qsTr("BMS configuration saved to file"), true)
|
|
}
|
|
}
|
|
}
|
|
|
|
Settings {
|
|
category: "saveConfiguration"
|
|
property alias folder: saveFileDialog.folder
|
|
}
|
|
}
|
|
}
|
|
|
|
ScrollBar.vertical: Controls.ScrollBar {}
|
|
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
}
|
|
|
|
ColumnLayout {
|
|
spacing: contentRowSpacing
|
|
|
|
Controls.LinkLabel {
|
|
text: qsTr("Serial number")
|
|
onClicked: settingsFlickable.contentY = serialNumberSettingsFrame.mapToItem(settingsFlickable.contentItem, 0, 0).y
|
|
}
|
|
|
|
Controls.LinkLabel {
|
|
text: qsTr("Configuration")
|
|
onClicked: settingsFlickable.contentY = configurationSettingsFrame.mapToItem(settingsFlickable.contentItem, 0, 0).y
|
|
}
|
|
|
|
Controls.LinkLabel {
|
|
text: qsTr("SOC")
|
|
onClicked: settingsFlickable.contentY = socSettingsFrame.mapToItem(settingsFlickable.contentItem, 0, 0).y
|
|
}
|
|
|
|
Controls.LinkLabel {
|
|
text: qsTr("Limits")
|
|
onClicked: settingsFlickable.contentY = limitSettingsFrame.mapToItem(settingsFlickable.contentItem, 0, 0).y
|
|
}
|
|
|
|
Controls.LinkLabel {
|
|
text: qsTr("Cell configuration")
|
|
onClicked: settingsFlickable.contentY = cellSettingsFrame.mapToItem(settingsFlickable.contentItem, 0, 0).y
|
|
}
|
|
|
|
Controls.LinkLabel {
|
|
text: qsTr("Balancing configuration")
|
|
onClicked: settingsFlickable.contentY = balancingSettingsFrame.mapToItem(settingsFlickable.contentItem, 0, 0).y
|
|
}
|
|
|
|
Controls.LinkLabel {
|
|
text: qsTr("Output settings")
|
|
onClicked: settingsFlickable.contentY = outputSettingsFrame.mapToItem(settingsFlickable.contentItem, 0, 0).y
|
|
}
|
|
|
|
Controls.LinkLabel {
|
|
text: qsTr("Current sensor value \"0\"")
|
|
onClicked: {
|
|
settingsFlickable.contentY = zeroSensorSettingsFrame.mapToItem(settingsFlickable.contentItem, 0, 0).y
|
|
settingsFlickable.returnToBounds()
|
|
}
|
|
}
|
|
|
|
Item {
|
|
Layout.fillHeight: true
|
|
}
|
|
|
|
ColumnLayout {
|
|
spacing: 15
|
|
|
|
Controls.OutlineButton {
|
|
text: qsTr("Read default settings")
|
|
Layout.fillWidth: true
|
|
onClicked: if (BmsInterface.isPortConnected()) {
|
|
BmsInterface.commands().getBMSconfDefault()
|
|
}
|
|
}
|
|
|
|
Controls.OutlineButton {
|
|
text: qsTr("Read current settings from BMS")
|
|
Layout.fillWidth: true
|
|
onClicked: if (BmsInterface.isPortConnected()) {
|
|
BmsInterface.commands().getBMSconf()
|
|
}
|
|
}
|
|
|
|
Controls.OutlineButton {
|
|
text: qsTr("Write current values to BMS")
|
|
Layout.fillWidth: true
|
|
onClicked: if (BmsInterface.isPortConnected()) {
|
|
writeValuesToConfig()
|
|
BmsInterface.commands().setBMSconf()
|
|
}
|
|
}
|
|
|
|
Controls.Button {
|
|
text: qsTr("Write to non-volatile memory of BMS")
|
|
Layout.fillWidth: true
|
|
onClicked: if (BmsInterface.isPortConnected()) {
|
|
needWait(true, qsTr("The settings are written to non-volatile memory.\nWait, please."))
|
|
writeValuesToConfig()
|
|
BmsInterface.commands().storeBMSConfig()
|
|
}
|
|
}
|
|
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
Layout.maximumWidth: 280
|
|
Layout.fillHeight: true
|
|
}
|
|
|
|
function writeValuesToConfig() {
|
|
BmsInterface.bmsConfig().setParamValue("notUsedCurrentThreshold", parseFloat(serialNumberField.text))
|
|
|
|
BmsInterface.bmsConfig().setParamValue("cellMonitorICCount", parseInt(numberOfBoardsField.text))
|
|
BmsInterface.bmsConfig().setParamValue("noOfCellsSeries", parseInt(numberOfCellsField.text))
|
|
|
|
BmsInterface.bmsConfig().setParamValue("noOfCellsParallel", parseInt(numberOfParallelCellsField.text))
|
|
BmsInterface.bmsConfig().setParamValue("batteryCapacity", parseFloat(batteryCapacityField.text))
|
|
|
|
BmsInterface.bmsConfig().setParamValue("maxAllowedCurrent", parseFloat(maximumChargeCurrentField.text))
|
|
BmsInterface.bmsConfig().setParamValue("maxMismatchThreshold", parseFloat(maximumLoadCurrentField.text))
|
|
BmsInterface.bmsConfig().setParamValue("allowedTempBattChargingMax", parseFloat(maximumTemperatureField.text))
|
|
|
|
BmsInterface.bmsConfig().setParamValue("cellHardUnderVoltage", parseFloat(lowerDisableThresholdField.text))
|
|
BmsInterface.bmsConfig().setParamValue("cellHardOverVoltage", parseFloat(upperDisableThresholdField.text))
|
|
BmsInterface.bmsConfig().setParamValue("cellLCSoftUnderVoltage", parseFloat(lowerEnableThresholdField.text))
|
|
BmsInterface.bmsConfig().setParamValue("cellSoftOverVoltage", parseFloat(upperEnableThresholdField.text))
|
|
|
|
BmsInterface.bmsConfig().setParamValue("cellBalanceStart", parseFloat(balancingStartVoltageField.text))
|
|
BmsInterface.bmsConfig().setParamValue("cellBalanceDifferenceThreshold", parseFloat(balancingStartDeltaVoltageField.text))
|
|
BmsInterface.bmsConfig().setParamValue("cellBalanceUpdateInterval", parseInt(balancingCellIntervalField.text))
|
|
|
|
BmsInterface.bmsConfig().setParamValue("shuntLCFactor", parseFloat(zeroSensorValueField.text))
|
|
}
|
|
|
|
Connections {
|
|
target: BmsInterface.bmsConfig()
|
|
onUpdated: {
|
|
serialNumberField.text = Number(BmsInterface.bmsConfig().getParamDouble("notUsedCurrentThreshold")).toFixed()
|
|
|
|
numberOfBoardsField.text = BmsInterface.bmsConfig().getParamInt("cellMonitorICCount")
|
|
numberOfCellsField.text = BmsInterface.bmsConfig().getParamInt("noOfCellsSeries")
|
|
|
|
numberOfParallelCellsField.text = BmsInterface.bmsConfig().getParamInt("noOfCellsParallel")
|
|
batteryCapacityField.text = MathHelper.roundDouble(BmsInterface.bmsConfig().getParamDouble("batteryCapacity"))
|
|
|
|
maximumChargeCurrentField.text = MathHelper.roundDouble(BmsInterface.bmsConfig().getParamDouble("maxAllowedCurrent"))
|
|
maximumLoadCurrentField.text = MathHelper.roundDouble(BmsInterface.bmsConfig().getParamDouble("maxMismatchThreshold"))
|
|
maximumTemperatureField.text = MathHelper.roundDouble(BmsInterface.bmsConfig().getParamDouble("allowedTempBattChargingMax"))
|
|
|
|
lowerDisableThresholdField.text = MathHelper.roundDouble(BmsInterface.bmsConfig().getParamDouble("cellHardUnderVoltage"))
|
|
upperDisableThresholdField.text = MathHelper.roundDouble(BmsInterface.bmsConfig().getParamDouble("cellHardOverVoltage"))
|
|
lowerEnableThresholdField.text = MathHelper.roundDouble(BmsInterface.bmsConfig().getParamDouble("cellLCSoftUnderVoltage"))
|
|
upperEnableThresholdField.text = MathHelper.roundDouble(BmsInterface.bmsConfig().getParamDouble("cellSoftOverVoltage"))
|
|
|
|
balancingStartVoltageField.text = MathHelper.roundDouble(BmsInterface.bmsConfig().getParamDouble("cellBalanceStart"))
|
|
balancingStartDeltaVoltageField.text = MathHelper.roundDouble(BmsInterface.bmsConfig().getParamDouble("cellBalanceDifferenceThreshold"))
|
|
balancingCellIntervalField.text = BmsInterface.bmsConfig().getParamInt("cellBalanceUpdateInterval")
|
|
|
|
zeroSensorValueField.text = MathHelper.roundDouble(BmsInterface.bmsConfig().getParamDouble("shuntLCFactor"))
|
|
}
|
|
}
|
|
}
|