Skip to content

Commit 5dc0140

Browse files
izakblammit
authored andcommitted
PV inverters: menu for additional PV-inverter modbus settings
This adds a menu for adding additional port and unit ID settings for PV-inverters. victronenergy/venus#1531
1 parent 161a9ee commit 5dc0140

File tree

4 files changed

+184
-0
lines changed

4 files changed

+184
-0
lines changed

cmake/ModuleVenus_Sources.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,8 +373,10 @@ set (VictronVenusOS_QML_MODULE_SOURCES
373373
pages/settings/PageSettingsFirmwareOffline.qml
374374
pages/settings/PageSettingsFirmwareOnline.qml
375375
pages/settings/PageSettingsFronius.qml
376+
pages/settings/PageSettingsFroniusAddLocation.qml
376377
pages/settings/PageSettingsFroniusInverter.qml
377378
pages/settings/PageSettingsFroniusInverters.qml
379+
pages/settings/PageSettingsFroniusModbus.qml
378380
pages/settings/PageSettingsFroniusSetIpAddresses.qml
379381
pages/settings/PageSettingsFroniusShowIpAddresses.qml
380382
pages/settings/PageSettingsGeneral.qml

pages/settings/PageSettingsFronius.qml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ Page {
6262
text: CommonWords.automatic_scanning
6363
dataItem.uid: Global.systemSettings.serviceUid + "/Settings/Fronius/AutoScan"
6464
}
65+
66+
ListNavigation {
67+
//% "Modbus port and unit ID settings"
68+
text: qsTrId("page_settings_fronius_modbus_settings")
69+
onClicked: Global.pageManager.pushPage("/pages/settings/PageSettingsFroniusModbus.qml", {"title": text})
70+
}
6571
}
6672
}
6773
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
** Copyright (C) 2025 Victron Energy B.V.
3+
** See LICENSE.txt for license information.
4+
*/
5+
6+
import QtQuick
7+
import Victron.VenusOS
8+
9+
Page {
10+
id: root
11+
12+
property VeQuickItem locations
13+
14+
//% "Add Modbus port and unit ID"
15+
title: qsTrId("page_settings_fronius_add_modbus_location")
16+
17+
GradientListView {
18+
model: VisibleItemModel {
19+
20+
ListPortField {
21+
id: port
22+
secondaryText: "1502"
23+
}
24+
25+
ListIntField {
26+
id: unit
27+
28+
//% "Unit ID"
29+
text: qsTrId("page_settings_fronius_add_modbus_unitid")
30+
secondaryText: "1"
31+
validateInput: function() {
32+
const valueAsInt = parseInt(textField.text)
33+
if (isNaN(valueAsInt) || valueAsInt <= 0 || valueAsInt > 247) {
34+
//% "%1 is not a valid unit number. Use a number between 1-247."
35+
return Utils.validationResult(VenusOS.InputValidation_Result_Error, qsTrId("page_settings_fronius_unitid_invalid").arg(textField.text))
36+
}
37+
return Utils.validationResult(VenusOS.InputValidation_Result_OK, "", valueAsInt)
38+
}
39+
}
40+
41+
ListButton {
42+
//% "Add"
43+
secondaryText: qsTrId("page_settings_fronius_add_modbus_location_button")
44+
onClicked: {
45+
const fields = [port, unit]
46+
for (let i = 0; i < fields.length; ++i) {
47+
const resultStatus = fields[i].runValidation(VenusOS.InputValidation_ValidateAndSave)
48+
if (resultStatus !== VenusOS.InputValidation_Result_OK) {
49+
return
50+
}
51+
}
52+
53+
let s = [port.secondaryText, unit.secondaryText].join(':');
54+
if (locations.value && locations.value.length) {
55+
s = locations.value + ',' + s;
56+
}
57+
58+
locations.setValue(s);
59+
Global.pageManager.popPage()
60+
}
61+
}
62+
}
63+
}
64+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
** Copyright (C) 2025 Victron Energy B.V.
3+
** See LICENSE.txt for license information.
4+
*/
5+
6+
import QtQuick
7+
import Victron.VenusOS
8+
9+
Page {
10+
id: root
11+
12+
property string settings: Global.systemSettings.serviceUid
13+
14+
topRightButton: Global.systemSettings.canAccess(VenusOS.User_AccessType_Installer)
15+
? VenusOS.StatusBar_RightButton_Add
16+
: VenusOS.StatusBar_RightButton_None
17+
18+
Connections {
19+
target: Global.mainView?.statusBar ?? null
20+
enabled: root.isCurrentPage
21+
22+
function onRightButtonClicked() {
23+
Global.pageManager.pushPage("/pages/settings/PageSettingsFroniusAddLocation.qml", { locations: _locations } )
24+
}
25+
}
26+
27+
VeQuickItem {
28+
id: _locations
29+
30+
uid: root.settings + "/Settings/Fronius/ModbusAlternates"
31+
// eg: [[1501,1],[1502,2]]
32+
}
33+
34+
35+
GradientListView {
36+
header: PrimaryListLabel {
37+
horizontalAlignment: Text.AlignHCenter
38+
//% "The default modbus port is 502 and the default unit ID is 126.\n"
39+
//% "Here you can add additional ports and unit IDs to scan for PV inverters."
40+
text: qsTrId("page_settings_fronius_modbus_locations_note")
41+
}
42+
model: _locations.value ? _locations.value.split(',') : []
43+
delegate: ListItem {
44+
id: locationDelegate
45+
46+
property int locationNumber: index + 1
47+
property var modbusAlternates: modelData.split(':')
48+
49+
//% "Port/Unit ID %1"
50+
text: qsTrId("page_settings_fronius_modbus_location_number").arg(locationNumber)
51+
content.spacing: 30
52+
content.children: [
53+
Label {
54+
id: portNumber
55+
56+
anchors.verticalCenter: parent?.verticalCenter
57+
text: modbusAlternates[0].toUpperCase() // eg. '1501'
58+
},
59+
Label {
60+
id: unitAddress
61+
62+
anchors.verticalCenter: parent?.verticalCenter
63+
text: modbusAlternates[1] // unit address
64+
},
65+
RemoveButton {
66+
id: removeButton
67+
visible: locationDelegate.clickable
68+
onClicked: {
69+
Global.dialogLayer.open(removeLocationDialog, {
70+
modbusLocation: modelData,
71+
//% "Port: %1 (Unit %2)"
72+
description: qsTrId("page_settings_fronius_modbus_remove_location_description")
73+
.arg(portNumber.text)
74+
.arg(unitAddress.text)
75+
})
76+
}
77+
}
78+
]
79+
80+
interactive: true
81+
writeAccessLevel: VenusOS.User_AccessType_Installer
82+
onClicked: removeButton.clicked()
83+
}
84+
}
85+
86+
Component {
87+
id: removeLocationDialog
88+
89+
ModalWarningDialog {
90+
91+
property var modbusLocation
92+
93+
//% "Remove Modbus port and unit ID?"
94+
title: qsTrId("page_settings_fronius_modbus_remove_location")
95+
dialogDoneOptions: VenusOS.ModalDialog_DoneOptions_OkAndCancel
96+
height: Theme.geometry_modalDialog_height_small
97+
icon.color: Theme.color_orange
98+
acceptText: CommonWords.remove
99+
100+
onAccepted: {
101+
const locations = _locations.value ? _locations.value.split(',') : []
102+
for (let i = 0; i < locations.length; ++i) {
103+
if (locations[i] === modbusLocation) {
104+
locations.splice(i, 1)
105+
_locations.setValue(locations.join(','))
106+
break
107+
}
108+
}
109+
}
110+
}
111+
}
112+
}

0 commit comments

Comments
 (0)