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 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 {} 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 validator: DoubleValidator {} Layout.fillWidth: true Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2 } Controls.TextField { id: maximumLoadCurrentField validator: DoubleValidator {} 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 validator: DoubleValidator {} 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 validator: DoubleValidator {} Layout.fillWidth: true Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2 } Controls.TextField { id: upperShutdownThresholdField validator: DoubleValidator {} 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 validator: DoubleValidator {} Layout.fillWidth: true Layout.maximumWidth: (parent.width - parent.columnSpacing) / 2 } Controls.TextField { id: balancingStartDeltaVoltageField validator: DoubleValidator {} 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 validator: DoubleValidator {} 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 onClicked: BmsInterface.commands().getBMSconfDefault() } Controls.OutlineButton { text: qsTr("Read current settings from BMS") Layout.fillWidth: true onClicked: BmsInterface.commands().getBMSconf() } 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 } Connections { target: BmsInterface.bmsConfig() onUpdated: { serialNumberField.text = BmsInterface.bmsConfig().getParamDouble("notUsedCurrentThreshold") numberOfBoardsField.text = BmsInterface.bmsConfig().getParamInt("cellMonitorICCount") numberOfCellsField.text = BmsInterface.bmsConfig().getParamInt("noOfCellsSeries") numberOfParallelCellsField.text = BmsInterface.bmsConfig().getParamInt("noOfCellsParallel") batteryCapacityField.text = BmsInterface.bmsConfig().getParamDouble("batteryCapacity") maximumChargeCurrentField.text = BmsInterface.bmsConfig().getParamDouble("maxAllowedCurrent") maximumLoadCurrentField.text = BmsInterface.bmsConfig().getParamDouble("maxMismatchThreshold") maximumTemperatureField.text = BmsInterface.bmsConfig().getParamDouble("allowedTempBattChargingMax") // TODO lowerShutdownThresholdField.text = BmsInterface.bmsConfig().getParamDouble("cellHardUnderVoltage") upperShutdownThresholdField.text = BmsInterface.bmsConfig().getParamDouble("cellHardOverVoltage") // TODO balancingStartVoltageField.text = BmsInterface.bmsConfig().getParamDouble("cellBalanceStart") balancingStartDeltaVoltageField.text = BmsInterface.bmsConfig().getParamDouble("cellBalanceDifferenceThreshold") zeroSensorValueField.text = BmsInterface.bmsConfig().getParamDouble("shuntLCFactor") } } Connections { target: BmsInterface onPortConnectedChanged: getValues() } onVisibleChanged: getValues() function getValues() { if (BmsInterface.isPortConnected() && visible) { BmsInterface.commands().getBMSconf() } } }