613 lines
22 KiB
QML
613 lines
22 KiB
QML
import QtQuick 2.12
|
|
import QtQuick.Controls 2.12
|
|
import QtQuick.Layouts 1.12
|
|
|
|
import Controls 1.0 as Controls
|
|
import Cubo 1.0
|
|
|
|
RowLayout {
|
|
property real contentPadding: 35
|
|
property real contentRowSpacing: 20
|
|
property real contentColumnSpacing: 35
|
|
|
|
spacing: contentColumnSpacing
|
|
|
|
Flickable {
|
|
id: settingsFlickable
|
|
clip: true
|
|
contentHeight: configLayout.height
|
|
|
|
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
|
|
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
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: numberOfCellsField
|
|
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
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: batteryCapacityField
|
|
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")
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.SubtitleLabel {
|
|
text: qsTr("Maximum load current, A")
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: maximumChargeCurrentField
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: maximumLoadCurrentField
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.SubtitleLabel {
|
|
text: qsTr("Maximum temperature, °C")
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
Layout.columnSpan: 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: maximumTemperatureField
|
|
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 shutdown threshold, V")
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.SubtitleLabel {
|
|
text: qsTr("Upper shutdown threshold, V")
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: lowerShutdownThresholdField
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: upperShutdownThresholdField
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
// TODO
|
|
// Controls.SubtitleLabel {
|
|
// text: qsTr("Lower shutdown threshold, V")
|
|
// Layout.fillWidth: true
|
|
// Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
// }
|
|
|
|
// Controls.SubtitleLabel {
|
|
// text: qsTr("Upper shutdown threshold, V")
|
|
// Layout.fillWidth: true
|
|
// Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
// }
|
|
|
|
// Controls.TextField {
|
|
// id: lowerShutdownThresholdField
|
|
// Layout.fillWidth: true
|
|
// Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
// }
|
|
|
|
// Controls.TextField {
|
|
// id: upperShutdownThresholdField
|
|
// 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
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2
|
|
}
|
|
|
|
Controls.TextField {
|
|
id: balancingStartDeltaVoltageField
|
|
Layout.fillWidth: true
|
|
Layout.maximumWidth: (parent.width - parent.columnSpacing) / 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 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")
|
|
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
|
|
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
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ScrollBar.vertical: Controls.ScrollBar {
|
|
// policy: ScrollBar.AlwaysOn
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
Item {
|
|
Layout.fillHeight: true
|
|
}
|
|
|
|
ColumnLayout {
|
|
spacing: 15
|
|
|
|
Controls.OutlineButton {
|
|
text: qsTr("Read settings from file")
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
Controls.OutlineButton {
|
|
text: qsTr("Read current settings from BMS")
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
Controls.OutlineButton {
|
|
text: qsTr("Write to non-volatile memory of BMS")
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
Controls.Button {
|
|
text: qsTr("Write current values to BMS")
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
Layout.maximumWidth: 320
|
|
Layout.fillHeight: true
|
|
}
|
|
}
|