diff --git a/ExtTransferSwitch.py b/ExtTransferSwitch.py index 28d8c660..ea53dce5 100755 --- a/ExtTransferSwitch.py +++ b/ExtTransferSwitch.py @@ -29,26 +29,18 @@ import os import time import dbus - -dbusSettingsPath = "com.victronenergy.settings" -dbusSystemPath = "com.victronenergy.system" - - - -# accommodate both Python 2 and 3 -# if the Python 3 GLib import fails, import the Python 2 gobject -try: - from gi.repository import GLib # for Python 3 -except ImportError: - import gobject as GLib # for Python 2 - +from gi.repository import GLib # add the path to our own packages for import -# use an established Victron service to maintain compatiblity -sys.path.insert(1, os.path.join('/opt/victronenergy/dbus-systemcalc-py', 'ext', 'velib_python')) +sys.path.insert(1, "/data/SetupHelper/velib_python") from vedbus import VeDbusService from ve_utils import wrap_dbus_value from settingsdevice import SettingsDevice + +dbusSettingsPath = "com.victronenergy.settings" +dbusSystemPath = "com.victronenergy.system" + + class Monitor: def getVeBusObjects (self): diff --git a/FileSets/PatchSource/Battery.qml-v3.40~32 b/FileSets/PatchSource/Battery.qml-v3.34 similarity index 100% rename from FileSets/PatchSource/Battery.qml-v3.40~32 rename to FileSets/PatchSource/Battery.qml-v3.34 diff --git a/FileSets/PatchSource/Battery.qml-v3.40~32.orig b/FileSets/PatchSource/Battery.qml-v3.34.orig similarity index 100% rename from FileSets/PatchSource/Battery.qml-v3.40~32.orig rename to FileSets/PatchSource/Battery.qml-v3.34.orig diff --git a/FileSets/PatchSource/Battery.qml-v3.40~32.patch b/FileSets/PatchSource/Battery.qml-v3.34.patch similarity index 95% rename from FileSets/PatchSource/Battery.qml-v3.40~32.patch rename to FileSets/PatchSource/Battery.qml-v3.34.patch index 3e16a233..e81c0e2c 100644 --- a/FileSets/PatchSource/Battery.qml-v3.40~32.patch +++ b/FileSets/PatchSource/Battery.qml-v3.34.patch @@ -1,5 +1,5 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/Battery.qml-v3.40~32.orig 2024-07-09 10:19:41 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/Battery.qml-v3.40~32 2024-05-14 07:00:12 +--- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/Battery.qml-v3.34.orig 2024-07-09 10:19:41 ++++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/Battery.qml-v3.34 2024-05-14 07:00:12 @@ -6,9 +6,14 @@ width: 145 height: 101 diff --git a/FileSets/PatchSource/Battery.qml-v3.40~35 b/FileSets/PatchSource/Battery.qml-v3.40 similarity index 100% rename from FileSets/PatchSource/Battery.qml-v3.40~35 rename to FileSets/PatchSource/Battery.qml-v3.40 diff --git a/FileSets/PatchSource/Battery.qmlv3.40~35.orig b/FileSets/PatchSource/Battery.qmlv3.40.orig similarity index 100% rename from FileSets/PatchSource/Battery.qmlv3.40~35.orig rename to FileSets/PatchSource/Battery.qmlv3.40.orig diff --git a/FileSets/PatchSource/MbItemDigitalInput.qml-v2.94.patch b/FileSets/PatchSource/MbItemDigitalInput.qml-v2.94.patch deleted file mode 100644 index 0d330b9c..00000000 --- a/FileSets/PatchSource/MbItemDigitalInput.qml-v2.94.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/MbItemDigitalInput.qml-v2.94.orig 2024-07-09 10:19:46 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/MbItemDigitalInput.qml-v2.94 2024-03-07 00:11:36 -@@ -1,3 +1,5 @@ -+//// modified for ExtTransferSwitch package -+ - import QtQuick 1.1 - - MbItemOptions { -@@ -14,7 +16,10 @@ - MbOption { description: qsTr("Smoke alarm"); value: 6 }, - MbOption { description: qsTr("Fire alarm"); value: 7 }, - MbOption { description: qsTr("CO2 alarm"); value: 8 }, -- MbOption { description: qsTr("Generator"); value: 9 } -+ MbOption { description: qsTr("Generator"); value: 9 }, -+ MbOption { description: qsTr("Generic I/O"); value: 10 }, -+//// added for ExtTransferSwitch package -+ MbOption { description: qsTr("External transfer switch"); value: 11 } - ] - onValueChanged: { - if (valid) { diff --git a/FileSets/PatchSource/MbItemDigitalInput.qml-v3.40~35 b/FileSets/PatchSource/MbItemDigitalInput.qml-v3.40 similarity index 100% rename from FileSets/PatchSource/MbItemDigitalInput.qml-v3.40~35 rename to FileSets/PatchSource/MbItemDigitalInput.qml-v3.40 diff --git a/FileSets/PatchSource/MbItemDigitalInput.qml-v3.40~35.orig b/FileSets/PatchSource/MbItemDigitalInput.qml-v3.40.orig similarity index 100% rename from FileSets/PatchSource/MbItemDigitalInput.qml-v3.40~35.orig rename to FileSets/PatchSource/MbItemDigitalInput.qml-v3.40.orig diff --git a/FileSets/PatchSource/MbItemDigitalInput.qml-v3.40~35.patch b/FileSets/PatchSource/MbItemDigitalInput.qml-v3.40.patch similarity index 89% rename from FileSets/PatchSource/MbItemDigitalInput.qml-v3.40~35.patch rename to FileSets/PatchSource/MbItemDigitalInput.qml-v3.40.patch index b9e7ef1c..cbfd2dc7 100644 --- a/FileSets/PatchSource/MbItemDigitalInput.qml-v3.40~35.patch +++ b/FileSets/PatchSource/MbItemDigitalInput.qml-v3.40.patch @@ -1,5 +1,5 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/MbItemDigitalInput.qml-v3.40~35.orig 2024-07-09 10:19:45 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/MbItemDigitalInput.qml-v3.40~35 2024-05-14 07:00:12 +--- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/MbItemDigitalInput.qml-v3.40.orig 2024-07-09 10:19:45 ++++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/MbItemDigitalInput.qml-v3.40 2024-05-14 07:00:12 @@ -1,3 +1,5 @@ +//// modified for ExtTransferSwitch package + diff --git a/FileSets/PatchSource/MbSpinBox.qml-v2.73.patch b/FileSets/PatchSource/MbSpinBox.qml-v2.73.patch deleted file mode 100644 index e15cd8d5..00000000 --- a/FileSets/PatchSource/MbSpinBox.qml-v2.73.patch +++ /dev/null @@ -1,34 +0,0 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/MbSpinBox.qml-v2.73.orig 2024-07-09 10:19:46 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/MbSpinBox.qml-v2.73 2023-05-19 11:18:50 -@@ -1,3 +1,5 @@ -+////// GuiMods — added DarkMode -+ - import QtQuick 1.1 - import Qt.labs.components.native 1.0 - import com.victron.velib 1.0 -@@ -6,6 +8,10 @@ - id: root - cornerMark: !readOnly && !spinbox.enabled - -+////// GuiMods — DarkMode -+ property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } -+ property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 -+ - property bool valid: vItem.value !== undefined - property alias bind: vItem.bind - property string description -@@ -82,10 +88,12 @@ - - MbBackgroundRect { - id: graytag -- color: !spinbox.enabled? "#ddd": "#fff" -+////// GuiMods — DarkMode -+ color: !darkMode ? (!spinbox.enabled ? "#ddd": "#fff") : (!spinbox.enabled ? "#4b4b4b": "#747474") - height: spinbox.height + 6 - width: spinbox.width + unit.width + 10 -- border.color: "#ddd" -+////// GuiMods — DarkMode -+ border.color: !darkMode ? "#ddd" : "#4b4b4b" - border.width: spinbox.enabled ? 1 : 0 - anchors { - right: parent.right; rightMargin: style.marginDefault diff --git a/FileSets/PatchSource/MbSpinBox.qml-v2.89.patch b/FileSets/PatchSource/MbSpinBox.qml-v2.89.patch deleted file mode 100644 index 10f58d44..00000000 --- a/FileSets/PatchSource/MbSpinBox.qml-v2.89.patch +++ /dev/null @@ -1,34 +0,0 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/MbSpinBox.qml-v2.89.orig 2024-07-09 10:19:46 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/MbSpinBox.qml-v2.89 2023-05-19 11:20:34 -@@ -1,3 +1,5 @@ -+////// GuiMods — added DarkMode -+ - import QtQuick 1.1 - import Qt.labs.components.native 1.0 - import com.victron.velib 1.0 -@@ -6,6 +8,10 @@ - id: root - cornerMark: !readOnly && !spinbox.enabled - -+////// GuiMods — DarkMode -+ property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } -+ property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 -+ - property bool valid: vItem.value !== undefined - property alias bind: vItem.bind - property string description -@@ -82,10 +88,12 @@ - - MbBackgroundRect { - id: graytag -- color: !spinbox.enabled? "#ddd": "#fff" -+////// GuiMods — DarkMode -+ color: !darkMode ? (!spinbox.enabled ? "#ddd": "#fff") : (!spinbox.enabled ? "#4b4b4b": "#747474") - height: spinbox.height + 6 - width: spinbox.width + unit.width + 10 -- border.color: "#ddd" -+////// GuiMods — DarkMode -+ border.color: !darkMode ? "#ddd" : "#4b4b4b" - border.width: spinbox.enabled ? 1 : 0 - anchors { - right: parent.right; rightMargin: style.marginDefault diff --git a/FileSets/PatchSource/MbSpinBox.qml-v3.40~35 b/FileSets/PatchSource/MbSpinBox.qml-v3.40 similarity index 100% rename from FileSets/PatchSource/MbSpinBox.qml-v3.40~35 rename to FileSets/PatchSource/MbSpinBox.qml-v3.40 diff --git a/FileSets/PatchSource/MbSpinBox.qml-v3.40~35.orig b/FileSets/PatchSource/MbSpinBox.qml-v3.40.orig similarity index 100% rename from FileSets/PatchSource/MbSpinBox.qml-v3.40~35.orig rename to FileSets/PatchSource/MbSpinBox.qml-v3.40.orig diff --git a/FileSets/PatchSource/MbSpinBox.qml.patch b/FileSets/PatchSource/MbSpinBox.qml-v3.40.patch similarity index 93% rename from FileSets/PatchSource/MbSpinBox.qml.patch rename to FileSets/PatchSource/MbSpinBox.qml-v3.40.patch index 0a5a54e2..3619383c 100644 --- a/FileSets/PatchSource/MbSpinBox.qml.patch +++ b/FileSets/PatchSource/MbSpinBox.qml-v3.40.patch @@ -1,5 +1,5 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/MbSpinBox.qml.orig 2024-07-09 10:19:46 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/MbSpinBox.qml 2024-05-14 07:00:12 +--- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/MbSpinBox.qml-v3.40.orig 2024-07-09 10:19:46 ++++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/MbSpinBox.qml-v3.40 2024-05-14 07:00:12 @@ -6,6 +6,10 @@ id: root cornerMark: !readOnly && !spinbox.enabled diff --git a/FileSets/PatchSource/MbSpinBox.qml-v3.40~35.patch b/FileSets/PatchSource/MbSpinBox.qml-v3.40~35.patch deleted file mode 100644 index cc6ede5d..00000000 --- a/FileSets/PatchSource/MbSpinBox.qml-v3.40~35.patch +++ /dev/null @@ -1,28 +0,0 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/MbSpinBox.qml-v3.40~35.orig 2024-07-09 10:19:46 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/MbSpinBox.qml-v3.40~35 2024-05-14 07:00:12 -@@ -6,6 +6,10 @@ - id: root - cornerMark: !readOnly && !spinbox.enabled - -+////// GuiMods — DarkMode -+ property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } -+ property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 -+ - property string description - property bool readOnly: !userHasWriteAccess - property VBusItem item: VBusItem { -@@ -71,10 +75,12 @@ - - MbBackgroundRect { - id: graytag -- color: !spinbox.enabled? "#ddd": "#fff" -+////// GuiMods — DarkMode -+ color: !darkMode ? (!spinbox.enabled ? "#ddd": "#fff") : (!spinbox.enabled ? "#4b4b4b": "#747474") - height: spinbox.height + 6 - width: spinbox.width + unit.width + 10 -- border.color: "#ddd" -+////// GuiMods — DarkMode -+ border.color: !darkMode ? "#ddd" : "#4b4b4b" - border.width: spinbox.enabled ? 1 : 0 - anchors { - right: parent.right; rightMargin: style.marginDefault diff --git a/FileSets/PatchSource/MbStyle.qml-v2.94.patch b/FileSets/PatchSource/MbStyle.qml-v2.94.patch deleted file mode 100644 index 32217185..00000000 --- a/FileSets/PatchSource/MbStyle.qml-v2.94.patch +++ /dev/null @@ -1,43 +0,0 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/MbStyle.qml-v2.94.orig 2024-07-09 10:19:47 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/MbStyle.qml-v2.94 2023-05-19 11:06:05 -@@ -4,6 +4,10 @@ - * common style properties - */ - QtObject { -+////// GuiMods — DarkMode -+ property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } -+ property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 -+ - property bool isCurrentItem - - // Default MbItem size -@@ -13,19 +17,22 @@ - property string fontFamily: "DejaVu Sans Condensed" - property int fontPixelSize: 16 - -- property string borderColor: "#ddd" -- property string backgroundColor: isCurrentItem ? '#4790d0' : 'transparent' -- property string backgroundColorService: isCurrentItem ? "#2969a1" : '#ffe9b7' -+////// GuiMods — DarkMode -+ property string borderColor: !darkMode ? "#ddd" : "#4b4b4b" -+ property string backgroundColor: isCurrentItem ? (!darkMode ? '#4790d0' : '#234468') : 'transparent' -+ property string backgroundColorService: !darkMode ? (isCurrentItem ? "#2969a1" : '#ffe9b7') : (isCurrentItem ? "#234468" : '#7f745b') - property string backgroundColorComponent: borderColor - - // Text mainly used for description etc. -- property string textColor: "#000000" -- property string textColorSelected: "#FFFFFF" -+////// GuiMods — DarkMode -+ property string textColor: !darkMode ? "#000000" : "#fdfdfd" -+ property string textColorSelected: !darkMode ? "#FFFFFF" : "#fdfdfd" - - // Color typically used for values -- property string valueColor: "#333333" -+////// GuiMods — DarkMode -+ property string valueColor: !darkMode ? "#333333" : "#fdfdfd" - property int valueHorizontalAlignment: Text.AlignRight -- property string color2: "#333333" -+ property string color2: !darkMode ? "#333333" : "#fdfdfd" - - property int marginDefault: 8 - // margin between MbItem border and components for bottom / top diff --git a/FileSets/PatchSource/MbStyle.qml-v3.40~35 b/FileSets/PatchSource/MbStyle.qml-v3.40 similarity index 100% rename from FileSets/PatchSource/MbStyle.qml-v3.40~35 rename to FileSets/PatchSource/MbStyle.qml-v3.40 diff --git a/FileSets/PatchSource/MbStyle.qml-v3.40~35.orig b/FileSets/PatchSource/MbStyle.qml-v3.40.orig similarity index 100% rename from FileSets/PatchSource/MbStyle.qml-v3.40~35.orig rename to FileSets/PatchSource/MbStyle.qml-v3.40.orig diff --git a/FileSets/PatchSource/MbStyle.qml-v3.40~35.patch b/FileSets/PatchSource/MbStyle.qml-v3.40.patch similarity index 96% rename from FileSets/PatchSource/MbStyle.qml-v3.40~35.patch rename to FileSets/PatchSource/MbStyle.qml-v3.40.patch index b3c172e3..3e0e0033 100644 --- a/FileSets/PatchSource/MbStyle.qml-v3.40~35.patch +++ b/FileSets/PatchSource/MbStyle.qml-v3.40.patch @@ -1,5 +1,5 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/MbStyle.qml-v3.40~35.orig 2024-07-09 10:19:46 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/MbStyle.qml-v3.40~35 2024-05-14 07:00:12 +--- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/MbStyle.qml-v3.40.orig 2024-07-09 10:19:46 ++++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/MbStyle.qml-v3.40 2024-05-14 07:00:12 @@ -4,6 +4,10 @@ * common style properties */ diff --git a/FileSets/PatchSource/PageMain.qml-v2.94.patch b/FileSets/PatchSource/PageMain.qml-v2.94.patch deleted file mode 100644 index 4209a340..00000000 --- a/FileSets/PatchSource/PageMain.qml-v2.94.patch +++ /dev/null @@ -1,120 +0,0 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/PageMain.qml-v2.94.orig 2024-06-23 12:13:50 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/PageMain.qml-v2.94 2024-07-09 10:17:55 -@@ -1,11 +1,49 @@ -+//////// modified order to put Settings, then Notifications at top of list -+ - import QtQuick 1.1 -+import "utils.js" as Utils - import com.victron.velib 1.0 - - MbPage { - id: root - title: qsTr("Device List") -+ property VBusItem moveSettings: VBusItem { id: moveSettings; bind: Utils.path("com.victronenergy.settings", "/Settings/GuiMods/MoveSettings")} -+ property bool settingsAtTop: moveSettings.valid && moveSettings.value === 1 - - model: VisualModels { -+//////// put Settings at top of list -+ VisualItemModel { //////// use VisualItemModel below for v2.93 and earlier -+ MbSubMenu { -+ description: qsTr("Settings") -+ subpage: Component { PageSettings {} } -+ show: settingsAtTop -+ } -+ -+//////// put Notifications second -+ MbSubMenu { -+ id: menuNotificationsTop -+ description: qsTr("Notifications") -+ item: VBusItem { -+ property variant active: NotificationCenter.notifications.filter( -+ function isActive(obj) { return obj.active} ) -+ value: active.length > 0 ? active.length : "" -+ } -+ subpage: Component { PageNotifications {} } -+ show: settingsAtTop -+ } -+ -+ MbOK { -+ description: qsTr("Remove disconnected devices") -+ value: qsTr("Press to remove") -+ show: settingsAtTop && deviceList.disconnectedDevices != 0 -+ editable: true -+ -+ function clicked() { -+ listview.decrementCurrentIndex() -+ deviceList.removeDisconnected() -+ } -+ } -+ } - VisualDataModel { - model: VeSortFilterProxyModel { - model: DeviceList { -@@ -27,37 +65,40 @@ - subpage: model.page - } - } -- VisualItemModel { -- MbSubMenu { -- id: menuNotifications -- description: qsTr("Notifications") -- item: VBusItem { -- property variant active: NotificationCenter.notifications.filter( -- function isActive(obj) { return obj.active} ) -- value: active.length > 0 ? active.length : "" -- } -- subpage: Component { PageNotifications {} } -- } - -- MbSubMenu { -- description: qsTr("Settings") -- subpage: Component { PageSettings {} } -- } -+ VisualItemModel { //////// use VisualItemModel below for v2.93 and earlier -+ MbSubMenu { -+ id: menuNotifications -+ description: qsTr("Notifications") -+ item: VBusItem { -+ property variant active: NotificationCenter.notifications.filter( -+ function isActive(obj) { return obj.active} ) -+ value: active.length > 0 ? active.length : "" -+ } -+ subpage: Component { PageNotifications {} } -+ show: !settingsAtTop -+ } - -- MbOK { -- description: qsTr("Remove disconnected devices") -- value: qsTr("Press to remove") -- show: deviceList.disconnectedDevices != 0 -- editable: true -+ MbSubMenu { -+ description: qsTr("Settings") -+ subpage: Component { PageSettings {} } -+ show: !settingsAtTop -+ } - -- function clicked() { -- listview.decrementCurrentIndex() -- deviceList.removeDisconnected() -- } -- } -- } -- } -+ MbOK { -+ description: qsTr("Remove disconnected devices") -+ value: qsTr("Press to remove") -+ show: !settingsAtTop && deviceList.disconnectedDevices != 0 -+ editable: true - -+ function clicked() { -+ listview.decrementCurrentIndex() -+ deviceList.removeDisconnected() -+ } -+ } -+ } -+ } -+ - Component { - id: vebusPage - PageVebus {} diff --git a/FileSets/PatchSource/PageMain.qml-v3.40~13 b/FileSets/PatchSource/PageMain.qml-v3.34 similarity index 100% rename from FileSets/PatchSource/PageMain.qml-v3.40~13 rename to FileSets/PatchSource/PageMain.qml-v3.34 diff --git a/FileSets/PatchSource/PageMain.qml-v3.40~13.orig b/FileSets/PatchSource/PageMain.qml-v3.34.orig similarity index 100% rename from FileSets/PatchSource/PageMain.qml-v3.40~13.orig rename to FileSets/PatchSource/PageMain.qml-v3.34.orig diff --git a/FileSets/PatchSource/PageMain.qml-v3.40~13.patch b/FileSets/PatchSource/PageMain.qml-v3.34.patch similarity index 97% rename from FileSets/PatchSource/PageMain.qml-v3.40~13.patch rename to FileSets/PatchSource/PageMain.qml-v3.34.patch index f9d33465..10ff3252 100644 --- a/FileSets/PatchSource/PageMain.qml-v3.40~13.patch +++ b/FileSets/PatchSource/PageMain.qml-v3.34.patch @@ -1,5 +1,5 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/PageMain.qml-v3.40~13.orig 2024-07-08 09:45:00 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/PageMain.qml-v3.40~13 2024-07-09 09:53:47 +--- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/PageMain.qml-v3.34.orig 2024-07-08 09:45:00 ++++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/PageMain.qml-v3.34 2024-07-09 09:53:47 @@ -1,11 +1,48 @@ +//////// GuiMods modified order to put Settings, then Notifications at top of list + diff --git a/FileSets/PatchSource/PageMain.qml-v3.40~35 b/FileSets/PatchSource/PageMain.qml-v3.40 similarity index 100% rename from FileSets/PatchSource/PageMain.qml-v3.40~35 rename to FileSets/PatchSource/PageMain.qml-v3.40 diff --git a/FileSets/PatchSource/PageMain.qml-v3.40~35.orig b/FileSets/PatchSource/PageMain.qml-v3.40.orig similarity index 100% rename from FileSets/PatchSource/PageMain.qml-v3.40~35.orig rename to FileSets/PatchSource/PageMain.qml-v3.40.orig diff --git a/FileSets/PatchSource/PageMain.qml-v3.40~35.patch b/FileSets/PatchSource/PageMain.qml-v3.40.patch similarity index 97% rename from FileSets/PatchSource/PageMain.qml-v3.40~35.patch rename to FileSets/PatchSource/PageMain.qml-v3.40.patch index d5c785ca..8357d94c 100644 --- a/FileSets/PatchSource/PageMain.qml-v3.40~35.patch +++ b/FileSets/PatchSource/PageMain.qml-v3.40.patch @@ -1,5 +1,5 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/PageMain.qml-v3.40~35.orig 2024-07-08 09:45:00 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/PageMain.qml-v3.40~35 2024-07-09 09:55:28 +--- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/PageMain.qml-v3.40.orig 2024-07-08 09:45:00 ++++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/PageMain.qml-v3.40 2024-07-09 09:55:28 @@ -1,11 +1,48 @@ +//////// GuiMods modified order to put Settings, then Notifications at top of list + diff --git a/FileSets/PatchSource/PageSettingsDisplay.qml-v2.89.patch b/FileSets/PatchSource/PageSettingsDisplay.qml-v2.89.patch deleted file mode 100644 index 130db145..00000000 --- a/FileSets/PatchSource/PageSettingsDisplay.qml-v2.89.patch +++ /dev/null @@ -1,55 +0,0 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/PageSettingsDisplay.qml-v2.89.orig 2024-07-09 10:19:58 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/PageSettingsDisplay.qml-v2.89 2024-03-31 14:23:34 -@@ -1,10 +1,11 @@ -+//////// modified to add GuiMods controls - import QtQuick 1.1 - import com.victron.velib 1.0 - import "utils.js" as Utils - - MbPage { - id: root -- property string bindPrefix: "com.victronenergy.settings/Settings/Gui" -+ property string bindPrefix: "com.victronenergy.settings/Settings/Gui" - - model: VisualItemModel { - MbSwitch { -@@ -52,19 +53,37 @@ - ] - } - -+ -+////// GuiMods — DarkMode -+ MbSwitch -+ { -+ id: enableDarkMode -+ bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" -+ name: qsTr ("Dark Mode") -+ writeAccessLevel: User.AccessUser -+ } -+ - MbSwitch { - bind: Utils.path(bindPrefix, "/MobileOverview") - name: qsTr("Show boat & motorhome overview") - // When enabled set OverviewMobile as default overview - onClicked: if (checked) defaultOverview.setValue("OverviewMobile") -- VBusItem { id: defaultOverview; bind: "com.victronenergy.settings/Settings/Gui/DefaultOverview" } -+ VBusItem { id: defaultOverview; bind: "com.victronenergy.settings/Settings/Gui/DefaultOverview" } - } -- - MbSwitch { - bind: Utils.path(bindPrefix, "/TanksOverview") - name: qsTr("Show tanks overview") - } - -+//////// add Gui Mods menu -+ MbSubMenu { -+ id: guiModsMenu -+ description: qsTr("Gui Mods") -+ subpage: Component { -+ PageSettingsGuiMods { } -+ } -+ } -+ - MbItemOptions { - id: languageSelect - description: qsTr("Language") diff --git a/FileSets/PatchSource/PageSettingsDisplay.qml-v2.94.patch b/FileSets/PatchSource/PageSettingsDisplay.qml-v2.94.patch deleted file mode 100644 index 48a1e49e..00000000 --- a/FileSets/PatchSource/PageSettingsDisplay.qml-v2.94.patch +++ /dev/null @@ -1,40 +0,0 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/PageSettingsDisplay.qml-v2.94.orig 2024-07-09 10:19:58 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/PageSettingsDisplay.qml-v2.94 2023-05-19 11:06:05 -@@ -1,3 +1,5 @@ -+//////// modified to add GuiMods controls -+ - import QtQuick 1.1 - import com.victron.velib 1.0 - import "utils.js" as Utils -@@ -52,6 +54,15 @@ - ] - } - -+////// GuiMods — DarkMode -+ MbSwitch -+ { -+ id: enableDarkMode -+ bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" -+ name: qsTr ("Dark Mode") -+ writeAccessLevel: User.AccessUser -+ } -+ - MbSwitch { - bind: Utils.path(bindPrefix, "/MobileOverview") - name: qsTr("Show boat & motorhome overview") -@@ -65,6 +76,15 @@ - name: qsTr("Show tanks overview") - } - -+//////// add Gui Mods menu -+ MbSubMenu { -+ id: guiModsMenu -+ description: qsTr("Gui Mods") -+ subpage: Component { -+ PageSettingsGuiMods { } -+ } -+ } -+ - MbItemOptions { - id: languageSelect - description: qsTr("Language") diff --git a/FileSets/PatchSource/PageSettingsDisplay.qml-v3.01.patch b/FileSets/PatchSource/PageSettingsDisplay.qml-v3.01.patch deleted file mode 100644 index c293197c..00000000 --- a/FileSets/PatchSource/PageSettingsDisplay.qml-v3.01.patch +++ /dev/null @@ -1,58 +0,0 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/PageSettingsDisplay.qml-v3.01.orig 2024-07-09 10:19:58 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/PageSettingsDisplay.qml-v3.01 2023-11-21 21:35:51 -@@ -1,3 +1,5 @@ -+//////// modified to add GuiMods controls -+ - import QtQuick 1.1 - import com.victron.velib 1.0 - import "utils.js" as Utils -@@ -52,6 +54,15 @@ - ] - } - -+////// GuiMods — DarkMode -+ MbSwitch -+ { -+ id: colorScheme -+ bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" -+ name: qsTr ("Dark Mode") -+ writeAccessLevel: User.AccessUser -+ } -+ - MbSwitch { - bind: Utils.path(bindPrefix, "/MobileOverview") - name: qsTr("Show boat & motorhome overview") -@@ -65,12 +76,20 @@ - name: qsTr("Show tanks overview") - } - -+//////// add Gui Mods menu -+ MbSubMenu { -+ id: guiModsMenu -+ description: qsTr("Gui Mods") -+ subpage: Component { -+ PageSettingsGuiMods { } -+ } -+ } -+ - MbItemOptions { - id: languageSelect - description: qsTr("Language") - writeAccessLevel: User.AccessUser - bind: Utils.path(bindPrefix, "/Language") -- - // NOTE: do make sure application.cpp returns the correct fontForLanguage. - // The current font might not be able to display these values / the default - // font might not be contain the characters required for the selected language. -@@ -83,11 +102,9 @@ - MbOptionLang { description: "Français"; value: "fr" }, - MbOptionLang { description: "Italiano"; value: "it" }, - MbOptionLang { description: "Nederlands"; value: "nl" }, -- MbOptionLang { description: "Polski"; value: "pl" }, - MbOptionLang { description: "Русский"; value: "ru" }, - MbOptionLang { description: "Română"; value: "ro" }, - MbOptionLang { description: "Svenska"; value: "se" }, -- MbOptionLang { description: "ไทย"; value: "th" }, - MbOptionLang { description: "Türkçe"; value: "tr" }, - MbOptionLang { description: "中文"; value: "zh" }, - MbOptionLang { description: "العربية"; value: "ar" } diff --git a/FileSets/PatchSource/PageSettingsDisplay.qml-v3.40~35 b/FileSets/PatchSource/PageSettingsDisplay.qml-v3.40 similarity index 100% rename from FileSets/PatchSource/PageSettingsDisplay.qml-v3.40~35 rename to FileSets/PatchSource/PageSettingsDisplay.qml-v3.40 diff --git a/FileSets/PatchSource/PageSettingsDisplay.qml-v3.40~35.orig b/FileSets/PatchSource/PageSettingsDisplay.qml-v3.40.orig similarity index 100% rename from FileSets/PatchSource/PageSettingsDisplay.qml-v3.40~35.orig rename to FileSets/PatchSource/PageSettingsDisplay.qml-v3.40.orig diff --git a/FileSets/PatchSource/PageSettingsDisplay.qml-v3.40~8.patch b/FileSets/PatchSource/PageSettingsDisplay.qml-v3.40.patch similarity index 85% rename from FileSets/PatchSource/PageSettingsDisplay.qml-v3.40~8.patch rename to FileSets/PatchSource/PageSettingsDisplay.qml-v3.40.patch index 2d438d87..fa17a507 100644 --- a/FileSets/PatchSource/PageSettingsDisplay.qml-v3.40~8.patch +++ b/FileSets/PatchSource/PageSettingsDisplay.qml-v3.40.patch @@ -1,5 +1,5 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/PageSettingsDisplay.qml-v3.40~8.orig 2024-07-09 10:19:58 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/PageSettingsDisplay.qml-v3.40~8 2024-03-24 08:13:08 +--- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/PageSettingsDisplay.qml-v3.40.orig 2024-07-09 10:19:58 ++++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/PageSettingsDisplay.qml-v3.40 2024-05-14 07:00:12 @@ -1,3 +1,5 @@ +//////// modified to add GuiMods controls + diff --git a/FileSets/PatchSource/PageSettingsDisplay.qml-v3.40~35.patch b/FileSets/PatchSource/PageSettingsDisplay.qml-v3.40~35.patch deleted file mode 100644 index 0ded22bc..00000000 --- a/FileSets/PatchSource/PageSettingsDisplay.qml-v3.40~35.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/PageSettingsDisplay.qml-v3.40~35.orig 2024-07-09 10:19:58 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/PageSettingsDisplay.qml-v3.40~35 2024-05-14 07:00:12 -@@ -1,3 +1,5 @@ -+//////// modified to add GuiMods controls -+ - import QtQuick 1.1 - import com.victron.velib 1.0 - import "utils.js" as Utils -@@ -65,6 +67,15 @@ - name: qsTr("Show tanks overview") - } - -+//////// add Gui Mods menu -+ MbSubMenu { -+ id: guiModsMenu -+ description: qsTr("Gui Mods") -+ subpage: Component { -+ PageSettingsGuiMods { } -+ } -+ } -+ - MbItemOptions { - id: languageSelect - description: qsTr("Language") diff --git a/FileSets/PatchSource/attributes.csv-v2.94.patch b/FileSets/PatchSource/attributes.csv-v2.94.patch deleted file mode 100644 index 92ea1191..00000000 --- a/FileSets/PatchSource/attributes.csv-v2.94.patch +++ /dev/null @@ -1,5 +0,0 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/attributes.csv-v2.94.orig 2024-06-24 12:49:39 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/attributes.csv-v2.94 2024-05-14 07:00:12 -@@ -433 +433 @@ --com.victronenergy.digitalinput,/Type,i,2=Door;3=Bilge pump;4=Bilge alarm;5=Burglar alarm;6=Smoke alarm;7=Fire alarm;8=CO2 alarm,3424,uint16,1,R -+com.victronenergy.digitalinput,/Type,i,2=Door;3=Bilge pump;4=Bilge alarm;5=Burglar alarm;6=Smoke alarm;7=Fire alarm;8=CO2 alarm;9=Generator;10=ExtTransferSwitch,3424,uint16,1,R diff --git a/FileSets/PatchSource/attributes.csv-v3.40~35 b/FileSets/PatchSource/attributes.csv-v3.40 similarity index 100% rename from FileSets/PatchSource/attributes.csv-v3.40~35 rename to FileSets/PatchSource/attributes.csv-v3.40 diff --git a/FileSets/PatchSource/attributes.csv-v3.40~35.orig b/FileSets/PatchSource/attributes.csv-v3.40.orig similarity index 100% rename from FileSets/PatchSource/attributes.csv-v3.40~35.orig rename to FileSets/PatchSource/attributes.csv-v3.40.orig diff --git a/FileSets/PatchSource/attributes.csv-v3.40~35.patch b/FileSets/PatchSource/attributes.csv-v3.40.patch similarity index 85% rename from FileSets/PatchSource/attributes.csv-v3.40~35.patch rename to FileSets/PatchSource/attributes.csv-v3.40.patch index 47436c4a..fd63e775 100644 --- a/FileSets/PatchSource/attributes.csv-v3.40~35.patch +++ b/FileSets/PatchSource/attributes.csv-v3.40.patch @@ -1,5 +1,5 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/attributes.csv-v3.40~35.orig 2024-07-08 00:41:45 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/attributes.csv-v3.40~35 2024-07-08 09:11:43 +--- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/attributes.csv-v3.40.orig 2024-07-08 00:41:45 ++++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/attributes.csv-v3.40 2024-07-08 09:11:43 @@ -490 +490 @@ -com.victronenergy.digitalinput,/Type,i,2=Door;3=Bilge pump;4=Bilge alarm;5=Burglar alarm;6=Smoke alarm;7=Fire alarm;8=CO2 alarm;9=Generator,3424,uint16,1,R +com.victronenergy.digitalinput,/Type,i,2=Door;3=Bilge pump;4=Bilge alarm;5=Burglar alarm;6=Smoke alarm;7=Fire alarm;8=CO2 alarm;9=Generator,3424,uint16,1,R;11=ExtTransferSwitch,3424,uint16,1,R diff --git a/FileSets/PatchSource/dbus_systemcalc.py-v2.73.patch b/FileSets/PatchSource/dbus_systemcalc.py-v2.73.patch deleted file mode 100644 index 1d7237cc..00000000 --- a/FileSets/PatchSource/dbus_systemcalc.py-v2.73.patch +++ /dev/null @@ -1,300 +0,0 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/dbus_systemcalc.py-v2.73.orig 2024-07-08 07:47:23 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/dbus_systemcalc.py-v2.73 2023-08-31 21:32:44 -@@ -1,6 +1,8 @@ - #!/usr/bin/python -u - # -*- coding: utf-8 -*- - -+#### modified for GuiMods -+ - from dbus.mainloop.glib import DBusGMainLoop - import dbus - import gobject -@@ -73,6 +75,23 @@ - '/Ac/Out/L1/P': dummy, - '/Ac/Out/L2/P': dummy, - '/Ac/Out/L3/P': dummy, -+#### add for GuiMods -+ '/Ac/Out/L1/I': dummy, -+ '/Ac/Out/L2/I': dummy, -+ '/Ac/Out/L3/I': dummy, -+ '/Ac/Out/L1/V': dummy, -+ '/Ac/Out/L2/V': dummy, -+ '/Ac/Out/L3/V': dummy, -+ '/Ac/Out/L1/F': dummy, -+ '/Ac/Out/L2/F': dummy, -+ '/Ac/Out/L3/F': dummy, -+ '/Ac/ActiveIn/L1/V': dummy, -+ '/Ac/ActiveIn/L2/V': dummy, -+ '/Ac/ActiveIn/L3/V': dummy, -+ '/Ac/ActiveIn/L1/F': dummy, -+ '/Ac/ActiveIn/L2/F': dummy, -+ '/Ac/ActiveIn/L3/F': dummy, -+ - '/Connected': dummy, - '/ProductId': dummy, - '/ProductName': dummy, -@@ -101,7 +120,17 @@ - '/DeviceType' : dummy, - '/Ac/L1/Power': dummy, - '/Ac/L2/Power': dummy, -- '/Ac/L3/Power': dummy}, -+ '/Ac/L3/Power': dummy, -+#### add for GuiMods -+ '/Ac/L1/Current': dummy, -+ '/Ac/L2/Current': dummy, -+ '/Ac/L3/Current': dummy, -+ '/Ac/L1/Voltage': dummy, -+ '/Ac/L2/Voltage': dummy, -+ '/Ac/L3/Voltage': dummy, -+ '/Ac/L1/Frequency': dummy, -+ '/Ac/L2/Frequency': dummy, -+ '/Ac/L3/Frequency': dummy}, - 'com.victronenergy.genset' : { - '/Connected': dummy, - '/ProductName': dummy, -@@ -111,6 +140,17 @@ - '/Ac/L1/Power': dummy, - '/Ac/L2/Power': dummy, - '/Ac/L3/Power': dummy, -+#### add for GuiMods -+ '/Ac/L1/Current': dummy, -+ '/Ac/L2/Current': dummy, -+ '/Ac/L3/Current': dummy, -+ '/Ac/L1/Voltage': dummy, -+ '/Ac/L2/Voltage': dummy, -+ '/Ac/L3/Voltage': dummy, -+ '/Ac/L1/Frequency': dummy, -+ '/Ac/L2/Frequency': dummy, -+ '/Ac/L3/Frequency': dummy, -+ - '/StarterVoltage': dummy}, - 'com.victronenergy.settings' : { - '/Settings/SystemSetup/AcInput1' : dummy, -@@ -130,6 +170,11 @@ - '/Ac/Out/L1/P': dummy, - '/Ac/Out/L1/V': dummy, - '/Ac/Out/L1/I': dummy, -+#### add for GuiMods -+ '/Ac/Out/L1/V': dummy, -+ '/Ac/Out/L1/I': dummy, -+ '/Ac/Out/L1/F': dummy, -+ - '/Yield/Power': dummy, - '/Soc': dummy, - } -@@ -254,7 +299,50 @@ - '/Dc/Vebus/Power': {'gettext': '%.0F W'}, - '/Dc/System/Power': {'gettext': '%.0F W'}, - '/Ac/ActiveIn/Source': {'gettext': '%s'}, -- '/VebusService': {'gettext': '%s'} -+ '/VebusService': {'gettext': '%s'}, -+#### added for GuiMods -+ '/Ac/Grid/L1/Current': {'gettext': '%.1F A'}, -+ '/Ac/Grid/L2/Current': {'gettext': '%.1F A'}, -+ '/Ac/Grid/L3/Current': {'gettext': '%.1F A'}, -+ '/Ac/Grid/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Grid/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Grid/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Grid/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/Genset/L1/Current': {'gettext': '%.1F A'}, -+ '/Ac/Genset/L2/Current': {'gettext': '%.1F A'}, -+ '/Ac/Genset/L3/Current': {'gettext': '%.1F A'}, -+ '/Ac/Genset/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Genset/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Genset/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Genset/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/ConsumptionOnOutput/L1/Current': {'gettext': '%.1F A'}, -+ '/Ac/ConsumptionOnOutput/L2/Current': {'gettext': '%.1F A'}, -+ '/Ac/ConsumptionOnOutput/L3/Current': {'gettext': '%.1F A'}, -+ '/Ac/ConsumptionOnOutput/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnOutput/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnOutput/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnOutput/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/ConsumptionOnInput/L1/Current': {'gettext': '%.1F A'}, -+ '/Ac/ConsumptionOnInput/L2/Current': {'gettext': '%.1F A'}, -+ '/Ac/ConsumptionOnInput/L3/Current': {'gettext': '%.1F A'}, -+ '/Ac/ConsumptionOnInput/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnInput/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnInput/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnInput/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/Consumption/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Consumption/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Consumption/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Consumption/L1/Current': {'gettext': '%.1F A'}, -+ '/Ac/Consumption/L2/Current': {'gettext': '%.1F A'}, -+ '/Ac/Consumption/L3/Current': {'gettext': '%.1F A'}, -+ '/Ac/Consumption/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/ActiveIn/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ActiveIn/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ActiveIn/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ActiveIn/L1/Current': {'gettext': '%.1F A'}, -+ '/Ac/ActiveIn/L2/Current': {'gettext': '%.1F A'}, -+ '/Ac/ActiveIn/L3/Current': {'gettext': '%.1F A'}, -+ '/Ac/ActiveIn/Frequency': {'gettext': '%.1F Hz'}, - } - - for m in self._modules: -@@ -693,6 +781,13 @@ - - # ===== GRID METERS & CONSUMPTION ==== - consumption = { "L1" : None, "L2" : None, "L3" : None } -+#### added for GuiMods -+ currentconsumption = { "L1" : None, "L2" : None, "L3" : None } -+ voltageIn = { "L1" : None, "L2" : None, "L3" : None } -+ voltageOut = { "L1" : None, "L2" : None, "L3" : None } -+ frequencyIn = None -+ frequencyOut = None -+ - for device_type in ['Grid', 'Genset']: - servicename = 'com.victronenergy.%s' % device_type.lower() - energy_meter = self._get_first_connected_service(servicename) -@@ -709,30 +804,73 @@ - for phase in consumption: - p = None - pvpower = newvalues.get('/Ac/PvOn%s/%s/Power' % (device_type, phase)) -+#### added for GuiMods -+ mc = None -+ pvcurrent = newvalues.get('/Ac/PvOn%s/%s/Current' % (device_type, phase)) - if em_service is not None: - p = self._dbusmonitor.get_value(em_service, '/Ac/%s/Power' % phase) -+#### added for GuiMods -+ mc = self._dbusmonitor.get_value(em.service, '/Ac/%s/Current' % phase) -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(em.service, '/Ac/%s/Voltage' % phase) -+ if frequencyIn == None: -+ frequencyIn = self._dbusmonitor.get_value(em.service, '/Ac/%s/Frequency' % phase) -+ - # Compute consumption between energy meter and multi (meter power - multi AC in) and - # add an optional PV inverter on input to the mix. - c = None -+#### added for GuiMods -+ cc = None - if uses_active_input: - ac_in = self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/P' % phase) - if ac_in is not None: -- c = _safeadd(c, -ac_in) -+ try: -+ c = _safeadd(c, -ac_in) -+#### added for GuiMods -+ cc = _safeadd(cc, -self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/I' % phase)) -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(em.service, '/Ac/ActiveIn/%s/V' % phase) -+ if frequencyIn == None: -+ frequencyIn = self._dbusmonitor.get_value(em.service, '/Ac/ActiveIn/%s/F' % phase) -+ except TypeError: -+ pass -+ - # If there's any power coming from a PV inverter in the inactive AC in (which is unlikely), - # it will still be used, because there may also be a load in the same ACIn consuming - # power, or the power could be fed back to the net. - c = _safeadd(c, p, pvpower) - consumption[phase] = _safeadd(consumption[phase], _safemax(0, c)) -+#### added for GuiMods -+ cc = _safeadd(cc, mc, pvcurrent) -+ currentconsumption[phase] = _safeadd(currentconsumption[phase], _safemax(0, cc)) - else: - if uses_active_input: - p = self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/P' % phase) - if p is not None: - consumption[phase] = _safeadd(0, consumption[phase]) -+#### added for GuiMods -+ currentconsumption[phase] = _safeadd(0, currentconsumption[phase]) -+ mc = self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/I' % phase) -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/V' % phase) -+ if frequencyIn == None: -+ freq = self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/F' % phase) -+ if freq != None: -+ frequencyIn = freq -+ - # No relevant energy meter present. Assume there is no load between the grid and the multi. - # There may be a PV inverter present though (Hub-3 setup). - if pvpower != None: - p = _safeadd(p, -pvpower) -+#### added for GuiMods -+ mc = _safeadd(mc, -pvcurrent) - newvalues['/Ac/%s/%s/Power' % (device_type, phase)] = p -+#### added for GuiMods -+ newvalues['/Ac/%s/%s/Current' % (device_type, phase)] = mc -+ if p != None: -+ newvalues['/Ac/%s/%s/Voltage' % (device_type, phase)] = voltageIn[phase] -+ newvalues['/Ac/%s/Frequency' % (device_type)] = frequencyIn -+ - self._compute_number_of_phases('/Ac/%s' % device_type, newvalues) - product_id = None - device_type_id = None -@@ -743,6 +881,7 @@ - product_id = self._dbusmonitor.get_value(multi_path, '/ProductId') - newvalues['/Ac/%s/ProductId' % device_type] = product_id - newvalues['/Ac/%s/DeviceType' % device_type] = device_type_id -+ - # If we have an ESS system and RunWithoutGridMeter is set, there cannot be load on the AC-In, so it - # must be on AC-Out. Hence we do calculate AC-Out consumption even if 'useacout' is disabled. - # Similarly all load are by definition on the output if this is not an ESS system. -@@ -752,26 +891,62 @@ - self._dbusmonitor.get_value('com.victronenergy.settings', '/Settings/CGwacs/RunWithoutGridMeter') == 1 - for phase in consumption: - c = None -+#### added for GuiMods -+ a = None - if use_ac_out: - c = newvalues.get('/Ac/PvOnOutput/%s/Power' % phase) -+#### added for GuiMods -+ a = newvalues.get('/Ac/PvOnOutput/%s/Current' % phase) -+ if voltageOut[phase] == None: -+ voltageOut[phase] = newvalues.get('/Ac/PvOnOutput/%s/Voltage' % phase) -+ if frequencyOut == None: -+ frequencyOut = newvalues.get('/Ac/PvOnOutput/%s/Frequency' % phase) -+ - if multi_path is None: - for inv in vedirect_inverters: - ac_out = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/P' % phase) -+#### added for GuiMods -+ i = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/I' % phase) -+ if voltageOut[phase] == None: -+ voltageOut[phase] = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/V' % phase) -+ if frequencyOut == None: -+ frequencyOut = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/F' % phase) - - # Some models don't show power, calculate it - if ac_out is None: -- i = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/I' % phase) -- u = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/V' % phase) -- if None not in (i, u): -- ac_out = i * u -+#### modified for GuiMods -+ # u = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/V' % phase) -+ if None not in (i, voltageOut[phase]): -+ ac_out = i * voltageOut[phase] - c = _safeadd(c, ac_out) -+#### modified for GuiMods -+ a = _safeadd(a, i) - else: - ac_out = self._dbusmonitor.get_value(multi_path, '/Ac/Out/%s/P' % phase) - c = _safeadd(c, ac_out) - c = _safemax(0, c) -+#### added for GuiMods -+ a = _safemax(0, a) - newvalues['/Ac/ConsumptionOnOutput/%s/Power' % phase] = c - newvalues['/Ac/ConsumptionOnInput/%s/Power' % phase] = consumption[phase] - newvalues['/Ac/Consumption/%s/Power' % phase] = _safeadd(consumption[phase], c) -+#### added for GuiMods -+ newvalues['/Ac/Consumption/%s/Current' % phase] = _safeadd(currentconsumption[phase], a) -+ newvalues['/Ac/ConsumptionOnOutput/%s/Voltage' % phase] = voltageOut[phase] -+ newvalues['/Ac/ConsumptionOnInput/%s/Voltage' % phase] = voltageIn[phase] -+ if voltageOut[phase] != None: -+ newvalues['/Ac/Consumption/%s/Voltage' % phase] = voltageOut[phase] -+ elif voltageIn[phase] != None: -+ newvalues['/Ac/Consumption/%s/Voltage' % phase] = voltageIn[phase] -+ if frequencyIn != None: -+ newvalues['/Ac/ConsumptionOnInput/Frequency'] = frequencyIn -+ if frequencyOut != None: -+ newvalues['/Ac/ConsumptionOnOutput/Frequency'] = frequencyOut -+ if frequencyOut != None: -+ newvalues['/Ac/Consumption/Frequency'] = frequencyOut -+ elif frequencyIn != None: -+ newvalues['/Ac/Consumption/Frequency'] = frequencyIn -+ - self._compute_number_of_phases('/Ac/Consumption', newvalues) - self._compute_number_of_phases('/Ac/ConsumptionOnOutput', newvalues) - self._compute_number_of_phases('/Ac/ConsumptionOnInput', newvalues) diff --git a/FileSets/PatchSource/dbus_systemcalc.py-v2.84.patch b/FileSets/PatchSource/dbus_systemcalc.py-v2.84.patch deleted file mode 100644 index bd0c984f..00000000 --- a/FileSets/PatchSource/dbus_systemcalc.py-v2.84.patch +++ /dev/null @@ -1,291 +0,0 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/dbus_systemcalc.py-v2.84.orig 2024-07-08 07:47:23 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/dbus_systemcalc.py-v2.84 2023-08-31 21:32:44 -@@ -1,6 +1,8 @@ - #!/usr/bin/python3 -u - # -*- coding: utf-8 -*- - -+#### modified for GuiMods -+ - from dbus.mainloop.glib import DBusGMainLoop - import dbus - import argparse -@@ -74,6 +76,23 @@ - '/Ac/Out/L1/P': dummy, - '/Ac/Out/L2/P': dummy, - '/Ac/Out/L3/P': dummy, -+#### add for GuiMods -+ '/Ac/Out/L1/I': dummy, -+ '/Ac/Out/L2/I': dummy, -+ '/Ac/Out/L3/I': dummy, -+ '/Ac/Out/L1/V': dummy, -+ '/Ac/Out/L2/V': dummy, -+ '/Ac/Out/L3/V': dummy, -+ '/Ac/Out/L1/F': dummy, -+ '/Ac/Out/L2/F': dummy, -+ '/Ac/Out/L3/F': dummy, -+ '/Ac/ActiveIn/L1/V': dummy, -+ '/Ac/ActiveIn/L2/V': dummy, -+ '/Ac/ActiveIn/L3/V': dummy, -+ '/Ac/ActiveIn/L1/F': dummy, -+ '/Ac/ActiveIn/L2/F': dummy, -+ '/Ac/ActiveIn/L3/F': dummy, -+ - '/Connected': dummy, - '/ProductId': dummy, - '/ProductName': dummy, -@@ -108,7 +127,17 @@ - '/DeviceType' : dummy, - '/Ac/L1/Power': dummy, - '/Ac/L2/Power': dummy, -- '/Ac/L3/Power': dummy}, -+ '/Ac/L3/Power': dummy, -+#### add for GuiMods -+ '/Ac/L1/Current': dummy, -+ '/Ac/L2/Current': dummy, -+ '/Ac/L3/Current': dummy, -+ '/Ac/L1/Voltage': dummy, -+ '/Ac/L2/Voltage': dummy, -+ '/Ac/L3/Voltage': dummy, -+ '/Ac/L1/Frequency': dummy, -+ '/Ac/L2/Frequency': dummy, -+ '/Ac/L3/Frequency': dummy}, - 'com.victronenergy.genset' : { - '/Connected': dummy, - '/ProductName': dummy, -@@ -118,6 +147,17 @@ - '/Ac/L1/Power': dummy, - '/Ac/L2/Power': dummy, - '/Ac/L3/Power': dummy, -+#### add for GuiMods -+ '/Ac/L1/Current': dummy, -+ '/Ac/L2/Current': dummy, -+ '/Ac/L3/Current': dummy, -+ '/Ac/L1/Voltage': dummy, -+ '/Ac/L2/Voltage': dummy, -+ '/Ac/L3/Voltage': dummy, -+ '/Ac/L1/Frequency': dummy, -+ '/Ac/L2/Frequency': dummy, -+ '/Ac/L3/Frequency': dummy, -+ - '/StarterVoltage': dummy}, - 'com.victronenergy.settings' : { - '/Settings/SystemSetup/AcInput1' : dummy, -@@ -135,8 +175,13 @@ - '/Dc/0/Voltage': dummy, - '/Dc/0/Current': dummy, - '/Ac/Out/L1/P': dummy, -+ '/Ac/Out/L1/V': dummy, -+ '/Ac/Out/L1/I': dummy, -+#### add for GuiMods - '/Ac/Out/L1/V': dummy, - '/Ac/Out/L1/I': dummy, -+ '/Ac/Out/L1/F': dummy, -+ - '/Yield/Power': dummy, - '/Soc': dummy}, - 'com.victronenergy.dcsystem': { -@@ -270,6 +315,49 @@ - '/Ac/ActiveIn/L2/Power': {'gettext': '%.0F W'}, - '/Ac/ActiveIn/L3/Power': {'gettext': '%.0F W'}, - '/Ac/ActiveIn/NumberOfPhases': {'gettext': '%d'}, -+#### added for GuiMods -+ '/Ac/Grid/L1/Current': {'gettext': '%.1F A'}, -+ '/Ac/Grid/L2/Current': {'gettext': '%.1F A'}, -+ '/Ac/Grid/L3/Current': {'gettext': '%.1F A'}, -+ '/Ac/Grid/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Grid/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Grid/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Grid/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/Genset/L1/Current': {'gettext': '%.1F A'}, -+ '/Ac/Genset/L2/Current': {'gettext': '%.1F A'}, -+ '/Ac/Genset/L3/Current': {'gettext': '%.1F A'}, -+ '/Ac/Genset/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Genset/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Genset/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Genset/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/ConsumptionOnOutput/L1/Current': {'gettext': '%.1F A'}, -+ '/Ac/ConsumptionOnOutput/L2/Current': {'gettext': '%.1F A'}, -+ '/Ac/ConsumptionOnOutput/L3/Current': {'gettext': '%.1F A'}, -+ '/Ac/ConsumptionOnOutput/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnOutput/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnOutput/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnOutput/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/ConsumptionOnInput/L1/Current': {'gettext': '%.1F A'}, -+ '/Ac/ConsumptionOnInput/L2/Current': {'gettext': '%.1F A'}, -+ '/Ac/ConsumptionOnInput/L3/Current': {'gettext': '%.1F A'}, -+ '/Ac/ConsumptionOnInput/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnInput/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnInput/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnInput/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/Consumption/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Consumption/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Consumption/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Consumption/L1/Current': {'gettext': '%.1F A'}, -+ '/Ac/Consumption/L2/Current': {'gettext': '%.1F A'}, -+ '/Ac/Consumption/L3/Current': {'gettext': '%.1F A'}, -+ '/Ac/Consumption/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/ActiveIn/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ActiveIn/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ActiveIn/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ActiveIn/L1/Current': {'gettext': '%.1F A'}, -+ '/Ac/ActiveIn/L2/Current': {'gettext': '%.1F A'}, -+ '/Ac/ActiveIn/L3/Current': {'gettext': '%.1F A'}, -+ '/Ac/ActiveIn/Frequency': {'gettext': '%.1F Hz'}, - } - - for m in self._modules: -@@ -777,6 +865,13 @@ - ac_in_guess = 2 - - consumption = { "L1" : None, "L2" : None, "L3" : None } -+#### added for GuiMods -+ currentconsumption = { "L1" : None, "L2" : None, "L3" : None } -+ voltageIn = { "L1" : None, "L2" : None, "L3" : None } -+ voltageOut = { "L1" : None, "L2" : None, "L3" : None } -+ frequencyIn = None -+ frequencyOut = None -+ - for device_type, em, _types in (('Grid', grid_meter, (1, 3)), ('Genset', genset_meter, (2,))): - # If a grid meter is present we use values from it. If not, we look at the multi. If it has - # AcIn1 or AcIn2 connected to the grid, we use those values. -@@ -787,32 +882,74 @@ - for phase in consumption: - p = None - pvpower = newvalues.get('/Ac/PvOn%s/%s/Power' % (device_type, phase)) -+#### added for GuiMods -+ mc = None -+ pvcurrent = newvalues.get('/Ac/PvOn%s/%s/Current' % (device_type, phase)) - if em is not None: - p = self._dbusmonitor.get_value(em.service, '/Ac/%s/Power' % phase) -+#### added for GuiMods -+ mc = self._dbusmonitor.get_value(em.service, '/Ac/%s/Current' % phase) -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(em.service, '/Ac/%s/Voltage' % phase) -+ if frequencyIn == None: -+ frequencyIn = self._dbusmonitor.get_value(em.service, '/Ac/%s/Frequency' % phase) -+ - # Compute consumption between energy meter and multi (meter power - multi AC in) and - # add an optional PV inverter on input to the mix. - c = None -+#### added for GuiMods -+ cc = None - if uses_active_input: - ac_in = self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/P' % phase) - if ac_in is not None: -- c = _safeadd(c, -ac_in) -+ try: -+ c = _safeadd(c, -ac_in) -+#### added for GuiMods -+ cc = _safeadd(cc, -self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/I' % phase)) -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(em.service, '/Ac/ActiveIn/%s/V' % phase) -+ if frequencyIn == None: -+ frequencyIn = self._dbusmonitor.get_value(em.service, '/Ac/ActiveIn/%s/F' % phase) -+ except TypeError: -+ pass -+ - # If there's any power coming from a PV inverter in the inactive AC in (which is unlikely), - # it will still be used, because there may also be a load in the same ACIn consuming - # power, or the power could be fed back to the net. - c = _safeadd(c, p, pvpower) - consumption[phase] = _safeadd(consumption[phase], _safemax(0, c)) -+#### added for GuiMods -+ cc = _safeadd(cc, mc, pvcurrent) -+ currentconsumption[phase] = _safeadd(currentconsumption[phase], _safemax(0, cc)) - else: - if uses_active_input: - p = self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/P' % phase) - if p is not None: - consumption[phase] = _safeadd(0, consumption[phase]) -+#### added for GuiMods -+ currentconsumption[phase] = _safeadd(0, currentconsumption[phase]) -+ mc = self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/I' % phase) -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/V' % phase) -+ if frequencyIn == None: -+ freq = self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/F' % phase) -+ if freq != None: -+ frequencyIn = freq -+ - # No relevant energy meter present. Assume there is no load between the grid and the multi. - # There may be a PV inverter present though (Hub-3 setup). - if pvpower != None: - p = _safeadd(p, -pvpower) -+#### added for GuiMods -+ mc = _safeadd(mc, -pvcurrent) - newvalues['/Ac/%s/%s/Power' % (device_type, phase)] = p - if ac_in_guess in _types: - newvalues['/Ac/ActiveIn/%s/Power' % (phase,)] = p -+#### added for GuiMods -+ newvalues['/Ac/%s/%s/Current' % (device_type, phase)] = mc -+ if p != None: -+ newvalues['/Ac/%s/%s/Voltage' % (device_type, phase)] = voltageIn[phase] -+ newvalues['/Ac/%s/Frequency' % (device_type)] = frequencyIn - - self._compute_number_of_phases('/Ac/%s' % device_type, newvalues) - self._compute_number_of_phases('/Ac/ActiveIn', newvalues) -@@ -836,11 +973,26 @@ - self._dbusmonitor.get_value('com.victronenergy.settings', '/Settings/CGwacs/RunWithoutGridMeter') == 1 - for phase in consumption: - c = None -+#### added for GuiMods -+ a = None - if use_ac_out: - c = newvalues.get('/Ac/PvOnOutput/%s/Power' % phase) -+#### added for GuiMods -+ a = newvalues.get('/Ac/PvOnOutput/%s/Current' % phase) -+ if voltageOut[phase] == None: -+ voltageOut[phase] = newvalues.get('/Ac/PvOnOutput/%s/Voltage' % phase) -+ if frequencyOut == None: -+ frequencyOut = newvalues.get('/Ac/PvOnOutput/%s/Frequency' % phase) -+ - if multi_path is None: - for inv in vedirect_inverters: - ac_out = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/P' % phase) -+#### added for GuiMods -+ i = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/I' % phase) -+ if voltageOut[phase] == None: -+ voltageOut[phase] = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/V' % phase) -+ if frequencyOut == None: -+ frequencyOut = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/F' % phase) - - # Some models don't show power, calculate it - if ac_out is None: -@@ -848,14 +1000,37 @@ - u = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/V' % phase) - if None not in (i, u): - ac_out = i * u -+#### modified for GuiMods -+ # u = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/V' % phase) -+ if None not in (i, voltageOut[phase]): -+ ac_out = i * voltageOut[phase] - c = _safeadd(c, ac_out) - else: - ac_out = self._dbusmonitor.get_value(multi_path, '/Ac/Out/%s/P' % phase) - c = _safeadd(c, ac_out) - c = _safemax(0, c) -+#### added for GuiMods -+ a = _safemax(0, a) - newvalues['/Ac/ConsumptionOnOutput/%s/Power' % phase] = c - newvalues['/Ac/ConsumptionOnInput/%s/Power' % phase] = consumption[phase] - newvalues['/Ac/Consumption/%s/Power' % phase] = _safeadd(consumption[phase], c) -+#### added for GuiMods -+ newvalues['/Ac/Consumption/%s/Current' % phase] = _safeadd(currentconsumption[phase], a) -+ newvalues['/Ac/ConsumptionOnOutput/%s/Voltage' % phase] = voltageOut[phase] -+ newvalues['/Ac/ConsumptionOnInput/%s/Voltage' % phase] = voltageIn[phase] -+ if voltageOut[phase] != None: -+ newvalues['/Ac/Consumption/%s/Voltage' % phase] = voltageOut[phase] -+ elif voltageIn[phase] != None: -+ newvalues['/Ac/Consumption/%s/Voltage' % phase] = voltageIn[phase] -+ if frequencyIn != None: -+ newvalues['/Ac/ConsumptionOnInput/Frequency'] = frequencyIn -+ if frequencyOut != None: -+ newvalues['/Ac/ConsumptionOnOutput/Frequency'] = frequencyOut -+ if frequencyOut != None: -+ newvalues['/Ac/Consumption/Frequency'] = frequencyOut -+ elif frequencyIn != None: -+ newvalues['/Ac/Consumption/Frequency'] = frequencyIn -+ - self._compute_number_of_phases('/Ac/Consumption', newvalues) - self._compute_number_of_phases('/Ac/ConsumptionOnOutput', newvalues) - self._compute_number_of_phases('/Ac/ConsumptionOnInput', newvalues) diff --git a/FileSets/PatchSource/dbus_systemcalc.py-v2.89.patch b/FileSets/PatchSource/dbus_systemcalc.py-v2.89.patch deleted file mode 100644 index 1bf18f3e..00000000 --- a/FileSets/PatchSource/dbus_systemcalc.py-v2.89.patch +++ /dev/null @@ -1,385 +0,0 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/dbus_systemcalc.py-v2.89.orig 2024-07-08 07:47:23 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/dbus_systemcalc.py-v2.89 2023-08-31 21:32:44 -@@ -1,6 +1,8 @@ - #!/usr/bin/python3 -u - # -*- coding: utf-8 -*- - -+#### modified for GuiMods -+ - from dbus.mainloop.glib import DBusGMainLoop - import dbus - import argparse -@@ -74,6 +76,23 @@ - '/Ac/Out/L1/P': dummy, - '/Ac/Out/L2/P': dummy, - '/Ac/Out/L3/P': dummy, -+#### add for GuiMods -+ '/Ac/Out/L1/I': dummy, -+ '/Ac/Out/L2/I': dummy, -+ '/Ac/Out/L3/I': dummy, -+ '/Ac/Out/L1/V': dummy, -+ '/Ac/Out/L2/V': dummy, -+ '/Ac/Out/L3/V': dummy, -+ '/Ac/Out/L1/F': dummy, -+ '/Ac/Out/L2/F': dummy, -+ '/Ac/Out/L3/F': dummy, -+ '/Ac/ActiveIn/L1/V': dummy, -+ '/Ac/ActiveIn/L2/V': dummy, -+ '/Ac/ActiveIn/L3/V': dummy, -+ '/Ac/ActiveIn/L1/F': dummy, -+ '/Ac/ActiveIn/L2/F': dummy, -+ '/Ac/ActiveIn/L3/F': dummy, -+ - '/Connected': dummy, - '/ProductId': dummy, - '/ProductName': dummy, -@@ -108,7 +127,17 @@ - '/DeviceType' : dummy, - '/Ac/L1/Power': dummy, - '/Ac/L2/Power': dummy, -- '/Ac/L3/Power': dummy}, -+ '/Ac/L3/Power': dummy, -+#### add for GuiMods -+ '/Ac/L1/Current': dummy, -+ '/Ac/L2/Current': dummy, -+ '/Ac/L3/Current': dummy, -+ '/Ac/L1/Voltage': dummy, -+ '/Ac/L2/Voltage': dummy, -+ '/Ac/L3/Voltage': dummy, -+ '/Ac/L1/Frequency': dummy, -+ '/Ac/L2/Frequency': dummy, -+ '/Ac/L3/Frequency': dummy}, - 'com.victronenergy.genset' : { - '/Connected': dummy, - '/ProductName': dummy, -@@ -118,6 +147,17 @@ - '/Ac/L1/Power': dummy, - '/Ac/L2/Power': dummy, - '/Ac/L3/Power': dummy, -+#### add for GuiMods -+ '/Ac/L1/Current': dummy, -+ '/Ac/L2/Current': dummy, -+ '/Ac/L3/Current': dummy, -+ '/Ac/L1/Voltage': dummy, -+ '/Ac/L2/Voltage': dummy, -+ '/Ac/L3/Voltage': dummy, -+ '/Ac/L1/Frequency': dummy, -+ '/Ac/L2/Frequency': dummy, -+ '/Ac/L3/Frequency': dummy, -+ - '/StarterVoltage': dummy}, - 'com.victronenergy.settings' : { - '/Settings/SystemSetup/AcInput1' : dummy, -@@ -135,8 +175,11 @@ - '/Dc/0/Voltage': dummy, - '/Dc/0/Current': dummy, - '/Ac/Out/L1/P': dummy, -+#### add for GuiMods - '/Ac/Out/L1/V': dummy, - '/Ac/Out/L1/I': dummy, -+ '/Ac/Out/L1/F': dummy, -+ - '/Yield/Power': dummy, - '/Soc': dummy}, - 'com.victronenergy.multi': { -@@ -151,8 +194,12 @@ - '/Ac/In/1/L1/P': dummy, - '/Ac/In/2/L1/P': dummy, - '/Ac/Out/L1/P': dummy, -+#### add for GuiMods - '/Ac/Out/L1/V': dummy, - '/Ac/Out/L1/I': dummy, -+ '/Ac/Out/L1/I': dummy, -+ '/Ac/L1/F': dummy, -+ - '/Yield/Power': dummy, - '/Soc': dummy}, - 'com.victronenergy.dcsystem': { -@@ -230,6 +277,7 @@ - '/Ac/Grid/L1/Power': {'gettext': '%.0F W'}, - '/Ac/Grid/L2/Power': {'gettext': '%.0F W'}, - '/Ac/Grid/L3/Power': {'gettext': '%.0F W'}, -+ - '/Ac/Grid/NumberOfPhases': {'gettext': '%.0F W'}, - '/Ac/Grid/ProductId': {'gettext': '%s'}, - '/Ac/Grid/DeviceType': {'gettext': '%s'}, -@@ -251,6 +299,9 @@ - '/Ac/Consumption/L1/Power': {'gettext': '%.0F W'}, - '/Ac/Consumption/L2/Power': {'gettext': '%.0F W'}, - '/Ac/Consumption/L3/Power': {'gettext': '%.0F W'}, -+ '/Ac/Consumption/L1/Current': {'gettext': '%.1F A'}, -+ '/Ac/Consumption/L2/Current': {'gettext': '%.1F A'}, -+ '/Ac/Consumption/L3/Current': {'gettext': '%.1F A'}, - '/Ac/Consumption/NumberOfPhases': {'gettext': '%.0F W'}, - '/Ac/PvOnOutput/L1/Power': {'gettext': '%.0F W'}, - '/Ac/PvOnOutput/L2/Power': {'gettext': '%.0F W'}, -@@ -286,6 +337,50 @@ - '/Ac/ActiveIn/L2/Power': {'gettext': '%.0F W'}, - '/Ac/ActiveIn/L3/Power': {'gettext': '%.0F W'}, - '/Ac/ActiveIn/NumberOfPhases': {'gettext': '%d'}, -+#### added for GuiMods -+ '/Ac/Grid/L1/Current': {'gettext': '%.1F A'}, -+ '/Ac/Grid/L2/Current': {'gettext': '%.1F A'}, -+ '/Ac/Grid/L3/Current': {'gettext': '%.1F A'}, -+ '/Ac/Grid/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Grid/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Grid/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Grid/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/Genset/L1/Current': {'gettext': '%.1F A'}, -+ '/Ac/Genset/L2/Current': {'gettext': '%.1F A'}, -+ '/Ac/Genset/L3/Current': {'gettext': '%.1F A'}, -+ '/Ac/Genset/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Genset/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Genset/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Genset/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/ConsumptionOnOutput/L1/Current': {'gettext': '%.1F A'}, -+ '/Ac/ConsumptionOnOutput/L2/Current': {'gettext': '%.1F A'}, -+ '/Ac/ConsumptionOnOutput/L3/Current': {'gettext': '%.1F A'}, -+ '/Ac/ConsumptionOnOutput/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnOutput/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnOutput/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnOutput/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/ConsumptionOnInput/L1/Current': {'gettext': '%.1F A'}, -+ '/Ac/ConsumptionOnInput/L2/Current': {'gettext': '%.1F A'}, -+ '/Ac/ConsumptionOnInput/L3/Current': {'gettext': '%.1F A'}, -+ '/Ac/ConsumptionOnInput/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnInput/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnInput/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnInput/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/Consumption/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Consumption/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Consumption/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Consumption/L1/Current': {'gettext': '%.1F A'}, -+ '/Ac/Consumption/L2/Current': {'gettext': '%.1F A'}, -+ '/Ac/Consumption/L3/Current': {'gettext': '%.1F A'}, -+ '/Ac/Consumption/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/ActiveIn/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ActiveIn/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ActiveIn/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ActiveIn/L1/Current': {'gettext': '%.1F A'}, -+ '/Ac/ActiveIn/L2/Current': {'gettext': '%.1F A'}, -+ '/Ac/ActiveIn/L3/Current': {'gettext': '%.1F A'}, -+ '/Ac/ActiveIn/Frequency': {'gettext': '%.1F Hz'}, -+ - } - - for m in self._modules: -@@ -783,6 +878,7 @@ - newvalues['/Ac/ActiveIn/Source'] = ac_in_source - - # ===== GRID METERS & CONSUMPTION ==== -+#### begin GuiMods replaced section - added current, voltage and frequency - grid_meter = delegates.AcInputs.instance.gridmeter - genset_meter = delegates.AcInputs.instance.gensetmeter - -@@ -799,6 +895,13 @@ - ac_in_guess = 2 - - consumption = { "L1" : None, "L2" : None, "L3" : None } -+#### added for GuiMods -+ currentconsumption = { "L1" : None, "L2" : None, "L3" : None } -+ voltageIn = { "L1" : None, "L2" : None, "L3" : None } -+ voltageOut = { "L1" : None, "L2" : None, "L3" : None } -+ frequencyIn = None -+ frequencyOut = None -+ - for device_type, em, _types in (('Grid', grid_meter, (1, 3)), ('Genset', genset_meter, (2,))): - # If a grid meter is present we use values from it. If not, we look at the multi. If it has - # AcIn1 or AcIn2 connected to the grid, we use those values. -@@ -809,41 +912,109 @@ - for phase in consumption: - p = None - pvpower = newvalues.get('/Ac/PvOn%s/%s/Power' % (device_type, phase)) -+#### added for GuiMods -+ mc = None -+ pvcurrent = newvalues.get('/Ac/PvOn%s/%s/Current' % (device_type, phase)) - if em is not None: - p = self._dbusmonitor.get_value(em.service, '/Ac/%s/Power' % phase) -+#### added for GuiMods -+ mc = self._dbusmonitor.get_value(em.service, '/Ac/%s/Current' % phase) -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(em.service, '/Ac/%s/Voltage' % phase) -+ if frequencyIn == None: -+ frequencyIn = self._dbusmonitor.get_value(em.service, '/Ac/%s/Frequency' % phase) -+ - # Compute consumption between energy meter and multi (meter power - multi AC in) and - # add an optional PV inverter on input to the mix. - c = None -+#### added for GuiMods -+ cc = None - if uses_active_input: -- if multi_path is not None and (ac_in := self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/P' % phase)) is not None: -- c = _safeadd(c, -ac_in) -+ if multi_path is not None: -+ try: -+ c = _safeadd(c, -self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/P' % phase)) -+#### added for GuiMods -+ cc = _safeadd(cc, -self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/I' % phase)) -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(em.service, '/Ac/ActiveIn/%s/V' % phase) -+ if frequencyIn == None: -+ frequencyIn = self._dbusmonitor.get_value(em.service, '/Ac/ActiveIn/%s/F' % phase) -+ -+ except TypeError: -+ pass - elif non_vebus_inverter is not None and active_input in (0, 1): -- ac_in = self._dbusmonitor.get_value(non_vebus_inverter, '/Ac/In/%d/%s/P' % (active_input+1, phase)) -- if ac_in is not None: -- c = _safeadd(c, -ac_in) -+ try: -+ c = _safeadd(c, -self._dbusmonitor.get_value(non_vebus_inverter, '/Ac/In/%d/%s/P' % (active_input+1, phase))) -+#### added for GuiMods -+ cc = _safeadd(cc, -self._dbusmonitor.get_value(non_vebus_inverter, '/Ac/In/%d/%s/I' % (active_input+1, phase))) -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(em.service, '/Ac/In/%d/%s/V' % (active_input+1, phase)) -+ if frequencyIn == None: -+ frequencyIn = self._dbusmonitor.get_value(em.service, '/Ac/In/%d/%s/F' % (active_input+1, phase)) - -+ except TypeError: -+ pass -+ - # If there's any power coming from a PV inverter in the inactive AC in (which is unlikely), - # it will still be used, because there may also be a load in the same ACIn consuming - # power, or the power could be fed back to the net. - c = _safeadd(c, p, pvpower) - consumption[phase] = _safeadd(consumption[phase], _safemax(0, c)) -+#### added for GuiMods -+ cc = _safeadd(cc, mc, pvcurrent) -+ currentconsumption[phase] = _safeadd(currentconsumption[phase], _safemax(0, cc)) - else: - if uses_active_input: - if multi_path is not None and ( - p := self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/P' % phase)) is not None: - consumption[phase] = _safeadd(0, consumption[phase]) -+#### added for GuiMods -+ currentconsumption[phase] = _safeadd(0, currentconsumption[phase]) -+ mc = self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/I' % phase) -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/V' % phase) -+ if frequencyIn == None: -+ freq = self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/F' % phase) -+ if freq != None: -+ frequencyIn = freq -+ - elif non_vebus_inverter is not None and active_input in (0, 1): - p = self._dbusmonitor.get_value(non_vebus_inverter, '/Ac/In/%d/%s/P' % (active_input + 1, phase)) -+#### added for GuiMods -+ mc = self._dbusmonitor.get_value(non_vebus_inverter, '/Ac/In/%d/%s/I' % (active_input + 1, phase)) -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(non_vebus_inverter, '/Ac/In/%d/%s/V' % (active_input + 1, phase)) -+ if frequencyIn == None: -+ frequencyIn = self._dbusmonitor.get_value(non_vebus_inverter, '/Ac/In/%d/%s/F' % (active_input + 1, phase)) -+ - if p is not None: - consumption[phase] = _safeadd(0, consumption[phase]) -+#### added for GuiMods -+ currentconsumption[phase] = _safeadd(0, currentconsumption[phase]) - - # No relevant energy meter present. Assume there is no load between the grid and the multi. - # There may be a PV inverter present though (Hub-3 setup). -- if pvpower != None: -+ try: - p = _safeadd(p, -pvpower) -+#### added for GuiMods -+ mc = _safeadd(mc, -pvcurrent) -+ except TypeError: -+ pass -+ - newvalues['/Ac/%s/%s/Power' % (device_type, phase)] = p -+#### added for GuiMods -+ newvalues['/Ac/%s/%s/Current' % (device_type, phase)] = mc -+ if p != None: -+ newvalues['/Ac/%s/%s/Voltage' % (device_type, phase)] = voltageIn[phase] -+ newvalues['/Ac/%s/Frequency' % (device_type)] = frequencyIn -+ - if ac_in_guess in _types: - newvalues['/Ac/ActiveIn/%s/Power' % (phase,)] = p -+#### added for GuiMods -+ newvalues['/Ac/ActiveIn/%s/Current' % (phase,)] = mc -+ if p != None: -+ newvalues['/Ac/ActiveIn/%s/Voltage' % (phase,)] = voltageIn[phase] -+ newvalues['/Ac/ActiveIn/Frequency'] = frequencyIn - - self._compute_number_of_phases('/Ac/%s' % device_type, newvalues) - self._compute_number_of_phases('/Ac/ActiveIn', newvalues) -@@ -870,26 +1041,75 @@ - self._dbusmonitor.get_value('com.victronenergy.settings', '/Settings/CGwacs/RunWithoutGridMeter') == 1 - for phase in consumption: - c = None -+#### added for GuiMods -+ a = None - if use_ac_out: - c = newvalues.get('/Ac/PvOnOutput/%s/Power' % phase) -+#### added for GuiMods -+ a = newvalues.get('/Ac/PvOnOutput/%s/Current' % phase) -+ if voltageOut[phase] == None: -+ voltageOut[phase] = newvalues.get('/Ac/PvOnOutput/%s/Voltage' % phase) -+ if frequencyOut == None: -+ frequencyOut = newvalues.get('/Ac/PvOnOutput/%s/Frequency' % phase) -+ - if multi_path is None: - for inv in non_vebus_inverters: - ac_out = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/P' % phase) -+#### added for GuiMods -+ i = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/I' % phase) -+ if voltageOut[phase] == None: -+ voltageOut[phase] = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/V' % phase) -+ if frequencyOut == None: -+ frequencyOut = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/F' % phase) - -- # Some models don't show power, calculate it -+ # Some models don't show power, try apparent power, -+ # else calculate it - if ac_out is None: -- i = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/I' % phase) -- u = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/V' % phase) -- if None not in (i, u): -- ac_out = i * u -+ ac_out = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/S' % phase) -+ if ac_out is None: -+#### modified for GuiMods -+ # u = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/V' % phase) -+ if None not in (i, voltageOut[phase]): -+ ac_out = i * voltageOut[phase] - c = _safeadd(c, ac_out) -+#### modified for GuiMods -+ a = _safeadd(a, i) - else: - ac_out = self._dbusmonitor.get_value(multi_path, '/Ac/Out/%s/P' % phase) - c = _safeadd(c, ac_out) -+#### added for GuiMods -+ i_out = self._dbusmonitor.get_value(multi_path, '/Ac/Out/%s/I' % phase) -+ a = _safeadd(a, i_out) -+ if voltageOut[phase] == None: -+ voltageOut[phase] = self._dbusmonitor.get_value(multi_path, '/Ac/Out/%s/V' % phase) -+ if frequencyOut == None: -+ frequencyOut = self._dbusmonitor.get_value(multi_path, '/Ac/Out/%s/F' % phase) - c = _safemax(0, c) -+#### added for GuiMods -+ a = _safemax(0, a) - newvalues['/Ac/ConsumptionOnOutput/%s/Power' % phase] = c -+ newvalues['/Ac/ConsumptionOnOutput/%s/Current' % phase] = a - newvalues['/Ac/ConsumptionOnInput/%s/Power' % phase] = consumption[phase] -+ newvalues['/Ac/ConsumptionOnInput/%s/Current' % phase] = currentconsumption[phase] - newvalues['/Ac/Consumption/%s/Power' % phase] = _safeadd(consumption[phase], c) -+#### added for GuiMods -+ newvalues['/Ac/Consumption/%s/Current' % phase] = _safeadd(currentconsumption[phase], a) -+ newvalues['/Ac/ConsumptionOnOutput/%s/Voltage' % phase] = voltageOut[phase] -+ newvalues['/Ac/ConsumptionOnInput/%s/Voltage' % phase] = voltageIn[phase] -+ if voltageOut[phase] != None: -+ newvalues['/Ac/Consumption/%s/Voltage' % phase] = voltageOut[phase] -+ elif voltageIn[phase] != None: -+ newvalues['/Ac/Consumption/%s/Voltage' % phase] = voltageIn[phase] -+ if frequencyIn != None: -+ newvalues['/Ac/ConsumptionOnInput/Frequency'] = frequencyIn -+ if frequencyOut != None: -+ newvalues['/Ac/ConsumptionOnOutput/Frequency'] = frequencyOut -+ if frequencyOut != None: -+ newvalues['/Ac/Consumption/Frequency'] = frequencyOut -+ elif frequencyIn != None: -+ newvalues['/Ac/Consumption/Frequency'] = frequencyIn -+ -+#### end GuiMods replaced section - self._compute_number_of_phases('/Ac/Consumption', newvalues) - self._compute_number_of_phases('/Ac/ConsumptionOnOutput', newvalues) - self._compute_number_of_phases('/Ac/ConsumptionOnInput', newvalues) diff --git a/FileSets/PatchSource/dbus_systemcalc.py-v2.94.patch b/FileSets/PatchSource/dbus_systemcalc.py-v2.94.patch deleted file mode 100644 index a36ac77a..00000000 --- a/FileSets/PatchSource/dbus_systemcalc.py-v2.94.patch +++ /dev/null @@ -1,384 +0,0 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/dbus_systemcalc.py-v2.94.orig 2024-07-08 07:47:23 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/dbus_systemcalc.py-v2.94 2023-08-31 21:32:44 -@@ -1,6 +1,8 @@ - #!/usr/bin/python3 -u - # -*- coding: utf-8 -*- - -+#### modified for GuiMods -+ - from dbus.mainloop.glib import DBusGMainLoop - import dbus - import argparse -@@ -83,6 +85,20 @@ - '/Ac/Out/L1/I': dummy, - '/Ac/Out/L2/I': dummy, - '/Ac/Out/L3/I': dummy, -+#### add for GuiMods -+ '/Ac/Out/L1/V': dummy, -+ '/Ac/Out/L2/V': dummy, -+ '/Ac/Out/L3/V': dummy, -+ '/Ac/Out/L1/F': dummy, -+ '/Ac/Out/L2/F': dummy, -+ '/Ac/Out/L3/F': dummy, -+ '/Ac/ActiveIn/L1/V': dummy, -+ '/Ac/ActiveIn/L2/V': dummy, -+ '/Ac/ActiveIn/L3/V': dummy, -+ '/Ac/ActiveIn/L1/F': dummy, -+ '/Ac/ActiveIn/L2/F': dummy, -+ '/Ac/ActiveIn/L3/F': dummy, -+ - '/Connected': dummy, - '/ProductId': dummy, - '/ProductName': dummy, -@@ -120,7 +136,14 @@ - '/Ac/L3/Power': dummy, - '/Ac/L1/Current': dummy, - '/Ac/L2/Current': dummy, -- '/Ac/L3/Current': dummy}, -+ '/Ac/L3/Current': dummy, -+#### add for GuiMods -+ '/Ac/L1/Voltage': dummy, -+ '/Ac/L2/Voltage': dummy, -+ '/Ac/L3/Voltage': dummy, -+ '/Ac/L1/Frequency': dummy, -+ '/Ac/L2/Frequency': dummy, -+ '/Ac/L3/Frequency': dummy}, - 'com.victronenergy.genset' : { - '/Connected': dummy, - '/ProductName': dummy, -@@ -133,6 +156,14 @@ - '/Ac/L1/Current': dummy, - '/Ac/L2/Current': dummy, - '/Ac/L3/Current': dummy, -+#### add for GuiMods -+ '/Ac/L1/Voltage': dummy, -+ '/Ac/L2/Voltage': dummy, -+ '/Ac/L3/Voltage': dummy, -+ '/Ac/L1/Frequency': dummy, -+ '/Ac/L2/Frequency': dummy, -+ '/Ac/L3/Frequency': dummy, -+ - '/StarterVoltage': dummy}, - 'com.victronenergy.settings' : { - '/Settings/SystemSetup/AcInput1' : dummy, -@@ -153,6 +184,9 @@ - '/Ac/Out/L1/S': dummy, - '/Ac/Out/L1/V': dummy, - '/Ac/Out/L1/I': dummy, -+#### add for GuiMods -+ '/Ac/Out/L1/F': dummy, -+ - '/Yield/Power': dummy, - '/Soc': dummy}, - 'com.victronenergy.multi': { -@@ -171,6 +205,9 @@ - '/Ac/Out/L1/P': dummy, - '/Ac/Out/L1/V': dummy, - '/Ac/Out/L1/I': dummy, -+#### add for GuiMods -+ '/Ac/L1/F': dummy, -+ - '/Yield/Power': dummy, - '/Soc': dummy}, - 'com.victronenergy.dcsystem': { -@@ -179,6 +216,15 @@ - }, - 'com.victronenergy.alternator': { - '/Dc/0/Power': dummy -+ }, -+#### added for GuiMods -+ 'com.victronenergy.dcsource': { -+ '/Dc/0/Power': dummy, -+ '/Settings/MonitorMode': dummy -+ }, -+ 'com.victronenergy.motordrive': -+ { -+ '/Dc/0/Power': dummy - } - } - -@@ -335,6 +381,33 @@ - '/Ac/ActiveIn/L2/Current': {'gettext': '%.1F A'}, - '/Ac/ActiveIn/L3/Current': {'gettext': '%.1F A'}, - '/Ac/ActiveIn/NumberOfPhases': {'gettext': '%d'}, -+#### added for GuiMods -+ '/Dc/WindGenerator/Power': {'gettext': '%.0F W'}, -+ '/Dc/MotorDrive/Power': {'gettext': '%.0F W'}, -+ '/Ac/Grid/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Grid/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Grid/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Grid/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/Genset/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Genset/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Genset/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Genset/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/ConsumptionOnOutput/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnOutput/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnOutput/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnOutput/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/ConsumptionOnInput/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnInput/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnInput/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnInput/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/Consumption/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Consumption/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Consumption/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Consumption/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/ActiveIn/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ActiveIn/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ActiveIn/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ActiveIn/Frequency': {'gettext': '%.1F Hz'}, - } - - for m in self._modules: -@@ -354,6 +427,9 @@ - for service, instance in self._dbusmonitor.get_service_list().items(): - self._device_added(service, instance, do_service_change=False) - -+#### added for GuiMods -+ self.dcSystemPower = [0, 0, 0] -+ - self._handleservicechange() - self._updatevalues() - -@@ -619,15 +695,48 @@ - # ==== ALTERNATOR ==== - alternators = self._dbusmonitor.get_service_list('com.victronenergy.alternator') - for alternator in alternators: -+#### changed for GuiMods -+ # some alternators do not provide a valid power value if not running -+ # or below a minimum power/current -+ # so fill in a zero power so that the systemcalc power becomes valid - # Assume the battery connected to output 0 is the main battery - p = self._dbusmonitor.get_value(alternator, '/Dc/0/Power') - if p is None: -- continue -+ #### continue -+ p = 0 - - if '/Dc/Alternator/Power' not in newvalues: - newvalues['/Dc/Alternator/Power'] = p - else: - newvalues['/Dc/Alternator/Power'] += p -+ -+#### added for GuiMods -+ # ==== MOTOR DRIVE ==== -+ motordrives = self._dbusmonitor.get_service_list('com.victronenergy.motordrive') -+ for motordrive in motordrives: -+ p = self._dbusmonitor.get_value(motordrive, '/Dc/0/Power') -+ if p is None: -+ p = 0 -+ -+ if '/Dc/MotorDrive/Power' not in newvalues: -+ newvalues['/Dc/MotorDrive/Power'] = p -+ else: -+ newvalues['/Dc/MotorDrive/Power'] += p -+ -+#### added for GuiMods -+ # ==== DC SOURCES ==== -+ dcSources = self._dbusmonitor.get_service_list('com.victronenergy.dcsource') -+ for dcSource in dcSources: -+ monitorMode = self._dbusmonitor.get_value(dcSource,'/Settings/MonitorMode') -+ # ==== WIND GENERATOR ==== -+ if monitorMode == -8: -+ p = self._dbusmonitor.get_value(dcSource, '/Dc/0/Power') -+ if p is None: -+ continue -+ if '/Dc/WindGenerator/Power' not in newvalues: -+ newvalues['/Dc/WindGenerator/Power'] = p -+ else: -+ newvalues['/Dc/WindGenerator/Power'] += p - - # ==== CHARGERS ==== - chargers = self._dbusmonitor.get_service_list('com.victronenergy.charger') -@@ -791,6 +900,9 @@ - charger_power = newvalues.get('/Dc/Charger/Power', 0) - fuelcell_power = newvalues.get('/Dc/FuelCell/Power', 0) - alternator_power = newvalues.get('/Dc/Alternator/Power', 0) -+#### added for GuiMods -+ windgen_power = newvalues.get('/Dc/WindGenerator/Power', 0) -+ motordrive_power = newvalues.get('/Dc/MotorDrive/Power', 0) - - # If there are VE.Direct inverters, remove their power from the - # DC estimate. This is done using the AC value when the DC -@@ -811,7 +923,12 @@ - # displayed. For now, we leave it out so that in the current - # version of Venus it does not break user's expectations. - #newvalues['/Dc/System/Power'] = dc_pv_power + charger_power + fuelcell_power + vebuspower - inverter_power - battery_power - alternator_power -- newvalues['/Dc/System/Power'] = dc_pv_power + charger_power + fuelcell_power + vebuspower - inverter_power - battery_power -+#### changed for GuiMods -+ # average DC system power over 3 passes (seconds) to minimize wild swings in displayed value -+ self.dcSystemPower[2] = self.dcSystemPower[1] -+ self.dcSystemPower[1] = self.dcSystemPower[2] -+ self.dcSystemPower[0] = dc_pv_power + charger_power + fuelcell_power + vebuspower - inverter_power - battery_power + alternator_power + windgen_power - motordrive_power -+ newvalues['/Dc/System/Power'] = (self.dcSystemPower[0] + self.dcSystemPower[1] + self.dcSystemPower[2]) / 3 - - elif self._settings['hasdcsystem'] == 1 and solarchargers_loadoutput_power is not None: - newvalues['/Dc/System/MeasurementType'] = 0 # estimated -@@ -873,6 +990,13 @@ - - consumption = { "L1" : None, "L2" : None, "L3" : None } - currentconsumption = { "L1" : None, "L2" : None, "L3" : None } -+ -+#### added for GuiMods -+ voltageIn = { "L1" : None, "L2" : None, "L3" : None } -+ voltageOut = { "L1" : None, "L2" : None, "L3" : None } -+ frequencyIn = None -+ frequencyOut = None -+ - for device_type, em, _types in (('Grid', grid_meter, (1, 3)), ('Genset', genset_meter, (2,))): - # If a grid meter is present we use values from it. If not, we look at the multi. If it has - # AcIn1 or AcIn2 connected to the grid, we use those values. -@@ -888,6 +1012,12 @@ - if em is not None: - p = self._dbusmonitor.get_value(em.service, '/Ac/%s/Power' % phase) - mc = self._dbusmonitor.get_value(em.service, '/Ac/%s/Current' % phase) -+#### added for GuiMods -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(em.service, '/Ac/%s/Voltage' % phase) -+ if frequencyIn == None: -+ frequencyIn = self._dbusmonitor.get_value(em.service, '/Ac/%s/Frequency' % phase) -+ - # Compute consumption between energy meter and multi (meter power - multi AC in) and - # add an optional PV inverter on input to the mix. - c = None -@@ -897,12 +1027,24 @@ - try: - c = _safeadd(c, -self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/P' % phase)) - cc = _safeadd(cc, -self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/I' % phase)) -+#### added for GuiMods -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(em.service, '/Ac/ActiveIn/%s/V' % phase) -+ if frequencyIn == None: -+ frequencyIn = self._dbusmonitor.get_value(em.service, '/Ac/ActiveIn/%s/F' % phase) -+ - except TypeError: - pass - elif non_vebus_inverter is not None and active_input in (0, 1): - try: - c = _safeadd(c, -self._dbusmonitor.get_value(non_vebus_inverter, '/Ac/In/%d/%s/P' % (active_input+1, phase))) - cc = _safeadd(cc, -self._dbusmonitor.get_value(non_vebus_inverter, '/Ac/In/%d/%s/I' % (active_input+1, phase))) -+#### added for GuiMods -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(em.service, '/Ac/In/%d/%s/V' % (active_input+1, phase)) -+ if frequencyIn == None: -+ frequencyIn = self._dbusmonitor.get_value(em.service, '/Ac/In/%d/%s/F' % (active_input+1, phase)) -+ - except TypeError: - pass - -@@ -920,9 +1062,23 @@ - consumption[phase] = _safeadd(0, consumption[phase]) - currentconsumption[phase] = _safeadd(0, currentconsumption[phase]) - mc = self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/I' % phase) -+#### added for GuiMods -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/V' % phase) -+ if frequencyIn == None: -+ freq = self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/F' % phase) -+ if freq != None: -+ frequencyIn = freq -+ - elif non_vebus_inverter is not None and active_input in (0, 1): - p = self._dbusmonitor.get_value(non_vebus_inverter, '/Ac/In/%d/%s/P' % (active_input + 1, phase)) - mc = self._dbusmonitor.get_value(non_vebus_inverter, '/Ac/In/%d/%s/I' % (active_input + 1, phase)) -+#### added for GuiMods -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(non_vebus_inverter, '/Ac/In/%d/%s/V' % (active_input + 1, phase)) -+ if frequencyIn == None: -+ frequencyIn = self._dbusmonitor.get_value(non_vebus_inverter, '/Ac/In/%d/%s/F' % (active_input + 1, phase)) -+ - if p is not None: - consumption[phase] = _safeadd(0, consumption[phase]) - currentconsumption[phase] = _safeadd(0, currentconsumption[phase]) -@@ -937,9 +1093,19 @@ - - newvalues['/Ac/%s/%s/Power' % (device_type, phase)] = p - newvalues['/Ac/%s/%s/Current' % (device_type, phase)] = mc -+#### added for GuiMods -+ if p != None: -+ newvalues['/Ac/%s/%s/Voltage' % (device_type, phase)] = voltageIn[phase] -+ newvalues['/Ac/%s/Frequency' % (device_type)] = frequencyIn -+ - if ac_in_guess in _types: - newvalues['/Ac/ActiveIn/%s/Power' % (phase,)] = p - newvalues['/Ac/ActiveIn/%s/Current' % (phase,)] = mc -+#### added for GuiMods -+ if p != None: -+ newvalues['/Ac/ActiveIn/%s/Voltage' % (phase,)] = voltageIn[phase] -+ if frequencyIn != None: -+ newvalues['/Ac/ActiveIn/Frequency'] = frequencyIn - - self._compute_number_of_phases('/Ac/%s' % device_type, newvalues) - self._compute_number_of_phases('/Ac/ActiveIn', newvalues) -@@ -970,19 +1136,32 @@ - if use_ac_out: - c = newvalues.get('/Ac/PvOnOutput/%s/Power' % phase) - a = newvalues.get('/Ac/PvOnOutput/%s/Current' % phase) -+#### added for GuiMods -+ if voltageOut[phase] == None: -+ voltageOut[phase] = newvalues.get('/Ac/PvOnOutput/%s/Voltage' % phase) -+ if frequencyOut == None: -+ frequencyOut = newvalues.get('/Ac/PvOnOutput/%s/Frequency' % phase) -+ - if multi_path is None: - for inv in non_vebus_inverters: - ac_out = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/P' % phase) - i = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/I' % phase) - -+#### added for GuiMods -+ if voltageOut[phase] == None: -+ voltageOut[phase] = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/V' % phase) -+ if frequencyOut == None: -+ frequencyOut = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/F' % phase) -+ - # Some models don't show power, try apparent power, - # else calculate it - if ac_out is None: - ac_out = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/S' % phase) - if ac_out is None: -- u = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/V' % phase) -- if None not in (i, u): -- ac_out = i * u -+#### modified for GuiMods -+ # u = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/V' % phase) -+ if None not in (i, voltageOut[phase]): -+ ac_out = i * voltageOut[phase] - c = _safeadd(c, ac_out) - a = _safeadd(a, i) - else: -@@ -990,6 +1169,11 @@ - c = _safeadd(c, ac_out) - i_out = self._dbusmonitor.get_value(multi_path, '/Ac/Out/%s/I' % phase) - a = _safeadd(a, i_out) -+#### added for GuiMods -+ if voltageOut[phase] == None: -+ voltageOut[phase] = self._dbusmonitor.get_value(multi_path, '/Ac/Out/%s/V' % phase) -+ if frequencyOut == None: -+ frequencyOut = self._dbusmonitor.get_value(multi_path, '/Ac/Out/%s/F' % phase) - c = _safemax(0, c) - a = _safemax(0, a) - newvalues['/Ac/ConsumptionOnOutput/%s/Power' % phase] = c -@@ -998,6 +1182,22 @@ - newvalues['/Ac/ConsumptionOnInput/%s/Current' % phase] = currentconsumption[phase] - newvalues['/Ac/Consumption/%s/Power' % phase] = _safeadd(consumption[phase], c) - newvalues['/Ac/Consumption/%s/Current' % phase] = _safeadd(currentconsumption[phase], a) -+#### added for GuiMods -+ newvalues['/Ac/ConsumptionOnOutput/%s/Voltage' % phase] = voltageOut[phase] -+ newvalues['/Ac/ConsumptionOnInput/%s/Voltage' % phase] = voltageIn[phase] -+ if voltageOut[phase] != None: -+ newvalues['/Ac/Consumption/%s/Voltage' % phase] = voltageOut[phase] -+ elif voltageIn[phase] != None: -+ newvalues['/Ac/Consumption/%s/Voltage' % phase] = voltageIn[phase] -+ if frequencyIn != None: -+ newvalues['/Ac/ConsumptionOnInput/Frequency'] = frequencyIn -+ if frequencyOut != None: -+ newvalues['/Ac/ConsumptionOnOutput/Frequency'] = frequencyOut -+ if frequencyOut != None: -+ newvalues['/Ac/Consumption/Frequency'] = frequencyOut -+ elif frequencyIn != None: -+ newvalues['/Ac/Consumption/Frequency'] = frequencyIn -+ - self._compute_number_of_phases('/Ac/Consumption', newvalues) - self._compute_number_of_phases('/Ac/ConsumptionOnOutput', newvalues) - self._compute_number_of_phases('/Ac/ConsumptionOnInput', newvalues) diff --git a/FileSets/PatchSource/dbus_systemcalc.py-v3.40~2 b/FileSets/PatchSource/dbus_systemcalc.py-v3.34 similarity index 100% rename from FileSets/PatchSource/dbus_systemcalc.py-v3.40~2 rename to FileSets/PatchSource/dbus_systemcalc.py-v3.34 diff --git a/FileSets/PatchSource/dbus_systemcalc.py-v3.40~2.orig b/FileSets/PatchSource/dbus_systemcalc.py-v3.34.orig similarity index 100% rename from FileSets/PatchSource/dbus_systemcalc.py-v3.40~2.orig rename to FileSets/PatchSource/dbus_systemcalc.py-v3.34.orig diff --git a/FileSets/PatchSource/dbus_systemcalc.py-v3.40~2.patch b/FileSets/PatchSource/dbus_systemcalc.py-v3.34.patch similarity index 99% rename from FileSets/PatchSource/dbus_systemcalc.py-v3.40~2.patch rename to FileSets/PatchSource/dbus_systemcalc.py-v3.34.patch index 341f40ba..c50f5a7c 100644 --- a/FileSets/PatchSource/dbus_systemcalc.py-v3.40~2.patch +++ b/FileSets/PatchSource/dbus_systemcalc.py-v3.34.patch @@ -1,5 +1,5 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/dbus_systemcalc.py-v3.40~2.orig 2024-07-08 07:47:23 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/dbus_systemcalc.py-v3.40~2 2024-04-04 21:38:40 +--- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/dbus_systemcalc.py-v3.34.orig 2024-07-08 07:47:23 ++++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/dbus_systemcalc.py-v3.34 2024-04-04 21:38:40 @@ -1,6 +1,8 @@ #!/usr/bin/python3 -u # -*- coding: utf-8 -*- diff --git a/FileSets/PatchSource/dbus_systemcalc.py-v3.40~35 b/FileSets/PatchSource/dbus_systemcalc.py-v3.40 similarity index 100% rename from FileSets/PatchSource/dbus_systemcalc.py-v3.40~35 rename to FileSets/PatchSource/dbus_systemcalc.py-v3.40 diff --git a/FileSets/PatchSource/dbus_systemcalc.py-v3.40~35.orig b/FileSets/PatchSource/dbus_systemcalc.py-v3.40.orig similarity index 100% rename from FileSets/PatchSource/dbus_systemcalc.py-v3.40~35.orig rename to FileSets/PatchSource/dbus_systemcalc.py-v3.40.orig diff --git a/FileSets/PatchSource/dbus_systemcalc.py-v3.40~35.patch b/FileSets/PatchSource/dbus_systemcalc.py-v3.40.patch similarity index 99% rename from FileSets/PatchSource/dbus_systemcalc.py-v3.40~35.patch rename to FileSets/PatchSource/dbus_systemcalc.py-v3.40.patch index 5426930f..08385e5f 100644 --- a/FileSets/PatchSource/dbus_systemcalc.py-v3.40~35.patch +++ b/FileSets/PatchSource/dbus_systemcalc.py-v3.40.patch @@ -1,5 +1,5 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/dbus_systemcalc.py-v3.40~35.orig 2024-07-08 07:47:22 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/dbus_systemcalc.py-v3.40~35 2024-07-08 07:46:54 +--- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/dbus_systemcalc.py-v3.40.orig 2024-07-08 07:47:22 ++++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/dbus_systemcalc.py-v3.40 2024-07-08 07:46:54 @@ -1,6 +1,8 @@ #!/usr/bin/python3 -u # -*- coding: utf-8 -*- diff --git a/FileSets/PatchSource/dbus_systemcalc.py-v3.40~10.patch b/FileSets/PatchSource/dbus_systemcalc.py-v3.40~10.patch deleted file mode 100644 index 943be143..00000000 --- a/FileSets/PatchSource/dbus_systemcalc.py-v3.40~10.patch +++ /dev/null @@ -1,392 +0,0 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/dbus_systemcalc.py-v3.40~10.orig 2024-07-08 07:47:23 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/dbus_systemcalc.py-v3.40~10 2024-04-23 14:45:34 -@@ -1,6 +1,8 @@ - #!/usr/bin/python3 -u - # -*- coding: utf-8 -*- - -+#### modified for GuiMods -+ - from dbus.mainloop.glib import DBusGMainLoop - import dbus - import argparse -@@ -72,6 +74,20 @@ - '/Ac/Out/L1/I': dummy, - '/Ac/Out/L2/I': dummy, - '/Ac/Out/L3/I': dummy, -+#### add for GuiMods -+ '/Ac/Out/L1/V': dummy, -+ '/Ac/Out/L2/V': dummy, -+ '/Ac/Out/L3/V': dummy, -+ '/Ac/Out/L1/F': dummy, -+ '/Ac/Out/L2/F': dummy, -+ '/Ac/Out/L3/F': dummy, -+ '/Ac/ActiveIn/L1/V': dummy, -+ '/Ac/ActiveIn/L2/V': dummy, -+ '/Ac/ActiveIn/L3/V': dummy, -+ '/Ac/ActiveIn/L1/F': dummy, -+ '/Ac/ActiveIn/L2/F': dummy, -+ '/Ac/ActiveIn/L3/F': dummy, -+ - '/Connected': dummy, - '/ProductId': dummy, - '/ProductName': dummy, -@@ -109,7 +125,14 @@ - '/Ac/L3/Power': dummy, - '/Ac/L1/Current': dummy, - '/Ac/L2/Current': dummy, -- '/Ac/L3/Current': dummy}, -+ '/Ac/L3/Current': dummy, -+#### add for GuiMods -+ '/Ac/L1/Voltage': dummy, -+ '/Ac/L2/Voltage': dummy, -+ '/Ac/L3/Voltage': dummy, -+ '/Ac/L1/Frequency': dummy, -+ '/Ac/L2/Frequency': dummy, -+ '/Ac/L3/Frequency': dummy}, - 'com.victronenergy.genset' : { - '/Connected': dummy, - '/ProductName': dummy, -@@ -122,6 +145,14 @@ - '/Ac/L1/Current': dummy, - '/Ac/L2/Current': dummy, - '/Ac/L3/Current': dummy, -+#### add for GuiMods -+ '/Ac/L1/Voltage': dummy, -+ '/Ac/L2/Voltage': dummy, -+ '/Ac/L3/Voltage': dummy, -+ '/Ac/L1/Frequency': dummy, -+ '/Ac/L2/Frequency': dummy, -+ '/Ac/L3/Frequency': dummy, -+ - '/StarterVoltage': dummy}, - 'com.victronenergy.settings' : { - '/Settings/SystemSetup/AcInput1' : dummy, -@@ -151,6 +182,9 @@ - '/Ac/Out/L3/S': dummy, - '/Ac/Out/L3/V': dummy, - '/Ac/Out/L3/I': dummy, -+#### add for GuiMods -+ '/Ac/Out/L1/F': dummy, -+ - '/Yield/Power': dummy, - '/Soc': dummy}, - 'com.victronenergy.multi': { -@@ -184,6 +218,9 @@ - '/Ac/Out/L3/P': dummy, - '/Ac/Out/L3/V': dummy, - '/Ac/Out/L3/I': dummy, -+#### add for GuiMods -+ '/Ac/Out/L1/F': dummy, -+ - '/Yield/Power': dummy, - '/Soc': dummy}, - 'com.victronenergy.dcsystem': { -@@ -192,6 +229,15 @@ - }, - 'com.victronenergy.alternator': { - '/Dc/0/Power': dummy -+ }, -+#### added for GuiMods -+ 'com.victronenergy.dcsource': { -+ '/Dc/0/Power': dummy, -+ '/Settings/MonitorMode': dummy -+ }, -+ 'com.victronenergy.motordrive': -+ { -+ '/Dc/0/Power': dummy - } - } - -@@ -348,6 +394,8 @@ - '/Dc/Charger/Power': {'gettext': '%.0F %%'}, - '/Dc/FuelCell/Power': {'gettext': '%.0F %%'}, - '/Dc/Alternator/Power': {'gettext': '%.0F W'}, -+ '/Dc/Vebus/Current': {'gettext': '%.1F A'}, -+ '/Dc/Vebus/Power': {'gettext': '%.0F W'}, - '/Dc/System/Power': {'gettext': '%.0F W'}, - '/Dc/System/MeasurementType': {'gettext': '%d'}, - '/Ac/ActiveIn/Source': {'gettext': '%s'}, -@@ -365,7 +413,34 @@ - '/Ac/Consumption/Current/Max': {'gettext': '%.1F'}, - '/Pv/Power/Max': {'gettext': '%d'}, - '/Dc/Input/Power/Max': {'gettext': '%d'}, -- '/Dc/System/Power/Max': {'gettext': '%d'} -+ '/Dc/System/Power/Max': {'gettext': '%d'}, -+#### added for GuiMods -+ '/Dc/WindGenerator/Power': {'gettext': '%.0F W'}, -+ '/Dc/MotorDrive/Power': {'gettext': '%.0F W'}, -+ '/Ac/Grid/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Grid/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Grid/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Grid/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/Genset/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Genset/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Genset/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Genset/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/ConsumptionOnOutput/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnOutput/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnOutput/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnOutput/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/ConsumptionOnInput/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnInput/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnInput/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnInput/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/Consumption/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Consumption/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Consumption/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Consumption/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/ActiveIn/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ActiveIn/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ActiveIn/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ActiveIn/Frequency': {'gettext': '%.1F Hz'}, - } - - for m in self._modules: -@@ -384,6 +459,9 @@ - self._changed = True - for service, instance in self._dbusmonitor.get_service_list().items(): - self._device_added(service, instance, do_service_change=False) -+ -+#### added for GuiMods -+ self.dcSystemPower = [0, 0, 0] - - self._handleservicechange() - self._updatevalues() -@@ -633,16 +711,50 @@ - # ==== ALTERNATOR ==== - alternators = self._dbusmonitor.get_service_list('com.victronenergy.alternator') - for alternator in alternators: -+#### modified for GuiMods -+ # some alternators do not provide a valid power value if not running -+ # or below a minimum power/current -+ # so fill in a zero power so that the systemcalc power becomes valid - # Assume the battery connected to output 0 is the main battery - p = self._dbusmonitor.get_value(alternator, '/Dc/0/Power') - if p is None: - continue -+ p = 0 - - if '/Dc/Alternator/Power' not in newvalues: - newvalues['/Dc/Alternator/Power'] = p - else: - newvalues['/Dc/Alternator/Power'] += p - -+ -+#### added for GuiMods -+ # ==== MOTOR DRIVE ==== -+ motordrives = self._dbusmonitor.get_service_list('com.victronenergy.motordrive') -+ for motordrive in motordrives: -+ p = self._dbusmonitor.get_value(motordrive, '/Dc/0/Power') -+ if p is None: -+ p = 0 -+ -+ if '/Dc/MotorDrive/Power' not in newvalues: -+ newvalues['/Dc/MotorDrive/Power'] = p -+ else: -+ newvalues['/Dc/MotorDrive/Power'] += p -+ -+#### added for GuiMods -+ # ==== DC SOURCES ==== -+ dcSources = self._dbusmonitor.get_service_list('com.victronenergy.dcsource') -+ for dcSource in dcSources: -+ monitorMode = self._dbusmonitor.get_value(dcSource,'/Settings/MonitorMode') -+ # ==== WIND GENERATOR ==== -+ if monitorMode == -8: -+ p = self._dbusmonitor.get_value(dcSource, '/Dc/0/Power') -+ if p is None: -+ continue -+ if '/Dc/WindGenerator/Power' not in newvalues: -+ newvalues['/Dc/WindGenerator/Power'] = p -+ else: -+ newvalues['/Dc/WindGenerator/Power'] += p -+ - # ==== CHARGERS ==== - chargers = self._dbusmonitor.get_service_list('com.victronenergy.charger') - charger_batteryvoltage = None -@@ -804,6 +916,9 @@ - charger_power = newvalues.get('/Dc/Charger/Power', 0) - fuelcell_power = newvalues.get('/Dc/FuelCell/Power', 0) - alternator_power = newvalues.get('/Dc/Alternator/Power', 0) -+#### added for GuiMods -+ windgen_power = newvalues.get('/Dc/WindGenerator/Power', 0) -+ motordrive_power = newvalues.get('/Dc/MotorDrive/Power', 0) - - # If there are VE.Direct inverters, remove their power from the - # DC estimate. This is done using the AC value when the DC -@@ -824,7 +939,12 @@ - # displayed. For now, we leave it out so that in the current - # version of Venus it does not break user's expectations. - #newvalues['/Dc/System/Power'] = dc_pv_power + charger_power + fuelcell_power + vebuspower + inverter_power - battery_power - alternator_power -- newvalues['/Dc/System/Power'] = dc_pv_power + charger_power + fuelcell_power + vebuspower + inverter_power - battery_power -+#### changed for GuiMods -+ # average DC system power over 3 passes (seconds) to minimize wild swings in displayed value -+ self.dcSystemPower[2] = self.dcSystemPower[1] -+ self.dcSystemPower[1] = self.dcSystemPower[0] -+ self.dcSystemPower[0] = dc_pv_power + charger_power + fuelcell_power + vebuspower + inverter_power - battery_power + alternator_power + windgen_power - motordrive_power -+ newvalues['/Dc/System/Power'] = (self.dcSystemPower[0] + self.dcSystemPower[1] + self.dcSystemPower[2]) / 3 - - elif self._settings['hasdcsystem'] == 1 and solarchargers_loadoutput_power is not None: - newvalues['/Dc/System/MeasurementType'] = 0 # estimated -@@ -871,6 +991,13 @@ - - consumption = { "L1" : None, "L2" : None, "L3" : None } - currentconsumption = { "L1" : None, "L2" : None, "L3" : None } -+ -+#### added for GuiMods -+ voltageIn = { "L1" : None, "L2" : None, "L3" : None } -+ voltageOut = { "L1" : None, "L2" : None, "L3" : None } -+ frequencyIn = None -+ frequencyOut = None -+ - for device_type, em, _types in (('Grid', grid_meter, (1, 3)), ('Genset', genset_meter, (2,))): - # If a grid meter is present we use values from it. If not, we look at the multi. If it has - # AcIn1 or AcIn2 connected to the grid, we use those values. -@@ -886,6 +1013,12 @@ - if em is not None: - p = self._dbusmonitor.get_value(em.service, '/Ac/%s/Power' % phase) - mc = self._dbusmonitor.get_value(em.service, '/Ac/%s/Current' % phase) -+#### added for GuiMods -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(em.service, '/Ac/%s/Voltage' % phase) -+ if frequencyIn == None: -+ frequencyIn = self._dbusmonitor.get_value(em.service, '/Ac/%s/Frequency' % phase) -+ - # Compute consumption between energy meter and multi (meter power - multi AC in) and - # add an optional PV inverter on input to the mix. - c = None -@@ -895,6 +1028,12 @@ - try: - c = _safeadd(c, -self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/P' % phase)) - cc = _safeadd(cc, -self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/I' % phase)) -+#### added for GuiMods -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(em.service, '/Ac/ActiveIn/%s/V' % phase) -+ if frequencyIn == None: -+ frequencyIn = self._dbusmonitor.get_value(em.service, '/Ac/ActiveIn/%s/F' % phase) -+ - except TypeError: - pass - elif non_vebus_inverter is not None and active_input in (0, 1): -@@ -902,6 +1041,12 @@ - try: - c = _safeadd(c, -self._dbusmonitor.get_value(i, '/Ac/In/%d/%s/P' % (active_input+1, phase))) - cc = _safeadd(cc, -self._dbusmonitor.get_value(i, '/Ac/In/%d/%s/I' % (active_input+1, phase))) -+#### added for GuiMods -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(i, '/Ac/In/%d/%s/V' % (active_input+1, phase)) -+ if frequencyIn == None: -+ frequencyIn = self._dbusmonitor.get_value(i, '/Ac/In/%d/%s/F' % (active_input+1, phase)) -+ - except TypeError: - pass - -@@ -919,12 +1064,26 @@ - consumption[phase] = _safeadd(0, consumption[phase]) - currentconsumption[phase] = _safeadd(0, currentconsumption[phase]) - mc = self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/I' % phase) -+#### added for GuiMods -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/V' % phase) -+ if frequencyIn == None: -+ freq = self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/F' % phase) -+ if freq != None: -+ frequencyIn = freq -+ - elif non_vebus_inverter is not None and active_input in (0, 1): - for i in non_vebus_inverters: - p = _safeadd(p, - self._dbusmonitor.get_value(i, '/Ac/In/%d/%s/P' % (active_input + 1, phase))) - mc = _safeadd(mc, - self._dbusmonitor.get_value(i, '/Ac/In/%d/%s/I' % (active_input + 1, phase))) -+#### added for GuiMods -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(i, '/Ac/In/%d/%s/V' % (active_input + 1, phase)) -+ if frequencyIn == None: -+ frequencyIn = self._dbusmonitor.get_value(i, '/Ac/In/%d/%s/F' % (active_input + 1, phase)) -+ - if p is not None: - consumption[phase] = _safeadd(0, consumption[phase]) - currentconsumption[phase] = _safeadd(0, currentconsumption[phase]) -@@ -939,9 +1098,18 @@ - - newvalues['/Ac/%s/%s/Power' % (device_type, phase)] = p - newvalues['/Ac/%s/%s/Current' % (device_type, phase)] = mc -+#### added for GuiMods -+ if p != None: -+ newvalues['/Ac/%s/%s/Voltage' % (device_type, phase)] = voltageIn[phase] -+ newvalues['/Ac/%s/Frequency' % (device_type)] = frequencyIn -+ - if ac_in_guess in _types: - newvalues['/Ac/ActiveIn/%s/Power' % (phase,)] = p - newvalues['/Ac/ActiveIn/%s/Current' % (phase,)] = mc -+#### added for GuiMods -+ if p != None: -+ newvalues['/Ac/ActiveIn/%s/Voltage' % (phase,)] = voltageIn[phase] -+ newvalues['/Ac/ActiveIn/Frequency'] = frequencyIn - - self._compute_number_of_phases('/Ac/%s' % device_type, newvalues) - self._compute_number_of_phases('/Ac/ActiveIn', newvalues) -@@ -972,16 +1140,28 @@ - if use_ac_out: - c = newvalues.get('/Ac/PvOnOutput/%s/Power' % phase) - a = newvalues.get('/Ac/PvOnOutput/%s/Current' % phase) -+#### added for GuiMods -+ if voltageOut[phase] == None: -+ voltageOut[phase] = newvalues.get('/Ac/PvOnOutput/%s/Voltage' % phase) -+ if frequencyOut == None: -+ frequencyOut = newvalues.get('/Ac/PvOnOutput/%s/Frequency' % phase) -+ - if multi_path is None: - for inv in non_vebus_inverters: - ac_out = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/P' % phase) - i = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/I' % phase) -+#### added for GuiMods -+ if voltageOut[phase] == None: -+ voltageOut[phase] = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/V' % phase) -+ if frequencyOut == None: -+ frequencyOut = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/F' % phase) - - # Some models don't show power, try apparent power, - # else calculate it - if ac_out is None: - ac_out = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/S' % phase) - if ac_out is None: -+#### modified for GuiMods - u = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/V' % phase) - if None not in (i, u): - ac_out = i * u -@@ -992,6 +1172,11 @@ - c = _safeadd(c, ac_out) - i_out = self._dbusmonitor.get_value(multi_path, '/Ac/Out/%s/I' % phase) - a = _safeadd(a, i_out) -+#### added for GuiMods -+ if voltageOut[phase] == None: -+ voltageOut[phase] = self._dbusmonitor.get_value(multi_path, '/Ac/Out/%s/V' % phase) -+ if frequencyOut == None: -+ frequencyOut = self._dbusmonitor.get_value(multi_path, '/Ac/Out/%s/F' % phase) - c = _safemax(0, c) - a = _safemax(0, a) - newvalues['/Ac/ConsumptionOnOutput/%s/Power' % phase] = c -@@ -1000,6 +1185,22 @@ - newvalues['/Ac/ConsumptionOnInput/%s/Current' % phase] = currentconsumption[phase] - newvalues['/Ac/Consumption/%s/Power' % phase] = _safeadd(consumption[phase], c) - newvalues['/Ac/Consumption/%s/Current' % phase] = _safeadd(currentconsumption[phase], a) -+#### added for GuiMods -+ newvalues['/Ac/ConsumptionOnOutput/%s/Voltage' % phase] = voltageOut[phase] -+ newvalues['/Ac/ConsumptionOnInput/%s/Voltage' % phase] = voltageIn[phase] -+ if voltageOut[phase] != None: -+ newvalues['/Ac/Consumption/%s/Voltage' % phase] = voltageOut[phase] -+ elif voltageIn[phase] != None: -+ newvalues['/Ac/Consumption/%s/Voltage' % phase] = voltageIn[phase] -+ if frequencyIn != None: -+ newvalues['/Ac/ConsumptionOnInput/Frequency'] = frequencyIn -+ if frequencyOut != None: -+ newvalues['/Ac/ConsumptionOnOutput/Frequency'] = frequencyOut -+ if frequencyOut != None: -+ newvalues['/Ac/Consumption/Frequency'] = frequencyOut -+ elif frequencyIn != None: -+ newvalues['/Ac/Consumption/Frequency'] = frequencyIn -+ - self._compute_number_of_phases('/Ac/Consumption', newvalues) - self._compute_number_of_phases('/Ac/ConsumptionOnOutput', newvalues) - self._compute_number_of_phases('/Ac/ConsumptionOnInput', newvalues) diff --git a/FileSets/PatchSource/dbus_systemcalc.py-v3.40~15.patch b/FileSets/PatchSource/dbus_systemcalc.py-v3.40~15.patch deleted file mode 100644 index ef9781ab..00000000 --- a/FileSets/PatchSource/dbus_systemcalc.py-v3.40~15.patch +++ /dev/null @@ -1,569 +0,0 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/dbus_systemcalc.py-v3.40~15.orig 2024-07-08 07:47:23 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/dbus_systemcalc.py-v3.40~15 2024-05-17 06:54:36 -@@ -1,6 +1,8 @@ - #!/usr/bin/python3 -u - # -*- coding: utf-8 -*- - -+#### modified for GuiMods -+ - from dbus.mainloop.glib import DBusGMainLoop - import dbus - import argparse -@@ -72,6 +74,20 @@ - '/Ac/Out/L1/I': dummy, - '/Ac/Out/L2/I': dummy, - '/Ac/Out/L3/I': dummy, -+#### add for GuiMods -+ '/Ac/Out/L1/V': dummy, -+ '/Ac/Out/L2/V': dummy, -+ '/Ac/Out/L3/V': dummy, -+ '/Ac/Out/L1/F': dummy, -+ '/Ac/Out/L2/F': dummy, -+ '/Ac/Out/L3/F': dummy, -+ '/Ac/ActiveIn/L1/V': dummy, -+ '/Ac/ActiveIn/L2/V': dummy, -+ '/Ac/ActiveIn/L3/V': dummy, -+ '/Ac/ActiveIn/L1/F': dummy, -+ '/Ac/ActiveIn/L2/F': dummy, -+ '/Ac/ActiveIn/L3/F': dummy, -+ - '/Connected': dummy, - '/ProductId': dummy, - '/ProductName': dummy, -@@ -109,7 +125,14 @@ - '/Ac/L3/Power': dummy, - '/Ac/L1/Current': dummy, - '/Ac/L2/Current': dummy, -- '/Ac/L3/Current': dummy}, -+ '/Ac/L3/Current': dummy, -+#### add for GuiMods -+ '/Ac/L1/Voltage': dummy, -+ '/Ac/L2/Voltage': dummy, -+ '/Ac/L3/Voltage': dummy, -+ '/Ac/L1/Frequency': dummy, -+ '/Ac/L2/Frequency': dummy, -+ '/Ac/L3/Frequency': dummy}, - 'com.victronenergy.genset' : { - '/Connected': dummy, - '/ProductName': dummy, -@@ -122,6 +145,14 @@ - '/Ac/L1/Current': dummy, - '/Ac/L2/Current': dummy, - '/Ac/L3/Current': dummy, -+#### add for GuiMods -+ '/Ac/L1/Voltage': dummy, -+ '/Ac/L2/Voltage': dummy, -+ '/Ac/L3/Voltage': dummy, -+ '/Ac/L1/Frequency': dummy, -+ '/Ac/L2/Frequency': dummy, -+ '/Ac/L3/Frequency': dummy, -+ - '/StarterVoltage': dummy}, - 'com.victronenergy.settings' : { - '/Settings/SystemSetup/AcInput1' : dummy, -@@ -151,6 +182,9 @@ - '/Ac/Out/L3/S': dummy, - '/Ac/Out/L3/V': dummy, - '/Ac/Out/L3/I': dummy, -+#### add for GuiMods -+ '/Ac/Out/L1/F': dummy, -+ - '/Yield/Power': dummy, - '/Soc': dummy}, - 'com.victronenergy.multi': { -@@ -184,6 +218,9 @@ - '/Ac/Out/L3/P': dummy, - '/Ac/Out/L3/V': dummy, - '/Ac/Out/L3/I': dummy, -+#### add for GuiMods -+ '/Ac/Out/L1/F': dummy, -+ - '/Yield/Power': dummy, - '/Soc': dummy}, - 'com.victronenergy.dcsystem': { -@@ -191,6 +228,15 @@ - '/Dc/0/Power': dummy - }, - 'com.victronenergy.alternator': { -+ '/Dc/0/Power': dummy -+ }, -+#### added for GuiMods -+ 'com.victronenergy.dcsource': { -+ '/Dc/0/Power': dummy, -+ '/Settings/MonitorMode': dummy -+ }, -+ 'com.victronenergy.motordrive': -+ { - '/Dc/0/Power': dummy - } - } -@@ -232,24 +278,39 @@ - self._dbusmonitor = self._create_dbus_monitor(dbus_tree, valueChangedCallback=self._dbus_value_changed, - deviceAddedCallback=self._device_added, deviceRemovedCallback=self._device_removed) - -+ # Used to store AC output maximum values for the scenarios: -+ # No AC input connected -+ # Ac input 1 connected -+ # Ac input 2 connected -+ self._acMaxima = { -+ 'NoAcIn': 0, -+ 'AcIn1': 0, -+ 'AcIn2': 0 -+ } -+ -+ self._minMaxPaths = { -+ '/Ac/In/0/Current/Min': [float(0), -float("inf"), 0], -+ '/Ac/In/1/Current/Min': [float(0), -float("inf"), 0], -+ '/Ac/In/0/Current/Max': [float(0), 0, float("inf")], -+ '/Ac/In/1/Current/Max': [float(0), 0, float("inf")], -+ '/Dc/Input/Power/Max': [float(0), 0, float("inf")], -+ '/Dc/System/Power/Max': [float(0), 0, float("inf")], -+ '/Pv/Power/Max': [float(0), 0, float("inf")] -+ } -+ -+ for p in self._acMaxima.keys(): -+ self._minMaxPaths['/Ac/%s/Consumption/Current/Max' % p] = [float(0), 0, float("inf")] -+ - # Connect to localsettings - supported_settings = { - 'batteryservice': ['/Settings/SystemSetup/BatteryService', self.BATSERVICE_DEFAULT, 0, 0], - 'hasdcsystem': ['/Settings/SystemSetup/HasDcSystem', 0, 0, 1], - 'useacout': ['/Settings/SystemSetup/HasAcOutSystem', 1, 0, 1], -- 'gaugeautomax': ['/Settings/Gui/Gauges/AutoMax', 1, 0, 1], -- 'acin0min': ['/Settings/Gui/Gauges/Ac/In/0/Current/Min', float(0), -float("inf"), 0], -- 'acin1min': ['/Settings/Gui/Gauges/Ac/In/1/Current/Min', float(0), -float("inf"), 0], -- 'acin0max': ['/Settings/Gui/Gauges/Ac/In/0/Current/Max', float(0), 0, float("inf")], -- 'acin1max': ['/Settings/Gui/Gauges/Ac/In/1/Current/Max', float(0), 0, float("inf")], -- 'dcinmax': ['/Settings/Gui/Gauges/Dc/Input/Power/Max', float(0), 0, float("inf")], -- 'dcsysmax': ['/Settings/Gui/Gauges/Dc/System/Power/Max', float(0), 0, float("inf")], -- 'pvmax': ['/Settings/Gui/Gauges/Pv/Power/Max', float(0), 0, float("inf")], -- 'noacinmax': ['/Settings/Gui/Gauges/Ac/NoAcIn/Consumption/Current/Max', float(0), 0, float("inf")], -- 'acin1max': ['/Settings/Gui/Gauges/Ac/AcIn1/Consumption/Current/Max', float(0), 0, float("inf")], -- 'acin2max': ['/Settings/Gui/Gauges/Ac/AcIn2/Consumption/Current/Max', float(0), 0, float("inf")], -- } -+ 'gaugeautomax': ['/Settings/Gui/Gauges/AutoMax', 1, 0, 1]} - -+ for p, s in self._minMaxPaths.items(): -+ supported_settings[p] = ['/Settings/Gui/Gauges' + p, s[0], s[1], s[2]] -+ - for m in self._modules: - for setting in m.get_settings(): - supported_settings[setting[0]] = list(setting[1:]) -@@ -333,6 +394,8 @@ - '/Dc/Charger/Power': {'gettext': '%.0F %%'}, - '/Dc/FuelCell/Power': {'gettext': '%.0F %%'}, - '/Dc/Alternator/Power': {'gettext': '%.0F W'}, -+ '/Dc/Vebus/Current': {'gettext': '%.1F A'}, -+ '/Dc/Vebus/Power': {'gettext': '%.0F W'}, - '/Dc/System/Power': {'gettext': '%.0F W'}, - '/Dc/System/MeasurementType': {'gettext': '%d'}, - '/Ac/ActiveIn/Source': {'gettext': '%s'}, -@@ -343,6 +406,41 @@ - '/Ac/ActiveIn/L2/Current': {'gettext': '%.1F A'}, - '/Ac/ActiveIn/L3/Current': {'gettext': '%.1F A'}, - '/Ac/ActiveIn/NumberOfPhases': {'gettext': '%d'}, -+ '/Ac/In/0/Current/Min': {'gettext': '%.1F'}, -+ '/Ac/In/0/Current/Max': {'gettext': '%.1F'}, -+ '/Ac/In/1/Current/Min': {'gettext': '%.1F'}, -+ '/Ac/In/1/Current/Max': {'gettext': '%.1F'}, -+ '/Ac/Consumption/Current/Max': {'gettext': '%.1F'}, -+ '/Pv/Power/Max': {'gettext': '%d'}, -+ '/Dc/Input/Power/Max': {'gettext': '%d'}, -+ '/Dc/System/Power/Max': {'gettext': '%d'}, -+#### added for GuiMods -+ '/Dc/WindGenerator/Power': {'gettext': '%.0F W'}, -+ '/Dc/MotorDrive/Power': {'gettext': '%.0F W'}, -+ '/Ac/Grid/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Grid/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Grid/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Grid/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/Genset/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Genset/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Genset/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Genset/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/ConsumptionOnOutput/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnOutput/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnOutput/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnOutput/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/ConsumptionOnInput/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnInput/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnInput/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ConsumptionOnInput/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/Consumption/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Consumption/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Consumption/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/Consumption/Frequency': {'gettext': '%.1F Hz'}, -+ '/Ac/ActiveIn/L1/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ActiveIn/L2/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ActiveIn/L3/Voltage': {'gettext': '%.1F V'}, -+ '/Ac/ActiveIn/Frequency': {'gettext': '%.1F Hz'}, - } - - for m in self._modules: -@@ -362,6 +460,9 @@ - for service, instance in self._dbusmonitor.get_service_list().items(): - self._device_added(service, instance, do_service_change=False) - -+#### added for GuiMods -+ self.dcSystemPower = [0, 0, 0] -+ - self._handleservicechange() - self._updatevalues() - -@@ -611,16 +712,50 @@ - # ==== ALTERNATOR ==== - alternators = self._dbusmonitor.get_service_list('com.victronenergy.alternator') - for alternator in alternators: -+#### modified for GuiMods -+ # some alternators do not provide a valid power value if not running -+ # or below a minimum power/current -+ # so fill in a zero power so that the systemcalc power becomes valid - # Assume the battery connected to output 0 is the main battery - p = self._dbusmonitor.get_value(alternator, '/Dc/0/Power') - if p is None: - continue -+ p = 0 - - if '/Dc/Alternator/Power' not in newvalues: - newvalues['/Dc/Alternator/Power'] = p - else: - newvalues['/Dc/Alternator/Power'] += p -+ -+ -+#### added for GuiMods -+ # ==== MOTOR DRIVE ==== -+ motordrives = self._dbusmonitor.get_service_list('com.victronenergy.motordrive') -+ for motordrive in motordrives: -+ p = self._dbusmonitor.get_value(motordrive, '/Dc/0/Power') -+ if p is None: -+ p = 0 -+ -+ if '/Dc/MotorDrive/Power' not in newvalues: -+ newvalues['/Dc/MotorDrive/Power'] = p -+ else: -+ newvalues['/Dc/MotorDrive/Power'] += p - -+#### added for GuiMods -+ # ==== DC SOURCES ==== -+ dcSources = self._dbusmonitor.get_service_list('com.victronenergy.dcsource') -+ for dcSource in dcSources: -+ monitorMode = self._dbusmonitor.get_value(dcSource,'/Settings/MonitorMode') -+ # ==== WIND GENERATOR ==== -+ if monitorMode == -8: -+ p = self._dbusmonitor.get_value(dcSource, '/Dc/0/Power') -+ if p is None: -+ continue -+ if '/Dc/WindGenerator/Power' not in newvalues: -+ newvalues['/Dc/WindGenerator/Power'] = p -+ else: -+ newvalues['/Dc/WindGenerator/Power'] += p -+ - # ==== CHARGERS ==== - chargers = self._dbusmonitor.get_service_list('com.victronenergy.charger') - charger_batteryvoltage = None -@@ -782,6 +917,9 @@ - charger_power = newvalues.get('/Dc/Charger/Power', 0) - fuelcell_power = newvalues.get('/Dc/FuelCell/Power', 0) - alternator_power = newvalues.get('/Dc/Alternator/Power', 0) -+#### added for GuiMods -+ windgen_power = newvalues.get('/Dc/WindGenerator/Power', 0) -+ motordrive_power = newvalues.get('/Dc/MotorDrive/Power', 0) - - # If there are VE.Direct inverters, remove their power from the - # DC estimate. This is done using the AC value when the DC -@@ -802,7 +940,12 @@ - # displayed. For now, we leave it out so that in the current - # version of Venus it does not break user's expectations. - #newvalues['/Dc/System/Power'] = dc_pv_power + charger_power + fuelcell_power + vebuspower + inverter_power - battery_power - alternator_power -- newvalues['/Dc/System/Power'] = dc_pv_power + charger_power + fuelcell_power + vebuspower + inverter_power - battery_power -+#### changed for GuiMods -+ # average DC system power over 3 passes (seconds) to minimize wild swings in displayed value -+ self.dcSystemPower[2] = self.dcSystemPower[1] -+ self.dcSystemPower[1] = self.dcSystemPower[0] -+ self.dcSystemPower[0] = dc_pv_power + charger_power + fuelcell_power + vebuspower + inverter_power - battery_power + alternator_power + windgen_power - motordrive_power -+ newvalues['/Dc/System/Power'] = (self.dcSystemPower[0] + self.dcSystemPower[1] + self.dcSystemPower[2]) / 3 - - elif self._settings['hasdcsystem'] == 1 and solarchargers_loadoutput_power is not None: - newvalues['/Dc/System/MeasurementType'] = 0 # estimated -@@ -849,6 +992,13 @@ - - consumption = { "L1" : None, "L2" : None, "L3" : None } - currentconsumption = { "L1" : None, "L2" : None, "L3" : None } -+ -+#### added for GuiMods -+ voltageIn = { "L1" : None, "L2" : None, "L3" : None } -+ voltageOut = { "L1" : None, "L2" : None, "L3" : None } -+ frequencyIn = None -+ frequencyOut = None -+ - for device_type, em, _types in (('Grid', grid_meter, (1, 3)), ('Genset', genset_meter, (2,))): - # If a grid meter is present we use values from it. If not, we look at the multi. If it has - # AcIn1 or AcIn2 connected to the grid, we use those values. -@@ -864,6 +1014,12 @@ - if em is not None: - p = self._dbusmonitor.get_value(em.service, '/Ac/%s/Power' % phase) - mc = self._dbusmonitor.get_value(em.service, '/Ac/%s/Current' % phase) -+#### added for GuiMods -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(em.service, '/Ac/%s/Voltage' % phase) -+ if frequencyIn == None: -+ frequencyIn = self._dbusmonitor.get_value(em.service, '/Ac/%s/Frequency' % phase) -+ - # Compute consumption between energy meter and multi (meter power - multi AC in) and - # add an optional PV inverter on input to the mix. - c = None -@@ -873,6 +1029,12 @@ - try: - c = _safeadd(c, -self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/P' % phase)) - cc = _safeadd(cc, -self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/I' % phase)) -+#### added for GuiMods -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(em.service, '/Ac/ActiveIn/%s/V' % phase) -+ if frequencyIn == None: -+ frequencyIn = self._dbusmonitor.get_value(em.service, '/Ac/ActiveIn/%s/F' % phase) -+ - except TypeError: - pass - elif non_vebus_inverter is not None and active_input in (0, 1): -@@ -880,6 +1042,12 @@ - try: - c = _safeadd(c, -self._dbusmonitor.get_value(i, '/Ac/In/%d/%s/P' % (active_input+1, phase))) - cc = _safeadd(cc, -self._dbusmonitor.get_value(i, '/Ac/In/%d/%s/I' % (active_input+1, phase))) -+#### added for GuiMods -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(i, '/Ac/In/%d/%s/V' % (active_input+1, phase)) -+ if frequencyIn == None: -+ frequencyIn = self._dbusmonitor.get_value(i, '/Ac/In/%d/%s/F' % (active_input+1, phase)) -+ - except TypeError: - pass - -@@ -897,12 +1065,26 @@ - consumption[phase] = _safeadd(0, consumption[phase]) - currentconsumption[phase] = _safeadd(0, currentconsumption[phase]) - mc = self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/I' % phase) -+#### added for GuiMods -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/V' % phase) -+ if frequencyIn == None: -+ freq = self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/F' % phase) -+ if freq != None: -+ frequencyIn = freq -+ - elif non_vebus_inverter is not None and active_input in (0, 1): - for i in non_vebus_inverters: - p = _safeadd(p, - self._dbusmonitor.get_value(i, '/Ac/In/%d/%s/P' % (active_input + 1, phase))) - mc = _safeadd(mc, - self._dbusmonitor.get_value(i, '/Ac/In/%d/%s/I' % (active_input + 1, phase))) -+#### added for GuiMods -+ if voltageIn[phase] == None: -+ voltageIn[phase] = self._dbusmonitor.get_value(i, '/Ac/In/%d/%s/V' % (active_input + 1, phase)) -+ if frequencyIn == None: -+ frequencyIn = self._dbusmonitor.get_value(i, '/Ac/In/%d/%s/F' % (active_input + 1, phase)) -+ - if p is not None: - consumption[phase] = _safeadd(0, consumption[phase]) - currentconsumption[phase] = _safeadd(0, currentconsumption[phase]) -@@ -917,9 +1099,18 @@ - - newvalues['/Ac/%s/%s/Power' % (device_type, phase)] = p - newvalues['/Ac/%s/%s/Current' % (device_type, phase)] = mc -+#### added for GuiMods -+ if p != None: -+ newvalues['/Ac/%s/%s/Voltage' % (device_type, phase)] = voltageIn[phase] -+ newvalues['/Ac/%s/Frequency' % (device_type)] = frequencyIn -+ - if ac_in_guess in _types: - newvalues['/Ac/ActiveIn/%s/Power' % (phase,)] = p - newvalues['/Ac/ActiveIn/%s/Current' % (phase,)] = mc -+#### added for GuiMods -+ if p != None: -+ newvalues['/Ac/ActiveIn/%s/Voltage' % (phase,)] = voltageIn[phase] -+ newvalues['/Ac/ActiveIn/Frequency'] = frequencyIn - - self._compute_number_of_phases('/Ac/%s' % device_type, newvalues) - self._compute_number_of_phases('/Ac/ActiveIn', newvalues) -@@ -950,16 +1141,28 @@ - if use_ac_out: - c = newvalues.get('/Ac/PvOnOutput/%s/Power' % phase) - a = newvalues.get('/Ac/PvOnOutput/%s/Current' % phase) -+#### added for GuiMods -+ if voltageOut[phase] == None: -+ voltageOut[phase] = newvalues.get('/Ac/PvOnOutput/%s/Voltage' % phase) -+ if frequencyOut == None: -+ frequencyOut = newvalues.get('/Ac/PvOnOutput/%s/Frequency' % phase) -+ - if multi_path is None: - for inv in non_vebus_inverters: - ac_out = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/P' % phase) - i = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/I' % phase) -+#### added for GuiMods -+ if voltageOut[phase] == None: -+ voltageOut[phase] = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/V' % phase) -+ if frequencyOut == None: -+ frequencyOut = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/F' % phase) - - # Some models don't show power, try apparent power, - # else calculate it - if ac_out is None: - ac_out = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/S' % phase) - if ac_out is None: -+#### modified for GuiMods - u = self._dbusmonitor.get_value(inv, '/Ac/Out/%s/V' % phase) - if None not in (i, u): - ac_out = i * u -@@ -970,6 +1173,11 @@ - c = _safeadd(c, ac_out) - i_out = self._dbusmonitor.get_value(multi_path, '/Ac/Out/%s/I' % phase) - a = _safeadd(a, i_out) -+#### added for GuiMods -+ if voltageOut[phase] == None: -+ voltageOut[phase] = self._dbusmonitor.get_value(multi_path, '/Ac/Out/%s/V' % phase) -+ if frequencyOut == None: -+ frequencyOut = self._dbusmonitor.get_value(multi_path, '/Ac/Out/%s/F' % phase) - c = _safemax(0, c) - a = _safemax(0, a) - newvalues['/Ac/ConsumptionOnOutput/%s/Power' % phase] = c -@@ -978,6 +1186,22 @@ - newvalues['/Ac/ConsumptionOnInput/%s/Current' % phase] = currentconsumption[phase] - newvalues['/Ac/Consumption/%s/Power' % phase] = _safeadd(consumption[phase], c) - newvalues['/Ac/Consumption/%s/Current' % phase] = _safeadd(currentconsumption[phase], a) -+#### added for GuiMods -+ newvalues['/Ac/ConsumptionOnOutput/%s/Voltage' % phase] = voltageOut[phase] -+ newvalues['/Ac/ConsumptionOnInput/%s/Voltage' % phase] = voltageIn[phase] -+ if voltageOut[phase] != None: -+ newvalues['/Ac/Consumption/%s/Voltage' % phase] = voltageOut[phase] -+ elif voltageIn[phase] != None: -+ newvalues['/Ac/Consumption/%s/Voltage' % phase] = voltageIn[phase] -+ if frequencyIn != None: -+ newvalues['/Ac/ConsumptionOnInput/Frequency'] = frequencyIn -+ if frequencyOut != None: -+ newvalues['/Ac/ConsumptionOnOutput/Frequency'] = frequencyOut -+ if frequencyOut != None: -+ newvalues['/Ac/Consumption/Frequency'] = frequencyOut -+ elif frequencyIn != None: -+ newvalues['/Ac/Consumption/Frequency'] = frequencyIn -+ - self._compute_number_of_phases('/Ac/Consumption', newvalues) - self._compute_number_of_phases('/Ac/ConsumptionOnOutput', newvalues) - self._compute_number_of_phases('/Ac/ConsumptionOnInput', newvalues) -@@ -986,29 +1210,29 @@ - m.update_values(newvalues) - - # ==== UPDATE MINIMUM AND MAXIMUM LEVELS ==== -- if (self._settings['gaugeautomax']): -- # min/max values are stored and updated in localsettings -- # values are stored under /Settings/Gui/Briefview -- # /Settings/Gui/Gauges/AutoMax: -- # 1-> Automatic: Gauge limits are updated automatically and stored in localsettings -- # 0-> Manual: Gauge limits are entered manually by the user -- # The gui pulls the gauge limits from localsettings and provides -- # a means for the user to set them if Automax is off. -+ # min/max values are stored in localsettings and synched once in a while. -+ # values are stored under /Settings/Gui/Briefview -+ # /Settings/Gui/Gauges/AutoMax: -+ # 1-> Automatic: Maxima are updated automatically and synched to localsettings -+ # 0-> Manual: Maxima are pulled from localsettings. -+ # min/max computations are done here because the _updatevalues method abstracts them -+ # away from the delegates. - -- # AC output -- # This maximum is maintained for 3 situations: -- # 1: AC input 1 is connected -- # 2: AC input 2 is connected -- # 3: No AC input is connected -- # All 3 scenarios may lead to different maximum values since the capabilities of the system changes. -- # So 3 different maxima are stored and relayed to /Ac/Consumption/Current/Max based on the active scenario. -- activeIn = 'acin1' if (self._dbusservice['/Ac/In/0/Connected'] == 1) else \ -- 'acin2' if (self._dbusservice['/Ac/In/1/Connected'] == 1) else \ -- 'noacin' -+ # AC output -+ # This maximum is maintained for 3 situations: -+ # 1: AC input 1 is connected -+ # 2: AC input 2 is connected -+ # 3: No AC input is connected -+ # All 3 scenarios may lead to different maximum values since the capabilities of the system changes. -+ # So 3 different maxima are stored and relayed to /Ac/Consumption/Current/Max based on the active scenario. -+ activeIn = 'AcIn1' if (self._dbusservice['/Ac/In/0/Connected'] == 1) else \ -+ 'AcIn2' if (self._dbusservice['/Ac/In/1/Connected'] == 1) else \ -+ 'NoAcIn' - -- # Quattro has 2 AC inputs which cannot be active simultaneously. -- # activeIn needs to 1 when 'Ac/In/1/Connected' is 1 and can be 0 otherwise. -- activeInNr = int(activeIn[-1]) -1 if activeIn != 'noacin' else None -+ # Quattro has 2 AC inputs which cannot be active simultaneously. -+ # activeIn needs to 1 when 'Ac/In/1/Connected' is 1 and can be 0 otherwise. -+ if (self._settings['gaugeautomax']): -+ activeInNr = int(activeIn[-1]) -1 if activeIn != 'NoAcIn' else None - - # AC input - # Minimum values occur when feeding back to the grid. -@@ -1016,34 +1240,36 @@ - # Update correct '/Ac/In/..' based on the current active input. - # When no inputs are active, paths '/Ac/In/[0/1]/Current/[Min/Max] will all be invalidated. - if(activeInNr != None): -- self._settings['acin%smin' % activeInNr] = min(0, -- self._settings['acin%smin' % activeInNr] or float("inf"), -+ newvalues['/Ac/In/%s/Current/Min' % activeInNr] = min(0, -+ self._dbusservice['/Ac/In/%s/Current/Min' % activeInNr] or float("inf"), - newvalues.get('/Ac/ActiveIn/L1/Current') or float("inf"), - newvalues.get('/Ac/ActiveIn/L2/Current') or float("inf"), - newvalues.get('/Ac/ActiveIn/L3/Current') or float("inf")) - -- self._settings['acin%smax' % activeInNr] = max(self._settings['acin%smax' % activeInNr] or 0, -+ newvalues['/Ac/In/%s/Current/Max' % activeInNr] = max(self._dbusservice['/Ac/In/%s/Current/Min' % activeInNr] or 0, - newvalues.get('/Ac/ActiveIn/L1/Current') or 0, - newvalues.get('/Ac/ActiveIn/L2/Current') or 0, - newvalues.get('/Ac/ActiveIn/L3/Current') or 0) - -- self._settings['%smax' % activeIn] = max(self._settings['%smax' % activeIn], -+ self._acMaxima[activeIn] = max(self._acMaxima[activeIn], - newvalues.get('/Ac/Consumption/L1/Current') or 0, - newvalues.get('/Ac/Consumption/L2/Current') or 0, - newvalues.get('/Ac/Consumption/L3/Current') or 0) - -+ newvalues['/Ac/Consumption/Current/Max'] = self._acMaxima[activeIn] -+ - # DC input -- self._settings['dcinmax'] = max(self._settings['dcinmax'] or 0, -+ newvalues['/Dc/Input/Power/Max'] = max(self._dbusservice['/Dc/Input/Power/Max'] or 0, - sum([newvalues.get('/Dc/Charger/Power') or 0, - newvalues.get('/Dc/FuelCell/Power') or 0, - newvalues.get('/Dc/Alternator/Power') or 0])) - - # DC output -- self._settings['dcsysmax'] = _safemax(self._settings['dcsysmax'] or 0, -+ newvalues['/Dc/System/Power/Max'] = _safemax(self._dbusservice['/Dc/System/Power/Max'] or 0, - newvalues.get('/Dc/System/Power') or 0) - - # PV power -- self._settings['pvmax'] = _safemax(self._settings['pvmax'] or 0, -+ newvalues['/Pv/Power/Max'] = _safemax(self._dbusservice['/Pv/Power/Max'] or 0, - _safeadd(newvalues.get('/Dc/Pv/Power') or 0, - self._dbusservice['/Ac/PvOnGrid/L1/Power'], - self._dbusservice['/Ac/PvOnGrid/L2/Power'], -@@ -1055,6 +1281,23 @@ - self._dbusservice['/Ac/PvOnOutput/L2/Power'], - self._dbusservice['/Ac/PvOnOutput/L3/Power'])) - -+ # Sync max values to localsettings (once each second) -+ for p in self._minMaxPaths.keys(): -+ if (p in newvalues and newvalues[p] != self._settings[p]): -+ self._settings[p] = newvalues[p] -+ -+ # Store the ac maxima values for the 3 different scenarios. These aren't in newvalues. -+ if(self._acMaxima[activeIn] != self._settings['/Ac/%s/Consumption/Current/Max' % activeIn]): -+ self._settings['/Ac/%s/Consumption/Current/Max' % activeIn] = self._acMaxima[activeIn] -+ -+ # Manual mode: relay min/max settings from localsettings to newvalues -+ # We have to fill newvalues on every iteration here because if we don't the value in dbusservice is invalidated -+ else: -+ for p in self._minMaxPaths.keys(): -+ newvalues[p] = self._settings[p] -+ -+ newvalues['/Ac/Consumption/Current/Max'] = self._settings['/Ac/%s/Consumption/Current/Max' % activeIn] -+ - # ==== UPDATE DBUS ITEMS ==== - with self._dbusservice as sss: - for path in self._summeditems.keys(): diff --git a/FileSets/PatchSource/main.qml-v2.94.patch b/FileSets/PatchSource/main.qml-v2.94.patch deleted file mode 100644 index ca2a6bf5..00000000 --- a/FileSets/PatchSource/main.qml-v2.94.patch +++ /dev/null @@ -1,470 +0,0 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/main.qml-v2.94.orig 2024-07-08 09:16:57 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/main.qml-v2.94 2023-05-19 16:35:06 -@@ -1,3 +1,6 @@ -+//////// Modified to hide the OverviewTiles page -+//////// Modified to substitute flow overview pages -+ - import QtQuick 1.1 - - import Qt.labs.components.native 1.0 -@@ -16,48 +19,108 @@ - property bool completed: false - property bool showAlert: NotificationCenter.alert - property bool alarm: NotificationCenter.alarm -- property bool overviewsLoaded: defaultOverview.valid && generatorOverview.valid && mobileOverview.valid && tanksOverview.valid && startWithMenu.valid -+//////// added for GuiMods flow pages -+ property bool overviewsLoaded: defaultOverview.valid && generatorOverview.valid && mobileOverview.valid && startWithMenu.valid && mobileOverviewEnhanced.valid && guiModsFlowOverview.valid && generatorOverviewEnhanced.valid - property string bindPrefix: "com.victronenergy.settings" - - property bool isNotificationPage: pageStack.currentPage && pageStack.currentPage.title === qsTr("Notifications") - property bool isOverviewPage: pageStack.currentPage && pageStack.currentPage.model === overviewModel; - property bool isOfflineFwUpdatePage: pageStack.currentPage && pageStack.currentPage.objectName === "offlineFwUpdatePage"; - -- -+//////// modified for GuiMods pages - property string hubOverviewType: theSystem.systemType.valid ? -- withoutGridMeter.value === 1 ? "Hub" : theSystem.systemType.value : "" -+ withoutGridMeter.value === 1 ? "Hub" : theSystem.systemType.value : "unknown" -+ property string currentHubOverview: "OverviewHub.qml" -+ property string currentMobileOverview: "" -+ property string currentGeneratorOverview: "" - - // Keep track of the current view (menu/overview) to show as default next time the - // CCGX is restarted - onIsOverviewPageChanged: startWithMenu.setValue(isOverviewPage ? 0 : 1) - -- // Add the correct OverviewHub page -- onHubOverviewTypeChanged: { -- switch(hubOverviewType){ -- case "Hub": -- case "Hub-1": -- case "Hub-2": -- case "Hub-3": -- replaceOverview("OverviewGridParallel.qml", "OverviewHub.qml"); -- break; -- case "Hub-4": -- case "ESS": -- replaceOverview("OverviewHub.qml", "OverviewGridParallel.qml"); -- break; -- default: -- break; -+ // Add the correct OverviewGridParallelEnhanced page -+//////// modified for OverviewHubEnhanced page -+ onHubOverviewTypeChanged: selectHubOverview () -+ -+ VBusItem -+ { -+ id: guiModsFlowOverview -+ bind: "com.victronenergy.settings/Settings/GuiMods/FlowOverview" -+ onValueChanged: selectHubOverview () -+ } -+ -+////// GuiMods — DarkMode -+ property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } -+ property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 -+ -+////// GuiMods — DarkMode -+ Rectangle { -+ anchors -+ { -+ fill: parent - } -- // Workaround the QTBUG-17012 (only the first sentence in each case of Switch Statement can be executed) -- // by adding a return statement -- return -+ color: !darkMode ? "transparent" : "#202020" -+ z: -1 - } - -+ // base a new hub selection on the hub type and the enhanced flow overview flag -+ function selectHubOverview () -+ { -+ var newHubOverview = currentHubOverview -+ // Victron stock overviews with automatic selection -+ if (guiModsFlowOverview.value == 0) -+ { -+ switch(hubOverviewType){ -+ case "Hub": -+ case "Hub-1": -+ case "Hub-2": -+ case "Hub-3": -+ case "unknown": -+ newHubOverview = "OverviewHub.qml" -+ break; -+ case "Hub-4": -+ case "ESS": -+ newHubOverview = "OverviewGridParallel.qml" -+ break; -+ default: -+ break; -+ } -+ } -+ // Gui Mods simple flow -+ else if (guiModsFlowOverview.value === 1) -+ { -+ newHubOverview = "OverviewHubEnhanced.qml" -+ } -+ // Gui Mods complex flow (AC coupled or DC coupled) -+ else -+ { -+ newHubOverview = "OverviewFlowComplex.qml" -+ } -+ -+ if (newHubOverview != currentHubOverview) -+ { -+ replaceOverview(currentHubOverview, newHubOverview); -+ currentHubOverview = newHubOverview -+ } -+ -+ // Workaround the QTBUG-17012 (only the first sentence in each case of Switch Statement can be executed) -+ // by adding a return statement -+ return -+ } -+ - VBusItem { - id: generatorOverview - bind: "com.victronenergy.settings/Settings/Relay/Function" -- onValueChanged: extraOverview("OverviewGeneratorRelay.qml", value === 1) -+ onValueChanged: selectGeneratorOverview () - } - -+ VBusItem -+ { -+ id: generatorOverviewEnhanced -+ bind: "com.victronenergy.settings/Settings/GuiMods/UseEnhancedGeneratorOverview" -+ onValueChanged: selectGeneratorOverview () -+ } -+ - VBusItem { - id: fischerPandaGenOverview - bind: "com.victronenergy.generator.startstop1/AutoStartEnabled" -@@ -69,22 +132,103 @@ - } - } - } -- -- VBusItem { -- id: mobileOverview -- bind: "com.victronenergy.settings/Settings/Gui/MobileOverview" -- onValueChanged:{ -- extraOverview("OverviewMobile.qml", value === 1) -- } -+ function selectGeneratorOverview () -+ { -+ var newGeneratorOverview -+ if (generatorOverview.value === 1) -+ { -+ if (generatorOverviewEnhanced.value === 1) -+ newGeneratorOverview = "OverviewGeneratorRelayEnhanced.qml" -+ else -+ newGeneratorOverview = "OverviewGeneratorRelay.qml" -+ if (currentGeneratorOverview === "") -+ extraOverview (newGeneratorOverview, true) -+ else -+ replaceOverview (currentGeneratorOverview, newGeneratorOverview) -+ currentGeneratorOverview = newGeneratorOverview -+ } -+ else -+ { -+ // hide existing generator overview if any -+ if (currentGeneratorOverview != "") -+ { -+ extraOverview (currentGeneratorOverview, false) -+ currentGeneratorOverview = "" -+ } -+ } - } -- VBusItem { -- id: tanksOverview -- bind: "com.victronenergy.settings/Settings/Gui/TanksOverview" -- onValueChanged:{ -- extraOverview("OverviewTanks.qml", value === 1) -- } -- } - -+//////// handle OverviewMobileEnhanced page -+ VBusItem -+ { -+ id: mobileOverview -+ bind: "com.victronenergy.settings/Settings/Gui/MobileOverview" -+ onValueChanged: selectMobileOverview () -+ } -+ VBusItem -+ { -+ id: mobileOverviewEnhanced -+ bind: "com.victronenergy.settings/Settings/GuiMods/UseEnhancedMobileOverview" -+ onValueChanged: selectMobileOverview () -+ } -+ -+ // base a new mobile overview selection on the the mobile overview and enhanced mobile overview flags -+ function selectMobileOverview () -+ { -+ var newMobileOverview -+ if (mobileOverview.value === 1) -+ { -+ if (mobileOverviewEnhanced.value === 1) -+ newMobileOverview = "OverviewMobileEnhanced.qml" -+ else -+ newMobileOverview = "OverviewMobile.qml" -+ if (currentMobileOverview === "") -+ extraOverview (newMobileOverview, true) -+ else -+ replaceOverview (currentMobileOverview, newMobileOverview) -+ currentMobileOverview = newMobileOverview -+ } -+ else -+ { -+ // hide existing mobile overview if any -+ if (currentMobileOverview != "") -+ { -+ extraOverview (currentMobileOverview, false) -+ currentMobileOverview = "" -+ } -+ } -+ } -+ -+//////// show/hide the OverviewTiles page -+ VBusItem -+ { -+ id: showOverviewTiles -+ bind: "com.victronenergy.settings/Settings/GuiMods/ShowTileOverview" -+ onValueChanged: extraOverview ("OverviewTiles.qml", value === 1) -+ } -+ -+//////// show/hide the OverviewRelays page -+ VBusItem { -+ id: showOverviewRelays -+ bind: "com.victronenergy.settings/Settings/GuiMods/ShowRelayOverview" -+ onValueChanged: extraOverview ("OverviewRelays.qml", value === 1) -+ } -+ -+//////// show/hide the Overview Tanks/Temps/Digital Inputs page -+ VBusItem { -+ id: showOverviewTanksTemps -+ bind: "com.victronenergy.settings/Settings/GuiMods/ShowTanksTempsDigIn" -+ onValueChanged: extraOverview ("OverviewTanksTempsDigInputs.qml", value === 1) -+ } -+ -+ VBusItem { -+ id: tanksOverview -+ bind: "com.victronenergy.settings/Settings/Gui/TanksOverview" -+ onValueChanged:{ -+ extraOverview("OverviewTanks.qml", value === 1) -+ } -+ } -+ - VBusItem { - id: startWithMenu - bind: "com.victronenergy.settings/Settings/Gui/StartWithMenuView" -@@ -150,76 +294,111 @@ - id: mbTools - height: parent.height - -- Item { -- anchors.verticalCenter: parent.verticalCenter -- anchors.left: mbTools.left -- height: mbTools.height -- width: 200 -+//// GuiMods - DarkMode -+ Row -+ { -+ spacing: 0 -+ anchors.fill: parent -+ Item { -+ id: pagesItem -+ anchors.verticalCenter: parent.verticalCenter -+ height: mbTools.height -+ width: 170 - -- MouseArea { -- anchors.fill: parent -- onClicked: { -- if (pageStack.currentPage) -- pageStack.currentPage.toolbarHandler.leftAction(true) -+ MouseArea { -+ anchors.fill: parent -+ onClicked: { -+ if (pageStack.currentPage) -+ pageStack.currentPage.toolbarHandler.leftAction(true) -+ } - } -+ -+ Row { -+ anchors.verticalCenter: parent.verticalCenter -+ anchors.horizontalCenter: parent.horizontalCenter -+ -+ MbIcon { -+ anchors.verticalCenter: parent.verticalCenter -+ iconId: pageStack.currentPage ? pageStack.currentPage.leftIcon : "" -+ } -+ -+ Text { -+ anchors.verticalCenter: parent.verticalCenter -+ text: pageStack.currentPage ? pageStack.currentPage.leftText : "" -+ color: "white" -+ font.bold: true -+ font.pixelSize: 16 -+ } -+ } - } - -- Row { -- anchors.centerIn: parent -+ Item { -+ anchors.verticalCenter: parent.verticalCenter -+ height: mbTools.height -+ width: mbTools.width - pagesItem.width - menusItem.width - centerScrollIndicator.width - -- MbIcon { -- anchors.verticalCenter: parent.verticalCenter -- iconId: pageStack.currentPage ? pageStack.currentPage.leftIcon : "" -+ MouseArea -+ { -+ anchors.fill: parent -+ onClicked: -+ { -+ if (darkModeItem.valid) -+ darkModeItem.setValue (! darkMode) -+ } - } - -- Text { -- anchors.verticalCenter: parent.verticalCenter -- text: pageStack.currentPage ? pageStack.currentPage.leftText : "" -+ Text -+ { -+ anchors.fill: parent -+ horizontalAlignment: Text.AlignHCenter -+ text: qsTr ("change to") + "\n" + (darkMode ? qsTr ("Light mode") : qsTr ("Dark mode")) - color: "white" - font.bold: true -- font.pixelSize: 16 -+ font.pixelSize: 12 -+ visible: darkModeItem.valid - } - } -- } -- -- MbIcon { -- id: centerScrollIndicator -- -- anchors { -- horizontalCenter: parent.horizontalCenter -- verticalCenter: mbTools.verticalCenter -+ Item -+ { -+ id: centerScrollIndicator -+ anchors.verticalCenter: parent.verticalCenter -+ height: mbTools.height -+ width: 20 -+ MbIcon { -+ anchors.verticalCenter: parent.verticalCenter -+ iconId: pageStack.currentPage ? pageStack.currentPage.scrollIndicator : "" -+ } - } -- iconId: pageStack.currentPage ? pageStack.currentPage.scrollIndicator : "" -- } - -- Item { -- anchors.verticalCenter: parent.verticalCenter -- height: mbTools.height -- anchors.right: mbTools.right -- width: 200 -+ Item { -+ id: menusItem -+ anchors.verticalCenter: parent.verticalCenter -+ height: mbTools.height -+ width: pagesItem.width - -- MouseArea { -- anchors.fill: parent -- onClicked: { -- if (pageStack.currentPage) -- pageStack.currentPage.toolbarHandler.rightAction(true) -+ MouseArea { -+ anchors.fill: parent -+ onClicked: { -+ if (pageStack.currentPage) -+ pageStack.currentPage.toolbarHandler.rightAction(true) -+ } - } -- } - -- Row { -- anchors.centerIn: parent -+ Row { -+ anchors.centerIn: parent - -- MbIcon { -- iconId: pageStack.currentPage ? pageStack.currentPage.rightIcon : "" -- anchors.verticalCenter: parent.verticalCenter -- } -+ MbIcon { -+ iconId: pageStack.currentPage ? pageStack.currentPage.rightIcon : "" -+ anchors.verticalCenter: parent.verticalCenter -+ } - -- Text { -- text: pageStack.currentPage ? pageStack.currentPage.rightText : "" -- anchors.verticalCenter: parent.verticalCenter -- color: "white" -- font.bold: true -- font.pixelSize: 16 -+ Text { -+ text: pageStack.currentPage ? pageStack.currentPage.rightText : "" -+ anchors.verticalCenter: parent.verticalCenter -+ color: "white" -+ font.bold: true -+ font.pixelSize: 16 -+ } - } - } - } -@@ -234,9 +413,10 @@ - ListElement { - pageSource: "OverviewHub.qml" - } -- ListElement { -- pageSource: "OverviewTiles.qml" -- } -+//////// (commented out) -- added dynamically above -+// ListElement { -+// pageSource: "OverviewTiles.qml" -+// } - } - - Component { -@@ -255,7 +435,12 @@ - Timer { - interval: 2000 - running: completed && overviewsLoaded && startWithMenu.valid -- onTriggered: if (startWithMenu.value === 0) showOverview() -+ onTriggered: -+ { -+//////// modified for OverviewGridParallelEnhanced page -+ selectHubOverview () -+ if (startWithMenu.value === 0) showOverview() -+ } - } - - function getDefaultOverviewIndex() -@@ -309,11 +494,19 @@ - } - } - -+//////// Modified to append page if oldPage not found - function replaceOverview(oldPage, newPage) - { - for (var i = 0; i < overviewModel.count; i++) -+ { - if (overviewModel.get(i).pageSource === oldPage) -+ { - overviewModel.get(i).pageSource = newPage -+ return -+ } -+ } -+ // here if oldPage wasn't found -- append the new page -+ overviewModel.append({"pageSource": newPage}) - } - - // Central mover for the ball animation on the overviews diff --git a/FileSets/PatchSource/main.qml-v3.40~13 b/FileSets/PatchSource/main.qml-v3.34 similarity index 100% rename from FileSets/PatchSource/main.qml-v3.40~13 rename to FileSets/PatchSource/main.qml-v3.34 diff --git a/FileSets/PatchSource/main.qml-v3.40~13.orig b/FileSets/PatchSource/main.qml-v3.34.orig similarity index 100% rename from FileSets/PatchSource/main.qml-v3.40~13.orig rename to FileSets/PatchSource/main.qml-v3.34.orig diff --git a/FileSets/PatchSource/main.qml-v3.40~13.patch b/FileSets/PatchSource/main.qml-v3.34.patch similarity index 99% rename from FileSets/PatchSource/main.qml-v3.40~13.patch rename to FileSets/PatchSource/main.qml-v3.34.patch index 1f865d9c..b49adf80 100644 --- a/FileSets/PatchSource/main.qml-v3.40~13.patch +++ b/FileSets/PatchSource/main.qml-v3.34.patch @@ -1,5 +1,5 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/main.qml-v3.40~13.orig 2024-07-08 09:16:57 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/main.qml-v3.40~13 2024-05-14 07:00:12 +--- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/main.qml-v3.34.orig 2024-07-08 09:16:57 ++++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/main.qml-v3.34 2024-05-14 07:00:12 @@ -1,3 +1,6 @@ +//////// Modified to hide the OverviewTiles page +//////// Modified to substitute flow overview pages diff --git a/FileSets/PatchSource/main.qml-v3.40~35 b/FileSets/PatchSource/main.qml-v3.40 similarity index 100% rename from FileSets/PatchSource/main.qml-v3.40~35 rename to FileSets/PatchSource/main.qml-v3.40 diff --git a/FileSets/PatchSource/main.qml-v3.40~35.orig b/FileSets/PatchSource/main.qml-v3.40.orig similarity index 100% rename from FileSets/PatchSource/main.qml-v3.40~35.orig rename to FileSets/PatchSource/main.qml-v3.40.orig diff --git a/FileSets/PatchSource/main.qml-v3.40~35.patch b/FileSets/PatchSource/main.qml-v3.40.patch similarity index 99% rename from FileSets/PatchSource/main.qml-v3.40~35.patch rename to FileSets/PatchSource/main.qml-v3.40.patch index f3466692..ce4e1617 100644 --- a/FileSets/PatchSource/main.qml-v3.40~35.patch +++ b/FileSets/PatchSource/main.qml-v3.40.patch @@ -1,5 +1,5 @@ ---- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/main.qml-v3.40~35.orig 2024-07-08 09:16:57 -+++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/main.qml-v3.40~35 2024-05-17 07:34:02 +--- /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/main.qml-v3.40.orig 2024-07-08 09:16:57 ++++ /Users/Kevin/GitHub/GuiMods.copy/FileSets/PatchSource/main.qml-v3.40 2024-05-17 07:34:02 @@ -1,3 +1,6 @@ +//////// Modified to hide the OverviewTiles page +//////// Modified to substitute flow overview pages diff --git a/FileSets/PatchSource/MbItemDigitalInput.qml-v2.94 b/FileSets/PatchSource/obsoletePatches/MbItemDigitalInput.qml-v2.94 similarity index 100% rename from FileSets/PatchSource/MbItemDigitalInput.qml-v2.94 rename to FileSets/PatchSource/obsoletePatches/MbItemDigitalInput.qml-v2.94 diff --git a/FileSets/PatchSource/MbItemDigitalInput.qml-v2.94.orig b/FileSets/PatchSource/obsoletePatches/MbItemDigitalInput.qml-v2.94.orig similarity index 100% rename from FileSets/PatchSource/MbItemDigitalInput.qml-v2.94.orig rename to FileSets/PatchSource/obsoletePatches/MbItemDigitalInput.qml-v2.94.orig diff --git a/FileSets/PatchSource/MbSpinBox.qml-v2.73 b/FileSets/PatchSource/obsoletePatches/MbSpinBox.qml-v2.73 similarity index 100% rename from FileSets/PatchSource/MbSpinBox.qml-v2.73 rename to FileSets/PatchSource/obsoletePatches/MbSpinBox.qml-v2.73 diff --git a/FileSets/PatchSource/MbSpinBox.qml-v2.73.orig b/FileSets/PatchSource/obsoletePatches/MbSpinBox.qml-v2.73.orig similarity index 100% rename from FileSets/PatchSource/MbSpinBox.qml-v2.73.orig rename to FileSets/PatchSource/obsoletePatches/MbSpinBox.qml-v2.73.orig diff --git a/FileSets/PatchSource/MbSpinBox.qml-v2.89 b/FileSets/PatchSource/obsoletePatches/MbSpinBox.qml-v2.89 similarity index 100% rename from FileSets/PatchSource/MbSpinBox.qml-v2.89 rename to FileSets/PatchSource/obsoletePatches/MbSpinBox.qml-v2.89 diff --git a/FileSets/PatchSource/MbSpinBox.qml-v2.89.orig b/FileSets/PatchSource/obsoletePatches/MbSpinBox.qml-v2.89.orig similarity index 100% rename from FileSets/PatchSource/MbSpinBox.qml-v2.89.orig rename to FileSets/PatchSource/obsoletePatches/MbSpinBox.qml-v2.89.orig diff --git a/FileSets/PatchSource/MbStyle.qml-v2.94 b/FileSets/PatchSource/obsoletePatches/MbStyle.qml-v2.94 similarity index 100% rename from FileSets/PatchSource/MbStyle.qml-v2.94 rename to FileSets/PatchSource/obsoletePatches/MbStyle.qml-v2.94 diff --git a/FileSets/PatchSource/MbStyle.qml-v2.94.orig b/FileSets/PatchSource/obsoletePatches/MbStyle.qml-v2.94.orig similarity index 100% rename from FileSets/PatchSource/MbStyle.qml-v2.94.orig rename to FileSets/PatchSource/obsoletePatches/MbStyle.qml-v2.94.orig diff --git a/FileSets/PatchSource/PageMain.qml-v2.94 b/FileSets/PatchSource/obsoletePatches/PageMain.qml-v2.94 similarity index 100% rename from FileSets/PatchSource/PageMain.qml-v2.94 rename to FileSets/PatchSource/obsoletePatches/PageMain.qml-v2.94 diff --git a/FileSets/PatchSource/PageMain.qml-v2.94.orig b/FileSets/PatchSource/obsoletePatches/PageMain.qml-v2.94.orig similarity index 100% rename from FileSets/PatchSource/PageMain.qml-v2.94.orig rename to FileSets/PatchSource/obsoletePatches/PageMain.qml-v2.94.orig diff --git a/FileSets/PatchSource/PageSettingsDisplay.qml-v2.89 b/FileSets/PatchSource/obsoletePatches/PageSettingsDisplay.qml-v2.89 similarity index 100% rename from FileSets/PatchSource/PageSettingsDisplay.qml-v2.89 rename to FileSets/PatchSource/obsoletePatches/PageSettingsDisplay.qml-v2.89 diff --git a/FileSets/PatchSource/PageSettingsDisplay.qml-v2.89.orig b/FileSets/PatchSource/obsoletePatches/PageSettingsDisplay.qml-v2.89.orig similarity index 100% rename from FileSets/PatchSource/PageSettingsDisplay.qml-v2.89.orig rename to FileSets/PatchSource/obsoletePatches/PageSettingsDisplay.qml-v2.89.orig diff --git a/FileSets/PatchSource/PageSettingsDisplay.qml-v2.94 b/FileSets/PatchSource/obsoletePatches/PageSettingsDisplay.qml-v2.94 similarity index 100% rename from FileSets/PatchSource/PageSettingsDisplay.qml-v2.94 rename to FileSets/PatchSource/obsoletePatches/PageSettingsDisplay.qml-v2.94 diff --git a/FileSets/PatchSource/PageSettingsDisplay.qml-v2.94.orig b/FileSets/PatchSource/obsoletePatches/PageSettingsDisplay.qml-v2.94.orig similarity index 100% rename from FileSets/PatchSource/PageSettingsDisplay.qml-v2.94.orig rename to FileSets/PatchSource/obsoletePatches/PageSettingsDisplay.qml-v2.94.orig diff --git a/FileSets/PatchSource/PageSettingsDisplay.qml-v3.01 b/FileSets/PatchSource/obsoletePatches/PageSettingsDisplay.qml-v3.01 similarity index 100% rename from FileSets/PatchSource/PageSettingsDisplay.qml-v3.01 rename to FileSets/PatchSource/obsoletePatches/PageSettingsDisplay.qml-v3.01 diff --git a/FileSets/PatchSource/PageSettingsDisplay.qml-v3.01.orig b/FileSets/PatchSource/obsoletePatches/PageSettingsDisplay.qml-v3.01.orig similarity index 100% rename from FileSets/PatchSource/PageSettingsDisplay.qml-v3.01.orig rename to FileSets/PatchSource/obsoletePatches/PageSettingsDisplay.qml-v3.01.orig diff --git a/FileSets/PatchSource/PageSettingsDisplay.qml-v3.40~8 b/FileSets/PatchSource/obsoletePatches/PageSettingsDisplay.qml-v3.40~8 similarity index 100% rename from FileSets/PatchSource/PageSettingsDisplay.qml-v3.40~8 rename to FileSets/PatchSource/obsoletePatches/PageSettingsDisplay.qml-v3.40~8 diff --git a/FileSets/PatchSource/PageSettingsDisplay.qml-v3.40~8.orig b/FileSets/PatchSource/obsoletePatches/PageSettingsDisplay.qml-v3.40~8.orig similarity index 100% rename from FileSets/PatchSource/PageSettingsDisplay.qml-v3.40~8.orig rename to FileSets/PatchSource/obsoletePatches/PageSettingsDisplay.qml-v3.40~8.orig diff --git a/FileSets/PatchSource/attributes.csv-v2.94 b/FileSets/PatchSource/obsoletePatches/attributes.csv-v2.94 similarity index 100% rename from FileSets/PatchSource/attributes.csv-v2.94 rename to FileSets/PatchSource/obsoletePatches/attributes.csv-v2.94 diff --git a/FileSets/PatchSource/attributes.csv-v2.94.orig b/FileSets/PatchSource/obsoletePatches/attributes.csv-v2.94.orig similarity index 100% rename from FileSets/PatchSource/attributes.csv-v2.94.orig rename to FileSets/PatchSource/obsoletePatches/attributes.csv-v2.94.orig diff --git a/FileSets/PatchSource/dbus_systemcalc.py-v2.73 b/FileSets/PatchSource/obsoletePatches/dbus_systemcalc.py-v2.73 similarity index 100% rename from FileSets/PatchSource/dbus_systemcalc.py-v2.73 rename to FileSets/PatchSource/obsoletePatches/dbus_systemcalc.py-v2.73 diff --git a/FileSets/PatchSource/dbus_systemcalc.py-v2.73.orig b/FileSets/PatchSource/obsoletePatches/dbus_systemcalc.py-v2.73.orig similarity index 100% rename from FileSets/PatchSource/dbus_systemcalc.py-v2.73.orig rename to FileSets/PatchSource/obsoletePatches/dbus_systemcalc.py-v2.73.orig diff --git a/FileSets/PatchSource/dbus_systemcalc.py-v2.84 b/FileSets/PatchSource/obsoletePatches/dbus_systemcalc.py-v2.84 similarity index 100% rename from FileSets/PatchSource/dbus_systemcalc.py-v2.84 rename to FileSets/PatchSource/obsoletePatches/dbus_systemcalc.py-v2.84 diff --git a/FileSets/PatchSource/dbus_systemcalc.py-v2.84.orig b/FileSets/PatchSource/obsoletePatches/dbus_systemcalc.py-v2.84.orig similarity index 100% rename from FileSets/PatchSource/dbus_systemcalc.py-v2.84.orig rename to FileSets/PatchSource/obsoletePatches/dbus_systemcalc.py-v2.84.orig diff --git a/FileSets/PatchSource/dbus_systemcalc.py-v2.89 b/FileSets/PatchSource/obsoletePatches/dbus_systemcalc.py-v2.89 similarity index 100% rename from FileSets/PatchSource/dbus_systemcalc.py-v2.89 rename to FileSets/PatchSource/obsoletePatches/dbus_systemcalc.py-v2.89 diff --git a/FileSets/PatchSource/dbus_systemcalc.py-v2.89.orig b/FileSets/PatchSource/obsoletePatches/dbus_systemcalc.py-v2.89.orig similarity index 100% rename from FileSets/PatchSource/dbus_systemcalc.py-v2.89.orig rename to FileSets/PatchSource/obsoletePatches/dbus_systemcalc.py-v2.89.orig diff --git a/FileSets/PatchSource/dbus_systemcalc.py-v2.94 b/FileSets/PatchSource/obsoletePatches/dbus_systemcalc.py-v2.94 similarity index 100% rename from FileSets/PatchSource/dbus_systemcalc.py-v2.94 rename to FileSets/PatchSource/obsoletePatches/dbus_systemcalc.py-v2.94 diff --git a/FileSets/PatchSource/dbus_systemcalc.py-v2.94.orig b/FileSets/PatchSource/obsoletePatches/dbus_systemcalc.py-v2.94.orig similarity index 100% rename from FileSets/PatchSource/dbus_systemcalc.py-v2.94.orig rename to FileSets/PatchSource/obsoletePatches/dbus_systemcalc.py-v2.94.orig diff --git a/FileSets/PatchSource/dbus_systemcalc.py-v3.40~10.orig b/FileSets/PatchSource/obsoletePatches/dbus_systemcalc.py-v3.40~10.orig similarity index 100% rename from FileSets/PatchSource/dbus_systemcalc.py-v3.40~10.orig rename to FileSets/PatchSource/obsoletePatches/dbus_systemcalc.py-v3.40~10.orig diff --git a/FileSets/PatchSource/dbus_systemcalc.py-v3.40~15 b/FileSets/PatchSource/obsoletePatches/dbus_systemcalc.py-v3.40~15 similarity index 100% rename from FileSets/PatchSource/dbus_systemcalc.py-v3.40~15 rename to FileSets/PatchSource/obsoletePatches/dbus_systemcalc.py-v3.40~15 diff --git a/FileSets/PatchSource/dbus_systemcalc.py-v3.40~15.orig b/FileSets/PatchSource/obsoletePatches/dbus_systemcalc.py-v3.40~15.orig similarity index 100% rename from FileSets/PatchSource/dbus_systemcalc.py-v3.40~15.orig rename to FileSets/PatchSource/obsoletePatches/dbus_systemcalc.py-v3.40~15.orig diff --git a/FileSets/PatchSource/main.qml-v2.94 b/FileSets/PatchSource/obsoletePatches/main.qml-v2.94 similarity index 100% rename from FileSets/PatchSource/main.qml-v2.94 rename to FileSets/PatchSource/obsoletePatches/main.qml-v2.94 diff --git a/FileSets/PatchSource/main.qml-v2.94.orig b/FileSets/PatchSource/obsoletePatches/main.qml-v2.94.orig similarity index 100% rename from FileSets/PatchSource/main.qml-v2.94.orig rename to FileSets/PatchSource/obsoletePatches/main.qml-v2.94.orig diff --git a/FileSets/v2.71/Battery.qml b/FileSets/v2.71/Battery.qml deleted file mode 120000 index ef252511..00000000 --- a/FileSets/v2.71/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/Battery.qml \ No newline at end of file diff --git a/FileSets/v2.71/DetailAcInput.qml b/FileSets/v2.71/DetailAcInput.qml deleted file mode 120000 index f498c052..00000000 --- a/FileSets/v2.71/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v2.71/DetailInverter.qml b/FileSets/v2.71/DetailInverter.qml deleted file mode 120000 index e1656472..00000000 --- a/FileSets/v2.71/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v2.71/DetailLoadsCombined.qml b/FileSets/v2.71/DetailLoadsCombined.qml deleted file mode 120000 index 5a6cbd28..00000000 --- a/FileSets/v2.71/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v2.71/DetailLoadsOnInput.qml b/FileSets/v2.71/DetailLoadsOnInput.qml deleted file mode 120000 index bafd47ec..00000000 --- a/FileSets/v2.71/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v2.71/DetailLoadsOnOutput.qml b/FileSets/v2.71/DetailLoadsOnOutput.qml deleted file mode 120000 index e68fec20..00000000 --- a/FileSets/v2.71/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v2.71/HubData.qml b/FileSets/v2.71/HubData.qml deleted file mode 120000 index a6aa4a1a..00000000 --- a/FileSets/v2.71/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/HubData.qml \ No newline at end of file diff --git a/FileSets/v2.71/LINKS_ONLY b/FileSets/v2.71/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.71/MbEditBox.qml b/FileSets/v2.71/MbEditBox.qml deleted file mode 120000 index 8381b7d5..00000000 --- a/FileSets/v2.71/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v2.71/MbEditBoxDateTime.qml b/FileSets/v2.71/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v2.71/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.71/MbItem.qml b/FileSets/v2.71/MbItem.qml deleted file mode 120000 index 1280e190..00000000 --- a/FileSets/v2.71/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItem.qml \ No newline at end of file diff --git a/FileSets/v2.71/MbItemDigitalInput.qml b/FileSets/v2.71/MbItemDigitalInput.qml deleted file mode 120000 index 63943a08..00000000 --- a/FileSets/v2.71/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.71/MbSpinBox.qml b/FileSets/v2.71/MbSpinBox.qml deleted file mode 120000 index 16fd5f89..00000000 --- a/FileSets/v2.71/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v2.71/MbStyle.qml b/FileSets/v2.71/MbStyle.qml deleted file mode 120000 index db6f181f..00000000 --- a/FileSets/v2.71/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v2.71/MbSubMenu.qml b/FileSets/v2.71/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v2.71/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.71/Multi.qml b/FileSets/v2.71/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v2.71/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.71/ObjectAcConnection.qml b/FileSets/v2.71/ObjectAcConnection.qml deleted file mode 120000 index add04331..00000000 --- a/FileSets/v2.71/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v2.71/OverviewAcValuesEnhanced.qml b/FileSets/v2.71/OverviewAcValuesEnhanced.qml deleted file mode 120000 index f4b169a7..00000000 --- a/FileSets/v2.71/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.71/OverviewBox.qml b/FileSets/v2.71/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v2.71/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.71/OverviewConnection.qml b/FileSets/v2.71/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v2.71/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.71/OverviewConnectionEnd.qml b/FileSets/v2.71/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v2.71/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.71/OverviewFlowComplex.qml b/FileSets/v2.71/OverviewFlowComplex.qml deleted file mode 120000 index 6b747507..00000000 --- a/FileSets/v2.71/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v2.71/OverviewGeneratorEnhanced.qml b/FileSets/v2.71/OverviewGeneratorEnhanced.qml deleted file mode 120000 index b0670070..00000000 --- a/FileSets/v2.71/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.71/OverviewGeneratorRelayEnhanced.qml b/FileSets/v2.71/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index c6fa07f9..00000000 --- a/FileSets/v2.71/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.71/OverviewGridParallel.qml b/FileSets/v2.71/OverviewGridParallel.qml deleted file mode 120000 index cbf456ca..00000000 --- a/FileSets/v2.71/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v2.71/OverviewHub.qml b/FileSets/v2.71/OverviewHub.qml deleted file mode 120000 index 99e50064..00000000 --- a/FileSets/v2.71/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v2.71/OverviewHubEnhanced.qml b/FileSets/v2.71/OverviewHubEnhanced.qml deleted file mode 120000 index 5b4d2d98..00000000 --- a/FileSets/v2.71/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.71/OverviewMobileEnhanced.qml b/FileSets/v2.71/OverviewMobileEnhanced.qml deleted file mode 120000 index 55c5da34..00000000 --- a/FileSets/v2.71/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.71/OverviewSolarCharger.qml b/FileSets/v2.71/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v2.71/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.71/OverviewSolarInverter.qml b/FileSets/v2.71/OverviewSolarInverter.qml deleted file mode 120000 index 7cea58a2..00000000 --- a/FileSets/v2.71/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v2.71/OverviewTankDelegate.qml b/FileSets/v2.71/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v2.71/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.71/OverviewTanks.qml b/FileSets/v2.71/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v2.71/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.71/OverviewTanksTempsDigInputs.qml b/FileSets/v2.71/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 0bbf4066..00000000 --- a/FileSets/v2.71/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v2.71/PageDigitalInput.qml b/FileSets/v2.71/PageDigitalInput.qml deleted file mode 120000 index 839f7874..00000000 --- a/FileSets/v2.71/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.71/PageGenerator.qml b/FileSets/v2.71/PageGenerator.qml deleted file mode 120000 index cae51ecb..00000000 --- a/FileSets/v2.71/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.71/PageMain.qml b/FileSets/v2.71/PageMain.qml deleted file mode 120000 index 956b0cb8..00000000 --- a/FileSets/v2.71/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/PageMain.qml \ No newline at end of file diff --git a/FileSets/v2.71/PageSettingsDisplay.qml b/FileSets/v2.71/PageSettingsDisplay.qml deleted file mode 120000 index b3885a68..00000000 --- a/FileSets/v2.71/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v2.71/PageSettingsGenerator.qml b/FileSets/v2.71/PageSettingsGenerator.qml deleted file mode 120000 index 861e41bb..00000000 --- a/FileSets/v2.71/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.71/PageSettingsGuiMods.qml b/FileSets/v2.71/PageSettingsGuiMods.qml deleted file mode 120000 index bcd0c7b3..00000000 --- a/FileSets/v2.71/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v2.71/PageSettingsRelay.qml b/FileSets/v2.71/PageSettingsRelay.qml deleted file mode 120000 index dba342ad..00000000 --- a/FileSets/v2.71/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v2.71/PowerGauge.qml b/FileSets/v2.71/PowerGauge.qml deleted file mode 120000 index d8c1092a..00000000 --- a/FileSets/v2.71/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v2.71/Tile.qml b/FileSets/v2.71/Tile.qml deleted file mode 120000 index aa80e332..00000000 --- a/FileSets/v2.71/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/Tile.qml \ No newline at end of file diff --git a/FileSets/v2.71/TileDigIn.qml b/FileSets/v2.71/TileDigIn.qml deleted file mode 120000 index 4d2cf228..00000000 --- a/FileSets/v2.71/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v2.71/TileRelay.qml b/FileSets/v2.71/TileRelay.qml deleted file mode 120000 index 4313882d..00000000 --- a/FileSets/v2.71/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v2.71/TileText.qml b/FileSets/v2.71/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v2.71/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.71/attributes.csv b/FileSets/v2.71/attributes.csv deleted file mode 120000 index b7a7945f..00000000 --- a/FileSets/v2.71/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v2.73/attributes.csv \ No newline at end of file diff --git a/FileSets/v2.71/dbus_digitalinputs.py b/FileSets/v2.71/dbus_digitalinputs.py deleted file mode 120000 index fb25a639..00000000 --- a/FileSets/v2.71/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v2.73/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v2.71/dbus_generator.py b/FileSets/v2.71/dbus_generator.py deleted file mode 120000 index eab67cf6..00000000 --- a/FileSets/v2.71/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v2.73/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v2.71/dbus_systemcalc.py b/FileSets/v2.71/dbus_systemcalc.py deleted file mode 120000 index 272e5b0b..00000000 --- a/FileSets/v2.71/dbus_systemcalc.py +++ /dev/null @@ -1 +0,0 @@ -../v2.73/dbus_systemcalc.py \ No newline at end of file diff --git a/FileSets/v2.71/main.qml b/FileSets/v2.71/main.qml deleted file mode 120000 index 54acc57c..00000000 --- a/FileSets/v2.71/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/main.qml \ No newline at end of file diff --git a/FileSets/v2.71/startstop.py b/FileSets/v2.71/startstop.py deleted file mode 120000 index 213287fe..00000000 --- a/FileSets/v2.71/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v2.73/startstop.py \ No newline at end of file diff --git a/FileSets/v2.71/styles.css b/FileSets/v2.71/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v2.71/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v2.72/Battery.qml b/FileSets/v2.72/Battery.qml deleted file mode 120000 index ef252511..00000000 --- a/FileSets/v2.72/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/Battery.qml \ No newline at end of file diff --git a/FileSets/v2.72/COMPLETE b/FileSets/v2.72/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.72/DetailAcInput.qml b/FileSets/v2.72/DetailAcInput.qml deleted file mode 120000 index f498c052..00000000 --- a/FileSets/v2.72/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v2.72/DetailInverter.qml b/FileSets/v2.72/DetailInverter.qml deleted file mode 120000 index e1656472..00000000 --- a/FileSets/v2.72/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v2.72/DetailLoadsCombined.qml b/FileSets/v2.72/DetailLoadsCombined.qml deleted file mode 120000 index 5a6cbd28..00000000 --- a/FileSets/v2.72/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v2.72/DetailLoadsOnInput.qml b/FileSets/v2.72/DetailLoadsOnInput.qml deleted file mode 120000 index bafd47ec..00000000 --- a/FileSets/v2.72/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v2.72/DetailLoadsOnOutput.qml b/FileSets/v2.72/DetailLoadsOnOutput.qml deleted file mode 120000 index e68fec20..00000000 --- a/FileSets/v2.72/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v2.72/HubData.qml b/FileSets/v2.72/HubData.qml deleted file mode 120000 index a6aa4a1a..00000000 --- a/FileSets/v2.72/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/HubData.qml \ No newline at end of file diff --git a/FileSets/v2.72/LINKS_ONLY b/FileSets/v2.72/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.72/MbEditBox.qml b/FileSets/v2.72/MbEditBox.qml deleted file mode 120000 index 8381b7d5..00000000 --- a/FileSets/v2.72/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v2.72/MbEditBoxDateTime.qml b/FileSets/v2.72/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v2.72/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.72/MbItem.qml b/FileSets/v2.72/MbItem.qml deleted file mode 120000 index 1280e190..00000000 --- a/FileSets/v2.72/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItem.qml \ No newline at end of file diff --git a/FileSets/v2.72/MbItemDigitalInput.qml b/FileSets/v2.72/MbItemDigitalInput.qml deleted file mode 120000 index 63943a08..00000000 --- a/FileSets/v2.72/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.72/MbSpinBox.qml b/FileSets/v2.72/MbSpinBox.qml deleted file mode 120000 index 16fd5f89..00000000 --- a/FileSets/v2.72/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v2.72/MbStyle.qml b/FileSets/v2.72/MbStyle.qml deleted file mode 120000 index db6f181f..00000000 --- a/FileSets/v2.72/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v2.72/MbSubMenu.qml b/FileSets/v2.72/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v2.72/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.72/Multi.qml b/FileSets/v2.72/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v2.72/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.72/ObjectAcConnection.qml b/FileSets/v2.72/ObjectAcConnection.qml deleted file mode 120000 index add04331..00000000 --- a/FileSets/v2.72/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v2.72/OverviewAcValuesEnhanced.qml b/FileSets/v2.72/OverviewAcValuesEnhanced.qml deleted file mode 120000 index f4b169a7..00000000 --- a/FileSets/v2.72/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.72/OverviewBox.qml b/FileSets/v2.72/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v2.72/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.72/OverviewConnection.qml b/FileSets/v2.72/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v2.72/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.72/OverviewConnectionEnd.qml b/FileSets/v2.72/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v2.72/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.72/OverviewFlowComplex.qml b/FileSets/v2.72/OverviewFlowComplex.qml deleted file mode 120000 index 6b747507..00000000 --- a/FileSets/v2.72/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v2.72/OverviewGeneratorEnhanced.qml b/FileSets/v2.72/OverviewGeneratorEnhanced.qml deleted file mode 120000 index b0670070..00000000 --- a/FileSets/v2.72/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.72/OverviewGeneratorRelayEnhanced.qml b/FileSets/v2.72/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index c6fa07f9..00000000 --- a/FileSets/v2.72/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.72/OverviewGridParallel.qml b/FileSets/v2.72/OverviewGridParallel.qml deleted file mode 120000 index cbf456ca..00000000 --- a/FileSets/v2.72/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v2.72/OverviewHub.qml b/FileSets/v2.72/OverviewHub.qml deleted file mode 120000 index 99e50064..00000000 --- a/FileSets/v2.72/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v2.72/OverviewHubEnhanced.qml b/FileSets/v2.72/OverviewHubEnhanced.qml deleted file mode 120000 index 5b4d2d98..00000000 --- a/FileSets/v2.72/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.72/OverviewMobileEnhanced.qml b/FileSets/v2.72/OverviewMobileEnhanced.qml deleted file mode 120000 index 55c5da34..00000000 --- a/FileSets/v2.72/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.72/OverviewSolarCharger.qml b/FileSets/v2.72/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v2.72/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.72/OverviewSolarInverter.qml b/FileSets/v2.72/OverviewSolarInverter.qml deleted file mode 120000 index 7cea58a2..00000000 --- a/FileSets/v2.72/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v2.72/OverviewTankDelegate.qml b/FileSets/v2.72/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v2.72/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.72/OverviewTanks.qml b/FileSets/v2.72/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v2.72/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.72/OverviewTanksTempsDigInputs.qml b/FileSets/v2.72/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 0bbf4066..00000000 --- a/FileSets/v2.72/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v2.72/PageDigitalInput.qml b/FileSets/v2.72/PageDigitalInput.qml deleted file mode 120000 index 839f7874..00000000 --- a/FileSets/v2.72/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.72/PageGenerator.qml b/FileSets/v2.72/PageGenerator.qml deleted file mode 120000 index cae51ecb..00000000 --- a/FileSets/v2.72/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.72/PageMain.qml b/FileSets/v2.72/PageMain.qml deleted file mode 120000 index 956b0cb8..00000000 --- a/FileSets/v2.72/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/PageMain.qml \ No newline at end of file diff --git a/FileSets/v2.72/PageSettingsDisplay.qml b/FileSets/v2.72/PageSettingsDisplay.qml deleted file mode 120000 index b3885a68..00000000 --- a/FileSets/v2.72/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v2.72/PageSettingsGenerator.qml b/FileSets/v2.72/PageSettingsGenerator.qml deleted file mode 120000 index 861e41bb..00000000 --- a/FileSets/v2.72/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.72/PageSettingsGuiMods.qml b/FileSets/v2.72/PageSettingsGuiMods.qml deleted file mode 120000 index bcd0c7b3..00000000 --- a/FileSets/v2.72/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v2.72/PageSettingsRelay.qml b/FileSets/v2.72/PageSettingsRelay.qml deleted file mode 120000 index dba342ad..00000000 --- a/FileSets/v2.72/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v2.72/PowerGauge.qml b/FileSets/v2.72/PowerGauge.qml deleted file mode 120000 index d8c1092a..00000000 --- a/FileSets/v2.72/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v2.72/Tile.qml b/FileSets/v2.72/Tile.qml deleted file mode 120000 index aa80e332..00000000 --- a/FileSets/v2.72/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/Tile.qml \ No newline at end of file diff --git a/FileSets/v2.72/TileDigIn.qml b/FileSets/v2.72/TileDigIn.qml deleted file mode 120000 index 4d2cf228..00000000 --- a/FileSets/v2.72/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.73/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v2.72/TileRelay.qml b/FileSets/v2.72/TileRelay.qml deleted file mode 120000 index 4313882d..00000000 --- a/FileSets/v2.72/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v2.72/TileText.qml b/FileSets/v2.72/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v2.72/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.72/attributes.csv b/FileSets/v2.72/attributes.csv deleted file mode 120000 index b7a7945f..00000000 --- a/FileSets/v2.72/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v2.73/attributes.csv \ No newline at end of file diff --git a/FileSets/v2.72/dbus_digitalinputs.py b/FileSets/v2.72/dbus_digitalinputs.py deleted file mode 120000 index fb25a639..00000000 --- a/FileSets/v2.72/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v2.73/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v2.72/dbus_generator.py b/FileSets/v2.72/dbus_generator.py deleted file mode 120000 index eab67cf6..00000000 --- a/FileSets/v2.72/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v2.73/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v2.72/dbus_systemcalc.py b/FileSets/v2.72/dbus_systemcalc.py deleted file mode 120000 index 272e5b0b..00000000 --- a/FileSets/v2.72/dbus_systemcalc.py +++ /dev/null @@ -1 +0,0 @@ -../v2.73/dbus_systemcalc.py \ No newline at end of file diff --git a/FileSets/v2.72/main.qml b/FileSets/v2.72/main.qml deleted file mode 120000 index 54acc57c..00000000 --- a/FileSets/v2.72/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/main.qml \ No newline at end of file diff --git a/FileSets/v2.72/startstop.py b/FileSets/v2.72/startstop.py deleted file mode 120000 index 213287fe..00000000 --- a/FileSets/v2.72/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v2.73/startstop.py \ No newline at end of file diff --git a/FileSets/v2.72/styles.css b/FileSets/v2.72/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v2.72/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v2.73/Battery.qml b/FileSets/v2.73/Battery.qml deleted file mode 120000 index ef252511..00000000 --- a/FileSets/v2.73/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/Battery.qml \ No newline at end of file diff --git a/FileSets/v2.73/COMPLETE b/FileSets/v2.73/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.73/DetailAcInput.qml b/FileSets/v2.73/DetailAcInput.qml deleted file mode 100644 index 0d71ee29..00000000 --- a/FileSets/v2.73/DetailAcInput.qml +++ /dev/null @@ -1,607 +0,0 @@ -////// detail page for setting input current limit -////// and displaying AC input details -////// pushed from Flow overview - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 -import "enhancedFormat.js" as EnhFmt - -MbPage { - id: root - - title: "AC Input detail" - - property variant sys: theSystem - property string systemPrefix: "com.victronenergy.system" - property string settingsPrefix: "com.victronenergy.settings" - - property int fontPixelSize: 18 - property color buttonColor: "#979797" - property color pressedColor: "#d3d3d3" - property color backgroundColor: "#b3b3b3" - - property int buttonHeight: 40 - - property int dataColumns: 4 - property int rowTitleWidth: 100 - property int totalDataWidth: 340 - rowTitleWidth - property int tableColumnWidth: totalDataWidth / dataColumns - - property int legColumnWidth: phaseCount <= 1 ? tableColumnWidth * 3 : tableColumnWidth * 3 / phaseCount - - property int phaseCount: sys.acInput.phaseCount.valid ? sys.acInput.phaseCount.value : 0 - - VBusItem { id: vebusServiceItem; bind: Utils.path(systemPrefix, "/VebusService") } - property string inverterService: vebusServiceItem.valid ? vebusServiceItem.value : "" - VBusItem { id: splitPhaseL2Passthru; bind: Utils.path(inverterService, "/Ac/State/SplitPhaseL2Passthru") } - property bool splitPhasePassthruDisabled: splitPhaseL2Passthru.valid && splitPhaseL2Passthru.value === 0 - - property real actualCurrentLimit: 0 - property real newCurrentLimit: 0 - - VBusItem { id: acLimitPreset1Item; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/AcCurrentLimit/Preset1") } - VBusItem { id: acLimitPreset2Item; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/AcCurrentLimit/Preset2") } - VBusItem { id: acLimitPreset3Item; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/AcCurrentLimit/Preset3") } - VBusItem { id: acLimitPreset4Item; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/AcCurrentLimit/Preset4") } - property real acLimitPreset1: acLimitPreset1Item.valid ? acLimitPreset1Item.value : 0 - property real acLimitPreset2: acLimitPreset2Item.valid ? acLimitPreset2Item.value : 0 - property real acLimitPreset3: acLimitPreset3Item.valid ? acLimitPreset3Item.value : 0 - property real acLimitPreset4: acLimitPreset4Item.valid ? acLimitPreset4Item.value : 0 - - property bool currentLimitIsAdjustable: currentLimitIsAdjustableItem.valid && currentLimitIsAdjustableItem.value == 1 && currentLimitItem.valid - - Component.onCompleted: { getActualCurrent () } - - VBusItem - { - id: currentLimitIsAdjustableItem - bind: Utils.path(inverterService, "/Ac/ActiveIn/CurrentLimitIsAdjustable") - onValueChanged: getActualCurrent () - onValidChanged: getActualCurrent () - } - VBusItem - { - id: currentLimitItem - bind: Utils.path(inverterService, "/Ac/ActiveIn/CurrentLimit") - onValueChanged: getActualCurrent () - onValidChanged: getActualCurrent () - } - VBusItem { id: activeInputItem; bind: Utils.path(inverterService, "/Ac/ActiveIn/ActiveInput") } - VBusItem { id: numberOfAcInputs; bind: Utils.path(inverterService, "/Ac/In/NumberOfAcInputs") } - VBusItem { id: activeSourceItem; bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") } - VBusItem { id: acIn1sourceItem; bind: Utils.path(settingsPrefix, "/Settings/SystemSetup/AcInput1") } - VBusItem { id: acIn2sourceItem; bind: Utils.path(settingsPrefix, "/Settings/SystemSetup/AcInput2") } - property int activeSource: activeSourceItem.valid ? activeSourceItem.value : 0 - property int acIn1source: acIn1sourceItem.valid ? acIn1sourceItem.value : 0 - property int acIn2source: acIn2sourceItem.valid ? acIn2sourceItem.value : 0 - property int activeInput: activeInputItem.valid && activeInputItem.value == 1 ? 2 : 1 - property bool hasTwoInputs: numberOfAcInputs.valid && numberOfAcInputs.value == 2 - - property variant acSourceName: [qsTr("---"), qsTr("Grid"), qsTr("Generator"), qsTr("Shore")] - - // background - Rectangle - { - anchors - { - fill: parent - } - color: root.backgroundColor - } - - Row - { - spacing: 5 - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - width: parent.width - 6 - Column - { - spacing: 2 - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Total Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.power, "W") - } - PowerGauge - { - id: gauge - width: totalDataWidth - tableColumnWidth - height: 15 - connection: sys.acInput - useInputCurrentLimit: true - maxForwardPowerParameter: "" // handled internally - uses input current limit and AC input voltage - maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxFeedInPower" - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + tableColumnWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Active Source") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth - tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: - { - if (activeSource == 240) - return quTr ("no input") - else if (hasTwoInputs) - return acSourceName[activeSource] + " (AC in " + activeInput + ")" - else - return acSourceName[activeSource] - } - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L1" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L2"; visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L3"; visible: phaseCount >= 3 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: qsTr ("Freq") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.powerL1, "W") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.acInput.powerL2, "W"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.powerL3, "W"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Voltage / Freq") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.voltageL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.acInput.voltageL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.voltageL3, "V"); visible: phaseCount >= 3 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.frequency, "Hz") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.currentL1, "A") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.acInput.currentL2, "A"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.currentL3, "A"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("CurrentLimit") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: - { - var newText - if (newCurrentLimit != actualCurrentLimit) - newText = qsTr(" New ") + newCurrentLimit.toFixed (1) + " A" - else - newText = "" - return currentLimitItem.valid ? currentLimitItem.value.toFixed (1) + " A" + newText: "--" } - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: "L2 values included in L1" - visible: splitPhasePassthruDisabled } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: qsTr("Avaliable Sources") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L1" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L2"; visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L3"; visible: phaseCount >= 3 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: qsTr ("Freq") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: 20; horizontalAlignment: Text.AlignHCenter - text: activeSource == 1 || activeSource == 3 ? ">" : "" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth - 20; horizontalAlignment: Text.AlignRight - text: - { - if (acIn1source == 3 || acIn2source == 3) - return acSourceName[3] - else - return acSourceName[1] - } - } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.grid.voltageL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.grid.voltageL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.grid.voltageL3, "V"); visible: phaseCount >= 3 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.grid.frequency, "Hz") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: 20; horizontalAlignment: Text.AlignHCenter - text: activeSource == 2 ? ">" : "" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth - 20; horizontalAlignment: Text.AlignRight - text: acSourceName[2] } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.genset.voltageL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.genset.voltageL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.genset.voltageL3, "V"); visible: phaseCount >= 3 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.genset.frequency, "Hz") } - } - } - Column - { - id: currentButtonColumn - width: 128 - spacing: 4 - - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: currentButtonColumn.width; horizontalAlignment: Text.AlignHCenter - text: qsTr("Current Limit") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: currentButtonColumn.width; horizontalAlignment: Text.AlignHCenter - text: qsTr("is not adjustable")} - visible: !currentLimitIsAdjustable - } - Row - { - visible: currentLimitIsAdjustable - width: (parent.width / 2) - 2 - spacing: 4 - DetailButton - { - id: preset1button - baseColor: newCurrentLimit === acLimitPreset1 ? "black" : root.buttonColor - pressedColor: root.pressedColor - opacity: acLimitPreset1 === 0 ? 0.001 : 1 - height: 40 - width: parent.width - onClicked: setNewValue (acLimitPreset1) - enabled: acLimitPreset1 === 0 ? false : true - content: TileText - { - text: qsTr(acLimitPreset1 + " A"); font.bold: true; - color: "white" - } - } - DetailButton - { - id: preset2button - baseColor: newCurrentLimit === acLimitPreset2 ? "black" : root.buttonColor - pressedColor: root.pressedColor - opacity: acLimitPreset2 === 0 ? 0.001 : 1 - height: 40 - width: parent.width - onClicked: setNewValue (acLimitPreset2) - enabled: acLimitPreset2 === 0 ? false : true - content: TileText - { - text: qsTr(acLimitPreset2 + " A"); font.bold: true; - color: "white" - } - } - } - Row - { - visible: currentLimitIsAdjustable - width: (parent.width / 2) - 2 - spacing: 4 - DetailButton - { - id: preset3button - baseColor: newCurrentLimit === acLimitPreset3 ? "black" : root.buttonColor - pressedColor: root.pressedColor - opacity: acLimitPreset3 === 0 ? 0.001 : 1 - height: 40 - width: parent.width - onClicked: setNewValue (acLimitPreset3) - enabled: acLimitPreset3 === 0 ? false : true - content: TileText - { - text: qsTr(acLimitPreset3 + " A"); font.bold: true; - color: "white" - } - } - DetailButton - { - visible: currentLimitIsAdjustable - id: preset4button - baseColor: newCurrentLimit === acLimitPreset4 ? "black" : root.buttonColor - pressedColor: root.pressedColor - opacity: acLimitPreset4 === 0 ? 0.001 : 1 - height: 40 - width: parent.width - onClicked: setNewValue (acLimitPreset4) - enabled: acLimitPreset4 === 0 ? false : true - content: TileText - { - text: qsTr(acLimitPreset4 + " A"); font.bold: true; - color: "white" - } - } - } - Row - { - visible: currentLimitIsAdjustable - width: (parent.width / 2) - 2 - spacing: 4 - DetailButton - { - id: trimMinus - baseColor: root.buttonColor - pressedColor: root.pressedColor - height: 40 - width: parent.width - enablePressAndHold: true - onClicked: trimNewValue (-1) - enabled: newCurrentLimit === acLimitPreset4 ? false : true - content: TileText - { - text: qsTr("-1 A"); font.bold: true; - color: "white" - } - } - DetailButton - { - id: trimPlus - baseColor: root.buttonColor - pressedColor: root.pressedColor - height: 40 - width: parent.width - enablePressAndHold: true - onClicked: trimNewValue (+1) - content: TileText - { - text: qsTr("+1 A"); font.bold: true; - color: "white" - } - } - } - Row - { - visible: currentLimitIsAdjustable - width: parent.width - spacing: 4 - DetailButton - { - id: acceptButton - baseColor: root.buttonColor - pressedColor: root.pressedColor - height: 40 - width: parent.width - onClicked: accept() - content: TileText { text: qsTr ("Accept New"); - font.bold: true; color: newCurrentLimit !== actualCurrentLimit ? "white" : "#d9d9d9" } - } - } - } - } - - function setNewValue (newValue) - { - if (currentLimitIsAdjustable) - newCurrentLimit = newValue - } - - function trimNewValue (trimValue) - { - if (!currentLimitIsAdjustable) - return - - newCurrentLimit += trimValue - if (newCurrentLimit < 0) - newCurrentLimit = 0 - } - - function cancel () - { - newCurrentLimit = actualCurrentLimit - pageStack.pop() - } - - function accept () - { - if (currentLimitIsAdjustable) - { - currentLimitItem.setValue (newCurrentLimit) - pageStack.pop() // return to main screen after changing input current limit - } - } - - function getActualCurrent () - { - actualCurrentLimit = currentLimitItem.valid ? currentLimitItem.value : 0 - newCurrentLimit = actualCurrentLimit - } - - // When new service is found check if is a tank sensor - Connections - { - target: DBusServices - onDbusServiceFound: addService(service) - } - - //// hard key handler - // used to press buttons when touch isn't available - // UP and DOWN buttons cycle through the list of buttons - // "space" button is used to simulate a button press - // button must be highlighted so that other uses of "space" - // will still occur - - // list of buttons to be accessed via hard buttons - property variant buttonList: - [ - preset1button, preset2button, preset3button, preset4button, trimMinus, trimPlus, acceptButton - ] - - property int buttonIndex: 0 - - Timer - { - id: targetTimer - interval: 5000 - repeat: false - running: false - onTriggered: { clearHighlight () } - } - - Keys.forwardTo: [keyHandler] - - Item - { - id: keyHandler - Keys.onDownPressed: - { - nextTarget (+1) - event.accepted = true - } - - Keys.onUpPressed: - { - nextTarget (-1) - event.accepted = true - } - } - - function nextTarget (increment) - { - // make one pass through all possible targets to find an enabled one - // if found, that's the new selectedTarget, - // if not selectedTarget does not change - var newIndex = buttonIndex - for (var i = 0; i < buttonList.length; i++) - { - // just restore highlight if not visible - if ( ! targetTimer.running && buttonList[newIndex].visible) - { - setActiveButton (buttonIndex) - return - } - newIndex += increment - if (newIndex >= buttonList.length) - newIndex = 0 - else if (newIndex < 0) - newIndex = buttonList.length - 1 - if (buttonList[newIndex].visible) - { - setActiveButton (newIndex) - break - } - } - } - - // Keys.onSpacePressed doesn't work - stolen by pageHandler - // so build a custom page handler so "space" can be used to press a button - pageToolbarHandler: detailToolbarHandler - ToolbarHandlerPages - { - id: detailToolbarHandler - isDefault: true - function centerAction() - { - acceptSpaceButton () - } - } - - function acceptSpaceButton () - { - if (targetTimer.running) - { - buttonList[buttonIndex].clicked () - } - } - - function setActiveButton (newIndex) - { - buttonIndex = newIndex - for (var i = 0; i < buttonList.length; i++) - if (i == newIndex) - buttonList[i].highlight = true - else - buttonList[i].highlight = false - targetTimer.restart () - } - - function clearHighlight () - { - for (var i = 0; i < buttonList.length; i++) - buttonList[i].highlight = false - } -} diff --git a/FileSets/v2.73/DetailAcInput.qml.orig b/FileSets/v2.73/DetailAcInput.qml.orig deleted file mode 100644 index fa82295c..00000000 --- a/FileSets/v2.73/DetailAcInput.qml.orig +++ /dev/null @@ -1,142 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -Item { - id: root - - property string systemPrefix: "com.victronenergy.system" - property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" - - property variant battery: _battery - property alias dcSystem: _dcSystem - property alias pvCharger: _pvCharger - property alias pvOnAcIn1: _pvOnAcIn1 - property alias pvOnAcIn2: _pvOnAcIn2 - property alias pvOnAcOut: _pvOnAcOut - property alias vebusDc: _vebusDc - property alias acLoad: _acLoad - property alias acInLoad: _acInLoad - property alias acOutLoad: _acOutLoad - property alias grid: _grid - property alias genset: _genset - property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } - property variant acSource: _acSource.value - - property alias pvOnGrid: _pvOnAcIn2 - property variant acInput: (acSource === acSourceGenset ? _genset : - (acSource === acSourceGrid || acSource === acSourceShore ? _grid : - _acUnknown)) - - property int batteryStateIdle: 0 - property int batteryStateCharging: 1 - property int batteryStateDischarging: 2 - - property int acSourceNotAvailable: 0 - property int acSourceGrid: 1 - property int acSourceGenset: 2 - property int acSourceShore: 3 // same as grid - - property alias pvInvertersProductIds: _pvInvertersProductIds - property alias batteryProductId: _batteryProductId - - VBusItem { - id: _pvInvertersProductIds - bind: Utils.path(systemPrefix, "/PvInvertersProductIds") - } - - VBusItem { - id: _batteryProductId - bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") - } - - VBusItem { - id: _vebusService - bind: Utils.path(systemPrefix, "/VebusService") - } - - QtObject { - id: _pvCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} - } - - ObjectAcConnection { - id: _pvOnAcOut - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") - } - - ObjectAcConnection { - id: _pvOnAcIn1 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") - } - - ObjectAcConnection { - id: _pvOnAcIn2 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") - } - - ObjectAcConnection { - id: _genset - bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") - } - - VBusItem { - id: _acSource - bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") - } - - ObjectAcConnection { - id: _grid - bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") - } - - ObjectAcConnection { - id: _acLoad - bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") - } - - ObjectAcConnection { - id: _acOutLoad - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") - } - - ObjectAcConnection { - id: _acInLoad - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") - } - - ObjectAcConnection { - id: _acUnknown - } - - QtObject { - id: _vebusDc - /* - * property VBusItem power: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Power"); unit: "W"} - * DONE: can interface doesn't support this yet! TODO use it...? - */ - property VBusItem current: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Current"); unit: "A"} - property VBusItem voltage: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Voltage"); unit: "V"} - property VBusItem power: VBusItem { - value: _vebusDc.current.valid && _vebusDc.voltage.valid ? - _vebusDc.current.value * _vebusDc.voltage.value : - undefined - unit: "W" - } - } - - QtObject { - id: _battery - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} - property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} - property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} - property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} - - // Get the battery charge state, see batteryState properties - property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} - } - - QtObject { - id: _dcSystem - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} - } -} diff --git a/FileSets/v2.73/DetailInverter.qml b/FileSets/v2.73/DetailInverter.qml deleted file mode 100644 index a78dd573..00000000 --- a/FileSets/v2.73/DetailInverter.qml +++ /dev/null @@ -1,556 +0,0 @@ -////// detail page for setting inverter mode -////// and displaying inverter details -////// pushed from Flow overview - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 -import "enhancedFormat.js" as EnhFmt - -MbPage { - id: root - - title: "Inverter detail" - - property variant sys: theSystem - property string systemPrefix: "com.victronenergy.system" - - property int fontPixelSize: 18 - property color buttonColor: "#979797" - property color pressedColor: "#d3d3d3" - property color backgroundColor: "#b3b3b3" - - property int inverterMode: inverterModeItem.valid ? inverterModeItem.value : 0 - property bool editable: inverterService != "" && inverterModeItem.valid - property int buttonHeight: 40 - property int tableColumnWidth: 80 - property int rowTitleWidth: 130 - property int dataColumns: 3 - property int totalDataWidth: tableColumnWidth * dataColumns - property int legColumnWidth: phaseCount <= 1 ? totalDataWidth : totalDataWidth / phaseCount - - property int numberOfMultis: 0 - property int numberOfInverters: 0 - property string inverterService: "" - property bool isInverter: numberOfMultis === 0 && numberOfInverters === 1 - - Component.onCompleted: { discoverServices(); highlightMode () } - - VBusItem - { - id: inverterModeItem - bind: Utils.path(inverterService, "/Mode") - onValidChanged: highlightMode () - onValueChanged: highlightMode () - } - property VBusItem systemState: VBusItem { bind: Utils.path(systemPrefix, "/SystemState/State") } - SystemState - { - id: vebusState - bind: systemState.valid ? Utils.path(systemPrefix, "/SystemState/State") : Utils.path(inverterService, "/State") - } - VBusItem { id: pInL1; bind: Utils.path(inverterService, "/Ac/ActiveIn/L1/P") } - VBusItem { id: pInL2; bind: Utils.path(inverterService, "/Ac/ActiveIn/L2/P") } - VBusItem { id: pInL3; bind: Utils.path(inverterService, "/Ac/ActiveIn/L2/P") } - VBusItem { id: vInL1; bind: Utils.path(inverterService, "/Ac/ActiveIn/L1/V") } - VBusItem { id: vInL2; bind: Utils.path(inverterService, "/Ac/ActiveIn/L2/V") } - VBusItem { id: vInL3; bind: Utils.path(inverterService, "/Ac/ActiveIn/L3/V") } - VBusItem { id: iInL1; bind: Utils.path(inverterService, "/Ac/ActiveIn/L1/I") } - VBusItem { id: iInL2; bind: Utils.path(inverterService, "/Ac/ActiveIn/L2/I") } - VBusItem { id: iInL3; bind: Utils.path(inverterService, "/Ac/ActiveIn/L3/I") } - VBusItem { id: pOutL1; bind: Utils.path(inverterService, "/Ac/Out/L1/P") } - VBusItem { id: pOutL2; bind: Utils.path(inverterService, "/Ac/Out/L2/P") } - VBusItem { id: pOutL3; bind: Utils.path(inverterService, "/Ac/Out/L3/P") } - VBusItem { id: vOutL1; bind: Utils.path(inverterService, "/Ac/Out/L1/V") } - VBusItem { id: vOutL2; bind: Utils.path(inverterService, "/Ac/Out/L2/V") } - VBusItem { id: vOutL3; bind: Utils.path(inverterService, "/Ac/Out/L3/V") } - VBusItem { id: iOutL1; bind: Utils.path(inverterService, "/Ac/Out/L1/I") } - VBusItem { id: iOutL2; bind: Utils.path(inverterService, "/Ac/Out/L2/I") } - VBusItem { id: iOutL3; bind: Utils.path(inverterService, "/Ac/Out/L3/I") } - VBusItem { id: fInL1; bind: Utils.path(inverterService, "/Ac/ActiveIn/L1/F") } - VBusItem { id: fOutL1; bind: Utils.path(inverterService, "/Ac/Out/L1/F") } - VBusItem { id: dcPower; bind: Utils.path(inverterService, "/Dc/0/Power") } - VBusItem { id: dcCurrent; bind: Utils.path(inverterService, "/Dc/0/Current") } - VBusItem { id: splitPhaseL2Passthru; bind: Utils.path(inverterService, "/Ac/State/SplitPhaseL2Passthru") } - VBusItem { id: phaseCountItem; bind: Utils.path(inverterService, "/Ac/NumberOfPhases") } - - property bool noL2inverter: splitPhaseL2Passthru.valid - property bool l2AndL1OutSummed: noL2inverter && splitPhaseL2Passthru.value === 0 - property int phaseCount: phaseCountItem.valid ? phaseCountItem.value : 0 - - // background - Rectangle - { - anchors - { - fill: parent - } - color: root.backgroundColor - } - - Row - { - spacing: 5 - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - Column - { - spacing: 2 - Row - { - PowerGaugeMulti - { - id: gauge - width: rowTitleWidth + totalDataWidth - height: 15 - inverterService: root.inverterService - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Total Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: - { - var total = 0 - var totalValid = false - if (pOutL1.valid && pInL1.valid) - { - total += pOutL1.value - pInL1.value - totalValid = true - } - if (pOutL2.valid && pInL2.valid) - { - total += pOutL2.value - pInL2.value - totalValid = true - } - if (pOutL3.valid && pInL3.valid) - { - total += pOutL3.value - pInL3.value - totalValid = true - } - if (totalValid) - return EnhFmt.formatValue (total, "W") - else - return "--" - } - } - visible: phaseCount >= 2 - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("State") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: vebusState.text } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: "" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L1" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L2" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L3"; visible: phaseCount >= 3 } - visible: phaseCount >= 2 - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: formatValueDiff (pOutL1, pInL1, "W") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: - { - if (l2AndL1OutSummed) - return "< < <" - else if (noL2inverter) - return qsTr("none") - else - return formatValueDiff (pOutL2, pInL2, "W") - } - visible: phaseCount >= 2 - } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: formatValueDiff (pOutL3, pInL3, "W"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Input Voltage") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (vInL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (vInL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (vInL3, "V"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Output Voltage") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (vOutL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (vOutL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (vOutL3, "V"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Input Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (iInL1, "A") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (iInL2, "A"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (iInL3, "A"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Output Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (iOutL1, "A") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l2AndL1OutSummed ? "< < <" : EnhFmt.formatVBusItem (iOutL2, "A"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (iOutL3, "A"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Frequency In / Out") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth / 2; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (fInL1, "Hz") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth / 2; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (fOutL1, "Hz") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("DC Power / Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth * 0.4; horizontalAlignment: Text.AlignHCenter - text: - { - if (! dcPower.valid) - return "" - else if (dcPower.value > 0) - return qsTr ("supplying") - else if (dcPower.value < 0) - return qsTr ("consuming") - else - return "" - } - } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth * 0.3; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (dcPower, "W") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth * 0.3; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (dcCurrent, "A") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: l2AndL1OutSummed ? qsTr ("L2 Output values included in L1") : qsTr ("L2 AC out from AC in (no inverter)") - visible: noL2inverter - } - } - } - Column - { - width: 80 - spacing: 4 - - DetailButton - { - id: onButton - baseColor: inverterMode === 3 ? "green" : "#e6ffe6" - pressedColor: root.pressedColor - height: root.buttonHeight - width: parent.width - 6 - visible: !isInverter - onClicked: changeMode(3) - content: TileText - { - text: qsTr("On"); font.bold: true; - color: inverterMode === 3 ? "white" : "black" - } - } - DetailButton - { - id: offButton - baseColor: inverterMode === 4 ? "black" : "#e6e6e6" - pressedColor: root.pressedColor - height: root.buttonHeight - width: parent.width - 6 - onClicked: changeMode(4) - content: TileText - { - text: qsTr("Off"); font.bold: true; - color: inverterMode === 4 ? "white" : "black" - } - } - DetailButton - { - id: invertOnlyButton - baseColor: inverterMode === 2 ? "blue" : "#ccccff" - pressedColor: root.pressedColor - height: root.buttonHeight - width: parent.width - 6 - onClicked: changeMode(2) - content: TileText - { - text: isInverter ? qsTr("On") : qsTr("Inverter\nOnly"); font.bold: true; - color: inverterMode === 2 ? "white" : "black" - } - } - DetailButton - { - id: chargeOnlyButton - baseColor: inverterMode === 1 ? "orange" : "#ffedcc" - pressedColor: root.pressedColor - height: root.buttonHeight - width: parent.width - 6 - visible: !isInverter - onClicked: changeMode(1) - content: TileText - { - text: qsTr("Charger\nOnly"); font.bold: true; - color: inverterMode === 1 ? "white" : "black" - } - } - DetailButton - { - id: ecoButton - baseColor: inverterMode === 5 ? "orange" : "#ffedcc" - pressedColor: root.pressedColor - height: root.buttonHeight - width: parent.width - 6 - visible: isInverter - onClicked: changeMode(5) - content: TileText - { - text: qsTr("Eco"); font.bold: true; - color: inverterMode === 5 ? "white" : "black" - } - } - } - } - - function changeMode(newMode) - { - if (editable) - { - inverterModeItem.setValue(newMode) - pageStack.pop() // return to flow screen after changing inverter mode - } - } - - function cancel() - { - pageStack.pop() - } - - function highlightMode () - { - if (editable) - inverterMode = inverterModeItem.value - else - inverterMode = 0 - } - - - // When new service is found check if is a tank sensor - Connections - { - target: DBusServices - onDbusServiceFound: addService(service) - } - - function addService(service) - { - switch (service.type) - { - case DBusService.DBUS_SERVICE_MULTI: - case DBusService.DBUS_SERVICE_MULTI_RS: - numberOfMultis++ - if (numberOfMultis === 1) - inverterService = service.name; - break;; - case DBusService.DBUS_SERVICE_INVERTER: - numberOfInverters++ - if (numberOfInverters === 1 && numberOfMultis === 0) - inverterService = service.name; - break;; - } - } - - // Detect available services of interest - function discoverServices() - { - numberOfMultis = 0 - numberOfInverters = 0 - inverterService = "" - for (var i = 0; i < DBusServices.count; i++) - { - addService(DBusServices.at(i)) - } - } - - function formatValueDiff (item1, item2, unit) - { - if (item1.valid && item2.valid) - return EnhFmt.formatValue (item1.value - item2.value, unit) - else - return "--" - } - - - //// hard key handler - // used to press buttons when touch isn't available - // UP and DOWN buttons cycle through the list of buttons - // "space" button is used to simulate a button press - // button must be highlighted so that other uses of "space" - // will still occur - - // list of buttons to be accessed via hard buttons - property variant buttonList: - [ - onButton, offButton, invertOnlyButton, chargeOnlyButton, ecoButton - ] - - property int buttonIndex: 0 - - Timer - { - id: targetTimer - interval: 5000 - repeat: false - running: false - onTriggered: { clearHighlight () } - } - - Keys.forwardTo: [keyHandler] - - Item - { - id: keyHandler - Keys.onDownPressed: - { - nextTarget (+1) - event.accepted = true - } - - Keys.onUpPressed: - { - nextTarget (-1) - event.accepted = true - } - } - - function nextTarget (increment) - { - // make one pass through all possible targets to find an enabled one - // if found, that's the new selectedTarget, - // if not selectedTarget does not change - var newIndex = buttonIndex - for (var i = 0; i < buttonList.length; i++) - { - // just restore highlight if not visible - if ( ! targetTimer.running && buttonList[newIndex].visible) - { - setActiveButton (buttonIndex) - return - } - newIndex += increment - if (newIndex >= buttonList.length) - newIndex = 0 - else if (newIndex < 0) - newIndex = buttonList.length - 1 - if (buttonList[newIndex].visible) - { - setActiveButton (newIndex) - break - } - } - } - - // Keys.onSpacePressed doesn't work - stolen by pageHandler - // so build a custom page handler so "space" can be used to press a button - pageToolbarHandler: detailToolbarHandler - ToolbarHandlerPages - { - id: detailToolbarHandler - isDefault: true - function centerAction() - { - acceptSpaceButton () - } - } - - function acceptSpaceButton () - { - if (targetTimer.running) - { - buttonList[buttonIndex].clicked () - } - } - - function setActiveButton (newIndex) - { - buttonIndex = newIndex - for (var i = 0; i < buttonList.length; i++) - if (i == newIndex) - buttonList[i].highlight = true - else - buttonList[i].highlight = false - targetTimer.restart () - } - - function clearHighlight () - { - for (var i = 0; i < buttonList.length; i++) - buttonList[i].highlight = false - } -} diff --git a/FileSets/v2.73/DetailInverter.qml.orig b/FileSets/v2.73/DetailInverter.qml.orig deleted file mode 100644 index fa82295c..00000000 --- a/FileSets/v2.73/DetailInverter.qml.orig +++ /dev/null @@ -1,142 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -Item { - id: root - - property string systemPrefix: "com.victronenergy.system" - property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" - - property variant battery: _battery - property alias dcSystem: _dcSystem - property alias pvCharger: _pvCharger - property alias pvOnAcIn1: _pvOnAcIn1 - property alias pvOnAcIn2: _pvOnAcIn2 - property alias pvOnAcOut: _pvOnAcOut - property alias vebusDc: _vebusDc - property alias acLoad: _acLoad - property alias acInLoad: _acInLoad - property alias acOutLoad: _acOutLoad - property alias grid: _grid - property alias genset: _genset - property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } - property variant acSource: _acSource.value - - property alias pvOnGrid: _pvOnAcIn2 - property variant acInput: (acSource === acSourceGenset ? _genset : - (acSource === acSourceGrid || acSource === acSourceShore ? _grid : - _acUnknown)) - - property int batteryStateIdle: 0 - property int batteryStateCharging: 1 - property int batteryStateDischarging: 2 - - property int acSourceNotAvailable: 0 - property int acSourceGrid: 1 - property int acSourceGenset: 2 - property int acSourceShore: 3 // same as grid - - property alias pvInvertersProductIds: _pvInvertersProductIds - property alias batteryProductId: _batteryProductId - - VBusItem { - id: _pvInvertersProductIds - bind: Utils.path(systemPrefix, "/PvInvertersProductIds") - } - - VBusItem { - id: _batteryProductId - bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") - } - - VBusItem { - id: _vebusService - bind: Utils.path(systemPrefix, "/VebusService") - } - - QtObject { - id: _pvCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} - } - - ObjectAcConnection { - id: _pvOnAcOut - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") - } - - ObjectAcConnection { - id: _pvOnAcIn1 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") - } - - ObjectAcConnection { - id: _pvOnAcIn2 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") - } - - ObjectAcConnection { - id: _genset - bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") - } - - VBusItem { - id: _acSource - bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") - } - - ObjectAcConnection { - id: _grid - bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") - } - - ObjectAcConnection { - id: _acLoad - bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") - } - - ObjectAcConnection { - id: _acOutLoad - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") - } - - ObjectAcConnection { - id: _acInLoad - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") - } - - ObjectAcConnection { - id: _acUnknown - } - - QtObject { - id: _vebusDc - /* - * property VBusItem power: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Power"); unit: "W"} - * DONE: can interface doesn't support this yet! TODO use it...? - */ - property VBusItem current: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Current"); unit: "A"} - property VBusItem voltage: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Voltage"); unit: "V"} - property VBusItem power: VBusItem { - value: _vebusDc.current.valid && _vebusDc.voltage.valid ? - _vebusDc.current.value * _vebusDc.voltage.value : - undefined - unit: "W" - } - } - - QtObject { - id: _battery - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} - property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} - property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} - property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} - - // Get the battery charge state, see batteryState properties - property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} - } - - QtObject { - id: _dcSystem - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} - } -} diff --git a/FileSets/v2.73/DetailLoadsCombined.qml b/FileSets/v2.73/DetailLoadsCombined.qml deleted file mode 100644 index d286c158..00000000 --- a/FileSets/v2.73/DetailLoadsCombined.qml +++ /dev/null @@ -1,147 +0,0 @@ -////// detail page for displaying critical AC output details -////// pushed from Flow overview - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 -import "enhancedFormat.js" as EnhFmt - -MbPage { - id: root - - title: qsTr ("AC Loads detail") - - property variant sys: theSystem - property string systemPrefix: "com.victronenergy.system" - - property int fontPixelSize: 18 - property color backgroundColor: "#b3b3b3" - - property int dataColumns: 3 - property int rowTitleWidth: 130 - property int totalDataWidth: root.width - rowTitleWidth - 20 - property int tableColumnWidth: totalDataWidth / dataColumns - property int legColumnWidth: phaseCount <= 1 ? totalDataWidth : totalDataWidth / phaseCount - - property int phaseCount: sys.acLoad.phaseCount.valid ? sys.acLoad.phaseCount.value : 0 - - VBusItem { id: vebusServiceItem; bind: Utils.path(systemPrefix, "/VebusService") } - property string inverterService: vebusServiceItem.valid ? vebusServiceItem.value : "" - VBusItem { id: splitPhaseL2Passthru; bind: Utils.path(inverterService, "/Ac/State/SplitPhaseL2Passthru") } - property bool l1AndL2OutShorted: splitPhaseL2Passthru.valid && splitPhaseL2Passthru.value === 0 - - // background - Rectangle - { - anchors - { - fill: parent - } - color: root.backgroundColor - } - - Row - { - spacing: 5 - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - Column - { - spacing: 2 - Row - { - Text { id: totalLabel; font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Total Power") } - Text { id: totalPower; font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.power, "W") - } - PowerGauge - { - id: gauge - width: (root.width * 0.9) - totalLabel.width - totalPower.width - height: 15 - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputMaxPower" - connection: sys.acLoad - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: "" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L1" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L2"; visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L3"; visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.powerL1, "W") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l1AndL2OutShorted ? "< < <" : EnhFmt.formatVBusItem (sys.acLoad.powerL2, "W"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.powerL3, "W"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Voltage") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.voltageL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l1AndL2OutShorted ? "< < <" : EnhFmt.formatVBusItem (sys.acLoad.voltageL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.voltageL3, "V"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.currentL1, "A") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l1AndL2OutShorted ? "< < <" : EnhFmt.formatVBusItem (sys.acLoad.currentL2, "A"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.currentL3, "A"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Frequency") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.frequency, "Hz") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: "L2 values included in L1" - visible: l1AndL2OutShorted } - } - } - } -} diff --git a/FileSets/v2.73/DetailLoadsCombined.qml.orig b/FileSets/v2.73/DetailLoadsCombined.qml.orig deleted file mode 100644 index fa82295c..00000000 --- a/FileSets/v2.73/DetailLoadsCombined.qml.orig +++ /dev/null @@ -1,142 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -Item { - id: root - - property string systemPrefix: "com.victronenergy.system" - property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" - - property variant battery: _battery - property alias dcSystem: _dcSystem - property alias pvCharger: _pvCharger - property alias pvOnAcIn1: _pvOnAcIn1 - property alias pvOnAcIn2: _pvOnAcIn2 - property alias pvOnAcOut: _pvOnAcOut - property alias vebusDc: _vebusDc - property alias acLoad: _acLoad - property alias acInLoad: _acInLoad - property alias acOutLoad: _acOutLoad - property alias grid: _grid - property alias genset: _genset - property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } - property variant acSource: _acSource.value - - property alias pvOnGrid: _pvOnAcIn2 - property variant acInput: (acSource === acSourceGenset ? _genset : - (acSource === acSourceGrid || acSource === acSourceShore ? _grid : - _acUnknown)) - - property int batteryStateIdle: 0 - property int batteryStateCharging: 1 - property int batteryStateDischarging: 2 - - property int acSourceNotAvailable: 0 - property int acSourceGrid: 1 - property int acSourceGenset: 2 - property int acSourceShore: 3 // same as grid - - property alias pvInvertersProductIds: _pvInvertersProductIds - property alias batteryProductId: _batteryProductId - - VBusItem { - id: _pvInvertersProductIds - bind: Utils.path(systemPrefix, "/PvInvertersProductIds") - } - - VBusItem { - id: _batteryProductId - bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") - } - - VBusItem { - id: _vebusService - bind: Utils.path(systemPrefix, "/VebusService") - } - - QtObject { - id: _pvCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} - } - - ObjectAcConnection { - id: _pvOnAcOut - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") - } - - ObjectAcConnection { - id: _pvOnAcIn1 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") - } - - ObjectAcConnection { - id: _pvOnAcIn2 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") - } - - ObjectAcConnection { - id: _genset - bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") - } - - VBusItem { - id: _acSource - bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") - } - - ObjectAcConnection { - id: _grid - bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") - } - - ObjectAcConnection { - id: _acLoad - bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") - } - - ObjectAcConnection { - id: _acOutLoad - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") - } - - ObjectAcConnection { - id: _acInLoad - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") - } - - ObjectAcConnection { - id: _acUnknown - } - - QtObject { - id: _vebusDc - /* - * property VBusItem power: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Power"); unit: "W"} - * DONE: can interface doesn't support this yet! TODO use it...? - */ - property VBusItem current: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Current"); unit: "A"} - property VBusItem voltage: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Voltage"); unit: "V"} - property VBusItem power: VBusItem { - value: _vebusDc.current.valid && _vebusDc.voltage.valid ? - _vebusDc.current.value * _vebusDc.voltage.value : - undefined - unit: "W" - } - } - - QtObject { - id: _battery - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} - property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} - property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} - property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} - - // Get the battery charge state, see batteryState properties - property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} - } - - QtObject { - id: _dcSystem - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} - } -} diff --git a/FileSets/v2.73/DetailLoadsOnInput.qml b/FileSets/v2.73/DetailLoadsOnInput.qml deleted file mode 100644 index 77e99645..00000000 --- a/FileSets/v2.73/DetailLoadsOnInput.qml +++ /dev/null @@ -1,147 +0,0 @@ -////// detail page for displaying non-critical AC output details -////// pushed from Flow overview - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 -import "enhancedFormat.js" as EnhFmt - -MbPage { - id: root - - title: "Loads on AC Input Detail" - - property variant sys: theSystem - property string systemPrefix: "com.victronenergy.system" - - property int fontPixelSize: 18 - property color backgroundColor: "#b3b3b3" - - property int dataColumns: 3 - property int rowTitleWidth: 130 - property int totalDataWidth: root.width - rowTitleWidth - 20 - property int tableColumnWidth: totalDataWidth / dataColumns - property int legColumnWidth: phaseCount <= 1 ? totalDataWidth : totalDataWidth / phaseCount - - property int phaseCount: sys.acInLoad.phaseCount.valid ? sys.acInLoad.phaseCount.value : 0 - - VBusItem { id: vebusServiceItem; bind: Utils.path(systemPrefix, "/VebusService") } - property string inverterService: vebusServiceItem.valid ? vebusServiceItem.value : "" - VBusItem { id: splitPhaseL2Passthru; bind: Utils.path(inverterService, "/Ac/State/SplitPhaseL2Passthru") } - property bool l1AndL2OutShorted: splitPhaseL2Passthru.valid && splitPhaseL2Passthru.value === 0 - - // background - Rectangle - { - anchors - { - fill: parent - } - color: root.backgroundColor - } - - Row - { - spacing: 5 - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - Column - { - spacing: 2 - Row - { - Text { id: totalLabel; font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Total Power") } - Text { id: totalPower; font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.power, "W") - } - PowerGauge - { - id: gauge - width: (root.width * 0.9) - totalLabel.width - totalPower.width - height: 15 - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputMaxPower" - connection: sys.acInLoad - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: "" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L1" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L2"; visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L3"; visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.powerL1, "W") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l1AndL2OutShorted ? "< < <" : EnhFmt.formatVBusItem (sys.acInLoad.powerL2, "W"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.powerL3, "W"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Voltage") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.voltageL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l1AndL2OutShorted ? "< < <" : EnhFmt.formatVBusItem (sys.acInLoad.voltageL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.voltageL3, "V"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.currentL1, "A") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l1AndL2OutShorted ? "< < <" : EnhFmt.formatVBusItem (sys.acInLoad.currentL2, "A"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.currentL3, "A"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Frequency") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.frequency, "Hz") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: "L2 values included in L1" - visible: l1AndL2OutShorted } - } - } - } -} diff --git a/FileSets/v2.73/DetailLoadsOnInput.qml.orig b/FileSets/v2.73/DetailLoadsOnInput.qml.orig deleted file mode 100644 index fa82295c..00000000 --- a/FileSets/v2.73/DetailLoadsOnInput.qml.orig +++ /dev/null @@ -1,142 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -Item { - id: root - - property string systemPrefix: "com.victronenergy.system" - property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" - - property variant battery: _battery - property alias dcSystem: _dcSystem - property alias pvCharger: _pvCharger - property alias pvOnAcIn1: _pvOnAcIn1 - property alias pvOnAcIn2: _pvOnAcIn2 - property alias pvOnAcOut: _pvOnAcOut - property alias vebusDc: _vebusDc - property alias acLoad: _acLoad - property alias acInLoad: _acInLoad - property alias acOutLoad: _acOutLoad - property alias grid: _grid - property alias genset: _genset - property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } - property variant acSource: _acSource.value - - property alias pvOnGrid: _pvOnAcIn2 - property variant acInput: (acSource === acSourceGenset ? _genset : - (acSource === acSourceGrid || acSource === acSourceShore ? _grid : - _acUnknown)) - - property int batteryStateIdle: 0 - property int batteryStateCharging: 1 - property int batteryStateDischarging: 2 - - property int acSourceNotAvailable: 0 - property int acSourceGrid: 1 - property int acSourceGenset: 2 - property int acSourceShore: 3 // same as grid - - property alias pvInvertersProductIds: _pvInvertersProductIds - property alias batteryProductId: _batteryProductId - - VBusItem { - id: _pvInvertersProductIds - bind: Utils.path(systemPrefix, "/PvInvertersProductIds") - } - - VBusItem { - id: _batteryProductId - bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") - } - - VBusItem { - id: _vebusService - bind: Utils.path(systemPrefix, "/VebusService") - } - - QtObject { - id: _pvCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} - } - - ObjectAcConnection { - id: _pvOnAcOut - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") - } - - ObjectAcConnection { - id: _pvOnAcIn1 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") - } - - ObjectAcConnection { - id: _pvOnAcIn2 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") - } - - ObjectAcConnection { - id: _genset - bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") - } - - VBusItem { - id: _acSource - bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") - } - - ObjectAcConnection { - id: _grid - bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") - } - - ObjectAcConnection { - id: _acLoad - bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") - } - - ObjectAcConnection { - id: _acOutLoad - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") - } - - ObjectAcConnection { - id: _acInLoad - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") - } - - ObjectAcConnection { - id: _acUnknown - } - - QtObject { - id: _vebusDc - /* - * property VBusItem power: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Power"); unit: "W"} - * DONE: can interface doesn't support this yet! TODO use it...? - */ - property VBusItem current: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Current"); unit: "A"} - property VBusItem voltage: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Voltage"); unit: "V"} - property VBusItem power: VBusItem { - value: _vebusDc.current.valid && _vebusDc.voltage.valid ? - _vebusDc.current.value * _vebusDc.voltage.value : - undefined - unit: "W" - } - } - - QtObject { - id: _battery - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} - property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} - property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} - property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} - - // Get the battery charge state, see batteryState properties - property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} - } - - QtObject { - id: _dcSystem - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} - } -} diff --git a/FileSets/v2.73/DetailLoadsOnOutput.qml b/FileSets/v2.73/DetailLoadsOnOutput.qml deleted file mode 100644 index ea917556..00000000 --- a/FileSets/v2.73/DetailLoadsOnOutput.qml +++ /dev/null @@ -1,152 +0,0 @@ -////// detail page for displaying critical AC output details -////// pushed from Flow overview - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 -import "enhancedFormat.js" as EnhFmt - -MbPage { - id: root - - title: combineAcLoads ? qsTr ("AC Loads detail") : qsTr ("Loads on AC Output detail") - - property variant sys: theSystem - property string systemPrefix: "com.victronenergy.system" - property string settingsPrefix: "com.victronenergy.settings" - - property int fontPixelSize: 18 - property color backgroundColor: "#b3b3b3" - - property int dataColumns: 3 - property int rowTitleWidth: 130 - property int totalDataWidth: root.width - rowTitleWidth - 20 - property int tableColumnWidth: totalDataWidth / dataColumns - property int legColumnWidth: phaseCount <= 1 ? totalDataWidth : totalDataWidth / phaseCount - - property int phaseCount: outputLoad.phaseCount.valid ? outputLoad.phaseCount.value : 0 - - VBusItem { id: vebusServiceItem; bind: Utils.path(systemPrefix, "/VebusService") } - property string inverterService: vebusServiceItem.valid ? vebusServiceItem.value : "" - VBusItem { id: splitPhaseL2Passthru; bind: Utils.path(inverterService, "/Ac/State/SplitPhaseL2Passthru") } - property bool l1AndL2OutShorted: splitPhaseL2Passthru.valid && splitPhaseL2Passthru.value === 0 - - VBusItem { id: _combineAcLoads; bind: "com.victronenergy.settings/Settings/GuiMods/EnhancedFlowCombineLoads" } - property bool combineAcLoads: _combineAcLoads.valid && _combineAcLoads.value === 1 - property variant outputLoad: combineAcLoads ? sys.acLoad : sys.acOutLoad - - // background - Rectangle - { - anchors - { - fill: parent - } - color: root.backgroundColor - } - - Row - { - spacing: 5 - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - Column - { - spacing: 2 - Row - { - Text { id: totalLabel; font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Total Power") } - Text { id: totalPower; font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.power, "W") - } - PowerGauge - { - id: gauge - width: (root.width * 0.9) - totalLabel.width - totalPower.width - height: 15 - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputMaxPower" - connection: outputLoad - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: "" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L1" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L2"; visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L3"; visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.powerL1, "W") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l1AndL2OutShorted ? "< < <" : EnhFmt.formatVBusItem (outputLoad.powerL2, "W"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.powerL3, "W"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Voltage") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.voltageL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l1AndL2OutShorted ? "< < <" : EnhFmt.formatVBusItem (outputLoad.voltageL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.voltageL3, "V"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.currentL1, "A") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l1AndL2OutShorted ? "< < <" : EnhFmt.formatVBusItem (outputLoad.currentL2, "A"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.currentL3, "A"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Frequency") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.frequency, "Hz") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: "L2 values included in L1" - visible: l1AndL2OutShorted } - } - } - } -} diff --git a/FileSets/v2.73/DetailLoadsOnOutput.qml.orig b/FileSets/v2.73/DetailLoadsOnOutput.qml.orig deleted file mode 100644 index fa82295c..00000000 --- a/FileSets/v2.73/DetailLoadsOnOutput.qml.orig +++ /dev/null @@ -1,142 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -Item { - id: root - - property string systemPrefix: "com.victronenergy.system" - property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" - - property variant battery: _battery - property alias dcSystem: _dcSystem - property alias pvCharger: _pvCharger - property alias pvOnAcIn1: _pvOnAcIn1 - property alias pvOnAcIn2: _pvOnAcIn2 - property alias pvOnAcOut: _pvOnAcOut - property alias vebusDc: _vebusDc - property alias acLoad: _acLoad - property alias acInLoad: _acInLoad - property alias acOutLoad: _acOutLoad - property alias grid: _grid - property alias genset: _genset - property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } - property variant acSource: _acSource.value - - property alias pvOnGrid: _pvOnAcIn2 - property variant acInput: (acSource === acSourceGenset ? _genset : - (acSource === acSourceGrid || acSource === acSourceShore ? _grid : - _acUnknown)) - - property int batteryStateIdle: 0 - property int batteryStateCharging: 1 - property int batteryStateDischarging: 2 - - property int acSourceNotAvailable: 0 - property int acSourceGrid: 1 - property int acSourceGenset: 2 - property int acSourceShore: 3 // same as grid - - property alias pvInvertersProductIds: _pvInvertersProductIds - property alias batteryProductId: _batteryProductId - - VBusItem { - id: _pvInvertersProductIds - bind: Utils.path(systemPrefix, "/PvInvertersProductIds") - } - - VBusItem { - id: _batteryProductId - bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") - } - - VBusItem { - id: _vebusService - bind: Utils.path(systemPrefix, "/VebusService") - } - - QtObject { - id: _pvCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} - } - - ObjectAcConnection { - id: _pvOnAcOut - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") - } - - ObjectAcConnection { - id: _pvOnAcIn1 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") - } - - ObjectAcConnection { - id: _pvOnAcIn2 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") - } - - ObjectAcConnection { - id: _genset - bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") - } - - VBusItem { - id: _acSource - bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") - } - - ObjectAcConnection { - id: _grid - bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") - } - - ObjectAcConnection { - id: _acLoad - bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") - } - - ObjectAcConnection { - id: _acOutLoad - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") - } - - ObjectAcConnection { - id: _acInLoad - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") - } - - ObjectAcConnection { - id: _acUnknown - } - - QtObject { - id: _vebusDc - /* - * property VBusItem power: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Power"); unit: "W"} - * DONE: can interface doesn't support this yet! TODO use it...? - */ - property VBusItem current: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Current"); unit: "A"} - property VBusItem voltage: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Voltage"); unit: "V"} - property VBusItem power: VBusItem { - value: _vebusDc.current.valid && _vebusDc.voltage.valid ? - _vebusDc.current.value * _vebusDc.voltage.value : - undefined - unit: "W" - } - } - - QtObject { - id: _battery - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} - property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} - property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} - property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} - - // Get the battery charge state, see batteryState properties - property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} - } - - QtObject { - id: _dcSystem - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} - } -} diff --git a/FileSets/v2.73/HubData.qml b/FileSets/v2.73/HubData.qml deleted file mode 100644 index 0a8cb7f4..00000000 --- a/FileSets/v2.73/HubData.qml +++ /dev/null @@ -1,224 +0,0 @@ -//////// modified for VE.Direct inverter support -//////// modified for grid/genset meter -//////// added alternator, AC charger, wind generator - -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -Item { - id: root - - property variant sys: theSystem - - property string systemPrefix: "com.victronenergy.system" - property string settingsPrefix: "com.victronenergy.settings" - property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" - -//////// add to support VE.Direct inverters - property string inverterService: "" -//////// add for grid/genset meters - property string gridMeterService: "" - property string gensetService: "" - - property variant battery: _battery - property alias dcSystem: _dcSystem - property alias alternator: _alternator - property alias windGenerator: _windGenerator - property alias fuelCell: _fuelCell - property alias acCharger: _acCharger - property alias pvCharger: _pvCharger - property alias pvOnAcIn1: _pvOnAcIn1 - property alias pvOnAcIn2: _pvOnAcIn2 - property alias pvOnAcOut: _pvOnAcOut - property alias vebusDc: _vebusDc - property alias acLoad: _acLoad - property alias acInLoad: _acInLoad - property alias acOutLoad: _acOutLoad - property alias grid: _grid - property alias genset: _genset - property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } - property variant acSource: _acSource.value - - property alias pvOnGrid: _pvOnAcIn2 - property variant acInput: (acSource === acSourceGenset ? _genset : - (acSource === acSourceGrid || acSource === acSourceShore ? _grid : - _acUnknown)) - - property int batteryStateIdle: 0 - property int batteryStateCharging: 1 - property int batteryStateDischarging: 2 - - property int acSourceNotAvailable: 0 - property int acSourceGrid: 1 - property int acSourceGenset: 2 - property int acSourceShore: 3 // same as grid - - property alias pvInvertersProductIds: _pvInvertersProductIds - property alias batteryProductId: _batteryProductId - - VBusItem { - id: _pvInvertersProductIds - bind: Utils.path(systemPrefix, "/PvInvertersProductIds") - } - - VBusItem { - id: _batteryProductId - bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") - } - - VBusItem { - id: _vebusService - bind: Utils.path(systemPrefix, "/VebusService") - } - - QtObject { - id: _pvCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} - } - -//////// added alternator - QtObject { - id: _alternator - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Alternator/Power"); unit: "W"} - } - -//////// added AC charger - QtObject { - id: _acCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Charger/Power"); unit: "W"} - } - -//////// added wind generator - QtObject { - id: _windGenerator - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/WindGenerator/Power"); unit: "W"} - } - -//////// added fuel cell - QtObject { - id: _fuelCell - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/FuelCell/Power"); unit: "W"} - } - - ObjectAcConnection { - id: _pvOnAcOut - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") - } - - ObjectAcConnection { - id: _pvOnAcIn1 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") - } - - ObjectAcConnection { - id: _pvOnAcIn2 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") - } - - ObjectAcConnection { - id: _genset - bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") -//////// modified for VE.Direct inverter support - inverterSource: "/Ac/ActiveIn" - inverterService: sys.vebusPrefix != "" ? sys.vebusPrefix : root.inverterService - } - - VBusItem { - id: _acSource - bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") - } - - ObjectAcConnection { - id: _grid - bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") -//////// modified for VE.Direct inverter support - inverterSource: "/Ac/ActiveIn" - inverterService: sys.vebusPrefix != "" ? sys.vebusPrefix : root.inverterService - } - - ObjectAcConnection { - id: _acLoad - bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") -//////// modified for VE.Direct inverter support - inverterSource: "/Ac/Out" - inverterService: sys.vebusPrefix != "" ? sys.vebusPrefix : root.inverterService - } - - ObjectAcConnection { - id: _acOutLoad - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") - } - - ObjectAcConnection { - id: _acInLoad - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") - } - - ObjectAcConnection { - id: _acUnknown - } - - QtObject { - id: _vebusDc - /* - * property VBusItem power: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Power"); unit: "W"} - * DONE: can interface doesn't support this yet! TODO use it...? - */ - property VBusItem current: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Current"); unit: "A"} - property VBusItem voltage: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Voltage"); unit: "V"} - property VBusItem power: VBusItem { - value: _vebusDc.current.valid && _vebusDc.voltage.valid ? - _vebusDc.current.value * _vebusDc.voltage.value : - undefined - unit: "W" - } - } - - QtObject { - id: _battery - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} - property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} - property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} - property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} - - // Get the battery charge state, see batteryState properties - property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} - } - - QtObject { - id: _dcSystem - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} - } - -//////// add to support for adjustable watt / killowatt display switching - VBusItem { id: kwThresholdItem; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/KilowattThreshold") } - property int kilowattThreshold: kwThresholdItem.valid ? kwThresholdItem.value : 1000 - -//////// add to support VE.Direct inverters - Component.onCompleted: discoverServices() - - // When new service is found check if is a tank sensor - Connections - { - target: DBusServices - onDbusServiceFound: addService(service) - } - function addService(service) - { - switch (service.type) - { - case DBusService.DBUS_SERVICE_INVERTER: - if (inverterService === "") - inverterService = service.name; - break;; - } - } - - // Check available services inverter services - function discoverServices() - { - for (var i = 0; i < DBusServices.count; i++) - addService(DBusServices.at(i)) - } -} diff --git a/FileSets/v2.73/HubData.qml.orig b/FileSets/v2.73/HubData.qml.orig deleted file mode 100644 index fa82295c..00000000 --- a/FileSets/v2.73/HubData.qml.orig +++ /dev/null @@ -1,142 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -Item { - id: root - - property string systemPrefix: "com.victronenergy.system" - property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" - - property variant battery: _battery - property alias dcSystem: _dcSystem - property alias pvCharger: _pvCharger - property alias pvOnAcIn1: _pvOnAcIn1 - property alias pvOnAcIn2: _pvOnAcIn2 - property alias pvOnAcOut: _pvOnAcOut - property alias vebusDc: _vebusDc - property alias acLoad: _acLoad - property alias acInLoad: _acInLoad - property alias acOutLoad: _acOutLoad - property alias grid: _grid - property alias genset: _genset - property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } - property variant acSource: _acSource.value - - property alias pvOnGrid: _pvOnAcIn2 - property variant acInput: (acSource === acSourceGenset ? _genset : - (acSource === acSourceGrid || acSource === acSourceShore ? _grid : - _acUnknown)) - - property int batteryStateIdle: 0 - property int batteryStateCharging: 1 - property int batteryStateDischarging: 2 - - property int acSourceNotAvailable: 0 - property int acSourceGrid: 1 - property int acSourceGenset: 2 - property int acSourceShore: 3 // same as grid - - property alias pvInvertersProductIds: _pvInvertersProductIds - property alias batteryProductId: _batteryProductId - - VBusItem { - id: _pvInvertersProductIds - bind: Utils.path(systemPrefix, "/PvInvertersProductIds") - } - - VBusItem { - id: _batteryProductId - bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") - } - - VBusItem { - id: _vebusService - bind: Utils.path(systemPrefix, "/VebusService") - } - - QtObject { - id: _pvCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} - } - - ObjectAcConnection { - id: _pvOnAcOut - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") - } - - ObjectAcConnection { - id: _pvOnAcIn1 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") - } - - ObjectAcConnection { - id: _pvOnAcIn2 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") - } - - ObjectAcConnection { - id: _genset - bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") - } - - VBusItem { - id: _acSource - bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") - } - - ObjectAcConnection { - id: _grid - bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") - } - - ObjectAcConnection { - id: _acLoad - bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") - } - - ObjectAcConnection { - id: _acOutLoad - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") - } - - ObjectAcConnection { - id: _acInLoad - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") - } - - ObjectAcConnection { - id: _acUnknown - } - - QtObject { - id: _vebusDc - /* - * property VBusItem power: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Power"); unit: "W"} - * DONE: can interface doesn't support this yet! TODO use it...? - */ - property VBusItem current: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Current"); unit: "A"} - property VBusItem voltage: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Voltage"); unit: "V"} - property VBusItem power: VBusItem { - value: _vebusDc.current.valid && _vebusDc.voltage.valid ? - _vebusDc.current.value * _vebusDc.voltage.value : - undefined - unit: "W" - } - } - - QtObject { - id: _battery - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} - property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} - property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} - property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} - - // Get the battery charge state, see batteryState properties - property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} - } - - QtObject { - id: _dcSystem - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} - } -} diff --git a/FileSets/v2.73/MbEditBox.qml b/FileSets/v2.73/MbEditBox.qml deleted file mode 120000 index 8381b7d5..00000000 --- a/FileSets/v2.73/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v2.73/MbEditBoxDateTime.qml b/FileSets/v2.73/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v2.73/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.73/MbItem.qml b/FileSets/v2.73/MbItem.qml deleted file mode 120000 index 1280e190..00000000 --- a/FileSets/v2.73/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItem.qml \ No newline at end of file diff --git a/FileSets/v2.73/MbItemDigitalInput.qml b/FileSets/v2.73/MbItemDigitalInput.qml deleted file mode 120000 index 63943a08..00000000 --- a/FileSets/v2.73/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.73/MbStyle.qml b/FileSets/v2.73/MbStyle.qml deleted file mode 120000 index db6f181f..00000000 --- a/FileSets/v2.73/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v2.73/MbSubMenu.qml b/FileSets/v2.73/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v2.73/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.73/Multi.qml b/FileSets/v2.73/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v2.73/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.73/ObjectAcConnection.qml b/FileSets/v2.73/ObjectAcConnection.qml deleted file mode 100644 index 33265b1c..00000000 --- a/FileSets/v2.73/ObjectAcConnection.qml +++ /dev/null @@ -1,53 +0,0 @@ -////// modified to show voltage, current and frequency in flow overview -////// modified to show bar graphs -////// modified to use grid or genset meter if present - -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -QtObject { - property string bindPrefix - property string inverterService: "" - property string inverterSource: "" - - property VBusItem powerL1: VBusItem { bind: Utils.path(bindPrefix, "/L1/Power"); unit: "W"} - property VBusItem powerL2: VBusItem { bind: Utils.path(bindPrefix, "/L2/Power"); unit: "W"} - property VBusItem powerL3: VBusItem { bind: Utils.path(bindPrefix, "/L3/Power"); unit: "W"} - property VBusItem power: VBusItem { unit: "W" } - property VBusItem phaseCount: VBusItem { bind: Utils.path(bindPrefix, "/NumberOfPhases") } -////// added for compatibility with v2.80 changes - property bool splitPhaseL2PassthruDisabled: false - property bool isAcOutput: false - property bool l1AndL2OutShorted: splitPhaseL2PassthruDisabled && isAcOutput -////// added to show bar graphs - property VBusItem inverterState: VBusItem { bind: Utils.path(systemPrefix, "/SystemState/State" ) } - - ////// add to show voltage, current, frequency and bar graphs and use grid/genset meter - property VBusItem voltageL1: VBusItem { bind: Utils.path (bindPrefix, "/L1/Voltage"); unit: "V"} - property VBusItem voltageL2: VBusItem { bind: Utils.path (bindPrefix, "/L2/Voltage"); unit: "V"} - property VBusItem voltageL3: VBusItem { bind: Utils.path (bindPrefix, "/L3/Voltage"); unit: "V"} - - property VBusItem currentL1: VBusItem { bind: Utils.path (bindPrefix, "/L1/Current"); unit: "A"} - property VBusItem currentL2: VBusItem { bind: Utils.path (bindPrefix, "/L2/Current"); unit: "A"} - property VBusItem currentL3: VBusItem { bind: Utils.path (bindPrefix, "/L3/Current"); unit: "A"} - - property VBusItem frequency: VBusItem { bind: Utils.path (bindPrefix, "/Frequency"); unit: "Hz"} - - property VBusItem inCurrentLimit: VBusItem { bind: Utils.path(inverterService, inverterSource, "/CurrentLimit"); unit: "A"} - ////// end add to show voltage, current and frequency - - // As systemcalc doesn't provide the totals anymore we calculate it here. - // Timer is needed because the values are not received in once and then the total - // changes too often on system with more than one phase - property Timer timer: Timer { - interval: 1000 - running: true - repeat: true - onTriggered: { - power.value = powerL1.valid || powerL2.valid || powerL3.valid ? (powerL1.valid ? powerL1.value : 0) + - (powerL2.valid ? powerL2.value : 0) + - (powerL3.valid ? powerL3.value : 0) : undefined - } - } -} diff --git a/FileSets/v2.73/ObjectAcConnection.qml.orig b/FileSets/v2.73/ObjectAcConnection.qml.orig deleted file mode 100644 index 61299413..00000000 --- a/FileSets/v2.73/ObjectAcConnection.qml.orig +++ /dev/null @@ -1,26 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -QtObject { - property string bindPrefix - - property VBusItem powerL1: VBusItem { bind: Utils.path(bindPrefix, "/L1/Power"); unit: "W"} - property VBusItem powerL2: VBusItem { bind: Utils.path(bindPrefix, "/L2/Power"); unit: "W"} - property VBusItem powerL3: VBusItem { bind: Utils.path(bindPrefix, "/L3/Power"); unit: "W"} - property VBusItem phaseCount: VBusItem { bind: Utils.path(bindPrefix, "/NumberOfPhases") } - property VBusItem power: VBusItem { unit: "W" } - // As systemcalc doesn't provide the totals anymore we calculate it here. - // Timer is needed because the values are not received in once and then the total - // changes too often on system with more than one phase - property Timer timer: Timer { - interval: 1000 - running: true - repeat: true - onTriggered: { - power.value = powerL1.valid || powerL2.valid || powerL3.valid ? (powerL1.valid ? powerL1.value : 0) + - (powerL2.valid ? powerL2.value : 0) + - (powerL3.valid ? powerL3.value : 0) : undefined - } - } -} diff --git a/FileSets/v2.73/OverviewAcValuesEnhanced.qml b/FileSets/v2.73/OverviewAcValuesEnhanced.qml deleted file mode 100644 index f50eca37..00000000 --- a/FileSets/v2.73/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1,101 +0,0 @@ -////// modified to show voltage, current and frequency in flow overview -// only displays values for sys.acInput and sys.acLoad -// because other connections don't have related parameters -////// modified to show power bar graphs - - -import QtQuick 1.1 -import "enhancedFormat.js" as EnhFmt - -Item { - id: root - width: parent.width - height: parent.height - - // NOTE: data is taken by qml, hence it is called connection - property variant connection - - property int phaseCount: root.connection !== undefined && root.connection.phaseCount.valid ? root.connection.phaseCount.value : 0 - - Column { -////// modified to show power bar graphs - y: 6 - - width: parent.width - spacing: 0 - - // total power - TileText { - text: EnhFmt.formatVBusItem (root.connection.power) -////// modified to show power bar graphs - font.pixelSize: 19 - height: 21 - visible: phaseCount >= 1 - } - - // voltage for single leg - TileText { - text: EnhFmt.formatVBusItem (root.connection.voltageL1, "V") - visible: phaseCount === 1 - font.pixelSize: 15 - } - // current for single leg - TileText { - text: EnhFmt.formatVBusItem (root.connection.currentL1, "A") - font.pixelSize: 15 - visible: phaseCount === 1 - } - - // power, voltage and current for multiple legs - TileText { - text: "L1:" + EnhFmt.formatVBusItem (root.connection.powerL1, "W") - + " " + EnhFmt.formatVBusItem (root.connection.voltageL1, "V") - + " " + EnhFmt.formatVBusItem (root.connection.currentL1, "A") - visible: phaseCount >= 2 - font.pixelSize: 11 - } - // spacer to avoid connection dot - TileText { - text: "" - visible: phaseCount === 2 || phaseCount === 3 && root.height >= 90 - font.pixelSize: 8 - } - TileText { - text: "L2:" + EnhFmt.formatVBusItem (root.connection.powerL2, "W") - + " " + EnhFmt.formatVBusItem (root.connection.voltageL2, "V") - + " " + EnhFmt.formatVBusItem (root.connection.currentL2, "A") - visible: phaseCount >= 2 - font.pixelSize: 11 - } - TileText { - text: "L3:" + EnhFmt.formatVBusItem (root.connection.powerL3, "W") - + " " + EnhFmt.formatVBusItem (root.connection.voltageL3, "V") - + " " + EnhFmt.formatVBusItem (root.connection.currentL3, "A") - visible: phaseCount >= 3 - font.pixelSize: 11 - } - // spacer - TileText { - text: "" - visible: phaseCount === 2 && root.height >= 90 - font.pixelSize: 11 - } - TileText { - text: EnhFmt.formatVBusItem (root.connection.frequency, "Hz") - font.pixelSize: phaseCount >= 2 ? 11 : 15 - visible: phaseCount === 1 || root.connection != sys.acInput - } - TileText { - text: qsTr("Limit: ") + EnhFmt.formatVBusItem (root.connection.inCurrentLimit) - font.pixelSize: 15 - visible: phaseCount === 1 && root.connection == sys.acInput - } - // frequency and input current limit for multiple legs - TileText { - text: EnhFmt.formatVBusItem (root.connection.frequency, "Hz") - + " " + EnhFmt.formatVBusItem (root.connection.inCurrentLimit) - font.pixelSize: 11 - visible: phaseCount >= 2 && root.connection == sys.acInput - } - } -} diff --git a/FileSets/v2.73/OverviewAcValuesEnhanced.qml.orig b/FileSets/v2.73/OverviewAcValuesEnhanced.qml.orig deleted file mode 100644 index 7b90c518..00000000 --- a/FileSets/v2.73/OverviewAcValuesEnhanced.qml.orig +++ /dev/null @@ -1,37 +0,0 @@ -import QtQuick 1.1 - -Item { - id: root - width: parent.width - - // NOTE: data is taken by qml, hence it is called connection - property variant connection - - Column { - y: 0 - - width: parent.width - spacing: 0 - - TileText { - text: root.connection ? root.connection.power.format(0) : "" - font.pixelSize: 25 - height: 27 - } - - TileText { - text: root.connection ? "L1: " + root.connection.powerL1.format(0) : "" - visible: root.connection !== undefined && root.connection.phaseCount.valid && root.connection.phaseCount.value > 1 - } - - TileText { - text: root.connection ? "L2: " + root.connection.powerL2.format(0) : "" - visible: root.connection !== undefined && root.connection.phaseCount.valid && root.connection.phaseCount.value >= 2 - } - - TileText { - text: root.connection ? "L3: " + root.connection.powerL3.format(0) : "" - visible: root.connection !== undefined && root.connection.phaseCount.valid && root.connection.phaseCount.value >= 3 - } - } -} diff --git a/FileSets/v2.73/OverviewBox.qml b/FileSets/v2.73/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v2.73/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.73/OverviewConnection.qml b/FileSets/v2.73/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v2.73/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.73/OverviewConnectionEnd.qml b/FileSets/v2.73/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v2.73/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.73/OverviewFlowComplex.qml b/FileSets/v2.73/OverviewFlowComplex.qml deleted file mode 120000 index 6b747507..00000000 --- a/FileSets/v2.73/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v2.73/OverviewGeneratorEnhanced.qml b/FileSets/v2.73/OverviewGeneratorEnhanced.qml deleted file mode 120000 index b0670070..00000000 --- a/FileSets/v2.73/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.73/OverviewGeneratorRelayEnhanced.qml b/FileSets/v2.73/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index c6fa07f9..00000000 --- a/FileSets/v2.73/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.73/OverviewGridParallel.qml b/FileSets/v2.73/OverviewGridParallel.qml deleted file mode 120000 index cbf456ca..00000000 --- a/FileSets/v2.73/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v2.73/OverviewHub.qml b/FileSets/v2.73/OverviewHub.qml deleted file mode 100644 index cc4d7252..00000000 --- a/FileSets/v2.73/OverviewHub.qml +++ /dev/null @@ -1,322 +0,0 @@ -////// GuiMods — added DarkMode - -import QtQuick 1.1 -import "utils.js" as Utils - -OverviewPage { - id: root - -////// GuiMods — DarkMode - property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } - property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 - - property variant sys: theSystem - property bool hasAcSolarOnAcIn1: sys.pvOnAcIn1.power.valid - property bool hasAcSolarOnAcIn2: sys.pvOnAcIn2.power.valid - property bool hasAcSolarOnIn: hasAcSolarOnAcIn1 || hasAcSolarOnAcIn2 - property bool hasAcSolarOnOut: sys.pvOnAcOut.power.valid - property bool hasAcSolar: hasAcSolarOnIn || hasAcSolarOnOut - property bool hasDcSolar: sys.pvCharger.power.valid - property bool hasDcAndAcSolar: hasAcSolar && hasDcSolar - - title: qsTr("Overview") - - OverviewBox { - id: acInBox - - width: 148 - height: showStatusBar ? 100 : 120 - title: getAcSourceName(sys.acSource) -////// GuiMods — DarkMode - titleColor: !darkMode ? "#E74c3c" : "#73261E" - color: !darkMode ? "#C0392B" : "#601C15" - - anchors { - top: multi.top - left: parent.left; leftMargin: 10 - } - - values: OverviewAcValues { - connection: sys.acInput - } - - MbIcon { - iconId: getAcSourceIcon(sys.acSource) - anchors { - bottom: parent.bottom - left: parent.left; leftMargin: 2 - } - opacity: 0.5 - } - } - - Multi { - id: multi - anchors { - horizontalCenter: parent.horizontalCenter - top: parent.top; topMargin: 5 - } - } - - OverviewBox { - id: acLoadBox - title: qsTr("AC Loads") -////// GuiMods — DarkMode - color: !darkMode ? "#27AE60" : "#135730" - titleColor: !darkMode ? "#2ECC71" : "#176638" - width: 148 - height: showStatusBar ? 100 : 120 - - anchors { - right: parent.right; rightMargin: 10 - top: multi.top - } - - values: OverviewAcValues { - connection: sys.acLoad - } - } - - Battery { - id: battery - - soc: sys.battery.soc.valid ? sys.battery.soc.value : 0 - - anchors { - bottom: parent.bottom; bottomMargin: 5; - left: parent.left; leftMargin: 10 - } - values: Column { - width: parent.width - - TileText { - // Use value here instead of format() because format adds the unit to the number and we - // show the percentage symbol in a separated smaller text. - text: sys.battery.soc.value === undefined ? "--" : sys.battery.soc.value.toFixed(0) - font.pixelSize: 40 - - Text { - anchors { - bottom: parent.bottom; bottomMargin: 9 - horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: parent.paintedWidth / 2 + 5 - } - visible: sys.battery.soc.valid - text: "%" - color: "white" - font.bold: true - font.pixelSize: 12 - } - } - TileText { - text: sys.battery.power.format(0) - } - TileText { - text: sys.battery.voltage.format(1) + " " + sys.battery.current.format(1) - } - } - } - - VBusItem { - id: hasDcSys - bind: "com.victronenergy.settings/Settings/SystemSetup/HasDcSystem" - } - - OverviewBox { - id: dcSystemBox - width: 105 - height: 45 - visible: hasDcSys.value > 0 - title: qsTr("DC Power") - - anchors { - horizontalCenter: multi.horizontalCenter - bottom: parent.bottom; bottomMargin: 5 - } - - values: TileText { - anchors.centerIn: parent - text: sys.dcSystem.power.format(0) - } - } - - OverviewSolarCharger { - id: blueSolarCharger - - height: hasDcAndAcSolar ? 65 : 114 - width: 148 - title: qsTr("PV Charger") - showChargerIcon: !hasDcAndAcSolar - visible: hasDcSolar || hasDcAndAcSolar - - anchors { - right: root.right; rightMargin: 10 - bottom: root.bottom; bottomMargin: 5; - } - - values: TileText { - y: 5 - text: sys.pvCharger.power.format(0) - font.pixelSize: 20 - } - } - - OverviewSolarInverter { - id: pvInverter - height: hasDcAndAcSolar ? 65 : 115 - width: 148 - title: qsTr("PV Inverter") - showInverterIcon: !hasDcAndAcSolar - visible: hasAcSolar - - anchors { - right: root.right; rightMargin: 10; - bottom: root.bottom; bottomMargin: hasDcAndAcSolar ? 75 : 5 - } - - OverviewAcValues { - connection: hasAcSolarOnOut ? sys.pvOnAcOut : hasAcSolarOnAcIn1 ? sys.pvOnAcIn1 : sys.pvOnAcIn2 - visible: !coupledPvAc.visible - } - - TileText { - id: coupledPvAc - - property double pvInverterOnAcOut: sys.pvOnAcOut.power.valid ? sys.pvOnAcOut.power.value : 0 - property double pvInverterOnAcIn1: sys.pvOnAcIn1.power.valid ? sys.pvOnAcIn1.power.value : 0 - property double pvInverterOnAcIn2: sys.pvOnAcIn2.power.valid ? sys.pvOnAcIn2.power.value : 0 - - y: 5 - text: (pvInverterOnAcOut + pvInverterOnAcIn1 + pvInverterOnAcIn2).toFixed(0) + "W" - font.pixelSize: hasDcAndAcSolar ? 20 : 25 - visible: hasDcAndAcSolar || (hasAcSolarOnIn && hasAcSolarOnOut) || (hasAcSolarOnAcIn1 && hasAcSolarOnAcIn2) - } - } - - OverviewEssReason { - anchors { - bottom: parent.bottom; bottomMargin: dcSystemBox.visible ? battery.height + 15 : 5 - horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: dcSystemBox.visible ? -(root.width / 2 - battery.width / 2 - 10) : 0 - } - } - - OverviewConnection { - id: acInToMulti - ballCount: 2 - path: straight - active: root.active - value: flow(sys.acInput ? sys.acInput.power : 0) - - anchors { - left: acInBox.right; leftMargin: -10; top: multi.verticalCenter; - right: multi.left; rightMargin: -10; bottom: multi.verticalCenter - } - } - - OverviewConnection { - id: multiToAcLoads - ballCount: 2 - path: straight - active: root.active - value: flow(sys.acLoad.power) - - anchors { - left: multi.right; leftMargin: -10; - top: multi.verticalCenter - right: acLoadBox.left; rightMargin: -10 - bottom: multi.verticalCenter - } - } - - OverviewConnection { - id: pvInverterToMulti - - property int hasDcAndAcFlow: Utils.sign(noNoise(sys.pvOnAcOut.power) + noNoise(sys.pvOnAcIn1.power) + noNoise(sys.pvOnAcIn2.power)) - - ballCount: 4 - path: corner - active: root.active && hasAcSolar - value: hasDcAndAcSolar ? hasDcAndAcFlow : flow(sys.pvOnAcOut.power) - - anchors { - left: pvInverter.left; leftMargin: 8 - top: pvInverter.verticalCenter; topMargin: hasDcAndAcSolar ? 1 : 0 - right: multi.horizontalCenter; rightMargin: -20 - bottom: multi.bottom; bottomMargin: 10 - } - } - - // invisible anchor point to connect the chargers to the battery - Item { - id: dcConnect - anchors { - left: multi.horizontalCenter; leftMargin: hasAcSolar ? -20 : 0 - bottom: dcSystemBox.top; bottomMargin: 10 - } - } - - OverviewConnection { - id: multiToDcConnect - ballCount: 3 - path: straight - active: root.active - value: -flow(sys.vebusDc.power); - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: dcConnect.left - bottom: multi.bottom; bottomMargin: 10 - } - } - - OverviewConnection { - id: blueSolarChargerDcConnect - ballCount: 3 - path: straight - active: root.active && hasDcSolar - value: -flow(sys.pvCharger.power) - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: blueSolarCharger.left; rightMargin: -8 - bottom: dcConnect.top; - } - } - - OverviewConnection { - id: chargersToBattery - ballCount: 3 - path: straight - active: root.active - value: Utils.sign(noNoise(sys.pvCharger.power) + noNoise(sys.vebusDc.power)) - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: battery.right; rightMargin: 10 - bottom: dcConnect.top - } - } - - OverviewConnection { - id: batteryToDcSystem - ballCount: 2 - path: straight - active: root.active && hasDcSys.value > 0 - value: flow(sys.dcSystem.power) - - anchors { - left: battery.right; leftMargin: -10 - top: dcSystemBox.verticalCenter; - right: dcSystemBox.left; rightMargin: -10 - bottom: dcSystemBox.verticalCenter - } - } -} diff --git a/FileSets/v2.73/OverviewHub.qml.orig b/FileSets/v2.73/OverviewHub.qml.orig deleted file mode 100644 index d588aa94..00000000 --- a/FileSets/v2.73/OverviewHub.qml.orig +++ /dev/null @@ -1,314 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -OverviewPage { - id: root - - property variant sys: theSystem - property bool hasAcSolarOnAcIn1: sys.pvOnAcIn1.power.valid - property bool hasAcSolarOnAcIn2: sys.pvOnAcIn2.power.valid - property bool hasAcSolarOnIn: hasAcSolarOnAcIn1 || hasAcSolarOnAcIn2 - property bool hasAcSolarOnOut: sys.pvOnAcOut.power.valid - property bool hasAcSolar: hasAcSolarOnIn || hasAcSolarOnOut - property bool hasDcSolar: sys.pvCharger.power.valid - property bool hasDcAndAcSolar: hasAcSolar && hasDcSolar - - title: qsTr("Overview") - - OverviewBox { - id: acInBox - - width: 148 - height: showStatusBar ? 100 : 120 - title: getAcSourceName(sys.acSource) - titleColor: "#E74c3c" - color: "#C0392B" - - anchors { - top: multi.top - left: parent.left; leftMargin: 10 - } - - values: OverviewAcValues { - connection: sys.acInput - } - - MbIcon { - iconId: getAcSourceIcon(sys.acSource) - anchors { - bottom: parent.bottom - left: parent.left; leftMargin: 2 - } - opacity: 0.5 - } - } - - Multi { - id: multi - anchors { - horizontalCenter: parent.horizontalCenter - top: parent.top; topMargin: 5 - } - } - - OverviewBox { - id: acLoadBox - title: qsTr("AC Loads") - color: "#27AE60" - titleColor: "#2ECC71" - width: 148 - height: showStatusBar ? 100 : 120 - - anchors { - right: parent.right; rightMargin: 10 - top: multi.top - } - - values: OverviewAcValues { - connection: sys.acLoad - } - } - - Battery { - id: battery - - soc: sys.battery.soc.valid ? sys.battery.soc.value : 0 - - anchors { - bottom: parent.bottom; bottomMargin: 5; - left: parent.left; leftMargin: 10 - } - values: Column { - width: parent.width - - TileText { - // Use value here instead of format() because format adds the unit to the number and we - // show the percentage symbol in a separated smaller text. - text: sys.battery.soc.value === undefined ? "--" : sys.battery.soc.value.toFixed(0) - font.pixelSize: 40 - - Text { - anchors { - bottom: parent.bottom; bottomMargin: 9 - horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: parent.paintedWidth / 2 + 5 - } - visible: sys.battery.soc.valid - text: "%" - color: "white" - font.bold: true - font.pixelSize: 12 - } - } - TileText { - text: sys.battery.power.format(0) - } - TileText { - text: sys.battery.voltage.format(1) + " " + sys.battery.current.format(1) - } - } - } - - VBusItem { - id: hasDcSys - bind: "com.victronenergy.settings/Settings/SystemSetup/HasDcSystem" - } - - OverviewBox { - id: dcSystemBox - width: 105 - height: 45 - visible: hasDcSys.value > 0 - title: qsTr("DC Power") - - anchors { - horizontalCenter: multi.horizontalCenter - bottom: parent.bottom; bottomMargin: 5 - } - - values: TileText { - anchors.centerIn: parent - text: sys.dcSystem.power.format(0) - } - } - - OverviewSolarCharger { - id: blueSolarCharger - - height: hasDcAndAcSolar ? 65 : 114 - width: 148 - title: qsTr("PV Charger") - showChargerIcon: !hasDcAndAcSolar - visible: hasDcSolar || hasDcAndAcSolar - - anchors { - right: root.right; rightMargin: 10 - bottom: root.bottom; bottomMargin: 5; - } - - values: TileText { - y: 5 - text: sys.pvCharger.power.format(0) - font.pixelSize: 20 - } - } - - OverviewSolarInverter { - id: pvInverter - height: hasDcAndAcSolar ? 65 : 115 - width: 148 - title: qsTr("PV Inverter") - showInverterIcon: !hasDcAndAcSolar - visible: hasAcSolar - - anchors { - right: root.right; rightMargin: 10; - bottom: root.bottom; bottomMargin: hasDcAndAcSolar ? 75 : 5 - } - - OverviewAcValues { - connection: hasAcSolarOnOut ? sys.pvOnAcOut : hasAcSolarOnAcIn1 ? sys.pvOnAcIn1 : sys.pvOnAcIn2 - visible: !coupledPvAc.visible - } - - TileText { - id: coupledPvAc - - property double pvInverterOnAcOut: sys.pvOnAcOut.power.valid ? sys.pvOnAcOut.power.value : 0 - property double pvInverterOnAcIn1: sys.pvOnAcIn1.power.valid ? sys.pvOnAcIn1.power.value : 0 - property double pvInverterOnAcIn2: sys.pvOnAcIn2.power.valid ? sys.pvOnAcIn2.power.value : 0 - - y: 5 - text: (pvInverterOnAcOut + pvInverterOnAcIn1 + pvInverterOnAcIn2).toFixed(0) + "W" - font.pixelSize: hasDcAndAcSolar ? 20 : 25 - visible: hasDcAndAcSolar || (hasAcSolarOnIn && hasAcSolarOnOut) || (hasAcSolarOnAcIn1 && hasAcSolarOnAcIn2) - } - } - - OverviewEssReason { - anchors { - bottom: parent.bottom; bottomMargin: dcSystemBox.visible ? battery.height + 15 : 5 - horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: dcSystemBox.visible ? -(root.width / 2 - battery.width / 2 - 10) : 0 - } - } - - OverviewConnection { - id: acInToMulti - ballCount: 2 - path: straight - active: root.active - value: flow(sys.acInput ? sys.acInput.power : 0) - - anchors { - left: acInBox.right; leftMargin: -10; top: multi.verticalCenter; - right: multi.left; rightMargin: -10; bottom: multi.verticalCenter - } - } - - OverviewConnection { - id: multiToAcLoads - ballCount: 2 - path: straight - active: root.active - value: flow(sys.acLoad.power) - - anchors { - left: multi.right; leftMargin: -10; - top: multi.verticalCenter - right: acLoadBox.left; rightMargin: -10 - bottom: multi.verticalCenter - } - } - - OverviewConnection { - id: pvInverterToMulti - - property int hasDcAndAcFlow: Utils.sign(noNoise(sys.pvOnAcOut.power) + noNoise(sys.pvOnAcIn1.power) + noNoise(sys.pvOnAcIn2.power)) - - ballCount: 4 - path: corner - active: root.active && hasAcSolar - value: hasDcAndAcSolar ? hasDcAndAcFlow : flow(sys.pvOnAcOut.power) - - anchors { - left: pvInverter.left; leftMargin: 8 - top: pvInverter.verticalCenter; topMargin: hasDcAndAcSolar ? 1 : 0 - right: multi.horizontalCenter; rightMargin: -20 - bottom: multi.bottom; bottomMargin: 10 - } - } - - // invisible anchor point to connect the chargers to the battery - Item { - id: dcConnect - anchors { - left: multi.horizontalCenter; leftMargin: hasAcSolar ? -20 : 0 - bottom: dcSystemBox.top; bottomMargin: 10 - } - } - - OverviewConnection { - id: multiToDcConnect - ballCount: 3 - path: straight - active: root.active - value: -flow(sys.vebusDc.power); - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: dcConnect.left - bottom: multi.bottom; bottomMargin: 10 - } - } - - OverviewConnection { - id: blueSolarChargerDcConnect - ballCount: 3 - path: straight - active: root.active && hasDcSolar - value: -flow(sys.pvCharger.power) - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: blueSolarCharger.left; rightMargin: -8 - bottom: dcConnect.top; - } - } - - OverviewConnection { - id: chargersToBattery - ballCount: 3 - path: straight - active: root.active - value: Utils.sign(noNoise(sys.pvCharger.power) + noNoise(sys.vebusDc.power)) - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: battery.right; rightMargin: 10 - bottom: dcConnect.top - } - } - - OverviewConnection { - id: batteryToDcSystem - ballCount: 2 - path: straight - active: root.active && hasDcSys.value > 0 - value: flow(sys.dcSystem.power) - - anchors { - left: battery.right; leftMargin: -10 - top: dcSystemBox.verticalCenter; - right: dcSystemBox.left; rightMargin: -10 - bottom: dcSystemBox.verticalCenter - } - } -} diff --git a/FileSets/v2.73/OverviewHubEnhanced.qml b/FileSets/v2.73/OverviewHubEnhanced.qml deleted file mode 100644 index b60710af..00000000 --- a/FileSets/v2.73/OverviewHubEnhanced.qml +++ /dev/null @@ -1,1449 +0,0 @@ -////// MODIFIED to show: -////// tanks in a row along bottom -////// PV voltage and current and DC power current (up to 2 MPPTs with tanks and temps or 3 without) -////// PV inverter power (up to 2 with tanks and temps or 3 without) -////// voltage, current, frequency in AC tiles (plus current limit for AC input) -////// time of day -////// current in DC Loads -////// remaining time in Battery tile -////// bar graphs on AC in/out and Multi -////// detail pages for all tiles -////// bar gauge on PV Charger tile -////// add support for VE.Direct inverters - -import QtQuick 1.1 -import "utils.js" as Utils -////// ADDED to show tanks -import com.victron.velib 1.0 -import "timeToGo.js" as TTG -import "enhancedFormat.js" as EnhFmt - -OverviewPage { - id: root - - property variant sys: theSystem - - property string systemPrefix: "com.victronenergy.system" - property string guiModsPrefix: "com.victronenergy.settings/Settings/GuiMods" - VBusItem { id: vebusService; bind: Utils.path(systemPrefix, "/VebusService") } - property bool isMulti: vebusService.valid - property string veDirectInverterService: "" - property string inverterService: vebusService.valid ? vebusService.value : veDirectInverterService - - VBusItem { id: replaceAcInItem; bind: Utils.path(guiModsPrefix, "/ReplaceInactiveAcIn") } - property bool hasAlternator: sys.alternator.power.valid - property bool replaceAcIn: replaceAcInItem.valid && replaceAcInItem.value == 1 && hasAlternator && (sys.acSource == 0 || sys.acSource == 240) - property bool showAcInput: ((isMulti || sys.acInput.power.valid) && ! replaceAcIn) || showAllTiles - property bool showAlternator: !showAcInput && hasAlternator - property double alternatorFlow: showAlternator ? noNoise (sys.alternator.power) : 0 - property bool showAcLoads: isMulti || sys.acLoad.power.valid || veDirectInverterService != "" - property bool showDcSystem: (hasDcSystemItem.valid && hasDcSystemItem.value > 0) || showAllTiles - property bool hasInverter: false - property bool showInverter: hasInverter || inverterService != "" || showAllTiles - - property bool hasAcSolarOnAcIn1: sys.pvOnAcIn1.power.valid - property bool hasAcSolarOnAcIn2: sys.pvOnAcIn2.power.valid - property bool hasAcSolarOnIn: hasAcSolarOnAcIn1 || hasAcSolarOnAcIn2 - property bool hasAcSolarOnOut: sys.pvOnAcOut.power.valid - property bool hasAcSolar: hasAcSolarOnIn || hasAcSolarOnOut - property bool hasDcSolar: sys.pvCharger.power.valid - property bool hasDcAndAcSolar: hasAcSolar && hasDcSolar - property bool showDcAndAcSolar: hasDcAndAcSolar || showAllTiles - property bool showDcSolar: hasDcSolar || showAllTiles - property bool showAcSolar: hasAcSolar || showAllTiles -////// ADDED to show tanks - property int bottomOffset: 45 - property string settingsBindPreffix: "com.victronenergy.settings" - property string pumpBindPreffix: "com.victronenergy.pump.startstop0" - property int numberOfTanks: 0 - property int numberOfTemps: 0 -//////// added/modified for control show/hide gauges, tanks and temps from menus - property int tankCount: showTanksEnable ? tankModel.rowCount : 0 - property int tempCount: showTempsEnable ? numberOfTemps : 0 - property int tankTempCount: tankCount + tempCount - property bool showTanks: showTanksEnable ? showStatusBar ? false : tankCount > 0 ? true : false : false - property bool showTemps: showTempsEnable ? showStatusBar ? false : tempCount > 0 ? true : false : false - property bool showTanksTemps: showTanks || showTemps - property int compactThreshold: 45 // height below this will be compacted vertically - property int batteryHeight: 91 - property bool compact: showTanks && showTemps && tankTempCount > 4 - property int tanksHeight: compact ? 22 : 45 - -//////// add for PV CHARGER voltage and current - property string pvChargerPrefix1: "" - property string pvChargerPrefix2: "" - property string pvChargerPrefix3: "" - property string pvChargerPrefix4: "" - property string pvChargerPrefix5: "" - property string pvChargerPrefix6: "" - property string pvChargerPrefix7: "" - property int numberOfPvChargers: 0 - property int pvChargerRows: showTanksTemps ? 4 : 7 - property int pvRowsPerCharger: Math.max ( 1, Math.min (pvChargerRows / numberOfPvChargers, 3)) - property bool pvChargerCompact: pvRowsPerCharger < 3 ? true : false - property bool pvShowDetails: pvRowsPerCharger >= 2 ? true : false - -//////// add for PV INVERTER power - property string pvInverterPrefix1: "" - property string pvInverterPrefix2: "" - property string pvInverterPrefix3: "" - property int numberOfPvInverters: 0 - -//////// add for alternator - alternator replaces AC in if AC in is not present - property string alternatorPrefix1: "" - property string alternatorPrefix2: "" - property int numberOfAlternators: 0 - VBusItem { id: alternatorName1; bind: Utils.path(alternatorPrefix1, "/CustomName") } - VBusItem { id: alternatorPower1; bind: Utils.path(alternatorPrefix1, "/Dc/0/Power") } - VBusItem { id: alternatorVoltage1; bind: Utils.path(alternatorPrefix1, "/Dc/0/Voltage") } - VBusItem { id: alternatorCurrent1; bind: Utils.path(alternatorPrefix1, "/Dc/0/Current") } - VBusItem { id: alternatorName2; bind: Utils.path(alternatorPrefix2, "/CustomName") } - VBusItem { id: alternatorPower2; bind: Utils.path(alternatorPrefix2, "/Dc/0/Power") } - -//////// added for control show/hide gauges, tanks and temps from menus - VBusItem { id: showGaugesItem; bind: Utils.path(guiModsPrefix, "/ShowGauges") } - property bool showGauges: showGaugesItem.valid ? showGaugesItem.value === 1 ? true : false : false - VBusItem { id: showTanksItem; bind: Utils.path(guiModsPrefix, "/ShowEnhancedFlowOverviewTanks") } - property bool showTanksEnable: showTanksItem.valid ? showTanksItem.value === 1 ? true : false : false - VBusItem { id: showTempsItem; bind: Utils.path(guiModsPrefix, "/ShowEnhancedFlowOverviewTemps") } - property bool showTempsEnable: showTempsItem.valid ? showTempsItem.value === 1 ? true : false : false - -//////// added to show/dim tiles - VBusItem { id: showInactiveTilesItem; bind: Utils.path(guiModsPrefix, "/ShowInactiveFlowTiles") } - property real disabledTileOpacity: (showInactiveTiles && showInactiveTilesItem.value === 1) ? 0.3 : 1 - property bool showInactiveTiles: showInactiveTilesItem.valid && showInactiveTilesItem.value >= 1 - - VBusItem { id: showBatteryTempItem; bind: Utils.path(guiModsPrefix, "/ShowBatteryTempOnFlows") } - property bool showBatteryTemp: showBatteryTempItem.valid && showBatteryTempItem.value == 1 - - // for debug, ignore validity checks so all tiles and their flow lines will show - property bool showAllTiles: showInactiveTilesItem.valid && showInactiveTilesItem.value == 3 - -//////// added to control time display - VBusItem { id: timeFormatItem; bind: Utils.path(guiModsPrefix, "/TimeFormat") } - property string timeFormat: getTimeFormat () - - function getTimeFormat () - { - if (!timeFormatItem.valid || timeFormatItem.value === 0) - return "" - else if (timeFormatItem.value === 2) - return "h:mm ap" - else - return "hh:mm" - } - -//////// add to display individual PV charger power - VBusItem { id: pvName1; bind: Utils.path(pvChargerPrefix1, "/CustomName") } - VBusItem { id: pvPower1; bind: Utils.path(pvChargerPrefix1, "/Yield/Power") } - VBusItem { id: pvVoltage1; bind: Utils.path(pvChargerPrefix1, "/Pv/V") } - VBusItem { id: pvCurrent1; bind: Utils.path(pvChargerPrefix1, "/Pv/I") } - VBusItem { id: pv1NrTrackers; bind: Utils.path(pvChargerPrefix1, "/NrOfTrackers") } - VBusItem { id: pvName2; bind: Utils.path(pvChargerPrefix2, "/CustomName") } - VBusItem { id: pvPower2; bind: Utils.path(pvChargerPrefix2, "/Yield/Power") } - VBusItem { id: pvVoltage2; bind: Utils.path(pvChargerPrefix2, "/Pv/V") } - VBusItem { id: pvCurrent2; bind: Utils.path(pvChargerPrefix2, "/Pv/I") } - VBusItem { id: pv2NrTrackers; bind: Utils.path(pvChargerPrefix2, "/NrOfTrackers") } - VBusItem { id: pvName3; bind: Utils.path(pvChargerPrefix3, "/CustomName") } - VBusItem { id: pvPower3; bind: Utils.path(pvChargerPrefix3, "/Yield/Power") } - VBusItem { id: pvVoltage3; bind: Utils.path(pvChargerPrefix3, "/Pv/V") } - VBusItem { id: pvCurrent3; bind: Utils.path(pvChargerPrefix3, "/Pv/I") } - VBusItem { id: pv3NrTrackers; bind: Utils.path(pvChargerPrefix3, "/NrOfTrackers") } - VBusItem { id: pvName4; bind: Utils.path(pvChargerPrefix4, "/CustomName") } - VBusItem { id: pvPower4; bind: Utils.path(pvChargerPrefix4, "/Yield/Power") } - VBusItem { id: pvName5; bind: Utils.path(pvChargerPrefix5, "/CustomName") } - VBusItem { id: pvPower5; bind: Utils.path(pvChargerPrefix5, "/Yield/Power") } - VBusItem { id: pvName6; bind: Utils.path(pvChargerPrefix6, "/CustomName") } - VBusItem { id: pvPower6; bind: Utils.path(pvChargerPrefix6, "/Yield/Power") } - VBusItem { id: pvName7; bind: Utils.path(pvChargerPrefix7, "/CustomName") } - VBusItem { id: pvPower7; bind: Utils.path(pvChargerPrefix7, "/Yield/Power") } - - VBusItem { id: timeToGo; bind: Utils.path("com.victronenergy.system","/Dc/Battery/TimeToGo") } - -//////// add to display PV Inverter power - VBusItem { id: pvInverterPower1; bind: Utils.path(pvInverterPrefix1, "/Ac/Power") } - VBusItem { id: pvInverterL1Power1; bind: Utils.path(pvInverterPrefix1, "/Ac/L1/Power") } - VBusItem { id: pvInverterL2Power1; bind: Utils.path(pvInverterPrefix1, "/Ac/L2/Power") } - VBusItem { id: pvInverterL3Power1; bind: Utils.path(pvInverterPrefix1, "/Ac/L3/Power") } - VBusItem { id: pvInverterName1; bind: Utils.path(pvInverterPrefix1, "/CustomName") } - VBusItem { id: pvInverterPower2; bind: Utils.path(pvInverterPrefix2, "/Ac/Power") } - VBusItem { id: pvInverterName2; bind: Utils.path(pvInverterPrefix2, "/CustomName") } - VBusItem { id: pvInverterPower3; bind: Utils.path(pvInverterPrefix3, "/Ac/Power") } - VBusItem { id: pvInverterName3; bind: Utils.path(pvInverterPrefix3, "/CustomName") } - -//////// add to display AC input ignored - VBusItem { id: ignoreAcInput1; bind: Utils.path(inverterService, "/Ac/State/IgnoreAcIn1") } - VBusItem { id: ignoreAcInput2; bind: Utils.path(inverterService, "/Ac/State/IgnoreAcIn2") } - VBusItem { id: acActiveInput; bind: Utils.path(inverterService, "/Ac/ActiveIn/ActiveInput") } - - VBusItem { id: hasDcSystemItem; bind: "com.victronenergy.settings/Settings/SystemSetup/HasDcSystem" } - - //Component.onCompleted: { discoverServices(); showHelp () } - onActiveChanged: - { - if (root.active) - { - discoverServices() - showHelp () - } - } - - title: qsTr("Simple Overview") - - OverviewBox { - id: acInBox - titleColor: "#E74c3c" - color: "#C0392B" - opacity: showAcInput ? 1 : disabledTileOpacity - visible: showAcInput || showInactiveTiles - width: 148 - height: showStatusBar ? 100 : 120 - title: - { - // input 1 is active - if (acActiveInput.value == 0) - { - if (ignoreAcInput1.valid && ignoreAcInput1.value == 1) - return qsTr ("AC In 1 Ignored") - else - return getAcSourceName(sys.acSource) - } - // input 2 is active - else if (acActiveInput.value == 1) - { - if (ignoreAcInput2.valid && ignoreAcInput2.value == 1) - return qsTr ("AC In 2 Ignored") - else - return getAcSourceName(sys.acSource) - } - else - return "no input" - } - anchors { - top: multi.top - left: parent.left; leftMargin: 10 - } - - values: OverviewAcValuesEnhanced { - connection: sys.acInput - } - - MbIcon { - iconId: getAcSourceIcon(sys.acSource) - anchors { - bottom: parent.bottom - left: parent.left; leftMargin: 2 - } - opacity: 0.5 - } -////// add power bar graph - PowerGauge - { - id: acInBar - width: parent.width - height: 12 - anchors - { - top: parent.top; topMargin: 16 - horizontalCenter: parent.horizontalCenter - } - connection: sys.acInput - useInputCurrentLimit: true - maxForwardPowerParameter: "" - maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxFeedInPower" - show: showGauges && showAcInput - } - DetailTarget { id: acInputTarget; detailsPage: "DetailAcInput.qml" } - } - - //// add alternator if AC input not present - OverviewBox { - id: alternatorBox - title: qsTr ("Alternator") - color: "#157894" - titleColor: "#419FB9" - opacity: showAlternator ? 1 : disabledTileOpacity - visible: showAlternator || showInactiveTiles && ! acInBox.visible - width: 148 - height: showStatusBar ? 100 : 120 - anchors.fill: acInBox - values: Column - { - width: parent.width - TileText - { - text: " " - font.pixelSize: 6 - } - TileText - { - text: EnhFmt.formatVBusItem (sys.alternator.power, "W") - font.pixelSize: 19 - } - TileText - { - text: alternatorName1.valid ? alternatorName1.value : "-" - visible: showAlternator && numberOfAlternators >= 1 - } - TileText - { - text: EnhFmt.formatVBusItem (alternatorPower1, "W") - font.pixelSize: 15 - visible: showAlternator && numberOfAlternators > 1 - } - TileText { - text: EnhFmt.formatVBusItem (alternatorVoltage1, "V") - font.pixelSize: 15 - visible: showAlternator && numberOfAlternators == 1 - } - TileText { - text: EnhFmt.formatVBusItem (alternatorCurrent1, "A") - font.pixelSize: 15 - visible: showAlternator && numberOfAlternators == 1 - } - TileText - { - text: alternatorName2.valid ? alternatorName2.value : "-" - visible: showAlternator && numberOfAlternators >= 2 - } - TileText - { - text: EnhFmt.formatVBusItem (alternatorPower1, "W") - font.pixelSize: 15 - visible: showAlternator && numberOfAlternators >= 2 - } - } - - PowerGauge - { - id: alternatorBar - width: parent.width - height: 12 - anchors - { - top: parent.top; topMargin: 16 - horizontalCenter: parent.horizontalCenter - } - connection: sys.alternator - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxAlternatorPower" - visible: showGauges && showAlternator - } - DetailTarget { id: alternatorTarget; detailsPage: "DetailAlternator.qml" } - } - - MultiEnhanced { - id: multi - anchors { - horizontalCenter: parent.horizontalCenter - top: parent.top; topMargin: 3 - } - inverterService: root.inverterService - opacity: showInverter ? 1 : disabledTileOpacity - visible: showInverter || showInactiveTiles -////// add power bar graph - PowerGaugeMulti - { - id: multiBar - width: multi.width - height: 12 - anchors - { - top: parent.top; topMargin: 23 - horizontalCenter: parent.horizontalCenter - } - inverterService: root.inverterService - visible: showGauges && showInverter - } - DetailTarget { id: multiTarget; detailsPage: "DetailInverter.qml"; width: 60; height: 60 } - } - -////// ADDED to show time inside inverter icon - Timer { - id: wallClock - running: timeFormat != "" - repeat: true - interval: 1000 - triggeredOnStart: true - onTriggered: time = Qt.formatDateTime(new Date(), timeFormat) - property string time - } - TileText - { - text: wallClock.time - font.pixelSize: 18 - color: showInverter || darkMode ? "white" : "black" - anchors - { - top: multi.top; topMargin: 96 - horizontalCenter: multi.horizontalCenter - } - show: wallClock.running - } - - OverviewBox { - id: acLoadBox - visible: showAcLoads || showInactiveTiles - opacity: showAcLoads ? 1 : disabledTileOpacity - title: qsTr("AC Loads") - color: "#27AE60" - titleColor: "#2ECC71" - width: 148 - height: showStatusBar ? 80 : 102 - - anchors { - right: parent.right; rightMargin: 10 - top: multi.top - } - - values: OverviewAcValuesEnhanced { - connection: sys.acLoad - } -////// add power bar graph - PowerGauge - { - id: acLoadBar - width: parent.width - height: 12 - anchors - { - top: parent.top; topMargin: 16 - horizontalCenter: parent.horizontalCenter - } - connection: sys.acLoad - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputMaxPower" - show: showGauges && showAcLoads - } - DetailTarget { id: loadsOnOutputTarget; detailsPage: "DetailLoadsCombined.qml" } - } - - Battery { - id: battery - width: acInBox.width - soc: sys.battery.soc.valid ? sys.battery.soc.value : 0 -////// add battery current bar graph - PowerGaugeBattery - { - id: batteryBar - width: parent.width - height: 10 - anchors - { - top: parent.top; topMargin: 52 - horizontalCenter: parent.horizontalCenter - } - show: showGauges - } - -////// MODIFIED to show tanks - height: batteryHeight + 5 - anchors { - bottom: parent.bottom; bottomMargin: showTanksTemps ? bottomOffset + 3 : 5; - left: parent.left; leftMargin: 10 - } - values: Column { - width: parent.width - - TileText { - text: sys.battery.soc.value === undefined ? "--" : sys.battery.soc.format (0) - font.pixelSize: 25 - } - TileText { - text: sys.battery.power.format(0) - } - TileText { - text: " " - font.pixelSize: 6 - } - TileText { - text: EnhFmt.formatVBusItem (sys.battery.voltage, "V ", 2) - + EnhFmt.formatVBusItem (sys.battery.current, "A") - } - TileText { - text: timeToGo.valid ? qsTr ("Remain: ") + TTG.formatTimeToGo (timeToGo) : qsTr (" ") - } - } - DetailTarget { id: batteryTarget; detailsPage: "DetailBattery.qml" } - } - - VBusItem { id: dcSystemNameItem; bind: Utils.path(settingsBindPreffix, "/Settings/GuiMods/CustomDcSystemName") } - - OverviewBox { - id: dcSystemBox -////// wider to make room for current - width: multi.width + 20 - height: 45 - opacity: showDcSystem ? 1 : disabledTileOpacity - visible: showDcSystem || showInactiveTiles - title: dcSystemNameItem.valid && dcSystemNameItem.value != "" ? dcSystemNameItem.value : qsTr ("DC System") - - anchors { - horizontalCenter: multi.horizontalCenter - horizontalCenterOffset: 2 -////// MODIFIED to show tanks - bottom: parent.bottom; bottomMargin: showTanksTemps ? bottomOffset + 3 : 5 - } - - values: - [ - TileText - { - width: parent.width - anchors - { - horizontalCenter: parent.horizontalCenter - bottom: parent.bottom; bottomMargin: 0 - } - ////// modified to show current - text: - { - if (showDcSystem) - { - var current = "" - if (sys.dcSystem.power.valid && sys.battery.voltage.valid) - current = " " + EnhFmt.formatValue (sys.dcSystem.power.value / sys.battery.voltage.value, "A") - return EnhFmt.formatVBusItem (sys.dcSystem.power) + current - } - else - return "--" - } - } - ] - PowerGauge - { - id: dcSystemGauge - width: parent.width - height: 8 - anchors - { - top: parent.top; topMargin: 19 - left: parent.left; leftMargin: 18 - right: parent.right - } - connection: sys.dcSystem - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/DcSystemMaxLoad" - maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/DcSystemMaxCharge" - showLabels: true - show: showGauges && showDcSystem - - } - DetailTarget { id: dcSystemTarget; detailsPage: "DetailDcSystem.qml" } - } - - property int pvOffset1: 27 - property int pvRowSpacing: 16 - property int pvOffset2: pvOffset1 + pvRowSpacing * pvRowsPerCharger - property int pvOffset3: pvOffset2 + pvRowSpacing * pvRowsPerCharger - property int pvOffset4: pvOffset3 + pvRowSpacing * pvRowsPerCharger - property int pvOffset5: pvOffset4 + pvRowSpacing * pvRowsPerCharger - property int pvOffset6: pvOffset5 + pvRowSpacing * pvRowsPerCharger - property int pvOffset7: pvOffset6 + pvRowSpacing * pvRowsPerCharger - -////// replaced OverviewSolarCharger with OverviewBox - OverviewBox { - id: pvChargerBox - title: qsTr("PV Charger") - titleColor: "#F4B350" - color: "#F39C12" - visible: hasDcSolar || showInactiveTiles - opacity: hasDcSolar ? 1 : disabledTileOpacity - -////// MODIFIED to show tanks & provide extra space if not - height: - { - var availableHeight = root.height - 3 - acLoadBox.height - 5 - (showTanksTemps ? bottomOffset + 3 : 5) - if (showDcAndAcSolar) - return ((availableHeight - 5) / 2) + 4 - else if (showDcSolar) - return availableHeight - else - return 0 - } - width: 148 - - anchors { - right: root.right; rightMargin: 10 - bottom: parent.bottom; bottomMargin: showTanksTemps ? bottomOffset + 3 : 5 - } - -////// moved sun icon here from OverviewSolarChager so it can be put below text, etc - MbIcon { - iconId: "overview-sun" - anchors { - bottom: parent.bottom - right: parent.right; rightMargin: 2 - } - opacity: 0.5 - visible: ! showDcAndAcSolar - } - -//////// modified to add power for individual PV charger info - values: - [ - TileText { - y: 8 - text: EnhFmt.formatVBusItem (sys.pvCharger.power) - font.pixelSize: 19 - }, - MarqueeEnhanced - { - y: pvOffset1 - id: pv1Name - // ofset left margin for this row if showing tanks/temps - width: - { - if (pvChargerCompact) - { - if (showTanksTemps) - return ((parent.width / 2) - 15) - else - return ((parent.width / 2) - 5) - } - else - return (parent.width - 10) - } - anchors.left: parent.left; anchors.leftMargin: (showTanksTemps && pvChargerCompact) ? 15 : 5 - height: 15 - text: pvName1.valid ? pvName1.value : "pv 1" - textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter - fontSize: 15 - Connections { target: scrollTimer; onTriggered: pv1Name.doScroll() } - scroll: false - visible: numberOfPvChargers >= 1 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset1 + (pvChargerCompact ? 0 : pvRowSpacing) - text: EnhFmt.formatVBusItem (pvPower1, "W") - horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter - anchors.right: parent.right; anchors.rightMargin: 5 - font.pixelSize: 15 - visible: numberOfPvChargers >= 1 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset1 + pvRowSpacing * (pvChargerCompact ? 1 : 2) - text: - { - var voltageText, currentText - if (root.numberOfPvChargers < 1) - return " " - else - { - if (pv1NrTrackers.valid && pv1NrTrackers.value > 1) - return qsTr ("multiple trackers") - else if (pvVoltage1.valid) - voltageText = EnhFmt.formatVBusItem (pvVoltage1, "V") - else - voltageText = "??V" - if (pvCurrent1.valid) - currentText = EnhFmt.formatVBusItem (pvCurrent1, "A") - else if (pvPower1.valid) - currentText = EnhFmt.formatValue ((pvPower1.value / pvVoltage1.value), "A") - else - currentText = "??A" - return voltageText + " " + currentText - } - } - font.pixelSize: 15 - visible: pvShowDetails && numberOfPvChargers >= 1 - }, - MarqueeEnhanced - { - y: pvOffset2 - id: pv2Name - width: pvChargerCompact ? ((parent.width / 2) - 5) : parent.width - 10 - anchors.left: parent.left; anchors.leftMargin: 5 - height: 15 - text: pvName2.valid ? pvName2.value : "pv 2" - textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter - fontSize: 15 - Connections { target: scrollTimer; onTriggered: pv2Name.doScroll() } - scroll: false - visible: numberOfPvChargers >= 2 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset2 + (pvChargerCompact ? 0 : pvRowSpacing) - text: EnhFmt.formatVBusItem (pvPower2, "W") - horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter - anchors.right: parent.right; anchors.rightMargin: 5 - font.pixelSize: 15 - visible: numberOfPvChargers >= 2 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset2 + pvRowSpacing * (pvChargerCompact ? 1 : 2) - text: - { - var voltageText, currentText - if (root.numberOfPvChargers < 2) - return " " - else - { - if (pv2NrTrackers.valid && pv2NrTrackers.value > 1) - return qsTr ("multiple trackers") - else if (pvVoltage2.valid) - voltageText = EnhFmt.formatVBusItem (pvVoltage2, "V") - else - voltageText = "??V" - if (pvCurrent2.valid) - currentText = EnhFmt.formatVBusItem (pvCurrent2, "A") - else if (pvPower2.valid) - currentText = EnhFmt.formatValue ((pvPower2.value / pvVoltage2.value), "A") - else - currentText = "??A" - return voltageText + " " + currentText - } - } - font.pixelSize: 15 - visible: pvShowDetails && numberOfPvChargers >= 2 - }, - MarqueeEnhanced - { - y: pvOffset4 - id: pv4Name - // ofset left margin for this row if NOT showing tanks/temps - width: - { - if (pvChargerCompact) - { - if (! showTanksTemps) - return ((parent.width / 2) - 15) - else - return ((parent.width / 2) - 5) - } - else - return (parent.width - 10) - } - anchors.left: parent.left; anchors.leftMargin: ( ! showTanksTemps && pvChargerCompact) ? 15 : 5 - height: 15 - text: pvName4.valid ? pvName4.value : "pv 4" - textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter - fontSize: 15 - Connections { target: scrollTimer; onTriggered: pv4Name.doScroll() } - scroll: false - visible: numberOfPvChargers >= 4 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset4 + (pvChargerCompact ? 0 : pvRowSpacing) - text: EnhFmt.formatVBusItem (pvPower4, "W") - anchors.right: parent.right; anchors.rightMargin: 5 - horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter - font.pixelSize: 15 - visible: numberOfPvChargers >= 4 && ! showDcAndAcSolar - }, - MarqueeEnhanced - { - y: pvOffset5 - id: pv5Name - width: pvChargerCompact ? ((parent.width / 2) - 5) : parent.width - 10 - anchors.left: parent.left; anchors.leftMargin: 5 - height: 15 - text: pvName5.valid ? pvName5.value : "pv 5" - textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter - fontSize: 15 - Connections { target: scrollTimer; onTriggered: pv5Name.doScroll() } - scroll: false - visible: numberOfPvChargers >= 5 && pvChargerRows >= 5 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset5 + (pvChargerCompact ? 0 : pvRowSpacing) - text: EnhFmt.formatVBusItem (pvPower5, "W") - anchors.right: parent.right; anchors.rightMargin: 5 - horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter - font.pixelSize: 15 - visible: numberOfPvChargers >= 5 && pvChargerRows >= 5 && ! showDcAndAcSolar - }, - MarqueeEnhanced - { - y: pvOffset6 - id: pv6Name - width: pvChargerCompact ? ((parent.width / 2) - 5) : parent.width - 10 - anchors.left: parent.left; anchors.leftMargin: 5 - height: 15 - text: pvName6.valid ? pvName6.value : "pv 6" - textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter - fontSize: 15 - Connections { target: scrollTimer; onTriggered: pv6Name.doScroll() } - scroll: false - visible: numberOfPvChargers >= 6 && pvChargerRows >= 6 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset6 + (pvChargerCompact ? 0 : pvRowSpacing) - text: EnhFmt.formatVBusItem (pvPower6, "W") - anchors.right: parent.right; anchors.rightMargin: 5 - horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter - font.pixelSize: 15 - visible: numberOfPvChargers >= 6 && pvChargerRows >= 6 && ! showDcAndAcSolar - }, - MarqueeEnhanced - { - y: pvOffset7 - id: pv7Name - width: pvChargerCompact ? ((parent.width / 2) - 5) : parent.width - 10 - anchors.left: parent.left; anchors.leftMargin: 5 - height: 15 - text: pvName7.valid ? pvName7.value : "pv 7" - textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter - fontSize: 15 - Connections { target: scrollTimer; onTriggered: pv6Name.doScroll() } - scroll: false - visible: numberOfPvChargers >= 7 && pvChargerRows >= 7 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset7 + (pvChargerCompact ? 0 : pvRowSpacing) - text: EnhFmt.formatVBusItem (pvPower7, "W") - anchors.right: parent.right; anchors.rightMargin: 5 - horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter - font.pixelSize: 15 - visible: numberOfPvChargers >= 7 && pvChargerRows >= 7 && ! showDcAndAcSolar - } - ] -////// add power bar graph - PowerGauge - { - id: pvChargerBar - width: parent.width - (showDcAndAcSolar && ! showTanksTemps ? 20 : 0) - height: 10 - anchors - { - top: parent.top; topMargin: 19 - right: parent.right; rightMargin: 0.5 - } - connection: sys.pvCharger - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvChargerMaxPower" - show: showGauges && showDcSolar - } - DetailTarget { id: pvChargerTarget; detailsPage: "DetailPvCharger.qml" } - } - -////// replaced OverviewSolarInverter with OverviewBox - OverviewBox { - id: pvInverter - title: qsTr("PV Inverter") - titleColor: "#F4B350" - color: "#F39C12" - visible: hasAcSolar || showInactiveTiles - opacity: hasAcSolar ? 1 : disabledTileOpacity - -////// MODIFIED to show tanks & provide extra space if not - height: - { - var availableHeight = root.height - 3 - acLoadBox.height -5 - availableHeight -= (showTanksTemps ? bottomOffset + 3 : 5) - if (showDcAndAcSolar) - availableHeight -= pvChargerBox.height + 5 - if (showAcSolar) - return availableHeight - else - return 0 - } - width: 148 - - anchors { - right: root.right; rightMargin: 10; - bottom: showDcAndAcSolar ? pvChargerBox.top : root.bottom - bottomMargin: showDcAndAcSolar ? 5 : showTanksTemps ? bottomOffset + 3 : 5 - } - - values: - [ - TileText { - id: coupledPvAc - - property double pvInverterOnAcOut: sys.pvOnAcOut.power.valid ? sys.pvOnAcOut.power.value : 0 - property double pvInverterOnAcIn1: sys.pvOnAcIn1.power.valid ? sys.pvOnAcIn1.power.value : 0 - property double pvInverterOnAcIn2: sys.pvOnAcIn2.power.valid ? sys.pvOnAcIn2.power.value : 0 - property bool powerValid: sys.pvOnAcOut.power.valid || sys.pvOnAcIn1.power.valid || sys.pvOnAcIn2.power.valid - - y: 10 - text: powerValid ? EnhFmt.formatValue (pvInverterOnAcOut + pvInverterOnAcIn1 + pvInverterOnAcIn2, "W") : "" - font.pixelSize: 19 - visible: showAcSolar - }, -//////// add individual PV inverter powers - TileText { - y: 31 - text: pvInverterName1.valid ? pvInverterName1.value : "-" - visible: !showDcAndAcSolar && numberOfPvInverters >= 2 - }, - TileText { - y: 47 - text: EnhFmt.formatVBusItem (pvInverterPower1, "W") - font.pixelSize: 15 - visible: !showDcAndAcSolar && numberOfPvInverters >= 2 - }, - TileText { - y: 63 - text: pvInverterName2.valid ? pvInverterName2.value : "-" - visible: !showDcAndAcSolar && numberOfPvInverters >= 2 - }, - TileText { - y: 77 - text: EnhFmt.formatVBusItem (pvInverterPower2, "W") - font.pixelSize: 15 - visible: !showDcAndAcSolar && numberOfPvInverters >= 2 - }, - TileText { - y: 93 - text: pvInverterName3.valid ? pvInverterName3.value : "-" - visible: !showDcAndAcSolar && numberOfPvInverters >=3 && ! showTanksTemps - }, - TileText { - y: 107 - text: EnhFmt.formatVBusItem (pvInverterPower3, "W") - font.pixelSize: 15 - visible: !showDcAndAcSolar && numberOfPvInverters >=3 && ! showTanksTemps - }, - TileText { - y: 31 - text: qsTr ("L1: ") + EnhFmt.formatVBusItem (pvInverterL1Power1, "W") - visible: !showDcAndAcSolar && numberOfPvInverters == 1 && pvInverterL1Power1.valid && (pvInverterL2Power1.valid || pvInverterL3Power1.valid) - }, - TileText { - y: 47 - text: qsTr ("L2: ") + EnhFmt.formatVBusItem (pvInverterL2Power1, "W") - visible: !showDcAndAcSolar && numberOfPvInverters == 1 && pvInverterL2Power1.valid - }, - TileText { - y: 63 - text: qsTr ("L3: ") + EnhFmt.formatVBusItem (pvInverterL3Power1, "W") - visible: !showDcAndAcSolar && numberOfPvInverters == 1 && pvInverterL3Power1.valid - } - ] -////// add power bar graph -////// only shows one of possibly 3 PV inverter locations !!!!!!!!!!!!!!!!!!!!! - PowerGauge - { - id: pvInverterBar - width: parent.width - height: 12 - anchors - { - top: parent.top; topMargin: 19 - horizontalCenter: parent.horizontalCenter - } - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvOnOutputMaxPower" - maxForwardPowerParameter2: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvOnGridMaxPower" - connection: sys.pvOnAcOut - connection2: sys.pvOnGrid - visible: showGauges && showAcSolar - } - DetailTarget { id: pvInverterTarget; detailsPage: "DetailPvInverter.qml" } - } - - OverviewConnection { - id: acInToMulti - visible: showAcInput - ballCount: 2 - path: straight - active: root.active && showAcInput && showInverter - value: flow(sys.acInput ? sys.acInput.power : 0) - - anchors { - left: acInBox.right; leftMargin: -10 - right: multi.left; rightMargin: -10; bottom: acInBox.bottom; bottomMargin: 25 - } - } - - OverviewConnection { - id: multiToAcLoads - ballCount: 2 - path: straight - active: root.active && ( showAcLoads && showInverter ) - value: flow(sys.acLoad.power) - - anchors { - left: multi.right; leftMargin: -10; - right: acLoadBox.left; rightMargin: -10 - bottom: acLoadBox.bottom; bottomMargin: 8 - } - } - - OverviewConnection { - id: pvInverterToMulti - ballCount: 3 - path: corner - active: root.active && showAcSolar - value: Utils.sign(noNoise(sys.pvOnAcOut.power) + noNoise(sys.pvOnAcIn1.power) + noNoise(sys.pvOnAcIn2.power)) - - anchors { - left: pvInverter.left; leftMargin: 8 - top: pvInverter.verticalCenter; topMargin: showDcAndAcSolar ? 10 : 0 - right: multi.horizontalCenter; rightMargin: -20 - bottom: multi.bottom; bottomMargin: 10 - } - } - - // invisible anchor point to connect the chargers to the battery - Item { - id: dcConnect - anchors { - left: multi.horizontalCenter; leftMargin: showAcSolar ? -20 : 0 - bottom: dcSystemBox.top; bottomMargin: showDcAndAcSolar ? 7 : 10 - } - } - - OverviewConnection - { - id: dcBus2 - ballCount: 2 - path: straight - active: root.active && ( showInverter || showDcSolar ) - value: -Utils.sign (noNoise (sys.pvCharger.power) + noNoise (sys.vebusDc.power)) - startPointVisible: false - endPointVisible: false - - anchors { - right: dcConnect.left - top: dcConnect.top - - left: multi.left; leftMargin: -10 - bottom: dcConnect.top - } - } - - OverviewConnection - { - id: alternatorToDcBus2 - ballCount: 3 - path: corner - active: root.active && showAlternator - value: Utils.sign (alternatorFlow) - endPointVisible: false - anchors - { - left: alternatorBox.right; leftMargin: -10 - top: alternatorBox.bottom; topMargin: -15 - - right: dcBus2.left - bottom: dcBus2.bottom - } - } - - OverviewConnection { - id: multiToDcConnect - ballCount: showTanksTemps ? 2 : 4 - path: straight - active: root.active && showInverter - value: -flow(sys.vebusDc.power); - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: dcConnect.left - bottom: multi.bottom; bottomMargin: 10 - } - } - - OverviewConnection { - id: pvChargerBoxDcConnect - ballCount: 3 - path: straight - active: root.active && showDcSolar - value: -flow(sys.pvCharger.power) - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: pvChargerBox.left; rightMargin: -8 - bottom: dcConnect.top; - } - } - - OverviewConnection { - id: batteryToDcBus2 - ballCount: 1 - path: straight - active: root.active && ( showInverter || showDcSolar ) - value: Utils.sign(noNoise(sys.pvCharger.power) + noNoise(sys.vebusDc.power) + alternatorFlow) - startPointVisible: false - - anchors { - left: dcBus2.left - top: dcBus2.top - - right: battery.right; rightMargin: 10 - bottom: dcBus2.top - } - } - - OverviewConnection { - id: batteryToDcSystem - ballCount: 2 - path: straight - active: root.active && showDcSystem - value: flow(sys.dcSystem.power) - - anchors { - left: battery.right; leftMargin: -10 - top: dcSystemBox.verticalCenter; - right: dcSystemBox.left; rightMargin: -10 - bottom: dcSystemBox.verticalCenter - } - } -////// moved order so it covers connections -////// moved to under Multi - OverviewEssReason { - anchors { - top: multi.bottom; topMargin: 7 - horizontalCenter: parent.horizontalCenter - } - } - -////// ADDED to show tanks & temps - // Synchronise tank name text scroll start and PV Charger name scroll - Timer - { - id: scrollTimer - interval: 15000 - repeat: true - running: root.active - } - ListView - { - id: tanksColum - - visible: showTanks - width: compact ? root.width : root.width * tankCount / tankTempCount - property int tileWidth: width / Math.min (count, 5.2) - height: root.tanksHeight - anchors - { - bottom: root.bottom - left: root.left - } - - // flickable list if more than will fit across bottom of screen - interactive: count > 4 ? true : false - orientation: ListView.Horizontal - - model: TankModel { id: tankModel } - delegate: TileTankEnhanced { - // Without an intermediate assignment this will trigger a binding loop warning. - property variant theService: DBusServices.get(buddy.id) - service: theService - width: tanksColum.tileWidth - height: root.tanksHeight - pumpBindPrefix: root.pumpBindPreffix - compact: root.compact - Connections { - target: scrollTimer - onTriggered: doScroll() - } - } - Tile { - title: qsTr("TANKS") - anchors.fill: parent - values: TileText { - text: qsTr("") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - ListModel { id: tanksModel } - - ListView - { - id: tempsColumn - - visible: showTemps - width: compact ? root.width : root.width * tempCount / tankTempCount - property int tileWidth: width / Math.min (count, 5.2) - height: root.tanksHeight - anchors - { - bottom: root.bottom - bottomMargin: compact ? root.tanksHeight : 0 - right: root.right - } - - // make list flickable if more tiles than will fit completely - interactive: count > 4 ? true : false - orientation: ListView.Horizontal - - model: tempsModel - delegate: TileTemp - { - width: tempsColumn.tileWidth - height: tempsColumn.height - compact: root.compact - Connections - { - target: scrollTimer - onTriggered: doScroll() - } - } - Tile - { - title: qsTr("TEMPS") - anchors.fill: parent - values: TileText - { - text: qsTr("") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - ListModel { id: tempsModel } - - // When new service is found add resources as appropriate - Connections - { - target: DBusServices - onDbusServiceFound: addService(service) - } - - // hack to get value(s) from within a loop inside a function when service is changing - property string tempServiceName: "" - property VBusItem temperatureItem: VBusItem { bind: Utils.path(tempServiceName, "/Dc/0/Temperature") } - - function addService(service) - { - switch (service.type) - { -//////// add for temp sensors - case DBusService.DBUS_SERVICE_TEMPERATURE_SENSOR: - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - break;; - case DBusService.DBUS_SERVICE_MULTI: - hasInverter = true - root.tempServiceName = service.name - if (temperatureItem.valid && showBatteryTemp) - { - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - } - break;; -//////// add for VE.Direct inverters - case DBusService.DBUS_SERVICE_INVERTER: - hasInverter = true - if (veDirectInverterService == "") - veDirectInverterService = service.name; - break;; - -//////// add for PV CHARGER voltage and current display - case DBusService.DBUS_SERVICE_SOLAR_CHARGER: - case DBusService.DBUS_SERVICE_MULTI_RS: - if ( service.type == DBusService.DBUS_SERVICE_MULTI_RS ) - hasInverter = true - numberOfPvChargers++ - if (numberOfPvChargers === 1) - pvChargerPrefix1 = service.name; - else if (numberOfPvChargers === 2) - pvChargerPrefix2 = service.name; - else if (numberOfPvChargers === 3) - pvChargerPrefix3 = service.name; - else if (numberOfPvChargers === 4) - pvChargerPrefix4 = service.name; - else if (numberOfPvChargers === 5) - pvChargerPrefix5 = service.name; - else if (numberOfPvChargers === 6) - pvChargerPrefix6 = service.name; - else if (numberOfPvChargers === 7) - pvChargerPrefix7 = service.name; - break;; - -//////// add for PV INVERTER power display - case DBusService.DBUS_SERVICE_PV_INVERTER: - numberOfPvInverters++ - if (numberOfPvInverters === 1) - pvInverterPrefix1 = service.name; - else if (numberOfPvInverters === 2) - pvInverterPrefix2 = service.name; - else if (numberOfPvInverters === 3) - pvInverterPrefix3 = service.name; - break;; - case DBusService.DBUS_SERVICE_BATTERY: - root.tempServiceName = service.name - if (temperatureItem.valid && showBatteryTemp) - { - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - } - break;; - //////// add for alternator - case DBusService.DBUS_SERVICE_ALTERNATOR: - numberOfAlternators++ - if (numberOfAlternators === 1) - alternatorPrefix1 = service.name; - else if (numberOfAlternators === 2) - alternatorPrefix2 = service.name; - break;; - } - } - - // Detect available services of interest - function discoverServices() - { - numberOfTanks = 0 - numberOfTemps = 0 - numberOfPvChargers = 0 - numberOfPvInverters = 0 - numberOfAlternators = 0 - veDirectInverterService = "" - hasInverter = false - pvChargerPrefix1 = "" - pvChargerPrefix2 = "" - pvChargerPrefix3 = "" - pvChargerPrefix4 = "" - pvChargerPrefix5 = "" - pvChargerPrefix6 = "" - pvChargerPrefix7 = "" - pvInverterPrefix1 = "" - pvInverterPrefix2 = "" - pvInverterPrefix3 = "" - alternatorPrefix1 = "" - alternatorPrefix2 = "" - tempsModel.clear() - for (var i = 0; i < DBusServices.count; i++) - { - addService(DBusServices.at(i)) - } - } - -// Details targets - - // help message shown when menu is first drawn - Rectangle - { - id: helpBox - color: "white" - width: multi.width - height: 32 - opacity: 0.7 - anchors - { - top: multi.bottom; topMargin: 1 - horizontalCenter: root.horizontalCenter - } - visible: false - TileText - { - text: qsTr ( "Tap tile center for detail at any time" ) - color: "black" - anchors.fill: helpBox - wrapMode: Text.WordWrap - font.pixelSize: 12 - visible: parent.visible - } - } - - //// hard key handler - // used to press buttons when touch isn't available - // UP and DOWN buttons cycle through the list of touch areas - // "space" button is used to simulate a touch on the area - // target must be highlighted so that other uses of "space" - // will still occur - - // list of all details touchable areas - property variant targetList: - [ - acInputTarget, alternatorTarget, batteryTarget, - multiTarget, dcSystemTarget, - loadsOnOutputTarget, pvInverterTarget, pvChargerTarget - ] - - property int selectedTarget: 0 - - Timer - { - id: targetTimer - interval: 5000 - repeat: false - running: false - onTriggered: { hideAllTargets () } - } - - Keys.forwardTo: [keyHandler] - Item - { - id: keyHandler - Keys.onUpPressed: - { - nextTarget (-1) - event.accepted = true - } - - Keys.onDownPressed: - { - nextTarget (+1) - event.accepted = true - } - Keys.onSpacePressed: - { - if (targetTimer.running) - { - var foo // hack to make clicked() work - bar.clicked (foo) - event.accepted = true - } - else - event.accepted = false - } - } - // hack to make clicked() work - property variant bar: targetList[selectedTarget] - - function nextTarget (increment) - { - // make one pass through all possible targets to find an enabled one - // if found, that's the new selectedTarget, - // if not selectedTarget does not change - var newIndex = selectedTarget - for (var i = 0; i < targetList.length; i++) - { - if (( ! targetTimer.running || helpBox.visible) && targetList[newIndex].enabled) - { - highlightSelectedTarget () - return - } - newIndex += increment - if (newIndex >= targetList.length) - newIndex = 0 - else if (newIndex < 0) - newIndex = targetList.length - 1 - if (targetList[newIndex].enabled) - { - selectedTarget = newIndex - highlightSelectedTarget () - break - } - } - } - - function showHelp () - { - for (var i = 0; i < targetList.length; i++) - { - targetList[i].targetVisible = true - } - helpBox.visible = true - targetTimer.restart () - } - function hideAllTargets () - { - for (var i = 0; i < targetList.length; i++) - { - targetList[i].targetVisible = false - } - helpBox.visible = false - } - function highlightSelectedTarget () - { - for (var i = 0; i < targetList.length; i++) - { - if (targetList[i] == targetList[selectedTarget]) - targetList[i].targetVisible = true - else - targetList[i].targetVisible = false - } - helpBox.visible = false - targetTimer.restart () - } -} diff --git a/FileSets/v2.73/OverviewHubEnhanced.qml.orig b/FileSets/v2.73/OverviewHubEnhanced.qml.orig deleted file mode 100644 index d588aa94..00000000 --- a/FileSets/v2.73/OverviewHubEnhanced.qml.orig +++ /dev/null @@ -1,314 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -OverviewPage { - id: root - - property variant sys: theSystem - property bool hasAcSolarOnAcIn1: sys.pvOnAcIn1.power.valid - property bool hasAcSolarOnAcIn2: sys.pvOnAcIn2.power.valid - property bool hasAcSolarOnIn: hasAcSolarOnAcIn1 || hasAcSolarOnAcIn2 - property bool hasAcSolarOnOut: sys.pvOnAcOut.power.valid - property bool hasAcSolar: hasAcSolarOnIn || hasAcSolarOnOut - property bool hasDcSolar: sys.pvCharger.power.valid - property bool hasDcAndAcSolar: hasAcSolar && hasDcSolar - - title: qsTr("Overview") - - OverviewBox { - id: acInBox - - width: 148 - height: showStatusBar ? 100 : 120 - title: getAcSourceName(sys.acSource) - titleColor: "#E74c3c" - color: "#C0392B" - - anchors { - top: multi.top - left: parent.left; leftMargin: 10 - } - - values: OverviewAcValues { - connection: sys.acInput - } - - MbIcon { - iconId: getAcSourceIcon(sys.acSource) - anchors { - bottom: parent.bottom - left: parent.left; leftMargin: 2 - } - opacity: 0.5 - } - } - - Multi { - id: multi - anchors { - horizontalCenter: parent.horizontalCenter - top: parent.top; topMargin: 5 - } - } - - OverviewBox { - id: acLoadBox - title: qsTr("AC Loads") - color: "#27AE60" - titleColor: "#2ECC71" - width: 148 - height: showStatusBar ? 100 : 120 - - anchors { - right: parent.right; rightMargin: 10 - top: multi.top - } - - values: OverviewAcValues { - connection: sys.acLoad - } - } - - Battery { - id: battery - - soc: sys.battery.soc.valid ? sys.battery.soc.value : 0 - - anchors { - bottom: parent.bottom; bottomMargin: 5; - left: parent.left; leftMargin: 10 - } - values: Column { - width: parent.width - - TileText { - // Use value here instead of format() because format adds the unit to the number and we - // show the percentage symbol in a separated smaller text. - text: sys.battery.soc.value === undefined ? "--" : sys.battery.soc.value.toFixed(0) - font.pixelSize: 40 - - Text { - anchors { - bottom: parent.bottom; bottomMargin: 9 - horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: parent.paintedWidth / 2 + 5 - } - visible: sys.battery.soc.valid - text: "%" - color: "white" - font.bold: true - font.pixelSize: 12 - } - } - TileText { - text: sys.battery.power.format(0) - } - TileText { - text: sys.battery.voltage.format(1) + " " + sys.battery.current.format(1) - } - } - } - - VBusItem { - id: hasDcSys - bind: "com.victronenergy.settings/Settings/SystemSetup/HasDcSystem" - } - - OverviewBox { - id: dcSystemBox - width: 105 - height: 45 - visible: hasDcSys.value > 0 - title: qsTr("DC Power") - - anchors { - horizontalCenter: multi.horizontalCenter - bottom: parent.bottom; bottomMargin: 5 - } - - values: TileText { - anchors.centerIn: parent - text: sys.dcSystem.power.format(0) - } - } - - OverviewSolarCharger { - id: blueSolarCharger - - height: hasDcAndAcSolar ? 65 : 114 - width: 148 - title: qsTr("PV Charger") - showChargerIcon: !hasDcAndAcSolar - visible: hasDcSolar || hasDcAndAcSolar - - anchors { - right: root.right; rightMargin: 10 - bottom: root.bottom; bottomMargin: 5; - } - - values: TileText { - y: 5 - text: sys.pvCharger.power.format(0) - font.pixelSize: 20 - } - } - - OverviewSolarInverter { - id: pvInverter - height: hasDcAndAcSolar ? 65 : 115 - width: 148 - title: qsTr("PV Inverter") - showInverterIcon: !hasDcAndAcSolar - visible: hasAcSolar - - anchors { - right: root.right; rightMargin: 10; - bottom: root.bottom; bottomMargin: hasDcAndAcSolar ? 75 : 5 - } - - OverviewAcValues { - connection: hasAcSolarOnOut ? sys.pvOnAcOut : hasAcSolarOnAcIn1 ? sys.pvOnAcIn1 : sys.pvOnAcIn2 - visible: !coupledPvAc.visible - } - - TileText { - id: coupledPvAc - - property double pvInverterOnAcOut: sys.pvOnAcOut.power.valid ? sys.pvOnAcOut.power.value : 0 - property double pvInverterOnAcIn1: sys.pvOnAcIn1.power.valid ? sys.pvOnAcIn1.power.value : 0 - property double pvInverterOnAcIn2: sys.pvOnAcIn2.power.valid ? sys.pvOnAcIn2.power.value : 0 - - y: 5 - text: (pvInverterOnAcOut + pvInverterOnAcIn1 + pvInverterOnAcIn2).toFixed(0) + "W" - font.pixelSize: hasDcAndAcSolar ? 20 : 25 - visible: hasDcAndAcSolar || (hasAcSolarOnIn && hasAcSolarOnOut) || (hasAcSolarOnAcIn1 && hasAcSolarOnAcIn2) - } - } - - OverviewEssReason { - anchors { - bottom: parent.bottom; bottomMargin: dcSystemBox.visible ? battery.height + 15 : 5 - horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: dcSystemBox.visible ? -(root.width / 2 - battery.width / 2 - 10) : 0 - } - } - - OverviewConnection { - id: acInToMulti - ballCount: 2 - path: straight - active: root.active - value: flow(sys.acInput ? sys.acInput.power : 0) - - anchors { - left: acInBox.right; leftMargin: -10; top: multi.verticalCenter; - right: multi.left; rightMargin: -10; bottom: multi.verticalCenter - } - } - - OverviewConnection { - id: multiToAcLoads - ballCount: 2 - path: straight - active: root.active - value: flow(sys.acLoad.power) - - anchors { - left: multi.right; leftMargin: -10; - top: multi.verticalCenter - right: acLoadBox.left; rightMargin: -10 - bottom: multi.verticalCenter - } - } - - OverviewConnection { - id: pvInverterToMulti - - property int hasDcAndAcFlow: Utils.sign(noNoise(sys.pvOnAcOut.power) + noNoise(sys.pvOnAcIn1.power) + noNoise(sys.pvOnAcIn2.power)) - - ballCount: 4 - path: corner - active: root.active && hasAcSolar - value: hasDcAndAcSolar ? hasDcAndAcFlow : flow(sys.pvOnAcOut.power) - - anchors { - left: pvInverter.left; leftMargin: 8 - top: pvInverter.verticalCenter; topMargin: hasDcAndAcSolar ? 1 : 0 - right: multi.horizontalCenter; rightMargin: -20 - bottom: multi.bottom; bottomMargin: 10 - } - } - - // invisible anchor point to connect the chargers to the battery - Item { - id: dcConnect - anchors { - left: multi.horizontalCenter; leftMargin: hasAcSolar ? -20 : 0 - bottom: dcSystemBox.top; bottomMargin: 10 - } - } - - OverviewConnection { - id: multiToDcConnect - ballCount: 3 - path: straight - active: root.active - value: -flow(sys.vebusDc.power); - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: dcConnect.left - bottom: multi.bottom; bottomMargin: 10 - } - } - - OverviewConnection { - id: blueSolarChargerDcConnect - ballCount: 3 - path: straight - active: root.active && hasDcSolar - value: -flow(sys.pvCharger.power) - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: blueSolarCharger.left; rightMargin: -8 - bottom: dcConnect.top; - } - } - - OverviewConnection { - id: chargersToBattery - ballCount: 3 - path: straight - active: root.active - value: Utils.sign(noNoise(sys.pvCharger.power) + noNoise(sys.vebusDc.power)) - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: battery.right; rightMargin: 10 - bottom: dcConnect.top - } - } - - OverviewConnection { - id: batteryToDcSystem - ballCount: 2 - path: straight - active: root.active && hasDcSys.value > 0 - value: flow(sys.dcSystem.power) - - anchors { - left: battery.right; leftMargin: -10 - top: dcSystemBox.verticalCenter; - right: dcSystemBox.left; rightMargin: -10 - bottom: dcSystemBox.verticalCenter - } - } -} diff --git a/FileSets/v2.73/OverviewMobileEnhanced.qml b/FileSets/v2.73/OverviewMobileEnhanced.qml deleted file mode 100644 index c364293f..00000000 --- a/FileSets/v2.73/OverviewMobileEnhanced.qml +++ /dev/null @@ -1,987 +0,0 @@ -// GuiMods Enhancements to OverviewMobile screen - -// Removed logo and added AC INPUT and SYSTEM tiles originally displayed on other overviews -// Added voltage, current and frequency to AC INPUT and AC LOADS tiles -// Added source (Grid, Generator, Shore Power) to AC INPUT tile -// Replaced to/from battery with current in DC SYSTEM tile -// DC SYSTEM tile title now reflects direction: "DC LOADS, DC CHARGER" -// Rearranged tiles to match a left to right signal flow : sources on left, loads on right -// Standardized "info" tile sizes to 1 or 1.5 wide x 1 or 2 high -// infoArea defines usable space for info tiles and all tiles are a child of infoArea -// (makes repositioning easier than when they were in separate column objects) -// Large text for main paremeter in each tile has been reduced in size to allow more parameters without -// expanding tile height (30 to 22) -// merged SYSTEM and STATUS tiles -// removed speed from STATUS to reduce tile height -// hide "reason" text if it's blank to save space -// changed clock to 12-hour format -// Capitialized battery state: "Idle", "Charging", "Discharging" -// errors and notificaitons in SYSTEM/STATUS tile may push clock off bottom of tile -// Tile content for items that are not present are made invisible - tile remains in place -// that is no height adjustments when a tile provides no information -// Adjust button widths so that pump button fits within tank column -// Hide pump button when not enabled giving more room for tanks -// Add temperature sensors to tanks column -// add control of VE.Direct inverters - -// Includes changes to handle SeeLevel NMEA2000 tank sensor: -// Ignore the real incoming tank dBus service because it's information changes -// Changes in TileText.qml are also part of the TankRepeater package - -// Search for //////// to find changes - -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils -import "timeToGo.js" as TTG -import "enhancedFormat.js" as EnhFmt - -OverviewPage { - title: qsTr("Mobile") - id: root - - property color detailColor: "#b3b3b3" - property real touchTargetOpacity: 0.3 - property int touchArea: 40 - - property variant sys: theSystem - property string settingsBindPreffix: "com.victronenergy.settings" - property string pumpBindPreffix: "com.victronenergy.pump.startstop0" - property variant activeNotifications: NotificationCenter.notifications.filter( - function isActive(obj) { return obj.active} ) - property string noAdjustableByDmc: qsTr("This setting is disabled when a Digital Multi Control " + - "is connected. If it was recently disconnected execute " + - "\"Redetect system\" that is available on the inverter menu page.") - property string noAdjustableByBms: qsTr("This setting is disabled when a VE.Bus BMS " + - "is connected. If it was recently disconnected execute " + - "\"Redetect system\" that is available on the inverter menu page.") - property string noAdjustableTextByConfig: qsTr("This setting is disabled. " + - "Possible reasons are \"Overruled by remote\" is not enabled or " + - "an assistant is preventing the adjustment. Please, check " + - "the inverter configuration with VEConfigure.") - -//////// added to keep track of tanks and temps - property int numberOfTemps: 0 - property int tankTempCount: tankModel.rowCount + numberOfTemps - property real tanksTempsHeight: root.height - (pumpButton.pumpEnabled ? pumpButton.height : 0) - property real tanksHeight: tankModel.rowCount > 0 ? tanksTempsHeight * tankModel.rowCount / tankTempCount : 0 - property real tempsHeight: tanksTempsHeight - tanksHeight - property real minimumTankHeight: 21 - property real maxTankHeight: 80 - property real tankTileHeight: Math.min (Math.max (tanksTempsHeight / tankTempCount, minimumTankHeight), maxTankHeight) - - property bool compact: tankTempCount > (pumpButton.pumpEnabled ? 5 : 6) - - property string systemPrefix: "com.victronenergy.system" - VBusItem { id: vebusService; bind: Utils.path(systemPrefix, "/VebusService") } - property bool isMulti: vebusService.valid - property string veDirectInverterService: "" - property string inverterService: vebusService.valid ? vebusService.value : veDirectInverterService - - property bool isInverter: ! isMulti && veDirectInverterService != "" - property bool hasAcInput: isMulti - VBusItem { id: _hasAcOutSystem; bind: "com.victronenergy.settings/Settings/SystemSetup/HasAcOutSystem" } - property bool hasAcOutSystem: _hasAcOutSystem.value === 1 - -//////// add for system state - property bool hasSystemState: _systemState.valid - -//////// add for SYSTEM tile and voltage, power and frequency values - property VBusItem _systemState: VBusItem { bind: Utils.path(systemPrefix, "/SystemState/State") } -//////// add for PV CHARGER voltage and current - property string pvChargerPrefix: "" - property int numberOfPvChargers: 0 - - - //////// standard tile sizes - //////// positions are left, center, right and top, center, bottom of infoArea - property int tankWidth: 130 - - property int upperTileHeight: 185 /////////// was upperTileHeight - property int acTileHeight: height - upperTileHeight - - property int infoWidth: width - tankWidth - property int infoWidth3Column: infoWidth / 3 - property int infoWidth2Column: infoWidth / 2 - -//////// add for PV Charger voltage and current - VBusItem { id: pvNrTrackers; bind: Utils.path(pvChargerPrefix, "/NrOfTrackers") } - property bool singleTracker: ! pvNrTrackers.valid || pvNrTrackers.value == 1 - property bool showPvVI: numberOfPvChargers == 1 && singleTracker - VBusItem { id: pvPower; bind: Utils.path(pvChargerPrefix, "/Yield/Power") } - VBusItem { id: pvVoltage; bind: Utils.path(pvChargerPrefix, singleTracker ? "/Pv/V" : "/Pv/0/V") } - -//////// add for inverter mode in STATUS - VBusItem { id: inverterMode; bind: Utils.path(inverterService, "/Mode") } - -//////// add for gauges - VBusItem { id: showGaugesItem; bind: Utils.path(guiModsPrefix, "/ShowGauges") } - property bool showGauges: showGaugesItem.valid ? showGaugesItem.value === 1 ? true : false : false - -//////// added to control time display - property string guiModsPrefix: "com.victronenergy.settings/Settings/GuiMods" - VBusItem { id: timeFormatItem; bind: Utils.path(guiModsPrefix, "/TimeFormat") } - property string timeFormat: getTimeFormat () - - function getTimeFormat () - { - if (!timeFormatItem.valid || timeFormatItem.value === 0) - return "" - else if (timeFormatItem.value === 2) - return "h:mm ap" - else - return "hh:mm" - } - - Component.onCompleted: { discoverServices(); showHelp () } - - // define usable space for tiles but don't show anything - Rectangle { - id: infoArea - visible: false - anchors { - left: parent.left - right: tanksColum.left - top: parent.top; - bottom: parent.bottom; - } - } - -//////// change time to selectable 12/24 hour format - Timer { - id: wallClock - running: timeFormat != "" - repeat: true - interval: 1000 - triggeredOnStart: true - onTriggered: time = Qt.formatDateTime(new Date(), timeFormat) - property string time - } - - VBusItem { id: systemName; bind: Utils.path(settingsBindPreffix, "/Settings/SystemSetup/SystemName") } - -//////// copied SYSTEM from OverviewTiles.qml & combined SYSTEM and STATUS tiles - Tile { - title: qsTr("STATUS") - id: statusTile - anchors { left: parent.left; top: parent.top } - width: root.infoWidth3Column - height: root.upperTileHeight - inverterTile.height - color: "#4789d0" - - -//////// relorder to give priority to errors - values: [ - TileText { - text: systemName.valid && systemName.value !== "" ? systemName.value : sys.systemType.valid ? sys.systemType.value.toUpperCase() : "" - font.pixelSize: 16 - wrapMode: Text.WordWrap - width: statusTile.width - 5 - }, - TileText { - text: wallClock.running ? wallClock.time : "" - font.pixelSize: 15 - }, -//////// combine SystemReason with notifications - MarqueeEnhanced { - text: - { - if (activeNotifications.length === 0) - return systemReasonMessage.text - else - return notificationText() + " || " + systemReasonMessage.text - } - width: statusTile.width - textHorizontalAlignment: Text.AlignHCenter - interval: 100 - SystemReasonMessage { - id: systemReasonMessage - } - }, - TileText { - property VeQuickItem gpsService: VeQuickItem { uid: "dbus/com.victronenergy.system/GpsService" } - property VeQuickItem speed: VeQuickItem { uid: Utils.path("dbus/", gpsService.value, "/Speed") } - property VeQuickItem speedUnit: VeQuickItem { uid: "dbus/com.victronenergy.settings/Settings/Gps/SpeedUnit" } - - text: speed.value === undefined ? "" : getValue() - visible: speed.value !== undefined && speedUnit.value !== undefined - - function getValue() - { - if (speed.value < 0.5) // blank speed if less than about 1 MPH - return " " - if (speedUnit.value === "km/h") - return (speed.value * 3.6).toFixed(1) + speedUnit.value - if (speedUnit.value === "mph") - return (speed.value * 2.236936).toFixed(1) + speedUnit.value - if (speedUnit.value === "kt") - return (speed.value * (3600/1852)).toFixed(1) + speedUnit.value - return speed.value.toFixed(2) + "m/s" - } - } - ] - } // end Tile STATUS - - Tile { - title: qsTr("INVERTER") - id: inverterTile - anchors { left: parent.left; top: statusTile.bottom } - width: root.infoWidth3Column - height: 62 - color: "#4789d0" - - - values: [ - TileText - { - text: inverterMode.valid ? inverterMode.text : "--" - }, - TileText { - text: qsTr(systemState.text) - - SystemState { - id: systemState - bind: hasSystemState?Utils.path(systemPrefix, "/SystemState/State"):Utils.path(inverterService, "/State") - } - } - ] -////// add power bar graph - PowerGaugeMulti - { - id: multiBar - width: parent.width - 10 - height: 8 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - inverterService: root.inverterService - show: showGauges - } - DetailTarget { id: multiTarget; detailsPage: "DetailInverter.qml" } - } // end Tile INVERTER - - Tile { - title: qsTr("BATTERY") - id: batteryTile - anchors { horizontalCenter: infoArea.horizontalCenter; top: infoArea.top } - width: root.infoWidth3Column - height: root.upperTileHeight - - values: [ - TileText // spacer - { - text: "" - font.pixelSize: 6 - }, - TileText { - text: sys.battery.soc.absFormat(0) - font.pixelSize: 22 - //////// remove height (for consistency with other tiles) - }, - TileText { - text: { - if (!sys.battery.state.valid) - return "---" - switch(sys.battery.state.value) { - //////// change - capitalized words look better - case sys.batteryStateIdle: return qsTr("Idle") - case sys.batteryStateCharging : return qsTr("Charging") - case sys.batteryStateDischarging : return qsTr("Discharging") - } - } - }, - TileText { -//////// change to show negative for battery drain - text: sys.battery.power.text - }, - TileText { - text: sys.battery.voltage.format(2) - }, - TileText { - text: sys.battery.current.format(1) - }, - TileText { - text: qsTr("Remaining:") - visible: timeToGo.valid - }, - TileText { - id: timeToGoText - text: timeToGo.valid ? TTG.formatTimeToGo (timeToGo) : " " - visible: timeToGo.valid - - VBusItem { - id: timeToGo - bind: Utils.path("com.victronenergy.system","/Dc/Battery/TimeToGo") - } - } - ] -////// add battery current bar graph - PowerGaugeBattery - { - id: batteryBar - width: parent.width - 10 - height: 8 - endLabelFontSize: 14 - endLabelBackgroundColor: batteryTile.color - anchors - { - top: parent.top; topMargin: 22 - horizontalCenter: parent.horizontalCenter - } - show: showGauges - } - DetailTarget { id: batteryTarget; detailsPage: "DetailBattery.qml" } - } // end Tile BATTERY - - VBusItem { id: dcSystemNameItem; bind: Utils.path(settingsBindPreffix, "/Settings/GuiMods/CustomDcSystemName") } - - Tile { - title: dcSystemNameItem.valid && dcSystemNameItem.value != "" ? dcSystemNameItem.value : qsTr ("DC SYSTEM") - id: dcSystem - anchors { right: infoArea.right; bottom: infoArea.bottom; bottomMargin: root.acTileHeight } - width: root.infoWidth3Column - height: (root.upperTileHeight / 2) - 5 - color: "#16a085" - values: [ - TileText { - font.pixelSize: 22 - text: EnhFmt.formatVBusItem (sys.dcSystem.power) - visible: sys.dcSystem.power.valid - }, - ////// replace to/from battery with current - TileText { - text: !sys.dcSystem.power.valid ? "---" : - EnhFmt.formatValue (sys.dcSystem.power.value / sys.battery.voltage.value, "A") - visible: sys.dcSystem.power.valid - } - ] - PowerGauge - { - id: dcSystemGauge - width: parent.width - 10 - height: 8 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.dcSystem - endLabelFontSize: 12 - endLabelBackgroundColor: dcSystem.color - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/DcSystemMaxLoad" - maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/DcSystemMaxCharge" - showLabels: true - show: showGauges && sys.dcSystem.power.valid - } - DetailTarget { id: dcSystemTarget; detailsPage: "DetailDcSystem.qml" } - } // end Tile DC SYSTEM - - Tile { - id: solarTile - title: qsTr("PV CHARGER") - anchors { right: infoArea.right; top: infoArea.top } - width: root.infoWidth3Column - height: root.upperTileHeight - dcSystem.height - color: "#2cc36b" - values: [ - TileText { - font.pixelSize: 22 - text: EnhFmt.formatVBusItem (sys.pvCharger.power) - }, - //////// add voltage - TileText { - text: - { - if (showPvVI) - return EnhFmt.formatVBusItem (pvVoltage, "V") - else - return "" - } - visible: showPvVI - }, - //////// add =current - TileText { - text: - { - if (showPvVI && pvPower.valid && pvVoltage.valid) - { - var voltage = pvVoltage.value - return EnhFmt.formatValue ((pvPower.value / voltage), "A") - } - else - return "" - } - visible: showPvVI - } - ] -////// add power bar graph - PowerGauge - { - id: pvChargerBar - width: parent.width - 10 - height: 8 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.pvCharger - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvChargerMaxPower" - show: showGauges && sys.pvCharger.power.valid - } - DetailTarget { id: pvChargerTarget; detailsPage: "DetailPvCharger.qml" } - } // end Tile PV CHARGER - -//////// add to display AC input ignored - VBusItem { id: ignoreAcInput; bind: Utils.path(inverterService, "/Ac/State/IgnoreAcIn1") } - -//////// add AC INPUT tile - Tile { - id: acInputTile - title: { - if (isInverter) - return qsTr ("No AC Input") - else if (ignoreAcInput.valid && ignoreAcInput.value == 1) - return qsTr ("AC In Ignored") - else - { - switch(sys.acSource) { - case 1: return qsTr("GRID") - case 2: return qsTr("GENERATOR") - case 3: return qsTr("SHORE POWER") - default: return qsTr("AC INPUT") - } - } - } - anchors { left: infoArea.left; bottom: infoArea.bottom } - width: root.infoWidth2Column - height: root.acTileHeight - color: "#82acde" -//////// add voltage and current - VBusItem { id: currentLimit; bind: Utils.path(inverterService, "/Ac/ActiveIn/CurrentLimit") } - values: [ - TileText { - visible: isMulti - text: EnhFmt.formatVBusItem (sys.acInput.power) - font.pixelSize: 20 - - }, -//////// add voltage and current - TileText { - visible: isMulti - text: EnhFmt.formatVBusItem (sys.acInput.voltageL1, "V") + " " + EnhFmt.formatVBusItem (sys.acInput.currentL1, "A") + " " + EnhFmt.formatVBusItem (sys.acInput.frequency, "Hz") - }, - TileText - { - text: qsTr ("Limit: ") + EnhFmt.formatVBusItem (currentLimit, "A") - visible: currentLimit.valid - } - ] -////// add power bar graph - PowerGauge - { - id: acInBar - width: parent.width - 10 - height: 8 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.acInput - useInputCurrentLimit: true - maxForwardPowerParameter: "" - maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxFeedInPower" - show: showGauges && hasAcInput - } - DetailTarget { id: acInputTarget; detailsPage: "DetailAcInput.qml" } - } - - Tile { - title: qsTr("AC LOADS") - id: acLoadsTile - anchors { right: infoArea.right; bottom: infoArea.bottom} - width: root.infoWidth2Column - height: root.acTileHeight - color: "#e68e8a" -//////// add voltage and current - VBusItem { id: outVoltage; bind: Utils.path(inverterService, "/Ac/Out/L1/V") } - VBusItem { id: outCurrent; bind: Utils.path(inverterService, "/Ac/Out/L1/I") } - VBusItem { id: outFrequency; bind: Utils.path(inverterService, "/Ac/Out/L1/F") } - - values: [ - TileText { - text: EnhFmt.formatVBusItem (sys.acLoad.power) - font.pixelSize: 22 - }, -//////// add voltage and current - no frequency for VE.Direct inverter - TileText { - text: - { - var lineText = "" - if (isMulti || isInverter) - { - lineText = EnhFmt.formatVBusItem (outVoltage, "V") + " " + EnhFmt.formatVBusItem (outCurrent, "A") - if (isMulti) - lineText += " " + EnhFmt.formatVBusItem (outFrequency, "Hz") - } - return lineText - } - } - ] -////// add power bar graph - PowerGauge - { - id: acLoadBar - width: parent.width - 10 - height: 8 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.acLoad - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputMaxPower" - show: showGauges && hasAcOutSystem - } - DetailTarget { id: acLoadsOnOutputTarget; detailsPage: "DetailLoadsOnOutput.qml" } - } - - // Synchronise tank name text scroll start - Timer { - id: scrollTimer - interval: 15000 - repeat: true -//////// modified to control compact differently - running: root.active - } - - ListView { - id: tanksColum - - anchors { - top: root.top - right: root.right - } - height: root.tanksHeight - width: root.tankWidth -//////// make list flickable if more tiles than will fit completely - interactive: root.tankTileHeight * count > (tanksColum.height + 1) ? true : false - - model: TankModel { id: tankModel } - delegate: TileTankEnhanced { - // Without an intermediate assignment this will trigger a binding loop warning. - property variant theService: DBusServices.get(buddy.id) - service: theService - width: tanksColum.width - height: root.tankTileHeight - pumpBindPrefix: root.pumpBindPreffix -//////// modified to control compact differently - compact: root.compact - Connections { - target: scrollTimer - onTriggered: doScroll() - } - } - Tile { - title: qsTr("TANKS") - anchors.fill: parent - values: TileText { - text: qsTr("") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - -//////// added temperature ListView and Model - ListView { - id: tempsColumn - - anchors { - top: tanksColum.bottom - right: root.right - } - height: root.tempsHeight - width: root.tankWidth -//////// make list flickable if more tiles than will fit completely - interactive: root.tankTileHeight * count > (tempsColumn.height + 1) ? true : false - - model: tempsModel - delegate: TileTemp - { - width: tempsColumn.width - height: root.tankTileHeight -//////// modified to control compact differently - compact: root.compact - Connections - { - target: scrollTimer - onTriggered: doScroll() - } - } - Tile - { - title: qsTr("TEMPS") - anchors.fill: parent - values: TileText - { - text: qsTr("") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - ListModel { id: tempsModel } - - Tile { - id: pumpButton - - anchors.right: parent.right - anchors.bottom: parent.bottom - - property variant texts: [ qsTr("AUTO"), qsTr("ON"), qsTr("OFF")] - property int value: 0 - property bool reset: false - property bool pumpEnabled: pumpRelay.value === 3 - isCurrentItem: false // not used by GuiMods key handler - focus shown a different way - //focus: root.active && isCurrentItem // don't switch focus -- messes up key handler - - title: qsTr("PUMP") - width: pumpEnabled ? root.tankWidth : 0 - height: 45 - editable: true - readOnly: false - color: pumpButtonMouseArea.containsPressed ? "#d3d3d3" : "#A8A8A8" - - VBusItem { id: pump; bind: Utils.path(settingsBindPreffix, "/Settings/Pump0/Mode") } - VBusItem { id: pumpRelay; bind: Utils.path(settingsBindPreffix, "/Settings/Relay/Function") } - - values: [ - TileText { - text: pumpButton.pumpEnabled ? qsTr("%1").arg(pumpButton.texts[pumpButton.value]) : qsTr("DISABLED") - } - ] - - function edit() { - if (!pumpEnabled) { - toast.createToast(qsTr("Pump functionality is not enabled. To enable it go to the relay settings page and set function to \"Tank pump\""), 5000) - return - } - - reset = true - applyAnimation.restart() - reset = false - - if (value < 2) - value++ - else - value = 0 - } - - MouseArea { - id: pumpButtonMouseArea - property bool containsPressed: containsMouse && pressed - anchors.fill: parent - onClicked: { - parent.edit() - } - } - - Rectangle { - id: timerRect - height: 2 - width: pumpButton.width * 0.8 - visible: applyAnimation.running - anchors { - bottom: parent.bottom; bottomMargin: 5 - horizontalCenter: parent.horizontalCenter - } - } - - SequentialAnimation { - id: applyAnimation - alwaysRunToEnd: false - NumberAnimation { - target: timerRect - property: "width" - from: 0 - to: pumpButton.width * 0.8 - duration: 3000 - } - - ColorAnimation { - target: pumpButton - property: "color" - from: "#A8A8A8" - to: "#4789d0" - duration: 200 - } - - ColorAnimation { - target: pumpButton - property: "color" - from: "#4789d0" - to: "#A8A8A8" - duration: 200 - } - PropertyAction { - target: timerRect - property: "width" - value: 0 - } - // Do not set value if the animation is restarted by user pressing the button - // to move between options - onCompleted: if (!pumpButton.reset) pump.setValue(pumpButton.value) - } - DetailTarget { id: pumpButtonTarget; detailsPage: "" } - } - - // When new service is found add resources as appropriate - Connections { - target: DBusServices - onDbusServiceFound: addService(service) - } - - // hack to get value(s) from within a loop inside a function when service is changing - property string tempServiceName: "" - property VBusItem temperatureItem: VBusItem { bind: Utils.path(tempServiceName, "/Dc/0/Temperature") } - -//////// rewrite to use switch in place of if statements - function addService(service) - { - switch (service.type) - { -//////// add for temp sensors - case DBusService.DBUS_SERVICE_TEMPERATURE_SENSOR: - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - break;; - case DBusService.DBUS_SERVICE_MULTI: - root.tempServiceName = service.name - if (temperatureItem.valid) - { - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - } - break;; -//////// add for VE.Direct inverters - case DBusService.DBUS_SERVICE_INVERTER: - if (veDirectInverterService == "") - veDirectInverterService = service.name; - break;; - -//////// add for PV CHARGER voltage and current display - case DBusService.DBUS_SERVICE_SOLAR_CHARGER: - numberOfPvChargers++ - if (pvChargerPrefix === "") - pvChargerPrefix = service.name; - break;; - case DBusService.DBUS_SERVICE_BATTERY: - root.tempServiceName = service.name - if (temperatureItem.valid) - { - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - } - break;; - } - } - - // Check available services to find tank sesnsors -//////// rewrite to always call addService, removing redundant service type checks - function discoverServices() - { - numberOfTemps = 0 - numberOfPvChargers = 0 - veDirectInverterService = "" - tempsModel.clear() - for (var i = 0; i < DBusServices.count; i++) - addService(DBusServices.at(i)) - } - - function notificationText() - { - if (activeNotifications.length === 0) - return qsTr("") - - var descr = [] - for (var n = 0; n < activeNotifications.length; n++) { - var notification = activeNotifications[n]; - - var text = notification.serviceName + " - " + notification.description; - if (notification.value !== "" ) - text += ": " + notification.value - - descr.push(text) - } - - return descr.join(" | ") - } - - VBusItem { id: dmc; bind: Utils.path(inverterService, "/Devices/Dmc/Version") } - VBusItem { id: bms; bind: Utils.path(inverterService, "/Devices/Bms/Version") } - - - -// Details targets -////// display detail targets and help message when first displayed. - Timer { - id: helpTimer - running: false - repeat: false - interval: 5000 - triggeredOnStart: true - } - - // help message shown when menu is first drawn - Rectangle - { - id: helpBox - color: "white" - width: 150 - height: 32 - opacity: 0.7 - anchors - { - horizontalCenter: infoArea.horizontalCenter - verticalCenter: infoArea.verticalCenter - } - visible: false - } - TileText - { - text: qsTr ( "Tap tile center for detail at any time" ) - color: "black" - anchors.fill: helpBox - wrapMode: Text.WordWrap - font.pixelSize: 12 - show: helpBox.visible - } - - - //// hard key handler - // used to press buttons when touch isn't available - // UP and DOWN buttons cycle through the list of touch areas - // "space" button is used to simulate a touch on the area - // target must be highlighted so that other uses of "space" - // will still occur - - // list of all details touchable areas - // pump button sets value locally, no details page - // so is hanelded differently - // it must be LAST in the list because target list index is used for special processing - property variant targetList: - [ - multiTarget, batteryTarget, pvChargerTarget, dcSystemTarget, - acInputTarget, acLoadsOnOutputTarget, pumpButtonTarget // pump MUST BE LAST - ] - - property int selectedTarget: 0 - - Timer - { - id: targetTimer - interval: 5000 - repeat: false - running: false - onTriggered: { hideAllTargets () } - } - - Keys.forwardTo: [keyHandler] - Item - { - id: keyHandler - Keys.onUpPressed: - { - nextTarget (-1) - event.accepted = true - } - - Keys.onDownPressed: - { - nextTarget (+1) - event.accepted = true - } - Keys.onSpacePressed: - { - if (targetTimer.running) - { - var foo // hack to make clicked() work - if (selectedTarget == targetList.length - 1) - pumpButton.edit () - else - bar.clicked (foo) - event.accepted = true - } - else - event.accepted = false - } - } - // hack to make clicked() work - property variant bar: targetList[selectedTarget] - - function nextTarget (increment) - { - // make one pass through all possible targets to find an enabled one - // if found, that's the new selectedTarget, - // if not selectedTarget does not change - var newIndex = selectedTarget - for (var i = 0; i < targetList.length; i++) - { - if (( ! targetTimer.running || helpBox.visible) && targetList[newIndex].enabled) - { - highlightSelectedTarget () - return - } - newIndex += increment - if (newIndex >= targetList.length) - newIndex = 0 - else if (newIndex < 0) - newIndex = targetList.length - 1 - var includeTarget - if (newIndex == targetList.length - 1) - includeTarget = pumpButton.pumpEnabled - else - includeTarget = targetList[newIndex].enabled - if (includeTarget) - { - selectedTarget = newIndex - highlightSelectedTarget () - break - } - } - } - - function showHelp () - { - for (var i = 0; i < targetList.length; i++) - { - targetList[i].targetVisible = true - } - helpBox.visible = true - targetTimer.restart () - } - function hideAllTargets () - { - for (var i = 0; i < targetList.length; i++) - targetList[i].targetVisible = false - helpBox.visible = false - } - function highlightSelectedTarget () - { - for (var i = 0; i < targetList.length; i++) - { - if (targetList[i] == targetList[selectedTarget]) - targetList[i].targetVisible = true - else - targetList[i].targetVisible = false - } - targetTimer.restart () - helpBox.visible = false - } -} diff --git a/FileSets/v2.73/OverviewMobileEnhanced.qml.orig b/FileSets/v2.73/OverviewMobileEnhanced.qml.orig deleted file mode 100644 index 91415f35..00000000 --- a/FileSets/v2.73/OverviewMobileEnhanced.qml.orig +++ /dev/null @@ -1,642 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -OverviewPage { - id: root - - property variant sys: theSystem - property string settingsBindPreffix: "com.victronenergy.settings" - property string pumpBindPreffix: "com.victronenergy.pump.startstop0" - property variant activeNotifications: NotificationCenter.notifications.filter( - function isActive(obj) { return obj.active} ) - property string noAdjustableByDmc: qsTr("This setting is disabled when a Digital Multi Control " + - "is connected. If it was recently disconnected execute " + - "\"Redetect system\" that is avalible on the inverter menu page.") - property string noAdjustableByBms: qsTr("This setting is disabled when a VE.Bus BMS " + - "is connected. If it was recently disconnected execute " + - "\"Redetect system\" that is avalible on the inverter menu page.") - property string noAdjustableTextByConfig: qsTr("This setting is disabled. " + - "Possible reasons are \"Overruled by remote\" is not enabled or " + - "an assistant is preventing the adjustment. Please, check " + - "the inverter configuration with VEConfigure.") - property int numberOfMultis: 0 - property string vebusPrefix: "" - - // Keeps track of which button on the bottom row is active - property int buttonIndex: 0 - - title: qsTr("Mobile") - - Component.onCompleted: discoverMulti() - - ListView { - id: pwColumn - - property int tilesCount: solarTile.visible || dcSystem.visible ? 3 : 2 - property int tileHeight: Math.ceil(height / tilesCount) - interactive: false // static tiles - - width: 136 - anchors { - left: parent.left - top: parent.top; - bottom: acModeButton.top; - } - - model: VisualItemModel { - Tile { - width: pwColumn.width - height: visible ? pwColumn.tileHeight : 0 - title: qsTr("AC INPUT") - color: "#82acde" - visible: !dcSystem.visible || !solarTile.visible - values: [ - TileText { - text: sys.acInput.power.uiText - font.pixelSize: 30 - } - - ] - } - - TileAcPower { - width: pwColumn.width - height: visible ? pwColumn.tileHeight : 0 - title: qsTr("AC LOADS") - color: "#e68e8a" - values: [ - TileText { - text: sys.acLoad.power.uiText - font.pixelSize: 30 - } - ] - } - - Tile { - id: solarTile - width: pwColumn.width - height: visible ? pwColumn.tileHeight : 0 - title: qsTr("PV CHARGER") - color: "#2cc36b" - visible : sys.pvCharger.power.valid - - values: [ - TileText { - font.pixelSize: 30 - text: sys.pvCharger.power.uiText - } - ] - } - Tile { - id: dcSystem - width: pwColumn.width - height: visible ? pwColumn.tileHeight : 0 - title: qsTr("DC SYSTEM") - color: "#16a085" - visible : hasDcSys.value === 1 - - VBusItem { - id: hasDcSys - bind: Utils.path(settingsBindPreffix, "/Settings/SystemSetup/HasDcSystem") - } - - values: [ - TileText { - font.pixelSize: 30 - text: sys.dcSystem.power.format(0) - }, - TileText { - text: !sys.dcSystem.power.valid ? "---" : - sys.dcSystem.power.value < 0 ? qsTr("to battery") : qsTr("from battery") - } - ] - } - } - } - - Tile { - id: logoTile - - color: "#575748" - height: 120 - anchors { - left: pwColumn.right - right: tanksColum.left - top: parent.top - } - - MbIcon { - x: 1 - y: 1 - // see below, so the svg instead of a png if there is a 1x1 image - visible: customImage.sourceSize.width === 1 && customImage.sourceSize.height === 1 - iconId: "mobile-builder-logo-svg" - } - - // The uploaded png, the default is a 1x1 transparent pixel now. - Image { - id: customImage - source: "image://theme/mobile-builder-logo" - anchors.centerIn: parent - } - } - - Tile { - id: batteryTile - height: 112 - title: qsTr("BATTERY") - anchors { - left: pwColumn.right - right: stateTile.left - top: logoTile.bottom - bottom: acModeButton.top - } - - values: [ - TileText { - text: sys.battery.soc.absFormat(0) - font.pixelSize: 30 - height: 32 - }, - TileText { - text: { - if (!sys.battery.state.valid) - return "---" - switch(sys.battery.state.value) { - case sys.batteryStateIdle: return qsTr("idle") - case sys.batteryStateCharging : return qsTr("charging") - case sys.batteryStateDischarging : return qsTr("discharging") - } - } - }, - TileText { - text: sys.battery.power.absFormat(0) - }, - TileText { - text: sys.battery.voltage.format(1) + " " + sys.battery.current.format(1) - } - ] - } - - Tile { - id: stateTile - - width: 104 - title: qsTr("STATUS") - color: "#4789d0" - - anchors { - right: tanksColum.left - top: logoTile.bottom - bottom: acModeButton.top - } - - Timer { - id: wallClock - - running: true - repeat: true - interval: 1000 - triggeredOnStart: true - onTriggered: time = Qt.formatDateTime(new Date(), "hh:mm") - - property string time - } - - values: [ - TileText { - id: systemTile - text: wallClock.time - font.pixelSize: 30 - }, - TileText { - property VeQuickItem gpsService: VeQuickItem { uid: "dbus/com.victronenergy.system/GpsService" } - property VeQuickItem speed: VeQuickItem { uid: Utils.path("dbus/", gpsService.value, "/Speed") } - property VeQuickItem speedUnit: VeQuickItem { uid: "dbus/com.victronenergy.settings/Settings/Gps/SpeedUnit" } - - text: speed.value === undefined ? "" : getValue() - visible: speed.value !== undefined && speedUnit.value !== undefined - - function getValue() - { - if (speedUnit.value === "km/h") - return (speed.value * 3.6).toFixed(1) + speedUnit.value - if (speedUnit.value === "mph") - return (speed.value * 2.236936).toFixed(1) + speedUnit.value - if (speedUnit.value === "kt") - return (speed.value * (3600/1852)).toFixed(1) + speedUnit.value - return speed.value.toFixed(2) + "m/s" - } - }, - Marquee { - text: notificationText() - width: stateTile.width - interval: 100 - fontSize: 13 - } - ] - } - - ListView { - id: tanksColum - - property int tileHeight: Math.ceil(height / Math.max(count, 2)) - width: 134 - interactive: false // static tiles - model: TankModel { id: tankModel } - delegate: TileTank { - // Without an intermediate assignment this will trigger a binding loop warning. - property variant theService: DBusServices.get(buddy.id) - service: theService - width: tanksColum.width - height: tanksColum.tileHeight - pumpBindPrefix: root.pumpBindPreffix - compact: tankModel.rowCount > (pumpButton.pumpEnabled ? 4 : 5) - Connections { - target: scrollTimer - onTriggered: doScroll() - } - } - - anchors { - top: root.top - bottom: pumpButton.pumpEnabled ? acModeButton.top : acModeButton.bottom - right: root.right - } - - // Synchronise tank name text scroll start - Timer { - id: scrollTimer - interval: 15000 - repeat: true - running: root.active && tankModel.rowCount > 4 - } - - Tile { - title: qsTr("TANKS") - anchors.fill: parent - values: TileText { - text: qsTr("No tanks found") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - - Keys.forwardTo: [keyHandler] - - Item { - id: keyHandler - Keys.onLeftPressed: { - if (buttonIndex > 0) - buttonIndex-- - - event.accepted = true - } - - Keys.onRightPressed: { - if (buttonIndex < (pumpButton.pumpEnabled ? 2 : 1)) - buttonIndex++ - - event.accepted = true - } - } - - MouseArea { - anchors.fill: parent - enabled: parent.active - onPressed: mouse.accepted = acCurrentButton.expanded - onClicked: acCurrentButton.cancel() - } - - TileSpinBox { - id: acCurrentButton - - anchors.bottom: parent.bottom - anchors.left: parent.left - isCurrentItem: (buttonIndex == 0) - focus: root.active && isCurrentItem - - bind: Utils.path(vebusPrefix, "/Ac/ActiveIn/CurrentLimit") - title: qsTr("AC CURRENT LIMIT") - color: containsMouse && !editMode ? "#d3d3d3" : "#A8A8A8" - width: pumpButton.pumpEnabled ? 160 : 173 - fontPixelSize: 14 - unit: "A" - readOnly: currentLimitIsAdjustable.value !== 1 || numberOfMultis > 1 - buttonColor: "#979797" - - VBusItem { id: currentLimitIsAdjustable; bind: Utils.path(vebusPrefix, "/Ac/ActiveIn/CurrentLimitIsAdjustable") } - - Keys.onSpacePressed: showErrorToast(event) - - function editIsAllowed() { - if (numberOfMultis > 1) { - toast.createToast(qsTr("It is not possible to change this setting when there are more than one inverter connected."), 5000) - return false - } - - if (currentLimitIsAdjustable.value === 0) { - if (dmc.valid) { - toast.createToast(noAdjustableByDmc, 5000) - return false - } - if (bms.valid) { - toast.createToast(noAdjustableByBms, 5000) - return false - } - if (!dmc.valid && !bms.valid) { - toast.createToast(noAdjustableTextByConfig, 5000) - return false - } - } - - return true - } - - function showErrorToast(event) { - editIsAllowed() - event.accepted = true - } - } - - Tile { - id: acModeButton - anchors.left: acCurrentButton.right - anchors.bottom: parent.bottom - property variant texts: { 4: qsTr("OFF"), 3: qsTr("ON"), 1: qsTr("CHARGER ONLY") } - property int value: mode.valid ? mode.value : 3 - property int shownValue: applyAnimation2.running ? applyAnimation2.pendingValue : value - - isCurrentItem: (buttonIndex == 1) - focus: root.active && isCurrentItem - - editable: true - readOnly: !modeIsAdjustable.valid || modeIsAdjustable.value !== 1 || numberOfMultis > 1 - width: pumpButton.pumpEnabled ? 160 : 173 - height: 45 - color: acModeButtonMouseArea.containsPressed ? "#d3d3d3" : "#A8A8A8" - title: qsTr("AC MODE") - - values: [ - TileText { - text: modeIsAdjustable.valid && numberOfMultis === 1 ? qsTr("%1").arg(acModeButton.texts[acModeButton.shownValue]) : qsTr("NOT AVAILABLE") - } - ] - - VBusItem { id: mode; bind: Utils.path(vebusPrefix, "/Mode") } - VBusItem { id: modeIsAdjustable; bind: Utils.path(vebusPrefix,"/ModeIsAdjustable") } - - Keys.onSpacePressed: edit() - - function edit() { - if (!mode.valid) - return - - if (numberOfMultis > 1) { - toast.createToast(qsTr("It is not possible to change this setting when there are more than one inverter connected."), 5000) - return - } - - if (modeIsAdjustable.value === 0) { - if (dmc.valid) - toast.createToast(noAdjustableByDmc, 5000) - if (bms.valid) - toast.createToast(noAdjustableByBms, 5000) - if (!dmc.valid && !bms.valid) - toast.createToast(noAdjustableTextByConfig, 5000) - return - } - - switch (shownValue) { - case 4: - applyAnimation2.pendingValue = 3 - break; - case 3: - applyAnimation2.pendingValue = 1 - break; - case 1: - applyAnimation2.pendingValue = 4 - break; - } - - applyAnimation2.restart() - } - - MouseArea { - id: acModeButtonMouseArea - anchors.fill: parent - property bool containsPressed: containsMouse && pressed - onClicked: { - buttonIndex = 1 - parent.edit() - } - } - - Rectangle { - id: timerRect2 - height: 2 - width: acModeButton.width * 0.8 - visible: applyAnimation2.running - anchors { - bottom: parent.bottom; bottomMargin: 5 - horizontalCenter: parent.horizontalCenter - } - } - - SequentialAnimation { - id: applyAnimation2 - - property int pendingValue - - NumberAnimation { - target: timerRect2 - property: "width" - from: 0 - to: acModeButton.width * 0.8 - duration: 3000 - } - - ColorAnimation { - target: acModeButton - property: "color" - from: "#A8A8A8" - to: "#4789d0" - duration: 200 - } - - ColorAnimation { - target: acModeButton - property: "color" - from: "#4789d0" - to: "#A8A8A8" - duration: 200 - } - PropertyAction { - target: timerRect2 - property: "width" - value: 0 - } - - ScriptAction { script: mode.setValue(applyAnimation2.pendingValue) } - - PauseAnimation { duration: 1000 } - } - } - - Tile { - id: pumpButton - - anchors.left: acModeButton.right - anchors.bottom: parent.bottom - - property variant texts: [ qsTr("AUTO"), qsTr("ON"), qsTr("OFF")] - property int value: 0 - property bool reset: false - property bool pumpEnabled: pumpRelay.value === 3 - - show: pumpEnabled - isCurrentItem: (buttonIndex == 2) - focus: root.active && isCurrentItem - - title: qsTr("PUMP") - width: show ? 160 : 0 - height: 45 - editable: true - readOnly: false - color: pumpButtonMouseArea.containsPressed ? "#d3d3d3" : "#A8A8A8" - - VBusItem { id: pump; bind: Utils.path(settingsBindPreffix, "/Settings/Pump0/Mode") } - VBusItem { id: pumpRelay; bind: Utils.path(settingsBindPreffix, "/Settings/Relay/Function") } - - values: [ - TileText { - text: pumpButton.pumpEnabled ? qsTr("%1").arg(pumpButton.texts[pumpButton.value]) : qsTr("DISABLED") - } - ] - - Keys.onSpacePressed: edit() - - function edit() { - if (!pumpEnabled) { - toast.createToast(qsTr("Pump functionality is not enabled. To enable it go to the relay settings page and set function to \"Tank pump\""), 5000) - return - } - - reset = true - applyAnimation.restart() - reset = false - - if (value < 2) - value++ - else - value = 0 - } - - MouseArea { - id: pumpButtonMouseArea - property bool containsPressed: containsMouse && pressed - anchors.fill: parent - onClicked: { - buttonIndex = 2 - parent.edit() - } - } - - Rectangle { - id: timerRect - height: 2 - width: pumpButton.width * 0.8 - visible: applyAnimation.running - anchors { - bottom: parent.bottom; bottomMargin: 5 - horizontalCenter: parent.horizontalCenter - } - } - - SequentialAnimation { - id: applyAnimation - alwaysRunToEnd: false - NumberAnimation { - target: timerRect - property: "width" - from: 0 - to: pumpButton.width * 0.8 - duration: 3000 - } - - ColorAnimation { - target: pumpButton - property: "color" - from: "#A8A8A8" - to: "#4789d0" - duration: 200 - } - - ColorAnimation { - target: pumpButton - property: "color" - from: "#4789d0" - to: "#A8A8A8" - duration: 200 - } - PropertyAction { - target: timerRect - property: "width" - value: 0 - } - // Do not set value if the animation is restarted by user pressing the button - // to move between options - onCompleted: if (!pumpButton.reset) pump.setValue(pumpButton.value) - } - } - - // When new service is found check if is a tank sensor - Connections { - target: DBusServices - onDbusServiceFound: addService(service) - } - - function addService(service) - { - if (service.type === DBusService.DBUS_SERVICE_MULTI) { - numberOfMultis++ - if (vebusPrefix === "") - vebusPrefix = service.name; - } - } - - // Check available services to find tank sesnsors - function discoverMulti() - { - for (var i = 0; i < DBusServices.count; i++) { - if (DBusServices.at(i).type === DBusService.DBUS_SERVICE_MULTI) { - addService(DBusServices.at(i)) - } - } - } - - function notificationText() - { - if (activeNotifications.length === 0) - return qsTr("no alarms") - - var descr = [] - for (var n = 0; n < activeNotifications.length; n++) { - var notification = activeNotifications[n]; - - var text = notification.serviceName + " - " + notification.description; - if (notification.value !== "" ) - text += ": " + notification.value - - descr.push(text) - } - - return descr.join(" | ") - } - - VBusItem { id: dmc; bind: Utils.path(vebusPrefix, "/Devices/Dmc/Version") } - VBusItem { id: bms; bind: Utils.path(vebusPrefix, "/Devices/Bms/Version") } -} diff --git a/FileSets/v2.73/OverviewSolarCharger.qml b/FileSets/v2.73/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v2.73/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.73/OverviewSolarInverter.qml b/FileSets/v2.73/OverviewSolarInverter.qml deleted file mode 120000 index 7cea58a2..00000000 --- a/FileSets/v2.73/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v2.73/OverviewTankDelegate.qml b/FileSets/v2.73/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v2.73/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.73/OverviewTanks.qml b/FileSets/v2.73/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v2.73/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.73/OverviewTanksTempsDigInputs.qml.orig b/FileSets/v2.73/OverviewTanksTempsDigInputs.qml.orig deleted file mode 100644 index 91415f35..00000000 --- a/FileSets/v2.73/OverviewTanksTempsDigInputs.qml.orig +++ /dev/null @@ -1,642 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -OverviewPage { - id: root - - property variant sys: theSystem - property string settingsBindPreffix: "com.victronenergy.settings" - property string pumpBindPreffix: "com.victronenergy.pump.startstop0" - property variant activeNotifications: NotificationCenter.notifications.filter( - function isActive(obj) { return obj.active} ) - property string noAdjustableByDmc: qsTr("This setting is disabled when a Digital Multi Control " + - "is connected. If it was recently disconnected execute " + - "\"Redetect system\" that is avalible on the inverter menu page.") - property string noAdjustableByBms: qsTr("This setting is disabled when a VE.Bus BMS " + - "is connected. If it was recently disconnected execute " + - "\"Redetect system\" that is avalible on the inverter menu page.") - property string noAdjustableTextByConfig: qsTr("This setting is disabled. " + - "Possible reasons are \"Overruled by remote\" is not enabled or " + - "an assistant is preventing the adjustment. Please, check " + - "the inverter configuration with VEConfigure.") - property int numberOfMultis: 0 - property string vebusPrefix: "" - - // Keeps track of which button on the bottom row is active - property int buttonIndex: 0 - - title: qsTr("Mobile") - - Component.onCompleted: discoverMulti() - - ListView { - id: pwColumn - - property int tilesCount: solarTile.visible || dcSystem.visible ? 3 : 2 - property int tileHeight: Math.ceil(height / tilesCount) - interactive: false // static tiles - - width: 136 - anchors { - left: parent.left - top: parent.top; - bottom: acModeButton.top; - } - - model: VisualItemModel { - Tile { - width: pwColumn.width - height: visible ? pwColumn.tileHeight : 0 - title: qsTr("AC INPUT") - color: "#82acde" - visible: !dcSystem.visible || !solarTile.visible - values: [ - TileText { - text: sys.acInput.power.uiText - font.pixelSize: 30 - } - - ] - } - - TileAcPower { - width: pwColumn.width - height: visible ? pwColumn.tileHeight : 0 - title: qsTr("AC LOADS") - color: "#e68e8a" - values: [ - TileText { - text: sys.acLoad.power.uiText - font.pixelSize: 30 - } - ] - } - - Tile { - id: solarTile - width: pwColumn.width - height: visible ? pwColumn.tileHeight : 0 - title: qsTr("PV CHARGER") - color: "#2cc36b" - visible : sys.pvCharger.power.valid - - values: [ - TileText { - font.pixelSize: 30 - text: sys.pvCharger.power.uiText - } - ] - } - Tile { - id: dcSystem - width: pwColumn.width - height: visible ? pwColumn.tileHeight : 0 - title: qsTr("DC SYSTEM") - color: "#16a085" - visible : hasDcSys.value === 1 - - VBusItem { - id: hasDcSys - bind: Utils.path(settingsBindPreffix, "/Settings/SystemSetup/HasDcSystem") - } - - values: [ - TileText { - font.pixelSize: 30 - text: sys.dcSystem.power.format(0) - }, - TileText { - text: !sys.dcSystem.power.valid ? "---" : - sys.dcSystem.power.value < 0 ? qsTr("to battery") : qsTr("from battery") - } - ] - } - } - } - - Tile { - id: logoTile - - color: "#575748" - height: 120 - anchors { - left: pwColumn.right - right: tanksColum.left - top: parent.top - } - - MbIcon { - x: 1 - y: 1 - // see below, so the svg instead of a png if there is a 1x1 image - visible: customImage.sourceSize.width === 1 && customImage.sourceSize.height === 1 - iconId: "mobile-builder-logo-svg" - } - - // The uploaded png, the default is a 1x1 transparent pixel now. - Image { - id: customImage - source: "image://theme/mobile-builder-logo" - anchors.centerIn: parent - } - } - - Tile { - id: batteryTile - height: 112 - title: qsTr("BATTERY") - anchors { - left: pwColumn.right - right: stateTile.left - top: logoTile.bottom - bottom: acModeButton.top - } - - values: [ - TileText { - text: sys.battery.soc.absFormat(0) - font.pixelSize: 30 - height: 32 - }, - TileText { - text: { - if (!sys.battery.state.valid) - return "---" - switch(sys.battery.state.value) { - case sys.batteryStateIdle: return qsTr("idle") - case sys.batteryStateCharging : return qsTr("charging") - case sys.batteryStateDischarging : return qsTr("discharging") - } - } - }, - TileText { - text: sys.battery.power.absFormat(0) - }, - TileText { - text: sys.battery.voltage.format(1) + " " + sys.battery.current.format(1) - } - ] - } - - Tile { - id: stateTile - - width: 104 - title: qsTr("STATUS") - color: "#4789d0" - - anchors { - right: tanksColum.left - top: logoTile.bottom - bottom: acModeButton.top - } - - Timer { - id: wallClock - - running: true - repeat: true - interval: 1000 - triggeredOnStart: true - onTriggered: time = Qt.formatDateTime(new Date(), "hh:mm") - - property string time - } - - values: [ - TileText { - id: systemTile - text: wallClock.time - font.pixelSize: 30 - }, - TileText { - property VeQuickItem gpsService: VeQuickItem { uid: "dbus/com.victronenergy.system/GpsService" } - property VeQuickItem speed: VeQuickItem { uid: Utils.path("dbus/", gpsService.value, "/Speed") } - property VeQuickItem speedUnit: VeQuickItem { uid: "dbus/com.victronenergy.settings/Settings/Gps/SpeedUnit" } - - text: speed.value === undefined ? "" : getValue() - visible: speed.value !== undefined && speedUnit.value !== undefined - - function getValue() - { - if (speedUnit.value === "km/h") - return (speed.value * 3.6).toFixed(1) + speedUnit.value - if (speedUnit.value === "mph") - return (speed.value * 2.236936).toFixed(1) + speedUnit.value - if (speedUnit.value === "kt") - return (speed.value * (3600/1852)).toFixed(1) + speedUnit.value - return speed.value.toFixed(2) + "m/s" - } - }, - Marquee { - text: notificationText() - width: stateTile.width - interval: 100 - fontSize: 13 - } - ] - } - - ListView { - id: tanksColum - - property int tileHeight: Math.ceil(height / Math.max(count, 2)) - width: 134 - interactive: false // static tiles - model: TankModel { id: tankModel } - delegate: TileTank { - // Without an intermediate assignment this will trigger a binding loop warning. - property variant theService: DBusServices.get(buddy.id) - service: theService - width: tanksColum.width - height: tanksColum.tileHeight - pumpBindPrefix: root.pumpBindPreffix - compact: tankModel.rowCount > (pumpButton.pumpEnabled ? 4 : 5) - Connections { - target: scrollTimer - onTriggered: doScroll() - } - } - - anchors { - top: root.top - bottom: pumpButton.pumpEnabled ? acModeButton.top : acModeButton.bottom - right: root.right - } - - // Synchronise tank name text scroll start - Timer { - id: scrollTimer - interval: 15000 - repeat: true - running: root.active && tankModel.rowCount > 4 - } - - Tile { - title: qsTr("TANKS") - anchors.fill: parent - values: TileText { - text: qsTr("No tanks found") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - - Keys.forwardTo: [keyHandler] - - Item { - id: keyHandler - Keys.onLeftPressed: { - if (buttonIndex > 0) - buttonIndex-- - - event.accepted = true - } - - Keys.onRightPressed: { - if (buttonIndex < (pumpButton.pumpEnabled ? 2 : 1)) - buttonIndex++ - - event.accepted = true - } - } - - MouseArea { - anchors.fill: parent - enabled: parent.active - onPressed: mouse.accepted = acCurrentButton.expanded - onClicked: acCurrentButton.cancel() - } - - TileSpinBox { - id: acCurrentButton - - anchors.bottom: parent.bottom - anchors.left: parent.left - isCurrentItem: (buttonIndex == 0) - focus: root.active && isCurrentItem - - bind: Utils.path(vebusPrefix, "/Ac/ActiveIn/CurrentLimit") - title: qsTr("AC CURRENT LIMIT") - color: containsMouse && !editMode ? "#d3d3d3" : "#A8A8A8" - width: pumpButton.pumpEnabled ? 160 : 173 - fontPixelSize: 14 - unit: "A" - readOnly: currentLimitIsAdjustable.value !== 1 || numberOfMultis > 1 - buttonColor: "#979797" - - VBusItem { id: currentLimitIsAdjustable; bind: Utils.path(vebusPrefix, "/Ac/ActiveIn/CurrentLimitIsAdjustable") } - - Keys.onSpacePressed: showErrorToast(event) - - function editIsAllowed() { - if (numberOfMultis > 1) { - toast.createToast(qsTr("It is not possible to change this setting when there are more than one inverter connected."), 5000) - return false - } - - if (currentLimitIsAdjustable.value === 0) { - if (dmc.valid) { - toast.createToast(noAdjustableByDmc, 5000) - return false - } - if (bms.valid) { - toast.createToast(noAdjustableByBms, 5000) - return false - } - if (!dmc.valid && !bms.valid) { - toast.createToast(noAdjustableTextByConfig, 5000) - return false - } - } - - return true - } - - function showErrorToast(event) { - editIsAllowed() - event.accepted = true - } - } - - Tile { - id: acModeButton - anchors.left: acCurrentButton.right - anchors.bottom: parent.bottom - property variant texts: { 4: qsTr("OFF"), 3: qsTr("ON"), 1: qsTr("CHARGER ONLY") } - property int value: mode.valid ? mode.value : 3 - property int shownValue: applyAnimation2.running ? applyAnimation2.pendingValue : value - - isCurrentItem: (buttonIndex == 1) - focus: root.active && isCurrentItem - - editable: true - readOnly: !modeIsAdjustable.valid || modeIsAdjustable.value !== 1 || numberOfMultis > 1 - width: pumpButton.pumpEnabled ? 160 : 173 - height: 45 - color: acModeButtonMouseArea.containsPressed ? "#d3d3d3" : "#A8A8A8" - title: qsTr("AC MODE") - - values: [ - TileText { - text: modeIsAdjustable.valid && numberOfMultis === 1 ? qsTr("%1").arg(acModeButton.texts[acModeButton.shownValue]) : qsTr("NOT AVAILABLE") - } - ] - - VBusItem { id: mode; bind: Utils.path(vebusPrefix, "/Mode") } - VBusItem { id: modeIsAdjustable; bind: Utils.path(vebusPrefix,"/ModeIsAdjustable") } - - Keys.onSpacePressed: edit() - - function edit() { - if (!mode.valid) - return - - if (numberOfMultis > 1) { - toast.createToast(qsTr("It is not possible to change this setting when there are more than one inverter connected."), 5000) - return - } - - if (modeIsAdjustable.value === 0) { - if (dmc.valid) - toast.createToast(noAdjustableByDmc, 5000) - if (bms.valid) - toast.createToast(noAdjustableByBms, 5000) - if (!dmc.valid && !bms.valid) - toast.createToast(noAdjustableTextByConfig, 5000) - return - } - - switch (shownValue) { - case 4: - applyAnimation2.pendingValue = 3 - break; - case 3: - applyAnimation2.pendingValue = 1 - break; - case 1: - applyAnimation2.pendingValue = 4 - break; - } - - applyAnimation2.restart() - } - - MouseArea { - id: acModeButtonMouseArea - anchors.fill: parent - property bool containsPressed: containsMouse && pressed - onClicked: { - buttonIndex = 1 - parent.edit() - } - } - - Rectangle { - id: timerRect2 - height: 2 - width: acModeButton.width * 0.8 - visible: applyAnimation2.running - anchors { - bottom: parent.bottom; bottomMargin: 5 - horizontalCenter: parent.horizontalCenter - } - } - - SequentialAnimation { - id: applyAnimation2 - - property int pendingValue - - NumberAnimation { - target: timerRect2 - property: "width" - from: 0 - to: acModeButton.width * 0.8 - duration: 3000 - } - - ColorAnimation { - target: acModeButton - property: "color" - from: "#A8A8A8" - to: "#4789d0" - duration: 200 - } - - ColorAnimation { - target: acModeButton - property: "color" - from: "#4789d0" - to: "#A8A8A8" - duration: 200 - } - PropertyAction { - target: timerRect2 - property: "width" - value: 0 - } - - ScriptAction { script: mode.setValue(applyAnimation2.pendingValue) } - - PauseAnimation { duration: 1000 } - } - } - - Tile { - id: pumpButton - - anchors.left: acModeButton.right - anchors.bottom: parent.bottom - - property variant texts: [ qsTr("AUTO"), qsTr("ON"), qsTr("OFF")] - property int value: 0 - property bool reset: false - property bool pumpEnabled: pumpRelay.value === 3 - - show: pumpEnabled - isCurrentItem: (buttonIndex == 2) - focus: root.active && isCurrentItem - - title: qsTr("PUMP") - width: show ? 160 : 0 - height: 45 - editable: true - readOnly: false - color: pumpButtonMouseArea.containsPressed ? "#d3d3d3" : "#A8A8A8" - - VBusItem { id: pump; bind: Utils.path(settingsBindPreffix, "/Settings/Pump0/Mode") } - VBusItem { id: pumpRelay; bind: Utils.path(settingsBindPreffix, "/Settings/Relay/Function") } - - values: [ - TileText { - text: pumpButton.pumpEnabled ? qsTr("%1").arg(pumpButton.texts[pumpButton.value]) : qsTr("DISABLED") - } - ] - - Keys.onSpacePressed: edit() - - function edit() { - if (!pumpEnabled) { - toast.createToast(qsTr("Pump functionality is not enabled. To enable it go to the relay settings page and set function to \"Tank pump\""), 5000) - return - } - - reset = true - applyAnimation.restart() - reset = false - - if (value < 2) - value++ - else - value = 0 - } - - MouseArea { - id: pumpButtonMouseArea - property bool containsPressed: containsMouse && pressed - anchors.fill: parent - onClicked: { - buttonIndex = 2 - parent.edit() - } - } - - Rectangle { - id: timerRect - height: 2 - width: pumpButton.width * 0.8 - visible: applyAnimation.running - anchors { - bottom: parent.bottom; bottomMargin: 5 - horizontalCenter: parent.horizontalCenter - } - } - - SequentialAnimation { - id: applyAnimation - alwaysRunToEnd: false - NumberAnimation { - target: timerRect - property: "width" - from: 0 - to: pumpButton.width * 0.8 - duration: 3000 - } - - ColorAnimation { - target: pumpButton - property: "color" - from: "#A8A8A8" - to: "#4789d0" - duration: 200 - } - - ColorAnimation { - target: pumpButton - property: "color" - from: "#4789d0" - to: "#A8A8A8" - duration: 200 - } - PropertyAction { - target: timerRect - property: "width" - value: 0 - } - // Do not set value if the animation is restarted by user pressing the button - // to move between options - onCompleted: if (!pumpButton.reset) pump.setValue(pumpButton.value) - } - } - - // When new service is found check if is a tank sensor - Connections { - target: DBusServices - onDbusServiceFound: addService(service) - } - - function addService(service) - { - if (service.type === DBusService.DBUS_SERVICE_MULTI) { - numberOfMultis++ - if (vebusPrefix === "") - vebusPrefix = service.name; - } - } - - // Check available services to find tank sesnsors - function discoverMulti() - { - for (var i = 0; i < DBusServices.count; i++) { - if (DBusServices.at(i).type === DBusService.DBUS_SERVICE_MULTI) { - addService(DBusServices.at(i)) - } - } - } - - function notificationText() - { - if (activeNotifications.length === 0) - return qsTr("no alarms") - - var descr = [] - for (var n = 0; n < activeNotifications.length; n++) { - var notification = activeNotifications[n]; - - var text = notification.serviceName + " - " + notification.description; - if (notification.value !== "" ) - text += ": " + notification.value - - descr.push(text) - } - - return descr.join(" | ") - } - - VBusItem { id: dmc; bind: Utils.path(vebusPrefix, "/Devices/Dmc/Version") } - VBusItem { id: bms; bind: Utils.path(vebusPrefix, "/Devices/Bms/Version") } -} diff --git a/FileSets/v2.73/PageDigitalInput.qml b/FileSets/v2.73/PageDigitalInput.qml deleted file mode 120000 index 839f7874..00000000 --- a/FileSets/v2.73/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.73/PageGenerator.qml b/FileSets/v2.73/PageGenerator.qml deleted file mode 120000 index cae51ecb..00000000 --- a/FileSets/v2.73/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.73/PageSettingsDisplay.qml b/FileSets/v2.73/PageSettingsDisplay.qml deleted file mode 120000 index b3885a68..00000000 --- a/FileSets/v2.73/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v2.73/PageSettingsGenerator.qml b/FileSets/v2.73/PageSettingsGenerator.qml deleted file mode 120000 index 861e41bb..00000000 --- a/FileSets/v2.73/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.73/PageSettingsGuiMods.qml b/FileSets/v2.73/PageSettingsGuiMods.qml deleted file mode 100644 index b1ae80a2..00000000 --- a/FileSets/v2.73/PageSettingsGuiMods.qml +++ /dev/null @@ -1,270 +0,0 @@ -/////// new menu for all Gui Mods - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 - -MbPage { - id: root - title: qsTr("Gui Mods") - property string bindPrefixGuiMods: "com.victronenergy.settings/Settings/GuiMods" - property string bindPrefix: "com.victronenergy.settings/Settings/Gui" - - property bool showFlowParams: flowOverview.item.valid && flowOverview.item.value >= 1 - property bool showComplexParams: flowOverview.item.valid && flowOverview.item.value >= 2 - property bool showAcCoupledParams: flowOverview.item.valid && flowOverview.item.value == 3 - - model: VisualItemModel - { - MbSwitch - { - id: showTileOverview - bind: Utils.path (bindPrefixGuiMods, "/ShowTileOverview") - name: qsTr ("Show Tile Overview") - writeAccessLevel: User.AccessUser - } - - MbSwitch - { - id: moveSettings - bind: Utils.path (bindPrefixGuiMods, "/MoveSettings") - name: qsTr ("Move Settings to top of Device List") - writeAccessLevel: User.AccessUser - } - - MbSwitch { - id: relayOverview - bind: Utils.path (bindPrefixGuiMods, "/ShowRelayOverview") - name: qsTr ("Show Relay overview") - writeAccessLevel: User.AccessUser - } - MbSwitch { - id: tanksTempsOverview - bind: Utils.path (bindPrefixGuiMods, "/ShowTanksTempsDigIn") - name: qsTr ("Show Tanks, Temps, Digital Input overview") - writeAccessLevel: User.AccessUser - } - - MbSwitch - { - id: useEnhGeneratorOverview - bind: Utils.path (bindPrefixGuiMods, "/UsedEnhancedGeneratorOverview") - name: qsTr ("Use Enhanced Generator Overview") - writeAccessLevel: User.AccessUser - } - - // duplicate mobile overview on/off here for convenience - MbSwitch { - id: mobileOverview - bind: Utils.path (bindPrefix, "/MobileOverview") - name: qsTr ("Show boat & motorhome overview") - writeAccessLevel: User.AccessUser - } - MbSwitch - { - id: useEnhMobileOverview - bind: Utils.path (bindPrefixGuiMods, "/UseEnhancedMobileOverview") - name: qsTr ("Use Enhanced Mobile Overview") - // When enabled set Enhanced OverviewMobile as default overview - onClicked: - { - if (!checked) - { - // also enable Mobile Overview when turning on use enhanced Mobile Overview - showMobileOverview.setValue (1) - } - } - VBusItem { id: showMobileOverview; bind: Utils.path (bindPrefix, "/MobileOverview") } - writeAccessLevel: User.AccessUser - } - - MbItemOptions - { - id: flowOverview - description: qsTr("Flow overview") - bind: Utils.path (bindPrefixGuiMods, "/FlowOverview") - possibleValues: - [ - MbOption {description: qsTr("Victron stock"); value: 0}, - MbOption {description: qsTr("GuiMods simple"); value: 1}, - MbOption {description: qsTr("GuiMods DC Coupled"); value: 2}, - MbOption {description: qsTr("GuiMods AC Coupled"); value: 3} - ] - } - - MbSwitch - { - id: combineLoads - bind: Utils.path (bindPrefixGuiMods, "/EnhancedFlowCombineLoads") - name: qsTr ("Combine AC input/ouput loads") - show: root.showAcCoupledParams - writeAccessLevel: User.AccessInstaller - } - MbSwitch - { - id: showLoadsOnInput - bind: Utils.path (bindPrefixGuiMods, "/ShowEnhancedFlowLoadsOnInput") - name: qsTr ("Show Loads On Input") - show: root.showAcCoupledParams && ! combineLoads.checked - writeAccessLevel: User.AccessInstaller - } - - MbSwitch - { - id: showTanks - bind: Utils.path (bindPrefixGuiMods, "/ShowEnhancedFlowOverviewTanks") - name: qsTr ("Show tanks on Flow Overview") - show: root.showFlowParams - writeAccessLevel: User.AccessUser - } - MbItemOptions - { - id: tankFormat - description: qsTr("Tank bar format") - bind: Utils.path (bindPrefixGuiMods, "/TankBarFormat") - possibleValues: - [ - MbOption {description: qsTr("%"); value: 1}, - MbOption {description: qsTr("units"); value: 2}, - MbOption {description: qsTr("% + units"); value: 0} - ] - } - MbSwitch - { - id: showTemps - bind: Utils.path (bindPrefixGuiMods, "/ShowEnhancedFlowOverviewTemps") - name: qsTr ("Show temperatures on Flow Overview") - show: root.showFlowParams - writeAccessLevel: User.AccessUser - } - MbSwitch - { - id: showBatteryTemps - bind: Utils.path (bindPrefixGuiMods, "/ShowBatteryTempOnFlows") - name: qsTr ("Show battery temperature on Flow Overview") - show: showTemps.item.value == 1 - writeAccessLevel: User.AccessUser - } - MbSwitch - { - id: shortenTankNames - bind: Utils.path (bindPrefixGuiMods, "/ShortenTankNames") - name: qsTr ("Shorten tank names") - writeAccessLevel: User.AccessUser - } - - MbSwitch - { - id: replaceInactiveAcIn - bind: Utils.path (bindPrefixGuiMods, "/ReplaceInactiveAcIn") - name: qsTr ("Replace AC in if inactive") - writeAccessLevel: User.AccessUser - } - - MbEditBox { - id: dcSystemName - description: qsTr("DC System tile name") - item.bind: Utils.path (bindPrefixGuiMods, "/CustomDcSystemName") - maximumLength: 32 - enableSpaceBar: true - } - - MbSpinBox { - description: qsTr ("AC Input Limit Preset 1") - bind: Utils.path (bindPrefixGuiMods, "/AcCurrentLimit/Preset1") - unit: "A" - stepSize: 1 - min: 0 - max: 999 - writeAccessLevel: User.AccessUser - } - - MbSpinBox { - description: qsTr ("AC Input Limit Preset 2") - bind: Utils.path (bindPrefixGuiMods, "/AcCurrentLimit/Preset2") - unit: "A" - stepSize: 1 - min: 0 - max: 999 - writeAccessLevel: User.AccessUser - } - - MbSpinBox { - description: qsTr ("AC Input Limit Preset 3") - bind: Utils.path (bindPrefixGuiMods, "/AcCurrentLimit/Preset3") - unit: "A" - stepSize: 1 - min: 0 - max: 999 - writeAccessLevel: User.AccessUser - } - - MbSpinBox { - description: qsTr ("AC Input Limit Preset 4") - bind: Utils.path (bindPrefixGuiMods, "/AcCurrentLimit/Preset4") - unit: "A" - stepSize: 1 - min: 0 - max: 999 - writeAccessLevel: User.AccessUser - } - - MbItemOptions - { - id: tempScale - description: qsTr ("Temperature scale") - bind: Utils.path (bindPrefixGuiMods, "/TemperatureScale") - possibleValues: - [ - MbOption { description: "°C"; value: 1 }, - MbOption { description: "°F"; value: 2 }, - MbOption { description: qsTr("both °C & °F"); value: 0 } - ] - writeAccessLevel: User.AccessUser - } - - MbSpinBox { - description: qsTr ("Watt / Kilowatt threshold") - bind: Utils.path (bindPrefixGuiMods, "/KilowattThreshold") - unit: "W" - stepSize: 100 - min: 1000 - max: 10000 - writeAccessLevel: User.AccessUser - } - - MbItemOptions - { - id: timeFormat - description: qsTr ("Time format") - bind: Utils.path (bindPrefixGuiMods, "/TimeFormat") - possibleValues: - [ - MbOption { description: qsTr("24 hour"); value: 1 }, - MbOption { description: qsTr("12 hour AM/PM"); value: 2 }, - MbOption { description: qsTr("don't show time"); value: 0 } - ] - writeAccessLevel: User.AccessUser - } - MbItemOptions - { - id: inactiveFlowTiles - description: qsTr ("Inactive Tiles on Flow Overview") - bind: Utils.path (bindPrefixGuiMods, "/ShowInactiveFlowTiles") - show: root.showFlowParams - possibleValues: - [ - MbOption { description: qsTr("Show Dimmed"); value: 1 }, - MbOption { description: qsTr("Show Full"); value: 2 }, - MbOption { description: qsTr("Hide"); value: 0 } - ] - writeAccessLevel: User.AccessUser - } - MbSubMenu - { - description: qsTr("Power Gauges") - subpage: Component { PageSettingsGuiModsGauges {} } - show: root.showFlowParams - } - } -} diff --git a/FileSets/v2.73/PageSettingsGuiMods.qml.orig b/FileSets/v2.73/PageSettingsGuiMods.qml.orig deleted file mode 100644 index 6cceb202..00000000 --- a/FileSets/v2.73/PageSettingsGuiMods.qml.orig +++ /dev/null @@ -1,311 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - property string cgwacsPath: "com.victronenergy.settings/Settings/CGwacs" - property string settingsPrefix: "com.victronenergy.settings" - property string batteryLifePath: cgwacsPath + "/BatteryLife" - // Hub4Mode - property int hub4PhaseCompensation: 1 - property int hub4PhaseSplit: 2 - property int hub4Disabled: 3 - // BatteryLifeState - property int batteryLifeStateDisabled: 0 - property int batteryLifeStateRestart: 1 - property int batteryLifeStateDefault: 2 - property int batteryLifeStateAbsorption: 3 - property int batteryLifeStateFloat: 4 - property int batteryLifeStateDischarged: 5 - property int batteryLifeStateForceCharge: 6 - property int batteryLifeStateSustain: 7 - property int batteryLifeStateLowSocCharge: 8 - property int batteryKeepCharged: 9 - property int batterySocGuardDefault: 10 - property int batterySocGuardDischarged: 11 - property int batterySocGuardLowSocCharge: 12 - - property VBusItem systemType: VBusItem { bind: "com.victronenergy.system/SystemType" } - property VBusItem gridSetpoint: VBusItem { bind: "com.victronenergy.settings/Settings/CGwacs/AcPowerSetPoint" } - property VBusItem maxChargePowerItem: VBusItem { bind: Utils.path(cgwacsPath, "/MaxChargePower") } - property VBusItem maxDischargePowerItem: VBusItem { bind: Utils.path(cgwacsPath, "/MaxDischargePower") } - property VBusItem socLimitItem: VBusItem { bind: Utils.path(batteryLifePath, "/SocLimit") } - property VBusItem minSocLimitItem: VBusItem { bind: Utils.path(batteryLifePath, "/MinimumSocLimit") } - property VBusItem stateItem: VBusItem { bind: Utils.path(batteryLifePath, "/State") } - property VBusItem hub4Mode: VBusItem { bind: Utils.path(cgwacsPath, "/Hub4Mode") } - property VBusItem maxChargeCurrentControl: VBusItem { bind: "com.victronenergy.system/Control/MaxChargeCurrent" } - - title: systemType.value === "Hub-4" ? systemType.value : qsTr("ESS") - model: systemType.value === "ESS" || systemType.value === "Hub-4" ? hub4Settings : noHub4 - - VisualItemModel { - id: noHub4 - - MbItemText { - text: qsTr("No ESS Assistant found") - } - } - - function isBatteryLifeActive(state) { - switch (state) { - case batteryLifeStateRestart: - case batteryLifeStateDefault: - case batteryLifeStateAbsorption: - case batteryLifeStateFloat: - case batteryLifeStateDischarged: - case batteryLifeStateForceCharge: - case batteryLifeStateSustain: - case batteryLifeStateLowSocCharge: - return true - default: - return false - } - } - - function isBatterySocGuardActive(state) { - switch (state) { - case batterySocGuardDefault: - case batterySocGuardDischarged: - case batterySocGuardLowSocCharge: - return true - default: - return false - } - } - - VisualItemModel { - id: hub4Settings - - MbItemOptions { - function getLocalValue(hub4Mode, state) { - if (hub4Mode === undefined || state === undefined) - return undefined - if (hub4Mode === hub4Disabled) - return 3 - if (isBatteryLifeActive(state)) - return 0 - if (isBatterySocGuardActive(state)) - return 1 - if (state === batteryKeepCharged) - return 2 - return 0 - } - - description: qsTr("Mode") - localValue: getLocalValue(hub4Mode.value, stateItem.value) - possibleValues:[ - MbOption { description: qsTr("Optimized (with BatteryLife)"); value: 0 }, - MbOption { description: qsTr("Optimized (without BatteryLife)"); value: 1 }, - MbOption { description: qsTr("Keep batteries charged"); value: 2 }, - MbOption { description: qsTr("External control"); value: 3 } - ] - onLocalValueChanged: { - if (localValue === undefined) - return - // Hub 4 mode - if (localValue === 3 && hub4Mode.value !== hub4Disabled) { - hub4Mode.setValue(hub4Disabled) - } else if (localValue !== 3 && hub4Mode.value === hub4Disabled) { - hub4Mode.setValue(hub4PhaseCompensation) - } - // BatteryLife state - switch (localValue) { - case 0: - if (!isBatteryLifeActive(stateItem.value)) - stateItem.setValue(batteryLifeStateRestart) - break - case 1: - if (!isBatterySocGuardActive(stateItem.value)) - stateItem.setValue(batterySocGuardDefault) - break - case 2: - stateItem.setValue(batteryKeepCharged) - break - case 3: - stateItem.setValue(batteryLifeStateDisabled) - break - } - } - } - - MbItemOptions { - id: withoutGridMeter - description: qsTr("Grid metering") - bind: Utils.path(cgwacsPath, '/RunWithoutGridMeter') - show: hub4Mode.value !== hub4Disabled - enabled: userHasWriteAccess - possibleValues:[ - MbOption { description: qsTr("External meter"); value: 0 }, - MbOption { description: qsTr("Inverter/Charger"); value: 1 } - ] - } - - MbSwitch { - bind: Utils.path(settingsPrefix, "/Settings/SystemSetup/HasAcOutSystem") - name: qsTr("Inverter AC output in use") - show: withoutGridMeter.value == 0 - } - - - MbItemOptions { - description: qsTr("Multiphase regulation") - bind: hub4Mode.bind - show: hub4Mode.value !== hub4Disabled && stateItem.value !== batteryKeepCharged - enabled: userHasWriteAccess - possibleValues:[ - MbOption { description: qsTr("Total of all phases"); value: hub4PhaseCompensation }, - MbOption { description: qsTr("Individual phase"); value: hub4PhaseSplit } - ] - onOptionSelected: { - if (newValue === hub4PhaseSplit) { - toast.createToast(qsTr("Each phase is regulated to individually achieve the grid setpoint (system efficiency is decreased).\n\n" + - "CAUTION: Use only if required by the utility provider"), 15000); - } else if (newValue === hub4PhaseCompensation) { - toast.createToast(qsTr("The total of all phases is intelligently regulated to achieve the grid setpoint (system efficiency is optimised).\n\n" + - "Use unless prohibited by the utility provider"), 15000); - } - } - } - - MbSpinBox { - id: minSocLimit - description: qsTr("Minimum SOC (unless grid fails)") - enabled: userHasWriteAccess - show: hub4Mode.value !== hub4Disabled && stateItem.value !== batteryKeepCharged - bind: Utils.path(batteryLifePath, "/MinimumSocLimit") - numOfDecimals: 0 - unit: "%" - min: 0 - max: 100 - stepSize: 5 - } - - MbItemValue { - id: socLimit - description: qsTr("Active SOC limit") - show: hub4Mode.value !== hub4Disabled && isBatteryLifeActive(stateItem.value) - item.value: Math.max(minSocLimitItem.value, socLimitItem.value) - item.unit: '%' - } - - MbItemOptions { - description: qsTr("BatteryLife state") - value: stateItem.value - readonly: true - show: hub4Mode.value !== hub4Disabled && isBatteryLifeActive(stateItem.value) - possibleValues:[ - // Values below taken from MaintenanceState enum in dbus-cgwacs - MbOption { description: qsTr("Self-consumption"); value: 2 }, - MbOption { description: qsTr("Self-consumption"); value: 3 }, - MbOption { description: qsTr("Self-consumption"); value: 4 }, - MbOption { description: qsTr("Discharge disabled"); value: 5 }, - MbOption { description: qsTr("Slow charge"); value: 6 }, - MbOption { description: qsTr("Sustain"); value: 7 } - ] - } - - MbSwitch { - id: maxChargePowerSwitch - name: qsTr("Limit charge power") - checked: maxChargePowerItem.value >= 0 - enabled: userHasWriteAccess - show: hub4Mode.value !== hub4Disabled && !(maxChargeCurrentControl.valid && maxChargeCurrentControl.value) - onCheckedChanged: { - if (checked && maxChargePowerItem.value < 0) - maxChargePowerItem.setValue(1000) - else if (!checked && maxChargePowerItem.value >= 0) - maxChargePowerItem.setValue(-1) - } - } - - MbSpinBox { - id: maxChargePower - description: qsTr("Maximum charge power") - enabled: userHasWriteAccess - show: maxChargePowerSwitch.show && maxChargePowerSwitch.checked - bind: Utils.path(cgwacsPath, "/MaxChargePower") - numOfDecimals: 0 - unit: "W" - min: 0 - max: 200000 - stepSize: 50 - } - - MbSwitch { - id: maxInverterPowerSwitch - name: qsTr("Limit inverter power") - checked: maxDischargePowerItem.value >= 0 - enabled: userHasWriteAccess - show: hub4Mode.value !== hub4Disabled && stateItem.value !== batteryKeepCharged - onCheckedChanged: { - if (checked && maxDischargePowerItem.value < 0) - maxDischargePowerItem.setValue(1000) - else if (!checked && maxDischargePowerItem.value >= 0) - maxDischargePowerItem.setValue(-1) - } - } - - MbSpinBox { - id: maxDischargePower - description: qsTr("Maximum inverter power") - enabled: userHasWriteAccess - show: maxInverterPowerSwitch.show && maxInverterPowerSwitch.checked - bind: Utils.path(cgwacsPath, "/MaxDischargePower") - numOfDecimals: 0 - unit: "W" - min: 0 - max: 300000 - stepSize: 50 - } - - MbSpinBox { - description: qsTr("Grid setpoint") - show: hub4Mode.value !== hub4Disabled && stateItem.value !== batteryKeepCharged - enabled: userHasWriteAccess - bind: "com.victronenergy.settings/Settings/CGwacs/AcPowerSetPoint" - numOfDecimals: 0 - unit: "W" - stepSize: 10 - } - - MbSubMenu { - id: feedinSetupItem - description: qsTr("Grid feed-in") - show: hub4Mode.value !== hub4Disabled - subpage: Component { - PageSettingsHub4Feedin { - title: feedinSetupItem.description - } - } - } - - MbSubMenu { - id: scheduleSettings - property string bindPrefix: "com.victronenergy.settings/Settings/CGwacs/BatteryLife/Schedule/Charge/" - description: qsTr("Scheduled charging") - show: hub4Mode.value !== hub4Disabled && stateItem.value !== batteryKeepCharged - subpage: Component { - MbPage { - title: scheduleSettings.description - model: VisualItemModel { - ChargeScheduleItem { bindPrefix: scheduleSettings.bindPrefix; scheduleNumber: 0 } - ChargeScheduleItem { bindPrefix: scheduleSettings.bindPrefix; scheduleNumber: 1 } - ChargeScheduleItem { bindPrefix: scheduleSettings.bindPrefix; scheduleNumber: 2 } - ChargeScheduleItem { bindPrefix: scheduleSettings.bindPrefix; scheduleNumber: 3 } - ChargeScheduleItem { bindPrefix: scheduleSettings.bindPrefix; scheduleNumber: 4 } - } - } - } - } - - MbSubMenu { - id: deviceItem - description: qsTr("Debug") - show: hub4Mode.value !== hub4Disabled && user.accessLevel >= User.AccessService - backgroundColor: style.backgroundColorService - subpage: Component { - PageHub4Debug { } - } - } - } -} diff --git a/FileSets/v2.73/PageSettingsRelay.qml b/FileSets/v2.73/PageSettingsRelay.qml deleted file mode 100644 index ee03cbe7..00000000 --- a/FileSets/v2.73/PageSettingsRelay.qml +++ /dev/null @@ -1,502 +0,0 @@ -//////// modified to -//////// add 6 relays for Raspberry PI -//////// custom relay name for Relay Overview -//////// show/hide relay in Relay Overview - -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: pageRelaySettings - title: qsTr("Relay") - property string bindPrefix: "com.victronenergy.settings" - property VBusItem relay1Item: VBusItem { bind: "com.victronenergy.system/Relay/0/State" } - property bool hasRelay1: relay1Item.valid - property VBusItem relay2Item: VBusItem { bind: "com.victronenergy.system/Relay/1/State" } - property bool hasRelay2: relay2Item.valid - property VBusItem relay3Item: VBusItem { bind: "com.victronenergy.system/Relay/2/State" } - property bool hasRelay3: relay3Item.valid - property VBusItem relay4Item: VBusItem { bind: "com.victronenergy.system/Relay/3/State" } - property bool hasRelay4: relay4Item.valid - property VBusItem relay5Item: VBusItem { bind: "com.victronenergy.system/Relay/4/State" } - property bool hasRelay5: relay5Item.valid - property VBusItem relay6Item: VBusItem { bind: "com.victronenergy.system/Relay/5/State" } - property bool hasRelay6: relay6Item.valid - property VBusItem relay7Item: VBusItem { bind: "com.victronenergy.system/Relay/6/State" } - property bool hasRelay7: relay7Item.valid - property VBusItem relay8Item: VBusItem { bind: "com.victronenergy.system/Relay/7/State" } - property bool hasRelay8: relay8Item.valid - property VBusItem relay9Item: VBusItem { bind: "com.victronenergy.system/Relay/8/State" } - property bool hasRelay9: relay9Item.valid - property VBusItem relay10Item: VBusItem { bind: "com.victronenergy.system/Relay/9/State" } - property bool hasRelay10: relay10Item.valid - property VBusItem relay11Item: VBusItem { bind: "com.victronenergy.system/Relay/10/State" } - property bool hasRelay11: relay11Item.valid - property VBusItem relay12Item: VBusItem { bind: "com.victronenergy.system/Relay/11/State" } - property bool hasRelay12: relay12Item.valid - property VBusItem relay13Item: VBusItem { bind: "com.victronenergy.system/Relay/12/State" } - property bool hasRelay13: relay13Item.valid - property VBusItem relay14Item: VBusItem { bind: "com.victronenergy.system/Relay/13/State" } - property bool hasRelay14: relay14Item.valid - property VBusItem relay15Item: VBusItem { bind: "com.victronenergy.system/Relay/14/State" } - property bool hasRelay15: relay15Item.valid - property VBusItem relay16Item: VBusItem { bind: "com.victronenergy.system/Relay/15/State" } - property bool hasRelay16: relay16Item.valid - property VBusItem relay17Item: VBusItem { bind: "com.victronenergy.system/Relay/16/State" } - property bool hasRelay17: relay17Item.valid - property VBusItem relay18Item: VBusItem { bind: "com.victronenergy.system/Relay/17/State" } - property bool hasRelay18: relay18Item.valid - - property VBusItem relay1NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/0/CustomName") } - property VBusItem relay2NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/1/CustomName") } - property VBusItem relay3NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/2/CustomName") } - property VBusItem relay4NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/3/CustomName") } - property VBusItem relay5NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/4/CustomName") } - property VBusItem relay6NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/5/CustomName") } - property VBusItem relay7NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/6/CustomName") } - property VBusItem relay8NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/7/CustomName") } - property VBusItem relay9NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/8/CustomName") } - property VBusItem relay10NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/9/CustomName") } - property VBusItem relay11NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/10/CustomName") } - property VBusItem relay12NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/11/CustomName") } - property VBusItem relay13NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/12/CustomName") } - property VBusItem relay14NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/13/CustomName") } - property VBusItem relay15NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/14/CustomName") } - property VBusItem relay16NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/15/CustomName") } - property VBusItem relay17NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/16/CustomName") } - property VBusItem relay18NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/17/CustomName") } - - function relayName (nameItem, relayNumber) - { - var prefix, suffix - if (nameItem.valid && nameItem.value != "") - { - prefix = nameItem.value + " (" - suffix = ")" - } - else - { - prefix = "" - suffix = "" - } - if (relayNumber == 1) - return prefix + (hasRelay1 ? qsTr("Relay 1") : qsTr("Relay")) + suffix + " " + qsTr("On") - else - return prefix + qsTr("Relay") + " " + relayNumber + suffix + " " + qsTr("On") - } - - model: VisualItemModel { - MbItemOptions { - id: relay1Function - description: hasRelay2 ? qsTr("Function (Relay 1)") : qsTr("Function") - bind: Utils.path(bindPrefix, "/Settings/Relay/Function") - possibleValues:[ - MbOption { description: qsTr("Alarm relay"); value: 0 }, - MbOption { description: qsTr("Generator start/stop"); value: 1 }, - MbOption { description: qsTr("Tank pump"); value: 3 }, - MbOption { description: qsTr("Manual"); value: 2 } - ] - } - - MbItemOptions { - description: qsTr("Alarm relay polarity") - bind: Utils.path(bindPrefix, "/Settings/Relay/Polarity") - show: hasRelay1 && relay1Function.value === 0 - possibleValues: [ - MbOption { description: qsTr("Normally open"); value: 0 }, - MbOption { description: qsTr("Normally closed"); value: 1 } - ] - } - - MbSwitch { - id: relay1Switch - // Use a one-way binding, because the usual binding: - // checked: Relay.relayOn - // will be broken when the switched toggled, and changes in the relayOn property made - // elsewhere will not change the state of the switch any more. - Binding { - target: relay1Switch - property: "checked" - value: Relay.relayOn - when: true - } - enabled: userHasWriteAccess - name: qsTr("Alarm relay On") - onCheckedChanged: relay1Item.setValue(checked); - show: hasRelay1 && relay1Function.value === 0 - } - - MbSwitch { - id: manualSwitch2 - name: relayName (relay2NameItem, 2) - bind: "com.victronenergy.system/Relay/1/State" - show: hasRelay2 && relay2Function.value === 2 - } - MbSwitch { - id: manualSwitch3 - name: relayName (relay3NameItem, 3) - bind: "com.victronenergy.system/Relay/2/State" - show: hasRelay3 - } - MbSwitch { - id: manualSwitch4 - name: relayName (relay4NameItem, 4) - bind: "com.victronenergy.system/Relay/3/State" - show: hasRelay4 - } - MbSwitch { - id: manualSwitch5 - name: relayName (relay5NameItem, 5) - bind: "com.victronenergy.system/Relay/4/State" - show: hasRelay5 - } - MbSwitch { - id: manualSwitch6 - name: relayName (relay6NameItem, 6) - bind: "com.victronenergy.system/Relay/5/State" - show: hasRelay6 - } - MbSwitch { - id: manualSwitch7 - name: relayName (relay7NameItem, 7) - bind: "com.victronenergy.system/Relay/6/State" - show: hasRelay7 - } - MbSwitch { - id: manualSwitch8 - name: relayName (relay8NameItem, 8) - bind: "com.victronenergy.system/Relay/7/State" - show: hasRelay8 - } - MbSwitch { - id: manualSwitch9 - name: relayName (relay9NameItem, 9) - bind: "com.victronenergy.system/Relay/8/State" - show: hasRelay9 - } - MbSwitch { - id: manualSwitch10 - name: relayName (relay10NameItem, 10) - bind: "com.victronenergy.system/Relay/9/State" - show: hasRelay10 - } - MbSwitch { - id: manualSwitch11 - name: relayName (relay11NameItem, 11) - bind: "com.victronenergy.system/Relay/10/State" - show: hasRelay11 - } - MbSwitch { - id: manualSwitch12 - name: relayName (relay12NameItem, 12) - bind: "com.victronenergy.system/Relay/11/State" - show: hasRelay12 - } - MbSwitch { - id: manualSwitch13 - name: relayName (relay13NameItem, 13) - bind: "com.victronenergy.system/Relay/12/State" - show: hasRelay13 - } - MbSwitch { - id: manualSwitch14 - name: relayName (relay14NameItem, 14) - bind: "com.victronenergy.system/Relay/13/State" - show: hasRelay14 - } - MbSwitch { - id: manualSwitch15 - name: relayName (relay15NameItem, 15) - bind: "com.victronenergy.system/Relay/14/State" - show: hasRelay15 - } - MbSwitch { - id: manualSwitch16 - name: relayName (relay16NameItem, 16) - bind: "com.victronenergy.system/Relay/15/State" - show: hasRelay16 - } - MbSwitch { - id: manualSwitch17 - name: relayName (relay17NameItem, 17) - bind: "com.victronenergy.system/Relay/16/State" - show: hasRelay17 - } - MbSwitch { - id: manualSwitch18 - name: relayName (relay18NameItem, 18) - bind: "com.victronenergy.system/Relay/17/State" - show: hasRelay18 - } - - MbEditBox { - id: relay1name - description: qsTr("Relay 1 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/0/CustomName" - show: hasRelay1 && item.valid && relay1Function.value === 2 // manual mode - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay1 - name: qsTr("Show Relay 1 in overview") - bind: "com.victronenergy.settings/Settings/Relay/0/Show" - show: hasRelay1 - } - - MbEditBox { - id: relay2name - description: qsTr("Relay 2 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/1/CustomName" - show: hasRelay2 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay2 - name: qsTr("Show Relay 2 in overview") - bind: "com.victronenergy.settings/Settings/Relay/1/Show" - show: hasRelay2 - } - - MbEditBox { - id: relay3name - description: qsTr("Relay 3 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/2/CustomName" - show: hasRelay3 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay3 - name: qsTr("Show Relay 3 in overview") - bind: "com.victronenergy.settings/Settings/Relay/2/Show" - show: hasRelay3 - } - - MbEditBox { - id: relay4name - description: qsTr("Relay 4 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/3/CustomName" - show: hasRelay4 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay4 - name: qsTr("Show Relay 4 in overview") - bind: "com.victronenergy.settings/Settings/Relay/3/Show" - show: hasRelay4 - } - - MbEditBox { - id: relay5name - description: qsTr("Relay 5 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/4/CustomName" - show: hasRelay5 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay5 - name: qsTr("Show Relay 5 in overview") - bind: "com.victronenergy.settings/Settings/Relay/4/Show" - show: hasRelay5 - } - - MbEditBox { - id: relay6name - description: qsTr("Relay 6 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/5/CustomName" - show: hasRelay6 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay6 - name: qsTr("Show Relay 6 in overview") - bind: "com.victronenergy.settings/Settings/Relay/5/Show" - show: hasRelay6 - } - - MbEditBox { - id: relay7name - description: qsTr("Relay 7 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/6/CustomName" - show: hasRelay7 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay7 - name: qsTr("Show Relay 7 in overview") - bind: "com.victronenergy.settings/Settings/Relay/6/Show" - show: hasRelay7 - } - - MbEditBox { - id: relay8name - description: qsTr("Relay 8 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/7/CustomName" - show: hasRelay8 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay8 - name: qsTr("Show Relay 8 in overview") - bind: "com.victronenergy.settings/Settings/Relay/7/Show" - show: hasRelay8 - } - - MbEditBox { - id: relay9name - description: qsTr("Relay 9 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/8/CustomName" - show: hasRelay9 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay9 - name: qsTr("Show Relay 9 in overview") - bind: "com.victronenergy.settings/Settings/Relay/8/Show" - show: hasRelay9 - } - - MbEditBox { - id: relay10name - description: qsTr("Relay 10 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/9/CustomName" - show: hasRelay10 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay10 - name: qsTr("Show Relay 10 in overview") - bind: "com.victronenergy.settings/Settings/Relay/9/Show" - show: hasRelay10 - } - - MbEditBox { - id: relay11name - description: qsTr("Relay 11 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/10/CustomName" - show: hasRelay11 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay11 - name: qsTr("Show Relay 11 in overview") - bind: "com.victronenergy.settings/Settings/Relay/10/Show" - show: hasRelay11 - } - - MbEditBox { - id: relay12name - description: qsTr("Relay 12 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/11/CustomName" - show: hasRelay12 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay12 - name: qsTr("Show Relay 12 in overview") - bind: "com.victronenergy.settings/Settings/Relay/11/Show" - show: hasRelay12 - } - - MbEditBox { - id: relay13name - description: qsTr("Relay 13 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/12/CustomName" - show: hasRelay13 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay13 - name: qsTr("Show Relay 13 in overview") - bind: "com.victronenergy.settings/Settings/Relay/12/Show" - show: hasRelay13 - } - - MbEditBox { - id: relay14name - description: qsTr("Relay 14 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/13/CustomName" - show: hasRelay14 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay14 - name: qsTr("Show Relay 14 in overview") - bind: "com.victronenergy.settings/Settings/Relay/13/Show" - show: hasRelay14 - } - - MbEditBox { - id: relay15name - description: qsTr("Relay 15 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/14/CustomName" - show: hasRelay15 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay15 - name: qsTr("Show Relay 15 in overview") - bind: "com.victronenergy.settings/Settings/Relay/14/Show" - show: hasRelay15 - } - - MbEditBox { - id: relay16name - description: qsTr("Relay 16 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/15/CustomName" - show: hasRelay16 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay16 - name: qsTr("Show Relay 16 in overview") - bind: "com.victronenergy.settings/Settings/Relay/15/Show" - show: hasRelay16 - } - - MbEditBox { - id: relay17name - description: qsTr("Relay 17 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/16/CustomName" - show: hasRelay17 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay17 - name: qsTr("Show Relay 17 in overview") - bind: "com.victronenergy.settings/Settings/Relay/16/Show" - show: hasRelay17 - } - MbEditBox { - id: relay18name - description: qsTr("Relay 18 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/17/CustomName" - show: hasRelay18 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay18 - name: qsTr("Show Relay 18 in overview") - bind: "com.victronenergy.settings/Settings/Relay/17/Show" - show: hasRelay18 - } - } -} diff --git a/FileSets/v2.73/PageSettingsRelay.qml.orig b/FileSets/v2.73/PageSettingsRelay.qml.orig deleted file mode 100644 index b5191240..00000000 --- a/FileSets/v2.73/PageSettingsRelay.qml.orig +++ /dev/null @@ -1,67 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: pageRelaySettings - title: qsTr("Relay") - property string bindPrefix: "com.victronenergy.settings" - property VBusItem relay1Item: VBusItem { bind: "com.victronenergy.system/Relay/1/State" } - property bool hasRelay1: relay1Item.valid - - model: VisualItemModel { - MbItemOptions { - id: relayFunction - description: hasRelay1 ? qsTr("Function (Relay 1)") : qsTr("Function") - bind: Utils.path(bindPrefix, "/Settings/Relay/Function") - possibleValues:[ - MbOption { description: qsTr("Alarm relay"); value: 0 }, - MbOption { description: qsTr("Generator start/stop"); value: 1 }, - MbOption { description: qsTr("Tank pump"); value: 3 }, - MbOption { description: qsTr("Manual"); value: 2 } - ] - } - - MbItemOptions { - description: qsTr("Alarm relay polarity") - bind: Utils.path(bindPrefix, "/Settings/Relay/Polarity") - show: relayFunction.value === 0 - possibleValues: [ - MbOption { description: qsTr("Normally open"); value: 0 }, - MbOption { description: qsTr("Normally closed"); value: 1 } - ] - } - - MbSwitch { - id: relaySwitch - // Use a one-way binding, because the usual binding: - // checked: Relay.relayOn - // will be broken when the switched toggled, and changes in the relayOn property made - // elsewhere will not change the state of the switch any more. - Binding { - target: relaySwitch - property: "checked" - value: Relay.relayOn - when: true - } - enabled: userHasWriteAccess - name: qsTr("Alarm relay On") - onCheckedChanged: Relay.relayOn = checked; - show: relayFunction.value === 0 - } - - MbSwitch { - id: manualSwitch - name: hasRelay1 ? qsTr("Relay 1 On") : qsTr("Relay On") - bind: "com.victronenergy.system/Relay/0/State" - show: relayFunction.value === 2 // manual mode - } - - MbSwitch { - id: manualSwitch1 - name: qsTr("Relay 2 On") - bind: "com.victronenergy.system/Relay/1/State" - show: hasRelay1 - } - } -} diff --git a/FileSets/v2.73/PowerGauge.qml b/FileSets/v2.73/PowerGauge.qml deleted file mode 100644 index 40002f55..00000000 --- a/FileSets/v2.73/PowerGauge.qml +++ /dev/null @@ -1,319 +0,0 @@ -// displays value as a bar surrounded by three range regions -// use for I/O, PV inverter & charger - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 - -Item { - id: root - -////// GuiMods — DarkMode - property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } - property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 - - property variant connection - // connection2 accommodates combined PV inverter AC input and AC output - property variant connection2: undefined - property bool includeConnection2: connection2 != undefined - - - property bool reversePower: false - property bool useInputCurrentLimit: false - property variant endLabelFontSize: 16 - property color endLabelBackgroundColor: "transparent" - - property int phaseCount1: root.connection == undefined ? 0 : root.connection.l1AndL2OutShorted ? 1 : connection.phaseCount != undefined && connection.phaseCount.valid ? connection.phaseCount.value : 1 - property int phaseCount2: root.connection2 == undefined ? 0 : root.connection2.l1AndL2OutShorted ? 1 : connection2.phaseCount != undefined && connection2.phaseCount.valid ? connection2.phaseCount.value : 1 - - property int phaseCount: includeConnection2 ? Math.max (phaseCount1, phaseCount2) : phaseCount1 - - - property string maxForwardPowerParameter: "" - VBusItem { id: maxForwardLimitItem; bind: root.maxForwardPowerParameter } - property string maxForwardPowerParameter2: "" - VBusItem { id: maxForwardLimitItem2; bind: root.maxForwardPowerParameter2 } - - property string maxReversePowerParameter: "" - VBusItem { id: maxReverseLimitItem; bind: root.maxReversePowerParameter } - - property real inPowerLimit: sys.acInput.inCurrentLimit.valid ? sys.acInput.inCurrentLimit.value * sys.acInput.voltageL1.value : 0 - - property real maxForwardPower1: maxForwardLimitItem.valid ? maxForwardLimitItem.value : 0 - property real maxForwardPower2: maxForwardLimitItem2.valid ? maxForwardLimitItem2.value : 0 - property real maxForwardLimit: useInputCurrentLimit ? inPowerLimit : maxForwardPower1 + maxForwardPower2 - property real maxReverseLimit: maxReverseLimitItem.valid ? maxReverseLimitItem.value : 0 - // overload range is 10% of forward to reverse limits - property real overload: (maxForwardLimit + maxReverseLimit) * 0.1 - property real maxForwardDisplayed: maxForwardLimit > 0 ? maxForwardLimit + overload : 0 - property real maxReverseDisplayed: maxReverseLimit > 0 ? maxReverseLimit + overload : 0 - property real totalPowerDisplayed: maxForwardDisplayed + maxReverseDisplayed - - property bool showLabels: false - property variant endLabelColor: "white" - property real labelOffset: 15 - property real showLeftLabel: showGauge && showLabels && maxReverseLimit != 0 - property bool showRightLabel: showGauge && showLabels && maxForwardLimit != 0 - property int labelCount: (showLeftLabel ? 1 : 0) + (showRightLabel ? 1 : 0) - - property bool showGauge: root.connection != undefined && totalPowerDisplayed > 0 && phaseCount > 0 - property real scaleFactor: showGauge ? (root.width - (labelCount * labelOffset)) / totalPowerDisplayed : 0 - property real zeroOffset: showGauge ? ( maxReverseDisplayed * scaleFactor + (showLeftLabel ? labelOffset : 0 )) : 0 - - property int barSpacing: phaseCount > 0 ? Math.max (height / (phaseCount + 1), 2) : 0 - property int barHeight: barSpacing < 3 ? barSpacing : barSpacing - 1 - property int firstBarVertPos: (height - barSpacing * phaseCount) / 2 - property real bar1offset - property real bar2offset - property real bar3offset - - property color bar1color: "black" - property color bar2color: "black" - property color bar3color: "black" - - // left end label - Rectangle - { - anchors.fill: leftlabelText - color: endLabelBackgroundColor - visible: showLeftLabel - } - TileText - { - id: leftlabelText - text: "S" - color: endLabelColor - font.pixelSize: endLabelFontSize - width: labelOffset - anchors - { - verticalCenter: root.verticalCenter - verticalCenterOffset: 1 - left: root.left - } - visible: showLeftLabel - } - // right end label - Rectangle - { - anchors.fill: rightLabelText - color: endLabelBackgroundColor - visible: showRightLabel - } - TileText - { - id: rightLabelText - text: "C" - color: endLabelColor - font.pixelSize: endLabelFontSize - width: labelOffset - anchors - { - verticalCenter: leftlabelText.verticalCenter - right: root.right - } - visible: showRightLabel - } - // overload range Left - Rectangle - { - id: overloadLeft - width: showGauge ? scaleFactor * (maxReverseDisplayed - maxReverseLimit) : 0 - height: root.height - clip: true -////// GuiMods — DarkMode - color: !darkMode ? "#ffb3b3" : "#bf8686" - visible: showGauge - anchors - { - top: root.top - left: root.left; leftMargin: showLeftLabel ? labelOffset : 0 - } - } - // OK range (both left and right in a single rectangle) - Rectangle - { - id: okRange - width: showGauge ? scaleFactor * (maxForwardLimit + maxReverseLimit) : 0 - height: root.height - clip: true -////// GuiMods — DarkMode - color: !darkMode ? "#99ff99" : "#73bf73" - visible: showGauge - anchors - { - top: root.top - left: overloadLeft.right - } - } - // overload range right - Rectangle - { - id: overloadRight - width: showGauge ? scaleFactor * (maxForwardDisplayed - maxForwardLimit) : 0 - height: root.height - clip: true -////// GuiMods — DarkMode - color: !darkMode ? "#ffb3b3" : "#bf8686" - visible: showGauge - anchors - { - top: root.top - left: okRange.right - } - } - - // actual bars - Rectangle - { - id: bar1 - width: phaseCount >= 1 ? calculateBar1width () : 0 - height: barHeight - clip: true - color: root.bar1color - anchors - { - top: root.top; topMargin: firstBarVertPos - left: root.left; leftMargin: root.bar1offset - - } - visible: showGauge && phaseCount >= 1 - } - Rectangle - { - id: bar2 - width: phaseCount >= 2 ? calculateBar2width () : 0 - height: barHeight - clip: true - color: root.bar2color - anchors - { - top: root.top; topMargin: firstBarVertPos + barSpacing - left: root.left; leftMargin: root.bar2offset - } - visible: showGauge && phaseCount >= 2 - } - Rectangle - { - id: bar3 - width: phaseCount >= 3 ? calculateBar3width () : 0 - height: barHeight - clip: true - color: root.bar3color - anchors - { - top: root.top; topMargin: firstBarVertPos + barSpacing * 2 - left: root.left; leftMargin: root.bar3offset - } - visible: showGauge && phaseCount >= 3 - } - - // zero line - draw last so it's on top - Rectangle - { - id: zeroLine - width: 1 - height: root.height - clip: true - color: "black" - visible: showGauge && maxReverseLimit > 0 - anchors - { - top: root.top - left: root.left - leftMargin: zeroOffset - } - } - - function calculateBar1width () - { - var currentValue = 0.0, barWidth - if (root.connection.powerL1 != undefined) - currentValue += root.connection.powerL1.valid ? root.connection.powerL1.value : 0 - else if (root.connection.power != undefined) - currentValue += root.connection.power.valid ? root.connection.power.value : 0 - if (includeConnection2) - { - if (root.connection2.powerL1 != undefined) - currentValue += root.connection2.powerL1.valid ? root.connection2.powerL1.value : 0 - else if (root.connection2.power != undefined) - currentValue += root.connection2.power.valid ? root.connection2.power.value : 0 - } - - if (reversePower) - currentValue = -currentValue - - root.bar1color = getBarColor (currentValue) - barWidth = Math.min ( Math.max (currentValue, -maxReverseDisplayed), maxForwardDisplayed) * scaleFactor - // left of bar is at 0 point - if (barWidth >= 0) - { - root.bar1offset = zeroOffset - return barWidth - } - // RIGHT of bar is at 0 point - else - { - root.bar1offset = zeroOffset + barWidth - return -barWidth - } - } - function calculateBar2width () - { - var currentValue, barWidth - currentValue = root.connection.powerL2.valid ? root.connection.powerL2.value : 0 - if (includeConnection2) - currentValue += root.connection2.powerL2.valid ? root.connection2.powerL2.value : 0 - - if (reversePower) - currentValue = -currentValue - root.bar2color = getBarColor (currentValue) - barWidth = Math.min ( Math.max (currentValue, -maxReverseDisplayed), maxForwardDisplayed) * scaleFactor - // left of bar is at 0 point - if (barWidth >= 0) - { - root.bar2offset = zeroOffset - return barWidth - } - // RIGHT of bar is at 0 point - else - { - root.bar2offset = zeroOffset + barWidth - return -barWidth - } - } - function calculateBar3width () - { - var currentValue, barWidth - currentValue = root.connection.powerL3.valid ? root.connection.powerL3.value : 0 - if (includeConnection2) - currentValue += root.connection2.powerL3.valid ? root.connection2.powerL3.value : 0 - - if (reversePower) - currentValue = -currentValue - root.bar3color = getBarColor (currentValue) - barWidth = Math.min ( Math.max (currentValue, -maxReverseDisplayed), maxForwardDisplayed) * scaleFactor - // left of bar is at 0 point - if (barWidth >= 0) - { - root.bar3offset = zeroOffset - return barWidth - } - // RIGHT of bar is at 0 point - else - { - root.bar3offset = zeroOffset + barWidth - return -barWidth - } - } - - function getBarColor (currentValue) - { - if (currentValue > maxForwardLimit || currentValue < -maxReverseLimit) -////// GuiMods — DarkMode - return !darkMode ? "#ff0000" : "#bf0000" - else -////// GuiMods — DarkMode - return !darkMode ? "#008000" : "#006000" - } -} diff --git a/FileSets/v2.73/PowerGauge.qml.orig b/FileSets/v2.73/PowerGauge.qml.orig deleted file mode 100644 index fa82295c..00000000 --- a/FileSets/v2.73/PowerGauge.qml.orig +++ /dev/null @@ -1,142 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -Item { - id: root - - property string systemPrefix: "com.victronenergy.system" - property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" - - property variant battery: _battery - property alias dcSystem: _dcSystem - property alias pvCharger: _pvCharger - property alias pvOnAcIn1: _pvOnAcIn1 - property alias pvOnAcIn2: _pvOnAcIn2 - property alias pvOnAcOut: _pvOnAcOut - property alias vebusDc: _vebusDc - property alias acLoad: _acLoad - property alias acInLoad: _acInLoad - property alias acOutLoad: _acOutLoad - property alias grid: _grid - property alias genset: _genset - property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } - property variant acSource: _acSource.value - - property alias pvOnGrid: _pvOnAcIn2 - property variant acInput: (acSource === acSourceGenset ? _genset : - (acSource === acSourceGrid || acSource === acSourceShore ? _grid : - _acUnknown)) - - property int batteryStateIdle: 0 - property int batteryStateCharging: 1 - property int batteryStateDischarging: 2 - - property int acSourceNotAvailable: 0 - property int acSourceGrid: 1 - property int acSourceGenset: 2 - property int acSourceShore: 3 // same as grid - - property alias pvInvertersProductIds: _pvInvertersProductIds - property alias batteryProductId: _batteryProductId - - VBusItem { - id: _pvInvertersProductIds - bind: Utils.path(systemPrefix, "/PvInvertersProductIds") - } - - VBusItem { - id: _batteryProductId - bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") - } - - VBusItem { - id: _vebusService - bind: Utils.path(systemPrefix, "/VebusService") - } - - QtObject { - id: _pvCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} - } - - ObjectAcConnection { - id: _pvOnAcOut - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") - } - - ObjectAcConnection { - id: _pvOnAcIn1 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") - } - - ObjectAcConnection { - id: _pvOnAcIn2 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") - } - - ObjectAcConnection { - id: _genset - bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") - } - - VBusItem { - id: _acSource - bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") - } - - ObjectAcConnection { - id: _grid - bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") - } - - ObjectAcConnection { - id: _acLoad - bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") - } - - ObjectAcConnection { - id: _acOutLoad - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") - } - - ObjectAcConnection { - id: _acInLoad - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") - } - - ObjectAcConnection { - id: _acUnknown - } - - QtObject { - id: _vebusDc - /* - * property VBusItem power: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Power"); unit: "W"} - * DONE: can interface doesn't support this yet! TODO use it...? - */ - property VBusItem current: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Current"); unit: "A"} - property VBusItem voltage: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Voltage"); unit: "V"} - property VBusItem power: VBusItem { - value: _vebusDc.current.valid && _vebusDc.voltage.valid ? - _vebusDc.current.value * _vebusDc.voltage.value : - undefined - unit: "W" - } - } - - QtObject { - id: _battery - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} - property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} - property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} - property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} - - // Get the battery charge state, see batteryState properties - property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} - } - - QtObject { - id: _dcSystem - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} - } -} diff --git a/FileSets/v2.73/Tile.qml b/FileSets/v2.73/Tile.qml deleted file mode 120000 index aa80e332..00000000 --- a/FileSets/v2.73/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/Tile.qml \ No newline at end of file diff --git a/FileSets/v2.73/TileDigIn.qml b/FileSets/v2.73/TileDigIn.qml deleted file mode 100644 index 5a107e0d..00000000 --- a/FileSets/v2.73/TileDigIn.qml +++ /dev/null @@ -1,131 +0,0 @@ -// New for GuiMods to display digital inputs -// based on TileTank.qml - -import QtQuick 1.1 -import "utils.js" as Utils -import "tanksensor.js" as TankSensor - -Tile { - id: root - - property string bindPrefix: serviceName - property VBusItem nameItem: VBusItem { bind: Utils.path(bindPrefix, "/CustomName") } - property VBusItem deviceItem: VBusItem { bind: Utils.path(bindPrefix, "/DeviceInstance") } - property VBusItem aggregateItem: VBusItem { bind: Utils.path(bindPrefix, "/Aggregate") } - property string digInName: nameItem.valid && nameItem.value != "" ? nameItem.value : getType (type) - property VBusItem typeItem: VBusItem { bind: Utils.path(bindPrefix, "/Type") } - property VBusItem stateItem: VBusItem { bind: Utils.path(bindPrefix, "/State") } - property bool isPulseCounter: aggregateItem.valid - // pulse counter doesn't have /Type so fill it in here - property int type: isPulseCounter ? 1 : typeItem.valid ? typeItem.value : 0 - - property variant bkgdColors: [ "#b3b3b3", "#4aa3df", "#1abc9c", "#F39C12", "#95a5a6", "#95a5a6","#dcc6e0", "#f1a9a0", "#7f8c8d", "#ebbc3a" ] - property color bkgdColor: type > 0 && type < 10 ? bkgdColors [type] : "#b3b3b3" - property variant units: ["m3", "L", "gal", "gal"] - - - function getType(type) - { - switch (type) - { - case 0: - return qsTr("Disabled") - case 1: - return qsTr("Pulse meter") - case 2: - return qsTr("Door alarm") - case 3: - return qsTr("Bilge pump") - case 4: - return qsTr("Bilge alarm") - case 5: - return qsTr("Burglar alarm") - case 6: - return qsTr("Smoke alarm") - case 7: - return qsTr("Fire alarm") - case 8: - return qsTr("CO2 alarm") - case 9: - return qsTr("Generator") - case 10: - return qsTr("Generic I/O") -//// added for ExtTransferSwitch package - case 11: - return qsTr("Transfer switch") - default: - return "Unknown" - } - } - - function getState(st) - { - switch (st) - { - case 0: - return qsTr("Low") - case 1: - return qsTr("High") - case 2: - return qsTr("Off") - case 3: - return qsTr("On") - case 4: - return qsTr("No") - case 5: - return qsTr("Yes") - case 6: - return qsTr("Open") - case 7: - return qsTr("Closed") - case 8: - return qsTr("Ok") - case 9: - return qsTr("Alarm") - case 10: - return qsTr("Running") - case 11: - return qsTr("Stopped") -//// added for ExtTransferSwitch package - case 12: - return qsTr("On Generator") - case 13: - return qsTr("On Grid") - default: - return qsTr("Unknown") - } - - } - - title: digInName + " (In " + (deviceItem.valid ? (deviceItem.value.toString ()) : "?") + ")" - - color: bkgdColor - - VBusItem - { - id: unitItem - bind: Utils.path("com.victronenergy.settings/Settings/System/VolumeUnit") - } - - values: Item - { - width: root.width - 10 - height: 12 - TileText - { - width: root.width - text: - { - if (isPulseCounter) - return aggregateItem.value.toString() + (unitItem.valid ? units[unitItem.value] : "??") - else - return stateItem.valid ? getState (stateItem.value) : "??" - } - horizontalAlignment: Text.AlignHCenter - anchors - { - horizontalCenter: parent.horizontalCenter - } - } - } -} diff --git a/FileSets/v2.73/TileDigIn.qml.orig b/FileSets/v2.73/TileDigIn.qml.orig deleted file mode 100755 index c675ae4f..00000000 --- a/FileSets/v2.73/TileDigIn.qml.orig +++ /dev/null @@ -1,537 +0,0 @@ -#!/usr/bin/python -u - -import sys, os -import signal -from threading import Thread -from select import select, epoll, EPOLLPRI -from functools import partial -from collections import namedtuple -from argparse import ArgumentParser -import traceback -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) - -from dbus.mainloop.glib import DBusGMainLoop -import dbus -import gobject -from vedbus import VeDbusService -from settingsdevice import SettingsDevice - -VERSION = '0.11' -MAXCOUNT = 2**31-1 -SAVEINTERVAL = 60000 - -INPUT_FUNCTION_COUNTER = 1 -INPUT_FUNCTION_INPUT = 2 - -Translation = namedtuple('Translation', ['no', 'yes']) - -# Only append at the end -INPUTTYPES = [ - 'Disabled', - 'Pulse meter', - 'Door', - 'Bilge pump', - 'Bilge alarm', - 'Burglar alarm', - 'Smoke alarm', - 'Fire alarm', - 'CO2 alarm', - 'Generator' -] - -# Translations. The text will be used only for GetText, it will be translated -# in the gui. -TRANSLATIONS = [ - Translation('low', 'high'), - Translation('off', 'on'), - Translation('no', 'yes'), - Translation('open', 'closed'), - Translation('ok', 'alarm'), - Translation('running', 'stopped') -] - -class SystemBus(dbus.bus.BusConnection): - def __new__(cls): - return dbus.bus.BusConnection.__new__(cls, dbus.bus.BusConnection.TYPE_SYSTEM) - -class SessionBus(dbus.bus.BusConnection): - def __new__(cls): - return dbus.bus.BusConnection.__new__(cls, dbus.bus.BusConnection.TYPE_SESSION) - -class BasePulseCounter(object): - pass - -class DebugPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - - def register(self, path, gpio): - self.gpiomap[gpio] = None - return 0 - - def unregister(self, gpio): - del self.gpiomap[gpio] - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - from itertools import cycle - from time import sleep - for level in cycle([0, 1]): - gpios = self.gpiomap.keys() - for gpio in gpios: - yield gpio, level - sleep(0.25/len(self.gpiomap)) - -class EpollPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - self.states = {} - self.ob = epoll() - - def register(self, path, gpio): - path = os.path.realpath(path) - - # Set up gpio for rising edge interrupts - with open(os.path.join(path, 'edge'), 'ab') as fp: - fp.write('both') - - fp = open(os.path.join(path, 'value'), 'rb') - level = int(fp.read()) # flush it in case it's high at startup - self.gpiomap[gpio] = fp - self.states[gpio] = level - self.ob.register(fp, EPOLLPRI) - return level - - def unregister(self, gpio): - fp = self.gpiomap[gpio] - self.ob.unregister(fp) - del self.gpiomap[gpio] - del self.states[gpio] - fp.close() - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - while True: - # We have a timeout of 1 second on the poll, because poll() only - # looks at files in the epoll object at the time poll() was called. - # The timeout means we let other files (added via calls to - # register/unregister) into the loop at least that often. - self.ob.poll(1) - - # When coming out of the epoll call, we read all the gpios to make - # sure we didn't miss any edges. This is a safety fallback that - # ensures everything is up to date once a second, but - # edge-triggered results are handled immediately. - # NOTE: There has not been a report of a missed interrupt yet. - # Belts and suspenders. - for gpio, fp in self.gpiomap.iteritems(): - os.lseek(fp.fileno(), 0, os.SEEK_SET) - v = int(os.read(fp.fileno(), 1)) - if v != self.states[gpio]: - self.states[gpio] = v - yield gpio, v - -class PollingPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - - def register(self, path, gpio): - path = os.path.realpath(path) - - fp = open(os.path.join(path, 'value'), 'rb') - level = int(fp.read()) - self.gpiomap[gpio] = [fp, level] - return level - - def unregister(self, gpio): - del self.gpiomap[gpio] - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - from itertools import cycle - from time import sleep - while True: - for gpio, (fp, level) in self.gpiomap.iteritems(): - fp.seek(0, os.SEEK_SET) - v = int(fp.read()) - if v != level: - self.gpiomap[gpio][1] = v - yield gpio, v - sleep(1) - -class HandlerMaker(type): - """ Meta-class for keeping track of all extended classes. """ - def __init__(cls, name, bases, attrs): - if not hasattr(cls, 'handlers'): - cls.handlers = {} - else: - cls.handlers[cls.type_id] = cls - -class PinHandler(object): - product_id = 0xFFFF - _product_name = 'Generic GPIO' - dbus_name = "digital" - __metaclass__ = HandlerMaker - def __init__(self, bus, base, path, gpio, settings): - self.gpio = gpio - self.path = path - self.bus = bus - self.settings = settings - self._level = 0 # Remember last state - - self.service = VeDbusService( - "{}.{}.input{:02d}".format(base, self.dbus_name, gpio), bus=bus) - - # Add objects required by ve-api - self.service.add_path('/Mgmt/ProcessName', __file__) - self.service.add_path('/Mgmt/ProcessVersion', VERSION) - self.service.add_path('/Mgmt/Connection', path) - self.service.add_path('/DeviceInstance', gpio) - self.service.add_path('/ProductId', self.product_id) - self.service.add_path('/ProductName', self.product_name) - self.service.add_path('/Connected', 1) - - # Custom name setting - def _change_name(p, v): - # This should fire a change event that will update product_name - # below. - settings['name'] = v - return True - - self.service.add_path('/CustomName', settings['name'], writeable=True, - onchangecallback=_change_name) - - # We'll count the pulses for all types of services - self.service.add_path('/Count', value=settings['count']) - - @property - def product_name(self): - return self.settings['name'] or self._product_name - - @product_name.setter - def product_name(self, v): - # Some pin types don't have an associated service (Disabled pins for - # example) - if self.service is not None: - self.service['/ProductName'] = v or self._product_name - - def deactivate(self): - self.save_count() - self.service.__del__() - del self.service - self.service = None - - @property - def level(self): - return self._level - - @level.setter - def level(self, l): - self._level = int(bool(l)) - - def toggle(self, level): - # Only increment Count on rising edge. - if level and level != self._level: - self.service['/Count'] = (self.service['/Count']+1) % MAXCOUNT - self._level = level - - def refresh(self): - """ Toggle state to last remembered state. This is called if settings - are changed so the Service can recalculate paths. """ - self.toggle(self._level) - - def save_count(self): - if self.service is not None: - self.settings['count'] = self.count - - @property - def active(self): - return self.service is not None - - @property - def count(self): - return self.service['/Count'] - - @count.setter - def count(self, v): - self.service['/Count'] = v - - @classmethod - def createHandler(cls, _type, *args, **kwargs): - if _type in cls.handlers: - return cls.handlers[_type](*args, **kwargs) - return None - - -class DisabledPin(PinHandler): - """ Place holder for a disabled pin. """ - _product_name = 'Disabled' - type_id = 0 - def __init__(self, bus, base, path, gpio, settings): - self.service = None - self.bus = bus - self.settings = settings - self._level = 0 # Remember last state - - def deactivate(self): - pass - - def toggle(self, level): - self._level = level - - def save_count(self): - # Do nothing - pass - - @property - def count(self): - return self.settings['count'] - - @count.setter - def count(self, v): - pass - - def refresh(self): - pass - - -class VolumeCounter(PinHandler): - product_id = 0xA165 - _product_name = "Generic pulse meter" - dbus_name = "pulsemeter" - type_id = 1 - - def __init__(self, bus, base, path, gpio, settings): - super(VolumeCounter, self).__init__(bus, base, path, gpio, settings) - self.service.add_path('/Aggregate', value=self.count*self.rate, - gettextcallback=lambda p, v: (str(v) + ' cubic meter')) - - @property - def rate(self): - return self.settings['rate'] - - def toggle(self, level): - super(VolumeCounter, self).toggle(level) - self.service['/Aggregate'] = self.count * self.rate - -class PinAlarm(PinHandler): - product_id = 0xA166 - _product_name = "Generic digital input" - dbus_name = "digitalinput" - type_id = 0xFF - translation = 0 # low, high - - def __init__(self, bus, base, path, gpio, settings): - super(PinAlarm, self).__init__(bus, base, path, gpio, settings) - self.service.add_path('/InputState', value=0) - self.service.add_path('/State', value=self.get_state(0), - gettextcallback=lambda p, v: TRANSLATIONS[v/2][v%2]) - self.service.add_path('/Alarm', value=self.get_alarm_state(0)) - - # Also expose the type - self.service.add_path('/Type', value=self.type_id, - gettextcallback=lambda p, v: INPUTTYPES[v]) - - def toggle(self, level): - super(PinAlarm, self).toggle(level) - self.service['/InputState'] = bool(level)*1 - self.service['/State'] = self.get_state(level) - # Ensure that the alarm flag resets if the /AlarmSetting config option - # disappears. - self.service['/Alarm'] = self.get_alarm_state(level) - - def get_state(self, level): - state = level ^ self.settings['invert'] - return 2 * self.translation + state - - def get_alarm_state(self, level): - return 2 * bool( - (level ^ self.settings['invertalarm']) and self.settings['alarm']) - - -# Various types of things we might want to monitor -class DoorSensor(PinAlarm): - _product_name = "Door alarm" - type_id = 2 - translation = 3 # open, closed - -class BilgePump(PinAlarm): - _product_name = "Bilge pump" - type_id = 3 - translation = 1 # off, on - -class BilgeAlarm(PinAlarm): - _product_name = "Bilge alarm" - type_id = 4 - translation = 4 # ok, alarm - -class BurglarAlarm(PinAlarm): - _product_name = "Burglar alarm" - type_id = 5 - translation = 4 # ok, alarm - -class SmokeAlarm(PinAlarm): - _product_name = "Smoke alarm" - type_id = 6 - translation = 4 # ok, alarm - -class FireAlarm(PinAlarm): - _product_name = "Fire alarm" - type_id = 7 - translation = 4 # ok, alarm - -class CO2Alarm(PinAlarm): - _product_name = "CO2 alarm" - type_id = 8 - translation = 4 # ok, alarm - -class Generator(PinAlarm): - _product_name = "Generator" - type_id = 9 - translation = 5 # running, stopped - - -def dbusconnection(): - return SessionBus() if 'DBUS_SESSION_BUS_ADDRESS' in os.environ else SystemBus() - - -def main(): - parser = ArgumentParser(description=sys.argv[0]) - parser.add_argument('--servicebase', - help='Base service name on dbus, default is com.victronenergy', - default='com.victronenergy') - parser.add_argument('--poll', - help='Use a different kind of polling. Options are epoll, dumb and debug', - default='epoll') - parser.add_argument('inputs', nargs='+', help='Path to digital input') - args = parser.parse_args() - - PulseCounter = { - 'debug': DebugPulseCounter, - 'poll': PollingPulseCounter, - }.get(args.poll, EpollPulseCounter) - - DBusGMainLoop(set_as_default=True) - - # Keep track of enabled services - services = {} - inputs = dict(enumerate(args.inputs, 1)) - pulses = PulseCounter() # callable that iterates over pulses - - def register_gpio(path, gpio, bus, settings): - _type = settings['inputtype'] - print "Registering GPIO {} for type {}".format(gpio, _type) - - handler = PinHandler.createHandler(_type, - bus, args.servicebase, path, gpio, settings) - services[gpio] = handler - - # Only monitor if enabled - if _type > 0: - handler.level = pulses.register(path, gpio) - handler.refresh() - - def unregister_gpio(gpio): - print "unRegistering GPIO {}".format(gpio) - pulses.unregister(gpio) - services[gpio].deactivate() - - def handle_setting_change(inp, setting, old, new): - if setting == 'inputtype': - if new: - # Get current bus and settings objects, to be reused - service = services[inp] - bus, settings = service.bus, service.settings - - # Input enabled. If already enabled, unregister the old one first. - if pulses.registered(inp): - unregister_gpio(inp) - - # Before registering the new input, reset its settings to defaults - settings['count'] = 0 - settings['invert'] = 0 - settings['invertalarm'] = 0 - settings['alarm'] = 0 - - # Register it - register_gpio(inputs[inp], inp, bus, settings) - elif old: - # Input disabled - unregister_gpio(inp) - elif setting in ('rate', 'invert', 'alarm', 'invertalarm'): - services[inp].refresh() - elif setting == 'name': - services[inp].product_name = new - elif setting == 'count': - # Don't want this triggered on a period save, so only execute - # if it has changed. - v = int(new) - s = services[inp] - if s.count != v: - s.count = v - s.refresh() - - for inp, pth in inputs.items(): - supported_settings = { - 'inputtype': ['/Settings/DigitalInput/{}/Type'.format(inp), 0, 0, len(INPUTTYPES)], - 'rate': ['/Settings/DigitalInput/{}/Multiplier'.format(inp), 0.001, 0, 1.0], - 'count': ['/Settings/DigitalInput/{}/Count'.format(inp), 0, 0, MAXCOUNT, 1], - 'invert': ['/Settings/DigitalInput/{}/InvertTranslation'.format(inp), 0, 0, 1], - 'invertalarm': ['/Settings/DigitalInput/{}/InvertAlarm'.format(inp), 0, 0, 1], - 'alarm': ['/Settings/DigitalInput/{}/AlarmSetting'.format(inp), 0, 0, 1], - 'name': ['/Settings/DigitalInput/{}/CustomName'.format(inp), '', '', ''], - } - bus = dbusconnection() - sd = SettingsDevice(bus, supported_settings, partial(handle_setting_change, inp), timeout=10) - register_gpio(pth, inp, bus, sd) - - def poll(mainloop): - from time import time - idx = 0 - - try: - for inp, level in pulses(): - # epoll object only resyncs once a second. We may receive - # a pulse for something that's been deregistered. - try: - services[inp].toggle(level) - except KeyError: - continue - except: - traceback.print_exc() - mainloop.quit() - - # Need to run the gpio polling in separate thread. Pass in the mainloop so - # the thread can kill us if there is an exception. - gobject.threads_init() - mainloop = gobject.MainLoop() - - poller = Thread(target=lambda: poll(mainloop)) - poller.daemon = True - poller.start() - - # Periodically save the counter - def save_counters(): - for inp in inputs: - services[inp].save_count() - return True - gobject.timeout_add(SAVEINTERVAL, save_counters) - - # Save counter on shutdown - signal.signal(signal.SIGTERM, lambda *args: sys.exit(0)) - - try: - mainloop.run() - except KeyboardInterrupt: - pass - finally: - save_counters() - -if __name__ == "__main__": - main() diff --git a/FileSets/v2.73/TileRelay.qml b/FileSets/v2.73/TileRelay.qml deleted file mode 120000 index 4313882d..00000000 --- a/FileSets/v2.73/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v2.73/TileText.qml b/FileSets/v2.73/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v2.73/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.73/dbus_digitalinputs.py b/FileSets/v2.73/dbus_digitalinputs.py deleted file mode 100755 index 0a9652b0..00000000 --- a/FileSets/v2.73/dbus_digitalinputs.py +++ /dev/null @@ -1,556 +0,0 @@ -#!/usr/bin/python -u - -#### modified for ExtTransferSwitch package - -import sys, os -import signal -from threading import Thread -from select import select, epoll, EPOLLPRI -from functools import partial -from collections import namedtuple -from argparse import ArgumentParser -import traceback -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) - -from dbus.mainloop.glib import DBusGMainLoop -import dbus -import gobject -from vedbus import VeDbusService -from settingsdevice import SettingsDevice - -VERSION = '0.11' -MAXCOUNT = 2**31-1 -SAVEINTERVAL = 60000 - -INPUT_FUNCTION_COUNTER = 1 -INPUT_FUNCTION_INPUT = 2 - -Translation = namedtuple('Translation', ['no', 'yes']) - -# Only append at the end -INPUTTYPES = [ - 'Disabled', - 'Pulse meter', - 'Door', - 'Bilge pump', - 'Bilge alarm', - 'Burglar alarm', - 'Smoke alarm', - 'Fire alarm', - 'CO2 alarm', - 'Generator', -#### added for ExtTransferSwitch package - 'Generic I/O', #added to make following entry line up across versions -#### added for ExtTransferSwitch package -- must be LAST in the list - 'Transfer switch' -] - -# Translations. The text will be used only for GetText, it will be translated -# in the gui. -TRANSLATIONS = [ - Translation('low', 'high'), - Translation('off', 'on'), - Translation('no', 'yes'), - Translation('open', 'closed'), - Translation('ok', 'alarm'), - Translation('running', 'stopped'), -#### added for ExtTransferSwitch package - Translation('on generator', 'on grid') -] - -class SystemBus(dbus.bus.BusConnection): - def __new__(cls): - return dbus.bus.BusConnection.__new__(cls, dbus.bus.BusConnection.TYPE_SYSTEM) - -class SessionBus(dbus.bus.BusConnection): - def __new__(cls): - return dbus.bus.BusConnection.__new__(cls, dbus.bus.BusConnection.TYPE_SESSION) - -class BasePulseCounter(object): - pass - -class DebugPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - - def register(self, path, gpio): - self.gpiomap[gpio] = None - return 0 - - def unregister(self, gpio): - del self.gpiomap[gpio] - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - from itertools import cycle - from time import sleep - for level in cycle([0, 1]): - gpios = self.gpiomap.keys() - for gpio in gpios: - yield gpio, level - sleep(0.25/len(self.gpiomap)) - -class EpollPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - self.states = {} - self.ob = epoll() - - def register(self, path, gpio): - path = os.path.realpath(path) - - # Set up gpio for rising edge interrupts - with open(os.path.join(path, 'edge'), 'ab') as fp: - fp.write('both') - - fp = open(os.path.join(path, 'value'), 'rb') - level = int(fp.read()) # flush it in case it's high at startup - self.gpiomap[gpio] = fp - self.states[gpio] = level - self.ob.register(fp, EPOLLPRI) - return level - - def unregister(self, gpio): - fp = self.gpiomap[gpio] - self.ob.unregister(fp) - del self.gpiomap[gpio] - del self.states[gpio] - fp.close() - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - while True: - # We have a timeout of 1 second on the poll, because poll() only - # looks at files in the epoll object at the time poll() was called. - # The timeout means we let other files (added via calls to - # register/unregister) into the loop at least that often. - self.ob.poll(1) - - # When coming out of the epoll call, we read all the gpios to make - # sure we didn't miss any edges. This is a safety fallback that - # ensures everything is up to date once a second, but - # edge-triggered results are handled immediately. - # NOTE: There has not been a report of a missed interrupt yet. - # Belts and suspenders. - for gpio, fp in self.gpiomap.iteritems(): - os.lseek(fp.fileno(), 0, os.SEEK_SET) - v = int(os.read(fp.fileno(), 1)) - if v != self.states[gpio]: - self.states[gpio] = v - yield gpio, v - -class PollingPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - - def register(self, path, gpio): - path = os.path.realpath(path) - - fp = open(os.path.join(path, 'value'), 'rb') - level = int(fp.read()) - self.gpiomap[gpio] = [fp, level] - return level - - def unregister(self, gpio): - del self.gpiomap[gpio] - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - from itertools import cycle - from time import sleep - while True: - for gpio, (fp, level) in self.gpiomap.iteritems(): - fp.seek(0, os.SEEK_SET) - v = int(fp.read()) - if v != level: - self.gpiomap[gpio][1] = v - yield gpio, v - sleep(1) - -class HandlerMaker(type): - """ Meta-class for keeping track of all extended classes. """ - def __init__(cls, name, bases, attrs): - if not hasattr(cls, 'handlers'): - cls.handlers = {} - else: - cls.handlers[cls.type_id] = cls - -class PinHandler(object): - product_id = 0xFFFF - _product_name = 'Generic GPIO' - dbus_name = "digital" - __metaclass__ = HandlerMaker - def __init__(self, bus, base, path, gpio, settings): - self.gpio = gpio - self.path = path - self.bus = bus - self.settings = settings - self._level = 0 # Remember last state - - self.service = VeDbusService( - "{}.{}.input{:02d}".format(base, self.dbus_name, gpio), bus=bus) - - # Add objects required by ve-api - self.service.add_path('/Mgmt/ProcessName', __file__) - self.service.add_path('/Mgmt/ProcessVersion', VERSION) - self.service.add_path('/Mgmt/Connection', path) - self.service.add_path('/DeviceInstance', gpio) - self.service.add_path('/ProductId', self.product_id) - self.service.add_path('/ProductName', self.product_name) - self.service.add_path('/Connected', 1) - - # Custom name setting - def _change_name(p, v): - # This should fire a change event that will update product_name - # below. - settings['name'] = v - return True - - self.service.add_path('/CustomName', settings['name'], writeable=True, - onchangecallback=_change_name) - - # We'll count the pulses for all types of services - self.service.add_path('/Count', value=settings['count']) - - @property - def product_name(self): - return self.settings['name'] or self._product_name - - @product_name.setter - def product_name(self, v): - # Some pin types don't have an associated service (Disabled pins for - # example) - if self.service is not None: - self.service['/ProductName'] = v or self._product_name - - def deactivate(self): - self.save_count() - self.service.__del__() - del self.service - self.service = None - - @property - def level(self): - return self._level - - @level.setter - def level(self, l): - self._level = int(bool(l)) - - def toggle(self, level): - # Only increment Count on rising edge. - if level and level != self._level: - self.service['/Count'] = (self.service['/Count']+1) % MAXCOUNT - self._level = level - - def refresh(self): - """ Toggle state to last remembered state. This is called if settings - are changed so the Service can recalculate paths. """ - self.toggle(self._level) - - def save_count(self): - if self.service is not None: - self.settings['count'] = self.count - - @property - def active(self): - return self.service is not None - - @property - def count(self): - return self.service['/Count'] - - @count.setter - def count(self, v): - self.service['/Count'] = v - - @classmethod - def createHandler(cls, _type, *args, **kwargs): - if _type in cls.handlers: - return cls.handlers[_type](*args, **kwargs) - return None - - -class DisabledPin(PinHandler): - """ Place holder for a disabled pin. """ - _product_name = 'Disabled' - type_id = 0 - def __init__(self, bus, base, path, gpio, settings): - self.service = None - self.bus = bus - self.settings = settings - self._level = 0 # Remember last state - - def deactivate(self): - pass - - def toggle(self, level): - self._level = level - - def save_count(self): - # Do nothing - pass - - @property - def count(self): - return self.settings['count'] - - @count.setter - def count(self, v): - pass - - def refresh(self): - pass - - -class VolumeCounter(PinHandler): - product_id = 0xA165 - _product_name = "Generic pulse meter" - dbus_name = "pulsemeter" - type_id = 1 - - def __init__(self, bus, base, path, gpio, settings): - super(VolumeCounter, self).__init__(bus, base, path, gpio, settings) - self.service.add_path('/Aggregate', value=self.count*self.rate, - gettextcallback=lambda p, v: (str(v) + ' cubic meter')) - - @property - def rate(self): - return self.settings['rate'] - - def toggle(self, level): - super(VolumeCounter, self).toggle(level) - self.service['/Aggregate'] = self.count * self.rate - -class PinAlarm(PinHandler): - product_id = 0xA166 - _product_name = "Generic digital input" - dbus_name = "digitalinput" - type_id = 0xFF - translation = 0 # low, high - - def __init__(self, bus, base, path, gpio, settings): - super(PinAlarm, self).__init__(bus, base, path, gpio, settings) - self.service.add_path('/InputState', value=0) - self.service.add_path('/State', value=self.get_state(0), - gettextcallback=lambda p, v: TRANSLATIONS[v/2][v%2]) - self.service.add_path('/Alarm', value=self.get_alarm_state(0)) - - # Also expose the type - self.service.add_path('/Type', value=self.type_id, - gettextcallback=lambda p, v: INPUTTYPES[v]) - - def toggle(self, level): - super(PinAlarm, self).toggle(level) - self.service['/InputState'] = bool(level)*1 - self.service['/State'] = self.get_state(level) - # Ensure that the alarm flag resets if the /AlarmSetting config option - # disappears. - self.service['/Alarm'] = self.get_alarm_state(level) - - def get_state(self, level): - state = level ^ self.settings['invert'] - return 2 * self.translation + state - - def get_alarm_state(self, level): - return 2 * bool( - (level ^ self.settings['invertalarm']) and self.settings['alarm']) - - -# Various types of things we might want to monitor -class DoorSensor(PinAlarm): - _product_name = "Door alarm" - type_id = 2 - translation = 3 # open, closed - -class BilgePump(PinAlarm): - _product_name = "Bilge pump" - type_id = 3 - translation = 1 # off, on - -class BilgeAlarm(PinAlarm): - _product_name = "Bilge alarm" - type_id = 4 - translation = 4 # ok, alarm - -class BurglarAlarm(PinAlarm): - _product_name = "Burglar alarm" - type_id = 5 - translation = 4 # ok, alarm - -class SmokeAlarm(PinAlarm): - _product_name = "Smoke alarm" - type_id = 6 - translation = 4 # ok, alarm - -class FireAlarm(PinAlarm): - _product_name = "Fire alarm" - type_id = 7 - translation = 4 # ok, alarm - -class CO2Alarm(PinAlarm): - _product_name = "CO2 alarm" - type_id = 8 - translation = 4 # ok, alarm - -class Generator(PinAlarm): - _product_name = "Generator" - type_id = 9 - translation = 5 # running, stopped - -#### added for ExtTransferSwitch package -class GenericIO(PinAlarm): - _product_name = "Generic I/O" - type_id = 10 - translation = 0 # low, high - -class TransferSwitch(PinAlarm): - _product_name = "External AC Input transfer switch" - type_id = 11 - translation = 5 # Grid In / Generator In - - -def dbusconnection(): - return SessionBus() if 'DBUS_SESSION_BUS_ADDRESS' in os.environ else SystemBus() - - -def main(): - parser = ArgumentParser(description=sys.argv[0]) - parser.add_argument('--servicebase', - help='Base service name on dbus, default is com.victronenergy', - default='com.victronenergy') - parser.add_argument('--poll', - help='Use a different kind of polling. Options are epoll, dumb and debug', - default='epoll') - parser.add_argument('inputs', nargs='+', help='Path to digital input') - args = parser.parse_args() - - PulseCounter = { - 'debug': DebugPulseCounter, - 'poll': PollingPulseCounter, - }.get(args.poll, EpollPulseCounter) - - DBusGMainLoop(set_as_default=True) - - # Keep track of enabled services - services = {} - inputs = dict(enumerate(args.inputs, 1)) - pulses = PulseCounter() # callable that iterates over pulses - - def register_gpio(path, gpio, bus, settings): - _type = settings['inputtype'] - print "Registering GPIO {} for type {}".format(gpio, _type) - - handler = PinHandler.createHandler(_type, - bus, args.servicebase, path, gpio, settings) - services[gpio] = handler - - # Only monitor if enabled - if _type > 0: - handler.level = pulses.register(path, gpio) - handler.refresh() - - def unregister_gpio(gpio): - print "unRegistering GPIO {}".format(gpio) - pulses.unregister(gpio) - services[gpio].deactivate() - - def handle_setting_change(inp, setting, old, new): - if setting == 'inputtype': - if new: - # Get current bus and settings objects, to be reused - service = services[inp] - bus, settings = service.bus, service.settings - - # Input enabled. If already enabled, unregister the old one first. - if pulses.registered(inp): - unregister_gpio(inp) - - # Before registering the new input, reset its settings to defaults - settings['count'] = 0 - settings['invert'] = 0 - settings['invertalarm'] = 0 - settings['alarm'] = 0 - - # Register it - register_gpio(inputs[inp], inp, bus, settings) - elif old: - # Input disabled - unregister_gpio(inp) - elif setting in ('rate', 'invert', 'alarm', 'invertalarm'): - services[inp].refresh() - elif setting == 'name': - services[inp].product_name = new - elif setting == 'count': - # Don't want this triggered on a period save, so only execute - # if it has changed. - v = int(new) - s = services[inp] - if s.count != v: - s.count = v - s.refresh() - - for inp, pth in inputs.items(): - supported_settings = { - 'inputtype': ['/Settings/DigitalInput/{}/Type'.format(inp), 0, 0, len(INPUTTYPES)], - 'rate': ['/Settings/DigitalInput/{}/Multiplier'.format(inp), 0.001, 0, 1.0], - 'count': ['/Settings/DigitalInput/{}/Count'.format(inp), 0, 0, MAXCOUNT, 1], - 'invert': ['/Settings/DigitalInput/{}/InvertTranslation'.format(inp), 0, 0, 1], - 'invertalarm': ['/Settings/DigitalInput/{}/InvertAlarm'.format(inp), 0, 0, 1], - 'alarm': ['/Settings/DigitalInput/{}/AlarmSetting'.format(inp), 0, 0, 1], - 'name': ['/Settings/DigitalInput/{}/CustomName'.format(inp), '', '', ''], - } - bus = dbusconnection() - sd = SettingsDevice(bus, supported_settings, partial(handle_setting_change, inp), timeout=10) - register_gpio(pth, inp, bus, sd) - - def poll(mainloop): - from time import time - idx = 0 - - try: - for inp, level in pulses(): - # epoll object only resyncs once a second. We may receive - # a pulse for something that's been deregistered. - try: - services[inp].toggle(level) - except KeyError: - continue - except: - traceback.print_exc() - mainloop.quit() - - # Need to run the gpio polling in separate thread. Pass in the mainloop so - # the thread can kill us if there is an exception. - gobject.threads_init() - mainloop = gobject.MainLoop() - - poller = Thread(target=lambda: poll(mainloop)) - poller.daemon = True - poller.start() - - # Periodically save the counter - def save_counters(): - for inp in inputs: - services[inp].save_count() - return True - gobject.timeout_add(SAVEINTERVAL, save_counters) - - # Save counter on shutdown - signal.signal(signal.SIGTERM, lambda *args: sys.exit(0)) - - try: - mainloop.run() - except KeyboardInterrupt: - pass - finally: - save_counters() - -if __name__ == "__main__": - main() diff --git a/FileSets/v2.73/dbus_digitalinputs.py.orig b/FileSets/v2.73/dbus_digitalinputs.py.orig deleted file mode 100755 index c675ae4f..00000000 --- a/FileSets/v2.73/dbus_digitalinputs.py.orig +++ /dev/null @@ -1,537 +0,0 @@ -#!/usr/bin/python -u - -import sys, os -import signal -from threading import Thread -from select import select, epoll, EPOLLPRI -from functools import partial -from collections import namedtuple -from argparse import ArgumentParser -import traceback -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) - -from dbus.mainloop.glib import DBusGMainLoop -import dbus -import gobject -from vedbus import VeDbusService -from settingsdevice import SettingsDevice - -VERSION = '0.11' -MAXCOUNT = 2**31-1 -SAVEINTERVAL = 60000 - -INPUT_FUNCTION_COUNTER = 1 -INPUT_FUNCTION_INPUT = 2 - -Translation = namedtuple('Translation', ['no', 'yes']) - -# Only append at the end -INPUTTYPES = [ - 'Disabled', - 'Pulse meter', - 'Door', - 'Bilge pump', - 'Bilge alarm', - 'Burglar alarm', - 'Smoke alarm', - 'Fire alarm', - 'CO2 alarm', - 'Generator' -] - -# Translations. The text will be used only for GetText, it will be translated -# in the gui. -TRANSLATIONS = [ - Translation('low', 'high'), - Translation('off', 'on'), - Translation('no', 'yes'), - Translation('open', 'closed'), - Translation('ok', 'alarm'), - Translation('running', 'stopped') -] - -class SystemBus(dbus.bus.BusConnection): - def __new__(cls): - return dbus.bus.BusConnection.__new__(cls, dbus.bus.BusConnection.TYPE_SYSTEM) - -class SessionBus(dbus.bus.BusConnection): - def __new__(cls): - return dbus.bus.BusConnection.__new__(cls, dbus.bus.BusConnection.TYPE_SESSION) - -class BasePulseCounter(object): - pass - -class DebugPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - - def register(self, path, gpio): - self.gpiomap[gpio] = None - return 0 - - def unregister(self, gpio): - del self.gpiomap[gpio] - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - from itertools import cycle - from time import sleep - for level in cycle([0, 1]): - gpios = self.gpiomap.keys() - for gpio in gpios: - yield gpio, level - sleep(0.25/len(self.gpiomap)) - -class EpollPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - self.states = {} - self.ob = epoll() - - def register(self, path, gpio): - path = os.path.realpath(path) - - # Set up gpio for rising edge interrupts - with open(os.path.join(path, 'edge'), 'ab') as fp: - fp.write('both') - - fp = open(os.path.join(path, 'value'), 'rb') - level = int(fp.read()) # flush it in case it's high at startup - self.gpiomap[gpio] = fp - self.states[gpio] = level - self.ob.register(fp, EPOLLPRI) - return level - - def unregister(self, gpio): - fp = self.gpiomap[gpio] - self.ob.unregister(fp) - del self.gpiomap[gpio] - del self.states[gpio] - fp.close() - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - while True: - # We have a timeout of 1 second on the poll, because poll() only - # looks at files in the epoll object at the time poll() was called. - # The timeout means we let other files (added via calls to - # register/unregister) into the loop at least that often. - self.ob.poll(1) - - # When coming out of the epoll call, we read all the gpios to make - # sure we didn't miss any edges. This is a safety fallback that - # ensures everything is up to date once a second, but - # edge-triggered results are handled immediately. - # NOTE: There has not been a report of a missed interrupt yet. - # Belts and suspenders. - for gpio, fp in self.gpiomap.iteritems(): - os.lseek(fp.fileno(), 0, os.SEEK_SET) - v = int(os.read(fp.fileno(), 1)) - if v != self.states[gpio]: - self.states[gpio] = v - yield gpio, v - -class PollingPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - - def register(self, path, gpio): - path = os.path.realpath(path) - - fp = open(os.path.join(path, 'value'), 'rb') - level = int(fp.read()) - self.gpiomap[gpio] = [fp, level] - return level - - def unregister(self, gpio): - del self.gpiomap[gpio] - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - from itertools import cycle - from time import sleep - while True: - for gpio, (fp, level) in self.gpiomap.iteritems(): - fp.seek(0, os.SEEK_SET) - v = int(fp.read()) - if v != level: - self.gpiomap[gpio][1] = v - yield gpio, v - sleep(1) - -class HandlerMaker(type): - """ Meta-class for keeping track of all extended classes. """ - def __init__(cls, name, bases, attrs): - if not hasattr(cls, 'handlers'): - cls.handlers = {} - else: - cls.handlers[cls.type_id] = cls - -class PinHandler(object): - product_id = 0xFFFF - _product_name = 'Generic GPIO' - dbus_name = "digital" - __metaclass__ = HandlerMaker - def __init__(self, bus, base, path, gpio, settings): - self.gpio = gpio - self.path = path - self.bus = bus - self.settings = settings - self._level = 0 # Remember last state - - self.service = VeDbusService( - "{}.{}.input{:02d}".format(base, self.dbus_name, gpio), bus=bus) - - # Add objects required by ve-api - self.service.add_path('/Mgmt/ProcessName', __file__) - self.service.add_path('/Mgmt/ProcessVersion', VERSION) - self.service.add_path('/Mgmt/Connection', path) - self.service.add_path('/DeviceInstance', gpio) - self.service.add_path('/ProductId', self.product_id) - self.service.add_path('/ProductName', self.product_name) - self.service.add_path('/Connected', 1) - - # Custom name setting - def _change_name(p, v): - # This should fire a change event that will update product_name - # below. - settings['name'] = v - return True - - self.service.add_path('/CustomName', settings['name'], writeable=True, - onchangecallback=_change_name) - - # We'll count the pulses for all types of services - self.service.add_path('/Count', value=settings['count']) - - @property - def product_name(self): - return self.settings['name'] or self._product_name - - @product_name.setter - def product_name(self, v): - # Some pin types don't have an associated service (Disabled pins for - # example) - if self.service is not None: - self.service['/ProductName'] = v or self._product_name - - def deactivate(self): - self.save_count() - self.service.__del__() - del self.service - self.service = None - - @property - def level(self): - return self._level - - @level.setter - def level(self, l): - self._level = int(bool(l)) - - def toggle(self, level): - # Only increment Count on rising edge. - if level and level != self._level: - self.service['/Count'] = (self.service['/Count']+1) % MAXCOUNT - self._level = level - - def refresh(self): - """ Toggle state to last remembered state. This is called if settings - are changed so the Service can recalculate paths. """ - self.toggle(self._level) - - def save_count(self): - if self.service is not None: - self.settings['count'] = self.count - - @property - def active(self): - return self.service is not None - - @property - def count(self): - return self.service['/Count'] - - @count.setter - def count(self, v): - self.service['/Count'] = v - - @classmethod - def createHandler(cls, _type, *args, **kwargs): - if _type in cls.handlers: - return cls.handlers[_type](*args, **kwargs) - return None - - -class DisabledPin(PinHandler): - """ Place holder for a disabled pin. """ - _product_name = 'Disabled' - type_id = 0 - def __init__(self, bus, base, path, gpio, settings): - self.service = None - self.bus = bus - self.settings = settings - self._level = 0 # Remember last state - - def deactivate(self): - pass - - def toggle(self, level): - self._level = level - - def save_count(self): - # Do nothing - pass - - @property - def count(self): - return self.settings['count'] - - @count.setter - def count(self, v): - pass - - def refresh(self): - pass - - -class VolumeCounter(PinHandler): - product_id = 0xA165 - _product_name = "Generic pulse meter" - dbus_name = "pulsemeter" - type_id = 1 - - def __init__(self, bus, base, path, gpio, settings): - super(VolumeCounter, self).__init__(bus, base, path, gpio, settings) - self.service.add_path('/Aggregate', value=self.count*self.rate, - gettextcallback=lambda p, v: (str(v) + ' cubic meter')) - - @property - def rate(self): - return self.settings['rate'] - - def toggle(self, level): - super(VolumeCounter, self).toggle(level) - self.service['/Aggregate'] = self.count * self.rate - -class PinAlarm(PinHandler): - product_id = 0xA166 - _product_name = "Generic digital input" - dbus_name = "digitalinput" - type_id = 0xFF - translation = 0 # low, high - - def __init__(self, bus, base, path, gpio, settings): - super(PinAlarm, self).__init__(bus, base, path, gpio, settings) - self.service.add_path('/InputState', value=0) - self.service.add_path('/State', value=self.get_state(0), - gettextcallback=lambda p, v: TRANSLATIONS[v/2][v%2]) - self.service.add_path('/Alarm', value=self.get_alarm_state(0)) - - # Also expose the type - self.service.add_path('/Type', value=self.type_id, - gettextcallback=lambda p, v: INPUTTYPES[v]) - - def toggle(self, level): - super(PinAlarm, self).toggle(level) - self.service['/InputState'] = bool(level)*1 - self.service['/State'] = self.get_state(level) - # Ensure that the alarm flag resets if the /AlarmSetting config option - # disappears. - self.service['/Alarm'] = self.get_alarm_state(level) - - def get_state(self, level): - state = level ^ self.settings['invert'] - return 2 * self.translation + state - - def get_alarm_state(self, level): - return 2 * bool( - (level ^ self.settings['invertalarm']) and self.settings['alarm']) - - -# Various types of things we might want to monitor -class DoorSensor(PinAlarm): - _product_name = "Door alarm" - type_id = 2 - translation = 3 # open, closed - -class BilgePump(PinAlarm): - _product_name = "Bilge pump" - type_id = 3 - translation = 1 # off, on - -class BilgeAlarm(PinAlarm): - _product_name = "Bilge alarm" - type_id = 4 - translation = 4 # ok, alarm - -class BurglarAlarm(PinAlarm): - _product_name = "Burglar alarm" - type_id = 5 - translation = 4 # ok, alarm - -class SmokeAlarm(PinAlarm): - _product_name = "Smoke alarm" - type_id = 6 - translation = 4 # ok, alarm - -class FireAlarm(PinAlarm): - _product_name = "Fire alarm" - type_id = 7 - translation = 4 # ok, alarm - -class CO2Alarm(PinAlarm): - _product_name = "CO2 alarm" - type_id = 8 - translation = 4 # ok, alarm - -class Generator(PinAlarm): - _product_name = "Generator" - type_id = 9 - translation = 5 # running, stopped - - -def dbusconnection(): - return SessionBus() if 'DBUS_SESSION_BUS_ADDRESS' in os.environ else SystemBus() - - -def main(): - parser = ArgumentParser(description=sys.argv[0]) - parser.add_argument('--servicebase', - help='Base service name on dbus, default is com.victronenergy', - default='com.victronenergy') - parser.add_argument('--poll', - help='Use a different kind of polling. Options are epoll, dumb and debug', - default='epoll') - parser.add_argument('inputs', nargs='+', help='Path to digital input') - args = parser.parse_args() - - PulseCounter = { - 'debug': DebugPulseCounter, - 'poll': PollingPulseCounter, - }.get(args.poll, EpollPulseCounter) - - DBusGMainLoop(set_as_default=True) - - # Keep track of enabled services - services = {} - inputs = dict(enumerate(args.inputs, 1)) - pulses = PulseCounter() # callable that iterates over pulses - - def register_gpio(path, gpio, bus, settings): - _type = settings['inputtype'] - print "Registering GPIO {} for type {}".format(gpio, _type) - - handler = PinHandler.createHandler(_type, - bus, args.servicebase, path, gpio, settings) - services[gpio] = handler - - # Only monitor if enabled - if _type > 0: - handler.level = pulses.register(path, gpio) - handler.refresh() - - def unregister_gpio(gpio): - print "unRegistering GPIO {}".format(gpio) - pulses.unregister(gpio) - services[gpio].deactivate() - - def handle_setting_change(inp, setting, old, new): - if setting == 'inputtype': - if new: - # Get current bus and settings objects, to be reused - service = services[inp] - bus, settings = service.bus, service.settings - - # Input enabled. If already enabled, unregister the old one first. - if pulses.registered(inp): - unregister_gpio(inp) - - # Before registering the new input, reset its settings to defaults - settings['count'] = 0 - settings['invert'] = 0 - settings['invertalarm'] = 0 - settings['alarm'] = 0 - - # Register it - register_gpio(inputs[inp], inp, bus, settings) - elif old: - # Input disabled - unregister_gpio(inp) - elif setting in ('rate', 'invert', 'alarm', 'invertalarm'): - services[inp].refresh() - elif setting == 'name': - services[inp].product_name = new - elif setting == 'count': - # Don't want this triggered on a period save, so only execute - # if it has changed. - v = int(new) - s = services[inp] - if s.count != v: - s.count = v - s.refresh() - - for inp, pth in inputs.items(): - supported_settings = { - 'inputtype': ['/Settings/DigitalInput/{}/Type'.format(inp), 0, 0, len(INPUTTYPES)], - 'rate': ['/Settings/DigitalInput/{}/Multiplier'.format(inp), 0.001, 0, 1.0], - 'count': ['/Settings/DigitalInput/{}/Count'.format(inp), 0, 0, MAXCOUNT, 1], - 'invert': ['/Settings/DigitalInput/{}/InvertTranslation'.format(inp), 0, 0, 1], - 'invertalarm': ['/Settings/DigitalInput/{}/InvertAlarm'.format(inp), 0, 0, 1], - 'alarm': ['/Settings/DigitalInput/{}/AlarmSetting'.format(inp), 0, 0, 1], - 'name': ['/Settings/DigitalInput/{}/CustomName'.format(inp), '', '', ''], - } - bus = dbusconnection() - sd = SettingsDevice(bus, supported_settings, partial(handle_setting_change, inp), timeout=10) - register_gpio(pth, inp, bus, sd) - - def poll(mainloop): - from time import time - idx = 0 - - try: - for inp, level in pulses(): - # epoll object only resyncs once a second. We may receive - # a pulse for something that's been deregistered. - try: - services[inp].toggle(level) - except KeyError: - continue - except: - traceback.print_exc() - mainloop.quit() - - # Need to run the gpio polling in separate thread. Pass in the mainloop so - # the thread can kill us if there is an exception. - gobject.threads_init() - mainloop = gobject.MainLoop() - - poller = Thread(target=lambda: poll(mainloop)) - poller.daemon = True - poller.start() - - # Periodically save the counter - def save_counters(): - for inp in inputs: - services[inp].save_count() - return True - gobject.timeout_add(SAVEINTERVAL, save_counters) - - # Save counter on shutdown - signal.signal(signal.SIGTERM, lambda *args: sys.exit(0)) - - try: - mainloop.run() - except KeyboardInterrupt: - pass - finally: - save_counters() - -if __name__ == "__main__": - main() diff --git a/FileSets/v2.73/dbus_generator.py b/FileSets/v2.73/dbus_generator.py deleted file mode 100755 index e5c5a276..00000000 --- a/FileSets/v2.73/dbus_generator.py +++ /dev/null @@ -1,350 +0,0 @@ -#!/usr/bin/python -u -# -*- coding: utf-8 -*- - -#### GuiMods -#### This file has been modified to allow the generator running state derived from the generator digital input -#### or the genset AC input -#### If the incoming generator state changes, the manual start state is updated -#### time accumulation is suspended when the generator is not running -#### A switch in the generator settings menucontrols whethter the incoming state affects manual start or time accumulaiton -#### It is now possible to start the generator manually and have it stop automatically based on the preset conditions -#### for automaitc start / stop -#### A service interval timer was added so the accumulated run time does not need to be reset, -#### providing total run time for the generator -#### Search for #### GuiMods to find changes - -from dbus.mainloop.glib import DBusGMainLoop -import dbus -import gobject -import argparse -import sys -import os -import signal -# Victron packages -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) -from vedbus import VeDbusService -from ve_utils import exit_on_error -from dbusmonitor import DbusMonitor -from settingsdevice import SettingsDevice -from logger import setup_logging -import logging -from gen_utils import dummy -import time -import relay -import fischerpanda - -softwareversion = '1.3.12' - -class Generator: - def __init__(self): - self._exit = False - self._instances = {} - self._modules = [relay, fischerpanda] - - # Common dbus services/path - commondbustree = { - 'com.victronenergy.settings': { - '/Settings/System/TimeZone': dummy, -#### GuiMods - paths are not correct in stock files - '/Settings/SystemSetup/AcInput1': dummy, - '/Settings/SystemSetup/AcInput2': dummy, - - '/Settings/Relay/Polarity': dummy - }, - 'com.victronenergy.battery': { - '/Dc/0/Voltage': dummy, - '/Dc/0/Current': dummy, - '/Dc/1/Voltage': dummy, - '/Dc/1/Current': dummy, - '/Soc': dummy - }, - 'com.victronenergy.vebus': { - '/Ac/Out/L1/P': dummy, - '/Ac/Out/L2/P': dummy, - '/Ac/Out/L3/P': dummy, - '/Alarms/L1/Overload': dummy, - '/Alarms/L2/Overload': dummy, - '/Alarms/L3/Overload': dummy, - '/Alarms/L1/HighTemperature': dummy, - '/Alarms/L2/HighTemperature': dummy, - '/Alarms/L3/HighTemperature': dummy, - '/Alarms/HighTemperature': dummy, - '/Alarms/Overload': dummy, - '/Ac/ActiveIn/ActiveInput': dummy, - '/Ac/ActiveIn/Connected': dummy, - '/Dc/0/Voltage': dummy, - '/Dc/0/Current': dummy, - '/Dc/1/Voltage': dummy, - '/Dc/1/Current': dummy, - '/Soc': dummy - }, - 'com.victronenergy.system': { - '/Ac/ConsumptionOnInput/L1/Power': dummy, - '/Ac/ConsumptionOnInput/L2/Power': dummy, - '/Ac/ConsumptionOnInput/L3/Power': dummy, - '/Ac/ConsumptionOnOutput/L1/Power': dummy, - '/Ac/ConsumptionOnOutput/L2/Power': dummy, - '/Ac/ConsumptionOnOutput/L3/Power': dummy, - '/Dc/Pv/Power': dummy, - '/AutoSelectedBatteryMeasurement': dummy, - '/Ac/ActiveIn/Source': dummy, - '/VebusService': dummy, - '/Dc/Battery/Voltage': dummy, - '/Dc/Battery/Current': dummy, - '/Dc/Battery/Soc': dummy, -#### GuiMods - '/Ac/Genset/Frequency': dummy, - '/Ac/In/NumberOfAcInputs': dummy - } - } - - # Settings base - settingsbase = { - 'autostart': ['/Settings/{0}/AutoStartEnabled', 1, 0, 1], - 'batterymeasurement': ['/Settings/{0}/Service', '', 0, 0], - 'accumulateddaily': ['/Settings/{0}/AccumulatedDaily', '', 0, 0, True], - 'accumulatedtotal': ['/Settings/{0}/AccumulatedTotal', 0, 0, 0, True], -#### GuiMods - 'timeSinceService': ['/Settings/{0}/TimeSinceService', 0, 0, 0, True], - 'linkManualStartToExternal': ['/Settings/{0}/LinkToExternalStatus', 0, 0, 0, True], - - 'batterymeasurement': ['/Settings/{0}/BatteryService', 'default', 0, 0], - 'minimumruntime': ['/Settings/{0}/MinimumRuntime', 0, 0, 86400], # minutes - 'stoponac1enabled': ['/Settings/{0}/StopWhenAc1Available', 0, 0, 10], - # On permanent loss of communication: 0 = Stop, 1 = Start, 2 = keep running - 'onlosscommunication': ['/Settings/{0}/OnLossCommunication', 0, 0, 2], - # Quiet hours - 'quiethoursenabled': ['/Settings/{0}/QuietHours/Enabled', 0, 0, 1], - 'quiethoursstarttime': ['/Settings/{0}/QuietHours/StartTime', 75600, 0, 86400], - 'quiethoursendtime': ['/Settings/{0}/QuietHours/EndTime', 21600, 0, 86400], - # SOC - 'socenabled': ['/Settings/{0}/Soc/Enabled', 0, 0, 1], - 'socstart': ['/Settings/{0}/Soc/StartValue', 80, 0, 100], - 'socstop': ['/Settings/{0}/Soc/StopValue', 90, 0, 100], - 'qh_socstart': ['/Settings/{0}/Soc/QuietHoursStartValue', 90, 0, 100], - 'qh_socstop': ['/Settings/{0}/Soc/QuietHoursStopValue', 90, 0, 100], - # Voltage - 'batteryvoltageenabled': ['/Settings/{0}/BatteryVoltage/Enabled', 0, 0, 1], - 'batteryvoltagestart': ['/Settings/{0}/BatteryVoltage/StartValue', 11.5, 0, 150], - 'batteryvoltagestop': ['/Settings/{0}/BatteryVoltage/StopValue', 12.4, 0, 150], - 'batteryvoltagestarttimer': ['/Settings/{0}/BatteryVoltage/StartTimer', 20, 0, 10000], - 'batteryvoltagestoptimer': ['/Settings/{0}/BatteryVoltage/StopTimer', 20, 0, 10000], - 'qh_batteryvoltagestart': ['/Settings/{0}/BatteryVoltage/QuietHoursStartValue', 11.9, 0, 100], - 'qh_batteryvoltagestop': ['/Settings/{0}/BatteryVoltage/QuietHoursStopValue', 12.4, 0, 100], - # Current - 'batterycurrentenabled': ['/Settings/{0}/BatteryCurrent/Enabled', 0, 0, 1], - 'batterycurrentstart': ['/Settings/{0}/BatteryCurrent/StartValue', 10.5, 0.5, 10000], - 'batterycurrentstop': ['/Settings/{0}/BatteryCurrent/StopValue', 5.5, 0, 10000], - 'batterycurrentstarttimer': ['/Settings/{0}/BatteryCurrent/StartTimer', 20, 0, 10000], - 'batterycurrentstoptimer': ['/Settings/{0}/BatteryCurrent/StopTimer', 20, 0, 10000], - 'qh_batterycurrentstart': ['/Settings/{0}/BatteryCurrent/QuietHoursStartValue', 20.5, 0, 10000], - 'qh_batterycurrentstop': ['/Settings/{0}/BatteryCurrent/QuietHoursStopValue', 15.5, 0, 10000], - # AC load - 'acloadenabled': ['/Settings/{0}/AcLoad/Enabled', 0, 0, 1], - # Measuerement, 0 = Total AC consumption, 1 = AC on inverter output, 2 = Single phase - 'acloadmeasuerment': ['/Settings/{0}/AcLoad/Measurement', 0, 0, 100], - 'acloadstart': ['/Settings/{0}/AcLoad/StartValue', 1600, 5, 100000], - 'acloadstop': ['/Settings/{0}/AcLoad/StopValue', 800, 0, 100000], - 'acloadstarttimer': ['/Settings/{0}/AcLoad/StartTimer', 20, 0, 10000], - 'acloadstoptimer': ['/Settings/{0}/AcLoad/StopTimer', 20, 0, 10000], - 'qh_acloadstart': ['/Settings/{0}/AcLoad/QuietHoursStartValue', 1900, 0, 100000], - 'qh_acloadstop': ['/Settings/{0}/AcLoad/QuietHoursStopValue', 1200, 0, 100000], - # VE.Bus high temperature - 'inverterhightempenabled': ['/Settings/{0}/InverterHighTemp/Enabled', 0, 0, 1], - 'inverterhightempstarttimer': ['/Settings/{0}/InverterHighTemp/StartTimer', 20, 0, 10000], - 'inverterhightempstoptimer': ['/Settings/{0}/InverterHighTemp/StopTimer', 20, 0, 10000], - # VE.Bus overload - 'inverteroverloadenabled': ['/Settings/{0}/InverterOverload/Enabled', 0, 0, 1], - 'inverteroverloadstarttimer': ['/Settings/{0}/InverterOverload/StartTimer', 20, 0, 10000], - 'inverteroverloadstoptimer': ['/Settings/{0}/InverterOverload/StopTimer', 20, 0, 10000], - # TestRun - 'testrunenabled': ['/Settings/{0}/TestRun/Enabled', 0, 0, 1], - 'testrunstartdate': ['/Settings/{0}/TestRun/StartDate', 1483228800, 0, 10000000000.1], - 'testrunstarttimer': ['/Settings/{0}/TestRun/StartTime', 54000, 0, 86400], - 'testruninterval': ['/Settings/{0}/TestRun/Interval', 28, 1, 365], - 'testrunruntime': ['/Settings/{0}/TestRun/Duration', 7200, 1, 86400], - 'testrunskipruntime': ['/Settings/{0}/TestRun/SkipRuntime', 0, 0, 100000], - 'testruntillbatteryfull': ['/Settings/{0}/TestRun/RunTillBatteryFull', 0, 0, 1], - # Alarms - 'nogeneratoratacinalarm': ['/Settings/{0}/Alarms/NoGeneratorAtAcIn', 0, 0, 1] - } - - settings = {} - dbus_tree = dict(commondbustree) - - for m in self._modules: - # Create settings for each module - # Settings are created under the module prefix, for example: - # /Settings/Generator0/AcLoad/Enabled - # /Settings/FischerPanda0/AcLoad/Enabled - for s in settingsbase: - v = settingsbase[s][:] # Copy - v[0] = v[0].format(m.name) - settings[s + m.name] = v - - # Get all services/paths that must be monitored - # There are a base of common services/pathas that must be monitored - # for the correct function such as battery monitors of vebus devices - # and a extra ones that is only used by a certain module, these - # are mainly the "remote switch". - for i in m.monitoring: - if i in commondbustree: - for s in m.monitoring[i]: - dbus_tree[i][s] = m.monitoring[i][s] - else: - dbus_tree[i] = m.monitoring[i] - - # Create settings device which is shared - self._settings = self._create_settings(settings, self._handlechangedsetting) - - # Create dbusmonitor, this is shared by all the instances - self._dbusmonitor = self._create_dbus_monitor(dbus_tree, valueChangedCallback=self._dbus_value_changed, - deviceAddedCallback=self._device_added, deviceRemovedCallback=self._device_removed) - - # Create dbus service - # Paths for each instance will be added to this service like: - # com.victronenergy.generator.startstop0/FischerPanda0/State - # com.victronenergy.generator.startstop0/Generator0/State - self._dbusservice = self._create_dbus_service() - - # Call device_added for all existing devices at startup. - for service, instance in self._dbusmonitor.get_service_list().items(): - self._device_added(service, instance) - - gobject.timeout_add(1000, exit_on_error, self._handletimertick) - - def _handlechangedsetting(self, setting, oldvalue, newvalue): - for i in self._instances: - self._instances[i].handlechangedsetting(setting, oldvalue, newvalue) - - def _device_added(self, dbusservicename, instance): - # If settings check built-in relays - if dbusservicename == 'com.victronenergy.settings': - self._handle_builtin_relay('/Settings/Relay/Function') - - self._add_device(dbusservicename) - - for i in self._instances: - self._instances[i].device_added(dbusservicename, instance) - - def _dbus_value_changed(self, dbusServiceName, dbusPath, options, changes, deviceInstance): - # Track built-in relays - if "/Settings/Relay/Function" in dbusPath: - self._handle_builtin_relay(dbusPath) - - # Some devices like Fischer Panda gensets doesn't disappear from dbus - # when disconnected so check '/Connected' value to add or remove start/stop - # for that device - if dbusPath == "/Connected": - if self._dbusmonitor.get_value(dbusServiceName, dbusPath) == 0: - self._remove_device(dbusServiceName) - else: - self._add_device(dbusServiceName) - - for i in self._instances: - self._instances[i].dbus_value_changed(dbusServiceName, dbusPath, options, changes, deviceInstance) - - def _device_removed(self, dbusservicename, instance): - if dbusservicename == 'com.victronenergy.settings': - self._handle_builtin_relay('/Settings/Relay/Function') - for i in self._instances: - self._instances[i].device_removed(dbusservicename, instance) - - def _create_dbus_monitor(self, *args, **kwargs): - return DbusMonitor(*args, **kwargs) - - def _create_settings(self, *args, **kwargs): - bus = dbus.SessionBus() if 'DBUS_SESSION_BUS_ADDRESS' in os.environ else dbus.SystemBus() - return SettingsDevice(bus, *args, timeout=10, **kwargs) - - def _add_device(self, service): - for i in self._modules: - # Check if module can handle this service - if i.remoteprefix not in service: - continue - # Check and create start/stop instance for the device - if i.check_device(self._dbusmonitor, service): - self._instances[service] = i.create(self._dbusmonitor, - self._dbusservice, - service, self._settings) - - def _handle_builtin_relay(self, dbuspath): - function = self._dbusmonitor.get_value('com.victronenergy.settings', dbuspath) - relaynr = 'generator0' - relayservice = 'com.victronenergy.system' - - # Create a instance if relay function is set to 1 (gen. start/stop) - # otherwise remove the instance if exists - if function == 1: - self._instances[relaynr] = relay.create(self._dbusmonitor, - self._dbusservice, - relayservice, - self._settings) - elif relaynr in self._instances: - self._instances[relaynr].remove() - del self._instances[relaynr] - - def _remove_device(self, servicename): - if servicename in self._instances: - if self._instances[servicename] is not None: - self._instances[servicename].remove() - del self._instances[servicename] - - def terminate(self, signum, frame): - # Remove instances before exiting, remote services might need to perform actions before releasing control - # of the switch - for i in self._instances: - self._instances[i].remove() - os._exit(0) - - def _handletimertick(self): - # try catch, to make sure that we kill ourselves on an error. Without this try-catch, there would - # be an error written to stdout, and then the timer would not be restarted, resulting in a dead- - # lock waiting for manual intervention -> not good! - try: - for i in self._instances: - self._instances[i].tick() - except: - self._instances[i].remove() - import traceback - traceback.print_exc() - sys.exit(1) - return True - - def _create_dbus_service(self): - dbusservice = VeDbusService("com.victronenergy.generator.startstop0") - dbusservice.add_mandatory_paths( - processname=__file__, - processversion=softwareversion, - connection='generator', - deviceinstance=0, - productid=None, - productname=None, - firmwareversion=None, - hardwareversion=None, - connected=1) - return dbusservice - -if __name__ == '__main__': - # Argument parsing - parser = argparse.ArgumentParser( - description='Start and stop a generator based on conditions' - ) - - parser.add_argument('-d', '--debug', help='set logging level to debug', - action='store_true') - args = parser.parse_args() - - print '-------- dbus_generator, v' + softwareversion + ' is starting up --------' - - logger = setup_logging(args.debug) - - # Have a mainloop, so we can send/receive asynchronous calls to and from dbus - DBusGMainLoop(set_as_default=True) - - generator = Generator() - signal.signal(signal.SIGTERM, generator.terminate) - - # Start and run the mainloop - mainloop = gobject.MainLoop() - mainloop.run() diff --git a/FileSets/v2.73/dbus_generator.py.orig b/FileSets/v2.73/dbus_generator.py.orig deleted file mode 100755 index 3ec624e6..00000000 --- a/FileSets/v2.73/dbus_generator.py.orig +++ /dev/null @@ -1,329 +0,0 @@ -#!/usr/bin/python -u -# -*- coding: utf-8 -*- - -from dbus.mainloop.glib import DBusGMainLoop -import dbus -import gobject -import argparse -import sys -import os -import signal -# Victron packages -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) -from vedbus import VeDbusService -from ve_utils import exit_on_error -from dbusmonitor import DbusMonitor -from settingsdevice import SettingsDevice -from logger import setup_logging -import logging -from gen_utils import dummy -import time -import relay -import fischerpanda - -softwareversion = '1.3.12' - -class Generator: - def __init__(self): - self._exit = False - self._instances = {} - self._modules = [relay, fischerpanda] - - # Common dbus services/path - commondbustree = { - 'com.victronenergy.settings': { - '/Settings/System/TimeZone': dummy, - '/Settings/System/AcInput1': dummy, - '/Settings/System/AcInput2': dummy, - '/Settings/Relay/Polarity': dummy - }, - 'com.victronenergy.battery': { - '/Dc/0/Voltage': dummy, - '/Dc/0/Current': dummy, - '/Dc/1/Voltage': dummy, - '/Dc/1/Current': dummy, - '/Soc': dummy - }, - 'com.victronenergy.vebus': { - '/Ac/Out/L1/P': dummy, - '/Ac/Out/L2/P': dummy, - '/Ac/Out/L3/P': dummy, - '/Alarms/L1/Overload': dummy, - '/Alarms/L2/Overload': dummy, - '/Alarms/L3/Overload': dummy, - '/Alarms/L1/HighTemperature': dummy, - '/Alarms/L2/HighTemperature': dummy, - '/Alarms/L3/HighTemperature': dummy, - '/Alarms/HighTemperature': dummy, - '/Alarms/Overload': dummy, - '/Ac/ActiveIn/ActiveInput': dummy, - '/Ac/ActiveIn/Connected': dummy, - '/Dc/0/Voltage': dummy, - '/Dc/0/Current': dummy, - '/Dc/1/Voltage': dummy, - '/Dc/1/Current': dummy, - '/Soc': dummy - }, - 'com.victronenergy.system': { - '/Ac/ConsumptionOnInput/L1/Power': dummy, - '/Ac/ConsumptionOnInput/L2/Power': dummy, - '/Ac/ConsumptionOnInput/L3/Power': dummy, - '/Ac/ConsumptionOnOutput/L1/Power': dummy, - '/Ac/ConsumptionOnOutput/L2/Power': dummy, - '/Ac/ConsumptionOnOutput/L3/Power': dummy, - '/Dc/Pv/Power': dummy, - '/AutoSelectedBatteryMeasurement': dummy, - '/Ac/ActiveIn/Source': dummy, - '/VebusService': dummy, - '/Dc/Battery/Voltage': dummy, - '/Dc/Battery/Current': dummy, - '/Dc/Battery/Soc': dummy - } - } - - # Settings base - settingsbase = { - 'autostart': ['/Settings/{0}/AutoStartEnabled', 1, 0, 1], - 'batterymeasurement': ['/Settings/{0}/Service', '', 0, 0], - 'accumulateddaily': ['/Settings/{0}/AccumulatedDaily', '', 0, 0, True], - 'accumulatedtotal': ['/Settings/{0}/AccumulatedTotal', 0, 0, 0, True], - 'batterymeasurement': ['/Settings/{0}/BatteryService', 'default', 0, 0], - 'minimumruntime': ['/Settings/{0}/MinimumRuntime', 0, 0, 86400], # minutes - 'stoponac1enabled': ['/Settings/{0}/StopWhenAc1Available', 0, 0, 10], - # On permanent loss of communication: 0 = Stop, 1 = Start, 2 = keep running - 'onlosscommunication': ['/Settings/{0}/OnLossCommunication', 0, 0, 2], - # Quiet hours - 'quiethoursenabled': ['/Settings/{0}/QuietHours/Enabled', 0, 0, 1], - 'quiethoursstarttime': ['/Settings/{0}/QuietHours/StartTime', 75600, 0, 86400], - 'quiethoursendtime': ['/Settings/{0}/QuietHours/EndTime', 21600, 0, 86400], - # SOC - 'socenabled': ['/Settings/{0}/Soc/Enabled', 0, 0, 1], - 'socstart': ['/Settings/{0}/Soc/StartValue', 80, 0, 100], - 'socstop': ['/Settings/{0}/Soc/StopValue', 90, 0, 100], - 'qh_socstart': ['/Settings/{0}/Soc/QuietHoursStartValue', 90, 0, 100], - 'qh_socstop': ['/Settings/{0}/Soc/QuietHoursStopValue', 90, 0, 100], - # Voltage - 'batteryvoltageenabled': ['/Settings/{0}/BatteryVoltage/Enabled', 0, 0, 1], - 'batteryvoltagestart': ['/Settings/{0}/BatteryVoltage/StartValue', 11.5, 0, 150], - 'batteryvoltagestop': ['/Settings/{0}/BatteryVoltage/StopValue', 12.4, 0, 150], - 'batteryvoltagestarttimer': ['/Settings/{0}/BatteryVoltage/StartTimer', 20, 0, 10000], - 'batteryvoltagestoptimer': ['/Settings/{0}/BatteryVoltage/StopTimer', 20, 0, 10000], - 'qh_batteryvoltagestart': ['/Settings/{0}/BatteryVoltage/QuietHoursStartValue', 11.9, 0, 100], - 'qh_batteryvoltagestop': ['/Settings/{0}/BatteryVoltage/QuietHoursStopValue', 12.4, 0, 100], - # Current - 'batterycurrentenabled': ['/Settings/{0}/BatteryCurrent/Enabled', 0, 0, 1], - 'batterycurrentstart': ['/Settings/{0}/BatteryCurrent/StartValue', 10.5, 0.5, 10000], - 'batterycurrentstop': ['/Settings/{0}/BatteryCurrent/StopValue', 5.5, 0, 10000], - 'batterycurrentstarttimer': ['/Settings/{0}/BatteryCurrent/StartTimer', 20, 0, 10000], - 'batterycurrentstoptimer': ['/Settings/{0}/BatteryCurrent/StopTimer', 20, 0, 10000], - 'qh_batterycurrentstart': ['/Settings/{0}/BatteryCurrent/QuietHoursStartValue', 20.5, 0, 10000], - 'qh_batterycurrentstop': ['/Settings/{0}/BatteryCurrent/QuietHoursStopValue', 15.5, 0, 10000], - # AC load - 'acloadenabled': ['/Settings/{0}/AcLoad/Enabled', 0, 0, 1], - # Measuerement, 0 = Total AC consumption, 1 = AC on inverter output, 2 = Single phase - 'acloadmeasuerment': ['/Settings/{0}/AcLoad/Measurement', 0, 0, 100], - 'acloadstart': ['/Settings/{0}/AcLoad/StartValue', 1600, 5, 100000], - 'acloadstop': ['/Settings/{0}/AcLoad/StopValue', 800, 0, 100000], - 'acloadstarttimer': ['/Settings/{0}/AcLoad/StartTimer', 20, 0, 10000], - 'acloadstoptimer': ['/Settings/{0}/AcLoad/StopTimer', 20, 0, 10000], - 'qh_acloadstart': ['/Settings/{0}/AcLoad/QuietHoursStartValue', 1900, 0, 100000], - 'qh_acloadstop': ['/Settings/{0}/AcLoad/QuietHoursStopValue', 1200, 0, 100000], - # VE.Bus high temperature - 'inverterhightempenabled': ['/Settings/{0}/InverterHighTemp/Enabled', 0, 0, 1], - 'inverterhightempstarttimer': ['/Settings/{0}/InverterHighTemp/StartTimer', 20, 0, 10000], - 'inverterhightempstoptimer': ['/Settings/{0}/InverterHighTemp/StopTimer', 20, 0, 10000], - # VE.Bus overload - 'inverteroverloadenabled': ['/Settings/{0}/InverterOverload/Enabled', 0, 0, 1], - 'inverteroverloadstarttimer': ['/Settings/{0}/InverterOverload/StartTimer', 20, 0, 10000], - 'inverteroverloadstoptimer': ['/Settings/{0}/InverterOverload/StopTimer', 20, 0, 10000], - # TestRun - 'testrunenabled': ['/Settings/{0}/TestRun/Enabled', 0, 0, 1], - 'testrunstartdate': ['/Settings/{0}/TestRun/StartDate', 1483228800, 0, 10000000000.1], - 'testrunstarttimer': ['/Settings/{0}/TestRun/StartTime', 54000, 0, 86400], - 'testruninterval': ['/Settings/{0}/TestRun/Interval', 28, 1, 365], - 'testrunruntime': ['/Settings/{0}/TestRun/Duration', 7200, 1, 86400], - 'testrunskipruntime': ['/Settings/{0}/TestRun/SkipRuntime', 0, 0, 100000], - 'testruntillbatteryfull': ['/Settings/{0}/TestRun/RunTillBatteryFull', 0, 0, 1], - # Alarms - 'nogeneratoratacinalarm': ['/Settings/{0}/Alarms/NoGeneratorAtAcIn', 0, 0, 1] - } - - settings = {} - dbus_tree = dict(commondbustree) - - for m in self._modules: - # Create settings for each module - # Settings are created under the module prefix, for example: - # /Settings/Generator0/AcLoad/Enabled - # /Settings/FischerPanda0/AcLoad/Enabled - for s in settingsbase: - v = settingsbase[s][:] # Copy - v[0] = v[0].format(m.name) - settings[s + m.name] = v - - # Get all services/paths that must be monitored - # There are a base of common services/pathas that must be monitored - # for the correct function such as battery monitors of vebus devices - # and a extra ones that is only used by a certain module, these - # are mainly the "remote switch". - for i in m.monitoring: - if i in commondbustree: - for s in m.monitoring[i]: - dbus_tree[i][s] = m.monitoring[i][s] - else: - dbus_tree[i] = m.monitoring[i] - - # Create settings device which is shared - self._settings = self._create_settings(settings, self._handlechangedsetting) - - # Create dbusmonitor, this is shared by all the instances - self._dbusmonitor = self._create_dbus_monitor(dbus_tree, valueChangedCallback=self._dbus_value_changed, - deviceAddedCallback=self._device_added, deviceRemovedCallback=self._device_removed) - - # Create dbus service - # Paths for each instance will be added to this service like: - # com.victronenergy.generator.startstop0/FischerPanda0/State - # com.victronenergy.generator.startstop0/Generator0/State - self._dbusservice = self._create_dbus_service() - - # Call device_added for all existing devices at startup. - for service, instance in self._dbusmonitor.get_service_list().items(): - self._device_added(service, instance) - - gobject.timeout_add(1000, exit_on_error, self._handletimertick) - - def _handlechangedsetting(self, setting, oldvalue, newvalue): - for i in self._instances: - self._instances[i].handlechangedsetting(setting, oldvalue, newvalue) - - def _device_added(self, dbusservicename, instance): - # If settings check built-in relays - if dbusservicename == 'com.victronenergy.settings': - self._handle_builtin_relay('/Settings/Relay/Function') - - self._add_device(dbusservicename) - - for i in self._instances: - self._instances[i].device_added(dbusservicename, instance) - - def _dbus_value_changed(self, dbusServiceName, dbusPath, options, changes, deviceInstance): - # Track built-in relays - if "/Settings/Relay/Function" in dbusPath: - self._handle_builtin_relay(dbusPath) - - # Some devices like Fischer Panda gensets doesn't disappear from dbus - # when disconnected so check '/Connected' value to add or remove start/stop - # for that device - if dbusPath == "/Connected": - if self._dbusmonitor.get_value(dbusServiceName, dbusPath) == 0: - self._remove_device(dbusServiceName) - else: - self._add_device(dbusServiceName) - - for i in self._instances: - self._instances[i].dbus_value_changed(dbusServiceName, dbusPath, options, changes, deviceInstance) - - def _device_removed(self, dbusservicename, instance): - if dbusservicename == 'com.victronenergy.settings': - self._handle_builtin_relay('/Settings/Relay/Function') - for i in self._instances: - self._instances[i].device_removed(dbusservicename, instance) - - def _create_dbus_monitor(self, *args, **kwargs): - return DbusMonitor(*args, **kwargs) - - def _create_settings(self, *args, **kwargs): - bus = dbus.SessionBus() if 'DBUS_SESSION_BUS_ADDRESS' in os.environ else dbus.SystemBus() - return SettingsDevice(bus, *args, timeout=10, **kwargs) - - def _add_device(self, service): - for i in self._modules: - # Check if module can handle this service - if i.remoteprefix not in service: - continue - # Check and create start/stop instance for the device - if i.check_device(self._dbusmonitor, service): - self._instances[service] = i.create(self._dbusmonitor, - self._dbusservice, - service, self._settings) - - def _handle_builtin_relay(self, dbuspath): - function = self._dbusmonitor.get_value('com.victronenergy.settings', dbuspath) - relaynr = 'generator0' - relayservice = 'com.victronenergy.system' - - # Create a instance if relay function is set to 1 (gen. start/stop) - # otherwise remove the instance if exists - if function == 1: - self._instances[relaynr] = relay.create(self._dbusmonitor, - self._dbusservice, - relayservice, - self._settings) - elif relaynr in self._instances: - self._instances[relaynr].remove() - del self._instances[relaynr] - - def _remove_device(self, servicename): - if servicename in self._instances: - if self._instances[servicename] is not None: - self._instances[servicename].remove() - del self._instances[servicename] - - def terminate(self, signum, frame): - # Remove instances before exiting, remote services might need to perform actions before releasing control - # of the switch - for i in self._instances: - self._instances[i].remove() - os._exit(0) - - def _handletimertick(self): - # try catch, to make sure that we kill ourselves on an error. Without this try-catch, there would - # be an error written to stdout, and then the timer would not be restarted, resulting in a dead- - # lock waiting for manual intervention -> not good! - try: - for i in self._instances: - self._instances[i].tick() - except: - self._instances[i].remove() - import traceback - traceback.print_exc() - sys.exit(1) - return True - - def _create_dbus_service(self): - dbusservice = VeDbusService("com.victronenergy.generator.startstop0") - dbusservice.add_mandatory_paths( - processname=__file__, - processversion=softwareversion, - connection='generator', - deviceinstance=0, - productid=None, - productname=None, - firmwareversion=None, - hardwareversion=None, - connected=1) - return dbusservice - -if __name__ == '__main__': - # Argument parsing - parser = argparse.ArgumentParser( - description='Start and stop a generator based on conditions' - ) - - parser.add_argument('-d', '--debug', help='set logging level to debug', - action='store_true') - args = parser.parse_args() - - print '-------- dbus_generator, v' + softwareversion + ' is starting up --------' - - logger = setup_logging(args.debug) - - # Have a mainloop, so we can send/receive asynchronous calls to and from dbus - DBusGMainLoop(set_as_default=True) - - generator = Generator() - signal.signal(signal.SIGTERM, generator.terminate) - - # Start and run the mainloop - mainloop = gobject.MainLoop() - mainloop.run() diff --git a/FileSets/v2.73/main.qml b/FileSets/v2.73/main.qml deleted file mode 120000 index 54acc57c..00000000 --- a/FileSets/v2.73/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/main.qml \ No newline at end of file diff --git a/FileSets/v2.73/startstop.py b/FileSets/v2.73/startstop.py deleted file mode 100755 index fa1f2ee0..00000000 --- a/FileSets/v2.73/startstop.py +++ /dev/null @@ -1,1207 +0,0 @@ -#!/usr/bin/python -u -# -*- coding: utf-8 -*- - -#### GuiMods -#### This file has been modified to allow the generator running state derived from the generator digital input -#### or the genset AC input -#### If the incoming generator state changes, the manual start state is updated -#### time accumulation is suspended when the generator is not running -#### A switch in the generator settings menucontrols whethter the incoming state affects manual start or time accumulaiton -#### It is now possible to start the generator manually and have it stop automatically based on the preset conditions -#### for automaitc start / stop -#### A service interval timer was added so the accumulated run time does not need to be reset, -#### providing total run time for the generator -#### Search for #### GuiMods to find changes - -# Function -# dbus_generator monitors the dbus for batteries (com.victronenergy.battery.*) and -# vebus com.victronenergy.vebus.* -# Battery and vebus monitors can be configured through the gui. -# It then monitors SOC, AC loads, battery current and battery voltage,to auto start/stop the generator based -# on the configuration settings. Generator can be started manually or periodically setting a tes trun period. -# Time zones function allows to use different values for the conditions along the day depending on time - -import dbus -import datetime -import calendar -import time -import sys -import json -import os -import logging -from os import environ -import monotonic_time -from gen_utils import DBusServicePrefix, SettingsPrefix, Errors, States, enum -# Victron packages -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) -from ve_utils import exit_on_error -from settingsdevice import SettingsDevice - -RunningConditions = enum( - Stopped = 0, - Manual = 1, - TestRun = 2, - LossOfCommunication = 3, - Soc = 4, - Acload = 5, - BatteryCurrent = 6, - BatteryVoltage = 7, - InverterHighTemp = 8, - InverterOverload = 9, - StopOnAc1 = 10) - -SYSTEM_SERVICE = 'com.victronenergy.system' -BATTERY_PREFIX = '/Dc/Battery' -HISTORY_DAYS = 30 - - -class StartStop: - def __init__(self): -#### GuiMods - self._last_update_mtime = 0 - self._accumulatedRunTime = 0 - self._digitalInputTypeObject = None - self._generatorInputStateObject = 0 - self._lastState = 0 - self._externalOverride = False - self._externalOverrideDelay = 99 - self._lastExternalOverride = False - self._searchDelay = 99 - self._linkToExternalState = False - - self._dbusservice = None - self._settings = None - self._dbusmonitor = None - self._remoteservice = None - self._name = None - self._enabled = False - - # One second per retry - self.RETRIES_ON_ERROR = 300 - self._testrun_soc_retries = 0 - self._last_counters_check = 0 - - self._starttime = 0 - self._manualstarttimer = 0 - self._last_runtime_update = 0 - self._timer_runnning = 0 - - # Manual battery service selection is deprecated in favour - # of getting the values directly from systemcalc, we keep - # manual selected services handling for compatibility reasons. - self._vebusservice = None - self._errorstate = 0 - self._battery_service = None - self._battery_prefix = None - - self._acpower_inverter_input = { - 'timeout': 0, - 'unabletostart': False - } - - self._condition_stack = { - 'batteryvoltage': { - 'name': 'batteryvoltage', - 'reached': False, - 'boolean': False, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'battery' - }, - 'batterycurrent': { - 'name': 'batterycurrent', - 'reached': False, - 'boolean': False, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'battery' - }, - 'acload': { - 'name': 'acload', - 'reached': False, - 'boolean': False, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - }, - 'inverterhightemp': { - 'name': 'inverterhightemp', - 'reached': False, - 'boolean': True, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - }, - 'inverteroverload': { - 'name': 'inverteroverload', - 'reached': False, - 'boolean': True, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - }, - 'soc': { - 'name': 'soc', - 'reached': False, - 'boolean': False, - 'timed': False, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'battery' - }, - 'stoponac1': { - 'name': 'stoponac1', - 'reached': False, - 'boolean': True, - 'timed': False, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - } - } - - def set_sources(self, dbusmonitor, dbusservice, settings, name, remoteservice): - self._dbusservice = DBusServicePrefix(dbusservice, name) - self._settings = SettingsPrefix(settings, name) - self._dbusmonitor = dbusmonitor - self._remoteservice = remoteservice - self._name = name - # Set timezone to user selected timezone - tz = self._dbusmonitor.get_value('com.victronenergy.settings', '/Settings/System/TimeZone') - environ['TZ'] = tz if tz else 'UTC' - - self.log_info('Start/stop instance created for %s.' % self._remoteservice) - self._remote_setup() - - def _create_paths(self): - # State: None = invalid, 0 = stopped, 1 = running - self._dbusservice.add_path('/State', value=None) - # RunningByConditionCode: Numeric Companion to /RunningByCondition below, but - # also encompassing a Stopped state. - self._dbusservice.add_path('/RunningByConditionCode', value=None) - # Error - self._dbusservice.add_path('/Error', value=None, gettextcallback=self._gettext) - # Condition that made the generator start - self._dbusservice.add_path('/RunningByCondition', value=None) - # Runtime - self._dbusservice.add_path('/Runtime', value=None, gettextcallback=self._gettext) - # Today runtime - self._dbusservice.add_path('/TodayRuntime', value=None, gettextcallback=self._gettext) - # Test run runtime - self._dbusservice.add_path('/TestRunIntervalRuntime', value=None , gettextcallback=self._gettext) - # Next test run date, values is 0 for test run disabled - self._dbusservice.add_path('/NextTestRun', value=None, gettextcallback=self._gettext) - # Next test run is needed 1, not needed 0 - self._dbusservice.add_path('/SkipTestRun', value=None) - # Manual start - self._dbusservice.add_path('/ManualStart', value=None, writeable=True) - # Manual start timer - self._dbusservice.add_path('/ManualStartTimer', value=None, writeable=True) - # Silent mode active - self._dbusservice.add_path('/QuietHours', value=None) - # Alarms - self._dbusservice.add_path('/Alarms/NoGeneratorAtAcIn', value=None) - - # We need to set the values after creating the paths to trigger the 'onValueChanged' event for the gui - # otherwise the gui will report the paths as invalid if we remove and recreate the paths without - # restarting the dbusservice. - self._dbusservice['/State'] = 0 - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped - self._dbusservice['/Error'] = 0 - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/Runtime'] = 0 - self._dbusservice['/TodayRuntime'] = 0 - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - self._dbusservice['/NextTestRun'] = None - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/ManualStart'] = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._dbusservice['/QuietHours'] = 0 - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - -#### GuiMods - # generator input running state - self._dbusservice.add_path('/GeneratorRunningState', value=None) - # external override active - self._dbusservice.add_path('/ExternalOverride', value=None) - self._dbusservice['/GeneratorRunningState'] = "?" - self._dbusservice['/ExternalOverride'] = False - - - def enable(self): - if self._enabled: - return - self.log_info('Enabling auto start/stop and taking control of remote switch') - self._create_paths() - self._determineservices() - self._update_remote_switch() - self._enabled = True - - def disable(self): - if not self._enabled: - return - self.log_info('Disabling auto start/stop, releasing control of remote switch') - self._remove_paths() - self._enabled = False - - def remove(self): - self.disable() - self.log_info('Removed from start/stop instances') - - def _remove_paths(self): - self._dbusservice.__delitem__('/State') - self._dbusservice.__delitem__('/RunningByConditionCode') - self._dbusservice.__delitem__('/Error') - self._dbusservice.__delitem__('/RunningByCondition') - self._dbusservice.__delitem__('/Runtime') - self._dbusservice.__delitem__('/TodayRuntime') - self._dbusservice.__delitem__('/TestRunIntervalRuntime') - self._dbusservice.__delitem__('/NextTestRun') - self._dbusservice.__delitem__('/SkipTestRun') - self._dbusservice.__delitem__('/ManualStart') - self._dbusservice.__delitem__('/ManualStartTimer') - self._dbusservice.__delitem__('/QuietHours') - self._dbusservice.__delitem__('/Alarms/NoGeneratorAtAcIn') -#### GuiMods - self._dbusservice.__delitem__('/GeneratorRunningState') - self._dbusservice.__delitem__('/ExternalOverride') - - def device_added(self, dbusservicename, instance): - self._determineservices() - - def device_removed(self, dbusservicename, instance): - self._determineservices() - - def get_error(self): - return self._dbusservice['/Error'] - - def set_error(self, errorn): - self._dbusservice['/Error'] = errorn - - def clear_error(self): - self._dbusservice['/Error'] = Errors.NONE - - def dbus_value_changed(self, dbusServiceName, dbusPath, options, changes, deviceInstance): - if self._dbusservice is None: - return - if dbusPath == '/AutoSelectedBatteryMeasurement' and self._settings['batterymeasurement'] == 'default': - self._determineservices() - - if dbusPath == '/VebusService': - self._determineservices() - - # Update env timezone when setting changes - if dbusPath == '/Settings/System/TimeZone': - environ['TZ'] = changes['Value'] if changes['Value'] else 'UTC' - - def handlechangedsetting(self, setting, oldvalue, newvalue): - if self._dbusservice is None: - return - if self._name not in setting: - # Not our setting - return - - s = self._settings.removeprefix(setting) - - if s == 'batterymeasurement': - self._determineservices() - # Reset retries and valid if service changes - for condition in self._condition_stack: - if self._condition_stack[condition]['monitoring'] == 'battery': - self._condition_stack[condition]['valid'] = True - self._condition_stack[condition]['retries'] = 0 - - if s == 'autostart': - self.log_info('Autostart function %s.' % ('enabled' if newvalue == 1 else 'disabled')) - - if self._dbusservice is not None and s == 'testruninterval': - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime( - self._settings['testruninterval']) - - def dbus_name_owner_changed(self, name, oldowner, newowner): - self._determineservices() - - def _gettext(self, path, value): - path = path.replace("/" + self._name, '') - - if path == '/Error': - return Errors.get_description(value) - if path == '/NextTestRun': - # Locale format date - d = datetime.datetime.fromtimestamp(value) - return d.strftime('%c') - elif path in ['/Runtime', '/TestRunIntervalRuntime', '/TodayRuntime']: - m, s = divmod(value, 60) - h, m = divmod(m, 60) - return '%dh, %dm, %ds' % (h, m, s) - else: - return str(value) - - def log_info(self, msg): - logging.info(self._name + ': %s' % msg) - - def tick(self): - if not self._enabled: - return - self._check_remote_status() -#### GuiMods - self._linkToExternalState = self._settings['linkManualStartToExternal'] == 1 - self._processGeneratorRunDetection () - - self._evaluate_startstop_conditions() - self._detect_generator_at_acinput() - - - - - def _evaluate_startstop_conditions(self): - if self.get_error() != Errors.NONE: - # First evaluation after an error, log it - if self._errorstate == 0: - self._errorstate = 1 - self._dbusservice['/State'] = States.ERROR - self.log_info('Error: #%i - %s, stop controlling remote.' % - (self.get_error(), - Errors.get_description(self.get_error()))) - elif self._errorstate == 1: - # Error cleared - self._errorstate = 0 - self.log_info('Error state cleared, taking control of remote switch.') - - # Conditions will be evaluated in this order - conditions = ['soc', 'acload', 'batterycurrent', 'batteryvoltage', 'inverterhightemp', 'inverteroverload', 'stoponac1'] - start = False - startbycondition = None - activecondition = self._dbusservice['/RunningByCondition'] - today = calendar.timegm(datetime.date.today().timetuple()) - self._timer_runnning = False - values = self._get_updated_values() - connection_lost = False - - self._check_quiet_hours() - - # New day, register it - if self._last_counters_check < today and self._dbusservice['/State'] == States.STOPPED: - self._last_counters_check = today - self._update_accumulated_time() - - # Update current and accumulated runtime. -#### GuiMods - self._accumulateRunTime () - -#### GuiMods - # A negative /ManualStartTimer is used by the GUI to signal the generator should start now - # but stop when all auto stop conditions have been met - # so we skip manual start evaluation if this is the case - # and set a flag for use below to ignore auto start conditions - # the generator is actually started by the auto start/stop logic below - if self._dbusservice['/ManualStartTimer'] < 0 and self._dbusservice['/ManualStart'] == 1: - self._dbusservice['/ManualStartTimer'] = 0 - self._dbusservice['/ManualStart'] = 0 - ignoreAutoStartCondition = True - else: - ignoreAutoStartCondition = False - if self._evaluate_manual_start(): - startbycondition = 'manual' - start = True - - # Conditions will only be evaluated if the autostart functionality is enabled - if self._settings['autostart'] == 1: - - if self._evaluate_testrun_condition(): - startbycondition = 'testrun' - start = True - - # Evaluate value conditions - for condition in conditions: -#### GuiMods - start = self._evaluate_condition(self._condition_stack[condition], values[condition], ignoreAutoStartCondition) or start - - startbycondition = condition if start and startbycondition is None else startbycondition - # Connection lost is set to true if the number of retries of one or more enabled conditions - # >= RETRIES_ON_ERROR - if self._condition_stack[condition]['enabled']: - connection_lost = self._condition_stack[condition]['retries'] >= self.RETRIES_ON_ERROR - - if self._condition_stack['stoponac1']['reached'] and startbycondition not in ['manual', 'testrun']: - start = False - if self._dbusservice['/State'] == States.RUNNING and activecondition not in ['manual', 'testrun']: - self.log_info('AC input 1 available, stopping') - - # If none condition is reached check if connection is lost and start/keep running the generator - # depending on '/OnLossCommunication' setting - if not start and connection_lost: - # Start always - if self._settings['onlosscommunication'] == 1: - start = True - startbycondition = 'lossofcommunication' - # Keep running if generator already started - if self._dbusservice['/State'] == States.RUNNING and self._settings['onlosscommunication'] == 2: - start = True - startbycondition = 'lossofcommunication' - -#### GuiMods - ## auto start disabled and generator is stopped - clear the 'reached' flags - elif self._dbusservice['/State'] == States.STOPPED: - for condition, data in self._condition_stack.items(): - self._reset_condition(data) - - if not start and self._errorstate: - self._stop_generator() - - if self._errorstate: - return - - if start: - self._start_generator(startbycondition) -#### GuiMods - # bypass the minimum run time check if External Override is active - elif (self._dbusservice['/Runtime'] >= self._settings['minimumruntime'] * 60 - or activecondition == 'manual') or self._dbusservice['/ExternalOverride']: - self._stop_generator() - - def _detect_generator_at_acinput(self): - state = self._dbusservice['/State'] - - if state == States.STOPPED: - self._reset_acpower_inverter_input() - return - - if self._settings['nogeneratoratacinalarm'] == 0: - self._reset_acpower_inverter_input() - return - - vebus_service = self._vebusservice if self._vebusservice else '' - activein_state = self._dbusmonitor.get_value( - vebus_service, '/Ac/ActiveIn/Connected') - - # Path not supported, skip evaluation - if activein_state == None: - return - - # Sources 0 = Not available, 1 = Grid, 2 = Generator, 3 = Shore - generator_acsource = self._dbusmonitor.get_value( - SYSTEM_SERVICE, '/Ac/ActiveIn/Source') == 2 - # Not connected = 0, connected = 1 - activein_connected = activein_state == 1 - - if generator_acsource and activein_connected: - if self._acpower_inverter_input['unabletostart']: - self.log_info('Generator detected at inverter AC input, alarm removed') - self._reset_acpower_inverter_input() - elif self._acpower_inverter_input['timeout'] < self.RETRIES_ON_ERROR: - self._acpower_inverter_input['timeout'] += 1 - elif not self._acpower_inverter_input['unabletostart']: - self._acpower_inverter_input['unabletostart'] = True - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 2 - self.log_info('Generator not detected at inverter AC input, triggering alarm') - - def _reset_acpower_inverter_input(self, clear_error=True): - if self._acpower_inverter_input['timeout'] != 0: - self._acpower_inverter_input['timeout'] = 0 - - if self._acpower_inverter_input['unabletostart'] != 0: - self._acpower_inverter_input['unabletostart'] = 0 - - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - - def _reset_condition(self, condition): - condition['reached'] = False - if condition['timed']: - condition['start_timer'] = 0 - condition['stop_timer'] = 0 - - def _check_condition(self, condition, value): - name = condition['name'] - - if self._settings[name + 'enabled'] == 0: - if condition['enabled']: - condition['enabled'] = False - self.log_info('Disabling (%s) condition' % name) - condition['retries'] = 0 - condition['valid'] = True - self._reset_condition(condition) - return False - - elif not condition['enabled']: - condition['enabled'] = True - self.log_info('Enabling (%s) condition' % name) - - if (condition['monitoring'] == 'battery') and (self._settings['batterymeasurement'] == 'nobattery'): - # If no battery monitor is selected reset the condition - self._reset_condition(condition) - return False - - if value is None and condition['valid']: - if condition['retries'] >= self.RETRIES_ON_ERROR: - logging.info('Error getting (%s) value, skipping evaluation till get a valid value' % name) - self._reset_condition(condition) - self._comunnication_lost = True - condition['valid'] = False - else: - condition['retries'] += 1 - if condition['retries'] == 1 or (condition['retries'] % 10) == 0: - self.log_info('Error getting (%s) value, retrying(#%i)' % (name, condition['retries'])) - return False - - elif value is not None and not condition['valid']: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['valid'] = True - condition['retries'] = 0 - - # Reset retries if value is valid - if value is not None and condition['retries'] > 0: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['retries'] = 0 - - return condition['valid'] - -#### GuiMods - def _evaluate_condition(self, condition, value, ignoreStartValue): - name = condition['name'] - setting = ('qh_' if self._dbusservice['/QuietHours'] == 1 else '') + name - startvalue = self._settings[setting + 'start'] if not condition['boolean'] else 1 - stopvalue = self._settings[setting + 'stop'] if not condition['boolean'] else 0 - - # Check if the condition has to be evaluated - if not self._check_condition(condition, value): - # If generator is started by this condition and value is invalid - # wait till RETRIES_ON_ERROR to skip the condition - if condition['reached'] and condition['retries'] <= self.RETRIES_ON_ERROR: - if condition['retries'] > 0: - return True - - return False - - # As this is a generic evaluation method, we need to know how to compare the values - # first check if start value should be greater than stop value and then compare - start_is_greater = startvalue > stopvalue - -#### GuiMods - stop = value <= stopvalue if start_is_greater else value >= stopvalue - # when starting manually and stopping based on auto stop values, - # start if stop condition is not satisfied - if ignoreStartValue: - start = not stop - else: - # When the condition is already reached only the stop value can set it to False - start = condition['reached'] or (value >= startvalue if start_is_greater else value <= startvalue) - - # Timed conditions must start/stop after the condition has been reached for a minimum - # time. - if condition['timed']: - if not condition['reached'] and start: - condition['start_timer'] += time.time() if condition['start_timer'] == 0 else 0 - start = time.time() - condition['start_timer'] >= self._settings[name + 'starttimer'] - condition['stop_timer'] *= int(not start) - self._timer_runnning = True - else: - condition['start_timer'] = 0 - - if condition['reached'] and stop: - condition['stop_timer'] += time.time() if condition['stop_timer'] == 0 else 0 - stop = time.time() - condition['stop_timer'] >= self._settings[name + 'stoptimer'] - condition['stop_timer'] *= int(not stop) - self._timer_runnning = True - else: - condition['stop_timer'] = 0 - - condition['reached'] = start and not stop - return condition['reached'] - - def _evaluate_manual_start(self): - if self._dbusservice['/ManualStart'] == 0: - if self._dbusservice['/RunningByCondition'] == 'manual': - self._dbusservice['/ManualStartTimer'] = 0 - return False - - start = True - # If /ManualStartTimer has a value greater than zero will use it to set a stop timer. - # If no timer is set, the generator will not stop until the user stops it manually. - # Once started by manual start, each evaluation the timer is decreased -#### GuiMods - if self._dbusservice['/ManualStartTimer'] > 0: - self._manualstarttimer += time.time() if self._manualstarttimer == 0 else 0 - self._dbusservice['/ManualStartTimer'] -= int(time.time()) - int(self._manualstarttimer) - self._manualstarttimer = time.time() - start = self._dbusservice['/ManualStartTimer'] > 0 - self._dbusservice['/ManualStart'] = int(start) - # Reset if timer is finished - self._manualstarttimer *= int(start) - self._dbusservice['/ManualStartTimer'] *= int(start) - - return start - - def _evaluate_testrun_condition(self): - if self._settings['testrunenabled'] == 0: - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/NextTestRun'] = None - return False - - today = datetime.date.today() - yesterday = today - datetime.timedelta(days=1) # Should deal well with DST - now = time.time() - runtillbatteryfull = self._settings['testruntillbatteryfull'] == 1 - soc = self._get_updated_values()['soc'] - batteryisfull = runtillbatteryfull and soc == 100 - duration = 60 if runtillbatteryfull else self._settings['testrunruntime'] - - try: - startdate = datetime.date.fromtimestamp(self._settings['testrunstartdate']) - _starttime = time.mktime(yesterday.timetuple()) + self._settings['testrunstarttimer'] - - # today might in fact still be yesterday, if this test run started - # before midnight and finishes after. If `now` still falls in - # yesterday's window, then by the temporal anthropic principle, - # which I just made up but loosely states that time must have - # these properties for observers to exist, it must be yesterday - # because we are here to observe it. - if _starttime <= now <= _starttime + duration: - today = yesterday - starttime = _starttime - else: - starttime = time.mktime(today.timetuple()) + self._settings['testrunstarttimer'] - except ValueError: - logging.debug('Invalid dates, skipping testrun') - return False - - # If start date is in the future set as NextTestRun and stop evaluating - if startdate > today: - self._dbusservice['/NextTestRun'] = time.mktime(startdate.timetuple()) - return False - - start = False - # If the accumulated runtime during the tes trun interval is greater than '/TestRunIntervalRuntime' - # the tes trun must be skipped - needed = (self._settings['testrunskipruntime'] > self._dbusservice['/TestRunIntervalRuntime'] - or self._settings['testrunskipruntime'] == 0) - self._dbusservice['/SkipTestRun'] = int(not needed) - - interval = self._settings['testruninterval'] - stoptime = starttime + duration - elapseddays = (today - startdate).days - mod = elapseddays % interval - - start = not bool(mod) and starttime <= now <= stoptime - - if runtillbatteryfull: - if soc is not None: - self._testrun_soc_retries = 0 - start = (start or self._dbusservice['/RunningByCondition'] == 'testrun') and not batteryisfull - elif self._dbusservice['/RunningByCondition'] == 'testrun': - if self._testrun_soc_retries < self.RETRIES_ON_ERROR: - self._testrun_soc_retries += 1 - start = True - if (self._testrun_soc_retries % 10) == 0: - self.log_info('Test run failed to get SOC value, retrying(#%i)' % self._testrun_soc_retries) - else: - self.log_info('Failed to get SOC after %i retries, terminating test run condition' % self._testrun_soc_retries) - start = False - else: - start = False - - if not bool(mod) and (now <= stoptime): - self._dbusservice['/NextTestRun'] = starttime - else: - self._dbusservice['/NextTestRun'] = (time.mktime((today + datetime.timedelta(days=interval - mod)).timetuple()) + - self._settings['testrunstarttimer']) - return start and needed - - def _check_quiet_hours(self): - active = False - if self._settings['quiethoursenabled'] == 1: - # Seconds after today 00:00 - timeinseconds = time.time() - time.mktime(datetime.date.today().timetuple()) - quiethoursstart = self._settings['quiethoursstarttime'] - quiethoursend = self._settings['quiethoursendtime'] - - # Check if the current time is between the start time and end time - if quiethoursstart < quiethoursend: - active = quiethoursstart <= timeinseconds and timeinseconds < quiethoursend - else: # End time is lower than start time, example Start: 21:00, end: 08:00 - active = not (quiethoursend < timeinseconds and timeinseconds < quiethoursstart) - - if self._dbusservice['/QuietHours'] == 0 and active: - self.log_info('Entering to quiet mode') - - elif self._dbusservice['/QuietHours'] == 1 and not active: - self.log_info('Leaving quiet mode') - - self._dbusservice['/QuietHours'] = int(active) - - return active - - def _update_accumulated_time(self): - seconds = self._dbusservice['/Runtime'] - accumulated = seconds - self._last_runtime_update - - self._settings['accumulatedtotal'] = int(self._settings['accumulatedtotal']) + accumulated -#### GuiMods - self._settings['timeSinceService'] = int(self._settings['timeSinceService']) + accumulated - # Using calendar to get timestamp in UTC, not local time - today_date = str(calendar.timegm(datetime.date.today().timetuple())) - - # If something goes wrong getting the json string create a new one - try: - accumulated_days = json.loads(self._settings['accumulateddaily']) - except ValueError: - accumulated_days = {today_date: 0} - - if (today_date in accumulated_days): - accumulated_days[today_date] += accumulated - else: - accumulated_days[today_date] = accumulated - - self._last_runtime_update = seconds - - # Keep the historical with a maximum of HISTORY_DAYS - while len(accumulated_days) > HISTORY_DAYS: - accumulated_days.pop(min(accumulated_days.keys()), None) - - # Upadate settings - self._settings['accumulateddaily'] = json.dumps(accumulated_days, sort_keys=True) - self._dbusservice['/TodayRuntime'] = self._interval_runtime(0) - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - - def _interval_runtime(self, days): - summ = 0 - try: - daily_record = json.loads(self._settings['accumulateddaily']) - except ValueError: - return 0 - - for i in range(days + 1): - previous_day = calendar.timegm((datetime.date.today() - datetime.timedelta(days=i)).timetuple()) - if str(previous_day) in daily_record.keys(): - summ += daily_record[str(previous_day)] if str(previous_day) in daily_record.keys() else 0 - - return summ - - def _get_battery(self): - battery = {} - if self._settings['batterymeasurement'] == 'default': - battery['service'] = SYSTEM_SERVICE - battery['prefix'] = BATTERY_PREFIX - else: - battery['service'] = self._battery_service if self._battery_service else '' - battery['prefix'] = self._battery_prefix if self._battery_prefix else '' - - return battery - - def _get_updated_values(self): - battery = self._get_battery() - vebus_service = self._vebusservice if self._vebusservice else '' - loadOnAcOut = [] - totalConsumption = [] - inverterHighTemp = [] - inverterOverload = [] - - values = { - 'batteryvoltage': self._dbusmonitor.get_value(battery['service'], battery['prefix'] + '/Voltage'), - 'batterycurrent': self._dbusmonitor.get_value(battery['service'], battery['prefix'] + '/Current'), - # Soc from the device doesn't have the '/Dc/0' prefix like the current and voltage do, but it does - # have the same prefix on systemcalc - 'soc': self._dbusmonitor.get_value(battery['service'], (battery['prefix'] if battery['prefix'] == BATTERY_PREFIX else '') + '/Soc'), - 'inverterhightemp': self._dbusmonitor.get_value(vebus_service, '/Alarms/HighTemperature'), - 'inverteroverload': self._dbusmonitor.get_value(vebus_service, '/Alarms/Overload') - } - - for phase in ['L1', 'L2', 'L3']: - # Get the values directly from the inverter, systemcalc doesn't provide raw inverted power - loadOnAcOut.append(self._dbusmonitor.get_value(vebus_service, ('/Ac/Out/%s/P' % phase))) - - # Calculate total consumption, '/Ac/Consumption/%s/Power' is deprecated - c_i = self._dbusmonitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnInput/%s/Power' % phase)) - c_o = self._dbusmonitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnOutput/%s/Power' % phase)) - totalConsumption.append(sum(filter(None, (c_i, c_o)))) - - # Inverter alarms must be fetched directly from the inverter service - inverterHighTemp.append(self._dbusmonitor.get_value(vebus_service, ('/Alarms/%s/HighTemperature' % phase))) - inverterOverload.append(self._dbusmonitor.get_value(vebus_service, ('/Alarms/%s/Overload' % phase))) - - # Toltal consumption - if self._settings['acloadmeasuerment'] == 0: - values['acload'] = sum(filter(None, totalConsumption)) - - # Load on inverter AC out - if self._settings['acloadmeasuerment'] == 1: - values['acload'] = sum(filter(None, loadOnAcOut)) - - # Highest phase load - if self._settings['acloadmeasuerment'] == 2: - values['acload'] = max(loadOnAcOut) - - # AC input 1 - activein = self._dbusmonitor.get_value(vebus_service, '/Ac/ActiveIn/ActiveInput') - # Active input is connected - connected = self._dbusmonitor.get_value(vebus_service, '/Ac/ActiveIn/Connected') - if None not in (activein, connected): - values['stoponac1'] = activein == 0 and connected == 1 - else: - values['stoponac1'] = None - - # Invalidate if vebus is not available - if loadOnAcOut[0] == None: - values['acload'] = None - - if values['batterycurrent']: - values['batterycurrent'] *= -1 - - # When multi is connected to CAN-bus, alarms are published to - # /Alarms/Overload... but when connected to vebus alarms are - # splitted in three phases and published to /Alarms/LX/Overload... - if values['inverteroverload'] == None: - values['inverteroverload'] = max(inverterOverload) - - if values['inverterhightemp'] == None: - values['inverterhightemp'] = max(inverterHighTemp) - - return values - - def _determineservices(self): - # batterymeasurement is either 'default' or 'com_victronenergy_battery_288/Dc/0'. - # In case it is set to default, we use the AutoSelected battery - # measurement, given by SystemCalc. - batterymeasurement = None - newbatteryservice = None - batteryprefix = '' - selectedbattery = self._settings['batterymeasurement'] - vebusservice = None - - if selectedbattery == 'default': - batterymeasurement = 'default' - elif len(selectedbattery.split('/', 1)) == 2: # Only very basic sanity checking.. - batterymeasurement = self._settings['batterymeasurement'] - elif selectedbattery == 'nobattery': - batterymeasurement = None - else: - # Exception: unexpected value for batterymeasurement - pass - - if batterymeasurement and batterymeasurement != 'default': - batteryprefix = '/' + batterymeasurement.split('/', 1)[1] - - # Get the current battery servicename - if self._battery_service: - oldservice = self._battery_service - else: - oldservice = None - - if batterymeasurement != 'default': - battery_instance = int(batterymeasurement.split('_', 3)[3].split('/')[0]) - service_type = None - - if 'vebus' in batterymeasurement: - service_type = 'vebus' - elif 'battery' in batterymeasurement: - service_type = 'battery' - - newbatteryservice = self._get_servicename_by_instance(battery_instance, service_type) - elif batterymeasurement == 'default': - newbatteryservice = 'default' - - if newbatteryservice and newbatteryservice != oldservice: - if selectedbattery == 'default': - self.log_info('Getting battery values from systemcalc.') - if selectedbattery == 'nobattery': - self.log_info('Battery monitoring disabled! Stop evaluating related conditions') - self._battery_service = None - self._battery_prefix = None - self.log_info('Battery service we need (%s) found! Using it for generator start/stop' % batterymeasurement) - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - elif not newbatteryservice and newbatteryservice != oldservice: - self.log_info('Error getting battery service!') - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - - # Get the default VE.Bus service - vebusservice = self._dbusmonitor.get_value('com.victronenergy.system', '/VebusService') - if vebusservice: - if self._vebusservice != vebusservice: - self._vebusservice = vebusservice - self.log_info('Vebus service (%s) found! Using it for generator start/stop' % vebusservice) - else: - if self._vebusservice is not None: - self.log_info('Vebus service (%s) dissapeared! Stop evaluating related conditions' % self._vebusservice) - else: - self.log_info('Error getting Vebus service!') - self._vebusservice = None - - def _get_servicename_by_instance(self, instance, service_type=None): - sv = None - services = self._dbusmonitor.get_service_list() - - for service in services: - if service_type and service_type not in service: - continue - - if services[service] == instance: - sv = service - break - - return sv - - def _get_monotonic_seconds(self): - return monotonic_time.monotonic_time().to_seconds_double() - - def _start_generator(self, condition): - state = self._dbusservice['/State'] - remote_state = self._get_remote_switch_state() - - # This function will start the generator in the case generator not - # already running. When differs, the RunningByCondition is updated - if state == States.STOPPED or remote_state != state: - self._dbusservice['/State'] = States.RUNNING - self._update_remote_switch() - self._starttime = monotonic_time.monotonic_time().to_seconds_double() - self.log_info('Starting generator by %s condition' % condition) - elif self._dbusservice['/RunningByCondition'] != condition: - self.log_info('Generator previously running by %s condition is now running by %s condition' - % (self._dbusservice['/RunningByCondition'], condition)) - - self._dbusservice['/RunningByCondition'] = condition - self._dbusservice['/RunningByConditionCode'] = RunningConditions.lookup(condition) - - def _stop_generator(self): - state = self._dbusservice['/State'] - remote_state = self._get_remote_switch_state() - - if state == 1 or remote_state != state: - self._dbusservice['/State'] = States.STOPPED - self._update_remote_switch() - self.log_info('Stopping generator that was running by %s condition' % - str(self._dbusservice['/RunningByCondition'])) - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped -#### GuiMods - self._accumulateRunTime () - - self._starttime = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._manualstarttimer = 0 - self._last_runtime_update = 0 - - def _update_remote_switch(self): - self._set_remote_switch_state(dbus.Int32(self._dbusservice['/State'], variant_level=1)) - - def _get_remote_switch_state(self): - raise Exception('This function should be overridden') - - def _set_remote_switch_state(self, value): - raise Exception('This function should be overridden') - - # Check the remote status, for example errors - def _check_remote_status(self): - raise Exception('This function should be overridden') - - def _remote_setup(self): - raise Exception('This function should be overridden') - - def _create_dbus_monitor(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_settings(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_dbus_service(self): - raise Exception('This function should be overridden') - -#### GuiMods - -# this function connects the generator digital input (if any) -# OR the generator AC input detection -# to the generator /ManualStart and updates dbus paths used by the GUI -# -# if the generator digital input changes from stopped to running -# AND no run conditions are active, a manual start is innitiated -# -# if the generator digital input changes from running to stopped -# AND a manual start is active, a manual stop is innitiated -# -# /GeneratorRunningState provides the input running state from the digital input to the GUI -# R = running -# S = stopped -# ? = unknown (no digital input found) -# -# /ExternalOverride is used by the GUI to alert the user when there is a conflict -# between the generator running state and the state Venus -# /ExternalOverride is True if /GeneratorRunningState is S -# AND the /RunningCondition is not stopped (which includes a manual run) -# activation is delayed 5 seconds to allow transitions to settle -# -# we must first find the geneator digital input, if it exists at all -# we serche all dBus services looking for a digital input with type generator (9) -# the search only occurs every 10 seconds -# - - def _processGeneratorRunDetection (self): - TheBus = dbus.SystemBus() - generatorState = self._dbusservice['/State'] - try: - # current input service is no longer valid - # search for a new one only every 10 seconds to avoid unnecessary processing - if (self._digitalInputTypeObject == None or self._digitalInputTypeObject.GetValue() != 9) and self._searchDelay > 10: - newInputService = "" - for service in TheBus.list_names(): - # found a digital input servic, now check the type - if service.startswith ("com.victronenergy.digitalinput"): - self._digitalInputTypeObject = TheBus.get_object (service, '/Type') - # found it! - if self._digitalInputTypeObject.GetValue() == 9: - newInputService = service - break - - # found new service - get objects for use later - if newInputService != "": - self.log_info ("Found generator digital input service at %s" % newInputService) - self._generatorInputStateObject = TheBus.get_object(newInputService, '/State') - else: - if self._generatorInputStateObject != None: - self.log_info ("Generator digital input service NOT found") - self._generatorInputStateObject = None - self._digitalInputTypeObject = None - self._searchDelay = 0 # start delay timer - - # if serch delay timer is active, increment it now - if self._searchDelay <= 10: - self._searchDelay += 1 - - - # collect generator input states - inputState = '?' - # if generator digital input is present, use that - if self._generatorInputStateObject != None: - inputState = self._generatorInputStateObject.GetValue () - if inputState == 10: - inputState = 'R' - elif inputState == 11: - inputState = 'S' - - # update /GeneratorRunningState - if inputState != self._lastState: - self._dbusservice['/GeneratorRunningState'] = inputState - - # forward input state changes to /ManualStart - if self._linkToExternalState: - if inputState == "R" and generatorState == States.STOPPED: - self.log_info ("generator was started externally - syncing ManualStart state") - self._dbusservice['/ManualStart'] = 1 - elif inputState == "S" and self._dbusservice['/ManualStart'] == 1 \ - and generatorState in (States.RUNNING, States.WARMUP, States.COOLDOWN): - self.log_info ("generator was stopped externally - syncing ManualStart state") - self._dbusservice['/ManualStart'] = 0 - - # update /ExternalOverride - if inputState == "S" and self._linkToExternalState and generatorState == States.RUNNING: - if self._externalOverrideDelay > 5: - self._externalOverride = True - else: - self._externalOverrideDelay += 1 - else: - self._externalOverride = False - self._externalOverrideDelay = 0 - - if self._externalOverride != self._lastExternalOverride: - self._dbusservice['/ExternalOverride'] = self._externalOverride - self._lastExternalOverride = self._externalOverride - - except dbus.DBusException: - self.log_info ("dbus exception - generator digital input no longer valid") - self._generatorInputStateObject = None - self._digitalInputTypeObject = None - inputState = 0 - - self._lastState = inputState - - -# -# control the accumulaiton of run time based on generator input Running state -# if the internal state is RUNNING run time is accumulated in self._accumulatedRunTime -# run time is accumulated if the generator's running state is known to be running or -# if the generator running state can't be determined -# the accumulated time dBus parameter and daily and total time accumulators are updated -# only once everh 60 seconds to minimize processor load -# if the internal state is STOPPED, one last dBus, daily and total time updates are done -# then the current time accumulator is cleared - - def _accumulateRunTime (self): - - mtime = monotonic_time.monotonic_time().to_seconds_double() - - # grab running state from dBus once, use it many timed below - - if self._dbusservice['/State'] == States.RUNNING: - internalRun = True - else: - internalRun = False - - # if internal state is running, accumulate time if generator is running - if internalRun: - accumuateTime = True - # start new accumulation if not done prevously - if self._last_accumulate_time == 0: - self._last_accumulate_time = mtime - - # if link to external state is enabled, don't accumulate time if running state is stopped (accumulate if R or ?) - if self._linkToExternalState: - try: - if self._dbusservice['/GeneratorRunningState'] == "S": - accumuateTime = False - - # if no Forwarder service, allow accumulation - except dbus.DBusException: - self.log_info ("dBus exception in startstop.py") - - # internal state STOPPED so don't add new time to the accumulation - # but there may be time already accumulated that needs to be added to daily and total accumulations - else: - accumuateTime = False - - # accumulate run time if we passed all the tests above - if accumuateTime: - self._accumulatedRunTime += mtime - self._last_accumulate_time - self._last_accumulate_time = mtime - - # dbus and settings updates trigger time-intensive processing so only do this once every 60 seconds - doUpdate = False - if internalRun: - if mtime - self._last_update_mtime >= 60: - doUpdate = True - self._last_update_mtime = mtime - # it is also done one last time when state is no longer RUNNING - elif self._last_update_mtime != 0: - doUpdate = True - - if doUpdate: - self._update_accumulated_time() - - # stopped - clear the current time accumulator - if internalRun == False: - self._last_update_mtime = 0 - self._accumulatedRunTime = 0 - self._last_accumulate_time = 0 - - self._dbusservice['/Runtime'] = int(self._accumulatedRunTime) diff --git a/FileSets/v2.73/startstop.py.orig b/FileSets/v2.73/startstop.py.orig deleted file mode 100644 index a38f1a90..00000000 --- a/FileSets/v2.73/startstop.py.orig +++ /dev/null @@ -1,964 +0,0 @@ -#!/usr/bin/python -u -# -*- coding: utf-8 -*- - -# Function -# dbus_generator monitors the dbus for batteries (com.victronenergy.battery.*) and -# vebus com.victronenergy.vebus.* -# Battery and vebus monitors can be configured through the gui. -# It then monitors SOC, AC loads, battery current and battery voltage,to auto start/stop the generator based -# on the configuration settings. Generator can be started manually or periodically setting a tes trun period. -# Time zones function allows to use different values for the conditions along the day depending on time - -import dbus -import datetime -import calendar -import time -import sys -import json -import os -import logging -from os import environ -import monotonic_time -from gen_utils import DBusServicePrefix, SettingsPrefix, Errors, States, enum -# Victron packages -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) -from ve_utils import exit_on_error -from settingsdevice import SettingsDevice - -RunningConditions = enum( - Stopped = 0, - Manual = 1, - TestRun = 2, - LossOfCommunication = 3, - Soc = 4, - Acload = 5, - BatteryCurrent = 6, - BatteryVoltage = 7, - InverterHighTemp = 8, - InverterOverload = 9, - StopOnAc1 = 10) - -SYSTEM_SERVICE = 'com.victronenergy.system' -BATTERY_PREFIX = '/Dc/Battery' -HISTORY_DAYS = 30 - - -class StartStop: - def __init__(self): - self._dbusservice = None - self._settings = None - self._dbusmonitor = None - self._remoteservice = None - self._name = None - self._enabled = False - - # One second per retry - self.RETRIES_ON_ERROR = 300 - self._testrun_soc_retries = 0 - self._last_counters_check = 0 - - self._starttime = 0 - self._manualstarttimer = 0 - self._last_runtime_update = 0 - self._timer_runnning = 0 - - # Manual battery service selection is deprecated in favour - # of getting the values directly from systemcalc, we keep - # manual selected services handling for compatibility reasons. - self._vebusservice = None - self._errorstate = 0 - self._battery_service = None - self._battery_prefix = None - - self._acpower_inverter_input = { - 'timeout': 0, - 'unabletostart': False - } - - self._condition_stack = { - 'batteryvoltage': { - 'name': 'batteryvoltage', - 'reached': False, - 'boolean': False, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'battery' - }, - 'batterycurrent': { - 'name': 'batterycurrent', - 'reached': False, - 'boolean': False, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'battery' - }, - 'acload': { - 'name': 'acload', - 'reached': False, - 'boolean': False, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - }, - 'inverterhightemp': { - 'name': 'inverterhightemp', - 'reached': False, - 'boolean': True, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - }, - 'inverteroverload': { - 'name': 'inverteroverload', - 'reached': False, - 'boolean': True, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - }, - 'soc': { - 'name': 'soc', - 'reached': False, - 'boolean': False, - 'timed': False, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'battery' - }, - 'stoponac1': { - 'name': 'stoponac1', - 'reached': False, - 'boolean': True, - 'timed': False, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - } - } - - def set_sources(self, dbusmonitor, dbusservice, settings, name, remoteservice): - self._dbusservice = DBusServicePrefix(dbusservice, name) - self._settings = SettingsPrefix(settings, name) - self._dbusmonitor = dbusmonitor - self._remoteservice = remoteservice - self._name = name - # Set timezone to user selected timezone - tz = self._dbusmonitor.get_value('com.victronenergy.settings', '/Settings/System/TimeZone') - environ['TZ'] = tz if tz else 'UTC' - - self.log_info('Start/stop instance created for %s.' % self._remoteservice) - self._remote_setup() - - def _create_paths(self): - # State: None = invalid, 0 = stopped, 1 = running - self._dbusservice.add_path('/State', value=None) - # RunningByConditionCode: Numeric Companion to /RunningByCondition below, but - # also encompassing a Stopped state. - self._dbusservice.add_path('/RunningByConditionCode', value=None) - # Error - self._dbusservice.add_path('/Error', value=None, gettextcallback=self._gettext) - # Condition that made the generator start - self._dbusservice.add_path('/RunningByCondition', value=None) - # Runtime - self._dbusservice.add_path('/Runtime', value=None, gettextcallback=self._gettext) - # Today runtime - self._dbusservice.add_path('/TodayRuntime', value=None, gettextcallback=self._gettext) - # Test run runtime - self._dbusservice.add_path('/TestRunIntervalRuntime', value=None , gettextcallback=self._gettext) - # Next test run date, values is 0 for test run disabled - self._dbusservice.add_path('/NextTestRun', value=None, gettextcallback=self._gettext) - # Next test run is needed 1, not needed 0 - self._dbusservice.add_path('/SkipTestRun', value=None) - # Manual start - self._dbusservice.add_path('/ManualStart', value=None, writeable=True) - # Manual start timer - self._dbusservice.add_path('/ManualStartTimer', value=None, writeable=True) - # Silent mode active - self._dbusservice.add_path('/QuietHours', value=None) - # Alarms - self._dbusservice.add_path('/Alarms/NoGeneratorAtAcIn', value=None) - - # We need to set the values after creating the paths to trigger the 'onValueChanged' event for the gui - # otherwise the gui will report the paths as invalid if we remove and recreate the paths without - # restarting the dbusservice. - self._dbusservice['/State'] = 0 - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped - self._dbusservice['/Error'] = 0 - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/Runtime'] = 0 - self._dbusservice['/TodayRuntime'] = 0 - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - self._dbusservice['/NextTestRun'] = None - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/ManualStart'] = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._dbusservice['/QuietHours'] = 0 - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - - - - def enable(self): - if self._enabled: - return - self.log_info('Enabling auto start/stop and taking control of remote switch') - self._create_paths() - self._determineservices() - self._update_remote_switch() - self._enabled = True - - def disable(self): - if not self._enabled: - return - self.log_info('Disabling auto start/stop, releasing control of remote switch') - self._remove_paths() - self._enabled = False - - def remove(self): - self.disable() - self.log_info('Removed from start/stop instances') - - def _remove_paths(self): - self._dbusservice.__delitem__('/State') - self._dbusservice.__delitem__('/RunningByConditionCode') - self._dbusservice.__delitem__('/Error') - self._dbusservice.__delitem__('/RunningByCondition') - self._dbusservice.__delitem__('/Runtime') - self._dbusservice.__delitem__('/TodayRuntime') - self._dbusservice.__delitem__('/TestRunIntervalRuntime') - self._dbusservice.__delitem__('/NextTestRun') - self._dbusservice.__delitem__('/SkipTestRun') - self._dbusservice.__delitem__('/ManualStart') - self._dbusservice.__delitem__('/ManualStartTimer') - self._dbusservice.__delitem__('/QuietHours') - self._dbusservice.__delitem__('/Alarms/NoGeneratorAtAcIn') - - def device_added(self, dbusservicename, instance): - self._determineservices() - - def device_removed(self, dbusservicename, instance): - self._determineservices() - - def get_error(self): - return self._dbusservice['/Error'] - - def set_error(self, errorn): - self._dbusservice['/Error'] = errorn - - def clear_error(self): - self._dbusservice['/Error'] = Errors.NONE - - def dbus_value_changed(self, dbusServiceName, dbusPath, options, changes, deviceInstance): - if self._dbusservice is None: - return - if dbusPath == '/AutoSelectedBatteryMeasurement' and self._settings['batterymeasurement'] == 'default': - self._determineservices() - - if dbusPath == '/VebusService': - self._determineservices() - - # Update env timezone when setting changes - if dbusPath == '/Settings/System/TimeZone': - environ['TZ'] = changes['Value'] if changes['Value'] else 'UTC' - - def handlechangedsetting(self, setting, oldvalue, newvalue): - if self._dbusservice is None: - return - if self._name not in setting: - # Not our setting - return - - s = self._settings.removeprefix(setting) - - if s == 'batterymeasurement': - self._determineservices() - # Reset retries and valid if service changes - for condition in self._condition_stack: - if self._condition_stack[condition]['monitoring'] == 'battery': - self._condition_stack[condition]['valid'] = True - self._condition_stack[condition]['retries'] = 0 - - if s == 'autostart': - self.log_info('Autostart function %s.' % ('enabled' if newvalue == 1 else 'disabled')) - - if self._dbusservice is not None and s == 'testruninterval': - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime( - self._settings['testruninterval']) - - def dbus_name_owner_changed(self, name, oldowner, newowner): - self._determineservices() - - def _gettext(self, path, value): - path = path.replace("/" + self._name, '') - - if path == '/Error': - return Errors.get_description(value) - if path == '/NextTestRun': - # Locale format date - d = datetime.datetime.fromtimestamp(value) - return d.strftime('%c') - elif path in ['/Runtime', '/TestRunIntervalRuntime', '/TodayRuntime']: - m, s = divmod(value, 60) - h, m = divmod(m, 60) - return '%dh, %dm, %ds' % (h, m, s) - else: - return str(value) - - def log_info(self, msg): - logging.info(self._name + ': %s' % msg) - - def tick(self): - if not self._enabled: - return - self._check_remote_status() - self._evaluate_startstop_conditions() - self._detect_generator_at_acinput() - - def _evaluate_startstop_conditions(self): - if self.get_error() != Errors.NONE: - # First evaluation after an error, log it - if self._errorstate == 0: - self._errorstate = 1 - self._dbusservice['/State'] = States.ERROR - self.log_info('Error: #%i - %s, stop controlling remote.' % - (self.get_error(), - Errors.get_description(self.get_error()))) - elif self._errorstate == 1: - # Error cleared - self._errorstate = 0 - self.log_info('Error state cleared, taking control of remote switch.') - - # Conditions will be evaluated in this order - conditions = ['soc', 'acload', 'batterycurrent', 'batteryvoltage', 'inverterhightemp', 'inverteroverload', 'stoponac1'] - start = False - startbycondition = None - activecondition = self._dbusservice['/RunningByCondition'] - today = calendar.timegm(datetime.date.today().timetuple()) - self._timer_runnning = False - values = self._get_updated_values() - connection_lost = False - - self._check_quiet_hours() - - # New day, register it - if self._last_counters_check < today and self._dbusservice['/State'] == States.STOPPED: - self._last_counters_check = today - self._update_accumulated_time() - - # Update current and accumulated runtime. - # By performance reasons, accumulated runtime is only updated - # once per 60s. When the generator stops is also updated. - if self._dbusservice['/State'] == States.RUNNING: - mtime = monotonic_time.monotonic_time().to_seconds_double() - if (mtime - self._starttime) - self._last_runtime_update >= 60: - self._dbusservice['/Runtime'] = int(mtime - self._starttime) - self._update_accumulated_time() - elif self._last_runtime_update == 0: - self._dbusservice['/Runtime'] = int(mtime - self._starttime) - - - if self._evaluate_manual_start(): - startbycondition = 'manual' - start = True - - # Conditions will only be evaluated if the autostart functionality is enabled - if self._settings['autostart'] == 1: - - if self._evaluate_testrun_condition(): - startbycondition = 'testrun' - start = True - - # Evaluate value conditions - for condition in conditions: - start = self._evaluate_condition(self._condition_stack[condition], values[condition]) or start - startbycondition = condition if start and startbycondition is None else startbycondition - # Connection lost is set to true if the number of retries of one or more enabled conditions - # >= RETRIES_ON_ERROR - if self._condition_stack[condition]['enabled']: - connection_lost = self._condition_stack[condition]['retries'] >= self.RETRIES_ON_ERROR - - if self._condition_stack['stoponac1']['reached'] and startbycondition not in ['manual', 'testrun']: - start = False - if self._dbusservice['/State'] == States.RUNNING and activecondition not in ['manual', 'testrun']: - self.log_info('AC input 1 available, stopping') - - # If none condition is reached check if connection is lost and start/keep running the generator - # depending on '/OnLossCommunication' setting - if not start and connection_lost: - # Start always - if self._settings['onlosscommunication'] == 1: - start = True - startbycondition = 'lossofcommunication' - # Keep running if generator already started - if self._dbusservice['/State'] == States.RUNNING and self._settings['onlosscommunication'] == 2: - start = True - startbycondition = 'lossofcommunication' - - if not start and self._errorstate: - self._stop_generator() - - if self._errorstate: - return - - if start: - self._start_generator(startbycondition) - elif (self._dbusservice['/Runtime'] >= self._settings['minimumruntime'] * 60 - or activecondition == 'manual'): - self._stop_generator() - - def _detect_generator_at_acinput(self): - state = self._dbusservice['/State'] - - if state == States.STOPPED: - self._reset_acpower_inverter_input() - return - - if self._settings['nogeneratoratacinalarm'] == 0: - self._reset_acpower_inverter_input() - return - - vebus_service = self._vebusservice if self._vebusservice else '' - activein_state = self._dbusmonitor.get_value( - vebus_service, '/Ac/ActiveIn/Connected') - - # Path not supported, skip evaluation - if activein_state == None: - return - - # Sources 0 = Not available, 1 = Grid, 2 = Generator, 3 = Shore - generator_acsource = self._dbusmonitor.get_value( - SYSTEM_SERVICE, '/Ac/ActiveIn/Source') == 2 - # Not connected = 0, connected = 1 - activein_connected = activein_state == 1 - - if generator_acsource and activein_connected: - if self._acpower_inverter_input['unabletostart']: - self.log_info('Generator detected at inverter AC input, alarm removed') - self._reset_acpower_inverter_input() - elif self._acpower_inverter_input['timeout'] < self.RETRIES_ON_ERROR: - self._acpower_inverter_input['timeout'] += 1 - elif not self._acpower_inverter_input['unabletostart']: - self._acpower_inverter_input['unabletostart'] = True - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 2 - self.log_info('Generator not detected at inverter AC input, triggering alarm') - - def _reset_acpower_inverter_input(self, clear_error=True): - if self._acpower_inverter_input['timeout'] != 0: - self._acpower_inverter_input['timeout'] = 0 - - if self._acpower_inverter_input['unabletostart'] != 0: - self._acpower_inverter_input['unabletostart'] = 0 - - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - - def _reset_condition(self, condition): - condition['reached'] = False - if condition['timed']: - condition['start_timer'] = 0 - condition['stop_timer'] = 0 - - def _check_condition(self, condition, value): - name = condition['name'] - - if self._settings[name + 'enabled'] == 0: - if condition['enabled']: - condition['enabled'] = False - self.log_info('Disabling (%s) condition' % name) - condition['retries'] = 0 - condition['valid'] = True - self._reset_condition(condition) - return False - - elif not condition['enabled']: - condition['enabled'] = True - self.log_info('Enabling (%s) condition' % name) - - if (condition['monitoring'] == 'battery') and (self._settings['batterymeasurement'] == 'nobattery'): - # If no battery monitor is selected reset the condition - self._reset_condition(condition) - return False - - if value is None and condition['valid']: - if condition['retries'] >= self.RETRIES_ON_ERROR: - logging.info('Error getting (%s) value, skipping evaluation till get a valid value' % name) - self._reset_condition(condition) - self._comunnication_lost = True - condition['valid'] = False - else: - condition['retries'] += 1 - if condition['retries'] == 1 or (condition['retries'] % 10) == 0: - self.log_info('Error getting (%s) value, retrying(#%i)' % (name, condition['retries'])) - return False - - elif value is not None and not condition['valid']: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['valid'] = True - condition['retries'] = 0 - - # Reset retries if value is valid - if value is not None and condition['retries'] > 0: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['retries'] = 0 - - return condition['valid'] - - def _evaluate_condition(self, condition, value): - name = condition['name'] - setting = ('qh_' if self._dbusservice['/QuietHours'] == 1 else '') + name - startvalue = self._settings[setting + 'start'] if not condition['boolean'] else 1 - stopvalue = self._settings[setting + 'stop'] if not condition['boolean'] else 0 - - # Check if the condition has to be evaluated - if not self._check_condition(condition, value): - # If generator is started by this condition and value is invalid - # wait till RETRIES_ON_ERROR to skip the condition - if condition['reached'] and condition['retries'] <= self.RETRIES_ON_ERROR: - if condition['retries'] > 0: - return True - - return False - - # As this is a generic evaluation method, we need to know how to compare the values - # first check if start value should be greater than stop value and then compare - start_is_greater = startvalue > stopvalue - - # When the condition is already reached only the stop value can set it to False - start = condition['reached'] or (value >= startvalue if start_is_greater else value <= startvalue) - stop = value <= stopvalue if start_is_greater else value >= stopvalue - - # Timed conditions must start/stop after the condition has been reached for a minimum - # time. - if condition['timed']: - if not condition['reached'] and start: - condition['start_timer'] += time.time() if condition['start_timer'] == 0 else 0 - start = time.time() - condition['start_timer'] >= self._settings[name + 'starttimer'] - condition['stop_timer'] *= int(not start) - self._timer_runnning = True - else: - condition['start_timer'] = 0 - - if condition['reached'] and stop: - condition['stop_timer'] += time.time() if condition['stop_timer'] == 0 else 0 - stop = time.time() - condition['stop_timer'] >= self._settings[name + 'stoptimer'] - condition['stop_timer'] *= int(not stop) - self._timer_runnning = True - else: - condition['stop_timer'] = 0 - - condition['reached'] = start and not stop - return condition['reached'] - - def _evaluate_manual_start(self): - if self._dbusservice['/ManualStart'] == 0: - if self._dbusservice['/RunningByCondition'] == 'manual': - self._dbusservice['/ManualStartTimer'] = 0 - return False - - start = True - # If /ManualStartTimer has a value greater than zero will use it to set a stop timer. - # If no timer is set, the generator will not stop until the user stops it manually. - # Once started by manual start, each evaluation the timer is decreased - if self._dbusservice['/ManualStartTimer'] != 0: - self._manualstarttimer += time.time() if self._manualstarttimer == 0 else 0 - self._dbusservice['/ManualStartTimer'] -= int(time.time()) - int(self._manualstarttimer) - self._manualstarttimer = time.time() - start = self._dbusservice['/ManualStartTimer'] > 0 - self._dbusservice['/ManualStart'] = int(start) - # Reset if timer is finished - self._manualstarttimer *= int(start) - self._dbusservice['/ManualStartTimer'] *= int(start) - - return start - - def _evaluate_testrun_condition(self): - if self._settings['testrunenabled'] == 0: - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/NextTestRun'] = None - return False - - today = datetime.date.today() - yesterday = today - datetime.timedelta(days=1) # Should deal well with DST - now = time.time() - runtillbatteryfull = self._settings['testruntillbatteryfull'] == 1 - soc = self._get_updated_values()['soc'] - batteryisfull = runtillbatteryfull and soc == 100 - duration = 60 if runtillbatteryfull else self._settings['testrunruntime'] - - try: - startdate = datetime.date.fromtimestamp(self._settings['testrunstartdate']) - _starttime = time.mktime(yesterday.timetuple()) + self._settings['testrunstarttimer'] - - # today might in fact still be yesterday, if this test run started - # before midnight and finishes after. If `now` still falls in - # yesterday's window, then by the temporal anthropic principle, - # which I just made up but loosely states that time must have - # these properties for observers to exist, it must be yesterday - # because we are here to observe it. - if _starttime <= now <= _starttime + duration: - today = yesterday - starttime = _starttime - else: - starttime = time.mktime(today.timetuple()) + self._settings['testrunstarttimer'] - except ValueError: - logging.debug('Invalid dates, skipping testrun') - return False - - # If start date is in the future set as NextTestRun and stop evaluating - if startdate > today: - self._dbusservice['/NextTestRun'] = time.mktime(startdate.timetuple()) - return False - - start = False - # If the accumulated runtime during the tes trun interval is greater than '/TestRunIntervalRuntime' - # the tes trun must be skipped - needed = (self._settings['testrunskipruntime'] > self._dbusservice['/TestRunIntervalRuntime'] - or self._settings['testrunskipruntime'] == 0) - self._dbusservice['/SkipTestRun'] = int(not needed) - - interval = self._settings['testruninterval'] - stoptime = starttime + duration - elapseddays = (today - startdate).days - mod = elapseddays % interval - - start = not bool(mod) and starttime <= now <= stoptime - - if runtillbatteryfull: - if soc is not None: - self._testrun_soc_retries = 0 - start = (start or self._dbusservice['/RunningByCondition'] == 'testrun') and not batteryisfull - elif self._dbusservice['/RunningByCondition'] == 'testrun': - if self._testrun_soc_retries < self.RETRIES_ON_ERROR: - self._testrun_soc_retries += 1 - start = True - if (self._testrun_soc_retries % 10) == 0: - self.log_info('Test run failed to get SOC value, retrying(#%i)' % self._testrun_soc_retries) - else: - self.log_info('Failed to get SOC after %i retries, terminating test run condition' % self._testrun_soc_retries) - start = False - else: - start = False - - if not bool(mod) and (now <= stoptime): - self._dbusservice['/NextTestRun'] = starttime - else: - self._dbusservice['/NextTestRun'] = (time.mktime((today + datetime.timedelta(days=interval - mod)).timetuple()) + - self._settings['testrunstarttimer']) - return start and needed - - def _check_quiet_hours(self): - active = False - if self._settings['quiethoursenabled'] == 1: - # Seconds after today 00:00 - timeinseconds = time.time() - time.mktime(datetime.date.today().timetuple()) - quiethoursstart = self._settings['quiethoursstarttime'] - quiethoursend = self._settings['quiethoursendtime'] - - # Check if the current time is between the start time and end time - if quiethoursstart < quiethoursend: - active = quiethoursstart <= timeinseconds and timeinseconds < quiethoursend - else: # End time is lower than start time, example Start: 21:00, end: 08:00 - active = not (quiethoursend < timeinseconds and timeinseconds < quiethoursstart) - - if self._dbusservice['/QuietHours'] == 0 and active: - self.log_info('Entering to quiet mode') - - elif self._dbusservice['/QuietHours'] == 1 and not active: - self.log_info('Leaving quiet mode') - - self._dbusservice['/QuietHours'] = int(active) - - return active - - def _update_accumulated_time(self): - seconds = self._dbusservice['/Runtime'] - accumulated = seconds - self._last_runtime_update - - self._settings['accumulatedtotal'] = int(self._settings['accumulatedtotal']) + accumulated - # Using calendar to get timestamp in UTC, not local time - today_date = str(calendar.timegm(datetime.date.today().timetuple())) - - # If something goes wrong getting the json string create a new one - try: - accumulated_days = json.loads(self._settings['accumulateddaily']) - except ValueError: - accumulated_days = {today_date: 0} - - if (today_date in accumulated_days): - accumulated_days[today_date] += accumulated - else: - accumulated_days[today_date] = accumulated - - self._last_runtime_update = seconds - - # Keep the historical with a maximum of HISTORY_DAYS - while len(accumulated_days) > HISTORY_DAYS: - accumulated_days.pop(min(accumulated_days.keys()), None) - - # Upadate settings - self._settings['accumulateddaily'] = json.dumps(accumulated_days, sort_keys=True) - self._dbusservice['/TodayRuntime'] = self._interval_runtime(0) - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - - def _interval_runtime(self, days): - summ = 0 - try: - daily_record = json.loads(self._settings['accumulateddaily']) - except ValueError: - return 0 - - for i in range(days + 1): - previous_day = calendar.timegm((datetime.date.today() - datetime.timedelta(days=i)).timetuple()) - if str(previous_day) in daily_record.keys(): - summ += daily_record[str(previous_day)] if str(previous_day) in daily_record.keys() else 0 - - return summ - - def _get_battery(self): - battery = {} - if self._settings['batterymeasurement'] == 'default': - battery['service'] = SYSTEM_SERVICE - battery['prefix'] = BATTERY_PREFIX - else: - battery['service'] = self._battery_service if self._battery_service else '' - battery['prefix'] = self._battery_prefix if self._battery_prefix else '' - - return battery - - def _get_updated_values(self): - battery = self._get_battery() - vebus_service = self._vebusservice if self._vebusservice else '' - loadOnAcOut = [] - totalConsumption = [] - inverterHighTemp = [] - inverterOverload = [] - - values = { - 'batteryvoltage': self._dbusmonitor.get_value(battery['service'], battery['prefix'] + '/Voltage'), - 'batterycurrent': self._dbusmonitor.get_value(battery['service'], battery['prefix'] + '/Current'), - # Soc from the device doesn't have the '/Dc/0' prefix like the current and voltage do, but it does - # have the same prefix on systemcalc - 'soc': self._dbusmonitor.get_value(battery['service'], (battery['prefix'] if battery['prefix'] == BATTERY_PREFIX else '') + '/Soc'), - 'inverterhightemp': self._dbusmonitor.get_value(vebus_service, '/Alarms/HighTemperature'), - 'inverteroverload': self._dbusmonitor.get_value(vebus_service, '/Alarms/Overload') - } - - for phase in ['L1', 'L2', 'L3']: - # Get the values directly from the inverter, systemcalc doesn't provide raw inverted power - loadOnAcOut.append(self._dbusmonitor.get_value(vebus_service, ('/Ac/Out/%s/P' % phase))) - - # Calculate total consumption, '/Ac/Consumption/%s/Power' is deprecated - c_i = self._dbusmonitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnInput/%s/Power' % phase)) - c_o = self._dbusmonitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnOutput/%s/Power' % phase)) - totalConsumption.append(sum(filter(None, (c_i, c_o)))) - - # Inverter alarms must be fetched directly from the inverter service - inverterHighTemp.append(self._dbusmonitor.get_value(vebus_service, ('/Alarms/%s/HighTemperature' % phase))) - inverterOverload.append(self._dbusmonitor.get_value(vebus_service, ('/Alarms/%s/Overload' % phase))) - - # Toltal consumption - if self._settings['acloadmeasuerment'] == 0: - values['acload'] = sum(filter(None, totalConsumption)) - - # Load on inverter AC out - if self._settings['acloadmeasuerment'] == 1: - values['acload'] = sum(filter(None, loadOnAcOut)) - - # Highest phase load - if self._settings['acloadmeasuerment'] == 2: - values['acload'] = max(loadOnAcOut) - - # AC input 1 - activein = self._dbusmonitor.get_value(vebus_service, '/Ac/ActiveIn/ActiveInput') - # Active input is connected - connected = self._dbusmonitor.get_value(vebus_service, '/Ac/ActiveIn/Connected') - if None not in (activein, connected): - values['stoponac1'] = activein == 0 and connected == 1 - else: - values['stoponac1'] = None - - # Invalidate if vebus is not available - if loadOnAcOut[0] == None: - values['acload'] = None - - if values['batterycurrent']: - values['batterycurrent'] *= -1 - - # When multi is connected to CAN-bus, alarms are published to - # /Alarms/Overload... but when connected to vebus alarms are - # splitted in three phases and published to /Alarms/LX/Overload... - if values['inverteroverload'] == None: - values['inverteroverload'] = max(inverterOverload) - - if values['inverterhightemp'] == None: - values['inverterhightemp'] = max(inverterHighTemp) - - return values - - def _determineservices(self): - # batterymeasurement is either 'default' or 'com_victronenergy_battery_288/Dc/0'. - # In case it is set to default, we use the AutoSelected battery - # measurement, given by SystemCalc. - batterymeasurement = None - newbatteryservice = None - batteryprefix = '' - selectedbattery = self._settings['batterymeasurement'] - vebusservice = None - - if selectedbattery == 'default': - batterymeasurement = 'default' - elif len(selectedbattery.split('/', 1)) == 2: # Only very basic sanity checking.. - batterymeasurement = self._settings['batterymeasurement'] - elif selectedbattery == 'nobattery': - batterymeasurement = None - else: - # Exception: unexpected value for batterymeasurement - pass - - if batterymeasurement and batterymeasurement != 'default': - batteryprefix = '/' + batterymeasurement.split('/', 1)[1] - - # Get the current battery servicename - if self._battery_service: - oldservice = self._battery_service - else: - oldservice = None - - if batterymeasurement != 'default': - battery_instance = int(batterymeasurement.split('_', 3)[3].split('/')[0]) - service_type = None - - if 'vebus' in batterymeasurement: - service_type = 'vebus' - elif 'battery' in batterymeasurement: - service_type = 'battery' - - newbatteryservice = self._get_servicename_by_instance(battery_instance, service_type) - elif batterymeasurement == 'default': - newbatteryservice = 'default' - - if newbatteryservice and newbatteryservice != oldservice: - if selectedbattery == 'default': - self.log_info('Getting battery values from systemcalc.') - if selectedbattery == 'nobattery': - self.log_info('Battery monitoring disabled! Stop evaluating related conditions') - self._battery_service = None - self._battery_prefix = None - self.log_info('Battery service we need (%s) found! Using it for generator start/stop' % batterymeasurement) - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - elif not newbatteryservice and newbatteryservice != oldservice: - self.log_info('Error getting battery service!') - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - - # Get the default VE.Bus service - vebusservice = self._dbusmonitor.get_value('com.victronenergy.system', '/VebusService') - if vebusservice: - if self._vebusservice != vebusservice: - self._vebusservice = vebusservice - self.log_info('Vebus service (%s) found! Using it for generator start/stop' % vebusservice) - else: - if self._vebusservice is not None: - self.log_info('Vebus service (%s) dissapeared! Stop evaluating related conditions' % self._vebusservice) - else: - self.log_info('Error getting Vebus service!') - self._vebusservice = None - - def _get_servicename_by_instance(self, instance, service_type=None): - sv = None - services = self._dbusmonitor.get_service_list() - - for service in services: - if service_type and service_type not in service: - continue - - if services[service] == instance: - sv = service - break - - return sv - - def _get_monotonic_seconds(self): - return monotonic_time.monotonic_time().to_seconds_double() - - def _start_generator(self, condition): - state = self._dbusservice['/State'] - remote_state = self._get_remote_switch_state() - - # This function will start the generator in the case generator not - # already running. When differs, the RunningByCondition is updated - if state == States.STOPPED or remote_state != state: - self._dbusservice['/State'] = States.RUNNING - self._update_remote_switch() - self._starttime = monotonic_time.monotonic_time().to_seconds_double() - self.log_info('Starting generator by %s condition' % condition) - elif self._dbusservice['/RunningByCondition'] != condition: - self.log_info('Generator previously running by %s condition is now running by %s condition' - % (self._dbusservice['/RunningByCondition'], condition)) - - self._dbusservice['/RunningByCondition'] = condition - self._dbusservice['/RunningByConditionCode'] = RunningConditions.lookup(condition) - - def _stop_generator(self): - state = self._dbusservice['/State'] - remote_state = self._get_remote_switch_state() - - if state == 1 or remote_state != state: - self._dbusservice['/State'] = States.STOPPED - self._update_remote_switch() - self.log_info('Stopping generator that was running by %s condition' % - str(self._dbusservice['/RunningByCondition'])) - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped - self._update_accumulated_time() - self._starttime = 0 - self._dbusservice['/Runtime'] = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._manualstarttimer = 0 - self._last_runtime_update = 0 - - def _update_remote_switch(self): - self._set_remote_switch_state(dbus.Int32(self._dbusservice['/State'], variant_level=1)) - - def _get_remote_switch_state(self): - raise Exception('This function should be overridden') - - def _set_remote_switch_state(self, value): - raise Exception('This function should be overridden') - - # Check the remote status, for example errors - def _check_remote_status(self): - raise Exception('This function should be overridden') - - def _remote_setup(self): - raise Exception('This function should be overridden') - - def _create_dbus_monitor(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_settings(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_dbus_service(self): - raise Exception('This function should be overridden') diff --git a/FileSets/v2.73/styles.css b/FileSets/v2.73/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v2.73/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v2.80/Battery.qml b/FileSets/v2.80/Battery.qml deleted file mode 120000 index ef252511..00000000 --- a/FileSets/v2.80/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/Battery.qml \ No newline at end of file diff --git a/FileSets/v2.80/COMPLETE b/FileSets/v2.80/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.80/DetailAcInput.qml b/FileSets/v2.80/DetailAcInput.qml deleted file mode 120000 index b040d3b7..00000000 --- a/FileSets/v2.80/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v2.80/DetailInverter.qml b/FileSets/v2.80/DetailInverter.qml deleted file mode 120000 index d02cb165..00000000 --- a/FileSets/v2.80/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v2.80/DetailLoadsCombined.qml b/FileSets/v2.80/DetailLoadsCombined.qml deleted file mode 120000 index 858daaea..00000000 --- a/FileSets/v2.80/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v2.80/DetailLoadsOnInput.qml b/FileSets/v2.80/DetailLoadsOnInput.qml deleted file mode 120000 index df0a1562..00000000 --- a/FileSets/v2.80/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v2.80/DetailLoadsOnOutput.qml b/FileSets/v2.80/DetailLoadsOnOutput.qml deleted file mode 120000 index 33ab936b..00000000 --- a/FileSets/v2.80/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v2.80/HubData.qml b/FileSets/v2.80/HubData.qml deleted file mode 120000 index 8e608582..00000000 --- a/FileSets/v2.80/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/HubData.qml \ No newline at end of file diff --git a/FileSets/v2.80/LINKS_ONLY b/FileSets/v2.80/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.80/MbEditBox.qml b/FileSets/v2.80/MbEditBox.qml deleted file mode 120000 index 8381b7d5..00000000 --- a/FileSets/v2.80/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v2.80/MbEditBoxDateTime.qml b/FileSets/v2.80/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v2.80/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.80/MbItem.qml b/FileSets/v2.80/MbItem.qml deleted file mode 120000 index 1280e190..00000000 --- a/FileSets/v2.80/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItem.qml \ No newline at end of file diff --git a/FileSets/v2.80/MbItemDigitalInput.qml b/FileSets/v2.80/MbItemDigitalInput.qml deleted file mode 120000 index 63943a08..00000000 --- a/FileSets/v2.80/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.80/MbSpinBox.qml b/FileSets/v2.80/MbSpinBox.qml deleted file mode 120000 index 4160ecd2..00000000 --- a/FileSets/v2.80/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v2.80/MbStyle.qml b/FileSets/v2.80/MbStyle.qml deleted file mode 120000 index db6f181f..00000000 --- a/FileSets/v2.80/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v2.80/MbSubMenu.qml b/FileSets/v2.80/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v2.80/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.80/Multi.qml b/FileSets/v2.80/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v2.80/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.80/ObjectAcConnection.qml b/FileSets/v2.80/ObjectAcConnection.qml deleted file mode 120000 index 9ca254ed..00000000 --- a/FileSets/v2.80/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v2.80/OverviewAcValuesEnhanced.qml b/FileSets/v2.80/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 4d6d5018..00000000 --- a/FileSets/v2.80/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.80/OverviewBox.qml b/FileSets/v2.80/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v2.80/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.80/OverviewConnection.qml b/FileSets/v2.80/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v2.80/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.80/OverviewConnectionEnd.qml b/FileSets/v2.80/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v2.80/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.80/OverviewFlowComplex.qml b/FileSets/v2.80/OverviewFlowComplex.qml deleted file mode 120000 index 6b747507..00000000 --- a/FileSets/v2.80/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v2.80/OverviewGeneratorEnhanced.qml b/FileSets/v2.80/OverviewGeneratorEnhanced.qml deleted file mode 120000 index b0670070..00000000 --- a/FileSets/v2.80/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.80/OverviewGeneratorRelayEnhanced.qml b/FileSets/v2.80/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index c6fa07f9..00000000 --- a/FileSets/v2.80/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.80/OverviewGridParallel.qml b/FileSets/v2.80/OverviewGridParallel.qml deleted file mode 120000 index cbf456ca..00000000 --- a/FileSets/v2.80/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v2.80/OverviewHub.qml b/FileSets/v2.80/OverviewHub.qml deleted file mode 120000 index 3f37eb0c..00000000 --- a/FileSets/v2.80/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v2.80/OverviewHubEnhanced.qml b/FileSets/v2.80/OverviewHubEnhanced.qml deleted file mode 120000 index 6dc4f1d8..00000000 --- a/FileSets/v2.80/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.80/OverviewMobileEnhanced.qml b/FileSets/v2.80/OverviewMobileEnhanced.qml deleted file mode 120000 index a70d4024..00000000 --- a/FileSets/v2.80/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.80/OverviewSolarCharger.qml b/FileSets/v2.80/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v2.80/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.80/OverviewSolarInverter.qml b/FileSets/v2.80/OverviewSolarInverter.qml deleted file mode 120000 index 7cea58a2..00000000 --- a/FileSets/v2.80/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v2.80/OverviewTankDelegate.qml b/FileSets/v2.80/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v2.80/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.80/OverviewTanks.qml b/FileSets/v2.80/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v2.80/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.80/OverviewTanksTempsDigInputs.qml b/FileSets/v2.80/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index d080b0f4..00000000 --- a/FileSets/v2.80/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v2.80/PageDigitalInput.qml b/FileSets/v2.80/PageDigitalInput.qml deleted file mode 120000 index 839f7874..00000000 --- a/FileSets/v2.80/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.80/PageGenerator.qml b/FileSets/v2.80/PageGenerator.qml deleted file mode 120000 index cae51ecb..00000000 --- a/FileSets/v2.80/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.80/PageMain.qml b/FileSets/v2.80/PageMain.qml deleted file mode 120000 index 9f74fa85..00000000 --- a/FileSets/v2.80/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageMain.qml \ No newline at end of file diff --git a/FileSets/v2.80/PageSettingsDisplay.qml b/FileSets/v2.80/PageSettingsDisplay.qml deleted file mode 120000 index b3885a68..00000000 --- a/FileSets/v2.80/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v2.80/PageSettingsGenerator.qml b/FileSets/v2.80/PageSettingsGenerator.qml deleted file mode 120000 index 861e41bb..00000000 --- a/FileSets/v2.80/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.80/PageSettingsGuiMods.qml b/FileSets/v2.80/PageSettingsGuiMods.qml deleted file mode 120000 index d3534bd3..00000000 --- a/FileSets/v2.80/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v2.80/PageSettingsRelay.qml b/FileSets/v2.80/PageSettingsRelay.qml deleted file mode 120000 index 6861254c..00000000 --- a/FileSets/v2.80/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v2.80/PowerGauge.qml b/FileSets/v2.80/PowerGauge.qml deleted file mode 120000 index d82ac28a..00000000 --- a/FileSets/v2.80/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v2.80/Tile.qml b/FileSets/v2.80/Tile.qml deleted file mode 120000 index aa80e332..00000000 --- a/FileSets/v2.80/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/Tile.qml \ No newline at end of file diff --git a/FileSets/v2.80/TileDigIn.qml b/FileSets/v2.80/TileDigIn.qml deleted file mode 120000 index 2f8c7989..00000000 --- a/FileSets/v2.80/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v2.80/TileRelay.qml b/FileSets/v2.80/TileRelay.qml deleted file mode 120000 index 4313882d..00000000 --- a/FileSets/v2.80/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v2.80/TileText.qml b/FileSets/v2.80/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v2.80/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.80/attributes.csv b/FileSets/v2.80/attributes.csv deleted file mode 120000 index 5a253081..00000000 --- a/FileSets/v2.80/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v2.89/attributes.csv \ No newline at end of file diff --git a/FileSets/v2.80/dbus_digitalinputs.py b/FileSets/v2.80/dbus_digitalinputs.py deleted file mode 120000 index 52bec86e..00000000 --- a/FileSets/v2.80/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v2.80/dbus_generator.py b/FileSets/v2.80/dbus_generator.py deleted file mode 120000 index f8e02b46..00000000 --- a/FileSets/v2.80/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v2.80/dbus_systemcalc.py b/FileSets/v2.80/dbus_systemcalc.py deleted file mode 120000 index 90f60e6c..00000000 --- a/FileSets/v2.80/dbus_systemcalc.py +++ /dev/null @@ -1 +0,0 @@ -../v2.84/dbus_systemcalc.py \ No newline at end of file diff --git a/FileSets/v2.80/main.qml b/FileSets/v2.80/main.qml deleted file mode 120000 index 54acc57c..00000000 --- a/FileSets/v2.80/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/main.qml \ No newline at end of file diff --git a/FileSets/v2.80/startstop.py b/FileSets/v2.80/startstop.py deleted file mode 120000 index cea1575a..00000000 --- a/FileSets/v2.80/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/startstop.py \ No newline at end of file diff --git a/FileSets/v2.80/styles.css b/FileSets/v2.80/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v2.80/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v2.81/Battery.qml b/FileSets/v2.81/Battery.qml deleted file mode 120000 index ef252511..00000000 --- a/FileSets/v2.81/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/Battery.qml \ No newline at end of file diff --git a/FileSets/v2.81/COMPLETE b/FileSets/v2.81/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.81/DetailAcInput.qml b/FileSets/v2.81/DetailAcInput.qml deleted file mode 120000 index b040d3b7..00000000 --- a/FileSets/v2.81/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v2.81/DetailInverter.qml b/FileSets/v2.81/DetailInverter.qml deleted file mode 120000 index d02cb165..00000000 --- a/FileSets/v2.81/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v2.81/DetailLoadsCombined.qml b/FileSets/v2.81/DetailLoadsCombined.qml deleted file mode 120000 index 858daaea..00000000 --- a/FileSets/v2.81/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v2.81/DetailLoadsOnInput.qml b/FileSets/v2.81/DetailLoadsOnInput.qml deleted file mode 120000 index df0a1562..00000000 --- a/FileSets/v2.81/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v2.81/DetailLoadsOnOutput.qml b/FileSets/v2.81/DetailLoadsOnOutput.qml deleted file mode 120000 index 33ab936b..00000000 --- a/FileSets/v2.81/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v2.81/HubData.qml b/FileSets/v2.81/HubData.qml deleted file mode 120000 index 8e608582..00000000 --- a/FileSets/v2.81/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/HubData.qml \ No newline at end of file diff --git a/FileSets/v2.81/LINKS_ONLY b/FileSets/v2.81/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.81/MbEditBox.qml b/FileSets/v2.81/MbEditBox.qml deleted file mode 120000 index 8381b7d5..00000000 --- a/FileSets/v2.81/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v2.81/MbEditBoxDateTime.qml b/FileSets/v2.81/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v2.81/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.81/MbItem.qml b/FileSets/v2.81/MbItem.qml deleted file mode 120000 index 1280e190..00000000 --- a/FileSets/v2.81/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItem.qml \ No newline at end of file diff --git a/FileSets/v2.81/MbItemDigitalInput.qml b/FileSets/v2.81/MbItemDigitalInput.qml deleted file mode 120000 index 63943a08..00000000 --- a/FileSets/v2.81/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.81/MbSpinBox.qml b/FileSets/v2.81/MbSpinBox.qml deleted file mode 120000 index 4160ecd2..00000000 --- a/FileSets/v2.81/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v2.81/MbStyle.qml b/FileSets/v2.81/MbStyle.qml deleted file mode 120000 index db6f181f..00000000 --- a/FileSets/v2.81/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v2.81/MbSubMenu.qml b/FileSets/v2.81/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v2.81/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.81/Multi.qml b/FileSets/v2.81/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v2.81/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.81/ObjectAcConnection.qml b/FileSets/v2.81/ObjectAcConnection.qml deleted file mode 120000 index 9ca254ed..00000000 --- a/FileSets/v2.81/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v2.81/OverviewAcValuesEnhanced.qml b/FileSets/v2.81/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 4d6d5018..00000000 --- a/FileSets/v2.81/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.81/OverviewBox.qml b/FileSets/v2.81/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v2.81/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.81/OverviewConnection.qml b/FileSets/v2.81/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v2.81/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.81/OverviewConnectionEnd.qml b/FileSets/v2.81/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v2.81/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.81/OverviewFlowComplex.qml b/FileSets/v2.81/OverviewFlowComplex.qml deleted file mode 120000 index 6b747507..00000000 --- a/FileSets/v2.81/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v2.81/OverviewGeneratorEnhanced.qml b/FileSets/v2.81/OverviewGeneratorEnhanced.qml deleted file mode 120000 index b0670070..00000000 --- a/FileSets/v2.81/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.81/OverviewGeneratorRelayEnhanced.qml b/FileSets/v2.81/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index c6fa07f9..00000000 --- a/FileSets/v2.81/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.81/OverviewGridParallel.qml b/FileSets/v2.81/OverviewGridParallel.qml deleted file mode 120000 index cbf456ca..00000000 --- a/FileSets/v2.81/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v2.81/OverviewHub.qml b/FileSets/v2.81/OverviewHub.qml deleted file mode 120000 index 3f37eb0c..00000000 --- a/FileSets/v2.81/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v2.81/OverviewHubEnhanced.qml b/FileSets/v2.81/OverviewHubEnhanced.qml deleted file mode 120000 index 6dc4f1d8..00000000 --- a/FileSets/v2.81/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.81/OverviewMobileEnhanced.qml b/FileSets/v2.81/OverviewMobileEnhanced.qml deleted file mode 120000 index a70d4024..00000000 --- a/FileSets/v2.81/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.81/OverviewSolarCharger.qml b/FileSets/v2.81/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v2.81/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.81/OverviewSolarInverter.qml b/FileSets/v2.81/OverviewSolarInverter.qml deleted file mode 120000 index 7cea58a2..00000000 --- a/FileSets/v2.81/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v2.81/OverviewTankDelegate.qml b/FileSets/v2.81/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v2.81/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.81/OverviewTanks.qml b/FileSets/v2.81/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v2.81/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.81/OverviewTanksTempsDigInputs.qml b/FileSets/v2.81/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index d080b0f4..00000000 --- a/FileSets/v2.81/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v2.81/PageDigitalInput.qml b/FileSets/v2.81/PageDigitalInput.qml deleted file mode 120000 index 839f7874..00000000 --- a/FileSets/v2.81/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.81/PageGenerator.qml b/FileSets/v2.81/PageGenerator.qml deleted file mode 120000 index cae51ecb..00000000 --- a/FileSets/v2.81/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.81/PageMain.qml b/FileSets/v2.81/PageMain.qml deleted file mode 120000 index 9f74fa85..00000000 --- a/FileSets/v2.81/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageMain.qml \ No newline at end of file diff --git a/FileSets/v2.81/PageSettingsDisplay.qml b/FileSets/v2.81/PageSettingsDisplay.qml deleted file mode 120000 index b3885a68..00000000 --- a/FileSets/v2.81/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v2.81/PageSettingsGenerator.qml b/FileSets/v2.81/PageSettingsGenerator.qml deleted file mode 120000 index 861e41bb..00000000 --- a/FileSets/v2.81/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.81/PageSettingsGuiMods.qml b/FileSets/v2.81/PageSettingsGuiMods.qml deleted file mode 120000 index d3534bd3..00000000 --- a/FileSets/v2.81/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v2.81/PageSettingsRelay.qml b/FileSets/v2.81/PageSettingsRelay.qml deleted file mode 120000 index 6861254c..00000000 --- a/FileSets/v2.81/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v2.81/PowerGauge.qml b/FileSets/v2.81/PowerGauge.qml deleted file mode 120000 index d82ac28a..00000000 --- a/FileSets/v2.81/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v2.81/Tile.qml b/FileSets/v2.81/Tile.qml deleted file mode 120000 index aa80e332..00000000 --- a/FileSets/v2.81/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/Tile.qml \ No newline at end of file diff --git a/FileSets/v2.81/TileDigIn.qml b/FileSets/v2.81/TileDigIn.qml deleted file mode 120000 index 2f8c7989..00000000 --- a/FileSets/v2.81/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v2.81/TileRelay.qml b/FileSets/v2.81/TileRelay.qml deleted file mode 120000 index 4313882d..00000000 --- a/FileSets/v2.81/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v2.81/TileText.qml b/FileSets/v2.81/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v2.81/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.81/attributes.csv b/FileSets/v2.81/attributes.csv deleted file mode 120000 index 5a253081..00000000 --- a/FileSets/v2.81/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v2.89/attributes.csv \ No newline at end of file diff --git a/FileSets/v2.81/dbus_digitalinputs.py b/FileSets/v2.81/dbus_digitalinputs.py deleted file mode 120000 index 52bec86e..00000000 --- a/FileSets/v2.81/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v2.81/dbus_generator.py b/FileSets/v2.81/dbus_generator.py deleted file mode 120000 index f8e02b46..00000000 --- a/FileSets/v2.81/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v2.81/dbus_systemcalc.py b/FileSets/v2.81/dbus_systemcalc.py deleted file mode 120000 index 90f60e6c..00000000 --- a/FileSets/v2.81/dbus_systemcalc.py +++ /dev/null @@ -1 +0,0 @@ -../v2.84/dbus_systemcalc.py \ No newline at end of file diff --git a/FileSets/v2.81/main.qml b/FileSets/v2.81/main.qml deleted file mode 120000 index 54acc57c..00000000 --- a/FileSets/v2.81/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/main.qml \ No newline at end of file diff --git a/FileSets/v2.81/startstop.py b/FileSets/v2.81/startstop.py deleted file mode 120000 index cea1575a..00000000 --- a/FileSets/v2.81/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/startstop.py \ No newline at end of file diff --git a/FileSets/v2.81/styles.css b/FileSets/v2.81/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v2.81/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v2.82/Battery.qml b/FileSets/v2.82/Battery.qml deleted file mode 120000 index ef252511..00000000 --- a/FileSets/v2.82/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/Battery.qml \ No newline at end of file diff --git a/FileSets/v2.82/COMPLETE b/FileSets/v2.82/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.82/DetailAcInput.qml b/FileSets/v2.82/DetailAcInput.qml deleted file mode 120000 index b040d3b7..00000000 --- a/FileSets/v2.82/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v2.82/DetailInverter.qml b/FileSets/v2.82/DetailInverter.qml deleted file mode 120000 index d02cb165..00000000 --- a/FileSets/v2.82/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v2.82/DetailLoadsCombined.qml b/FileSets/v2.82/DetailLoadsCombined.qml deleted file mode 120000 index 858daaea..00000000 --- a/FileSets/v2.82/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v2.82/DetailLoadsOnInput.qml b/FileSets/v2.82/DetailLoadsOnInput.qml deleted file mode 120000 index df0a1562..00000000 --- a/FileSets/v2.82/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v2.82/DetailLoadsOnOutput.qml b/FileSets/v2.82/DetailLoadsOnOutput.qml deleted file mode 120000 index 33ab936b..00000000 --- a/FileSets/v2.82/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v2.82/HubData.qml b/FileSets/v2.82/HubData.qml deleted file mode 120000 index 8e608582..00000000 --- a/FileSets/v2.82/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/HubData.qml \ No newline at end of file diff --git a/FileSets/v2.82/LINKS_ONLY b/FileSets/v2.82/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.82/MbEditBox.qml b/FileSets/v2.82/MbEditBox.qml deleted file mode 120000 index 8381b7d5..00000000 --- a/FileSets/v2.82/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v2.82/MbEditBoxDateTime.qml b/FileSets/v2.82/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v2.82/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.82/MbItem.qml b/FileSets/v2.82/MbItem.qml deleted file mode 120000 index 1280e190..00000000 --- a/FileSets/v2.82/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItem.qml \ No newline at end of file diff --git a/FileSets/v2.82/MbItemDigitalInput.qml b/FileSets/v2.82/MbItemDigitalInput.qml deleted file mode 120000 index 63943a08..00000000 --- a/FileSets/v2.82/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.82/MbSpinBox.qml b/FileSets/v2.82/MbSpinBox.qml deleted file mode 120000 index 4160ecd2..00000000 --- a/FileSets/v2.82/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v2.82/MbStyle.qml b/FileSets/v2.82/MbStyle.qml deleted file mode 120000 index db6f181f..00000000 --- a/FileSets/v2.82/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v2.82/MbSubMenu.qml b/FileSets/v2.82/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v2.82/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.82/Multi.qml b/FileSets/v2.82/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v2.82/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.82/ObjectAcConnection.qml b/FileSets/v2.82/ObjectAcConnection.qml deleted file mode 120000 index 9ca254ed..00000000 --- a/FileSets/v2.82/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v2.82/OverviewAcValuesEnhanced.qml b/FileSets/v2.82/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 4d6d5018..00000000 --- a/FileSets/v2.82/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.82/OverviewBox.qml b/FileSets/v2.82/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v2.82/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.82/OverviewConnection.qml b/FileSets/v2.82/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v2.82/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.82/OverviewConnectionEnd.qml b/FileSets/v2.82/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v2.82/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.82/OverviewFlowComplex.qml b/FileSets/v2.82/OverviewFlowComplex.qml deleted file mode 120000 index 6b747507..00000000 --- a/FileSets/v2.82/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v2.82/OverviewGeneratorEnhanced.qml b/FileSets/v2.82/OverviewGeneratorEnhanced.qml deleted file mode 120000 index b0670070..00000000 --- a/FileSets/v2.82/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.82/OverviewGeneratorRelayEnhanced.qml b/FileSets/v2.82/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index c6fa07f9..00000000 --- a/FileSets/v2.82/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.82/OverviewGridParallel.qml b/FileSets/v2.82/OverviewGridParallel.qml deleted file mode 120000 index cbf456ca..00000000 --- a/FileSets/v2.82/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v2.82/OverviewHub.qml b/FileSets/v2.82/OverviewHub.qml deleted file mode 120000 index 3f37eb0c..00000000 --- a/FileSets/v2.82/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v2.82/OverviewHubEnhanced.qml b/FileSets/v2.82/OverviewHubEnhanced.qml deleted file mode 120000 index 6dc4f1d8..00000000 --- a/FileSets/v2.82/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.82/OverviewMobileEnhanced.qml b/FileSets/v2.82/OverviewMobileEnhanced.qml deleted file mode 120000 index a70d4024..00000000 --- a/FileSets/v2.82/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.82/OverviewSolarCharger.qml b/FileSets/v2.82/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v2.82/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.82/OverviewSolarInverter.qml b/FileSets/v2.82/OverviewSolarInverter.qml deleted file mode 120000 index 7cea58a2..00000000 --- a/FileSets/v2.82/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v2.82/OverviewTankDelegate.qml b/FileSets/v2.82/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v2.82/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.82/OverviewTanks.qml b/FileSets/v2.82/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v2.82/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.82/OverviewTanksTempsDigInputs.qml b/FileSets/v2.82/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index d080b0f4..00000000 --- a/FileSets/v2.82/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v2.82/PageDigitalInput.qml b/FileSets/v2.82/PageDigitalInput.qml deleted file mode 120000 index 839f7874..00000000 --- a/FileSets/v2.82/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.82/PageGenerator.qml b/FileSets/v2.82/PageGenerator.qml deleted file mode 120000 index cae51ecb..00000000 --- a/FileSets/v2.82/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.82/PageMain.qml b/FileSets/v2.82/PageMain.qml deleted file mode 120000 index 9f74fa85..00000000 --- a/FileSets/v2.82/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageMain.qml \ No newline at end of file diff --git a/FileSets/v2.82/PageSettingsDisplay.qml b/FileSets/v2.82/PageSettingsDisplay.qml deleted file mode 120000 index b3885a68..00000000 --- a/FileSets/v2.82/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v2.82/PageSettingsGenerator.qml b/FileSets/v2.82/PageSettingsGenerator.qml deleted file mode 120000 index 861e41bb..00000000 --- a/FileSets/v2.82/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.82/PageSettingsGuiMods.qml b/FileSets/v2.82/PageSettingsGuiMods.qml deleted file mode 120000 index d3534bd3..00000000 --- a/FileSets/v2.82/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v2.82/PageSettingsRelay.qml b/FileSets/v2.82/PageSettingsRelay.qml deleted file mode 120000 index 6861254c..00000000 --- a/FileSets/v2.82/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v2.82/PowerGauge.qml b/FileSets/v2.82/PowerGauge.qml deleted file mode 120000 index d82ac28a..00000000 --- a/FileSets/v2.82/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v2.82/Tile.qml b/FileSets/v2.82/Tile.qml deleted file mode 120000 index aa80e332..00000000 --- a/FileSets/v2.82/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/Tile.qml \ No newline at end of file diff --git a/FileSets/v2.82/TileDigIn.qml b/FileSets/v2.82/TileDigIn.qml deleted file mode 120000 index 2f8c7989..00000000 --- a/FileSets/v2.82/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v2.82/TileRelay.qml b/FileSets/v2.82/TileRelay.qml deleted file mode 120000 index 4313882d..00000000 --- a/FileSets/v2.82/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v2.82/TileText.qml b/FileSets/v2.82/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v2.82/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.82/attributes.csv b/FileSets/v2.82/attributes.csv deleted file mode 120000 index 5a253081..00000000 --- a/FileSets/v2.82/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v2.89/attributes.csv \ No newline at end of file diff --git a/FileSets/v2.82/dbus_digitalinputs.py b/FileSets/v2.82/dbus_digitalinputs.py deleted file mode 120000 index 52bec86e..00000000 --- a/FileSets/v2.82/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v2.82/dbus_generator.py b/FileSets/v2.82/dbus_generator.py deleted file mode 120000 index f8e02b46..00000000 --- a/FileSets/v2.82/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v2.82/dbus_systemcalc.py b/FileSets/v2.82/dbus_systemcalc.py deleted file mode 120000 index 90f60e6c..00000000 --- a/FileSets/v2.82/dbus_systemcalc.py +++ /dev/null @@ -1 +0,0 @@ -../v2.84/dbus_systemcalc.py \ No newline at end of file diff --git a/FileSets/v2.82/main.qml b/FileSets/v2.82/main.qml deleted file mode 120000 index 54acc57c..00000000 --- a/FileSets/v2.82/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/main.qml \ No newline at end of file diff --git a/FileSets/v2.82/startstop.py b/FileSets/v2.82/startstop.py deleted file mode 120000 index cea1575a..00000000 --- a/FileSets/v2.82/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/startstop.py \ No newline at end of file diff --git a/FileSets/v2.82/styles.css b/FileSets/v2.82/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v2.82/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v2.83/Battery.qml b/FileSets/v2.83/Battery.qml deleted file mode 120000 index ef252511..00000000 --- a/FileSets/v2.83/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/Battery.qml \ No newline at end of file diff --git a/FileSets/v2.83/COMPLETE b/FileSets/v2.83/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.83/DetailAcInput.qml b/FileSets/v2.83/DetailAcInput.qml deleted file mode 120000 index b040d3b7..00000000 --- a/FileSets/v2.83/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v2.83/DetailInverter.qml b/FileSets/v2.83/DetailInverter.qml deleted file mode 120000 index d02cb165..00000000 --- a/FileSets/v2.83/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v2.83/DetailLoadsCombined.qml b/FileSets/v2.83/DetailLoadsCombined.qml deleted file mode 120000 index 858daaea..00000000 --- a/FileSets/v2.83/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v2.83/DetailLoadsOnInput.qml b/FileSets/v2.83/DetailLoadsOnInput.qml deleted file mode 120000 index df0a1562..00000000 --- a/FileSets/v2.83/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v2.83/DetailLoadsOnOutput.qml b/FileSets/v2.83/DetailLoadsOnOutput.qml deleted file mode 120000 index 33ab936b..00000000 --- a/FileSets/v2.83/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v2.83/HubData.qml b/FileSets/v2.83/HubData.qml deleted file mode 120000 index 8e608582..00000000 --- a/FileSets/v2.83/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/HubData.qml \ No newline at end of file diff --git a/FileSets/v2.83/LINKS_ONLY b/FileSets/v2.83/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.83/MbEditBox.qml b/FileSets/v2.83/MbEditBox.qml deleted file mode 120000 index 8381b7d5..00000000 --- a/FileSets/v2.83/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v2.83/MbEditBoxDateTime.qml b/FileSets/v2.83/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v2.83/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.83/MbItem.qml b/FileSets/v2.83/MbItem.qml deleted file mode 120000 index 1280e190..00000000 --- a/FileSets/v2.83/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItem.qml \ No newline at end of file diff --git a/FileSets/v2.83/MbItemDigitalInput.qml b/FileSets/v2.83/MbItemDigitalInput.qml deleted file mode 120000 index 63943a08..00000000 --- a/FileSets/v2.83/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.83/MbSpinBox.qml b/FileSets/v2.83/MbSpinBox.qml deleted file mode 120000 index 4160ecd2..00000000 --- a/FileSets/v2.83/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v2.83/MbStyle.qml b/FileSets/v2.83/MbStyle.qml deleted file mode 120000 index db6f181f..00000000 --- a/FileSets/v2.83/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v2.83/MbSubMenu.qml b/FileSets/v2.83/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v2.83/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.83/Multi.qml b/FileSets/v2.83/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v2.83/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.83/ObjectAcConnection.qml b/FileSets/v2.83/ObjectAcConnection.qml deleted file mode 120000 index 9ca254ed..00000000 --- a/FileSets/v2.83/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v2.83/OverviewAcValuesEnhanced.qml b/FileSets/v2.83/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 4d6d5018..00000000 --- a/FileSets/v2.83/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.83/OverviewBox.qml b/FileSets/v2.83/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v2.83/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.83/OverviewConnection.qml b/FileSets/v2.83/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v2.83/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.83/OverviewConnectionEnd.qml b/FileSets/v2.83/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v2.83/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.83/OverviewFlowComplex.qml b/FileSets/v2.83/OverviewFlowComplex.qml deleted file mode 120000 index 6b747507..00000000 --- a/FileSets/v2.83/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v2.83/OverviewGeneratorEnhanced.qml b/FileSets/v2.83/OverviewGeneratorEnhanced.qml deleted file mode 120000 index b0670070..00000000 --- a/FileSets/v2.83/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.83/OverviewGeneratorRelayEnhanced.qml b/FileSets/v2.83/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index c6fa07f9..00000000 --- a/FileSets/v2.83/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.83/OverviewGridParallel.qml b/FileSets/v2.83/OverviewGridParallel.qml deleted file mode 120000 index cbf456ca..00000000 --- a/FileSets/v2.83/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v2.83/OverviewHub.qml b/FileSets/v2.83/OverviewHub.qml deleted file mode 120000 index 3f37eb0c..00000000 --- a/FileSets/v2.83/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v2.83/OverviewHubEnhanced.qml b/FileSets/v2.83/OverviewHubEnhanced.qml deleted file mode 120000 index 6dc4f1d8..00000000 --- a/FileSets/v2.83/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.83/OverviewMobileEnhanced.qml b/FileSets/v2.83/OverviewMobileEnhanced.qml deleted file mode 120000 index a70d4024..00000000 --- a/FileSets/v2.83/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.83/OverviewSolarCharger.qml b/FileSets/v2.83/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v2.83/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.83/OverviewSolarInverter.qml b/FileSets/v2.83/OverviewSolarInverter.qml deleted file mode 120000 index 7cea58a2..00000000 --- a/FileSets/v2.83/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v2.83/OverviewTankDelegate.qml b/FileSets/v2.83/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v2.83/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.83/OverviewTanks.qml b/FileSets/v2.83/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v2.83/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.83/OverviewTanksTempsDigInputs.qml b/FileSets/v2.83/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index d080b0f4..00000000 --- a/FileSets/v2.83/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v2.83/PageDigitalInput.qml b/FileSets/v2.83/PageDigitalInput.qml deleted file mode 120000 index 839f7874..00000000 --- a/FileSets/v2.83/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.83/PageGenerator.qml b/FileSets/v2.83/PageGenerator.qml deleted file mode 120000 index cae51ecb..00000000 --- a/FileSets/v2.83/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.83/PageMain.qml b/FileSets/v2.83/PageMain.qml deleted file mode 120000 index 9f74fa85..00000000 --- a/FileSets/v2.83/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageMain.qml \ No newline at end of file diff --git a/FileSets/v2.83/PageSettingsDisplay.qml b/FileSets/v2.83/PageSettingsDisplay.qml deleted file mode 120000 index b3885a68..00000000 --- a/FileSets/v2.83/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v2.83/PageSettingsGenerator.qml b/FileSets/v2.83/PageSettingsGenerator.qml deleted file mode 120000 index 861e41bb..00000000 --- a/FileSets/v2.83/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.83/PageSettingsGuiMods.qml b/FileSets/v2.83/PageSettingsGuiMods.qml deleted file mode 120000 index d3534bd3..00000000 --- a/FileSets/v2.83/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v2.83/PageSettingsRelay.qml b/FileSets/v2.83/PageSettingsRelay.qml deleted file mode 120000 index 6861254c..00000000 --- a/FileSets/v2.83/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v2.83/PowerGauge.qml b/FileSets/v2.83/PowerGauge.qml deleted file mode 120000 index d82ac28a..00000000 --- a/FileSets/v2.83/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v2.83/Tile.qml b/FileSets/v2.83/Tile.qml deleted file mode 120000 index aa80e332..00000000 --- a/FileSets/v2.83/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/Tile.qml \ No newline at end of file diff --git a/FileSets/v2.83/TileDigIn.qml b/FileSets/v2.83/TileDigIn.qml deleted file mode 120000 index 2f8c7989..00000000 --- a/FileSets/v2.83/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v2.83/TileRelay.qml b/FileSets/v2.83/TileRelay.qml deleted file mode 120000 index 4313882d..00000000 --- a/FileSets/v2.83/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v2.83/TileText.qml b/FileSets/v2.83/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v2.83/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.83/attributes.csv b/FileSets/v2.83/attributes.csv deleted file mode 120000 index 5a253081..00000000 --- a/FileSets/v2.83/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v2.89/attributes.csv \ No newline at end of file diff --git a/FileSets/v2.83/dbus_digitalinputs.py b/FileSets/v2.83/dbus_digitalinputs.py deleted file mode 120000 index 52bec86e..00000000 --- a/FileSets/v2.83/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v2.83/dbus_generator.py b/FileSets/v2.83/dbus_generator.py deleted file mode 120000 index f8e02b46..00000000 --- a/FileSets/v2.83/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v2.83/dbus_systemcalc.py b/FileSets/v2.83/dbus_systemcalc.py deleted file mode 120000 index 90f60e6c..00000000 --- a/FileSets/v2.83/dbus_systemcalc.py +++ /dev/null @@ -1 +0,0 @@ -../v2.84/dbus_systemcalc.py \ No newline at end of file diff --git a/FileSets/v2.83/main.qml b/FileSets/v2.83/main.qml deleted file mode 120000 index 54acc57c..00000000 --- a/FileSets/v2.83/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/main.qml \ No newline at end of file diff --git a/FileSets/v2.83/startstop.py b/FileSets/v2.83/startstop.py deleted file mode 120000 index cea1575a..00000000 --- a/FileSets/v2.83/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/startstop.py \ No newline at end of file diff --git a/FileSets/v2.83/styles.css b/FileSets/v2.83/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v2.83/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v2.84/Battery.qml b/FileSets/v2.84/Battery.qml deleted file mode 120000 index ef252511..00000000 --- a/FileSets/v2.84/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/Battery.qml \ No newline at end of file diff --git a/FileSets/v2.84/COMPLETE b/FileSets/v2.84/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.84/DetailAcInput.qml b/FileSets/v2.84/DetailAcInput.qml deleted file mode 120000 index b040d3b7..00000000 --- a/FileSets/v2.84/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v2.84/DetailInverter.qml b/FileSets/v2.84/DetailInverter.qml deleted file mode 120000 index d02cb165..00000000 --- a/FileSets/v2.84/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v2.84/DetailLoadsCombined.qml b/FileSets/v2.84/DetailLoadsCombined.qml deleted file mode 120000 index 858daaea..00000000 --- a/FileSets/v2.84/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v2.84/DetailLoadsOnInput.qml b/FileSets/v2.84/DetailLoadsOnInput.qml deleted file mode 120000 index df0a1562..00000000 --- a/FileSets/v2.84/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v2.84/DetailLoadsOnOutput.qml b/FileSets/v2.84/DetailLoadsOnOutput.qml deleted file mode 120000 index 33ab936b..00000000 --- a/FileSets/v2.84/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v2.84/HubData.qml b/FileSets/v2.84/HubData.qml deleted file mode 120000 index 8e608582..00000000 --- a/FileSets/v2.84/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/HubData.qml \ No newline at end of file diff --git a/FileSets/v2.84/LINKS_ONLY b/FileSets/v2.84/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.84/MbEditBox.qml b/FileSets/v2.84/MbEditBox.qml deleted file mode 120000 index 8381b7d5..00000000 --- a/FileSets/v2.84/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v2.84/MbEditBoxDateTime.qml b/FileSets/v2.84/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v2.84/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.84/MbItem.qml b/FileSets/v2.84/MbItem.qml deleted file mode 120000 index 1280e190..00000000 --- a/FileSets/v2.84/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItem.qml \ No newline at end of file diff --git a/FileSets/v2.84/MbItemDigitalInput.qml b/FileSets/v2.84/MbItemDigitalInput.qml deleted file mode 120000 index 63943a08..00000000 --- a/FileSets/v2.84/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.84/MbSpinBox.qml b/FileSets/v2.84/MbSpinBox.qml deleted file mode 120000 index 4160ecd2..00000000 --- a/FileSets/v2.84/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v2.84/MbStyle.qml b/FileSets/v2.84/MbStyle.qml deleted file mode 120000 index db6f181f..00000000 --- a/FileSets/v2.84/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v2.84/MbSubMenu.qml b/FileSets/v2.84/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v2.84/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.84/Multi.qml b/FileSets/v2.84/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v2.84/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.84/ObjectAcConnection.qml b/FileSets/v2.84/ObjectAcConnection.qml deleted file mode 120000 index 9ca254ed..00000000 --- a/FileSets/v2.84/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v2.84/OverviewAcValuesEnhanced.qml b/FileSets/v2.84/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 4d6d5018..00000000 --- a/FileSets/v2.84/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.84/OverviewBox.qml b/FileSets/v2.84/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v2.84/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.84/OverviewConnection.qml b/FileSets/v2.84/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v2.84/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.84/OverviewConnectionEnd.qml b/FileSets/v2.84/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v2.84/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.84/OverviewFlowComplex.qml b/FileSets/v2.84/OverviewFlowComplex.qml deleted file mode 120000 index 6b747507..00000000 --- a/FileSets/v2.84/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v2.84/OverviewGeneratorEnhanced.qml b/FileSets/v2.84/OverviewGeneratorEnhanced.qml deleted file mode 120000 index b0670070..00000000 --- a/FileSets/v2.84/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.84/OverviewGeneratorRelayEnhanced.qml b/FileSets/v2.84/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index c6fa07f9..00000000 --- a/FileSets/v2.84/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.84/OverviewGridParallel.qml b/FileSets/v2.84/OverviewGridParallel.qml deleted file mode 120000 index cbf456ca..00000000 --- a/FileSets/v2.84/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v2.84/OverviewHub.qml b/FileSets/v2.84/OverviewHub.qml deleted file mode 120000 index 3f37eb0c..00000000 --- a/FileSets/v2.84/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v2.84/OverviewHubEnhanced.qml b/FileSets/v2.84/OverviewHubEnhanced.qml deleted file mode 120000 index 6dc4f1d8..00000000 --- a/FileSets/v2.84/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.84/OverviewMobileEnhanced.qml b/FileSets/v2.84/OverviewMobileEnhanced.qml deleted file mode 120000 index a70d4024..00000000 --- a/FileSets/v2.84/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.84/OverviewSolarCharger.qml b/FileSets/v2.84/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v2.84/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.84/OverviewSolarInverter.qml b/FileSets/v2.84/OverviewSolarInverter.qml deleted file mode 120000 index 7cea58a2..00000000 --- a/FileSets/v2.84/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v2.84/OverviewTankDelegate.qml b/FileSets/v2.84/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v2.84/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.84/OverviewTanks.qml b/FileSets/v2.84/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v2.84/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.84/OverviewTanksTempsDigInputs.qml b/FileSets/v2.84/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index d080b0f4..00000000 --- a/FileSets/v2.84/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v2.84/PageDigitalInput.qml b/FileSets/v2.84/PageDigitalInput.qml deleted file mode 120000 index 839f7874..00000000 --- a/FileSets/v2.84/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.84/PageGenerator.qml b/FileSets/v2.84/PageGenerator.qml deleted file mode 120000 index cae51ecb..00000000 --- a/FileSets/v2.84/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.84/PageMain.qml b/FileSets/v2.84/PageMain.qml deleted file mode 120000 index 9f74fa85..00000000 --- a/FileSets/v2.84/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageMain.qml \ No newline at end of file diff --git a/FileSets/v2.84/PageSettingsDisplay.qml b/FileSets/v2.84/PageSettingsDisplay.qml deleted file mode 120000 index b3885a68..00000000 --- a/FileSets/v2.84/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v2.84/PageSettingsGenerator.qml b/FileSets/v2.84/PageSettingsGenerator.qml deleted file mode 120000 index 861e41bb..00000000 --- a/FileSets/v2.84/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.84/PageSettingsGuiMods.qml b/FileSets/v2.84/PageSettingsGuiMods.qml deleted file mode 120000 index d3534bd3..00000000 --- a/FileSets/v2.84/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v2.84/PageSettingsRelay.qml b/FileSets/v2.84/PageSettingsRelay.qml deleted file mode 120000 index 6861254c..00000000 --- a/FileSets/v2.84/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v2.84/PowerGauge.qml b/FileSets/v2.84/PowerGauge.qml deleted file mode 120000 index d82ac28a..00000000 --- a/FileSets/v2.84/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v2.84/Tile.qml b/FileSets/v2.84/Tile.qml deleted file mode 120000 index aa80e332..00000000 --- a/FileSets/v2.84/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/Tile.qml \ No newline at end of file diff --git a/FileSets/v2.84/TileDigIn.qml b/FileSets/v2.84/TileDigIn.qml deleted file mode 120000 index 2f8c7989..00000000 --- a/FileSets/v2.84/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v2.84/TileRelay.qml b/FileSets/v2.84/TileRelay.qml deleted file mode 120000 index 4313882d..00000000 --- a/FileSets/v2.84/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v2.84/TileText.qml b/FileSets/v2.84/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v2.84/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.84/attributes.csv b/FileSets/v2.84/attributes.csv deleted file mode 120000 index 5a253081..00000000 --- a/FileSets/v2.84/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v2.89/attributes.csv \ No newline at end of file diff --git a/FileSets/v2.84/dbus_digitalinputs.py b/FileSets/v2.84/dbus_digitalinputs.py deleted file mode 120000 index 52bec86e..00000000 --- a/FileSets/v2.84/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v2.84/dbus_generator.py b/FileSets/v2.84/dbus_generator.py deleted file mode 120000 index f8e02b46..00000000 --- a/FileSets/v2.84/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v2.84/main.qml b/FileSets/v2.84/main.qml deleted file mode 120000 index 54acc57c..00000000 --- a/FileSets/v2.84/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/main.qml \ No newline at end of file diff --git a/FileSets/v2.84/startstop.py b/FileSets/v2.84/startstop.py deleted file mode 120000 index cea1575a..00000000 --- a/FileSets/v2.84/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/startstop.py \ No newline at end of file diff --git a/FileSets/v2.84/styles.css b/FileSets/v2.84/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v2.84/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v2.85/Battery.qml b/FileSets/v2.85/Battery.qml deleted file mode 120000 index ef252511..00000000 --- a/FileSets/v2.85/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/Battery.qml \ No newline at end of file diff --git a/FileSets/v2.85/COMPLETE b/FileSets/v2.85/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.85/DetailAcInput.qml b/FileSets/v2.85/DetailAcInput.qml deleted file mode 120000 index b040d3b7..00000000 --- a/FileSets/v2.85/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v2.85/DetailInverter.qml b/FileSets/v2.85/DetailInverter.qml deleted file mode 120000 index d02cb165..00000000 --- a/FileSets/v2.85/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v2.85/DetailLoadsCombined.qml b/FileSets/v2.85/DetailLoadsCombined.qml deleted file mode 120000 index 858daaea..00000000 --- a/FileSets/v2.85/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v2.85/DetailLoadsOnInput.qml b/FileSets/v2.85/DetailLoadsOnInput.qml deleted file mode 120000 index df0a1562..00000000 --- a/FileSets/v2.85/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v2.85/DetailLoadsOnOutput.qml b/FileSets/v2.85/DetailLoadsOnOutput.qml deleted file mode 120000 index 33ab936b..00000000 --- a/FileSets/v2.85/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v2.85/HubData.qml b/FileSets/v2.85/HubData.qml deleted file mode 120000 index 8e608582..00000000 --- a/FileSets/v2.85/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/HubData.qml \ No newline at end of file diff --git a/FileSets/v2.85/LINKS_ONLY b/FileSets/v2.85/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.85/MbEditBox.qml b/FileSets/v2.85/MbEditBox.qml deleted file mode 120000 index 8381b7d5..00000000 --- a/FileSets/v2.85/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v2.85/MbEditBoxDateTime.qml b/FileSets/v2.85/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v2.85/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.85/MbItem.qml b/FileSets/v2.85/MbItem.qml deleted file mode 120000 index 1280e190..00000000 --- a/FileSets/v2.85/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItem.qml \ No newline at end of file diff --git a/FileSets/v2.85/MbItemDigitalInput.qml b/FileSets/v2.85/MbItemDigitalInput.qml deleted file mode 120000 index 63943a08..00000000 --- a/FileSets/v2.85/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.85/MbSpinBox.qml b/FileSets/v2.85/MbSpinBox.qml deleted file mode 120000 index 4160ecd2..00000000 --- a/FileSets/v2.85/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v2.85/MbStyle.qml b/FileSets/v2.85/MbStyle.qml deleted file mode 120000 index db6f181f..00000000 --- a/FileSets/v2.85/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v2.85/MbSubMenu.qml b/FileSets/v2.85/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v2.85/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.85/Multi.qml b/FileSets/v2.85/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v2.85/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.85/ObjectAcConnection.qml b/FileSets/v2.85/ObjectAcConnection.qml deleted file mode 120000 index 9ca254ed..00000000 --- a/FileSets/v2.85/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v2.85/OverviewAcValuesEnhanced.qml b/FileSets/v2.85/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 4d6d5018..00000000 --- a/FileSets/v2.85/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.85/OverviewBox.qml b/FileSets/v2.85/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v2.85/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.85/OverviewConnection.qml b/FileSets/v2.85/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v2.85/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.85/OverviewConnectionEnd.qml b/FileSets/v2.85/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v2.85/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.85/OverviewFlowComplex.qml b/FileSets/v2.85/OverviewFlowComplex.qml deleted file mode 120000 index 6b747507..00000000 --- a/FileSets/v2.85/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v2.85/OverviewGeneratorEnhanced.qml b/FileSets/v2.85/OverviewGeneratorEnhanced.qml deleted file mode 120000 index b0670070..00000000 --- a/FileSets/v2.85/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.85/OverviewGeneratorRelayEnhanced.qml b/FileSets/v2.85/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index c6fa07f9..00000000 --- a/FileSets/v2.85/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.85/OverviewGridParallel.qml b/FileSets/v2.85/OverviewGridParallel.qml deleted file mode 120000 index cbf456ca..00000000 --- a/FileSets/v2.85/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v2.85/OverviewHub.qml b/FileSets/v2.85/OverviewHub.qml deleted file mode 120000 index 3f37eb0c..00000000 --- a/FileSets/v2.85/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v2.85/OverviewHubEnhanced.qml b/FileSets/v2.85/OverviewHubEnhanced.qml deleted file mode 120000 index 6dc4f1d8..00000000 --- a/FileSets/v2.85/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.85/OverviewMobileEnhanced.qml b/FileSets/v2.85/OverviewMobileEnhanced.qml deleted file mode 120000 index a70d4024..00000000 --- a/FileSets/v2.85/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.85/OverviewSolarCharger.qml b/FileSets/v2.85/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v2.85/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.85/OverviewSolarInverter.qml b/FileSets/v2.85/OverviewSolarInverter.qml deleted file mode 120000 index 7cea58a2..00000000 --- a/FileSets/v2.85/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v2.85/OverviewTankDelegate.qml b/FileSets/v2.85/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v2.85/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.85/OverviewTanks.qml b/FileSets/v2.85/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v2.85/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.85/OverviewTanksTempsDigInputs.qml b/FileSets/v2.85/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index d080b0f4..00000000 --- a/FileSets/v2.85/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v2.85/PageDigitalInput.qml b/FileSets/v2.85/PageDigitalInput.qml deleted file mode 120000 index 839f7874..00000000 --- a/FileSets/v2.85/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.85/PageGenerator.qml b/FileSets/v2.85/PageGenerator.qml deleted file mode 120000 index cae51ecb..00000000 --- a/FileSets/v2.85/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.85/PageMain.qml b/FileSets/v2.85/PageMain.qml deleted file mode 120000 index 9f74fa85..00000000 --- a/FileSets/v2.85/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageMain.qml \ No newline at end of file diff --git a/FileSets/v2.85/PageSettingsDisplay.qml b/FileSets/v2.85/PageSettingsDisplay.qml deleted file mode 120000 index b3885a68..00000000 --- a/FileSets/v2.85/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v2.85/PageSettingsGenerator.qml b/FileSets/v2.85/PageSettingsGenerator.qml deleted file mode 120000 index 861e41bb..00000000 --- a/FileSets/v2.85/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.85/PageSettingsGuiMods.qml b/FileSets/v2.85/PageSettingsGuiMods.qml deleted file mode 120000 index d3534bd3..00000000 --- a/FileSets/v2.85/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v2.85/PageSettingsRelay.qml b/FileSets/v2.85/PageSettingsRelay.qml deleted file mode 120000 index 6861254c..00000000 --- a/FileSets/v2.85/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v2.85/PowerGauge.qml b/FileSets/v2.85/PowerGauge.qml deleted file mode 120000 index d82ac28a..00000000 --- a/FileSets/v2.85/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v2.85/Tile.qml b/FileSets/v2.85/Tile.qml deleted file mode 120000 index aa80e332..00000000 --- a/FileSets/v2.85/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/Tile.qml \ No newline at end of file diff --git a/FileSets/v2.85/TileDigIn.qml b/FileSets/v2.85/TileDigIn.qml deleted file mode 120000 index 2f8c7989..00000000 --- a/FileSets/v2.85/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v2.85/TileRelay.qml b/FileSets/v2.85/TileRelay.qml deleted file mode 120000 index 4313882d..00000000 --- a/FileSets/v2.85/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v2.85/TileText.qml b/FileSets/v2.85/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v2.85/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.85/attributes.csv b/FileSets/v2.85/attributes.csv deleted file mode 120000 index 5a253081..00000000 --- a/FileSets/v2.85/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v2.89/attributes.csv \ No newline at end of file diff --git a/FileSets/v2.85/dbus_digitalinputs.py b/FileSets/v2.85/dbus_digitalinputs.py deleted file mode 120000 index 52bec86e..00000000 --- a/FileSets/v2.85/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v2.85/dbus_generator.py b/FileSets/v2.85/dbus_generator.py deleted file mode 120000 index f8e02b46..00000000 --- a/FileSets/v2.85/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v2.85/dbus_systemcalc.py b/FileSets/v2.85/dbus_systemcalc.py deleted file mode 120000 index 0548b1ea..00000000 --- a/FileSets/v2.85/dbus_systemcalc.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/dbus_systemcalc.py \ No newline at end of file diff --git a/FileSets/v2.85/main.qml b/FileSets/v2.85/main.qml deleted file mode 120000 index 54acc57c..00000000 --- a/FileSets/v2.85/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/main.qml \ No newline at end of file diff --git a/FileSets/v2.85/startstop.py b/FileSets/v2.85/startstop.py deleted file mode 120000 index cea1575a..00000000 --- a/FileSets/v2.85/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/startstop.py \ No newline at end of file diff --git a/FileSets/v2.85/styles.css b/FileSets/v2.85/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v2.85/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v2.86/Battery.qml b/FileSets/v2.86/Battery.qml deleted file mode 120000 index ef252511..00000000 --- a/FileSets/v2.86/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/Battery.qml \ No newline at end of file diff --git a/FileSets/v2.86/COMPLETE b/FileSets/v2.86/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.86/DetailAcInput.qml b/FileSets/v2.86/DetailAcInput.qml deleted file mode 120000 index b040d3b7..00000000 --- a/FileSets/v2.86/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v2.86/DetailInverter.qml b/FileSets/v2.86/DetailInverter.qml deleted file mode 120000 index d02cb165..00000000 --- a/FileSets/v2.86/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v2.86/DetailLoadsCombined.qml b/FileSets/v2.86/DetailLoadsCombined.qml deleted file mode 120000 index 858daaea..00000000 --- a/FileSets/v2.86/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v2.86/DetailLoadsOnInput.qml b/FileSets/v2.86/DetailLoadsOnInput.qml deleted file mode 120000 index df0a1562..00000000 --- a/FileSets/v2.86/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v2.86/DetailLoadsOnOutput.qml b/FileSets/v2.86/DetailLoadsOnOutput.qml deleted file mode 120000 index 33ab936b..00000000 --- a/FileSets/v2.86/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v2.86/HubData.qml b/FileSets/v2.86/HubData.qml deleted file mode 120000 index 8e608582..00000000 --- a/FileSets/v2.86/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/HubData.qml \ No newline at end of file diff --git a/FileSets/v2.86/LINKS_ONLY b/FileSets/v2.86/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.86/MbEditBox.qml b/FileSets/v2.86/MbEditBox.qml deleted file mode 120000 index 8381b7d5..00000000 --- a/FileSets/v2.86/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v2.86/MbEditBoxDateTime.qml b/FileSets/v2.86/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v2.86/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.86/MbItem.qml b/FileSets/v2.86/MbItem.qml deleted file mode 120000 index 1280e190..00000000 --- a/FileSets/v2.86/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItem.qml \ No newline at end of file diff --git a/FileSets/v2.86/MbItemDigitalInput.qml b/FileSets/v2.86/MbItemDigitalInput.qml deleted file mode 120000 index 63943a08..00000000 --- a/FileSets/v2.86/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.86/MbSpinBox.qml b/FileSets/v2.86/MbSpinBox.qml deleted file mode 120000 index 4160ecd2..00000000 --- a/FileSets/v2.86/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v2.86/MbStyle.qml b/FileSets/v2.86/MbStyle.qml deleted file mode 120000 index db6f181f..00000000 --- a/FileSets/v2.86/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v2.86/MbSubMenu.qml b/FileSets/v2.86/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v2.86/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.86/Multi.qml b/FileSets/v2.86/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v2.86/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.86/ObjectAcConnection.qml b/FileSets/v2.86/ObjectAcConnection.qml deleted file mode 120000 index 9ca254ed..00000000 --- a/FileSets/v2.86/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v2.86/OverviewAcValuesEnhanced.qml b/FileSets/v2.86/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 4d6d5018..00000000 --- a/FileSets/v2.86/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.86/OverviewBox.qml b/FileSets/v2.86/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v2.86/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.86/OverviewConnection.qml b/FileSets/v2.86/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v2.86/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.86/OverviewConnectionEnd.qml b/FileSets/v2.86/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v2.86/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.86/OverviewFlowComplex.qml b/FileSets/v2.86/OverviewFlowComplex.qml deleted file mode 120000 index 6b747507..00000000 --- a/FileSets/v2.86/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v2.86/OverviewGeneratorEnhanced.qml b/FileSets/v2.86/OverviewGeneratorEnhanced.qml deleted file mode 120000 index b0670070..00000000 --- a/FileSets/v2.86/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.86/OverviewGeneratorRelayEnhanced.qml b/FileSets/v2.86/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index c6fa07f9..00000000 --- a/FileSets/v2.86/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.86/OverviewGridParallel.qml b/FileSets/v2.86/OverviewGridParallel.qml deleted file mode 120000 index cbf456ca..00000000 --- a/FileSets/v2.86/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v2.86/OverviewHub.qml b/FileSets/v2.86/OverviewHub.qml deleted file mode 120000 index 3f37eb0c..00000000 --- a/FileSets/v2.86/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v2.86/OverviewHubEnhanced.qml b/FileSets/v2.86/OverviewHubEnhanced.qml deleted file mode 120000 index 6dc4f1d8..00000000 --- a/FileSets/v2.86/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.86/OverviewMobileEnhanced.qml b/FileSets/v2.86/OverviewMobileEnhanced.qml deleted file mode 120000 index a70d4024..00000000 --- a/FileSets/v2.86/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.86/OverviewSolarCharger.qml b/FileSets/v2.86/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v2.86/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.86/OverviewSolarInverter.qml b/FileSets/v2.86/OverviewSolarInverter.qml deleted file mode 120000 index 7cea58a2..00000000 --- a/FileSets/v2.86/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v2.86/OverviewTankDelegate.qml b/FileSets/v2.86/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v2.86/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.86/OverviewTanks.qml b/FileSets/v2.86/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v2.86/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.86/OverviewTanksTempsDigInputs.qml b/FileSets/v2.86/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index d080b0f4..00000000 --- a/FileSets/v2.86/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v2.86/PageDigitalInput.qml b/FileSets/v2.86/PageDigitalInput.qml deleted file mode 120000 index 839f7874..00000000 --- a/FileSets/v2.86/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.86/PageGenerator.qml b/FileSets/v2.86/PageGenerator.qml deleted file mode 120000 index cae51ecb..00000000 --- a/FileSets/v2.86/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.86/PageMain.qml b/FileSets/v2.86/PageMain.qml deleted file mode 120000 index 9f74fa85..00000000 --- a/FileSets/v2.86/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageMain.qml \ No newline at end of file diff --git a/FileSets/v2.86/PageSettingsDisplay.qml b/FileSets/v2.86/PageSettingsDisplay.qml deleted file mode 120000 index b3885a68..00000000 --- a/FileSets/v2.86/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v2.86/PageSettingsGenerator.qml b/FileSets/v2.86/PageSettingsGenerator.qml deleted file mode 120000 index 861e41bb..00000000 --- a/FileSets/v2.86/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.86/PageSettingsGuiMods.qml b/FileSets/v2.86/PageSettingsGuiMods.qml deleted file mode 120000 index d3534bd3..00000000 --- a/FileSets/v2.86/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v2.86/PageSettingsRelay.qml b/FileSets/v2.86/PageSettingsRelay.qml deleted file mode 120000 index 6861254c..00000000 --- a/FileSets/v2.86/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v2.86/PowerGauge.qml b/FileSets/v2.86/PowerGauge.qml deleted file mode 120000 index d82ac28a..00000000 --- a/FileSets/v2.86/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v2.86/Tile.qml b/FileSets/v2.86/Tile.qml deleted file mode 120000 index aa80e332..00000000 --- a/FileSets/v2.86/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/Tile.qml \ No newline at end of file diff --git a/FileSets/v2.86/TileDigIn.qml b/FileSets/v2.86/TileDigIn.qml deleted file mode 120000 index 2f8c7989..00000000 --- a/FileSets/v2.86/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v2.86/TileRelay.qml b/FileSets/v2.86/TileRelay.qml deleted file mode 120000 index 4313882d..00000000 --- a/FileSets/v2.86/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v2.86/TileText.qml b/FileSets/v2.86/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v2.86/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.86/attributes.csv b/FileSets/v2.86/attributes.csv deleted file mode 120000 index 5a253081..00000000 --- a/FileSets/v2.86/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v2.89/attributes.csv \ No newline at end of file diff --git a/FileSets/v2.86/dbus_digitalinputs.py b/FileSets/v2.86/dbus_digitalinputs.py deleted file mode 120000 index 52bec86e..00000000 --- a/FileSets/v2.86/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v2.86/dbus_generator.py b/FileSets/v2.86/dbus_generator.py deleted file mode 120000 index f8e02b46..00000000 --- a/FileSets/v2.86/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v2.86/dbus_systemcalc.py b/FileSets/v2.86/dbus_systemcalc.py deleted file mode 120000 index 0548b1ea..00000000 --- a/FileSets/v2.86/dbus_systemcalc.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/dbus_systemcalc.py \ No newline at end of file diff --git a/FileSets/v2.86/main.qml b/FileSets/v2.86/main.qml deleted file mode 120000 index 54acc57c..00000000 --- a/FileSets/v2.86/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/main.qml \ No newline at end of file diff --git a/FileSets/v2.86/startstop.py b/FileSets/v2.86/startstop.py deleted file mode 120000 index cea1575a..00000000 --- a/FileSets/v2.86/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/startstop.py \ No newline at end of file diff --git a/FileSets/v2.86/styles.css b/FileSets/v2.86/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v2.86/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v2.87/Battery.qml b/FileSets/v2.87/Battery.qml deleted file mode 120000 index ef252511..00000000 --- a/FileSets/v2.87/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/Battery.qml \ No newline at end of file diff --git a/FileSets/v2.87/COMPLETE b/FileSets/v2.87/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.87/DetailAcInput.qml b/FileSets/v2.87/DetailAcInput.qml deleted file mode 120000 index b040d3b7..00000000 --- a/FileSets/v2.87/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v2.87/DetailInverter.qml b/FileSets/v2.87/DetailInverter.qml deleted file mode 120000 index d02cb165..00000000 --- a/FileSets/v2.87/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v2.87/DetailLoadsCombined.qml b/FileSets/v2.87/DetailLoadsCombined.qml deleted file mode 120000 index 858daaea..00000000 --- a/FileSets/v2.87/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v2.87/DetailLoadsOnInput.qml b/FileSets/v2.87/DetailLoadsOnInput.qml deleted file mode 120000 index df0a1562..00000000 --- a/FileSets/v2.87/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v2.87/DetailLoadsOnOutput.qml b/FileSets/v2.87/DetailLoadsOnOutput.qml deleted file mode 120000 index 33ab936b..00000000 --- a/FileSets/v2.87/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v2.87/HubData.qml b/FileSets/v2.87/HubData.qml deleted file mode 120000 index 8e608582..00000000 --- a/FileSets/v2.87/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/HubData.qml \ No newline at end of file diff --git a/FileSets/v2.87/LINKS_ONLY b/FileSets/v2.87/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.87/MbEditBox.qml b/FileSets/v2.87/MbEditBox.qml deleted file mode 120000 index 8381b7d5..00000000 --- a/FileSets/v2.87/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v2.87/MbEditBoxDateTime.qml b/FileSets/v2.87/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v2.87/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.87/MbItem.qml b/FileSets/v2.87/MbItem.qml deleted file mode 120000 index 1280e190..00000000 --- a/FileSets/v2.87/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItem.qml \ No newline at end of file diff --git a/FileSets/v2.87/MbItemDigitalInput.qml b/FileSets/v2.87/MbItemDigitalInput.qml deleted file mode 120000 index 63943a08..00000000 --- a/FileSets/v2.87/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.87/MbSpinBox.qml b/FileSets/v2.87/MbSpinBox.qml deleted file mode 120000 index 4160ecd2..00000000 --- a/FileSets/v2.87/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v2.87/MbStyle.qml b/FileSets/v2.87/MbStyle.qml deleted file mode 120000 index db6f181f..00000000 --- a/FileSets/v2.87/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v2.87/MbSubMenu.qml b/FileSets/v2.87/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v2.87/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.87/Multi.qml b/FileSets/v2.87/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v2.87/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.87/ObjectAcConnection.qml b/FileSets/v2.87/ObjectAcConnection.qml deleted file mode 120000 index 9ca254ed..00000000 --- a/FileSets/v2.87/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v2.87/OverviewAcValuesEnhanced.qml b/FileSets/v2.87/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 4d6d5018..00000000 --- a/FileSets/v2.87/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.87/OverviewBox.qml b/FileSets/v2.87/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v2.87/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.87/OverviewConnection.qml b/FileSets/v2.87/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v2.87/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.87/OverviewConnectionEnd.qml b/FileSets/v2.87/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v2.87/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.87/OverviewFlowComplex.qml b/FileSets/v2.87/OverviewFlowComplex.qml deleted file mode 120000 index 6b747507..00000000 --- a/FileSets/v2.87/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v2.87/OverviewGeneratorEnhanced.qml b/FileSets/v2.87/OverviewGeneratorEnhanced.qml deleted file mode 120000 index b0670070..00000000 --- a/FileSets/v2.87/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.87/OverviewGeneratorRelayEnhanced.qml b/FileSets/v2.87/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index c6fa07f9..00000000 --- a/FileSets/v2.87/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.87/OverviewGridParallel.qml b/FileSets/v2.87/OverviewGridParallel.qml deleted file mode 120000 index cbf456ca..00000000 --- a/FileSets/v2.87/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v2.87/OverviewHub.qml b/FileSets/v2.87/OverviewHub.qml deleted file mode 120000 index 3f37eb0c..00000000 --- a/FileSets/v2.87/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v2.87/OverviewHubEnhanced.qml b/FileSets/v2.87/OverviewHubEnhanced.qml deleted file mode 120000 index 6dc4f1d8..00000000 --- a/FileSets/v2.87/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.87/OverviewMobileEnhanced.qml b/FileSets/v2.87/OverviewMobileEnhanced.qml deleted file mode 120000 index a70d4024..00000000 --- a/FileSets/v2.87/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.87/OverviewSolarCharger.qml b/FileSets/v2.87/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v2.87/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.87/OverviewSolarInverter.qml b/FileSets/v2.87/OverviewSolarInverter.qml deleted file mode 120000 index 7cea58a2..00000000 --- a/FileSets/v2.87/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v2.87/OverviewTankDelegate.qml b/FileSets/v2.87/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v2.87/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.87/OverviewTanks.qml b/FileSets/v2.87/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v2.87/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.87/OverviewTanksTempsDigInputs.qml b/FileSets/v2.87/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index d080b0f4..00000000 --- a/FileSets/v2.87/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v2.87/PageDigitalInput.qml b/FileSets/v2.87/PageDigitalInput.qml deleted file mode 120000 index 839f7874..00000000 --- a/FileSets/v2.87/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.87/PageGenerator.qml b/FileSets/v2.87/PageGenerator.qml deleted file mode 120000 index cae51ecb..00000000 --- a/FileSets/v2.87/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.87/PageMain.qml b/FileSets/v2.87/PageMain.qml deleted file mode 120000 index 9f74fa85..00000000 --- a/FileSets/v2.87/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageMain.qml \ No newline at end of file diff --git a/FileSets/v2.87/PageSettingsDisplay.qml b/FileSets/v2.87/PageSettingsDisplay.qml deleted file mode 120000 index b3885a68..00000000 --- a/FileSets/v2.87/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v2.87/PageSettingsGenerator.qml b/FileSets/v2.87/PageSettingsGenerator.qml deleted file mode 120000 index 861e41bb..00000000 --- a/FileSets/v2.87/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.87/PageSettingsGuiMods.qml b/FileSets/v2.87/PageSettingsGuiMods.qml deleted file mode 120000 index d3534bd3..00000000 --- a/FileSets/v2.87/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v2.87/PageSettingsRelay.qml b/FileSets/v2.87/PageSettingsRelay.qml deleted file mode 120000 index 6861254c..00000000 --- a/FileSets/v2.87/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v2.87/PowerGauge.qml b/FileSets/v2.87/PowerGauge.qml deleted file mode 120000 index d82ac28a..00000000 --- a/FileSets/v2.87/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v2.87/Tile.qml b/FileSets/v2.87/Tile.qml deleted file mode 120000 index aa80e332..00000000 --- a/FileSets/v2.87/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/Tile.qml \ No newline at end of file diff --git a/FileSets/v2.87/TileDigIn.qml b/FileSets/v2.87/TileDigIn.qml deleted file mode 120000 index 2f8c7989..00000000 --- a/FileSets/v2.87/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v2.87/TileRelay.qml b/FileSets/v2.87/TileRelay.qml deleted file mode 120000 index 4313882d..00000000 --- a/FileSets/v2.87/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v2.87/TileText.qml b/FileSets/v2.87/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v2.87/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.87/attributes.csv b/FileSets/v2.87/attributes.csv deleted file mode 120000 index 5a253081..00000000 --- a/FileSets/v2.87/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v2.89/attributes.csv \ No newline at end of file diff --git a/FileSets/v2.87/dbus_digitalinputs.py b/FileSets/v2.87/dbus_digitalinputs.py deleted file mode 120000 index 52bec86e..00000000 --- a/FileSets/v2.87/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v2.87/dbus_generator.py b/FileSets/v2.87/dbus_generator.py deleted file mode 120000 index f8e02b46..00000000 --- a/FileSets/v2.87/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v2.87/dbus_systemcalc.py b/FileSets/v2.87/dbus_systemcalc.py deleted file mode 120000 index 0548b1ea..00000000 --- a/FileSets/v2.87/dbus_systemcalc.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/dbus_systemcalc.py \ No newline at end of file diff --git a/FileSets/v2.87/main.qml b/FileSets/v2.87/main.qml deleted file mode 120000 index 54acc57c..00000000 --- a/FileSets/v2.87/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.89/main.qml \ No newline at end of file diff --git a/FileSets/v2.87/startstop.py b/FileSets/v2.87/startstop.py deleted file mode 120000 index cea1575a..00000000 --- a/FileSets/v2.87/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v2.89/startstop.py \ No newline at end of file diff --git a/FileSets/v2.87/styles.css b/FileSets/v2.87/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v2.87/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v2.89/Battery.qml b/FileSets/v2.89/Battery.qml deleted file mode 120000 index ef252511..00000000 --- a/FileSets/v2.89/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/Battery.qml \ No newline at end of file diff --git a/FileSets/v2.89/COMPLETE b/FileSets/v2.89/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.89/DetailAcInput.qml b/FileSets/v2.89/DetailAcInput.qml deleted file mode 120000 index b040d3b7..00000000 --- a/FileSets/v2.89/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v2.89/DetailInverter.qml b/FileSets/v2.89/DetailInverter.qml deleted file mode 120000 index d02cb165..00000000 --- a/FileSets/v2.89/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v2.89/DetailLoadsCombined.qml b/FileSets/v2.89/DetailLoadsCombined.qml deleted file mode 120000 index 858daaea..00000000 --- a/FileSets/v2.89/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v2.89/DetailLoadsOnInput.qml b/FileSets/v2.89/DetailLoadsOnInput.qml deleted file mode 120000 index df0a1562..00000000 --- a/FileSets/v2.89/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v2.89/DetailLoadsOnOutput.qml b/FileSets/v2.89/DetailLoadsOnOutput.qml deleted file mode 120000 index 33ab936b..00000000 --- a/FileSets/v2.89/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v2.89/HubData.qml b/FileSets/v2.89/HubData.qml deleted file mode 120000 index 8e608582..00000000 --- a/FileSets/v2.89/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/HubData.qml \ No newline at end of file diff --git a/FileSets/v2.89/MbEditBox.qml b/FileSets/v2.89/MbEditBox.qml deleted file mode 120000 index 8381b7d5..00000000 --- a/FileSets/v2.89/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v2.89/MbEditBoxDateTime.qml b/FileSets/v2.89/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v2.89/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.89/MbItem.qml b/FileSets/v2.89/MbItem.qml deleted file mode 120000 index 1280e190..00000000 --- a/FileSets/v2.89/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItem.qml \ No newline at end of file diff --git a/FileSets/v2.89/MbItemDigitalInput.qml b/FileSets/v2.89/MbItemDigitalInput.qml deleted file mode 120000 index 63943a08..00000000 --- a/FileSets/v2.89/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.89/MbStyle.qml b/FileSets/v2.89/MbStyle.qml deleted file mode 120000 index db6f181f..00000000 --- a/FileSets/v2.89/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v2.89/MbSubMenu.qml b/FileSets/v2.89/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v2.89/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.89/Multi.qml b/FileSets/v2.89/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v2.89/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.89/ObjectAcConnection.qml b/FileSets/v2.89/ObjectAcConnection.qml deleted file mode 120000 index 9ca254ed..00000000 --- a/FileSets/v2.89/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v2.89/OverviewAcValuesEnhanced.qml b/FileSets/v2.89/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 4d6d5018..00000000 --- a/FileSets/v2.89/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.89/OverviewBox.qml b/FileSets/v2.89/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v2.89/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.89/OverviewConnection.qml b/FileSets/v2.89/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v2.89/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.89/OverviewConnectionEnd.qml b/FileSets/v2.89/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v2.89/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.89/OverviewFlowComplex.qml b/FileSets/v2.89/OverviewFlowComplex.qml deleted file mode 120000 index 6b747507..00000000 --- a/FileSets/v2.89/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v2.89/OverviewGeneratorEnhanced.qml b/FileSets/v2.89/OverviewGeneratorEnhanced.qml deleted file mode 120000 index b0670070..00000000 --- a/FileSets/v2.89/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.89/OverviewGeneratorRelayEnhanced.qml b/FileSets/v2.89/OverviewGeneratorRelayEnhanced.qml deleted file mode 100644 index 9710ada6..00000000 --- a/FileSets/v2.89/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -OverviewGeneratorEnhanced { - icon: "image://theme/overview-generator" - settingsBindPrefix: "com.victronenergy.settings/Settings/Generator0" - bindPrefix: "com.victronenergy.generator.startstop0/Generator0" -} diff --git a/FileSets/v2.89/OverviewGeneratorRelayEnhanced.qml.orig b/FileSets/v2.89/OverviewGeneratorRelayEnhanced.qml.orig deleted file mode 100644 index 0fcaa6bc..00000000 --- a/FileSets/v2.89/OverviewGeneratorRelayEnhanced.qml.orig +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -OverviewGenerator { - icon: "image://theme/overview-generator" - settingsBindPrefix: "com.victronenergy.settings/Settings/Generator0" - bindPrefix: "com.victronenergy.generator.startstop0/Generator0" -} diff --git a/FileSets/v2.89/OverviewGridParallel.qml b/FileSets/v2.89/OverviewGridParallel.qml deleted file mode 120000 index cbf456ca..00000000 --- a/FileSets/v2.89/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v2.89/OverviewHub.qml b/FileSets/v2.89/OverviewHub.qml deleted file mode 120000 index 3f37eb0c..00000000 --- a/FileSets/v2.89/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v2.89/OverviewHubEnhanced.qml b/FileSets/v2.89/OverviewHubEnhanced.qml deleted file mode 120000 index 6dc4f1d8..00000000 --- a/FileSets/v2.89/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.89/OverviewMobileEnhanced.qml b/FileSets/v2.89/OverviewMobileEnhanced.qml deleted file mode 100644 index a845328b..00000000 --- a/FileSets/v2.89/OverviewMobileEnhanced.qml +++ /dev/null @@ -1,987 +0,0 @@ -// GuiMods Enhancements to OverviewMobile screen - -// Removed logo and added AC INPUT and SYSTEM tiles originally displayed on other overviews -// Added voltage, current and frequency to AC INPUT and AC LOADS tiles -// Added source (Grid, Generator, Shore Power) to AC INPUT tile -// Replaced to/from battery with current in DC SYSTEM tile -// DC SYSTEM tile title now reflects direction: "DC LOADS, DC CHARGER" -// Rearranged tiles to match a left to right signal flow : sources on left, loads on right -// Standardized "info" tile sizes to 1 or 1.5 wide x 1 or 2 high -// infoArea defines usable space for info tiles and all tiles are a child of infoArea -// (makes repositioning easier than when they were in separate column objects) -// Large text for main paremeter in each tile has been reduced in size to allow more parameters without -// expanding tile height (30 to 22) -// merged SYSTEM and STATUS tiles -// removed speed from STATUS to reduce tile height -// hide "reason" text if it's blank to save space -// changed clock to 12-hour format -// Capitialized battery state: "Idle", "Charging", "Discharging" -// errors and notificaitons in SYSTEM/STATUS tile may push clock off bottom of tile -// Tile content for items that are not present are made invisible - tile remains in place -// that is no height adjustments when a tile provides no information -// Adjust button widths so that pump button fits within tank column -// Hide pump button when not enabled giving more room for tanks -// Add temperature sensors to tanks column -// add control of VE.Direct inverters - -// Includes changes to handle SeeLevel NMEA2000 tank sensor: -// Ignore the real incoming tank dBus service because it's information changes -// Changes in TileText.qml are also part of the TankRepeater package - -// Search for //////// to find changes - -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils -import "timeToGo.js" as TTG -import "enhancedFormat.js" as EnhFmt - -OverviewPage { - title: qsTr("Mobile") - id: root - - property color detailColor: "#b3b3b3" - property real touchTargetOpacity: 0.3 - property int touchArea: 40 - - property variant sys: theSystem - property string settingsBindPreffix: "com.victronenergy.settings" - property string pumpBindPreffix: "com.victronenergy.pump.startstop0" - property variant activeNotifications: NotificationCenter.notifications.filter( - function isActive(obj) { return obj.active} ) - property string noAdjustableByDmc: qsTr("This setting is disabled when a Digital Multi Control " + - "is connected. If it was recently disconnected execute " + - "\"Redetect system\" that is available on the inverter menu page.") - property string noAdjustableByBms: qsTr("This setting is disabled when a VE.Bus BMS " + - "is connected. If it was recently disconnected execute " + - "\"Redetect system\" that is available on the inverter menu page.") - property string noAdjustableTextByConfig: qsTr("This setting is disabled. " + - "Possible reasons are \"Overruled by remote\" is not enabled or " + - "an assistant is preventing the adjustment. Please, check " + - "the inverter configuration with VEConfigure.") - -//////// added to keep track of tanks and temps - property int numberOfTemps: 0 - property int tankTempCount: tankModel.rowCount + numberOfTemps - property real tanksTempsHeight: root.height - (pumpButton.pumpEnabled ? pumpButton.height : 0) - property real tanksHeight: tankModel.rowCount > 0 ? tanksTempsHeight * tankModel.rowCount / tankTempCount : 0 - property real tempsHeight: tanksTempsHeight - tanksHeight - property real minimumTankHeight: 21 - property real maxTankHeight: 80 - property real tankTileHeight: Math.min (Math.max (tanksTempsHeight / tankTempCount, minimumTankHeight), maxTankHeight) - - property bool compact: tankTempCount > (pumpButton.pumpEnabled ? 5 : 6) - - property string systemPrefix: "com.victronenergy.system" - VBusItem { id: vebusService; bind: Utils.path(systemPrefix, "/VebusService") } - property bool isMulti: vebusService.valid - property string veDirectInverterService: "" - property string inverterService: vebusService.valid ? vebusService.value : veDirectInverterService - - property bool isInverter: ! isMulti && veDirectInverterService != "" - - property bool hasAcInput: isMulti - VBusItem { id: _hasAcOutSystem; bind: "com.victronenergy.settings/Settings/SystemSetup/HasAcOutSystem" } - property bool hasAcOutSystem: _hasAcOutSystem.value === 1 - -//////// add for system state - property bool hasSystemState: _systemState.valid - -//////// add for SYSTEM tile and voltage, power and frequency values - property VBusItem _systemState: VBusItem { bind: Utils.path(systemPrefix, "/SystemState/State") } -//////// add for PV CHARGER voltage and current - property string pvChargerPrefix: "" - property int numberOfPvChargers: 0 - - - //////// standard tile sizes - //////// positions are left, center, right and top, center, bottom of infoArea - property int tankWidth: 130 - - property int upperTileHeight: 185 - property int acTileHeight: height - upperTileHeight - - property int infoWidth: width - tankWidth - property int infoWidth3Column: infoWidth / 3 - property int infoWidth2Column: infoWidth / 2 - -//////// add for PV Charger voltage and current - VBusItem { id: pvNrTrackers; bind: Utils.path(pvChargerPrefix, "/NrOfTrackers") } - property bool singleTracker: ! pvNrTrackers.valid || pvNrTrackers.value == 1 - property bool showPvVI: numberOfPvChargers == 1 && singleTracker - VBusItem { id: pvPower; bind: Utils.path(pvChargerPrefix, "/Yield/Power") } - VBusItem { id: pvVoltage; bind: Utils.path(pvChargerPrefix, singleTracker ? "/Pv/V" : "/Pv/0/V") } - -//////// add for inverter mode in STATUS - VBusItem { id: inverterMode; bind: Utils.path(inverterService, "/Mode") } - -//////// add for gauges - VBusItem { id: showGaugesItem; bind: Utils.path(guiModsPrefix, "/ShowGauges") } - property bool showGauges: showGaugesItem.valid ? showGaugesItem.value === 1 ? true : false : false - -//////// added to control time display - property string guiModsPrefix: "com.victronenergy.settings/Settings/GuiMods" - VBusItem { id: timeFormatItem; bind: Utils.path(guiModsPrefix, "/TimeFormat") } - property string timeFormat: getTimeFormat () - - function getTimeFormat () - { - if (!timeFormatItem.valid || timeFormatItem.value === 0) - return "" - else if (timeFormatItem.value === 2) - return "h:mm ap" - else - return "hh:mm" - } - - Component.onCompleted: { discoverServices(); showHelp () } - - // define usable space for tiles but don't show anything - Rectangle { - id: infoArea - visible: false - anchors { - left: parent.left - right: tanksColum.left - top: parent.top; - bottom: parent.bottom; - } - } - -//////// change time to selectable 12/24 hour format - Timer { - id: wallClock - running: timeFormat != "" - repeat: true - interval: 1000 - triggeredOnStart: true - onTriggered: time = Qt.formatDateTime(new Date(), timeFormat) - property string time - } - - VBusItem { id: systemName; bind: Utils.path(settingsBindPreffix, "/Settings/SystemSetup/SystemName") } - -//////// copied SYSTEM from OverviewTiles.qml & combined SYSTEM and STATUS tiles - Tile { - title: qsTr("STATUS") - id: statusTile - anchors { left: parent.left; top: parent.top } - width: root.infoWidth3Column - height: root.upperTileHeight - inverterTile.height - color: "#4789d0" - -//////// relorder to give priority to errors - values: [ - TileText { - text: systemName.valid && systemName.value !== "" ? systemName.value : sys.systemType.valid ? sys.systemType.value.toUpperCase() : "" - font.pixelSize: 16 - wrapMode: Text.WordWrap - width: statusTile.width - 5 - }, - TileText { - text: wallClock.running ? wallClock.time : "" - font.pixelSize: 15 - }, -//////// combine SystemReason with notifications - MarqueeEnhanced { - text: - { - if (activeNotifications.length === 0) - return systemReasonMessage.text - else - return notificationText() + " || " + systemReasonMessage.text - } - width: statusTile.width - textHorizontalAlignment: Text.AlignHCenter - interval: 100 - SystemReasonMessage { - id: systemReasonMessage - } - }, - TileText { - property VeQuickItem gpsService: VeQuickItem { uid: "dbus/com.victronenergy.system/GpsService" } - property VeQuickItem speed: VeQuickItem { uid: Utils.path("dbus/", gpsService.value, "/Speed") } - property VeQuickItem speedUnit: VeQuickItem { uid: "dbus/com.victronenergy.settings/Settings/Gps/SpeedUnit" } - - text: speed.value === undefined ? "" : getValue() - visible: speed.value !== undefined && speedUnit.value !== undefined - - function getValue() - { - if (speed.value < 0.5) // blank speed if less than about 1 MPH - return " " - if (speedUnit.value === "km/h") - return (speed.value * 3.6).toFixed(1) + speedUnit.value - if (speedUnit.value === "mph") - return (speed.value * 2.236936).toFixed(1) + speedUnit.value - if (speedUnit.value === "kt") - return (speed.value * (3600/1852)).toFixed(1) + speedUnit.value - return speed.value.toFixed(2) + "m/s" - } - } - ] - } // end Tile STATUS - Tile { - title: qsTr("INVERTER") - id: inverterTile - anchors { left: parent.left; top: statusTile.bottom } - width: root.infoWidth3Column - height: 62 - color: "#4789d0" - - -//////// relorder to give priority to errors - values: [ - TileText - { - text: inverterMode.valid ? inverterMode.text : "--" - }, - TileText { - text: qsTr(systemState.text) - - SystemState { - id: systemState - bind: hasSystemState?Utils.path(systemPrefix, "/SystemState/State"):Utils.path(inverterService, "/State") - } - } - ] -////// add power bar graph - PowerGaugeMulti - { - id: multiBar - width: parent.width - 10 - height: 8 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - inverterService: root.inverterService - visible: showGauges - } - DetailTarget { id: multiTarget; detailsPage: "DetailInverter.qml" } - } // end Tile INVERTER - - Tile { - title: qsTr("BATTERY") - id: batteryTile - anchors { horizontalCenter: infoArea.horizontalCenter; top: infoArea.top } - width: root.infoWidth3Column - height: root.upperTileHeight - - values: [ - TileText // spacer - { - text: "" - font.pixelSize: 6 - }, - TileText { - text: sys.battery.soc.absFormat(0) - font.pixelSize: 22 - //////// remove height (for consistency with other tiles) - }, - TileText { - text: { - if (!sys.battery.state.valid) - return "---" - switch(sys.battery.state.value) { - //////// change - capitalized words look better - case sys.batteryStateIdle: return qsTr("Idle") - case sys.batteryStateCharging : return qsTr("Charging") - case sys.batteryStateDischarging : return qsTr("Discharging") - } - } - }, - TileText { -//////// change to show negative for battery drain - text: sys.battery.power.text - font.pixelSize: 18 - }, - TileText { - text: sys.battery.voltage.format(2) - }, - TileText { - text: sys.battery.current.format(1) - }, - TileText { - text: qsTr("Remaining:") - visible: timeToGo.valid - }, - TileText { - id: timeToGoText - text: timeToGo.valid ? TTG.formatTimeToGo (timeToGo) : " " - visible: timeToGo.valid - - VBusItem { - id: timeToGo - bind: Utils.path("com.victronenergy.system","/Dc/Battery/TimeToGo") - } - } - ] -////// add battery current bar graph - PowerGaugeBattery - { - id: batteryBar - width: parent.width - 10 - height: 8 - endLabelFontSize: 14 - endLabelBackgroundColor: batteryTile.color - anchors - { - top: parent.top; topMargin: 22 - horizontalCenter: parent.horizontalCenter - } - visible: showGauges - } - DetailTarget { id: batteryTarget; detailsPage: "DetailBattery.qml" } - } // end Tile BATTERY - - VBusItem { id: dcSystemNameItem; bind: Utils.path(settingsBindPreffix, "/Settings/GuiMods/CustomDcSystemName") } - - Tile { - title: dcSystemNameItem.valid && dcSystemNameItem.value != "" ? dcSystemNameItem.value : qsTr ("DC SYSTEM") - id: dcSystem - anchors { right: infoArea.right; bottom: infoArea.bottom; bottomMargin: root.acTileHeight } - width: root.infoWidth3Column - height: (root.upperTileHeight / 2) - 5 - color: "#16a085" - values: [ - TileText { - font.pixelSize: 22 - text: EnhFmt.formatVBusItem (sys.dcSystem.power) - visible: sys.dcSystem.power.valid - }, - ////// replace to/from battery with current - TileText { - text: !sys.dcSystem.power.valid ? "---" : - EnhFmt.formatValue (sys.dcSystem.power.value / sys.battery.voltage.value, "A") - visible: sys.dcSystem.power.valid - } - ] - PowerGauge - { - id: dcSystemGauge - width: parent.width - 10 - height: 8 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.dcSystem - endLabelFontSize: 12 - endLabelBackgroundColor: dcSystem.color - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/DcSystemMaxLoad" - maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/DcSystemMaxCharge" - showLabels: true - visible: showGauges && sys.dcSystem.power.valid - } - DetailTarget { id: dcSystemTarget; detailsPage: "DetailDcSystem.qml" } - } // end Tile DC SYSTEM - - Tile { - id: solarTile - title: qsTr("PV CHARGER") - anchors { right: infoArea.right; top: infoArea.top } - width: root.infoWidth3Column - height: root.upperTileHeight - dcSystem.height - color: "#2cc36b" - values: [ - TileText { - font.pixelSize: 22 - text: EnhFmt.formatVBusItem (sys.pvCharger.power) - }, - //////// add voltage - TileText { - text: - { - if (showPvVI) - return EnhFmt.formatVBusItem (pvVoltage, "V") - else - return "" - } - visible: showPvVI - }, - //////// add =current - TileText { - text: - { - if (showPvVI && pvPower.valid && pvVoltage.valid) - { - var voltage = pvVoltage.value - return EnhFmt.formatValue ((pvPower.value / voltage), "A") - } - else - return "" - } - visible: showPvVI - } - ] -////// add power bar graph - PowerGauge - { - id: pvChargerBar - width: parent.width - 10 - height: 8 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.pvCharger - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvChargerMaxPower" - visible: showGauges && sys.pvCharger.power.valid - } - DetailTarget { id: pvChargerTarget; detailsPage: "DetailPvCharger.qml" } - } // end Tile PV CHARGER - -//////// add to display AC input ignored - VBusItem { id: ignoreAcInput; bind: Utils.path(inverterService, "/Ac/State/IgnoreAcIn1") } - -//////// add AC INPUT tile - Tile { - id: acInputTile - title: { - if (isInverter) - return qsTr ("No AC Input") - else if (ignoreAcInput.valid && ignoreAcInput.value == 1) - return qsTr ("AC In Ignored") - else - { - switch(sys.acSource) { - case 1: return qsTr("GRID") - case 2: return qsTr("GENERATOR") - case 3: return qsTr("SHORE POWER") - default: return qsTr("AC INPUT") - } - } - } - anchors { left: infoArea.left; bottom: infoArea.bottom } - width: root.infoWidth2Column - height: root.acTileHeight - color: "#82acde" -//////// add voltage and current - VBusItem { id: currentLimit; bind: Utils.path(inverterService, "/Ac/ActiveIn/CurrentLimit") } - values: [ - TileText { - visible: isMulti - text: EnhFmt.formatVBusItem (sys.acInput.power) - font.pixelSize: 20 - - }, -//////// add voltage and current - TileText { - visible: isMulti - text: EnhFmt.formatVBusItem (sys.acInput.voltageL1, "V") + " " + EnhFmt.formatVBusItem (sys.acInput.currentL1, "A") + " " + EnhFmt.formatVBusItem (sys.acInput.frequency, "Hz") - }, - TileText - { - text: qsTr ("Limit: ") + EnhFmt.formatVBusItem (currentLimit, "A") - visible: currentLimit.valid - } - ] -////// add power bar graph - PowerGauge - { - id: acInBar - width: parent.width - 10 - height: 8 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - useInputCurrentLimit: true - connection: sys.acInput - maxForwardPowerParameter: "" // handled internally - uses input current limit and AC input voltage - maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxFeedInPower" - visible: showGauges && hasAcInput - } - DetailTarget { id: acInputTarget; detailsPage: "DetailAcInput.qml" } - } - - Tile { - title: qsTr("AC LOADS") - id: acLoadsTile - anchors { right: infoArea.right; bottom: infoArea.bottom} - width: root.infoWidth2Column - height: root.acTileHeight - color: "#e68e8a" -//////// add voltage and current - VBusItem { id: outVoltage; bind: Utils.path(inverterService, "/Ac/Out/L1/V") } - VBusItem { id: outCurrent; bind: Utils.path(inverterService, "/Ac/Out/L1/I") } - VBusItem { id: outFrequency; bind: Utils.path(inverterService, "/Ac/Out/L1/F") } - - values: [ - TileText { - text: EnhFmt.formatVBusItem (sys.acLoad.power) - font.pixelSize: 22 - }, -//////// add voltage and current - no frequency for VE.Direct inverter - TileText { - text: - { - var lineText = "" - if (isMulti || isInverter) - { - lineText = EnhFmt.formatVBusItem (outVoltage, "V") + " " + EnhFmt.formatVBusItem (outCurrent, "A") - if (isMulti) - lineText += " " + EnhFmt.formatVBusItem (outFrequency, "Hz") - } - return lineText - } - } - ] -////// add power bar graph - PowerGauge - { - id: acLoadBar - width: parent.width - 10 - height: 8 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.acLoad - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputMaxPower" - visible: showGauges && hasAcOutSystem - } - DetailTarget { id: acLoadsOnOutputTarget; detailsPage: "DetailLoadsOnOutput.qml" } - } - - // Synchronise tank name text scroll start - Timer { - id: scrollTimer - interval: 15000 - repeat: true -//////// modified to control compact differently - running: root.active - } - - ListView { - id: tanksColum - - anchors { - top: root.top - right: root.right - } - height: root.tanksHeight - width: root.tankWidth -//////// make list flickable if more tiles than will fit completely - interactive: root.tankTileHeight * count > (tanksColum.height + 1) ? true : false - - model: TankModel { id: tankModel } - delegate: TileTankEnhanced { - // Without an intermediate assignment this will trigger a binding loop warning. - property variant theService: DBusServices.get(buddy.id) - service: theService - width: tanksColum.width - height: root.tankTileHeight - pumpBindPrefix: root.pumpBindPreffix -//////// modified to control compact differently - compact: root.compact - Connections { - target: scrollTimer - onTriggered: doScroll() - } - } - Tile { - title: qsTr("TANKS") - anchors.fill: parent - values: TileText { - text: qsTr("") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - -//////// added temperature ListView and Model - ListView { - id: tempsColumn - - anchors { - top: tanksColum.bottom - right: root.right - } - height: root.tempsHeight - width: root.tankWidth -//////// make list flickable if more tiles than will fit completely - interactive: root.tankTileHeight * count > (tempsColumn.height + 1) ? true : false - - model: tempsModel - delegate: TileTemp - { - width: tempsColumn.width - height: root.tankTileHeight -//////// modified to control compact differently - compact: root.compact - Connections - { - target: scrollTimer - onTriggered: doScroll() - } - } - Tile - { - title: qsTr("TEMPS") - anchors.fill: parent - values: TileText - { - text: qsTr("") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - ListModel { id: tempsModel } - - Tile { - id: pumpButton - - anchors.right: parent.right - anchors.bottom: parent.bottom - - property variant texts: [ qsTr("AUTO"), qsTr("ON"), qsTr("OFF")] - property int value: 0 - property bool reset: false - property bool pumpEnabled: pumpRelay.value === 3 - isCurrentItem: false // not used by GuiMods key handler - focus shown a different way - //focus: root.active && isCurrentItem // don't switch focus -- messes up key handler - - title: qsTr("PUMP") - width: pumpEnabled ? root.tankWidth : 0 - height: 45 - editable: true - readOnly: false - color: pumpButtonMouseArea.containsPressed ? "#d3d3d3" : "#A8A8A8" - - VBusItem { id: pump; bind: Utils.path(settingsBindPreffix, "/Settings/Pump0/Mode") } - VBusItem { id: pumpRelay; bind: Utils.path(settingsBindPreffix, "/Settings/Relay/Function") } - - values: [ - TileText { - text: pumpButton.pumpEnabled ? qsTr("%1").arg(pumpButton.texts[pumpButton.value]) : qsTr("DISABLED") - } - ] - - function edit() { - if (!pumpEnabled) { - toast.createToast(qsTr("Pump functionality is not enabled. To enable it go to the relay settings page and set function to \"Tank pump\""), 5000) - return - } - - reset = true - applyAnimation.restart() - reset = false - - if (value < 2) - value++ - else - value = 0 - } - - MouseArea { - id: pumpButtonMouseArea - property bool containsPressed: containsMouse && pressed - anchors.fill: parent - onClicked: { - parent.edit() - } - } - - Rectangle { - id: timerRect - height: 2 - width: pumpButton.width * 0.8 - visible: applyAnimation.running - anchors { - bottom: parent.bottom; bottomMargin: 5 - horizontalCenter: parent.horizontalCenter - } - } - - SequentialAnimation { - id: applyAnimation - alwaysRunToEnd: false - NumberAnimation { - target: timerRect - property: "width" - from: 0 - to: pumpButton.width * 0.8 - duration: 3000 - } - - ColorAnimation { - target: pumpButton - property: "color" - from: "#A8A8A8" - to: "#4789d0" - duration: 200 - } - - ColorAnimation { - target: pumpButton - property: "color" - from: "#4789d0" - to: "#A8A8A8" - duration: 200 - } - PropertyAction { - target: timerRect - property: "width" - value: 0 - } - // Do not set value if the animation is restarted by user pressing the button - // to move between options - onCompleted: if (!pumpButton.reset) pump.setValue(pumpButton.value) - } - DetailTarget { id: pumpButtonTarget; detailsPage: "" } - } - - // When new service is found add resources as appropriate - Connections { - target: DBusServices - onDbusServiceFound: addService(service) - } - - // hack to get value(s) from within a loop inside a function when service is changing - property string tempServiceName: "" - property VBusItem temperatureItem: VBusItem { bind: Utils.path(tempServiceName, "/Dc/0/Temperature") } - -//////// rewrite to use switch in place of if statements - function addService(service) - { - switch (service.type) - { -//////// add for temp sensors - case DBusService.DBUS_SERVICE_TEMPERATURE_SENSOR: - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - break;; - case DBusService.DBUS_SERVICE_MULTI: - root.tempServiceName = service.name - if (temperatureItem.valid) - { - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - } - break;; -//////// add for VE.Direct inverters - case DBusService.DBUS_SERVICE_INVERTER: - if (veDirectInverterService == "") - veDirectInverterService = service.name; - break;; - -//////// add for PV CHARGER voltage and current display - case DBusService.DBUS_SERVICE_SOLAR_CHARGER: - numberOfPvChargers++ - if (pvChargerPrefix === "") - pvChargerPrefix = service.name; - break;; - case DBusService.DBUS_SERVICE_BATTERY: - root.tempServiceName = service.name - if (temperatureItem.valid) - { - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - } - break;; - } - } - - // Check available services to find tank sesnsors -//////// rewrite to always call addService, removing redundant service type checks - function discoverServices() - { - numberOfTemps = 0 - numberOfPvChargers = 0 - veDirectInverterService = "" - tempsModel.clear() - for (var i = 0; i < DBusServices.count; i++) - addService(DBusServices.at(i)) - } - - function notificationText() - { - if (activeNotifications.length === 0) - return qsTr("") - - var descr = [] - for (var n = 0; n < activeNotifications.length; n++) { - var notification = activeNotifications[n]; - - var text = notification.serviceName + " - " + notification.description; - if (notification.value !== "" ) - text += ": " + notification.value - - descr.push(text) - } - - return descr.join(" | ") - } - - VBusItem { id: dmc; bind: Utils.path(inverterService, "/Devices/Dmc/Version") } - VBusItem { id: bms; bind: Utils.path(inverterService, "/Devices/Bms/Version") } - - -// Details targets -////// display detail targets and help message when first displayed. - Timer { - id: helpTimer - running: false - repeat: false - interval: 5000 - triggeredOnStart: true - } - - // help message shown when menu is first drawn - Rectangle - { - id: helpBox - color: "white" - width: 150 - height: 32 - opacity: 0.7 - anchors - { - horizontalCenter: infoArea.horizontalCenter - verticalCenter: infoArea.verticalCenter - } - visible: false - } - TileText - { - text: qsTr ( "Tap tile center for detail at any time" ) - color: "black" - anchors.fill: helpBox - wrapMode: Text.WordWrap - font.pixelSize: 12 - visible: helpBox.visible - } - - - //// hard key handler - // used to press buttons when touch isn't available - // UP and DOWN buttons cycle through the list of touch areas - // "space" button is used to simulate a touch on the area - // target must be highlighted so that other uses of "space" - // will still occur - - // list of all details touchable areas - // pump button sets value locally, no details page - // so is hanelded differently - // it must be LAST in the list because target list index is used for special processing - property variant targetList: - [ - multiTarget, batteryTarget, pvChargerTarget, dcSystemTarget, - acInputTarget, acLoadsOnOutputTarget, pumpButtonTarget // pump MUST BE LAST - ] - - property int selectedTarget: 0 - - Timer - { - id: targetTimer - interval: 5000 - repeat: false - running: false - onTriggered: { hideAllTargets () } - } - - Keys.forwardTo: [keyHandler] - Item - { - id: keyHandler - Keys.onUpPressed: - { - nextTarget (-1) - event.accepted = true - } - - Keys.onDownPressed: - { - nextTarget (+1) - event.accepted = true - } - Keys.onSpacePressed: - { - if (targetTimer.running) - { - var foo // hack to make clicked() work - if (selectedTarget == targetList.length - 1) - pumpButton.edit () - else - bar.clicked (foo) - event.accepted = true - } - else - event.accepted = false - } - } - // hack to make clicked() work - property variant bar: targetList[selectedTarget] - - function nextTarget (increment) - { - // make one pass through all possible targets to find an enabled one - // if found, that's the new selectedTarget, - // if not selectedTarget does not change - var newIndex = selectedTarget - for (var i = 0; i < targetList.length; i++) - { - if (( ! targetTimer.running || helpBox.visible) && targetList[newIndex].enabled) - { - highlightSelectedTarget () - return - } - newIndex += increment - if (newIndex >= targetList.length) - newIndex = 0 - else if (newIndex < 0) - newIndex = targetList.length - 1 - var includeTarget - if (newIndex == targetList.length - 1) - includeTarget = pumpButton.pumpEnabled - else - includeTarget = targetList[newIndex].enabled - if (includeTarget) - { - selectedTarget = newIndex - highlightSelectedTarget () - break - } - } - } - - function showHelp () - { - for (var i = 0; i < targetList.length; i++) - { - targetList[i].targetVisible = true - } - helpBox.visible = true - targetTimer.restart () - } - function hideAllTargets () - { - for (var i = 0; i < targetList.length; i++) - targetList[i].targetVisible = false - helpBox.visible = false - } - function highlightSelectedTarget () - { - for (var i = 0; i < targetList.length; i++) - { - if (targetList[i] == targetList[selectedTarget]) - targetList[i].targetVisible = true - else - targetList[i].targetVisible = false - } - targetTimer.restart () - helpBox.visible = false - } -} diff --git a/FileSets/v2.89/OverviewMobileEnhanced.qml.orig b/FileSets/v2.89/OverviewMobileEnhanced.qml.orig deleted file mode 100644 index 749e1439..00000000 --- a/FileSets/v2.89/OverviewMobileEnhanced.qml.orig +++ /dev/null @@ -1,637 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -OverviewPage { - id: root - - property variant sys: theSystem - property string settingsBindPreffix: "com.victronenergy.settings" - property string pumpBindPreffix: "com.victronenergy.pump.startstop0" - property variant activeNotifications: NotificationCenter.notifications.filter( - function isActive(obj) { return obj.active} ) - property string noAdjustableByDmc: qsTr("This setting is disabled when a Digital Multi Control " + - "is connected. If it was recently disconnected execute " + - "\"Redetect system\" that is available on the inverter menu page.") - property string noAdjustableByBms: qsTr("This setting is disabled when a VE.Bus BMS " + - "is connected. If it was recently disconnected execute " + - "\"Redetect system\" that is available on the inverter menu page.") - property string noAdjustableTextByConfig: qsTr("This setting is disabled. " + - "Possible reasons are \"Overruled by remote\" is not enabled or " + - "an assistant is preventing the adjustment. Please, check " + - "the inverter configuration with VEConfigure.") - property int numberOfMultis: 0 - property string vebusPrefix: "" - - // Keeps track of which button on the bottom row is active - property int buttonIndex: 0 - - title: qsTr("Mobile") - - Component.onCompleted: discoverMulti() - - ListView { - id: pwColumn - - property int tilesCount: solarTile.visible || dcSystem.visible ? 3 : 2 - property int tileHeight: Math.ceil(height / tilesCount) - interactive: false // static tiles - - width: 136 - anchors { - left: parent.left - top: parent.top; - bottom: acModeButton.top; - } - - model: VisualItemModel { - Tile { - width: pwColumn.width - height: visible ? pwColumn.tileHeight : 0 - title: qsTr("AC INPUT") - color: "#82acde" - visible: !dcSystem.visible || !solarTile.visible - values: [ - TileText { - text: sys.acInput.power.uiText - font.pixelSize: 30 - } - - ] - } - - TileAcPower { - width: pwColumn.width - height: visible ? pwColumn.tileHeight : 0 - title: qsTr("AC LOADS") - color: "#e68e8a" - values: [ - TileText { - text: sys.acLoad.power.uiText - font.pixelSize: 30 - } - ] - } - - Tile { - id: solarTile - width: pwColumn.width - height: visible ? pwColumn.tileHeight : 0 - title: qsTr("PV CHARGER") - color: "#2cc36b" - visible : sys.pvCharger.power.valid - - values: [ - TileText { - font.pixelSize: 30 - text: sys.pvCharger.power.uiText - } - ] - } - Tile { - id: dcSystem - width: pwColumn.width - height: visible ? pwColumn.tileHeight : 0 - title: qsTr("DC SYSTEM") - color: "#16a085" - visible: sys.dcSystem.power.valid - - values: [ - TileText { - font.pixelSize: 30 - text: sys.dcSystem.power.format(0) - }, - TileText { - text: !sys.dcSystem.power.valid ? "---" : - sys.dcSystem.power.value < 0 ? qsTr("to battery") : qsTr("from battery") - } - ] - } - } - } - - Tile { - id: logoTile - - color: "#575748" - height: 120 - anchors { - left: pwColumn.right - right: tanksColum.left - top: parent.top - } - - MbIcon { - x: 1 - y: 1 - // see below, so the svg instead of a png if there is a 1x1 image - visible: customImage.sourceSize.width === 1 && customImage.sourceSize.height === 1 - iconId: "mobile-builder-logo-svg" - } - - // The uploaded png, the default is a 1x1 transparent pixel now. - Image { - id: customImage - source: "image://theme/mobile-builder-logo" - anchors.centerIn: parent - } - } - - Tile { - id: batteryTile - height: 112 - title: qsTr("BATTERY") - anchors { - left: pwColumn.right - right: stateTile.left - top: logoTile.bottom - bottom: acModeButton.top - } - - values: [ - TileText { - text: sys.battery.soc.absFormat(0) - font.pixelSize: 30 - height: 32 - }, - TileText { - text: { - if (!sys.battery.state.valid) - return "---" - switch(sys.battery.state.value) { - case sys.batteryStateIdle: return qsTr("idle") - case sys.batteryStateCharging : return qsTr("charging") - case sys.batteryStateDischarging : return qsTr("discharging") - } - } - }, - TileText { - text: sys.battery.power.absFormat(0) - }, - TileText { - text: sys.battery.voltage.format(1) + " " + sys.battery.current.format(1) - } - ] - } - - Tile { - id: stateTile - - width: 104 - title: qsTr("STATUS") - color: "#4789d0" - - anchors { - right: tanksColum.left - top: logoTile.bottom - bottom: acModeButton.top - } - - Timer { - id: wallClock - - running: true - repeat: true - interval: 1000 - triggeredOnStart: true - onTriggered: time = Qt.formatDateTime(new Date(), "hh:mm") - - property string time - } - - values: [ - TileText { - id: systemTile - text: wallClock.time - font.pixelSize: 30 - }, - TileText { - property VeQuickItem gpsService: VeQuickItem { uid: "dbus/com.victronenergy.system/GpsService" } - property VeQuickItem speed: VeQuickItem { uid: Utils.path("dbus/", gpsService.value, "/Speed") } - property VeQuickItem speedUnit: VeQuickItem { uid: "dbus/com.victronenergy.settings/Settings/Gps/SpeedUnit" } - - text: speed.value === undefined ? "" : getValue() - visible: speed.value !== undefined && speedUnit.value !== undefined - - function getValue() - { - if (speedUnit.value === "km/h") - return (speed.value * 3.6).toFixed(1) + speedUnit.value - if (speedUnit.value === "mph") - return (speed.value * 2.236936).toFixed(1) + speedUnit.value - if (speedUnit.value === "kt") - return (speed.value * (3600/1852)).toFixed(1) + speedUnit.value - return speed.value.toFixed(2) + "m/s" - } - }, - Marquee { - text: notificationText() - width: stateTile.width - interval: 100 - fontSize: 13 - } - ] - } - - ListView { - id: tanksColum - - property int tileHeight: Math.ceil(height / Math.max(count, 2)) - width: 134 - interactive: false // static tiles - model: TankModel { id: tankModel } - delegate: TileTank { - // Without an intermediate assignment this will trigger a binding loop warning. - property variant theService: DBusServices.get(buddy.id) - service: theService - width: tanksColum.width - height: tanksColum.tileHeight - pumpBindPrefix: root.pumpBindPreffix - compact: tankModel.rowCount > (pumpButton.pumpEnabled ? 4 : 5) - Connections { - target: scrollTimer - onTriggered: doScroll() - } - } - - anchors { - top: root.top - bottom: pumpButton.pumpEnabled ? acModeButton.top : acModeButton.bottom - right: root.right - } - - // Synchronise tank name text scroll start - Timer { - id: scrollTimer - interval: 15000 - repeat: true - running: root.active && tankModel.rowCount > 4 - } - - Tile { - title: qsTr("TANKS") - anchors.fill: parent - values: TileText { - text: qsTr("No tanks found") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - - Keys.forwardTo: [keyHandler] - - Item { - id: keyHandler - Keys.onLeftPressed: { - if (buttonIndex > 0) - buttonIndex-- - - event.accepted = true - } - - Keys.onRightPressed: { - if (buttonIndex < (pumpButton.pumpEnabled ? 2 : 1)) - buttonIndex++ - - event.accepted = true - } - } - - MouseArea { - anchors.fill: parent - enabled: parent.active - onPressed: mouse.accepted = acCurrentButton.expanded - onClicked: acCurrentButton.cancel() - } - - TileSpinBox { - id: acCurrentButton - - anchors.bottom: parent.bottom - anchors.left: parent.left - isCurrentItem: (buttonIndex == 0) - focus: root.active && isCurrentItem - - bind: Utils.path(vebusPrefix, "/Ac/ActiveIn/CurrentLimit") - title: qsTr("AC CURRENT LIMIT") - color: containsMouse && !editMode ? "#d3d3d3" : "#A8A8A8" - width: pumpButton.pumpEnabled ? 160 : 173 - fontPixelSize: 14 - unit: "A" - readOnly: currentLimitIsAdjustable.value !== 1 || numberOfMultis > 1 - buttonColor: "#979797" - - VBusItem { id: currentLimitIsAdjustable; bind: Utils.path(vebusPrefix, "/Ac/ActiveIn/CurrentLimitIsAdjustable") } - - Keys.onSpacePressed: showErrorToast(event) - - function editIsAllowed() { - if (numberOfMultis > 1) { - toast.createToast(qsTr("It is not possible to change this setting when there are more than one inverter connected."), 5000) - return false - } - - if (currentLimitIsAdjustable.value === 0) { - if (dmc.valid) { - toast.createToast(noAdjustableByDmc, 5000) - return false - } - if (bms.valid) { - toast.createToast(noAdjustableByBms, 5000) - return false - } - if (!dmc.valid && !bms.valid) { - toast.createToast(noAdjustableTextByConfig, 5000) - return false - } - } - - return true - } - - function showErrorToast(event) { - editIsAllowed() - event.accepted = true - } - } - - Tile { - id: acModeButton - anchors.left: acCurrentButton.right - anchors.bottom: parent.bottom - property variant texts: { 4: qsTr("OFF"), 3: qsTr("ON"), 1: qsTr("CHARGER ONLY") } - property int value: mode.valid ? mode.value : 3 - property int shownValue: applyAnimation2.running ? applyAnimation2.pendingValue : value - - isCurrentItem: (buttonIndex == 1) - focus: root.active && isCurrentItem - - editable: true - readOnly: !modeIsAdjustable.valid || modeIsAdjustable.value !== 1 || numberOfMultis > 1 - width: pumpButton.pumpEnabled ? 160 : 173 - height: 45 - color: acModeButtonMouseArea.containsPressed ? "#d3d3d3" : "#A8A8A8" - title: qsTr("AC MODE") - - values: [ - TileText { - text: modeIsAdjustable.valid && numberOfMultis === 1 ? qsTr("%1").arg(acModeButton.texts[acModeButton.shownValue]) : qsTr("NOT AVAILABLE") - } - ] - - VBusItem { id: mode; bind: Utils.path(vebusPrefix, "/Mode") } - VBusItem { id: modeIsAdjustable; bind: Utils.path(vebusPrefix,"/ModeIsAdjustable") } - - Keys.onSpacePressed: edit() - - function edit() { - if (!mode.valid) - return - - if (numberOfMultis > 1) { - toast.createToast(qsTr("It is not possible to change this setting when there are more than one inverter connected."), 5000) - return - } - - if (modeIsAdjustable.value === 0) { - if (dmc.valid) - toast.createToast(noAdjustableByDmc, 5000) - if (bms.valid) - toast.createToast(noAdjustableByBms, 5000) - if (!dmc.valid && !bms.valid) - toast.createToast(noAdjustableTextByConfig, 5000) - return - } - - switch (shownValue) { - case 4: - applyAnimation2.pendingValue = 3 - break; - case 3: - applyAnimation2.pendingValue = 1 - break; - case 1: - applyAnimation2.pendingValue = 4 - break; - } - - applyAnimation2.restart() - } - - MouseArea { - id: acModeButtonMouseArea - anchors.fill: parent - property bool containsPressed: containsMouse && pressed - onClicked: { - buttonIndex = 1 - parent.edit() - } - } - - Rectangle { - id: timerRect2 - height: 2 - width: acModeButton.width * 0.8 - visible: applyAnimation2.running - anchors { - bottom: parent.bottom; bottomMargin: 5 - horizontalCenter: parent.horizontalCenter - } - } - - SequentialAnimation { - id: applyAnimation2 - - property int pendingValue - - NumberAnimation { - target: timerRect2 - property: "width" - from: 0 - to: acModeButton.width * 0.8 - duration: 3000 - } - - ColorAnimation { - target: acModeButton - property: "color" - from: "#A8A8A8" - to: "#4789d0" - duration: 200 - } - - ColorAnimation { - target: acModeButton - property: "color" - from: "#4789d0" - to: "#A8A8A8" - duration: 200 - } - PropertyAction { - target: timerRect2 - property: "width" - value: 0 - } - - ScriptAction { script: mode.setValue(applyAnimation2.pendingValue) } - - PauseAnimation { duration: 1000 } - } - } - - Tile { - id: pumpButton - - anchors.left: acModeButton.right - anchors.bottom: parent.bottom - - property variant texts: [ qsTr("AUTO"), qsTr("ON"), qsTr("OFF")] - property int value: 0 - property bool reset: false - property bool pumpEnabled: pumpRelay.value === 3 - - show: pumpEnabled - isCurrentItem: (buttonIndex == 2) - focus: root.active && isCurrentItem - - title: qsTr("PUMP") - width: show ? 160 : 0 - height: 45 - editable: true - readOnly: false - color: pumpButtonMouseArea.containsPressed ? "#d3d3d3" : "#A8A8A8" - - VBusItem { id: pump; bind: Utils.path(settingsBindPreffix, "/Settings/Pump0/Mode") } - VBusItem { id: pumpRelay; bind: Utils.path(settingsBindPreffix, "/Settings/Relay/Function") } - - values: [ - TileText { - text: pumpButton.pumpEnabled ? qsTr("%1").arg(pumpButton.texts[pumpButton.value]) : qsTr("DISABLED") - } - ] - - Keys.onSpacePressed: edit() - - function edit() { - if (!pumpEnabled) { - toast.createToast(qsTr("Pump functionality is not enabled. To enable it go to the relay settings page and set function to \"Tank pump\""), 5000) - return - } - - reset = true - applyAnimation.restart() - reset = false - - if (value < 2) - value++ - else - value = 0 - } - - MouseArea { - id: pumpButtonMouseArea - property bool containsPressed: containsMouse && pressed - anchors.fill: parent - onClicked: { - buttonIndex = 2 - parent.edit() - } - } - - Rectangle { - id: timerRect - height: 2 - width: pumpButton.width * 0.8 - visible: applyAnimation.running - anchors { - bottom: parent.bottom; bottomMargin: 5 - horizontalCenter: parent.horizontalCenter - } - } - - SequentialAnimation { - id: applyAnimation - alwaysRunToEnd: false - NumberAnimation { - target: timerRect - property: "width" - from: 0 - to: pumpButton.width * 0.8 - duration: 3000 - } - - ColorAnimation { - target: pumpButton - property: "color" - from: "#A8A8A8" - to: "#4789d0" - duration: 200 - } - - ColorAnimation { - target: pumpButton - property: "color" - from: "#4789d0" - to: "#A8A8A8" - duration: 200 - } - PropertyAction { - target: timerRect - property: "width" - value: 0 - } - // Do not set value if the animation is restarted by user pressing the button - // to move between options - onCompleted: if (!pumpButton.reset) pump.setValue(pumpButton.value) - } - } - - // When new service is found check if is a tank sensor - Connections { - target: DBusServices - onDbusServiceFound: addService(service) - } - - function addService(service) - { - if (service.type === DBusService.DBUS_SERVICE_MULTI) { - numberOfMultis++ - if (vebusPrefix === "") - vebusPrefix = service.name; - } - } - - // Check available services to find tank sesnsors - function discoverMulti() - { - for (var i = 0; i < DBusServices.count; i++) { - if (DBusServices.at(i).type === DBusService.DBUS_SERVICE_MULTI) { - addService(DBusServices.at(i)) - } - } - } - - function notificationText() - { - if (activeNotifications.length === 0) - return qsTr("no alarms") - - var descr = [] - for (var n = 0; n < activeNotifications.length; n++) { - var notification = activeNotifications[n]; - - var text = notification.serviceName + " - " + notification.description; - if (notification.value !== "" ) - text += ": " + notification.value - - descr.push(text) - } - - return descr.join(" | ") - } - - VBusItem { id: dmc; bind: Utils.path(vebusPrefix, "/Devices/Dmc/Version") } - VBusItem { id: bms; bind: Utils.path(vebusPrefix, "/Devices/Bms/Version") } -} diff --git a/FileSets/v2.89/OverviewSolarCharger.qml b/FileSets/v2.89/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v2.89/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.89/OverviewSolarInverter.qml b/FileSets/v2.89/OverviewSolarInverter.qml deleted file mode 120000 index 7cea58a2..00000000 --- a/FileSets/v2.89/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v2.89/OverviewTankDelegate.qml b/FileSets/v2.89/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v2.89/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.89/OverviewTanks.qml b/FileSets/v2.89/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v2.89/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.89/OverviewTanksTempsDigInputs.qml b/FileSets/v2.89/OverviewTanksTempsDigInputs.qml deleted file mode 100644 index 616d3b12..00000000 --- a/FileSets/v2.89/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1,208 +0,0 @@ -//// New overview page for tanks, temps and digital inputs -//// part of GuiMods -//// based on tank/temps column in mobile overview - -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils -import "timeToGo.js" as TTG - -OverviewPage { - title: qsTr("Tanks & Temps & Digital Inputs") - id: root - - property variant sys: theSystem - property string systemPrefix: "com.victronenergy.system" - property string settingsBindPreffix: "com.victronenergy.settings" - property string pumpBindPreffix: "com.victronenergy.pump.startstop0" - - property int numberOfTanks: tankModel.rowCount - property real tanksHeight: root.height - property real minTankHeight: 21 // use for temps also - property real maxTankHeight: 80 // use for temps also - property real tankTileHeight: Math.min (Math.max (tanksHeight / numberOfTanks, minTankHeight), maxTankHeight) - property bool tanksCompact: numberOfTanks > 6 - - property int numberOfTemps: 0 - property real tempsHeight: root.height - property real tempsTileHeight: Math.min (Math.max (tempsHeight / numberOfTemps, minTankHeight), maxTankHeight) - property bool tempsCompact: numberOfTemps > 6 - - property int tankWidth: parent.width / 3 - property int tempsWidth: tankWidth - property int digInWidth: tankWidth - - property int numberOfDigIn: 0 - property real digInHeight: root.height - property real digInTileHeight: Math.min (Math.max (digInHeight / numberOfDigIn, minTankHeight), maxTankHeight) - - Component.onCompleted: { discoverServices() } - - // Synchronise name text scroll start - Timer { - id: scrollTimer - interval: 15000 - repeat: true - running: root.active - } - - ListView { - id: tanksColum - - anchors { - top: root.top - left: root.left - } - height: root.tanksHeight - width: root.tankWidth - interactive: root.tankTileHeight * count > (tanksColum.height + 1) ? true : false - - model: TankModel { id: tankModel } - delegate: TileTankEnhanced { - // Without an intermediate assignment this will trigger a binding loop warning. - property variant theService: DBusServices.get(buddy.id) - service: theService - width: tanksColum.width - height: root.tankTileHeight - pumpBindPrefix: root.pumpBindPreffix - compact: root.tanksCompact - Connections - { - target: scrollTimer - onTriggered: doScroll() - } - } - Tile { - title: numberOfTanks == 0 ? qsTr ("no tanks") : qsTr("Tanks") - anchors.fill: parent - color: "#b3b3b3" - values: TileText { - text: qsTr("") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - - ListView { - id: tempsColumn - - anchors { - top: root.top - left: tanksColum.right - } - height: root.tempsHeight - width: root.tempsWidth - // make list flickable if more tiles than will fit completely - interactive: root.tankTileHeight * count > (tempsColumn.height + 1) ? true : false - - model: tempsModel - delegate: TileTemp - { - width: tempsColumn.width - height: root.tempsTileHeight - compact: root.tempsCompact - Connections - { - target: scrollTimer - onTriggered: doScroll() - } - } - Tile - { - title: numberOfTemps == 0 ? qsTr ("no temps") : qsTr("Temps") - anchors.fill: parent - color: "#b3b3b3" - values: TileText - { - text: qsTr("") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - ListModel { id: tempsModel } - - ListView { - id: digInputsColumn - - anchors { - top: root.top - right: root.right - } - height: root.digInHeight - width: root.digInWidth - // make list flickable if more tiles than will fit completely - interactive: root.digInTileHeight * count > (digInputsColumn.height + 1) ? true : false - - model: digInModel - delegate: TileDigIn - { - width: digInputsColumn.width - height: root.digInTileHeight - } - Tile - { - title: numberOfDigIn == 0 ? qsTr ("no digital inputs") : qsTr("Digital Inputs") - anchors.fill: parent - color: "#b3b3b3" - values: TileText - { - text: qsTr("") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - ListModel { id: digInModel } - - - // When new service is found add resources as appropriate - Connections { - target: DBusServices - onDbusServiceFound: addService(service) - } - - // hack to get value(s) from within a loop inside a function when service is changing - property string tempServiceName: "" - property VBusItem temperatureItem: VBusItem { bind: Utils.path(tempServiceName, "/Dc/0/Temperature") } - - function addService(service) - { - switch (service.type) - { - case DBusService.DBUS_SERVICE_TEMPERATURE_SENSOR: - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - break;; - case DBusService.DBUS_SERVICE_DIGITAL_INPUT: - case DBusService.DBUS_SERVICE_PULSE_COUNTER: - numberOfDigIn++ - digInModel.append({serviceName: service.name}) - break;; - case DBusService.DBUS_SERVICE_BATTERY: - case DBusService.DBUS_SERVICE_MULTI: - root.tempServiceName = service.name - if (temperatureItem.valid) - { - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - } - break;; - } - } - - // Check available services to find tank sesnsors - function discoverServices() - { - numberOfTemps = 0 - tempsModel.clear() - numberOfDigIn = 0 - digInModel.clear() - for (var i = 0; i < DBusServices.count; i++) - addService(DBusServices.at(i)) - } -} diff --git a/FileSets/v2.89/OverviewTanksTempsDigInputs.qml.orig b/FileSets/v2.89/OverviewTanksTempsDigInputs.qml.orig deleted file mode 100644 index 749e1439..00000000 --- a/FileSets/v2.89/OverviewTanksTempsDigInputs.qml.orig +++ /dev/null @@ -1,637 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -OverviewPage { - id: root - - property variant sys: theSystem - property string settingsBindPreffix: "com.victronenergy.settings" - property string pumpBindPreffix: "com.victronenergy.pump.startstop0" - property variant activeNotifications: NotificationCenter.notifications.filter( - function isActive(obj) { return obj.active} ) - property string noAdjustableByDmc: qsTr("This setting is disabled when a Digital Multi Control " + - "is connected. If it was recently disconnected execute " + - "\"Redetect system\" that is available on the inverter menu page.") - property string noAdjustableByBms: qsTr("This setting is disabled when a VE.Bus BMS " + - "is connected. If it was recently disconnected execute " + - "\"Redetect system\" that is available on the inverter menu page.") - property string noAdjustableTextByConfig: qsTr("This setting is disabled. " + - "Possible reasons are \"Overruled by remote\" is not enabled or " + - "an assistant is preventing the adjustment. Please, check " + - "the inverter configuration with VEConfigure.") - property int numberOfMultis: 0 - property string vebusPrefix: "" - - // Keeps track of which button on the bottom row is active - property int buttonIndex: 0 - - title: qsTr("Mobile") - - Component.onCompleted: discoverMulti() - - ListView { - id: pwColumn - - property int tilesCount: solarTile.visible || dcSystem.visible ? 3 : 2 - property int tileHeight: Math.ceil(height / tilesCount) - interactive: false // static tiles - - width: 136 - anchors { - left: parent.left - top: parent.top; - bottom: acModeButton.top; - } - - model: VisualItemModel { - Tile { - width: pwColumn.width - height: visible ? pwColumn.tileHeight : 0 - title: qsTr("AC INPUT") - color: "#82acde" - visible: !dcSystem.visible || !solarTile.visible - values: [ - TileText { - text: sys.acInput.power.uiText - font.pixelSize: 30 - } - - ] - } - - TileAcPower { - width: pwColumn.width - height: visible ? pwColumn.tileHeight : 0 - title: qsTr("AC LOADS") - color: "#e68e8a" - values: [ - TileText { - text: sys.acLoad.power.uiText - font.pixelSize: 30 - } - ] - } - - Tile { - id: solarTile - width: pwColumn.width - height: visible ? pwColumn.tileHeight : 0 - title: qsTr("PV CHARGER") - color: "#2cc36b" - visible : sys.pvCharger.power.valid - - values: [ - TileText { - font.pixelSize: 30 - text: sys.pvCharger.power.uiText - } - ] - } - Tile { - id: dcSystem - width: pwColumn.width - height: visible ? pwColumn.tileHeight : 0 - title: qsTr("DC SYSTEM") - color: "#16a085" - visible: sys.dcSystem.power.valid - - values: [ - TileText { - font.pixelSize: 30 - text: sys.dcSystem.power.format(0) - }, - TileText { - text: !sys.dcSystem.power.valid ? "---" : - sys.dcSystem.power.value < 0 ? qsTr("to battery") : qsTr("from battery") - } - ] - } - } - } - - Tile { - id: logoTile - - color: "#575748" - height: 120 - anchors { - left: pwColumn.right - right: tanksColum.left - top: parent.top - } - - MbIcon { - x: 1 - y: 1 - // see below, so the svg instead of a png if there is a 1x1 image - visible: customImage.sourceSize.width === 1 && customImage.sourceSize.height === 1 - iconId: "mobile-builder-logo-svg" - } - - // The uploaded png, the default is a 1x1 transparent pixel now. - Image { - id: customImage - source: "image://theme/mobile-builder-logo" - anchors.centerIn: parent - } - } - - Tile { - id: batteryTile - height: 112 - title: qsTr("BATTERY") - anchors { - left: pwColumn.right - right: stateTile.left - top: logoTile.bottom - bottom: acModeButton.top - } - - values: [ - TileText { - text: sys.battery.soc.absFormat(0) - font.pixelSize: 30 - height: 32 - }, - TileText { - text: { - if (!sys.battery.state.valid) - return "---" - switch(sys.battery.state.value) { - case sys.batteryStateIdle: return qsTr("idle") - case sys.batteryStateCharging : return qsTr("charging") - case sys.batteryStateDischarging : return qsTr("discharging") - } - } - }, - TileText { - text: sys.battery.power.absFormat(0) - }, - TileText { - text: sys.battery.voltage.format(1) + " " + sys.battery.current.format(1) - } - ] - } - - Tile { - id: stateTile - - width: 104 - title: qsTr("STATUS") - color: "#4789d0" - - anchors { - right: tanksColum.left - top: logoTile.bottom - bottom: acModeButton.top - } - - Timer { - id: wallClock - - running: true - repeat: true - interval: 1000 - triggeredOnStart: true - onTriggered: time = Qt.formatDateTime(new Date(), "hh:mm") - - property string time - } - - values: [ - TileText { - id: systemTile - text: wallClock.time - font.pixelSize: 30 - }, - TileText { - property VeQuickItem gpsService: VeQuickItem { uid: "dbus/com.victronenergy.system/GpsService" } - property VeQuickItem speed: VeQuickItem { uid: Utils.path("dbus/", gpsService.value, "/Speed") } - property VeQuickItem speedUnit: VeQuickItem { uid: "dbus/com.victronenergy.settings/Settings/Gps/SpeedUnit" } - - text: speed.value === undefined ? "" : getValue() - visible: speed.value !== undefined && speedUnit.value !== undefined - - function getValue() - { - if (speedUnit.value === "km/h") - return (speed.value * 3.6).toFixed(1) + speedUnit.value - if (speedUnit.value === "mph") - return (speed.value * 2.236936).toFixed(1) + speedUnit.value - if (speedUnit.value === "kt") - return (speed.value * (3600/1852)).toFixed(1) + speedUnit.value - return speed.value.toFixed(2) + "m/s" - } - }, - Marquee { - text: notificationText() - width: stateTile.width - interval: 100 - fontSize: 13 - } - ] - } - - ListView { - id: tanksColum - - property int tileHeight: Math.ceil(height / Math.max(count, 2)) - width: 134 - interactive: false // static tiles - model: TankModel { id: tankModel } - delegate: TileTank { - // Without an intermediate assignment this will trigger a binding loop warning. - property variant theService: DBusServices.get(buddy.id) - service: theService - width: tanksColum.width - height: tanksColum.tileHeight - pumpBindPrefix: root.pumpBindPreffix - compact: tankModel.rowCount > (pumpButton.pumpEnabled ? 4 : 5) - Connections { - target: scrollTimer - onTriggered: doScroll() - } - } - - anchors { - top: root.top - bottom: pumpButton.pumpEnabled ? acModeButton.top : acModeButton.bottom - right: root.right - } - - // Synchronise tank name text scroll start - Timer { - id: scrollTimer - interval: 15000 - repeat: true - running: root.active && tankModel.rowCount > 4 - } - - Tile { - title: qsTr("TANKS") - anchors.fill: parent - values: TileText { - text: qsTr("No tanks found") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - - Keys.forwardTo: [keyHandler] - - Item { - id: keyHandler - Keys.onLeftPressed: { - if (buttonIndex > 0) - buttonIndex-- - - event.accepted = true - } - - Keys.onRightPressed: { - if (buttonIndex < (pumpButton.pumpEnabled ? 2 : 1)) - buttonIndex++ - - event.accepted = true - } - } - - MouseArea { - anchors.fill: parent - enabled: parent.active - onPressed: mouse.accepted = acCurrentButton.expanded - onClicked: acCurrentButton.cancel() - } - - TileSpinBox { - id: acCurrentButton - - anchors.bottom: parent.bottom - anchors.left: parent.left - isCurrentItem: (buttonIndex == 0) - focus: root.active && isCurrentItem - - bind: Utils.path(vebusPrefix, "/Ac/ActiveIn/CurrentLimit") - title: qsTr("AC CURRENT LIMIT") - color: containsMouse && !editMode ? "#d3d3d3" : "#A8A8A8" - width: pumpButton.pumpEnabled ? 160 : 173 - fontPixelSize: 14 - unit: "A" - readOnly: currentLimitIsAdjustable.value !== 1 || numberOfMultis > 1 - buttonColor: "#979797" - - VBusItem { id: currentLimitIsAdjustable; bind: Utils.path(vebusPrefix, "/Ac/ActiveIn/CurrentLimitIsAdjustable") } - - Keys.onSpacePressed: showErrorToast(event) - - function editIsAllowed() { - if (numberOfMultis > 1) { - toast.createToast(qsTr("It is not possible to change this setting when there are more than one inverter connected."), 5000) - return false - } - - if (currentLimitIsAdjustable.value === 0) { - if (dmc.valid) { - toast.createToast(noAdjustableByDmc, 5000) - return false - } - if (bms.valid) { - toast.createToast(noAdjustableByBms, 5000) - return false - } - if (!dmc.valid && !bms.valid) { - toast.createToast(noAdjustableTextByConfig, 5000) - return false - } - } - - return true - } - - function showErrorToast(event) { - editIsAllowed() - event.accepted = true - } - } - - Tile { - id: acModeButton - anchors.left: acCurrentButton.right - anchors.bottom: parent.bottom - property variant texts: { 4: qsTr("OFF"), 3: qsTr("ON"), 1: qsTr("CHARGER ONLY") } - property int value: mode.valid ? mode.value : 3 - property int shownValue: applyAnimation2.running ? applyAnimation2.pendingValue : value - - isCurrentItem: (buttonIndex == 1) - focus: root.active && isCurrentItem - - editable: true - readOnly: !modeIsAdjustable.valid || modeIsAdjustable.value !== 1 || numberOfMultis > 1 - width: pumpButton.pumpEnabled ? 160 : 173 - height: 45 - color: acModeButtonMouseArea.containsPressed ? "#d3d3d3" : "#A8A8A8" - title: qsTr("AC MODE") - - values: [ - TileText { - text: modeIsAdjustable.valid && numberOfMultis === 1 ? qsTr("%1").arg(acModeButton.texts[acModeButton.shownValue]) : qsTr("NOT AVAILABLE") - } - ] - - VBusItem { id: mode; bind: Utils.path(vebusPrefix, "/Mode") } - VBusItem { id: modeIsAdjustable; bind: Utils.path(vebusPrefix,"/ModeIsAdjustable") } - - Keys.onSpacePressed: edit() - - function edit() { - if (!mode.valid) - return - - if (numberOfMultis > 1) { - toast.createToast(qsTr("It is not possible to change this setting when there are more than one inverter connected."), 5000) - return - } - - if (modeIsAdjustable.value === 0) { - if (dmc.valid) - toast.createToast(noAdjustableByDmc, 5000) - if (bms.valid) - toast.createToast(noAdjustableByBms, 5000) - if (!dmc.valid && !bms.valid) - toast.createToast(noAdjustableTextByConfig, 5000) - return - } - - switch (shownValue) { - case 4: - applyAnimation2.pendingValue = 3 - break; - case 3: - applyAnimation2.pendingValue = 1 - break; - case 1: - applyAnimation2.pendingValue = 4 - break; - } - - applyAnimation2.restart() - } - - MouseArea { - id: acModeButtonMouseArea - anchors.fill: parent - property bool containsPressed: containsMouse && pressed - onClicked: { - buttonIndex = 1 - parent.edit() - } - } - - Rectangle { - id: timerRect2 - height: 2 - width: acModeButton.width * 0.8 - visible: applyAnimation2.running - anchors { - bottom: parent.bottom; bottomMargin: 5 - horizontalCenter: parent.horizontalCenter - } - } - - SequentialAnimation { - id: applyAnimation2 - - property int pendingValue - - NumberAnimation { - target: timerRect2 - property: "width" - from: 0 - to: acModeButton.width * 0.8 - duration: 3000 - } - - ColorAnimation { - target: acModeButton - property: "color" - from: "#A8A8A8" - to: "#4789d0" - duration: 200 - } - - ColorAnimation { - target: acModeButton - property: "color" - from: "#4789d0" - to: "#A8A8A8" - duration: 200 - } - PropertyAction { - target: timerRect2 - property: "width" - value: 0 - } - - ScriptAction { script: mode.setValue(applyAnimation2.pendingValue) } - - PauseAnimation { duration: 1000 } - } - } - - Tile { - id: pumpButton - - anchors.left: acModeButton.right - anchors.bottom: parent.bottom - - property variant texts: [ qsTr("AUTO"), qsTr("ON"), qsTr("OFF")] - property int value: 0 - property bool reset: false - property bool pumpEnabled: pumpRelay.value === 3 - - show: pumpEnabled - isCurrentItem: (buttonIndex == 2) - focus: root.active && isCurrentItem - - title: qsTr("PUMP") - width: show ? 160 : 0 - height: 45 - editable: true - readOnly: false - color: pumpButtonMouseArea.containsPressed ? "#d3d3d3" : "#A8A8A8" - - VBusItem { id: pump; bind: Utils.path(settingsBindPreffix, "/Settings/Pump0/Mode") } - VBusItem { id: pumpRelay; bind: Utils.path(settingsBindPreffix, "/Settings/Relay/Function") } - - values: [ - TileText { - text: pumpButton.pumpEnabled ? qsTr("%1").arg(pumpButton.texts[pumpButton.value]) : qsTr("DISABLED") - } - ] - - Keys.onSpacePressed: edit() - - function edit() { - if (!pumpEnabled) { - toast.createToast(qsTr("Pump functionality is not enabled. To enable it go to the relay settings page and set function to \"Tank pump\""), 5000) - return - } - - reset = true - applyAnimation.restart() - reset = false - - if (value < 2) - value++ - else - value = 0 - } - - MouseArea { - id: pumpButtonMouseArea - property bool containsPressed: containsMouse && pressed - anchors.fill: parent - onClicked: { - buttonIndex = 2 - parent.edit() - } - } - - Rectangle { - id: timerRect - height: 2 - width: pumpButton.width * 0.8 - visible: applyAnimation.running - anchors { - bottom: parent.bottom; bottomMargin: 5 - horizontalCenter: parent.horizontalCenter - } - } - - SequentialAnimation { - id: applyAnimation - alwaysRunToEnd: false - NumberAnimation { - target: timerRect - property: "width" - from: 0 - to: pumpButton.width * 0.8 - duration: 3000 - } - - ColorAnimation { - target: pumpButton - property: "color" - from: "#A8A8A8" - to: "#4789d0" - duration: 200 - } - - ColorAnimation { - target: pumpButton - property: "color" - from: "#4789d0" - to: "#A8A8A8" - duration: 200 - } - PropertyAction { - target: timerRect - property: "width" - value: 0 - } - // Do not set value if the animation is restarted by user pressing the button - // to move between options - onCompleted: if (!pumpButton.reset) pump.setValue(pumpButton.value) - } - } - - // When new service is found check if is a tank sensor - Connections { - target: DBusServices - onDbusServiceFound: addService(service) - } - - function addService(service) - { - if (service.type === DBusService.DBUS_SERVICE_MULTI) { - numberOfMultis++ - if (vebusPrefix === "") - vebusPrefix = service.name; - } - } - - // Check available services to find tank sesnsors - function discoverMulti() - { - for (var i = 0; i < DBusServices.count; i++) { - if (DBusServices.at(i).type === DBusService.DBUS_SERVICE_MULTI) { - addService(DBusServices.at(i)) - } - } - } - - function notificationText() - { - if (activeNotifications.length === 0) - return qsTr("no alarms") - - var descr = [] - for (var n = 0; n < activeNotifications.length; n++) { - var notification = activeNotifications[n]; - - var text = notification.serviceName + " - " + notification.description; - if (notification.value !== "" ) - text += ": " + notification.value - - descr.push(text) - } - - return descr.join(" | ") - } - - VBusItem { id: dmc; bind: Utils.path(vebusPrefix, "/Devices/Dmc/Version") } - VBusItem { id: bms; bind: Utils.path(vebusPrefix, "/Devices/Bms/Version") } -} diff --git a/FileSets/v2.89/PageDigitalInput.qml b/FileSets/v2.89/PageDigitalInput.qml deleted file mode 120000 index 839f7874..00000000 --- a/FileSets/v2.89/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.89/PageGenerator.qml b/FileSets/v2.89/PageGenerator.qml deleted file mode 120000 index cae51ecb..00000000 --- a/FileSets/v2.89/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.89/PageSettingsGenerator.qml b/FileSets/v2.89/PageSettingsGenerator.qml deleted file mode 100644 index 02f8dda0..00000000 --- a/FileSets/v2.89/PageSettingsGenerator.qml +++ /dev/null @@ -1,189 +0,0 @@ -//// GuiMods -//// addd service interval and reset -//// added link to external state enable - -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: root - title: qsTr("Generator start/stop settings") - property string settingsBindPrefix - property string startStopBindPrefix - - model: VisualItemModel { - - MbSubMenu { - id: conditions - description: qsTr("Conditions") - subpage: - Component { - PageGeneratorConditions { - title: qsTr("Conditions") - bindPrefix: root.settingsBindPrefix - } - } - } - - MbSpinBox { - description: qsTr("Minimum run time") - bind: Utils.path(settingsBindPrefix, "/MinimumRuntime") - unit: "m" - numOfDecimals: 0 - stepSize: 1 - } - - MbSwitch { -//// GuiMods - id: detectGeneratorAtAcIn - property bool generatorIsSet: acIn1Source.value === 2 || acIn2Source.value === 2 - name: qsTr("Detect generator at AC input") - bind: Utils.path(settingsBindPrefix, "/Alarms/NoGeneratorAtAcIn") - enabled: valid && (generatorIsSet || checked) - onClicked: { - if (!checked) { - if (!generatorIsSet) { - toast.createToast(qsTr("None of the AC inputs is set to generator. Go to the system setup page and set the correct " + - "AC input to generator in order to enable this functionality."), 10000, "icon-info-active") - } else { - toast.createToast(qsTr("An alarm will be triggered when no power from the generator is detected at the inverter AC input. " + - "Make sure that the correct AC input is set to generator on the system setup page."), 12000, "icon-info-active") - } - } - } - - VBusItem { - id: acIn1Source - bind: "com.victronenergy.settings/Settings/SystemSetup/AcInput1" - } - - VBusItem { - id: acIn2Source - bind: "com.victronenergy.settings/Settings/SystemSetup/AcInput2" - } - } - -//// GuiMods - MbSwitch { - name: qsTr("Link to external running state") - bind: Utils.path(settingsBindPrefix, "/LinkToExternalStatus") - onClicked: - { - if (!checked) - toast.createToast(qsTr("Manual run will be synchronized with the generaror 'is running digital input' or AC input"), 10000, "icon-info-active") - } - } - - MbSwitch { - id: timeZones - name: qsTr("Quiet hours") - bind: Utils.path(settingsBindPrefix, "/QuietHours/Enabled") - enabled: valid - writeAccessLevel: User.AccessUser - } - - MbEditBoxTime { - description: qsTr("Quiet hours start time") - item.bind: Utils.path(settingsBindPrefix, "/QuietHours/StartTime") - show: timeZones.checked - writeAccessLevel: User.AccessUser - } - - MbEditBoxTime { - description: qsTr("Quiet hours end time") - item.bind: Utils.path(settingsBindPrefix, "/QuietHours/EndTime") - show: timeZones.checked - writeAccessLevel: User.AccessUser - } - - MbOK { - description: qsTr("Reset daily run time counters") - value: qsTr("Press to reset") - enabled: true - editable: enabled - onClicked: { - if (state.value === 0) { - var now = new Date() - var today = new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate())) - var todayInSeconds = today.getTime() / 1000 - resetDaily.setValue('{"%1" : 0}'.arg(todayInSeconds.toString())) - toast.createToast(qsTr("The daily runtime counter has been reset")) - } else if (state.value === 1) { - toast.createToast(qsTr("It is not possible to modify the counters while the generator is running")) - } - } - - VBusItem { - id: resetDaily - bind: Utils.path(settingsBindPrefix, "/AccumulatedDaily") - } - } - - MbEditBox { - id: setTotalRunTime - description: qsTr("Generator total run time (hours)") - item { - bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") - text: Math.round(item.value / 60 / 60) - } -//// added to avoid full keyboard - numericOnlyLayout: true - matchString: "0123456789" - maximumLength: 6 - ignoreChars: "h" - enabled: state.value === 0 - - function editTextToValue() { - return parseInt(_editText, 10) * 60 * 60 - } - - Keys.onSpacePressed: { - if (!enabled) - toast.createToast(qsTr("It is not possible to modify the counters while the generator is running")) - } - } - -//// GuiMods - MbEditBox - { - id: serviceInterval - description: qsTr("Generator service interval (hours)") - item { - bind: Utils.path(settingsBindPrefix, "/ServiceInterval") - text: Math.round(item.value / 60 / 60) - } - numericOnlyLayout: true - matchString: "0123456789" - maximumLength: 6 - ignoreChars: "h" - - function editTextToValue() { - return parseInt(_editText, 10) * 60 * 60 - } - } - MbOK - { - description: qsTr("Reset service timer") - value: qsTr("Press to reset") - show: timeSinceService.valid && timeSinceService.value > 0 - editable: true - VBusItem - { - id: timeSinceService - bind: Utils.path(settingsBindPrefix, "/TimeSinceService") - } - - function clicked() - { - timeSinceService.setValue (0) - toast.createToast(qsTr("the service timer has been reset to ") + (serviceInterval.item.value / 3600).toFixed (0) + "h") - } - } - } - - VBusItem { - id: state - bind: Utils.path(startStopBindPrefix, "/State") - } -} diff --git a/FileSets/v2.89/PageSettingsGenerator.qml.orig b/FileSets/v2.89/PageSettingsGenerator.qml.orig deleted file mode 100644 index 77725f0e..00000000 --- a/FileSets/v2.89/PageSettingsGenerator.qml.orig +++ /dev/null @@ -1,133 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: root - title: qsTr("Generator start/stop settings") - property string settingsBindPrefix - property string startStopBindPrefix - - model: VisualItemModel { - - MbSubMenu { - id: conditions - description: qsTr("Conditions") - subpage: - Component { - PageGeneratorConditions { - title: qsTr("Conditions") - bindPrefix: root.settingsBindPrefix - } - } - } - - MbSpinBox { - description: qsTr("Minimum run time") - bind: Utils.path(settingsBindPrefix, "/MinimumRuntime") - unit: "m" - numOfDecimals: 0 - stepSize: 1 - } - - MbSwitch { - property bool generatorIsSet: acIn1Source.value === 2 || acIn2Source.value === 2 - name: qsTr("Detect generator at AC input") - bind: Utils.path(settingsBindPrefix, "/Alarms/NoGeneratorAtAcIn") - enabled: valid && (generatorIsSet || checked) - onClicked: { - if (!checked) { - if (!generatorIsSet) { - toast.createToast(qsTr("None of the AC inputs is set to generator. Go to the system setup page and set the correct " + - "AC input to generator in order to enable this functionality."), 10000, "icon-info-active") - } else { - toast.createToast(qsTr("An alarm will be triggered when no power from the generator is detected at the inverter AC input. " + - "Make sure that the correct AC input is set to generator on the system setup page."), 12000, "icon-info-active") - } - } - } - - VBusItem { - id: acIn1Source - bind: "com.victronenergy.settings/Settings/SystemSetup/AcInput1" - } - - VBusItem { - id: acIn2Source - bind: "com.victronenergy.settings/Settings/SystemSetup/AcInput2" - } - } - - MbSwitch { - id: timeZones - name: qsTr("Quiet hours") - bind: Utils.path(settingsBindPrefix, "/QuietHours/Enabled") - enabled: valid - writeAccessLevel: User.AccessUser - } - - MbEditBoxTime { - description: qsTr("Quiet hours start time") - item.bind: Utils.path(settingsBindPrefix, "/QuietHours/StartTime") - show: timeZones.checked - writeAccessLevel: User.AccessUser - } - - MbEditBoxTime { - description: qsTr("Quiet hours end time") - item.bind: Utils.path(settingsBindPrefix, "/QuietHours/EndTime") - show: timeZones.checked - writeAccessLevel: User.AccessUser - } - - MbOK { - description: qsTr("Reset daily run time counters") - value: qsTr("Press to reset") - enabled: true - editable: enabled - onClicked: { - if (state.value === 0) { - var now = new Date() - var today = new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate())) - var todayInSeconds = today.getTime() / 1000 - resetDaily.setValue('{"%1" : 0}'.arg(todayInSeconds.toString())) - toast.createToast(qsTr("The daily runtime counter has been reset")) - } else if (state.value === 1) { - toast.createToast(qsTr("It is not possible to modify the counters while the generator is running")) - } - } - - VBusItem { - id: resetDaily - bind: Utils.path(settingsBindPrefix, "/AccumulatedDaily") - } - } - - MbEditBox { - id: setTotalRunTime - description: qsTr("Generator total run time (hours)") - item { - bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") - text: Math.round(item.value / 60 / 60) - } - matchString: "0123456789" - maximumLength: 6 - ignoreChars: "h" - enabled: state.value === 0 - - function editTextToValue() { - return parseInt(_editText, 10) * 60 * 60 - } - - Keys.onSpacePressed: { - if (!enabled) - toast.createToast(qsTr("It is not possible to modify the counters while the generator is running")) - } - } - } - - VBusItem { - id: state - bind: Utils.path(startStopBindPrefix, "/State") - } -} diff --git a/FileSets/v2.89/PageSettingsGuiMods.qml b/FileSets/v2.89/PageSettingsGuiMods.qml deleted file mode 100644 index b4cf0928..00000000 --- a/FileSets/v2.89/PageSettingsGuiMods.qml +++ /dev/null @@ -1,274 +0,0 @@ -/////// new menu for all Gui Mods - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 - -MbPage { - id: root - title: qsTr("Gui Mods") - property string bindPrefixGuiMods: "com.victronenergy.settings/Settings/GuiMods" - property string bindPrefix: "com.victronenergy.settings/Settings/Gui" - - property bool showFlowParams: flowOverview.item.valid && flowOverview.item.value >= 1 - property bool showComplexParams: flowOverview.item.valid && flowOverview.item.value >= 2 - property bool showAcCoupledParams: flowOverview.item.valid && flowOverview.item.value == 3 - - model: VisualItemModel - { - MbSwitch - { - id: showTileOverview - bind: Utils.path (bindPrefixGuiMods, "/ShowTileOverview") - name: qsTr ("Show Tile Overview") - writeAccessLevel: User.AccessUser - } - - MbSwitch - { - id: moveSettings - bind: Utils.path (bindPrefixGuiMods, "/MoveSettings") - name: qsTr ("Move Settings to top of Device List") - writeAccessLevel: User.AccessUser - } - - MbSwitch { - id: relayOverview - bind: Utils.path (bindPrefixGuiMods, "/ShowRelayOverview") - name: qsTr ("Show Relay overview") - writeAccessLevel: User.AccessUser - } - MbSwitch { - id: tanksTempsOverview - bind: Utils.path (bindPrefixGuiMods, "/ShowTanksTempsDigIn") - name: qsTr ("Show Tanks, Temps, Digital Input overview") - writeAccessLevel: User.AccessUser - } - - MbSwitch - { - id: useEnhGeneratorOverview - bind: Utils.path (bindPrefixGuiMods, "/UsedEnhancedGeneratorOverview") - name: qsTr ("Use Enhanced Generator Overview") - writeAccessLevel: User.AccessUser - } - - // duplicate mobile overview on/off here for convenience - MbSwitch { - id: mobileOverview - bind: Utils.path (bindPrefix, "/MobileOverview") - name: qsTr ("Show boat & motorhome overview") - writeAccessLevel: User.AccessUser - } - MbSwitch - { - id: useEnhMobileOverview - bind: Utils.path (bindPrefixGuiMods, "/UseEnhancedMobileOverview") - name: qsTr ("Use Enhanced Mobile Overview") - // When enabled set Enhanced OverviewMobile as default overview - onClicked: - { - if (!checked) - { - // also enable Mobile Overview when turning on use enhanced Mobile Overview - showMobileOverview.setValue (1) - } - } - VBusItem { id: showMobileOverview; bind: Utils.path (bindPrefix, "/MobileOverview") } - writeAccessLevel: User.AccessUser - } - - MbItemOptions - { - id: flowOverview - description: qsTr("Flow overview") - bind: Utils.path (bindPrefixGuiMods, "/FlowOverview") - possibleValues: - [ - MbOption {description: qsTr("Victron stock"); value: 0}, - MbOption {description: qsTr("GuiMods simple"); value: 1}, - MbOption {description: qsTr("GuiMods DC Coupled"); value: 2}, - MbOption {description: qsTr("GuiMods AC Coupled"); value: 3} - ] - } - - MbSwitch - { - id: combineLoads - bind: Utils.path (bindPrefixGuiMods, "/EnhancedFlowCombineLoads") - name: qsTr ("Combine AC input/ouput loads") - show: root.showAcCoupledParams - writeAccessLevel: User.AccessInstaller - } - MbSwitch - { - id: showLoadsOnInput - bind: Utils.path (bindPrefixGuiMods, "/ShowEnhancedFlowLoadsOnInput") - name: qsTr ("Show Loads On Input") - show: root.showAcCoupledParams && ! combineLoads.checked - writeAccessLevel: User.AccessInstaller - } - - MbSwitch - { - id: showTanks - bind: Utils.path (bindPrefixGuiMods, "/ShowEnhancedFlowOverviewTanks") - name: qsTr ("Show tanks on Flow Overview") - show: root.showFlowParams - writeAccessLevel: User.AccessUser - } - MbItemOptions - { - id: tankFormat - description: qsTr("Tank bar format") - bind: Utils.path (bindPrefixGuiMods, "/TankBarFormat") - possibleValues: - [ - MbOption {description: qsTr("%"); value: 1}, - MbOption {description: qsTr("units"); value: 2}, - MbOption {description: qsTr("% + units"); value: 0} - ] - } - MbSwitch - { - id: showTemps - bind: Utils.path (bindPrefixGuiMods, "/ShowEnhancedFlowOverviewTemps") - name: qsTr ("Show temperatures on Flow Overview") - show: root.showFlowParams - writeAccessLevel: User.AccessUser - } - MbSwitch - { - id: showBatteryTemps - bind: Utils.path (bindPrefixGuiMods, "/ShowBatteryTempOnFlows") - name: qsTr ("Show battery temperature on Flow Overview") - show: showTemps.item.value == 1 - writeAccessLevel: User.AccessUser - } - MbSwitch - { - id: shortenTankNames - bind: Utils.path (bindPrefixGuiMods, "/ShortenTankNames") - name: qsTr ("Shorten tank names") - writeAccessLevel: User.AccessUser - } - - MbEditBox { - id: dcSystemName - description: qsTr("DC System tile name") - item.bind: Utils.path (bindPrefixGuiMods, "/CustomDcSystemName") - maximumLength: 32 - enableSpaceBar: true - } - - MbSwitch - { - id: replaceInactiveAcIn - bind: Utils.path (bindPrefixGuiMods, "/ReplaceInactiveAcIn") - name: qsTr ("Replace AC in if inactive") - writeAccessLevel: User.AccessUser - } - - MbSpinBox { - description: qsTr ("AC Input Limit Preset 1") - bind: Utils.path (bindPrefixGuiMods, "/AcCurrentLimit/Preset1") - unit: "A" - numOfDecimals: 0 - stepSize: 1 - min: 0 - max: 999 - writeAccessLevel: User.AccessUser - } - - MbSpinBox { - description: qsTr ("AC Input Limit Preset 2") - bind: Utils.path (bindPrefixGuiMods, "/AcCurrentLimit/Preset2") - unit: "A" - numOfDecimals: 0 - stepSize: 1 - min: 0 - max: 999 - writeAccessLevel: User.AccessUser - } - - MbSpinBox { - description: qsTr ("AC Input Limit Preset 3") - bind: Utils.path (bindPrefixGuiMods, "/AcCurrentLimit/Preset3") - unit: "A" - numOfDecimals: 0 - stepSize: 1 - min: 0 - max: 999 - writeAccessLevel: User.AccessUser - } - - MbSpinBox { - description: qsTr ("AC Input Limit Preset 4") - bind: Utils.path (bindPrefixGuiMods, "/AcCurrentLimit/Preset4") - unit: "A" - numOfDecimals: 0 - stepSize: 1 - min: 0 - max: 999 - writeAccessLevel: User.AccessUser - } - - MbItemOptions - { - id: tempScale - description: qsTr ("Temperature scale") - bind: Utils.path (bindPrefixGuiMods, "/TemperatureScale") - possibleValues: - [ - MbOption { description: "°C"; value: 1 }, - MbOption { description: "°F"; value: 2 }, - MbOption { description: qsTr("both °C & °F"); value: 0 } - ] - writeAccessLevel: User.AccessUser - } - - MbSpinBox { - description: qsTr ("Watt / Kilowatt threshold") - bind: Utils.path (bindPrefixGuiMods, "/KilowattThreshold") - unit: "W" - stepSize: 100 - min: 1000 - max: 10000 - writeAccessLevel: User.AccessUser - } - - MbItemOptions - { - id: timeFormat - description: qsTr ("Time format") - bind: Utils.path (bindPrefixGuiMods, "/TimeFormat") - possibleValues: - [ - MbOption { description: qsTr("24 hour"); value: 1 }, - MbOption { description: qsTr("12 hour AM/PM"); value: 2 }, - MbOption { description: qsTr("don't show time"); value: 0 } - ] - writeAccessLevel: User.AccessUser - } - MbItemOptions - { - id: inactiveFlowTiles - description: qsTr ("Inactive Tiles on Flow Overview") - bind: Utils.path (bindPrefixGuiMods, "/ShowInactiveFlowTiles") - show: root.showFlowParams - possibleValues: - [ - MbOption { description: qsTr("Show Dimmed"); value: 1 }, - MbOption { description: qsTr("Show Full"); value: 2 }, - MbOption { description: qsTr("Hide"); value: 0 } - ] - writeAccessLevel: User.AccessUser - } - MbSubMenu - { - description: qsTr("Power Gauges") - subpage: Component { PageSettingsGuiModsGauges {} } - show: root.showFlowParams - } - } -} diff --git a/FileSets/v2.89/PageSettingsGuiMods.qml.orig b/FileSets/v2.89/PageSettingsGuiMods.qml.orig deleted file mode 100644 index 8bfeb627..00000000 --- a/FileSets/v2.89/PageSettingsGuiMods.qml.orig +++ /dev/null @@ -1,312 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - property string cgwacsPath: "com.victronenergy.settings/Settings/CGwacs" - property string settingsPrefix: "com.victronenergy.settings" - property string batteryLifePath: cgwacsPath + "/BatteryLife" - // Hub4Mode - property int hub4PhaseCompensation: 1 - property int hub4PhaseSplit: 2 - property int hub4Disabled: 3 - // BatteryLifeState - property int batteryLifeStateDisabled: 0 - property int batteryLifeStateRestart: 1 - property int batteryLifeStateDefault: 2 - property int batteryLifeStateAbsorption: 3 - property int batteryLifeStateFloat: 4 - property int batteryLifeStateDischarged: 5 - property int batteryLifeStateForceCharge: 6 - property int batteryLifeStateSustain: 7 - property int batteryLifeStateLowSocCharge: 8 - property int batteryKeepCharged: 9 - property int batterySocGuardDefault: 10 - property int batterySocGuardDischarged: 11 - property int batterySocGuardLowSocCharge: 12 - - property VBusItem systemType: VBusItem { bind: "com.victronenergy.system/SystemType" } - property VBusItem gridSetpoint: VBusItem { bind: "com.victronenergy.settings/Settings/CGwacs/AcPowerSetPoint" } - property VBusItem maxChargePowerItem: VBusItem { bind: Utils.path(cgwacsPath, "/MaxChargePower") } - property VBusItem maxDischargePowerItem: VBusItem { bind: Utils.path(cgwacsPath, "/MaxDischargePower") } - property VBusItem socLimitItem: VBusItem { bind: Utils.path(batteryLifePath, "/SocLimit") } - property VBusItem minSocLimitItem: VBusItem { bind: Utils.path(batteryLifePath, "/MinimumSocLimit") } - property VBusItem stateItem: VBusItem { bind: Utils.path(batteryLifePath, "/State") } - property VBusItem hub4Mode: VBusItem { bind: Utils.path(cgwacsPath, "/Hub4Mode") } - property VBusItem maxChargeCurrentControl: VBusItem { bind: "com.victronenergy.system/Control/MaxChargeCurrent" } - - title: systemType.value === "Hub-4" ? systemType.value : qsTr("ESS") - model: systemType.value === "ESS" || systemType.value === "Hub-4" ? hub4Settings : noHub4 - - VisualItemModel { - id: noHub4 - - MbItemText { - text: qsTr("No ESS Assistant found") - } - } - - function isBatteryLifeActive(state) { - switch (state) { - case batteryLifeStateRestart: - case batteryLifeStateDefault: - case batteryLifeStateAbsorption: - case batteryLifeStateFloat: - case batteryLifeStateDischarged: - case batteryLifeStateForceCharge: - case batteryLifeStateSustain: - case batteryLifeStateLowSocCharge: - return true - default: - return false - } - } - - function isBatterySocGuardActive(state) { - switch (state) { - case batterySocGuardDefault: - case batterySocGuardDischarged: - case batterySocGuardLowSocCharge: - return true - default: - return false - } - } - - VisualItemModel { - id: hub4Settings - - MbItemOptions { - function getLocalValue(hub4Mode, state) { - if (hub4Mode === undefined || state === undefined) - return undefined - if (hub4Mode === hub4Disabled) - return 3 - if (isBatteryLifeActive(state)) - return 0 - if (isBatterySocGuardActive(state)) - return 1 - if (state === batteryKeepCharged) - return 2 - return 0 - } - - description: qsTr("Mode") - localValue: getLocalValue(hub4Mode.value, stateItem.value) - possibleValues:[ - MbOption { description: qsTr("Optimized (with BatteryLife)"); value: 0 }, - MbOption { description: qsTr("Optimized (without BatteryLife)"); value: 1 }, - MbOption { description: qsTr("Keep batteries charged"); value: 2 }, - MbOption { description: qsTr("External control"); value: 3 } - ] - onLocalValueChanged: { - if (localValue === undefined) - return - // Hub 4 mode - if (localValue === 3 && hub4Mode.value !== hub4Disabled) { - hub4Mode.setValue(hub4Disabled) - } else if (localValue !== 3 && hub4Mode.value === hub4Disabled) { - hub4Mode.setValue(hub4PhaseCompensation) - } - // BatteryLife state - switch (localValue) { - case 0: - if (!isBatteryLifeActive(stateItem.value)) - stateItem.setValue(batteryLifeStateRestart) - break - case 1: - if (!isBatterySocGuardActive(stateItem.value)) - stateItem.setValue(batterySocGuardDefault) - break - case 2: - stateItem.setValue(batteryKeepCharged) - break - case 3: - stateItem.setValue(batteryLifeStateDisabled) - break - } - } - } - - MbItemOptions { - id: withoutGridMeter - description: qsTr("Grid metering") - bind: Utils.path(cgwacsPath, '/RunWithoutGridMeter') - show: hub4Mode.value !== hub4Disabled - enabled: userHasWriteAccess - possibleValues:[ - MbOption { description: qsTr("External meter"); value: 0 }, - MbOption { description: qsTr("Inverter/Charger"); value: 1 } - ] - } - - MbSwitch { - bind: Utils.path(settingsPrefix, "/Settings/SystemSetup/HasAcOutSystem") - name: qsTr("Inverter AC output in use") - show: withoutGridMeter.value == 0 - } - - - MbItemOptions { - description: qsTr("Multiphase regulation") - bind: hub4Mode.bind - show: hub4Mode.value !== hub4Disabled && stateItem.value !== batteryKeepCharged - enabled: userHasWriteAccess - possibleValues:[ - MbOption { description: qsTr("Total of all phases"); value: hub4PhaseCompensation }, - MbOption { description: qsTr("Individual phase"); value: hub4PhaseSplit } - ] - onOptionSelected: { - if (newValue === hub4PhaseSplit) { - toast.createToast(qsTr("Each phase is regulated to individually achieve the grid setpoint (system efficiency is decreased).\n\n" + - "CAUTION: Use only if required by the utility provider"), 15000); - } else if (newValue === hub4PhaseCompensation) { - toast.createToast(qsTr("The total of all phases is intelligently regulated to achieve the grid setpoint (system efficiency is optimised).\n\n" + - "Use unless prohibited by the utility provider"), 15000); - } - } - } - - MbSpinBox { - id: minSocLimit - description: qsTr("Minimum SOC (unless grid fails)") - enabled: userHasWriteAccess - show: hub4Mode.value !== hub4Disabled && stateItem.value !== batteryKeepCharged - bind: Utils.path(batteryLifePath, "/MinimumSocLimit") - numOfDecimals: 0 - unit: "%" - min: 0 - max: 100 - stepSize: 5 - } - - MbItemValue { - id: socLimit - description: qsTr("Active SOC limit") - show: hub4Mode.value !== hub4Disabled && isBatteryLifeActive(stateItem.value) - item.value: Math.max(minSocLimitItem.value, socLimitItem.value) - item.unit: '%' - } - - MbItemOptions { - description: qsTr("BatteryLife state") - value: stateItem.value - readonly: true - show: hub4Mode.value !== hub4Disabled && isBatteryLifeActive(stateItem.value) - possibleValues:[ - // Values below taken from MaintenanceState enum in dbus-cgwacs - MbOption { description: qsTr("Self-consumption"); value: 2 }, - MbOption { description: qsTr("Self-consumption"); value: 3 }, - MbOption { description: qsTr("Self-consumption"); value: 4 }, - MbOption { description: qsTr("Discharge disabled"); value: 5 }, - MbOption { description: qsTr("Slow charge"); value: 6 }, - MbOption { description: qsTr("Sustain"); value: 7 }, - MbOption { description: qsTr("Recharge"); value: 8 } - ] - } - - MbSwitch { - id: maxChargePowerSwitch - name: qsTr("Limit charge power") - checked: maxChargePowerItem.value >= 0 - enabled: userHasWriteAccess - show: hub4Mode.value !== hub4Disabled && !(maxChargeCurrentControl.valid && maxChargeCurrentControl.value) - onCheckedChanged: { - if (checked && maxChargePowerItem.value < 0) - maxChargePowerItem.setValue(1000) - else if (!checked && maxChargePowerItem.value >= 0) - maxChargePowerItem.setValue(-1) - } - } - - MbSpinBox { - id: maxChargePower - description: qsTr("Maximum charge power") - enabled: userHasWriteAccess - show: maxChargePowerSwitch.show && maxChargePowerSwitch.checked - bind: Utils.path(cgwacsPath, "/MaxChargePower") - numOfDecimals: 0 - unit: "W" - min: 0 - max: 200000 - stepSize: 50 - } - - MbSwitch { - id: maxInverterPowerSwitch - name: qsTr("Limit inverter power") - checked: maxDischargePowerItem.value >= 0 - enabled: userHasWriteAccess - show: hub4Mode.value !== hub4Disabled && stateItem.value !== batteryKeepCharged - onCheckedChanged: { - if (checked && maxDischargePowerItem.value < 0) - maxDischargePowerItem.setValue(1000) - else if (!checked && maxDischargePowerItem.value >= 0) - maxDischargePowerItem.setValue(-1) - } - } - - MbSpinBox { - id: maxDischargePower - description: qsTr("Maximum inverter power") - enabled: userHasWriteAccess - show: maxInverterPowerSwitch.show && maxInverterPowerSwitch.checked - bind: Utils.path(cgwacsPath, "/MaxDischargePower") - numOfDecimals: 0 - unit: "W" - min: 0 - max: 300000 - stepSize: 50 - } - - MbSpinBox { - description: qsTr("Grid setpoint") - show: hub4Mode.value !== hub4Disabled && stateItem.value !== batteryKeepCharged - enabled: userHasWriteAccess - bind: "com.victronenergy.settings/Settings/CGwacs/AcPowerSetPoint" - numOfDecimals: 0 - unit: "W" - stepSize: 10 - } - - MbSubMenu { - id: feedinSetupItem - description: qsTr("Grid feed-in") - show: hub4Mode.value !== hub4Disabled - subpage: Component { - PageSettingsHub4Feedin { - title: feedinSetupItem.description - } - } - } - - MbSubMenu { - id: scheduleSettings - property string bindPrefix: "com.victronenergy.settings/Settings/CGwacs/BatteryLife/Schedule/Charge/" - description: qsTr("Scheduled charging") - show: hub4Mode.value !== hub4Disabled && stateItem.value !== batteryKeepCharged - subpage: Component { - MbPage { - title: scheduleSettings.description - model: VisualItemModel { - ChargeScheduleItem { bindPrefix: scheduleSettings.bindPrefix; scheduleNumber: 0 } - ChargeScheduleItem { bindPrefix: scheduleSettings.bindPrefix; scheduleNumber: 1 } - ChargeScheduleItem { bindPrefix: scheduleSettings.bindPrefix; scheduleNumber: 2 } - ChargeScheduleItem { bindPrefix: scheduleSettings.bindPrefix; scheduleNumber: 3 } - ChargeScheduleItem { bindPrefix: scheduleSettings.bindPrefix; scheduleNumber: 4 } - } - } - } - } - - MbSubMenu { - id: deviceItem - description: qsTr("Debug") - show: hub4Mode.value !== hub4Disabled && user.accessLevel >= User.AccessService - backgroundColor: style.backgroundColorService - subpage: Component { - PageHub4Debug { } - } - } - } -} diff --git a/FileSets/v2.89/PageSettingsRelay.qml b/FileSets/v2.89/PageSettingsRelay.qml deleted file mode 120000 index 6861254c..00000000 --- a/FileSets/v2.89/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v2.89/PowerGauge.qml b/FileSets/v2.89/PowerGauge.qml deleted file mode 120000 index d82ac28a..00000000 --- a/FileSets/v2.89/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v2.89/Tile.qml b/FileSets/v2.89/Tile.qml deleted file mode 120000 index aa80e332..00000000 --- a/FileSets/v2.89/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/Tile.qml \ No newline at end of file diff --git a/FileSets/v2.89/TileDigIn.qml b/FileSets/v2.89/TileDigIn.qml deleted file mode 100644 index 5a107e0d..00000000 --- a/FileSets/v2.89/TileDigIn.qml +++ /dev/null @@ -1,131 +0,0 @@ -// New for GuiMods to display digital inputs -// based on TileTank.qml - -import QtQuick 1.1 -import "utils.js" as Utils -import "tanksensor.js" as TankSensor - -Tile { - id: root - - property string bindPrefix: serviceName - property VBusItem nameItem: VBusItem { bind: Utils.path(bindPrefix, "/CustomName") } - property VBusItem deviceItem: VBusItem { bind: Utils.path(bindPrefix, "/DeviceInstance") } - property VBusItem aggregateItem: VBusItem { bind: Utils.path(bindPrefix, "/Aggregate") } - property string digInName: nameItem.valid && nameItem.value != "" ? nameItem.value : getType (type) - property VBusItem typeItem: VBusItem { bind: Utils.path(bindPrefix, "/Type") } - property VBusItem stateItem: VBusItem { bind: Utils.path(bindPrefix, "/State") } - property bool isPulseCounter: aggregateItem.valid - // pulse counter doesn't have /Type so fill it in here - property int type: isPulseCounter ? 1 : typeItem.valid ? typeItem.value : 0 - - property variant bkgdColors: [ "#b3b3b3", "#4aa3df", "#1abc9c", "#F39C12", "#95a5a6", "#95a5a6","#dcc6e0", "#f1a9a0", "#7f8c8d", "#ebbc3a" ] - property color bkgdColor: type > 0 && type < 10 ? bkgdColors [type] : "#b3b3b3" - property variant units: ["m3", "L", "gal", "gal"] - - - function getType(type) - { - switch (type) - { - case 0: - return qsTr("Disabled") - case 1: - return qsTr("Pulse meter") - case 2: - return qsTr("Door alarm") - case 3: - return qsTr("Bilge pump") - case 4: - return qsTr("Bilge alarm") - case 5: - return qsTr("Burglar alarm") - case 6: - return qsTr("Smoke alarm") - case 7: - return qsTr("Fire alarm") - case 8: - return qsTr("CO2 alarm") - case 9: - return qsTr("Generator") - case 10: - return qsTr("Generic I/O") -//// added for ExtTransferSwitch package - case 11: - return qsTr("Transfer switch") - default: - return "Unknown" - } - } - - function getState(st) - { - switch (st) - { - case 0: - return qsTr("Low") - case 1: - return qsTr("High") - case 2: - return qsTr("Off") - case 3: - return qsTr("On") - case 4: - return qsTr("No") - case 5: - return qsTr("Yes") - case 6: - return qsTr("Open") - case 7: - return qsTr("Closed") - case 8: - return qsTr("Ok") - case 9: - return qsTr("Alarm") - case 10: - return qsTr("Running") - case 11: - return qsTr("Stopped") -//// added for ExtTransferSwitch package - case 12: - return qsTr("On Generator") - case 13: - return qsTr("On Grid") - default: - return qsTr("Unknown") - } - - } - - title: digInName + " (In " + (deviceItem.valid ? (deviceItem.value.toString ()) : "?") + ")" - - color: bkgdColor - - VBusItem - { - id: unitItem - bind: Utils.path("com.victronenergy.settings/Settings/System/VolumeUnit") - } - - values: Item - { - width: root.width - 10 - height: 12 - TileText - { - width: root.width - text: - { - if (isPulseCounter) - return aggregateItem.value.toString() + (unitItem.valid ? units[unitItem.value] : "??") - else - return stateItem.valid ? getState (stateItem.value) : "??" - } - horizontalAlignment: Text.AlignHCenter - anchors - { - horizontalCenter: parent.horizontalCenter - } - } - } -} diff --git a/FileSets/v2.89/TileDigIn.qml.orig b/FileSets/v2.89/TileDigIn.qml.orig deleted file mode 100755 index 79b58848..00000000 --- a/FileSets/v2.89/TileDigIn.qml.orig +++ /dev/null @@ -1,534 +0,0 @@ -#!/usr/bin/python3 -u - -import sys, os -import signal -from threading import Thread -from select import select, epoll, EPOLLPRI -from functools import partial -from collections import namedtuple -from argparse import ArgumentParser -import traceback -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) - -from dbus.mainloop.glib import DBusGMainLoop -import dbus -from gi.repository import GLib -from vedbus import VeDbusService -from settingsdevice import SettingsDevice - -VERSION = '0.15' -MAXCOUNT = 2**31-1 -SAVEINTERVAL = 60000 - -INPUT_FUNCTION_COUNTER = 1 -INPUT_FUNCTION_INPUT = 2 - -Translation = namedtuple('Translation', ['no', 'yes']) - -# Only append at the end -INPUTTYPES = [ - 'Disabled', - 'Pulse meter', - 'Door', - 'Bilge pump', - 'Bilge alarm', - 'Burglar alarm', - 'Smoke alarm', - 'Fire alarm', - 'CO2 alarm', - 'Generator' -] - -# Translations. The text will be used only for GetText, it will be translated -# in the gui. -TRANSLATIONS = [ - Translation('low', 'high'), - Translation('off', 'on'), - Translation('no', 'yes'), - Translation('open', 'closed'), - Translation('ok', 'alarm'), - Translation('running', 'stopped') -] - -class SystemBus(dbus.bus.BusConnection): - def __new__(cls): - return dbus.bus.BusConnection.__new__(cls, dbus.bus.BusConnection.TYPE_SYSTEM) - -class SessionBus(dbus.bus.BusConnection): - def __new__(cls): - return dbus.bus.BusConnection.__new__(cls, dbus.bus.BusConnection.TYPE_SESSION) - -class BasePulseCounter(object): - pass - -class DebugPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - - def register(self, path, gpio): - self.gpiomap[gpio] = None - return 0 - - def unregister(self, gpio): - del self.gpiomap[gpio] - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - from itertools import cycle - from time import sleep - for level in cycle([0, 1]): - for gpio in list(self.gpiomap.keys()): - yield gpio, level - sleep(0.25/len(self.gpiomap)) - -class EpollPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - self.states = {} - self.ob = epoll() - - def register(self, path, gpio): - path = os.path.realpath(path) - - # Set up gpio for rising edge interrupts - with open(os.path.join(path, 'edge'), 'ab') as fp: - fp.write(b'both') - - fp = open(os.path.join(path, 'value'), 'rb') - level = int(fp.read()) # flush it in case it's high at startup - self.gpiomap[gpio] = fp - self.states[gpio] = level - self.ob.register(fp, EPOLLPRI) - return level - - def unregister(self, gpio): - fp = self.gpiomap[gpio] - self.ob.unregister(fp) - del self.gpiomap[gpio] - del self.states[gpio] - fp.close() - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - while True: - # We have a timeout of 1 second on the poll, because poll() only - # looks at files in the epoll object at the time poll() was called. - # The timeout means we let other files (added via calls to - # register/unregister) into the loop at least that often. - self.ob.poll(1) - - # When coming out of the epoll call, we read all the gpios to make - # sure we didn't miss any edges. This is a safety fallback that - # ensures everything is up to date once a second, but - # edge-triggered results are handled immediately. - # NOTE: There has not been a report of a missed interrupt yet. - # Belts and suspenders. - for gpio, fp in list(self.gpiomap.items()): - os.lseek(fp.fileno(), 0, os.SEEK_SET) - v = int(os.read(fp.fileno(), 1)) - if v != self.states[gpio]: - self.states[gpio] = v - yield gpio, v - -class PollingPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - - def register(self, path, gpio): - path = os.path.realpath(path) - - fp = open(os.path.join(path, 'value'), 'rb') - level = int(fp.read()) - self.gpiomap[gpio] = [fp, level] - return level - - def unregister(self, gpio): - del self.gpiomap[gpio] - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - from itertools import cycle - from time import sleep - while True: - for gpio, (fp, level) in list(self.gpiomap.items()): - fp.seek(0, os.SEEK_SET) - v = int(fp.read()) - if v != level: - self.gpiomap[gpio][1] = v - yield gpio, v - sleep(1) - -class HandlerMaker(type): - """ Meta-class for keeping track of all extended classes. """ - def __init__(cls, name, bases, attrs): - if not hasattr(cls, 'handlers'): - cls.handlers = {} - else: - cls.handlers[cls.type_id] = cls - -class PinHandler(object, metaclass=HandlerMaker): - product_id = 0xFFFF - _product_name = 'Generic GPIO' - dbus_name = "digital" - def __init__(self, bus, base, path, gpio, settings): - self.gpio = gpio - self.path = path - self.bus = bus - self.settings = settings - self._level = 0 # Remember last state - - self.service = VeDbusService( - "{}.{}.input{:02d}".format(base, self.dbus_name, gpio), bus=bus) - - # Add objects required by ve-api - self.service.add_path('/Mgmt/ProcessName', __file__) - self.service.add_path('/Mgmt/ProcessVersion', VERSION) - self.service.add_path('/Mgmt/Connection', path) - self.service.add_path('/DeviceInstance', gpio) - self.service.add_path('/ProductId', self.product_id) - self.service.add_path('/ProductName', self.product_name) - self.service.add_path('/Connected', 1) - - # Custom name setting - def _change_name(p, v): - # This should fire a change event that will update product_name - # below. - settings['name'] = v - return True - - self.service.add_path('/CustomName', settings['name'], writeable=True, - onchangecallback=_change_name) - - # We'll count the pulses for all types of services - self.service.add_path('/Count', value=settings['count']) - - @property - def product_name(self): - return self.settings['name'] or self._product_name - - @product_name.setter - def product_name(self, v): - # Some pin types don't have an associated service (Disabled pins for - # example) - if self.service is not None: - self.service['/ProductName'] = v or self._product_name - - def deactivate(self): - self.save_count() - self.service.__del__() - del self.service - self.service = None - - @property - def level(self): - return self._level - - @level.setter - def level(self, l): - self._level = int(bool(l)) - - def toggle(self, level): - # Only increment Count on rising edge. - if level and level != self._level: - self.service['/Count'] = (self.service['/Count']+1) % MAXCOUNT - self._level = level - - def refresh(self): - """ Toggle state to last remembered state. This is called if settings - are changed so the Service can recalculate paths. """ - self.toggle(self._level) - - def save_count(self): - if self.service is not None: - self.settings['count'] = self.count - - @property - def active(self): - return self.service is not None - - @property - def count(self): - return self.service['/Count'] - - @count.setter - def count(self, v): - self.service['/Count'] = v - - @classmethod - def createHandler(cls, _type, *args, **kwargs): - if _type in cls.handlers: - return cls.handlers[_type](*args, **kwargs) - return None - - -class DisabledPin(PinHandler): - """ Place holder for a disabled pin. """ - _product_name = 'Disabled' - type_id = 0 - def __init__(self, bus, base, path, gpio, settings): - self.service = None - self.bus = bus - self.settings = settings - self._level = 0 # Remember last state - - def deactivate(self): - pass - - def toggle(self, level): - self._level = level - - def save_count(self): - # Do nothing - pass - - @property - def count(self): - return self.settings['count'] - - @count.setter - def count(self, v): - pass - - def refresh(self): - pass - - -class VolumeCounter(PinHandler): - product_id = 0xA165 - _product_name = "Generic pulse meter" - dbus_name = "pulsemeter" - type_id = 1 - - def __init__(self, bus, base, path, gpio, settings): - super(VolumeCounter, self).__init__(bus, base, path, gpio, settings) - self.service.add_path('/Aggregate', value=self.count*self.rate, - gettextcallback=lambda p, v: (str(v) + ' cubic meter')) - - @property - def rate(self): - return self.settings['rate'] - - def toggle(self, level): - super(VolumeCounter, self).toggle(level) - self.service['/Aggregate'] = self.count * self.rate - -class PinAlarm(PinHandler): - product_id = 0xA166 - _product_name = "Generic digital input" - dbus_name = "digitalinput" - type_id = 0xFF - translation = 0 # low, high - - def __init__(self, bus, base, path, gpio, settings): - super(PinAlarm, self).__init__(bus, base, path, gpio, settings) - self.service.add_path('/InputState', value=0) - self.service.add_path('/State', value=self.get_state(0), - gettextcallback=lambda p, v: TRANSLATIONS[v//2][v%2]) - self.service.add_path('/Alarm', value=self.get_alarm_state(0)) - - # Also expose the type - self.service.add_path('/Type', value=self.type_id, - gettextcallback=lambda p, v: INPUTTYPES[v]) - - def toggle(self, level): - super(PinAlarm, self).toggle(level) - self.service['/InputState'] = bool(level)*1 - self.service['/State'] = self.get_state(level) - # Ensure that the alarm flag resets if the /AlarmSetting config option - # disappears. - self.service['/Alarm'] = self.get_alarm_state(level) - - def get_state(self, level): - state = level ^ self.settings['invert'] - return 2 * self.translation + state - - def get_alarm_state(self, level): - return 2 * bool( - (level ^ self.settings['invertalarm']) and self.settings['alarm']) - - -# Various types of things we might want to monitor -class DoorSensor(PinAlarm): - _product_name = "Door alarm" - type_id = 2 - translation = 3 # open, closed - -class BilgePump(PinAlarm): - _product_name = "Bilge pump" - type_id = 3 - translation = 1 # off, on - -class BilgeAlarm(PinAlarm): - _product_name = "Bilge alarm" - type_id = 4 - translation = 4 # ok, alarm - -class BurglarAlarm(PinAlarm): - _product_name = "Burglar alarm" - type_id = 5 - translation = 4 # ok, alarm - -class SmokeAlarm(PinAlarm): - _product_name = "Smoke alarm" - type_id = 6 - translation = 4 # ok, alarm - -class FireAlarm(PinAlarm): - _product_name = "Fire alarm" - type_id = 7 - translation = 4 # ok, alarm - -class CO2Alarm(PinAlarm): - _product_name = "CO2 alarm" - type_id = 8 - translation = 4 # ok, alarm - -class Generator(PinAlarm): - _product_name = "Generator" - type_id = 9 - translation = 5 # running, stopped - - -def dbusconnection(): - return SessionBus() if 'DBUS_SESSION_BUS_ADDRESS' in os.environ else SystemBus() - - -def main(): - parser = ArgumentParser(description=sys.argv[0]) - parser.add_argument('--servicebase', - help='Base service name on dbus, default is com.victronenergy', - default='com.victronenergy') - parser.add_argument('--poll', - help='Use a different kind of polling. Options are epoll, dumb and debug', - default='epoll') - parser.add_argument('inputs', nargs='+', help='Path to digital input') - args = parser.parse_args() - - PulseCounter = { - 'debug': DebugPulseCounter, - 'poll': PollingPulseCounter, - }.get(args.poll, EpollPulseCounter) - - DBusGMainLoop(set_as_default=True) - - # Keep track of enabled services - services = {} - inputs = dict(enumerate(args.inputs, 1)) - pulses = PulseCounter() # callable that iterates over pulses - - def register_gpio(path, gpio, bus, settings): - _type = settings['inputtype'] - print ("Registering GPIO {} for type {}".format(gpio, _type)) - - handler = PinHandler.createHandler(_type, - bus, args.servicebase, path, gpio, settings) - services[gpio] = handler - - # Only monitor if enabled - if _type > 0: - handler.level = pulses.register(path, gpio) - handler.refresh() - - def unregister_gpio(gpio): - print ("unRegistering GPIO {}".format(gpio)) - pulses.unregister(gpio) - services[gpio].deactivate() - - def handle_setting_change(inp, setting, old, new): - if setting == 'inputtype': - if new: - # Get current bus and settings objects, to be reused - service = services[inp] - bus, settings = service.bus, service.settings - - # Input enabled. If already enabled, unregister the old one first. - if pulses.registered(inp): - unregister_gpio(inp) - - # Before registering the new input, reset its settings to defaults - settings['count'] = 0 - settings['invert'] = 0 - settings['invertalarm'] = 0 - settings['alarm'] = 0 - - # Register it - register_gpio(inputs[inp], inp, bus, settings) - elif old: - # Input disabled - unregister_gpio(inp) - elif setting in ('rate', 'invert', 'alarm', 'invertalarm'): - services[inp].refresh() - elif setting == 'name': - services[inp].product_name = new - elif setting == 'count': - # Don't want this triggered on a period save, so only execute - # if it has changed. - v = int(new) - s = services[inp] - if s.count != v: - s.count = v - s.refresh() - - for inp, pth in inputs.items(): - supported_settings = { - 'inputtype': ['/Settings/DigitalInput/{}/Type'.format(inp), 0, 0, len(INPUTTYPES)], - 'rate': ['/Settings/DigitalInput/{}/Multiplier'.format(inp), 0.001, 0, 1.0], - 'count': ['/Settings/DigitalInput/{}/Count'.format(inp), 0, 0, MAXCOUNT, 1], - 'invert': ['/Settings/DigitalInput/{}/InvertTranslation'.format(inp), 0, 0, 1], - 'invertalarm': ['/Settings/DigitalInput/{}/InvertAlarm'.format(inp), 0, 0, 1], - 'alarm': ['/Settings/DigitalInput/{}/AlarmSetting'.format(inp), 0, 0, 1], - 'name': ['/Settings/DigitalInput/{}/CustomName'.format(inp), '', '', ''], - } - bus = dbusconnection() - sd = SettingsDevice(bus, supported_settings, partial(handle_setting_change, inp), timeout=10) - register_gpio(pth, inp, bus, sd) - - def poll(mainloop): - from time import time - idx = 0 - - try: - for inp, level in pulses(): - # epoll object only resyncs once a second. We may receive - # a pulse for something that's been deregistered. - try: - services[inp].toggle(level) - except KeyError: - continue - except: - traceback.print_exc() - mainloop.quit() - - # Need to run the gpio polling in separate thread. Pass in the mainloop so - # the thread can kill us if there is an exception. - mainloop = GLib.MainLoop() - - poller = Thread(target=lambda: poll(mainloop)) - poller.daemon = True - poller.start() - - # Periodically save the counter - def save_counters(): - for inp in inputs: - services[inp].save_count() - return True - GLib.timeout_add(SAVEINTERVAL, save_counters) - - # Save counter on shutdown - signal.signal(signal.SIGTERM, lambda *args: sys.exit(0)) - - try: - mainloop.run() - except KeyboardInterrupt: - pass - finally: - save_counters() - -if __name__ == "__main__": - main() diff --git a/FileSets/v2.89/TileRelay.qml b/FileSets/v2.89/TileRelay.qml deleted file mode 100644 index 2b3051c0..00000000 --- a/FileSets/v2.89/TileRelay.qml +++ /dev/null @@ -1,507 +0,0 @@ -// New for GuiMods to display and control relays on separate overview page - -import QtQuick 1.1 -import "utils.js" as Utils - -Tile { - id: root - - property string systemPrefix: "com.victronenergy.system" - property string settingsPrefix: "com.victronenergy.settings" - property string functionPath: relayNumber === 0 ? "/Settings/Relay/Function" : "/Settings/Relay/" + relayNumber + "/Function" - property string polarityPath: relayNumber === 0 ? "/Settings/Relay/Polarity" : "/Settings/Relay/" + relayNumber + "/Polarity" - - property int relayFunction: 0 - property bool relayInverted: polarityItem.valid ? polarityItem.value : false - property bool relayActive: flase - - property string activeText: "" - property string inactiveText: "" - property string offButtonText: "" - property string onButtonText: "" - property string autoButtonText: "" - property string functionText: "" - property bool autoButtonActive: false - property bool offButtonActive: false - property bool onButtonActive: false - - ////// GuiMods — DarkMode - property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } - property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 - - VBusItem - { - id: stateItem - bind: Utils.path(systemPrefix, "/Relay/", relayNumber, "/State") - onValueChanged: updateButtons () - } - VBusItem - { - id: nameItem - bind: Utils.path(settingsPrefix, "/Settings/Relay/", relayNumber, "/CustomName") - } - VBusItem - { - id: functionItem - bind: Utils.path(settingsPrefix, functionPath) - onValueChanged: updateFunction () - } - VBusItem - { - id: polarityItem - bind: Utils.path(settingsPrefix, polarityPath) - } - VBusItem - { - id: generatorManualStartItem - bind: Utils.path("com.victronenergy.generator.startstop0" , "/Generator0/ManualStart") - onValueChanged: updateButtons () - } - VBusItem - { - id: generatorAutoRunItem - bind: Utils.path(settingsPrefix, "/Settings/Generator0/AutoStartEnabled") - onValueChanged: updateButtons () - } - VBusItem - { - id: generatorStateItem - bind: Utils.path("com.victronenergy.generator.startstop0" , "/State") - } - VBusItem - { - id: generatorConditionItem - bind: Utils.path("com.victronenergy.generator.startstop0" , "/RunningByConditionCode") - } - VBusItem - { - id: generatorExternalOverrideItem - bind: Utils.path("com.victronenergy.generator.startstop0" , "/ExternalOverride") - } - VBusItem - { - id: pumpModeItem - bind: Utils.path(settingsPrefix, "/Settings/Pump0/Mode") - onValueChanged: updateButtons () - } - - // relay function changes may instantiate new dBus services which takes time - // this timer triggers button refreshe after a suitable delay (2 S) - Timer - { - id: functionDelayTimer - interval: 2000 - repeat: false - running: false - onTriggered: updateButtons () - } - - Component.onCompleted: updateFunction () - -////// GuiMods — DarkMode - color: !darkMode ? "#d9d9d9" : "#202020" - border.color: !darkMode ? "#fff" : "#707070" - - function doScroll() - { - relayName.doScroll() - } - - values: Item - { - Column - { - width: root.width - x: 3 - spacing: 4 - visible: true - anchors - { - horizontalCenter: parent.horizontalCenter - top: parent.top - } - Text - { - font.pixelSize: 12 - font.bold: true -////// GuiMods DarkMode - color: !darkMode ? "black" : "gray" - anchors - { - horizontalCenter: parent.horizontalCenter - } - horizontalAlignment: Text.AlignHCenter - text: "Relay " + (relayNumber + 1) - } - MarqueeEnhanced - { - id: relayName - width: parent.width - 4 - text: nameItem.valid && nameItem.value != "" ? nameItem.value : " " - fontSize: 12 - bold: true -////// GuiMods DarkMode - textColor: !darkMode ? "black" : "gray" - scroll: false - } - Text - { - font.pixelSize: 12 - font.bold: true -////// GuiMods DarkMode - color: !darkMode ? "black" : "gray" - anchors.horizontalCenter: parent.horizontalCenter - horizontalAlignment: Text.AlignHCenter - text: functionText - } - - MarqueeEnhanced - { - id: relayState - width: parent.width - 4 - fontSize: 12 - bold: true -////// GuiMods DarkMode - textColor: !darkMode ? "black" : "gray" - scroll: false - text: - { - // special handling for generator - if (relayFunction == 1) - { - if (generatorExternalOverrideItem.valid && generatorExternalOverrideItem.value == 1) - return qsTr ("External override - stopped") - else if (!generatorStateItem.valid) - return qsTr ("Error") - else if (generatorStateItem.value == 2) - return qsTr("Warm-up") - else if (generatorStateItem.value == 3) - return qsTr("Cool-down") - else if (generatorStateItem.value == 4) - return qsTr("Stopping") - else if (generatorConditionItem.valid) - { - switch (generatorConditionItem.value) - { - case 0: - return qsTr ("Stopped") - case 1: - return qsTr ("Man run") - case 2: - return qsTr ("Test run") - case 3: - return qsTr ("Loss of comms run") - case 4: - return qsTr ("SOC run") - case 5: - return qsTr ("Load run") - case 6: - return qsTr ("Battery current run") - case 7: - return qsTr ("Battery voltage run") - case 8: - return qsTr ("Inverter temperature run") - case 9: - return qsTr ("Inverter overload run") - default: - return "??" - } - } - else - return "??" - } - else if (stateItem.valid) - { - if (relayActive) - return activeText - else - return inactiveText - } - else - return "??" - } - } - // spacer - Text - { - font.pixelSize: 4 - font.bold: true - color: "black" - height: 4 - anchors.horizontalCenter: parent.horizontalCenter - horizontalAlignment: Text.AlignHCenter - text: " " - } - Button - { - id: onButton -////// GuiMods - DarkMode - baseColor: !darkMode ? (onButtonActive ? "green" : "#e6ffe6") : (onButtonActive ? "#003000" : "#003000") - pressedColor: "#979797" - height: 40 - width: parent.width - 6 - anchors.horizontalCenter: parent.horizontalCenter - onClicked: buttonPress (1) - content: TileText - { - text: onButtonText; font.bold: true; - color: onButtonActive ? "white" : "black" - } - } - Button - { - id: offButton -////// GuiMods - DarkMode - baseColor: !darkMode ? (offButtonActive ? "black" : "#e6e6e6") : (offButtonActive ? "gray" : "gray") - pressedColor: "#979797" - height: 40 - width: parent.width - 6 - anchors.horizontalCenter: parent.horizontalCenter - onClicked: buttonPress (2) - content: TileText - { - text: offButtonText; font.bold: true; - color: offButtonActive ? "white" : "black" - } - } - Button - { - id: autoButton -////// GuiMods - DarkMode - baseColor: !darkMode ? (autoButtonActive ? "orange" : "#ffedcc") : (autoButtonActive ? "#3a2600" : "#3a2600") - pressedColor: "#979797" - height: 40 - width: parent.width - 6 - anchors.horizontalCenter: parent.horizontalCenter - onClicked: buttonPress (3) - content: TileText - { - text: autoButtonText; font.bold: true; - color: autoButtonActive ? "white" : "black" - } - } - } - } - function updateFunction () - { - if (functionItem.valid) - { - relayFunction = functionItem.value - switch (relayFunction) - { - // Alarm - no buttons - case 0: - functionText = qsTr("Alarm") - activeText = qsTr("Alarm") - inactiveText = qsTr("No Alarm") - offButtonText = "" - onButtonText = "" - autoButtonText = "" - onButton.visible = false - offButton.visible = false - autoButton.visible = false - break;; - // Generator - case 1: - functionText = qsTr("Generator") - activeText = qsTr("") // generator state text handled below - inactiveText = qsTr("") - onButtonText = qsTr("Manual\nStart") - offButtonText = qsTr("Manual\nStop") - autoButtonText = qsTr("Auto\nEnable") - onButton.visible = true - offButton.visible = true - autoButton.visible = true - break;; - // pump - case 3: - functionText = qsTr("Pump") - activeText = qsTr("On") - inactiveText = qsTr("Off") - onButtonText = qsTr("On") - offButtonText = qsTr("Off") - autoButtonText = qsTr("Auto") - onButton.visible = true - offButton.visible = true - autoButton.visible = true - break;; - // temperature - case 4: - functionText = qsTr("Temp") - activeText = qsTr("Alarm") - inactiveText = qsTr("No Alarm") - onButtonText = "--" - offButtonText = "--" - autoButtonText = "--" - onButton.visible = false - offButton.visible = false - autoButton.visible = false - break;; - // manual (2) and undefined - default: - functionText = qsTr("Manual") - activeText = qsTr("On") - inactiveText = qsTr("Off") - onButtonText = qsTr("On") - offButtonText = qsTr("Off") - autoButtonText = "" - onButton.visible = true - offButton.visible = true - autoButton.visible = false - break;; - } - } - // only relay 1 has a function selector, so use manual settings for other relays - else - { - relayFunction = 2 - functionText = qsTr("Manual") - activeText = qsTr("On") - inactiveText = qsTr("Off") - onButtonText = qsTr("On") - offButtonText = qsTr("Off") - autoButtonText = "--" // empty string causes interactions - autoButton.visible = false - } - updateButtons () - } - - function updateButtons () - { - switch (relayFunction) - { - // alarm - no buttons - case 0: - break;; - // Generator - case 1: - if (generatorManualStartItem.valid) - { - onButtonActive = generatorManualStartItem.value === 1 - offButtonActive = ! onButtonActive - } - else - { - offButtonActive = false - onButtonActive = false - } - if (generatorAutoRunItem.valid) - autoButtonActive = generatorAutoRunItem.value - else - autoButtonActive = false - break;; - // pump - case 3: - if (pumpModeItem.valid) - { - switch (pumpModeItem.value) - { - // Auto - case 0: - onButtonActive = false - offButtonActive = false - autoButtonActive = true - break;; - // On - case 1: - onButtonActive = true - offButtonActive = false - autoButtonActive = false - break;; - // Off - case 2: - onButtonActive = false - offButtonActive = true - autoButtonActive = false - break;; - default: - onButtonActive = false - offButtonActive = false - autoButtonActive = false - break;; - } - } - else - { - offButtonActive = false - onButtonActive = false - autoButtonActive = false - } - break;; - // manual (2) and undefined - default: - relayActive = stateItem.value === 1 != relayInverted - onButtonActive = relayActive - offButtonActive = ! onButtonActive - autoButtonActive = false - break;; - } - } - - function buttonPress (button) - { - switch (relayFunction) - { - // Generator - case 1: - switch (button) - { - // on - case 1: - generatorManualStartItem.setValue (1) - break;; - // off - case 2: - generatorManualStartItem.setValue (0) - break;; - // auto - case 3: - // toggle value - generatorAutoRunItem.setValue (generatorAutoRunItem.value === 1 ? 0 : 1) - break;; - default: - break;; - } - break;; - // pump - case 3: - switch (button) - { - // on - case 1: - pumpModeItem.setValue (1) - break;; - // off - case 2: - pumpModeItem.setValue (2) - break;; - // auto - case 3: - pumpModeItem.setValue (0) - break;; - default: - break;; - } - break;; - // alarm - no buttons - case 0: - break;; - // manual (2) and undefined - default: - switch (button) - { - // on - case 1: - stateItem.setValue (1) - break;; - // off - case 2: - stateItem.setValue (0) - break;; - default: - break;; - } - break;; - } - } -} diff --git a/FileSets/v2.89/TileRelay.qml.orig b/FileSets/v2.89/TileRelay.qml.orig deleted file mode 100644 index 9b46079f..00000000 --- a/FileSets/v2.89/TileRelay.qml.orig +++ /dev/null @@ -1,23 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -PageGenerator { - - title: qsTr("Generator start/stop") - settingsBindPrefix: "com.victronenergy.settings/Settings/Generator0" - startStopBindPrefix: "com.victronenergy.generator.startstop0/Generator0" - - property VBusItem relayFunction: VBusItem { bind: Utils.path("com.victronenergy.settings", "/Settings/Relay/Function") } - - model: !relayFunction.valid || relayFunction.value === 1 ? startStopModel : disabledModel - - VisualItemModel { - id: disabledModel - MbItemText { - wrapMode: Text.WordWrap - text: qsTr("Generator start/stop function is not enabled, go to relay settings and set " + - "function to \"Generator start/stop\"") - } - } -} diff --git a/FileSets/v2.89/TileText.qml b/FileSets/v2.89/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v2.89/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.89/dbus_digitalinputs.py b/FileSets/v2.89/dbus_digitalinputs.py deleted file mode 100755 index c43295bc..00000000 --- a/FileSets/v2.89/dbus_digitalinputs.py +++ /dev/null @@ -1,553 +0,0 @@ -#!/usr/bin/python3 -u - -#### modified for ExtTransferSwitch package - -import sys, os -import signal -from threading import Thread -from select import select, epoll, EPOLLPRI -from functools import partial -from collections import namedtuple -from argparse import ArgumentParser -import traceback -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) - -from dbus.mainloop.glib import DBusGMainLoop -import dbus -from gi.repository import GLib -from vedbus import VeDbusService -from settingsdevice import SettingsDevice - -VERSION = '0.15' -MAXCOUNT = 2**31-1 -SAVEINTERVAL = 60000 - -INPUT_FUNCTION_COUNTER = 1 -INPUT_FUNCTION_INPUT = 2 - -Translation = namedtuple('Translation', ['no', 'yes']) - -# Only append at the end -INPUTTYPES = [ - 'Disabled', - 'Pulse meter', - 'Door', - 'Bilge pump', - 'Bilge alarm', - 'Burglar alarm', - 'Smoke alarm', - 'Fire alarm', - 'CO2 alarm', - 'Generator', -#### added for ExtTransferSwitch package - 'Generic I/O', #added to make following entry line up across versions -#### added for ExtTransferSwitch package -- must be LAST in the list - 'Transfer switch' -] - -# Translations. The text will be used only for GetText, it will be translated -# in the gui. -TRANSLATIONS = [ - Translation('low', 'high'), - Translation('off', 'on'), - Translation('no', 'yes'), - Translation('open', 'closed'), - Translation('ok', 'alarm'), - Translation('running', 'stopped'), -#### added for ExtTransferSwitch package - Translation('on generator', 'on grid') -] - -class SystemBus(dbus.bus.BusConnection): - def __new__(cls): - return dbus.bus.BusConnection.__new__(cls, dbus.bus.BusConnection.TYPE_SYSTEM) - -class SessionBus(dbus.bus.BusConnection): - def __new__(cls): - return dbus.bus.BusConnection.__new__(cls, dbus.bus.BusConnection.TYPE_SESSION) - -class BasePulseCounter(object): - pass - -class DebugPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - - def register(self, path, gpio): - self.gpiomap[gpio] = None - return 0 - - def unregister(self, gpio): - del self.gpiomap[gpio] - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - from itertools import cycle - from time import sleep - for level in cycle([0, 1]): - for gpio in list(self.gpiomap.keys()): - yield gpio, level - sleep(0.25/len(self.gpiomap)) - -class EpollPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - self.states = {} - self.ob = epoll() - - def register(self, path, gpio): - path = os.path.realpath(path) - - # Set up gpio for rising edge interrupts - with open(os.path.join(path, 'edge'), 'ab') as fp: - fp.write(b'both') - - fp = open(os.path.join(path, 'value'), 'rb') - level = int(fp.read()) # flush it in case it's high at startup - self.gpiomap[gpio] = fp - self.states[gpio] = level - self.ob.register(fp, EPOLLPRI) - return level - - def unregister(self, gpio): - fp = self.gpiomap[gpio] - self.ob.unregister(fp) - del self.gpiomap[gpio] - del self.states[gpio] - fp.close() - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - while True: - # We have a timeout of 1 second on the poll, because poll() only - # looks at files in the epoll object at the time poll() was called. - # The timeout means we let other files (added via calls to - # register/unregister) into the loop at least that often. - self.ob.poll(1) - - # When coming out of the epoll call, we read all the gpios to make - # sure we didn't miss any edges. This is a safety fallback that - # ensures everything is up to date once a second, but - # edge-triggered results are handled immediately. - # NOTE: There has not been a report of a missed interrupt yet. - # Belts and suspenders. - for gpio, fp in list(self.gpiomap.items()): - os.lseek(fp.fileno(), 0, os.SEEK_SET) - v = int(os.read(fp.fileno(), 1)) - if v != self.states[gpio]: - self.states[gpio] = v - yield gpio, v - -class PollingPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - - def register(self, path, gpio): - path = os.path.realpath(path) - - fp = open(os.path.join(path, 'value'), 'rb') - level = int(fp.read()) - self.gpiomap[gpio] = [fp, level] - return level - - def unregister(self, gpio): - del self.gpiomap[gpio] - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - from itertools import cycle - from time import sleep - while True: - for gpio, (fp, level) in list(self.gpiomap.items()): - fp.seek(0, os.SEEK_SET) - v = int(fp.read()) - if v != level: - self.gpiomap[gpio][1] = v - yield gpio, v - sleep(1) - -class HandlerMaker(type): - """ Meta-class for keeping track of all extended classes. """ - def __init__(cls, name, bases, attrs): - if not hasattr(cls, 'handlers'): - cls.handlers = {} - else: - cls.handlers[cls.type_id] = cls - -class PinHandler(object, metaclass=HandlerMaker): - product_id = 0xFFFF - _product_name = 'Generic GPIO' - dbus_name = "digital" - def __init__(self, bus, base, path, gpio, settings): - self.gpio = gpio - self.path = path - self.bus = bus - self.settings = settings - self._level = 0 # Remember last state - - self.service = VeDbusService( - "{}.{}.input{:02d}".format(base, self.dbus_name, gpio), bus=bus) - - # Add objects required by ve-api - self.service.add_path('/Mgmt/ProcessName', __file__) - self.service.add_path('/Mgmt/ProcessVersion', VERSION) - self.service.add_path('/Mgmt/Connection', path) - self.service.add_path('/DeviceInstance', gpio) - self.service.add_path('/ProductId', self.product_id) - self.service.add_path('/ProductName', self.product_name) - self.service.add_path('/Connected', 1) - - # Custom name setting - def _change_name(p, v): - # This should fire a change event that will update product_name - # below. - settings['name'] = v - return True - - self.service.add_path('/CustomName', settings['name'], writeable=True, - onchangecallback=_change_name) - - # We'll count the pulses for all types of services - self.service.add_path('/Count', value=settings['count']) - - @property - def product_name(self): - return self.settings['name'] or self._product_name - - @product_name.setter - def product_name(self, v): - # Some pin types don't have an associated service (Disabled pins for - # example) - if self.service is not None: - self.service['/ProductName'] = v or self._product_name - - def deactivate(self): - self.save_count() - self.service.__del__() - del self.service - self.service = None - - @property - def level(self): - return self._level - - @level.setter - def level(self, l): - self._level = int(bool(l)) - - def toggle(self, level): - # Only increment Count on rising edge. - if level and level != self._level: - self.service['/Count'] = (self.service['/Count']+1) % MAXCOUNT - self._level = level - - def refresh(self): - """ Toggle state to last remembered state. This is called if settings - are changed so the Service can recalculate paths. """ - self.toggle(self._level) - - def save_count(self): - if self.service is not None: - self.settings['count'] = self.count - - @property - def active(self): - return self.service is not None - - @property - def count(self): - return self.service['/Count'] - - @count.setter - def count(self, v): - self.service['/Count'] = v - - @classmethod - def createHandler(cls, _type, *args, **kwargs): - if _type in cls.handlers: - return cls.handlers[_type](*args, **kwargs) - return None - - -class DisabledPin(PinHandler): - """ Place holder for a disabled pin. """ - _product_name = 'Disabled' - type_id = 0 - def __init__(self, bus, base, path, gpio, settings): - self.service = None - self.bus = bus - self.settings = settings - self._level = 0 # Remember last state - - def deactivate(self): - pass - - def toggle(self, level): - self._level = level - - def save_count(self): - # Do nothing - pass - - @property - def count(self): - return self.settings['count'] - - @count.setter - def count(self, v): - pass - - def refresh(self): - pass - - -class VolumeCounter(PinHandler): - product_id = 0xA165 - _product_name = "Generic pulse meter" - dbus_name = "pulsemeter" - type_id = 1 - - def __init__(self, bus, base, path, gpio, settings): - super(VolumeCounter, self).__init__(bus, base, path, gpio, settings) - self.service.add_path('/Aggregate', value=self.count*self.rate, - gettextcallback=lambda p, v: (str(v) + ' cubic meter')) - - @property - def rate(self): - return self.settings['rate'] - - def toggle(self, level): - super(VolumeCounter, self).toggle(level) - self.service['/Aggregate'] = self.count * self.rate - -class PinAlarm(PinHandler): - product_id = 0xA166 - _product_name = "Generic digital input" - dbus_name = "digitalinput" - type_id = 0xFF - translation = 0 # low, high - - def __init__(self, bus, base, path, gpio, settings): - super(PinAlarm, self).__init__(bus, base, path, gpio, settings) - self.service.add_path('/InputState', value=0) - self.service.add_path('/State', value=self.get_state(0), - gettextcallback=lambda p, v: TRANSLATIONS[v//2][v%2]) - self.service.add_path('/Alarm', value=self.get_alarm_state(0)) - - # Also expose the type - self.service.add_path('/Type', value=self.type_id, - gettextcallback=lambda p, v: INPUTTYPES[v]) - - def toggle(self, level): - super(PinAlarm, self).toggle(level) - self.service['/InputState'] = bool(level)*1 - self.service['/State'] = self.get_state(level) - # Ensure that the alarm flag resets if the /AlarmSetting config option - # disappears. - self.service['/Alarm'] = self.get_alarm_state(level) - - def get_state(self, level): - state = level ^ self.settings['invert'] - return 2 * self.translation + state - - def get_alarm_state(self, level): - return 2 * bool( - (level ^ self.settings['invertalarm']) and self.settings['alarm']) - - -# Various types of things we might want to monitor -class DoorSensor(PinAlarm): - _product_name = "Door alarm" - type_id = 2 - translation = 3 # open, closed - -class BilgePump(PinAlarm): - _product_name = "Bilge pump" - type_id = 3 - translation = 1 # off, on - -class BilgeAlarm(PinAlarm): - _product_name = "Bilge alarm" - type_id = 4 - translation = 4 # ok, alarm - -class BurglarAlarm(PinAlarm): - _product_name = "Burglar alarm" - type_id = 5 - translation = 4 # ok, alarm - -class SmokeAlarm(PinAlarm): - _product_name = "Smoke alarm" - type_id = 6 - translation = 4 # ok, alarm - -class FireAlarm(PinAlarm): - _product_name = "Fire alarm" - type_id = 7 - translation = 4 # ok, alarm - -class CO2Alarm(PinAlarm): - _product_name = "CO2 alarm" - type_id = 8 - translation = 4 # ok, alarm - -class Generator(PinAlarm): - _product_name = "Generator" - type_id = 9 - translation = 5 # running, stopped - -#### added for ExtTransferSwitch package -class GenericIO(PinAlarm): - _product_name = "Generic I/O" - type_id = 10 - translation = 0 # low, high - -class TransferSwitch(PinAlarm): - _product_name = "External AC Input transfer switch" - type_id = 11 - translation = 5 # Grid In / Generator In - - -def dbusconnection(): - return SessionBus() if 'DBUS_SESSION_BUS_ADDRESS' in os.environ else SystemBus() - - -def main(): - parser = ArgumentParser(description=sys.argv[0]) - parser.add_argument('--servicebase', - help='Base service name on dbus, default is com.victronenergy', - default='com.victronenergy') - parser.add_argument('--poll', - help='Use a different kind of polling. Options are epoll, dumb and debug', - default='epoll') - parser.add_argument('inputs', nargs='+', help='Path to digital input') - args = parser.parse_args() - - PulseCounter = { - 'debug': DebugPulseCounter, - 'poll': PollingPulseCounter, - }.get(args.poll, EpollPulseCounter) - - DBusGMainLoop(set_as_default=True) - - # Keep track of enabled services - services = {} - inputs = dict(enumerate(args.inputs, 1)) - pulses = PulseCounter() # callable that iterates over pulses - - def register_gpio(path, gpio, bus, settings): - _type = settings['inputtype'] - print ("Registering GPIO {} for type {}".format(gpio, _type)) - - handler = PinHandler.createHandler(_type, - bus, args.servicebase, path, gpio, settings) - services[gpio] = handler - - # Only monitor if enabled - if _type > 0: - handler.level = pulses.register(path, gpio) - handler.refresh() - - def unregister_gpio(gpio): - print ("unRegistering GPIO {}".format(gpio)) - pulses.unregister(gpio) - services[gpio].deactivate() - - def handle_setting_change(inp, setting, old, new): - if setting == 'inputtype': - if new: - # Get current bus and settings objects, to be reused - service = services[inp] - bus, settings = service.bus, service.settings - - # Input enabled. If already enabled, unregister the old one first. - if pulses.registered(inp): - unregister_gpio(inp) - - # Before registering the new input, reset its settings to defaults - settings['count'] = 0 - settings['invert'] = 0 - settings['invertalarm'] = 0 - settings['alarm'] = 0 - - # Register it - register_gpio(inputs[inp], inp, bus, settings) - elif old: - # Input disabled - unregister_gpio(inp) - elif setting in ('rate', 'invert', 'alarm', 'invertalarm'): - services[inp].refresh() - elif setting == 'name': - services[inp].product_name = new - elif setting == 'count': - # Don't want this triggered on a period save, so only execute - # if it has changed. - v = int(new) - s = services[inp] - if s.count != v: - s.count = v - s.refresh() - - for inp, pth in inputs.items(): - supported_settings = { - 'inputtype': ['/Settings/DigitalInput/{}/Type'.format(inp), 0, 0, len(INPUTTYPES)], - 'rate': ['/Settings/DigitalInput/{}/Multiplier'.format(inp), 0.001, 0, 1.0], - 'count': ['/Settings/DigitalInput/{}/Count'.format(inp), 0, 0, MAXCOUNT, 1], - 'invert': ['/Settings/DigitalInput/{}/InvertTranslation'.format(inp), 0, 0, 1], - 'invertalarm': ['/Settings/DigitalInput/{}/InvertAlarm'.format(inp), 0, 0, 1], - 'alarm': ['/Settings/DigitalInput/{}/AlarmSetting'.format(inp), 0, 0, 1], - 'name': ['/Settings/DigitalInput/{}/CustomName'.format(inp), '', '', ''], - } - bus = dbusconnection() - sd = SettingsDevice(bus, supported_settings, partial(handle_setting_change, inp), timeout=10) - register_gpio(pth, inp, bus, sd) - - def poll(mainloop): - from time import time - idx = 0 - - try: - for inp, level in pulses(): - # epoll object only resyncs once a second. We may receive - # a pulse for something that's been deregistered. - try: - services[inp].toggle(level) - except KeyError: - continue - except: - traceback.print_exc() - mainloop.quit() - - # Need to run the gpio polling in separate thread. Pass in the mainloop so - # the thread can kill us if there is an exception. - mainloop = GLib.MainLoop() - - poller = Thread(target=lambda: poll(mainloop)) - poller.daemon = True - poller.start() - - # Periodically save the counter - def save_counters(): - for inp in inputs: - services[inp].save_count() - return True - GLib.timeout_add(SAVEINTERVAL, save_counters) - - # Save counter on shutdown - signal.signal(signal.SIGTERM, lambda *args: sys.exit(0)) - - try: - mainloop.run() - except KeyboardInterrupt: - pass - finally: - save_counters() - -if __name__ == "__main__": - main() diff --git a/FileSets/v2.89/dbus_digitalinputs.py.orig b/FileSets/v2.89/dbus_digitalinputs.py.orig deleted file mode 100755 index 79b58848..00000000 --- a/FileSets/v2.89/dbus_digitalinputs.py.orig +++ /dev/null @@ -1,534 +0,0 @@ -#!/usr/bin/python3 -u - -import sys, os -import signal -from threading import Thread -from select import select, epoll, EPOLLPRI -from functools import partial -from collections import namedtuple -from argparse import ArgumentParser -import traceback -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) - -from dbus.mainloop.glib import DBusGMainLoop -import dbus -from gi.repository import GLib -from vedbus import VeDbusService -from settingsdevice import SettingsDevice - -VERSION = '0.15' -MAXCOUNT = 2**31-1 -SAVEINTERVAL = 60000 - -INPUT_FUNCTION_COUNTER = 1 -INPUT_FUNCTION_INPUT = 2 - -Translation = namedtuple('Translation', ['no', 'yes']) - -# Only append at the end -INPUTTYPES = [ - 'Disabled', - 'Pulse meter', - 'Door', - 'Bilge pump', - 'Bilge alarm', - 'Burglar alarm', - 'Smoke alarm', - 'Fire alarm', - 'CO2 alarm', - 'Generator' -] - -# Translations. The text will be used only for GetText, it will be translated -# in the gui. -TRANSLATIONS = [ - Translation('low', 'high'), - Translation('off', 'on'), - Translation('no', 'yes'), - Translation('open', 'closed'), - Translation('ok', 'alarm'), - Translation('running', 'stopped') -] - -class SystemBus(dbus.bus.BusConnection): - def __new__(cls): - return dbus.bus.BusConnection.__new__(cls, dbus.bus.BusConnection.TYPE_SYSTEM) - -class SessionBus(dbus.bus.BusConnection): - def __new__(cls): - return dbus.bus.BusConnection.__new__(cls, dbus.bus.BusConnection.TYPE_SESSION) - -class BasePulseCounter(object): - pass - -class DebugPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - - def register(self, path, gpio): - self.gpiomap[gpio] = None - return 0 - - def unregister(self, gpio): - del self.gpiomap[gpio] - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - from itertools import cycle - from time import sleep - for level in cycle([0, 1]): - for gpio in list(self.gpiomap.keys()): - yield gpio, level - sleep(0.25/len(self.gpiomap)) - -class EpollPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - self.states = {} - self.ob = epoll() - - def register(self, path, gpio): - path = os.path.realpath(path) - - # Set up gpio for rising edge interrupts - with open(os.path.join(path, 'edge'), 'ab') as fp: - fp.write(b'both') - - fp = open(os.path.join(path, 'value'), 'rb') - level = int(fp.read()) # flush it in case it's high at startup - self.gpiomap[gpio] = fp - self.states[gpio] = level - self.ob.register(fp, EPOLLPRI) - return level - - def unregister(self, gpio): - fp = self.gpiomap[gpio] - self.ob.unregister(fp) - del self.gpiomap[gpio] - del self.states[gpio] - fp.close() - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - while True: - # We have a timeout of 1 second on the poll, because poll() only - # looks at files in the epoll object at the time poll() was called. - # The timeout means we let other files (added via calls to - # register/unregister) into the loop at least that often. - self.ob.poll(1) - - # When coming out of the epoll call, we read all the gpios to make - # sure we didn't miss any edges. This is a safety fallback that - # ensures everything is up to date once a second, but - # edge-triggered results are handled immediately. - # NOTE: There has not been a report of a missed interrupt yet. - # Belts and suspenders. - for gpio, fp in list(self.gpiomap.items()): - os.lseek(fp.fileno(), 0, os.SEEK_SET) - v = int(os.read(fp.fileno(), 1)) - if v != self.states[gpio]: - self.states[gpio] = v - yield gpio, v - -class PollingPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - - def register(self, path, gpio): - path = os.path.realpath(path) - - fp = open(os.path.join(path, 'value'), 'rb') - level = int(fp.read()) - self.gpiomap[gpio] = [fp, level] - return level - - def unregister(self, gpio): - del self.gpiomap[gpio] - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - from itertools import cycle - from time import sleep - while True: - for gpio, (fp, level) in list(self.gpiomap.items()): - fp.seek(0, os.SEEK_SET) - v = int(fp.read()) - if v != level: - self.gpiomap[gpio][1] = v - yield gpio, v - sleep(1) - -class HandlerMaker(type): - """ Meta-class for keeping track of all extended classes. """ - def __init__(cls, name, bases, attrs): - if not hasattr(cls, 'handlers'): - cls.handlers = {} - else: - cls.handlers[cls.type_id] = cls - -class PinHandler(object, metaclass=HandlerMaker): - product_id = 0xFFFF - _product_name = 'Generic GPIO' - dbus_name = "digital" - def __init__(self, bus, base, path, gpio, settings): - self.gpio = gpio - self.path = path - self.bus = bus - self.settings = settings - self._level = 0 # Remember last state - - self.service = VeDbusService( - "{}.{}.input{:02d}".format(base, self.dbus_name, gpio), bus=bus) - - # Add objects required by ve-api - self.service.add_path('/Mgmt/ProcessName', __file__) - self.service.add_path('/Mgmt/ProcessVersion', VERSION) - self.service.add_path('/Mgmt/Connection', path) - self.service.add_path('/DeviceInstance', gpio) - self.service.add_path('/ProductId', self.product_id) - self.service.add_path('/ProductName', self.product_name) - self.service.add_path('/Connected', 1) - - # Custom name setting - def _change_name(p, v): - # This should fire a change event that will update product_name - # below. - settings['name'] = v - return True - - self.service.add_path('/CustomName', settings['name'], writeable=True, - onchangecallback=_change_name) - - # We'll count the pulses for all types of services - self.service.add_path('/Count', value=settings['count']) - - @property - def product_name(self): - return self.settings['name'] or self._product_name - - @product_name.setter - def product_name(self, v): - # Some pin types don't have an associated service (Disabled pins for - # example) - if self.service is not None: - self.service['/ProductName'] = v or self._product_name - - def deactivate(self): - self.save_count() - self.service.__del__() - del self.service - self.service = None - - @property - def level(self): - return self._level - - @level.setter - def level(self, l): - self._level = int(bool(l)) - - def toggle(self, level): - # Only increment Count on rising edge. - if level and level != self._level: - self.service['/Count'] = (self.service['/Count']+1) % MAXCOUNT - self._level = level - - def refresh(self): - """ Toggle state to last remembered state. This is called if settings - are changed so the Service can recalculate paths. """ - self.toggle(self._level) - - def save_count(self): - if self.service is not None: - self.settings['count'] = self.count - - @property - def active(self): - return self.service is not None - - @property - def count(self): - return self.service['/Count'] - - @count.setter - def count(self, v): - self.service['/Count'] = v - - @classmethod - def createHandler(cls, _type, *args, **kwargs): - if _type in cls.handlers: - return cls.handlers[_type](*args, **kwargs) - return None - - -class DisabledPin(PinHandler): - """ Place holder for a disabled pin. """ - _product_name = 'Disabled' - type_id = 0 - def __init__(self, bus, base, path, gpio, settings): - self.service = None - self.bus = bus - self.settings = settings - self._level = 0 # Remember last state - - def deactivate(self): - pass - - def toggle(self, level): - self._level = level - - def save_count(self): - # Do nothing - pass - - @property - def count(self): - return self.settings['count'] - - @count.setter - def count(self, v): - pass - - def refresh(self): - pass - - -class VolumeCounter(PinHandler): - product_id = 0xA165 - _product_name = "Generic pulse meter" - dbus_name = "pulsemeter" - type_id = 1 - - def __init__(self, bus, base, path, gpio, settings): - super(VolumeCounter, self).__init__(bus, base, path, gpio, settings) - self.service.add_path('/Aggregate', value=self.count*self.rate, - gettextcallback=lambda p, v: (str(v) + ' cubic meter')) - - @property - def rate(self): - return self.settings['rate'] - - def toggle(self, level): - super(VolumeCounter, self).toggle(level) - self.service['/Aggregate'] = self.count * self.rate - -class PinAlarm(PinHandler): - product_id = 0xA166 - _product_name = "Generic digital input" - dbus_name = "digitalinput" - type_id = 0xFF - translation = 0 # low, high - - def __init__(self, bus, base, path, gpio, settings): - super(PinAlarm, self).__init__(bus, base, path, gpio, settings) - self.service.add_path('/InputState', value=0) - self.service.add_path('/State', value=self.get_state(0), - gettextcallback=lambda p, v: TRANSLATIONS[v//2][v%2]) - self.service.add_path('/Alarm', value=self.get_alarm_state(0)) - - # Also expose the type - self.service.add_path('/Type', value=self.type_id, - gettextcallback=lambda p, v: INPUTTYPES[v]) - - def toggle(self, level): - super(PinAlarm, self).toggle(level) - self.service['/InputState'] = bool(level)*1 - self.service['/State'] = self.get_state(level) - # Ensure that the alarm flag resets if the /AlarmSetting config option - # disappears. - self.service['/Alarm'] = self.get_alarm_state(level) - - def get_state(self, level): - state = level ^ self.settings['invert'] - return 2 * self.translation + state - - def get_alarm_state(self, level): - return 2 * bool( - (level ^ self.settings['invertalarm']) and self.settings['alarm']) - - -# Various types of things we might want to monitor -class DoorSensor(PinAlarm): - _product_name = "Door alarm" - type_id = 2 - translation = 3 # open, closed - -class BilgePump(PinAlarm): - _product_name = "Bilge pump" - type_id = 3 - translation = 1 # off, on - -class BilgeAlarm(PinAlarm): - _product_name = "Bilge alarm" - type_id = 4 - translation = 4 # ok, alarm - -class BurglarAlarm(PinAlarm): - _product_name = "Burglar alarm" - type_id = 5 - translation = 4 # ok, alarm - -class SmokeAlarm(PinAlarm): - _product_name = "Smoke alarm" - type_id = 6 - translation = 4 # ok, alarm - -class FireAlarm(PinAlarm): - _product_name = "Fire alarm" - type_id = 7 - translation = 4 # ok, alarm - -class CO2Alarm(PinAlarm): - _product_name = "CO2 alarm" - type_id = 8 - translation = 4 # ok, alarm - -class Generator(PinAlarm): - _product_name = "Generator" - type_id = 9 - translation = 5 # running, stopped - - -def dbusconnection(): - return SessionBus() if 'DBUS_SESSION_BUS_ADDRESS' in os.environ else SystemBus() - - -def main(): - parser = ArgumentParser(description=sys.argv[0]) - parser.add_argument('--servicebase', - help='Base service name on dbus, default is com.victronenergy', - default='com.victronenergy') - parser.add_argument('--poll', - help='Use a different kind of polling. Options are epoll, dumb and debug', - default='epoll') - parser.add_argument('inputs', nargs='+', help='Path to digital input') - args = parser.parse_args() - - PulseCounter = { - 'debug': DebugPulseCounter, - 'poll': PollingPulseCounter, - }.get(args.poll, EpollPulseCounter) - - DBusGMainLoop(set_as_default=True) - - # Keep track of enabled services - services = {} - inputs = dict(enumerate(args.inputs, 1)) - pulses = PulseCounter() # callable that iterates over pulses - - def register_gpio(path, gpio, bus, settings): - _type = settings['inputtype'] - print ("Registering GPIO {} for type {}".format(gpio, _type)) - - handler = PinHandler.createHandler(_type, - bus, args.servicebase, path, gpio, settings) - services[gpio] = handler - - # Only monitor if enabled - if _type > 0: - handler.level = pulses.register(path, gpio) - handler.refresh() - - def unregister_gpio(gpio): - print ("unRegistering GPIO {}".format(gpio)) - pulses.unregister(gpio) - services[gpio].deactivate() - - def handle_setting_change(inp, setting, old, new): - if setting == 'inputtype': - if new: - # Get current bus and settings objects, to be reused - service = services[inp] - bus, settings = service.bus, service.settings - - # Input enabled. If already enabled, unregister the old one first. - if pulses.registered(inp): - unregister_gpio(inp) - - # Before registering the new input, reset its settings to defaults - settings['count'] = 0 - settings['invert'] = 0 - settings['invertalarm'] = 0 - settings['alarm'] = 0 - - # Register it - register_gpio(inputs[inp], inp, bus, settings) - elif old: - # Input disabled - unregister_gpio(inp) - elif setting in ('rate', 'invert', 'alarm', 'invertalarm'): - services[inp].refresh() - elif setting == 'name': - services[inp].product_name = new - elif setting == 'count': - # Don't want this triggered on a period save, so only execute - # if it has changed. - v = int(new) - s = services[inp] - if s.count != v: - s.count = v - s.refresh() - - for inp, pth in inputs.items(): - supported_settings = { - 'inputtype': ['/Settings/DigitalInput/{}/Type'.format(inp), 0, 0, len(INPUTTYPES)], - 'rate': ['/Settings/DigitalInput/{}/Multiplier'.format(inp), 0.001, 0, 1.0], - 'count': ['/Settings/DigitalInput/{}/Count'.format(inp), 0, 0, MAXCOUNT, 1], - 'invert': ['/Settings/DigitalInput/{}/InvertTranslation'.format(inp), 0, 0, 1], - 'invertalarm': ['/Settings/DigitalInput/{}/InvertAlarm'.format(inp), 0, 0, 1], - 'alarm': ['/Settings/DigitalInput/{}/AlarmSetting'.format(inp), 0, 0, 1], - 'name': ['/Settings/DigitalInput/{}/CustomName'.format(inp), '', '', ''], - } - bus = dbusconnection() - sd = SettingsDevice(bus, supported_settings, partial(handle_setting_change, inp), timeout=10) - register_gpio(pth, inp, bus, sd) - - def poll(mainloop): - from time import time - idx = 0 - - try: - for inp, level in pulses(): - # epoll object only resyncs once a second. We may receive - # a pulse for something that's been deregistered. - try: - services[inp].toggle(level) - except KeyError: - continue - except: - traceback.print_exc() - mainloop.quit() - - # Need to run the gpio polling in separate thread. Pass in the mainloop so - # the thread can kill us if there is an exception. - mainloop = GLib.MainLoop() - - poller = Thread(target=lambda: poll(mainloop)) - poller.daemon = True - poller.start() - - # Periodically save the counter - def save_counters(): - for inp in inputs: - services[inp].save_count() - return True - GLib.timeout_add(SAVEINTERVAL, save_counters) - - # Save counter on shutdown - signal.signal(signal.SIGTERM, lambda *args: sys.exit(0)) - - try: - mainloop.run() - except KeyboardInterrupt: - pass - finally: - save_counters() - -if __name__ == "__main__": - main() diff --git a/FileSets/v2.89/dbus_generator.py b/FileSets/v2.89/dbus_generator.py deleted file mode 100755 index e71c1381..00000000 --- a/FileSets/v2.89/dbus_generator.py +++ /dev/null @@ -1,351 +0,0 @@ -#!/usr/bin/python3 -u -# -*- coding: utf-8 -*- - -#### GuiMods -#### This file has been modified to allow the generator running state derived from the generator digital input -#### or the genset AC input -#### If the incoming generator state changes, the manual start state is updated -#### time accumulation is suspended when the generator is not running -#### A switch in the generator settings menucontrols whethter the incoming state affects manual start or time accumulaiton -#### It is now possible to start the generator manually and have it stop automatically based on the preset conditions -#### for automaitc start / stop -#### A service interval timer was added so the accumulated run time does not need to be reset, -#### providing total run time for the generator -#### Search for #### GuiMods to find changes - -from dbus.mainloop.glib import DBusGMainLoop -import dbus -import argparse -import sys -import os -import signal -from gi.repository import GLib - -# Victron packages -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) -from vedbus import VeDbusService -from ve_utils import exit_on_error -from dbusmonitor import DbusMonitor -from settingsdevice import SettingsDevice -from logger import setup_logging -import logging -from gen_utils import dummy -import time -import relay -import fischerpanda - -softwareversion = '1.4.6' - -class Generator: - def __init__(self): - self._exit = False - self._instances = {} - self._modules = [relay, fischerpanda] - - # Common dbus services/path - commondbustree = { - 'com.victronenergy.settings': { - '/Settings/System/TimeZone': dummy, -#### GuiMods - paths are not correct in stock files - '/Settings/SystemSetup/AcInput1': dummy, - '/Settings/SystemSetup/AcInput2': dummy, - - '/Settings/Relay/Polarity': dummy - }, - 'com.victronenergy.battery': { - '/Dc/0/Voltage': dummy, - '/Dc/0/Current': dummy, - '/Dc/1/Voltage': dummy, - '/Dc/1/Current': dummy, - '/Soc': dummy - }, - 'com.victronenergy.vebus': { - '/Ac/Out/L1/P': dummy, - '/Ac/Out/L2/P': dummy, - '/Ac/Out/L3/P': dummy, - '/Alarms/L1/Overload': dummy, - '/Alarms/L2/Overload': dummy, - '/Alarms/L3/Overload': dummy, - '/Alarms/L1/HighTemperature': dummy, - '/Alarms/L2/HighTemperature': dummy, - '/Alarms/L3/HighTemperature': dummy, - '/Alarms/HighTemperature': dummy, - '/Alarms/Overload': dummy, - '/Ac/ActiveIn/ActiveInput': dummy, - '/Ac/ActiveIn/Connected': dummy, - '/Dc/0/Voltage': dummy, - '/Dc/0/Current': dummy, - '/Dc/1/Voltage': dummy, - '/Dc/1/Current': dummy, - '/Soc': dummy - }, - 'com.victronenergy.system': { - '/Ac/ConsumptionOnInput/L1/Power': dummy, - '/Ac/ConsumptionOnInput/L2/Power': dummy, - '/Ac/ConsumptionOnInput/L3/Power': dummy, - '/Ac/ConsumptionOnOutput/L1/Power': dummy, - '/Ac/ConsumptionOnOutput/L2/Power': dummy, - '/Ac/ConsumptionOnOutput/L3/Power': dummy, - '/Dc/Pv/Power': dummy, - '/AutoSelectedBatteryMeasurement': dummy, - '/Ac/ActiveIn/Source': dummy, - '/VebusService': dummy, - '/Dc/Battery/Voltage': dummy, - '/Dc/Battery/Current': dummy, - '/Dc/Battery/Soc': dummy, -#### GuiMods - '/Ac/Genset/Frequency': dummy, - '/Ac/In/NumberOfAcInputs': dummy - } - } - - # Settings base - settingsbase = { - 'autostart': ['/Settings/{0}/AutoStartEnabled', 1, 0, 1], - 'batterymeasurement': ['/Settings/{0}/Service', '', 0, 0], - 'accumulateddaily': ['/Settings/{0}/AccumulatedDaily', '', 0, 0, True], - 'accumulatedtotal': ['/Settings/{0}/AccumulatedTotal', 0, 0, 0, True], -#### GuiMods - 'timeSinceService': ['/Settings/{0}/TimeSinceService', 0, 0, 0, True], - 'linkManualStartToExternal': ['/Settings/{0}/LinkToExternalStatus', 0, 0, 0, True], - - 'batterymeasurement': ['/Settings/{0}/BatteryService', 'default', 0, 0], - 'minimumruntime': ['/Settings/{0}/MinimumRuntime', 0, 0, 86400], # minutes - 'stoponac1enabled': ['/Settings/{0}/StopWhenAc1Available', 0, 0, 10], - # On permanent loss of communication: 0 = Stop, 1 = Start, 2 = keep running - 'onlosscommunication': ['/Settings/{0}/OnLossCommunication', 0, 0, 2], - # Quiet hours - 'quiethoursenabled': ['/Settings/{0}/QuietHours/Enabled', 0, 0, 1], - 'quiethoursstarttime': ['/Settings/{0}/QuietHours/StartTime', 75600, 0, 86400], - 'quiethoursendtime': ['/Settings/{0}/QuietHours/EndTime', 21600, 0, 86400], - # SOC - 'socenabled': ['/Settings/{0}/Soc/Enabled', 0, 0, 1], - 'socstart': ['/Settings/{0}/Soc/StartValue', 80, 0, 100], - 'socstop': ['/Settings/{0}/Soc/StopValue', 90, 0, 100], - 'qh_socstart': ['/Settings/{0}/Soc/QuietHoursStartValue', 90, 0, 100], - 'qh_socstop': ['/Settings/{0}/Soc/QuietHoursStopValue', 90, 0, 100], - # Voltage - 'batteryvoltageenabled': ['/Settings/{0}/BatteryVoltage/Enabled', 0, 0, 1], - 'batteryvoltagestart': ['/Settings/{0}/BatteryVoltage/StartValue', 11.5, 0, 150], - 'batteryvoltagestop': ['/Settings/{0}/BatteryVoltage/StopValue', 12.4, 0, 150], - 'batteryvoltagestarttimer': ['/Settings/{0}/BatteryVoltage/StartTimer', 20, 0, 10000], - 'batteryvoltagestoptimer': ['/Settings/{0}/BatteryVoltage/StopTimer', 20, 0, 10000], - 'qh_batteryvoltagestart': ['/Settings/{0}/BatteryVoltage/QuietHoursStartValue', 11.9, 0, 100], - 'qh_batteryvoltagestop': ['/Settings/{0}/BatteryVoltage/QuietHoursStopValue', 12.4, 0, 100], - # Current - 'batterycurrentenabled': ['/Settings/{0}/BatteryCurrent/Enabled', 0, 0, 1], - 'batterycurrentstart': ['/Settings/{0}/BatteryCurrent/StartValue', 10.5, 0.5, 10000], - 'batterycurrentstop': ['/Settings/{0}/BatteryCurrent/StopValue', 5.5, 0, 10000], - 'batterycurrentstarttimer': ['/Settings/{0}/BatteryCurrent/StartTimer', 20, 0, 10000], - 'batterycurrentstoptimer': ['/Settings/{0}/BatteryCurrent/StopTimer', 20, 0, 10000], - 'qh_batterycurrentstart': ['/Settings/{0}/BatteryCurrent/QuietHoursStartValue', 20.5, 0, 10000], - 'qh_batterycurrentstop': ['/Settings/{0}/BatteryCurrent/QuietHoursStopValue', 15.5, 0, 10000], - # AC load - 'acloadenabled': ['/Settings/{0}/AcLoad/Enabled', 0, 0, 1], - # Measuerement, 0 = Total AC consumption, 1 = AC on inverter output, 2 = Single phase - 'acloadmeasuerment': ['/Settings/{0}/AcLoad/Measurement', 0, 0, 100], - 'acloadstart': ['/Settings/{0}/AcLoad/StartValue', 1600, 5, 1000000], - 'acloadstop': ['/Settings/{0}/AcLoad/StopValue', 800, 0, 1000000], - 'acloadstarttimer': ['/Settings/{0}/AcLoad/StartTimer', 20, 0, 10000], - 'acloadstoptimer': ['/Settings/{0}/AcLoad/StopTimer', 20, 0, 10000], - 'qh_acloadstart': ['/Settings/{0}/AcLoad/QuietHoursStartValue', 1900, 0, 1000000], - 'qh_acloadstop': ['/Settings/{0}/AcLoad/QuietHoursStopValue', 1200, 0, 1000000], - # VE.Bus high temperature - 'inverterhightempenabled': ['/Settings/{0}/InverterHighTemp/Enabled', 0, 0, 1], - 'inverterhightempstarttimer': ['/Settings/{0}/InverterHighTemp/StartTimer', 20, 0, 10000], - 'inverterhightempstoptimer': ['/Settings/{0}/InverterHighTemp/StopTimer', 20, 0, 10000], - # VE.Bus overload - 'inverteroverloadenabled': ['/Settings/{0}/InverterOverload/Enabled', 0, 0, 1], - 'inverteroverloadstarttimer': ['/Settings/{0}/InverterOverload/StartTimer', 20, 0, 10000], - 'inverteroverloadstoptimer': ['/Settings/{0}/InverterOverload/StopTimer', 20, 0, 10000], - # TestRun - 'testrunenabled': ['/Settings/{0}/TestRun/Enabled', 0, 0, 1], - 'testrunstartdate': ['/Settings/{0}/TestRun/StartDate', 1483228800, 0, 10000000000.1], - 'testrunstarttimer': ['/Settings/{0}/TestRun/StartTime', 54000, 0, 86400], - 'testruninterval': ['/Settings/{0}/TestRun/Interval', 28, 1, 365], - 'testrunruntime': ['/Settings/{0}/TestRun/Duration', 7200, 1, 86400], - 'testrunskipruntime': ['/Settings/{0}/TestRun/SkipRuntime', 0, 0, 100000], - 'testruntillbatteryfull': ['/Settings/{0}/TestRun/RunTillBatteryFull', 0, 0, 1], - # Alarms - 'nogeneratoratacinalarm': ['/Settings/{0}/Alarms/NoGeneratorAtAcIn', 0, 0, 1] - } - - settings = {} - dbus_tree = dict(commondbustree) - - for m in self._modules: - # Create settings for each module - # Settings are created under the module prefix, for example: - # /Settings/Generator0/AcLoad/Enabled - # /Settings/FischerPanda0/AcLoad/Enabled - for s in settingsbase: - v = settingsbase[s][:] # Copy - v[0] = v[0].format(m.name) - settings[s + m.name] = v - - # Get all services/paths that must be monitored - # There are a base of common services/pathas that must be monitored - # for the correct function such as battery monitors of vebus devices - # and a extra ones that is only used by a certain module, these - # are mainly the "remote switch". - for i in m.monitoring: - if i in commondbustree: - for s in m.monitoring[i]: - dbus_tree[i][s] = m.monitoring[i][s] - else: - dbus_tree[i] = m.monitoring[i] - - # Create settings device which is shared - self._settings = self._create_settings(settings, self._handlechangedsetting) - - # Create dbusmonitor, this is shared by all the instances - self._dbusmonitor = self._create_dbus_monitor(dbus_tree, valueChangedCallback=self._dbus_value_changed, - deviceAddedCallback=self._device_added, deviceRemovedCallback=self._device_removed) - - # Create dbus service - # Paths for each instance will be added to this service like: - # com.victronenergy.generator.startstop0/FischerPanda0/State - # com.victronenergy.generator.startstop0/Generator0/State - self._dbusservice = self._create_dbus_service() - - # Call device_added for all existing devices at startup. - for service, instance in self._dbusmonitor.get_service_list().items(): - self._device_added(service, instance) - - GLib.timeout_add(1000, exit_on_error, self._handletimertick) - - def _handlechangedsetting(self, setting, oldvalue, newvalue): - for i in self._instances: - self._instances[i].handlechangedsetting(setting, oldvalue, newvalue) - - def _device_added(self, dbusservicename, instance): - # If settings check built-in relays - if dbusservicename == 'com.victronenergy.settings': - self._handle_builtin_relay('/Settings/Relay/Function') - - self._add_device(dbusservicename) - - for i in self._instances: - self._instances[i].device_added(dbusservicename, instance) - - def _dbus_value_changed(self, dbusServiceName, dbusPath, options, changes, deviceInstance): - # Track built-in relays - if "/Settings/Relay/Function" in dbusPath: - self._handle_builtin_relay(dbusPath) - - # Some devices like Fischer Panda gensets doesn't disappear from dbus - # when disconnected so check '/Connected' value to add or remove start/stop - # for that device - if dbusPath == "/Connected": - if self._dbusmonitor.get_value(dbusServiceName, dbusPath) == 0: - self._remove_device(dbusServiceName) - else: - self._add_device(dbusServiceName) - - for i in self._instances: - self._instances[i].dbus_value_changed(dbusServiceName, dbusPath, options, changes, deviceInstance) - - def _device_removed(self, dbusservicename, instance): - if dbusservicename == 'com.victronenergy.settings': - self._handle_builtin_relay('/Settings/Relay/Function') - for i in self._instances: - self._instances[i].device_removed(dbusservicename, instance) - - def _create_dbus_monitor(self, *args, **kwargs): - return DbusMonitor(*args, **kwargs) - - def _create_settings(self, *args, **kwargs): - bus = dbus.SessionBus() if 'DBUS_SESSION_BUS_ADDRESS' in os.environ else dbus.SystemBus() - return SettingsDevice(bus, *args, timeout=10, **kwargs) - - def _add_device(self, service): - for i in self._modules: - # Check if module can handle this service - if i.remoteprefix not in service: - continue - # Check and create start/stop instance for the device - if i.check_device(self._dbusmonitor, service): - self._instances[service] = i.create(self._dbusmonitor, - self._dbusservice, - service, self._settings) - - def _handle_builtin_relay(self, dbuspath): - function = self._dbusmonitor.get_value('com.victronenergy.settings', dbuspath) - relaynr = 'generator0' - relayservice = 'com.victronenergy.system' - - # Create a instance if relay function is set to 1 (gen. start/stop) - # otherwise remove the instance if exists - if function == 1: - self._instances[relaynr] = relay.create(self._dbusmonitor, - self._dbusservice, - relayservice, - self._settings) - elif relaynr in self._instances: - self._instances[relaynr].remove() - del self._instances[relaynr] - - def _remove_device(self, servicename): - if servicename in self._instances: - if self._instances[servicename] is not None: - self._instances[servicename].remove() - del self._instances[servicename] - - def terminate(self, signum, frame): - # Remove instances before exiting, remote services might need to perform actions before releasing control - # of the switch - for i in self._instances: - self._instances[i].remove() - os._exit(0) - - def _handletimertick(self): - # try catch, to make sure that we kill ourselves on an error. Without this try-catch, there would - # be an error written to stdout, and then the timer would not be restarted, resulting in a dead- - # lock waiting for manual intervention -> not good! - try: - for i in self._instances: - self._instances[i].tick() - except: - self._instances[i].remove() - import traceback - traceback.print_exc() - sys.exit(1) - return True - - def _create_dbus_service(self): - dbusservice = VeDbusService("com.victronenergy.generator.startstop0") - dbusservice.add_mandatory_paths( - processname=__file__, - processversion=softwareversion, - connection='generator', - deviceinstance=0, - productid=None, - productname=None, - firmwareversion=None, - hardwareversion=None, - connected=1) - return dbusservice - -if __name__ == '__main__': - # Argument parsing - parser = argparse.ArgumentParser( - description='Start and stop a generator based on conditions' - ) - - parser.add_argument('-d', '--debug', help='set logging level to debug', - action='store_true') - args = parser.parse_args() - - print ('-------- dbus_generator, v' + softwareversion + ' is starting up --------') - - logger = setup_logging(args.debug) - - # Have a mainloop, so we can send/receive asynchronous calls to and from dbus - DBusGMainLoop(set_as_default=True) - - generator = Generator() - signal.signal(signal.SIGTERM, generator.terminate) - - # Start and run the mainloop - mainloop = GLib.MainLoop() - mainloop.run() diff --git a/FileSets/v2.89/dbus_generator.py.orig b/FileSets/v2.89/dbus_generator.py.orig deleted file mode 100755 index ae3933bb..00000000 --- a/FileSets/v2.89/dbus_generator.py.orig +++ /dev/null @@ -1,330 +0,0 @@ -#!/usr/bin/python3 -u -# -*- coding: utf-8 -*- - -from dbus.mainloop.glib import DBusGMainLoop -import dbus -import argparse -import sys -import os -import signal -from gi.repository import GLib - -# Victron packages -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) -from vedbus import VeDbusService -from ve_utils import exit_on_error -from dbusmonitor import DbusMonitor -from settingsdevice import SettingsDevice -from logger import setup_logging -import logging -from gen_utils import dummy -import time -import relay -import fischerpanda - -softwareversion = '1.4.6' - -class Generator: - def __init__(self): - self._exit = False - self._instances = {} - self._modules = [relay, fischerpanda] - - # Common dbus services/path - commondbustree = { - 'com.victronenergy.settings': { - '/Settings/System/TimeZone': dummy, - '/Settings/System/AcInput1': dummy, - '/Settings/System/AcInput2': dummy, - '/Settings/Relay/Polarity': dummy - }, - 'com.victronenergy.battery': { - '/Dc/0/Voltage': dummy, - '/Dc/0/Current': dummy, - '/Dc/1/Voltage': dummy, - '/Dc/1/Current': dummy, - '/Soc': dummy - }, - 'com.victronenergy.vebus': { - '/Ac/Out/L1/P': dummy, - '/Ac/Out/L2/P': dummy, - '/Ac/Out/L3/P': dummy, - '/Alarms/L1/Overload': dummy, - '/Alarms/L2/Overload': dummy, - '/Alarms/L3/Overload': dummy, - '/Alarms/L1/HighTemperature': dummy, - '/Alarms/L2/HighTemperature': dummy, - '/Alarms/L3/HighTemperature': dummy, - '/Alarms/HighTemperature': dummy, - '/Alarms/Overload': dummy, - '/Ac/ActiveIn/ActiveInput': dummy, - '/Ac/ActiveIn/Connected': dummy, - '/Dc/0/Voltage': dummy, - '/Dc/0/Current': dummy, - '/Dc/1/Voltage': dummy, - '/Dc/1/Current': dummy, - '/Soc': dummy - }, - 'com.victronenergy.system': { - '/Ac/ConsumptionOnInput/L1/Power': dummy, - '/Ac/ConsumptionOnInput/L2/Power': dummy, - '/Ac/ConsumptionOnInput/L3/Power': dummy, - '/Ac/ConsumptionOnOutput/L1/Power': dummy, - '/Ac/ConsumptionOnOutput/L2/Power': dummy, - '/Ac/ConsumptionOnOutput/L3/Power': dummy, - '/Dc/Pv/Power': dummy, - '/AutoSelectedBatteryMeasurement': dummy, - '/Ac/ActiveIn/Source': dummy, - '/VebusService': dummy, - '/Dc/Battery/Voltage': dummy, - '/Dc/Battery/Current': dummy, - '/Dc/Battery/Soc': dummy - } - } - - # Settings base - settingsbase = { - 'autostart': ['/Settings/{0}/AutoStartEnabled', 1, 0, 1], - 'batterymeasurement': ['/Settings/{0}/Service', '', 0, 0], - 'accumulateddaily': ['/Settings/{0}/AccumulatedDaily', '', 0, 0, True], - 'accumulatedtotal': ['/Settings/{0}/AccumulatedTotal', 0, 0, 0, True], - 'batterymeasurement': ['/Settings/{0}/BatteryService', 'default', 0, 0], - 'minimumruntime': ['/Settings/{0}/MinimumRuntime', 0, 0, 86400], # minutes - 'stoponac1enabled': ['/Settings/{0}/StopWhenAc1Available', 0, 0, 10], - # On permanent loss of communication: 0 = Stop, 1 = Start, 2 = keep running - 'onlosscommunication': ['/Settings/{0}/OnLossCommunication', 0, 0, 2], - # Quiet hours - 'quiethoursenabled': ['/Settings/{0}/QuietHours/Enabled', 0, 0, 1], - 'quiethoursstarttime': ['/Settings/{0}/QuietHours/StartTime', 75600, 0, 86400], - 'quiethoursendtime': ['/Settings/{0}/QuietHours/EndTime', 21600, 0, 86400], - # SOC - 'socenabled': ['/Settings/{0}/Soc/Enabled', 0, 0, 1], - 'socstart': ['/Settings/{0}/Soc/StartValue', 80, 0, 100], - 'socstop': ['/Settings/{0}/Soc/StopValue', 90, 0, 100], - 'qh_socstart': ['/Settings/{0}/Soc/QuietHoursStartValue', 90, 0, 100], - 'qh_socstop': ['/Settings/{0}/Soc/QuietHoursStopValue', 90, 0, 100], - # Voltage - 'batteryvoltageenabled': ['/Settings/{0}/BatteryVoltage/Enabled', 0, 0, 1], - 'batteryvoltagestart': ['/Settings/{0}/BatteryVoltage/StartValue', 11.5, 0, 150], - 'batteryvoltagestop': ['/Settings/{0}/BatteryVoltage/StopValue', 12.4, 0, 150], - 'batteryvoltagestarttimer': ['/Settings/{0}/BatteryVoltage/StartTimer', 20, 0, 10000], - 'batteryvoltagestoptimer': ['/Settings/{0}/BatteryVoltage/StopTimer', 20, 0, 10000], - 'qh_batteryvoltagestart': ['/Settings/{0}/BatteryVoltage/QuietHoursStartValue', 11.9, 0, 100], - 'qh_batteryvoltagestop': ['/Settings/{0}/BatteryVoltage/QuietHoursStopValue', 12.4, 0, 100], - # Current - 'batterycurrentenabled': ['/Settings/{0}/BatteryCurrent/Enabled', 0, 0, 1], - 'batterycurrentstart': ['/Settings/{0}/BatteryCurrent/StartValue', 10.5, 0.5, 10000], - 'batterycurrentstop': ['/Settings/{0}/BatteryCurrent/StopValue', 5.5, 0, 10000], - 'batterycurrentstarttimer': ['/Settings/{0}/BatteryCurrent/StartTimer', 20, 0, 10000], - 'batterycurrentstoptimer': ['/Settings/{0}/BatteryCurrent/StopTimer', 20, 0, 10000], - 'qh_batterycurrentstart': ['/Settings/{0}/BatteryCurrent/QuietHoursStartValue', 20.5, 0, 10000], - 'qh_batterycurrentstop': ['/Settings/{0}/BatteryCurrent/QuietHoursStopValue', 15.5, 0, 10000], - # AC load - 'acloadenabled': ['/Settings/{0}/AcLoad/Enabled', 0, 0, 1], - # Measuerement, 0 = Total AC consumption, 1 = AC on inverter output, 2 = Single phase - 'acloadmeasuerment': ['/Settings/{0}/AcLoad/Measurement', 0, 0, 100], - 'acloadstart': ['/Settings/{0}/AcLoad/StartValue', 1600, 5, 1000000], - 'acloadstop': ['/Settings/{0}/AcLoad/StopValue', 800, 0, 1000000], - 'acloadstarttimer': ['/Settings/{0}/AcLoad/StartTimer', 20, 0, 10000], - 'acloadstoptimer': ['/Settings/{0}/AcLoad/StopTimer', 20, 0, 10000], - 'qh_acloadstart': ['/Settings/{0}/AcLoad/QuietHoursStartValue', 1900, 0, 1000000], - 'qh_acloadstop': ['/Settings/{0}/AcLoad/QuietHoursStopValue', 1200, 0, 1000000], - # VE.Bus high temperature - 'inverterhightempenabled': ['/Settings/{0}/InverterHighTemp/Enabled', 0, 0, 1], - 'inverterhightempstarttimer': ['/Settings/{0}/InverterHighTemp/StartTimer', 20, 0, 10000], - 'inverterhightempstoptimer': ['/Settings/{0}/InverterHighTemp/StopTimer', 20, 0, 10000], - # VE.Bus overload - 'inverteroverloadenabled': ['/Settings/{0}/InverterOverload/Enabled', 0, 0, 1], - 'inverteroverloadstarttimer': ['/Settings/{0}/InverterOverload/StartTimer', 20, 0, 10000], - 'inverteroverloadstoptimer': ['/Settings/{0}/InverterOverload/StopTimer', 20, 0, 10000], - # TestRun - 'testrunenabled': ['/Settings/{0}/TestRun/Enabled', 0, 0, 1], - 'testrunstartdate': ['/Settings/{0}/TestRun/StartDate', 1483228800, 0, 10000000000.1], - 'testrunstarttimer': ['/Settings/{0}/TestRun/StartTime', 54000, 0, 86400], - 'testruninterval': ['/Settings/{0}/TestRun/Interval', 28, 1, 365], - 'testrunruntime': ['/Settings/{0}/TestRun/Duration', 7200, 1, 86400], - 'testrunskipruntime': ['/Settings/{0}/TestRun/SkipRuntime', 0, 0, 100000], - 'testruntillbatteryfull': ['/Settings/{0}/TestRun/RunTillBatteryFull', 0, 0, 1], - # Alarms - 'nogeneratoratacinalarm': ['/Settings/{0}/Alarms/NoGeneratorAtAcIn', 0, 0, 1] - } - - settings = {} - dbus_tree = dict(commondbustree) - - for m in self._modules: - # Create settings for each module - # Settings are created under the module prefix, for example: - # /Settings/Generator0/AcLoad/Enabled - # /Settings/FischerPanda0/AcLoad/Enabled - for s in settingsbase: - v = settingsbase[s][:] # Copy - v[0] = v[0].format(m.name) - settings[s + m.name] = v - - # Get all services/paths that must be monitored - # There are a base of common services/pathas that must be monitored - # for the correct function such as battery monitors of vebus devices - # and a extra ones that is only used by a certain module, these - # are mainly the "remote switch". - for i in m.monitoring: - if i in commondbustree: - for s in m.monitoring[i]: - dbus_tree[i][s] = m.monitoring[i][s] - else: - dbus_tree[i] = m.monitoring[i] - - # Create settings device which is shared - self._settings = self._create_settings(settings, self._handlechangedsetting) - - # Create dbusmonitor, this is shared by all the instances - self._dbusmonitor = self._create_dbus_monitor(dbus_tree, valueChangedCallback=self._dbus_value_changed, - deviceAddedCallback=self._device_added, deviceRemovedCallback=self._device_removed) - - # Create dbus service - # Paths for each instance will be added to this service like: - # com.victronenergy.generator.startstop0/FischerPanda0/State - # com.victronenergy.generator.startstop0/Generator0/State - self._dbusservice = self._create_dbus_service() - - # Call device_added for all existing devices at startup. - for service, instance in self._dbusmonitor.get_service_list().items(): - self._device_added(service, instance) - - GLib.timeout_add(1000, exit_on_error, self._handletimertick) - - def _handlechangedsetting(self, setting, oldvalue, newvalue): - for i in self._instances: - self._instances[i].handlechangedsetting(setting, oldvalue, newvalue) - - def _device_added(self, dbusservicename, instance): - # If settings check built-in relays - if dbusservicename == 'com.victronenergy.settings': - self._handle_builtin_relay('/Settings/Relay/Function') - - self._add_device(dbusservicename) - - for i in self._instances: - self._instances[i].device_added(dbusservicename, instance) - - def _dbus_value_changed(self, dbusServiceName, dbusPath, options, changes, deviceInstance): - # Track built-in relays - if "/Settings/Relay/Function" in dbusPath: - self._handle_builtin_relay(dbusPath) - - # Some devices like Fischer Panda gensets doesn't disappear from dbus - # when disconnected so check '/Connected' value to add or remove start/stop - # for that device - if dbusPath == "/Connected": - if self._dbusmonitor.get_value(dbusServiceName, dbusPath) == 0: - self._remove_device(dbusServiceName) - else: - self._add_device(dbusServiceName) - - for i in self._instances: - self._instances[i].dbus_value_changed(dbusServiceName, dbusPath, options, changes, deviceInstance) - - def _device_removed(self, dbusservicename, instance): - if dbusservicename == 'com.victronenergy.settings': - self._handle_builtin_relay('/Settings/Relay/Function') - for i in self._instances: - self._instances[i].device_removed(dbusservicename, instance) - - def _create_dbus_monitor(self, *args, **kwargs): - return DbusMonitor(*args, **kwargs) - - def _create_settings(self, *args, **kwargs): - bus = dbus.SessionBus() if 'DBUS_SESSION_BUS_ADDRESS' in os.environ else dbus.SystemBus() - return SettingsDevice(bus, *args, timeout=10, **kwargs) - - def _add_device(self, service): - for i in self._modules: - # Check if module can handle this service - if i.remoteprefix not in service: - continue - # Check and create start/stop instance for the device - if i.check_device(self._dbusmonitor, service): - self._instances[service] = i.create(self._dbusmonitor, - self._dbusservice, - service, self._settings) - - def _handle_builtin_relay(self, dbuspath): - function = self._dbusmonitor.get_value('com.victronenergy.settings', dbuspath) - relaynr = 'generator0' - relayservice = 'com.victronenergy.system' - - # Create a instance if relay function is set to 1 (gen. start/stop) - # otherwise remove the instance if exists - if function == 1: - self._instances[relaynr] = relay.create(self._dbusmonitor, - self._dbusservice, - relayservice, - self._settings) - elif relaynr in self._instances: - self._instances[relaynr].remove() - del self._instances[relaynr] - - def _remove_device(self, servicename): - if servicename in self._instances: - if self._instances[servicename] is not None: - self._instances[servicename].remove() - del self._instances[servicename] - - def terminate(self, signum, frame): - # Remove instances before exiting, remote services might need to perform actions before releasing control - # of the switch - for i in self._instances: - self._instances[i].remove() - os._exit(0) - - def _handletimertick(self): - # try catch, to make sure that we kill ourselves on an error. Without this try-catch, there would - # be an error written to stdout, and then the timer would not be restarted, resulting in a dead- - # lock waiting for manual intervention -> not good! - try: - for i in self._instances: - self._instances[i].tick() - except: - self._instances[i].remove() - import traceback - traceback.print_exc() - sys.exit(1) - return True - - def _create_dbus_service(self): - dbusservice = VeDbusService("com.victronenergy.generator.startstop0") - dbusservice.add_mandatory_paths( - processname=__file__, - processversion=softwareversion, - connection='generator', - deviceinstance=0, - productid=None, - productname=None, - firmwareversion=None, - hardwareversion=None, - connected=1) - return dbusservice - -if __name__ == '__main__': - # Argument parsing - parser = argparse.ArgumentParser( - description='Start and stop a generator based on conditions' - ) - - parser.add_argument('-d', '--debug', help='set logging level to debug', - action='store_true') - args = parser.parse_args() - - print ('-------- dbus_generator, v' + softwareversion + ' is starting up --------') - - logger = setup_logging(args.debug) - - # Have a mainloop, so we can send/receive asynchronous calls to and from dbus - DBusGMainLoop(set_as_default=True) - - generator = Generator() - signal.signal(signal.SIGTERM, generator.terminate) - - # Start and run the mainloop - mainloop = GLib.MainLoop() - mainloop.run() diff --git a/FileSets/v2.89/startstop.py b/FileSets/v2.89/startstop.py deleted file mode 100644 index b247a5f6..00000000 --- a/FileSets/v2.89/startstop.py +++ /dev/null @@ -1,1207 +0,0 @@ -#!/usr/bin/python -u -# -*- coding: utf-8 -*- - -#### GuiMods -#### This file has been modified to allow the generator running state derived from the generator digital input -#### or the genset AC input -#### If the incoming generator state changes, the manual start state is updated -#### time accumulation is suspended when the generator is not running -#### A switch in the generator settings menucontrols whethter the incoming state affects manual start or time accumulaiton -#### It is now possible to start the generator manually and have it stop automatically based on the preset conditions -#### for automaitc start / stop -#### A service interval timer was added so the accumulated run time does not need to be reset, -#### providing total run time for the generator -#### Search for #### GuiMods to find changes - -# Function -# dbus_generator monitors the dbus for batteries (com.victronenergy.battery.*) and -# vebus com.victronenergy.vebus.* -# Battery and vebus monitors can be configured through the gui. -# It then monitors SOC, AC loads, battery current and battery voltage,to auto start/stop the generator based -# on the configuration settings. Generator can be started manually or periodically setting a tes trun period. -# Time zones function allows to use different values for the conditions along the day depending on time - -import dbus -import datetime -import calendar -import time -import sys -import json -import os -import logging -from os import environ -import monotonic_time -from gen_utils import DBusServicePrefix, SettingsPrefix, Errors, States, enum -# Victron packages -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) -from ve_utils import exit_on_error -from settingsdevice import SettingsDevice - -RunningConditions = enum( - Stopped = 0, - Manual = 1, - TestRun = 2, - LossOfCommunication = 3, - Soc = 4, - Acload = 5, - BatteryCurrent = 6, - BatteryVoltage = 7, - InverterHighTemp = 8, - InverterOverload = 9, - StopOnAc1 = 10) - -SYSTEM_SERVICE = 'com.victronenergy.system' -BATTERY_PREFIX = '/Dc/Battery' -HISTORY_DAYS = 30 - - -def safe_max(args): - try: - return max(x for x in args if x is not None) - except ValueError: - return None - -class StartStop(object): - def __init__(self): -#### GuiMods - self._last_update_mtime = 0 - self._accumulatedRunTime = 0 - self._digitalInputTypeObject = None - self._generatorInputStateObject = 0 - self._lastState = 0 - self._externalOverride = False - self._externalOverrideDelay = 99 - self._lastExternalOverride = False - self._searchDelay = 99 - self._linkToExternalState = False - - self._dbusservice = None - self._settings = None - self._dbusmonitor = None - self._remoteservice = None - self._name = None - self._enabled = False - - # One second per retry - self.RETRIES_ON_ERROR = 300 - self._testrun_soc_retries = 0 - self._last_counters_check = 0 - - self._starttime = 0 - self._manualstarttimer = 0 - self._last_runtime_update = 0 - self._timer_runnning = 0 - - # Manual battery service selection is deprecated in favour - # of getting the values directly from systemcalc, we keep - # manual selected services handling for compatibility reasons. - self._vebusservice = None - self._errorstate = 0 - self._battery_service = None - self._battery_prefix = None - - self._acpower_inverter_input = { - 'timeout': 0, - 'unabletostart': False - } - - self._condition_stack = { - 'batteryvoltage': { - 'name': 'batteryvoltage', - 'reached': False, - 'boolean': False, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'battery' - }, - 'batterycurrent': { - 'name': 'batterycurrent', - 'reached': False, - 'boolean': False, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'battery' - }, - 'acload': { - 'name': 'acload', - 'reached': False, - 'boolean': False, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - }, - 'inverterhightemp': { - 'name': 'inverterhightemp', - 'reached': False, - 'boolean': True, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - }, - 'inverteroverload': { - 'name': 'inverteroverload', - 'reached': False, - 'boolean': True, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - }, - 'soc': { - 'name': 'soc', - 'reached': False, - 'boolean': False, - 'timed': False, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'battery' - }, - 'stoponac1': { - 'name': 'stoponac1', - 'reached': False, - 'boolean': True, - 'timed': False, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - } - } - - def set_sources(self, dbusmonitor, dbusservice, settings, name, remoteservice): - self._dbusservice = DBusServicePrefix(dbusservice, name) - self._settings = SettingsPrefix(settings, name) - self._dbusmonitor = dbusmonitor - self._remoteservice = remoteservice - self._name = name - # Set timezone to user selected timezone - tz = self._dbusmonitor.get_value('com.victronenergy.settings', '/Settings/System/TimeZone') - environ['TZ'] = tz if tz else 'UTC' - time.tzset() - - self.log_info('Start/stop instance created for %s.' % self._remoteservice) - self._remote_setup() - - def _create_paths(self): - # State: None = invalid, 0 = stopped, 1 = running - self._dbusservice.add_path('/State', value=None) - # RunningByConditionCode: Numeric Companion to /RunningByCondition below, but - # also encompassing a Stopped state. - self._dbusservice.add_path('/RunningByConditionCode', value=None) - # Error - self._dbusservice.add_path('/Error', value=None, gettextcallback=self._gettext) - # Condition that made the generator start - self._dbusservice.add_path('/RunningByCondition', value=None) - # Runtime - self._dbusservice.add_path('/Runtime', value=None, gettextcallback=self._gettext) - # Today runtime - self._dbusservice.add_path('/TodayRuntime', value=None, gettextcallback=self._gettext) - # Test run runtime - self._dbusservice.add_path('/TestRunIntervalRuntime', value=None , gettextcallback=self._gettext) - # Next test run date, values is 0 for test run disabled - self._dbusservice.add_path('/NextTestRun', value=None, gettextcallback=self._gettext) - # Next test run is needed 1, not needed 0 - self._dbusservice.add_path('/SkipTestRun', value=None) - # Manual start - self._dbusservice.add_path('/ManualStart', value=None, writeable=True) - # Manual start timer - self._dbusservice.add_path('/ManualStartTimer', value=None, writeable=True) - # Silent mode active - self._dbusservice.add_path('/QuietHours', value=None) - # Alarms - self._dbusservice.add_path('/Alarms/NoGeneratorAtAcIn', value=None) - - # We need to set the values after creating the paths to trigger the 'onValueChanged' event for the gui - # otherwise the gui will report the paths as invalid if we remove and recreate the paths without - # restarting the dbusservice. - self._dbusservice['/State'] = 0 - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped - self._dbusservice['/Error'] = 0 - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/Runtime'] = 0 - self._dbusservice['/TodayRuntime'] = 0 - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - self._dbusservice['/NextTestRun'] = None - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/ManualStart'] = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._dbusservice['/QuietHours'] = 0 - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - -#### GuiMods - # generator input running state - self._dbusservice.add_path('/GeneratorRunningState', value=None) - # external override active - self._dbusservice.add_path('/ExternalOverride', value=None) - self._dbusservice['/GeneratorRunningState'] = "?" - self._dbusservice['/ExternalOverride'] = False - - def enable(self): - if self._enabled: - return - self.log_info('Enabling auto start/stop and taking control of remote switch') - self._create_paths() - self._determineservices() - self._update_remote_switch() - self._enabled = True - - def disable(self): - if not self._enabled: - return - self.log_info('Disabling auto start/stop, releasing control of remote switch') - self._remove_paths() - self._enabled = False - - def remove(self): - self.disable() - self.log_info('Removed from start/stop instances') - - def _remove_paths(self): - self._dbusservice.__delitem__('/State') - self._dbusservice.__delitem__('/RunningByConditionCode') - self._dbusservice.__delitem__('/Error') - self._dbusservice.__delitem__('/RunningByCondition') - self._dbusservice.__delitem__('/Runtime') - self._dbusservice.__delitem__('/TodayRuntime') - self._dbusservice.__delitem__('/TestRunIntervalRuntime') - self._dbusservice.__delitem__('/NextTestRun') - self._dbusservice.__delitem__('/SkipTestRun') - self._dbusservice.__delitem__('/ManualStart') - self._dbusservice.__delitem__('/ManualStartTimer') - self._dbusservice.__delitem__('/QuietHours') - self._dbusservice.__delitem__('/Alarms/NoGeneratorAtAcIn') -#### GuiMods - self._dbusservice.__delitem__('/GeneratorRunningState') - self._dbusservice.__delitem__('/ExternalOverride') - - - def device_added(self, dbusservicename, instance): - self._determineservices() - - def device_removed(self, dbusservicename, instance): - self._determineservices() - - def get_error(self): - return self._dbusservice['/Error'] - - def set_error(self, errorn): - self._dbusservice['/Error'] = errorn - - def clear_error(self): - self._dbusservice['/Error'] = Errors.NONE - - def dbus_value_changed(self, dbusServiceName, dbusPath, options, changes, deviceInstance): - if self._dbusservice is None: - return - if dbusPath == '/AutoSelectedBatteryMeasurement' and self._settings['batterymeasurement'] == 'default': - self._determineservices() - - if dbusPath == '/VebusService': - self._determineservices() - - # Update env timezone when setting changes - if dbusPath == '/Settings/System/TimeZone': - environ['TZ'] = changes['Value'] if changes['Value'] else 'UTC' - - def handlechangedsetting(self, setting, oldvalue, newvalue): - if self._dbusservice is None: - return - if self._name not in setting: - # Not our setting - return - - s = self._settings.removeprefix(setting) - - if s == 'batterymeasurement': - self._determineservices() - # Reset retries and valid if service changes - for condition in self._condition_stack: - if self._condition_stack[condition]['monitoring'] == 'battery': - self._condition_stack[condition]['valid'] = True - self._condition_stack[condition]['retries'] = 0 - - if s == 'autostart': - self.log_info('Autostart function %s.' % ('enabled' if newvalue == 1 else 'disabled')) - - if self._dbusservice is not None and s == 'testruninterval': - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime( - self._settings['testruninterval']) - - def dbus_name_owner_changed(self, name, oldowner, newowner): - self._determineservices() - - def _gettext(self, path, value): - path = path.replace("/" + self._name, '') - - if path == '/Error': - return Errors.get_description(value) - if path == '/NextTestRun': - # Locale format date - d = datetime.datetime.fromtimestamp(value) - return d.strftime('%c') - elif path in ['/Runtime', '/TestRunIntervalRuntime', '/TodayRuntime']: - m, s = divmod(value, 60) - h, m = divmod(m, 60) - return '%dh, %dm, %ds' % (h, m, s) - else: - return str(value) - - def log_info(self, msg): - logging.info(self._name + ': %s' % msg) - - def tick(self): - if not self._enabled: - return - self._check_remote_status() -#### GuiMods - self._linkToExternalState = self._settings['linkManualStartToExternal'] == 1 - self._processGeneratorRunDetection () - - self._evaluate_startstop_conditions() - self._detect_generator_at_acinput() - - - - - def _evaluate_startstop_conditions(self): - if self.get_error() != Errors.NONE: - # First evaluation after an error, log it - if self._errorstate == 0: - self._errorstate = 1 - self._dbusservice['/State'] = States.ERROR - self.log_info('Error: #%i - %s, stop controlling remote.' % - (self.get_error(), - Errors.get_description(self.get_error()))) - elif self._errorstate == 1: - # Error cleared - self._errorstate = 0 - self.log_info('Error state cleared, taking control of remote switch.') - - # Conditions will be evaluated in this order - conditions = ['soc', 'acload', 'batterycurrent', 'batteryvoltage', 'inverterhightemp', 'inverteroverload', 'stoponac1'] - start = False - startbycondition = None - activecondition = self._dbusservice['/RunningByCondition'] - today = calendar.timegm(datetime.date.today().timetuple()) - self._timer_runnning = False - values = self._get_updated_values() - connection_lost = False - - self._check_quiet_hours() - - # New day, register it - if self._last_counters_check < today and self._dbusservice['/State'] == States.STOPPED: - self._last_counters_check = today - self._update_accumulated_time() - - # Update current and accumulated runtime. -#### GuiMods - self._accumulateRunTime () - -#### GuiMods - # A negative /ManualStartTimer is used by the GUI to signal the generator should start now - # but stop when all auto stop conditions have been met - # so we skip manual start evaluation if this is the case - # and set a flag for use below to ignore auto start conditions - # the generator is actually started by the auto start/stop logic below - if self._dbusservice['/ManualStartTimer'] < 0 and self._dbusservice['/ManualStart'] == 1: - self._dbusservice['/ManualStartTimer'] = 0 - self._dbusservice['/ManualStart'] = 0 - ignoresAutoStartCondition = True - else: - ignoresAutoStartCondition = False - if self._evaluate_manual_start(): - startbycondition = 'manual' - start = True - - # Conditions will only be evaluated if the autostart functionality is enabled - if self._settings['autostart'] == 1: - - if self._evaluate_testrun_condition(): - startbycondition = 'testrun' - start = True - - # Evaluate value conditions - for condition in conditions: -#### GuiMods - start = self._evaluate_condition(self._condition_stack[condition], values[condition], ignoresAutoStartCondition) or start - startbycondition = condition if start and startbycondition is None else startbycondition - # Connection lost is set to true if the number of retries of one or more enabled conditions - # >= RETRIES_ON_ERROR - if self._condition_stack[condition]['enabled']: - connection_lost = self._condition_stack[condition]['retries'] >= self.RETRIES_ON_ERROR - - if self._condition_stack['stoponac1']['reached'] and startbycondition not in ['manual', 'testrun']: - start = False - if self._dbusservice['/State'] == States.RUNNING and activecondition not in ['manual', 'testrun']: - self.log_info('AC input 1 available, stopping') - - # If none condition is reached check if connection is lost and start/keep running the generator - # depending on '/OnLossCommunication' setting - if not start and connection_lost: - # Start always - if self._settings['onlosscommunication'] == 1: - start = True - startbycondition = 'lossofcommunication' - # Keep running if generator already started - if self._dbusservice['/State'] == States.RUNNING and self._settings['onlosscommunication'] == 2: - start = True - startbycondition = 'lossofcommunication' - - if not start and self._errorstate: - self._stop_generator() - - if self._errorstate: - return - - if start: - self._start_generator(startbycondition) -#### GuiMods - # bypass the minimum run time check if External Override is active - elif (self._dbusservice['/Runtime'] >= self._settings['minimumruntime'] * 60 - or activecondition == 'manual') or self._dbusservice['/ExternalOverride']: - self._stop_generator() - - def _detect_generator_at_acinput(self): - state = self._dbusservice['/State'] - - if state == States.STOPPED: - self._reset_acpower_inverter_input() - return - - if self._settings['nogeneratoratacinalarm'] == 0: - self._reset_acpower_inverter_input() - return - - vebus_service = self._vebusservice if self._vebusservice else '' - activein_state = self._dbusmonitor.get_value( - vebus_service, '/Ac/ActiveIn/Connected') - - # Path not supported, skip evaluation - if activein_state == None: - return - - # Sources 0 = Not available, 1 = Grid, 2 = Generator, 3 = Shore - generator_acsource = self._dbusmonitor.get_value( - SYSTEM_SERVICE, '/Ac/ActiveIn/Source') == 2 - # Not connected = 0, connected = 1 - activein_connected = activein_state == 1 - - if generator_acsource and activein_connected: - if self._acpower_inverter_input['unabletostart']: - self.log_info('Generator detected at inverter AC input, alarm removed') - self._reset_acpower_inverter_input() - elif self._acpower_inverter_input['timeout'] < self.RETRIES_ON_ERROR: - self._acpower_inverter_input['timeout'] += 1 - elif not self._acpower_inverter_input['unabletostart']: - self._acpower_inverter_input['unabletostart'] = True - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 2 - self.log_info('Generator not detected at inverter AC input, triggering alarm') - - def _reset_acpower_inverter_input(self, clear_error=True): - if self._acpower_inverter_input['timeout'] != 0: - self._acpower_inverter_input['timeout'] = 0 - - if self._acpower_inverter_input['unabletostart'] != 0: - self._acpower_inverter_input['unabletostart'] = 0 - - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - - def _reset_condition(self, condition): - condition['reached'] = False - if condition['timed']: - condition['start_timer'] = 0 - condition['stop_timer'] = 0 - - def _check_condition(self, condition, value): - name = condition['name'] - - if self._settings[name + 'enabled'] == 0: - if condition['enabled']: - condition['enabled'] = False - self.log_info('Disabling (%s) condition' % name) - condition['retries'] = 0 - condition['valid'] = True - self._reset_condition(condition) - return False - - elif not condition['enabled']: - condition['enabled'] = True - self.log_info('Enabling (%s) condition' % name) - - if (condition['monitoring'] == 'battery') and (self._settings['batterymeasurement'] == 'nobattery'): - # If no battery monitor is selected reset the condition - self._reset_condition(condition) - return False - - if value is None and condition['valid']: - if condition['retries'] >= self.RETRIES_ON_ERROR: - logging.info('Error getting (%s) value, skipping evaluation till get a valid value' % name) - self._reset_condition(condition) - self._comunnication_lost = True - condition['valid'] = False - else: - condition['retries'] += 1 - if condition['retries'] == 1 or (condition['retries'] % 10) == 0: - self.log_info('Error getting (%s) value, retrying(#%i)' % (name, condition['retries'])) - return False - - elif value is not None and not condition['valid']: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['valid'] = True - condition['retries'] = 0 - - # Reset retries if value is valid - if value is not None and condition['retries'] > 0: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['retries'] = 0 - - return condition['valid'] - -#### GuiMods - def _evaluate_condition(self, condition, value, ignoreStartValue): - name = condition['name'] - setting = ('qh_' if self._dbusservice['/QuietHours'] == 1 else '') + name - startvalue = self._settings[setting + 'start'] if not condition['boolean'] else 1 - stopvalue = self._settings[setting + 'stop'] if not condition['boolean'] else 0 - - # Check if the condition has to be evaluated - if not self._check_condition(condition, value): - # If generator is started by this condition and value is invalid - # wait till RETRIES_ON_ERROR to skip the condition - if condition['reached'] and condition['retries'] <= self.RETRIES_ON_ERROR: - if condition['retries'] > 0: - return True - - return False - - # As this is a generic evaluation method, we need to know how to compare the values - # first check if start value should be greater than stop value and then compare - start_is_greater = startvalue > stopvalue - -#### GuiMods - stop = value <= stopvalue if start_is_greater else value >= stopvalue - # when starting manually and stopping based on auto stop values, - # start if stop condition is not satisfied - if ignoreStartValue: - start = not stop - else: - # When the condition is already reached only the stop value can set it to False - start = condition['reached'] or (value >= startvalue if start_is_greater else value <= startvalue) - - # Timed conditions must start/stop after the condition has been reached for a minimum - # time. - if condition['timed']: - if not condition['reached'] and start: - condition['start_timer'] += time.time() if condition['start_timer'] == 0 else 0 - start = time.time() - condition['start_timer'] >= self._settings[name + 'starttimer'] - condition['stop_timer'] *= int(not start) - self._timer_runnning = True - else: - condition['start_timer'] = 0 - - if condition['reached'] and stop: - condition['stop_timer'] += time.time() if condition['stop_timer'] == 0 else 0 - stop = time.time() - condition['stop_timer'] >= self._settings[name + 'stoptimer'] - condition['stop_timer'] *= int(not stop) - self._timer_runnning = True - else: - condition['stop_timer'] = 0 - - condition['reached'] = start and not stop - return condition['reached'] - - def _evaluate_manual_start(self): - if self._dbusservice['/ManualStart'] == 0: - if self._dbusservice['/RunningByCondition'] == 'manual': - self._dbusservice['/ManualStartTimer'] = 0 - return False - - start = True - # If /ManualStartTimer has a value greater than zero will use it to set a stop timer. - # If no timer is set, the generator will not stop until the user stops it manually. - # Once started by manual start, each evaluation the timer is decreased -#### GuiMods - if self._dbusservice['/ManualStartTimer'] > 0: - self._manualstarttimer += time.time() if self._manualstarttimer == 0 else 0 - self._dbusservice['/ManualStartTimer'] -= int(time.time()) - int(self._manualstarttimer) - self._manualstarttimer = time.time() - start = self._dbusservice['/ManualStartTimer'] > 0 - self._dbusservice['/ManualStart'] = int(start) - # Reset if timer is finished - self._manualstarttimer *= int(start) - self._dbusservice['/ManualStartTimer'] *= int(start) - - return start - - def _evaluate_testrun_condition(self): - if self._settings['testrunenabled'] == 0: - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/NextTestRun'] = None - return False - - today = datetime.date.today() - yesterday = today - datetime.timedelta(days=1) # Should deal well with DST - now = time.time() - runtillbatteryfull = self._settings['testruntillbatteryfull'] == 1 - soc = self._get_updated_values()['soc'] - batteryisfull = runtillbatteryfull and soc == 100 - duration = 60 if runtillbatteryfull else self._settings['testrunruntime'] - - try: - startdate = datetime.date.fromtimestamp(self._settings['testrunstartdate']) - _starttime = time.mktime(yesterday.timetuple()) + self._settings['testrunstarttimer'] - - # today might in fact still be yesterday, if this test run started - # before midnight and finishes after. If `now` still falls in - # yesterday's window, then by the temporal anthropic principle, - # which I just made up but loosely states that time must have - # these properties for observers to exist, it must be yesterday - # because we are here to observe it. - if _starttime <= now <= _starttime + duration: - today = yesterday - starttime = _starttime - else: - starttime = time.mktime(today.timetuple()) + self._settings['testrunstarttimer'] - except ValueError: - logging.debug('Invalid dates, skipping testrun') - return False - - # If start date is in the future set as NextTestRun and stop evaluating - if startdate > today: - self._dbusservice['/NextTestRun'] = time.mktime(startdate.timetuple()) - return False - - start = False - # If the accumulated runtime during the tes trun interval is greater than '/TestRunIntervalRuntime' - # the tes trun must be skipped - needed = (self._settings['testrunskipruntime'] > self._dbusservice['/TestRunIntervalRuntime'] - or self._settings['testrunskipruntime'] == 0) - self._dbusservice['/SkipTestRun'] = int(not needed) - - interval = self._settings['testruninterval'] - stoptime = starttime + duration - elapseddays = (today - startdate).days - mod = elapseddays % interval - - start = not bool(mod) and starttime <= now <= stoptime - - if runtillbatteryfull: - if soc is not None: - self._testrun_soc_retries = 0 - start = (start or self._dbusservice['/RunningByCondition'] == 'testrun') and not batteryisfull - elif self._dbusservice['/RunningByCondition'] == 'testrun': - if self._testrun_soc_retries < self.RETRIES_ON_ERROR: - self._testrun_soc_retries += 1 - start = True - if (self._testrun_soc_retries % 10) == 0: - self.log_info('Test run failed to get SOC value, retrying(#%i)' % self._testrun_soc_retries) - else: - self.log_info('Failed to get SOC after %i retries, terminating test run condition' % self._testrun_soc_retries) - start = False - else: - start = False - - if not bool(mod) and (now <= stoptime): - self._dbusservice['/NextTestRun'] = starttime - else: - self._dbusservice['/NextTestRun'] = (time.mktime((today + datetime.timedelta(days=interval - mod)).timetuple()) + - self._settings['testrunstarttimer']) - return start and needed - - def _check_quiet_hours(self): - active = False - if self._settings['quiethoursenabled'] == 1: - # Seconds after today 00:00 - timeinseconds = time.time() - time.mktime(datetime.date.today().timetuple()) - quiethoursstart = self._settings['quiethoursstarttime'] - quiethoursend = self._settings['quiethoursendtime'] - - # Check if the current time is between the start time and end time - if quiethoursstart < quiethoursend: - active = quiethoursstart <= timeinseconds and timeinseconds < quiethoursend - else: # End time is lower than start time, example Start: 21:00, end: 08:00 - active = not (quiethoursend < timeinseconds and timeinseconds < quiethoursstart) - - if self._dbusservice['/QuietHours'] == 0 and active: - self.log_info('Entering to quiet mode') - - elif self._dbusservice['/QuietHours'] == 1 and not active: - self.log_info('Leaving quiet mode') - - self._dbusservice['/QuietHours'] = int(active) - - return active - - def _update_accumulated_time(self): - seconds = self._dbusservice['/Runtime'] - accumulated = seconds - self._last_runtime_update - - self._settings['accumulatedtotal'] = int(self._settings['accumulatedtotal']) + accumulated -#### GuiMods - self._settings['timeSinceService'] = int(self._settings['timeSinceService']) + accumulated - # Using calendar to get timestamp in UTC, not local time - today_date = str(calendar.timegm(datetime.date.today().timetuple())) - - # If something goes wrong getting the json string create a new one - try: - accumulated_days = json.loads(self._settings['accumulateddaily']) - except ValueError: - accumulated_days = {today_date: 0} - - if (today_date in accumulated_days): - accumulated_days[today_date] += accumulated - else: - accumulated_days[today_date] = accumulated - - self._last_runtime_update = seconds - - # Keep the historical with a maximum of HISTORY_DAYS - while len(accumulated_days) > HISTORY_DAYS: - accumulated_days.pop(min(accumulated_days.keys()), None) - - # Upadate settings - self._settings['accumulateddaily'] = json.dumps(accumulated_days, sort_keys=True) - self._dbusservice['/TodayRuntime'] = self._interval_runtime(0) - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - - def _interval_runtime(self, days): - summ = 0 - try: - daily_record = json.loads(self._settings['accumulateddaily']) - except ValueError: - return 0 - - for i in range(days + 1): - previous_day = calendar.timegm((datetime.date.today() - datetime.timedelta(days=i)).timetuple()) - if str(previous_day) in daily_record.keys(): - summ += daily_record[str(previous_day)] if str(previous_day) in daily_record.keys() else 0 - - return summ - - def _get_battery(self): - battery = {} - if self._settings['batterymeasurement'] == 'default': - battery['service'] = SYSTEM_SERVICE - battery['prefix'] = BATTERY_PREFIX - else: - battery['service'] = self._battery_service if self._battery_service else '' - battery['prefix'] = self._battery_prefix if self._battery_prefix else '' - - return battery - - def _get_updated_values(self): - battery = self._get_battery() - vebus_service = self._vebusservice if self._vebusservice else '' - loadOnAcOut = [] - totalConsumption = [] - inverterHighTemp = [] - inverterOverload = [] - - values = { - 'batteryvoltage': self._dbusmonitor.get_value(battery['service'], battery['prefix'] + '/Voltage'), - 'batterycurrent': self._dbusmonitor.get_value(battery['service'], battery['prefix'] + '/Current'), - # Soc from the device doesn't have the '/Dc/0' prefix like the current and voltage do, but it does - # have the same prefix on systemcalc - 'soc': self._dbusmonitor.get_value(battery['service'], (battery['prefix'] if battery['prefix'] == BATTERY_PREFIX else '') + '/Soc'), - 'inverterhightemp': self._dbusmonitor.get_value(vebus_service, '/Alarms/HighTemperature'), - 'inverteroverload': self._dbusmonitor.get_value(vebus_service, '/Alarms/Overload') - } - - for phase in ['L1', 'L2', 'L3']: - # Get the values directly from the inverter, systemcalc doesn't provide raw inverted power - loadOnAcOut.append(self._dbusmonitor.get_value(vebus_service, ('/Ac/Out/%s/P' % phase))) - - # Calculate total consumption, '/Ac/Consumption/%s/Power' is deprecated - c_i = self._dbusmonitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnInput/%s/Power' % phase)) - c_o = self._dbusmonitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnOutput/%s/Power' % phase)) - totalConsumption.append(sum(filter(None, (c_i, c_o)))) - - # Inverter alarms must be fetched directly from the inverter service - inverterHighTemp.append(self._dbusmonitor.get_value(vebus_service, ('/Alarms/%s/HighTemperature' % phase))) - inverterOverload.append(self._dbusmonitor.get_value(vebus_service, ('/Alarms/%s/Overload' % phase))) - - # Toltal consumption - if self._settings['acloadmeasuerment'] == 0: - values['acload'] = sum(filter(None, totalConsumption)) - - # Load on inverter AC out - if self._settings['acloadmeasuerment'] == 1: - values['acload'] = sum(filter(None, loadOnAcOut)) - - # Highest phase load - if self._settings['acloadmeasuerment'] == 2: - values['acload'] = safe_max(loadOnAcOut) - - # AC input 1 - activein = self._dbusmonitor.get_value(vebus_service, '/Ac/ActiveIn/ActiveInput') - # Active input is connected - connected = self._dbusmonitor.get_value(vebus_service, '/Ac/ActiveIn/Connected') - if None not in (activein, connected): - values['stoponac1'] = activein == 0 and connected == 1 - else: - values['stoponac1'] = None - - # Invalidate if vebus is not available - if loadOnAcOut[0] == None: - values['acload'] = None - - if values['batterycurrent']: - values['batterycurrent'] *= -1 - - # When multi is connected to CAN-bus, alarms are published to - # /Alarms/Overload... but when connected to vebus alarms are - # splitted in three phases and published to /Alarms/LX/Overload... - if values['inverteroverload'] == None: - values['inverteroverload'] = safe_max(inverterOverload) - - if values['inverterhightemp'] == None: - values['inverterhightemp'] = safe_max(inverterHighTemp) - - return values - - def _determineservices(self): - # batterymeasurement is either 'default' or 'com_victronenergy_battery_288/Dc/0'. - # In case it is set to default, we use the AutoSelected battery - # measurement, given by SystemCalc. - batterymeasurement = None - newbatteryservice = None - batteryprefix = '' - selectedbattery = self._settings['batterymeasurement'] - vebusservice = None - - if selectedbattery == 'default': - batterymeasurement = 'default' - elif len(selectedbattery.split('/', 1)) == 2: # Only very basic sanity checking.. - batterymeasurement = self._settings['batterymeasurement'] - elif selectedbattery == 'nobattery': - batterymeasurement = None - else: - # Exception: unexpected value for batterymeasurement - pass - - if batterymeasurement and batterymeasurement != 'default': - batteryprefix = '/' + batterymeasurement.split('/', 1)[1] - - # Get the current battery servicename - if self._battery_service: - oldservice = self._battery_service - else: - oldservice = None - - if batterymeasurement != 'default': - battery_instance = int(batterymeasurement.split('_', 3)[3].split('/')[0]) - service_type = None - - if 'vebus' in batterymeasurement: - service_type = 'vebus' - elif 'battery' in batterymeasurement: - service_type = 'battery' - - newbatteryservice = self._get_servicename_by_instance(battery_instance, service_type) - elif batterymeasurement == 'default': - newbatteryservice = 'default' - - if newbatteryservice and newbatteryservice != oldservice: - if selectedbattery == 'default': - self.log_info('Getting battery values from systemcalc.') - if selectedbattery == 'nobattery': - self.log_info('Battery monitoring disabled! Stop evaluating related conditions') - self._battery_service = None - self._battery_prefix = None - self.log_info('Battery service we need (%s) found! Using it for generator start/stop' % batterymeasurement) - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - elif not newbatteryservice and newbatteryservice != oldservice: - self.log_info('Error getting battery service!') - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - - # Get the default VE.Bus service - vebusservice = self._dbusmonitor.get_value('com.victronenergy.system', '/VebusService') - if vebusservice: - if self._vebusservice != vebusservice: - self._vebusservice = vebusservice - self.log_info('Vebus service (%s) found! Using it for generator start/stop' % vebusservice) - else: - if self._vebusservice is not None: - self.log_info('Vebus service (%s) dissapeared! Stop evaluating related conditions' % self._vebusservice) - else: - self.log_info('Error getting Vebus service!') - self._vebusservice = None - - def _get_servicename_by_instance(self, instance, service_type=None): - sv = None - services = self._dbusmonitor.get_service_list() - - for service in services: - if service_type and service_type not in service: - continue - - if services[service] == instance: - sv = service - break - - return sv - - def _get_monotonic_seconds(self): - return monotonic_time.monotonic_time().to_seconds_double() - - def _start_generator(self, condition): - state = self._dbusservice['/State'] - remote_state = self._get_remote_switch_state() - - # This function will start the generator in the case generator not - # already running. When differs, the RunningByCondition is updated - if state == States.STOPPED or remote_state != state: - self._dbusservice['/State'] = States.RUNNING - self._update_remote_switch() - self._starttime = monotonic_time.monotonic_time().to_seconds_double() - self.log_info('Starting generator by %s condition' % condition) - elif self._dbusservice['/RunningByCondition'] != condition: - self.log_info('Generator previously running by %s condition is now running by %s condition' - % (self._dbusservice['/RunningByCondition'], condition)) - - self._dbusservice['/RunningByCondition'] = condition - self._dbusservice['/RunningByConditionCode'] = RunningConditions.lookup(condition) - - def _stop_generator(self): - state = self._dbusservice['/State'] - remote_state = self._get_remote_switch_state() - - if state == 1 or remote_state != state: - self._dbusservice['/State'] = States.STOPPED - self._update_remote_switch() - self.log_info('Stopping generator that was running by %s condition' % - str(self._dbusservice['/RunningByCondition'])) - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped -#### GuiMods - self._accumulateRunTime () - - self._starttime = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._manualstarttimer = 0 - self._last_runtime_update = 0 - - def _update_remote_switch(self): - self._set_remote_switch_state(dbus.Int32(self._dbusservice['/State'], variant_level=1)) - - def _get_remote_switch_state(self): - raise Exception('This function should be overridden') - - def _set_remote_switch_state(self, value): - raise Exception('This function should be overridden') - - # Check the remote status, for example errors - def _check_remote_status(self): - raise Exception('This function should be overridden') - - def _remote_setup(self): - raise Exception('This function should be overridden') - - def _create_dbus_monitor(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_settings(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_dbus_service(self): - raise Exception('This function should be overridden') - -#### GuiMods - -# this function connects the generator digital input (if any) -# OR the generator AC input detection -# to the generator /ManualStart and updates dbus paths used by the GUI -# -# if the generator digital input changes from stopped to running -# AND no run conditions are active, a manual start is innitiated -# -# if the generator digital input changes from running to stopped -# AND a manual start is active, a manual stop is innitiated -# -# /GeneratorRunningState provides the input running state from the digital input to the GUI -# R = running -# S = stopped -# ? = unknown (no digital input found) -# -# /ExternalOverride is used by the GUI to alert the user when there is a conflict -# between the generator running state and the state Venus -# /ExternalOverride is True if /GeneratorRunningState is S -# AND the /RunningCondition is not stopped (which includes a manual run) -# activation is delayed 5 seconds to allow transitions to settle -# -# we must first find the geneator digital input, if it exists at all -# we serche all dBus services looking for a digital input with type generator (9) -# the search only occurs every 10 seconds -# - - def _processGeneratorRunDetection (self): - TheBus = dbus.SystemBus() - generatorState = self._dbusservice['/State'] - try: - # current input service is no longer valid - # search for a new one only every 10 seconds to avoid unnecessary processing - if (self._digitalInputTypeObject == None or self._digitalInputTypeObject.GetValue() != 9) and self._searchDelay > 10: - newInputService = "" - for service in TheBus.list_names(): - # found a digital input servic, now check the type - if service.startswith ("com.victronenergy.digitalinput"): - self._digitalInputTypeObject = TheBus.get_object (service, '/Type') - # found it! - if self._digitalInputTypeObject.GetValue() == 9: - newInputService = service - break - - # found new service - get objects for use later - if newInputService != "": - self.log_info ("Found generator digital input service at %s" % newInputService) - self._generatorInputStateObject = TheBus.get_object(newInputService, '/State') - else: - if self._generatorInputStateObject != None: - self.log_info ("Generator digital input service NOT found") - self._generatorInputStateObject = None - self._digitalInputTypeObject = None - self._searchDelay = 0 # start delay timer - - # if serch delay timer is active, increment it now - if self._searchDelay <= 10: - self._searchDelay += 1 - - - # collect generator input states - inputState = '?' - # if generator digital input is present, use that - if self._generatorInputStateObject != None: - inputState = self._generatorInputStateObject.GetValue () - if inputState == 10: - inputState = 'R' - elif inputState == 11: - inputState = 'S' - - # update /GeneratorRunningState - if inputState != self._lastState: - self._dbusservice['/GeneratorRunningState'] = inputState - - # forward input state changes to /ManualStart - if self._linkToExternalState: - if inputState == "R" and generatorState == States.STOPPED: - self.log_info ("generator was started externally - syncing ManualStart state") - self._dbusservice['/ManualStart'] = 1 - elif inputState == "S" and self._dbusservice['/ManualStart'] == 1 \ - and generatorState in (States.RUNNING, States.WARMUP, States.COOLDOWN): - self.log_info ("generator was stopped externally - syncing ManualStart state") - self._dbusservice['/ManualStart'] = 0 - - # update /ExternalOverride - if inputState == "S" and self._linkToExternalState and generatorState == States.RUNNING: - if self._externalOverrideDelay > 5: - self._externalOverride = True - else: - self._externalOverrideDelay += 1 - else: - self._externalOverride = False - self._externalOverrideDelay = 0 - - if self._externalOverride != self._lastExternalOverride: - self._dbusservice['/ExternalOverride'] = self._externalOverride - self._lastExternalOverride = self._externalOverride - - except dbus.DBusException: - self.log_info ("dbus exception - generator digital input no longer valid") - self._generatorInputStateObject = None - self._digitalInputTypeObject = None - inputState = 0 - - self._lastState = inputState - - -# -# control the accumulaiton of run time based on generator input Running state -# if the internal state is RUNNING run time is accumulated in self._accumulatedRunTime -# run time is accumulated if the generator's running state is known to be running or -# if the generator running state can't be determined -# the accumulated time dBus parameter and daily and total time accumulators are updated -# only once everh 60 seconds to minimize processor load -# if the internal state is STOPPED, one last dBus, daily and total time updates are done -# then the current time accumulator is cleared - - def _accumulateRunTime (self): - - mtime = monotonic_time.monotonic_time().to_seconds_double() - - # grab running state from dBus once, use it many timed below - - if self._dbusservice['/State'] == States.RUNNING: - internalRun = True - else: - internalRun = False - - # if internal state is running, accumulate time if generator is running - if internalRun: - accumuateTime = True - # start new accumulation if not done prevously - if self._last_accumulate_time == 0: - self._last_accumulate_time = mtime - - # if link to external state is enabled, don't accumulate time if running state is stopped (accumulate if R or ?) - if self._linkToExternalState: - try: - if self._dbusservice['/GeneratorRunningState'] == "S": - accumuateTime = False - - # if no Forwarder service, allow accumulation - except dbus.DBusException: - self.log_info ("dBus exception in startstop.py") - - # internal state STOPPED so don't add new time to the accumulation - # but there may be time already accumulated that needs to be added to daily and total accumulations - else: - accumuateTime = False - - # accumulate run time if we passed all the tests above - if accumuateTime: - self._accumulatedRunTime += mtime - self._last_accumulate_time - self._last_accumulate_time = mtime - - # dbus and settings updates trigger time-intensive processing so only do this once every 60 seconds - doUpdate = False - if internalRun: - if mtime - self._last_update_mtime >= 60: - doUpdate = True - self._last_update_mtime = mtime - # it is also done one last time when state is no longer RUNNING - elif self._last_update_mtime != 0: - doUpdate = True - - if doUpdate: - self._update_accumulated_time() - - # stopped - clear the current time accumulator - if internalRun == False: - self._last_update_mtime = 0 - self._accumulatedRunTime = 0 - self._last_accumulate_time = 0 - - self._dbusservice['/Runtime'] = int(self._accumulatedRunTime) diff --git a/FileSets/v2.89/startstop.py.orig b/FileSets/v2.89/startstop.py.orig deleted file mode 100644 index a83b75f7..00000000 --- a/FileSets/v2.89/startstop.py.orig +++ /dev/null @@ -1,970 +0,0 @@ -#!/usr/bin/python -u -# -*- coding: utf-8 -*- - -# Function -# dbus_generator monitors the dbus for batteries (com.victronenergy.battery.*) and -# vebus com.victronenergy.vebus.* -# Battery and vebus monitors can be configured through the gui. -# It then monitors SOC, AC loads, battery current and battery voltage,to auto start/stop the generator based -# on the configuration settings. Generator can be started manually or periodically setting a tes trun period. -# Time zones function allows to use different values for the conditions along the day depending on time - -import dbus -import datetime -import calendar -import time -import sys -import json -import os -import logging -from os import environ -import monotonic_time -from gen_utils import DBusServicePrefix, SettingsPrefix, Errors, States, enum -# Victron packages -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) -from ve_utils import exit_on_error -from settingsdevice import SettingsDevice - -RunningConditions = enum( - Stopped = 0, - Manual = 1, - TestRun = 2, - LossOfCommunication = 3, - Soc = 4, - Acload = 5, - BatteryCurrent = 6, - BatteryVoltage = 7, - InverterHighTemp = 8, - InverterOverload = 9, - StopOnAc1 = 10) - -SYSTEM_SERVICE = 'com.victronenergy.system' -BATTERY_PREFIX = '/Dc/Battery' -HISTORY_DAYS = 30 - -def safe_max(args): - try: - return max(x for x in args if x is not None) - except ValueError: - return None - -class StartStop(object): - def __init__(self): - self._dbusservice = None - self._settings = None - self._dbusmonitor = None - self._remoteservice = None - self._name = None - self._enabled = False - - # One second per retry - self.RETRIES_ON_ERROR = 300 - self._testrun_soc_retries = 0 - self._last_counters_check = 0 - - self._starttime = 0 - self._manualstarttimer = 0 - self._last_runtime_update = 0 - self._timer_runnning = 0 - - # Manual battery service selection is deprecated in favour - # of getting the values directly from systemcalc, we keep - # manual selected services handling for compatibility reasons. - self._vebusservice = None - self._errorstate = 0 - self._battery_service = None - self._battery_prefix = None - - self._acpower_inverter_input = { - 'timeout': 0, - 'unabletostart': False - } - - self._condition_stack = { - 'batteryvoltage': { - 'name': 'batteryvoltage', - 'reached': False, - 'boolean': False, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'battery' - }, - 'batterycurrent': { - 'name': 'batterycurrent', - 'reached': False, - 'boolean': False, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'battery' - }, - 'acload': { - 'name': 'acload', - 'reached': False, - 'boolean': False, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - }, - 'inverterhightemp': { - 'name': 'inverterhightemp', - 'reached': False, - 'boolean': True, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - }, - 'inverteroverload': { - 'name': 'inverteroverload', - 'reached': False, - 'boolean': True, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - }, - 'soc': { - 'name': 'soc', - 'reached': False, - 'boolean': False, - 'timed': False, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'battery' - }, - 'stoponac1': { - 'name': 'stoponac1', - 'reached': False, - 'boolean': True, - 'timed': False, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - } - } - - def set_sources(self, dbusmonitor, dbusservice, settings, name, remoteservice): - self._dbusservice = DBusServicePrefix(dbusservice, name) - self._settings = SettingsPrefix(settings, name) - self._dbusmonitor = dbusmonitor - self._remoteservice = remoteservice - self._name = name - # Set timezone to user selected timezone - tz = self._dbusmonitor.get_value('com.victronenergy.settings', '/Settings/System/TimeZone') - environ['TZ'] = tz if tz else 'UTC' - time.tzset() - - self.log_info('Start/stop instance created for %s.' % self._remoteservice) - self._remote_setup() - - def _create_paths(self): - # State: None = invalid, 0 = stopped, 1 = running - self._dbusservice.add_path('/State', value=None) - # RunningByConditionCode: Numeric Companion to /RunningByCondition below, but - # also encompassing a Stopped state. - self._dbusservice.add_path('/RunningByConditionCode', value=None) - # Error - self._dbusservice.add_path('/Error', value=None, gettextcallback=self._gettext) - # Condition that made the generator start - self._dbusservice.add_path('/RunningByCondition', value=None) - # Runtime - self._dbusservice.add_path('/Runtime', value=None, gettextcallback=self._gettext) - # Today runtime - self._dbusservice.add_path('/TodayRuntime', value=None, gettextcallback=self._gettext) - # Test run runtime - self._dbusservice.add_path('/TestRunIntervalRuntime', value=None , gettextcallback=self._gettext) - # Next test run date, values is 0 for test run disabled - self._dbusservice.add_path('/NextTestRun', value=None, gettextcallback=self._gettext) - # Next test run is needed 1, not needed 0 - self._dbusservice.add_path('/SkipTestRun', value=None) - # Manual start - self._dbusservice.add_path('/ManualStart', value=None, writeable=True) - # Manual start timer - self._dbusservice.add_path('/ManualStartTimer', value=None, writeable=True) - # Silent mode active - self._dbusservice.add_path('/QuietHours', value=None) - # Alarms - self._dbusservice.add_path('/Alarms/NoGeneratorAtAcIn', value=None) - - # We need to set the values after creating the paths to trigger the 'onValueChanged' event for the gui - # otherwise the gui will report the paths as invalid if we remove and recreate the paths without - # restarting the dbusservice. - self._dbusservice['/State'] = 0 - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped - self._dbusservice['/Error'] = 0 - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/Runtime'] = 0 - self._dbusservice['/TodayRuntime'] = 0 - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - self._dbusservice['/NextTestRun'] = None - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/ManualStart'] = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._dbusservice['/QuietHours'] = 0 - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - - - - def enable(self): - if self._enabled: - return - self.log_info('Enabling auto start/stop and taking control of remote switch') - self._create_paths() - self._determineservices() - self._update_remote_switch() - self._enabled = True - - def disable(self): - if not self._enabled: - return - self.log_info('Disabling auto start/stop, releasing control of remote switch') - self._remove_paths() - self._enabled = False - - def remove(self): - self.disable() - self.log_info('Removed from start/stop instances') - - def _remove_paths(self): - self._dbusservice.__delitem__('/State') - self._dbusservice.__delitem__('/RunningByConditionCode') - self._dbusservice.__delitem__('/Error') - self._dbusservice.__delitem__('/RunningByCondition') - self._dbusservice.__delitem__('/Runtime') - self._dbusservice.__delitem__('/TodayRuntime') - self._dbusservice.__delitem__('/TestRunIntervalRuntime') - self._dbusservice.__delitem__('/NextTestRun') - self._dbusservice.__delitem__('/SkipTestRun') - self._dbusservice.__delitem__('/ManualStart') - self._dbusservice.__delitem__('/ManualStartTimer') - self._dbusservice.__delitem__('/QuietHours') - self._dbusservice.__delitem__('/Alarms/NoGeneratorAtAcIn') - - def device_added(self, dbusservicename, instance): - self._determineservices() - - def device_removed(self, dbusservicename, instance): - self._determineservices() - - def get_error(self): - return self._dbusservice['/Error'] - - def set_error(self, errorn): - self._dbusservice['/Error'] = errorn - - def clear_error(self): - self._dbusservice['/Error'] = Errors.NONE - - def dbus_value_changed(self, dbusServiceName, dbusPath, options, changes, deviceInstance): - if self._dbusservice is None: - return - if dbusPath == '/AutoSelectedBatteryMeasurement' and self._settings['batterymeasurement'] == 'default': - self._determineservices() - - if dbusPath == '/VebusService': - self._determineservices() - - # Update env timezone when setting changes - if dbusPath == '/Settings/System/TimeZone': - environ['TZ'] = changes['Value'] if changes['Value'] else 'UTC' - - def handlechangedsetting(self, setting, oldvalue, newvalue): - if self._dbusservice is None: - return - if self._name not in setting: - # Not our setting - return - - s = self._settings.removeprefix(setting) - - if s == 'batterymeasurement': - self._determineservices() - # Reset retries and valid if service changes - for condition in self._condition_stack: - if self._condition_stack[condition]['monitoring'] == 'battery': - self._condition_stack[condition]['valid'] = True - self._condition_stack[condition]['retries'] = 0 - - if s == 'autostart': - self.log_info('Autostart function %s.' % ('enabled' if newvalue == 1 else 'disabled')) - - if self._dbusservice is not None and s == 'testruninterval': - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime( - self._settings['testruninterval']) - - def dbus_name_owner_changed(self, name, oldowner, newowner): - self._determineservices() - - def _gettext(self, path, value): - path = path.replace("/" + self._name, '') - - if path == '/Error': - return Errors.get_description(value) - if path == '/NextTestRun': - # Locale format date - d = datetime.datetime.fromtimestamp(value) - return d.strftime('%c') - elif path in ['/Runtime', '/TestRunIntervalRuntime', '/TodayRuntime']: - m, s = divmod(value, 60) - h, m = divmod(m, 60) - return '%dh, %dm, %ds' % (h, m, s) - else: - return str(value) - - def log_info(self, msg): - logging.info(self._name + ': %s' % msg) - - def tick(self): - if not self._enabled: - return - self._check_remote_status() - self._evaluate_startstop_conditions() - self._detect_generator_at_acinput() - - def _evaluate_startstop_conditions(self): - if self.get_error() != Errors.NONE: - # First evaluation after an error, log it - if self._errorstate == 0: - self._errorstate = 1 - self._dbusservice['/State'] = States.ERROR - self.log_info('Error: #%i - %s, stop controlling remote.' % - (self.get_error(), - Errors.get_description(self.get_error()))) - elif self._errorstate == 1: - # Error cleared - self._errorstate = 0 - self.log_info('Error state cleared, taking control of remote switch.') - - # Conditions will be evaluated in this order - conditions = ['soc', 'acload', 'batterycurrent', 'batteryvoltage', 'inverterhightemp', 'inverteroverload', 'stoponac1'] - start = False - startbycondition = None - activecondition = self._dbusservice['/RunningByCondition'] - today = calendar.timegm(datetime.date.today().timetuple()) - self._timer_runnning = False - values = self._get_updated_values() - connection_lost = False - - self._check_quiet_hours() - - # New day, register it - if self._last_counters_check < today and self._dbusservice['/State'] == States.STOPPED: - self._last_counters_check = today - self._update_accumulated_time() - - # Update current and accumulated runtime. - # By performance reasons, accumulated runtime is only updated - # once per 60s. When the generator stops is also updated. - if self._dbusservice['/State'] == States.RUNNING: - mtime = monotonic_time.monotonic_time().to_seconds_double() - if (mtime - self._starttime) - self._last_runtime_update >= 60: - self._dbusservice['/Runtime'] = int(mtime - self._starttime) - self._update_accumulated_time() - elif self._last_runtime_update == 0: - self._dbusservice['/Runtime'] = int(mtime - self._starttime) - - - if self._evaluate_manual_start(): - startbycondition = 'manual' - start = True - - # Conditions will only be evaluated if the autostart functionality is enabled - if self._settings['autostart'] == 1: - - if self._evaluate_testrun_condition(): - startbycondition = 'testrun' - start = True - - # Evaluate value conditions - for condition in conditions: - start = self._evaluate_condition(self._condition_stack[condition], values[condition]) or start - startbycondition = condition if start and startbycondition is None else startbycondition - # Connection lost is set to true if the number of retries of one or more enabled conditions - # >= RETRIES_ON_ERROR - if self._condition_stack[condition]['enabled']: - connection_lost = self._condition_stack[condition]['retries'] >= self.RETRIES_ON_ERROR - - if self._condition_stack['stoponac1']['reached'] and startbycondition not in ['manual', 'testrun']: - start = False - if self._dbusservice['/State'] == States.RUNNING and activecondition not in ['manual', 'testrun']: - self.log_info('AC input 1 available, stopping') - - # If none condition is reached check if connection is lost and start/keep running the generator - # depending on '/OnLossCommunication' setting - if not start and connection_lost: - # Start always - if self._settings['onlosscommunication'] == 1: - start = True - startbycondition = 'lossofcommunication' - # Keep running if generator already started - if self._dbusservice['/State'] == States.RUNNING and self._settings['onlosscommunication'] == 2: - start = True - startbycondition = 'lossofcommunication' - - if not start and self._errorstate: - self._stop_generator() - - if self._errorstate: - return - - if start: - self._start_generator(startbycondition) - elif (self._dbusservice['/Runtime'] >= self._settings['minimumruntime'] * 60 - or activecondition == 'manual'): - self._stop_generator() - - def _detect_generator_at_acinput(self): - state = self._dbusservice['/State'] - - if state == States.STOPPED: - self._reset_acpower_inverter_input() - return - - if self._settings['nogeneratoratacinalarm'] == 0: - self._reset_acpower_inverter_input() - return - - vebus_service = self._vebusservice if self._vebusservice else '' - activein_state = self._dbusmonitor.get_value( - vebus_service, '/Ac/ActiveIn/Connected') - - # Path not supported, skip evaluation - if activein_state == None: - return - - # Sources 0 = Not available, 1 = Grid, 2 = Generator, 3 = Shore - generator_acsource = self._dbusmonitor.get_value( - SYSTEM_SERVICE, '/Ac/ActiveIn/Source') == 2 - # Not connected = 0, connected = 1 - activein_connected = activein_state == 1 - - if generator_acsource and activein_connected: - if self._acpower_inverter_input['unabletostart']: - self.log_info('Generator detected at inverter AC input, alarm removed') - self._reset_acpower_inverter_input() - elif self._acpower_inverter_input['timeout'] < self.RETRIES_ON_ERROR: - self._acpower_inverter_input['timeout'] += 1 - elif not self._acpower_inverter_input['unabletostart']: - self._acpower_inverter_input['unabletostart'] = True - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 2 - self.log_info('Generator not detected at inverter AC input, triggering alarm') - - def _reset_acpower_inverter_input(self, clear_error=True): - if self._acpower_inverter_input['timeout'] != 0: - self._acpower_inverter_input['timeout'] = 0 - - if self._acpower_inverter_input['unabletostart'] != 0: - self._acpower_inverter_input['unabletostart'] = 0 - - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - - def _reset_condition(self, condition): - condition['reached'] = False - if condition['timed']: - condition['start_timer'] = 0 - condition['stop_timer'] = 0 - - def _check_condition(self, condition, value): - name = condition['name'] - - if self._settings[name + 'enabled'] == 0: - if condition['enabled']: - condition['enabled'] = False - self.log_info('Disabling (%s) condition' % name) - condition['retries'] = 0 - condition['valid'] = True - self._reset_condition(condition) - return False - - elif not condition['enabled']: - condition['enabled'] = True - self.log_info('Enabling (%s) condition' % name) - - if (condition['monitoring'] == 'battery') and (self._settings['batterymeasurement'] == 'nobattery'): - # If no battery monitor is selected reset the condition - self._reset_condition(condition) - return False - - if value is None and condition['valid']: - if condition['retries'] >= self.RETRIES_ON_ERROR: - logging.info('Error getting (%s) value, skipping evaluation till get a valid value' % name) - self._reset_condition(condition) - self._comunnication_lost = True - condition['valid'] = False - else: - condition['retries'] += 1 - if condition['retries'] == 1 or (condition['retries'] % 10) == 0: - self.log_info('Error getting (%s) value, retrying(#%i)' % (name, condition['retries'])) - return False - - elif value is not None and not condition['valid']: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['valid'] = True - condition['retries'] = 0 - - # Reset retries if value is valid - if value is not None and condition['retries'] > 0: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['retries'] = 0 - - return condition['valid'] - - def _evaluate_condition(self, condition, value): - name = condition['name'] - setting = ('qh_' if self._dbusservice['/QuietHours'] == 1 else '') + name - startvalue = self._settings[setting + 'start'] if not condition['boolean'] else 1 - stopvalue = self._settings[setting + 'stop'] if not condition['boolean'] else 0 - - # Check if the condition has to be evaluated - if not self._check_condition(condition, value): - # If generator is started by this condition and value is invalid - # wait till RETRIES_ON_ERROR to skip the condition - if condition['reached'] and condition['retries'] <= self.RETRIES_ON_ERROR: - if condition['retries'] > 0: - return True - - return False - - # As this is a generic evaluation method, we need to know how to compare the values - # first check if start value should be greater than stop value and then compare - start_is_greater = startvalue > stopvalue - - # When the condition is already reached only the stop value can set it to False - start = condition['reached'] or (value >= startvalue if start_is_greater else value <= startvalue) - stop = value <= stopvalue if start_is_greater else value >= stopvalue - - # Timed conditions must start/stop after the condition has been reached for a minimum - # time. - if condition['timed']: - if not condition['reached'] and start: - condition['start_timer'] += time.time() if condition['start_timer'] == 0 else 0 - start = time.time() - condition['start_timer'] >= self._settings[name + 'starttimer'] - condition['stop_timer'] *= int(not start) - self._timer_runnning = True - else: - condition['start_timer'] = 0 - - if condition['reached'] and stop: - condition['stop_timer'] += time.time() if condition['stop_timer'] == 0 else 0 - stop = time.time() - condition['stop_timer'] >= self._settings[name + 'stoptimer'] - condition['stop_timer'] *= int(not stop) - self._timer_runnning = True - else: - condition['stop_timer'] = 0 - - condition['reached'] = start and not stop - return condition['reached'] - - def _evaluate_manual_start(self): - if self._dbusservice['/ManualStart'] == 0: - if self._dbusservice['/RunningByCondition'] == 'manual': - self._dbusservice['/ManualStartTimer'] = 0 - return False - - start = True - # If /ManualStartTimer has a value greater than zero will use it to set a stop timer. - # If no timer is set, the generator will not stop until the user stops it manually. - # Once started by manual start, each evaluation the timer is decreased - if self._dbusservice['/ManualStartTimer'] != 0: - self._manualstarttimer += time.time() if self._manualstarttimer == 0 else 0 - self._dbusservice['/ManualStartTimer'] -= int(time.time()) - int(self._manualstarttimer) - self._manualstarttimer = time.time() - start = self._dbusservice['/ManualStartTimer'] > 0 - self._dbusservice['/ManualStart'] = int(start) - # Reset if timer is finished - self._manualstarttimer *= int(start) - self._dbusservice['/ManualStartTimer'] *= int(start) - - return start - - def _evaluate_testrun_condition(self): - if self._settings['testrunenabled'] == 0: - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/NextTestRun'] = None - return False - - today = datetime.date.today() - yesterday = today - datetime.timedelta(days=1) # Should deal well with DST - now = time.time() - runtillbatteryfull = self._settings['testruntillbatteryfull'] == 1 - soc = self._get_updated_values()['soc'] - batteryisfull = runtillbatteryfull and soc == 100 - duration = 60 if runtillbatteryfull else self._settings['testrunruntime'] - - try: - startdate = datetime.date.fromtimestamp(self._settings['testrunstartdate']) - _starttime = time.mktime(yesterday.timetuple()) + self._settings['testrunstarttimer'] - - # today might in fact still be yesterday, if this test run started - # before midnight and finishes after. If `now` still falls in - # yesterday's window, then by the temporal anthropic principle, - # which I just made up but loosely states that time must have - # these properties for observers to exist, it must be yesterday - # because we are here to observe it. - if _starttime <= now <= _starttime + duration: - today = yesterday - starttime = _starttime - else: - starttime = time.mktime(today.timetuple()) + self._settings['testrunstarttimer'] - except ValueError: - logging.debug('Invalid dates, skipping testrun') - return False - - # If start date is in the future set as NextTestRun and stop evaluating - if startdate > today: - self._dbusservice['/NextTestRun'] = time.mktime(startdate.timetuple()) - return False - - start = False - # If the accumulated runtime during the tes trun interval is greater than '/TestRunIntervalRuntime' - # the tes trun must be skipped - needed = (self._settings['testrunskipruntime'] > self._dbusservice['/TestRunIntervalRuntime'] - or self._settings['testrunskipruntime'] == 0) - self._dbusservice['/SkipTestRun'] = int(not needed) - - interval = self._settings['testruninterval'] - stoptime = starttime + duration - elapseddays = (today - startdate).days - mod = elapseddays % interval - - start = not bool(mod) and starttime <= now <= stoptime - - if runtillbatteryfull: - if soc is not None: - self._testrun_soc_retries = 0 - start = (start or self._dbusservice['/RunningByCondition'] == 'testrun') and not batteryisfull - elif self._dbusservice['/RunningByCondition'] == 'testrun': - if self._testrun_soc_retries < self.RETRIES_ON_ERROR: - self._testrun_soc_retries += 1 - start = True - if (self._testrun_soc_retries % 10) == 0: - self.log_info('Test run failed to get SOC value, retrying(#%i)' % self._testrun_soc_retries) - else: - self.log_info('Failed to get SOC after %i retries, terminating test run condition' % self._testrun_soc_retries) - start = False - else: - start = False - - if not bool(mod) and (now <= stoptime): - self._dbusservice['/NextTestRun'] = starttime - else: - self._dbusservice['/NextTestRun'] = (time.mktime((today + datetime.timedelta(days=interval - mod)).timetuple()) + - self._settings['testrunstarttimer']) - return start and needed - - def _check_quiet_hours(self): - active = False - if self._settings['quiethoursenabled'] == 1: - # Seconds after today 00:00 - timeinseconds = time.time() - time.mktime(datetime.date.today().timetuple()) - quiethoursstart = self._settings['quiethoursstarttime'] - quiethoursend = self._settings['quiethoursendtime'] - - # Check if the current time is between the start time and end time - if quiethoursstart < quiethoursend: - active = quiethoursstart <= timeinseconds and timeinseconds < quiethoursend - else: # End time is lower than start time, example Start: 21:00, end: 08:00 - active = not (quiethoursend < timeinseconds and timeinseconds < quiethoursstart) - - if self._dbusservice['/QuietHours'] == 0 and active: - self.log_info('Entering to quiet mode') - - elif self._dbusservice['/QuietHours'] == 1 and not active: - self.log_info('Leaving quiet mode') - - self._dbusservice['/QuietHours'] = int(active) - - return active - - def _update_accumulated_time(self): - seconds = self._dbusservice['/Runtime'] - accumulated = seconds - self._last_runtime_update - - self._settings['accumulatedtotal'] = int(self._settings['accumulatedtotal']) + accumulated - # Using calendar to get timestamp in UTC, not local time - today_date = str(calendar.timegm(datetime.date.today().timetuple())) - - # If something goes wrong getting the json string create a new one - try: - accumulated_days = json.loads(self._settings['accumulateddaily']) - except ValueError: - accumulated_days = {today_date: 0} - - if (today_date in accumulated_days): - accumulated_days[today_date] += accumulated - else: - accumulated_days[today_date] = accumulated - - self._last_runtime_update = seconds - - # Keep the historical with a maximum of HISTORY_DAYS - while len(accumulated_days) > HISTORY_DAYS: - accumulated_days.pop(min(accumulated_days.keys()), None) - - # Upadate settings - self._settings['accumulateddaily'] = json.dumps(accumulated_days, sort_keys=True) - self._dbusservice['/TodayRuntime'] = self._interval_runtime(0) - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - - def _interval_runtime(self, days): - summ = 0 - try: - daily_record = json.loads(self._settings['accumulateddaily']) - except ValueError: - return 0 - - for i in range(days + 1): - previous_day = calendar.timegm((datetime.date.today() - datetime.timedelta(days=i)).timetuple()) - if str(previous_day) in daily_record.keys(): - summ += daily_record[str(previous_day)] if str(previous_day) in daily_record.keys() else 0 - - return summ - - def _get_battery(self): - battery = {} - if self._settings['batterymeasurement'] == 'default': - battery['service'] = SYSTEM_SERVICE - battery['prefix'] = BATTERY_PREFIX - else: - battery['service'] = self._battery_service if self._battery_service else '' - battery['prefix'] = self._battery_prefix if self._battery_prefix else '' - - return battery - - def _get_updated_values(self): - battery = self._get_battery() - vebus_service = self._vebusservice if self._vebusservice else '' - loadOnAcOut = [] - totalConsumption = [] - inverterHighTemp = [] - inverterOverload = [] - - values = { - 'batteryvoltage': self._dbusmonitor.get_value(battery['service'], battery['prefix'] + '/Voltage'), - 'batterycurrent': self._dbusmonitor.get_value(battery['service'], battery['prefix'] + '/Current'), - # Soc from the device doesn't have the '/Dc/0' prefix like the current and voltage do, but it does - # have the same prefix on systemcalc - 'soc': self._dbusmonitor.get_value(battery['service'], (battery['prefix'] if battery['prefix'] == BATTERY_PREFIX else '') + '/Soc'), - 'inverterhightemp': self._dbusmonitor.get_value(vebus_service, '/Alarms/HighTemperature'), - 'inverteroverload': self._dbusmonitor.get_value(vebus_service, '/Alarms/Overload') - } - - for phase in ['L1', 'L2', 'L3']: - # Get the values directly from the inverter, systemcalc doesn't provide raw inverted power - loadOnAcOut.append(self._dbusmonitor.get_value(vebus_service, ('/Ac/Out/%s/P' % phase))) - - # Calculate total consumption, '/Ac/Consumption/%s/Power' is deprecated - c_i = self._dbusmonitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnInput/%s/Power' % phase)) - c_o = self._dbusmonitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnOutput/%s/Power' % phase)) - totalConsumption.append(sum(filter(None, (c_i, c_o)))) - - # Inverter alarms must be fetched directly from the inverter service - inverterHighTemp.append(self._dbusmonitor.get_value(vebus_service, ('/Alarms/%s/HighTemperature' % phase))) - inverterOverload.append(self._dbusmonitor.get_value(vebus_service, ('/Alarms/%s/Overload' % phase))) - - # Toltal consumption - if self._settings['acloadmeasuerment'] == 0: - values['acload'] = sum(filter(None, totalConsumption)) - - # Load on inverter AC out - if self._settings['acloadmeasuerment'] == 1: - values['acload'] = sum(filter(None, loadOnAcOut)) - - # Highest phase load - if self._settings['acloadmeasuerment'] == 2: - values['acload'] = safe_max(loadOnAcOut) - - # AC input 1 - activein = self._dbusmonitor.get_value(vebus_service, '/Ac/ActiveIn/ActiveInput') - # Active input is connected - connected = self._dbusmonitor.get_value(vebus_service, '/Ac/ActiveIn/Connected') - if None not in (activein, connected): - values['stoponac1'] = activein == 0 and connected == 1 - else: - values['stoponac1'] = None - - # Invalidate if vebus is not available - if loadOnAcOut[0] == None: - values['acload'] = None - - if values['batterycurrent']: - values['batterycurrent'] *= -1 - - # When multi is connected to CAN-bus, alarms are published to - # /Alarms/Overload... but when connected to vebus alarms are - # splitted in three phases and published to /Alarms/LX/Overload... - if values['inverteroverload'] == None: - values['inverteroverload'] = safe_max(inverterOverload) - - if values['inverterhightemp'] == None: - values['inverterhightemp'] = safe_max(inverterHighTemp) - - return values - - def _determineservices(self): - # batterymeasurement is either 'default' or 'com_victronenergy_battery_288/Dc/0'. - # In case it is set to default, we use the AutoSelected battery - # measurement, given by SystemCalc. - batterymeasurement = None - newbatteryservice = None - batteryprefix = '' - selectedbattery = self._settings['batterymeasurement'] - vebusservice = None - - if selectedbattery == 'default': - batterymeasurement = 'default' - elif len(selectedbattery.split('/', 1)) == 2: # Only very basic sanity checking.. - batterymeasurement = self._settings['batterymeasurement'] - elif selectedbattery == 'nobattery': - batterymeasurement = None - else: - # Exception: unexpected value for batterymeasurement - pass - - if batterymeasurement and batterymeasurement != 'default': - batteryprefix = '/' + batterymeasurement.split('/', 1)[1] - - # Get the current battery servicename - if self._battery_service: - oldservice = self._battery_service - else: - oldservice = None - - if batterymeasurement != 'default': - battery_instance = int(batterymeasurement.split('_', 3)[3].split('/')[0]) - service_type = None - - if 'vebus' in batterymeasurement: - service_type = 'vebus' - elif 'battery' in batterymeasurement: - service_type = 'battery' - - newbatteryservice = self._get_servicename_by_instance(battery_instance, service_type) - elif batterymeasurement == 'default': - newbatteryservice = 'default' - - if newbatteryservice and newbatteryservice != oldservice: - if selectedbattery == 'default': - self.log_info('Getting battery values from systemcalc.') - if selectedbattery == 'nobattery': - self.log_info('Battery monitoring disabled! Stop evaluating related conditions') - self._battery_service = None - self._battery_prefix = None - self.log_info('Battery service we need (%s) found! Using it for generator start/stop' % batterymeasurement) - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - elif not newbatteryservice and newbatteryservice != oldservice: - self.log_info('Error getting battery service!') - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - - # Get the default VE.Bus service - vebusservice = self._dbusmonitor.get_value('com.victronenergy.system', '/VebusService') - if vebusservice: - if self._vebusservice != vebusservice: - self._vebusservice = vebusservice - self.log_info('Vebus service (%s) found! Using it for generator start/stop' % vebusservice) - else: - if self._vebusservice is not None: - self.log_info('Vebus service (%s) dissapeared! Stop evaluating related conditions' % self._vebusservice) - else: - self.log_info('Error getting Vebus service!') - self._vebusservice = None - - def _get_servicename_by_instance(self, instance, service_type=None): - sv = None - services = self._dbusmonitor.get_service_list() - - for service in services: - if service_type and service_type not in service: - continue - - if services[service] == instance: - sv = service - break - - return sv - - def _get_monotonic_seconds(self): - return monotonic_time.monotonic_time().to_seconds_double() - - def _start_generator(self, condition): - state = self._dbusservice['/State'] - remote_state = self._get_remote_switch_state() - - # This function will start the generator in the case generator not - # already running. When differs, the RunningByCondition is updated - if state == States.STOPPED or remote_state != state: - self._dbusservice['/State'] = States.RUNNING - self._update_remote_switch() - self._starttime = monotonic_time.monotonic_time().to_seconds_double() - self.log_info('Starting generator by %s condition' % condition) - elif self._dbusservice['/RunningByCondition'] != condition: - self.log_info('Generator previously running by %s condition is now running by %s condition' - % (self._dbusservice['/RunningByCondition'], condition)) - - self._dbusservice['/RunningByCondition'] = condition - self._dbusservice['/RunningByConditionCode'] = RunningConditions.lookup(condition) - - def _stop_generator(self): - state = self._dbusservice['/State'] - remote_state = self._get_remote_switch_state() - - if state == 1 or remote_state != state: - self._dbusservice['/State'] = States.STOPPED - self._update_remote_switch() - self.log_info('Stopping generator that was running by %s condition' % - str(self._dbusservice['/RunningByCondition'])) - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped - self._update_accumulated_time() - self._starttime = 0 - self._dbusservice['/Runtime'] = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._manualstarttimer = 0 - self._last_runtime_update = 0 - - def _update_remote_switch(self): - self._set_remote_switch_state(dbus.Int32(self._dbusservice['/State'], variant_level=1)) - - def _get_remote_switch_state(self): - raise Exception('This function should be overridden') - - def _set_remote_switch_state(self, value): - raise Exception('This function should be overridden') - - # Check the remote status, for example errors - def _check_remote_status(self): - raise Exception('This function should be overridden') - - def _remote_setup(self): - raise Exception('This function should be overridden') - - def _create_dbus_monitor(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_settings(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_dbus_service(self): - raise Exception('This function should be overridden') diff --git a/FileSets/v2.89/styles.css b/FileSets/v2.89/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v2.89/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v2.90/Battery.qml b/FileSets/v2.90/Battery.qml deleted file mode 120000 index ef252511..00000000 --- a/FileSets/v2.90/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/Battery.qml \ No newline at end of file diff --git a/FileSets/v2.90/COMPLETE b/FileSets/v2.90/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.90/DetailAcInput.qml b/FileSets/v2.90/DetailAcInput.qml deleted file mode 120000 index b040d3b7..00000000 --- a/FileSets/v2.90/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v2.90/DetailInverter.qml b/FileSets/v2.90/DetailInverter.qml deleted file mode 120000 index d02cb165..00000000 --- a/FileSets/v2.90/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v2.90/DetailLoadsCombined.qml b/FileSets/v2.90/DetailLoadsCombined.qml deleted file mode 120000 index 858daaea..00000000 --- a/FileSets/v2.90/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v2.90/DetailLoadsOnInput.qml b/FileSets/v2.90/DetailLoadsOnInput.qml deleted file mode 120000 index df0a1562..00000000 --- a/FileSets/v2.90/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v2.90/DetailLoadsOnOutput.qml b/FileSets/v2.90/DetailLoadsOnOutput.qml deleted file mode 120000 index 33ab936b..00000000 --- a/FileSets/v2.90/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v2.90/HubData.qml b/FileSets/v2.90/HubData.qml deleted file mode 120000 index 8e608582..00000000 --- a/FileSets/v2.90/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/HubData.qml \ No newline at end of file diff --git a/FileSets/v2.90/LINKS_ONLY b/FileSets/v2.90/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.90/MbEditBox.qml b/FileSets/v2.90/MbEditBox.qml deleted file mode 120000 index 8381b7d5..00000000 --- a/FileSets/v2.90/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v2.90/MbEditBoxDateTime.qml b/FileSets/v2.90/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v2.90/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.90/MbItem.qml b/FileSets/v2.90/MbItem.qml deleted file mode 120000 index 1280e190..00000000 --- a/FileSets/v2.90/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItem.qml \ No newline at end of file diff --git a/FileSets/v2.90/MbItemDigitalInput.qml b/FileSets/v2.90/MbItemDigitalInput.qml deleted file mode 120000 index 63943a08..00000000 --- a/FileSets/v2.90/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.90/MbSpinBox.qml b/FileSets/v2.90/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v2.90/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v2.90/MbStyle.qml b/FileSets/v2.90/MbStyle.qml deleted file mode 120000 index db6f181f..00000000 --- a/FileSets/v2.90/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v2.90/MbSubMenu.qml b/FileSets/v2.90/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v2.90/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.90/Multi.qml b/FileSets/v2.90/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v2.90/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.90/ObjectAcConnection.qml b/FileSets/v2.90/ObjectAcConnection.qml deleted file mode 120000 index 9ca254ed..00000000 --- a/FileSets/v2.90/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v2.90/OverviewAcValuesEnhanced.qml b/FileSets/v2.90/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 4d6d5018..00000000 --- a/FileSets/v2.90/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.90/OverviewBox.qml b/FileSets/v2.90/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v2.90/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.90/OverviewConnection.qml b/FileSets/v2.90/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v2.90/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.90/OverviewConnectionEnd.qml b/FileSets/v2.90/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v2.90/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.90/OverviewFlowComplex.qml b/FileSets/v2.90/OverviewFlowComplex.qml deleted file mode 120000 index 6b747507..00000000 --- a/FileSets/v2.90/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v2.90/OverviewGeneratorEnhanced.qml b/FileSets/v2.90/OverviewGeneratorEnhanced.qml deleted file mode 120000 index b0670070..00000000 --- a/FileSets/v2.90/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.90/OverviewGeneratorRelayEnhanced.qml b/FileSets/v2.90/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index a73c8a3d..00000000 --- a/FileSets/v2.90/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.90/OverviewGridParallel.qml b/FileSets/v2.90/OverviewGridParallel.qml deleted file mode 120000 index cbf456ca..00000000 --- a/FileSets/v2.90/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v2.90/OverviewHub.qml b/FileSets/v2.90/OverviewHub.qml deleted file mode 120000 index 3f37eb0c..00000000 --- a/FileSets/v2.90/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v2.90/OverviewHubEnhanced.qml b/FileSets/v2.90/OverviewHubEnhanced.qml deleted file mode 120000 index 6dc4f1d8..00000000 --- a/FileSets/v2.90/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.90/OverviewMobileEnhanced.qml b/FileSets/v2.90/OverviewMobileEnhanced.qml deleted file mode 120000 index 018db24c..00000000 --- a/FileSets/v2.90/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.90/OverviewSolarCharger.qml b/FileSets/v2.90/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v2.90/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.90/OverviewSolarInverter.qml b/FileSets/v2.90/OverviewSolarInverter.qml deleted file mode 120000 index 7cea58a2..00000000 --- a/FileSets/v2.90/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v2.90/OverviewTankDelegate.qml b/FileSets/v2.90/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v2.90/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.90/OverviewTanks.qml b/FileSets/v2.90/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v2.90/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.90/OverviewTanksTempsDigInputs.qml b/FileSets/v2.90/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index a23a89ff..00000000 --- a/FileSets/v2.90/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v2.90/PageDigitalInput.qml b/FileSets/v2.90/PageDigitalInput.qml deleted file mode 120000 index 839f7874..00000000 --- a/FileSets/v2.90/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.90/PageGenerator.qml b/FileSets/v2.90/PageGenerator.qml deleted file mode 120000 index cae51ecb..00000000 --- a/FileSets/v2.90/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.90/PageMain.qml b/FileSets/v2.90/PageMain.qml deleted file mode 120000 index 5e666266..00000000 --- a/FileSets/v2.90/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageMain.qml \ No newline at end of file diff --git a/FileSets/v2.90/PageSettingsDisplay.qml b/FileSets/v2.90/PageSettingsDisplay.qml deleted file mode 120000 index 01b1e643..00000000 --- a/FileSets/v2.90/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v2.90/PageSettingsGenerator.qml b/FileSets/v2.90/PageSettingsGenerator.qml deleted file mode 120000 index 38551ef5..00000000 --- a/FileSets/v2.90/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.90/PageSettingsGuiMods.qml b/FileSets/v2.90/PageSettingsGuiMods.qml deleted file mode 120000 index 93ed29c4..00000000 --- a/FileSets/v2.90/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v2.90/PageSettingsRelay.qml b/FileSets/v2.90/PageSettingsRelay.qml deleted file mode 120000 index 6861254c..00000000 --- a/FileSets/v2.90/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v2.90/PowerGauge.qml b/FileSets/v2.90/PowerGauge.qml deleted file mode 120000 index d82ac28a..00000000 --- a/FileSets/v2.90/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v2.90/Tile.qml b/FileSets/v2.90/Tile.qml deleted file mode 120000 index aa80e332..00000000 --- a/FileSets/v2.90/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/Tile.qml \ No newline at end of file diff --git a/FileSets/v2.90/TileDigIn.qml b/FileSets/v2.90/TileDigIn.qml deleted file mode 120000 index db2f94da..00000000 --- a/FileSets/v2.90/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v2.90/TileRelay.qml b/FileSets/v2.90/TileRelay.qml deleted file mode 120000 index 29d3452b..00000000 --- a/FileSets/v2.90/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v2.90/TileText.qml b/FileSets/v2.90/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v2.90/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.90/attributes.csv b/FileSets/v2.90/attributes.csv deleted file mode 120000 index 4c220b6a..00000000 --- a/FileSets/v2.90/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v2.94/attributes.csv \ No newline at end of file diff --git a/FileSets/v2.90/dbus_digitalinputs.py b/FileSets/v2.90/dbus_digitalinputs.py deleted file mode 120000 index 1cc0e582..00000000 --- a/FileSets/v2.90/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v2.94/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v2.90/dbus_generator.py b/FileSets/v2.90/dbus_generator.py deleted file mode 120000 index 09bd88b5..00000000 --- a/FileSets/v2.90/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v2.90/dbus_systemcalc.py b/FileSets/v2.90/dbus_systemcalc.py deleted file mode 120000 index b200f73c..00000000 --- a/FileSets/v2.90/dbus_systemcalc.py +++ /dev/null @@ -1 +0,0 @@ -../v2.92/dbus_systemcalc.py \ No newline at end of file diff --git a/FileSets/v2.90/main.qml b/FileSets/v2.90/main.qml deleted file mode 120000 index a8f936b3..00000000 --- a/FileSets/v2.90/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/main.qml \ No newline at end of file diff --git a/FileSets/v2.90/startstop.py b/FileSets/v2.90/startstop.py deleted file mode 120000 index ba884560..00000000 --- a/FileSets/v2.90/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v2.94/startstop.py \ No newline at end of file diff --git a/FileSets/v2.90/styles.css b/FileSets/v2.90/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v2.90/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v2.91/Battery.qml b/FileSets/v2.91/Battery.qml deleted file mode 120000 index ef252511..00000000 --- a/FileSets/v2.91/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/Battery.qml \ No newline at end of file diff --git a/FileSets/v2.91/COMPLETE b/FileSets/v2.91/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.91/DetailAcInput.qml b/FileSets/v2.91/DetailAcInput.qml deleted file mode 120000 index b040d3b7..00000000 --- a/FileSets/v2.91/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v2.91/DetailInverter.qml b/FileSets/v2.91/DetailInverter.qml deleted file mode 120000 index d02cb165..00000000 --- a/FileSets/v2.91/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v2.91/DetailLoadsCombined.qml b/FileSets/v2.91/DetailLoadsCombined.qml deleted file mode 120000 index 858daaea..00000000 --- a/FileSets/v2.91/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v2.91/DetailLoadsOnInput.qml b/FileSets/v2.91/DetailLoadsOnInput.qml deleted file mode 120000 index df0a1562..00000000 --- a/FileSets/v2.91/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v2.91/DetailLoadsOnOutput.qml b/FileSets/v2.91/DetailLoadsOnOutput.qml deleted file mode 120000 index 33ab936b..00000000 --- a/FileSets/v2.91/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v2.91/HubData.qml b/FileSets/v2.91/HubData.qml deleted file mode 120000 index 8e608582..00000000 --- a/FileSets/v2.91/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/HubData.qml \ No newline at end of file diff --git a/FileSets/v2.91/LINKS_ONLY b/FileSets/v2.91/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.91/MbEditBox.qml b/FileSets/v2.91/MbEditBox.qml deleted file mode 120000 index 8381b7d5..00000000 --- a/FileSets/v2.91/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v2.91/MbEditBoxDateTime.qml b/FileSets/v2.91/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v2.91/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.91/MbItem.qml b/FileSets/v2.91/MbItem.qml deleted file mode 120000 index 1280e190..00000000 --- a/FileSets/v2.91/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItem.qml \ No newline at end of file diff --git a/FileSets/v2.91/MbItemDigitalInput.qml b/FileSets/v2.91/MbItemDigitalInput.qml deleted file mode 120000 index 63943a08..00000000 --- a/FileSets/v2.91/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.91/MbSpinBox.qml b/FileSets/v2.91/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v2.91/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v2.91/MbStyle.qml b/FileSets/v2.91/MbStyle.qml deleted file mode 120000 index db6f181f..00000000 --- a/FileSets/v2.91/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v2.91/MbSubMenu.qml b/FileSets/v2.91/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v2.91/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.91/Multi.qml b/FileSets/v2.91/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v2.91/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.91/ObjectAcConnection.qml b/FileSets/v2.91/ObjectAcConnection.qml deleted file mode 120000 index 9ca254ed..00000000 --- a/FileSets/v2.91/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v2.91/OverviewAcValuesEnhanced.qml b/FileSets/v2.91/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 4d6d5018..00000000 --- a/FileSets/v2.91/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.91/OverviewBox.qml b/FileSets/v2.91/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v2.91/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.91/OverviewConnection.qml b/FileSets/v2.91/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v2.91/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.91/OverviewConnectionEnd.qml b/FileSets/v2.91/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v2.91/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.91/OverviewFlowComplex.qml b/FileSets/v2.91/OverviewFlowComplex.qml deleted file mode 120000 index 6b747507..00000000 --- a/FileSets/v2.91/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v2.91/OverviewGeneratorEnhanced.qml b/FileSets/v2.91/OverviewGeneratorEnhanced.qml deleted file mode 120000 index b0670070..00000000 --- a/FileSets/v2.91/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.91/OverviewGeneratorRelayEnhanced.qml b/FileSets/v2.91/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index a73c8a3d..00000000 --- a/FileSets/v2.91/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.91/OverviewGridParallel.qml b/FileSets/v2.91/OverviewGridParallel.qml deleted file mode 120000 index cbf456ca..00000000 --- a/FileSets/v2.91/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v2.91/OverviewHub.qml b/FileSets/v2.91/OverviewHub.qml deleted file mode 120000 index 3f37eb0c..00000000 --- a/FileSets/v2.91/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v2.91/OverviewHubEnhanced.qml b/FileSets/v2.91/OverviewHubEnhanced.qml deleted file mode 120000 index 6dc4f1d8..00000000 --- a/FileSets/v2.91/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.91/OverviewMobileEnhanced.qml b/FileSets/v2.91/OverviewMobileEnhanced.qml deleted file mode 120000 index 018db24c..00000000 --- a/FileSets/v2.91/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.91/OverviewSolarCharger.qml b/FileSets/v2.91/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v2.91/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.91/OverviewSolarInverter.qml b/FileSets/v2.91/OverviewSolarInverter.qml deleted file mode 120000 index 7cea58a2..00000000 --- a/FileSets/v2.91/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v2.91/OverviewTankDelegate.qml b/FileSets/v2.91/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v2.91/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.91/OverviewTanks.qml b/FileSets/v2.91/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v2.91/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.91/OverviewTanksTempsDigInputs.qml b/FileSets/v2.91/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index a23a89ff..00000000 --- a/FileSets/v2.91/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v2.91/PageDigitalInput.qml b/FileSets/v2.91/PageDigitalInput.qml deleted file mode 120000 index 839f7874..00000000 --- a/FileSets/v2.91/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.91/PageGenerator.qml b/FileSets/v2.91/PageGenerator.qml deleted file mode 120000 index cae51ecb..00000000 --- a/FileSets/v2.91/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.91/PageMain.qml b/FileSets/v2.91/PageMain.qml deleted file mode 120000 index 5e666266..00000000 --- a/FileSets/v2.91/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageMain.qml \ No newline at end of file diff --git a/FileSets/v2.91/PageSettingsDisplay.qml b/FileSets/v2.91/PageSettingsDisplay.qml deleted file mode 120000 index 01b1e643..00000000 --- a/FileSets/v2.91/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v2.91/PageSettingsGenerator.qml b/FileSets/v2.91/PageSettingsGenerator.qml deleted file mode 120000 index 38551ef5..00000000 --- a/FileSets/v2.91/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.91/PageSettingsGuiMods.qml b/FileSets/v2.91/PageSettingsGuiMods.qml deleted file mode 120000 index 93ed29c4..00000000 --- a/FileSets/v2.91/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v2.91/PageSettingsRelay.qml b/FileSets/v2.91/PageSettingsRelay.qml deleted file mode 120000 index 6861254c..00000000 --- a/FileSets/v2.91/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v2.91/PowerGauge.qml b/FileSets/v2.91/PowerGauge.qml deleted file mode 120000 index d82ac28a..00000000 --- a/FileSets/v2.91/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v2.91/Tile.qml b/FileSets/v2.91/Tile.qml deleted file mode 120000 index aa80e332..00000000 --- a/FileSets/v2.91/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/Tile.qml \ No newline at end of file diff --git a/FileSets/v2.91/TileDigIn.qml b/FileSets/v2.91/TileDigIn.qml deleted file mode 120000 index db2f94da..00000000 --- a/FileSets/v2.91/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v2.91/TileRelay.qml b/FileSets/v2.91/TileRelay.qml deleted file mode 120000 index 29d3452b..00000000 --- a/FileSets/v2.91/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v2.91/TileText.qml b/FileSets/v2.91/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v2.91/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.91/attributes.csv b/FileSets/v2.91/attributes.csv deleted file mode 120000 index 4c220b6a..00000000 --- a/FileSets/v2.91/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v2.94/attributes.csv \ No newline at end of file diff --git a/FileSets/v2.91/dbus_digitalinputs.py b/FileSets/v2.91/dbus_digitalinputs.py deleted file mode 120000 index 1cc0e582..00000000 --- a/FileSets/v2.91/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v2.94/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v2.91/dbus_generator.py b/FileSets/v2.91/dbus_generator.py deleted file mode 120000 index 09bd88b5..00000000 --- a/FileSets/v2.91/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v2.91/dbus_systemcalc.py b/FileSets/v2.91/dbus_systemcalc.py deleted file mode 120000 index b200f73c..00000000 --- a/FileSets/v2.91/dbus_systemcalc.py +++ /dev/null @@ -1 +0,0 @@ -../v2.92/dbus_systemcalc.py \ No newline at end of file diff --git a/FileSets/v2.91/main.qml b/FileSets/v2.91/main.qml deleted file mode 120000 index a8f936b3..00000000 --- a/FileSets/v2.91/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/main.qml \ No newline at end of file diff --git a/FileSets/v2.91/startstop.py b/FileSets/v2.91/startstop.py deleted file mode 120000 index ba884560..00000000 --- a/FileSets/v2.91/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v2.94/startstop.py \ No newline at end of file diff --git a/FileSets/v2.91/styles.css b/FileSets/v2.91/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v2.91/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v2.92/Battery.qml b/FileSets/v2.92/Battery.qml deleted file mode 120000 index ef252511..00000000 --- a/FileSets/v2.92/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/Battery.qml \ No newline at end of file diff --git a/FileSets/v2.92/COMPLETE b/FileSets/v2.92/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.92/DetailAcInput.qml b/FileSets/v2.92/DetailAcInput.qml deleted file mode 120000 index b040d3b7..00000000 --- a/FileSets/v2.92/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v2.92/DetailInverter.qml b/FileSets/v2.92/DetailInverter.qml deleted file mode 120000 index d02cb165..00000000 --- a/FileSets/v2.92/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v2.92/DetailLoadsCombined.qml b/FileSets/v2.92/DetailLoadsCombined.qml deleted file mode 120000 index 858daaea..00000000 --- a/FileSets/v2.92/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v2.92/DetailLoadsOnInput.qml b/FileSets/v2.92/DetailLoadsOnInput.qml deleted file mode 120000 index df0a1562..00000000 --- a/FileSets/v2.92/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v2.92/DetailLoadsOnOutput.qml b/FileSets/v2.92/DetailLoadsOnOutput.qml deleted file mode 120000 index 33ab936b..00000000 --- a/FileSets/v2.92/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v2.92/HubData.qml b/FileSets/v2.92/HubData.qml deleted file mode 120000 index 8e608582..00000000 --- a/FileSets/v2.92/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/HubData.qml \ No newline at end of file diff --git a/FileSets/v2.92/LINKS_ONLY b/FileSets/v2.92/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.92/MbEditBox.qml b/FileSets/v2.92/MbEditBox.qml deleted file mode 120000 index 8381b7d5..00000000 --- a/FileSets/v2.92/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v2.92/MbEditBoxDateTime.qml b/FileSets/v2.92/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v2.92/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.92/MbItem.qml b/FileSets/v2.92/MbItem.qml deleted file mode 120000 index 1280e190..00000000 --- a/FileSets/v2.92/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItem.qml \ No newline at end of file diff --git a/FileSets/v2.92/MbItemDigitalInput.qml b/FileSets/v2.92/MbItemDigitalInput.qml deleted file mode 120000 index 63943a08..00000000 --- a/FileSets/v2.92/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.92/MbSpinBox.qml b/FileSets/v2.92/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v2.92/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v2.92/MbStyle.qml b/FileSets/v2.92/MbStyle.qml deleted file mode 120000 index db6f181f..00000000 --- a/FileSets/v2.92/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v2.92/MbSubMenu.qml b/FileSets/v2.92/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v2.92/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.92/Multi.qml b/FileSets/v2.92/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v2.92/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.92/ObjectAcConnection.qml b/FileSets/v2.92/ObjectAcConnection.qml deleted file mode 120000 index 9ca254ed..00000000 --- a/FileSets/v2.92/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v2.92/OverviewAcValuesEnhanced.qml b/FileSets/v2.92/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 4d6d5018..00000000 --- a/FileSets/v2.92/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.92/OverviewBox.qml b/FileSets/v2.92/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v2.92/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.92/OverviewConnection.qml b/FileSets/v2.92/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v2.92/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.92/OverviewConnectionEnd.qml b/FileSets/v2.92/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v2.92/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.92/OverviewFlowComplex.qml b/FileSets/v2.92/OverviewFlowComplex.qml deleted file mode 120000 index 6b747507..00000000 --- a/FileSets/v2.92/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v2.92/OverviewGeneratorEnhanced.qml b/FileSets/v2.92/OverviewGeneratorEnhanced.qml deleted file mode 120000 index b0670070..00000000 --- a/FileSets/v2.92/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.92/OverviewGeneratorRelayEnhanced.qml b/FileSets/v2.92/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index a73c8a3d..00000000 --- a/FileSets/v2.92/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.92/OverviewGridParallel.qml b/FileSets/v2.92/OverviewGridParallel.qml deleted file mode 120000 index cbf456ca..00000000 --- a/FileSets/v2.92/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v2.92/OverviewHub.qml b/FileSets/v2.92/OverviewHub.qml deleted file mode 120000 index 3f37eb0c..00000000 --- a/FileSets/v2.92/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v2.92/OverviewHubEnhanced.qml b/FileSets/v2.92/OverviewHubEnhanced.qml deleted file mode 120000 index 6dc4f1d8..00000000 --- a/FileSets/v2.92/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.92/OverviewMobileEnhanced.qml b/FileSets/v2.92/OverviewMobileEnhanced.qml deleted file mode 120000 index 018db24c..00000000 --- a/FileSets/v2.92/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.92/OverviewSolarCharger.qml b/FileSets/v2.92/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v2.92/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.92/OverviewSolarInverter.qml b/FileSets/v2.92/OverviewSolarInverter.qml deleted file mode 120000 index 7cea58a2..00000000 --- a/FileSets/v2.92/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v2.92/OverviewTankDelegate.qml b/FileSets/v2.92/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v2.92/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.92/OverviewTanks.qml b/FileSets/v2.92/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v2.92/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.92/OverviewTanksTempsDigInputs.qml b/FileSets/v2.92/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index a23a89ff..00000000 --- a/FileSets/v2.92/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v2.92/PageDigitalInput.qml b/FileSets/v2.92/PageDigitalInput.qml deleted file mode 120000 index 839f7874..00000000 --- a/FileSets/v2.92/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.92/PageGenerator.qml b/FileSets/v2.92/PageGenerator.qml deleted file mode 120000 index cae51ecb..00000000 --- a/FileSets/v2.92/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.92/PageMain.qml b/FileSets/v2.92/PageMain.qml deleted file mode 120000 index 5e666266..00000000 --- a/FileSets/v2.92/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageMain.qml \ No newline at end of file diff --git a/FileSets/v2.92/PageSettingsDisplay.qml b/FileSets/v2.92/PageSettingsDisplay.qml deleted file mode 120000 index 01b1e643..00000000 --- a/FileSets/v2.92/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v2.92/PageSettingsGenerator.qml b/FileSets/v2.92/PageSettingsGenerator.qml deleted file mode 120000 index 38551ef5..00000000 --- a/FileSets/v2.92/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.92/PageSettingsGuiMods.qml b/FileSets/v2.92/PageSettingsGuiMods.qml deleted file mode 120000 index 93ed29c4..00000000 --- a/FileSets/v2.92/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v2.92/PageSettingsRelay.qml b/FileSets/v2.92/PageSettingsRelay.qml deleted file mode 120000 index 6861254c..00000000 --- a/FileSets/v2.92/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v2.92/PowerGauge.qml b/FileSets/v2.92/PowerGauge.qml deleted file mode 120000 index d82ac28a..00000000 --- a/FileSets/v2.92/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v2.92/Tile.qml b/FileSets/v2.92/Tile.qml deleted file mode 120000 index aa80e332..00000000 --- a/FileSets/v2.92/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/Tile.qml \ No newline at end of file diff --git a/FileSets/v2.92/TileDigIn.qml b/FileSets/v2.92/TileDigIn.qml deleted file mode 120000 index db2f94da..00000000 --- a/FileSets/v2.92/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v2.92/TileRelay.qml b/FileSets/v2.92/TileRelay.qml deleted file mode 120000 index 29d3452b..00000000 --- a/FileSets/v2.92/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v2.92/TileText.qml b/FileSets/v2.92/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v2.92/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.92/attributes.csv b/FileSets/v2.92/attributes.csv deleted file mode 120000 index 4c220b6a..00000000 --- a/FileSets/v2.92/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v2.94/attributes.csv \ No newline at end of file diff --git a/FileSets/v2.92/dbus_digitalinputs.py b/FileSets/v2.92/dbus_digitalinputs.py deleted file mode 120000 index 1cc0e582..00000000 --- a/FileSets/v2.92/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v2.94/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v2.92/dbus_generator.py b/FileSets/v2.92/dbus_generator.py deleted file mode 120000 index 09bd88b5..00000000 --- a/FileSets/v2.92/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v2.92/main.qml b/FileSets/v2.92/main.qml deleted file mode 120000 index a8f936b3..00000000 --- a/FileSets/v2.92/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/main.qml \ No newline at end of file diff --git a/FileSets/v2.92/startstop.py b/FileSets/v2.92/startstop.py deleted file mode 120000 index ba884560..00000000 --- a/FileSets/v2.92/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v2.94/startstop.py \ No newline at end of file diff --git a/FileSets/v2.92/styles.css b/FileSets/v2.92/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v2.92/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v2.93/Battery.qml b/FileSets/v2.93/Battery.qml deleted file mode 120000 index ef252511..00000000 --- a/FileSets/v2.93/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/Battery.qml \ No newline at end of file diff --git a/FileSets/v2.93/COMPLETE b/FileSets/v2.93/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.93/DetailAcInput.qml b/FileSets/v2.93/DetailAcInput.qml deleted file mode 120000 index b040d3b7..00000000 --- a/FileSets/v2.93/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v2.93/DetailInverter.qml b/FileSets/v2.93/DetailInverter.qml deleted file mode 120000 index d02cb165..00000000 --- a/FileSets/v2.93/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v2.93/DetailLoadsCombined.qml b/FileSets/v2.93/DetailLoadsCombined.qml deleted file mode 120000 index 858daaea..00000000 --- a/FileSets/v2.93/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v2.93/DetailLoadsOnInput.qml b/FileSets/v2.93/DetailLoadsOnInput.qml deleted file mode 120000 index df0a1562..00000000 --- a/FileSets/v2.93/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v2.93/DetailLoadsOnOutput.qml b/FileSets/v2.93/DetailLoadsOnOutput.qml deleted file mode 120000 index 33ab936b..00000000 --- a/FileSets/v2.93/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v2.93/HubData.qml b/FileSets/v2.93/HubData.qml deleted file mode 120000 index 8e608582..00000000 --- a/FileSets/v2.93/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/HubData.qml \ No newline at end of file diff --git a/FileSets/v2.93/LINKS_ONLY b/FileSets/v2.93/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.93/MbEditBox.qml b/FileSets/v2.93/MbEditBox.qml deleted file mode 120000 index 8381b7d5..00000000 --- a/FileSets/v2.93/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v2.93/MbEditBoxDateTime.qml b/FileSets/v2.93/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v2.93/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.93/MbItem.qml b/FileSets/v2.93/MbItem.qml deleted file mode 120000 index 1280e190..00000000 --- a/FileSets/v2.93/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItem.qml \ No newline at end of file diff --git a/FileSets/v2.93/MbItemDigitalInput.qml b/FileSets/v2.93/MbItemDigitalInput.qml deleted file mode 120000 index 63943a08..00000000 --- a/FileSets/v2.93/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.93/MbSpinBox.qml b/FileSets/v2.93/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v2.93/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v2.93/MbStyle.qml b/FileSets/v2.93/MbStyle.qml deleted file mode 120000 index db6f181f..00000000 --- a/FileSets/v2.93/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v2.93/MbSubMenu.qml b/FileSets/v2.93/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v2.93/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.93/Multi.qml b/FileSets/v2.93/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v2.93/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.93/ObjectAcConnection.qml b/FileSets/v2.93/ObjectAcConnection.qml deleted file mode 120000 index 9ca254ed..00000000 --- a/FileSets/v2.93/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v2.93/OverviewAcValuesEnhanced.qml b/FileSets/v2.93/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 4d6d5018..00000000 --- a/FileSets/v2.93/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.93/OverviewBox.qml b/FileSets/v2.93/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v2.93/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.93/OverviewConnection.qml b/FileSets/v2.93/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v2.93/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.93/OverviewConnectionEnd.qml b/FileSets/v2.93/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v2.93/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.93/OverviewFlowComplex.qml b/FileSets/v2.93/OverviewFlowComplex.qml deleted file mode 120000 index 6b747507..00000000 --- a/FileSets/v2.93/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v2.93/OverviewGeneratorEnhanced.qml b/FileSets/v2.93/OverviewGeneratorEnhanced.qml deleted file mode 120000 index b0670070..00000000 --- a/FileSets/v2.93/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.93/OverviewGeneratorRelayEnhanced.qml b/FileSets/v2.93/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index a73c8a3d..00000000 --- a/FileSets/v2.93/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.93/OverviewGridParallel.qml b/FileSets/v2.93/OverviewGridParallel.qml deleted file mode 120000 index cbf456ca..00000000 --- a/FileSets/v2.93/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v2.93/OverviewHub.qml b/FileSets/v2.93/OverviewHub.qml deleted file mode 120000 index 3f37eb0c..00000000 --- a/FileSets/v2.93/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v2.93/OverviewHubEnhanced.qml b/FileSets/v2.93/OverviewHubEnhanced.qml deleted file mode 120000 index 6dc4f1d8..00000000 --- a/FileSets/v2.93/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.93/OverviewMobileEnhanced.qml b/FileSets/v2.93/OverviewMobileEnhanced.qml deleted file mode 120000 index 018db24c..00000000 --- a/FileSets/v2.93/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.93/OverviewSolarCharger.qml b/FileSets/v2.93/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v2.93/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.93/OverviewSolarInverter.qml b/FileSets/v2.93/OverviewSolarInverter.qml deleted file mode 120000 index 7cea58a2..00000000 --- a/FileSets/v2.93/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v2.93/OverviewTankDelegate.qml b/FileSets/v2.93/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v2.93/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.93/OverviewTanks.qml b/FileSets/v2.93/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v2.93/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.93/OverviewTanksTempsDigInputs.qml b/FileSets/v2.93/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index a23a89ff..00000000 --- a/FileSets/v2.93/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v2.93/PageDigitalInput.qml b/FileSets/v2.93/PageDigitalInput.qml deleted file mode 120000 index 839f7874..00000000 --- a/FileSets/v2.93/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v2.93/PageGenerator.qml b/FileSets/v2.93/PageGenerator.qml deleted file mode 120000 index cae51ecb..00000000 --- a/FileSets/v2.93/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.93/PageMain.qml b/FileSets/v2.93/PageMain.qml deleted file mode 120000 index 5e666266..00000000 --- a/FileSets/v2.93/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageMain.qml \ No newline at end of file diff --git a/FileSets/v2.93/PageSettingsDisplay.qml b/FileSets/v2.93/PageSettingsDisplay.qml deleted file mode 120000 index 01b1e643..00000000 --- a/FileSets/v2.93/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v2.93/PageSettingsGenerator.qml b/FileSets/v2.93/PageSettingsGenerator.qml deleted file mode 120000 index 38551ef5..00000000 --- a/FileSets/v2.93/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v2.93/PageSettingsGuiMods.qml b/FileSets/v2.93/PageSettingsGuiMods.qml deleted file mode 120000 index 93ed29c4..00000000 --- a/FileSets/v2.93/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v2.93/PageSettingsRelay.qml b/FileSets/v2.93/PageSettingsRelay.qml deleted file mode 120000 index 6861254c..00000000 --- a/FileSets/v2.93/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v2.93/PowerGauge.qml b/FileSets/v2.93/PowerGauge.qml deleted file mode 120000 index d82ac28a..00000000 --- a/FileSets/v2.93/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v2.93/Tile.qml b/FileSets/v2.93/Tile.qml deleted file mode 120000 index aa80e332..00000000 --- a/FileSets/v2.93/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/Tile.qml \ No newline at end of file diff --git a/FileSets/v2.93/TileDigIn.qml b/FileSets/v2.93/TileDigIn.qml deleted file mode 120000 index db2f94da..00000000 --- a/FileSets/v2.93/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v2.93/TileRelay.qml b/FileSets/v2.93/TileRelay.qml deleted file mode 120000 index 29d3452b..00000000 --- a/FileSets/v2.93/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v2.93/TileText.qml b/FileSets/v2.93/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v2.93/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.93/attributes.csv b/FileSets/v2.93/attributes.csv deleted file mode 120000 index 4c220b6a..00000000 --- a/FileSets/v2.93/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v2.94/attributes.csv \ No newline at end of file diff --git a/FileSets/v2.93/dbus_digitalinputs.py b/FileSets/v2.93/dbus_digitalinputs.py deleted file mode 120000 index 1cc0e582..00000000 --- a/FileSets/v2.93/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v2.94/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v2.93/dbus_generator.py b/FileSets/v2.93/dbus_generator.py deleted file mode 120000 index 09bd88b5..00000000 --- a/FileSets/v2.93/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v2.93/dbus_systemcalc.py b/FileSets/v2.93/dbus_systemcalc.py deleted file mode 120000 index 8070e46d..00000000 --- a/FileSets/v2.93/dbus_systemcalc.py +++ /dev/null @@ -1 +0,0 @@ -../v2.94/dbus_systemcalc.py \ No newline at end of file diff --git a/FileSets/v2.93/main.qml b/FileSets/v2.93/main.qml deleted file mode 120000 index a8f936b3..00000000 --- a/FileSets/v2.93/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v2.94/main.qml \ No newline at end of file diff --git a/FileSets/v2.93/startstop.py b/FileSets/v2.93/startstop.py deleted file mode 120000 index ba884560..00000000 --- a/FileSets/v2.93/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v2.94/startstop.py \ No newline at end of file diff --git a/FileSets/v2.93/styles.css b/FileSets/v2.93/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v2.93/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v2.94/Battery.qml b/FileSets/v2.94/Battery.qml deleted file mode 120000 index ef252511..00000000 --- a/FileSets/v2.94/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/Battery.qml \ No newline at end of file diff --git a/FileSets/v2.94/COMPLETE b/FileSets/v2.94/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v2.94/DetailAcInput.qml b/FileSets/v2.94/DetailAcInput.qml deleted file mode 120000 index b040d3b7..00000000 --- a/FileSets/v2.94/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v2.94/DetailInverter.qml b/FileSets/v2.94/DetailInverter.qml deleted file mode 120000 index d02cb165..00000000 --- a/FileSets/v2.94/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v2.94/DetailLoadsCombined.qml b/FileSets/v2.94/DetailLoadsCombined.qml deleted file mode 120000 index 858daaea..00000000 --- a/FileSets/v2.94/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v2.94/DetailLoadsOnInput.qml b/FileSets/v2.94/DetailLoadsOnInput.qml deleted file mode 120000 index df0a1562..00000000 --- a/FileSets/v2.94/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v2.94/DetailLoadsOnOutput.qml b/FileSets/v2.94/DetailLoadsOnOutput.qml deleted file mode 120000 index 33ab936b..00000000 --- a/FileSets/v2.94/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v2.94/HubData.qml b/FileSets/v2.94/HubData.qml deleted file mode 120000 index 8e608582..00000000 --- a/FileSets/v2.94/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/HubData.qml \ No newline at end of file diff --git a/FileSets/v2.94/MbEditBox.qml b/FileSets/v2.94/MbEditBox.qml deleted file mode 120000 index 8381b7d5..00000000 --- a/FileSets/v2.94/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v2.94/MbEditBoxDateTime.qml b/FileSets/v2.94/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v2.94/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.94/MbSpinBox.qml b/FileSets/v2.94/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v2.94/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v2.94/MbSubMenu.qml b/FileSets/v2.94/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v2.94/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.94/Multi.qml b/FileSets/v2.94/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v2.94/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.94/ObjectAcConnection.qml b/FileSets/v2.94/ObjectAcConnection.qml deleted file mode 120000 index 9ca254ed..00000000 --- a/FileSets/v2.94/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v2.94/OverviewAcValuesEnhanced.qml b/FileSets/v2.94/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 4d6d5018..00000000 --- a/FileSets/v2.94/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.94/OverviewBox.qml b/FileSets/v2.94/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v2.94/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.94/OverviewConnection.qml b/FileSets/v2.94/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v2.94/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.94/OverviewConnectionEnd.qml b/FileSets/v2.94/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v2.94/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.94/OverviewFlowComplex.qml b/FileSets/v2.94/OverviewFlowComplex.qml deleted file mode 120000 index 6b747507..00000000 --- a/FileSets/v2.94/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v2.94/OverviewGeneratorEnhanced.qml b/FileSets/v2.94/OverviewGeneratorEnhanced.qml deleted file mode 100644 index 50f7590d..00000000 --- a/FileSets/v2.94/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1,536 +0,0 @@ -// GuiMods enhanced generator overview -// This file has been modified to: -// add Auto Start display and control -// show voltage, current, frequency, and power gauge in AC input tile -// show the generator running state inside the icon top left -// show a warning when the generator digital input and expected generator state disagree -// move current run time to separate tile - -import QtQuick 1.1 -import "utils.js" as Utils -import "enhancedFormat.js" as EnhFmt - -OverviewPage { - id: root - - property string settingsBindPrefix - property string bindPrefix - property variant sys: theSystem -//////// added to show alternator in place of inactive genset - property string guiModsPrefix: "com.victronenergy.settings/Settings/GuiMods" - VBusItem { id: replaceAcInItem; bind: Utils.path(guiModsPrefix, "/ReplaceInactiveAcIn") } - property bool hasAlternator: sys.alternator.power.valid - property bool showAlternator: replaceAcInItem.valid && replaceAcInItem.value == 1 && hasAlternator && ! sys.genset.power.valid - property bool showAcIn: ! showAlternator - - property string icon: "image://theme/overview-generator" - property VBusItem state: VBusItem { bind: Utils.path(bindPrefix, "/State") } - property VBusItem error: VBusItem { bind: Utils.path(bindPrefix, "/Error") } - property VBusItem runningTime: VBusItem { bind: Utils.path(bindPrefix, "/Runtime") } - property VBusItem runningBy: VBusItem { bind: Utils.path(bindPrefix, "/RunningByConditionCode") } - property VBusItem totalAcummulatedTime: VBusItem { bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") } - property VBusItem quietHours: VBusItem { bind: Utils.path(bindPrefix, "/QuietHours") } - property VBusItem testRunDuration: VBusItem { bind: Utils.path(settingsBindPrefix, "/TestRun/Duration") } - property VBusItem nextTestRun: VBusItem { bind: Utils.path(bindPrefix, "/NextTestRun") } - property VBusItem skipTestRun: VBusItem { bind: Utils.path(bindPrefix, "/SkipTestRun") } - - property VBusItem todayRuntime: VBusItem { bind: Utils.path(bindPrefix, "/TodayRuntime") } - property VBusItem manualTimer: VBusItem { bind: Utils.path(bindPrefix, "/ManualStartTimer") } - property VBusItem autoStart: VBusItem { bind: Utils.path(settingsBindPrefix, "/AutoStartEnabled") } - - property bool errors: ! state.valid || state.value == 10 - - property VBusItem externalOverrideItem: VBusItem { bind: Utils.path(bindPrefix, "/ExternalOverride") } - property bool externalOverride: externalOverrideItem.valid && externalOverrideItem.value == 1 && ! errors - property VBusItem runningState: VBusItem { bind: Utils.path(bindPrefix, "/GeneratorRunningState") } - - VBusItem { id: showGaugesItem; bind: Utils.path(guiModsPrefix, "/ShowGauges") } - property bool showGauges: showGaugesItem.valid ? showGaugesItem.value === 1 ? true : false : false - property bool editMode: autoRunTile.editMode || manualTile.editMode - - VBusItem { id: generatorServiceInterval; bind: Utils.path(settingsBindPrefix, "/ServiceInterval") } - VBusItem { id: timeSinceService; bind: Utils.path(settingsBindPrefix, "/TimeSinceService") } - property bool showServiceInfo: timeSinceService.valid && generatorServiceInterval.valid && generatorServiceInterval.value > 0 - property bool serviceOverdue: showServiceInfo && timeSinceService.value > generatorServiceInterval.value - - //////// add to display AC input ignored - VBusItem { id: ignoreAcInput1; bind: Utils.path(sys.vebusPrefix, "/Ac/State/IgnoreAcIn1") } - VBusItem { id: ignoreAcInput2; bind: Utils.path(sys.vebusPrefix, "/Ac/State/IgnoreAcIn2") } - VBusItem { id: acActiveInput; bind: Utils.path(sys.vebusPrefix, "/Ac/ActiveIn/ActiveInput") } - VBusItem { id: ac1source; bind: Utils.path("com.victronenergy.settings", "/Settings/SystemSetup/AcInput1") } - VBusItem { id: ac2source; bind: Utils.path("com.victronenergy.settings", "/Settings/SystemSetup/AcInput2") } - - title: qsTr("Generator") - - property bool autoStartSelected: false - - Component.onCompleted: - { - setFocusManual () - } - - Keys.forwardTo: [keyHandler] - Item - { - id: keyHandler - Keys.onUpPressed: - { - setFocusAuto () - event.accepted = true - } - Keys.onDownPressed: - { - setFocusManual () - event.accepted = true - } - // prevents page changes while timers are running - //// Keys.onReturnPressed: event.accepted = manualTile.startCountdown || autoRunTile.startCountdown - //// Keys.onEscapePressed: event.accepted = manualTile.startCountdown || autoRunTile.startCountdown - } - - function setFocusManual () - { - autoStartSelected = false - } - - function setFocusAuto () - { - autoStartSelected = true - } - - function formatTime (time) - { - if (time >= 3600) - return (time / 3600).toFixed(0) + " h" - else - return (time / 60).toFixed(0) + " m" - } - - function stateDescription() - { - if (!state.valid) - return qsTr ("") - else if (state.value === 10) - { - switch(error.value) - { - case 1: - return qsTr("Error: Remote switch control disabled") - case 2: - return qsTr("Error: Generator in fault condition") - case 3: - return qsTr("Error: Generator not detected at AC input") - default: - return qsTr("Error") - } - } - else - { - var condition = "" - var running = true - var manual = false - switch (runningBy.value) - { - case 0: // stopped - condition = "" - running = false - break;; - case 1: - manual = true - condition = "" - break;; - case 2: - condition = qsTr("Test run") - break;; - case 3: - condition = qsTr("Loss of communication") - break;; - case 4: - condition = qsTr("SOC") - break;; - case 5: - condition = qsTr("AC load") - break;; - case 6: - condition = qsTr("Battery current") - break;; - case 7: - condition = qsTr("Battery voltage") - break;; - case 8: - condition = qsTr("Inverter temperature") - break;; - case 9: - condition = qsTr("Inverter overload") - break;; - default: - condition = qsTr("???") - break;; - } - - if (externalOverride) - { - if (running && ! manual) - return qsTr ("auto pending: ") + condition - else - return " " - } - else if (manual) - { - if (manualTimer.valid && manualTimer.value > 0) - return qsTr("Timed run") - else - return qsTr("Manual run") - } - else if (running) - return qsTr ("auto run: ") + condition - else - return " " - } - } - - function getNextTestRun() - { - if ( ! root.state.valid) - return "" - if (!nextTestRun.value) - return qsTr("No test run programmed") - - var todayDate = new Date() - var nextDate = new Date(nextTestRun.value * 1000) - var nextDateEnd = new Date(nextDate.getTime()) - var message = "" - // blank "next run" if test run is active - if (runningBy.value == 2) - return " " - else if (todayDate.getDate() == nextDate.getDate() && todayDate.getMonth() == nextDate.getMonth()) - { - message = qsTr("Next test run today %1").arg( - Qt.formatDateTime(nextDate, "hh:mm").toString()) - } - else - { - message = qsTr("Next test run on %1").arg( - Qt.formatDateTime(nextDate, "dd/MM/yyyy").toString()) - nextDateEnd.setSeconds(testRunDuration.value) } - - if (skipTestRun.value === 1) - message += qsTr(" \(skipped\)") - - return message - } - - Tile { - id: imageTile - width: 180 - height: 136 - MbIcon { - id: generator - source: icon - anchors.centerIn: parent - } - anchors { top: parent.top; left: parent.left } - values: [ - // spacer - TileText { - width: imageTile.width - 5 - text: " " - font.pixelSize: 62 - }, - TileText { - width: imageTile.width - 5 - text: runningState.valid ? runningState.value == "R" ? "Running " : runningState.value == "S" ? "Stopped " : "" : "" - } - ] - } - - Tile { - id: statusTile - height: imageTile.height - color: "#4789d0" - anchors { top: parent.top; left: imageTile.right; right: root.right } - title: qsTr("STATUS") - values: [ - TileText - { - width: statusTile.width - 5 - color: externalOverride ? "yellow" : "white" - text: - { - var runPrefix - var message - if ( ! root.state.valid) - return qsTr ("Generator not connected") - else if (root.state.value === 2) - runPrefix = qsTr("Warming up for ") - else - runPrefix = qsTr ("Running for ") - if (!root.state.valid) - message = "" - else if (externalOverride) - message = qsTr("External Override - stopped") - else if (root.state.value === 3) - message = qsTr("Cool-down") - else if (runningBy.value == 0) - message = qsTr ("Stopped") - else if ( ! runningTime.valid) - message = runPrefix + "??" - else - { - message = runPrefix + formatTime (runningTime.value) - if (manualTimer.valid && manualTimer.value > 0) - message += qsTr (" ends in ") + formatTime (manualTimer.value) - } - return message - } - }, - Rectangle - { - width: parent.width - height: 3 - color: "transparent" - }, - TileTextMultiLine - { - text: stateDescription() - width: statusTile.width - 5 - }, - Rectangle - { - width: parent.width - height: 3 - color: "transparent" - }, - TileText - { - text: qsTr("\nQuiet hours"); - width: statusTile.width - 5 - font.bold: runningBy.valid && runningBy.value != 0 - color: font.bold ? "yellow" : "white" - visible: quietHours.value === 1 - }, - Rectangle - { - width: parent.width - height: 3 - color: "transparent" - }, - TileTextMultiLine - { - width: statusTile.width - 5 - text: getNextTestRun() - } - ] - } - - Tile { - id: acInTile - title: qsTr("GENERATOR POWER") - width: 150 - height: 136 - color: "#82acde" - anchors { top: imageTile.bottom; left: parent.left } - visible: showAcIn - values: - [ - OverviewAcValuesEnhanced - { - connection: sys.genset - visible: sys.genset.power.valid - }, - TileText - { - width: acInTile.width - 5 - text: - { - if (ac1source.valid && ac1source.value == 2) - { - if (ignoreAcInput1.valid && ignoreAcInput1.value == 1) - return qsTr ("\nAC In Ignored\nduring\ngenerator\nstart / stop") - else - return "" - } - else if (ac2source.valid && ac2source.value == 2) - { - if (ignoreAcInput2.valid && ignoreAcInput2.value == 1) - return qsTr ("\nAC In Ignored\nduring\ngenerator\nstart / stop") - else - return "" - } - else - return qsTr ("\nAC In\nis not\ngenerator") - } - visible: !sys.genset.power.valid - } - ] -////// add power bar graph - PowerGauge - { - id: acInBar - width: parent.width - height: 12 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.genset - useInputCurrentLimit: true - maxForwardPowerParameter: "" - maxReversePowerParameter: "" - visible: showGauges && sys.genset.power.valid - } - } - -//////// added to show alternator in place of AC generator - Tile { - id: alternatorTile - title: qsTr("ALTERNATOR POWER") - color: "#157894" - anchors.fill: acInTile - visible: showAlternator - values: - [ - TileText - { - text: EnhFmt.formatVBusItem (sys.alternator.power, "W") - font.pixelSize: 22 - } - ] -////// add power bar graph - PowerGauge - { - id: alternatorGauge - width: parent.width - height: 12 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.alternator - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxAlternatorPower" - visible: showGauges && showAlternator - } - } - - Tile { - id: runTimeTile - title: qsTr("RUN TIMES") - width: 140 - anchors { top: acInTile.top; bottom: parent.bottom; left: acInTile.right } - values: [ - TileText - { - width: runTimeTile.width - 5 - text: qsTr ("Today") - }, - TileText { - width: runTimeTile.width - 5 - text: todayRuntime.valid ? formatTime (todayRuntime.value) : "--" - }, - Rectangle - { - width: parent.width - height: 3 - color: "transparent" - }, - TileText - { - width: runTimeTile.width - 5 - text: qsTr ("Accumulated") - }, - TileText - { - width: runTimeTile.width - 5 - text: totalAcummulatedTime.valid ? formatTime (totalAcummulatedTime.value) : "--" - }, - Rectangle - { - width: parent.width - height: 3 - color: "transparent" - }, - TileText - { - width: runTimeTile.width - 5 - visible: showServiceInfo - color: serviceOverdue ? "red" : "white" - text: serviceOverdue ? qsTr ("Service OVERDUE") : qsTr ("Service in") - }, - TileText - { - width: runTimeTile.width - 5 - visible: showServiceInfo - color: serviceOverdue ? "red" : "white" - text: formatTime (Math.abs (generatorServiceInterval.value - timeSinceService.value)) - } - ] - } - - TileAutoRunEnhanced - { - id: autoRunTile - bindPrefix: root.bindPrefix - focus: root.active && autoStartSelected - connected: state.valid - tileHeight: acInTile.height / 2 - anchors { - bottom: parent.bottom; bottomMargin: tileHeight - left: runTimeTile.right - right: parent.right - } - } - - TileManualStartEnhanced - { - id: manualTile - bindPrefix: root.bindPrefix - focus: root.active && ! autoStartSelected - connected: state.valid - tileHeight: acInTile.height / 2 - anchors { - bottom: parent.bottom - left: runTimeTile.right - right: parent.right - } - } - - // mouse areas must be AFTER their associated objects so those objects can catch mouse events - // rejected by these areas - // mouse targets need to be disabled while changes are pending - MouseArea { - id: autoRunTarget - anchors.fill: autoRunTile - enabled: root.active && ! editMode - onPressed: - { - if ( ! root.autoStartSelected ) - { - setFocusAuto () - mouse.accepted = true - } - else - { - mouse.accepted = false - } - } - } - MouseArea { - id: manualStartTarget - anchors.fill: manualTile - enabled: root.active && ! editMode - onPressed: - { - if ( root.autoStartSelected ) - { - setFocusManual () - mouse.accepted = true - } - else - { - mouse.accepted = false - } - } - } -} diff --git a/FileSets/v2.94/OverviewGeneratorEnhanced.qml.orig b/FileSets/v2.94/OverviewGeneratorEnhanced.qml.orig deleted file mode 100644 index c710a390..00000000 --- a/FileSets/v2.94/OverviewGeneratorEnhanced.qml.orig +++ /dev/null @@ -1,189 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: root - title: qsTr("Generator start/stop") - property string settingsBindPrefix - property string startStopBindPrefix - property alias startStopModel: _startStopModel - property bool allowDisableAutostart: true - property VBusItem activeCondition: VBusItem { bind: Utils.path(startStopBindPrefix, "/RunningByCondition") } - property VBusItem generatorState: VBusItem { bind: Utils.path(startStopBindPrefix, "/State") } - property VBusItem runningTime: VBusItem { bind: Utils.path(startStopBindPrefix, "/Runtime") } - property VBusItem historicalData: VBusItem { bind: Utils.path(settingsBindPrefix, "/AccumulatedDaily") } - property VBusItem functionEnabled: VBusItem { bind: Utils.path(startStopBindPrefix, "/State") } - - function getState() - { - if (generatorState.value === 10) - return qsTr("Error") - - switch(activeCondition.value) { - case 'soc': - return qsTr("Running by SOC condition") - case 'acload': - return qsTr("Running by AC Load condition") - case 'batterycurrent': - return qsTr("Running by battery current condition") - case 'batteryvoltage': - return qsTr("Running by battery voltage condition") - case 'inverterhightemp': - return qsTr("Running by inverter high temperature") - case 'inverteroverload': - return qsTr("Running by inverter overload") - case 'testrun': - return qsTr("Test run") - case 'lossofcommunication': - return qsTr("Running by loss of communication") - case 'manual': - return qsTr("Manually started") - default: - return qsTr("Stopped") - } - } - - model: startStopModel - - function formatError(text, value) - { - return "#" + value.toString() + " " + text - } - - VisualItemModel { - id: _startStopModel - - MbItemValue { - description: qsTr("State") - item.text: activeCondition.valid ? getState() : '---' - } - - MbItemOptions { - id: _gensetStatus - description: qsTr("Error") - bind: Utils.path(startStopBindPrefix, "/Error") - readonly: true - show: valid - possibleValues: [ - MbOption { description: qsTr("No error"); value: 0 }, - MbOption { description: formatError(qsTr("Remote switch control disabled"), 1); value: 1 }, - MbOption { description: formatError(qsTr("Generator in fault condition"), 2); value: 2 }, - MbOption { description: formatError(qsTr("Generator not detected at AC input"), 3); value: 3 } - ] - } - - MbItemValue { - description: qsTr("Run time") - item.text: runningTime.valid ? Utils.secondsToNoSecsString(runningTime.value) : "0" - show: generatorState.value === 1 - } - - MbItemValue { - description: qsTr("Total run time") - item { - bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") - text: Utils.secondsToNoSecsString(item.value) - } - } - - MbItemValue { - description: qsTr("Accumulated running time since last test run") - show: user.accessLevel >= User.AccessService && nextTestRun.show - backgroundColor: style.backgroundColorService - item { - text: Utils.secondsToNoSecsString(item.value) - bind: Utils.path(startStopBindPrefix, "/TestRunIntervalRuntime") - } - } - - MbItemValue { - id: nextTestRun - description: qsTr("Time to next test run") - show: item.valid && item.value > 0 - item { - text: { - var remainingTime = item.value - new Date().getTime() / 1000 - if (remainingTime > 0) - return Utils.secondsToNoSecsString(remainingTime).toString() - return qsTr("Running now") - } - bind: Utils.path(startStopBindPrefix, "/NextTestRun") - } - } - - MbSwitch { - name: qsTr("Auto start functionality") - bind: Utils.path(settingsBindPrefix, "/AutoStartEnabled") - show: allowDisableAutostart - } - - MbSubMenu { - description: qsTr("Manual start") - subpage: Component { - MbPage { - id: manualStartPage - title: qsTr("Manual start") - model: VisualItemModel { - MbSwitch { - id: manualSwitch - name: qsTr("Start generator") - bind: Utils.path(startStopBindPrefix, "/ManualStart") - writeAccessLevel: User.AccessUser - onCheckedChanged: { - if (manualStartPage.active) { - if (!checked) - toast.createToast(qsTr("Stopping, generator will continue running if other conditions are reached"), 3000) - if (checked && stopTimer.value == 0) - toast.createToast(qsTr("Starting, generator won't stop till user intervention"), 5000) - if (checked && stopTimer.value > 0) - toast.createToast(qsTr("Starting. The generator will stop in %1, unless other conditions keep it running").arg(Utils.secondsToString(stopTimer.value)), 5000) - } - } - - VBusItem { - id: stopTimer - bind: Utils.path(startStopBindPrefix, "/ManualStartTimer") - } - } - - MbEditBoxTime { - description: qsTr("Run for (hh:mm)") - readonly: manualSwitch.checked - item.bind: Utils.path(startStopBindPrefix, "/ManualStartTimer") - writeAccessLevel: User.AccessUser - } - } - } - } - } - - MbSubMenu { - description: qsTr("Daily run time") - subpage: MbPage { - // Invert the order - property variant keys: historicalData.valid ? - Object.keys(JSON.parse(historicalData.value)).reverse() : 0 - - title: qsTr("Daily run time") - focus: active - model: keys - delegate: MbItemValue { - description: Qt.formatDate(new Date(parseInt(keys[index]) * 1000), "dd-MM-yyyy"); - item.text: Utils.secondsToNoSecsString(JSON.parse(historicalData.value)[keys[index]]) - } - } - } - - MbSubMenu { - id: conditions - description: qsTr("Settings") - subpage: Component { - PageSettingsGenerator { - settingsBindPrefix: root.settingsBindPrefix - startStopBindPrefix: root.startStopBindPrefix - } - } - } - } -} diff --git a/FileSets/v2.94/OverviewGeneratorRelayEnhanced.qml b/FileSets/v2.94/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index a73c8a3d..00000000 --- a/FileSets/v2.94/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.94/OverviewGridParallel.qml b/FileSets/v2.94/OverviewGridParallel.qml deleted file mode 120000 index cbf456ca..00000000 --- a/FileSets/v2.94/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v2.94/OverviewHub.qml b/FileSets/v2.94/OverviewHub.qml deleted file mode 120000 index 3f37eb0c..00000000 --- a/FileSets/v2.94/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v2.94/OverviewHubEnhanced.qml b/FileSets/v2.94/OverviewHubEnhanced.qml deleted file mode 120000 index 6dc4f1d8..00000000 --- a/FileSets/v2.94/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v2.94/OverviewMobileEnhanced.qml b/FileSets/v2.94/OverviewMobileEnhanced.qml deleted file mode 100644 index d421abd0..00000000 --- a/FileSets/v2.94/OverviewMobileEnhanced.qml +++ /dev/null @@ -1,989 +0,0 @@ -// GuiMods Enhancements to OverviewMobile screen - -// Removed logo and added AC INPUT and SYSTEM tiles originally displayed on other overviews -// Added voltage, current and frequency to AC INPUT and AC LOADS tiles -// Added source (Grid, Generator, Shore Power) to AC INPUT tile -// Replaced to/from battery with current in DC SYSTEM tile -// DC SYSTEM tile title now reflects direction: "DC LOADS, DC CHARGER" -// Rearranged tiles to match a left to right signal flow : sources on left, loads on right -// Standardized "info" tile sizes to 1 or 1.5 wide x 1 or 2 high -// infoArea defines usable space for info tiles and all tiles are a child of infoArea -// (makes repositioning easier than when they were in separate column objects) -// Large text for main paremeter in each tile has been reduced in size to allow more parameters without -// expanding tile height (30 to 22) -// merged SYSTEM and STATUS tiles -// removed speed from STATUS to reduce tile height -// hide "reason" text if it's blank to save space -// changed clock to 12-hour format -// Capitialized battery state: "Idle", "Charging", "Discharging" -// errors and notificaitons in SYSTEM/STATUS tile may push clock off bottom of tile -// Tile content for items that are not present are made invisible - tile remains in place -// that is no height adjustments when a tile provides no information -// Adjust button widths so that pump button fits within tank column -// Hide pump button when not enabled giving more room for tanks -// Add temperature sensors to tanks column -// add control of VE.Direct inverters - -// Includes changes to handle SeeLevel NMEA2000 tank sensor: -// Ignore the real incoming tank dBus service because it's information changes -// Changes in TileText.qml are also part of the TankRepeater package - -// Search for //////// to find changes - -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils -import "timeToGo.js" as TTG -import "enhancedFormat.js" as EnhFmt - -OverviewPage { - title: qsTr("Mobile") - id: root - - property color detailColor: "#b3b3b3" - property real touchTargetOpacity: 0.3 - property int touchArea: 40 - - property variant sys: theSystem - property string settingsBindPreffix: "com.victronenergy.settings" - property string pumpBindPreffix: "com.victronenergy.pump.startstop0" - property variant activeNotifications: NotificationCenter.notifications.filter( - function isActive(obj) { return obj.active} ) - property string noAdjustableByDmc: qsTr("This setting is disabled when a Digital Multi Control " + - "is connected. If it was recently disconnected execute " + - "\"Redetect system\" that is available on the inverter menu page.") - property string noAdjustableByBms: qsTr("This setting is disabled when a VE.Bus BMS " + - "is connected. If it was recently disconnected execute " + - "\"Redetect system\" that is available on the inverter menu page.") - property string noAdjustableTextByConfig: qsTr("This setting is disabled. " + - "Possible reasons are \"Overruled by remote\" is not enabled or " + - "an assistant is preventing the adjustment. Please, check " + - "the inverter configuration with VEConfigure.") - -//////// added to keep track of tanks and temps - property int numberOfTemps: 0 - property int tankTempCount: tankModel.rowCount + numberOfTemps - property real tanksTempsHeight: root.height - (pumpButton.pumpEnabled ? pumpButton.height : 0) - property real tanksHeight: tankModel.rowCount > 0 ? tanksTempsHeight * tankModel.rowCount / tankTempCount : 0 - property real tempsHeight: tanksTempsHeight - tanksHeight - property real minimumTankHeight: 21 - property real maxTankHeight: 80 - property real tankTileHeight: Math.min (Math.max (tanksTempsHeight / tankTempCount, minimumTankHeight), maxTankHeight) - - property bool compact: tankTempCount > (pumpButton.pumpEnabled ? 5 : 6) - - property string systemPrefix: "com.victronenergy.system" - VBusItem { id: vebusService; bind: Utils.path(systemPrefix, "/VebusService") } - property bool isMulti: vebusService.valid - property string veDirectInverterService: "" - property string inverterService: vebusService.valid ? vebusService.value : veDirectInverterService - - property bool isInverter: ! isMulti && veDirectInverterService != "" - property bool hasAcInput: isMulti - VBusItem { id: _hasAcOutSystem; bind: "com.victronenergy.settings/Settings/SystemSetup/HasAcOutSystem" } - property bool hasAcOutSystem: _hasAcOutSystem.value === 1 - -//////// add for system state - property bool hasSystemState: _systemState.valid - -//////// add for SYSTEM tile and voltage, power and frequency values - property VBusItem _systemState: VBusItem { bind: Utils.path(systemPrefix, "/SystemState/State") } -//////// add for PV CHARGER voltage and current - property string pvChargerPrefix: "" - property int numberOfPvChargers: 0 - - - //////// standard tile sizes - //////// positions are left, center, right and top, center, bottom of infoArea - property int tankWidth: 130 - - property int upperTileHeight: 185 - property int acTileHeight: height - upperTileHeight - - property int infoWidth: width - tankWidth - property int infoWidth3Column: infoWidth / 3 - property int infoWidth2Column: infoWidth / 2 - -//////// add for PV Charger voltage and current - VBusItem { id: pvNrTrackers; bind: Utils.path(pvChargerPrefix, "/NrOfTrackers") } - property bool singleTracker: ! pvNrTrackers.valid || pvNrTrackers.value == 1 - property bool showPvVI: numberOfPvChargers == 1 && singleTracker - VBusItem { id: pvPower; bind: Utils.path(pvChargerPrefix, "/Yield/Power") } - VBusItem { id: pvVoltage; bind: Utils.path(pvChargerPrefix, singleTracker ? "/Pv/V" : "/Pv/0/V") } - -//////// add for inverter mode in STATUS - VBusItem { id: inverterMode; bind: Utils.path(inverterService, "/Mode") } - -//////// add for gauges - VBusItem { id: showGaugesItem; bind: Utils.path(guiModsPrefix, "/ShowGauges") } - property bool showGauges: showGaugesItem.valid ? showGaugesItem.value === 1 ? true : false : false - -//////// added to control time display - property string guiModsPrefix: "com.victronenergy.settings/Settings/GuiMods" - VBusItem { id: timeFormatItem; bind: Utils.path(guiModsPrefix, "/TimeFormat") } - property string timeFormat: getTimeFormat () - - function getTimeFormat () - { - if (!timeFormatItem.valid || timeFormatItem.value === 0) - return "" - else if (timeFormatItem.value === 2) - return "h:mm ap" - else - return "hh:mm" - } - - Component.onCompleted: { discoverServices(); showHelp () } - - // define usable space for tiles but don't show anything - Rectangle { - id: infoArea - visible: false - anchors { - left: parent.left - right: tanksColum.left - top: parent.top; - bottom: parent.bottom; - } - } - -//////// change time to selectable 12/24 hour format - Timer { - id: wallClock - running: timeFormat != "" - repeat: true - interval: 1000 - triggeredOnStart: true - onTriggered: time = Qt.formatDateTime(new Date(), timeFormat) - property string time - } - - VBusItem { id: systemName; bind: Utils.path(settingsBindPreffix, "/Settings/SystemSetup/SystemName") } - -//////// copied SYSTEM from OverviewTiles.qml & combined SYSTEM and STATUS tiles - Tile { - title: qsTr("STATUS") - id: statusTile - anchors { left: parent.left; top: parent.top } - width: root.infoWidth3Column - height: root.upperTileHeight - inverterTile.height - color: "#4789d0" - -//////// relorder to give priority to errors - values: [ - TileText { - text: systemName.valid && systemName.value !== "" ? systemName.value : sys.systemType.valid ? sys.systemType.value.toUpperCase() : "" - font.pixelSize: 16 - wrapMode: Text.WordWrap - width: statusTile.width - 5 - }, - TileText { - text: wallClock.running ? wallClock.time : "" - font.pixelSize: 15 - }, -//////// combine SystemReason with notifications - MarqueeEnhanced { - text: - { - if (activeNotifications.length === 0) - return systemReasonMessage.text - else - return notificationText() + " || " + systemReasonMessage.text - } - width: statusTile.width - textHorizontalAlignment: Text.AlignHCenter - interval: 100 - SystemReasonMessage { - id: systemReasonMessage - } - }, - TileText { - property VeQuickItem gpsService: VeQuickItem { uid: "dbus/com.victronenergy.system/GpsService" } - property VeQuickItem speed: VeQuickItem { uid: Utils.path("dbus/", gpsService.value, "/Speed") } - property VeQuickItem speedUnit: VeQuickItem { uid: "dbus/com.victronenergy.settings/Settings/Gps/SpeedUnit" } - - text: speed.value === undefined ? "" : getValue() - visible: speed.value !== undefined && speedUnit.value !== undefined - - function getValue() - { - if (speed.value < 0.5) // blank speed if less than about 1 MPH - return " " - if (speedUnit.value === "km/h") - return (speed.value * 3.6).toFixed(1) + speedUnit.value - if (speedUnit.value === "mph") - return (speed.value * 2.236936).toFixed(1) + speedUnit.value - if (speedUnit.value === "kt") - return (speed.value * (3600/1852)).toFixed(1) + speedUnit.value - return speed.value.toFixed(2) + "m/s" - } - } - ] - } // end Tile STATUS - Tile - { - title: qsTr("INVERTER") - id: inverterTile - anchors { left: parent.left; top: statusTile.bottom } - width: root.infoWidth3Column - height: 62 - color: "#4789d0" - - values: [ - TileText - { - text: inverterMode.valid ? inverterMode.text : "--" - }, - TileText { - text: qsTr(systemState.text) - - SystemState { - id: systemState - bind: hasSystemState?Utils.path(systemPrefix, "/SystemState/State"):Utils.path(inverterService, "/State") - } - } - ] -////// add power bar graph - PowerGaugeMulti - { - id: multiBar - width: parent.width - 10 - height: 8 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - inverterService: root.inverterService - show: showGauges - } - DetailTarget { id: multiTarget; detailsPage: "DetailInverter.qml" } - } // end Tile INVERTER - - Tile { - title: qsTr("BATTERY") - id: batteryTile - anchors { horizontalCenter: infoArea.horizontalCenter; top: infoArea.top } - width: root.infoWidth3Column - height: root.upperTileHeight - - values: [ - TileText // spacer - { - text: "" - font.pixelSize: 6 - }, - TileText { - text: sys.battery.soc.absFormat(0) - font.pixelSize: 22 - //////// remove height (for consistency with other tiles) - }, - TileText { - text: { - if (!sys.battery.state.valid) - return "---" - switch(sys.battery.state.value) { - //////// change - capitalized words look better - case sys.batteryStateIdle: return qsTr("Idle") - case sys.batteryStateCharging : return qsTr("Charging") - case sys.batteryStateDischarging : return qsTr("Discharging") - } - } - }, - TileText { -//////// change to show negative for battery drain - text: sys.battery.power.text - font.pixelSize: 18 - }, - TileText { - text: sys.battery.voltage.format(2) - }, - TileText { - text: sys.battery.current.format(1) - }, - TileText { - text: qsTr("Remaining:") - visible: timeToGo.valid - }, - TileText { - id: timeToGoText - text: timeToGo.valid ? TTG.formatTimeToGo (timeToGo) : " " - visible: timeToGo.valid - - VBusItem { - id: timeToGo - bind: Utils.path("com.victronenergy.system","/Dc/Battery/TimeToGo") - } - } - ] -////// add battery current bar graph - PowerGaugeBattery - { - id: batteryBar - width: parent.width - 10 - height: 8 - endLabelFontSize: 14 - endLabelBackgroundColor: batteryTile.color - anchors - { - top: parent.top; topMargin: 22 - horizontalCenter: parent.horizontalCenter - } - show: showGauges - } - DetailTarget { id: batteryTarget; detailsPage: "DetailBattery.qml" } - } // end Tile BATTERY - - VBusItem { id: dcSystemNameItem; bind: Utils.path(settingsBindPreffix, "/Settings/GuiMods/CustomDcSystemName") } - - Tile { - title: dcSystemNameItem.valid && dcSystemNameItem.value != "" ? dcSystemNameItem.value : qsTr ("DC SYSTEM") - id: dcSystem - anchors { right: infoArea.right; bottom: infoArea.bottom; bottomMargin: root.acTileHeight } - width: root.infoWidth3Column - height: (root.upperTileHeight / 2) - 5 - color: "#16a085" - values: [ - TileText { // spacer - font.pixelSize: 6 - text: "" - }, - TileText { - font.pixelSize: 22 - text: EnhFmt.formatVBusItem (sys.dcSystem.power) - visible: sys.dcSystem.power.valid - }, - ////// replace to/from battery with current - TileText { - text: !sys.dcSystem.power.valid ? "---" : - EnhFmt.formatValue (sys.dcSystem.power.value / sys.battery.voltage.value, "A") - visible: sys.dcSystem.power.valid - } - ] - PowerGauge - { - id: dcSystemGauge - width: parent.width - 10 - height: 8 - anchors - { - top: parent.top; topMargin: 22 - horizontalCenter: parent.horizontalCenter - } - connection: sys.dcSystem - endLabelFontSize: 12 - endLabelBackgroundColor: dcSystem.color - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/DcSystemMaxLoad" - maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/DcSystemMaxCharge" - showLabels: true - show: showGauges && sys.dcSystem.power.valid - } - DetailTarget { id: dcSystemTarget; detailsPage: "DetailDcSystem.qml" } - } // end Tile DC SYSTEM - - Tile { - id: solarTile - title: qsTr("PV CHARGER") - anchors { right: infoArea.right; top: infoArea.top } - width: root.infoWidth3Column - height: root.upperTileHeight - dcSystem.height - color: "#2cc36b" - values: [ - TileText { - font.pixelSize: 22 - text: EnhFmt.formatVBusItem (sys.pvCharger.power) - }, - //////// add voltage - TileText { - text: - { - if (showPvVI) - return EnhFmt.formatVBusItem (pvVoltage, "V") - else - return "" - } - visible: showPvVI - }, - //////// add current - TileText { - text: - { - if (showPvVI && pvPower.valid && pvVoltage.valid) - { - var voltage = pvVoltage.value - return EnhFmt.formatValue ((pvPower.value / voltage), "A") - } - else - return "" - } - visible: showPvVI - } - ] -////// add power bar graph - PowerGauge - { - id: pvChargerBar - width: parent.width - 10 - height: 8 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.pvCharger - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvChargerMaxPower" - show: showGauges && sys.pvCharger.power.valid - } - DetailTarget { id: pvChargerTarget; detailsPage: "DetailPvCharger.qml" } - } // end Tile PV CHARGER - -//////// add to display AC input ignored - VBusItem { id: ignoreAcInput; bind: Utils.path(inverterService, "/Ac/State/IgnoreAcIn1") } - -//////// add AC INPUT tile - Tile { - id: acInputTile - title: { - if (isInverter) - return qsTr ("No AC Input") - else if (ignoreAcInput.valid && ignoreAcInput.value == 1) - return qsTr ("AC In Ignored") - else - { - switch(sys.acSource) { - case 1: return qsTr("GRID") - case 2: return qsTr("GENERATOR") - case 3: return qsTr("SHORE POWER") - default: return qsTr("AC INPUT") - } - } - } - anchors { left: infoArea.left; bottom: infoArea.bottom } - width: root.infoWidth2Column - height: root.acTileHeight - color: "#82acde" -//////// add voltage and current - VBusItem { id: currentLimit; bind: Utils.path(inverterService, "/Ac/ActiveIn/CurrentLimit") } - values: [ - TileText { - visible: isMulti - text: EnhFmt.formatVBusItem (sys.acInput.power) - font.pixelSize: 20 - - }, -//////// add voltage and current - TileText { - visible: isMulti - text: EnhFmt.formatVBusItem (sys.acInput.voltageL1, "V") + " " + EnhFmt.formatVBusItem (sys.acInput.currentL1, "A") + " " + EnhFmt.formatVBusItem (sys.acInput.frequency, "Hz") - }, - TileText - { - text: qsTr ("Limit: ") + EnhFmt.formatVBusItem (currentLimit, "A") - visible: currentLimit.valid - } - ] -////// add power bar graph - PowerGauge - { - id: acInBar - width: parent.width - 10 - height: 8 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.acInput - useInputCurrentLimit: true - maxForwardPowerParameter: "" - maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxFeedInPower" - show: showGauges && hasAcInput - } - DetailTarget { id: acInputTarget; detailsPage: "DetailAcInput.qml" } - } - - Tile { - title: qsTr("AC LOADS") - id: acLoadsTile - anchors { right: infoArea.right; bottom: infoArea.bottom} - width: root.infoWidth2Column - height: root.acTileHeight - color: "#e68e8a" -//////// add voltage and current - VBusItem { id: outVoltage; bind: Utils.path(inverterService, "/Ac/Out/L1/V") } - VBusItem { id: outCurrent; bind: Utils.path(inverterService, "/Ac/Out/L1/I") } - VBusItem { id: outFrequency; bind: Utils.path(inverterService, "/Ac/Out/L1/F") } - - values: [ - TileText { - text: EnhFmt.formatVBusItem (sys.acLoad.power) - font.pixelSize: 22 - }, -//////// add voltage and current - no frequency for VE.Direct inverter - TileText { - text: - { - var lineText = "" - if (isMulti || isInverter) - { - lineText = EnhFmt.formatVBusItem (outVoltage, "V") + " " + EnhFmt.formatVBusItem (outCurrent, "A") - if (isMulti) - lineText += " " + EnhFmt.formatVBusItem (outFrequency, "Hz") - } - return lineText - } - } - ] -////// add power bar graph - PowerGauge - { - id: acLoadBar - width: parent.width - 10 - height: 8 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.acLoad - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputMaxPower" - show: showGauges && hasAcOutSystem - } - DetailTarget { id: acLoadsOnOutputTarget; detailsPage: "DetailLoadsOnOutput.qml" } - } - - // Synchronise tank name text scroll start - Timer { - id: scrollTimer - interval: 15000 - repeat: true - running: root.active - } - - ListView { - id: tanksColum - - anchors { - top: root.top - right: root.right - } - height: root.tanksHeight - width: root.tankWidth -//////// make list flickable if more tiles than will fit completely - interactive: root.tankTileHeight * count > (tanksColum.height + 1) ? true : false - - model: TankModel { id: tankModel } - delegate: TileTankEnhanced { - // Without an intermediate assignment this will trigger a binding loop warning. - property variant theService: DBusServices.get(buddy.id) - service: theService - width: tanksColum.width - height: root.tankTileHeight - pumpBindPrefix: root.pumpBindPreffix -//////// modified to control compact differently - compact: root.compact - Connections { - target: scrollTimer - onTriggered: doScroll() - } - } - Tile { - title: qsTr("TANKS") - anchors.fill: parent - values: TileText { - text: qsTr("") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - -//////// added temperature ListView and Model - ListView { - id: tempsColumn - - anchors { - top: tanksColum.bottom - right: root.right - } - height: root.tempsHeight - width: root.tankWidth -//////// make list flickable if more tiles than will fit completely - interactive: root.tankTileHeight * count > (tempsColumn.height + 1) ? true : false - - model: tempsModel - delegate: TileTemp - { - width: tempsColumn.width - height: root.tankTileHeight -//////// modified to control compact differently - compact: root.compact - Connections - { - target: scrollTimer - onTriggered: doScroll() - } - } - Tile - { - title: qsTr("TEMPS") - anchors.fill: parent - values: TileText - { - text: qsTr("") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - ListModel { id: tempsModel } - - Tile { - id: pumpButton - - anchors.right: parent.right - anchors.bottom: parent.bottom - - property variant texts: [ qsTr("AUTO"), qsTr("ON"), qsTr("OFF")] - property int value: 0 - property bool reset: false - property bool pumpEnabled: pumpRelay.value === 3 - isCurrentItem: false // not used by GuiMods key handler - focus shown a different way - //focus: root.active && isCurrentItem // don't switch focus -- messes up key handler - - title: qsTr("PUMP") - width: pumpEnabled ? root.tankWidth : 0 - height: 45 - editable: true - readOnly: false - color: pumpButtonMouseArea.containsPressed ? "#d3d3d3" : "#A8A8A8" - - VBusItem { id: pump; bind: Utils.path(settingsBindPreffix, "/Settings/Pump0/Mode") } - VBusItem { id: pumpRelay; bind: Utils.path(settingsBindPreffix, "/Settings/Relay/Function") } - - values: [ - TileText { - text: pumpButton.pumpEnabled ? qsTr("%1").arg(pumpButton.texts[pumpButton.value]) : qsTr("DISABLED") - } - ] - - function edit() { - if (!pumpEnabled) { - toast.createToast(qsTr("Pump functionality is not enabled. To enable it go to the relay settings page and set function to \"Tank pump\""), 5000) - return - } - - reset = true - applyAnimation.restart() - reset = false - - if (value < 2) - value++ - else - value = 0 - } - - MouseArea { - id: pumpButtonMouseArea - property bool containsPressed: containsMouse && pressed - anchors.fill: parent - onClicked: { - parent.edit() - } - } - - Rectangle { - id: timerRect - height: 2 - width: pumpButton.width * 0.8 - visible: applyAnimation.running - anchors { - bottom: parent.bottom; bottomMargin: 5 - horizontalCenter: parent.horizontalCenter - } - } - - SequentialAnimation { - id: applyAnimation - alwaysRunToEnd: false - NumberAnimation { - target: timerRect - property: "width" - from: 0 - to: pumpButton.width * 0.8 - duration: 3000 - } - - ColorAnimation { - target: pumpButton - property: "color" - from: "#A8A8A8" - to: "#4789d0" - duration: 200 - } - - ColorAnimation { - target: pumpButton - property: "color" - from: "#4789d0" - to: "#A8A8A8" - duration: 200 - } - PropertyAction { - target: timerRect - property: "width" - value: 0 - } - // Do not set value if the animation is restarted by user pressing the button - // to move between options - onCompleted: if (!pumpButton.reset) pump.setValue(pumpButton.value) - } - DetailTarget { id: pumpButtonTarget; detailsPage: "" } - } - - // When new service is found add resources as appropriate - Connections { - target: DBusServices - onDbusServiceFound: addService(service) - } - - // hack to get value(s) from within a loop inside a function when service is changing - property string tempServiceName: "" - property VBusItem temperatureItem: VBusItem { bind: Utils.path(tempServiceName, "/Dc/0/Temperature") } - -//////// rewrite to use switch in place of if statements - function addService(service) - { - switch (service.type) - { -//////// add for temp sensors - case DBusService.DBUS_SERVICE_TEMPERATURE_SENSOR: - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - break;; - case DBusService.DBUS_SERVICE_MULTI: - root.tempServiceName = service.name - if (temperatureItem.valid) - { - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - } - break;; -//////// add for VE.Direct inverters - case DBusService.DBUS_SERVICE_INVERTER: - if (veDirectInverterService == "") - veDirectInverterService = service.name; - break;; - -//////// add for PV CHARGER voltage and current display - case DBusService.DBUS_SERVICE_SOLAR_CHARGER: - numberOfPvChargers++ - if (pvChargerPrefix === "") - pvChargerPrefix = service.name; - break;; - case DBusService.DBUS_SERVICE_BATTERY: - root.tempServiceName = service.name - if (temperatureItem.valid) - { - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - } - break;; - } - } - - // Check available services to find tank sesnsors -//////// rewrite to always call addService, removing redundant service type checks - function discoverServices() - { - numberOfTemps = 0 - numberOfPvChargers = 0 - veDirectInverterService = "" - tempsModel.clear() - for (var i = 0; i < DBusServices.count; i++) - addService(DBusServices.at(i)) - } - - function notificationText() - { - if (activeNotifications.length === 0) - return qsTr("") - - var descr = [] - for (var n = 0; n < activeNotifications.length; n++) { - var notification = activeNotifications[n]; - - var text = notification.serviceName + " - " + notification.description; - if (notification.value !== "" ) - text += ": " + notification.value - - descr.push(text) - } - - return descr.join(" | ") - } - - VBusItem { id: dmc; bind: Utils.path(inverterService, "/Devices/Dmc/Version") } - VBusItem { id: bms; bind: Utils.path(inverterService, "/Devices/Bms/Version") } - - - -// Details targets -////// display detail targets and help message when first displayed. - Timer { - id: helpTimer - running: false - repeat: false - interval: 5000 - triggeredOnStart: true - } - - // help message shown when menu is first drawn - Rectangle - { - id: helpBox - color: "white" - width: 150 - height: 32 - opacity: 0.7 - anchors - { - horizontalCenter: infoArea.horizontalCenter - verticalCenter: infoArea.verticalCenter - } - visible: false - } - TileText - { - text: qsTr ( "Tap tile center for detail at any time" ) - color: "black" - anchors.fill: helpBox - wrapMode: Text.WordWrap - font.pixelSize: 12 - show: helpBox.visible - } - - - //// hard key handler - // used to press buttons when touch isn't available - // UP and DOWN buttons cycle through the list of touch areas - // "space" button is used to simulate a touch on the area - // target must be highlighted so that other uses of "space" - // will still occur - - // list of all details touchable areas - // pump button sets value locally, no details page - // so is hanelded differently - // it must be LAST in the list because target list index is used for special processing - property variant targetList: - [ - multiTarget, batteryTarget, pvChargerTarget, dcSystemTarget, - acInputTarget, acLoadsOnOutputTarget, pumpButtonTarget // pump MUST BE LAST - ] - - property int selectedTarget: 0 - - Timer - { - id: targetTimer - interval: 5000 - repeat: false - running: false - onTriggered: { hideAllTargets () } - } - - Keys.forwardTo: [keyHandler] - Item - { - id: keyHandler - Keys.onUpPressed: - { - nextTarget (-1) - event.accepted = true - } - - Keys.onDownPressed: - { - nextTarget (+1) - event.accepted = true - } - Keys.onSpacePressed: - { - if (targetTimer.running) - { - var foo // hack to make clicked() work - if (selectedTarget == targetList.length - 1) - pumpButton.edit () - else - bar.clicked (foo) - event.accepted = true - } - else - event.accepted = false - } - } - // hack to make clicked() work - property variant bar: targetList[selectedTarget] - - function nextTarget (increment) - { - // make one pass through all possible targets to find an enabled one - // if found, that's the new selectedTarget, - // if not selectedTarget does not change - var newIndex = selectedTarget - for (var i = 0; i < targetList.length; i++) - { - if (( ! targetTimer.running || helpBox.visible) && targetList[newIndex].enabled) - { - highlightSelectedTarget () - return - } - newIndex += increment - if (newIndex >= targetList.length) - newIndex = 0 - else if (newIndex < 0) - newIndex = targetList.length - 1 - var includeTarget - if (newIndex == targetList.length - 1) - includeTarget = pumpButton.pumpEnabled - else - includeTarget = targetList[newIndex].enabled - if (includeTarget) - { - selectedTarget = newIndex - highlightSelectedTarget () - break - } - } - } - - function showHelp () - { - for (var i = 0; i < targetList.length; i++) - { - targetList[i].targetVisible = true - } - helpBox.visible = true - targetTimer.restart () - } - function hideAllTargets () - { - for (var i = 0; i < targetList.length; i++) - targetList[i].targetVisible = false - helpBox.visible = false - } - function highlightSelectedTarget () - { - for (var i = 0; i < targetList.length; i++) - { - if (targetList[i] == targetList[selectedTarget]) - targetList[i].targetVisible = true - else - targetList[i].targetVisible = false - } - targetTimer.restart () - helpBox.visible = false - } -} diff --git a/FileSets/v2.94/OverviewMobileEnhanced.qml.orig b/FileSets/v2.94/OverviewMobileEnhanced.qml.orig deleted file mode 100644 index 9b3d74f3..00000000 --- a/FileSets/v2.94/OverviewMobileEnhanced.qml.orig +++ /dev/null @@ -1,640 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -OverviewPage { - id: root - - property variant sys: theSystem - property string settingsBindPreffix: "com.victronenergy.settings" - property string pumpBindPreffix: "com.victronenergy.pump.startstop0" - property variant activeNotifications: NotificationCenter.notifications.filter( - function isActive(obj) { return obj.active} ) - property string noAdjustableByDmc: qsTr("This setting is disabled when a Digital Multi Control " + - "is connected. If it was recently disconnected execute " + - "\"Redetect system\" that is available on the inverter menu page.") - property string noAdjustableByBms: qsTr("This setting is disabled when a VE.Bus BMS " + - "is connected. If it was recently disconnected execute " + - "\"Redetect system\" that is available on the inverter menu page.") - property string noAdjustableTextByConfig: qsTr("This setting is disabled. " + - "Possible reasons are \"Overruled by remote\" is not enabled or " + - "an assistant is preventing the adjustment. Please, check " + - "the inverter configuration with VEConfigure.") - property int numberOfMultis: 0 - property string vebusPrefix: "" - - // Keeps track of which button on the bottom row is active - property int buttonIndex: 0 - - title: qsTr("Mobile") - - Component.onCompleted: discoverMulti() - - ListView { - id: pwColumn - - property int tilesCount: solarTile.visible || dcSystem.visible ? 3 : 2 - property int tileHeight: Math.ceil(height / tilesCount) - interactive: false // static tiles - - width: 136 - anchors { - left: parent.left - top: parent.top; - bottom: acModeButton.top; - } - - model: VisualItemModel { - Tile { - width: pwColumn.width - height: visible ? pwColumn.tileHeight : 0 - title: qsTr("AC INPUT") - color: "#82acde" - visible: !dcSystem.visible || !solarTile.visible - values: [ - TileText { - text: sys.acInput.power.text - font.pixelSize: 30 - } - - ] - } - - TileAcPower { - width: pwColumn.width - height: visible ? pwColumn.tileHeight : 0 - title: qsTr("AC LOADS") - color: "#e68e8a" - values: [ - TileText { - text: sys.acLoad.power.text - font.pixelSize: 30 - } - ] - } - - Tile { - id: solarTile - width: pwColumn.width - height: visible ? pwColumn.tileHeight : 0 - title: qsTr("PV CHARGER") - color: "#2cc36b" - visible : sys.pvCharger.power.valid - - values: [ - TileText { - font.pixelSize: 30 - text: sys.pvCharger.power.text - } - ] - } - Tile { - id: dcSystem - width: pwColumn.width - height: visible ? pwColumn.tileHeight : 0 - title: qsTr("DC SYSTEM") - color: "#16a085" - visible: sys.dcSystem.power.valid - - values: [ - TileText { - font.pixelSize: 30 - text: sys.dcSystem.power.format(0) - }, - TileText { - text: !sys.dcSystem.power.valid ? "---" : - sys.dcSystem.power.value < 0 ? qsTr("to battery") : qsTr("from battery") - } - ] - } - } - } - - Tile { - id: logoTile - - color: "#575748" - height: 120 - anchors { - left: pwColumn.right - right: tanksColum.left - top: parent.top - } - - MbIcon { - x: 1 - y: 1 - // see below, so the svg instead of a png if there is a 1x1 image - visible: customImage.sourceSize.width === 1 && customImage.sourceSize.height === 1 - iconId: "mobile-builder-logo-svg" - } - - // The uploaded png, the default is a 1x1 transparent pixel now. - Image { - id: customImage - source: "image://theme/mobile-builder-logo" - anchors.centerIn: parent - } - } - - Tile { - id: batteryTile - height: 112 - title: qsTr("BATTERY") - anchors { - left: pwColumn.right - right: stateTile.left - top: logoTile.bottom - bottom: acModeButton.top - } - - values: [ - TileText { - text: sys.battery.soc.absFormat(0) - font.pixelSize: 30 - height: 32 - }, - TileText { - text: { - if (!sys.battery.state.valid) - return "---" - switch(sys.battery.state.value) { - case sys.batteryStateIdle: return qsTr("idle") - case sys.batteryStateCharging : return qsTr("charging") - case sys.batteryStateDischarging : return qsTr("discharging") - } - } - }, - TileText { - text: sys.battery.power.absFormat(0) - }, - TileText { - text: sys.battery.voltage.format(1) + " " + sys.battery.current.format(1) - } - ] - } - - Tile { - id: stateTile - - width: 104 - title: qsTr("STATUS") - color: "#4789d0" - - anchors { - right: tanksColum.left - top: logoTile.bottom - bottom: acModeButton.top - } - - Timer { - id: wallClock - - running: true - repeat: true - interval: 1000 - triggeredOnStart: true - onTriggered: time = Qt.formatDateTime(new Date(), "hh:mm") - - property string time - } - - values: [ - TileText { - id: systemTile - text: wallClock.time - font.pixelSize: 30 - }, - TileText { - property VeQuickItem gpsService: VeQuickItem { uid: "dbus/com.victronenergy.system/GpsService" } - property VeQuickItem speed: VeQuickItem { uid: Utils.path("dbus/", gpsService.value, "/Speed") } - property VeQuickItem speedUnit: VeQuickItem { uid: "dbus/com.victronenergy.settings/Settings/Gps/SpeedUnit" } - - text: speed.value === undefined ? "" : getValue() - visible: speed.value !== undefined && speedUnit.value !== undefined - - function getValue() - { - if (speedUnit.value === "km/h") - return (speed.value * 3.6).toFixed(1) + speedUnit.value - if (speedUnit.value === "mph") - return (speed.value * 2.236936).toFixed(1) + speedUnit.value - if (speedUnit.value === "kt") - return (speed.value * (3600/1852)).toFixed(1) + speedUnit.value - return speed.value.toFixed(2) + "m/s" - } - }, - Marquee { - text: notificationText() - width: stateTile.width - interval: 100 - fontSize: 13 - } - ] - } - - ListView { - id: tanksColum - - property int tileHeight: Math.ceil(height / Math.max(count, 2)) - width: 134 - interactive: false // static tiles - model: TankModel { id: tankModel } - delegate: TileTank { - // Without an intermediate assignment this will trigger a binding loop warning. - property variant theService: DBusServices.get(buddy.id) - service: theService - width: tanksColum.width - height: tanksColum.tileHeight - pumpBindPrefix: root.pumpBindPreffix - compact: tankModel.rowCount > (pumpButton.pumpEnabled ? 4 : 5) - Connections { - target: scrollTimer - onTriggered: doScroll() - } - } - - anchors { - top: root.top - bottom: pumpButton.pumpEnabled ? acModeButton.top : acModeButton.bottom - right: root.right - } - - // Synchronise tank name text scroll start - Timer { - id: scrollTimer - interval: 15000 - repeat: true - running: root.active && tankModel.rowCount > 4 - } - - Tile { - title: qsTr("TANKS") - anchors.fill: parent - values: TileText { - text: qsTr("No tanks found") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - - Keys.forwardTo: [keyHandler] - - Item { - id: keyHandler - Keys.onLeftPressed: { - if (buttonIndex > 0) - buttonIndex-- - - event.accepted = true - } - - Keys.onRightPressed: { - if (buttonIndex < (pumpButton.pumpEnabled ? 2 : 1)) - buttonIndex++ - - event.accepted = true - } - } - - MouseArea { - anchors.fill: parent - enabled: parent.active - onPressed: mouse.accepted = acCurrentButton.expanded - onClicked: acCurrentButton.cancel() - } - - TileSpinBox { - id: acCurrentButton - - anchors.bottom: parent.bottom - anchors.left: parent.left - isCurrentItem: (buttonIndex == 0) - focus: root.active && isCurrentItem - - bind: Utils.path(vebusPrefix, "/Ac/ActiveIn/CurrentLimit") - title: qsTr("AC CURRENT LIMIT") - color: containsMouse && !editMode ? "#d3d3d3" : "#A8A8A8" - width: pumpButton.pumpEnabled ? 160 : 173 - fontPixelSize: 14 - unit: "A" - readOnly: currentLimitIsAdjustable.value !== 1 || numberOfMultis > 1 - buttonColor: "#979797" - - VBusItem { id: currentLimitIsAdjustable; bind: Utils.path(vebusPrefix, "/Ac/ActiveIn/CurrentLimitIsAdjustable") } - - Keys.onSpacePressed: showErrorToast(event) - - function editIsAllowed() { - if (numberOfMultis > 1) { - toast.createToast(qsTr("It is not possible to change this setting when there are more than one inverter connected."), 5000) - return false - } - - if (currentLimitIsAdjustable.value === 0) { - if (dmc.valid) { - toast.createToast(noAdjustableByDmc, 5000) - return false - } - if (bms.valid) { - toast.createToast(noAdjustableByBms, 5000) - return false - } - if (!dmc.valid && !bms.valid) { - toast.createToast(noAdjustableTextByConfig, 5000) - return false - } - } - - return true - } - - function showErrorToast(event) { - editIsAllowed() - event.accepted = true - } - } - - Tile { - id: acModeButton - anchors.left: acCurrentButton.right - anchors.bottom: parent.bottom - property variant texts: { 4: qsTr("OFF"), 3: qsTr("ON"), 1: qsTr("CHARGER ONLY"), 2: qsTr("INVERTER ONLY") } - property int value: mode.valid ? mode.value : 3 - property int shownValue: applyAnimation2.running ? applyAnimation2.pendingValue : value - - isCurrentItem: (buttonIndex == 1) - focus: root.active && isCurrentItem - - editable: true - readOnly: !modeIsAdjustable.valid || modeIsAdjustable.value !== 1 || numberOfMultis > 1 - width: pumpButton.pumpEnabled ? 160 : 173 - height: 45 - color: acModeButtonMouseArea.containsPressed ? "#d3d3d3" : "#A8A8A8" - title: qsTr("AC MODE") - - values: [ - TileText { - text: modeIsAdjustable.valid && numberOfMultis === 1 ? qsTr("%1").arg(acModeButton.texts[acModeButton.shownValue]) : qsTr("NOT AVAILABLE") - } - ] - - VBusItem { id: mode; bind: Utils.path(vebusPrefix, "/Mode") } - VBusItem { id: modeIsAdjustable; bind: Utils.path(vebusPrefix,"/ModeIsAdjustable") } - - Keys.onSpacePressed: edit() - - function edit() { - if (!mode.valid) - return - - if (numberOfMultis > 1) { - toast.createToast(qsTr("It is not possible to change this setting when there are more than one inverter connected."), 5000) - return - } - - if (modeIsAdjustable.value === 0) { - if (dmc.valid) - toast.createToast(noAdjustableByDmc, 5000) - if (bms.valid) - toast.createToast(noAdjustableByBms, 5000) - if (!dmc.valid && !bms.valid) - toast.createToast(noAdjustableTextByConfig, 5000) - return - } - - switch (shownValue) { - case 4: - applyAnimation2.pendingValue = 3 - break; - case 3: - applyAnimation2.pendingValue = 1 - break; - case 2: - applyAnimation2.pendingValue = 4 - break; - case 1: - applyAnimation2.pendingValue = 2 - break; - } - - applyAnimation2.restart() - } - - MouseArea { - id: acModeButtonMouseArea - anchors.fill: parent - property bool containsPressed: containsMouse && pressed - onClicked: { - buttonIndex = 1 - parent.edit() - } - } - - Rectangle { - id: timerRect2 - height: 2 - width: acModeButton.width * 0.8 - visible: applyAnimation2.running - anchors { - bottom: parent.bottom; bottomMargin: 5 - horizontalCenter: parent.horizontalCenter - } - } - - SequentialAnimation { - id: applyAnimation2 - - property int pendingValue - - NumberAnimation { - target: timerRect2 - property: "width" - from: 0 - to: acModeButton.width * 0.8 - duration: 3000 - } - - ColorAnimation { - target: acModeButton - property: "color" - from: "#A8A8A8" - to: "#4789d0" - duration: 200 - } - - ColorAnimation { - target: acModeButton - property: "color" - from: "#4789d0" - to: "#A8A8A8" - duration: 200 - } - PropertyAction { - target: timerRect2 - property: "width" - value: 0 - } - - ScriptAction { script: mode.setValue(applyAnimation2.pendingValue) } - - PauseAnimation { duration: 1000 } - } - } - - Tile { - id: pumpButton - - anchors.left: acModeButton.right - anchors.bottom: parent.bottom - - property variant texts: [ qsTr("AUTO"), qsTr("ON"), qsTr("OFF")] - property int value: 0 - property bool reset: false - property bool pumpEnabled: pumpRelay.value === 3 - - show: pumpEnabled - isCurrentItem: (buttonIndex == 2) - focus: root.active && isCurrentItem - - title: qsTr("PUMP") - width: show ? 160 : 0 - height: 45 - editable: true - readOnly: false - color: pumpButtonMouseArea.containsPressed ? "#d3d3d3" : "#A8A8A8" - - VBusItem { id: pump; bind: Utils.path(settingsBindPreffix, "/Settings/Pump0/Mode") } - VBusItem { id: pumpRelay; bind: Utils.path(settingsBindPreffix, "/Settings/Relay/Function") } - - values: [ - TileText { - text: pumpButton.pumpEnabled ? qsTr("%1").arg(pumpButton.texts[pumpButton.value]) : qsTr("DISABLED") - } - ] - - Keys.onSpacePressed: edit() - - function edit() { - if (!pumpEnabled) { - toast.createToast(qsTr("Pump functionality is not enabled. To enable it go to the relay settings page and set function to \"Tank pump\""), 5000) - return - } - - reset = true - applyAnimation.restart() - reset = false - - if (value < 2) - value++ - else - value = 0 - } - - MouseArea { - id: pumpButtonMouseArea - property bool containsPressed: containsMouse && pressed - anchors.fill: parent - onClicked: { - buttonIndex = 2 - parent.edit() - } - } - - Rectangle { - id: timerRect - height: 2 - width: pumpButton.width * 0.8 - visible: applyAnimation.running - anchors { - bottom: parent.bottom; bottomMargin: 5 - horizontalCenter: parent.horizontalCenter - } - } - - SequentialAnimation { - id: applyAnimation - alwaysRunToEnd: false - NumberAnimation { - target: timerRect - property: "width" - from: 0 - to: pumpButton.width * 0.8 - duration: 3000 - } - - ColorAnimation { - target: pumpButton - property: "color" - from: "#A8A8A8" - to: "#4789d0" - duration: 200 - } - - ColorAnimation { - target: pumpButton - property: "color" - from: "#4789d0" - to: "#A8A8A8" - duration: 200 - } - PropertyAction { - target: timerRect - property: "width" - value: 0 - } - // Do not set value if the animation is restarted by user pressing the button - // to move between options - onCompleted: if (!pumpButton.reset) pump.setValue(pumpButton.value) - } - } - - // When new service is found check if is a tank sensor - Connections { - target: DBusServices - onDbusServiceFound: addService(service) - } - - function addService(service) - { - if (service.type === DBusService.DBUS_SERVICE_MULTI) { - numberOfMultis++ - if (vebusPrefix === "") - vebusPrefix = service.name; - } - } - - // Check available services to find tank sesnsors - function discoverMulti() - { - for (var i = 0; i < DBusServices.count; i++) { - if (DBusServices.at(i).type === DBusService.DBUS_SERVICE_MULTI) { - addService(DBusServices.at(i)) - } - } - } - - function notificationText() - { - if (activeNotifications.length === 0) - return qsTr("no alarms") - - var descr = [] - for (var n = 0; n < activeNotifications.length; n++) { - var notification = activeNotifications[n]; - - var text = notification.serviceName + " - " + notification.description; - if (notification.value !== "" ) - text += ": " + notification.value - - descr.push(text) - } - - return descr.join(" | ") - } - - VBusItem { id: dmc; bind: Utils.path(vebusPrefix, "/Devices/Dmc/Version") } - VBusItem { id: bms; bind: Utils.path(vebusPrefix, "/Devices/Bms/Version") } -} diff --git a/FileSets/v2.94/OverviewSolarCharger.qml b/FileSets/v2.94/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v2.94/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.94/OverviewSolarInverter.qml b/FileSets/v2.94/OverviewSolarInverter.qml deleted file mode 120000 index 7cea58a2..00000000 --- a/FileSets/v2.94/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v2.94/OverviewTankDelegate.qml b/FileSets/v2.94/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v2.94/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.94/OverviewTanks.qml b/FileSets/v2.94/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v2.94/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.94/OverviewTanksTempsDigInputs.qml b/FileSets/v2.94/OverviewTanksTempsDigInputs.qml deleted file mode 100644 index 781e163c..00000000 --- a/FileSets/v2.94/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1,207 +0,0 @@ -//// New overview page for tanks, temps and digital inputs -//// part of GuiMods -//// based on tank/temps column in mobile overview - -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils -import "timeToGo.js" as TTG - -OverviewPage { - title: qsTr("Tanks & Temps & Digital Inputs") - id: root - - property variant sys: theSystem - property string systemPrefix: "com.victronenergy.system" - property string settingsBindPreffix: "com.victronenergy.settings" - property string pumpBindPreffix: "com.victronenergy.pump.startstop0" - - property int numberOfTanks: tankModel.rowCount - property real tanksHeight: root.height - property real minTankHeight: 21 // use for temps also - property real maxTankHeight: 80 // use for temps also - property real tankTileHeight: Math.min (Math.max (tanksHeight / numberOfTanks, minTankHeight), maxTankHeight) - property bool tanksCompact: numberOfTanks > 6 - - property int numberOfTemps: 0 - property real tempsHeight: root.height - property real tempsTileHeight: Math.min (Math.max (tempsHeight / numberOfTemps, minTankHeight), maxTankHeight) - property bool tempsCompact: numberOfTemps > 6 - - property int tankWidth: parent.width / 3 - property int tempsWidth: tankWidth - property int digInWidth: tankWidth - - property int numberOfDigIn: 0 - property real digInHeight: root.height - property real digInTileHeight: Math.min (Math.max (digInHeight / numberOfDigIn, minTankHeight), maxTankHeight) - - Component.onCompleted: { discoverServices() } - - // Synchronise name text scroll start - Timer { - id: scrollTimer - interval: 15000 - repeat: true - running: root.active - } - - ListView { - id: tanksColum - - anchors { - top: root.top - left: root.left - } - height: root.tanksHeight - width: root.tankWidth - interactive: root.tankTileHeight * count > (tanksColum.height + 1) ? true : false - - model: TankModel { id: tankModel } - delegate: TileTankEnhanced { - // Without an intermediate assignment this will trigger a binding loop warning. - property variant theService: DBusServices.get(buddy.id) - service: theService - width: tanksColum.width - height: root.tankTileHeight - pumpBindPrefix: root.pumpBindPreffix - compact: root.tanksCompact - Connections { - target: scrollTimer - onTriggered: doScroll() - } - } - Tile { - title: numberOfTanks == 0 ? qsTr ("no tanks") : qsTr("Tanks") - anchors.fill: parent - color: "#b3b3b3" - values: TileText { - text: qsTr("") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - - ListView { - id: tempsColumn - - anchors { - top: root.top - left: tanksColum.right - } - height: root.tempsHeight - width: root.tempsWidth - // make list flickable if more tiles than will fit completely - interactive: root.tankTileHeight * count > (tempsColumn.height + 1) ? true : false - - model: tempsModel - delegate: TileTemp - { - width: tempsColumn.width - height: root.tempsTileHeight - compact: root.tempsCompact - Connections - { - target: scrollTimer - onTriggered: doScroll() - } - } - Tile - { - title: numberOfTemps == 0 ? qsTr ("no temps") : qsTr("Temps") - anchors.fill: parent - color: "#b3b3b3" - values: TileText - { - text: qsTr("") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - ListModel { id: tempsModel } - - ListView { - id: digInputsColumn - - anchors { - top: root.top - right: root.right - } - height: root.digInHeight - width: root.digInWidth - // make list flickable if more tiles than will fit completely - interactive: root.digInTileHeight * count > (digInputsColumn.height + 1) ? true : false - - model: digInModel - delegate: TileDigIn - { - width: digInputsColumn.width - height: root.digInTileHeight - } - Tile - { - title: numberOfDigIn == 0 ? qsTr ("no digital inputs") : qsTr("Digital Inputs") - anchors.fill: parent - color: "#b3b3b3" - values: TileText - { - text: qsTr("") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - ListModel { id: digInModel } - - - // When new service is found add resources as appropriate - Connections { - target: DBusServices - onDbusServiceFound: addService(service) - } - - // hack to get value(s) from within a loop inside a function when service is changing - property string tempServiceName: "" - property VBusItem temperatureItem: VBusItem { bind: Utils.path(tempServiceName, "/Dc/0/Temperature") } - - function addService(service) - { - switch (service.type) - { - case DBusService.DBUS_SERVICE_TEMPERATURE_SENSOR: - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - break;; - case DBusService.DBUS_SERVICE_DIGITAL_INPUT: - case DBusService.DBUS_SERVICE_PULSE_COUNTER: - numberOfDigIn++ - digInModel.append({serviceName: service.name}) - break;; - case DBusService.DBUS_SERVICE_BATTERY: - case DBusService.DBUS_SERVICE_MULTI: - root.tempServiceName = service.name - if (temperatureItem.valid) - { - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - } - break;; - } - } - - // Check available services to find tank sesnsors - function discoverServices() - { - numberOfTemps = 0 - tempsModel.clear() - numberOfDigIn = 0 - digInModel.clear() - for (var i = 0; i < DBusServices.count; i++) - addService(DBusServices.at(i)) - } -} diff --git a/FileSets/v2.94/OverviewTanksTempsDigInputs.qml.orig b/FileSets/v2.94/OverviewTanksTempsDigInputs.qml.orig deleted file mode 100644 index 9b3d74f3..00000000 --- a/FileSets/v2.94/OverviewTanksTempsDigInputs.qml.orig +++ /dev/null @@ -1,640 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -OverviewPage { - id: root - - property variant sys: theSystem - property string settingsBindPreffix: "com.victronenergy.settings" - property string pumpBindPreffix: "com.victronenergy.pump.startstop0" - property variant activeNotifications: NotificationCenter.notifications.filter( - function isActive(obj) { return obj.active} ) - property string noAdjustableByDmc: qsTr("This setting is disabled when a Digital Multi Control " + - "is connected. If it was recently disconnected execute " + - "\"Redetect system\" that is available on the inverter menu page.") - property string noAdjustableByBms: qsTr("This setting is disabled when a VE.Bus BMS " + - "is connected. If it was recently disconnected execute " + - "\"Redetect system\" that is available on the inverter menu page.") - property string noAdjustableTextByConfig: qsTr("This setting is disabled. " + - "Possible reasons are \"Overruled by remote\" is not enabled or " + - "an assistant is preventing the adjustment. Please, check " + - "the inverter configuration with VEConfigure.") - property int numberOfMultis: 0 - property string vebusPrefix: "" - - // Keeps track of which button on the bottom row is active - property int buttonIndex: 0 - - title: qsTr("Mobile") - - Component.onCompleted: discoverMulti() - - ListView { - id: pwColumn - - property int tilesCount: solarTile.visible || dcSystem.visible ? 3 : 2 - property int tileHeight: Math.ceil(height / tilesCount) - interactive: false // static tiles - - width: 136 - anchors { - left: parent.left - top: parent.top; - bottom: acModeButton.top; - } - - model: VisualItemModel { - Tile { - width: pwColumn.width - height: visible ? pwColumn.tileHeight : 0 - title: qsTr("AC INPUT") - color: "#82acde" - visible: !dcSystem.visible || !solarTile.visible - values: [ - TileText { - text: sys.acInput.power.text - font.pixelSize: 30 - } - - ] - } - - TileAcPower { - width: pwColumn.width - height: visible ? pwColumn.tileHeight : 0 - title: qsTr("AC LOADS") - color: "#e68e8a" - values: [ - TileText { - text: sys.acLoad.power.text - font.pixelSize: 30 - } - ] - } - - Tile { - id: solarTile - width: pwColumn.width - height: visible ? pwColumn.tileHeight : 0 - title: qsTr("PV CHARGER") - color: "#2cc36b" - visible : sys.pvCharger.power.valid - - values: [ - TileText { - font.pixelSize: 30 - text: sys.pvCharger.power.text - } - ] - } - Tile { - id: dcSystem - width: pwColumn.width - height: visible ? pwColumn.tileHeight : 0 - title: qsTr("DC SYSTEM") - color: "#16a085" - visible: sys.dcSystem.power.valid - - values: [ - TileText { - font.pixelSize: 30 - text: sys.dcSystem.power.format(0) - }, - TileText { - text: !sys.dcSystem.power.valid ? "---" : - sys.dcSystem.power.value < 0 ? qsTr("to battery") : qsTr("from battery") - } - ] - } - } - } - - Tile { - id: logoTile - - color: "#575748" - height: 120 - anchors { - left: pwColumn.right - right: tanksColum.left - top: parent.top - } - - MbIcon { - x: 1 - y: 1 - // see below, so the svg instead of a png if there is a 1x1 image - visible: customImage.sourceSize.width === 1 && customImage.sourceSize.height === 1 - iconId: "mobile-builder-logo-svg" - } - - // The uploaded png, the default is a 1x1 transparent pixel now. - Image { - id: customImage - source: "image://theme/mobile-builder-logo" - anchors.centerIn: parent - } - } - - Tile { - id: batteryTile - height: 112 - title: qsTr("BATTERY") - anchors { - left: pwColumn.right - right: stateTile.left - top: logoTile.bottom - bottom: acModeButton.top - } - - values: [ - TileText { - text: sys.battery.soc.absFormat(0) - font.pixelSize: 30 - height: 32 - }, - TileText { - text: { - if (!sys.battery.state.valid) - return "---" - switch(sys.battery.state.value) { - case sys.batteryStateIdle: return qsTr("idle") - case sys.batteryStateCharging : return qsTr("charging") - case sys.batteryStateDischarging : return qsTr("discharging") - } - } - }, - TileText { - text: sys.battery.power.absFormat(0) - }, - TileText { - text: sys.battery.voltage.format(1) + " " + sys.battery.current.format(1) - } - ] - } - - Tile { - id: stateTile - - width: 104 - title: qsTr("STATUS") - color: "#4789d0" - - anchors { - right: tanksColum.left - top: logoTile.bottom - bottom: acModeButton.top - } - - Timer { - id: wallClock - - running: true - repeat: true - interval: 1000 - triggeredOnStart: true - onTriggered: time = Qt.formatDateTime(new Date(), "hh:mm") - - property string time - } - - values: [ - TileText { - id: systemTile - text: wallClock.time - font.pixelSize: 30 - }, - TileText { - property VeQuickItem gpsService: VeQuickItem { uid: "dbus/com.victronenergy.system/GpsService" } - property VeQuickItem speed: VeQuickItem { uid: Utils.path("dbus/", gpsService.value, "/Speed") } - property VeQuickItem speedUnit: VeQuickItem { uid: "dbus/com.victronenergy.settings/Settings/Gps/SpeedUnit" } - - text: speed.value === undefined ? "" : getValue() - visible: speed.value !== undefined && speedUnit.value !== undefined - - function getValue() - { - if (speedUnit.value === "km/h") - return (speed.value * 3.6).toFixed(1) + speedUnit.value - if (speedUnit.value === "mph") - return (speed.value * 2.236936).toFixed(1) + speedUnit.value - if (speedUnit.value === "kt") - return (speed.value * (3600/1852)).toFixed(1) + speedUnit.value - return speed.value.toFixed(2) + "m/s" - } - }, - Marquee { - text: notificationText() - width: stateTile.width - interval: 100 - fontSize: 13 - } - ] - } - - ListView { - id: tanksColum - - property int tileHeight: Math.ceil(height / Math.max(count, 2)) - width: 134 - interactive: false // static tiles - model: TankModel { id: tankModel } - delegate: TileTank { - // Without an intermediate assignment this will trigger a binding loop warning. - property variant theService: DBusServices.get(buddy.id) - service: theService - width: tanksColum.width - height: tanksColum.tileHeight - pumpBindPrefix: root.pumpBindPreffix - compact: tankModel.rowCount > (pumpButton.pumpEnabled ? 4 : 5) - Connections { - target: scrollTimer - onTriggered: doScroll() - } - } - - anchors { - top: root.top - bottom: pumpButton.pumpEnabled ? acModeButton.top : acModeButton.bottom - right: root.right - } - - // Synchronise tank name text scroll start - Timer { - id: scrollTimer - interval: 15000 - repeat: true - running: root.active && tankModel.rowCount > 4 - } - - Tile { - title: qsTr("TANKS") - anchors.fill: parent - values: TileText { - text: qsTr("No tanks found") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - - Keys.forwardTo: [keyHandler] - - Item { - id: keyHandler - Keys.onLeftPressed: { - if (buttonIndex > 0) - buttonIndex-- - - event.accepted = true - } - - Keys.onRightPressed: { - if (buttonIndex < (pumpButton.pumpEnabled ? 2 : 1)) - buttonIndex++ - - event.accepted = true - } - } - - MouseArea { - anchors.fill: parent - enabled: parent.active - onPressed: mouse.accepted = acCurrentButton.expanded - onClicked: acCurrentButton.cancel() - } - - TileSpinBox { - id: acCurrentButton - - anchors.bottom: parent.bottom - anchors.left: parent.left - isCurrentItem: (buttonIndex == 0) - focus: root.active && isCurrentItem - - bind: Utils.path(vebusPrefix, "/Ac/ActiveIn/CurrentLimit") - title: qsTr("AC CURRENT LIMIT") - color: containsMouse && !editMode ? "#d3d3d3" : "#A8A8A8" - width: pumpButton.pumpEnabled ? 160 : 173 - fontPixelSize: 14 - unit: "A" - readOnly: currentLimitIsAdjustable.value !== 1 || numberOfMultis > 1 - buttonColor: "#979797" - - VBusItem { id: currentLimitIsAdjustable; bind: Utils.path(vebusPrefix, "/Ac/ActiveIn/CurrentLimitIsAdjustable") } - - Keys.onSpacePressed: showErrorToast(event) - - function editIsAllowed() { - if (numberOfMultis > 1) { - toast.createToast(qsTr("It is not possible to change this setting when there are more than one inverter connected."), 5000) - return false - } - - if (currentLimitIsAdjustable.value === 0) { - if (dmc.valid) { - toast.createToast(noAdjustableByDmc, 5000) - return false - } - if (bms.valid) { - toast.createToast(noAdjustableByBms, 5000) - return false - } - if (!dmc.valid && !bms.valid) { - toast.createToast(noAdjustableTextByConfig, 5000) - return false - } - } - - return true - } - - function showErrorToast(event) { - editIsAllowed() - event.accepted = true - } - } - - Tile { - id: acModeButton - anchors.left: acCurrentButton.right - anchors.bottom: parent.bottom - property variant texts: { 4: qsTr("OFF"), 3: qsTr("ON"), 1: qsTr("CHARGER ONLY"), 2: qsTr("INVERTER ONLY") } - property int value: mode.valid ? mode.value : 3 - property int shownValue: applyAnimation2.running ? applyAnimation2.pendingValue : value - - isCurrentItem: (buttonIndex == 1) - focus: root.active && isCurrentItem - - editable: true - readOnly: !modeIsAdjustable.valid || modeIsAdjustable.value !== 1 || numberOfMultis > 1 - width: pumpButton.pumpEnabled ? 160 : 173 - height: 45 - color: acModeButtonMouseArea.containsPressed ? "#d3d3d3" : "#A8A8A8" - title: qsTr("AC MODE") - - values: [ - TileText { - text: modeIsAdjustable.valid && numberOfMultis === 1 ? qsTr("%1").arg(acModeButton.texts[acModeButton.shownValue]) : qsTr("NOT AVAILABLE") - } - ] - - VBusItem { id: mode; bind: Utils.path(vebusPrefix, "/Mode") } - VBusItem { id: modeIsAdjustable; bind: Utils.path(vebusPrefix,"/ModeIsAdjustable") } - - Keys.onSpacePressed: edit() - - function edit() { - if (!mode.valid) - return - - if (numberOfMultis > 1) { - toast.createToast(qsTr("It is not possible to change this setting when there are more than one inverter connected."), 5000) - return - } - - if (modeIsAdjustable.value === 0) { - if (dmc.valid) - toast.createToast(noAdjustableByDmc, 5000) - if (bms.valid) - toast.createToast(noAdjustableByBms, 5000) - if (!dmc.valid && !bms.valid) - toast.createToast(noAdjustableTextByConfig, 5000) - return - } - - switch (shownValue) { - case 4: - applyAnimation2.pendingValue = 3 - break; - case 3: - applyAnimation2.pendingValue = 1 - break; - case 2: - applyAnimation2.pendingValue = 4 - break; - case 1: - applyAnimation2.pendingValue = 2 - break; - } - - applyAnimation2.restart() - } - - MouseArea { - id: acModeButtonMouseArea - anchors.fill: parent - property bool containsPressed: containsMouse && pressed - onClicked: { - buttonIndex = 1 - parent.edit() - } - } - - Rectangle { - id: timerRect2 - height: 2 - width: acModeButton.width * 0.8 - visible: applyAnimation2.running - anchors { - bottom: parent.bottom; bottomMargin: 5 - horizontalCenter: parent.horizontalCenter - } - } - - SequentialAnimation { - id: applyAnimation2 - - property int pendingValue - - NumberAnimation { - target: timerRect2 - property: "width" - from: 0 - to: acModeButton.width * 0.8 - duration: 3000 - } - - ColorAnimation { - target: acModeButton - property: "color" - from: "#A8A8A8" - to: "#4789d0" - duration: 200 - } - - ColorAnimation { - target: acModeButton - property: "color" - from: "#4789d0" - to: "#A8A8A8" - duration: 200 - } - PropertyAction { - target: timerRect2 - property: "width" - value: 0 - } - - ScriptAction { script: mode.setValue(applyAnimation2.pendingValue) } - - PauseAnimation { duration: 1000 } - } - } - - Tile { - id: pumpButton - - anchors.left: acModeButton.right - anchors.bottom: parent.bottom - - property variant texts: [ qsTr("AUTO"), qsTr("ON"), qsTr("OFF")] - property int value: 0 - property bool reset: false - property bool pumpEnabled: pumpRelay.value === 3 - - show: pumpEnabled - isCurrentItem: (buttonIndex == 2) - focus: root.active && isCurrentItem - - title: qsTr("PUMP") - width: show ? 160 : 0 - height: 45 - editable: true - readOnly: false - color: pumpButtonMouseArea.containsPressed ? "#d3d3d3" : "#A8A8A8" - - VBusItem { id: pump; bind: Utils.path(settingsBindPreffix, "/Settings/Pump0/Mode") } - VBusItem { id: pumpRelay; bind: Utils.path(settingsBindPreffix, "/Settings/Relay/Function") } - - values: [ - TileText { - text: pumpButton.pumpEnabled ? qsTr("%1").arg(pumpButton.texts[pumpButton.value]) : qsTr("DISABLED") - } - ] - - Keys.onSpacePressed: edit() - - function edit() { - if (!pumpEnabled) { - toast.createToast(qsTr("Pump functionality is not enabled. To enable it go to the relay settings page and set function to \"Tank pump\""), 5000) - return - } - - reset = true - applyAnimation.restart() - reset = false - - if (value < 2) - value++ - else - value = 0 - } - - MouseArea { - id: pumpButtonMouseArea - property bool containsPressed: containsMouse && pressed - anchors.fill: parent - onClicked: { - buttonIndex = 2 - parent.edit() - } - } - - Rectangle { - id: timerRect - height: 2 - width: pumpButton.width * 0.8 - visible: applyAnimation.running - anchors { - bottom: parent.bottom; bottomMargin: 5 - horizontalCenter: parent.horizontalCenter - } - } - - SequentialAnimation { - id: applyAnimation - alwaysRunToEnd: false - NumberAnimation { - target: timerRect - property: "width" - from: 0 - to: pumpButton.width * 0.8 - duration: 3000 - } - - ColorAnimation { - target: pumpButton - property: "color" - from: "#A8A8A8" - to: "#4789d0" - duration: 200 - } - - ColorAnimation { - target: pumpButton - property: "color" - from: "#4789d0" - to: "#A8A8A8" - duration: 200 - } - PropertyAction { - target: timerRect - property: "width" - value: 0 - } - // Do not set value if the animation is restarted by user pressing the button - // to move between options - onCompleted: if (!pumpButton.reset) pump.setValue(pumpButton.value) - } - } - - // When new service is found check if is a tank sensor - Connections { - target: DBusServices - onDbusServiceFound: addService(service) - } - - function addService(service) - { - if (service.type === DBusService.DBUS_SERVICE_MULTI) { - numberOfMultis++ - if (vebusPrefix === "") - vebusPrefix = service.name; - } - } - - // Check available services to find tank sesnsors - function discoverMulti() - { - for (var i = 0; i < DBusServices.count; i++) { - if (DBusServices.at(i).type === DBusService.DBUS_SERVICE_MULTI) { - addService(DBusServices.at(i)) - } - } - } - - function notificationText() - { - if (activeNotifications.length === 0) - return qsTr("no alarms") - - var descr = [] - for (var n = 0; n < activeNotifications.length; n++) { - var notification = activeNotifications[n]; - - var text = notification.serviceName + " - " + notification.description; - if (notification.value !== "" ) - text += ": " + notification.value - - descr.push(text) - } - - return descr.join(" | ") - } - - VBusItem { id: dmc; bind: Utils.path(vebusPrefix, "/Devices/Dmc/Version") } - VBusItem { id: bms; bind: Utils.path(vebusPrefix, "/Devices/Bms/Version") } -} diff --git a/FileSets/v2.94/PageGenerator.qml b/FileSets/v2.94/PageGenerator.qml deleted file mode 100644 index efa0d75f..00000000 --- a/FileSets/v2.94/PageGenerator.qml +++ /dev/null @@ -1,221 +0,0 @@ -//// added service interval -//// changed total time to hours (from varilable format) - -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: root - title: qsTr("Generator start/stop") - property string settingsBindPrefix - property string startStopBindPrefix - property alias startStopModel: _startStopModel - property bool allowDisableAutostart: true - property VBusItem activeCondition: VBusItem { bind: Utils.path(startStopBindPrefix, "/RunningByCondition") } - property VBusItem generatorState: VBusItem { bind: Utils.path(startStopBindPrefix, "/State") } - property VBusItem runningTime: VBusItem { bind: Utils.path(startStopBindPrefix, "/Runtime") } - property VBusItem historicalData: VBusItem { bind: Utils.path(settingsBindPrefix, "/AccumulatedDaily") } - property VBusItem functionEnabled: VBusItem { bind: Utils.path(startStopBindPrefix, "/State") } - -//// added service interval - VBusItem { id: generatorServiceInterval; bind: Utils.path(settingsBindPrefix, "/ServiceInterval") } - VBusItem { id: timeSinceService; bind: Utils.path(settingsBindPrefix, "/TimeSinceService") } - property bool serviceIntervalValid: timeSinceService.valid && generatorServiceInterval.valid && generatorServiceInterval.value > 0 - property bool serviceOverdue: serviceIntervalValid && timeSinceService.value > generatorServiceInterval.value - -//// changed total time to hours (from varilable format) - function formatTime (time) - { - if (time >= 3600) - return (time / 3600).toFixed(0) + " h" - else - return (time / 60).toFixed(0) + " m" - } - - - function getState() - { - if (generatorState.value === 10) - return qsTr("Error") - - switch(activeCondition.value) { - case 'soc': - return qsTr("Running by SOC condition") - case 'acload': - return qsTr("Running by AC Load condition") - case 'batterycurrent': - return qsTr("Running by battery current condition") - case 'batteryvoltage': - return qsTr("Running by battery voltage condition") - case 'inverterhightemp': - return qsTr("Running by inverter high temperature") - case 'inverteroverload': - return qsTr("Running by inverter overload") - case 'testrun': - return qsTr("Test run") - case 'lossofcommunication': - return qsTr("Running by loss of communication") - case 'manual': - return qsTr("Manually started") - default: - return qsTr("Stopped") - } - } - - model: startStopModel - - function formatError(text, value) - { - return "#" + value.toString() + " " + text - } - - VisualItemModel { - id: _startStopModel - - MbItemValue { - description: qsTr("State") - item.text: activeCondition.valid ? getState() : '---' - } - - MbItemOptions { - id: _gensetStatus - description: qsTr("Error") - bind: Utils.path(startStopBindPrefix, "/Error") - readonly: true - show: valid - possibleValues: [ - MbOption { description: qsTr("No error"); value: 0 }, - MbOption { description: formatError(qsTr("Remote switch control disabled"), 1); value: 1 }, - MbOption { description: formatError(qsTr("Generator in fault condition"), 2); value: 2 }, - MbOption { description: formatError(qsTr("Generator not detected at AC input"), 3); value: 3 } - ] - } - - MbItemValue { - description: qsTr("Run time") - item.text: runningTime.valid ? Utils.secondsToNoSecsString(runningTime.value) : "0" - show: generatorState.value === 1 - } - - MbItemValue { - description: qsTr("Total run time") - show: item.valid - item { - bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") -//// changed total time to hours (from varilable format) - text: formatTime (item.value) - } - } - - MbItemValue { - description: qsTr("Accumulated running time since last test run") - show: user.accessLevel >= User.AccessService && nextTestRun.show - backgroundColor: style.backgroundColorService - item { - text: Utils.secondsToNoSecsString(item.value) - bind: Utils.path(startStopBindPrefix, "/TestRunIntervalRuntime") - } - } - - MbItemValue { - id: nextTestRun - description: qsTr("Time to next test run") - show: item.valid && item.value > 0 - item { - text: { - var remainingTime = item.value - new Date().getTime() / 1000 - if (remainingTime > 0) - return Utils.secondsToNoSecsString(remainingTime).toString() - return qsTr("Running now") - } - bind: Utils.path(startStopBindPrefix, "/NextTestRun") - } - } - -//// added service interval - MbItemValue { - id: serviceTime - description: serviceOverdue ? qsTr("Service OVERDUE") : qsTr("Time to next service") - show: serviceIntervalValid - item - { - text: formatTime (Math.abs (generatorServiceInterval.value - timeSinceService.value)) - } - } - - MbSwitch { - name: qsTr("Auto start functionality") - bind: Utils.path(settingsBindPrefix, "/AutoStartEnabled") - show: allowDisableAutostart - } - - MbSubMenu { - description: qsTr("Manual start") - subpage: Component { - MbPage { - id: manualStartPage - title: qsTr("Manual start") - model: VisualItemModel { - MbSwitch { - id: manualSwitch - name: qsTr("Start generator") - bind: Utils.path(startStopBindPrefix, "/ManualStart") - writeAccessLevel: User.AccessUser - onCheckedChanged: { - if (manualStartPage.active) { - if (!checked) - toast.createToast(qsTr("Stopping, generator will continue running if other conditions are reached"), 3000) - if (checked && stopTimer.value == 0) - toast.createToast(qsTr("Starting, generator won't stop till user intervention"), 5000) - if (checked && stopTimer.value > 0) - toast.createToast(qsTr("Starting. The generator will stop in %1, unless other conditions keep it running").arg(Utils.secondsToString(stopTimer.value)), 5000) - } - } - - VBusItem { - id: stopTimer - bind: Utils.path(startStopBindPrefix, "/ManualStartTimer") - } - } - - MbEditBoxTime { - description: qsTr("Run for (hh:mm)") - readonly: manualSwitch.checked - item.bind: Utils.path(startStopBindPrefix, "/ManualStartTimer") - writeAccessLevel: User.AccessUser - } - } - } - } - } - - MbSubMenu { - description: qsTr("Daily run time") - subpage: MbPage { - // Invert the order - property variant keys: historicalData.valid ? - Object.keys(JSON.parse(historicalData.value)).reverse() : 0 - - title: qsTr("Daily run time") - focus: active - model: keys - delegate: MbItemValue { - description: Qt.formatDate(new Date(parseInt(keys[index]) * 1000), "dd-MM-yyyy"); - item.text: Utils.secondsToNoSecsString(JSON.parse(historicalData.value)[keys[index]]) - } - } - } - - MbSubMenu { - id: conditions - description: qsTr("Settings") - subpage: Component { - PageSettingsGenerator { - settingsBindPrefix: root.settingsBindPrefix - startStopBindPrefix: root.startStopBindPrefix - } - } - } - } -} diff --git a/FileSets/v2.94/PageGenerator.qml.orig b/FileSets/v2.94/PageGenerator.qml.orig deleted file mode 100644 index c710a390..00000000 --- a/FileSets/v2.94/PageGenerator.qml.orig +++ /dev/null @@ -1,189 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: root - title: qsTr("Generator start/stop") - property string settingsBindPrefix - property string startStopBindPrefix - property alias startStopModel: _startStopModel - property bool allowDisableAutostart: true - property VBusItem activeCondition: VBusItem { bind: Utils.path(startStopBindPrefix, "/RunningByCondition") } - property VBusItem generatorState: VBusItem { bind: Utils.path(startStopBindPrefix, "/State") } - property VBusItem runningTime: VBusItem { bind: Utils.path(startStopBindPrefix, "/Runtime") } - property VBusItem historicalData: VBusItem { bind: Utils.path(settingsBindPrefix, "/AccumulatedDaily") } - property VBusItem functionEnabled: VBusItem { bind: Utils.path(startStopBindPrefix, "/State") } - - function getState() - { - if (generatorState.value === 10) - return qsTr("Error") - - switch(activeCondition.value) { - case 'soc': - return qsTr("Running by SOC condition") - case 'acload': - return qsTr("Running by AC Load condition") - case 'batterycurrent': - return qsTr("Running by battery current condition") - case 'batteryvoltage': - return qsTr("Running by battery voltage condition") - case 'inverterhightemp': - return qsTr("Running by inverter high temperature") - case 'inverteroverload': - return qsTr("Running by inverter overload") - case 'testrun': - return qsTr("Test run") - case 'lossofcommunication': - return qsTr("Running by loss of communication") - case 'manual': - return qsTr("Manually started") - default: - return qsTr("Stopped") - } - } - - model: startStopModel - - function formatError(text, value) - { - return "#" + value.toString() + " " + text - } - - VisualItemModel { - id: _startStopModel - - MbItemValue { - description: qsTr("State") - item.text: activeCondition.valid ? getState() : '---' - } - - MbItemOptions { - id: _gensetStatus - description: qsTr("Error") - bind: Utils.path(startStopBindPrefix, "/Error") - readonly: true - show: valid - possibleValues: [ - MbOption { description: qsTr("No error"); value: 0 }, - MbOption { description: formatError(qsTr("Remote switch control disabled"), 1); value: 1 }, - MbOption { description: formatError(qsTr("Generator in fault condition"), 2); value: 2 }, - MbOption { description: formatError(qsTr("Generator not detected at AC input"), 3); value: 3 } - ] - } - - MbItemValue { - description: qsTr("Run time") - item.text: runningTime.valid ? Utils.secondsToNoSecsString(runningTime.value) : "0" - show: generatorState.value === 1 - } - - MbItemValue { - description: qsTr("Total run time") - item { - bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") - text: Utils.secondsToNoSecsString(item.value) - } - } - - MbItemValue { - description: qsTr("Accumulated running time since last test run") - show: user.accessLevel >= User.AccessService && nextTestRun.show - backgroundColor: style.backgroundColorService - item { - text: Utils.secondsToNoSecsString(item.value) - bind: Utils.path(startStopBindPrefix, "/TestRunIntervalRuntime") - } - } - - MbItemValue { - id: nextTestRun - description: qsTr("Time to next test run") - show: item.valid && item.value > 0 - item { - text: { - var remainingTime = item.value - new Date().getTime() / 1000 - if (remainingTime > 0) - return Utils.secondsToNoSecsString(remainingTime).toString() - return qsTr("Running now") - } - bind: Utils.path(startStopBindPrefix, "/NextTestRun") - } - } - - MbSwitch { - name: qsTr("Auto start functionality") - bind: Utils.path(settingsBindPrefix, "/AutoStartEnabled") - show: allowDisableAutostart - } - - MbSubMenu { - description: qsTr("Manual start") - subpage: Component { - MbPage { - id: manualStartPage - title: qsTr("Manual start") - model: VisualItemModel { - MbSwitch { - id: manualSwitch - name: qsTr("Start generator") - bind: Utils.path(startStopBindPrefix, "/ManualStart") - writeAccessLevel: User.AccessUser - onCheckedChanged: { - if (manualStartPage.active) { - if (!checked) - toast.createToast(qsTr("Stopping, generator will continue running if other conditions are reached"), 3000) - if (checked && stopTimer.value == 0) - toast.createToast(qsTr("Starting, generator won't stop till user intervention"), 5000) - if (checked && stopTimer.value > 0) - toast.createToast(qsTr("Starting. The generator will stop in %1, unless other conditions keep it running").arg(Utils.secondsToString(stopTimer.value)), 5000) - } - } - - VBusItem { - id: stopTimer - bind: Utils.path(startStopBindPrefix, "/ManualStartTimer") - } - } - - MbEditBoxTime { - description: qsTr("Run for (hh:mm)") - readonly: manualSwitch.checked - item.bind: Utils.path(startStopBindPrefix, "/ManualStartTimer") - writeAccessLevel: User.AccessUser - } - } - } - } - } - - MbSubMenu { - description: qsTr("Daily run time") - subpage: MbPage { - // Invert the order - property variant keys: historicalData.valid ? - Object.keys(JSON.parse(historicalData.value)).reverse() : 0 - - title: qsTr("Daily run time") - focus: active - model: keys - delegate: MbItemValue { - description: Qt.formatDate(new Date(parseInt(keys[index]) * 1000), "dd-MM-yyyy"); - item.text: Utils.secondsToNoSecsString(JSON.parse(historicalData.value)[keys[index]]) - } - } - } - - MbSubMenu { - id: conditions - description: qsTr("Settings") - subpage: Component { - PageSettingsGenerator { - settingsBindPrefix: root.settingsBindPrefix - startStopBindPrefix: root.startStopBindPrefix - } - } - } - } -} diff --git a/FileSets/v2.94/PageSettingsGenerator.qml b/FileSets/v2.94/PageSettingsGenerator.qml deleted file mode 100644 index 489f8f2c..00000000 --- a/FileSets/v2.94/PageSettingsGenerator.qml +++ /dev/null @@ -1,192 +0,0 @@ -//// GuiMods -//// addd service interval and reset -//// added link to external state enable - -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: root - title: qsTr("Generator start/stop settings") - property string settingsBindPrefix - property string startStopBindPrefix - - model: VisualItemModel { - - MbSubMenu { - id: conditions - description: qsTr("Conditions") - subpage: - Component { - PageGeneratorConditions { - title: qsTr("Conditions") - bindPrefix: root.settingsBindPrefix - } - } - } - - MbSpinBox { - description: qsTr("Minimum run time") - item { - bind: Utils.path(settingsBindPrefix, "/MinimumRuntime") - unit: "m" - decimals: 0 - step: 1 - } - } - - MbSwitch { -//// GuiMods - id: detectGeneratorAtAcIn - - property bool generatorIsSet: acIn1Source.value === 2 || acIn2Source.value === 2 - name: qsTr("Detect generator at AC input") - bind: Utils.path(settingsBindPrefix, "/Alarms/NoGeneratorAtAcIn") - enabled: valid && (generatorIsSet || checked) - onClicked: { - if (!checked) { - if (!generatorIsSet) { - toast.createToast(qsTr("None of the AC inputs is set to generator. Go to the system setup page and set the correct " + - "AC input to generator in order to enable this functionality."), 10000, "icon-info-active") - } else { - toast.createToast(qsTr("An alarm will be triggered when no power from the generator is detected at the inverter AC input. " + - "Make sure that the correct AC input is set to generator on the system setup page."), 12000, "icon-info-active") - } - } - } - - VBusItem { - id: acIn1Source - bind: "com.victronenergy.settings/Settings/SystemSetup/AcInput1" - } - - VBusItem { - id: acIn2Source - bind: "com.victronenergy.settings/Settings/SystemSetup/AcInput2" - } - } - -//// GuiMods - MbSwitch { - name: qsTr("Link to external running state") - bind: Utils.path(settingsBindPrefix, "/LinkToExternalStatus") - onClicked: - { - if (!checked) - toast.createToast(qsTr("Manual run will be synchronized with the generaror 'is running digital input' or AC input"), 10000, "icon-info-active") - } - } - - MbSwitch { - id: timeZones - name: qsTr("Quiet hours") - bind: Utils.path(settingsBindPrefix, "/QuietHours/Enabled") - enabled: valid - writeAccessLevel: User.AccessUser - } - - MbEditBoxTime { - description: qsTr("Quiet hours start time") - item.bind: Utils.path(settingsBindPrefix, "/QuietHours/StartTime") - show: timeZones.checked - writeAccessLevel: User.AccessUser - } - - MbEditBoxTime { - description: qsTr("Quiet hours end time") - item.bind: Utils.path(settingsBindPrefix, "/QuietHours/EndTime") - show: timeZones.checked - writeAccessLevel: User.AccessUser - } - - MbOK { - description: qsTr("Reset daily run time counters") - value: qsTr("Press to reset") - enabled: true - editable: enabled - onClicked: { - if (state.value === 0) { - var now = new Date() - var today = new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate())) - var todayInSeconds = today.getTime() / 1000 - resetDaily.setValue('{"%1" : 0}'.arg(todayInSeconds.toString())) - toast.createToast(qsTr("The daily runtime counter has been reset")) - } else if (state.value === 1) { - toast.createToast(qsTr("It is not possible to modify the counters while the generator is running")) - } - } - - VBusItem { - id: resetDaily - bind: Utils.path(settingsBindPrefix, "/AccumulatedDaily") - } - } - - MbEditBox { - id: setTotalRunTime - description: qsTr("Generator total run time (hours)") - item { - bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") - text: Math.round(item.value / 60 / 60) - } -//// added to avoid full keyboard - numericOnlyLayout: true - matchString: "0123456789" - maximumLength: 6 - ignoreChars: "h" - enabled: state.value === 0 - - function editTextToValue() { - return parseInt(_editText, 10) * 60 * 60 - } - - Keys.onSpacePressed: { - if (!enabled) - toast.createToast(qsTr("It is not possible to modify the counters while the generator is running")) - } - } - -//// GuiMods - MbEditBox - { - id: serviceInterval - description: qsTr("Generator service interval (hours)") - item { - bind: Utils.path(settingsBindPrefix, "/ServiceInterval") - text: Math.round(item.value / 60 / 60) - } - numericOnlyLayout: true - matchString: "0123456789" - maximumLength: 6 - ignoreChars: "h" - - function editTextToValue() { - return parseInt(_editText, 10) * 60 * 60 - } - } - MbOK - { - description: qsTr("Reset service timer") - value: qsTr("Press to reset") - show: timeSinceService.valid && timeSinceService.value > 0 - editable: true - VBusItem - { - id: timeSinceService - bind: Utils.path(settingsBindPrefix, "/TimeSinceService") - } - - function clicked() - { - timeSinceService.setValue (0) - toast.createToast(qsTr("the service timer has been reset to ") + (serviceInterval.item.value / 3600).toFixed (0) + "h") - } - } - } - - VBusItem { - id: state - bind: Utils.path(startStopBindPrefix, "/State") - } -} diff --git a/FileSets/v2.94/PageSettingsGenerator.qml.orig b/FileSets/v2.94/PageSettingsGenerator.qml.orig deleted file mode 100644 index bbadbcea..00000000 --- a/FileSets/v2.94/PageSettingsGenerator.qml.orig +++ /dev/null @@ -1,135 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: root - title: qsTr("Generator start/stop settings") - property string settingsBindPrefix - property string startStopBindPrefix - - model: VisualItemModel { - - MbSubMenu { - id: conditions - description: qsTr("Conditions") - subpage: - Component { - PageGeneratorConditions { - title: qsTr("Conditions") - bindPrefix: root.settingsBindPrefix - } - } - } - - MbSpinBox { - description: qsTr("Minimum run time") - item { - bind: Utils.path(settingsBindPrefix, "/MinimumRuntime") - unit: "m" - decimals: 0 - step: 1 - } - } - - MbSwitch { - property bool generatorIsSet: acIn1Source.value === 2 || acIn2Source.value === 2 - name: qsTr("Detect generator at AC input") - bind: Utils.path(settingsBindPrefix, "/Alarms/NoGeneratorAtAcIn") - enabled: valid && (generatorIsSet || checked) - onClicked: { - if (!checked) { - if (!generatorIsSet) { - toast.createToast(qsTr("None of the AC inputs is set to generator. Go to the system setup page and set the correct " + - "AC input to generator in order to enable this functionality."), 10000, "icon-info-active") - } else { - toast.createToast(qsTr("An alarm will be triggered when no power from the generator is detected at the inverter AC input. " + - "Make sure that the correct AC input is set to generator on the system setup page."), 12000, "icon-info-active") - } - } - } - - VBusItem { - id: acIn1Source - bind: "com.victronenergy.settings/Settings/SystemSetup/AcInput1" - } - - VBusItem { - id: acIn2Source - bind: "com.victronenergy.settings/Settings/SystemSetup/AcInput2" - } - } - - MbSwitch { - id: timeZones - name: qsTr("Quiet hours") - bind: Utils.path(settingsBindPrefix, "/QuietHours/Enabled") - enabled: valid - writeAccessLevel: User.AccessUser - } - - MbEditBoxTime { - description: qsTr("Quiet hours start time") - item.bind: Utils.path(settingsBindPrefix, "/QuietHours/StartTime") - show: timeZones.checked - writeAccessLevel: User.AccessUser - } - - MbEditBoxTime { - description: qsTr("Quiet hours end time") - item.bind: Utils.path(settingsBindPrefix, "/QuietHours/EndTime") - show: timeZones.checked - writeAccessLevel: User.AccessUser - } - - MbOK { - description: qsTr("Reset daily run time counters") - value: qsTr("Press to reset") - enabled: true - editable: enabled - onClicked: { - if (state.value === 0) { - var now = new Date() - var today = new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate())) - var todayInSeconds = today.getTime() / 1000 - resetDaily.setValue('{"%1" : 0}'.arg(todayInSeconds.toString())) - toast.createToast(qsTr("The daily runtime counter has been reset")) - } else if (state.value === 1) { - toast.createToast(qsTr("It is not possible to modify the counters while the generator is running")) - } - } - - VBusItem { - id: resetDaily - bind: Utils.path(settingsBindPrefix, "/AccumulatedDaily") - } - } - - MbEditBox { - id: setTotalRunTime - description: qsTr("Generator total run time (hours)") - item { - bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") - text: Math.round(item.value / 60 / 60) - } - matchString: "0123456789" - maximumLength: 6 - ignoreChars: "h" - enabled: state.value === 0 - - function editTextToValue() { - return parseInt(_editText, 10) * 60 * 60 - } - - Keys.onSpacePressed: { - if (!enabled) - toast.createToast(qsTr("It is not possible to modify the counters while the generator is running")) - } - } - } - - VBusItem { - id: state - bind: Utils.path(startStopBindPrefix, "/State") - } -} diff --git a/FileSets/v2.94/PageSettingsGuiMods.qml b/FileSets/v2.94/PageSettingsGuiMods.qml deleted file mode 100644 index f8a6d653..00000000 --- a/FileSets/v2.94/PageSettingsGuiMods.qml +++ /dev/null @@ -1,290 +0,0 @@ -/////// new menu for all Gui Mods - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 - -MbPage { - id: root - title: qsTr("Gui Mods") - property string bindPrefixGuiMods: "com.victronenergy.settings/Settings/GuiMods" - property string bindPrefix: "com.victronenergy.settings/Settings/Gui" - property VBusItem systemScaleItem: VBusItem { bind: "com.victronenergy.settings/Settings/System/Units/Temperature" } - - property bool showFlowParams: flowOverview.item.valid && flowOverview.item.value >= 1 - property bool showComplexParams: flowOverview.item.valid && flowOverview.item.value >= 2 - property bool showAcCoupledParams: flowOverview.item.valid && flowOverview.item.value == 3 - - model: VisualItemModel - { - MbSwitch - { - id: showTileOverview - bind: Utils.path (bindPrefixGuiMods, "/ShowTileOverview") - name: qsTr ("Show Tile Overview") - writeAccessLevel: User.AccessUser - } - - MbSwitch - { - id: moveSettings - bind: Utils.path (bindPrefixGuiMods, "/MoveSettings") - name: qsTr ("Move Settings to top of Device List") - writeAccessLevel: User.AccessUser - } - - MbSwitch { - id: relayOverview - bind: Utils.path (bindPrefixGuiMods, "/ShowRelayOverview") - name: qsTr ("Show Relay overview") - writeAccessLevel: User.AccessUser - } - MbSwitch { - id: tanksTempsOverview - bind: Utils.path (bindPrefixGuiMods, "/ShowTanksTempsDigIn") - name: qsTr ("Show Tanks, Temps, Digital Input overview") - writeAccessLevel: User.AccessUser - } - - MbSwitch - { - id: useEnhGeneratorOverview - bind: Utils.path (bindPrefixGuiMods, "/UseEnhancedGeneratorOverview") - name: qsTr ("Use Enhanced Generator Overview") - writeAccessLevel: User.AccessUser - } - - // duplicate mobile overview on/off here for convenience - MbSwitch { - id: mobileOverview - bind: Utils.path (bindPrefix, "/MobileOverview") - name: qsTr ("Show boat & motorhome overview") - writeAccessLevel: User.AccessUser - } - MbSwitch - { - id: useEnhMobileOverview - bind: Utils.path (bindPrefixGuiMods, "/UseEnhancedMobileOverview") - name: qsTr ("Use Enhanced Mobile Overview") - // When enabled set Enhanced OverviewMobile as default overview - onClicked: - { - if (!checked) - { - // also enable Mobile Overview when turning on use enhanced Mobile Overview - showMobileOverview.setValue (1) - } - } - VBusItem { id: showMobileOverview; bind: Utils.path (bindPrefix, "/MobileOverview") } - writeAccessLevel: User.AccessUser - } - MbItemOptions - { - id: flowOverview - description: qsTr("Flow overview") - bind: Utils.path (bindPrefixGuiMods, "/FlowOverview") - possibleValues: - [ - MbOption {description: qsTr("Victron stock"); value: 0}, - MbOption {description: qsTr("GuiMods simple"); value: 1}, - MbOption {description: qsTr("GuiMods DC Coupled"); value: 2}, - MbOption {description: qsTr("GuiMods AC Coupled"); value: 3} - ] - } - - MbSwitch - { - id: combineLoads - bind: Utils.path (bindPrefixGuiMods, "/EnhancedFlowCombineLoads") - name: qsTr ("Combine AC input/ouput loads") - show: root.showAcCoupledParams - writeAccessLevel: User.AccessInstaller - } - MbSwitch - { - id: showLoadsOnInput - bind: Utils.path (bindPrefixGuiMods, "/ShowEnhancedFlowLoadsOnInput") - name: qsTr ("Show Loads On Input") - show: root.showAcCoupledParams && ! combineLoads.checked - writeAccessLevel: User.AccessInstaller - } - - MbSwitch - { - id: showTanks - bind: Utils.path (bindPrefixGuiMods, "/ShowEnhancedFlowOverviewTanks") - name: qsTr ("Show tanks on Flow Overview") - show: root.showFlowParams - writeAccessLevel: User.AccessUser - } - MbItemOptions - { - id: tankFormat - description: qsTr("Tank bar format") - bind: Utils.path (bindPrefixGuiMods, "/TankBarFormat") - possibleValues: - [ - MbOption {description: qsTr("%"); value: 1}, - MbOption {description: qsTr("units"); value: 2}, - MbOption {description: qsTr("% + units"); value: 0} - ] - } - MbSwitch - { - id: showTemps - bind: Utils.path (bindPrefixGuiMods, "/ShowEnhancedFlowOverviewTemps") - name: qsTr ("Show temperatures on Flow Overview") - show: root.showFlowParams - writeAccessLevel: User.AccessUser - } - MbSwitch - { - id: showBatteryTemps - bind: Utils.path (bindPrefixGuiMods, "/ShowBatteryTempOnFlows") - name: qsTr ("Show battery temperature on Flow Overview") - show: showTemps.item.value == 1 - writeAccessLevel: User.AccessUser - } - MbSwitch - { - id: shortenTankNames - bind: Utils.path (bindPrefixGuiMods, "/ShortenTankNames") - name: qsTr ("Shorten tank names") - writeAccessLevel: User.AccessUser - } - MbEditBox { - id: dcSystemName - description: qsTr("DC System tile name") - item.bind: Utils.path (bindPrefixGuiMods, "/CustomDcSystemName") - maximumLength: 32 - enableSpaceBar: true - } - - MbSwitch - { - id: replaceInactiveAcIn - bind: Utils.path (bindPrefixGuiMods, "/ReplaceInactiveAcIn") - name: qsTr ("Replace AC in if inactive") - writeAccessLevel: User.AccessUser - } - - MbSpinBox { - description: qsTr ("AC Input Limit Preset 1") - item - { - bind: Utils.path (bindPrefixGuiMods, "/AcCurrentLimit/Preset1") - unit: "A" - decimals: 0 - step: 1 - min: 0 - max: 999 - } - writeAccessLevel: User.AccessUser - } - - MbSpinBox { - description: qsTr ("AC Input Limit Preset 2") - item - { - bind: Utils.path (bindPrefixGuiMods, "/AcCurrentLimit/Preset2") - unit: "A" - decimals: 0 - step: 1 - min: 0 - max: 999 - } - writeAccessLevel: User.AccessUser - } - - MbSpinBox { - description: qsTr ("AC Input Limit Preset 3") - item - { - bind: Utils.path (bindPrefixGuiMods, "/AcCurrentLimit/Preset3") - unit: "A" - decimals: 0 - step: 1 - min: 0 - max: 999 - } - writeAccessLevel: User.AccessUser - } - - MbSpinBox { - description: qsTr ("AC Input Limit Preset 4") - item - { - bind: Utils.path (bindPrefixGuiMods, "/AcCurrentLimit/Preset4") - unit: "A" - decimals: 0 - step: 1 - min: 0 - max: 999 - } - writeAccessLevel: User.AccessUser - } - - MbItemOptions - { - id: tempScale - description: qsTr ("Temperature scale") - bind: Utils.path (bindPrefixGuiMods, "/TemperatureScale") - show: ! systemScaleItem.valid - possibleValues: - [ - MbOption { description: "°C"; value: 1 }, - MbOption { description: "°F"; value: 2 }, - MbOption { description: qsTr("both °C & °F"); value: 0 } - ] - writeAccessLevel: User.AccessUser - } - - MbSpinBox { - description: qsTr ("Watt / Kilowatt threshold") - item - { - bind: Utils.path (bindPrefixGuiMods, "/KilowattThreshold") - unit: "W" - decimals: 0 - step: 100 - min: 1000 - max: 10000 - } - writeAccessLevel: User.AccessUser - } - - MbItemOptions - { - id: timeFormat - description: qsTr ("Time format") - bind: Utils.path (bindPrefixGuiMods, "/TimeFormat") - possibleValues: - [ - MbOption { description: qsTr("24 hour"); value: 1 }, - MbOption { description: qsTr("12 hour AM/PM"); value: 2 }, - MbOption { description: qsTr("don't show time"); value: 0 } - ] - writeAccessLevel: User.AccessUser - } - MbItemOptions - { - id: inactiveFlowTiles - description: qsTr ("Inactive Tiles on Flow Overview") - bind: Utils.path (bindPrefixGuiMods, "/ShowInactiveFlowTiles") - show: root.showFlowParams - possibleValues: - [ - MbOption { description: qsTr("Show Dimmed"); value: 1 }, - MbOption { description: qsTr("Show Full"); value: 2 }, - MbOption { description: qsTr("Hide"); value: 0 } - ] - writeAccessLevel: User.AccessUser - } - MbSubMenu - { - description: qsTr("Power Gauges") - subpage: Component { PageSettingsGuiModsGauges {} } - show: root.showFlowParams - } - } -} diff --git a/FileSets/v2.94/PageSettingsGuiMods.qml.orig b/FileSets/v2.94/PageSettingsGuiMods.qml.orig deleted file mode 100644 index 9dd4bbff..00000000 --- a/FileSets/v2.94/PageSettingsGuiMods.qml.orig +++ /dev/null @@ -1,322 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - property string cgwacsPath: "com.victronenergy.settings/Settings/CGwacs" - property string settingsPrefix: "com.victronenergy.settings" - property string batteryLifePath: cgwacsPath + "/BatteryLife" - // Hub4Mode - property int hub4PhaseCompensation: 1 - property int hub4PhaseSplit: 2 - property int hub4Disabled: 3 - // BatteryLifeState - property int batteryLifeStateDisabled: 0 - property int batteryLifeStateRestart: 1 - property int batteryLifeStateDefault: 2 - property int batteryLifeStateAbsorption: 3 - property int batteryLifeStateFloat: 4 - property int batteryLifeStateDischarged: 5 - property int batteryLifeStateForceCharge: 6 - property int batteryLifeStateSustain: 7 - property int batteryLifeStateLowSocCharge: 8 - property int batteryKeepCharged: 9 - property int batterySocGuardDefault: 10 - property int batterySocGuardDischarged: 11 - property int batterySocGuardLowSocCharge: 12 - - property VBusItem systemType: VBusItem { bind: "com.victronenergy.system/SystemType" } - property VBusItem gridSetpoint: VBusItem { bind: "com.victronenergy.settings/Settings/CGwacs/AcPowerSetPoint" } - property VBusItem maxChargePowerItem: VBusItem { bind: Utils.path(cgwacsPath, "/MaxChargePower") } - property VBusItem maxDischargePowerItem: VBusItem { bind: Utils.path(cgwacsPath, "/MaxDischargePower") } - property VBusItem socLimitItem: VBusItem { bind: Utils.path(batteryLifePath, "/SocLimit") } - property VBusItem minSocLimitItem: VBusItem { bind: Utils.path(batteryLifePath, "/MinimumSocLimit") } - property VBusItem stateItem: VBusItem { bind: Utils.path(batteryLifePath, "/State") } - property VBusItem hub4Mode: VBusItem { bind: Utils.path(cgwacsPath, "/Hub4Mode") } - property VBusItem maxChargeCurrentControl: VBusItem { bind: "com.victronenergy.system/Control/MaxChargeCurrent" } - - title: systemType.value === "Hub-4" ? systemType.value : qsTr("ESS") - model: systemType.value === "ESS" || systemType.value === "Hub-4" ? hub4Settings : noHub4 - - VisualItemModel { - id: noHub4 - - MbItemText { - text: qsTr("No ESS Assistant found") - } - } - - function isBatteryLifeActive(state) { - switch (state) { - case batteryLifeStateRestart: - case batteryLifeStateDefault: - case batteryLifeStateAbsorption: - case batteryLifeStateFloat: - case batteryLifeStateDischarged: - case batteryLifeStateForceCharge: - case batteryLifeStateSustain: - case batteryLifeStateLowSocCharge: - return true - default: - return false - } - } - - function isBatterySocGuardActive(state) { - switch (state) { - case batterySocGuardDefault: - case batterySocGuardDischarged: - case batterySocGuardLowSocCharge: - return true - default: - return false - } - } - - VisualItemModel { - id: hub4Settings - - MbItemOptions { - function getLocalValue(hub4Mode, state) { - if (hub4Mode === undefined || state === undefined) - return undefined - if (hub4Mode === hub4Disabled) - return 3 - if (isBatteryLifeActive(state)) - return 0 - if (isBatterySocGuardActive(state)) - return 1 - if (state === batteryKeepCharged) - return 2 - return 0 - } - - description: qsTr("Mode") - localValue: getLocalValue(hub4Mode.value, stateItem.value) - possibleValues:[ - MbOption { description: qsTr("Optimized (with BatteryLife)"); value: 0 }, - MbOption { description: qsTr("Optimized (without BatteryLife)"); value: 1 }, - MbOption { description: qsTr("Keep batteries charged"); value: 2 }, - MbOption { description: qsTr("External control"); value: 3 } - ] - onLocalValueChanged: { - if (localValue === undefined) - return - // Hub 4 mode - if (localValue === 3 && hub4Mode.value !== hub4Disabled) { - hub4Mode.setValue(hub4Disabled) - } else if (localValue !== 3 && hub4Mode.value === hub4Disabled) { - hub4Mode.setValue(hub4PhaseCompensation) - } - // BatteryLife state - switch (localValue) { - case 0: - if (!isBatteryLifeActive(stateItem.value)) - stateItem.setValue(batteryLifeStateRestart) - break - case 1: - if (!isBatterySocGuardActive(stateItem.value)) - stateItem.setValue(batterySocGuardDefault) - break - case 2: - stateItem.setValue(batteryKeepCharged) - break - case 3: - stateItem.setValue(batteryLifeStateDisabled) - break - } - } - } - - MbItemOptions { - id: withoutGridMeter - description: qsTr("Grid metering") - bind: Utils.path(cgwacsPath, '/RunWithoutGridMeter') - show: hub4Mode.value !== hub4Disabled - enabled: userHasWriteAccess - possibleValues:[ - MbOption { description: qsTr("External meter"); value: 0 }, - MbOption { description: qsTr("Inverter/Charger"); value: 1 } - ] - } - - MbSwitch { - bind: Utils.path(settingsPrefix, "/Settings/SystemSetup/HasAcOutSystem") - name: qsTr("Inverter AC output in use") - show: withoutGridMeter.value == 0 - } - - - MbItemOptions { - description: qsTr("Multiphase regulation") - bind: hub4Mode.bind - show: hub4Mode.value !== hub4Disabled && stateItem.value !== batteryKeepCharged - enabled: userHasWriteAccess - possibleValues:[ - MbOption { description: qsTr("Total of all phases"); value: hub4PhaseCompensation }, - MbOption { description: qsTr("Individual phase"); value: hub4PhaseSplit } - ] - onOptionSelected: { - if (newValue === hub4PhaseSplit) { - toast.createToast(qsTr("Each phase is regulated to individually achieve the grid setpoint (system efficiency is decreased).\n\n" + - "CAUTION: Use only if required by the utility provider"), 15000); - } else if (newValue === hub4PhaseCompensation) { - toast.createToast(qsTr("The total of all phases is intelligently regulated to achieve the grid setpoint (system efficiency is optimised).\n\n" + - "Use unless prohibited by the utility provider"), 15000); - } - } - } - - MbSpinBox { - id: minSocLimit - description: qsTr("Minimum SOC (unless grid fails)") - enabled: userHasWriteAccess - show: hub4Mode.value !== hub4Disabled && stateItem.value !== batteryKeepCharged - item { - bind: Utils.path(batteryLifePath, "/MinimumSocLimit") - decimals: 0 - unit: "%" - min: 0 - max: 100 - step: 5 - } - } - - MbItemValue { - id: socLimit - description: qsTr("Active SOC limit") - show: hub4Mode.value !== hub4Disabled && isBatteryLifeActive(stateItem.value) - item { - value: Math.max(minSocLimitItem.value, socLimitItem.value) - unit: '%' - } - } - - MbItemOptions { - description: qsTr("BatteryLife state") - value: stateItem.value - readonly: true - show: hub4Mode.value !== hub4Disabled && isBatteryLifeActive(stateItem.value) - possibleValues:[ - // Values below taken from MaintenanceState enum in dbus-cgwacs - MbOption { description: qsTr("Self-consumption"); value: 2 }, - MbOption { description: qsTr("Self-consumption"); value: 3 }, - MbOption { description: qsTr("Self-consumption"); value: 4 }, - MbOption { description: qsTr("Discharge disabled"); value: 5 }, - MbOption { description: qsTr("Slow charge"); value: 6 }, - MbOption { description: qsTr("Sustain"); value: 7 }, - MbOption { description: qsTr("Recharge"); value: 8 } - ] - } - - MbSwitch { - id: maxChargePowerSwitch - name: qsTr("Limit charge power") - checked: maxChargePowerItem.value >= 0 - enabled: userHasWriteAccess - show: hub4Mode.value !== hub4Disabled && !(maxChargeCurrentControl.valid && maxChargeCurrentControl.value) - onCheckedChanged: { - if (checked && maxChargePowerItem.value < 0) - maxChargePowerItem.setValue(1000) - else if (!checked && maxChargePowerItem.value >= 0) - maxChargePowerItem.setValue(-1) - } - } - - MbSpinBox { - id: maxChargePower - description: qsTr("Maximum charge power") - enabled: userHasWriteAccess - show: maxChargePowerSwitch.show && maxChargePowerSwitch.checked - item { - bind: Utils.path(cgwacsPath, "/MaxChargePower") - decimals: 0 - unit: "W" - min: 0 - max: 200000 - step: 50 - } - } - - MbSwitch { - id: maxInverterPowerSwitch - name: qsTr("Limit inverter power") - checked: maxDischargePowerItem.value >= 0 - enabled: userHasWriteAccess - show: hub4Mode.value !== hub4Disabled && stateItem.value !== batteryKeepCharged - onCheckedChanged: { - if (checked && maxDischargePowerItem.value < 0) - maxDischargePowerItem.setValue(1000) - else if (!checked && maxDischargePowerItem.value >= 0) - maxDischargePowerItem.setValue(-1) - } - } - - MbSpinBox { - id: maxDischargePower - description: qsTr("Maximum inverter power") - enabled: userHasWriteAccess - show: maxInverterPowerSwitch.show && maxInverterPowerSwitch.checked - item { - bind: Utils.path(cgwacsPath, "/MaxDischargePower") - decimals: 0 - unit: "W" - min: 0 - max: 300000 - step: 50 - } - } - - MbSpinBox { - description: qsTr("Grid setpoint") - show: hub4Mode.value !== hub4Disabled && stateItem.value !== batteryKeepCharged - enabled: userHasWriteAccess - item { - bind: "com.victronenergy.settings/Settings/CGwacs/AcPowerSetPoint" - decimals: 0 - unit: "W" - step: 10 - } - } - - MbSubMenu { - id: feedinSetupItem - description: qsTr("Grid feed-in") - show: hub4Mode.value !== hub4Disabled - subpage: Component { - PageSettingsHub4Feedin { - title: feedinSetupItem.description - } - } - } - - MbSubMenu { - id: scheduleSettings - property string bindPrefix: "com.victronenergy.settings/Settings/CGwacs/BatteryLife/Schedule/Charge/" - description: qsTr("Scheduled charging") - show: hub4Mode.value !== hub4Disabled && stateItem.value !== batteryKeepCharged - subpage: Component { - MbPage { - title: scheduleSettings.description - model: VisualItemModel { - ChargeScheduleItem { bindPrefix: scheduleSettings.bindPrefix; scheduleNumber: 0 } - ChargeScheduleItem { bindPrefix: scheduleSettings.bindPrefix; scheduleNumber: 1 } - ChargeScheduleItem { bindPrefix: scheduleSettings.bindPrefix; scheduleNumber: 2 } - ChargeScheduleItem { bindPrefix: scheduleSettings.bindPrefix; scheduleNumber: 3 } - ChargeScheduleItem { bindPrefix: scheduleSettings.bindPrefix; scheduleNumber: 4 } - } - } - } - } - - MbSubMenu { - id: deviceItem - description: qsTr("Debug") - show: hub4Mode.value !== hub4Disabled && user.accessLevel >= User.AccessService - backgroundColor: style.backgroundColorService - subpage: Component { - PageHub4Debug { } - } - } - } -} diff --git a/FileSets/v2.94/PageSettingsRelay.qml b/FileSets/v2.94/PageSettingsRelay.qml deleted file mode 100644 index 4d2ae1c7..00000000 --- a/FileSets/v2.94/PageSettingsRelay.qml +++ /dev/null @@ -1,533 +0,0 @@ -//////// modified to -//////// add 6 relays for Raspberry PI -//////// custom relay name for Relay Overview -//////// show/hide relay in Relay Overview - -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: pageRelaySettings - title: qsTr("Relay") - property string bindPrefix: "com.victronenergy.settings" - property VBusItem relay1Item: VBusItem { bind: "com.victronenergy.system/Relay/0/State" } - property bool hasRelay1: relay1Item.valid - property VBusItem relay2Item: VBusItem { bind: "com.victronenergy.system/Relay/1/State" } - property bool hasRelay2: relay2Item.valid - property VBusItem relay3Item: VBusItem { bind: "com.victronenergy.system/Relay/2/State" } - property bool hasRelay3: relay3Item.valid - property VBusItem relay4Item: VBusItem { bind: "com.victronenergy.system/Relay/3/State" } - property bool hasRelay4: relay4Item.valid - property VBusItem relay5Item: VBusItem { bind: "com.victronenergy.system/Relay/4/State" } - property bool hasRelay5: relay5Item.valid - property VBusItem relay6Item: VBusItem { bind: "com.victronenergy.system/Relay/5/State" } - property bool hasRelay6: relay6Item.valid - property VBusItem relay7Item: VBusItem { bind: "com.victronenergy.system/Relay/6/State" } - property bool hasRelay7: relay7Item.valid - property VBusItem relay8Item: VBusItem { bind: "com.victronenergy.system/Relay/7/State" } - property bool hasRelay8: relay8Item.valid - property VBusItem relay9Item: VBusItem { bind: "com.victronenergy.system/Relay/8/State" } - property bool hasRelay9: relay9Item.valid - property VBusItem relay10Item: VBusItem { bind: "com.victronenergy.system/Relay/9/State" } - property bool hasRelay10: relay10Item.valid - property VBusItem relay11Item: VBusItem { bind: "com.victronenergy.system/Relay/10/State" } - property bool hasRelay11: relay11Item.valid - property VBusItem relay12Item: VBusItem { bind: "com.victronenergy.system/Relay/11/State" } - property bool hasRelay12: relay12Item.valid - property VBusItem relay13Item: VBusItem { bind: "com.victronenergy.system/Relay/12/State" } - property bool hasRelay13: relay13Item.valid - property VBusItem relay14Item: VBusItem { bind: "com.victronenergy.system/Relay/13/State" } - property bool hasRelay14: relay14Item.valid - property VBusItem relay15Item: VBusItem { bind: "com.victronenergy.system/Relay/14/State" } - property bool hasRelay15: relay15Item.valid - property VBusItem relay16Item: VBusItem { bind: "com.victronenergy.system/Relay/15/State" } - property bool hasRelay16: relay16Item.valid - property VBusItem relay17Item: VBusItem { bind: "com.victronenergy.system/Relay/16/State" } - property bool hasRelay17: relay17Item.valid - property VBusItem relay18Item: VBusItem { bind: "com.victronenergy.system/Relay/17/State" } - property bool hasRelay18: relay18Item.valid - - property VBusItem relay1NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/0/CustomName") } - property VBusItem relay2NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/1/CustomName") } - property VBusItem relay3NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/2/CustomName") } - property VBusItem relay4NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/3/CustomName") } - property VBusItem relay5NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/4/CustomName") } - property VBusItem relay6NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/5/CustomName") } - property VBusItem relay7NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/6/CustomName") } - property VBusItem relay8NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/7/CustomName") } - property VBusItem relay9NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/8/CustomName") } - property VBusItem relay10NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/9/CustomName") } - property VBusItem relay11NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/10/CustomName") } - property VBusItem relay12NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/11/CustomName") } - property VBusItem relay13NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/12/CustomName") } - property VBusItem relay14NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/13/CustomName") } - property VBusItem relay15NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/14/CustomName") } - property VBusItem relay16NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/15/CustomName") } - property VBusItem relay17NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/16/CustomName") } - property VBusItem relay18NameItem: VBusItem { bind: Utils.path(bindPrefix, "/Settings/Relay/17/CustomName") } - - function relayName (nameItem, relayNumber) - { - var prefix, suffix - if (nameItem.valid && nameItem.value != "") - { - prefix = nameItem.value + " (" - suffix = ")" - } - else - { - prefix = "" - suffix = "" - } - if (relayNumber == 1) - return prefix + (hasRelay1 ? qsTr("Relay 1") : qsTr("Relay")) + suffix + " " + qsTr("On") - else - return prefix + qsTr("Relay") + " " + relayNumber + suffix + " " + qsTr("On") - } - - model: VisualItemModel { - MbItemOptions { - id: relay1Function - description: hasRelay2 ? qsTr("Function (Relay 1)") : qsTr("Function") - bind: Utils.path(bindPrefix, "/Settings/Relay/Function") - possibleValues:[ - MbOption { description: qsTr("Alarm relay"); value: 0 }, - MbOption { description: qsTr("Generator start/stop"); value: 1 }, - MbOption { description: qsTr("Tank pump"); value: 3 }, - MbOption { description: qsTr("Manual"); value: 2 }, - MbOption { description: qsTr("Temperature"); value: 4 } - ] - show: hasRelay1 - } - - MbItemOptions { - description: qsTr("Alarm relay polarity") - bind: Utils.path(bindPrefix, "/Settings/Relay/Polarity") - show: hasRelay1 && relay1Function.value === 0 - possibleValues: [ - MbOption { description: qsTr("Normally open"); value: 0 }, - MbOption { description: qsTr("Normally closed"); value: 1 } - ] - } - - MbSwitch { - id: relay1Switch - // Use a one-way binding, because the usual binding: - // checked: Relay.relayOn - // will be broken when the switched toggled, and changes in the relayOn property made - // elsewhere will not change the state of the switch any more. - Binding { - target: relay1Switch - property: "checked" - value: Relay.relayOn - when: true - } - enabled: userHasWriteAccess - name: qsTr("Alarm relay On") - onCheckedChanged: Relay.relayOn = checked; - show: hasRelay1 && relay1Function.value === 0 - } - - MbSwitch { - id: manualSwitch1 - name: relayName (relay1NameItem, 1) - bind: "com.victronenergy.system/Relay/0/State" - show: hasRelay1 && relay1Function.value === 2 // manual mode - } - - MbItemOptions { - id: relay2Function - description: hasRelay2 ? qsTr("Function (Relay 2)") : qsTr("Function") - bind: Utils.path(bindPrefix, "/Settings/Relay/1/Function") - show: hasRelay2 - possibleValues:[ - MbOption { description: qsTr("Manual"); value: 2 }, - MbOption { description: qsTr("Temperature"); value: 4 } - ] - } - MbSwitch { - id: manualSwitch2 - name: relayName (relay2NameItem, 2) - bind: "com.victronenergy.system/Relay/1/State" - show: hasRelay2 && relay2Function.value === 2 - } - MbSwitch { - id: manualSwitch3 - name: relayName (relay3NameItem, 3) - bind: "com.victronenergy.system/Relay/2/State" - show: hasRelay3 - } - MbSwitch { - id: manualSwitch4 - name: relayName (relay4NameItem, 4) - bind: "com.victronenergy.system/Relay/3/State" - show: hasRelay4 - } - MbSwitch { - id: manualSwitch5 - name: relayName (relay5NameItem, 5) - bind: "com.victronenergy.system/Relay/4/State" - show: hasRelay5 - } - MbSwitch { - id: manualSwitch6 - name: relayName (relay6NameItem, 6) - bind: "com.victronenergy.system/Relay/5/State" - show: hasRelay6 - } - MbSwitch { - id: manualSwitch7 - name: relayName (relay7NameItem, 7) - bind: "com.victronenergy.system/Relay/6/State" - show: hasRelay7 - } - MbSwitch { - id: manualSwitch8 - name: relayName (relay8NameItem, 8) - bind: "com.victronenergy.system/Relay/7/State" - show: hasRelay8 - } - MbSwitch { - id: manualSwitch9 - name: relayName (relay9NameItem, 9) - bind: "com.victronenergy.system/Relay/8/State" - show: hasRelay9 - } - MbSwitch { - id: manualSwitch10 - name: relayName (relay10NameItem, 10) - bind: "com.victronenergy.system/Relay/9/State" - show: hasRelay10 - } - MbSwitch { - id: manualSwitch11 - name: relayName (relay11NameItem, 11) - bind: "com.victronenergy.system/Relay/10/State" - show: hasRelay11 - } - MbSwitch { - id: manualSwitch12 - name: relayName (relay12NameItem, 12) - bind: "com.victronenergy.system/Relay/11/State" - show: hasRelay12 - } - MbSwitch { - id: manualSwitch13 - name: relayName (relay13NameItem, 13) - bind: "com.victronenergy.system/Relay/12/State" - show: hasRelay13 - } - MbSwitch { - id: manualSwitch14 - name: relayName (relay14NameItem, 14) - bind: "com.victronenergy.system/Relay/13/State" - show: hasRelay14 - } - MbSwitch { - id: manualSwitch15 - name: relayName (relay15NameItem, 15) - bind: "com.victronenergy.system/Relay/14/State" - show: hasRelay15 - } - MbSwitch { - id: manualSwitch16 - name: relayName (relay16NameItem, 16) - bind: "com.victronenergy.system/Relay/15/State" - show: hasRelay16 - } - MbSwitch { - id: manualSwitch17 - name: relayName (relay17NameItem, 17) - bind: "com.victronenergy.system/Relay/16/State" - show: hasRelay17 - } - MbSwitch { - id: manualSwitch18 - name: relayName (relay18NameItem, 18) - bind: "com.victronenergy.system/Relay/17/State" - show: hasRelay18 - } - - MbSubMenu { - id: conditions - description: qsTr("Temperature control rules") - show: relay1Function.value === 4 || relay2Function.value === 4 - subpage: Component { - PageSettingsRelayTempSensors { - id: relayPage - title: qsTr("Temperature control rules") - } - } - } - - MbEditBox { - id: relay1name - description: qsTr("Relay 1 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/0/CustomName" - show: hasRelay1 && item.valid && relay1Function.value === 2 // manual mode - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay1 - name: qsTr("Show Relay 1 in overview") - bind: "com.victronenergy.settings/Settings/Relay/0/Show" - show: hasRelay1 - } - - MbEditBox { - id: relay2name - description: qsTr("Relay 2 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/1/CustomName" - show: hasRelay2 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay2 - name: qsTr("Show Relay 2 in overview") - bind: "com.victronenergy.settings/Settings/Relay/1/Show" - show: hasRelay2 - } - - MbEditBox { - id: relay3name - description: qsTr("Relay 3 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/2/CustomName" - show: hasRelay3 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay3 - name: qsTr("Show Relay 3 in overview") - bind: "com.victronenergy.settings/Settings/Relay/2/Show" - show: hasRelay3 - } - - MbEditBox { - id: relay4name - description: qsTr("Relay 4 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/3/CustomName" - show: hasRelay4 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay4 - name: qsTr("Show Relay 4 in overview") - bind: "com.victronenergy.settings/Settings/Relay/3/Show" - show: hasRelay4 - } - - MbEditBox { - id: relay5name - description: qsTr("Relay 5 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/4/CustomName" - show: hasRelay5 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay5 - name: qsTr("Show Relay 5 in overview") - bind: "com.victronenergy.settings/Settings/Relay/4/Show" - show: hasRelay5 - } - - MbEditBox { - id: relay6name - description: qsTr("Relay 6 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/5/CustomName" - show: hasRelay6 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay6 - name: qsTr("Show Relay 6 in overview") - bind: "com.victronenergy.settings/Settings/Relay/5/Show" - show: hasRelay6 - } - - MbEditBox { - id: relay7name - description: qsTr("Relay 7 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/6/CustomName" - show: hasRelay7 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay7 - name: qsTr("Show Relay 7 in overview") - bind: "com.victronenergy.settings/Settings/Relay/6/Show" - show: hasRelay7 - } - - MbEditBox { - id: relay8name - description: qsTr("Relay 8 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/7/CustomName" - show: hasRelay8 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay8 - name: qsTr("Show Relay 8 in overview") - bind: "com.victronenergy.settings/Settings/Relay/7/Show" - show: hasRelay8 - } - - MbEditBox { - id: relay9name - description: qsTr("Relay 9 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/8/CustomName" - show: hasRelay9 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay9 - name: qsTr("Show Relay 9 in overview") - bind: "com.victronenergy.settings/Settings/Relay/8/Show" - show: hasRelay9 - } - - MbEditBox { - id: relay10name - description: qsTr("Relay 10 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/9/CustomName" - show: hasRelay10 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay10 - name: qsTr("Show Relay 10 in overview") - bind: "com.victronenergy.settings/Settings/Relay/9/Show" - show: hasRelay10 - } - - MbEditBox { - id: relay11name - description: qsTr("Relay 11 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/10/CustomName" - show: hasRelay11 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay11 - name: qsTr("Show Relay 11 in overview") - bind: "com.victronenergy.settings/Settings/Relay/10/Show" - show: hasRelay11 - } - - MbEditBox { - id: relay12name - description: qsTr("Relay 12 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/11/CustomName" - show: hasRelay12 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay12 - name: qsTr("Show Relay 12 in overview") - bind: "com.victronenergy.settings/Settings/Relay/11/Show" - show: hasRelay12 - } - - MbEditBox { - id: relay13name - description: qsTr("Relay 13 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/12/CustomName" - show: hasRelay13 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay13 - name: qsTr("Show Relay 13 in overview") - bind: "com.victronenergy.settings/Settings/Relay/12/Show" - show: hasRelay13 - } - - MbEditBox { - id: relay14name - description: qsTr("Relay 14 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/13/CustomName" - show: hasRelay14 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay14 - name: qsTr("Show Relay 14 in overview") - bind: "com.victronenergy.settings/Settings/Relay/13/Show" - show: hasRelay14 - } - - MbEditBox { - id: relay15name - description: qsTr("Relay 15 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/14/CustomName" - show: hasRelay15 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay15 - name: qsTr("Show Relay 15 in overview") - bind: "com.victronenergy.settings/Settings/Relay/14/Show" - show: hasRelay15 - } - - MbEditBox { - id: relay16name - description: qsTr("Relay 16 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/15/CustomName" - show: hasRelay16 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay16 - name: qsTr("Show Relay 16 in overview") - bind: "com.victronenergy.settings/Settings/Relay/15/Show" - show: hasRelay16 - } - - MbEditBox { - id: relay17name - description: qsTr("Relay 17 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/16/CustomName" - show: hasRelay17 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay17 - name: qsTr("Show Relay 17 in overview") - bind: "com.victronenergy.settings/Settings/Relay/16/Show" - show: hasRelay17 - } - MbEditBox { - id: relay18name - description: qsTr("Relay 18 Name") - item.bind: "com.victronenergy.settings/Settings/Relay/17/CustomName" - show: hasRelay18 && item.valid - maximumLength: 32 - enableSpaceBar: true - } - MbSwitch { - id: showRelay18 - name: qsTr("Show Relay 18 in overview") - bind: "com.victronenergy.settings/Settings/Relay/17/Show" - show: hasRelay18 - } - } -} diff --git a/FileSets/v2.94/PageSettingsRelay.qml.orig b/FileSets/v2.94/PageSettingsRelay.qml.orig deleted file mode 100644 index dabaf6e2..00000000 --- a/FileSets/v2.94/PageSettingsRelay.qml.orig +++ /dev/null @@ -1,91 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: pageRelaySettings - title: qsTr("Relay") - property string bindPrefix: "com.victronenergy.settings" - property VBusItem relay1Item: VBusItem { bind: "com.victronenergy.system/Relay/1/State" } - property bool hasRelay1: relay1Item.valid - - model: VisualItemModel { - MbItemOptions { - id: relayFunction - description: hasRelay1 ? qsTr("Function (Relay 1)") : qsTr("Function") - bind: Utils.path(bindPrefix, "/Settings/Relay/Function") - possibleValues:[ - MbOption { description: qsTr("Alarm relay"); value: 0 }, - MbOption { description: qsTr("Generator start/stop"); value: 1 }, - MbOption { description: qsTr("Tank pump"); value: 3 }, - MbOption { description: qsTr("Manual"); value: 2 }, - MbOption { description: qsTr("Temperature"); value: 4 } - ] - } - - MbItemOptions { - description: qsTr("Alarm relay polarity") - bind: Utils.path(bindPrefix, "/Settings/Relay/Polarity") - show: relayFunction.value === 0 - possibleValues: [ - MbOption { description: qsTr("Normally open"); value: 0 }, - MbOption { description: qsTr("Normally closed"); value: 1 } - ] - } - - MbSwitch { - id: relaySwitch - // Use a one-way binding, because the usual binding: - // checked: Relay.relayOn - // will be broken when the switched toggled, and changes in the relayOn property made - // elsewhere will not change the state of the switch any more. - Binding { - target: relaySwitch - property: "checked" - value: Relay.relayOn - when: true - } - enabled: userHasWriteAccess - name: qsTr("Alarm relay On") - onCheckedChanged: Relay.relayOn = checked; - show: relayFunction.value === 0 - } - - MbSwitch { - id: manualSwitch - name: hasRelay1 ? qsTr("Relay 1 On") : qsTr("Relay On") - bind: "com.victronenergy.system/Relay/0/State" - show: relayFunction.value === 2 // manual mode - } - - MbItemOptions { - id: relay1Function - description: hasRelay1 ? qsTr("Function (Relay 2)") : qsTr("Function") - bind: Utils.path(bindPrefix, "/Settings/Relay/1/Function") - show: hasRelay1 - possibleValues:[ - MbOption { description: qsTr("Manual"); value: 2 }, - MbOption { description: qsTr("Temperature"); value: 4 } - ] - } - - MbSwitch { - id: manualSwitch1 - name: qsTr("Relay 2 On") - bind: "com.victronenergy.system/Relay/1/State" - show: hasRelay1 && relay1Function.value === 2 // manual - } - - MbSubMenu { - id: conditions - description: qsTr("Temperature control rules") - show: relayFunction.value === 4 || relay1Function.value === 4 - subpage: Component { - PageSettingsRelayTempSensors { - id: relayPage - title: qsTr("Temperature control rules") - } - } - } - } -} diff --git a/FileSets/v2.94/PowerGauge.qml b/FileSets/v2.94/PowerGauge.qml deleted file mode 120000 index d82ac28a..00000000 --- a/FileSets/v2.94/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v2.94/TileDigIn.qml b/FileSets/v2.94/TileDigIn.qml deleted file mode 100644 index 5a107e0d..00000000 --- a/FileSets/v2.94/TileDigIn.qml +++ /dev/null @@ -1,131 +0,0 @@ -// New for GuiMods to display digital inputs -// based on TileTank.qml - -import QtQuick 1.1 -import "utils.js" as Utils -import "tanksensor.js" as TankSensor - -Tile { - id: root - - property string bindPrefix: serviceName - property VBusItem nameItem: VBusItem { bind: Utils.path(bindPrefix, "/CustomName") } - property VBusItem deviceItem: VBusItem { bind: Utils.path(bindPrefix, "/DeviceInstance") } - property VBusItem aggregateItem: VBusItem { bind: Utils.path(bindPrefix, "/Aggregate") } - property string digInName: nameItem.valid && nameItem.value != "" ? nameItem.value : getType (type) - property VBusItem typeItem: VBusItem { bind: Utils.path(bindPrefix, "/Type") } - property VBusItem stateItem: VBusItem { bind: Utils.path(bindPrefix, "/State") } - property bool isPulseCounter: aggregateItem.valid - // pulse counter doesn't have /Type so fill it in here - property int type: isPulseCounter ? 1 : typeItem.valid ? typeItem.value : 0 - - property variant bkgdColors: [ "#b3b3b3", "#4aa3df", "#1abc9c", "#F39C12", "#95a5a6", "#95a5a6","#dcc6e0", "#f1a9a0", "#7f8c8d", "#ebbc3a" ] - property color bkgdColor: type > 0 && type < 10 ? bkgdColors [type] : "#b3b3b3" - property variant units: ["m3", "L", "gal", "gal"] - - - function getType(type) - { - switch (type) - { - case 0: - return qsTr("Disabled") - case 1: - return qsTr("Pulse meter") - case 2: - return qsTr("Door alarm") - case 3: - return qsTr("Bilge pump") - case 4: - return qsTr("Bilge alarm") - case 5: - return qsTr("Burglar alarm") - case 6: - return qsTr("Smoke alarm") - case 7: - return qsTr("Fire alarm") - case 8: - return qsTr("CO2 alarm") - case 9: - return qsTr("Generator") - case 10: - return qsTr("Generic I/O") -//// added for ExtTransferSwitch package - case 11: - return qsTr("Transfer switch") - default: - return "Unknown" - } - } - - function getState(st) - { - switch (st) - { - case 0: - return qsTr("Low") - case 1: - return qsTr("High") - case 2: - return qsTr("Off") - case 3: - return qsTr("On") - case 4: - return qsTr("No") - case 5: - return qsTr("Yes") - case 6: - return qsTr("Open") - case 7: - return qsTr("Closed") - case 8: - return qsTr("Ok") - case 9: - return qsTr("Alarm") - case 10: - return qsTr("Running") - case 11: - return qsTr("Stopped") -//// added for ExtTransferSwitch package - case 12: - return qsTr("On Generator") - case 13: - return qsTr("On Grid") - default: - return qsTr("Unknown") - } - - } - - title: digInName + " (In " + (deviceItem.valid ? (deviceItem.value.toString ()) : "?") + ")" - - color: bkgdColor - - VBusItem - { - id: unitItem - bind: Utils.path("com.victronenergy.settings/Settings/System/VolumeUnit") - } - - values: Item - { - width: root.width - 10 - height: 12 - TileText - { - width: root.width - text: - { - if (isPulseCounter) - return aggregateItem.value.toString() + (unitItem.valid ? units[unitItem.value] : "??") - else - return stateItem.valid ? getState (stateItem.value) : "??" - } - horizontalAlignment: Text.AlignHCenter - anchors - { - horizontalCenter: parent.horizontalCenter - } - } - } -} diff --git a/FileSets/v2.94/TileDigIn.qml.orig b/FileSets/v2.94/TileDigIn.qml.orig deleted file mode 100755 index a251e4e5..00000000 --- a/FileSets/v2.94/TileDigIn.qml.orig +++ /dev/null @@ -1,550 +0,0 @@ -#!/usr/bin/python3 -u - -import sys, os -import signal -from threading import Thread -from select import select, epoll, EPOLLPRI -from functools import partial -from collections import namedtuple -from argparse import ArgumentParser -import traceback -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) - -from dbus.mainloop.glib import DBusGMainLoop -import dbus -from gi.repository import GLib -from vedbus import VeDbusService -from settingsdevice import SettingsDevice - -VERSION = '0.17' -MAXCOUNT = 2**31-1 -SAVEINTERVAL = 60000 - -INPUT_FUNCTION_COUNTER = 1 -INPUT_FUNCTION_INPUT = 2 - -Translation = namedtuple('Translation', ['no', 'yes']) - -# Only append at the end -INPUTTYPES = [ - 'Disabled', - 'Pulse meter', - 'Door', - 'Bilge pump', - 'Bilge alarm', - 'Burglar alarm', - 'Smoke alarm', - 'Fire alarm', - 'CO2 alarm', - 'Generator', - 'Generic I/O' -] - -# Translations. The text will be used only for GetText, it will be translated -# in the gui. -TRANSLATIONS = [ - Translation('low', 'high'), - Translation('off', 'on'), - Translation('no', 'yes'), - Translation('open', 'closed'), - Translation('ok', 'alarm'), - Translation('running', 'stopped') -] - -class SystemBus(dbus.bus.BusConnection): - def __new__(cls): - return dbus.bus.BusConnection.__new__(cls, dbus.bus.BusConnection.TYPE_SYSTEM) - -class SessionBus(dbus.bus.BusConnection): - def __new__(cls): - return dbus.bus.BusConnection.__new__(cls, dbus.bus.BusConnection.TYPE_SESSION) - -class BasePulseCounter(object): - pass - -class DebugPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - - def register(self, path, gpio): - self.gpiomap[gpio] = None - return 0 - - def unregister(self, gpio): - del self.gpiomap[gpio] - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - from itertools import cycle - from time import sleep - for level in cycle([0, 1]): - for gpio in list(self.gpiomap.keys()): - yield gpio, level - sleep(0.25/len(self.gpiomap)) - -class EpollPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - self.states = {} - self.ob = epoll() - - def register(self, path, gpio): - path = os.path.realpath(path) - - # Set up gpio for rising edge interrupts - with open(os.path.join(path, 'edge'), 'ab') as fp: - fp.write(b'both') - - fp = open(os.path.join(path, 'value'), 'rb') - level = int(fp.read()) # flush it in case it's high at startup - self.gpiomap[gpio] = fp - self.states[gpio] = level - self.ob.register(fp, EPOLLPRI) - return level - - def unregister(self, gpio): - fp = self.gpiomap[gpio] - self.ob.unregister(fp) - del self.gpiomap[gpio] - del self.states[gpio] - fp.close() - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - while True: - # We have a timeout of 1 second on the poll, because poll() only - # looks at files in the epoll object at the time poll() was called. - # The timeout means we let other files (added via calls to - # register/unregister) into the loop at least that often. - self.ob.poll(1) - - # When coming out of the epoll call, we read all the gpios to make - # sure we didn't miss any edges. This is a safety fallback that - # ensures everything is up to date once a second, but - # edge-triggered results are handled immediately. - # NOTE: There has not been a report of a missed interrupt yet. - # Belts and suspenders. - for gpio, fp in list(self.gpiomap.items()): - os.lseek(fp.fileno(), 0, os.SEEK_SET) - v = int(os.read(fp.fileno(), 1)) - if v != self.states[gpio]: - self.states[gpio] = v - yield gpio, v - -class PollingPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - - def register(self, path, gpio): - path = os.path.realpath(path) - - fp = open(os.path.join(path, 'value'), 'rb') - level = int(fp.read()) - self.gpiomap[gpio] = [fp, level] - return level - - def unregister(self, gpio): - del self.gpiomap[gpio] - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - from itertools import cycle - from time import sleep - while True: - for gpio, (fp, level) in list(self.gpiomap.items()): - fp.seek(0, os.SEEK_SET) - v = int(fp.read()) - if v != level: - self.gpiomap[gpio][1] = v - yield gpio, v - sleep(1) - -class HandlerMaker(type): - """ Meta-class for keeping track of all extended classes. """ - def __init__(cls, name, bases, attrs): - if not hasattr(cls, 'handlers'): - cls.handlers = {} - else: - cls.handlers[cls.type_id] = cls - -class PinHandler(object, metaclass=HandlerMaker): - product_id = 0xFFFF - _product_name = 'Generic GPIO' - dbus_name = "digital" - def __init__(self, bus, base, path, gpio, settings): - self.gpio = gpio - self.path = path - self.bus = bus - self.settings = settings - self._level = 0 # Remember last state - - self.service = VeDbusService( - "{}.{}.input{:02d}".format(base, self.dbus_name, gpio), bus=bus) - - # Add objects required by ve-api - self.service.add_path('/Mgmt/ProcessName', __file__) - self.service.add_path('/Mgmt/ProcessVersion', VERSION) - self.service.add_path('/Mgmt/Connection', path) - self.service.add_path('/DeviceInstance', gpio) - self.service.add_path('/ProductId', self.product_id) - self.service.add_path('/ProductName', self.product_name) - self.service.add_path('/Connected', 1) - - # Custom name setting - def _change_name(p, v): - # This should fire a change event that will update product_name - # below. - settings['name'] = v - return True - - self.service.add_path('/CustomName', settings['name'], writeable=True, - onchangecallback=_change_name) - - # We'll count the pulses for all types of services - self.service.add_path('/Count', value=settings['count']) - - @property - def product_name(self): - return self.settings['name'] or self._product_name - - @product_name.setter - def product_name(self, v): - # Some pin types don't have an associated service (Disabled pins for - # example) - if self.service is not None: - self.service['/ProductName'] = v or self._product_name - - def deactivate(self): - self.save_count() - self.service.__del__() - del self.service - self.service = None - - @property - def level(self): - return self._level - - @level.setter - def level(self, l): - self._level = int(bool(l)) - - def toggle(self, level): - raise NotImplementedError - - def _toggle(self, level, service): - # Only increment Count on rising edge. - if level and level != self._level: - service['/Count'] = (service['/Count']+1) % MAXCOUNT - self._level = level - - def refresh(self): - """ Toggle state to last remembered state. This is called if settings - are changed so the Service can recalculate paths. """ - self.toggle(self._level) - - def save_count(self): - if self.service is not None: - self.settings['count'] = self.count - - @property - def active(self): - return self.service is not None - - @property - def count(self): - return self.service['/Count'] - - @count.setter - def count(self, v): - self.service['/Count'] = v - - @classmethod - def createHandler(cls, _type, *args, **kwargs): - if _type in cls.handlers: - return cls.handlers[_type](*args, **kwargs) - return None - - -class DisabledPin(PinHandler): - """ Place holder for a disabled pin. """ - _product_name = 'Disabled' - type_id = 0 - def __init__(self, bus, base, path, gpio, settings): - self.service = None - self.bus = bus - self.settings = settings - self._level = 0 # Remember last state - - def deactivate(self): - pass - - def toggle(self, level): - self._level = level - - def save_count(self): - # Do nothing - pass - - @property - def count(self): - return self.settings['count'] - - @count.setter - def count(self, v): - pass - - def refresh(self): - pass - - -class VolumeCounter(PinHandler): - product_id = 0xA165 - _product_name = "Generic pulse meter" - dbus_name = "pulsemeter" - type_id = 1 - - def __init__(self, bus, base, path, gpio, settings): - super(VolumeCounter, self).__init__(bus, base, path, gpio, settings) - self.service.add_path('/Aggregate', value=self.count*self.rate, - gettextcallback=lambda p, v: (str(v) + ' cubic meter')) - - @property - def rate(self): - return self.settings['rate'] - - def toggle(self, level): - with self.service as s: - super(VolumeCounter, self)._toggle(level, s) - s['/Aggregate'] = self.count * self.rate - -class PinAlarm(PinHandler): - product_id = 0xA166 - _product_name = "Generic digital input" - dbus_name = "digitalinput" - type_id = 0xFF - translation = 0 # low, high - - def __init__(self, bus, base, path, gpio, settings): - super(PinAlarm, self).__init__(bus, base, path, gpio, settings) - self.service.add_path('/InputState', value=0) - self.service.add_path('/State', value=self.get_state(0), - gettextcallback=lambda p, v: TRANSLATIONS[v//2][v%2]) - self.service.add_path('/Alarm', value=self.get_alarm_state(0)) - - # Also expose the type - self.service.add_path('/Type', value=self.type_id, - gettextcallback=lambda p, v: INPUTTYPES[v]) - - def toggle(self, level): - with self.service as s: - super(PinAlarm, self)._toggle(level, s) - s['/InputState'] = bool(level)*1 - s['/State'] = self.get_state(level) - # Ensure that the alarm flag resets if the /AlarmSetting config option - # disappears. - s['/Alarm'] = self.get_alarm_state(level) - - def get_state(self, level): - state = level ^ self.settings['invert'] - return 2 * self.translation + state - - def get_alarm_state(self, level): - return 2 * bool( - (level ^ self.settings['invertalarm']) and self.settings['alarm']) - - -# Various types of things we might want to monitor -class DoorSensor(PinAlarm): - _product_name = "Door alarm" - type_id = 2 - translation = 3 # open, closed - -class BilgePump(PinAlarm): - _product_name = "Bilge pump" - type_id = 3 - translation = 1 # off, on - -class BilgeAlarm(PinAlarm): - _product_name = "Bilge alarm" - type_id = 4 - translation = 4 # ok, alarm - -class BurglarAlarm(PinAlarm): - _product_name = "Burglar alarm" - type_id = 5 - translation = 4 # ok, alarm - -class SmokeAlarm(PinAlarm): - _product_name = "Smoke alarm" - type_id = 6 - translation = 4 # ok, alarm - -class FireAlarm(PinAlarm): - _product_name = "Fire alarm" - type_id = 7 - translation = 4 # ok, alarm - -class CO2Alarm(PinAlarm): - _product_name = "CO2 alarm" - type_id = 8 - translation = 4 # ok, alarm - -class Generator(PinAlarm): - _product_name = "Generator" - type_id = 9 - translation = 5 # running, stopped - -class GenericIO(PinAlarm): - _product_name = "Generic I/O" - type_id = 10 - translation = 0 # low, high - - -def dbusconnection(): - return SessionBus() if 'DBUS_SESSION_BUS_ADDRESS' in os.environ else SystemBus() - - -def main(): - parser = ArgumentParser(description=sys.argv[0]) - parser.add_argument('--servicebase', - help='Base service name on dbus, default is com.victronenergy', - default='com.victronenergy') - parser.add_argument('--poll', - help='Use a different kind of polling. Options are epoll, dumb and debug', - default='epoll') - parser.add_argument('inputs', nargs='+', help='Path to digital input') - args = parser.parse_args() - - PulseCounter = { - 'debug': DebugPulseCounter, - 'poll': PollingPulseCounter, - }.get(args.poll, EpollPulseCounter) - - DBusGMainLoop(set_as_default=True) - - # Keep track of enabled services - services = {} - inputs = dict(enumerate(args.inputs, 1)) - pulses = PulseCounter() # callable that iterates over pulses - - def register_gpio(path, gpio, bus, settings): - _type = settings['inputtype'] - print ("Registering GPIO {} for type {}".format(gpio, _type)) - - handler = PinHandler.createHandler(_type, - bus, args.servicebase, path, gpio, settings) - services[gpio] = handler - - # Only monitor if enabled - if _type > 0: - handler.level = pulses.register(path, gpio) - handler.refresh() - - def unregister_gpio(gpio): - print ("unRegistering GPIO {}".format(gpio)) - pulses.unregister(gpio) - services[gpio].deactivate() - - def handle_setting_change(inp, setting, old, new): - # This handler may also be called if some attribute of a setting - # is changed, but not the value. Bail if the value is unchanged. - if old == new: - return - - if setting == 'inputtype': - if new: - # Get current bus and settings objects, to be reused - service = services[inp] - bus, settings = service.bus, service.settings - - # Input enabled. If already enabled, unregister the old one first. - if pulses.registered(inp): - unregister_gpio(inp) - - # Before registering the new input, reset its settings to defaults - settings['count'] = 0 - settings['invert'] = 0 - settings['invertalarm'] = 0 - settings['alarm'] = 0 - - # Register it - register_gpio(inputs[inp], inp, bus, settings) - elif old: - # Input disabled - unregister_gpio(inp) - elif setting in ('rate', 'invert', 'alarm', 'invertalarm'): - services[inp].refresh() - elif setting == 'name': - services[inp].product_name = new - elif setting == 'count': - # Don't want this triggered on a period save, so only execute - # if it has changed. - v = int(new) - s = services[inp] - if s.count != v: - s.count = v - s.refresh() - - for inp, pth in inputs.items(): - supported_settings = { - 'inputtype': ['/Settings/DigitalInput/{}/Type'.format(inp), 0, 0, len(INPUTTYPES)], - 'rate': ['/Settings/DigitalInput/{}/Multiplier'.format(inp), 0.001, 0, 1.0], - 'count': ['/Settings/DigitalInput/{}/Count'.format(inp), 0, 0, MAXCOUNT, 1], - 'invert': ['/Settings/DigitalInput/{}/InvertTranslation'.format(inp), 0, 0, 1], - 'invertalarm': ['/Settings/DigitalInput/{}/InvertAlarm'.format(inp), 0, 0, 1], - 'alarm': ['/Settings/DigitalInput/{}/AlarmSetting'.format(inp), 0, 0, 1], - 'name': ['/Settings/DigitalInput/{}/CustomName'.format(inp), '', '', ''], - } - bus = dbusconnection() - sd = SettingsDevice(bus, supported_settings, partial(handle_setting_change, inp), timeout=10) - register_gpio(pth, inp, bus, sd) - - def poll(mainloop): - from time import time - idx = 0 - - try: - for inp, level in pulses(): - # epoll object only resyncs once a second. We may receive - # a pulse for something that's been deregistered. - try: - services[inp].toggle(level) - except KeyError: - continue - except: - traceback.print_exc() - mainloop.quit() - - # Need to run the gpio polling in separate thread. Pass in the mainloop so - # the thread can kill us if there is an exception. - mainloop = GLib.MainLoop() - - poller = Thread(target=lambda: poll(mainloop)) - poller.daemon = True - poller.start() - - # Periodically save the counter - def save_counters(): - for inp in inputs: - services[inp].save_count() - return True - GLib.timeout_add(SAVEINTERVAL, save_counters) - - # Save counter on shutdown - signal.signal(signal.SIGTERM, lambda *args: sys.exit(0)) - - try: - mainloop.run() - except KeyboardInterrupt: - pass - finally: - save_counters() - -if __name__ == "__main__": - main() diff --git a/FileSets/v2.94/TileRelay.qml b/FileSets/v2.94/TileRelay.qml deleted file mode 100644 index 22fd3768..00000000 --- a/FileSets/v2.94/TileRelay.qml +++ /dev/null @@ -1,488 +0,0 @@ -// New for GuiMods to display and control relays on separate overview page - -import QtQuick 1.1 -import "utils.js" as Utils - -Tile { - id: root - - property string systemPrefix: "com.victronenergy.system" - property string settingsPrefix: "com.victronenergy.settings" - property string functionPath: relayNumber === 0 ? "/Settings/Relay/Function" : "/Settings/Relay/" + relayNumber + "/Function" - property string polarityPath: relayNumber === 0 ? "/Settings/Relay/Polarity" : "/Settings/Relay/" + relayNumber + "/Polarity" - - property int relayFunction: 0 - property bool relayInverted: polarityItem.valid ? polarityItem.value : false - property bool relayActive: flase - - property string activeText: "" - property string inactiveText: "" - property string offButtonText: "" - property string onButtonText: "" - property string autoButtonText: "" - property string functionText: "" - property bool autoButtonActive: false - property bool offButtonActive: false - property bool onButtonActive: false - -////// GuiMods — DarkMode - property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } - property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 - - VBusItem - { - id: stateItem - bind: Utils.path(systemPrefix, "/Relay/", relayNumber, "/State") - onValueChanged: updateButtons () - } - VBusItem - { - id: nameItem - bind: Utils.path(settingsPrefix, "/Settings/Relay/", relayNumber, "/CustomName") - } - VBusItem - { - id: functionItem - bind: Utils.path(settingsPrefix, functionPath) - onValueChanged: updateFunction () - } - VBusItem - { - id: polarityItem - bind: Utils.path(settingsPrefix, polarityPath) - } - VBusItem - { - id: generatorManualStartItem - bind: Utils.path("com.victronenergy.generator.startstop0" , "/ManualStart") - onValidChanged: updateButtons () - onValueChanged: updateButtons () - } - VBusItem - { - id: generatorAutoRunItem - bind: Utils.path(settingsPrefix, "/Settings/Generator0/AutoStartEnabled") - onValidChanged: updateButtons () - onValueChanged: updateButtons () - } - VBusItem - { - id: generatorConditionItem - bind: Utils.path("com.victronenergy.generator.startstop0" , "/RunningByConditionCode") - } - VBusItem - { - id: generatorExternalOverrideItem - bind: Utils.path("com.victronenergy.generator.startstop0" , "/ExternalOverride") - } - VBusItem - { - id: pumpModeItem - bind: Utils.path(settingsPrefix, "/Settings/Pump0/Mode") - onValidChanged: updateButtons () - onValueChanged: updateButtons () - } - - Component.onCompleted: updateFunction () - -////// GuiMods — DarkMode - color: !darkMode ? "#d9d9d9" : "#202020" - border.color: !darkMode ? "#fff" : "#707070" - - function doScroll() - { - relayName.doScroll () - relayState.doScroll () - } - - values: Item - { - Column - { - width: root.width - x: 3 - spacing: 4 - visible: true - anchors - { - horizontalCenter: parent.horizontalCenter - top: parent.top - } - Text - { - font.pixelSize: 12 - font.bold: true -////// GuiMods DarkMode - color: !darkMode ? "black" : "gray" - anchors - { - horizontalCenter: parent.horizontalCenter - } - horizontalAlignment: Text.AlignHCenter - text: "Relay " + (relayNumber + 1) - } - MarqueeEnhanced - { - id: relayName - width: parent.width - 4 - text: nameItem.valid && nameItem.value != "" ? nameItem.value : " " - fontSize: 12 - bold: true -////// GuiMods DarkMode - textColor: !darkMode ? "black" : "gray" - scroll: false - } - Text - { - font.pixelSize: 12 - font.bold: true -////// GuiMods DarkMode - color: !darkMode ? "black" : "gray" - anchors.horizontalCenter: parent.horizontalCenter - horizontalAlignment: Text.AlignHCenter - text: functionText - } - - MarqueeEnhanced - { - id: relayState - width: parent.width - 4 - fontSize: 12 - bold: true -////// GuiMods DarkMode - textColor: !darkMode ? "black" : "gray" - scroll: false - text: - { - // special handling for generator - if (relayFunction == 1) - { - if (generatorExternalOverrideItem.valid && generatorExternalOverrideItem.value == 1) - return qsTr ("External override - stopped") - else if (generatorConditionItem.valid) - { - switch (generatorConditionItem.value) - { - case 0: - return qsTr ("Stopped") - case 1: - return qsTr ("Man run") - case 2: - return qsTr ("Test run") - case 3: - return qsTr ("Loss of comms run") - case 4: - return qsTr ("SOC run") - case 5: - return qsTr ("Load run") - case 6: - return qsTr ("Battery current run") - case 7: - return qsTr ("Battery voltage run") - case 8: - return qsTr ("Inverter temperature run") - case 9: - return qsTr ("Inverter overload run") - default: - return "??" - } - } - else - return "??" - } - else if (stateItem.valid) - { - if (relayActive) - return activeText - else - return inactiveText - } - else - return "??" - } - } - // spacer - Text - { - font.pixelSize: 4 - font.bold: true -////// GuiMods - DarkMode - color: !darkMode ? "black" : "gray" - height: 4 - anchors.horizontalCenter: parent.horizontalCenter - horizontalAlignment: Text.AlignHCenter - text: " " - } - Button - { - id: onButton -////// GuiMods - DarkMode - baseColor: !darkMode ? (onButtonActive ? "green" : "#e6ffe6") : (onButtonActive ? "#003000" : "#003000") - pressedColor: "#979797" - height: 40 - width: parent.width - 6 - anchors.horizontalCenter: parent.horizontalCenter - onClicked: buttonPress (1) - content: TileText - { - text: onButtonText; font.bold: true; - color: onButtonActive ? "white" : "black" - } - } - Button - { - id: offButton -////// GuiMods - DarkMode - baseColor: !darkMode ? (offButtonActive ? "black" : "#e6e6e6") : (offButtonActive ? "gray" : "gray") - pressedColor: "#979797" - height: 40 - width: parent.width - 6 - anchors.horizontalCenter: parent.horizontalCenter - onClicked: buttonPress (2) - content: TileText - { - text: offButtonText; font.bold: true; - color: offButtonActive ? "white" : "black" - } - } - Button - { - id: autoButton -////// GuiMods - DarkMode - baseColor: !darkMode ? (autoButtonActive ? "orange" : "#ffedcc") : (autoButtonActive ? "#3a2600" : "#3a2600") - pressedColor: "#979797" - height: 40 - width: parent.width - 6 - anchors.horizontalCenter: parent.horizontalCenter - onClicked: buttonPress (3) - content: TileText - { - text: autoButtonText; font.bold: true; - color: autoButtonActive ? "white" : "black" - } - } - } - } - function updateFunction () - { - if (functionItem.valid) - { - relayFunction = functionItem.value - switch (relayFunction) - { - // Alarm - no buttons - case 0: - functionText = qsTr("Alarm") - activeText = qsTr("Alarm") - inactiveText = qsTr("No Alarm") - offButtonText = "" - onButtonText = "" - autoButtonText = "" - onButton.show = false - offButton.show = false - autoButton.show = false - break;; - // Generator - case 1: - functionText = qsTr("Generator") - activeText = qsTr("") // generator state text handled below - inactiveText = qsTr("") - onButtonText = qsTr("Manual\nStart") - offButtonText = qsTr("Manual\nStop") - autoButtonText = qsTr("Auto\nEnable") - onButton.show = true - offButton.show = true - autoButton.show = true - break;; - // pump - case 3: - functionText = qsTr("Pump") - activeText = qsTr("On") - inactiveText = qsTr("Off") - onButtonText = qsTr("On") - offButtonText = qsTr("Off") - autoButtonText = qsTr("Auto") - onButton.show = true - offButton.show = true - autoButton.show = true - break;; - // temperature - case 4: - functionText = qsTr("Temp") - activeText = qsTr("Alarm") - inactiveText = qsTr("No Alarm") - onButtonText = "--" - offButtonText = "--" - autoButtonText = "--" - onButton.show = false - offButton.show = false - autoButton.show = false - break;; - // manual (2) and undefined - default: - functionText = qsTr("Manual") - activeText = qsTr("On") - inactiveText = qsTr("Off") - onButtonText = qsTr("On") - offButtonText = qsTr("Off") - autoButtonText = "" - onButton.show = true - offButton.show = true - autoButton.show = false - break;; - } - } - // only relay 1 has a function selector, so use manual settings for other relays - else - { - relayFunction = 2 - functionText = qsTr("Manual") - activeText = qsTr("On") - inactiveText = qsTr("Off") - onButtonText = qsTr("On") - offButtonText = qsTr("Off") - autoButtonText = "--" // empty string causes interactions - autoButton.show =false - } - updateButtons () - } - - function updateButtons () - { - switch (relayFunction) - { - // alarm - no buttons - case 0: - break;; - // Generator - case 1: - if (generatorManualStartItem.valid) - { - onButtonActive = generatorManualStartItem.value === 1 - offButtonActive = ! onButtonActive - } - else - { - offButtonActive = false - onButtonActive = false - } - if (generatorAutoRunItem.valid) - autoButtonActive = generatorAutoRunItem.value - else - autoButtonActive = false - break;; - // pump - case 3: - if (pumpModeItem.valid) - { - switch (pumpModeItem.value) - { - // Auto - case 0: - onButtonActive = false - offButtonActive = false - autoButtonActive = true - break;; - // On - case 1: - onButtonActive = true - offButtonActive = false - autoButtonActive = false - break;; - // Off - case 2: - onButtonActive = false - offButtonActive = true - autoButtonActive = false - break;; - default: - onButtonActive = false - offButtonActive = false - autoButtonActive = false - break;; - } - } - else - { - offButtonActive = false - onButtonActive = false - autoButtonActive = false - } - break;; - // manual (2) and undefined - default: - relayActive = stateItem.value === 1 != relayInverted - onButtonActive = relayActive - offButtonActive = ! onButtonActive - autoButtonActive = false - break;; - } - } - - function buttonPress (button) - { - switch (relayFunction) - { - // Generator - case 1: - switch (button) - { - // on - case 1: - generatorManualStartItem.setValue (1) - break;; - // off - case 2: - generatorManualStartItem.setValue (0) - break;; - // auto - case 3: - // toggle value - generatorAutoRunItem.setValue (generatorAutoRunItem.value === 1 ? 0 : 1) - break;; - default: - break;; - } - break;; - // pump - case 3: - switch (button) - { - // on - case 1: - pumpModeItem.setValue (1) - break;; - // off - case 2: - pumpModeItem.setValue (2) - break;; - // auto - case 3: - pumpModeItem.setValue (0) - break;; - default: - break;; - } - break;; - // alarm - no buttons - case 0: - break;; - // manual (2) and undefined - default: - switch (button) - { - // on - case 1: - stateItem.setValue (1) - break;; - // off - case 2: - stateItem.setValue (0) - break;; - default: - break;; - } - break;; - } - } -} diff --git a/FileSets/v2.94/TileRelay.qml.orig b/FileSets/v2.94/TileRelay.qml.orig deleted file mode 100644 index fc207add..00000000 --- a/FileSets/v2.94/TileRelay.qml.orig +++ /dev/null @@ -1,23 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -PageGenerator { - - title: qsTr("Generator start/stop") - settingsBindPrefix: "com.victronenergy.settings/Settings/Generator0" - startStopBindPrefix: "com.victronenergy.generator.startstop0" - - property VBusItem relayFunction: VBusItem { bind: Utils.path("com.victronenergy.settings", "/Settings/Relay/Function") } - - model: !relayFunction.valid || relayFunction.value === 1 ? startStopModel : disabledModel - - VisualItemModel { - id: disabledModel - MbItemText { - wrapMode: Text.WordWrap - text: qsTr("Generator start/stop function is not enabled, go to relay settings and set " + - "function to \"Generator start/stop\"") - } - } -} diff --git a/FileSets/v2.94/TileText.qml b/FileSets/v2.94/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v2.94/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.94/dbus_digitalinputs.py b/FileSets/v2.94/dbus_digitalinputs.py deleted file mode 100755 index 82fcc208..00000000 --- a/FileSets/v2.94/dbus_digitalinputs.py +++ /dev/null @@ -1,562 +0,0 @@ -#!/usr/bin/python3 -u - -#### modified for ExtTransferSwitch package - -import sys, os -import signal -from threading import Thread -from select import select, epoll, EPOLLPRI -from functools import partial -from collections import namedtuple -from argparse import ArgumentParser -import traceback -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) - -from dbus.mainloop.glib import DBusGMainLoop -import dbus -from gi.repository import GLib -from vedbus import VeDbusService -from settingsdevice import SettingsDevice - -VERSION = '0.17' -MAXCOUNT = 2**31-1 -SAVEINTERVAL = 60000 - -INPUT_FUNCTION_COUNTER = 1 -INPUT_FUNCTION_INPUT = 2 - -Translation = namedtuple('Translation', ['no', 'yes']) - -# Only append at the end -INPUTTYPES = [ - 'Disabled', - 'Pulse meter', - 'Door', - 'Bilge pump', - 'Bilge alarm', - 'Burglar alarm', - 'Smoke alarm', - 'Fire alarm', - 'CO2 alarm', - 'Generator', - 'Generic I/O', -#### added for ExtTransferSwitch package -- must be LAST in the list - 'Transfer switch' -] - -# Translations. The text will be used only for GetText, it will be translated -# in the gui. -TRANSLATIONS = [ - Translation('low', 'high'), - Translation('off', 'on'), - Translation('no', 'yes'), - Translation('open', 'closed'), - Translation('ok', 'alarm'), - Translation('running', 'stopped'), -#### added for ExtTransferSwitch package - Translation('on generator', 'on grid'), -] - -class SystemBus(dbus.bus.BusConnection): - def __new__(cls): - return dbus.bus.BusConnection.__new__(cls, dbus.bus.BusConnection.TYPE_SYSTEM) - -class SessionBus(dbus.bus.BusConnection): - def __new__(cls): - return dbus.bus.BusConnection.__new__(cls, dbus.bus.BusConnection.TYPE_SESSION) - -class BasePulseCounter(object): - pass - -class DebugPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - - def register(self, path, gpio): - self.gpiomap[gpio] = None - return 0 - - def unregister(self, gpio): - del self.gpiomap[gpio] - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - from itertools import cycle - from time import sleep - for level in cycle([0, 1]): - for gpio in list(self.gpiomap.keys()): - yield gpio, level - sleep(0.25/len(self.gpiomap)) - -class EpollPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - self.states = {} - self.ob = epoll() - - def register(self, path, gpio): - path = os.path.realpath(path) - - # Set up gpio for rising edge interrupts - with open(os.path.join(path, 'edge'), 'ab') as fp: - fp.write(b'both') - - fp = open(os.path.join(path, 'value'), 'rb') - level = int(fp.read()) # flush it in case it's high at startup - self.gpiomap[gpio] = fp - self.states[gpio] = level - self.ob.register(fp, EPOLLPRI) - return level - - def unregister(self, gpio): - fp = self.gpiomap[gpio] - self.ob.unregister(fp) - del self.gpiomap[gpio] - del self.states[gpio] - fp.close() - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - while True: - # We have a timeout of 1 second on the poll, because poll() only - # looks at files in the epoll object at the time poll() was called. - # The timeout means we let other files (added via calls to - # register/unregister) into the loop at least that often. - self.ob.poll(1) - - # When coming out of the epoll call, we read all the gpios to make - # sure we didn't miss any edges. This is a safety fallback that - # ensures everything is up to date once a second, but - # edge-triggered results are handled immediately. - # NOTE: There has not been a report of a missed interrupt yet. - # Belts and suspenders. - for gpio, fp in list(self.gpiomap.items()): - os.lseek(fp.fileno(), 0, os.SEEK_SET) - v = int(os.read(fp.fileno(), 1)) - if v != self.states[gpio]: - self.states[gpio] = v - yield gpio, v - -class PollingPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - - def register(self, path, gpio): - path = os.path.realpath(path) - - fp = open(os.path.join(path, 'value'), 'rb') - level = int(fp.read()) - self.gpiomap[gpio] = [fp, level] - return level - - def unregister(self, gpio): - del self.gpiomap[gpio] - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - from itertools import cycle - from time import sleep - while True: - for gpio, (fp, level) in list(self.gpiomap.items()): - fp.seek(0, os.SEEK_SET) - v = int(fp.read()) - if v != level: - self.gpiomap[gpio][1] = v - yield gpio, v - sleep(1) - -class HandlerMaker(type): - """ Meta-class for keeping track of all extended classes. """ - def __init__(cls, name, bases, attrs): - if not hasattr(cls, 'handlers'): - cls.handlers = {} - else: - cls.handlers[cls.type_id] = cls - -class PinHandler(object, metaclass=HandlerMaker): - product_id = 0xFFFF - _product_name = 'Generic GPIO' - dbus_name = "digital" - def __init__(self, bus, base, path, gpio, settings): - self.gpio = gpio - self.path = path - self.bus = bus - self.settings = settings - self._level = 0 # Remember last state - - self.service = VeDbusService( - "{}.{}.input{:02d}".format(base, self.dbus_name, gpio), bus=bus) - - # Add objects required by ve-api - self.service.add_path('/Mgmt/ProcessName', __file__) - self.service.add_path('/Mgmt/ProcessVersion', VERSION) - self.service.add_path('/Mgmt/Connection', path) - self.service.add_path('/DeviceInstance', gpio) - self.service.add_path('/ProductId', self.product_id) - self.service.add_path('/ProductName', self.product_name) - self.service.add_path('/Connected', 1) - - # Custom name setting - def _change_name(p, v): - # This should fire a change event that will update product_name - # below. - settings['name'] = v - return True - - self.service.add_path('/CustomName', settings['name'], writeable=True, - onchangecallback=_change_name) - - # We'll count the pulses for all types of services - self.service.add_path('/Count', value=settings['count']) - - @property - def product_name(self): - return self.settings['name'] or self._product_name - - @product_name.setter - def product_name(self, v): - # Some pin types don't have an associated service (Disabled pins for - # example) - if self.service is not None: - self.service['/ProductName'] = v or self._product_name - - def deactivate(self): - self.save_count() - self.service.__del__() - del self.service - self.service = None - - @property - def level(self): - return self._level - - @level.setter - def level(self, l): - self._level = int(bool(l)) - - def toggle(self, level): - raise NotImplementedError - - def _toggle(self, level, service): - # Only increment Count on rising edge. - if level and level != self._level: - service['/Count'] = (service['/Count']+1) % MAXCOUNT - self._level = level - - def refresh(self): - """ Toggle state to last remembered state. This is called if settings - are changed so the Service can recalculate paths. """ - self.toggle(self._level) - - def save_count(self): - if self.service is not None: - self.settings['count'] = self.count - - @property - def active(self): - return self.service is not None - - @property - def count(self): - return self.service['/Count'] - - @count.setter - def count(self, v): - self.service['/Count'] = v - - @classmethod - def createHandler(cls, _type, *args, **kwargs): - if _type in cls.handlers: - return cls.handlers[_type](*args, **kwargs) - return None - - -class DisabledPin(PinHandler): - """ Place holder for a disabled pin. """ - _product_name = 'Disabled' - type_id = 0 - def __init__(self, bus, base, path, gpio, settings): - self.service = None - self.bus = bus - self.settings = settings - self._level = 0 # Remember last state - - def deactivate(self): - pass - - def toggle(self, level): - self._level = level - - def save_count(self): - # Do nothing - pass - - @property - def count(self): - return self.settings['count'] - - @count.setter - def count(self, v): - pass - - def refresh(self): - pass - - -class VolumeCounter(PinHandler): - product_id = 0xA165 - _product_name = "Generic pulse meter" - dbus_name = "pulsemeter" - type_id = 1 - - def __init__(self, bus, base, path, gpio, settings): - super(VolumeCounter, self).__init__(bus, base, path, gpio, settings) - self.service.add_path('/Aggregate', value=self.count*self.rate, - gettextcallback=lambda p, v: (str(v) + ' cubic meter')) - - @property - def rate(self): - return self.settings['rate'] - - def toggle(self, level): - with self.service as s: - super(VolumeCounter, self)._toggle(level, s) - s['/Aggregate'] = self.count * self.rate - -class PinAlarm(PinHandler): - product_id = 0xA166 - _product_name = "Generic digital input" - dbus_name = "digitalinput" - type_id = 0xFF - translation = 0 # low, high - - def __init__(self, bus, base, path, gpio, settings): - super(PinAlarm, self).__init__(bus, base, path, gpio, settings) - self.service.add_path('/InputState', value=0) - self.service.add_path('/State', value=self.get_state(0), - gettextcallback=lambda p, v: TRANSLATIONS[v//2][v%2]) - self.service.add_path('/Alarm', value=self.get_alarm_state(0)) - - # Also expose the type - self.service.add_path('/Type', value=self.type_id, - gettextcallback=lambda p, v: INPUTTYPES[v]) - - def toggle(self, level): - with self.service as s: - super(PinAlarm, self)._toggle(level, s) - s['/InputState'] = bool(level)*1 - s['/State'] = self.get_state(level) - # Ensure that the alarm flag resets if the /AlarmSetting config option - # disappears. - s['/Alarm'] = self.get_alarm_state(level) - - def get_state(self, level): - state = level ^ self.settings['invert'] - return 2 * self.translation + state - - def get_alarm_state(self, level): - return 2 * bool( - (level ^ self.settings['invertalarm']) and self.settings['alarm']) - - -# Various types of things we might want to monitor -class DoorSensor(PinAlarm): - _product_name = "Door alarm" - type_id = 2 - translation = 3 # open, closed - -class BilgePump(PinAlarm): - _product_name = "Bilge pump" - type_id = 3 - translation = 1 # off, on - -class BilgeAlarm(PinAlarm): - _product_name = "Bilge alarm" - type_id = 4 - translation = 4 # ok, alarm - -class BurglarAlarm(PinAlarm): - _product_name = "Burglar alarm" - type_id = 5 - translation = 4 # ok, alarm - -class SmokeAlarm(PinAlarm): - _product_name = "Smoke alarm" - type_id = 6 - translation = 4 # ok, alarm - -class FireAlarm(PinAlarm): - _product_name = "Fire alarm" - type_id = 7 - translation = 4 # ok, alarm - -class CO2Alarm(PinAlarm): - _product_name = "CO2 alarm" - type_id = 8 - translation = 4 # ok, alarm - -class Generator(PinAlarm): - _product_name = "Generator" - type_id = 9 - translation = 5 # running, stopped - -class GenericIO(PinAlarm): - _product_name = "Generic I/O" - type_id = 10 - translation = 0 # low, high - -#### added for ExtTransferSwitch package -class TransferSwitch(PinAlarm): - _product_name = "External AC Input transfer switch" - type_id = 11 - translation = 6 # Grid In / Generator In - - -def dbusconnection(): - return SessionBus() if 'DBUS_SESSION_BUS_ADDRESS' in os.environ else SystemBus() - - -def main(): - parser = ArgumentParser(description=sys.argv[0]) - parser.add_argument('--servicebase', - help='Base service name on dbus, default is com.victronenergy', - default='com.victronenergy') - parser.add_argument('--poll', - help='Use a different kind of polling. Options are epoll, dumb and debug', - default='epoll') - parser.add_argument('inputs', nargs='+', help='Path to digital input') - args = parser.parse_args() - - PulseCounter = { - 'debug': DebugPulseCounter, - 'poll': PollingPulseCounter, - }.get(args.poll, EpollPulseCounter) - - DBusGMainLoop(set_as_default=True) - - # Keep track of enabled services - services = {} - inputs = dict(enumerate(args.inputs, 1)) - pulses = PulseCounter() # callable that iterates over pulses - - def register_gpio(path, gpio, bus, settings): - _type = settings['inputtype'] - print ("Registering GPIO {} for type {}".format(gpio, _type)) - - handler = PinHandler.createHandler(_type, - bus, args.servicebase, path, gpio, settings) - services[gpio] = handler - - # Only monitor if enabled - if _type > 0: - handler.level = pulses.register(path, gpio) - handler.refresh() - - def unregister_gpio(gpio): - print ("unRegistering GPIO {}".format(gpio)) - pulses.unregister(gpio) - services[gpio].deactivate() - - def handle_setting_change(inp, setting, old, new): - # This handler may also be called if some attribute of a setting - # is changed, but not the value. Bail if the value is unchanged. - if old == new: - return - - if setting == 'inputtype': - if new: - # Get current bus and settings objects, to be reused - service = services[inp] - bus, settings = service.bus, service.settings - - # Input enabled. If already enabled, unregister the old one first. - if pulses.registered(inp): - unregister_gpio(inp) - - # Before registering the new input, reset its settings to defaults - settings['count'] = 0 - settings['invert'] = 0 - settings['invertalarm'] = 0 - settings['alarm'] = 0 - - # Register it - register_gpio(inputs[inp], inp, bus, settings) - elif old: - # Input disabled - unregister_gpio(inp) - elif setting in ('rate', 'invert', 'alarm', 'invertalarm'): - services[inp].refresh() - elif setting == 'name': - services[inp].product_name = new - elif setting == 'count': - # Don't want this triggered on a period save, so only execute - # if it has changed. - v = int(new) - s = services[inp] - if s.count != v: - s.count = v - s.refresh() - - for inp, pth in inputs.items(): - supported_settings = { - 'inputtype': ['/Settings/DigitalInput/{}/Type'.format(inp), 0, 0, len(INPUTTYPES)], - 'rate': ['/Settings/DigitalInput/{}/Multiplier'.format(inp), 0.001, 0, 1.0], - 'count': ['/Settings/DigitalInput/{}/Count'.format(inp), 0, 0, MAXCOUNT, 1], - 'invert': ['/Settings/DigitalInput/{}/InvertTranslation'.format(inp), 0, 0, 1], - 'invertalarm': ['/Settings/DigitalInput/{}/InvertAlarm'.format(inp), 0, 0, 1], - 'alarm': ['/Settings/DigitalInput/{}/AlarmSetting'.format(inp), 0, 0, 1], - 'name': ['/Settings/DigitalInput/{}/CustomName'.format(inp), '', '', ''], - } - bus = dbusconnection() - sd = SettingsDevice(bus, supported_settings, partial(handle_setting_change, inp), timeout=10) - register_gpio(pth, inp, bus, sd) - - def poll(mainloop): - from time import time - idx = 0 - - try: - for inp, level in pulses(): - # epoll object only resyncs once a second. We may receive - # a pulse for something that's been deregistered. - try: - services[inp].toggle(level) - except KeyError: - continue - except: - traceback.print_exc() - mainloop.quit() - - # Need to run the gpio polling in separate thread. Pass in the mainloop so - # the thread can kill us if there is an exception. - mainloop = GLib.MainLoop() - - poller = Thread(target=lambda: poll(mainloop)) - poller.daemon = True - poller.start() - - # Periodically save the counter - def save_counters(): - for inp in inputs: - services[inp].save_count() - return True - GLib.timeout_add(SAVEINTERVAL, save_counters) - - # Save counter on shutdown - signal.signal(signal.SIGTERM, lambda *args: sys.exit(0)) - - try: - mainloop.run() - except KeyboardInterrupt: - pass - finally: - save_counters() - -if __name__ == "__main__": - main() diff --git a/FileSets/v2.94/dbus_digitalinputs.py.orig b/FileSets/v2.94/dbus_digitalinputs.py.orig deleted file mode 100755 index a251e4e5..00000000 --- a/FileSets/v2.94/dbus_digitalinputs.py.orig +++ /dev/null @@ -1,550 +0,0 @@ -#!/usr/bin/python3 -u - -import sys, os -import signal -from threading import Thread -from select import select, epoll, EPOLLPRI -from functools import partial -from collections import namedtuple -from argparse import ArgumentParser -import traceback -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) - -from dbus.mainloop.glib import DBusGMainLoop -import dbus -from gi.repository import GLib -from vedbus import VeDbusService -from settingsdevice import SettingsDevice - -VERSION = '0.17' -MAXCOUNT = 2**31-1 -SAVEINTERVAL = 60000 - -INPUT_FUNCTION_COUNTER = 1 -INPUT_FUNCTION_INPUT = 2 - -Translation = namedtuple('Translation', ['no', 'yes']) - -# Only append at the end -INPUTTYPES = [ - 'Disabled', - 'Pulse meter', - 'Door', - 'Bilge pump', - 'Bilge alarm', - 'Burglar alarm', - 'Smoke alarm', - 'Fire alarm', - 'CO2 alarm', - 'Generator', - 'Generic I/O' -] - -# Translations. The text will be used only for GetText, it will be translated -# in the gui. -TRANSLATIONS = [ - Translation('low', 'high'), - Translation('off', 'on'), - Translation('no', 'yes'), - Translation('open', 'closed'), - Translation('ok', 'alarm'), - Translation('running', 'stopped') -] - -class SystemBus(dbus.bus.BusConnection): - def __new__(cls): - return dbus.bus.BusConnection.__new__(cls, dbus.bus.BusConnection.TYPE_SYSTEM) - -class SessionBus(dbus.bus.BusConnection): - def __new__(cls): - return dbus.bus.BusConnection.__new__(cls, dbus.bus.BusConnection.TYPE_SESSION) - -class BasePulseCounter(object): - pass - -class DebugPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - - def register(self, path, gpio): - self.gpiomap[gpio] = None - return 0 - - def unregister(self, gpio): - del self.gpiomap[gpio] - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - from itertools import cycle - from time import sleep - for level in cycle([0, 1]): - for gpio in list(self.gpiomap.keys()): - yield gpio, level - sleep(0.25/len(self.gpiomap)) - -class EpollPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - self.states = {} - self.ob = epoll() - - def register(self, path, gpio): - path = os.path.realpath(path) - - # Set up gpio for rising edge interrupts - with open(os.path.join(path, 'edge'), 'ab') as fp: - fp.write(b'both') - - fp = open(os.path.join(path, 'value'), 'rb') - level = int(fp.read()) # flush it in case it's high at startup - self.gpiomap[gpio] = fp - self.states[gpio] = level - self.ob.register(fp, EPOLLPRI) - return level - - def unregister(self, gpio): - fp = self.gpiomap[gpio] - self.ob.unregister(fp) - del self.gpiomap[gpio] - del self.states[gpio] - fp.close() - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - while True: - # We have a timeout of 1 second on the poll, because poll() only - # looks at files in the epoll object at the time poll() was called. - # The timeout means we let other files (added via calls to - # register/unregister) into the loop at least that often. - self.ob.poll(1) - - # When coming out of the epoll call, we read all the gpios to make - # sure we didn't miss any edges. This is a safety fallback that - # ensures everything is up to date once a second, but - # edge-triggered results are handled immediately. - # NOTE: There has not been a report of a missed interrupt yet. - # Belts and suspenders. - for gpio, fp in list(self.gpiomap.items()): - os.lseek(fp.fileno(), 0, os.SEEK_SET) - v = int(os.read(fp.fileno(), 1)) - if v != self.states[gpio]: - self.states[gpio] = v - yield gpio, v - -class PollingPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - - def register(self, path, gpio): - path = os.path.realpath(path) - - fp = open(os.path.join(path, 'value'), 'rb') - level = int(fp.read()) - self.gpiomap[gpio] = [fp, level] - return level - - def unregister(self, gpio): - del self.gpiomap[gpio] - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - from itertools import cycle - from time import sleep - while True: - for gpio, (fp, level) in list(self.gpiomap.items()): - fp.seek(0, os.SEEK_SET) - v = int(fp.read()) - if v != level: - self.gpiomap[gpio][1] = v - yield gpio, v - sleep(1) - -class HandlerMaker(type): - """ Meta-class for keeping track of all extended classes. """ - def __init__(cls, name, bases, attrs): - if not hasattr(cls, 'handlers'): - cls.handlers = {} - else: - cls.handlers[cls.type_id] = cls - -class PinHandler(object, metaclass=HandlerMaker): - product_id = 0xFFFF - _product_name = 'Generic GPIO' - dbus_name = "digital" - def __init__(self, bus, base, path, gpio, settings): - self.gpio = gpio - self.path = path - self.bus = bus - self.settings = settings - self._level = 0 # Remember last state - - self.service = VeDbusService( - "{}.{}.input{:02d}".format(base, self.dbus_name, gpio), bus=bus) - - # Add objects required by ve-api - self.service.add_path('/Mgmt/ProcessName', __file__) - self.service.add_path('/Mgmt/ProcessVersion', VERSION) - self.service.add_path('/Mgmt/Connection', path) - self.service.add_path('/DeviceInstance', gpio) - self.service.add_path('/ProductId', self.product_id) - self.service.add_path('/ProductName', self.product_name) - self.service.add_path('/Connected', 1) - - # Custom name setting - def _change_name(p, v): - # This should fire a change event that will update product_name - # below. - settings['name'] = v - return True - - self.service.add_path('/CustomName', settings['name'], writeable=True, - onchangecallback=_change_name) - - # We'll count the pulses for all types of services - self.service.add_path('/Count', value=settings['count']) - - @property - def product_name(self): - return self.settings['name'] or self._product_name - - @product_name.setter - def product_name(self, v): - # Some pin types don't have an associated service (Disabled pins for - # example) - if self.service is not None: - self.service['/ProductName'] = v or self._product_name - - def deactivate(self): - self.save_count() - self.service.__del__() - del self.service - self.service = None - - @property - def level(self): - return self._level - - @level.setter - def level(self, l): - self._level = int(bool(l)) - - def toggle(self, level): - raise NotImplementedError - - def _toggle(self, level, service): - # Only increment Count on rising edge. - if level and level != self._level: - service['/Count'] = (service['/Count']+1) % MAXCOUNT - self._level = level - - def refresh(self): - """ Toggle state to last remembered state. This is called if settings - are changed so the Service can recalculate paths. """ - self.toggle(self._level) - - def save_count(self): - if self.service is not None: - self.settings['count'] = self.count - - @property - def active(self): - return self.service is not None - - @property - def count(self): - return self.service['/Count'] - - @count.setter - def count(self, v): - self.service['/Count'] = v - - @classmethod - def createHandler(cls, _type, *args, **kwargs): - if _type in cls.handlers: - return cls.handlers[_type](*args, **kwargs) - return None - - -class DisabledPin(PinHandler): - """ Place holder for a disabled pin. """ - _product_name = 'Disabled' - type_id = 0 - def __init__(self, bus, base, path, gpio, settings): - self.service = None - self.bus = bus - self.settings = settings - self._level = 0 # Remember last state - - def deactivate(self): - pass - - def toggle(self, level): - self._level = level - - def save_count(self): - # Do nothing - pass - - @property - def count(self): - return self.settings['count'] - - @count.setter - def count(self, v): - pass - - def refresh(self): - pass - - -class VolumeCounter(PinHandler): - product_id = 0xA165 - _product_name = "Generic pulse meter" - dbus_name = "pulsemeter" - type_id = 1 - - def __init__(self, bus, base, path, gpio, settings): - super(VolumeCounter, self).__init__(bus, base, path, gpio, settings) - self.service.add_path('/Aggregate', value=self.count*self.rate, - gettextcallback=lambda p, v: (str(v) + ' cubic meter')) - - @property - def rate(self): - return self.settings['rate'] - - def toggle(self, level): - with self.service as s: - super(VolumeCounter, self)._toggle(level, s) - s['/Aggregate'] = self.count * self.rate - -class PinAlarm(PinHandler): - product_id = 0xA166 - _product_name = "Generic digital input" - dbus_name = "digitalinput" - type_id = 0xFF - translation = 0 # low, high - - def __init__(self, bus, base, path, gpio, settings): - super(PinAlarm, self).__init__(bus, base, path, gpio, settings) - self.service.add_path('/InputState', value=0) - self.service.add_path('/State', value=self.get_state(0), - gettextcallback=lambda p, v: TRANSLATIONS[v//2][v%2]) - self.service.add_path('/Alarm', value=self.get_alarm_state(0)) - - # Also expose the type - self.service.add_path('/Type', value=self.type_id, - gettextcallback=lambda p, v: INPUTTYPES[v]) - - def toggle(self, level): - with self.service as s: - super(PinAlarm, self)._toggle(level, s) - s['/InputState'] = bool(level)*1 - s['/State'] = self.get_state(level) - # Ensure that the alarm flag resets if the /AlarmSetting config option - # disappears. - s['/Alarm'] = self.get_alarm_state(level) - - def get_state(self, level): - state = level ^ self.settings['invert'] - return 2 * self.translation + state - - def get_alarm_state(self, level): - return 2 * bool( - (level ^ self.settings['invertalarm']) and self.settings['alarm']) - - -# Various types of things we might want to monitor -class DoorSensor(PinAlarm): - _product_name = "Door alarm" - type_id = 2 - translation = 3 # open, closed - -class BilgePump(PinAlarm): - _product_name = "Bilge pump" - type_id = 3 - translation = 1 # off, on - -class BilgeAlarm(PinAlarm): - _product_name = "Bilge alarm" - type_id = 4 - translation = 4 # ok, alarm - -class BurglarAlarm(PinAlarm): - _product_name = "Burglar alarm" - type_id = 5 - translation = 4 # ok, alarm - -class SmokeAlarm(PinAlarm): - _product_name = "Smoke alarm" - type_id = 6 - translation = 4 # ok, alarm - -class FireAlarm(PinAlarm): - _product_name = "Fire alarm" - type_id = 7 - translation = 4 # ok, alarm - -class CO2Alarm(PinAlarm): - _product_name = "CO2 alarm" - type_id = 8 - translation = 4 # ok, alarm - -class Generator(PinAlarm): - _product_name = "Generator" - type_id = 9 - translation = 5 # running, stopped - -class GenericIO(PinAlarm): - _product_name = "Generic I/O" - type_id = 10 - translation = 0 # low, high - - -def dbusconnection(): - return SessionBus() if 'DBUS_SESSION_BUS_ADDRESS' in os.environ else SystemBus() - - -def main(): - parser = ArgumentParser(description=sys.argv[0]) - parser.add_argument('--servicebase', - help='Base service name on dbus, default is com.victronenergy', - default='com.victronenergy') - parser.add_argument('--poll', - help='Use a different kind of polling. Options are epoll, dumb and debug', - default='epoll') - parser.add_argument('inputs', nargs='+', help='Path to digital input') - args = parser.parse_args() - - PulseCounter = { - 'debug': DebugPulseCounter, - 'poll': PollingPulseCounter, - }.get(args.poll, EpollPulseCounter) - - DBusGMainLoop(set_as_default=True) - - # Keep track of enabled services - services = {} - inputs = dict(enumerate(args.inputs, 1)) - pulses = PulseCounter() # callable that iterates over pulses - - def register_gpio(path, gpio, bus, settings): - _type = settings['inputtype'] - print ("Registering GPIO {} for type {}".format(gpio, _type)) - - handler = PinHandler.createHandler(_type, - bus, args.servicebase, path, gpio, settings) - services[gpio] = handler - - # Only monitor if enabled - if _type > 0: - handler.level = pulses.register(path, gpio) - handler.refresh() - - def unregister_gpio(gpio): - print ("unRegistering GPIO {}".format(gpio)) - pulses.unregister(gpio) - services[gpio].deactivate() - - def handle_setting_change(inp, setting, old, new): - # This handler may also be called if some attribute of a setting - # is changed, but not the value. Bail if the value is unchanged. - if old == new: - return - - if setting == 'inputtype': - if new: - # Get current bus and settings objects, to be reused - service = services[inp] - bus, settings = service.bus, service.settings - - # Input enabled. If already enabled, unregister the old one first. - if pulses.registered(inp): - unregister_gpio(inp) - - # Before registering the new input, reset its settings to defaults - settings['count'] = 0 - settings['invert'] = 0 - settings['invertalarm'] = 0 - settings['alarm'] = 0 - - # Register it - register_gpio(inputs[inp], inp, bus, settings) - elif old: - # Input disabled - unregister_gpio(inp) - elif setting in ('rate', 'invert', 'alarm', 'invertalarm'): - services[inp].refresh() - elif setting == 'name': - services[inp].product_name = new - elif setting == 'count': - # Don't want this triggered on a period save, so only execute - # if it has changed. - v = int(new) - s = services[inp] - if s.count != v: - s.count = v - s.refresh() - - for inp, pth in inputs.items(): - supported_settings = { - 'inputtype': ['/Settings/DigitalInput/{}/Type'.format(inp), 0, 0, len(INPUTTYPES)], - 'rate': ['/Settings/DigitalInput/{}/Multiplier'.format(inp), 0.001, 0, 1.0], - 'count': ['/Settings/DigitalInput/{}/Count'.format(inp), 0, 0, MAXCOUNT, 1], - 'invert': ['/Settings/DigitalInput/{}/InvertTranslation'.format(inp), 0, 0, 1], - 'invertalarm': ['/Settings/DigitalInput/{}/InvertAlarm'.format(inp), 0, 0, 1], - 'alarm': ['/Settings/DigitalInput/{}/AlarmSetting'.format(inp), 0, 0, 1], - 'name': ['/Settings/DigitalInput/{}/CustomName'.format(inp), '', '', ''], - } - bus = dbusconnection() - sd = SettingsDevice(bus, supported_settings, partial(handle_setting_change, inp), timeout=10) - register_gpio(pth, inp, bus, sd) - - def poll(mainloop): - from time import time - idx = 0 - - try: - for inp, level in pulses(): - # epoll object only resyncs once a second. We may receive - # a pulse for something that's been deregistered. - try: - services[inp].toggle(level) - except KeyError: - continue - except: - traceback.print_exc() - mainloop.quit() - - # Need to run the gpio polling in separate thread. Pass in the mainloop so - # the thread can kill us if there is an exception. - mainloop = GLib.MainLoop() - - poller = Thread(target=lambda: poll(mainloop)) - poller.daemon = True - poller.start() - - # Periodically save the counter - def save_counters(): - for inp in inputs: - services[inp].save_count() - return True - GLib.timeout_add(SAVEINTERVAL, save_counters) - - # Save counter on shutdown - signal.signal(signal.SIGTERM, lambda *args: sys.exit(0)) - - try: - mainloop.run() - except KeyboardInterrupt: - pass - finally: - save_counters() - -if __name__ == "__main__": - main() diff --git a/FileSets/v2.94/dbus_generator.py b/FileSets/v2.94/dbus_generator.py deleted file mode 120000 index 09bd88b5..00000000 --- a/FileSets/v2.94/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.00~32/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v2.94/startstop.py b/FileSets/v2.94/startstop.py deleted file mode 100644 index 6e7cb81e..00000000 --- a/FileSets/v2.94/startstop.py +++ /dev/null @@ -1,1186 +0,0 @@ -#!/usr/bin/python -u -# -*- coding: utf-8 -*- - -#### GuiMods -#### This file has been modified to allow the generator running state derived from the generator digital input -#### or the genset AC input -#### If the incoming generator state changes, the manual start state is updated -#### time accumulation is suspended when the generator is not running -#### A switch in the generator settings menucontrols whethter the incoming state affects manual start or time accumulaiton -#### It is now possible to start the generator manually and have it stop automatically based on the preset conditions -#### for automaitc start / stop -#### A service interval timer was added so the accumulated run time does not need to be reset, -#### providing total run time for the generator -#### Search for #### GuiMods to find changes - -# Function -# dbus_generator monitors the dbus for batteries (com.victronenergy.battery.*) and -# vebus com.victronenergy.vebus.* -# Battery and vebus monitors can be configured through the gui. -# It then monitors SOC, AC loads, battery current and battery voltage,to auto start/stop the generator based -# on the configuration settings. Generator can be started manually or periodically setting a tes trun period. -# Time zones function allows to use different values for the conditions along the day depending on time - -import dbus -import datetime -import calendar -import time -import sys -import json -import os -import logging -from os import environ -import monotonic_time -from gen_utils import SettingsPrefix, Errors, States, enum -from gen_utils import create_dbus_service -# Victron packages -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) -from ve_utils import exit_on_error -from settingsdevice import SettingsDevice - -RunningConditions = enum( - Stopped = 0, - Manual = 1, - TestRun = 2, - LossOfCommunication = 3, - Soc = 4, - Acload = 5, - BatteryCurrent = 6, - BatteryVoltage = 7, - InverterHighTemp = 8, - InverterOverload = 9, - StopOnAc1 = 10) - -SYSTEM_SERVICE = 'com.victronenergy.system' -BATTERY_PREFIX = '/Dc/Battery' -HISTORY_DAYS = 30 - -def safe_max(args): - try: - return max(x for x in args if x is not None) - except ValueError: - return None - -class StartStop(object): - _driver = None - def __init__(self, instance): -#### GuiMods - self._last_update_mtime = 0 - self._accumulatedRunTime = 0 - self._digitalInputTypeObject = None - self._generatorInputStateObject = 0 - self._lastState = 0 - self._externalOverride = False - self._externalOverrideDelay = 99 - self._lastExternalOverride = False - self._searchDelay = 99 - self._linkToExternalState = False - - self._dbusservice = None - self._settings = None - self._dbusmonitor = None - self._remoteservice = None - self._name = None - self._enabled = False - self._instance = instance - - # One second per retry - self.RETRIES_ON_ERROR = 300 - self._testrun_soc_retries = 0 - self._last_counters_check = 0 - - self._starttime = 0 - self._manualstarttimer = 0 - self._last_runtime_update = 0 - self._timer_runnning = 0 - - # Manual battery service selection is deprecated in favour - # of getting the values directly from systemcalc, we keep - # manual selected services handling for compatibility reasons. - self._vebusservice = None - self._errorstate = 0 - self._battery_service = None - self._battery_prefix = None - - self._acpower_inverter_input = { - 'timeout': 0, - 'unabletostart': False - } - - self._condition_stack = { - 'batteryvoltage': { - 'name': 'batteryvoltage', - 'reached': False, - 'boolean': False, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'battery' - }, - 'batterycurrent': { - 'name': 'batterycurrent', - 'reached': False, - 'boolean': False, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'battery' - }, - 'acload': { - 'name': 'acload', - 'reached': False, - 'boolean': False, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - }, - 'inverterhightemp': { - 'name': 'inverterhightemp', - 'reached': False, - 'boolean': True, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - }, - 'inverteroverload': { - 'name': 'inverteroverload', - 'reached': False, - 'boolean': True, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - }, - 'soc': { - 'name': 'soc', - 'reached': False, - 'boolean': False, - 'timed': False, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'battery' - }, - 'stoponac1': { - 'name': 'stoponac1', - 'reached': False, - 'boolean': True, - 'timed': False, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - } - } - - def set_sources(self, dbusmonitor, settings, name, remoteservice): - self._settings = SettingsPrefix(settings, name) - self._dbusmonitor = dbusmonitor - self._remoteservice = remoteservice - self._name = name - - self.log_info('Start/stop instance created for %s.' % self._remoteservice) - self._remote_setup() - - def _create_service(self): - self._dbusservice = self._create_dbus_service() - - # The driver used for this start/stop service - self._dbusservice.add_path('/Type', value=self._driver) - # State: None = invalid, 0 = stopped, 1 = running - self._dbusservice.add_path('/State', value=None) - # RunningByConditionCode: Numeric Companion to /RunningByCondition below, but - # also encompassing a Stopped state. - self._dbusservice.add_path('/RunningByConditionCode', value=None) - # Error - self._dbusservice.add_path('/Error', value=None, gettextcallback=lambda p, v: Errors.get_description(v)) - # Condition that made the generator start - self._dbusservice.add_path('/RunningByCondition', value=None) - # Runtime - self._dbusservice.add_path('/Runtime', value=None, gettextcallback=self._seconds_to_text) - # Today runtime - self._dbusservice.add_path('/TodayRuntime', value=None, gettextcallback=self._seconds_to_text) - # Test run runtime - self._dbusservice.add_path('/TestRunIntervalRuntime', value=None , gettextcallback=self._seconds_to_text) - # Next test run date, values is 0 for test run disabled - self._dbusservice.add_path('/NextTestRun', value=None, gettextcallback=lambda p, v: datetime.datetime.fromtimestamp(v).strftime('%c')) - # Next test run is needed 1, not needed 0 - self._dbusservice.add_path('/SkipTestRun', value=None) - # Manual start - self._dbusservice.add_path('/ManualStart', value=None, writeable=True) - # Manual start timer - self._dbusservice.add_path('/ManualStartTimer', value=None, writeable=True) - # Silent mode active - self._dbusservice.add_path('/QuietHours', value=None) - # Alarms - self._dbusservice.add_path('/Alarms/NoGeneratorAtAcIn', value=None) - # Autostart - self._dbusservice.add_path('/AutoStartEnabled', value=None, writeable=True, onchangecallback=self._set_autostart) - - # We need to set the values after creating the paths to trigger the 'onValueChanged' event for the gui - # otherwise the gui will report the paths as invalid if we remove and recreate the paths without - # restarting the dbusservice. - self._dbusservice['/State'] = 0 - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped - self._dbusservice['/Error'] = 0 - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/Runtime'] = 0 - self._dbusservice['/TodayRuntime'] = 0 - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - self._dbusservice['/NextTestRun'] = None - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/ManualStart'] = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._dbusservice['/QuietHours'] = 0 - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - -#### GuiMods - # generator input running state - self._dbusservice.add_path('/GeneratorRunningState', value=None) - # external override active - self._dbusservice.add_path('/ExternalOverride', value=None) - self._dbusservice['/GeneratorRunningState'] = "?" - self._dbusservice['/ExternalOverride'] = False - - def _set_autostart(self, path, value): - if 0 <= value <= 1: - self._settings['autostart'] = int(value) - return True - return False - - def enable(self): - if self._enabled: - return - self.log_info('Enabling auto start/stop and taking control of remote switch') - self._create_service() - self._determineservices() - self._update_remote_switch() - self._enabled = True - - def disable(self): - if not self._enabled: - return - self.log_info('Disabling auto start/stop, releasing control of remote switch') - self._remove_service() - self._enabled = False - - def remove(self): - self.disable() - self.log_info('Removed from start/stop instances') - - def _remove_service(self): - self._dbusservice.__del__() - self._dbusservice = None - - def device_added(self, dbusservicename, instance): - self._determineservices() - - def device_removed(self, dbusservicename, instance): - self._determineservices() - - def get_error(self): - return self._dbusservice['/Error'] - - def set_error(self, errorn): - self._dbusservice['/Error'] = errorn - - def clear_error(self): - self._dbusservice['/Error'] = Errors.NONE - - def dbus_value_changed(self, dbusServiceName, dbusPath, options, changes, deviceInstance): - if self._dbusservice is None: - return - if dbusServiceName != 'com.victronenergy.system': - return - if dbusPath == '/AutoSelectedBatteryMeasurement' and self._settings['batterymeasurement'] == 'default': - self._determineservices() - - if dbusPath == '/VebusService': - self._determineservices() - - def handlechangedsetting(self, setting, oldvalue, newvalue): - if self._dbusservice is None: - return - if self._name not in setting: - # Not our setting - return - - s = self._settings.removeprefix(setting) - - if s == 'batterymeasurement': - self._determineservices() - # Reset retries and valid if service changes - for condition in self._condition_stack: - if self._condition_stack[condition]['monitoring'] == 'battery': - self._condition_stack[condition]['valid'] = True - self._condition_stack[condition]['retries'] = 0 - - if s == 'autostart': - self.log_info('Autostart function %s.' % ('enabled' if newvalue == 1 else 'disabled')) - self._dbusservice['/AutoStartEnabled'] = self._settings['autostart'] - - if self._dbusservice is not None and s == 'testruninterval': - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime( - self._settings['testruninterval']) - - def dbus_name_owner_changed(self, name, oldowner, newowner): - self._determineservices() - - def _seconds_to_text(self, path, value): - m, s = divmod(value, 60) - h, m = divmod(m, 60) - return '%dh, %dm, %ds' % (h, m, s) - - def log_info(self, msg): - logging.info(self._name + ': %s' % msg) - - def tick(self): - if not self._enabled: - return - self._check_remote_status() -#### GuiMods - self._linkToExternalState = self._settings['linkManualStartToExternal'] == 1 - self._processGeneratorRunDetection () - - self._evaluate_startstop_conditions() - self._detect_generator_at_acinput() - - def _evaluate_startstop_conditions(self): - if self.get_error() != Errors.NONE: - # First evaluation after an error, log it - if self._errorstate == 0: - self._errorstate = 1 - self._dbusservice['/State'] = States.ERROR - self.log_info('Error: #%i - %s, stop controlling remote.' % - (self.get_error(), - Errors.get_description(self.get_error()))) - elif self._errorstate == 1: - # Error cleared - self._errorstate = 0 - self.log_info('Error state cleared, taking control of remote switch.') - - # Conditions will be evaluated in this order - conditions = ['soc', 'acload', 'batterycurrent', 'batteryvoltage', 'inverterhightemp', 'inverteroverload', 'stoponac1'] - start = False - startbycondition = None - activecondition = self._dbusservice['/RunningByCondition'] - today = calendar.timegm(datetime.date.today().timetuple()) - self._timer_runnning = False - values = self._get_updated_values() - connection_lost = False - - self._check_quiet_hours() - - # New day, register it - if self._last_counters_check < today and self._dbusservice['/State'] == States.STOPPED: - self._last_counters_check = today - self._update_accumulated_time() - - # Update current and accumulated runtime. -#### GuiMods - self._accumulateRunTime () - -#### GuiMods - # A negative /ManualStartTimer is used by the GUI to signal the generator should start now - # but stop when all auto stop conditions have been met - # so we skip manual start evaluation if this is the case - # and set a flag for use below to ignore auto start conditions - # the generator is actually started by the auto start/stop logic below - if self._dbusservice['/ManualStartTimer'] < 0 and self._dbusservice['/ManualStart'] == 1: - self._dbusservice['/ManualStartTimer'] = 0 - self._dbusservice['/ManualStart'] = 0 - ignoresAutoStartCondition = True - else: - ignoresAutoStartCondition = False - if self._evaluate_manual_start(): - startbycondition = 'manual' - start = True - - # Conditions will only be evaluated if the autostart functionality is enabled - if self._settings['autostart'] == 1: - - if self._evaluate_testrun_condition(): - startbycondition = 'testrun' - start = True - - # Evaluate value conditions - for condition in conditions: -#### GuiMods - start = self._evaluate_condition(self._condition_stack[condition], values[condition], ignoresAutoStartCondition) or start - - startbycondition = condition if start and startbycondition is None else startbycondition - # Connection lost is set to true if the number of retries of one or more enabled conditions - # >= RETRIES_ON_ERROR - if self._condition_stack[condition]['enabled']: - connection_lost = self._condition_stack[condition]['retries'] >= self.RETRIES_ON_ERROR - - if self._condition_stack['stoponac1']['reached'] and startbycondition not in ['manual', 'testrun']: - start = False - if self._dbusservice['/State'] == States.RUNNING and activecondition not in ['manual', 'testrun']: - self.log_info('AC input 1 available, stopping') - - # If none condition is reached check if connection is lost and start/keep running the generator - # depending on '/OnLossCommunication' setting - if not start and connection_lost: - # Start always - if self._settings['onlosscommunication'] == 1: - start = True - startbycondition = 'lossofcommunication' - # Keep running if generator already started - if self._dbusservice['/State'] == States.RUNNING and self._settings['onlosscommunication'] == 2: - start = True - startbycondition = 'lossofcommunication' - - if not start and self._errorstate: - self._stop_generator() - - if self._errorstate: - return - - if start: - self._start_generator(startbycondition) -#### GuiMods - # bypass the minimum run time check if External Override is active - elif (self._dbusservice['/Runtime'] >= self._settings['minimumruntime'] * 60 - or activecondition == 'manual') or self._dbusservice['/ExternalOverride']: - self._stop_generator() - - def _detect_generator_at_acinput(self): - state = self._dbusservice['/State'] - - if state == States.STOPPED: - self._reset_acpower_inverter_input() - return - - if self._settings['nogeneratoratacinalarm'] == 0: - self._reset_acpower_inverter_input() - return - - vebus_service = self._vebusservice if self._vebusservice else '' - activein_state = self._dbusmonitor.get_value( - vebus_service, '/Ac/ActiveIn/Connected') - - # Path not supported, skip evaluation - if activein_state == None: - return - - # Sources 0 = Not available, 1 = Grid, 2 = Generator, 3 = Shore - generator_acsource = self._dbusmonitor.get_value( - SYSTEM_SERVICE, '/Ac/ActiveIn/Source') == 2 - # Not connected = 0, connected = 1 - activein_connected = activein_state == 1 - - if generator_acsource and activein_connected: - if self._acpower_inverter_input['unabletostart']: - self.log_info('Generator detected at inverter AC input, alarm removed') - self._reset_acpower_inverter_input() - elif self._acpower_inverter_input['timeout'] < self.RETRIES_ON_ERROR: - self._acpower_inverter_input['timeout'] += 1 - elif not self._acpower_inverter_input['unabletostart']: - self._acpower_inverter_input['unabletostart'] = True - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 2 - self.log_info('Generator not detected at inverter AC input, triggering alarm') - - def _reset_acpower_inverter_input(self, clear_error=True): - if self._acpower_inverter_input['timeout'] != 0: - self._acpower_inverter_input['timeout'] = 0 - - if self._acpower_inverter_input['unabletostart'] != 0: - self._acpower_inverter_input['unabletostart'] = 0 - - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - - def _reset_condition(self, condition): - condition['reached'] = False - if condition['timed']: - condition['start_timer'] = 0 - condition['stop_timer'] = 0 - - def _check_condition(self, condition, value): - name = condition['name'] - - if self._settings[name + 'enabled'] == 0: - if condition['enabled']: - condition['enabled'] = False - self.log_info('Disabling (%s) condition' % name) - condition['retries'] = 0 - condition['valid'] = True - self._reset_condition(condition) - return False - - elif not condition['enabled']: - condition['enabled'] = True - self.log_info('Enabling (%s) condition' % name) - - if (condition['monitoring'] == 'battery') and (self._settings['batterymeasurement'] == 'nobattery'): - # If no battery monitor is selected reset the condition - self._reset_condition(condition) - return False - - if value is None and condition['valid']: - if condition['retries'] >= self.RETRIES_ON_ERROR: - logging.info('Error getting (%s) value, skipping evaluation till get a valid value' % name) - self._reset_condition(condition) - self._comunnication_lost = True - condition['valid'] = False - else: - condition['retries'] += 1 - if condition['retries'] == 1 or (condition['retries'] % 10) == 0: - self.log_info('Error getting (%s) value, retrying(#%i)' % (name, condition['retries'])) - return False - - elif value is not None and not condition['valid']: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['valid'] = True - condition['retries'] = 0 - - # Reset retries if value is valid - if value is not None and condition['retries'] > 0: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['retries'] = 0 - - return condition['valid'] - -#### GuiMods - def _evaluate_condition(self, condition, value, ignoreStartValue): - name = condition['name'] - setting = ('qh_' if self._dbusservice['/QuietHours'] == 1 else '') + name - startvalue = self._settings[setting + 'start'] if not condition['boolean'] else 1 - stopvalue = self._settings[setting + 'stop'] if not condition['boolean'] else 0 - - # Check if the condition has to be evaluated - if not self._check_condition(condition, value): - # If generator is started by this condition and value is invalid - # wait till RETRIES_ON_ERROR to skip the condition - if condition['reached'] and condition['retries'] <= self.RETRIES_ON_ERROR: - if condition['retries'] > 0: - return True - - return False - - # As this is a generic evaluation method, we need to know how to compare the values - # first check if start value should be greater than stop value and then compare - start_is_greater = startvalue > stopvalue - -#### GuiMods - stop = value <= stopvalue if start_is_greater else value >= stopvalue - # when starting manually and stopping based on auto stop values, - # start if stop condition is not satisfied - if ignoreStartValue: - start = not stop - else: - # When the condition is already reached only the stop value can set it to False - start = condition['reached'] or (value >= startvalue if start_is_greater else value <= startvalue) - - # Timed conditions must start/stop after the condition has been reached for a minimum - # time. - if condition['timed']: - if not condition['reached'] and start: - condition['start_timer'] += time.time() if condition['start_timer'] == 0 else 0 - start = time.time() - condition['start_timer'] >= self._settings[name + 'starttimer'] - condition['stop_timer'] *= int(not start) - self._timer_runnning = True - else: - condition['start_timer'] = 0 - - if condition['reached'] and stop: - condition['stop_timer'] += time.time() if condition['stop_timer'] == 0 else 0 - stop = time.time() - condition['stop_timer'] >= self._settings[name + 'stoptimer'] - condition['stop_timer'] *= int(not stop) - self._timer_runnning = True - else: - condition['stop_timer'] = 0 - - condition['reached'] = start and not stop - return condition['reached'] - - def _evaluate_manual_start(self): - if self._dbusservice['/ManualStart'] == 0: - if self._dbusservice['/RunningByCondition'] == 'manual': - self._dbusservice['/ManualStartTimer'] = 0 - return False - - start = True - # If /ManualStartTimer has a value greater than zero will use it to set a stop timer. - # If no timer is set, the generator will not stop until the user stops it manually. - # Once started by manual start, each evaluation the timer is decreased -#### GuiMods - if self._dbusservice['/ManualStartTimer'] > 0: - self._manualstarttimer += time.time() if self._manualstarttimer == 0 else 0 - self._dbusservice['/ManualStartTimer'] -= int(time.time()) - int(self._manualstarttimer) - self._manualstarttimer = time.time() - start = self._dbusservice['/ManualStartTimer'] > 0 - self._dbusservice['/ManualStart'] = int(start) - # Reset if timer is finished - self._manualstarttimer *= int(start) - self._dbusservice['/ManualStartTimer'] *= int(start) - - return start - - def _evaluate_testrun_condition(self): - if self._settings['testrunenabled'] == 0: - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/NextTestRun'] = None - return False - - today = datetime.date.today() - yesterday = today - datetime.timedelta(days=1) # Should deal well with DST - now = time.time() - runtillbatteryfull = self._settings['testruntillbatteryfull'] == 1 - soc = self._get_updated_values()['soc'] - batteryisfull = runtillbatteryfull and soc == 100 - duration = 60 if runtillbatteryfull else self._settings['testrunruntime'] - - try: - startdate = datetime.date.fromtimestamp(self._settings['testrunstartdate']) - _starttime = time.mktime(yesterday.timetuple()) + self._settings['testrunstarttimer'] - - # today might in fact still be yesterday, if this test run started - # before midnight and finishes after. If `now` still falls in - # yesterday's window, then by the temporal anthropic principle, - # which I just made up but loosely states that time must have - # these properties for observers to exist, it must be yesterday - # because we are here to observe it. - if _starttime <= now <= _starttime + duration: - today = yesterday - starttime = _starttime - else: - starttime = time.mktime(today.timetuple()) + self._settings['testrunstarttimer'] - except ValueError: - logging.debug('Invalid dates, skipping testrun') - return False - - # If start date is in the future set as NextTestRun and stop evaluating - if startdate > today: - self._dbusservice['/NextTestRun'] = time.mktime(startdate.timetuple()) - return False - - start = False - # If the accumulated runtime during the tes trun interval is greater than '/TestRunIntervalRuntime' - # the tes trun must be skipped - needed = (self._settings['testrunskipruntime'] > self._dbusservice['/TestRunIntervalRuntime'] - or self._settings['testrunskipruntime'] == 0) - self._dbusservice['/SkipTestRun'] = int(not needed) - - interval = self._settings['testruninterval'] - stoptime = starttime + duration - elapseddays = (today - startdate).days - mod = elapseddays % interval - - start = not bool(mod) and starttime <= now <= stoptime - - if runtillbatteryfull: - if soc is not None: - self._testrun_soc_retries = 0 - start = (start or self._dbusservice['/RunningByCondition'] == 'testrun') and not batteryisfull - elif self._dbusservice['/RunningByCondition'] == 'testrun': - if self._testrun_soc_retries < self.RETRIES_ON_ERROR: - self._testrun_soc_retries += 1 - start = True - if (self._testrun_soc_retries % 10) == 0: - self.log_info('Test run failed to get SOC value, retrying(#%i)' % self._testrun_soc_retries) - else: - self.log_info('Failed to get SOC after %i retries, terminating test run condition' % self._testrun_soc_retries) - start = False - else: - start = False - - if not bool(mod) and (now <= stoptime): - self._dbusservice['/NextTestRun'] = starttime - else: - self._dbusservice['/NextTestRun'] = (time.mktime((today + datetime.timedelta(days=interval - mod)).timetuple()) + - self._settings['testrunstarttimer']) - return start and needed - - def _check_quiet_hours(self): - active = False - if self._settings['quiethoursenabled'] == 1: - # Seconds after today 00:00 - timeinseconds = time.time() - time.mktime(datetime.date.today().timetuple()) - quiethoursstart = self._settings['quiethoursstarttime'] - quiethoursend = self._settings['quiethoursendtime'] - - # Check if the current time is between the start time and end time - if quiethoursstart < quiethoursend: - active = quiethoursstart <= timeinseconds and timeinseconds < quiethoursend - else: # End time is lower than start time, example Start: 21:00, end: 08:00 - active = not (quiethoursend < timeinseconds and timeinseconds < quiethoursstart) - - if self._dbusservice['/QuietHours'] == 0 and active: - self.log_info('Entering to quiet mode') - - elif self._dbusservice['/QuietHours'] == 1 and not active: - self.log_info('Leaving quiet mode') - - self._dbusservice['/QuietHours'] = int(active) - - return active - - def _update_accumulated_time(self): - seconds = self._dbusservice['/Runtime'] - accumulated = seconds - self._last_runtime_update - - self._settings['accumulatedtotal'] = int(self._settings['accumulatedtotal']) + accumulated -#### GuiMods - self._settings['timeSinceService'] = int(self._settings['timeSinceService']) + accumulated - # Using calendar to get timestamp in UTC, not local time - today_date = str(calendar.timegm(datetime.date.today().timetuple())) - - # If something goes wrong getting the json string create a new one - try: - accumulated_days = json.loads(self._settings['accumulateddaily']) - except ValueError: - accumulated_days = {today_date: 0} - - if (today_date in accumulated_days): - accumulated_days[today_date] += accumulated - else: - accumulated_days[today_date] = accumulated - - self._last_runtime_update = seconds - - # Keep the historical with a maximum of HISTORY_DAYS - while len(accumulated_days) > HISTORY_DAYS: - accumulated_days.pop(min(accumulated_days.keys()), None) - - # Upadate settings - self._settings['accumulateddaily'] = json.dumps(accumulated_days, sort_keys=True) - self._dbusservice['/TodayRuntime'] = self._interval_runtime(0) - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - - def _interval_runtime(self, days): - summ = 0 - try: - daily_record = json.loads(self._settings['accumulateddaily']) - except ValueError: - return 0 - - for i in range(days + 1): - previous_day = calendar.timegm((datetime.date.today() - datetime.timedelta(days=i)).timetuple()) - if str(previous_day) in daily_record.keys(): - summ += daily_record[str(previous_day)] if str(previous_day) in daily_record.keys() else 0 - - return summ - - def _get_battery(self): - battery = {} - if self._settings['batterymeasurement'] == 'default': - battery['service'] = SYSTEM_SERVICE - battery['prefix'] = BATTERY_PREFIX - else: - battery['service'] = self._battery_service if self._battery_service else '' - battery['prefix'] = self._battery_prefix if self._battery_prefix else '' - - return battery - - def _get_updated_values(self): - battery = self._get_battery() - vebus_service = self._vebusservice if self._vebusservice else '' - loadOnAcOut = [] - totalConsumption = [] - inverterHighTemp = [] - inverterOverload = [] - - values = { - 'batteryvoltage': self._dbusmonitor.get_value(battery['service'], battery['prefix'] + '/Voltage'), - 'batterycurrent': self._dbusmonitor.get_value(battery['service'], battery['prefix'] + '/Current'), - # Soc from the device doesn't have the '/Dc/0' prefix like the current and voltage do, but it does - # have the same prefix on systemcalc - 'soc': self._dbusmonitor.get_value(battery['service'], (battery['prefix'] if battery['prefix'] == BATTERY_PREFIX else '') + '/Soc'), - 'inverterhightemp': self._dbusmonitor.get_value(vebus_service, '/Alarms/HighTemperature'), - 'inverteroverload': self._dbusmonitor.get_value(vebus_service, '/Alarms/Overload') - } - - for phase in ['L1', 'L2', 'L3']: - # Get the values directly from the inverter, systemcalc doesn't provide raw inverted power - loadOnAcOut.append(self._dbusmonitor.get_value(vebus_service, ('/Ac/Out/%s/P' % phase))) - - # Calculate total consumption, '/Ac/Consumption/%s/Power' is deprecated - c_i = self._dbusmonitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnInput/%s/Power' % phase)) - c_o = self._dbusmonitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnOutput/%s/Power' % phase)) - totalConsumption.append(sum(filter(None, (c_i, c_o)))) - - # Inverter alarms must be fetched directly from the inverter service - inverterHighTemp.append(self._dbusmonitor.get_value(vebus_service, ('/Alarms/%s/HighTemperature' % phase))) - inverterOverload.append(self._dbusmonitor.get_value(vebus_service, ('/Alarms/%s/Overload' % phase))) - - # Toltal consumption - if self._settings['acloadmeasuerment'] == 0: - values['acload'] = sum(filter(None, totalConsumption)) - - # Load on inverter AC out - if self._settings['acloadmeasuerment'] == 1: - values['acload'] = sum(filter(None, loadOnAcOut)) - - # Highest phase load - if self._settings['acloadmeasuerment'] == 2: - values['acload'] = safe_max(loadOnAcOut) - - # AC input 1 - activein = self._dbusmonitor.get_value(vebus_service, '/Ac/ActiveIn/ActiveInput') - # Active input is connected - connected = self._dbusmonitor.get_value(vebus_service, '/Ac/ActiveIn/Connected') - if None not in (activein, connected): - values['stoponac1'] = activein == 0 and connected == 1 - else: - values['stoponac1'] = None - - # Invalidate if vebus is not available - if loadOnAcOut[0] == None: - values['acload'] = None - - if values['batterycurrent']: - values['batterycurrent'] *= -1 - - # When multi is connected to CAN-bus, alarms are published to - # /Alarms/Overload... but when connected to vebus alarms are - # splitted in three phases and published to /Alarms/LX/Overload... - if values['inverteroverload'] == None: - values['inverteroverload'] = safe_max(inverterOverload) - - if values['inverterhightemp'] == None: - values['inverterhightemp'] = safe_max(inverterHighTemp) - - return values - - def _determineservices(self): - # batterymeasurement is either 'default' or 'com_victronenergy_battery_288/Dc/0'. - # In case it is set to default, we use the AutoSelected battery - # measurement, given by SystemCalc. - batterymeasurement = None - newbatteryservice = None - batteryprefix = '' - selectedbattery = self._settings['batterymeasurement'] - vebusservice = None - - if selectedbattery == 'default': - batterymeasurement = 'default' - elif len(selectedbattery.split('/', 1)) == 2: # Only very basic sanity checking.. - batterymeasurement = self._settings['batterymeasurement'] - elif selectedbattery == 'nobattery': - batterymeasurement = None - else: - # Exception: unexpected value for batterymeasurement - pass - - if batterymeasurement and batterymeasurement != 'default': - batteryprefix = '/' + batterymeasurement.split('/', 1)[1] - - # Get the current battery servicename - if self._battery_service: - oldservice = self._battery_service - else: - oldservice = None - - if batterymeasurement != 'default': - battery_instance = int(batterymeasurement.split('_', 3)[3].split('/')[0]) - service_type = None - - if 'vebus' in batterymeasurement: - service_type = 'vebus' - elif 'battery' in batterymeasurement: - service_type = 'battery' - - newbatteryservice = self._get_servicename_by_instance(battery_instance, service_type) - elif batterymeasurement == 'default': - newbatteryservice = 'default' - - if newbatteryservice and newbatteryservice != oldservice: - if selectedbattery == 'default': - self.log_info('Getting battery values from systemcalc.') - if selectedbattery == 'nobattery': - self.log_info('Battery monitoring disabled! Stop evaluating related conditions') - self._battery_service = None - self._battery_prefix = None - self.log_info('Battery service we need (%s) found! Using it for generator start/stop' % batterymeasurement) - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - elif not newbatteryservice and newbatteryservice != oldservice: - self.log_info('Error getting battery service!') - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - - # Get the default VE.Bus service - vebusservice = self._dbusmonitor.get_value('com.victronenergy.system', '/VebusService') - if vebusservice: - if self._vebusservice != vebusservice: - self._vebusservice = vebusservice - self.log_info('Vebus service (%s) found! Using it for generator start/stop' % vebusservice) - else: - if self._vebusservice is not None: - self.log_info('Vebus service (%s) dissapeared! Stop evaluating related conditions' % self._vebusservice) - else: - self.log_info('Error getting Vebus service!') - self._vebusservice = None - - def _get_servicename_by_instance(self, instance, service_type=None): - sv = None - services = self._dbusmonitor.get_service_list() - - for service in services: - if service_type and service_type not in service: - continue - - if services[service] == instance: - sv = service - break - - return sv - - def _get_monotonic_seconds(self): - return monotonic_time.monotonic_time().to_seconds_double() - - def _start_generator(self, condition): - state = self._dbusservice['/State'] - remote_state = self._get_remote_switch_state() - - # This function will start the generator in the case generator not - # already running. When differs, the RunningByCondition is updated - if state == States.STOPPED or remote_state != state: - self._dbusservice['/State'] = States.RUNNING - self._update_remote_switch() - self._starttime = monotonic_time.monotonic_time().to_seconds_double() - self.log_info('Starting generator by %s condition' % condition) - elif self._dbusservice['/RunningByCondition'] != condition: - self.log_info('Generator previously running by %s condition is now running by %s condition' - % (self._dbusservice['/RunningByCondition'], condition)) - - self._dbusservice['/RunningByCondition'] = condition - self._dbusservice['/RunningByConditionCode'] = RunningConditions.lookup(condition) - - def _stop_generator(self): - state = self._dbusservice['/State'] - remote_state = self._get_remote_switch_state() - - if state == 1 or remote_state != state: - self._dbusservice['/State'] = States.STOPPED - self._update_remote_switch() - self.log_info('Stopping generator that was running by %s condition' % - str(self._dbusservice['/RunningByCondition'])) - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped -#### GuiMods - self._accumulateRunTime () - self._starttime = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._manualstarttimer = 0 - self._last_runtime_update = 0 - - def _update_remote_switch(self): - self._set_remote_switch_state(dbus.Int32(self._dbusservice['/State'], variant_level=1)) - - def _get_remote_switch_state(self): - raise Exception('This function should be overridden') - - def _set_remote_switch_state(self, value): - raise Exception('This function should be overridden') - - # Check the remote status, for example errors - def _check_remote_status(self): - raise Exception('This function should be overridden') - - def _remote_setup(self): - raise Exception('This function should be overridden') - - def _create_dbus_monitor(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_settings(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_dbus_service(self): - return create_dbus_service(self._instance) - -#### GuiMods - -# this function connects the generator digital input (if any) -# OR the generator AC input detection -# to the generator /ManualStart and updates dbus paths used by the GUI -# -# if the generator digital input changes from stopped to running -# AND no run conditions are active, a manual start is innitiated -# -# if the generator digital input changes from running to stopped -# AND a manual start is active, a manual stop is innitiated -# -# /GeneratorRunningState provides the input running state from the digital input to the GUI -# R = running -# S = stopped -# ? = unknown (no digital input found) -# -# /ExternalOverride is used by the GUI to alert the user when there is a conflict -# between the generator running state and the state Venus -# /ExternalOverride is True if /GeneratorRunningState is S -# AND the /RunningCondition is not stopped (which includes a manual run) -# activation is delayed 5 seconds to allow transitions to settle -# -# we must first find the geneator digital input, if it exists at all -# we serche all dBus services looking for a digital input with type generator (9) -# the search only occurs every 10 seconds -# - - def _processGeneratorRunDetection (self): - TheBus = dbus.SystemBus() - generatorState = self._dbusservice['/State'] - try: - # current input service is no longer valid - # search for a new one only every 10 seconds to avoid unnecessary processing - if (self._digitalInputTypeObject == None or self._digitalInputTypeObject.GetValue() != 9) and self._searchDelay > 10: - newInputService = "" - for service in TheBus.list_names(): - # found a digital input servic, now check the type - if service.startswith ("com.victronenergy.digitalinput"): - self._digitalInputTypeObject = TheBus.get_object (service, '/Type') - # found it! - if self._digitalInputTypeObject.GetValue() == 9: - newInputService = service - break - - # found new service - get objects for use later - if newInputService != "": - self.log_info ("Found generator digital input service at %s" % newInputService) - self._generatorInputStateObject = TheBus.get_object(newInputService, '/State') - else: - if self._generatorInputStateObject != None: - self.log_info ("Generator digital input service NOT found") - self._generatorInputStateObject = None - self._digitalInputTypeObject = None - self._searchDelay = 0 # start delay timer - - # if serch delay timer is active, increment it now - if self._searchDelay <= 10: - self._searchDelay += 1 - - - # collect generator input states - inputState = '?' - # if generator digital input is present, use that - if self._generatorInputStateObject != None: - inputState = self._generatorInputStateObject.GetValue () - if inputState == 10: - inputState = 'R' - elif inputState == 11: - inputState = 'S' - - # update /GeneratorRunningState - if inputState != self._lastState: - self._dbusservice['/GeneratorRunningState'] = inputState - - # forward input state changes to /ManualStart - if self._linkToExternalState: - if inputState == "R" and generatorState == States.STOPPED: - self.log_info ("generator was started externally - syncing ManualStart state") - self._dbusservice['/ManualStart'] = 1 - elif inputState == "S" and self._dbusservice['/ManualStart'] == 1 \ - and generatorState in (States.RUNNING, States.WARMUP, States.COOLDOWN): - self.log_info ("generator was stopped externally - syncing ManualStart state") - self._dbusservice['/ManualStart'] = 0 - - # update /ExternalOverride - if inputState == "S" and self._linkToExternalState and generatorState == States.RUNNING: - if self._externalOverrideDelay > 5: - self._externalOverride = True - else: - self._externalOverrideDelay += 1 - else: - self._externalOverride = False - self._externalOverrideDelay = 0 - - if self._externalOverride != self._lastExternalOverride: - self._dbusservice['/ExternalOverride'] = self._externalOverride - self._lastExternalOverride = self._externalOverride - - except dbus.DBusException: - self.log_info ("dbus exception - generator digital input no longer valid") - self._generatorInputStateObject = None - self._digitalInputTypeObject = None - inputState = 0 - - self._lastState = inputState - - -# -# control the accumulaiton of run time based on generator input Running state -# if the internal state is RUNNING run time is accumulated in self._accumulatedRunTime -# run time is accumulated if the generator's running state is known to be running or -# if the generator running state can't be determined -# the accumulated time dBus parameter and daily and total time accumulators are updated -# only once everh 60 seconds to minimize processor load -# if the internal state is STOPPED, one last dBus, daily and total time updates are done -# then the current time accumulator is cleared - - def _accumulateRunTime (self): - - mtime = monotonic_time.monotonic_time().to_seconds_double() - - # grab running state from dBus once, use it many timed below - - if self._dbusservice['/State'] == States.RUNNING: - internalRun = True - else: - internalRun = False - - # if internal state is running, accumulate time if generator is running - if internalRun: - accumuateTime = True - # start new accumulation if not done prevously - if self._last_accumulate_time == 0: - self._last_accumulate_time = mtime - - # if link to external state is enabled, don't accumulate time if running state is stopped (accumulate if R or ?) - if self._linkToExternalState: - try: - if self._dbusservice['/GeneratorRunningState'] == "S": - accumuateTime = False - - # if no Forwarder service, allow accumulation - except dbus.DBusException: - self.log_info ("dBus exception in startstop.py") - - # internal state STOPPED so don't add new time to the accumulation - # but there may be time already accumulated that needs to be added to daily and total accumulations - else: - accumuateTime = False - - # accumulate run time if we passed all the tests above - if accumuateTime: - self._accumulatedRunTime += mtime - self._last_accumulate_time - self._last_accumulate_time = mtime - - # dbus and settings updates trigger time-intensive processing so only do this once every 60 seconds - doUpdate = False - if internalRun: - if mtime - self._last_update_mtime >= 60: - doUpdate = True - self._last_update_mtime = mtime - # it is also done one last time when state is no longer RUNNING - elif self._last_update_mtime != 0: - doUpdate = True - - if doUpdate: - self._update_accumulated_time() - - # stopped - clear the current time accumulator - if internalRun == False: - self._last_update_mtime = 0 - self._accumulatedRunTime = 0 - self._last_accumulate_time = 0 - - self._dbusservice['/Runtime'] = int(self._accumulatedRunTime) diff --git a/FileSets/v2.94/startstop.py.orig b/FileSets/v2.94/startstop.py.orig deleted file mode 100644 index 8fb9cc54..00000000 --- a/FileSets/v2.94/startstop.py.orig +++ /dev/null @@ -1,956 +0,0 @@ -#!/usr/bin/python -u -# -*- coding: utf-8 -*- - -# Function -# dbus_generator monitors the dbus for batteries (com.victronenergy.battery.*) and -# vebus com.victronenergy.vebus.* -# Battery and vebus monitors can be configured through the gui. -# It then monitors SOC, AC loads, battery current and battery voltage,to auto start/stop the generator based -# on the configuration settings. Generator can be started manually or periodically setting a tes trun period. -# Time zones function allows to use different values for the conditions along the day depending on time - -import dbus -import datetime -import calendar -import time -import sys -import json -import os -import logging -from os import environ -import monotonic_time -from gen_utils import SettingsPrefix, Errors, States, enum -from gen_utils import create_dbus_service -# Victron packages -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) -from ve_utils import exit_on_error -from settingsdevice import SettingsDevice - -RunningConditions = enum( - Stopped = 0, - Manual = 1, - TestRun = 2, - LossOfCommunication = 3, - Soc = 4, - Acload = 5, - BatteryCurrent = 6, - BatteryVoltage = 7, - InverterHighTemp = 8, - InverterOverload = 9, - StopOnAc1 = 10) - -SYSTEM_SERVICE = 'com.victronenergy.system' -BATTERY_PREFIX = '/Dc/Battery' -HISTORY_DAYS = 30 - -def safe_max(args): - try: - return max(x for x in args if x is not None) - except ValueError: - return None - -class StartStop(object): - _driver = None - def __init__(self, instance): - self._dbusservice = None - self._settings = None - self._dbusmonitor = None - self._remoteservice = None - self._name = None - self._enabled = False - self._instance = instance - - # One second per retry - self.RETRIES_ON_ERROR = 300 - self._testrun_soc_retries = 0 - self._last_counters_check = 0 - - self._starttime = 0 - self._manualstarttimer = 0 - self._last_runtime_update = 0 - self._timer_runnning = 0 - - # Manual battery service selection is deprecated in favour - # of getting the values directly from systemcalc, we keep - # manual selected services handling for compatibility reasons. - self._vebusservice = None - self._errorstate = 0 - self._battery_service = None - self._battery_prefix = None - - self._acpower_inverter_input = { - 'timeout': 0, - 'unabletostart': False - } - - self._condition_stack = { - 'batteryvoltage': { - 'name': 'batteryvoltage', - 'reached': False, - 'boolean': False, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'battery' - }, - 'batterycurrent': { - 'name': 'batterycurrent', - 'reached': False, - 'boolean': False, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'battery' - }, - 'acload': { - 'name': 'acload', - 'reached': False, - 'boolean': False, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - }, - 'inverterhightemp': { - 'name': 'inverterhightemp', - 'reached': False, - 'boolean': True, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - }, - 'inverteroverload': { - 'name': 'inverteroverload', - 'reached': False, - 'boolean': True, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - }, - 'soc': { - 'name': 'soc', - 'reached': False, - 'boolean': False, - 'timed': False, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'battery' - }, - 'stoponac1': { - 'name': 'stoponac1', - 'reached': False, - 'boolean': True, - 'timed': False, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - } - } - - def set_sources(self, dbusmonitor, settings, name, remoteservice): - self._settings = SettingsPrefix(settings, name) - self._dbusmonitor = dbusmonitor - self._remoteservice = remoteservice - self._name = name - - self.log_info('Start/stop instance created for %s.' % self._remoteservice) - self._remote_setup() - - def _create_service(self): - self._dbusservice = self._create_dbus_service() - - # The driver used for this start/stop service - self._dbusservice.add_path('/Type', value=self._driver) - # State: None = invalid, 0 = stopped, 1 = running - self._dbusservice.add_path('/State', value=None) - # RunningByConditionCode: Numeric Companion to /RunningByCondition below, but - # also encompassing a Stopped state. - self._dbusservice.add_path('/RunningByConditionCode', value=None) - # Error - self._dbusservice.add_path('/Error', value=None, gettextcallback=lambda p, v: Errors.get_description(v)) - # Condition that made the generator start - self._dbusservice.add_path('/RunningByCondition', value=None) - # Runtime - self._dbusservice.add_path('/Runtime', value=None, gettextcallback=self._seconds_to_text) - # Today runtime - self._dbusservice.add_path('/TodayRuntime', value=None, gettextcallback=self._seconds_to_text) - # Test run runtime - self._dbusservice.add_path('/TestRunIntervalRuntime', value=None , gettextcallback=self._seconds_to_text) - # Next test run date, values is 0 for test run disabled - self._dbusservice.add_path('/NextTestRun', value=None, gettextcallback=lambda p, v: datetime.datetime.fromtimestamp(v).strftime('%c')) - # Next test run is needed 1, not needed 0 - self._dbusservice.add_path('/SkipTestRun', value=None) - # Manual start - self._dbusservice.add_path('/ManualStart', value=None, writeable=True) - # Manual start timer - self._dbusservice.add_path('/ManualStartTimer', value=None, writeable=True) - # Silent mode active - self._dbusservice.add_path('/QuietHours', value=None) - # Alarms - self._dbusservice.add_path('/Alarms/NoGeneratorAtAcIn', value=None) - # Autostart - self._dbusservice.add_path('/AutoStartEnabled', value=None, writeable=True, onchangecallback=self._set_autostart) - - # We need to set the values after creating the paths to trigger the 'onValueChanged' event for the gui - # otherwise the gui will report the paths as invalid if we remove and recreate the paths without - # restarting the dbusservice. - self._dbusservice['/State'] = 0 - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped - self._dbusservice['/Error'] = 0 - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/Runtime'] = 0 - self._dbusservice['/TodayRuntime'] = 0 - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - self._dbusservice['/NextTestRun'] = None - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/ManualStart'] = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._dbusservice['/QuietHours'] = 0 - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - self._dbusservice['/AutoStartEnabled'] = self._settings['autostart'] - - def _set_autostart(self, path, value): - if 0 <= value <= 1: - self._settings['autostart'] = int(value) - return True - return False - - def enable(self): - if self._enabled: - return - self.log_info('Enabling auto start/stop and taking control of remote switch') - self._create_service() - self._determineservices() - self._update_remote_switch() - self._enabled = True - - def disable(self): - if not self._enabled: - return - self.log_info('Disabling auto start/stop, releasing control of remote switch') - self._remove_service() - self._enabled = False - - def remove(self): - self.disable() - self.log_info('Removed from start/stop instances') - - def _remove_service(self): - self._dbusservice.__del__() - self._dbusservice = None - - def device_added(self, dbusservicename, instance): - self._determineservices() - - def device_removed(self, dbusservicename, instance): - self._determineservices() - - def get_error(self): - return self._dbusservice['/Error'] - - def set_error(self, errorn): - self._dbusservice['/Error'] = errorn - - def clear_error(self): - self._dbusservice['/Error'] = Errors.NONE - - def dbus_value_changed(self, dbusServiceName, dbusPath, options, changes, deviceInstance): - if self._dbusservice is None: - return - if dbusServiceName != 'com.victronenergy.system': - return - if dbusPath == '/AutoSelectedBatteryMeasurement' and self._settings['batterymeasurement'] == 'default': - self._determineservices() - - if dbusPath == '/VebusService': - self._determineservices() - - def handlechangedsetting(self, setting, oldvalue, newvalue): - if self._dbusservice is None: - return - if self._name not in setting: - # Not our setting - return - - s = self._settings.removeprefix(setting) - - if s == 'batterymeasurement': - self._determineservices() - # Reset retries and valid if service changes - for condition in self._condition_stack: - if self._condition_stack[condition]['monitoring'] == 'battery': - self._condition_stack[condition]['valid'] = True - self._condition_stack[condition]['retries'] = 0 - - if s == 'autostart': - self.log_info('Autostart function %s.' % ('enabled' if newvalue == 1 else 'disabled')) - self._dbusservice['/AutoStartEnabled'] = self._settings['autostart'] - - if self._dbusservice is not None and s == 'testruninterval': - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime( - self._settings['testruninterval']) - - def dbus_name_owner_changed(self, name, oldowner, newowner): - self._determineservices() - - def _seconds_to_text(self, path, value): - m, s = divmod(value, 60) - h, m = divmod(m, 60) - return '%dh, %dm, %ds' % (h, m, s) - - def log_info(self, msg): - logging.info(self._name + ': %s' % msg) - - def tick(self): - if not self._enabled: - return - self._check_remote_status() - self._evaluate_startstop_conditions() - self._detect_generator_at_acinput() - - def _evaluate_startstop_conditions(self): - if self.get_error() != Errors.NONE: - # First evaluation after an error, log it - if self._errorstate == 0: - self._errorstate = 1 - self._dbusservice['/State'] = States.ERROR - self.log_info('Error: #%i - %s, stop controlling remote.' % - (self.get_error(), - Errors.get_description(self.get_error()))) - elif self._errorstate == 1: - # Error cleared - self._errorstate = 0 - self.log_info('Error state cleared, taking control of remote switch.') - - # Conditions will be evaluated in this order - conditions = ['soc', 'acload', 'batterycurrent', 'batteryvoltage', 'inverterhightemp', 'inverteroverload', 'stoponac1'] - start = False - startbycondition = None - activecondition = self._dbusservice['/RunningByCondition'] - today = calendar.timegm(datetime.date.today().timetuple()) - self._timer_runnning = False - values = self._get_updated_values() - connection_lost = False - - self._check_quiet_hours() - - # New day, register it - if self._last_counters_check < today and self._dbusservice['/State'] == States.STOPPED: - self._last_counters_check = today - self._update_accumulated_time() - - # Update current and accumulated runtime. - # By performance reasons, accumulated runtime is only updated - # once per 60s. When the generator stops is also updated. - if self._dbusservice['/State'] == States.RUNNING: - mtime = monotonic_time.monotonic_time().to_seconds_double() - if (mtime - self._starttime) - self._last_runtime_update >= 60: - self._dbusservice['/Runtime'] = int(mtime - self._starttime) - self._update_accumulated_time() - elif self._last_runtime_update == 0: - self._dbusservice['/Runtime'] = int(mtime - self._starttime) - - - if self._evaluate_manual_start(): - startbycondition = 'manual' - start = True - - # Conditions will only be evaluated if the autostart functionality is enabled - if self._settings['autostart'] == 1: - - if self._evaluate_testrun_condition(): - startbycondition = 'testrun' - start = True - - # Evaluate value conditions - for condition in conditions: - start = self._evaluate_condition(self._condition_stack[condition], values[condition]) or start - startbycondition = condition if start and startbycondition is None else startbycondition - # Connection lost is set to true if the number of retries of one or more enabled conditions - # >= RETRIES_ON_ERROR - if self._condition_stack[condition]['enabled']: - connection_lost = self._condition_stack[condition]['retries'] >= self.RETRIES_ON_ERROR - - if self._condition_stack['stoponac1']['reached'] and startbycondition not in ['manual', 'testrun']: - start = False - if self._dbusservice['/State'] == States.RUNNING and activecondition not in ['manual', 'testrun']: - self.log_info('AC input 1 available, stopping') - - # If none condition is reached check if connection is lost and start/keep running the generator - # depending on '/OnLossCommunication' setting - if not start and connection_lost: - # Start always - if self._settings['onlosscommunication'] == 1: - start = True - startbycondition = 'lossofcommunication' - # Keep running if generator already started - if self._dbusservice['/State'] == States.RUNNING and self._settings['onlosscommunication'] == 2: - start = True - startbycondition = 'lossofcommunication' - - if not start and self._errorstate: - self._stop_generator() - - if self._errorstate: - return - - if start: - self._start_generator(startbycondition) - elif (self._dbusservice['/Runtime'] >= self._settings['minimumruntime'] * 60 - or activecondition == 'manual'): - self._stop_generator() - - def _detect_generator_at_acinput(self): - state = self._dbusservice['/State'] - - if state == States.STOPPED: - self._reset_acpower_inverter_input() - return - - if self._settings['nogeneratoratacinalarm'] == 0: - self._reset_acpower_inverter_input() - return - - vebus_service = self._vebusservice if self._vebusservice else '' - activein_state = self._dbusmonitor.get_value( - vebus_service, '/Ac/ActiveIn/Connected') - - # Path not supported, skip evaluation - if activein_state == None: - return - - # Sources 0 = Not available, 1 = Grid, 2 = Generator, 3 = Shore - generator_acsource = self._dbusmonitor.get_value( - SYSTEM_SERVICE, '/Ac/ActiveIn/Source') == 2 - # Not connected = 0, connected = 1 - activein_connected = activein_state == 1 - - if generator_acsource and activein_connected: - if self._acpower_inverter_input['unabletostart']: - self.log_info('Generator detected at inverter AC input, alarm removed') - self._reset_acpower_inverter_input() - elif self._acpower_inverter_input['timeout'] < self.RETRIES_ON_ERROR: - self._acpower_inverter_input['timeout'] += 1 - elif not self._acpower_inverter_input['unabletostart']: - self._acpower_inverter_input['unabletostart'] = True - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 2 - self.log_info('Generator not detected at inverter AC input, triggering alarm') - - def _reset_acpower_inverter_input(self, clear_error=True): - if self._acpower_inverter_input['timeout'] != 0: - self._acpower_inverter_input['timeout'] = 0 - - if self._acpower_inverter_input['unabletostart'] != 0: - self._acpower_inverter_input['unabletostart'] = 0 - - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - - def _reset_condition(self, condition): - condition['reached'] = False - if condition['timed']: - condition['start_timer'] = 0 - condition['stop_timer'] = 0 - - def _check_condition(self, condition, value): - name = condition['name'] - - if self._settings[name + 'enabled'] == 0: - if condition['enabled']: - condition['enabled'] = False - self.log_info('Disabling (%s) condition' % name) - condition['retries'] = 0 - condition['valid'] = True - self._reset_condition(condition) - return False - - elif not condition['enabled']: - condition['enabled'] = True - self.log_info('Enabling (%s) condition' % name) - - if (condition['monitoring'] == 'battery') and (self._settings['batterymeasurement'] == 'nobattery'): - # If no battery monitor is selected reset the condition - self._reset_condition(condition) - return False - - if value is None and condition['valid']: - if condition['retries'] >= self.RETRIES_ON_ERROR: - logging.info('Error getting (%s) value, skipping evaluation till get a valid value' % name) - self._reset_condition(condition) - self._comunnication_lost = True - condition['valid'] = False - else: - condition['retries'] += 1 - if condition['retries'] == 1 or (condition['retries'] % 10) == 0: - self.log_info('Error getting (%s) value, retrying(#%i)' % (name, condition['retries'])) - return False - - elif value is not None and not condition['valid']: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['valid'] = True - condition['retries'] = 0 - - # Reset retries if value is valid - if value is not None and condition['retries'] > 0: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['retries'] = 0 - - return condition['valid'] - - def _evaluate_condition(self, condition, value): - name = condition['name'] - setting = ('qh_' if self._dbusservice['/QuietHours'] == 1 else '') + name - startvalue = self._settings[setting + 'start'] if not condition['boolean'] else 1 - stopvalue = self._settings[setting + 'stop'] if not condition['boolean'] else 0 - - # Check if the condition has to be evaluated - if not self._check_condition(condition, value): - # If generator is started by this condition and value is invalid - # wait till RETRIES_ON_ERROR to skip the condition - if condition['reached'] and condition['retries'] <= self.RETRIES_ON_ERROR: - if condition['retries'] > 0: - return True - - return False - - # As this is a generic evaluation method, we need to know how to compare the values - # first check if start value should be greater than stop value and then compare - start_is_greater = startvalue > stopvalue - - # When the condition is already reached only the stop value can set it to False - start = condition['reached'] or (value >= startvalue if start_is_greater else value <= startvalue) - stop = value <= stopvalue if start_is_greater else value >= stopvalue - - # Timed conditions must start/stop after the condition has been reached for a minimum - # time. - if condition['timed']: - if not condition['reached'] and start: - condition['start_timer'] += time.time() if condition['start_timer'] == 0 else 0 - start = time.time() - condition['start_timer'] >= self._settings[name + 'starttimer'] - condition['stop_timer'] *= int(not start) - self._timer_runnning = True - else: - condition['start_timer'] = 0 - - if condition['reached'] and stop: - condition['stop_timer'] += time.time() if condition['stop_timer'] == 0 else 0 - stop = time.time() - condition['stop_timer'] >= self._settings[name + 'stoptimer'] - condition['stop_timer'] *= int(not stop) - self._timer_runnning = True - else: - condition['stop_timer'] = 0 - - condition['reached'] = start and not stop - return condition['reached'] - - def _evaluate_manual_start(self): - if self._dbusservice['/ManualStart'] == 0: - if self._dbusservice['/RunningByCondition'] == 'manual': - self._dbusservice['/ManualStartTimer'] = 0 - return False - - start = True - # If /ManualStartTimer has a value greater than zero will use it to set a stop timer. - # If no timer is set, the generator will not stop until the user stops it manually. - # Once started by manual start, each evaluation the timer is decreased - if self._dbusservice['/ManualStartTimer'] != 0: - self._manualstarttimer += time.time() if self._manualstarttimer == 0 else 0 - self._dbusservice['/ManualStartTimer'] -= int(time.time()) - int(self._manualstarttimer) - self._manualstarttimer = time.time() - start = self._dbusservice['/ManualStartTimer'] > 0 - self._dbusservice['/ManualStart'] = int(start) - # Reset if timer is finished - self._manualstarttimer *= int(start) - self._dbusservice['/ManualStartTimer'] *= int(start) - - return start - - def _evaluate_testrun_condition(self): - if self._settings['testrunenabled'] == 0: - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/NextTestRun'] = None - return False - - today = datetime.date.today() - yesterday = today - datetime.timedelta(days=1) # Should deal well with DST - now = time.time() - runtillbatteryfull = self._settings['testruntillbatteryfull'] == 1 - soc = self._get_updated_values()['soc'] - batteryisfull = runtillbatteryfull and soc == 100 - duration = 60 if runtillbatteryfull else self._settings['testrunruntime'] - - try: - startdate = datetime.date.fromtimestamp(self._settings['testrunstartdate']) - _starttime = time.mktime(yesterday.timetuple()) + self._settings['testrunstarttimer'] - - # today might in fact still be yesterday, if this test run started - # before midnight and finishes after. If `now` still falls in - # yesterday's window, then by the temporal anthropic principle, - # which I just made up but loosely states that time must have - # these properties for observers to exist, it must be yesterday - # because we are here to observe it. - if _starttime <= now <= _starttime + duration: - today = yesterday - starttime = _starttime - else: - starttime = time.mktime(today.timetuple()) + self._settings['testrunstarttimer'] - except ValueError: - logging.debug('Invalid dates, skipping testrun') - return False - - # If start date is in the future set as NextTestRun and stop evaluating - if startdate > today: - self._dbusservice['/NextTestRun'] = time.mktime(startdate.timetuple()) - return False - - start = False - # If the accumulated runtime during the tes trun interval is greater than '/TestRunIntervalRuntime' - # the tes trun must be skipped - needed = (self._settings['testrunskipruntime'] > self._dbusservice['/TestRunIntervalRuntime'] - or self._settings['testrunskipruntime'] == 0) - self._dbusservice['/SkipTestRun'] = int(not needed) - - interval = self._settings['testruninterval'] - stoptime = starttime + duration - elapseddays = (today - startdate).days - mod = elapseddays % interval - - start = not bool(mod) and starttime <= now <= stoptime - - if runtillbatteryfull: - if soc is not None: - self._testrun_soc_retries = 0 - start = (start or self._dbusservice['/RunningByCondition'] == 'testrun') and not batteryisfull - elif self._dbusservice['/RunningByCondition'] == 'testrun': - if self._testrun_soc_retries < self.RETRIES_ON_ERROR: - self._testrun_soc_retries += 1 - start = True - if (self._testrun_soc_retries % 10) == 0: - self.log_info('Test run failed to get SOC value, retrying(#%i)' % self._testrun_soc_retries) - else: - self.log_info('Failed to get SOC after %i retries, terminating test run condition' % self._testrun_soc_retries) - start = False - else: - start = False - - if not bool(mod) and (now <= stoptime): - self._dbusservice['/NextTestRun'] = starttime - else: - self._dbusservice['/NextTestRun'] = (time.mktime((today + datetime.timedelta(days=interval - mod)).timetuple()) + - self._settings['testrunstarttimer']) - return start and needed - - def _check_quiet_hours(self): - active = False - if self._settings['quiethoursenabled'] == 1: - # Seconds after today 00:00 - timeinseconds = time.time() - time.mktime(datetime.date.today().timetuple()) - quiethoursstart = self._settings['quiethoursstarttime'] - quiethoursend = self._settings['quiethoursendtime'] - - # Check if the current time is between the start time and end time - if quiethoursstart < quiethoursend: - active = quiethoursstart <= timeinseconds and timeinseconds < quiethoursend - else: # End time is lower than start time, example Start: 21:00, end: 08:00 - active = not (quiethoursend < timeinseconds and timeinseconds < quiethoursstart) - - if self._dbusservice['/QuietHours'] == 0 and active: - self.log_info('Entering to quiet mode') - - elif self._dbusservice['/QuietHours'] == 1 and not active: - self.log_info('Leaving quiet mode') - - self._dbusservice['/QuietHours'] = int(active) - - return active - - def _update_accumulated_time(self): - seconds = self._dbusservice['/Runtime'] - accumulated = seconds - self._last_runtime_update - - self._settings['accumulatedtotal'] = int(self._settings['accumulatedtotal']) + accumulated - # Using calendar to get timestamp in UTC, not local time - today_date = str(calendar.timegm(datetime.date.today().timetuple())) - - # If something goes wrong getting the json string create a new one - try: - accumulated_days = json.loads(self._settings['accumulateddaily']) - except ValueError: - accumulated_days = {today_date: 0} - - if (today_date in accumulated_days): - accumulated_days[today_date] += accumulated - else: - accumulated_days[today_date] = accumulated - - self._last_runtime_update = seconds - - # Keep the historical with a maximum of HISTORY_DAYS - while len(accumulated_days) > HISTORY_DAYS: - accumulated_days.pop(min(accumulated_days.keys()), None) - - # Upadate settings - self._settings['accumulateddaily'] = json.dumps(accumulated_days, sort_keys=True) - self._dbusservice['/TodayRuntime'] = self._interval_runtime(0) - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - - def _interval_runtime(self, days): - summ = 0 - try: - daily_record = json.loads(self._settings['accumulateddaily']) - except ValueError: - return 0 - - for i in range(days + 1): - previous_day = calendar.timegm((datetime.date.today() - datetime.timedelta(days=i)).timetuple()) - if str(previous_day) in daily_record.keys(): - summ += daily_record[str(previous_day)] if str(previous_day) in daily_record.keys() else 0 - - return summ - - def _get_battery(self): - battery = {} - if self._settings['batterymeasurement'] == 'default': - battery['service'] = SYSTEM_SERVICE - battery['prefix'] = BATTERY_PREFIX - else: - battery['service'] = self._battery_service if self._battery_service else '' - battery['prefix'] = self._battery_prefix if self._battery_prefix else '' - - return battery - - def _get_updated_values(self): - battery = self._get_battery() - vebus_service = self._vebusservice if self._vebusservice else '' - loadOnAcOut = [] - totalConsumption = [] - inverterHighTemp = [] - inverterOverload = [] - - values = { - 'batteryvoltage': self._dbusmonitor.get_value(battery['service'], battery['prefix'] + '/Voltage'), - 'batterycurrent': self._dbusmonitor.get_value(battery['service'], battery['prefix'] + '/Current'), - # Soc from the device doesn't have the '/Dc/0' prefix like the current and voltage do, but it does - # have the same prefix on systemcalc - 'soc': self._dbusmonitor.get_value(battery['service'], (battery['prefix'] if battery['prefix'] == BATTERY_PREFIX else '') + '/Soc'), - 'inverterhightemp': self._dbusmonitor.get_value(vebus_service, '/Alarms/HighTemperature'), - 'inverteroverload': self._dbusmonitor.get_value(vebus_service, '/Alarms/Overload') - } - - for phase in ['L1', 'L2', 'L3']: - # Get the values directly from the inverter, systemcalc doesn't provide raw inverted power - loadOnAcOut.append(self._dbusmonitor.get_value(vebus_service, ('/Ac/Out/%s/P' % phase))) - - # Calculate total consumption, '/Ac/Consumption/%s/Power' is deprecated - c_i = self._dbusmonitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnInput/%s/Power' % phase)) - c_o = self._dbusmonitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnOutput/%s/Power' % phase)) - totalConsumption.append(sum(filter(None, (c_i, c_o)))) - - # Inverter alarms must be fetched directly from the inverter service - inverterHighTemp.append(self._dbusmonitor.get_value(vebus_service, ('/Alarms/%s/HighTemperature' % phase))) - inverterOverload.append(self._dbusmonitor.get_value(vebus_service, ('/Alarms/%s/Overload' % phase))) - - # Toltal consumption - if self._settings['acloadmeasuerment'] == 0: - values['acload'] = sum(filter(None, totalConsumption)) - - # Load on inverter AC out - if self._settings['acloadmeasuerment'] == 1: - values['acload'] = sum(filter(None, loadOnAcOut)) - - # Highest phase load - if self._settings['acloadmeasuerment'] == 2: - values['acload'] = safe_max(loadOnAcOut) - - # AC input 1 - activein = self._dbusmonitor.get_value(vebus_service, '/Ac/ActiveIn/ActiveInput') - # Active input is connected - connected = self._dbusmonitor.get_value(vebus_service, '/Ac/ActiveIn/Connected') - if None not in (activein, connected): - values['stoponac1'] = activein == 0 and connected == 1 - else: - values['stoponac1'] = None - - # Invalidate if vebus is not available - if loadOnAcOut[0] == None: - values['acload'] = None - - if values['batterycurrent']: - values['batterycurrent'] *= -1 - - # When multi is connected to CAN-bus, alarms are published to - # /Alarms/Overload... but when connected to vebus alarms are - # splitted in three phases and published to /Alarms/LX/Overload... - if values['inverteroverload'] == None: - values['inverteroverload'] = safe_max(inverterOverload) - - if values['inverterhightemp'] == None: - values['inverterhightemp'] = safe_max(inverterHighTemp) - - return values - - def _determineservices(self): - # batterymeasurement is either 'default' or 'com_victronenergy_battery_288/Dc/0'. - # In case it is set to default, we use the AutoSelected battery - # measurement, given by SystemCalc. - batterymeasurement = None - newbatteryservice = None - batteryprefix = '' - selectedbattery = self._settings['batterymeasurement'] - vebusservice = None - - if selectedbattery == 'default': - batterymeasurement = 'default' - elif len(selectedbattery.split('/', 1)) == 2: # Only very basic sanity checking.. - batterymeasurement = self._settings['batterymeasurement'] - elif selectedbattery == 'nobattery': - batterymeasurement = None - else: - # Exception: unexpected value for batterymeasurement - pass - - if batterymeasurement and batterymeasurement != 'default': - batteryprefix = '/' + batterymeasurement.split('/', 1)[1] - - # Get the current battery servicename - if self._battery_service: - oldservice = self._battery_service - else: - oldservice = None - - if batterymeasurement != 'default': - battery_instance = int(batterymeasurement.split('_', 3)[3].split('/')[0]) - service_type = None - - if 'vebus' in batterymeasurement: - service_type = 'vebus' - elif 'battery' in batterymeasurement: - service_type = 'battery' - - newbatteryservice = self._get_servicename_by_instance(battery_instance, service_type) - elif batterymeasurement == 'default': - newbatteryservice = 'default' - - if newbatteryservice and newbatteryservice != oldservice: - if selectedbattery == 'default': - self.log_info('Getting battery values from systemcalc.') - if selectedbattery == 'nobattery': - self.log_info('Battery monitoring disabled! Stop evaluating related conditions') - self._battery_service = None - self._battery_prefix = None - self.log_info('Battery service we need (%s) found! Using it for generator start/stop' % batterymeasurement) - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - elif not newbatteryservice and newbatteryservice != oldservice: - self.log_info('Error getting battery service!') - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - - # Get the default VE.Bus service - vebusservice = self._dbusmonitor.get_value('com.victronenergy.system', '/VebusService') - if vebusservice: - if self._vebusservice != vebusservice: - self._vebusservice = vebusservice - self.log_info('Vebus service (%s) found! Using it for generator start/stop' % vebusservice) - else: - if self._vebusservice is not None: - self.log_info('Vebus service (%s) dissapeared! Stop evaluating related conditions' % self._vebusservice) - else: - self.log_info('Error getting Vebus service!') - self._vebusservice = None - - def _get_servicename_by_instance(self, instance, service_type=None): - sv = None - services = self._dbusmonitor.get_service_list() - - for service in services: - if service_type and service_type not in service: - continue - - if services[service] == instance: - sv = service - break - - return sv - - def _get_monotonic_seconds(self): - return monotonic_time.monotonic_time().to_seconds_double() - - def _start_generator(self, condition): - state = self._dbusservice['/State'] - remote_state = self._get_remote_switch_state() - - # This function will start the generator in the case generator not - # already running. When differs, the RunningByCondition is updated - if state == States.STOPPED or remote_state != state: - self._dbusservice['/State'] = States.RUNNING - self._update_remote_switch() - self._starttime = monotonic_time.monotonic_time().to_seconds_double() - self.log_info('Starting generator by %s condition' % condition) - elif self._dbusservice['/RunningByCondition'] != condition: - self.log_info('Generator previously running by %s condition is now running by %s condition' - % (self._dbusservice['/RunningByCondition'], condition)) - - self._dbusservice['/RunningByCondition'] = condition - self._dbusservice['/RunningByConditionCode'] = RunningConditions.lookup(condition) - - def _stop_generator(self): - state = self._dbusservice['/State'] - remote_state = self._get_remote_switch_state() - - if state == 1 or remote_state != state: - self._dbusservice['/State'] = States.STOPPED - self._update_remote_switch() - self.log_info('Stopping generator that was running by %s condition' % - str(self._dbusservice['/RunningByCondition'])) - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped - self._update_accumulated_time() - self._starttime = 0 - self._dbusservice['/Runtime'] = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._manualstarttimer = 0 - self._last_runtime_update = 0 - - def _update_remote_switch(self): - self._set_remote_switch_state(dbus.Int32(self._dbusservice['/State'], variant_level=1)) - - def _get_remote_switch_state(self): - raise Exception('This function should be overridden') - - def _set_remote_switch_state(self, value): - raise Exception('This function should be overridden') - - # Check the remote status, for example errors - def _check_remote_status(self): - raise Exception('This function should be overridden') - - def _remote_setup(self): - raise Exception('This function should be overridden') - - def _create_dbus_monitor(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_settings(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_dbus_service(self): - return create_dbus_service(self._instance) diff --git a/FileSets/v2.94/styles.css b/FileSets/v2.94/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v2.94/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v3.00/Battery.qml b/FileSets/v3.00/Battery.qml deleted file mode 120000 index 42c802c0..00000000 --- a/FileSets/v3.00/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.00/COMPLETE b/FileSets/v3.00/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.00/DetailAcInput.qml b/FileSets/v3.00/DetailAcInput.qml deleted file mode 120000 index b040d3b7..00000000 --- a/FileSets/v3.00/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.00/DetailInverter.qml b/FileSets/v3.00/DetailInverter.qml deleted file mode 120000 index d02cb165..00000000 --- a/FileSets/v3.00/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.00/DetailLoadsCombined.qml b/FileSets/v3.00/DetailLoadsCombined.qml deleted file mode 120000 index 858daaea..00000000 --- a/FileSets/v3.00/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.00/DetailLoadsOnInput.qml b/FileSets/v3.00/DetailLoadsOnInput.qml deleted file mode 120000 index df0a1562..00000000 --- a/FileSets/v3.00/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.00/DetailLoadsOnOutput.qml b/FileSets/v3.00/DetailLoadsOnOutput.qml deleted file mode 120000 index 33ab936b..00000000 --- a/FileSets/v3.00/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.00/HubData.qml b/FileSets/v3.00/HubData.qml deleted file mode 120000 index 8e608582..00000000 --- a/FileSets/v3.00/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.00/LINKS_ONLY b/FileSets/v3.00/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.00/MbEditBox.qml b/FileSets/v3.00/MbEditBox.qml deleted file mode 120000 index 8381b7d5..00000000 --- a/FileSets/v3.00/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v3.00/MbEditBoxDateTime.qml b/FileSets/v3.00/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v3.00/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.00/MbItem.qml b/FileSets/v3.00/MbItem.qml deleted file mode 120000 index 048a313c..00000000 --- a/FileSets/v3.00/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.00/MbItemDigitalInput.qml b/FileSets/v3.00/MbItemDigitalInput.qml deleted file mode 120000 index 4404b520..00000000 --- a/FileSets/v3.00/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.00/MbSpinBox.qml b/FileSets/v3.00/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v3.00/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.00/MbStyle.qml b/FileSets/v3.00/MbStyle.qml deleted file mode 120000 index d1940446..00000000 --- a/FileSets/v3.00/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.00/MbSubMenu.qml b/FileSets/v3.00/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v3.00/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.00/Multi.qml b/FileSets/v3.00/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v3.00/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.00/ObjectAcConnection.qml b/FileSets/v3.00/ObjectAcConnection.qml deleted file mode 120000 index 9ca254ed..00000000 --- a/FileSets/v3.00/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewAcValuesEnhanced.qml b/FileSets/v3.00/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 4d6d5018..00000000 --- a/FileSets/v3.00/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewBox.qml b/FileSets/v3.00/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v3.00/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewConnection.qml b/FileSets/v3.00/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v3.00/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewConnectionEnd.qml b/FileSets/v3.00/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v3.00/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewFlowComplex.qml b/FileSets/v3.00/OverviewFlowComplex.qml deleted file mode 120000 index 6b747507..00000000 --- a/FileSets/v3.00/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewGeneratorEnhanced.qml b/FileSets/v3.00/OverviewGeneratorEnhanced.qml deleted file mode 120000 index c2a4905c..00000000 --- a/FileSets/v3.00/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.00/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index 1c9b530f..00000000 --- a/FileSets/v3.00/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewGridParallel.qml b/FileSets/v3.00/OverviewGridParallel.qml deleted file mode 120000 index cbf456ca..00000000 --- a/FileSets/v3.00/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewHub.qml b/FileSets/v3.00/OverviewHub.qml deleted file mode 120000 index 3f37eb0c..00000000 --- a/FileSets/v3.00/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewHubEnhanced.qml b/FileSets/v3.00/OverviewHubEnhanced.qml deleted file mode 120000 index 6dc4f1d8..00000000 --- a/FileSets/v3.00/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewMobileEnhanced.qml b/FileSets/v3.00/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.00/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewSolarCharger.qml b/FileSets/v3.00/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v3.00/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewSolarInverter.qml b/FileSets/v3.00/OverviewSolarInverter.qml deleted file mode 120000 index 4048703e..00000000 --- a/FileSets/v3.00/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewTankDelegate.qml b/FileSets/v3.00/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v3.00/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewTanks.qml b/FileSets/v3.00/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v3.00/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewTanksTempsDigInputs.qml b/FileSets/v3.00/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.00/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.00/PageDigitalInput.qml b/FileSets/v3.00/PageDigitalInput.qml deleted file mode 120000 index 3ebafb06..00000000 --- a/FileSets/v3.00/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.00/PageGenerator.qml b/FileSets/v3.00/PageGenerator.qml deleted file mode 120000 index bbdf0114..00000000 --- a/FileSets/v3.00/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.00/PageMain.qml b/FileSets/v3.00/PageMain.qml deleted file mode 120000 index 2f68fb1c..00000000 --- a/FileSets/v3.00/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.14/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.00/PageSettingsDisplay.qml b/FileSets/v3.00/PageSettingsDisplay.qml deleted file mode 120000 index 009d0dcd..00000000 --- a/FileSets/v3.00/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v3.00/PageSettingsGenerator.qml b/FileSets/v3.00/PageSettingsGenerator.qml deleted file mode 120000 index 07c23e55..00000000 --- a/FileSets/v3.00/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.00/PageSettingsGuiMods.qml b/FileSets/v3.00/PageSettingsGuiMods.qml deleted file mode 120000 index 072d9988..00000000 --- a/FileSets/v3.00/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.00/PageSettingsRelay.qml b/FileSets/v3.00/PageSettingsRelay.qml deleted file mode 120000 index 1b7ab4e1..00000000 --- a/FileSets/v3.00/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.22/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.00/PowerGauge.qml b/FileSets/v3.00/PowerGauge.qml deleted file mode 120000 index d82ac28a..00000000 --- a/FileSets/v3.00/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.00/Tile.qml b/FileSets/v3.00/Tile.qml deleted file mode 120000 index 0558cecf..00000000 --- a/FileSets/v3.00/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.00/TileDigIn.qml b/FileSets/v3.00/TileDigIn.qml deleted file mode 120000 index 5e8ba09e..00000000 --- a/FileSets/v3.00/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.00/TileRelay.qml b/FileSets/v3.00/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.00/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.00/TileText.qml b/FileSets/v3.00/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v3.00/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.00/attributes.csv b/FileSets/v3.00/attributes.csv deleted file mode 120000 index 151259cd..00000000 --- a/FileSets/v3.00/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v3.01/attributes.csv \ No newline at end of file diff --git a/FileSets/v3.00/dbus_digitalinputs.py b/FileSets/v3.00/dbus_digitalinputs.py deleted file mode 120000 index 25f64663..00000000 --- a/FileSets/v3.00/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v3.01/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.00/dbus_generator.py b/FileSets/v3.00/dbus_generator.py deleted file mode 120000 index a4ad0739..00000000 --- a/FileSets/v3.00/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.01/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.00/main.qml b/FileSets/v3.00/main.qml deleted file mode 120000 index 0cfb4fad..00000000 --- a/FileSets/v3.00/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/main.qml \ No newline at end of file diff --git a/FileSets/v3.00/startstop.py b/FileSets/v3.00/startstop.py deleted file mode 120000 index 874993d0..00000000 --- a/FileSets/v3.00/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v3.01/startstop.py \ No newline at end of file diff --git a/FileSets/v3.00/styles.css b/FileSets/v3.00/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v3.00/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v3.00~32/COMPLETE b/FileSets/v3.00~32/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.00~32/DetailAcInput.qml b/FileSets/v3.00~32/DetailAcInput.qml deleted file mode 120000 index b040d3b7..00000000 --- a/FileSets/v3.00~32/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/DetailInverter.qml b/FileSets/v3.00~32/DetailInverter.qml deleted file mode 120000 index d02cb165..00000000 --- a/FileSets/v3.00~32/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/DetailLoadsCombined.qml b/FileSets/v3.00~32/DetailLoadsCombined.qml deleted file mode 120000 index 858daaea..00000000 --- a/FileSets/v3.00~32/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/DetailLoadsOnInput.qml b/FileSets/v3.00~32/DetailLoadsOnInput.qml deleted file mode 120000 index df0a1562..00000000 --- a/FileSets/v3.00~32/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/DetailLoadsOnOutput.qml b/FileSets/v3.00~32/DetailLoadsOnOutput.qml deleted file mode 120000 index 33ab936b..00000000 --- a/FileSets/v3.00~32/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/HubData.qml b/FileSets/v3.00~32/HubData.qml deleted file mode 120000 index 8e608582..00000000 --- a/FileSets/v3.00~32/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/MbEditBox.qml b/FileSets/v3.00~32/MbEditBox.qml deleted file mode 120000 index 8381b7d5..00000000 --- a/FileSets/v3.00~32/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/MbEditBoxDateTime.qml b/FileSets/v3.00~32/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v3.00~32/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/MbItem.qml b/FileSets/v3.00~32/MbItem.qml deleted file mode 120000 index 048a313c..00000000 --- a/FileSets/v3.00~32/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/MbItemDigitalInput.qml b/FileSets/v3.00~32/MbItemDigitalInput.qml deleted file mode 120000 index 4404b520..00000000 --- a/FileSets/v3.00~32/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/MbSpinBox.qml b/FileSets/v3.00~32/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v3.00~32/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/MbStyle.qml b/FileSets/v3.00~32/MbStyle.qml deleted file mode 120000 index d1940446..00000000 --- a/FileSets/v3.00~32/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/MbSubMenu.qml b/FileSets/v3.00~32/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v3.00~32/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/Multi.qml b/FileSets/v3.00~32/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v3.00~32/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/ObjectAcConnection.qml b/FileSets/v3.00~32/ObjectAcConnection.qml deleted file mode 120000 index 9ca254ed..00000000 --- a/FileSets/v3.00~32/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/OverviewAcValuesEnhanced.qml b/FileSets/v3.00~32/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 4d6d5018..00000000 --- a/FileSets/v3.00~32/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/OverviewBox.qml b/FileSets/v3.00~32/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v3.00~32/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/OverviewConnection.qml b/FileSets/v3.00~32/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v3.00~32/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/OverviewConnectionEnd.qml b/FileSets/v3.00~32/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v3.00~32/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/OverviewFlowComplex.qml b/FileSets/v3.00~32/OverviewFlowComplex.qml deleted file mode 120000 index 6b747507..00000000 --- a/FileSets/v3.00~32/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/OverviewGeneratorEnhanced.qml b/FileSets/v3.00~32/OverviewGeneratorEnhanced.qml deleted file mode 100644 index 63042aae..00000000 --- a/FileSets/v3.00~32/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1,546 +0,0 @@ -// GuiMods enhanced generator overview -// This file has been modified to: -// add Auto Start display and control -// show voltage, current, frequency, and power gauge in AC input tile -// show the generator running state inside the icon top left -// show a warning when the generator digital input and expected generator state disagree -// move current run time to separate tile - -import QtQuick 1.1 -import "utils.js" as Utils -import "enhancedFormat.js" as EnhFmt - -OverviewPage { - id: root - - property string settingsBindPrefix - property string bindPrefix - property variant sys: theSystem -//////// added to show alternator in place of inactive genset - property string guiModsPrefix: "com.victronenergy.settings/Settings/GuiMods" - VBusItem { id: replaceAcInItem; bind: Utils.path(guiModsPrefix, "/ReplaceInactiveAcIn") } - property bool hasAlternator: sys.alternator.power.valid - property bool showAlternator: replaceAcInItem.valid && replaceAcInItem.value == 1 && hasAlternator && ! sys.genset.power.valid - property bool showAcIn: ! showAlternator - - property string icon: "image://theme/overview-generator" - property VBusItem state: VBusItem { bind: Utils.path(bindPrefix, "/State") } - property VBusItem error: VBusItem { bind: Utils.path(bindPrefix, "/Error") } - property VBusItem runningTime: VBusItem { bind: Utils.path(bindPrefix, "/Runtime") } - property VBusItem runningBy: VBusItem { bind: Utils.path(bindPrefix, "/RunningByConditionCode") } - property VBusItem totalAcummulatedTime: VBusItem { bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") } - property VBusItem quietHours: VBusItem { bind: Utils.path(bindPrefix, "/QuietHours") } - property VBusItem testRunDuration: VBusItem { bind: Utils.path(settingsBindPrefix, "/TestRun/Duration") } - property VBusItem nextTestRun: VBusItem { bind: Utils.path(bindPrefix, "/NextTestRun") } - property VBusItem skipTestRun: VBusItem { bind: Utils.path(bindPrefix, "/SkipTestRun") } - - property VBusItem todayRuntime: VBusItem { bind: Utils.path(bindPrefix, "/TodayRuntime") } - property VBusItem manualTimer: VBusItem { bind: Utils.path(bindPrefix, "/ManualStartTimer") } - property VBusItem autoStart: VBusItem { bind: Utils.path(settingsBindPrefix, "/AutoStartEnabled") } - - property bool errors: ! state.valid || state.value == 10 - - property VBusItem externalOverrideItem: VBusItem { bind: Utils.path(bindPrefix, "/ExternalOverride") } - property bool externalOverride: externalOverrideItem.valid && externalOverrideItem.value == 1 && ! errors - property VBusItem runningState: VBusItem { bind: Utils.path(bindPrefix, "/GeneratorRunningState") } - - VBusItem { id: showGaugesItem; bind: Utils.path(guiModsPrefix, "/ShowGauges") } - property bool showGauges: showGaugesItem.valid ? showGaugesItem.value === 1 ? true : false : false - property bool editMode: autoRunTile.editMode || manualTile.editMode - - VBusItem { id: generatorServiceInterval; bind: Utils.path(settingsBindPrefix, "/ServiceInterval") } - VBusItem { id: timeSinceService; bind: Utils.path(settingsBindPrefix, "/TimeSinceService") } - property bool showServiceInfo: timeSinceService.valid && generatorServiceInterval.valid && generatorServiceInterval.value > 0 - property bool serviceOverdue: showServiceInfo && timeSinceService.value > generatorServiceInterval.value - - //////// add to display AC input ignored - VBusItem { id: ignoreAcInput1; bind: Utils.path(sys.vebusPrefix, "/Ac/State/IgnoreAcIn1") } - VBusItem { id: ignoreAcInput2; bind: Utils.path(sys.vebusPrefix, "/Ac/State/IgnoreAcIn2") } - VBusItem { id: acActiveInput; bind: Utils.path(sys.vebusPrefix, "/Ac/ActiveIn/ActiveInput") } - VBusItem { id: ac1source; bind: Utils.path("com.victronenergy.settings", "/Settings/SystemSetup/AcInput1") } - VBusItem { id: ac2source; bind: Utils.path("com.victronenergy.settings", "/Settings/SystemSetup/AcInput2") } - - title: qsTr("Generator") - - property bool autoStartSelected: false - - Component.onCompleted: - { - setFocusManual () - } - - Keys.forwardTo: [keyHandler] - Item - { - id: keyHandler - Keys.onUpPressed: - { - setFocusAuto () - event.accepted = true - } - Keys.onDownPressed: - { - setFocusManual () - event.accepted = true - } - // prevents page changes while timers are running - //// Keys.onReturnPressed: event.accepted = manualTile.startCountdown || autoRunTile.startCountdown - //// Keys.onEscapePressed: event.accepted = manualTile.startCountdown || autoRunTile.startCountdown - } - - function setFocusManual () - { - autoStartSelected = false - } - - function setFocusAuto () - { - autoStartSelected = true - } - - function formatTime (time) - { - if (time >= 3600) - return (time / 3600).toFixed(0) + " h" - else - return (time / 60).toFixed(0) + " m" - } - - function stateDescription() - { - if (!state.valid) - return qsTr ("") - else if (state.value === 10) - { - switch(error.value) - { - case 1: - return qsTr("Error: Remote switch control disabled") - case 2: - return qsTr("Error: Generator in fault condition") - case 3: - return qsTr("Error: Generator not detected at AC input") - default: - return qsTr("Error") - } - } - else - { - var condition = "" - var running = true - var manual = false - switch (runningBy.value) - { - case 0: // stopped - condition = "" - running = false - break;; - case 1: - manual = true - condition = "" - break;; - case 2: - condition = qsTr("Test run") - break;; - case 3: - condition = qsTr("Loss of communication") - break;; - case 4: - condition = qsTr("SOC") - break;; - case 5: - condition = qsTr("AC load") - break;; - case 6: - condition = qsTr("Battery current") - break;; - case 7: - condition = qsTr("Battery voltage") - break;; - case 8: - condition = qsTr("Inverter temperature") - break;; - case 9: - condition = qsTr("Inverter overload") - break;; - default: - condition = qsTr("???") - break;; - } - - if (externalOverride) - { - if (running && ! manual) - return qsTr ("auto pending: ") + condition - else - return " " - } - else if (manual) - { - if (manualTimer.valid && manualTimer.value > 0) - return qsTr("Timed run") - else - return qsTr("Manual run") - } - else if (running) - return qsTr ("auto run: ") + condition - else - return " " - } - } - - function getNextTestRun() - { - if ( ! root.state.valid) - return "" - if (!nextTestRun.value) - return qsTr("No test run programmed") - - var todayDate = new Date() - var nextDate = new Date(nextTestRun.value * 1000) - var nextDateEnd = new Date(nextDate.getTime()) - var message = "" - // blank "next run" if test run is active - if (runningBy.value == 2) - return " " - else if (todayDate.getDate() == nextDate.getDate() && todayDate.getMonth() == nextDate.getMonth()) - { - message = qsTr("Next test run today %1").arg( - Qt.formatDateTime(nextDate, "hh:mm").toString()) - } - else - { - message = qsTr("Next test run on %1").arg( - Qt.formatDateTime(nextDate, "dd/MM/yyyy").toString()) - nextDateEnd.setSeconds(testRunDuration.value) } - - if (skipTestRun.value === 1) - message += qsTr(" \(skipped\)") - - return message - } - - Tile { - id: imageTile - width: 180 - height: 136 - MbIcon { - id: generator - source: icon - anchors.centerIn: parent - } - anchors { top: parent.top; left: parent.left } - values: [ - // spacer - TileText { - width: imageTile.width - 5 - text: " " - font.pixelSize: 62 - }, - TileText { - width: imageTile.width - 5 - text: runningState.valid ? runningState.value == "R" ? "Running " : runningState.value == "S" ? "Stopped " : "" : "" - } - ] - } - - Tile { - id: statusTile - height: imageTile.height - color: "#4789d0" - anchors { top: parent.top; left: imageTile.right; right: root.right } - title: qsTr("STATUS") - values: [ - TileText - { - width: statusTile.width - 5 - color: externalOverride ? "yellow" : "white" - text: - { - var runPrefix - var message - if ( ! root.state.valid) - return qsTr ("Generator not connected") - else if (root.state.value === 2) - runPrefix = qsTr("Warming up for ") - else - runPrefix = qsTr ("Running for ") - if (!root.state.valid) - message = "" - else if (externalOverride) - message = qsTr("External Override - stopped") - else if (root.state.value === 3) - message = qsTr("Cool-down") - else if (runningBy.value == 0) - message = qsTr ("Stopped") - else if ( ! runningTime.valid) - message = runPrefix + "??" - else - { - message = runPrefix + formatTime (runningTime.value) - if (manualTimer.valid && manualTimer.value > 0) - message += qsTr (" ends in ") + formatTime (manualTimer.value) - } - return message - } - }, - Rectangle - { - width: parent.width - height: 3 - color: "transparent" - }, - TileTextMultiLine - { - text: stateDescription() - width: statusTile.width - 5 - }, - Rectangle - { - width: parent.width - height: 3 - color: "transparent" - }, - TileText - { - text: qsTr("\nQuiet hours"); - width: statusTile.width - 5 - font.bold: runningBy.valid && runningBy.value != 0 - color: font.bold ? "yellow" : "white" - visible: quietHours.value === 1 - }, - Rectangle - { - width: parent.width - height: 3 - color: "transparent" - }, - TileTextMultiLine - { - width: statusTile.width - 5 - text: getNextTestRun() - } - ] - } - - Tile { - id: acInTile - title: qsTr("GENERATOR POWER") - width: 150 - height: 136 - color: "#82acde" - anchors { top: imageTile.bottom; left: parent.left } - visible: showAcIn - values: - [ - OverviewAcValuesEnhanced - { - connection: sys.genset - visible: sys.genset.power.valid - }, - TileText - { - width: acInTile.width - 5 - text: - { - // input 1 is active - if (acActiveInput.value == 0) - { - if (! ac1source.valid) - return qsTr ("\nno AC 1 In") - else if (ac1source.value != 2) - return qsTr ("AC In 1\nis not\ngenerator") - else if (ignoreAcInput1.valid && ignoreAcInput1.value == 1) - return qsTr ("AC In 1\nIgnored") - else - return "" - } - // input 2 is active - else if (acActiveInput.value == 1) - { - if (! ac2source.valid) - return qsTr ("\nno AC 2 In") - else if (ac2source.value != 2) - return qsTr ("AC In 2\nis not\ngenerator") - else if (ignoreAcInput2.valid && ignoreAcInput2.value == 1) - return qsTr ("AC In 2\nIgnored") - else - return "" - } - else - return "no\nactive\ninput" - } - visible: !sys.genset.power.valid - } - ] -////// add power bar graph - PowerGauge - { - id: acInBar - width: parent.width - height: 12 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.genset - useInputCurrentLimit: true - maxForwardPowerParameter: "" - maxReversePowerParameter: "" - visible: showGauges && sys.genset.power.valid - } - } - -//////// added to show alternator in place of AC generator - Tile { - id: alternatorTile - title: qsTr("ALTERNATOR POWER") - color: "#157894" - anchors.fill: acInTile - visible: showAlternator - values: - [ - TileText - { - text: EnhFmt.formatVBusItem (sys.alternator.power, "W") - font.pixelSize: 22 - } - ] -////// add power bar graph - PowerGauge - { - id: alternatorGauge - width: parent.width - height: 12 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.alternator - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxAlternatorPower" - visible: showGauges && showAlternator - } - } - - Tile { - id: runTimeTile - title: qsTr("RUN TIMES") - width: 140 - anchors { top: acInTile.top; bottom: parent.bottom; left: acInTile.right } - values: [ - TileText - { - width: runTimeTile.width - 5 - text: qsTr ("Today") - }, - TileText { - width: runTimeTile.width - 5 - text: todayRuntime.valid ? formatTime (todayRuntime.value) : "--" - }, - Rectangle - { - width: parent.width - height: 3 - color: "transparent" - }, - TileText - { - width: runTimeTile.width - 5 - text: qsTr ("Accumulated") - }, - TileText - { - width: runTimeTile.width - 5 - text: totalAcummulatedTime.valid ? formatTime (totalAcummulatedTime.value) : "--" - }, - Rectangle - { - width: parent.width - height: 3 - color: "transparent" - }, - TileText - { - width: runTimeTile.width - 5 - visible: showServiceInfo - color: serviceOverdue ? "red" : "white" - text: serviceOverdue ? qsTr ("Service OVERDUE") : qsTr ("Service in") - }, - TileText - { - width: runTimeTile.width - 5 - visible: showServiceInfo - color: serviceOverdue ? "red" : "white" - text: formatTime (Math.abs (generatorServiceInterval.value - timeSinceService.value)) - } - ] - } - - TileAutoRunEnhanced - { - id: autoRunTile - bindPrefix: root.bindPrefix - focus: root.active && autoStartSelected - connected: state.valid - tileHeight: acInTile.height / 2 - anchors { - bottom: parent.bottom; bottomMargin: tileHeight - left: runTimeTile.right - right: parent.right - } - } - - TileManualStartEnhanced - { - id: manualTile - bindPrefix: root.bindPrefix - focus: root.active && ! autoStartSelected - connected: state.valid - tileHeight: acInTile.height / 2 - anchors { - bottom: parent.bottom - left: runTimeTile.right - right: parent.right - } - } - - // mouse areas must be AFTER their associated objects so those objects can catch mouse events - // rejected by these areas - // mouse targets need to be disabled while changes are pending - MouseArea { - id: autoRunTarget - anchors.fill: autoRunTile - enabled: root.active && ! editMode - onPressed: - { - if ( ! root.autoStartSelected ) - { - setFocusAuto () - mouse.accepted = true - } - else - { - mouse.accepted = false - } - } - } - MouseArea { - id: manualStartTarget - anchors.fill: manualTile - enabled: root.active && ! editMode - onPressed: - { - if ( root.autoStartSelected ) - { - setFocusManual () - mouse.accepted = true - } - else - { - mouse.accepted = false - } - } - } -} diff --git a/FileSets/v3.00~32/OverviewGeneratorEnhanced.qml.orig b/FileSets/v3.00~32/OverviewGeneratorEnhanced.qml.orig deleted file mode 100644 index 91cb59fe..00000000 --- a/FileSets/v3.00~32/OverviewGeneratorEnhanced.qml.orig +++ /dev/null @@ -1,189 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: root - title: qsTr("Generator start/stop") - property string settingsBindPrefix - property string startStopBindPrefix - property alias startStopModel: _startStopModel - property bool allowDisableAutostart: true - property VBusItem activeCondition: VBusItem { bind: Utils.path(startStopBindPrefix, "/RunningByCondition") } - property VBusItem generatorState: VBusItem { bind: Utils.path(startStopBindPrefix, "/State") } - property VBusItem runningTime: VBusItem { bind: Utils.path(startStopBindPrefix, "/Runtime") } - property VBusItem historicalData: VBusItem { bind: Utils.path(settingsBindPrefix, "/AccumulatedDaily") } - property VBusItem functionEnabled: VBusItem { bind: Utils.path(startStopBindPrefix, "/State") } - - function getState() - { - if (generatorState.value === 10) - return qsTr("Error") - - switch(activeCondition.value) { - case 'soc': - return qsTr("Running by SOC condition") - case 'acload': - return qsTr("Running by AC Load condition") - case 'batterycurrent': - return qsTr("Running by battery current condition") - case 'batteryvoltage': - return qsTr("Running by battery voltage condition") - case 'inverterhightemp': - return qsTr("Running by inverter high temperature") - case 'inverteroverload': - return qsTr("Running by inverter overload") - case 'testrun': - return qsTr("Test run") - case 'lossofcommunication': - return qsTr("Running by loss of communication") - case 'manual': - return qsTr("Manually started") - default: - return qsTr("Stopped") - } - } - - model: startStopModel - - function formatError(text, value) - { - return "#" + value.toString() + " " + text - } - - VisibleItemModel { - id: _startStopModel - - MbItemValue { - description: qsTr("State") - item.text: activeCondition.valid ? getState() : '---' - } - - MbItemOptions { - id: _gensetStatus - description: qsTr("Error") - bind: Utils.path(startStopBindPrefix, "/Error") - readonly: true - show: valid - possibleValues: [ - MbOption { description: qsTr("No error"); value: 0 }, - MbOption { description: formatError(qsTr("Remote switch control disabled"), 1); value: 1 }, - MbOption { description: formatError(qsTr("Generator in fault condition"), 2); value: 2 }, - MbOption { description: formatError(qsTr("Generator not detected at AC input"), 3); value: 3 } - ] - } - - MbItemValue { - description: qsTr("Run time") - item.text: runningTime.valid ? Utils.secondsToNoSecsString(runningTime.value) : "0" - show: generatorState.value === 1 - } - - MbItemValue { - description: qsTr("Total run time") - item { - bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") - text: Utils.secondsToNoSecsString(item.value) - } - } - - MbItemValue { - description: qsTr("Accumulated running time since last test run") - show: user.accessLevel >= User.AccessService && nextTestRun.show - backgroundColor: style.backgroundColorService - item { - text: Utils.secondsToNoSecsString(item.value) - bind: Utils.path(startStopBindPrefix, "/TestRunIntervalRuntime") - } - } - - MbItemValue { - id: nextTestRun - description: qsTr("Time to next test run") - show: item.valid && item.value > 0 - item { - text: { - var remainingTime = item.value - new Date().getTime() / 1000 - if (remainingTime > 0) - return Utils.secondsToNoSecsString(remainingTime).toString() - return qsTr("Running now") - } - bind: Utils.path(startStopBindPrefix, "/NextTestRun") - } - } - - MbSwitch { - name: qsTr("Auto start functionality") - bind: Utils.path(settingsBindPrefix, "/AutoStartEnabled") - show: allowDisableAutostart - } - - MbSubMenu { - description: qsTr("Manual start") - subpage: Component { - MbPage { - id: manualStartPage - title: qsTr("Manual start") - model: VisibleItemModel { - MbSwitch { - id: manualSwitch - name: qsTr("Start generator") - bind: Utils.path(startStopBindPrefix, "/ManualStart") - writeAccessLevel: User.AccessUser - onCheckedChanged: { - if (manualStartPage.active) { - if (!checked) - toast.createToast(qsTr("Stopping, generator will continue running if other conditions are reached"), 3000) - if (checked && stopTimer.value == 0) - toast.createToast(qsTr("Starting, generator won't stop till user intervention"), 5000) - if (checked && stopTimer.value > 0) - toast.createToast(qsTr("Starting. The generator will stop in %1, unless other conditions keep it running").arg(Utils.secondsToString(stopTimer.value)), 5000) - } - } - - VBusItem { - id: stopTimer - bind: Utils.path(startStopBindPrefix, "/ManualStartTimer") - } - } - - MbEditBoxTime { - description: qsTr("Run for (hh:mm)") - readonly: manualSwitch.checked - item.bind: Utils.path(startStopBindPrefix, "/ManualStartTimer") - writeAccessLevel: User.AccessUser - } - } - } - } - } - - MbSubMenu { - description: qsTr("Daily run time") - subpage: MbPage { - // Invert the order - property variant keys: historicalData.valid ? - Object.keys(JSON.parse(historicalData.value)).reverse() : 0 - - title: qsTr("Daily run time") - focus: active - model: keys - delegate: MbItemValue { - description: Qt.formatDate(new Date(parseInt(keys[index]) * 1000), "dd-MM-yyyy"); - item.text: Utils.secondsToNoSecsString(JSON.parse(historicalData.value)[keys[index]]) - } - } - } - - MbSubMenu { - id: conditions - description: qsTr("Settings") - subpage: Component { - PageSettingsGenerator { - settingsBindPrefix: root.settingsBindPrefix - startStopBindPrefix: root.startStopBindPrefix - } - } - } - } -} diff --git a/FileSets/v3.00~32/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.00~32/OverviewGeneratorRelayEnhanced.qml deleted file mode 100644 index 501e2995..00000000 --- a/FileSets/v3.00~32/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -OverviewGeneratorEnhanced { - icon: "image://theme/overview-generator" - settingsBindPrefix: "com.victronenergy.settings/Settings/Generator0" - bindPrefix: "com.victronenergy.generator.startstop0" -} diff --git a/FileSets/v3.00~32/OverviewGeneratorRelayEnhanced.qml.orig b/FileSets/v3.00~32/OverviewGeneratorRelayEnhanced.qml.orig deleted file mode 100644 index d135ed43..00000000 --- a/FileSets/v3.00~32/OverviewGeneratorRelayEnhanced.qml.orig +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -OverviewGenerator { - icon: "image://theme/overview-generator" - settingsBindPrefix: "com.victronenergy.settings/Settings/Generator0" - bindPrefix: "com.victronenergy.generator.startstop0" -} diff --git a/FileSets/v3.00~32/OverviewGridParallel.qml b/FileSets/v3.00~32/OverviewGridParallel.qml deleted file mode 120000 index cbf456ca..00000000 --- a/FileSets/v3.00~32/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/OverviewHub.qml b/FileSets/v3.00~32/OverviewHub.qml deleted file mode 120000 index 3f37eb0c..00000000 --- a/FileSets/v3.00~32/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/OverviewHubEnhanced.qml b/FileSets/v3.00~32/OverviewHubEnhanced.qml deleted file mode 120000 index 6dc4f1d8..00000000 --- a/FileSets/v3.00~32/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/OverviewMobileEnhanced.qml b/FileSets/v3.00~32/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.00~32/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/OverviewSolarCharger.qml b/FileSets/v3.00~32/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v3.00~32/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/OverviewTankDelegate.qml b/FileSets/v3.00~32/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v3.00~32/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/OverviewTanks.qml b/FileSets/v3.00~32/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v3.00~32/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/OverviewTanksTempsDigInputs.qml b/FileSets/v3.00~32/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.00~32/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/PageGenerator.qml b/FileSets/v3.00~32/PageGenerator.qml deleted file mode 100644 index 0f81a482..00000000 --- a/FileSets/v3.00~32/PageGenerator.qml +++ /dev/null @@ -1,220 +0,0 @@ -//// added service interval -//// changed total time to hours (from varilable format) - -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: root - title: qsTr("Generator start/stop") - property string settingsBindPrefix - property string startStopBindPrefix - property alias startStopModel: _startStopModel - property bool allowDisableAutostart: true - property VBusItem activeCondition: VBusItem { bind: Utils.path(startStopBindPrefix, "/RunningByCondition") } - property VBusItem generatorState: VBusItem { bind: Utils.path(startStopBindPrefix, "/State") } - property VBusItem runningTime: VBusItem { bind: Utils.path(startStopBindPrefix, "/Runtime") } - property VBusItem historicalData: VBusItem { bind: Utils.path(settingsBindPrefix, "/AccumulatedDaily") } - property VBusItem functionEnabled: VBusItem { bind: Utils.path(startStopBindPrefix, "/State") } - -//// added service interval - VBusItem { id: generatorServiceInterval; bind: Utils.path(settingsBindPrefix, "/ServiceInterval") } - VBusItem { id: timeSinceService; bind: Utils.path(settingsBindPrefix, "/TimeSinceService") } - property bool serviceIntervalValid: timeSinceService.valid && generatorServiceInterval.valid && generatorServiceInterval.value > 0 - property bool serviceOverdue: serviceIntervalValid && timeSinceService.value > generatorServiceInterval.value - -//// changed total time to hours (from varilable format) - function formatTime (time) - { - if (time >= 3600) - return (time / 3600).toFixed(0) + " h" - else - return (time / 60).toFixed(0) + " m" - } - - - function getState() - { - if (generatorState.value === 10) - return qsTr("Error") - - switch(activeCondition.value) { - case 'soc': - return qsTr("Running by SOC condition") - case 'acload': - return qsTr("Running by AC Load condition") - case 'batterycurrent': - return qsTr("Running by battery current condition") - case 'batteryvoltage': - return qsTr("Running by battery voltage condition") - case 'inverterhightemp': - return qsTr("Running by inverter high temperature") - case 'inverteroverload': - return qsTr("Running by inverter overload") - case 'testrun': - return qsTr("Test run") - case 'lossofcommunication': - return qsTr("Running by loss of communication") - case 'manual': - return qsTr("Manually started") - default: - return qsTr("Stopped") - } - } - - model: startStopModel - - function formatError(text, value) - { - return "#" + value.toString() + " " + text - } - - VisibleItemModel { - id: _startStopModel - - MbItemValue { - description: qsTr("State") - item.text: activeCondition.valid ? getState() : '---' - } - - MbItemOptions { - id: _gensetStatus - description: qsTr("Error") - bind: Utils.path(startStopBindPrefix, "/Error") - readonly: true - show: valid - possibleValues: [ - MbOption { description: qsTr("No error"); value: 0 }, - MbOption { description: formatError(qsTr("Remote switch control disabled"), 1); value: 1 }, - MbOption { description: formatError(qsTr("Generator in fault condition"), 2); value: 2 }, - MbOption { description: formatError(qsTr("Generator not detected at AC input"), 3); value: 3 } - ] - } - - MbItemValue { - description: qsTr("Run time") - item.text: runningTime.valid ? Utils.secondsToNoSecsString(runningTime.value) : "0" - show: generatorState.value === 1 - } - - MbItemValue { - description: qsTr("Total run time") - item { - bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") -//// changed total time to hours (from varilable format) - text: formatTime (item.value) - } - } - - MbItemValue { - description: qsTr("Accumulated running time since last test run") - show: user.accessLevel >= User.AccessService && nextTestRun.show - backgroundColor: style.backgroundColorService - item { - text: Utils.secondsToNoSecsString(item.value) - bind: Utils.path(startStopBindPrefix, "/TestRunIntervalRuntime") - } - } - - MbItemValue { - id: nextTestRun - description: qsTr("Time to next test run") - show: item.valid && item.value > 0 - item { - text: { - var remainingTime = item.value - new Date().getTime() / 1000 - if (remainingTime > 0) - return Utils.secondsToNoSecsString(remainingTime).toString() - return qsTr("Running now") - } - bind: Utils.path(startStopBindPrefix, "/NextTestRun") - } - } - -//// added service interval - MbItemValue { - id: serviceTime - description: serviceOverdue ? qsTr("Service OVERDUE") : qsTr("Time to next service") - show: serviceIntervalValid - item - { - text: formatTime (Math.abs (generatorServiceInterval.value - timeSinceService.value)) - } - } - - MbSwitch { - name: qsTr("Auto start functionality") - bind: Utils.path(settingsBindPrefix, "/AutoStartEnabled") - show: allowDisableAutostart - } - - MbSubMenu { - description: qsTr("Manual start") - subpage: Component { - MbPage { - id: manualStartPage - title: qsTr("Manual start") - model: VisibleItemModel { - MbSwitch { - id: manualSwitch - name: qsTr("Start generator") - bind: Utils.path(startStopBindPrefix, "/ManualStart") - writeAccessLevel: User.AccessUser - onCheckedChanged: { - if (manualStartPage.active) { - if (!checked) - toast.createToast(qsTr("Stopping, generator will continue running if other conditions are reached"), 3000) - if (checked && stopTimer.value == 0) - toast.createToast(qsTr("Starting, generator won't stop till user intervention"), 5000) - if (checked && stopTimer.value > 0) - toast.createToast(qsTr("Starting. The generator will stop in %1, unless other conditions keep it running").arg(Utils.secondsToString(stopTimer.value)), 5000) - } - } - - VBusItem { - id: stopTimer - bind: Utils.path(startStopBindPrefix, "/ManualStartTimer") - } - } - - MbEditBoxTime { - description: qsTr("Run for (hh:mm)") - readonly: manualSwitch.checked - item.bind: Utils.path(startStopBindPrefix, "/ManualStartTimer") - writeAccessLevel: User.AccessUser - } - } - } - } - } - - MbSubMenu { - description: qsTr("Daily run time") - subpage: MbPage { - // Invert the order - property variant keys: historicalData.valid ? - Object.keys(JSON.parse(historicalData.value)).reverse() : 0 - - title: qsTr("Daily run time") - focus: active - model: keys - delegate: MbItemValue { - description: Qt.formatDate(new Date(parseInt(keys[index]) * 1000), "dd-MM-yyyy"); - item.text: Utils.secondsToNoSecsString(JSON.parse(historicalData.value)[keys[index]]) - } - } - } - - MbSubMenu { - id: conditions - description: qsTr("Settings") - subpage: Component { - PageSettingsGenerator { - settingsBindPrefix: root.settingsBindPrefix - startStopBindPrefix: root.startStopBindPrefix - } - } - } - } -} diff --git a/FileSets/v3.00~32/PageGenerator.qml.orig b/FileSets/v3.00~32/PageGenerator.qml.orig deleted file mode 100644 index 91cb59fe..00000000 --- a/FileSets/v3.00~32/PageGenerator.qml.orig +++ /dev/null @@ -1,189 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: root - title: qsTr("Generator start/stop") - property string settingsBindPrefix - property string startStopBindPrefix - property alias startStopModel: _startStopModel - property bool allowDisableAutostart: true - property VBusItem activeCondition: VBusItem { bind: Utils.path(startStopBindPrefix, "/RunningByCondition") } - property VBusItem generatorState: VBusItem { bind: Utils.path(startStopBindPrefix, "/State") } - property VBusItem runningTime: VBusItem { bind: Utils.path(startStopBindPrefix, "/Runtime") } - property VBusItem historicalData: VBusItem { bind: Utils.path(settingsBindPrefix, "/AccumulatedDaily") } - property VBusItem functionEnabled: VBusItem { bind: Utils.path(startStopBindPrefix, "/State") } - - function getState() - { - if (generatorState.value === 10) - return qsTr("Error") - - switch(activeCondition.value) { - case 'soc': - return qsTr("Running by SOC condition") - case 'acload': - return qsTr("Running by AC Load condition") - case 'batterycurrent': - return qsTr("Running by battery current condition") - case 'batteryvoltage': - return qsTr("Running by battery voltage condition") - case 'inverterhightemp': - return qsTr("Running by inverter high temperature") - case 'inverteroverload': - return qsTr("Running by inverter overload") - case 'testrun': - return qsTr("Test run") - case 'lossofcommunication': - return qsTr("Running by loss of communication") - case 'manual': - return qsTr("Manually started") - default: - return qsTr("Stopped") - } - } - - model: startStopModel - - function formatError(text, value) - { - return "#" + value.toString() + " " + text - } - - VisibleItemModel { - id: _startStopModel - - MbItemValue { - description: qsTr("State") - item.text: activeCondition.valid ? getState() : '---' - } - - MbItemOptions { - id: _gensetStatus - description: qsTr("Error") - bind: Utils.path(startStopBindPrefix, "/Error") - readonly: true - show: valid - possibleValues: [ - MbOption { description: qsTr("No error"); value: 0 }, - MbOption { description: formatError(qsTr("Remote switch control disabled"), 1); value: 1 }, - MbOption { description: formatError(qsTr("Generator in fault condition"), 2); value: 2 }, - MbOption { description: formatError(qsTr("Generator not detected at AC input"), 3); value: 3 } - ] - } - - MbItemValue { - description: qsTr("Run time") - item.text: runningTime.valid ? Utils.secondsToNoSecsString(runningTime.value) : "0" - show: generatorState.value === 1 - } - - MbItemValue { - description: qsTr("Total run time") - item { - bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") - text: Utils.secondsToNoSecsString(item.value) - } - } - - MbItemValue { - description: qsTr("Accumulated running time since last test run") - show: user.accessLevel >= User.AccessService && nextTestRun.show - backgroundColor: style.backgroundColorService - item { - text: Utils.secondsToNoSecsString(item.value) - bind: Utils.path(startStopBindPrefix, "/TestRunIntervalRuntime") - } - } - - MbItemValue { - id: nextTestRun - description: qsTr("Time to next test run") - show: item.valid && item.value > 0 - item { - text: { - var remainingTime = item.value - new Date().getTime() / 1000 - if (remainingTime > 0) - return Utils.secondsToNoSecsString(remainingTime).toString() - return qsTr("Running now") - } - bind: Utils.path(startStopBindPrefix, "/NextTestRun") - } - } - - MbSwitch { - name: qsTr("Auto start functionality") - bind: Utils.path(settingsBindPrefix, "/AutoStartEnabled") - show: allowDisableAutostart - } - - MbSubMenu { - description: qsTr("Manual start") - subpage: Component { - MbPage { - id: manualStartPage - title: qsTr("Manual start") - model: VisibleItemModel { - MbSwitch { - id: manualSwitch - name: qsTr("Start generator") - bind: Utils.path(startStopBindPrefix, "/ManualStart") - writeAccessLevel: User.AccessUser - onCheckedChanged: { - if (manualStartPage.active) { - if (!checked) - toast.createToast(qsTr("Stopping, generator will continue running if other conditions are reached"), 3000) - if (checked && stopTimer.value == 0) - toast.createToast(qsTr("Starting, generator won't stop till user intervention"), 5000) - if (checked && stopTimer.value > 0) - toast.createToast(qsTr("Starting. The generator will stop in %1, unless other conditions keep it running").arg(Utils.secondsToString(stopTimer.value)), 5000) - } - } - - VBusItem { - id: stopTimer - bind: Utils.path(startStopBindPrefix, "/ManualStartTimer") - } - } - - MbEditBoxTime { - description: qsTr("Run for (hh:mm)") - readonly: manualSwitch.checked - item.bind: Utils.path(startStopBindPrefix, "/ManualStartTimer") - writeAccessLevel: User.AccessUser - } - } - } - } - } - - MbSubMenu { - description: qsTr("Daily run time") - subpage: MbPage { - // Invert the order - property variant keys: historicalData.valid ? - Object.keys(JSON.parse(historicalData.value)).reverse() : 0 - - title: qsTr("Daily run time") - focus: active - model: keys - delegate: MbItemValue { - description: Qt.formatDate(new Date(parseInt(keys[index]) * 1000), "dd-MM-yyyy"); - item.text: Utils.secondsToNoSecsString(JSON.parse(historicalData.value)[keys[index]]) - } - } - } - - MbSubMenu { - id: conditions - description: qsTr("Settings") - subpage: Component { - PageSettingsGenerator { - settingsBindPrefix: root.settingsBindPrefix - startStopBindPrefix: root.startStopBindPrefix - } - } - } - } -} diff --git a/FileSets/v3.00~32/PageMain.qml b/FileSets/v3.00~32/PageMain.qml deleted file mode 120000 index 2f68fb1c..00000000 --- a/FileSets/v3.00~32/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.14/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/PageSettingsDisplay.qml b/FileSets/v3.00~32/PageSettingsDisplay.qml deleted file mode 120000 index 009d0dcd..00000000 --- a/FileSets/v3.00~32/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/PageSettingsGenerator.qml b/FileSets/v3.00~32/PageSettingsGenerator.qml deleted file mode 100644 index 8e24f445..00000000 --- a/FileSets/v3.00~32/PageSettingsGenerator.qml +++ /dev/null @@ -1,192 +0,0 @@ -//// GuiMods -//// addd service interval and reset -//// added link to external state enable - -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: root - title: qsTr("Generator start/stop settings") - property string settingsBindPrefix - property string startStopBindPrefix - - model: VisibleItemModel { - - MbSubMenu { - id: conditions - description: qsTr("Conditions") - subpage: - Component { - PageGeneratorConditions { - title: qsTr("Conditions") - bindPrefix: root.settingsBindPrefix - } - } - } - - MbSpinBox { - description: qsTr("Minimum run time") - item { - bind: Utils.path(settingsBindPrefix, "/MinimumRuntime") - unit: "m" - decimals: 0 - step: 1 - } - } - - MbSwitch { -//// GuiMods - id: detectGeneratorAtAcIn - - property bool generatorIsSet: acIn1Source.value === 2 || acIn2Source.value === 2 - name: qsTr("Detect generator at AC input") - bind: Utils.path(settingsBindPrefix, "/Alarms/NoGeneratorAtAcIn") - enabled: valid && (generatorIsSet || checked) - onClicked: { - if (!checked) { - if (!generatorIsSet) { - toast.createToast(qsTr("None of the AC inputs is set to generator. Go to the system setup page and set the correct " + - "AC input to generator in order to enable this functionality."), 10000, "icon-info-active") - } else { - toast.createToast(qsTr("An alarm will be triggered when no power from the generator is detected at the inverter AC input. " + - "Make sure that the correct AC input is set to generator on the system setup page."), 12000, "icon-info-active") - } - } - } - -//// GuiMods - MbSwitch { - name: qsTr("Link to external running state") - bind: Utils.path(settingsBindPrefix, "/LinkToExternalStatus") - onClicked: - { - if (!checked) - toast.createToast(qsTr("Manual run will be synchronized with the generaror 'is running digital input' or AC input"), 10000, "icon-info-active") - } - } - - VBusItem { - id: acIn1Source - bind: "com.victronenergy.settings/Settings/SystemSetup/AcInput1" - } - - VBusItem { - id: acIn2Source - bind: "com.victronenergy.settings/Settings/SystemSetup/AcInput2" - } - - MbSwitch { - id: timeZones - name: qsTr("Quiet hours") - bind: Utils.path(settingsBindPrefix, "/QuietHours/Enabled") - enabled: valid - writeAccessLevel: User.AccessUser - } - - MbEditBoxTime { - description: qsTr("Quiet hours start time") - item.bind: Utils.path(settingsBindPrefix, "/QuietHours/StartTime") - show: timeZones.checked - writeAccessLevel: User.AccessUser - } - - MbEditBoxTime { - description: qsTr("Quiet hours end time") - item.bind: Utils.path(settingsBindPrefix, "/QuietHours/EndTime") - show: timeZones.checked - writeAccessLevel: User.AccessUser - } - - MbOK { - description: qsTr("Reset daily run time counters") - value: qsTr("Press to reset") - enabled: true - editable: enabled - onClicked: { - if (state.value === 0) { - var now = new Date() - var today = new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate())) - var todayInSeconds = today.getTime() / 1000 - resetDaily.setValue('{"%1" : 0}'.arg(todayInSeconds.toString())) - toast.createToast(qsTr("The daily runtime counter has been reset")) - } else if (state.value === 1) { - toast.createToast(qsTr("It is not possible to modify the counters while the generator is running")) - } - } - - VBusItem { - id: resetDaily - bind: Utils.path(settingsBindPrefix, "/AccumulatedDaily") - } - } - - MbEditBox { - id: setTotalRunTime - description: qsTr("Generator total run time (hours)") - item { - bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") - text: Math.round(item.value / 60 / 60) - } -//// added to avoid full keyboard - numericOnlyLayout: true - matchString: "0123456789" - maximumLength: 6 - ignoreChars: "h" - enabled: state.value === 0 - - function editTextToValue() { - return parseInt(_editText, 10) * 60 * 60 - } - - Keys.onSpacePressed: { - if (!enabled) - toast.createToast(qsTr("It is not possible to modify the counters while the generator is running")) - } - } - } - -//// GuiMods - MbEditBox - { - id: serviceInterval - description: qsTr("Generator service interval (hours)") - item { - bind: Utils.path(settingsBindPrefix, "/ServiceInterval") - text: Math.round(item.value / 60 / 60) - } - numericOnlyLayout: true - matchString: "0123456789" - maximumLength: 6 - ignoreChars: "h" - - function editTextToValue() { - return parseInt(_editText, 10) * 60 * 60 - } - } - MbOK - { - description: qsTr("Reset service timer") - value: qsTr("Press to reset") - show: timeSinceService.valid && timeSinceService.value > 0 - editable: true - VBusItem - { - id: timeSinceService - bind: Utils.path(settingsBindPrefix, "/TimeSinceService") - } - - function clicked() - { - timeSinceService.setValue (0) - toast.createToast(qsTr("the service timer has been reset to ") + (serviceInterval.item.value / 3600).toFixed (0) + "h") - } - } - } - - VBusItem { - id: state - bind: Utils.path(startStopBindPrefix, "/State") - } -} diff --git a/FileSets/v3.00~32/PageSettingsGenerator.qml.orig b/FileSets/v3.00~32/PageSettingsGenerator.qml.orig deleted file mode 100644 index 88366179..00000000 --- a/FileSets/v3.00~32/PageSettingsGenerator.qml.orig +++ /dev/null @@ -1,135 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: root - title: qsTr("Generator start/stop settings") - property string settingsBindPrefix - property string startStopBindPrefix - - model: VisibleItemModel { - - MbSubMenu { - id: conditions - description: qsTr("Conditions") - subpage: - Component { - PageGeneratorConditions { - title: qsTr("Conditions") - bindPrefix: root.settingsBindPrefix - } - } - } - - MbSpinBox { - description: qsTr("Minimum run time") - item { - bind: Utils.path(settingsBindPrefix, "/MinimumRuntime") - unit: "m" - decimals: 0 - step: 1 - } - } - - MbSwitch { - property bool generatorIsSet: acIn1Source.value === 2 || acIn2Source.value === 2 - name: qsTr("Detect generator at AC input") - bind: Utils.path(settingsBindPrefix, "/Alarms/NoGeneratorAtAcIn") - enabled: valid && (generatorIsSet || checked) - onClicked: { - if (!checked) { - if (!generatorIsSet) { - toast.createToast(qsTr("None of the AC inputs is set to generator. Go to the system setup page and set the correct " + - "AC input to generator in order to enable this functionality."), 10000, "icon-info-active") - } else { - toast.createToast(qsTr("An alarm will be triggered when no power from the generator is detected at the inverter AC input. " + - "Make sure that the correct AC input is set to generator on the system setup page."), 12000, "icon-info-active") - } - } - } - - VBusItem { - id: acIn1Source - bind: "com.victronenergy.settings/Settings/SystemSetup/AcInput1" - } - - VBusItem { - id: acIn2Source - bind: "com.victronenergy.settings/Settings/SystemSetup/AcInput2" - } - } - - MbSwitch { - id: timeZones - name: qsTr("Quiet hours") - bind: Utils.path(settingsBindPrefix, "/QuietHours/Enabled") - enabled: valid - writeAccessLevel: User.AccessUser - } - - MbEditBoxTime { - description: qsTr("Quiet hours start time") - item.bind: Utils.path(settingsBindPrefix, "/QuietHours/StartTime") - show: timeZones.checked - writeAccessLevel: User.AccessUser - } - - MbEditBoxTime { - description: qsTr("Quiet hours end time") - item.bind: Utils.path(settingsBindPrefix, "/QuietHours/EndTime") - show: timeZones.checked - writeAccessLevel: User.AccessUser - } - - MbOK { - description: qsTr("Reset daily run time counters") - value: qsTr("Press to reset") - enabled: true - editable: enabled - onClicked: { - if (state.value === 0) { - var now = new Date() - var today = new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate())) - var todayInSeconds = today.getTime() / 1000 - resetDaily.setValue('{"%1" : 0}'.arg(todayInSeconds.toString())) - toast.createToast(qsTr("The daily runtime counter has been reset")) - } else if (state.value === 1) { - toast.createToast(qsTr("It is not possible to modify the counters while the generator is running")) - } - } - - VBusItem { - id: resetDaily - bind: Utils.path(settingsBindPrefix, "/AccumulatedDaily") - } - } - - MbEditBox { - id: setTotalRunTime - description: qsTr("Generator total run time (hours)") - item { - bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") - text: Math.round(item.value / 60 / 60) - } - matchString: "0123456789" - maximumLength: 6 - ignoreChars: "h" - enabled: state.value === 0 - - function editTextToValue() { - return parseInt(_editText, 10) * 60 * 60 - } - - Keys.onSpacePressed: { - if (!enabled) - toast.createToast(qsTr("It is not possible to modify the counters while the generator is running")) - } - } - } - - VBusItem { - id: state - bind: Utils.path(startStopBindPrefix, "/State") - } -} diff --git a/FileSets/v3.00~32/PageSettingsGuiMods.qml b/FileSets/v3.00~32/PageSettingsGuiMods.qml deleted file mode 120000 index 072d9988..00000000 --- a/FileSets/v3.00~32/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/PageSettingsRelay.qml b/FileSets/v3.00~32/PageSettingsRelay.qml deleted file mode 120000 index 1b7ab4e1..00000000 --- a/FileSets/v3.00~32/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.22/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/PowerGauge.qml b/FileSets/v3.00~32/PowerGauge.qml deleted file mode 120000 index d82ac28a..00000000 --- a/FileSets/v3.00~32/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/Tile.qml b/FileSets/v3.00~32/Tile.qml deleted file mode 120000 index 0558cecf..00000000 --- a/FileSets/v3.00~32/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/TileDigIn.qml b/FileSets/v3.00~32/TileDigIn.qml deleted file mode 120000 index 5e8ba09e..00000000 --- a/FileSets/v3.00~32/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/TileRelay.qml b/FileSets/v3.00~32/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.00~32/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/TileText.qml b/FileSets/v3.00~32/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v3.00~32/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/attributes.csv b/FileSets/v3.00~32/attributes.csv deleted file mode 120000 index 151259cd..00000000 --- a/FileSets/v3.00~32/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v3.01/attributes.csv \ No newline at end of file diff --git a/FileSets/v3.00~32/dbus_digitalinputs.py b/FileSets/v3.00~32/dbus_digitalinputs.py deleted file mode 120000 index 25f64663..00000000 --- a/FileSets/v3.00~32/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v3.01/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.00~32/dbus_generator.py b/FileSets/v3.00~32/dbus_generator.py deleted file mode 100755 index 0702f5eb..00000000 --- a/FileSets/v3.00~32/dbus_generator.py +++ /dev/null @@ -1,339 +0,0 @@ -#!/usr/bin/python3 -u -# -*- coding: utf-8 -*- - -#### GuiMods -#### This file has been modified to allow the generator running state derived from the generator digital input -#### or the genset AC input -#### If the incoming generator state changes, the manual start state is updated -#### time accumulation is suspended when the generator is not running -#### A switch in the generator settings menucontrols whethter the incoming state affects manual start or time accumulaiton -#### It is now possible to start the generator manually and have it stop automatically based on the preset conditions -#### for automaitc start / stop -#### A service interval timer was added so the accumulated run time does not need to be reset, -#### providing total run time for the generator -#### Search for #### GuiMods to find changes - -from dbus.mainloop.glib import DBusGMainLoop -import dbus -import argparse -import sys -import os -import signal -from gi.repository import GLib - -# Victron packages -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) -from vedbus import VeDbusService -from ve_utils import exit_on_error -from dbusmonitor import DbusMonitor -from settingsdevice import SettingsDevice -from logger import setup_logging -import logging -from gen_utils import dummy -import time -import relay -import fischerpanda -from version import softwareversion - -class Generator(object): - def __init__(self): - self._exit = False - self._instances = {} - self._modules = [relay, fischerpanda] - - # Common dbus services/path - commondbustree = { - 'com.victronenergy.settings': { - '/Settings/System/TimeZone': dummy, -#### GuiMods - paths are not correct in stock files - '/Settings/SystemSetup/AcInput1': dummy, - '/Settings/SystemSetup/AcInput2': dummy, - - '/Settings/Relay/Polarity': dummy - }, - 'com.victronenergy.battery': { - '/Dc/0/Voltage': dummy, - '/Dc/0/Current': dummy, - '/Dc/1/Voltage': dummy, - '/Dc/1/Current': dummy, - '/Soc': dummy - }, - 'com.victronenergy.vebus': { - '/Ac/Out/L1/P': dummy, - '/Ac/Out/L2/P': dummy, - '/Ac/Out/L3/P': dummy, - '/Alarms/L1/Overload': dummy, - '/Alarms/L2/Overload': dummy, - '/Alarms/L3/Overload': dummy, - '/Alarms/L1/HighTemperature': dummy, - '/Alarms/L2/HighTemperature': dummy, - '/Alarms/L3/HighTemperature': dummy, - '/Alarms/HighTemperature': dummy, - '/Alarms/Overload': dummy, - '/Ac/ActiveIn/ActiveInput': dummy, - '/Ac/ActiveIn/Connected': dummy, - '/Dc/0/Voltage': dummy, - '/Dc/0/Current': dummy, - '/Dc/1/Voltage': dummy, - '/Dc/1/Current': dummy, - '/Soc': dummy - }, - 'com.victronenergy.system': { - '/Ac/ConsumptionOnInput/L1/Power': dummy, - '/Ac/ConsumptionOnInput/L2/Power': dummy, - '/Ac/ConsumptionOnInput/L3/Power': dummy, - '/Ac/ConsumptionOnOutput/L1/Power': dummy, - '/Ac/ConsumptionOnOutput/L2/Power': dummy, - '/Ac/ConsumptionOnOutput/L3/Power': dummy, - '/Dc/Pv/Power': dummy, - '/AutoSelectedBatteryMeasurement': dummy, - '/Ac/ActiveIn/Source': dummy, - '/VebusService': dummy, - '/Dc/Battery/Voltage': dummy, - '/Dc/Battery/Current': dummy, - '/Dc/Battery/Soc': dummy, -#### GuiMods - '/Ac/Genset/Frequency': dummy, - '/Ac/In/NumberOfAcInputs': dummy - } - } - - # Settings base - settingsbase = { - 'autostart': ['/Settings/{0}/AutoStartEnabled', 0, 0, 1], - 'batterymeasurement': ['/Settings/{0}/Service', '', 0, 0], - 'accumulateddaily': ['/Settings/{0}/AccumulatedDaily', '', 0, 0, True], - 'accumulatedtotal': ['/Settings/{0}/AccumulatedTotal', 0, 0, 0, True], -#### GuiMods - 'timeSinceService': ['/Settings/{0}/TimeSinceService', 0, 0, 0, True], - 'linkManualStartToExternal': ['/Settings/{0}/LinkToExternalStatus', 0, 0, 0, True], - - 'batterymeasurement': ['/Settings/{0}/BatteryService', 'default', 0, 0], - 'minimumruntime': ['/Settings/{0}/MinimumRuntime', 0, 0, 86400], # minutes - 'stoponac1enabled': ['/Settings/{0}/StopWhenAc1Available', 0, 0, 10], - # On permanent loss of communication: 0 = Stop, 1 = Start, 2 = keep running - 'onlosscommunication': ['/Settings/{0}/OnLossCommunication', 0, 0, 2], - # Quiet hours - 'quiethoursenabled': ['/Settings/{0}/QuietHours/Enabled', 0, 0, 1], - 'quiethoursstarttime': ['/Settings/{0}/QuietHours/StartTime', 75600, 0, 86400], - 'quiethoursendtime': ['/Settings/{0}/QuietHours/EndTime', 21600, 0, 86400], - # SOC - 'socenabled': ['/Settings/{0}/Soc/Enabled', 0, 0, 1], - 'socstart': ['/Settings/{0}/Soc/StartValue', 80, 0, 100], - 'socstop': ['/Settings/{0}/Soc/StopValue', 90, 0, 100], - 'qh_socstart': ['/Settings/{0}/Soc/QuietHoursStartValue', 90, 0, 100], - 'qh_socstop': ['/Settings/{0}/Soc/QuietHoursStopValue', 90, 0, 100], - # Voltage - 'batteryvoltageenabled': ['/Settings/{0}/BatteryVoltage/Enabled', 0, 0, 1], - 'batteryvoltagestart': ['/Settings/{0}/BatteryVoltage/StartValue', 11.5, 0, 150], - 'batteryvoltagestop': ['/Settings/{0}/BatteryVoltage/StopValue', 12.4, 0, 150], - 'batteryvoltagestarttimer': ['/Settings/{0}/BatteryVoltage/StartTimer', 20, 0, 10000], - 'batteryvoltagestoptimer': ['/Settings/{0}/BatteryVoltage/StopTimer', 20, 0, 10000], - 'qh_batteryvoltagestart': ['/Settings/{0}/BatteryVoltage/QuietHoursStartValue', 11.9, 0, 100], - 'qh_batteryvoltagestop': ['/Settings/{0}/BatteryVoltage/QuietHoursStopValue', 12.4, 0, 100], - # Current - 'batterycurrentenabled': ['/Settings/{0}/BatteryCurrent/Enabled', 0, 0, 1], - 'batterycurrentstart': ['/Settings/{0}/BatteryCurrent/StartValue', 10.5, 0.5, 10000], - 'batterycurrentstop': ['/Settings/{0}/BatteryCurrent/StopValue', 5.5, 0, 10000], - 'batterycurrentstarttimer': ['/Settings/{0}/BatteryCurrent/StartTimer', 20, 0, 10000], - 'batterycurrentstoptimer': ['/Settings/{0}/BatteryCurrent/StopTimer', 20, 0, 10000], - 'qh_batterycurrentstart': ['/Settings/{0}/BatteryCurrent/QuietHoursStartValue', 20.5, 0, 10000], - 'qh_batterycurrentstop': ['/Settings/{0}/BatteryCurrent/QuietHoursStopValue', 15.5, 0, 10000], - # AC load - 'acloadenabled': ['/Settings/{0}/AcLoad/Enabled', 0, 0, 1], - # Measuerement, 0 = Total AC consumption, 1 = AC on inverter output, 2 = Single phase - 'acloadmeasuerment': ['/Settings/{0}/AcLoad/Measurement', 0, 0, 100], - 'acloadstart': ['/Settings/{0}/AcLoad/StartValue', 1600, 5, 1000000], - 'acloadstop': ['/Settings/{0}/AcLoad/StopValue', 800, 0, 1000000], - 'acloadstarttimer': ['/Settings/{0}/AcLoad/StartTimer', 20, 0, 10000], - 'acloadstoptimer': ['/Settings/{0}/AcLoad/StopTimer', 20, 0, 10000], - 'qh_acloadstart': ['/Settings/{0}/AcLoad/QuietHoursStartValue', 1900, 0, 1000000], - 'qh_acloadstop': ['/Settings/{0}/AcLoad/QuietHoursStopValue', 1200, 0, 1000000], - # VE.Bus high temperature - 'inverterhightempenabled': ['/Settings/{0}/InverterHighTemp/Enabled', 0, 0, 1], - 'inverterhightempstarttimer': ['/Settings/{0}/InverterHighTemp/StartTimer', 20, 0, 10000], - 'inverterhightempstoptimer': ['/Settings/{0}/InverterHighTemp/StopTimer', 20, 0, 10000], - # VE.Bus overload - 'inverteroverloadenabled': ['/Settings/{0}/InverterOverload/Enabled', 0, 0, 1], - 'inverteroverloadstarttimer': ['/Settings/{0}/InverterOverload/StartTimer', 20, 0, 10000], - 'inverteroverloadstoptimer': ['/Settings/{0}/InverterOverload/StopTimer', 20, 0, 10000], - # TestRun - 'testrunenabled': ['/Settings/{0}/TestRun/Enabled', 0, 0, 1], - 'testrunstartdate': ['/Settings/{0}/TestRun/StartDate', 1483228800, 0, 10000000000.1], - 'testrunstarttimer': ['/Settings/{0}/TestRun/StartTime', 54000, 0, 86400], - 'testruninterval': ['/Settings/{0}/TestRun/Interval', 28, 1, 365], - 'testrunruntime': ['/Settings/{0}/TestRun/Duration', 7200, 1, 86400], - 'testrunskipruntime': ['/Settings/{0}/TestRun/SkipRuntime', 0, 0, 100000], - 'testruntillbatteryfull': ['/Settings/{0}/TestRun/RunTillBatteryFull', 0, 0, 1], - # Alarms - 'nogeneratoratacinalarm': ['/Settings/{0}/Alarms/NoGeneratorAtAcIn', 0, 0, 1] - } - - settings = {} - dbus_tree = dict(commondbustree) - - for m in self._modules: - # Create settings for each module - # Settings are created under the module prefix, for example: - # /Settings/Generator0/AcLoad/Enabled - # /Settings/FischerPanda0/AcLoad/Enabled - for s in settingsbase: - v = settingsbase[s][:] # Copy - v[0] = v[0].format(m.name) - settings[s + m.name] = v - - # Get all services/paths that must be monitored - # There are a base of common services/pathas that must be monitored - # for the correct function such as battery monitors of vebus devices - # and a extra ones that is only used by a certain module, these - # are mainly the "remote switch". - for i in m.monitoring: - if i in commondbustree: - for s in m.monitoring[i]: - dbus_tree[i][s] = m.monitoring[i][s] - else: - dbus_tree[i] = m.monitoring[i] - - # Create settings device which is shared - self._settings = self._create_settings(settings, self._handlechangedsetting) - - # Create dbusmonitor, this is shared by all the instances - self._dbusmonitor = self._create_dbus_monitor(dbus_tree, valueChangedCallback=self._dbus_value_changed, - deviceAddedCallback=self._device_added, deviceRemovedCallback=self._device_removed) - - # Set timezone to user selected timezone - tz = self._dbusmonitor.get_value('com.victronenergy.settings', '/Settings/System/TimeZone') - os.environ['TZ'] = tz if tz else 'UTC' - time.tzset() - - # Call device_added for all existing devices at startup. - for service, instance in self._dbusmonitor.get_service_list().items(): - self._device_added(service, instance) - - GLib.timeout_add(1000, exit_on_error, self._handletimertick) - - def _handlechangedsetting(self, setting, oldvalue, newvalue): - for i in self._instances: - self._instances[i].handlechangedsetting(setting, oldvalue, newvalue) - - def _device_added(self, dbusservicename, instance): - # If settings check built-in relays - if dbusservicename == 'com.victronenergy.settings': - self._handle_builtin_relay('/Settings/Relay/Function') - - self._add_device(dbusservicename) - - for i in self._instances: - self._instances[i].device_added(dbusservicename, instance) - - def _dbus_value_changed(self, dbusServiceName, dbusPath, options, changes, deviceInstance): - # Track built-in relays - if "/Settings/Relay/Function" in dbusPath: - self._handle_builtin_relay(dbusPath) - - # Some devices like Fischer Panda gensets doesn't disappear from dbus - # when disconnected so check '/Connected' value to add or remove start/stop - # for that device - if dbusPath == "/Connected": - if self._dbusmonitor.get_value(dbusServiceName, dbusPath) == 0: - self._remove_device(dbusServiceName) - else: - self._add_device(dbusServiceName) - - # Update env timezone when setting changes - if (dbusServiceName, dbusPath) == ('com.victronenergy.settings', '/Settings/System/TimeZone'): - os.environ['TZ'] = changes['Value'] if changes['Value'] else 'UTC' - time.tzset() - - for i in self._instances: - self._instances[i].dbus_value_changed(dbusServiceName, dbusPath, options, changes, deviceInstance) - - def _device_removed(self, dbusservicename, instance): - if dbusservicename == 'com.victronenergy.settings': - self._handle_builtin_relay('/Settings/Relay/Function') - for i in self._instances: - self._instances[i].device_removed(dbusservicename, instance) - self._remove_device(dbusservicename) - - def _create_dbus_monitor(self, *args, **kwargs): - return DbusMonitor(*args, **kwargs) - - def _create_settings(self, *args, **kwargs): - bus = dbus.SessionBus() if 'DBUS_SESSION_BUS_ADDRESS' in os.environ else dbus.SystemBus() - return SettingsDevice(bus, *args, timeout=10, **kwargs) - - def _add_device(self, service): - for i in self._modules: - # Check if module can handle this service - if i.remoteprefix not in service: - continue - # Check and create start/stop instance for the device - if i.check_device(self._dbusmonitor, service): - self._instances[service] = i.create(self._dbusmonitor, - service, self._settings, i.device_instance) - - def _handle_builtin_relay(self, dbuspath): - function = self._dbusmonitor.get_value('com.victronenergy.settings', dbuspath) - relaynr = 'generator0' - relayservice = 'com.victronenergy.system' - - # Create a instance if relay function is set to 1 (gen. start/stop) - # otherwise remove the instance if exists - if function == 1: - self._instances[relaynr] = relay.create(self._dbusmonitor, - relayservice, - self._settings, relay.device_instance) - elif relaynr in self._instances: - self._instances[relaynr].remove() - del self._instances[relaynr] - - def _remove_device(self, servicename): - if servicename in self._instances: - if self._instances[servicename] is not None: - self._instances[servicename].remove() - del self._instances[servicename] - - def terminate(self, signum, frame): - # Remove instances before exiting, remote services might need to perform actions before releasing control - # of the switch - for i in self._instances: - self._instances[i].remove() - os._exit(0) - - def _handletimertick(self): - # try catch, to make sure that we kill ourselves on an error. Without this try-catch, there would - # be an error written to stdout, and then the timer would not be restarted, resulting in a dead- - # lock waiting for manual intervention -> not good! - try: - for i in self._instances: - self._instances[i].tick() - except: - self._instances[i].remove() - import traceback - traceback.print_exc() - sys.exit(1) - return True - -if __name__ == '__main__': - # Argument parsing - parser = argparse.ArgumentParser( - description='Start and stop a generator based on conditions' - ) - - parser.add_argument('-d', '--debug', help='set logging level to debug', - action='store_true') - args = parser.parse_args() - - print ('-------- dbus_generator, v' + softwareversion + ' is starting up --------') - - logger = setup_logging(args.debug) - - # Have a mainloop, so we can send/receive asynchronous calls to and from dbus - DBusGMainLoop(set_as_default=True) - - generator = Generator() - signal.signal(signal.SIGTERM, generator.terminate) - - # Start and run the mainloop - mainloop = GLib.MainLoop() - mainloop.run() diff --git a/FileSets/v3.00~32/dbus_generator.py.orig b/FileSets/v3.00~32/dbus_generator.py.orig deleted file mode 100755 index 45d603e4..00000000 --- a/FileSets/v3.00~32/dbus_generator.py.orig +++ /dev/null @@ -1,318 +0,0 @@ -#!/usr/bin/python3 -u -# -*- coding: utf-8 -*- - -from dbus.mainloop.glib import DBusGMainLoop -import dbus -import argparse -import sys -import os -import signal -from gi.repository import GLib - -# Victron packages -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) -from vedbus import VeDbusService -from ve_utils import exit_on_error -from dbusmonitor import DbusMonitor -from settingsdevice import SettingsDevice -from logger import setup_logging -import logging -from gen_utils import dummy -import time -import relay -import fischerpanda -from version import softwareversion - -class Generator(object): - def __init__(self): - self._exit = False - self._instances = {} - self._modules = [relay, fischerpanda] - - # Common dbus services/path - commondbustree = { - 'com.victronenergy.settings': { - '/Settings/System/TimeZone': dummy, - '/Settings/System/AcInput1': dummy, - '/Settings/System/AcInput2': dummy, - '/Settings/Relay/Polarity': dummy - }, - 'com.victronenergy.battery': { - '/Dc/0/Voltage': dummy, - '/Dc/0/Current': dummy, - '/Dc/1/Voltage': dummy, - '/Dc/1/Current': dummy, - '/Soc': dummy - }, - 'com.victronenergy.vebus': { - '/Ac/Out/L1/P': dummy, - '/Ac/Out/L2/P': dummy, - '/Ac/Out/L3/P': dummy, - '/Alarms/L1/Overload': dummy, - '/Alarms/L2/Overload': dummy, - '/Alarms/L3/Overload': dummy, - '/Alarms/L1/HighTemperature': dummy, - '/Alarms/L2/HighTemperature': dummy, - '/Alarms/L3/HighTemperature': dummy, - '/Alarms/HighTemperature': dummy, - '/Alarms/Overload': dummy, - '/Ac/ActiveIn/ActiveInput': dummy, - '/Ac/ActiveIn/Connected': dummy, - '/Dc/0/Voltage': dummy, - '/Dc/0/Current': dummy, - '/Dc/1/Voltage': dummy, - '/Dc/1/Current': dummy, - '/Soc': dummy - }, - 'com.victronenergy.system': { - '/Ac/ConsumptionOnInput/L1/Power': dummy, - '/Ac/ConsumptionOnInput/L2/Power': dummy, - '/Ac/ConsumptionOnInput/L3/Power': dummy, - '/Ac/ConsumptionOnOutput/L1/Power': dummy, - '/Ac/ConsumptionOnOutput/L2/Power': dummy, - '/Ac/ConsumptionOnOutput/L3/Power': dummy, - '/Dc/Pv/Power': dummy, - '/AutoSelectedBatteryMeasurement': dummy, - '/Ac/ActiveIn/Source': dummy, - '/VebusService': dummy, - '/Dc/Battery/Voltage': dummy, - '/Dc/Battery/Current': dummy, - '/Dc/Battery/Soc': dummy - } - } - - # Settings base - settingsbase = { - 'autostart': ['/Settings/{0}/AutoStartEnabled', 0, 0, 1], - 'batterymeasurement': ['/Settings/{0}/Service', '', 0, 0], - 'accumulateddaily': ['/Settings/{0}/AccumulatedDaily', '', 0, 0, True], - 'accumulatedtotal': ['/Settings/{0}/AccumulatedTotal', 0, 0, 0, True], - 'batterymeasurement': ['/Settings/{0}/BatteryService', 'default', 0, 0], - 'minimumruntime': ['/Settings/{0}/MinimumRuntime', 0, 0, 86400], # minutes - 'stoponac1enabled': ['/Settings/{0}/StopWhenAc1Available', 0, 0, 10], - # On permanent loss of communication: 0 = Stop, 1 = Start, 2 = keep running - 'onlosscommunication': ['/Settings/{0}/OnLossCommunication', 0, 0, 2], - # Quiet hours - 'quiethoursenabled': ['/Settings/{0}/QuietHours/Enabled', 0, 0, 1], - 'quiethoursstarttime': ['/Settings/{0}/QuietHours/StartTime', 75600, 0, 86400], - 'quiethoursendtime': ['/Settings/{0}/QuietHours/EndTime', 21600, 0, 86400], - # SOC - 'socenabled': ['/Settings/{0}/Soc/Enabled', 0, 0, 1], - 'socstart': ['/Settings/{0}/Soc/StartValue', 80, 0, 100], - 'socstop': ['/Settings/{0}/Soc/StopValue', 90, 0, 100], - 'qh_socstart': ['/Settings/{0}/Soc/QuietHoursStartValue', 90, 0, 100], - 'qh_socstop': ['/Settings/{0}/Soc/QuietHoursStopValue', 90, 0, 100], - # Voltage - 'batteryvoltageenabled': ['/Settings/{0}/BatteryVoltage/Enabled', 0, 0, 1], - 'batteryvoltagestart': ['/Settings/{0}/BatteryVoltage/StartValue', 11.5, 0, 150], - 'batteryvoltagestop': ['/Settings/{0}/BatteryVoltage/StopValue', 12.4, 0, 150], - 'batteryvoltagestarttimer': ['/Settings/{0}/BatteryVoltage/StartTimer', 20, 0, 10000], - 'batteryvoltagestoptimer': ['/Settings/{0}/BatteryVoltage/StopTimer', 20, 0, 10000], - 'qh_batteryvoltagestart': ['/Settings/{0}/BatteryVoltage/QuietHoursStartValue', 11.9, 0, 100], - 'qh_batteryvoltagestop': ['/Settings/{0}/BatteryVoltage/QuietHoursStopValue', 12.4, 0, 100], - # Current - 'batterycurrentenabled': ['/Settings/{0}/BatteryCurrent/Enabled', 0, 0, 1], - 'batterycurrentstart': ['/Settings/{0}/BatteryCurrent/StartValue', 10.5, 0.5, 10000], - 'batterycurrentstop': ['/Settings/{0}/BatteryCurrent/StopValue', 5.5, 0, 10000], - 'batterycurrentstarttimer': ['/Settings/{0}/BatteryCurrent/StartTimer', 20, 0, 10000], - 'batterycurrentstoptimer': ['/Settings/{0}/BatteryCurrent/StopTimer', 20, 0, 10000], - 'qh_batterycurrentstart': ['/Settings/{0}/BatteryCurrent/QuietHoursStartValue', 20.5, 0, 10000], - 'qh_batterycurrentstop': ['/Settings/{0}/BatteryCurrent/QuietHoursStopValue', 15.5, 0, 10000], - # AC load - 'acloadenabled': ['/Settings/{0}/AcLoad/Enabled', 0, 0, 1], - # Measuerement, 0 = Total AC consumption, 1 = AC on inverter output, 2 = Single phase - 'acloadmeasuerment': ['/Settings/{0}/AcLoad/Measurement', 0, 0, 100], - 'acloadstart': ['/Settings/{0}/AcLoad/StartValue', 1600, 5, 1000000], - 'acloadstop': ['/Settings/{0}/AcLoad/StopValue', 800, 0, 1000000], - 'acloadstarttimer': ['/Settings/{0}/AcLoad/StartTimer', 20, 0, 10000], - 'acloadstoptimer': ['/Settings/{0}/AcLoad/StopTimer', 20, 0, 10000], - 'qh_acloadstart': ['/Settings/{0}/AcLoad/QuietHoursStartValue', 1900, 0, 1000000], - 'qh_acloadstop': ['/Settings/{0}/AcLoad/QuietHoursStopValue', 1200, 0, 1000000], - # VE.Bus high temperature - 'inverterhightempenabled': ['/Settings/{0}/InverterHighTemp/Enabled', 0, 0, 1], - 'inverterhightempstarttimer': ['/Settings/{0}/InverterHighTemp/StartTimer', 20, 0, 10000], - 'inverterhightempstoptimer': ['/Settings/{0}/InverterHighTemp/StopTimer', 20, 0, 10000], - # VE.Bus overload - 'inverteroverloadenabled': ['/Settings/{0}/InverterOverload/Enabled', 0, 0, 1], - 'inverteroverloadstarttimer': ['/Settings/{0}/InverterOverload/StartTimer', 20, 0, 10000], - 'inverteroverloadstoptimer': ['/Settings/{0}/InverterOverload/StopTimer', 20, 0, 10000], - # TestRun - 'testrunenabled': ['/Settings/{0}/TestRun/Enabled', 0, 0, 1], - 'testrunstartdate': ['/Settings/{0}/TestRun/StartDate', 1483228800, 0, 10000000000.1], - 'testrunstarttimer': ['/Settings/{0}/TestRun/StartTime', 54000, 0, 86400], - 'testruninterval': ['/Settings/{0}/TestRun/Interval', 28, 1, 365], - 'testrunruntime': ['/Settings/{0}/TestRun/Duration', 7200, 1, 86400], - 'testrunskipruntime': ['/Settings/{0}/TestRun/SkipRuntime', 0, 0, 100000], - 'testruntillbatteryfull': ['/Settings/{0}/TestRun/RunTillBatteryFull', 0, 0, 1], - # Alarms - 'nogeneratoratacinalarm': ['/Settings/{0}/Alarms/NoGeneratorAtAcIn', 0, 0, 1] - } - - settings = {} - dbus_tree = dict(commondbustree) - - for m in self._modules: - # Create settings for each module - # Settings are created under the module prefix, for example: - # /Settings/Generator0/AcLoad/Enabled - # /Settings/FischerPanda0/AcLoad/Enabled - for s in settingsbase: - v = settingsbase[s][:] # Copy - v[0] = v[0].format(m.name) - settings[s + m.name] = v - - # Get all services/paths that must be monitored - # There are a base of common services/pathas that must be monitored - # for the correct function such as battery monitors of vebus devices - # and a extra ones that is only used by a certain module, these - # are mainly the "remote switch". - for i in m.monitoring: - if i in commondbustree: - for s in m.monitoring[i]: - dbus_tree[i][s] = m.monitoring[i][s] - else: - dbus_tree[i] = m.monitoring[i] - - # Create settings device which is shared - self._settings = self._create_settings(settings, self._handlechangedsetting) - - # Create dbusmonitor, this is shared by all the instances - self._dbusmonitor = self._create_dbus_monitor(dbus_tree, valueChangedCallback=self._dbus_value_changed, - deviceAddedCallback=self._device_added, deviceRemovedCallback=self._device_removed) - - # Set timezone to user selected timezone - tz = self._dbusmonitor.get_value('com.victronenergy.settings', '/Settings/System/TimeZone') - os.environ['TZ'] = tz if tz else 'UTC' - time.tzset() - - # Call device_added for all existing devices at startup. - for service, instance in self._dbusmonitor.get_service_list().items(): - self._device_added(service, instance) - - GLib.timeout_add(1000, exit_on_error, self._handletimertick) - - def _handlechangedsetting(self, setting, oldvalue, newvalue): - for i in self._instances: - self._instances[i].handlechangedsetting(setting, oldvalue, newvalue) - - def _device_added(self, dbusservicename, instance): - # If settings check built-in relays - if dbusservicename == 'com.victronenergy.settings': - self._handle_builtin_relay('/Settings/Relay/Function') - - self._add_device(dbusservicename) - - for i in self._instances: - self._instances[i].device_added(dbusservicename, instance) - - def _dbus_value_changed(self, dbusServiceName, dbusPath, options, changes, deviceInstance): - # Track built-in relays - if "/Settings/Relay/Function" in dbusPath: - self._handle_builtin_relay(dbusPath) - - # Some devices like Fischer Panda gensets doesn't disappear from dbus - # when disconnected so check '/Connected' value to add or remove start/stop - # for that device - if dbusPath == "/Connected": - if self._dbusmonitor.get_value(dbusServiceName, dbusPath) == 0: - self._remove_device(dbusServiceName) - else: - self._add_device(dbusServiceName) - - # Update env timezone when setting changes - if (dbusServiceName, dbusPath) == ('com.victronenergy.settings', '/Settings/System/TimeZone'): - os.environ['TZ'] = changes['Value'] if changes['Value'] else 'UTC' - time.tzset() - - for i in self._instances: - self._instances[i].dbus_value_changed(dbusServiceName, dbusPath, options, changes, deviceInstance) - - def _device_removed(self, dbusservicename, instance): - if dbusservicename == 'com.victronenergy.settings': - self._handle_builtin_relay('/Settings/Relay/Function') - for i in self._instances: - self._instances[i].device_removed(dbusservicename, instance) - self._remove_device(dbusservicename) - - def _create_dbus_monitor(self, *args, **kwargs): - return DbusMonitor(*args, **kwargs) - - def _create_settings(self, *args, **kwargs): - bus = dbus.SessionBus() if 'DBUS_SESSION_BUS_ADDRESS' in os.environ else dbus.SystemBus() - return SettingsDevice(bus, *args, timeout=10, **kwargs) - - def _add_device(self, service): - for i in self._modules: - # Check if module can handle this service - if i.remoteprefix not in service: - continue - # Check and create start/stop instance for the device - if i.check_device(self._dbusmonitor, service): - self._instances[service] = i.create(self._dbusmonitor, - service, self._settings, i.device_instance) - - def _handle_builtin_relay(self, dbuspath): - function = self._dbusmonitor.get_value('com.victronenergy.settings', dbuspath) - relaynr = 'generator0' - relayservice = 'com.victronenergy.system' - - # Create a instance if relay function is set to 1 (gen. start/stop) - # otherwise remove the instance if exists - if function == 1: - self._instances[relaynr] = relay.create(self._dbusmonitor, - relayservice, - self._settings, relay.device_instance) - elif relaynr in self._instances: - self._instances[relaynr].remove() - del self._instances[relaynr] - - def _remove_device(self, servicename): - if servicename in self._instances: - if self._instances[servicename] is not None: - self._instances[servicename].remove() - del self._instances[servicename] - - def terminate(self, signum, frame): - # Remove instances before exiting, remote services might need to perform actions before releasing control - # of the switch - for i in self._instances: - self._instances[i].remove() - os._exit(0) - - def _handletimertick(self): - # try catch, to make sure that we kill ourselves on an error. Without this try-catch, there would - # be an error written to stdout, and then the timer would not be restarted, resulting in a dead- - # lock waiting for manual intervention -> not good! - try: - for i in self._instances: - self._instances[i].tick() - except: - self._instances[i].remove() - import traceback - traceback.print_exc() - sys.exit(1) - return True - -if __name__ == '__main__': - # Argument parsing - parser = argparse.ArgumentParser( - description='Start and stop a generator based on conditions' - ) - - parser.add_argument('-d', '--debug', help='set logging level to debug', - action='store_true') - args = parser.parse_args() - - print ('-------- dbus_generator, v' + softwareversion + ' is starting up --------') - - logger = setup_logging(args.debug) - - # Have a mainloop, so we can send/receive asynchronous calls to and from dbus - DBusGMainLoop(set_as_default=True) - - generator = Generator() - signal.signal(signal.SIGTERM, generator.terminate) - - # Start and run the mainloop - mainloop = GLib.MainLoop() - mainloop.run() diff --git a/FileSets/v3.00~32/main.qml b/FileSets/v3.00~32/main.qml deleted file mode 120000 index 0cfb4fad..00000000 --- a/FileSets/v3.00~32/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.01/main.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/startstop.py b/FileSets/v3.00~32/startstop.py deleted file mode 100644 index c628a5dd..00000000 --- a/FileSets/v3.00~32/startstop.py +++ /dev/null @@ -1,1188 +0,0 @@ -#!/usr/bin/python -u -# -*- coding: utf-8 -*- - -#### GuiMods -#### This file has been modified to allow the generator running state derived from the generator digital input -#### or the genset AC input -#### If the incoming generator state changes, the manual start state is updated -#### time accumulation is suspended when the generator is not running -#### A switch in the generator settings menucontrols whethter the incoming state affects manual start or time accumulaiton -#### It is now possible to start the generator manually and have it stop automatically based on the preset conditions -#### for automaitc start / stop -#### A service interval timer was added so the accumulated run time does not need to be reset, -#### providing total run time for the generator -#### Search for #### GuiMods to find changes - -# Function -# dbus_generator monitors the dbus for batteries (com.victronenergy.battery.*) and -# vebus com.victronenergy.vebus.* -# Battery and vebus monitors can be configured through the gui. -# It then monitors SOC, AC loads, battery current and battery voltage,to auto start/stop the generator based -# on the configuration settings. Generator can be started manually or periodically setting a tes trun period. -# Time zones function allows to use different values for the conditions along the day depending on time - -import dbus -import datetime -import calendar -import time -import sys -import json -import os -import logging -from os import environ -import monotonic_time -from gen_utils import SettingsPrefix, Errors, States, enum -from gen_utils import create_dbus_service -# Victron packages -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) -from ve_utils import exit_on_error -from settingsdevice import SettingsDevice - -RunningConditions = enum( - Stopped = 0, - Manual = 1, - TestRun = 2, - LossOfCommunication = 3, - Soc = 4, - Acload = 5, - BatteryCurrent = 6, - BatteryVoltage = 7, - InverterHighTemp = 8, - InverterOverload = 9, - StopOnAc1 = 10) - -SYSTEM_SERVICE = 'com.victronenergy.system' -BATTERY_PREFIX = '/Dc/Battery' -HISTORY_DAYS = 30 - -def safe_max(args): - try: - return max(x for x in args if x is not None) - except ValueError: - return None - -class StartStop(object): - _driver = None - def __init__(self, instance): -#### GuiMods - self._last_update_mtime = 0 - self._accumulatedRunTime = 0 - self._digitalInputTypeObject = None - self._generatorInputStateObject = 0 - self._lastState = 0 - self._externalOverride = False - self._externalOverrideDelay = 99 - self._lastExternalOverride = False - self._searchDelay = 99 - self._linkToExternalState = False - - self._dbusservice = None - self._settings = None - self._dbusmonitor = None - self._remoteservice = None - self._name = None - self._enabled = False - self._instance = instance - - # One second per retry - self.RETRIES_ON_ERROR = 300 - self._testrun_soc_retries = 0 - self._last_counters_check = 0 - - self._starttime = 0 - self._manualstarttimer = 0 - self._last_runtime_update = 0 - self._timer_runnning = 0 - - # Manual battery service selection is deprecated in favour - # of getting the values directly from systemcalc, we keep - # manual selected services handling for compatibility reasons. - self._vebusservice = None - self._errorstate = 0 - self._battery_service = None - self._battery_prefix = None - - self._acpower_inverter_input = { - 'timeout': 0, - 'unabletostart': False - } - - self._condition_stack = { - 'batteryvoltage': { - 'name': 'batteryvoltage', - 'reached': False, - 'boolean': False, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'battery' - }, - 'batterycurrent': { - 'name': 'batterycurrent', - 'reached': False, - 'boolean': False, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'battery' - }, - 'acload': { - 'name': 'acload', - 'reached': False, - 'boolean': False, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - }, - 'inverterhightemp': { - 'name': 'inverterhightemp', - 'reached': False, - 'boolean': True, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - }, - 'inverteroverload': { - 'name': 'inverteroverload', - 'reached': False, - 'boolean': True, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - }, - 'soc': { - 'name': 'soc', - 'reached': False, - 'boolean': False, - 'timed': False, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'battery' - }, - 'stoponac1': { - 'name': 'stoponac1', - 'reached': False, - 'boolean': True, - 'timed': False, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - } - } - - def set_sources(self, dbusmonitor, settings, name, remoteservice): - self._settings = SettingsPrefix(settings, name) - self._dbusmonitor = dbusmonitor - self._remoteservice = remoteservice - self._name = name - - self.log_info('Start/stop instance created for %s.' % self._remoteservice) - self._remote_setup() - - def _create_service(self): - self._dbusservice = self._create_dbus_service() - - # The driver used for this start/stop service - self._dbusservice.add_path('/Type', value=self._driver) - # State: None = invalid, 0 = stopped, 1 = running - self._dbusservice.add_path('/State', value=None) - # RunningByConditionCode: Numeric Companion to /RunningByCondition below, but - # also encompassing a Stopped state. - self._dbusservice.add_path('/RunningByConditionCode', value=None) - # Error - self._dbusservice.add_path('/Error', value=None, gettextcallback=lambda p, v: Errors.get_description(v)) - # Condition that made the generator start - self._dbusservice.add_path('/RunningByCondition', value=None) - # Runtime - self._dbusservice.add_path('/Runtime', value=None, gettextcallback=self._seconds_to_text) - # Today runtime - self._dbusservice.add_path('/TodayRuntime', value=None, gettextcallback=self._seconds_to_text) - # Test run runtime - self._dbusservice.add_path('/TestRunIntervalRuntime', value=None , gettextcallback=self._seconds_to_text) - # Next test run date, values is 0 for test run disabled - self._dbusservice.add_path('/NextTestRun', value=None, gettextcallback=lambda p, v: datetime.datetime.fromtimestamp(v).strftime('%c')) - # Next test run is needed 1, not needed 0 - self._dbusservice.add_path('/SkipTestRun', value=None) - # Manual start - self._dbusservice.add_path('/ManualStart', value=None, writeable=True) - # Manual start timer - self._dbusservice.add_path('/ManualStartTimer', value=None, writeable=True) - # Silent mode active - self._dbusservice.add_path('/QuietHours', value=None) - # Alarms - self._dbusservice.add_path('/Alarms/NoGeneratorAtAcIn', value=None) - # Autostart - self._dbusservice.add_path('/AutoStartEnabled', value=None, writeable=True, onchangecallback=self._set_autostart) - # Accumulated runtime - self._dbusservice.add_path('/AccumulatedRuntime', value=None) - - # We need to set the values after creating the paths to trigger the 'onValueChanged' event for the gui - # otherwise the gui will report the paths as invalid if we remove and recreate the paths without - # restarting the dbusservice. - self._dbusservice['/State'] = 0 - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped - self._dbusservice['/Error'] = 0 - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/Runtime'] = 0 - self._dbusservice['/TodayRuntime'] = 0 - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - self._dbusservice['/NextTestRun'] = None - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/ManualStart'] = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._dbusservice['/QuietHours'] = 0 - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - self._dbusservice['/AutoStartEnabled'] = self._settings['autostart'] - self._dbusservice['/AccumulatedRuntime'] = int(self._settings['accumulatedtotal']) - -#### GuiMods - # generator input running state - self._dbusservice.add_path('/GeneratorRunningState', value=None) - # external override active - self._dbusservice.add_path('/ExternalOverride', value=None) - self._dbusservice['/GeneratorRunningState'] = "?" - self._dbusservice['/ExternalOverride'] = False - - def _set_autostart(self, path, value): - if 0 <= value <= 1: - self._settings['autostart'] = int(value) - return True - return False - - def enable(self): - if self._enabled: - return - self.log_info('Enabling auto start/stop and taking control of remote switch') - self._create_service() - self._determineservices() - self._update_remote_switch() - self._enabled = True - - def disable(self): - if not self._enabled: - return - self.log_info('Disabling auto start/stop, releasing control of remote switch') - self._remove_service() - self._enabled = False - - def remove(self): - self.disable() - self.log_info('Removed from start/stop instances') - - def _remove_service(self): - self._dbusservice.__del__() - self._dbusservice = None - - def device_added(self, dbusservicename, instance): - self._determineservices() - - def device_removed(self, dbusservicename, instance): - self._determineservices() - - def get_error(self): - return self._dbusservice['/Error'] - - def set_error(self, errorn): - self._dbusservice['/Error'] = errorn - - def clear_error(self): - self._dbusservice['/Error'] = Errors.NONE - - def dbus_value_changed(self, dbusServiceName, dbusPath, options, changes, deviceInstance): - if self._dbusservice is None: - return - if dbusServiceName != 'com.victronenergy.system': - return - if dbusPath == '/AutoSelectedBatteryMeasurement' and self._settings['batterymeasurement'] == 'default': - self._determineservices() - - if dbusPath == '/VebusService': - self._determineservices() - - def handlechangedsetting(self, setting, oldvalue, newvalue): - if self._dbusservice is None: - return - if self._name not in setting: - # Not our setting - return - - s = self._settings.removeprefix(setting) - - if s == 'batterymeasurement': - self._determineservices() - # Reset retries and valid if service changes - for condition in self._condition_stack: - if self._condition_stack[condition]['monitoring'] == 'battery': - self._condition_stack[condition]['valid'] = True - self._condition_stack[condition]['retries'] = 0 - - if s == 'autostart': - self.log_info('Autostart function %s.' % ('enabled' if newvalue == 1 else 'disabled')) - self._dbusservice['/AutoStartEnabled'] = self._settings['autostart'] - - if self._dbusservice is not None and s == 'testruninterval': - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime( - self._settings['testruninterval']) - - def _seconds_to_text(self, path, value): - m, s = divmod(value, 60) - h, m = divmod(m, 60) - return '%dh, %dm, %ds' % (h, m, s) - - def log_info(self, msg): - logging.info(self._name + ': %s' % msg) - - def tick(self): - if not self._enabled: - return - self._check_remote_status() -#### GuiMods - self._linkToExternalState = self._settings['linkManualStartToExternal'] == 1 - self._processGeneratorRunDetection () - - self._evaluate_startstop_conditions() - self._detect_generator_at_acinput() - - def _evaluate_startstop_conditions(self): - if self.get_error() != Errors.NONE: - # First evaluation after an error, log it - if self._errorstate == 0: - self._errorstate = 1 - self._dbusservice['/State'] = States.ERROR - self.log_info('Error: #%i - %s, stop controlling remote.' % - (self.get_error(), - Errors.get_description(self.get_error()))) - elif self._errorstate == 1: - # Error cleared - self._errorstate = 0 - self.log_info('Error state cleared, taking control of remote switch.') - - # Conditions will be evaluated in this order - conditions = ['soc', 'acload', 'batterycurrent', 'batteryvoltage', 'inverterhightemp', 'inverteroverload', 'stoponac1'] - start = False - startbycondition = None - activecondition = self._dbusservice['/RunningByCondition'] - today = calendar.timegm(datetime.date.today().timetuple()) - self._timer_runnning = False - values = self._get_updated_values() - connection_lost = False - - self._check_quiet_hours() - - # New day, register it - if self._last_counters_check < today and self._dbusservice['/State'] == States.STOPPED: - self._last_counters_check = today - self._update_accumulated_time() - - # Update current and accumulated runtime. -#### GuiMods - self._accumulateRunTime () - -#### GuiMods - # A negative /ManualStartTimer is used by the GUI to signal the generator should start now - # but stop when all auto stop conditions have been met - # so we skip manual start evaluation if this is the case - # and set a flag for use below to ignore auto start conditions - # the generator is actually started by the auto start/stop logic below - if self._dbusservice['/ManualStartTimer'] < 0 and self._dbusservice['/ManualStart'] == 1: - self._dbusservice['/ManualStartTimer'] = 0 - self._dbusservice['/ManualStart'] = 0 - ignoresAutoStartCondition = True - else: - ignoresAutoStartCondition = False - if self._evaluate_manual_start(): - startbycondition = 'manual' - start = True - - # Conditions will only be evaluated if the autostart functionality is enabled - if self._settings['autostart'] == 1: - - if self._evaluate_testrun_condition(): - startbycondition = 'testrun' - start = True - - # Evaluate value conditions - for condition in conditions: -#### GuiMods - start = self._evaluate_condition(self._condition_stack[condition], values[condition], ignoresAutoStartCondition) or start - - startbycondition = condition if start and startbycondition is None else startbycondition - # Connection lost is set to true if the number of retries of one or more enabled conditions - # >= RETRIES_ON_ERROR - if self._condition_stack[condition]['enabled']: - connection_lost = self._condition_stack[condition]['retries'] >= self.RETRIES_ON_ERROR - - if self._condition_stack['stoponac1']['reached'] and startbycondition not in ['manual', 'testrun']: - start = False - if self._dbusservice['/State'] == States.RUNNING and activecondition not in ['manual', 'testrun']: - self.log_info('AC input 1 available, stopping') - - # If none condition is reached check if connection is lost and start/keep running the generator - # depending on '/OnLossCommunication' setting - if not start and connection_lost: - # Start always - if self._settings['onlosscommunication'] == 1: - start = True - startbycondition = 'lossofcommunication' - # Keep running if generator already started - if self._dbusservice['/State'] == States.RUNNING and self._settings['onlosscommunication'] == 2: - start = True - startbycondition = 'lossofcommunication' - - if not start and self._errorstate: - self._stop_generator() - - if self._errorstate: - return - - if start: - self._start_generator(startbycondition) -#### GuiMods - # bypass the minimum run time check if External Override is active - elif (self._dbusservice['/Runtime'] >= self._settings['minimumruntime'] * 60 - or activecondition == 'manual') or self._dbusservice['/ExternalOverride']: - self._stop_generator() - - def _detect_generator_at_acinput(self): - state = self._dbusservice['/State'] - - if state == States.STOPPED: - self._reset_acpower_inverter_input() - return - - if self._settings['nogeneratoratacinalarm'] == 0: - self._reset_acpower_inverter_input() - return - - vebus_service = self._vebusservice if self._vebusservice else '' - activein_state = self._dbusmonitor.get_value( - vebus_service, '/Ac/ActiveIn/Connected') - - # Path not supported, skip evaluation - if activein_state == None: - return - - # Sources 0 = Not available, 1 = Grid, 2 = Generator, 3 = Shore - generator_acsource = self._dbusmonitor.get_value( - SYSTEM_SERVICE, '/Ac/ActiveIn/Source') == 2 - # Not connected = 0, connected = 1 - activein_connected = activein_state == 1 - - if generator_acsource and activein_connected: - if self._acpower_inverter_input['unabletostart']: - self.log_info('Generator detected at inverter AC input, alarm removed') - self._reset_acpower_inverter_input() - elif self._acpower_inverter_input['timeout'] < self.RETRIES_ON_ERROR: - self._acpower_inverter_input['timeout'] += 1 - elif not self._acpower_inverter_input['unabletostart']: - self._acpower_inverter_input['unabletostart'] = True - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 2 - self.log_info('Generator not detected at inverter AC input, triggering alarm') - - def _reset_acpower_inverter_input(self, clear_error=True): - if self._acpower_inverter_input['timeout'] != 0: - self._acpower_inverter_input['timeout'] = 0 - - if self._acpower_inverter_input['unabletostart'] != 0: - self._acpower_inverter_input['unabletostart'] = 0 - - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - - def _reset_condition(self, condition): - condition['reached'] = False - if condition['timed']: - condition['start_timer'] = 0 - condition['stop_timer'] = 0 - - def _check_condition(self, condition, value): - name = condition['name'] - - if self._settings[name + 'enabled'] == 0: - if condition['enabled']: - condition['enabled'] = False - self.log_info('Disabling (%s) condition' % name) - condition['retries'] = 0 - condition['valid'] = True - self._reset_condition(condition) - return False - - elif not condition['enabled']: - condition['enabled'] = True - self.log_info('Enabling (%s) condition' % name) - - if (condition['monitoring'] == 'battery') and (self._settings['batterymeasurement'] == 'nobattery'): - # If no battery monitor is selected reset the condition - self._reset_condition(condition) - return False - - if value is None and condition['valid']: - if condition['retries'] >= self.RETRIES_ON_ERROR: - logging.info('Error getting (%s) value, skipping evaluation till get a valid value' % name) - self._reset_condition(condition) - self._comunnication_lost = True - condition['valid'] = False - else: - condition['retries'] += 1 - if condition['retries'] == 1 or (condition['retries'] % 10) == 0: - self.log_info('Error getting (%s) value, retrying(#%i)' % (name, condition['retries'])) - return False - - elif value is not None and not condition['valid']: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['valid'] = True - condition['retries'] = 0 - - # Reset retries if value is valid - if value is not None and condition['retries'] > 0: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['retries'] = 0 - - return condition['valid'] - -#### GuiMods - def _evaluate_condition(self, condition, value, ignoreStartValue): - name = condition['name'] - setting = ('qh_' if self._dbusservice['/QuietHours'] == 1 else '') + name - startvalue = self._settings[setting + 'start'] if not condition['boolean'] else 1 - stopvalue = self._settings[setting + 'stop'] if not condition['boolean'] else 0 - - # Check if the condition has to be evaluated - if not self._check_condition(condition, value): - # If generator is started by this condition and value is invalid - # wait till RETRIES_ON_ERROR to skip the condition - if condition['reached'] and condition['retries'] <= self.RETRIES_ON_ERROR: - if condition['retries'] > 0: - return True - - return False - - # As this is a generic evaluation method, we need to know how to compare the values - # first check if start value should be greater than stop value and then compare - start_is_greater = startvalue > stopvalue - -#### GuiMods - stop = value <= stopvalue if start_is_greater else value >= stopvalue - # when starting manually and stopping based on auto stop values, - # start if stop condition is not satisfied - if ignoreStartValue: - start = not stop - else: - # When the condition is already reached only the stop value can set it to False - start = condition['reached'] or (value >= startvalue if start_is_greater else value <= startvalue) - - # Timed conditions must start/stop after the condition has been reached for a minimum - # time. - if condition['timed']: - if not condition['reached'] and start: - condition['start_timer'] += time.time() if condition['start_timer'] == 0 else 0 - start = time.time() - condition['start_timer'] >= self._settings[name + 'starttimer'] - condition['stop_timer'] *= int(not start) - self._timer_runnning = True - else: - condition['start_timer'] = 0 - - if condition['reached'] and stop: - condition['stop_timer'] += time.time() if condition['stop_timer'] == 0 else 0 - stop = time.time() - condition['stop_timer'] >= self._settings[name + 'stoptimer'] - condition['stop_timer'] *= int(not stop) - self._timer_runnning = True - else: - condition['stop_timer'] = 0 - - condition['reached'] = start and not stop - return condition['reached'] - - def _evaluate_manual_start(self): - if self._dbusservice['/ManualStart'] == 0: - if self._dbusservice['/RunningByCondition'] == 'manual': - self._dbusservice['/ManualStartTimer'] = 0 - return False - - start = True - # If /ManualStartTimer has a value greater than zero will use it to set a stop timer. - # If no timer is set, the generator will not stop until the user stops it manually. - # Once started by manual start, each evaluation the timer is decreased -#### GuiMods - if self._dbusservice['/ManualStartTimer'] > 0: - self._manualstarttimer += time.time() if self._manualstarttimer == 0 else 0 - self._dbusservice['/ManualStartTimer'] -= int(time.time()) - int(self._manualstarttimer) - self._manualstarttimer = time.time() - start = self._dbusservice['/ManualStartTimer'] > 0 - self._dbusservice['/ManualStart'] = int(start) - # Reset if timer is finished - self._manualstarttimer *= int(start) - self._dbusservice['/ManualStartTimer'] *= int(start) - - return start - - def _evaluate_testrun_condition(self): - if self._settings['testrunenabled'] == 0: - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/NextTestRun'] = None - return False - - today = datetime.date.today() - yesterday = today - datetime.timedelta(days=1) # Should deal well with DST - now = time.time() - runtillbatteryfull = self._settings['testruntillbatteryfull'] == 1 - soc = self._get_updated_values()['soc'] - batteryisfull = runtillbatteryfull and soc == 100 - duration = 60 if runtillbatteryfull else self._settings['testrunruntime'] - - try: - startdate = datetime.date.fromtimestamp(self._settings['testrunstartdate']) - _starttime = time.mktime(yesterday.timetuple()) + self._settings['testrunstarttimer'] - - # today might in fact still be yesterday, if this test run started - # before midnight and finishes after. If `now` still falls in - # yesterday's window, then by the temporal anthropic principle, - # which I just made up but loosely states that time must have - # these properties for observers to exist, it must be yesterday - # because we are here to observe it. - if _starttime <= now <= _starttime + duration: - today = yesterday - starttime = _starttime - else: - starttime = time.mktime(today.timetuple()) + self._settings['testrunstarttimer'] - except ValueError: - logging.debug('Invalid dates, skipping testrun') - return False - - # If start date is in the future set as NextTestRun and stop evaluating - if startdate > today: - self._dbusservice['/NextTestRun'] = time.mktime(startdate.timetuple()) - return False - - start = False - # If the accumulated runtime during the tes trun interval is greater than '/TestRunIntervalRuntime' - # the tes trun must be skipped - needed = (self._settings['testrunskipruntime'] > self._dbusservice['/TestRunIntervalRuntime'] - or self._settings['testrunskipruntime'] == 0) - self._dbusservice['/SkipTestRun'] = int(not needed) - - interval = self._settings['testruninterval'] - stoptime = starttime + duration - elapseddays = (today - startdate).days - mod = elapseddays % interval - - start = not bool(mod) and starttime <= now <= stoptime - - if runtillbatteryfull: - if soc is not None: - self._testrun_soc_retries = 0 - start = (start or self._dbusservice['/RunningByCondition'] == 'testrun') and not batteryisfull - elif self._dbusservice['/RunningByCondition'] == 'testrun': - if self._testrun_soc_retries < self.RETRIES_ON_ERROR: - self._testrun_soc_retries += 1 - start = True - if (self._testrun_soc_retries % 10) == 0: - self.log_info('Test run failed to get SOC value, retrying(#%i)' % self._testrun_soc_retries) - else: - self.log_info('Failed to get SOC after %i retries, terminating test run condition' % self._testrun_soc_retries) - start = False - else: - start = False - - if not bool(mod) and (now <= stoptime): - self._dbusservice['/NextTestRun'] = starttime - else: - self._dbusservice['/NextTestRun'] = (time.mktime((today + datetime.timedelta(days=interval - mod)).timetuple()) + - self._settings['testrunstarttimer']) - return start and needed - - def _check_quiet_hours(self): - active = False - if self._settings['quiethoursenabled'] == 1: - # Seconds after today 00:00 - timeinseconds = time.time() - time.mktime(datetime.date.today().timetuple()) - quiethoursstart = self._settings['quiethoursstarttime'] - quiethoursend = self._settings['quiethoursendtime'] - - # Check if the current time is between the start time and end time - if quiethoursstart < quiethoursend: - active = quiethoursstart <= timeinseconds and timeinseconds < quiethoursend - else: # End time is lower than start time, example Start: 21:00, end: 08:00 - active = not (quiethoursend < timeinseconds and timeinseconds < quiethoursstart) - - if self._dbusservice['/QuietHours'] == 0 and active: - self.log_info('Entering to quiet mode') - - elif self._dbusservice['/QuietHours'] == 1 and not active: - self.log_info('Leaving quiet mode') - - self._dbusservice['/QuietHours'] = int(active) - - return active - - def _update_accumulated_time(self): - seconds = self._dbusservice['/Runtime'] - accumulated = seconds - self._last_runtime_update - - self._settings['accumulatedtotal'] = accumulatedtotal = int(self._settings['accumulatedtotal']) + accumulated -#### GuiMods - self._settings['timeSinceService'] = int(self._settings['timeSinceService']) + accumulated - # Using calendar to get timestamp in UTC, not local time - today_date = str(calendar.timegm(datetime.date.today().timetuple())) - - # If something goes wrong getting the json string create a new one - try: - accumulated_days = json.loads(self._settings['accumulateddaily']) - except ValueError: - accumulated_days = {today_date: 0} - - if (today_date in accumulated_days): - accumulated_days[today_date] += accumulated - else: - accumulated_days[today_date] = accumulated - - self._last_runtime_update = seconds - - # Keep the historical with a maximum of HISTORY_DAYS - while len(accumulated_days) > HISTORY_DAYS: - accumulated_days.pop(min(accumulated_days.keys()), None) - - # Upadate settings - self._settings['accumulateddaily'] = json.dumps(accumulated_days, sort_keys=True) - self._dbusservice['/TodayRuntime'] = self._interval_runtime(0) - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - self._dbusservice['/AccumulatedRuntime'] = accumulatedtotal - - def _interval_runtime(self, days): - summ = 0 - try: - daily_record = json.loads(self._settings['accumulateddaily']) - except ValueError: - return 0 - - for i in range(days + 1): - previous_day = calendar.timegm((datetime.date.today() - datetime.timedelta(days=i)).timetuple()) - if str(previous_day) in daily_record.keys(): - summ += daily_record[str(previous_day)] if str(previous_day) in daily_record.keys() else 0 - - return summ - - def _get_battery(self): - battery = {} - if self._settings['batterymeasurement'] == 'default': - battery['service'] = SYSTEM_SERVICE - battery['prefix'] = BATTERY_PREFIX - else: - battery['service'] = self._battery_service if self._battery_service else '' - battery['prefix'] = self._battery_prefix if self._battery_prefix else '' - - return battery - - def _get_updated_values(self): - battery = self._get_battery() - vebus_service = self._vebusservice if self._vebusservice else '' - loadOnAcOut = [] - totalConsumption = [] - inverterHighTemp = [] - inverterOverload = [] - - values = { - 'batteryvoltage': self._dbusmonitor.get_value(battery['service'], battery['prefix'] + '/Voltage'), - 'batterycurrent': self._dbusmonitor.get_value(battery['service'], battery['prefix'] + '/Current'), - # Soc from the device doesn't have the '/Dc/0' prefix like the current and voltage do, but it does - # have the same prefix on systemcalc - 'soc': self._dbusmonitor.get_value(battery['service'], (battery['prefix'] if battery['prefix'] == BATTERY_PREFIX else '') + '/Soc'), - 'inverterhightemp': self._dbusmonitor.get_value(vebus_service, '/Alarms/HighTemperature'), - 'inverteroverload': self._dbusmonitor.get_value(vebus_service, '/Alarms/Overload') - } - - for phase in ['L1', 'L2', 'L3']: - # Get the values directly from the inverter, systemcalc doesn't provide raw inverted power - loadOnAcOut.append(self._dbusmonitor.get_value(vebus_service, ('/Ac/Out/%s/P' % phase))) - - # Calculate total consumption, '/Ac/Consumption/%s/Power' is deprecated - c_i = self._dbusmonitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnInput/%s/Power' % phase)) - c_o = self._dbusmonitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnOutput/%s/Power' % phase)) - totalConsumption.append(sum(filter(None, (c_i, c_o)))) - - # Inverter alarms must be fetched directly from the inverter service - inverterHighTemp.append(self._dbusmonitor.get_value(vebus_service, ('/Alarms/%s/HighTemperature' % phase))) - inverterOverload.append(self._dbusmonitor.get_value(vebus_service, ('/Alarms/%s/Overload' % phase))) - - # Toltal consumption - if self._settings['acloadmeasuerment'] == 0: - values['acload'] = sum(filter(None, totalConsumption)) - - # Load on inverter AC out - if self._settings['acloadmeasuerment'] == 1: - values['acload'] = sum(filter(None, loadOnAcOut)) - - # Highest phase load - if self._settings['acloadmeasuerment'] == 2: - values['acload'] = safe_max(loadOnAcOut) - - # AC input 1 - activein = self._dbusmonitor.get_value(vebus_service, '/Ac/ActiveIn/ActiveInput') - # Active input is connected - connected = self._dbusmonitor.get_value(vebus_service, '/Ac/ActiveIn/Connected') - if None not in (activein, connected): - values['stoponac1'] = activein == 0 and connected == 1 - else: - values['stoponac1'] = None - - # Invalidate if vebus is not available - if loadOnAcOut[0] == None: - values['acload'] = None - - if values['batterycurrent']: - values['batterycurrent'] *= -1 - - # When multi is connected to CAN-bus, alarms are published to - # /Alarms/Overload... but when connected to vebus alarms are - # splitted in three phases and published to /Alarms/LX/Overload... - if values['inverteroverload'] == None: - values['inverteroverload'] = safe_max(inverterOverload) - - if values['inverterhightemp'] == None: - values['inverterhightemp'] = safe_max(inverterHighTemp) - - return values - - def _determineservices(self): - # batterymeasurement is either 'default' or 'com_victronenergy_battery_288/Dc/0'. - # In case it is set to default, we use the AutoSelected battery - # measurement, given by SystemCalc. - batterymeasurement = None - newbatteryservice = None - batteryprefix = '' - selectedbattery = self._settings['batterymeasurement'] - vebusservice = None - - if selectedbattery == 'default': - batterymeasurement = 'default' - elif len(selectedbattery.split('/', 1)) == 2: # Only very basic sanity checking.. - batterymeasurement = self._settings['batterymeasurement'] - elif selectedbattery == 'nobattery': - batterymeasurement = None - else: - # Exception: unexpected value for batterymeasurement - pass - - if batterymeasurement and batterymeasurement != 'default': - batteryprefix = '/' + batterymeasurement.split('/', 1)[1] - - # Get the current battery servicename - if self._battery_service: - oldservice = self._battery_service - else: - oldservice = None - - if batterymeasurement != 'default': - battery_instance = int(batterymeasurement.split('_', 3)[3].split('/')[0]) - service_type = None - - if 'vebus' in batterymeasurement: - service_type = 'vebus' - elif 'battery' in batterymeasurement: - service_type = 'battery' - - newbatteryservice = self._get_servicename_by_instance(battery_instance, service_type) - elif batterymeasurement == 'default': - newbatteryservice = 'default' - - if newbatteryservice and newbatteryservice != oldservice: - if selectedbattery == 'default': - self.log_info('Getting battery values from systemcalc.') - if selectedbattery == 'nobattery': - self.log_info('Battery monitoring disabled! Stop evaluating related conditions') - self._battery_service = None - self._battery_prefix = None - self.log_info('Battery service we need (%s) found! Using it for generator start/stop' % batterymeasurement) - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - elif not newbatteryservice and newbatteryservice != oldservice: - self.log_info('Error getting battery service!') - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - - # Get the default VE.Bus service - vebusservice = self._dbusmonitor.get_value('com.victronenergy.system', '/VebusService') - if vebusservice: - if self._vebusservice != vebusservice: - self._vebusservice = vebusservice - self.log_info('Vebus service (%s) found! Using it for generator start/stop' % vebusservice) - else: - if self._vebusservice is not None: - self.log_info('Vebus service (%s) dissapeared! Stop evaluating related conditions' % self._vebusservice) - else: - self.log_info('Error getting Vebus service!') - self._vebusservice = None - - def _get_servicename_by_instance(self, instance, service_type=None): - sv = None - services = self._dbusmonitor.get_service_list() - - for service in services: - if service_type and service_type not in service: - continue - - if services[service] == instance: - sv = service - break - - return sv - - def _get_monotonic_seconds(self): - return monotonic_time.monotonic_time().to_seconds_double() - - def _start_generator(self, condition): - state = self._dbusservice['/State'] - remote_state = self._get_remote_switch_state() - - # This function will start the generator in the case generator not - # already running. When differs, the RunningByCondition is updated - if state == States.STOPPED or remote_state != state: - self._dbusservice['/State'] = States.RUNNING - self._update_remote_switch() - self._starttime = monotonic_time.monotonic_time().to_seconds_double() - self.log_info('Starting generator by %s condition' % condition) - elif self._dbusservice['/RunningByCondition'] != condition: - self.log_info('Generator previously running by %s condition is now running by %s condition' - % (self._dbusservice['/RunningByCondition'], condition)) - - self._dbusservice['/RunningByCondition'] = condition - self._dbusservice['/RunningByConditionCode'] = RunningConditions.lookup(condition) - - def _stop_generator(self): - state = self._dbusservice['/State'] - remote_state = self._get_remote_switch_state() - - if state == 1 or remote_state != state: - self._dbusservice['/State'] = States.STOPPED - self._update_remote_switch() - self.log_info('Stopping generator that was running by %s condition' % - str(self._dbusservice['/RunningByCondition'])) - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped -#### GuiMods - self._accumulateRunTime () - self._starttime = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._manualstarttimer = 0 - self._last_runtime_update = 0 - - def _update_remote_switch(self): - self._set_remote_switch_state(dbus.Int32(self._dbusservice['/State'], variant_level=1)) - - def _get_remote_switch_state(self): - raise Exception('This function should be overridden') - - def _set_remote_switch_state(self, value): - raise Exception('This function should be overridden') - - # Check the remote status, for example errors - def _check_remote_status(self): - raise Exception('This function should be overridden') - - def _remote_setup(self): - raise Exception('This function should be overridden') - - def _create_dbus_monitor(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_settings(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_dbus_service(self): - return create_dbus_service(self._instance) - -#### GuiMods - -# this function connects the generator digital input (if any) -# OR the generator AC input detection -# to the generator /ManualStart and updates dbus paths used by the GUI -# -# if the generator digital input changes from stopped to running -# AND no run conditions are active, a manual start is innitiated -# -# if the generator digital input changes from running to stopped -# AND a manual start is active, a manual stop is innitiated -# -# /GeneratorRunningState provides the input running state from the digital input to the GUI -# R = running -# S = stopped -# ? = unknown (no digital input found) -# -# /ExternalOverride is used by the GUI to alert the user when there is a conflict -# between the generator running state and the state Venus -# /ExternalOverride is True if /GeneratorRunningState is S -# AND the /RunningCondition is not stopped (which includes a manual run) -# activation is delayed 5 seconds to allow transitions to settle -# -# we must first find the geneator digital input, if it exists at all -# we serche all dBus services looking for a digital input with type generator (9) -# the search only occurs every 10 seconds -# - - def _processGeneratorRunDetection (self): - TheBus = dbus.SystemBus() - generatorState = self._dbusservice['/State'] - try: - # current input service is no longer valid - # search for a new one only every 10 seconds to avoid unnecessary processing - if (self._digitalInputTypeObject == None or self._digitalInputTypeObject.GetValue() != 9) and self._searchDelay > 10: - newInputService = "" - for service in TheBus.list_names(): - # found a digital input servic, now check the type - if service.startswith ("com.victronenergy.digitalinput"): - self._digitalInputTypeObject = TheBus.get_object (service, '/Type') - # found it! - if self._digitalInputTypeObject.GetValue() == 9: - newInputService = service - break - - # found new service - get objects for use later - if newInputService != "": - self.log_info ("Found generator digital input service at %s" % newInputService) - self._generatorInputStateObject = TheBus.get_object(newInputService, '/State') - else: - if self._generatorInputStateObject != None: - self.log_info ("Generator digital input service NOT found") - self._generatorInputStateObject = None - self._digitalInputTypeObject = None - self._searchDelay = 0 # start delay timer - - # if serch delay timer is active, increment it now - if self._searchDelay <= 10: - self._searchDelay += 1 - - - # collect generator input states - inputState = '?' - # if generator digital input is present, use that - if self._generatorInputStateObject != None: - inputState = self._generatorInputStateObject.GetValue () - if inputState == 10: - inputState = 'R' - elif inputState == 11: - inputState = 'S' - - # update /GeneratorRunningState - if inputState != self._lastState: - self._dbusservice['/GeneratorRunningState'] = inputState - - # forward input state changes to /ManualStart - if self._linkToExternalState: - if inputState == "R" and generatorState == States.STOPPED: - self.log_info ("generator was started externally - syncing ManualStart state") - self._dbusservice['/ManualStart'] = 1 - elif inputState == "S" and self._dbusservice['/ManualStart'] == 1 \ - and generatorState in (States.RUNNING, States.WARMUP, States.COOLDOWN): - self.log_info ("generator was stopped externally - syncing ManualStart state") - self._dbusservice['/ManualStart'] = 0 - - # update /ExternalOverride - if inputState == "S" and self._linkToExternalState and generatorState == States.RUNNING: - if self._externalOverrideDelay > 5: - self._externalOverride = True - else: - self._externalOverrideDelay += 1 - else: - self._externalOverride = False - self._externalOverrideDelay = 0 - - if self._externalOverride != self._lastExternalOverride: - self._dbusservice['/ExternalOverride'] = self._externalOverride - self._lastExternalOverride = self._externalOverride - - except dbus.DBusException: - self.log_info ("dbus exception - generator digital input no longer valid") - self._generatorInputStateObject = None - self._digitalInputTypeObject = None - inputState = 0 - - self._lastState = inputState - - -# -# control the accumulaiton of run time based on generator input Running state -# if the internal state is RUNNING run time is accumulated in self._accumulatedRunTime -# run time is accumulated if the generator's running state is known to be running or -# if the generator running state can't be determined -# the accumulated time dBus parameter and daily and total time accumulators are updated -# only once everh 60 seconds to minimize processor load -# if the internal state is STOPPED, one last dBus, daily and total time updates are done -# then the current time accumulator is cleared - - def _accumulateRunTime (self): - - mtime = monotonic_time.monotonic_time().to_seconds_double() - - # grab running state from dBus once, use it many timed below - - if self._dbusservice['/State'] == States.RUNNING: - internalRun = True - else: - internalRun = False - - # if internal state is running, accumulate time if generator is running - if internalRun: - accumuateTime = True - # start new accumulation if not done prevously - if self._last_accumulate_time == 0: - self._last_accumulate_time = mtime - - # if link to external state is enabled, don't accumulate time if running state is stopped (accumulate if R or ?) - if self._linkToExternalState: - try: - if self._dbusservice['/GeneratorRunningState'] == "S": - accumuateTime = False - - # if no Forwarder service, allow accumulation - except dbus.DBusException: - self.log_info ("dBus exception in startstop.py") - - # internal state STOPPED so don't add new time to the accumulation - # but there may be time already accumulated that needs to be added to daily and total accumulations - else: - accumuateTime = False - - # accumulate run time if we passed all the tests above - if accumuateTime: - self._accumulatedRunTime += mtime - self._last_accumulate_time - self._last_accumulate_time = mtime - - # dbus and settings updates trigger time-intensive processing so only do this once every 60 seconds - doUpdate = False - if internalRun: - if mtime - self._last_update_mtime >= 60: - doUpdate = True - self._last_update_mtime = mtime - # it is also done one last time when state is no longer RUNNING - elif self._last_update_mtime != 0: - doUpdate = True - - if doUpdate: - self._update_accumulated_time() - - # stopped - clear the current time accumulator - if internalRun == False: - self._last_update_mtime = 0 - self._accumulatedRunTime = 0 - self._last_accumulate_time = 0 - - self._dbusservice['/Runtime'] = int(self._accumulatedRunTime) diff --git a/FileSets/v3.00~32/startstop.py.orig b/FileSets/v3.00~32/startstop.py.orig deleted file mode 100644 index 904a02fd..00000000 --- a/FileSets/v3.00~32/startstop.py.orig +++ /dev/null @@ -1,957 +0,0 @@ -#!/usr/bin/python -u -# -*- coding: utf-8 -*- - -# Function -# dbus_generator monitors the dbus for batteries (com.victronenergy.battery.*) and -# vebus com.victronenergy.vebus.* -# Battery and vebus monitors can be configured through the gui. -# It then monitors SOC, AC loads, battery current and battery voltage,to auto start/stop the generator based -# on the configuration settings. Generator can be started manually or periodically setting a tes trun period. -# Time zones function allows to use different values for the conditions along the day depending on time - -import dbus -import datetime -import calendar -import time -import sys -import json -import os -import logging -from os import environ -import monotonic_time -from gen_utils import SettingsPrefix, Errors, States, enum -from gen_utils import create_dbus_service -# Victron packages -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) -from ve_utils import exit_on_error -from settingsdevice import SettingsDevice - -RunningConditions = enum( - Stopped = 0, - Manual = 1, - TestRun = 2, - LossOfCommunication = 3, - Soc = 4, - Acload = 5, - BatteryCurrent = 6, - BatteryVoltage = 7, - InverterHighTemp = 8, - InverterOverload = 9, - StopOnAc1 = 10) - -SYSTEM_SERVICE = 'com.victronenergy.system' -BATTERY_PREFIX = '/Dc/Battery' -HISTORY_DAYS = 30 - -def safe_max(args): - try: - return max(x for x in args if x is not None) - except ValueError: - return None - -class StartStop(object): - _driver = None - def __init__(self, instance): - self._dbusservice = None - self._settings = None - self._dbusmonitor = None - self._remoteservice = None - self._name = None - self._enabled = False - self._instance = instance - - # One second per retry - self.RETRIES_ON_ERROR = 300 - self._testrun_soc_retries = 0 - self._last_counters_check = 0 - - self._starttime = 0 - self._manualstarttimer = 0 - self._last_runtime_update = 0 - self._timer_runnning = 0 - - # Manual battery service selection is deprecated in favour - # of getting the values directly from systemcalc, we keep - # manual selected services handling for compatibility reasons. - self._vebusservice = None - self._errorstate = 0 - self._battery_service = None - self._battery_prefix = None - - self._acpower_inverter_input = { - 'timeout': 0, - 'unabletostart': False - } - - self._condition_stack = { - 'batteryvoltage': { - 'name': 'batteryvoltage', - 'reached': False, - 'boolean': False, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'battery' - }, - 'batterycurrent': { - 'name': 'batterycurrent', - 'reached': False, - 'boolean': False, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'battery' - }, - 'acload': { - 'name': 'acload', - 'reached': False, - 'boolean': False, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - }, - 'inverterhightemp': { - 'name': 'inverterhightemp', - 'reached': False, - 'boolean': True, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - }, - 'inverteroverload': { - 'name': 'inverteroverload', - 'reached': False, - 'boolean': True, - 'timed': True, - 'start_timer': 0, - 'stop_timer': 0, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - }, - 'soc': { - 'name': 'soc', - 'reached': False, - 'boolean': False, - 'timed': False, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'battery' - }, - 'stoponac1': { - 'name': 'stoponac1', - 'reached': False, - 'boolean': True, - 'timed': False, - 'valid': True, - 'enabled': False, - 'retries': 0, - 'monitoring': 'vebus' - } - } - - def set_sources(self, dbusmonitor, settings, name, remoteservice): - self._settings = SettingsPrefix(settings, name) - self._dbusmonitor = dbusmonitor - self._remoteservice = remoteservice - self._name = name - - self.log_info('Start/stop instance created for %s.' % self._remoteservice) - self._remote_setup() - - def _create_service(self): - self._dbusservice = self._create_dbus_service() - - # The driver used for this start/stop service - self._dbusservice.add_path('/Type', value=self._driver) - # State: None = invalid, 0 = stopped, 1 = running - self._dbusservice.add_path('/State', value=None) - # RunningByConditionCode: Numeric Companion to /RunningByCondition below, but - # also encompassing a Stopped state. - self._dbusservice.add_path('/RunningByConditionCode', value=None) - # Error - self._dbusservice.add_path('/Error', value=None, gettextcallback=lambda p, v: Errors.get_description(v)) - # Condition that made the generator start - self._dbusservice.add_path('/RunningByCondition', value=None) - # Runtime - self._dbusservice.add_path('/Runtime', value=None, gettextcallback=self._seconds_to_text) - # Today runtime - self._dbusservice.add_path('/TodayRuntime', value=None, gettextcallback=self._seconds_to_text) - # Test run runtime - self._dbusservice.add_path('/TestRunIntervalRuntime', value=None , gettextcallback=self._seconds_to_text) - # Next test run date, values is 0 for test run disabled - self._dbusservice.add_path('/NextTestRun', value=None, gettextcallback=lambda p, v: datetime.datetime.fromtimestamp(v).strftime('%c')) - # Next test run is needed 1, not needed 0 - self._dbusservice.add_path('/SkipTestRun', value=None) - # Manual start - self._dbusservice.add_path('/ManualStart', value=None, writeable=True) - # Manual start timer - self._dbusservice.add_path('/ManualStartTimer', value=None, writeable=True) - # Silent mode active - self._dbusservice.add_path('/QuietHours', value=None) - # Alarms - self._dbusservice.add_path('/Alarms/NoGeneratorAtAcIn', value=None) - # Autostart - self._dbusservice.add_path('/AutoStartEnabled', value=None, writeable=True, onchangecallback=self._set_autostart) - # Accumulated runtime - self._dbusservice.add_path('/AccumulatedRuntime', value=None) - - # We need to set the values after creating the paths to trigger the 'onValueChanged' event for the gui - # otherwise the gui will report the paths as invalid if we remove and recreate the paths without - # restarting the dbusservice. - self._dbusservice['/State'] = 0 - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped - self._dbusservice['/Error'] = 0 - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/Runtime'] = 0 - self._dbusservice['/TodayRuntime'] = 0 - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - self._dbusservice['/NextTestRun'] = None - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/ManualStart'] = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._dbusservice['/QuietHours'] = 0 - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - self._dbusservice['/AutoStartEnabled'] = self._settings['autostart'] - self._dbusservice['/AccumulatedRuntime'] = int(self._settings['accumulatedtotal']) - - def _set_autostart(self, path, value): - if 0 <= value <= 1: - self._settings['autostart'] = int(value) - return True - return False - - def enable(self): - if self._enabled: - return - self.log_info('Enabling auto start/stop and taking control of remote switch') - self._create_service() - self._determineservices() - self._update_remote_switch() - self._enabled = True - - def disable(self): - if not self._enabled: - return - self.log_info('Disabling auto start/stop, releasing control of remote switch') - self._remove_service() - self._enabled = False - - def remove(self): - self.disable() - self.log_info('Removed from start/stop instances') - - def _remove_service(self): - self._dbusservice.__del__() - self._dbusservice = None - - def device_added(self, dbusservicename, instance): - self._determineservices() - - def device_removed(self, dbusservicename, instance): - self._determineservices() - - def get_error(self): - return self._dbusservice['/Error'] - - def set_error(self, errorn): - self._dbusservice['/Error'] = errorn - - def clear_error(self): - self._dbusservice['/Error'] = Errors.NONE - - def dbus_value_changed(self, dbusServiceName, dbusPath, options, changes, deviceInstance): - if self._dbusservice is None: - return - if dbusServiceName != 'com.victronenergy.system': - return - if dbusPath == '/AutoSelectedBatteryMeasurement' and self._settings['batterymeasurement'] == 'default': - self._determineservices() - - if dbusPath == '/VebusService': - self._determineservices() - - def handlechangedsetting(self, setting, oldvalue, newvalue): - if self._dbusservice is None: - return - if self._name not in setting: - # Not our setting - return - - s = self._settings.removeprefix(setting) - - if s == 'batterymeasurement': - self._determineservices() - # Reset retries and valid if service changes - for condition in self._condition_stack: - if self._condition_stack[condition]['monitoring'] == 'battery': - self._condition_stack[condition]['valid'] = True - self._condition_stack[condition]['retries'] = 0 - - if s == 'autostart': - self.log_info('Autostart function %s.' % ('enabled' if newvalue == 1 else 'disabled')) - self._dbusservice['/AutoStartEnabled'] = self._settings['autostart'] - - if self._dbusservice is not None and s == 'testruninterval': - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime( - self._settings['testruninterval']) - - def _seconds_to_text(self, path, value): - m, s = divmod(value, 60) - h, m = divmod(m, 60) - return '%dh, %dm, %ds' % (h, m, s) - - def log_info(self, msg): - logging.info(self._name + ': %s' % msg) - - def tick(self): - if not self._enabled: - return - self._check_remote_status() - self._evaluate_startstop_conditions() - self._detect_generator_at_acinput() - - def _evaluate_startstop_conditions(self): - if self.get_error() != Errors.NONE: - # First evaluation after an error, log it - if self._errorstate == 0: - self._errorstate = 1 - self._dbusservice['/State'] = States.ERROR - self.log_info('Error: #%i - %s, stop controlling remote.' % - (self.get_error(), - Errors.get_description(self.get_error()))) - elif self._errorstate == 1: - # Error cleared - self._errorstate = 0 - self.log_info('Error state cleared, taking control of remote switch.') - - # Conditions will be evaluated in this order - conditions = ['soc', 'acload', 'batterycurrent', 'batteryvoltage', 'inverterhightemp', 'inverteroverload', 'stoponac1'] - start = False - startbycondition = None - activecondition = self._dbusservice['/RunningByCondition'] - today = calendar.timegm(datetime.date.today().timetuple()) - self._timer_runnning = False - values = self._get_updated_values() - connection_lost = False - - self._check_quiet_hours() - - # New day, register it - if self._last_counters_check < today and self._dbusservice['/State'] == States.STOPPED: - self._last_counters_check = today - self._update_accumulated_time() - - # Update current and accumulated runtime. - # By performance reasons, accumulated runtime is only updated - # once per 60s. When the generator stops is also updated. - if self._dbusservice['/State'] == States.RUNNING: - mtime = monotonic_time.monotonic_time().to_seconds_double() - if (mtime - self._starttime) - self._last_runtime_update >= 60: - self._dbusservice['/Runtime'] = int(mtime - self._starttime) - self._update_accumulated_time() - elif self._last_runtime_update == 0: - self._dbusservice['/Runtime'] = int(mtime - self._starttime) - - - if self._evaluate_manual_start(): - startbycondition = 'manual' - start = True - - # Conditions will only be evaluated if the autostart functionality is enabled - if self._settings['autostart'] == 1: - - if self._evaluate_testrun_condition(): - startbycondition = 'testrun' - start = True - - # Evaluate value conditions - for condition in conditions: - start = self._evaluate_condition(self._condition_stack[condition], values[condition]) or start - startbycondition = condition if start and startbycondition is None else startbycondition - # Connection lost is set to true if the number of retries of one or more enabled conditions - # >= RETRIES_ON_ERROR - if self._condition_stack[condition]['enabled']: - connection_lost = self._condition_stack[condition]['retries'] >= self.RETRIES_ON_ERROR - - if self._condition_stack['stoponac1']['reached'] and startbycondition not in ['manual', 'testrun']: - start = False - if self._dbusservice['/State'] == States.RUNNING and activecondition not in ['manual', 'testrun']: - self.log_info('AC input 1 available, stopping') - - # If none condition is reached check if connection is lost and start/keep running the generator - # depending on '/OnLossCommunication' setting - if not start and connection_lost: - # Start always - if self._settings['onlosscommunication'] == 1: - start = True - startbycondition = 'lossofcommunication' - # Keep running if generator already started - if self._dbusservice['/State'] == States.RUNNING and self._settings['onlosscommunication'] == 2: - start = True - startbycondition = 'lossofcommunication' - - if not start and self._errorstate: - self._stop_generator() - - if self._errorstate: - return - - if start: - self._start_generator(startbycondition) - elif (self._dbusservice['/Runtime'] >= self._settings['minimumruntime'] * 60 - or activecondition == 'manual'): - self._stop_generator() - - def _detect_generator_at_acinput(self): - state = self._dbusservice['/State'] - - if state == States.STOPPED: - self._reset_acpower_inverter_input() - return - - if self._settings['nogeneratoratacinalarm'] == 0: - self._reset_acpower_inverter_input() - return - - vebus_service = self._vebusservice if self._vebusservice else '' - activein_state = self._dbusmonitor.get_value( - vebus_service, '/Ac/ActiveIn/Connected') - - # Path not supported, skip evaluation - if activein_state == None: - return - - # Sources 0 = Not available, 1 = Grid, 2 = Generator, 3 = Shore - generator_acsource = self._dbusmonitor.get_value( - SYSTEM_SERVICE, '/Ac/ActiveIn/Source') == 2 - # Not connected = 0, connected = 1 - activein_connected = activein_state == 1 - - if generator_acsource and activein_connected: - if self._acpower_inverter_input['unabletostart']: - self.log_info('Generator detected at inverter AC input, alarm removed') - self._reset_acpower_inverter_input() - elif self._acpower_inverter_input['timeout'] < self.RETRIES_ON_ERROR: - self._acpower_inverter_input['timeout'] += 1 - elif not self._acpower_inverter_input['unabletostart']: - self._acpower_inverter_input['unabletostart'] = True - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 2 - self.log_info('Generator not detected at inverter AC input, triggering alarm') - - def _reset_acpower_inverter_input(self, clear_error=True): - if self._acpower_inverter_input['timeout'] != 0: - self._acpower_inverter_input['timeout'] = 0 - - if self._acpower_inverter_input['unabletostart'] != 0: - self._acpower_inverter_input['unabletostart'] = 0 - - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - - def _reset_condition(self, condition): - condition['reached'] = False - if condition['timed']: - condition['start_timer'] = 0 - condition['stop_timer'] = 0 - - def _check_condition(self, condition, value): - name = condition['name'] - - if self._settings[name + 'enabled'] == 0: - if condition['enabled']: - condition['enabled'] = False - self.log_info('Disabling (%s) condition' % name) - condition['retries'] = 0 - condition['valid'] = True - self._reset_condition(condition) - return False - - elif not condition['enabled']: - condition['enabled'] = True - self.log_info('Enabling (%s) condition' % name) - - if (condition['monitoring'] == 'battery') and (self._settings['batterymeasurement'] == 'nobattery'): - # If no battery monitor is selected reset the condition - self._reset_condition(condition) - return False - - if value is None and condition['valid']: - if condition['retries'] >= self.RETRIES_ON_ERROR: - logging.info('Error getting (%s) value, skipping evaluation till get a valid value' % name) - self._reset_condition(condition) - self._comunnication_lost = True - condition['valid'] = False - else: - condition['retries'] += 1 - if condition['retries'] == 1 or (condition['retries'] % 10) == 0: - self.log_info('Error getting (%s) value, retrying(#%i)' % (name, condition['retries'])) - return False - - elif value is not None and not condition['valid']: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['valid'] = True - condition['retries'] = 0 - - # Reset retries if value is valid - if value is not None and condition['retries'] > 0: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['retries'] = 0 - - return condition['valid'] - - def _evaluate_condition(self, condition, value): - name = condition['name'] - setting = ('qh_' if self._dbusservice['/QuietHours'] == 1 else '') + name - startvalue = self._settings[setting + 'start'] if not condition['boolean'] else 1 - stopvalue = self._settings[setting + 'stop'] if not condition['boolean'] else 0 - - # Check if the condition has to be evaluated - if not self._check_condition(condition, value): - # If generator is started by this condition and value is invalid - # wait till RETRIES_ON_ERROR to skip the condition - if condition['reached'] and condition['retries'] <= self.RETRIES_ON_ERROR: - if condition['retries'] > 0: - return True - - return False - - # As this is a generic evaluation method, we need to know how to compare the values - # first check if start value should be greater than stop value and then compare - start_is_greater = startvalue > stopvalue - - # When the condition is already reached only the stop value can set it to False - start = condition['reached'] or (value >= startvalue if start_is_greater else value <= startvalue) - stop = value <= stopvalue if start_is_greater else value >= stopvalue - - # Timed conditions must start/stop after the condition has been reached for a minimum - # time. - if condition['timed']: - if not condition['reached'] and start: - condition['start_timer'] += time.time() if condition['start_timer'] == 0 else 0 - start = time.time() - condition['start_timer'] >= self._settings[name + 'starttimer'] - condition['stop_timer'] *= int(not start) - self._timer_runnning = True - else: - condition['start_timer'] = 0 - - if condition['reached'] and stop: - condition['stop_timer'] += time.time() if condition['stop_timer'] == 0 else 0 - stop = time.time() - condition['stop_timer'] >= self._settings[name + 'stoptimer'] - condition['stop_timer'] *= int(not stop) - self._timer_runnning = True - else: - condition['stop_timer'] = 0 - - condition['reached'] = start and not stop - return condition['reached'] - - def _evaluate_manual_start(self): - if self._dbusservice['/ManualStart'] == 0: - if self._dbusservice['/RunningByCondition'] == 'manual': - self._dbusservice['/ManualStartTimer'] = 0 - return False - - start = True - # If /ManualStartTimer has a value greater than zero will use it to set a stop timer. - # If no timer is set, the generator will not stop until the user stops it manually. - # Once started by manual start, each evaluation the timer is decreased - if self._dbusservice['/ManualStartTimer'] != 0: - self._manualstarttimer += time.time() if self._manualstarttimer == 0 else 0 - self._dbusservice['/ManualStartTimer'] -= int(time.time()) - int(self._manualstarttimer) - self._manualstarttimer = time.time() - start = self._dbusservice['/ManualStartTimer'] > 0 - self._dbusservice['/ManualStart'] = int(start) - # Reset if timer is finished - self._manualstarttimer *= int(start) - self._dbusservice['/ManualStartTimer'] *= int(start) - - return start - - def _evaluate_testrun_condition(self): - if self._settings['testrunenabled'] == 0: - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/NextTestRun'] = None - return False - - today = datetime.date.today() - yesterday = today - datetime.timedelta(days=1) # Should deal well with DST - now = time.time() - runtillbatteryfull = self._settings['testruntillbatteryfull'] == 1 - soc = self._get_updated_values()['soc'] - batteryisfull = runtillbatteryfull and soc == 100 - duration = 60 if runtillbatteryfull else self._settings['testrunruntime'] - - try: - startdate = datetime.date.fromtimestamp(self._settings['testrunstartdate']) - _starttime = time.mktime(yesterday.timetuple()) + self._settings['testrunstarttimer'] - - # today might in fact still be yesterday, if this test run started - # before midnight and finishes after. If `now` still falls in - # yesterday's window, then by the temporal anthropic principle, - # which I just made up but loosely states that time must have - # these properties for observers to exist, it must be yesterday - # because we are here to observe it. - if _starttime <= now <= _starttime + duration: - today = yesterday - starttime = _starttime - else: - starttime = time.mktime(today.timetuple()) + self._settings['testrunstarttimer'] - except ValueError: - logging.debug('Invalid dates, skipping testrun') - return False - - # If start date is in the future set as NextTestRun and stop evaluating - if startdate > today: - self._dbusservice['/NextTestRun'] = time.mktime(startdate.timetuple()) - return False - - start = False - # If the accumulated runtime during the tes trun interval is greater than '/TestRunIntervalRuntime' - # the tes trun must be skipped - needed = (self._settings['testrunskipruntime'] > self._dbusservice['/TestRunIntervalRuntime'] - or self._settings['testrunskipruntime'] == 0) - self._dbusservice['/SkipTestRun'] = int(not needed) - - interval = self._settings['testruninterval'] - stoptime = starttime + duration - elapseddays = (today - startdate).days - mod = elapseddays % interval - - start = not bool(mod) and starttime <= now <= stoptime - - if runtillbatteryfull: - if soc is not None: - self._testrun_soc_retries = 0 - start = (start or self._dbusservice['/RunningByCondition'] == 'testrun') and not batteryisfull - elif self._dbusservice['/RunningByCondition'] == 'testrun': - if self._testrun_soc_retries < self.RETRIES_ON_ERROR: - self._testrun_soc_retries += 1 - start = True - if (self._testrun_soc_retries % 10) == 0: - self.log_info('Test run failed to get SOC value, retrying(#%i)' % self._testrun_soc_retries) - else: - self.log_info('Failed to get SOC after %i retries, terminating test run condition' % self._testrun_soc_retries) - start = False - else: - start = False - - if not bool(mod) and (now <= stoptime): - self._dbusservice['/NextTestRun'] = starttime - else: - self._dbusservice['/NextTestRun'] = (time.mktime((today + datetime.timedelta(days=interval - mod)).timetuple()) + - self._settings['testrunstarttimer']) - return start and needed - - def _check_quiet_hours(self): - active = False - if self._settings['quiethoursenabled'] == 1: - # Seconds after today 00:00 - timeinseconds = time.time() - time.mktime(datetime.date.today().timetuple()) - quiethoursstart = self._settings['quiethoursstarttime'] - quiethoursend = self._settings['quiethoursendtime'] - - # Check if the current time is between the start time and end time - if quiethoursstart < quiethoursend: - active = quiethoursstart <= timeinseconds and timeinseconds < quiethoursend - else: # End time is lower than start time, example Start: 21:00, end: 08:00 - active = not (quiethoursend < timeinseconds and timeinseconds < quiethoursstart) - - if self._dbusservice['/QuietHours'] == 0 and active: - self.log_info('Entering to quiet mode') - - elif self._dbusservice['/QuietHours'] == 1 and not active: - self.log_info('Leaving quiet mode') - - self._dbusservice['/QuietHours'] = int(active) - - return active - - def _update_accumulated_time(self): - seconds = self._dbusservice['/Runtime'] - accumulated = seconds - self._last_runtime_update - - self._settings['accumulatedtotal'] = accumulatedtotal = int(self._settings['accumulatedtotal']) + accumulated - # Using calendar to get timestamp in UTC, not local time - today_date = str(calendar.timegm(datetime.date.today().timetuple())) - - # If something goes wrong getting the json string create a new one - try: - accumulated_days = json.loads(self._settings['accumulateddaily']) - except ValueError: - accumulated_days = {today_date: 0} - - if (today_date in accumulated_days): - accumulated_days[today_date] += accumulated - else: - accumulated_days[today_date] = accumulated - - self._last_runtime_update = seconds - - # Keep the historical with a maximum of HISTORY_DAYS - while len(accumulated_days) > HISTORY_DAYS: - accumulated_days.pop(min(accumulated_days.keys()), None) - - # Upadate settings - self._settings['accumulateddaily'] = json.dumps(accumulated_days, sort_keys=True) - self._dbusservice['/TodayRuntime'] = self._interval_runtime(0) - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - self._dbusservice['/AccumulatedRuntime'] = accumulatedtotal - - def _interval_runtime(self, days): - summ = 0 - try: - daily_record = json.loads(self._settings['accumulateddaily']) - except ValueError: - return 0 - - for i in range(days + 1): - previous_day = calendar.timegm((datetime.date.today() - datetime.timedelta(days=i)).timetuple()) - if str(previous_day) in daily_record.keys(): - summ += daily_record[str(previous_day)] if str(previous_day) in daily_record.keys() else 0 - - return summ - - def _get_battery(self): - battery = {} - if self._settings['batterymeasurement'] == 'default': - battery['service'] = SYSTEM_SERVICE - battery['prefix'] = BATTERY_PREFIX - else: - battery['service'] = self._battery_service if self._battery_service else '' - battery['prefix'] = self._battery_prefix if self._battery_prefix else '' - - return battery - - def _get_updated_values(self): - battery = self._get_battery() - vebus_service = self._vebusservice if self._vebusservice else '' - loadOnAcOut = [] - totalConsumption = [] - inverterHighTemp = [] - inverterOverload = [] - - values = { - 'batteryvoltage': self._dbusmonitor.get_value(battery['service'], battery['prefix'] + '/Voltage'), - 'batterycurrent': self._dbusmonitor.get_value(battery['service'], battery['prefix'] + '/Current'), - # Soc from the device doesn't have the '/Dc/0' prefix like the current and voltage do, but it does - # have the same prefix on systemcalc - 'soc': self._dbusmonitor.get_value(battery['service'], (battery['prefix'] if battery['prefix'] == BATTERY_PREFIX else '') + '/Soc'), - 'inverterhightemp': self._dbusmonitor.get_value(vebus_service, '/Alarms/HighTemperature'), - 'inverteroverload': self._dbusmonitor.get_value(vebus_service, '/Alarms/Overload') - } - - for phase in ['L1', 'L2', 'L3']: - # Get the values directly from the inverter, systemcalc doesn't provide raw inverted power - loadOnAcOut.append(self._dbusmonitor.get_value(vebus_service, ('/Ac/Out/%s/P' % phase))) - - # Calculate total consumption, '/Ac/Consumption/%s/Power' is deprecated - c_i = self._dbusmonitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnInput/%s/Power' % phase)) - c_o = self._dbusmonitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnOutput/%s/Power' % phase)) - totalConsumption.append(sum(filter(None, (c_i, c_o)))) - - # Inverter alarms must be fetched directly from the inverter service - inverterHighTemp.append(self._dbusmonitor.get_value(vebus_service, ('/Alarms/%s/HighTemperature' % phase))) - inverterOverload.append(self._dbusmonitor.get_value(vebus_service, ('/Alarms/%s/Overload' % phase))) - - # Toltal consumption - if self._settings['acloadmeasuerment'] == 0: - values['acload'] = sum(filter(None, totalConsumption)) - - # Load on inverter AC out - if self._settings['acloadmeasuerment'] == 1: - values['acload'] = sum(filter(None, loadOnAcOut)) - - # Highest phase load - if self._settings['acloadmeasuerment'] == 2: - values['acload'] = safe_max(loadOnAcOut) - - # AC input 1 - activein = self._dbusmonitor.get_value(vebus_service, '/Ac/ActiveIn/ActiveInput') - # Active input is connected - connected = self._dbusmonitor.get_value(vebus_service, '/Ac/ActiveIn/Connected') - if None not in (activein, connected): - values['stoponac1'] = activein == 0 and connected == 1 - else: - values['stoponac1'] = None - - # Invalidate if vebus is not available - if loadOnAcOut[0] == None: - values['acload'] = None - - if values['batterycurrent']: - values['batterycurrent'] *= -1 - - # When multi is connected to CAN-bus, alarms are published to - # /Alarms/Overload... but when connected to vebus alarms are - # splitted in three phases and published to /Alarms/LX/Overload... - if values['inverteroverload'] == None: - values['inverteroverload'] = safe_max(inverterOverload) - - if values['inverterhightemp'] == None: - values['inverterhightemp'] = safe_max(inverterHighTemp) - - return values - - def _determineservices(self): - # batterymeasurement is either 'default' or 'com_victronenergy_battery_288/Dc/0'. - # In case it is set to default, we use the AutoSelected battery - # measurement, given by SystemCalc. - batterymeasurement = None - newbatteryservice = None - batteryprefix = '' - selectedbattery = self._settings['batterymeasurement'] - vebusservice = None - - if selectedbattery == 'default': - batterymeasurement = 'default' - elif len(selectedbattery.split('/', 1)) == 2: # Only very basic sanity checking.. - batterymeasurement = self._settings['batterymeasurement'] - elif selectedbattery == 'nobattery': - batterymeasurement = None - else: - # Exception: unexpected value for batterymeasurement - pass - - if batterymeasurement and batterymeasurement != 'default': - batteryprefix = '/' + batterymeasurement.split('/', 1)[1] - - # Get the current battery servicename - if self._battery_service: - oldservice = self._battery_service - else: - oldservice = None - - if batterymeasurement != 'default': - battery_instance = int(batterymeasurement.split('_', 3)[3].split('/')[0]) - service_type = None - - if 'vebus' in batterymeasurement: - service_type = 'vebus' - elif 'battery' in batterymeasurement: - service_type = 'battery' - - newbatteryservice = self._get_servicename_by_instance(battery_instance, service_type) - elif batterymeasurement == 'default': - newbatteryservice = 'default' - - if newbatteryservice and newbatteryservice != oldservice: - if selectedbattery == 'default': - self.log_info('Getting battery values from systemcalc.') - if selectedbattery == 'nobattery': - self.log_info('Battery monitoring disabled! Stop evaluating related conditions') - self._battery_service = None - self._battery_prefix = None - self.log_info('Battery service we need (%s) found! Using it for generator start/stop' % batterymeasurement) - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - elif not newbatteryservice and newbatteryservice != oldservice: - self.log_info('Error getting battery service!') - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - - # Get the default VE.Bus service - vebusservice = self._dbusmonitor.get_value('com.victronenergy.system', '/VebusService') - if vebusservice: - if self._vebusservice != vebusservice: - self._vebusservice = vebusservice - self.log_info('Vebus service (%s) found! Using it for generator start/stop' % vebusservice) - else: - if self._vebusservice is not None: - self.log_info('Vebus service (%s) dissapeared! Stop evaluating related conditions' % self._vebusservice) - else: - self.log_info('Error getting Vebus service!') - self._vebusservice = None - - def _get_servicename_by_instance(self, instance, service_type=None): - sv = None - services = self._dbusmonitor.get_service_list() - - for service in services: - if service_type and service_type not in service: - continue - - if services[service] == instance: - sv = service - break - - return sv - - def _get_monotonic_seconds(self): - return monotonic_time.monotonic_time().to_seconds_double() - - def _start_generator(self, condition): - state = self._dbusservice['/State'] - remote_state = self._get_remote_switch_state() - - # This function will start the generator in the case generator not - # already running. When differs, the RunningByCondition is updated - if state == States.STOPPED or remote_state != state: - self._dbusservice['/State'] = States.RUNNING - self._update_remote_switch() - self._starttime = monotonic_time.monotonic_time().to_seconds_double() - self.log_info('Starting generator by %s condition' % condition) - elif self._dbusservice['/RunningByCondition'] != condition: - self.log_info('Generator previously running by %s condition is now running by %s condition' - % (self._dbusservice['/RunningByCondition'], condition)) - - self._dbusservice['/RunningByCondition'] = condition - self._dbusservice['/RunningByConditionCode'] = RunningConditions.lookup(condition) - - def _stop_generator(self): - state = self._dbusservice['/State'] - remote_state = self._get_remote_switch_state() - - if state == 1 or remote_state != state: - self._dbusservice['/State'] = States.STOPPED - self._update_remote_switch() - self.log_info('Stopping generator that was running by %s condition' % - str(self._dbusservice['/RunningByCondition'])) - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped - self._update_accumulated_time() - self._starttime = 0 - self._dbusservice['/Runtime'] = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._manualstarttimer = 0 - self._last_runtime_update = 0 - - def _update_remote_switch(self): - self._set_remote_switch_state(dbus.Int32(self._dbusservice['/State'], variant_level=1)) - - def _get_remote_switch_state(self): - raise Exception('This function should be overridden') - - def _set_remote_switch_state(self, value): - raise Exception('This function should be overridden') - - # Check the remote status, for example errors - def _check_remote_status(self): - raise Exception('This function should be overridden') - - def _remote_setup(self): - raise Exception('This function should be overridden') - - def _create_dbus_monitor(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_settings(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_dbus_service(self): - return create_dbus_service(self._instance) diff --git a/FileSets/v3.00~32/styles.css b/FileSets/v3.00~32/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v3.00~32/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v3.01/COMPLETE b/FileSets/v3.01/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.01/DetailAcInput.qml b/FileSets/v3.01/DetailAcInput.qml deleted file mode 100644 index 0d71ee29..00000000 --- a/FileSets/v3.01/DetailAcInput.qml +++ /dev/null @@ -1,607 +0,0 @@ -////// detail page for setting input current limit -////// and displaying AC input details -////// pushed from Flow overview - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 -import "enhancedFormat.js" as EnhFmt - -MbPage { - id: root - - title: "AC Input detail" - - property variant sys: theSystem - property string systemPrefix: "com.victronenergy.system" - property string settingsPrefix: "com.victronenergy.settings" - - property int fontPixelSize: 18 - property color buttonColor: "#979797" - property color pressedColor: "#d3d3d3" - property color backgroundColor: "#b3b3b3" - - property int buttonHeight: 40 - - property int dataColumns: 4 - property int rowTitleWidth: 100 - property int totalDataWidth: 340 - rowTitleWidth - property int tableColumnWidth: totalDataWidth / dataColumns - - property int legColumnWidth: phaseCount <= 1 ? tableColumnWidth * 3 : tableColumnWidth * 3 / phaseCount - - property int phaseCount: sys.acInput.phaseCount.valid ? sys.acInput.phaseCount.value : 0 - - VBusItem { id: vebusServiceItem; bind: Utils.path(systemPrefix, "/VebusService") } - property string inverterService: vebusServiceItem.valid ? vebusServiceItem.value : "" - VBusItem { id: splitPhaseL2Passthru; bind: Utils.path(inverterService, "/Ac/State/SplitPhaseL2Passthru") } - property bool splitPhasePassthruDisabled: splitPhaseL2Passthru.valid && splitPhaseL2Passthru.value === 0 - - property real actualCurrentLimit: 0 - property real newCurrentLimit: 0 - - VBusItem { id: acLimitPreset1Item; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/AcCurrentLimit/Preset1") } - VBusItem { id: acLimitPreset2Item; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/AcCurrentLimit/Preset2") } - VBusItem { id: acLimitPreset3Item; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/AcCurrentLimit/Preset3") } - VBusItem { id: acLimitPreset4Item; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/AcCurrentLimit/Preset4") } - property real acLimitPreset1: acLimitPreset1Item.valid ? acLimitPreset1Item.value : 0 - property real acLimitPreset2: acLimitPreset2Item.valid ? acLimitPreset2Item.value : 0 - property real acLimitPreset3: acLimitPreset3Item.valid ? acLimitPreset3Item.value : 0 - property real acLimitPreset4: acLimitPreset4Item.valid ? acLimitPreset4Item.value : 0 - - property bool currentLimitIsAdjustable: currentLimitIsAdjustableItem.valid && currentLimitIsAdjustableItem.value == 1 && currentLimitItem.valid - - Component.onCompleted: { getActualCurrent () } - - VBusItem - { - id: currentLimitIsAdjustableItem - bind: Utils.path(inverterService, "/Ac/ActiveIn/CurrentLimitIsAdjustable") - onValueChanged: getActualCurrent () - onValidChanged: getActualCurrent () - } - VBusItem - { - id: currentLimitItem - bind: Utils.path(inverterService, "/Ac/ActiveIn/CurrentLimit") - onValueChanged: getActualCurrent () - onValidChanged: getActualCurrent () - } - VBusItem { id: activeInputItem; bind: Utils.path(inverterService, "/Ac/ActiveIn/ActiveInput") } - VBusItem { id: numberOfAcInputs; bind: Utils.path(inverterService, "/Ac/In/NumberOfAcInputs") } - VBusItem { id: activeSourceItem; bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") } - VBusItem { id: acIn1sourceItem; bind: Utils.path(settingsPrefix, "/Settings/SystemSetup/AcInput1") } - VBusItem { id: acIn2sourceItem; bind: Utils.path(settingsPrefix, "/Settings/SystemSetup/AcInput2") } - property int activeSource: activeSourceItem.valid ? activeSourceItem.value : 0 - property int acIn1source: acIn1sourceItem.valid ? acIn1sourceItem.value : 0 - property int acIn2source: acIn2sourceItem.valid ? acIn2sourceItem.value : 0 - property int activeInput: activeInputItem.valid && activeInputItem.value == 1 ? 2 : 1 - property bool hasTwoInputs: numberOfAcInputs.valid && numberOfAcInputs.value == 2 - - property variant acSourceName: [qsTr("---"), qsTr("Grid"), qsTr("Generator"), qsTr("Shore")] - - // background - Rectangle - { - anchors - { - fill: parent - } - color: root.backgroundColor - } - - Row - { - spacing: 5 - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - width: parent.width - 6 - Column - { - spacing: 2 - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Total Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.power, "W") - } - PowerGauge - { - id: gauge - width: totalDataWidth - tableColumnWidth - height: 15 - connection: sys.acInput - useInputCurrentLimit: true - maxForwardPowerParameter: "" // handled internally - uses input current limit and AC input voltage - maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxFeedInPower" - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + tableColumnWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Active Source") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth - tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: - { - if (activeSource == 240) - return quTr ("no input") - else if (hasTwoInputs) - return acSourceName[activeSource] + " (AC in " + activeInput + ")" - else - return acSourceName[activeSource] - } - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L1" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L2"; visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L3"; visible: phaseCount >= 3 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: qsTr ("Freq") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.powerL1, "W") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.acInput.powerL2, "W"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.powerL3, "W"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Voltage / Freq") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.voltageL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.acInput.voltageL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.voltageL3, "V"); visible: phaseCount >= 3 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.frequency, "Hz") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.currentL1, "A") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.acInput.currentL2, "A"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.currentL3, "A"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("CurrentLimit") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: - { - var newText - if (newCurrentLimit != actualCurrentLimit) - newText = qsTr(" New ") + newCurrentLimit.toFixed (1) + " A" - else - newText = "" - return currentLimitItem.valid ? currentLimitItem.value.toFixed (1) + " A" + newText: "--" } - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: "L2 values included in L1" - visible: splitPhasePassthruDisabled } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: qsTr("Avaliable Sources") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L1" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L2"; visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L3"; visible: phaseCount >= 3 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: qsTr ("Freq") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: 20; horizontalAlignment: Text.AlignHCenter - text: activeSource == 1 || activeSource == 3 ? ">" : "" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth - 20; horizontalAlignment: Text.AlignRight - text: - { - if (acIn1source == 3 || acIn2source == 3) - return acSourceName[3] - else - return acSourceName[1] - } - } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.grid.voltageL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.grid.voltageL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.grid.voltageL3, "V"); visible: phaseCount >= 3 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.grid.frequency, "Hz") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: 20; horizontalAlignment: Text.AlignHCenter - text: activeSource == 2 ? ">" : "" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth - 20; horizontalAlignment: Text.AlignRight - text: acSourceName[2] } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.genset.voltageL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.genset.voltageL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.genset.voltageL3, "V"); visible: phaseCount >= 3 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.genset.frequency, "Hz") } - } - } - Column - { - id: currentButtonColumn - width: 128 - spacing: 4 - - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: currentButtonColumn.width; horizontalAlignment: Text.AlignHCenter - text: qsTr("Current Limit") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: currentButtonColumn.width; horizontalAlignment: Text.AlignHCenter - text: qsTr("is not adjustable")} - visible: !currentLimitIsAdjustable - } - Row - { - visible: currentLimitIsAdjustable - width: (parent.width / 2) - 2 - spacing: 4 - DetailButton - { - id: preset1button - baseColor: newCurrentLimit === acLimitPreset1 ? "black" : root.buttonColor - pressedColor: root.pressedColor - opacity: acLimitPreset1 === 0 ? 0.001 : 1 - height: 40 - width: parent.width - onClicked: setNewValue (acLimitPreset1) - enabled: acLimitPreset1 === 0 ? false : true - content: TileText - { - text: qsTr(acLimitPreset1 + " A"); font.bold: true; - color: "white" - } - } - DetailButton - { - id: preset2button - baseColor: newCurrentLimit === acLimitPreset2 ? "black" : root.buttonColor - pressedColor: root.pressedColor - opacity: acLimitPreset2 === 0 ? 0.001 : 1 - height: 40 - width: parent.width - onClicked: setNewValue (acLimitPreset2) - enabled: acLimitPreset2 === 0 ? false : true - content: TileText - { - text: qsTr(acLimitPreset2 + " A"); font.bold: true; - color: "white" - } - } - } - Row - { - visible: currentLimitIsAdjustable - width: (parent.width / 2) - 2 - spacing: 4 - DetailButton - { - id: preset3button - baseColor: newCurrentLimit === acLimitPreset3 ? "black" : root.buttonColor - pressedColor: root.pressedColor - opacity: acLimitPreset3 === 0 ? 0.001 : 1 - height: 40 - width: parent.width - onClicked: setNewValue (acLimitPreset3) - enabled: acLimitPreset3 === 0 ? false : true - content: TileText - { - text: qsTr(acLimitPreset3 + " A"); font.bold: true; - color: "white" - } - } - DetailButton - { - visible: currentLimitIsAdjustable - id: preset4button - baseColor: newCurrentLimit === acLimitPreset4 ? "black" : root.buttonColor - pressedColor: root.pressedColor - opacity: acLimitPreset4 === 0 ? 0.001 : 1 - height: 40 - width: parent.width - onClicked: setNewValue (acLimitPreset4) - enabled: acLimitPreset4 === 0 ? false : true - content: TileText - { - text: qsTr(acLimitPreset4 + " A"); font.bold: true; - color: "white" - } - } - } - Row - { - visible: currentLimitIsAdjustable - width: (parent.width / 2) - 2 - spacing: 4 - DetailButton - { - id: trimMinus - baseColor: root.buttonColor - pressedColor: root.pressedColor - height: 40 - width: parent.width - enablePressAndHold: true - onClicked: trimNewValue (-1) - enabled: newCurrentLimit === acLimitPreset4 ? false : true - content: TileText - { - text: qsTr("-1 A"); font.bold: true; - color: "white" - } - } - DetailButton - { - id: trimPlus - baseColor: root.buttonColor - pressedColor: root.pressedColor - height: 40 - width: parent.width - enablePressAndHold: true - onClicked: trimNewValue (+1) - content: TileText - { - text: qsTr("+1 A"); font.bold: true; - color: "white" - } - } - } - Row - { - visible: currentLimitIsAdjustable - width: parent.width - spacing: 4 - DetailButton - { - id: acceptButton - baseColor: root.buttonColor - pressedColor: root.pressedColor - height: 40 - width: parent.width - onClicked: accept() - content: TileText { text: qsTr ("Accept New"); - font.bold: true; color: newCurrentLimit !== actualCurrentLimit ? "white" : "#d9d9d9" } - } - } - } - } - - function setNewValue (newValue) - { - if (currentLimitIsAdjustable) - newCurrentLimit = newValue - } - - function trimNewValue (trimValue) - { - if (!currentLimitIsAdjustable) - return - - newCurrentLimit += trimValue - if (newCurrentLimit < 0) - newCurrentLimit = 0 - } - - function cancel () - { - newCurrentLimit = actualCurrentLimit - pageStack.pop() - } - - function accept () - { - if (currentLimitIsAdjustable) - { - currentLimitItem.setValue (newCurrentLimit) - pageStack.pop() // return to main screen after changing input current limit - } - } - - function getActualCurrent () - { - actualCurrentLimit = currentLimitItem.valid ? currentLimitItem.value : 0 - newCurrentLimit = actualCurrentLimit - } - - // When new service is found check if is a tank sensor - Connections - { - target: DBusServices - onDbusServiceFound: addService(service) - } - - //// hard key handler - // used to press buttons when touch isn't available - // UP and DOWN buttons cycle through the list of buttons - // "space" button is used to simulate a button press - // button must be highlighted so that other uses of "space" - // will still occur - - // list of buttons to be accessed via hard buttons - property variant buttonList: - [ - preset1button, preset2button, preset3button, preset4button, trimMinus, trimPlus, acceptButton - ] - - property int buttonIndex: 0 - - Timer - { - id: targetTimer - interval: 5000 - repeat: false - running: false - onTriggered: { clearHighlight () } - } - - Keys.forwardTo: [keyHandler] - - Item - { - id: keyHandler - Keys.onDownPressed: - { - nextTarget (+1) - event.accepted = true - } - - Keys.onUpPressed: - { - nextTarget (-1) - event.accepted = true - } - } - - function nextTarget (increment) - { - // make one pass through all possible targets to find an enabled one - // if found, that's the new selectedTarget, - // if not selectedTarget does not change - var newIndex = buttonIndex - for (var i = 0; i < buttonList.length; i++) - { - // just restore highlight if not visible - if ( ! targetTimer.running && buttonList[newIndex].visible) - { - setActiveButton (buttonIndex) - return - } - newIndex += increment - if (newIndex >= buttonList.length) - newIndex = 0 - else if (newIndex < 0) - newIndex = buttonList.length - 1 - if (buttonList[newIndex].visible) - { - setActiveButton (newIndex) - break - } - } - } - - // Keys.onSpacePressed doesn't work - stolen by pageHandler - // so build a custom page handler so "space" can be used to press a button - pageToolbarHandler: detailToolbarHandler - ToolbarHandlerPages - { - id: detailToolbarHandler - isDefault: true - function centerAction() - { - acceptSpaceButton () - } - } - - function acceptSpaceButton () - { - if (targetTimer.running) - { - buttonList[buttonIndex].clicked () - } - } - - function setActiveButton (newIndex) - { - buttonIndex = newIndex - for (var i = 0; i < buttonList.length; i++) - if (i == newIndex) - buttonList[i].highlight = true - else - buttonList[i].highlight = false - targetTimer.restart () - } - - function clearHighlight () - { - for (var i = 0; i < buttonList.length; i++) - buttonList[i].highlight = false - } -} diff --git a/FileSets/v3.01/DetailAcInput.qml.orig b/FileSets/v3.01/DetailAcInput.qml.orig deleted file mode 100644 index daca5afc..00000000 --- a/FileSets/v3.01/DetailAcInput.qml.orig +++ /dev/null @@ -1,167 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -Item { - id: root - - property string systemPrefix: "com.victronenergy.system" - property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" - - property variant battery: _battery - property alias dcSystem: _dcSystem - property alias pvCharger: _pvCharger - property alias pvOnAcIn1: _pvOnAcIn1 - property alias pvOnAcIn2: _pvOnAcIn2 - property alias pvOnAcOut: _pvOnAcOut - property alias vebusDc: _vebusDc - property alias acLoad: _acLoad - property alias acInLoad: _acInLoad - property alias acOutLoad: _acOutLoad - property alias grid: _grid - property alias genset: _genset - property alias acInput: _activein - property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } - property variant acSource: _acSource.value - - property alias pvOnGrid: _pvOnAcIn2 - - property int batteryStateIdle: 0 - property int batteryStateCharging: 1 - property int batteryStateDischarging: 2 - - property int acSourceNotAvailable: 0 - property int acSourceGrid: 1 - property int acSourceGenset: 2 - property int acSourceShore: 3 // same as grid - - property alias pvInvertersProductIds: _pvInvertersProductIds - property alias batteryProductId: _batteryProductId - - VBusItem { - id: _pvInvertersProductIds - bind: Utils.path(systemPrefix, "/PvInvertersProductIds") - } - - VBusItem { - id: _batteryProductId - bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") - } - - VBusItem { - id: _vebusService - bind: Utils.path(systemPrefix, "/VebusService") - } - - QtObject { - id: _pvCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} - } - - ObjectAcConnection { - id: _pvOnAcOut - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") - } - - ObjectAcConnection { - id: _pvOnAcIn1 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") - } - - ObjectAcConnection { - id: _pvOnAcIn2 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") - } - - ObjectAcConnection { - id: _genset - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") - } - - VBusItem { - id: _acSource - bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") - } - - /* - * Single Multis that can be split-phase reports NrOfPhases of 2 - * When L2 is disconnected from the input the output L1 and L2 - * are shorted. This item indicates if L2 is passed through - * from AC-in to AC-out. - * 1: L2 is being passed through from AC-in to AC-out. - * 0: L1 and L2 are shorted together. - * invalid: The unit is configured in such way that its L2 output is not used. - */ - - VBusItem { - id: _splitPhaseL2Passthru - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2Passthru") - } - - ObjectAcConnection { - id: _grid - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") - } - - ObjectAcConnection { - id: _activein - bindPrefix: Utils.path(systemPrefix, "/Ac/ActiveIn") - } - - ObjectAcConnection { - id: _acLoad - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") - } - - ObjectAcConnection { - id: _acOutLoad - splitPhaseL2PassthruDisabled:_splitPhaseL2Passthru.value === 0 - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") - } - - ObjectAcConnection { - id: _acInLoad - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") - } - - ObjectAcConnection { - id: _acUnknown - } - - QtObject { - id: _vebusDc - /* - * property VBusItem power: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Power"); unit: "W"} - * DONE: can interface doesn't support this yet! TODO use it...? - */ - property VBusItem current: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Current"); unit: "A"} - property VBusItem voltage: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Voltage"); unit: "V"} - property VBusItem power: VBusItem { - value: _vebusDc.current.valid && _vebusDc.voltage.valid ? - _vebusDc.current.value * _vebusDc.voltage.value : - undefined - unit: "W" - } - } - - QtObject { - id: _battery - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} - property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} - property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} - property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} - - // Get the battery charge state, see batteryState properties - property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} - } - - QtObject { - id: _dcSystem - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} - } -} diff --git a/FileSets/v3.01/DetailInverter.qml b/FileSets/v3.01/DetailInverter.qml deleted file mode 100644 index 05b0f6ce..00000000 --- a/FileSets/v3.01/DetailInverter.qml +++ /dev/null @@ -1,556 +0,0 @@ -////// detail page for setting inverter mode -////// and displaying inverter details -////// pushed from Flow overview - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 -import "enhancedFormat.js" as EnhFmt - -MbPage { - id: root - - title: "Inverter detail" - - property variant sys: theSystem - property string systemPrefix: "com.victronenergy.system" - - property int fontPixelSize: 18 - property color buttonColor: "#979797" - property color pressedColor: "#d3d3d3" - property color backgroundColor: "#b3b3b3" - - property int inverterMode: inverterModeItem.valid ? inverterModeItem.value : 0 - property bool editable: inverterService != "" && inverterModeItem.valid - property int buttonHeight: 40 - property int tableColumnWidth: 80 - property int rowTitleWidth: 130 - property int dataColumns: 3 - property int totalDataWidth: tableColumnWidth * dataColumns - property int legColumnWidth: phaseCount <= 1 ? totalDataWidth : totalDataWidth / phaseCount - - property int numberOfMultis: 0 - property int numberOfInverters: 0 - property string inverterService: "" - property bool isInverter: numberOfMultis === 0 && numberOfInverters === 1 - - Component.onCompleted: { discoverServices(); highlightMode () } - - VBusItem - { - id: inverterModeItem - bind: Utils.path(inverterService, "/Mode") - onValidChanged: highlightMode () - onValueChanged: highlightMode () - } - property VBusItem systemState: VBusItem { bind: Utils.path(systemPrefix, "/SystemState/State") } - SystemState - { - id: vebusState - bind: systemState.valid ? Utils.path(systemPrefix, "/SystemState/State") : Utils.path(inverterService, "/State") - } - VBusItem { id: pInL1; bind: Utils.path(inverterService, "/Ac/ActiveIn/L1/P") } - VBusItem { id: pInL2; bind: Utils.path(inverterService, "/Ac/ActiveIn/L2/P") } - VBusItem { id: pInL3; bind: Utils.path(inverterService, "/Ac/ActiveIn/L2/P") } - VBusItem { id: vInL1; bind: Utils.path(inverterService, "/Ac/ActiveIn/L1/V") } - VBusItem { id: vInL2; bind: Utils.path(inverterService, "/Ac/ActiveIn/L2/V") } - VBusItem { id: vInL3; bind: Utils.path(inverterService, "/Ac/ActiveIn/L3/V") } - VBusItem { id: iInL1; bind: Utils.path(inverterService, "/Ac/ActiveIn/L1/I") } - VBusItem { id: iInL2; bind: Utils.path(inverterService, "/Ac/ActiveIn/L2/I") } - VBusItem { id: iInL3; bind: Utils.path(inverterService, "/Ac/ActiveIn/L3/I") } - VBusItem { id: pOutL1; bind: Utils.path(inverterService, "/Ac/Out/L1/P") } - VBusItem { id: pOutL2; bind: Utils.path(inverterService, "/Ac/Out/L2/P") } - VBusItem { id: pOutL3; bind: Utils.path(inverterService, "/Ac/Out/L3/P") } - VBusItem { id: vOutL1; bind: Utils.path(inverterService, "/Ac/Out/L1/V") } - VBusItem { id: vOutL2; bind: Utils.path(inverterService, "/Ac/Out/L2/V") } - VBusItem { id: vOutL3; bind: Utils.path(inverterService, "/Ac/Out/L3/V") } - VBusItem { id: iOutL1; bind: Utils.path(inverterService, "/Ac/Out/L1/I") } - VBusItem { id: iOutL2; bind: Utils.path(inverterService, "/Ac/Out/L2/I") } - VBusItem { id: iOutL3; bind: Utils.path(inverterService, "/Ac/Out/L3/I") } - VBusItem { id: fInL1; bind: Utils.path(inverterService, "/Ac/ActiveIn/L1/F") } - VBusItem { id: fOutL1; bind: Utils.path(inverterService, "/Ac/Out/L1/F") } - VBusItem { id: dcPower; bind: Utils.path(inverterService, "/Dc/0/Power") } - VBusItem { id: dcCurrent; bind: Utils.path(inverterService, "/Dc/0/Current") } - VBusItem { id: splitPhaseL2Passthru; bind: Utils.path(inverterService, "/Ac/State/SplitPhaseL2Passthru") } - VBusItem { id: phaseCountItem; bind: Utils.path(inverterService, "/Ac/NumberOfPhases") } - - property bool noL2inverter: splitPhaseL2Passthru.valid - property bool l2AndL1OutSummed: noL2inverter && splitPhaseL2Passthru.value === 0 - property int phaseCount: phaseCountItem.valid ? phaseCountItem.value : 0 - - // background - Rectangle - { - anchors - { - fill: parent - } - color: root.backgroundColor - } - - Row - { - spacing: 5 - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - Column - { - spacing: 2 - Row - { - PowerGaugeMulti - { - id: gauge - width: rowTitleWidth + totalDataWidth - height: 15 - inverterService: root.inverterService - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Total Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: - { - var total = 0 - var totalValid = false - if (pOutL1.valid && pInL1.valid) - { - total += pOutL1.value - pInL1.value - totalValid = true - } - if (pOutL2.valid && pInL2.valid) - { - total += pOutL2.value - pInL2.value - totalValid = true - } - if (pOutL3.valid && pInL3.valid) - { - total += pOutL3.value - pInL3.value - totalValid = true - } - if (totalValid) - return EnhFmt.formatValue (total, "W") - else - return "--" - } - } - visible: phaseCount >= 2 - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("State") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: vebusState.text } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: "" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L1" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L2" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L3"; visible: phaseCount >= 3 } - visible: phaseCount >= 2 - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: formatValueDiff (pOutL1, pInL1, "W") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: - { - if (l2AndL1OutSummed) - return "< < <" - else if (noL2inverter) - return qsTr("none") - else - return formatValueDiff (pOutL2, pInL2, "W") - } - visible: phaseCount >= 2 - } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: formatValueDiff (pOutL3, pInL3, "W"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Input Voltage") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (vInL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (vInL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (vInL3, "V"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Output Voltage") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (vOutL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (vOutL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (vOutL3, "V"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Input Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (iInL1, "A") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (iInL2, "A"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (iInL3, "A"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Output Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (iOutL1, "A") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l2AndL1OutSummed ? "< < <" : EnhFmt.formatVBusItem (iOutL2, "A"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (iOutL3, "A"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Frequency In / Out") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth / 2; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (fInL1, "Hz") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth / 2; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (fOutL1, "Hz") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("DC Power / Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth * 0.4; horizontalAlignment: Text.AlignHCenter - text: - { - if (! dcPower.valid) - return "" - else if (dcPower.value > 0) - return qsTr ("supplying") - else if (dcPower.value < 0) - return qsTr ("consuming") - else - return "" - } - } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth * 0.3; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (dcPower, "W") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth * 0.3; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (dcCurrent, "A") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: l2AndL1OutSummed ? qsTr ("L2 Output values included in L1") : qsTr ("L2 AC out from AC in (no inverter)") - visible: noL2inverter - } - } - } - Column - { - width: 80 - spacing: 4 - - DetailButton - { - id: onButton - baseColor: inverterMode === 3 ? "green" : "#e6ffe6" - pressedColor: root.pressedColor - height: root.buttonHeight - width: parent.width - 6 - visible: !isInverter - onClicked: changeMode(3) - content: TileText - { - text: qsTr("On"); font.bold: true; - color: inverterMode === 3 ? "white" : "black" - } - } - DetailButton - { - id: offButton - baseColor: inverterMode === 4 ? "black" : "#e6e6e6" - pressedColor: root.pressedColor - height: root.buttonHeight - width: parent.width - 6 - onClicked: changeMode(4) - content: TileText - { - text: qsTr("Off"); font.bold: true; - color: inverterMode === 4 ? "white" : "black" - } - } - DetailButton - { - id: invertOnlyButton - baseColor: inverterMode === 2 ? "blue" : "#ccccff" - pressedColor: root.pressedColor - height: root.buttonHeight - width: parent.width - 6 - onClicked: changeMode(2) - content: TileText - { - text: isInverter ? qsTr("On") : qsTr("Inverter\nOnly"); font.bold: true; - color: inverterMode === 2 ? "white" : "black" - } - } - DetailButton - { - id: chargeOnlyButton - baseColor: inverterMode === 1 ? "orange" : "#ffedcc" - pressedColor: root.pressedColor - height: root.buttonHeight - width: parent.width - 6 - visible: !isInverter - onClicked: changeMode(1) - content: TileText - { - text: qsTr("Charger\nOnly"); font.bold: true; - color: inverterMode === 1 ? "white" : "black" - } - } - DetailButton - { - id: ecoButton - baseColor: inverterMode === 5 ? "orange" : "#ffedcc" - pressedColor: root.pressedColor - height: root.buttonHeight - width: parent.width - 6 - visible: isInverter - onClicked: changeMode(5) - content: TileText - { - text: qsTr("Eco"); font.bold: true; - color: inverterMode === 5 ? "white" : "black" - } - } - } - } - - function changeMode(newMode) - { - if (editable) - { - inverterModeItem.setValue(newMode) - pageStack.pop() // return to flow screen after changing inverter mode - } - } - - function cancel() - { - pageStack.pop() - } - - function highlightMode () - { - if (editable) - inverterMode = inverterModeItem.value - else - inverterMode = 0 - } - - - // When new service is found check if is a tank sensor - Connections - { - target: DBusServices - onDbusServiceFound: addService(service) - } - - function addService(service) - { - switch (service.type) - { - case DBusService.DBUS_SERVICE_MULTI: - case DBusService.DBUS_SERVICE_MULTI_RS: - numberOfMultis++ - if (numberOfMultis === 1) - inverterService = service.name; - break;; - case DBusService.DBUS_SERVICE_INVERTER: - numberOfInverters++ - if (numberOfInverters === 1 && numberOfMultis === 0) - inverterService = service.name; - break;; - } - } - - // Detect available services of interest - function discoverServices() - { - numberOfMultis = 0 - numberOfInverters = 0 - inverterService = "" - for (var i = 0; i < DBusServices.count; i++) - { - addService(DBusServices.at(i)) - } - } - - function formatValueDiff (item1, item2, unit) - { - if (item1.valid && item2.valid) - return EnhFmt.formatValue (item1.value - item2.value, unit) - else - return "--" - } - - - //// hard key handler - // used to press buttons when touch isn't available - // UP and DOWN buttons cycle through the list of buttons - // "space" button is used to simulate a button press - // button must be highlighted so that other uses of "space" - // will still occur - - // list of buttons to be accessed via hard buttons - property variant buttonList: - [ - onButton, offButton, invertOnlyButton, chargeOnlyButton, ecoButton - ] - - property int buttonIndex: 0 - - Timer - { - id: targetTimer - interval: 5000 - repeat: false - running: false - onTriggered: { clearHighlight () } - } - - Keys.forwardTo: [keyHandler] - - Item - { - id: keyHandler - Keys.onDownPressed: - { - nextTarget (+1) - event.accepted = true - } - - Keys.onUpPressed: - { - nextTarget (-1) - event.accepted = true - } - } - - function nextTarget (increment) - { - // make one pass through all possible targets to find an enabled one - // if found, that's the new selectedTarget, - // if not selectedTarget does not change - var newIndex = buttonIndex - for (var i = 0; i < buttonList.length; i++) - { - // just restore highlight if not visible - if ( ! targetTimer.running && buttonList[newIndex].visible) - { - setActiveButton (buttonIndex) - return - } - newIndex += increment - if (newIndex >= buttonList.length) - newIndex = 0 - else if (newIndex < 0) - newIndex = buttonList.length - 1 - if (buttonList[newIndex].visible) - { - setActiveButton (newIndex) - break - } - } - } - - // Keys.onSpacePressed doesn't work - stolen by pageHandler - // so build a custom page handler so "space" can be used to press a button - pageToolbarHandler: detailToolbarHandler - ToolbarHandlerPages - { - id: detailToolbarHandler - isDefault: true - function centerAction() - { - acceptSpaceButton () - } - } - - function acceptSpaceButton () - { - if (targetTimer.running) - { - buttonList[buttonIndex].clicked () - } - } - - function setActiveButton (newIndex) - { - buttonIndex = newIndex - for (var i = 0; i < buttonList.length; i++) - if (i == newIndex) - buttonList[i].highlight = true - else - buttonList[i].highlight = false - targetTimer.restart () - } - - function clearHighlight () - { - for (var i = 0; i < buttonList.length; i++) - buttonList[i].highlight = false - } -} diff --git a/FileSets/v3.01/DetailInverter.qml.orig b/FileSets/v3.01/DetailInverter.qml.orig deleted file mode 100644 index daca5afc..00000000 --- a/FileSets/v3.01/DetailInverter.qml.orig +++ /dev/null @@ -1,167 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -Item { - id: root - - property string systemPrefix: "com.victronenergy.system" - property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" - - property variant battery: _battery - property alias dcSystem: _dcSystem - property alias pvCharger: _pvCharger - property alias pvOnAcIn1: _pvOnAcIn1 - property alias pvOnAcIn2: _pvOnAcIn2 - property alias pvOnAcOut: _pvOnAcOut - property alias vebusDc: _vebusDc - property alias acLoad: _acLoad - property alias acInLoad: _acInLoad - property alias acOutLoad: _acOutLoad - property alias grid: _grid - property alias genset: _genset - property alias acInput: _activein - property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } - property variant acSource: _acSource.value - - property alias pvOnGrid: _pvOnAcIn2 - - property int batteryStateIdle: 0 - property int batteryStateCharging: 1 - property int batteryStateDischarging: 2 - - property int acSourceNotAvailable: 0 - property int acSourceGrid: 1 - property int acSourceGenset: 2 - property int acSourceShore: 3 // same as grid - - property alias pvInvertersProductIds: _pvInvertersProductIds - property alias batteryProductId: _batteryProductId - - VBusItem { - id: _pvInvertersProductIds - bind: Utils.path(systemPrefix, "/PvInvertersProductIds") - } - - VBusItem { - id: _batteryProductId - bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") - } - - VBusItem { - id: _vebusService - bind: Utils.path(systemPrefix, "/VebusService") - } - - QtObject { - id: _pvCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} - } - - ObjectAcConnection { - id: _pvOnAcOut - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") - } - - ObjectAcConnection { - id: _pvOnAcIn1 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") - } - - ObjectAcConnection { - id: _pvOnAcIn2 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") - } - - ObjectAcConnection { - id: _genset - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") - } - - VBusItem { - id: _acSource - bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") - } - - /* - * Single Multis that can be split-phase reports NrOfPhases of 2 - * When L2 is disconnected from the input the output L1 and L2 - * are shorted. This item indicates if L2 is passed through - * from AC-in to AC-out. - * 1: L2 is being passed through from AC-in to AC-out. - * 0: L1 and L2 are shorted together. - * invalid: The unit is configured in such way that its L2 output is not used. - */ - - VBusItem { - id: _splitPhaseL2Passthru - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2Passthru") - } - - ObjectAcConnection { - id: _grid - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") - } - - ObjectAcConnection { - id: _activein - bindPrefix: Utils.path(systemPrefix, "/Ac/ActiveIn") - } - - ObjectAcConnection { - id: _acLoad - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") - } - - ObjectAcConnection { - id: _acOutLoad - splitPhaseL2PassthruDisabled:_splitPhaseL2Passthru.value === 0 - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") - } - - ObjectAcConnection { - id: _acInLoad - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") - } - - ObjectAcConnection { - id: _acUnknown - } - - QtObject { - id: _vebusDc - /* - * property VBusItem power: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Power"); unit: "W"} - * DONE: can interface doesn't support this yet! TODO use it...? - */ - property VBusItem current: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Current"); unit: "A"} - property VBusItem voltage: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Voltage"); unit: "V"} - property VBusItem power: VBusItem { - value: _vebusDc.current.valid && _vebusDc.voltage.valid ? - _vebusDc.current.value * _vebusDc.voltage.value : - undefined - unit: "W" - } - } - - QtObject { - id: _battery - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} - property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} - property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} - property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} - - // Get the battery charge state, see batteryState properties - property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} - } - - QtObject { - id: _dcSystem - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} - } -} diff --git a/FileSets/v3.01/DetailLoadsCombined.qml b/FileSets/v3.01/DetailLoadsCombined.qml deleted file mode 100644 index d286c158..00000000 --- a/FileSets/v3.01/DetailLoadsCombined.qml +++ /dev/null @@ -1,147 +0,0 @@ -////// detail page for displaying critical AC output details -////// pushed from Flow overview - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 -import "enhancedFormat.js" as EnhFmt - -MbPage { - id: root - - title: qsTr ("AC Loads detail") - - property variant sys: theSystem - property string systemPrefix: "com.victronenergy.system" - - property int fontPixelSize: 18 - property color backgroundColor: "#b3b3b3" - - property int dataColumns: 3 - property int rowTitleWidth: 130 - property int totalDataWidth: root.width - rowTitleWidth - 20 - property int tableColumnWidth: totalDataWidth / dataColumns - property int legColumnWidth: phaseCount <= 1 ? totalDataWidth : totalDataWidth / phaseCount - - property int phaseCount: sys.acLoad.phaseCount.valid ? sys.acLoad.phaseCount.value : 0 - - VBusItem { id: vebusServiceItem; bind: Utils.path(systemPrefix, "/VebusService") } - property string inverterService: vebusServiceItem.valid ? vebusServiceItem.value : "" - VBusItem { id: splitPhaseL2Passthru; bind: Utils.path(inverterService, "/Ac/State/SplitPhaseL2Passthru") } - property bool l1AndL2OutShorted: splitPhaseL2Passthru.valid && splitPhaseL2Passthru.value === 0 - - // background - Rectangle - { - anchors - { - fill: parent - } - color: root.backgroundColor - } - - Row - { - spacing: 5 - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - Column - { - spacing: 2 - Row - { - Text { id: totalLabel; font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Total Power") } - Text { id: totalPower; font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.power, "W") - } - PowerGauge - { - id: gauge - width: (root.width * 0.9) - totalLabel.width - totalPower.width - height: 15 - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputMaxPower" - connection: sys.acLoad - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: "" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L1" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L2"; visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L3"; visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.powerL1, "W") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l1AndL2OutShorted ? "< < <" : EnhFmt.formatVBusItem (sys.acLoad.powerL2, "W"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.powerL3, "W"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Voltage") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.voltageL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l1AndL2OutShorted ? "< < <" : EnhFmt.formatVBusItem (sys.acLoad.voltageL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.voltageL3, "V"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.currentL1, "A") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l1AndL2OutShorted ? "< < <" : EnhFmt.formatVBusItem (sys.acLoad.currentL2, "A"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.currentL3, "A"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Frequency") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.frequency, "Hz") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: "L2 values included in L1" - visible: l1AndL2OutShorted } - } - } - } -} diff --git a/FileSets/v3.01/DetailLoadsCombined.qml.orig b/FileSets/v3.01/DetailLoadsCombined.qml.orig deleted file mode 100644 index daca5afc..00000000 --- a/FileSets/v3.01/DetailLoadsCombined.qml.orig +++ /dev/null @@ -1,167 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -Item { - id: root - - property string systemPrefix: "com.victronenergy.system" - property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" - - property variant battery: _battery - property alias dcSystem: _dcSystem - property alias pvCharger: _pvCharger - property alias pvOnAcIn1: _pvOnAcIn1 - property alias pvOnAcIn2: _pvOnAcIn2 - property alias pvOnAcOut: _pvOnAcOut - property alias vebusDc: _vebusDc - property alias acLoad: _acLoad - property alias acInLoad: _acInLoad - property alias acOutLoad: _acOutLoad - property alias grid: _grid - property alias genset: _genset - property alias acInput: _activein - property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } - property variant acSource: _acSource.value - - property alias pvOnGrid: _pvOnAcIn2 - - property int batteryStateIdle: 0 - property int batteryStateCharging: 1 - property int batteryStateDischarging: 2 - - property int acSourceNotAvailable: 0 - property int acSourceGrid: 1 - property int acSourceGenset: 2 - property int acSourceShore: 3 // same as grid - - property alias pvInvertersProductIds: _pvInvertersProductIds - property alias batteryProductId: _batteryProductId - - VBusItem { - id: _pvInvertersProductIds - bind: Utils.path(systemPrefix, "/PvInvertersProductIds") - } - - VBusItem { - id: _batteryProductId - bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") - } - - VBusItem { - id: _vebusService - bind: Utils.path(systemPrefix, "/VebusService") - } - - QtObject { - id: _pvCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} - } - - ObjectAcConnection { - id: _pvOnAcOut - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") - } - - ObjectAcConnection { - id: _pvOnAcIn1 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") - } - - ObjectAcConnection { - id: _pvOnAcIn2 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") - } - - ObjectAcConnection { - id: _genset - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") - } - - VBusItem { - id: _acSource - bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") - } - - /* - * Single Multis that can be split-phase reports NrOfPhases of 2 - * When L2 is disconnected from the input the output L1 and L2 - * are shorted. This item indicates if L2 is passed through - * from AC-in to AC-out. - * 1: L2 is being passed through from AC-in to AC-out. - * 0: L1 and L2 are shorted together. - * invalid: The unit is configured in such way that its L2 output is not used. - */ - - VBusItem { - id: _splitPhaseL2Passthru - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2Passthru") - } - - ObjectAcConnection { - id: _grid - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") - } - - ObjectAcConnection { - id: _activein - bindPrefix: Utils.path(systemPrefix, "/Ac/ActiveIn") - } - - ObjectAcConnection { - id: _acLoad - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") - } - - ObjectAcConnection { - id: _acOutLoad - splitPhaseL2PassthruDisabled:_splitPhaseL2Passthru.value === 0 - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") - } - - ObjectAcConnection { - id: _acInLoad - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") - } - - ObjectAcConnection { - id: _acUnknown - } - - QtObject { - id: _vebusDc - /* - * property VBusItem power: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Power"); unit: "W"} - * DONE: can interface doesn't support this yet! TODO use it...? - */ - property VBusItem current: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Current"); unit: "A"} - property VBusItem voltage: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Voltage"); unit: "V"} - property VBusItem power: VBusItem { - value: _vebusDc.current.valid && _vebusDc.voltage.valid ? - _vebusDc.current.value * _vebusDc.voltage.value : - undefined - unit: "W" - } - } - - QtObject { - id: _battery - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} - property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} - property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} - property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} - - // Get the battery charge state, see batteryState properties - property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} - } - - QtObject { - id: _dcSystem - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} - } -} diff --git a/FileSets/v3.01/DetailLoadsOnInput.qml b/FileSets/v3.01/DetailLoadsOnInput.qml deleted file mode 100644 index 77e99645..00000000 --- a/FileSets/v3.01/DetailLoadsOnInput.qml +++ /dev/null @@ -1,147 +0,0 @@ -////// detail page for displaying non-critical AC output details -////// pushed from Flow overview - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 -import "enhancedFormat.js" as EnhFmt - -MbPage { - id: root - - title: "Loads on AC Input Detail" - - property variant sys: theSystem - property string systemPrefix: "com.victronenergy.system" - - property int fontPixelSize: 18 - property color backgroundColor: "#b3b3b3" - - property int dataColumns: 3 - property int rowTitleWidth: 130 - property int totalDataWidth: root.width - rowTitleWidth - 20 - property int tableColumnWidth: totalDataWidth / dataColumns - property int legColumnWidth: phaseCount <= 1 ? totalDataWidth : totalDataWidth / phaseCount - - property int phaseCount: sys.acInLoad.phaseCount.valid ? sys.acInLoad.phaseCount.value : 0 - - VBusItem { id: vebusServiceItem; bind: Utils.path(systemPrefix, "/VebusService") } - property string inverterService: vebusServiceItem.valid ? vebusServiceItem.value : "" - VBusItem { id: splitPhaseL2Passthru; bind: Utils.path(inverterService, "/Ac/State/SplitPhaseL2Passthru") } - property bool l1AndL2OutShorted: splitPhaseL2Passthru.valid && splitPhaseL2Passthru.value === 0 - - // background - Rectangle - { - anchors - { - fill: parent - } - color: root.backgroundColor - } - - Row - { - spacing: 5 - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - Column - { - spacing: 2 - Row - { - Text { id: totalLabel; font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Total Power") } - Text { id: totalPower; font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.power, "W") - } - PowerGauge - { - id: gauge - width: (root.width * 0.9) - totalLabel.width - totalPower.width - height: 15 - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputMaxPower" - connection: sys.acInLoad - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: "" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L1" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L2"; visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L3"; visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.powerL1, "W") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l1AndL2OutShorted ? "< < <" : EnhFmt.formatVBusItem (sys.acInLoad.powerL2, "W"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.powerL3, "W"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Voltage") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.voltageL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l1AndL2OutShorted ? "< < <" : EnhFmt.formatVBusItem (sys.acInLoad.voltageL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.voltageL3, "V"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.currentL1, "A") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l1AndL2OutShorted ? "< < <" : EnhFmt.formatVBusItem (sys.acInLoad.currentL2, "A"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.currentL3, "A"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Frequency") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.frequency, "Hz") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: "L2 values included in L1" - visible: l1AndL2OutShorted } - } - } - } -} diff --git a/FileSets/v3.01/DetailLoadsOnInput.qml.orig b/FileSets/v3.01/DetailLoadsOnInput.qml.orig deleted file mode 100644 index daca5afc..00000000 --- a/FileSets/v3.01/DetailLoadsOnInput.qml.orig +++ /dev/null @@ -1,167 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -Item { - id: root - - property string systemPrefix: "com.victronenergy.system" - property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" - - property variant battery: _battery - property alias dcSystem: _dcSystem - property alias pvCharger: _pvCharger - property alias pvOnAcIn1: _pvOnAcIn1 - property alias pvOnAcIn2: _pvOnAcIn2 - property alias pvOnAcOut: _pvOnAcOut - property alias vebusDc: _vebusDc - property alias acLoad: _acLoad - property alias acInLoad: _acInLoad - property alias acOutLoad: _acOutLoad - property alias grid: _grid - property alias genset: _genset - property alias acInput: _activein - property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } - property variant acSource: _acSource.value - - property alias pvOnGrid: _pvOnAcIn2 - - property int batteryStateIdle: 0 - property int batteryStateCharging: 1 - property int batteryStateDischarging: 2 - - property int acSourceNotAvailable: 0 - property int acSourceGrid: 1 - property int acSourceGenset: 2 - property int acSourceShore: 3 // same as grid - - property alias pvInvertersProductIds: _pvInvertersProductIds - property alias batteryProductId: _batteryProductId - - VBusItem { - id: _pvInvertersProductIds - bind: Utils.path(systemPrefix, "/PvInvertersProductIds") - } - - VBusItem { - id: _batteryProductId - bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") - } - - VBusItem { - id: _vebusService - bind: Utils.path(systemPrefix, "/VebusService") - } - - QtObject { - id: _pvCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} - } - - ObjectAcConnection { - id: _pvOnAcOut - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") - } - - ObjectAcConnection { - id: _pvOnAcIn1 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") - } - - ObjectAcConnection { - id: _pvOnAcIn2 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") - } - - ObjectAcConnection { - id: _genset - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") - } - - VBusItem { - id: _acSource - bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") - } - - /* - * Single Multis that can be split-phase reports NrOfPhases of 2 - * When L2 is disconnected from the input the output L1 and L2 - * are shorted. This item indicates if L2 is passed through - * from AC-in to AC-out. - * 1: L2 is being passed through from AC-in to AC-out. - * 0: L1 and L2 are shorted together. - * invalid: The unit is configured in such way that its L2 output is not used. - */ - - VBusItem { - id: _splitPhaseL2Passthru - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2Passthru") - } - - ObjectAcConnection { - id: _grid - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") - } - - ObjectAcConnection { - id: _activein - bindPrefix: Utils.path(systemPrefix, "/Ac/ActiveIn") - } - - ObjectAcConnection { - id: _acLoad - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") - } - - ObjectAcConnection { - id: _acOutLoad - splitPhaseL2PassthruDisabled:_splitPhaseL2Passthru.value === 0 - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") - } - - ObjectAcConnection { - id: _acInLoad - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") - } - - ObjectAcConnection { - id: _acUnknown - } - - QtObject { - id: _vebusDc - /* - * property VBusItem power: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Power"); unit: "W"} - * DONE: can interface doesn't support this yet! TODO use it...? - */ - property VBusItem current: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Current"); unit: "A"} - property VBusItem voltage: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Voltage"); unit: "V"} - property VBusItem power: VBusItem { - value: _vebusDc.current.valid && _vebusDc.voltage.valid ? - _vebusDc.current.value * _vebusDc.voltage.value : - undefined - unit: "W" - } - } - - QtObject { - id: _battery - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} - property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} - property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} - property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} - - // Get the battery charge state, see batteryState properties - property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} - } - - QtObject { - id: _dcSystem - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} - } -} diff --git a/FileSets/v3.01/DetailLoadsOnOutput.qml b/FileSets/v3.01/DetailLoadsOnOutput.qml deleted file mode 100644 index ea917556..00000000 --- a/FileSets/v3.01/DetailLoadsOnOutput.qml +++ /dev/null @@ -1,152 +0,0 @@ -////// detail page for displaying critical AC output details -////// pushed from Flow overview - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 -import "enhancedFormat.js" as EnhFmt - -MbPage { - id: root - - title: combineAcLoads ? qsTr ("AC Loads detail") : qsTr ("Loads on AC Output detail") - - property variant sys: theSystem - property string systemPrefix: "com.victronenergy.system" - property string settingsPrefix: "com.victronenergy.settings" - - property int fontPixelSize: 18 - property color backgroundColor: "#b3b3b3" - - property int dataColumns: 3 - property int rowTitleWidth: 130 - property int totalDataWidth: root.width - rowTitleWidth - 20 - property int tableColumnWidth: totalDataWidth / dataColumns - property int legColumnWidth: phaseCount <= 1 ? totalDataWidth : totalDataWidth / phaseCount - - property int phaseCount: outputLoad.phaseCount.valid ? outputLoad.phaseCount.value : 0 - - VBusItem { id: vebusServiceItem; bind: Utils.path(systemPrefix, "/VebusService") } - property string inverterService: vebusServiceItem.valid ? vebusServiceItem.value : "" - VBusItem { id: splitPhaseL2Passthru; bind: Utils.path(inverterService, "/Ac/State/SplitPhaseL2Passthru") } - property bool l1AndL2OutShorted: splitPhaseL2Passthru.valid && splitPhaseL2Passthru.value === 0 - - VBusItem { id: _combineAcLoads; bind: "com.victronenergy.settings/Settings/GuiMods/EnhancedFlowCombineLoads" } - property bool combineAcLoads: _combineAcLoads.valid && _combineAcLoads.value === 1 - property variant outputLoad: combineAcLoads ? sys.acLoad : sys.acOutLoad - - // background - Rectangle - { - anchors - { - fill: parent - } - color: root.backgroundColor - } - - Row - { - spacing: 5 - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - Column - { - spacing: 2 - Row - { - Text { id: totalLabel; font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Total Power") } - Text { id: totalPower; font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.power, "W") - } - PowerGauge - { - id: gauge - width: (root.width * 0.9) - totalLabel.width - totalPower.width - height: 15 - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputMaxPower" - connection: outputLoad - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: "" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L1" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L2"; visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L3"; visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.powerL1, "W") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l1AndL2OutShorted ? "< < <" : EnhFmt.formatVBusItem (outputLoad.powerL2, "W"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.powerL3, "W"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Voltage") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.voltageL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l1AndL2OutShorted ? "< < <" : EnhFmt.formatVBusItem (outputLoad.voltageL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.voltageL3, "V"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.currentL1, "A") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l1AndL2OutShorted ? "< < <" : EnhFmt.formatVBusItem (outputLoad.currentL2, "A"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.currentL3, "A"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Frequency") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.frequency, "Hz") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: "L2 values included in L1" - visible: l1AndL2OutShorted } - } - } - } -} diff --git a/FileSets/v3.01/DetailLoadsOnOutput.qml.orig b/FileSets/v3.01/DetailLoadsOnOutput.qml.orig deleted file mode 100644 index daca5afc..00000000 --- a/FileSets/v3.01/DetailLoadsOnOutput.qml.orig +++ /dev/null @@ -1,167 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -Item { - id: root - - property string systemPrefix: "com.victronenergy.system" - property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" - - property variant battery: _battery - property alias dcSystem: _dcSystem - property alias pvCharger: _pvCharger - property alias pvOnAcIn1: _pvOnAcIn1 - property alias pvOnAcIn2: _pvOnAcIn2 - property alias pvOnAcOut: _pvOnAcOut - property alias vebusDc: _vebusDc - property alias acLoad: _acLoad - property alias acInLoad: _acInLoad - property alias acOutLoad: _acOutLoad - property alias grid: _grid - property alias genset: _genset - property alias acInput: _activein - property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } - property variant acSource: _acSource.value - - property alias pvOnGrid: _pvOnAcIn2 - - property int batteryStateIdle: 0 - property int batteryStateCharging: 1 - property int batteryStateDischarging: 2 - - property int acSourceNotAvailable: 0 - property int acSourceGrid: 1 - property int acSourceGenset: 2 - property int acSourceShore: 3 // same as grid - - property alias pvInvertersProductIds: _pvInvertersProductIds - property alias batteryProductId: _batteryProductId - - VBusItem { - id: _pvInvertersProductIds - bind: Utils.path(systemPrefix, "/PvInvertersProductIds") - } - - VBusItem { - id: _batteryProductId - bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") - } - - VBusItem { - id: _vebusService - bind: Utils.path(systemPrefix, "/VebusService") - } - - QtObject { - id: _pvCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} - } - - ObjectAcConnection { - id: _pvOnAcOut - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") - } - - ObjectAcConnection { - id: _pvOnAcIn1 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") - } - - ObjectAcConnection { - id: _pvOnAcIn2 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") - } - - ObjectAcConnection { - id: _genset - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") - } - - VBusItem { - id: _acSource - bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") - } - - /* - * Single Multis that can be split-phase reports NrOfPhases of 2 - * When L2 is disconnected from the input the output L1 and L2 - * are shorted. This item indicates if L2 is passed through - * from AC-in to AC-out. - * 1: L2 is being passed through from AC-in to AC-out. - * 0: L1 and L2 are shorted together. - * invalid: The unit is configured in such way that its L2 output is not used. - */ - - VBusItem { - id: _splitPhaseL2Passthru - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2Passthru") - } - - ObjectAcConnection { - id: _grid - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") - } - - ObjectAcConnection { - id: _activein - bindPrefix: Utils.path(systemPrefix, "/Ac/ActiveIn") - } - - ObjectAcConnection { - id: _acLoad - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") - } - - ObjectAcConnection { - id: _acOutLoad - splitPhaseL2PassthruDisabled:_splitPhaseL2Passthru.value === 0 - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") - } - - ObjectAcConnection { - id: _acInLoad - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") - } - - ObjectAcConnection { - id: _acUnknown - } - - QtObject { - id: _vebusDc - /* - * property VBusItem power: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Power"); unit: "W"} - * DONE: can interface doesn't support this yet! TODO use it...? - */ - property VBusItem current: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Current"); unit: "A"} - property VBusItem voltage: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Voltage"); unit: "V"} - property VBusItem power: VBusItem { - value: _vebusDc.current.valid && _vebusDc.voltage.valid ? - _vebusDc.current.value * _vebusDc.voltage.value : - undefined - unit: "W" - } - } - - QtObject { - id: _battery - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} - property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} - property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} - property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} - - // Get the battery charge state, see batteryState properties - property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} - } - - QtObject { - id: _dcSystem - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} - } -} diff --git a/FileSets/v3.01/HubData.qml b/FileSets/v3.01/HubData.qml deleted file mode 100644 index 7ebcdcac..00000000 --- a/FileSets/v3.01/HubData.qml +++ /dev/null @@ -1,264 +0,0 @@ -//////// modified for VE.Direct inverter support -//////// modified for grid/genset meter -//////// added alternator, AC charger, wind generator - -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -Item { - id: root - - property variant sys: theSystem - - property string systemPrefix: "com.victronenergy.system" - property string settingsPrefix: "com.victronenergy.settings" - property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" - -//////// add to support VE.Direct inverters - property string inverterService: "" -//////// add for grid/genset meters - property string gridMeterService: "" - property string gensetService: "" - - property variant battery: _battery - property alias dcSystem: _dcSystem - property alias alternator: _alternator - property alias windGenerator: _windGenerator - property alias fuelCell: _fuelCell - property alias acCharger: _acCharger - property alias pvCharger: _pvCharger - property alias pvOnAcIn1: _pvOnAcIn1 - property alias pvOnAcIn2: _pvOnAcIn2 - property alias pvOnAcOut: _pvOnAcOut - property alias vebusDc: _vebusDc - property alias acLoad: _acLoad - property alias acInLoad: _acInLoad - property alias acOutLoad: _acOutLoad - property alias grid: _grid - property alias acInput: _activein - property alias genset: _genset - property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } - property variant acSource: _acSource.value - - property alias pvOnGrid: _pvOnAcIn2 - - property int batteryStateIdle: 0 - property int batteryStateCharging: 1 - property int batteryStateDischarging: 2 - - property int acSourceNotAvailable: 0 - property int acSourceGrid: 1 - property int acSourceGenset: 2 - property int acSourceShore: 3 // same as grid - - property alias pvInvertersProductIds: _pvInvertersProductIds - property alias batteryProductId: _batteryProductId - - VBusItem { - id: _pvInvertersProductIds - bind: Utils.path(systemPrefix, "/PvInvertersProductIds") - } - - VBusItem { - id: _batteryProductId - bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") - } - - VBusItem { - id: _vebusService - bind: Utils.path(systemPrefix, "/VebusService") - } - - QtObject { - id: _pvCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} - } - -//////// added alternator - QtObject { - id: _alternator - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Alternator/Power"); unit: "W"} - } - -//////// added AC charger - QtObject { - id: _acCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Charger/Power"); unit: "W"} - } - -//////// added wind generator - QtObject { - id: _windGenerator - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/WindGenerator/Power"); unit: "W"} - } - -//////// added fuel cell - QtObject { - id: _fuelCell - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/FuelCell/Power"); unit: "W"} - } - - ObjectAcConnection { - id: _pvOnAcOut - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") - } - - ObjectAcConnection { - id: _pvOnAcIn1 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") - } - - ObjectAcConnection { - id: _pvOnAcIn2 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") - } - - ObjectAcConnection { - id: _genset - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") -//////// modified for VE.Direct inverter support - inverterSource: "/Ac/ActiveIn" - inverterService: sys.vebusPrefix != "" ? sys.vebusPrefix : root.inverterService - } - - VBusItem { - id: _acSource - bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") - } - - /* - * Single Multis that can be split-phase reports NrOfPhases of 2 - * When L2 is disconnected from the input the output L1 and L2 - * are shorted. This item indicates if L2 is passed through - * from AC-in to AC-out. - * 1: L2 is being passed through from AC-in to AC-out. - * 0: L1 and L2 are shorted together. - * invalid: The unit is configured in such way that its L2 output is not used. - */ - - VBusItem { - id: _splitPhaseL2Passthru - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2Passthru") - } - - ObjectAcConnection { - id: _grid - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") -//////// modified for VE.Direct inverter support - inverterSource: "/Ac/ActiveIn" - inverterService: sys.vebusPrefix != "" ? sys.vebusPrefix : root.inverterService - } - - ObjectAcConnection { - id: _acLoad - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") -//////// modified for VE.Direct inverter support - inverterSource: "/Ac/Out" - inverterService: sys.vebusPrefix != "" ? sys.vebusPrefix : root.inverterService - } - - ObjectAcConnection { - id: _acOutLoad - splitPhaseL2PassthruDisabled:_splitPhaseL2Passthru.value === 0 - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") - } - - ObjectAcConnection { - id: _activein - bindPrefix: Utils.path(systemPrefix, "/Ac/ActiveIn") -//////// modified for VE.Direct inverter support - inverterSource: "/Ac/ActiveIn" - inverterService: sys.vebusPrefix != "" ? sys.vebusPrefix : root.inverterService - } - - ObjectAcConnection { - id: _acInLoad - splitPhaseL2PassthruDisabled:_splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") - } - - ObjectAcConnection { - id: _acUnknown - } - - QtObject { - id: _vebusDc - /* - * property VBusItem power: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Power"); unit: "W"} - * DONE: can interface doesn't support this yet! TODO use it...? - */ - property VBusItem current: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Current"); unit: "A"} - property VBusItem voltage: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Voltage"); unit: "V"} - property VBusItem power: VBusItem { - value: _vebusDc.current.valid && _vebusDc.voltage.valid ? - _vebusDc.current.value * _vebusDc.voltage.value : - undefined - unit: "W" - } - } - - QtObject { - id: _battery - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} - property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} - property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} - property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} - - // Get the battery charge state, see batteryState properties - property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} - } - - QtObject { - id: _dcSystem - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} - } - -//////// add to support for adjustable watt / killowatt display switching - VBusItem { id: kwThresholdItem; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/KilowattThreshold") } - property int kilowattThreshold: kwThresholdItem.valid ? kwThresholdItem.value : 1000 - -//////// add to support VE.Direct inverters -//////// and grid/genset meters - Component.onCompleted: discoverServices() - - // When new service is found check if is a tank sensor - Connections - { - target: DBusServices - onDbusServiceFound: addService(service) - } - function addService(service) - { - switch (service.type) - { - case DBusService.DBUS_SERVICE_INVERTER: - if (inverterService === "") - inverterService = service.name; - break;; - case DBusService.DBUS_SERVICE_GRIDMETER: - if (gridMeterService === "") - gridMeterService = service.name; - break;; - case DBusService.DBUS_SERVICE_GENSET: - if (gensetService === "") - gensetService = service.name; - break;; - } - } - - // Check available services inverter services - function discoverServices() - { - inverterService = "" - gridMeterService = "" - gensetService = "" - for (var i = 0; i < DBusServices.count; i++) - addService(DBusServices.at(i)) - } -} diff --git a/FileSets/v3.01/HubData.qml.orig b/FileSets/v3.01/HubData.qml.orig deleted file mode 100644 index daca5afc..00000000 --- a/FileSets/v3.01/HubData.qml.orig +++ /dev/null @@ -1,167 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -Item { - id: root - - property string systemPrefix: "com.victronenergy.system" - property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" - - property variant battery: _battery - property alias dcSystem: _dcSystem - property alias pvCharger: _pvCharger - property alias pvOnAcIn1: _pvOnAcIn1 - property alias pvOnAcIn2: _pvOnAcIn2 - property alias pvOnAcOut: _pvOnAcOut - property alias vebusDc: _vebusDc - property alias acLoad: _acLoad - property alias acInLoad: _acInLoad - property alias acOutLoad: _acOutLoad - property alias grid: _grid - property alias genset: _genset - property alias acInput: _activein - property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } - property variant acSource: _acSource.value - - property alias pvOnGrid: _pvOnAcIn2 - - property int batteryStateIdle: 0 - property int batteryStateCharging: 1 - property int batteryStateDischarging: 2 - - property int acSourceNotAvailable: 0 - property int acSourceGrid: 1 - property int acSourceGenset: 2 - property int acSourceShore: 3 // same as grid - - property alias pvInvertersProductIds: _pvInvertersProductIds - property alias batteryProductId: _batteryProductId - - VBusItem { - id: _pvInvertersProductIds - bind: Utils.path(systemPrefix, "/PvInvertersProductIds") - } - - VBusItem { - id: _batteryProductId - bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") - } - - VBusItem { - id: _vebusService - bind: Utils.path(systemPrefix, "/VebusService") - } - - QtObject { - id: _pvCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} - } - - ObjectAcConnection { - id: _pvOnAcOut - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") - } - - ObjectAcConnection { - id: _pvOnAcIn1 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") - } - - ObjectAcConnection { - id: _pvOnAcIn2 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") - } - - ObjectAcConnection { - id: _genset - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") - } - - VBusItem { - id: _acSource - bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") - } - - /* - * Single Multis that can be split-phase reports NrOfPhases of 2 - * When L2 is disconnected from the input the output L1 and L2 - * are shorted. This item indicates if L2 is passed through - * from AC-in to AC-out. - * 1: L2 is being passed through from AC-in to AC-out. - * 0: L1 and L2 are shorted together. - * invalid: The unit is configured in such way that its L2 output is not used. - */ - - VBusItem { - id: _splitPhaseL2Passthru - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2Passthru") - } - - ObjectAcConnection { - id: _grid - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") - } - - ObjectAcConnection { - id: _activein - bindPrefix: Utils.path(systemPrefix, "/Ac/ActiveIn") - } - - ObjectAcConnection { - id: _acLoad - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") - } - - ObjectAcConnection { - id: _acOutLoad - splitPhaseL2PassthruDisabled:_splitPhaseL2Passthru.value === 0 - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") - } - - ObjectAcConnection { - id: _acInLoad - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") - } - - ObjectAcConnection { - id: _acUnknown - } - - QtObject { - id: _vebusDc - /* - * property VBusItem power: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Power"); unit: "W"} - * DONE: can interface doesn't support this yet! TODO use it...? - */ - property VBusItem current: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Current"); unit: "A"} - property VBusItem voltage: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Voltage"); unit: "V"} - property VBusItem power: VBusItem { - value: _vebusDc.current.valid && _vebusDc.voltage.valid ? - _vebusDc.current.value * _vebusDc.voltage.value : - undefined - unit: "W" - } - } - - QtObject { - id: _battery - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} - property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} - property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} - property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} - - // Get the battery charge state, see batteryState properties - property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} - } - - QtObject { - id: _dcSystem - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} - } -} diff --git a/FileSets/v3.01/MbEditBox.qml b/FileSets/v3.01/MbEditBox.qml deleted file mode 120000 index 8381b7d5..00000000 --- a/FileSets/v3.01/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v3.01/MbEditBoxDateTime.qml b/FileSets/v3.01/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v3.01/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.01/MbItem.qml b/FileSets/v3.01/MbItem.qml deleted file mode 120000 index 048a313c..00000000 --- a/FileSets/v3.01/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.01/MbItemDigitalInput.qml b/FileSets/v3.01/MbItemDigitalInput.qml deleted file mode 120000 index 4404b520..00000000 --- a/FileSets/v3.01/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.01/MbSpinBox.qml b/FileSets/v3.01/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v3.01/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.01/MbStyle.qml b/FileSets/v3.01/MbStyle.qml deleted file mode 120000 index d1940446..00000000 --- a/FileSets/v3.01/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.01/MbSubMenu.qml b/FileSets/v3.01/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v3.01/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.01/Multi.qml b/FileSets/v3.01/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v3.01/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.01/ObjectAcConnection.qml b/FileSets/v3.01/ObjectAcConnection.qml deleted file mode 100644 index d0be93ee..00000000 --- a/FileSets/v3.01/ObjectAcConnection.qml +++ /dev/null @@ -1,52 +0,0 @@ -////// modified to show voltage, current and frequency in flow overview -////// modified to show bar graphs -////// modified to use grid or genset meter if present - -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -QtObject { - property string bindPrefix - property string inverterService: "" - property string inverterSource: "" - - property VBusItem powerL1: VBusItem { bind: Utils.path(bindPrefix, "/L1/Power"); unit: "W"} - property VBusItem powerL2: VBusItem { bind: Utils.path(bindPrefix, "/L2/Power"); unit: "W"} - property VBusItem powerL3: VBusItem { bind: Utils.path(bindPrefix, "/L3/Power"); unit: "W"} - property VBusItem power: VBusItem { unit: "W" } - property VBusItem phaseCount: VBusItem { bind: Utils.path(bindPrefix, "/NumberOfPhases") } - property bool splitPhaseL2PassthruDisabled: false - property bool isAcOutput: false - property bool l1AndL2OutShorted: splitPhaseL2PassthruDisabled && isAcOutput -////// added to show bar graphs - property VBusItem inverterState: VBusItem { bind: Utils.path(systemPrefix, "/SystemState/State" ) } - - ////// add to show voltage, current, frequency and bar graphs and use grid/genset meter - property VBusItem voltageL1: VBusItem { bind: Utils.path (bindPrefix, "/L1/Voltage"); unit: "V"} - property VBusItem voltageL2: VBusItem { bind: Utils.path (bindPrefix, "/L2/Voltage"); unit: "V"} - property VBusItem voltageL3: VBusItem { bind: Utils.path (bindPrefix, "/L3/Voltage"); unit: "V"} - - property VBusItem currentL1: VBusItem { bind: Utils.path (bindPrefix, "/L1/Current"); unit: "A"} - property VBusItem currentL2: VBusItem { bind: Utils.path (bindPrefix, "/L2/Current"); unit: "A"} - property VBusItem currentL3: VBusItem { bind: Utils.path (bindPrefix, "/L3/Current"); unit: "A"} - - property VBusItem frequency: VBusItem { bind: Utils.path (bindPrefix, "/Frequency"); unit: "Hz"} - - property VBusItem inCurrentLimit: VBusItem { bind: Utils.path(inverterService, inverterSource, "/CurrentLimit"); unit: "A"} - ////// end add to show voltage, current and frequency - - // As systemcalc doesn't provide the totals anymore we calculate it here. - // Timer is needed because the values are not received in once and then the total - // changes too often on system with more than one phase - property Timer timer: Timer { - interval: 1000 - running: true - repeat: true - onTriggered: { - power.value = powerL1.valid || powerL2.valid || powerL3.valid ? (powerL1.valid ? powerL1.value : 0) + - (powerL2.valid ? powerL2.value : 0) + - (powerL3.valid ? powerL3.value : 0) : undefined - } - } -} diff --git a/FileSets/v3.01/ObjectAcConnection.qml.orig b/FileSets/v3.01/ObjectAcConnection.qml.orig deleted file mode 100644 index c9c09a94..00000000 --- a/FileSets/v3.01/ObjectAcConnection.qml.orig +++ /dev/null @@ -1,30 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -QtObject { - property string bindPrefix - - property VBusItem powerL1: VBusItem { bind: Utils.path(bindPrefix, "/L1/Power"); unit: "W"} - property VBusItem powerL2: VBusItem { bind: Utils.path(bindPrefix, "/L2/Power"); unit: "W"} - property VBusItem powerL3: VBusItem { bind: Utils.path(bindPrefix, "/L3/Power"); unit: "W"} - property VBusItem phaseCount: VBusItem { bind: Utils.path(bindPrefix, "/NumberOfPhases") } - property bool splitPhaseL2PassthruDisabled: false - property bool isAcOutput: false - property bool l1AndL2OutShorted: splitPhaseL2PassthruDisabled && isAcOutput - - property VBusItem power: VBusItem { unit: "W" } - // As systemcalc doesn't provide the totals anymore we calculate it here. - // Timer is needed because the values are not received in once and then the total - // changes too often on system with more than one phase - property Timer timer: Timer { - interval: 1000 - running: true - repeat: true - onTriggered: { - power.value = powerL1.valid || powerL2.valid || powerL3.valid ? (powerL1.valid ? powerL1.value : 0) + - (powerL2.valid ? powerL2.value : 0) + - (powerL3.valid ? powerL3.value : 0) : undefined - } - } -} diff --git a/FileSets/v3.01/OverviewAcValuesEnhanced.qml b/FileSets/v3.01/OverviewAcValuesEnhanced.qml deleted file mode 100644 index 2009d9d7..00000000 --- a/FileSets/v3.01/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1,109 +0,0 @@ -////// modified to show voltage, current and frequency in flow overview -// only displays values for sys.acInput and sys.acLoad -// because other connections don't have related parameters -////// modified to show power bar graphs - - -import QtQuick 1.1 -import "enhancedFormat.js" as EnhFmt - -Item { - id: root - width: parent.width - height: parent.height - - // NOTE: data is taken by qml, hence it is called connection - property variant connection - - property int phaseCount: root.connection !== undefined && root.connection.phaseCount.valid ? root.connection.phaseCount.value : 0 - - Column { -////// modified to show power bar graphs - y: 6 - - width: parent.width - spacing: 0 - - // total power - TileText { - text: EnhFmt.formatVBusItem (root.connection.power) -////// modified to show power bar graphs - font.pixelSize: 19 - height: 21 - visible: phaseCount >= 1 - } - - // voltage for single leg - TileText { - text: EnhFmt.formatVBusItem (root.connection.voltageL1, "V") - visible: phaseCount === 1 - font.pixelSize: 15 - } - // current for single leg - TileText { - text: EnhFmt.formatVBusItem (root.connection.currentL1, "A") - font.pixelSize: 15 - visible: phaseCount === 1 - } - - // power, voltage and current for multiple legs - TileText { - text: "L1:" + EnhFmt.formatVBusItem (root.connection.powerL1, "W") - + " " + EnhFmt.formatVBusItem (root.connection.voltageL1, "V") - + " " + EnhFmt.formatVBusItem (root.connection.currentL1, "A") - visible: phaseCount >= 2 - font.pixelSize: 11 - } - // spacer to avoid connection dot - TileText { - text: "" - visible: phaseCount === 2 || phaseCount === 3 && root.height >= 90 - font.pixelSize: 8 - } - TileText { - text: - { - if (root.connection.l1AndL2OutShorted) - return "L2 included in L1" - else - { - return "L2:" + EnhFmt.formatVBusItem (root.connection.powerL2, "W") - + " " + EnhFmt.formatVBusItem (root.connection.voltageL2, "V") - + " " + EnhFmt.formatVBusItem (root.connection.currentL2, "A") - } - } - visible: phaseCount >= 2 - font.pixelSize: 11 - } - TileText { - text: "L3:" + EnhFmt.formatVBusItem (root.connection.powerL3, "W") - + " " + EnhFmt.formatVBusItem (root.connection.voltageL3, "V") - + " " + EnhFmt.formatVBusItem (root.connection.currentL3, "A") - visible: phaseCount >= 3 - font.pixelSize: 11 - } - // spacer - TileText { - text: "" - visible: phaseCount === 2 && root.height >= 90 - font.pixelSize: 11 - } - TileText { - text: EnhFmt.formatVBusItem (root.connection.frequency, "Hz") - font.pixelSize: phaseCount >= 2 ? 11 : 15 - visible: phaseCount === 1 || root.connection != sys.acInput - } - TileText { - text: qsTr("Limit: ") + EnhFmt.formatVBusItem (root.connection.inCurrentLimit) - font.pixelSize: 15 - visible: phaseCount === 1 && root.connection == sys.acInput - } - // frequency and input current limit for multiple legs - TileText { - text: EnhFmt.formatVBusItem (root.connection.frequency, "Hz") - + " " + EnhFmt.formatVBusItem (root.connection.inCurrentLimit) - font.pixelSize: 11 - visible: phaseCount >= 2 && root.connection == sys.acInput - } - } -} diff --git a/FileSets/v3.01/OverviewAcValuesEnhanced.qml.orig b/FileSets/v3.01/OverviewAcValuesEnhanced.qml.orig deleted file mode 100644 index 86f2f3a4..00000000 --- a/FileSets/v3.01/OverviewAcValuesEnhanced.qml.orig +++ /dev/null @@ -1,42 +0,0 @@ -import QtQuick 1.1 - -Item { - id: root - width: parent.width - - // NOTE: data is taken by qml, hence it is called connection - property variant connection - - Column { - y: 0 - - width: parent.width - spacing: 0 - - TileText { - text: root.connection ? root.connection.power.format(0) : "" - font.pixelSize: 25 - height: 27 - } - - TileText { - text: root.connection ? "L1: " + root.connection.powerL1.format(0) : "" - visible: root.connection !== undefined && root.connection.phaseCount.valid && root.connection.phaseCount.value > 1 && !root.connection.l1AndL2OutShorted - } - - TileText { - text: "L1 + L2" - visible: root.connection !== undefined && root.connection.phaseCount.valid && root.connection.phaseCount.value > 1 && root.connection.l1AndL2OutShorted - } - - TileText { - text: root.connection ? "L2: " + (!root.connection.splitPhaseL2PassthruDisabled ? root.connection.powerL2.format(0) : "--") : "" - visible: root.connection !== undefined && root.connection.phaseCount.valid && root.connection.phaseCount.value >= 2 && !root.connection.l1AndL2OutShorted - } - - TileText { - text: root.connection ? "L3: " + root.connection.powerL3.format(0) : "" - visible: root.connection !== undefined && root.connection.phaseCount.valid && root.connection.phaseCount.value >= 3 - } - } -} diff --git a/FileSets/v3.01/OverviewBox.qml b/FileSets/v3.01/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v3.01/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.01/OverviewConnection.qml b/FileSets/v3.01/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v3.01/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.01/OverviewConnectionEnd.qml b/FileSets/v3.01/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v3.01/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.01/OverviewFlowComplex.qml b/FileSets/v3.01/OverviewFlowComplex.qml deleted file mode 100644 index ce007a41..00000000 --- a/FileSets/v3.01/OverviewFlowComplex.qml +++ /dev/null @@ -1,1590 +0,0 @@ -///// Enhanced DC Coupled / AC Coupled Overview for GuiMods - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 -import "timeToGo.js" as TTG -import "enhancedFormat.js" as EnhFmt - -OverviewPage { - id: root - -////// GuiMods — DarkMode - property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } - property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 - - VBusItem { id: flowOverviewItem; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/FlowOverview") } - property bool dcCoupled: flowOverviewItem.valid && flowOverviewItem.value == 2 - - VBusItem { id: showInactiveTilesItem; bind: Utils.path(guiModsPrefix, "/ShowInactiveFlowTiles") } - property real disabledTileOpacity: (showInactiveTiles && showInactiveTilesItem.value === 1) ? 0.3 : 1 - property bool showInactiveTiles: showInactiveTilesItem.valid && showInactiveTilesItem.value >= 1 - property bool showInactiveFlow: showInactiveTilesItem.valid && showInactiveTilesItem.value == 3 - - property variant sys: theSystem - property string systemPrefix: "com.victronenergy.system" - property string settingsPrefix: "com.victronenergy.settings" - property color detailColor: "#b3b3b3" - property real laneWidth: (root.width - inOutTileWidth * 2 - battery.width) / 3 - - property int inOutTileHeight: (root.height - topOffset - bottomOffset - 3 * 5) / 4 - property int inOutTileWidth: 145 - VBusItem { id: timeToGo; bind: Utils.path(systemPrefix, "/Dc/Battery/TimeToGo") } - - VBusItem { id: vebusService; bind: Utils.path(systemPrefix, "/VebusService") } - property bool isMulti: vebusService.valid - property string veDirectInverterService: "" - property string inverterService: vebusService.valid ? vebusService.value : veDirectInverterService - - property bool combineAcLoads: dcCoupled || _combineAcLoads.valid && _combineAcLoads.value === 1 - property variant outputLoad: combineAcLoads ? sys.acLoad : sys.acOutLoad - - // for debug, ignore validity checks so all tiles and their flow lines will show - property bool showAllTiles: showInactiveTilesItem.valid && showInactiveTilesItem.value == 3 - - property bool hasInverter: false - property bool showInverter: hasInverter || inverterService != "" || showAllTiles - - property bool showLoadsOnOutput: showInverter || outputLoad.power.valid - property bool showAcInput: isMulti || sys.acInput.power.valid || showAllTiles - property bool hasLoadsOnInput: showAcInput && ! combineAcLoads && (! loadsOnInputItem.valid || loadsOnInputItem.value === 1) - property bool showLoadsOnInput: !dcCoupled && hasLoadsOnInput - property bool hasPvOnInput: sys.pvOnGrid.power.valid - property bool showPvOnInput: (!dcCoupled || !hasAcCharger) && hasPvOnInput - property bool hasPvOnOutput: sys.pvOnAcOut.power.valid - property bool showPvOnOutput: (!dcCoupled || !hasFuelCell) && hasPvOnOutput - property bool showPvCharger: sys.pvCharger.power.valid - property bool showDcSystem: (hasDcSystemItem.valid && hasDcSystemItem.value > 0) || showAllTiles - property bool showAlternator: (dcCoupled || !hasLoadsOnInput) && sys.alternator.power.valid - property bool hasFuelCell: sys.fuelCell.power.valid - property bool showFuelCell: (dcCoupled || !hasPvOnOutput) && hasFuelCell - property bool showWindGen: sys.windGenerator.power.valid - property bool hasAcCharger: sys.acCharger != undefined && sys.acCharger.power.valid - property bool showAcCharger: (dcCoupled || !hasPvOnInput) && hasAcCharger - - VBusItem { id: motorDrivePowerItem; bind: Utils.path(systemPrefix, "/Dc/MotorDrive/Power") } - property bool showMotorDrive: (dcCoupled || !hasLoadsOnInput) && ! showAlternator && motorDrivePowerItem.valid - - property int bottomOffset: showTanksTemps ? 45 : 5 - property int topOffset: showTanksTemps ? 1 : 5 - property string settingsBindPreffix: "com.victronenergy.settings" - property string pumpBindPreffix: "com.victronenergy.pump.startstop0" - property int numberOfTemps: 0 - - property int tankCount: showTanksEnable ? tankModel.rowCount : 0 - property int tempCount: showTempsEnable ? numberOfTemps : 0 - property int tankTempCount: tankCount + tempCount - property bool showTanks: showTanksEnable ? showStatusBar ? false : tankCount > 0 ? true : false : false - property bool showTemps: showTempsEnable ? showStatusBar ? false : tempCount > 0 ? true : false : false - property bool showTanksTemps: showTanks || showTemps - property int compactThreshold: 45 // height below this will be compacted vertically - property int batteryHeight: 91 - property bool compact: showTanks && showTemps && tankTempCount > 4 - property int tanksHeight: compact ? 22 : 45 - - VBusItem { id: ignoreAcInput1; bind: Utils.path(inverterService, "/Ac/State/IgnoreAcIn1") } - VBusItem { id: ignoreAcInput2; bind: Utils.path(inverterService, "/Ac/State/IgnoreAcIn2") } - VBusItem { id: acActiveInput; bind: Utils.path(inverterService, "/Ac/ActiveIn/ActiveInput") } - - property string guiModsPrefix: "com.victronenergy.settings/Settings/GuiMods" - VBusItem { id: showGaugesItem; bind: Utils.path(guiModsPrefix, "/ShowGauges") } - property bool showGauges: showGaugesItem.valid ? showGaugesItem.value === 1 ? true : false : false - VBusItem { id: showTanksItem; bind: Utils.path(guiModsPrefix, "/ShowEnhancedFlowOverviewTanks") } - property bool showTanksEnable: showTanksItem.valid ? showTanksItem.value === 1 ? true : false : false - VBusItem { id: showTempsItem; bind: Utils.path(guiModsPrefix, "/ShowEnhancedFlowOverviewTemps") } - property bool showTempsEnable: showTempsItem.valid ? showTempsItem.value === 1 ? true : false : false - - VBusItem { id: hasDcSystemItem; bind: "com.victronenergy.settings/Settings/SystemSetup/HasDcSystem" } - - VBusItem { id: timeFormatItem; bind: Utils.path(guiModsPrefix, "/TimeFormat") } - property string timeFormat: getTimeFormat () - - property double acInputFlow: showAcInput ? noNoise (sys.acInput.power) : 0 - property VBusItem vebusAcPower: VBusItem { bind: [sys.vebusPrefix, "/Ac/ActiveIn/P"] } - property double multiAcInputFlow: isMulti ? -noNoise (vebusAcPower) : 0 - property double pvOnInputFlow: showPvOnInput ? noNoise (sys.pvOnGrid.power) : 0 - property double loadsOnInputFlow: sys.acInLoad.power.valid ? -noNoise (sys.acInLoad.power) : 0 - property double pvInverterOnAcOutFlow: showPvOnOutput && sys.pvOnAcOut.power.valid ? noNoise (sys.pvOnAcOut.power) : 0 - property double acOutLoadFlow: sys.acOutLoad.power.valid ? -noNoise (sys.acOutLoad.power) : 0 - - property double pvChargerFlow: showPvCharger ? noNoise (sys.pvCharger.power) : 0 - property double dcSystemFlow: showDcSystem ? -noNoise (sys.dcSystem.power) : 0 - property double alternatorFlow: showAlternator ? noNoise (sys.alternator.power) : 0 - property double motorDriveFlow: showMotorDrive ? noNoise (motorDrivePowerItem) : 0 - property double inverterDcFlow: showInverter ? noNoise (sys.vebusDc.power) : 0 - property double batteryFlow: noNoise (sys.battery.power) - property double windGenFlow: noNoise (sys.windGenerator.power) - property double acChargerFlow: noNoise (sys.acCharger.power) - property double fuelCellFlow: noNoise (sys.fuelCell.power) - - VBusItem { id: showBatteryTempItem; bind: Utils.path(guiModsPrefix, "/ShowBatteryTempOnFlows") } - property bool showBatteryTemp: showBatteryTempItem.valid && showBatteryTempItem.value == 1 - - - function getTimeFormat () - { - if (!timeFormatItem.valid || timeFormatItem.value === 0) - return "" - else if (timeFormatItem.value === 2) - return "h:mm ap" - else - return "hh:mm" - } - - //Component.onCompleted: { discoverServices(); showHelp () } - onActiveChanged: - { - if (root.active) - { - discoverServices() - showHelp () - } - } - - title: dcCoupled ? qsTr("DC Coupled overview") : qsTr("AC Coupled overview") - - VBusItem { id: loadsOnInputItem; bind: "com.victronenergy.settings/Settings/GuiMods/ShowEnhancedFlowLoadsOnInput" } - VBusItem { id: _combineAcLoads; bind: "com.victronenergy.settings/Settings/GuiMods/EnhancedFlowCombineLoads" } - - OverviewBox { - id: acInBox - opacity: showAcInput ? 1 : disabledTileOpacity - visible: showAcInput || showInactiveTiles - width: inOutTileWidth - height: inOutTileHeight - title: - { - // input 1 is active - if (acActiveInput.value == 0) - { - if (ignoreAcInput1.valid && ignoreAcInput1.value == 1) - return qsTr ("AC In 1 Ignored") - else - return getAcSourceName(sys.acSource) - } - // input 2 is active - else if (acActiveInput.value == 1) - { - if (ignoreAcInput2.valid && ignoreAcInput2.value == 1) - return qsTr ("AC In 2 Ignored") - else - return getAcSourceName(sys.acSource) - } - else - return "no input" - } -////// GuiMods — DarkMode - titleColor: !darkMode ? "#E74c3c" : "#73261E" - color: !darkMode ? "#C0392B" : "#601C15" - anchors { - top: root.top; topMargin: topOffset - left: parent.left; leftMargin: 5 - } - values: TileText { - y: 13 - text: EnhFmt.formatVBusItem (sys.acInput.power) - font.pixelSize: 17 - visible: showAcInput - } - - MbIcon { - iconId: getAcSourceIcon(sys.acSource) - anchors { - bottom: parent.bottom - left: parent.left; leftMargin: 2 - } - opacity: 0.5 - } - PowerGauge - { - id: acInGauge - width: parent.width - height: 15 - anchors - { - top: parent.top; topMargin: 18 - horizontalCenter: parent.horizontalCenter - } - connection: sys.acInput - useInputCurrentLimit: true - maxForwardPowerParameter: "" - maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxFeedInPower" - visible: showGauges && showAcInput - } - DetailTarget { id: acInputTarget; detailsPage: "DetailAcInput.qml" } - } - - OverviewBox - { - id: pvInverterOnInput -////// GuiMods — DarkMode - titleColor: !darkMode ? "#F4B350" : "#7A5928" - color: !darkMode ? "#F39C12" : "#794E09" - title: qsTr("PV on Input") - width: inOutTileWidth - height: inOutTileHeight - visible: showPvOnInput || (showInactiveTiles && !dcCoupled) - opacity: showPvOnInput ? 1 : disabledTileOpacity - MbIcon - { - source: - { - var ids = sys.pvInvertersProductIds.text - if (ids.indexOf(0xA142) > -1) - return "image://theme/overview-fronius-logo" - return "" - } - visible: showPvOnInput - opacity: 0.3 - anchors { - bottom: parent.bottom - left: parent.left - margins: 2 - } - } - values: TileText { - y: 11 - text: EnhFmt.formatVBusItem (sys.pvOnGrid.power) - font.pixelSize: 17 - visible: showPvOnInput - } - anchors { - top: acInBox.bottom - topMargin: 5 - left: acInBox.left - } - PowerGauge - { - id: pvInverterOnInputGauge - width: parent.width - height: 15 - anchors - { - top: parent.top; topMargin: 18 - horizontalCenter: parent.horizontalCenter - } - connection: sys.pvOnGrid - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvOnGridMaxPower" - visible: showGauges && showPvOnInput - } - DetailTarget { id: pvOnInputTarget; detailsPage: "DetailPvInverter.qml" } - } - - OverviewBox { - id: acLoadOnInputBox - title: qsTr("AC In Loads") -////// GuiMods — DarkMode - color: !darkMode ? "#27AE60" : "#135730" - titleColor: !darkMode ? "#2ECC71" : "#176638" - width: inOutTileWidth - height: inOutTileHeight - opacity: showLoadsOnInput ? 1 : disabledTileOpacity - visible: showLoadsOnInput || (showInactiveTiles && !dcCoupled) - anchors { - top: pvInverterOnInput.bottom - topMargin: 5 - left: acInBox.left - } - values: TileText { - y: 13 - text: EnhFmt.formatVBusItem (sys.acInLoad.power) - font.pixelSize: 17 - visible: showLoadsOnInput - } - PowerGauge - { - id: acInLoadGauge - width: parent.width - height: 15 - anchors - { - top: parent.top; topMargin: 18 - horizontalCenter: parent.horizontalCenter - } - connection: sys.acInLoad - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputNonCriticalMaxPower" - visible: showGauges && showLoadsOnInput - } - DetailTarget { id: acLoadsOnInputTarget; detailsPage: "DetailLoadsOnInput.qml" } - } - - // check inverter to see if AC out 2 exists and hide noncritical loads if so - VBusItem { id: inverterOut2Item; bind: Utils.path(root.inverterService, "/Ac/Out/L2/V") } - - OverviewBox { - id: acOutputBox - title: combineAcLoads ? qsTr ("AC Loads") : qsTr ("AC Out Loads") -////// GuiMods — DarkMode - color: !darkMode ? "#27AE60" : "#135730" - titleColor: !darkMode ? "#2ECC71" : "#176638" - height: inOutTileHeight - width: inOutTileWidth - opacity: showLoadsOnOutput ? 1 : disabledTileOpacity - visible: showLoadsOnOutput || showInactiveTiles - anchors { - right: root.right; rightMargin: 5 - top: root.top; topMargin: topOffset - } - - values: TileText { - y: 13 - text: EnhFmt.formatVBusItem (outputLoad.power) - font.pixelSize: 17 - visible: showLoadsOnOutput - } - PowerGauge - { - id: acOutLoadGauge - width: parent.width - height: 15 - anchors - { - top: parent.top; topMargin: 18 - horizontalCenter: parent.horizontalCenter - } - connection: outputLoad - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputMaxPower" - visible: showGauges && showLoadsOnOutput - } - DetailTarget { id: acLoadsOnOutputTarget; detailsPage: "DetailLoadsOnOutput.qml" } - } - Timer { - id: wallClock - running: timeFormat != "" - repeat: true - - interval: 1000 - triggeredOnStart: true - onTriggered: time = Qt.formatDateTime(new Date(), timeFormat) - - property string time - } - - MultiEnhancedGP { - id: multi - iconId: "overview-inverter-short" - opacity: showInverter ? 1 : disabledTileOpacity - visible: showInverter || showInactiveTiles - anchors { - horizontalCenter: parent.horizontalCenter - top: acInBox.top - } - inverterService: root.inverterService - PowerGaugeMulti - { - id: multiGauge - width: multi.width - height: 13 - anchors - { - top: parent.top; topMargin: 21 - horizontalCenter: multi.horizontalCenter - } - inverterService: root.inverterService - visible: showGauges && showInverter - } - DetailTarget { id: multiTarget; detailsPage: "DetailInverter.qml"; width: 60; height: 60 } - } - TileText - { - text: wallClock.time - color: showInverter || darkMode ? "white" : "black" - width: inOutTileWidth - wrapMode: Text.WordWrap - font.pixelSize: 16 - anchors - { - bottom: multi.bottom; bottomMargin: 1 - horizontalCenter: multi.horizontalCenter; - horizontalCenterOffset: multiDcConnector.active ? -10 : 0 - } - visible: wallClock.running - } - - Battery { - id: battery - - soc: sys.battery.soc.valid ? sys.battery.soc.value : 0 - height: 99 - width: 145 - - anchors { - bottom: parent.bottom; bottomMargin: bottomOffset; - right: acOutputBox.left; rightMargin: laneWidth - } - PowerGaugeBattery - { - id: batteryGauge - width: parent.width - height: 10 - anchors - { - top: parent.top; topMargin: 30 - horizontalCenter: parent.horizontalCenter - } - visible: showGauges - } - values: Column { - y: 0 - width: parent.width - - TileText { - text: sys.battery.soc.valid ? sys.battery.soc.value.toFixed(0) : "--" - font.pixelSize: 20 - - Text { - anchors { - bottom: parent.bottom; bottomMargin: 4 - horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: parent.paintedWidth / 2 + 5 - } - visible: sys.battery.soc.valid - text: "%" - color: "white" - font.bold: true - font.pixelSize: 12 - } - } - // spacer - TileText - { - text: "" - height: 9 - } - TileText - { - font.pixelSize: 17 - text: timeToGo.valid ? TTG.formatTimeToGo (timeToGo) : " " - height: 19 - anchors - { - horizontalCenter: parent.horizontalCenter - horizontalCenterOffset: -(toGoText.paintedWidth / 2) - 3 - } - Text - { - id: toGoText - anchors - { - bottom: parent.bottom; bottomMargin: 0 - horizontalCenter: parent.horizontalCenter - horizontalCenterOffset: (parent.paintedWidth / 2) + (paintedWidth / 2) + 2 - } - visible: timeToGo.valid - text: qsTr ("Remaining") - color: "white" - font.pixelSize: 12 - } - } - TileText { - text: EnhFmt.formatVBusItem (sys.battery.voltage, "V ", 2) - + EnhFmt.formatVBusItem (sys.battery.current, "A") - } - TileText { - text: EnhFmt.formatVBusItem (sys.battery.power) - font.pixelSize: 17 - height: 19 - } - } - DetailTarget { id: batteryTarget; detailsPage: "DetailBattery.qml" } - } - - OverviewBox - { - id: pvInverterOnAcOut -////// GuiMods — DarkMode - titleColor: !darkMode ? "#F4B350" : "#7A5928" - color: !darkMode ? "#F39C12" : "#794E09" - title: qsTr("PV on Output") - width: inOutTileWidth - height: inOutTileHeight - opacity: showPvOnOutput ? 1 : disabledTileOpacity - visible: showPvOnOutput || (showInactiveTiles && !dcCoupled) - MbIcon - { - source: - { - var ids = sys.pvInvertersProductIds.text - if (ids.indexOf(0xA142) > -1) - return "image://theme/overview-fronius-logo" - return "" - } - visible: showPvOnOutput - opacity: 0.3 - anchors { - bottom: parent.bottom - right: parent.right - margins: 2 - } - } - - values: TileText { - y: 11 - text: EnhFmt.formatVBusItem (sys.pvOnAcOut.power) - font.pixelSize: 17 - visible: showPvOnOutput - } - anchors { - top: acOutputBox.bottom - topMargin: 5 - right: acOutputBox.right - } - PowerGauge - { - id: pvInverterOnAcOutGauge - width: parent.width - height: 15 - anchors - { - top: parent.top; topMargin: 18 - horizontalCenter: parent.horizontalCenter - } - connection: sys.pvOnAcOut - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvOnOutputMaxPower" - visible: showGauges && showPvOnOutput - } - DetailTarget { id: pvOnOutputTarget; detailsPage: "DetailPvInverter.qml" } - } - - OverviewBox - { - id: acChargerBox - title: qsTr ("AC Charger") -////// GuiMods — DarkMode - color: !darkMode ? "#157894" : "#0a3c4a" - titleColor: !darkMode ? "#419FB9" : "#204f5c" - height: inOutTileHeight - width: inOutTileWidth - opacity: showAcCharger ? 1 : disabledTileOpacity - visible: showAcCharger || (showInactiveTiles && dcCoupled) - anchors - { - left: root.left; leftMargin: 5 - bottom: alternatorBox.top; bottomMargin: 5 - } - values: TileText { - text: EnhFmt.formatVBusItem (sys.acCharger.power) - font.pixelSize: 17 - visible: showAcCharger - anchors - { - bottom: parent.bottom; bottomMargin: 0 - horizontalCenter: parent.horizontalCenter - } - } - PowerGauge - { - id: acChargerGauge - width: parent.width - height: 10 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.acCharger - reversePower: true - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxAcChargerPower" - visible: showGauges && showAcCharger - } - DetailTarget { id: acChargerTarget; detailsPage: "DetailAcCharger.qml" } - } - - OverviewBox - { - id: alternatorBox - title: qsTr ("Alternator") -////// GuiMods — DarkMode - color: !darkMode ? "#157894" : "#0a3c4a" - titleColor: !darkMode ? "#419FB9" : "#204f5c" - height: inOutTileHeight - width: inOutTileWidth - opacity: showAlternator ? 1 : disabledTileOpacity - visible: showAlternator || (showInactiveTiles && dcCoupled) - anchors - { - left: root.left; leftMargin: 5 - bottom: pvChargerBox.top; bottomMargin: 5 - } - values: TileText { - text: EnhFmt.formatVBusItem (sys.alternator.power) - font.pixelSize: 17 - visible: showAlternator - anchors - { - bottom: parent.bottom; bottomMargin: 0 - horizontalCenter: parent.horizontalCenter - } - } - PowerGauge - { - id: alternatorGauge - width: parent.width - height: 10 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.alternator - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxAlternatorPower" - visible: showGauges && showAlternator - } - DetailTarget { id: alternatorTarget; detailsPage: "DetailAlternator.qml" } - } - - OverviewBox - { - id: motorDriveBox - title: qsTr ("Motor Drive") -////// GuiMods — DarkMode - color: !darkMode ? "#157894" : "#0a3c4a" - titleColor: !darkMode ? "#419FB9" : "#204f5c" - height: inOutTileHeight - width: inOutTileWidth - opacity: showMotorDrive ? 1 : disabledTileOpacity - visible: showMotorDrive - anchors - { - left: root.left; leftMargin: 5 - bottom: pvChargerBox.top; bottomMargin: 5 - } - values: TileText { - text: EnhFmt.formatVBusItem (motorDrivePowerItem) - font.pixelSize: 17 - visible: showMotorDrive - anchors - { - bottom: parent.bottom; bottomMargin: 0 - horizontalCenter: parent.horizontalCenter - } - } - PowerGauge - { - id: motorDriveGauge - width: parent.width - height: 10 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: motorDrivePowerItem - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxMotorDriveLoad" - maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxMotorDriveCharge" - visible: showGauges && showMotorDrive - showLabels: true - } - DetailTarget { id: motorDriveTarget; detailsPage: "DetailMotorDrive.qml" } - } - - VBusItem { id: dcSystemNameItem; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/CustomDcSystemName") } - - OverviewBox { - id: dcSystemBox - width: inOutTileWidth - height: inOutTileHeight - opacity: showDcSystem ? 1 : disabledTileOpacity - visible: showDcSystem || showInactiveTiles - title: dcSystemNameItem.valid && dcSystemNameItem.value != "" ? dcSystemNameItem.value : qsTr ("DC System") - anchors - { - right: root.right; rightMargin: 5 - bottom: parent.bottom - bottomMargin: bottomOffset - } - values: TileText { - text: EnhFmt.formatVBusItem (sys.dcSystem.power) - font.pixelSize: 17 - visible: showDcSystem - anchors - { - bottom: parent.bottom; bottomMargin: 0 - horizontalCenter: parent.horizontalCenter - } - } - PowerGauge - { - id: dcSystemGauge - width: parent.width - height: 10 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.dcSystem - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/DcSystemMaxLoad" - maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/DcSystemMaxCharge" - showLabels: true - visible: showGauges && showDcSystem - } - DetailTarget { id: dcSystemTarget; detailsPage: "DetailDcSystem.qml" } - } - - OverviewBox { - id: fuelCellBox -////// GuiMods — DarkMode - color: !darkMode ? "#157894" : "#0a3c4a" - titleColor: !darkMode ? "#419FB9" : "#204f5c" - width: inOutTileWidth - height: inOutTileHeight - opacity: showFuelCell ? 1 : disabledTileOpacity - visible: showFuelCell || (showInactiveTiles && dcCoupled) - title: qsTr ("Fuel Cell") - anchors { - left: windGenBox.left - bottom: windGenBox.top; bottomMargin: 5 - } - values: TileText { - text: EnhFmt.formatVBusItem (sys.fuelCell.power) - font.pixelSize: 17 - visible: fuelCellBox.visible - anchors - { - bottom: parent.bottom; bottomMargin: 0 - horizontalCenter: parent.horizontalCenter - } - } - PowerGauge - { - id: fuelCellGauge - width: parent.width - height: 10 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.fuelCell - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxFuelCellPower" - visible: showGauges && fuelCellBox.visible - } - DetailTarget { id: fuelCellTarget; detailsPage: "DetailFuelCell.qml" } - } - - OverviewBox { - id: windGenBox -////// GuiMods — DarkMode - color: !darkMode ? "#157894" : "#0a3c4a" - titleColor: !darkMode ? "#419FB9" : "#204f5c" - width: inOutTileWidth - height: inOutTileHeight - opacity: showWindGen ? 1 : disabledTileOpacity - visible: showWindGen || showInactiveTiles - title: qsTr ("Wind Generator") - anchors - { - right: dcSystemBox.right - bottom: dcSystemBox.top; bottomMargin: 5 - } - values: TileText { - text: EnhFmt.formatVBusItem (sys.windGenerator.power) - font.pixelSize: 17 - visible: showWindGen - anchors - { - bottom: parent.bottom; bottomMargin: 0 - horizontalCenter: parent.horizontalCenter - } - } - PowerGauge - { - id: windGenGauge - width: parent.width - height: 10 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.windGenerator - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxWindGenPower" - visible: showGauges && showWindGen - } - DetailTarget { id: windGenTarget; detailsPage: "DetailWindGen.qml" } - } - - OverviewBox { - id: pvChargerBox - title: qsTr("PV Charger") -////// GuiMods — DarkMode - titleColor: !darkMode ? "#F4B350" : "#7A5928" - color: !darkMode ? "#F39C12" : "#794E09" - width: inOutTileWidth - height: inOutTileHeight - opacity: showPvCharger ? 1 : disabledTileOpacity - visible: showPvCharger || showInactiveTiles - anchors - { - left: root.left; leftMargin: 5 - bottom: parent.bottom; bottomMargin: bottomOffset - } - values: TileText { - y: 12 - text: EnhFmt.formatVBusItem (sys.pvCharger.power) - font.pixelSize: 17 - } - // moved sun icon here from OverviewSolarChager so it can be put below text, etc - MbIcon { - iconId: "overview-sun" - anchors { - bottom: parent.bottom - right: parent.right; rightMargin: 2 - } - opacity: 0.5 - } - - PowerGauge - { - id: pvChargerGauge - width: parent.width - height: 10 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.pvCharger - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvChargerMaxPower" - visible: showGauges && showPvCharger - } - DetailTarget { id: pvChargerTarget; detailsPage: "DetailPvCharger.qml" } - } - - // move ESS reason to Battery details page - - // invisible item to connection all AC input connections to.. - Item { - id: acInBus - width: laneWidth - anchors { - left: acInBox.right; - top: multi.top; topMargin: multi.height / 2 + 10 - bottom: pvInverterOnInput.bottom; bottomMargin: 8 - } - } - Item { - id: dcLaneLeft - width: laneWidth - anchors { - right: battery.left; - top: multi.top; topMargin: multi.height / 2 + 10 - bottom: dcSystemBox.bottom; bottomMargin: 8 - } - } - Item { - id: dcLaneRight - width: laneWidth * 0.8 - anchors { - left: battery.right; - - top: dcLaneLeft.top - bottom: dcLaneLeft.bottom - } - } - Item { - id: dcLaneTop - anchors { - left: battery.left - right: battery.right - top: multi.bottom; - bottom: battery.top - } - } - - OverviewConnection { - id: multiAcInFlow - ballCount: 1 - path: straight - active: root.active && ( showAcInput || showPvOnInput || showLoadsOnInput ) - value: -Utils.sign (multiAcInputFlow) - startPointVisible: false - endPointVisible: true - - anchors { - left: acInBus.horizontalCenter; leftMargin: -0.5 - right: multi.left; rightMargin: -8 - bottom: acInBus.top - } - } - - // AC source power flow - OverviewConnection { - id: acSource - ballCount: 1 - path: corner - active: root.active && showAcInput - value: Utils.sign (acInputFlow) - startPointVisible: true - endPointVisible: false - - anchors { - left: acInBox.right; leftMargin: -8 - right: acInBus.horizontalCenter - top: acInBox.bottom; topMargin: -8 - bottom: acInBus.top - } - } - - // Coupled AC sources - OverviewConnection { - id: coupledAcConnection - ballCount: 1 - path: straight - active: root.active && ((showLoadsOnInput && showPvOnInput) || (!dcCoupled && showInactiveFlow)) - value: -Utils.sign (pvOnInputFlow + loadsOnInputFlow) - startPointVisible: false - endPointVisible: false - - anchors { - right: acInBus.horizontalCenter - rightMargin: 0.5 // makes this line up with others - top: acInBus.top - bottom: acInBus.bottom - } - } - - // Grid inverter power flow - OverviewConnection { - id: pvInverterOnInputConnection - ballCount: showLoadsOnInput ? 1 : 2 - path: showLoadsOnInput || (!dcCoupled && showInactiveFlow) ? straight : corner - active: root.active && (showPvOnInput || (!dcCoupled && showInactiveFlow)) - value: Utils.sign (pvOnInputFlow) - startPointVisible: true - endPointVisible: false - - anchors { - left: pvInverterOnInput.right; leftMargin: -8 - right: acInBus.horizontalCenter - top: pvInverterOnInput.bottom; topMargin: -8 - bottom: showLoadsOnInput || (!dcCoupled && showInactiveFlow) ? pvInverterOnInput.bottom : multiAcInFlow.verticalCenter - bottomMargin: showLoadsOnInput || (!dcCoupled && showInactiveFlow) ? 8 : 0 - } - } - - // power to loads on input - OverviewConnection { - id: loadsOnInput - ballCount: 1 - path: corner - active: root.active && (showLoadsOnInput || (!dcCoupled && showInactiveFlow)) - value: Utils.sign (loadsOnInputFlow) - startPointVisible: true - endPointVisible: false - - anchors { - left: acLoadOnInputBox.right; leftMargin: -8 - right: acInBus.horizontalCenter - rightMargin: 0.5 // makes this line up with others - top: acLoadOnInputBox.top; topMargin: 8 - bottom: showPvOnInput|| (!dcCoupled && showInactiveFlow) ? acInBus.bottom : acInBus.top - } - } - - // invisible item to connection all AC output connections to.. - Item { - id: acOutNode - height: 6 - anchors { - left: multi.right - right: acOutputBox.left - verticalCenter: acInBus.top - } - } - - // AC out connection - OverviewConnection { - id: multiAcOutConnection - - ballCount: 1 - path: straight - active: root.active && ((showLoadsOnOutput || showPvOnOutput) || (!dcCoupled && showInactiveFlow)) - value: -Utils.sign (acOutLoadFlow + pvInverterOnAcOutFlow) - endPointVisible: false - - anchors { - left: multi.right; leftMargin: -8 - right: acOutNode.horizontalCenter - top: acOutNode.verticalCenter - } - } - - // loads on output conenction - OverviewConnection { - id: acOutBoxConnection - - ballCount: 1 - path: corner - active: root.active && (showLoadsOnOutput || (!dcCoupled && showInactiveFlow)) - value: Utils.sign (acOutLoadFlow) - startPointVisible: true - endPointVisible: false - - anchors { - right: acOutNode.horizontalCenter - rightMargin: -0.5 // makes this line up with others - left: acOutputBox.left; leftMargin: 8 - top: acOutputBox.bottom; topMargin: -8 - bottom: acOutNode.verticalCenter - } - } - - // PV Inverter on AC out connection - OverviewConnection { - id: pvOnAcOutConnection - - ballCount: 2 - path: corner - active: root.active && (showPvOnOutput || (!dcCoupled && showInactiveFlow)) - value: Utils.sign (pvInverterOnAcOutFlow) - startPointVisible: true - endPointVisible: false - - anchors { - left: pvInverterOnAcOut.left; leftMargin: 8 - top: pvInverterOnAcOut.bottom; topMargin: -8 - right: acOutNode.horizontalCenter - bottom: acOutNode.verticalCenter - } - } - - // invisible summing point for all DC connections - Item { - id: dcNode - height: 10 - width: 10 - anchors { - horizontalCenter: batteryDcConnector.horizontalCenter - verticalCenter: dcLaneTop.verticalCenter - } - } - - // DC bus segments - OverviewConnection { - id: dcBus1 - ballCount: 1 - path: straight - active: root.active && ((showAlternator || showMotorDrive || showPvCharger) || (dcCoupled && showInactiveFlow)) - value: -Utils.sign (alternatorFlow + motorDriveFlow + pvChargerFlow) - startPointVisible: false - endPointVisible: false - - anchors { - right: dcLaneLeft.horizontalCenter - rightMargin: 0.5 // makes this line up with others - bottom: alternatorConnection.verticalCenter - top: dcLaneTop.verticalCenter - } - } - OverviewConnection { - id: dcBus2 - ballCount: 1 - path: straight - active: root.active && ((showAlternator || showMotorDrive || showAcCharger || showPvCharger) || (dcCoupled && showInactiveFlow)) - value: Utils.sign (alternatorFlow + motorDriveFlow + pvChargerFlow + acChargerFlow) - startPointVisible: false - endPointVisible: false - - anchors { - left: dcLaneLeft.horizontalCenter - right: dcBus3.left - bottom: dcLaneTop.verticalCenter - } - } - OverviewConnection { - id: dcBus3 - ballCount: 2 - path: straight - active: root.active && ((showInverter || showFuelCell || showWindGen || showDcSystem) || showInactiveFlow) - value: -Utils.sign (inverterDcFlow + fuelCellFlow + windGenFlow + dcSystemFlow) - startPointVisible: false - endPointVisible: false - - anchors { - left: batteryDcConnector.horizontalCenter - right: multiDcConnector.horizontalCenter - bottom: dcLaneTop.verticalCenter - } - } - OverviewConnection { - id: dcBus4 - ballCount: 1 - path: straight - active: root.active && ((showFuelCell || showWindGen || showDcSystem) || showInactiveFlow) - value: -Utils.sign (fuelCellFlow + windGenFlow + dcSystemFlow) - startPointVisible: false - endPointVisible: false - - anchors { - left: multiDcConnector.horizontalCenter - right: dcLaneRight.horizontalCenter - bottom: dcLaneTop.verticalCenter - } - } - OverviewConnection { - id: dcBus5 - ballCount: 1 - path: straight - active: root.active && ((showWindGen || showDcSystem) || showInactiveFlow) - value: -Utils.sign (windGenFlow + dcSystemFlow) - startPointVisible: false - endPointVisible: false - - anchors { - left: dcLaneRight.horizontalCenter - top: dcLaneTop.verticalCenter - bottom: windGenConnection.verticalCenter - } - } - - - // DC connection multi to bus - OverviewConnection { - id: multiDcConnector - ballCount: 1 - path: straight - active: root.active && (showInverter || showInactiveFlow) - value: Utils.sign (inverterDcFlow) - startPointVisible: true - endPointVisible: false - - anchors { - right: multi.right; rightMargin: 25 - top: multi.bottom; topMargin: -8 - bottom: dcLaneTop.verticalCenter - } - } - // DC connection battery to bus - OverviewConnection { - id: batteryDcConnector - ballCount: 1 - path: straight - active: root.active && ((sys.battery.soc.valid || showDcSystem) || (dcCoupled && showInactiveFlow)) - value: -Utils.sign (batteryFlow) - startPointVisible: true - endPointVisible: false - - anchors { - left: battery.left; leftMargin: 35 - top: battery.top; topMargin: 15 - bottom: dcLaneTop.verticalCenter - } - } - - // AC charger to DC bus - OverviewConnection - { - id: acChargerConnection - ballCount: 1 - path: corner - active: root.active && (showAcCharger || (dcCoupled && showInactiveFlow)) - value: Utils.sign (acChargerFlow) - startPointVisible: true - endPointVisible: false - anchors - { - left: acChargerBox.right; leftMargin: -8 - top: acChargerBox.bottom; topMargin: -8 - right: dcLaneLeft.horizontalCenter - bottom: dcLaneTop.verticalCenter - } - } - - // Alternator to bus - OverviewConnection - { - id: alternatorConnection - ballCount: 1 - path: straight - active: root.active && (showAlternator || showMotorDrive || (dcCoupled && showInactiveFlow)) - value: Utils.sign (alternatorFlow + motorDriveFlow) - startPointVisible: true - endPointVisible: false - anchors - { - left: alternatorBox.right; leftMargin: -8 - top: alternatorBox.bottom; topMargin: -8 - right: dcLaneLeft.horizontalCenter - } - } - - // DC system to DC bus - OverviewConnection - { - id: dcSystemConnection - ballCount: 2 - path: corner - active: root.active && (showDcSystem || (dcCoupled && showInactiveFlow)) - value: Utils.sign (dcSystemFlow) - endPointVisible: false - anchors - { - left: dcSystemBox.left; leftMargin: 8 - top: dcSystemBox.bottom; topMargin: -8 - right: dcLaneRight.horizontalCenter - rightMargin: -0.5 // makes this line up with others - bottom: windGenConnection.verticalCenter - } - } - - - // other DC connection to DC right bus - OverviewConnection - { - id: fuelCellConnection - ballCount: 2 - path: corner - active: root.active && (showFuelCell || (dcCoupled && showInactiveFlow)) - value: Utils.sign (fuelCellFlow) - startPointVisible: true - endPointVisible: false - anchors - { - left: fuelCellBox.left; leftMargin: 8 - top: fuelCellBox.bottom; topMargin: -8 - right: dcLaneRight.horizontalCenter - rightMargin: -0.5 // makes this line up with others - bottom: dcLaneTop.verticalCenter - } - } - - // Wind Gen DC right bus - OverviewConnection - { - id: windGenConnection - ballCount: 1 - path: straight - active: root.active && (showWindGen || showInactiveFlow) - value: Utils.sign (windGenFlow) - startPointVisible: true - endPointVisible: false - anchors - { - left: windGenBox.left; leftMargin: 8 - top: windGenBox.bottom; topMargin: -8 - right: dcLaneRight.horizontalCenter - } - } - - // Solar charger to DC right bus - OverviewConnection - { - id: pvChargerConnection - ballCount: 2 - path: corner - active: root.active && (showPvCharger || showInactiveFlow) - value: Utils.sign (pvChargerFlow) - startPointVisible: true - endPointVisible: false - anchors - { - left: pvChargerBox.right; leftMargin: -8 - top: pvChargerBox.bottom; topMargin: -8 - right: dcLaneLeft.horizontalCenter - bottom: alternatorConnection.top - } - } - - // Synchronise tank name text scroll start - Timer - { - id: scrollTimer - interval: 15000 - repeat: true - running: root.active - } - - ListView - { - id: tanksColum - - visible: showTanks - width: compact ? root.width : root.width * tankCount / tankTempCount - property int tileWidth: width / Math.min (count, 5.2) - height: root.tanksHeight - anchors - { - bottom: root.bottom - left: root.left - } - - // flickable list if more than will fit across bottom of screen - interactive: count > 4 ? true : false - orientation: ListView.Horizontal - - model: TankModel { id: tankModel } - delegate: TileTankEnhanced { - // Without an intermediate assignment this will trigger a binding loop warning. - property variant theService: DBusServices.get(buddy.id) - service: theService - width: tanksColum.tileWidth - height: root.tanksHeight - pumpBindPrefix: root.pumpBindPreffix - compact: root.compact - Connections { - target: scrollTimer - onTriggered: doScroll() - } - } - Tile { - title: qsTr("tanks") - anchors.fill: parent - values: TileText { - text: qsTr("") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - - ListView - { - id: tempsColumn - - visible: showTemps - width: compact ? root.width : root.width * tempCount / tankTempCount - property int tileWidth: width / Math.min (count, 5.2) - height: root.tanksHeight - anchors - { - bottom: root.bottom - bottomMargin: compact ? root.tanksHeight : 0 - right: root.right - } - - // make list flickable if more tiles than will fit completely - interactive: count > 4 ? true : false - orientation: ListView.Horizontal - - model: tempsModel - delegate: TileTemp - { - width: tempsColumn.tileWidth - height: tempsColumn.height - compact: root.compact - Connections - { - target: scrollTimer - onTriggered: doScroll() - } - } - Tile - { - title: qsTr("TEMPS") - anchors.fill: parent - values: TileText - { - text: qsTr("") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - ListModel { id: tempsModel } - - // When new service is found check if is a tank sensor - Connections - { - target: DBusServices - onDbusServiceFound: addService(service) - } - - // hack to get value(s) from within a loop inside a function when service is changing - property string tempServiceName: "" - property VBusItem temperatureItem: VBusItem { bind: Utils.path(tempServiceName, "/Dc/0/Temperature") } - - function addService(service) - { - switch (service.type) - { - case DBusService.DBUS_SERVICE_TEMPERATURE_SENSOR: - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - break;; - - case DBusService.DBUS_SERVICE_MULTI: - hasInverter = true - root.tempServiceName = service.name - if (temperatureItem.valid && showBatteryTemp) - { - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - } - break;; - case DBusService.DBUS_SERVICE_MULTI_RS: - hasInverter = true - break;; - - case DBusService.DBUS_SERVICE_INVERTER: - hasInverter = true - if (veDirectInverterService == "") - veDirectInverterService = service.name; - break;; - case DBusService.DBUS_SERVICE_BATTERY: - root.tempServiceName = service.name - if (temperatureItem.valid && showBatteryTemp) - { - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - } - break;; - } - } - - // Detect available services of interest - function discoverServices() - { - numberOfTemps = 0 - tempsModel.clear() - veDirectInverterService = "" - hasInverter = false - for (var i = 0; i < DBusServices.count; i++) - { - addService(DBusServices.at(i)) - } - } - VBusItem { id: incomingTankName; - bind: Utils.path(settingsBindPreffix, "/Settings/Devices/TankRepeater/IncomingTankService") } - - // help message shown when menu is first drawn - Rectangle - { - id: helpBox - color: "white" - width: multi.width - height: 32 - opacity: 0.7 - anchors - { - verticalCenter: dcLaneTop.verticalCenter - horizontalCenter: root.horizontalCenter - } - visible: false - } - TileText - { - text: qsTr ( "Tap tile center for detail at any time" ) - color: "black" - anchors.fill: helpBox - wrapMode: Text.WordWrap - font.pixelSize: 12 - visible: helpBox.visible - } - - //// hard key handler - // used to press buttons when touch isn't available - // UP and DOWN buttons cycle through the list of touch areas - // "space" button is used to simulate a touch on the area - // target must be highlighted so that other uses of "space" - // will still occur - - // list of all details touchable areas - property variant targetList: - [ - acInputTarget, pvOnInputTarget, acLoadsOnInputTarget, - acChargerTarget, alternatorTarget, motorDriveTarget, pvChargerTarget, - multiTarget, batteryTarget, - acLoadsOnOutputTarget, pvOnOutputTarget, fuelCellTarget, windGenTarget, dcSystemTarget - ] - - property int selectedTarget: 0 - - Timer - { - id: targetTimer - interval: 5000 - repeat: false - running: false - onTriggered: { hideAllTargets () } - } - - Keys.forwardTo: [keyHandler] - Item - { - id: keyHandler - Keys.onUpPressed: - { - nextTarget (-1) - event.accepted = true - } - - Keys.onDownPressed: - { - nextTarget (+1) - event.accepted = true - } - Keys.onSpacePressed: - { - if (targetTimer.running) - { - var foo // hack to make clicked() work - bar.clicked (foo) - event.accepted = true - } - else - event.accepted = false - } - } - // hack to make clicked() work - property variant bar: targetList[selectedTarget] - - function nextTarget (increment) - { - // make one pass through all possible targets to find an enabled one - // if found, that's the new selectedTarget, - // if not selectedTarget does not change - var newIndex = selectedTarget - for (var i = 0; i < targetList.length; i++) - { - if (( ! targetTimer.running || helpBox.visible) && targetList[newIndex].enabled) - { - highlightSelectedTarget () - return - } - newIndex += increment - if (newIndex >= targetList.length) - newIndex = 0 - else if (newIndex < 0) - newIndex = targetList.length - 1 - if (targetList[newIndex].enabled) - { - selectedTarget = newIndex - highlightSelectedTarget () - break - } - } - } - - function showHelp () - { - for (var i = 0; i < targetList.length; i++) - { - targetList[i].targetVisible = true - } - helpBox.visible = true - targetTimer.restart () - } - function hideAllTargets () - { - for (var i = 0; i < targetList.length; i++) - { - targetList[i].targetVisible = false - } - helpBox.visible = false - } - function highlightSelectedTarget () - { - for (var i = 0; i < targetList.length; i++) - { - if (targetList[i] == targetList[selectedTarget]) - targetList[i].targetVisible = true - else - targetList[i].targetVisible = false - } - helpBox.visible = false - targetTimer.restart () - } -} diff --git a/FileSets/v3.01/OverviewFlowComplex.qml.orig b/FileSets/v3.01/OverviewFlowComplex.qml.orig deleted file mode 100644 index 44688485..00000000 --- a/FileSets/v3.01/OverviewFlowComplex.qml.orig +++ /dev/null @@ -1,481 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -OverviewPage { - id: root - - property variant sys: theSystem - property bool hasAcOutSystem: _hasAcOutSystem.value === 1 - - title: qsTr("Overview") - - VBusItem { - id: _hasAcOutSystem - bind: "com.victronenergy.settings/Settings/SystemSetup/HasAcOutSystem" - } - - OverviewBox { - id: acInBox - - width: 148 - height: 100 - title: getAcSourceName(sys.acSource) - titleColor: "#E74c3c" - color: "#C0392B" - anchors { - top: root.top; topMargin: 1 - left: parent.left; leftMargin: 5 - } - - values: OverviewAcValues { - connection: sys.acInput - } - - MbIcon { - iconId: getAcSourceIcon(sys.acSource) - anchors { - bottom: parent.bottom - left: parent.left; leftMargin: 2 - } - opacity: 0.5 - } - } - - OverviewBox { - id: acLoadBox - title: qsTr("AC Loads") - color: "#27AE60" - titleColor: "#2ECC71" - width: 148 - height: 100 - - anchors { - left: acInBox.right - leftMargin: hasAcOutSystem ? 10 : 174 - top: root.top; topMargin: 1 - } - - values: OverviewAcValues { - connection: sys.acInLoad - } - } - - OverviewBox { - id: acOutputBox - title: qsTr("Critical Loads") - color: "#157894" - titleColor: "#419FB9" - height: 100 - width: 148 - visible: hasAcOutSystem - anchors { - right: root.right; rightMargin: 5 - top: root.top; topMargin: 17 - } - - values: OverviewAcValues { - connection: sys.acOutLoad - } - } - - Multi { - id: multi - iconId: "overview-inverter-short" - anchors { - horizontalCenter: parent.horizontalCenter - bottom: root.bottom; bottomMargin: 39 - } - } - - // invisible item to connection all AC connections to.. - Item { - id: acBus - height: 10 - anchors { - left: acInBox.left; leftMargin: hasAcOutSystem ? 5 : acInBox.width - 5 - right: acLoadBox.right; rightMargin: 2 - bottom: acInBox.bottom; bottomMargin: -15 - } - } - - Battery { - id: battery - - soc: sys.battery.soc.valid ? sys.battery.soc.value : 0 - height: pvInverterOnGrid.visible ? 81 : 101 - width: 145 - - anchors { - bottom: parent.bottom; bottomMargin: 5; - left:parent.left; leftMargin: 5 - } - values: Column { - y: pvInverterOnGrid.visible ? 0 : 8 - width: parent.width - - TileText { - text: sys.battery.soc.valid ? sys.battery.soc.value.toFixed(0) : "--" - font.pixelSize: 30 - - Text { - anchors { - bottom: parent.bottom; bottomMargin: 4 - horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: parent.paintedWidth / 2 + 5 - } - visible: sys.battery.soc.valid - text: "%" - color: "white" - font.bold: true - font.pixelSize: 12 - } - } - TileText { - text: sys.battery.power.format(0) - } - TileText { - text: sys.battery.voltage.format(1) + " " + sys.battery.current.format(1) - } - } - } - - // PV inverter on AC in, AC Output ignored - OverviewSolarInverter { - id: pvInverterOnGridNoAcOut - title: qsTr("PV Inverter") - width: 154 - height: 100 - visible: sys.pvOnGrid.power.valid && !hasAcOutSystem - showInverterIcon: false - values: TileText { - y: 2 - text: sys.pvOnGrid.power.format(0) - font.pixelSize: 25 - } - anchors { - top: root.top; topMargin: 1 - horizontalCenter: root.horizontalCenter - } - } - - OverviewSolarInverter { - id: pvInverterOnGrid - title: qsTr("PV Inverter") - width: 148 - height: 60 - visible: sys.pvOnGrid.power.valid && hasAcOutSystem - showInverterIcon: false - values: TileText { - y: 2 - text: sys.pvOnGrid.power.format(0) - font.pixelSize: 20 - } - anchors { - bottom: battery.top; bottomMargin: 5 - left: root.left; leftMargin: 5 - } - } - - OverviewSolarInverter { - id: pvInverterOnAcOut - title: qsTr("PV Inverter") - width: 148 - height: 60 - visible: sys.pvOnAcOut.power.valid - showInverterIcon: false - - values: TileText { - y: 2 - text: sys.pvOnAcOut.power.format(0) - font.pixelSize: 20 - } - anchors { - bottom: blueSolarCharger.top; bottomMargin: 5 - right: parent.right; rightMargin: 5 - } - } - - OverviewSolarCharger { - id: blueSolarCharger - title: qsTr("PV Charger") - width: 148 - height: 60 - visible: sys.pvCharger.power.valid - showChargerIcon: false - - anchors { - right: root.right; rightMargin: 5 - bottom: root.bottom; bottomMargin: 5; - } - - values: TileText { - y: 2 - text: sys.pvCharger.power.format(0) - font.pixelSize: 20 - } - } - - OverviewEssReason { - anchors { - bottom: parent.bottom; bottomMargin: 5 - horizontalCenter: parent.horizontalCenter - } - } - - // AC source power flow - OverviewConnection { - id: acSource - ballCount: 4 - path: corner - active: root.active && hasAcOutSystem - value: flow(sys.acInput ? sys.acInput.power : undefined) * -1 - startPointVisible: false - - anchors { - right: acInBox.left; rightMargin: -9 - left: pvInverterOnGridConnection.horizontalCenter - bottom: acInBox.bottom; bottomMargin: 8 - top: acBus.verticalCenter - } - } - - // Coupled AC sources - OverviewConnection { - id: coupledAcConnection - - property VBusItem coupled: VBusItem { - property double gridPower: sys.acInput.power.valid ? sys.acInput.power.value : 0 - property double pvPower: sys.pvOnGrid.power.valid ? sys.pvOnGrid.power.value : 0 - value: gridPower + pvPower - } - - ballCount: 1 - path: straight - active: root.active && hasAcOutSystem - value: flow(coupled) - startPointVisible: false - endPointVisible: false - - anchors { - left: pvInverterOnGridConnection.right - right: vebusConnection.left - top: acBus.verticalCenter - bottom: acBus.verticalCenter - } - } - - // AC source power flow, ignored AC output - OverviewConnection { - id: acSourceNoAcOut - ballCount: 5 - path: corner - active: root.active && !hasAcOutSystem - value: acSource.value - startPointVisible: false - - anchors { - right: acInBox.left; rightMargin: -9 - left: pvInverterOnGridConnectionNoAcOut.horizontalCenter - bottom: acInBox.bottom; bottomMargin: 8 - top: acBus.verticalCenter - } - } - - // Coupled AC sources, ignored AC output - OverviewConnection { - id: coupledAcConnectionNoAcOut - - ballCount: 1 - path: straight - active: root.active && !hasAcOutSystem - value: coupledAcConnection.value - startPointVisible: false - endPointVisible: false - - anchors { - left: pvInverterOnGridConnectionNoAcOut.right - right: vebusConnection.left - top: acBus.verticalCenter - bottom: acBus.verticalCenter - } - } - - // Grid inverter power flow, ignored AC output - OverviewConnection { - id: pvInverterOnGridConnectionNoAcOut - ballCount: 1 - path: straight - active: root.active && pvInverterOnGridNoAcOut.visible - value: flow(sys.pvOnGrid ? sys.pvOnGrid.power : undefined) - startPointVisible: true - endPointVisible: false - - anchors { - top: pvInverterOnGridNoAcOut.bottom; topMargin: -8 - bottom: acBus.verticalCenter - left: pvInverterOnGridNoAcOut.left; leftMargin: 8 - right: pvInverterOnGridNoAcOut.left; rightMargin: -8 - } - } - - // Grid inverter power flow - OverviewConnection { - id: pvInverterOnGridConnection - ballCount: 1 - path: straight - active: root.active && pvInverterOnGrid.visible - value: flow(sys.pvOnGrid ? sys.pvOnGrid.power : undefined) * -1 - startPointVisible: false - - anchors { - top: acBus.verticalCenter - bottom: pvInverterOnGrid.top; bottomMargin: -8 - left: pvInverterOnGrid.right; leftMargin: -8 - } - } - - // power to loads - OverviewConnection { - id: loadConnection - ballCount: hasAcOutSystem ? 3 : 5 - path: corner - active: root.active - value: flow(sys.acInLoad.power) - startPointVisible: false - endPointVisible: true - - anchors { - right: acLoadBox.right; rightMargin: hasAcOutSystem ? 10 : acLoadBox.width - 10 - left: vebusConnection.horizontalCenter - top: acBus.verticalCenter - bottom: acLoadBox.bottom; bottomMargin: 8 - } - } - - // Towards vebus system - OverviewConnection { - id: vebusConnection - - property VBusItem vebusAcPower: VBusItem { bind: [sys.vebusPrefix, "/Ac/ActiveIn/P"] } - - ballCount: 1 - path: straight - active: root.active - value: flow(vebusAcPower) - startPointVisible: false - endPointVisible: true - - anchors { - left: multi.left; leftMargin: 8 - top: acBus.verticalCenter - bottom: multi.top; bottomMargin: -7 - } - } - - // AC out connection - OverviewConnection { - id: acOutConnection - - property double pvInverterOnAcOutPower: sys.pvOnAcOut.power.valid ? sys.pvOnAcOut.power.value : 0 - property double acOutLoad: sys.acOutLoad.power.valid ? sys.acOutLoad.power.value : 0 - property VBusItem vebusAcOutPower: VBusItem { value: acOutConnection.acOutLoad - acOutConnection.pvInverterOnAcOutPower } - - ballCount: 1 - path: straight - active: root.active && (hasAcOutSystem || pvInverterOnAcOut.visible) - value: flow(vebusAcOutPower) - endPointVisible: false - - anchors { - left: multi.right; leftMargin: -8 - right: acOutBoxConnection.left - top: multi.top; topMargin: 8 - } - } - - // UPS conenction - OverviewConnection { - id: acOutBoxConnection - - ballCount: 1 - path: straight - active: root.active && hasAcOutSystem - value: flow(sys.acOutLoad.power) - startPointVisible: false - - anchors { - left: acOutputBox.left; leftMargin: 10 - top: acOutConnection.verticalCenter - bottom: acOutputBox.bottom; bottomMargin: 9 - } - } - - // PV Inverter on AC out connection - OverviewConnection { - id: pvOnAcOutConnection - - ballCount: 1 - path: straight - active: root.active && pvInverterOnAcOut.visible - value: flow(sys.pvOnAcOut.power) - endPointVisible: false - - anchors { - left: acOutBoxConnection.left - bottom: acOutConnection.verticalCenter - top: pvInverterOnAcOut.top; topMargin: 8 - } - } - - // DC connection from multi - OverviewConnection { - ballCount: 1 - path: straight - active: root.active - value: flow(sys.vebusDc.power) - endPointVisible: false - - anchors { - right: dcConnection.right; - top: multi.bottom; topMargin: -10 - bottom: dcConnection.top; - } - } - - // Battery to DC connection - OverviewConnection { - ballCount: 3 - path: straight - active: root.active - value: Utils.sign(noNoise(sys.pvCharger.power) + noNoise(sys.vebusDc.power)) - startPointVisible: false - - anchors { - left: dcConnection.left; - top: dcConnection.verticalCenter - right: battery.right; rightMargin: 10 - } - } - - // Solar charger to DC connection - OverviewConnection { - ballCount: 3 - path: straight - active: root.active && blueSolarCharger.visible - value: flow(sys.pvCharger.power) - endPointVisible: false - - anchors { - right: dcConnection.right; - top: dcConnection.top - left: blueSolarCharger.left; leftMargin: 10 - } - } - - Item { - id: dcConnection - anchors { - horizontalCenter: multi.horizontalCenter - top: multi.bottom; topMargin: 10 - } - } -} diff --git a/FileSets/v3.01/OverviewGeneratorEnhanced.qml b/FileSets/v3.01/OverviewGeneratorEnhanced.qml deleted file mode 100644 index 63e81367..00000000 --- a/FileSets/v3.01/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1,536 +0,0 @@ -// GuiMods enhanced generator overview -// This file has been modified to: -// add Auto Start display and control -// show voltage, current, frequency, and power gauge in AC input tile -// show the generator running state inside the icon top left -// show a warning when the generator digital input and expected generator state disagree -// move current run time to separate tile - -import QtQuick 1.1 -import "utils.js" as Utils -import "enhancedFormat.js" as EnhFmt - -OverviewPage { - id: root - - property string settingsBindPrefix - property string bindPrefix - property variant sys: theSystem -//////// added to show alternator in place of inactive genset - property string guiModsPrefix: "com.victronenergy.settings/Settings/GuiMods" - VBusItem { id: replaceAcInItem; bind: Utils.path(guiModsPrefix, "/ReplaceInactiveAcIn") } - property bool hasAlternator: sys.alternator.power.valid - property bool showAlternator: replaceAcInItem.valid && replaceAcInItem.value == 1 && hasAlternator && ! sys.genset.power.valid - property bool showAcIn: ! showAlternator - - property string icon: "overview-generator" - property VBusItem state: VBusItem { bind: Utils.path(bindPrefix, "/State") } - property VBusItem error: VBusItem { bind: Utils.path(bindPrefix, "/Error") } - property VBusItem runningTime: VBusItem { bind: Utils.path(bindPrefix, "/Runtime") } - property VBusItem runningBy: VBusItem { bind: Utils.path(bindPrefix, "/RunningByConditionCode") } - property VBusItem totalAcummulatedTime: VBusItem { bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") } - property VBusItem quietHours: VBusItem { bind: Utils.path(bindPrefix, "/QuietHours") } - property VBusItem testRunDuration: VBusItem { bind: Utils.path(settingsBindPrefix, "/TestRun/Duration") } - property VBusItem nextTestRun: VBusItem { bind: Utils.path(bindPrefix, "/NextTestRun") } - property VBusItem skipTestRun: VBusItem { bind: Utils.path(bindPrefix, "/SkipTestRun") } - - property VBusItem todayRuntime: VBusItem { bind: Utils.path(bindPrefix, "/TodayRuntime") } - property VBusItem manualTimer: VBusItem { bind: Utils.path(bindPrefix, "/ManualStartTimer") } - property VBusItem autoStart: VBusItem { bind: Utils.path(settingsBindPrefix, "/AutoStartEnabled") } - - property bool errors: ! state.valid || state.value == 10 - - property VBusItem externalOverrideItem: VBusItem { bind: Utils.path(bindPrefix, "/ExternalOverride") } - property bool externalOverride: externalOverrideItem.valid && externalOverrideItem.value == 1 && ! errors - property VBusItem runningState: VBusItem { bind: Utils.path(bindPrefix, "/GeneratorRunningState") } - - VBusItem { id: showGaugesItem; bind: Utils.path(guiModsPrefix, "/ShowGauges") } - property bool showGauges: showGaugesItem.valid ? showGaugesItem.value === 1 ? true : false : false - property bool editMode: autoRunTile.editMode || manualTile.editMode - - VBusItem { id: generatorServiceInterval; bind: Utils.path(settingsBindPrefix, "/ServiceInterval") } - VBusItem { id: timeSinceService; bind: Utils.path(settingsBindPrefix, "/TimeSinceService") } - property bool showServiceInfo: timeSinceService.valid && generatorServiceInterval.valid && generatorServiceInterval.value > 0 - property bool serviceOverdue: showServiceInfo && timeSinceService.value > generatorServiceInterval.value - - //////// add to display AC input ignored - VBusItem { id: ignoreAcInput1; bind: Utils.path(sys.vebusPrefix, "/Ac/State/IgnoreAcIn1") } - VBusItem { id: ignoreAcInput2; bind: Utils.path(sys.vebusPrefix, "/Ac/State/IgnoreAcIn2") } - VBusItem { id: acActiveInput; bind: Utils.path(sys.vebusPrefix, "/Ac/ActiveIn/ActiveInput") } - VBusItem { id: ac1source; bind: Utils.path("com.victronenergy.settings", "/Settings/SystemSetup/AcInput1") } - VBusItem { id: ac2source; bind: Utils.path("com.victronenergy.settings", "/Settings/SystemSetup/AcInput2") } - - title: qsTr("Generator") - - property bool autoStartSelected: false - - Component.onCompleted: - { - setFocusManual () - } - - Keys.forwardTo: [keyHandler] - Item - { - id: keyHandler - Keys.onUpPressed: - { - setFocusAuto () - event.accepted = true - } - Keys.onDownPressed: - { - setFocusManual () - event.accepted = true - } - // prevents page changes while timers are running - //// Keys.onReturnPressed: event.accepted = manualTile.startCountdown || autoRunTile.startCountdown - //// Keys.onEscapePressed: event.accepted = manualTile.startCountdown || autoRunTile.startCountdown - } - - function setFocusManual () - { - autoStartSelected = false - } - - function setFocusAuto () - { - autoStartSelected = true - } - - function formatTime (time) - { - if (time >= 3600) - return (time / 3600).toFixed(0) + " h" - else - return (time / 60).toFixed(0) + " m" - } - - function stateDescription() - { - if (!state.valid) - return qsTr ("") - else if (state.value === 10) - { - switch(error.value) - { - case 1: - return qsTr("Error: Remote switch control disabled") - case 2: - return qsTr("Error: Generator in fault condition") - case 3: - return qsTr("Error: Generator not detected at AC input") - default: - return qsTr("Error") - } - } - else - { - var condition = "" - var running = true - var manual = false - switch (runningBy.value) - { - case 0: // stopped - condition = "" - running = false - break;; - case 1: - manual = true - condition = "" - break;; - case 2: - condition = qsTr("Test run") - break;; - case 3: - condition = qsTr("Loss of communication") - break;; - case 4: - condition = qsTr("SOC") - break;; - case 5: - condition = qsTr("AC load") - break;; - case 6: - condition = qsTr("Battery current") - break;; - case 7: - condition = qsTr("Battery voltage") - break;; - case 8: - condition = qsTr("Inverter temperature") - break;; - case 9: - condition = qsTr("Inverter overload") - break;; - default: - condition = qsTr("???") - break;; - } - - if (externalOverride) - { - if (running && ! manual) - return qsTr ("auto pending: ") + condition - else - return " " - } - else if (manual) - { - if (manualTimer.valid && manualTimer.value > 0) - return qsTr("Timed run") - else - return qsTr("Manual run") - } - else if (running) - return qsTr ("auto run: ") + condition - else - return " " - } - } - - function getNextTestRun() - { - if ( ! root.state.valid) - return "" - if (!nextTestRun.value) - return qsTr("No test run programmed") - - var todayDate = new Date() - var nextDate = new Date(nextTestRun.value * 1000) - var nextDateEnd = new Date(nextDate.getTime()) - var message = "" - // blank "next run" if test run is active - if (runningBy.value == 2) - return " " - else if (todayDate.getDate() == nextDate.getDate() && todayDate.getMonth() == nextDate.getMonth()) - { - message = qsTr("Next test run today %1").arg( - Qt.formatDateTime(nextDate, "hh:mm").toString()) - } - else - { - message = qsTr("Next test run on %1").arg( - Qt.formatDateTime(nextDate, "dd/MM/yyyy").toString()) - nextDateEnd.setSeconds(testRunDuration.value) } - - if (skipTestRun.value === 1) - message += qsTr(" \(skipped\)") - - return message - } - - Tile { - id: imageTile - width: 180 - height: 136 - MbIcon { - id: generator - iconId: icon - anchors.centerIn: parent - } - anchors { top: parent.top; left: parent.left } - values: [ - // spacer - TileText { - width: imageTile.width - 5 - text: " " - font.pixelSize: 62 - }, - TileText { - width: imageTile.width - 5 - text: runningState.valid ? runningState.value == "R" ? "Running " : runningState.value == "S" ? "Stopped " : "" : "" - } - ] - } - - Tile { - id: statusTile - height: imageTile.height - color: "#4789d0" - anchors { top: parent.top; left: imageTile.right; right: root.right } - title: qsTr("STATUS") - values: [ - TileText - { - width: statusTile.width - 5 - color: externalOverride ? "yellow" : "white" - text: - { - var runPrefix - var message - if ( ! root.state.valid) - return qsTr ("Generator not connected") - else if (root.state.value === 2) - runPrefix = qsTr("Warming up for ") - else - runPrefix = qsTr ("Running for ") - if (!root.state.valid) - message = "" - else if (externalOverride) - message = qsTr("External Override - stopped") - else if (root.state.value === 3) - message = qsTr("Cool-down") - else if (runningBy.value == 0) - message = qsTr ("Stopped") - else if ( ! runningTime.valid) - message = runPrefix + "??" - else - { - message = runPrefix + formatTime (runningTime.value) - if (manualTimer.valid && manualTimer.value > 0) - message += qsTr (" ends in ") + formatTime (manualTimer.value) - } - return message - } - }, - Rectangle - { - width: parent.width - height: 3 - color: "transparent" - }, - TileTextMultiLine - { - text: stateDescription() - width: statusTile.width - 5 - }, - Rectangle - { - width: parent.width - height: 3 - color: "transparent" - }, - TileText - { - text: qsTr("\nQuiet hours"); - width: statusTile.width - 5 - font.bold: runningBy.valid && runningBy.value != 0 - color: font.bold ? "yellow" : "white" - visible: quietHours.value === 1 - }, - Rectangle - { - width: parent.width - height: 3 - color: "transparent" - }, - TileTextMultiLine - { - width: statusTile.width - 5 - text: getNextTestRun() - } - ] - } - - Tile { - id: acInTile - title: qsTr("GENERATOR POWER") - width: 150 - height: 136 - color: "#82acde" - anchors { top: imageTile.bottom; left: parent.left } - visible: showAcIn - values: - [ - OverviewAcValuesEnhanced - { - connection: sys.genset - visible: sys.genset.power.valid - }, - TileText - { - width: acInTile.width - 5 - text: - { - if (ac1source.valid && ac1source.value == 2) - { - if (ignoreAcInput1.valid && ignoreAcInput1.value == 1) - return qsTr ("\nAC In Ignored\nduring\ngenerator\nstart / stop") - else - return "" - } - else if (ac2source.valid && ac2source.value == 2) - { - if (ignoreAcInput2.valid && ignoreAcInput2.value == 1) - return qsTr ("\nAC In Ignored\nduring\ngenerator\nstart / stop") - else - return "" - } - else - return qsTr ("\nAC In\nis not\ngenerator") - } - visible: !sys.genset.power.valid - } - ] -////// add power bar graph - PowerGauge - { - id: acInBar - width: parent.width - height: 12 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.genset - useInputCurrentLimit: true - maxForwardPowerParameter: "" - maxReversePowerParameter: "" - visible: showGauges && sys.genset.power.valid - } - } - -//////// added to show alternator in place of AC generator - Tile { - id: alternatorTile - title: qsTr("ALTERNATOR POWER") - color: "#157894" - anchors.fill: acInTile - visible: showAlternator - values: - [ - TileText - { - text: EnhFmt.formatVBusItem (sys.alternator.power, "W") - font.pixelSize: 22 - } - ] -////// add power bar graph - PowerGauge - { - id: alternatorGauge - width: parent.width - height: 12 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.alternator - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxAlternatorPower" - visible: showGauges && showAlternator - } - } - - Tile { - id: runTimeTile - title: qsTr("RUN TIMES") - width: 140 - anchors { top: acInTile.top; bottom: parent.bottom; left: acInTile.right } - values: [ - TileText - { - width: runTimeTile.width - 5 - text: qsTr ("Today") - }, - TileText { - width: runTimeTile.width - 5 - text: todayRuntime.valid ? formatTime (todayRuntime.value) : "--" - }, - Rectangle - { - width: parent.width - height: 3 - color: "transparent" - }, - TileText - { - width: runTimeTile.width - 5 - text: qsTr ("Accumulated") - }, - TileText - { - width: runTimeTile.width - 5 - text: totalAcummulatedTime.valid ? formatTime (totalAcummulatedTime.value) : "--" - }, - Rectangle - { - width: parent.width - height: 3 - color: "transparent" - }, - TileText - { - width: runTimeTile.width - 5 - visible: showServiceInfo - color: serviceOverdue ? "red" : "white" - text: serviceOverdue ? qsTr ("Service OVERDUE") : qsTr ("Service in") - }, - TileText - { - width: runTimeTile.width - 5 - visible: showServiceInfo - color: serviceOverdue ? "red" : "white" - text: formatTime (Math.abs (generatorServiceInterval.value - timeSinceService.value)) - } - ] - } - - TileAutoRunEnhanced - { - id: autoRunTile - bindPrefix: root.bindPrefix - focus: root.active && autoStartSelected - connected: state.valid - tileHeight: acInTile.height / 2 - anchors { - bottom: parent.bottom; bottomMargin: tileHeight - left: runTimeTile.right - right: parent.right - } - } - - TileManualStartEnhanced - { - id: manualTile - bindPrefix: root.bindPrefix - focus: root.active && ! autoStartSelected - connected: state.valid - tileHeight: acInTile.height / 2 - anchors { - bottom: parent.bottom - left: runTimeTile.right - right: parent.right - } - } - - // mouse areas must be AFTER their associated objects so those objects can catch mouse events - // rejected by these areas - // mouse targets need to be disabled while changes are pending - MouseArea { - id: autoRunTarget - anchors.fill: autoRunTile - enabled: root.active && ! editMode - onPressed: - { - if ( ! root.autoStartSelected ) - { - setFocusAuto () - mouse.accepted = true - } - else - { - mouse.accepted = false - } - } - } - MouseArea { - id: manualStartTarget - anchors.fill: manualTile - enabled: root.active && ! editMode - onPressed: - { - if ( root.autoStartSelected ) - { - setFocusManual () - mouse.accepted = true - } - else - { - mouse.accepted = false - } - } - } -} diff --git a/FileSets/v3.01/OverviewGeneratorEnhanced.qml.orig b/FileSets/v3.01/OverviewGeneratorEnhanced.qml.orig deleted file mode 100644 index 73fed5a5..00000000 --- a/FileSets/v3.01/OverviewGeneratorEnhanced.qml.orig +++ /dev/null @@ -1,194 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: root - title: qsTr("Generator start/stop") - property string settingsBindPrefix - property string startStopBindPrefix - property alias startStopModel: _startStopModel - property bool allowDisableAutostart: true - property VBusItem activeCondition: VBusItem { bind: Utils.path(startStopBindPrefix, "/RunningByCondition") } - property VBusItem generatorState: VBusItem { bind: Utils.path(startStopBindPrefix, "/State") } - property VBusItem runningTime: VBusItem { bind: Utils.path(startStopBindPrefix, "/Runtime") } - property VBusItem historicalData: VBusItem { bind: Utils.path(settingsBindPrefix, "/AccumulatedDaily") } - - function getState() - { - switch(generatorState.value) { - case 10: - return qsTr("Error") - case 2: - return qsTr("Warm-up") - case 3: - return qsTr("Cool-down") - } - - switch(activeCondition.value) { - case 'soc': - return qsTr("Running by SOC condition") - case 'acload': - return qsTr("Running by AC Load condition") - case 'batterycurrent': - return qsTr("Running by battery current condition") - case 'batteryvoltage': - return qsTr("Running by battery voltage condition") - case 'inverterhightemp': - return qsTr("Running by inverter high temperature") - case 'inverteroverload': - return qsTr("Running by inverter overload") - case 'testrun': - return qsTr("Test run") - case 'lossofcommunication': - return qsTr("Running by loss of communication") - case 'manual': - return qsTr("Manually started") - default: - return qsTr("Stopped") - } - } - - model: startStopModel - - function formatError(text, value) - { - return "#" + value.toString() + " " + text - } - - VisibleItemModel { - id: _startStopModel - - MbItemValue { - description: qsTr("State") - item.text: activeCondition.valid ? getState() : '---' - } - - MbItemOptions { - id: _gensetStatus - description: qsTr("Error") - bind: Utils.path(startStopBindPrefix, "/Error") - readonly: true - show: valid - possibleValues: [ - MbOption { description: qsTr("No error"); value: 0 }, - MbOption { description: formatError(qsTr("Remote switch control disabled"), 1); value: 1 }, - MbOption { description: formatError(qsTr("Generator in fault condition"), 2); value: 2 }, - MbOption { description: formatError(qsTr("Generator not detected at AC input"), 3); value: 3 } - ] - } - - MbItemValue { - description: qsTr("Run time") - item.text: runningTime.valid ? Utils.secondsToNoSecsString(runningTime.value) : "0" - show: generatorState.value in [1, 2, 3] // Running, Warm-up, Cool-down - } - - MbItemValue { - description: qsTr("Total run time") - item { - bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") - text: Utils.secondsToNoSecsString(item.value) - } - } - - MbItemValue { - description: qsTr("Accumulated running time since last test run") - show: user.accessLevel >= User.AccessService && nextTestRun.show - backgroundColor: style.backgroundColorService - item { - text: Utils.secondsToNoSecsString(item.value) - bind: Utils.path(startStopBindPrefix, "/TestRunIntervalRuntime") - } - } - - MbItemValue { - id: nextTestRun - description: qsTr("Time to next test run") - show: item.valid && item.value > 0 - item { - text: { - var remainingTime = item.value - new Date().getTime() / 1000 - if (remainingTime > 0) - return Utils.secondsToNoSecsString(remainingTime).toString() - return qsTr("Running now") - } - bind: Utils.path(startStopBindPrefix, "/NextTestRun") - } - } - - MbSwitch { - name: qsTr("Auto start functionality") - bind: Utils.path(settingsBindPrefix, "/AutoStartEnabled") - show: allowDisableAutostart - } - - MbSubMenu { - description: qsTr("Manual start") - subpage: Component { - MbPage { - id: manualStartPage - title: qsTr("Manual start") - model: VisibleItemModel { - MbSwitch { - id: manualSwitch - name: qsTr("Start generator") - bind: Utils.path(startStopBindPrefix, "/ManualStart") - writeAccessLevel: User.AccessUser - onCheckedChanged: { - if (manualStartPage.active) { - if (!checked) - toast.createToast(qsTr("Stopping, generator will continue running if other conditions are reached"), 3000) - if (checked && stopTimer.value == 0) - toast.createToast(qsTr("Starting, generator won't stop till user intervention"), 5000) - if (checked && stopTimer.value > 0) - toast.createToast(qsTr("Starting. The generator will stop in %1, unless other conditions keep it running").arg(Utils.secondsToString(stopTimer.value)), 5000) - } - } - - VBusItem { - id: stopTimer - bind: Utils.path(startStopBindPrefix, "/ManualStartTimer") - } - } - - MbEditBoxTime { - description: qsTr("Run for (hh:mm)") - readonly: manualSwitch.checked - item.bind: Utils.path(startStopBindPrefix, "/ManualStartTimer") - writeAccessLevel: User.AccessUser - } - } - } - } - } - - MbSubMenu { - description: qsTr("Daily run time") - subpage: MbPage { - // Invert the order - property variant keys: historicalData.valid ? - Object.keys(JSON.parse(historicalData.value)).reverse() : 0 - - title: qsTr("Daily run time") - focus: active - model: keys - delegate: MbItemValue { - description: Qt.formatDate(new Date(parseInt(keys[index]) * 1000), "dd-MM-yyyy"); - item.text: Utils.secondsToNoSecsString(JSON.parse(historicalData.value)[keys[index]]) - } - } - } - - MbSubMenu { - id: conditions - description: qsTr("Settings") - subpage: Component { - PageSettingsGenerator { - settingsBindPrefix: root.settingsBindPrefix - startStopBindPrefix: root.startStopBindPrefix - } - } - } - } -} diff --git a/FileSets/v3.01/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.01/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index 1c9b530f..00000000 --- a/FileSets/v3.01/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.01/OverviewGridParallel.qml b/FileSets/v3.01/OverviewGridParallel.qml deleted file mode 100644 index 6223b5e7..00000000 --- a/FileSets/v3.01/OverviewGridParallel.qml +++ /dev/null @@ -1,488 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -OverviewPage { - id: root - -////// GuiMods — DarkMode - property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } - property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 - - property variant sys: theSystem - property bool hasAcOutSystem: _hasAcOutSystem.value === 1 - - title: qsTr("Overview") - - VBusItem { - id: _hasAcOutSystem - bind: "com.victronenergy.settings/Settings/SystemSetup/HasAcOutSystem" - } - - OverviewBox { - id: acInBox - - width: 148 - height: 100 - title: getAcSourceName(sys.acSource) -////// GuiMods — DarkMode - titleColor: !darkMode ? "#E74c3c" : "#73261E" - color: !darkMode ? "#C0392B" : "#601C15" - anchors { - top: root.top; topMargin: 1 - left: parent.left; leftMargin: 5 - } - - values: OverviewAcValues { - connection: sys.acInput - } - - MbIcon { - iconId: getAcSourceIcon(sys.acSource) - anchors { - bottom: parent.bottom - left: parent.left; leftMargin: 2 - } - opacity: 0.5 - } - } - - OverviewBox { - id: acLoadBox - title: qsTr("AC Loads") -////// GuiMods — DarkMode - color: !darkMode ? "#27AE60" : "#135730" - titleColor: !darkMode ? "#2ECC71" : "#176638" - width: 148 - height: 100 - - anchors { - left: acInBox.right - leftMargin: hasAcOutSystem ? 10 : 174 - top: root.top; topMargin: 1 - } - - values: OverviewAcValues { - connection: sys.acInLoad - } - } - - OverviewBox { - id: acOutputBox - title: qsTr("Critical Loads") -////// GuiMods — DarkMode - color: !darkMode ? "#157894" : "#0a3c4a" - titleColor: !darkMode ? "#419FB9" : "#204f5c" - height: 100 - width: 148 - visible: hasAcOutSystem - anchors { - right: root.right; rightMargin: 5 - top: root.top; topMargin: 17 - } - - values: OverviewAcValues { - connection: sys.acOutLoad - } - } - - Multi { - id: multi - iconId: "overview-inverter-short" - anchors { - horizontalCenter: parent.horizontalCenter - bottom: root.bottom; bottomMargin: 39 - } - } - - // invisible item to connection all AC connections to.. - Item { - id: acBus - height: 10 - anchors { - left: acInBox.left; leftMargin: hasAcOutSystem ? 5 : acInBox.width - 5 - right: acLoadBox.right; rightMargin: 2 - bottom: acInBox.bottom; bottomMargin: -15 - } - } - - Battery { - id: battery - - soc: sys.battery.soc.valid ? sys.battery.soc.value : 0 - height: pvInverterOnGrid.visible ? 81 : 101 - width: 145 - - anchors { - bottom: parent.bottom; bottomMargin: 5; - left:parent.left; leftMargin: 5 - } - values: Column { - y: pvInverterOnGrid.visible ? 0 : 8 - width: parent.width - - TileText { - text: sys.battery.soc.valid ? sys.battery.soc.value.toFixed(0) : "--" - font.pixelSize: 30 - - Text { - anchors { - bottom: parent.bottom; bottomMargin: 4 - horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: parent.paintedWidth / 2 + 5 - } - visible: sys.battery.soc.valid - text: "%" - color: "white" - font.bold: true - font.pixelSize: 12 - } - } - TileText { - text: sys.battery.power.format(0) - } - TileText { - text: sys.battery.voltage.format(1) + " " + sys.battery.current.format(1) - } - } - } - - // PV inverter on AC in, AC Output ignored - OverviewSolarInverter { - id: pvInverterOnGridNoAcOut - title: qsTr("PV Inverter") - width: 154 - height: 100 - visible: sys.pvOnGrid.power.valid && !hasAcOutSystem - showInverterIcon: false - values: TileText { - y: 2 - text: sys.pvOnGrid.power.format(0) - font.pixelSize: 25 - } - anchors { - top: root.top; topMargin: 1 - horizontalCenter: root.horizontalCenter - } - } - - OverviewSolarInverter { - id: pvInverterOnGrid - title: qsTr("PV Inverter") - width: 148 - height: 60 - visible: sys.pvOnGrid.power.valid && hasAcOutSystem - showInverterIcon: false - values: TileText { - y: 2 - text: sys.pvOnGrid.power.format(0) - font.pixelSize: 20 - } - anchors { - bottom: battery.top; bottomMargin: 5 - left: root.left; leftMargin: 5 - } - } - - OverviewSolarInverter { - id: pvInverterOnAcOut - title: qsTr("PV Inverter") - width: 148 - height: 60 - visible: sys.pvOnAcOut.power.valid - showInverterIcon: false - - values: TileText { - y: 2 - text: sys.pvOnAcOut.power.format(0) - font.pixelSize: 20 - } - anchors { - bottom: blueSolarCharger.top; bottomMargin: 5 - right: parent.right; rightMargin: 5 - } - } - - OverviewSolarCharger { - id: blueSolarCharger - title: qsTr("PV Charger") - width: 148 - height: 60 - visible: sys.pvCharger.power.valid - showChargerIcon: false - - anchors { - right: root.right; rightMargin: 5 - bottom: root.bottom; bottomMargin: 5; - } - - values: TileText { - y: 2 - text: sys.pvCharger.power.format(0) - font.pixelSize: 20 - } - } - - OverviewEssReason { - anchors { - bottom: parent.bottom; bottomMargin: 5 - horizontalCenter: parent.horizontalCenter - } - } - - // AC source power flow - OverviewConnection { - id: acSource - ballCount: 4 - path: corner - active: root.active && hasAcOutSystem - value: flow(sys.acInput ? sys.acInput.power : undefined) * -1 - startPointVisible: false - - anchors { - right: acInBox.left; rightMargin: -9 - left: pvInverterOnGridConnection.horizontalCenter - bottom: acInBox.bottom; bottomMargin: 8 - top: acBus.verticalCenter - } - } - - // Coupled AC sources - OverviewConnection { - id: coupledAcConnection - - property VBusItem coupled: VBusItem { - property double gridPower: sys.acInput.power.valid ? sys.acInput.power.value : 0 - property double pvPower: sys.pvOnGrid.power.valid ? sys.pvOnGrid.power.value : 0 - value: gridPower + pvPower - } - - ballCount: 1 - path: straight - active: root.active && hasAcOutSystem - value: flow(coupled) - startPointVisible: false - endPointVisible: false - - anchors { - left: pvInverterOnGridConnection.right - right: vebusConnection.left - top: acBus.verticalCenter - bottom: acBus.verticalCenter - } - } - - // AC source power flow, ignored AC output - OverviewConnection { - id: acSourceNoAcOut - ballCount: 5 - path: corner - active: root.active && !hasAcOutSystem - value: acSource.value - startPointVisible: false - - anchors { - right: acInBox.left; rightMargin: -9 - left: pvInverterOnGridConnectionNoAcOut.horizontalCenter - bottom: acInBox.bottom; bottomMargin: 8 - top: acBus.verticalCenter - } - } - - // Coupled AC sources, ignored AC output - OverviewConnection { - id: coupledAcConnectionNoAcOut - - ballCount: 1 - path: straight - active: root.active && !hasAcOutSystem - value: coupledAcConnection.value - startPointVisible: false - endPointVisible: false - - anchors { - left: pvInverterOnGridConnectionNoAcOut.right - right: vebusConnection.left - top: acBus.verticalCenter - bottom: acBus.verticalCenter - } - } - - // Grid inverter power flow, ignored AC output - OverviewConnection { - id: pvInverterOnGridConnectionNoAcOut - ballCount: 1 - path: straight - active: root.active && pvInverterOnGridNoAcOut.visible - value: flow(sys.pvOnGrid ? sys.pvOnGrid.power : undefined) - startPointVisible: true - endPointVisible: false - - anchors { - top: pvInverterOnGridNoAcOut.bottom; topMargin: -8 - bottom: acBus.verticalCenter - left: pvInverterOnGridNoAcOut.left; leftMargin: 8 - right: pvInverterOnGridNoAcOut.left; rightMargin: -8 - } - } - - // Grid inverter power flow - OverviewConnection { - id: pvInverterOnGridConnection - ballCount: 1 - path: straight - active: root.active && pvInverterOnGrid.visible - value: flow(sys.pvOnGrid ? sys.pvOnGrid.power : undefined) * -1 - startPointVisible: false - - anchors { - top: acBus.verticalCenter - bottom: pvInverterOnGrid.top; bottomMargin: -8 - left: pvInverterOnGrid.right; leftMargin: -8 - } - } - - // power to loads - OverviewConnection { - id: loadConnection - ballCount: hasAcOutSystem ? 3 : 5 - path: corner - active: root.active - value: flow(sys.acInLoad.power) - startPointVisible: false - endPointVisible: true - - anchors { - right: acLoadBox.right; rightMargin: hasAcOutSystem ? 10 : acLoadBox.width - 10 - left: vebusConnection.horizontalCenter - top: acBus.verticalCenter - bottom: acLoadBox.bottom; bottomMargin: 8 - } - } - - // Towards vebus system - OverviewConnection { - id: vebusConnection - - property VBusItem vebusAcPower: VBusItem { bind: [sys.vebusPrefix, "/Ac/ActiveIn/P"] } - - ballCount: 1 - path: straight - active: root.active - value: flow(vebusAcPower) - startPointVisible: false - endPointVisible: true - - anchors { - left: multi.left; leftMargin: 8 - top: acBus.verticalCenter - bottom: multi.top; bottomMargin: -7 - } - } - - // AC out connection - OverviewConnection { - id: acOutConnection - - property double pvInverterOnAcOutPower: sys.pvOnAcOut.power.valid ? sys.pvOnAcOut.power.value : 0 - property double acOutLoad: sys.acOutLoad.power.valid ? sys.acOutLoad.power.value : 0 - property VBusItem vebusAcOutPower: VBusItem { value: acOutConnection.acOutLoad - acOutConnection.pvInverterOnAcOutPower } - - ballCount: 1 - path: straight - active: root.active && (hasAcOutSystem || pvInverterOnAcOut.visible) - value: flow(vebusAcOutPower) - endPointVisible: false - - anchors { - left: multi.right; leftMargin: -8 - right: acOutBoxConnection.left - top: multi.top; topMargin: 8 - } - } - - // UPS conenction - OverviewConnection { - id: acOutBoxConnection - - ballCount: 1 - path: straight - active: root.active && hasAcOutSystem - value: flow(sys.acOutLoad.power) - startPointVisible: false - - anchors { - left: acOutputBox.left; leftMargin: 10 - top: acOutConnection.verticalCenter - bottom: acOutputBox.bottom; bottomMargin: 9 - } - } - - // PV Inverter on AC out connection - OverviewConnection { - id: pvOnAcOutConnection - - ballCount: 1 - path: straight - active: root.active && pvInverterOnAcOut.visible - value: flow(sys.pvOnAcOut.power) - endPointVisible: false - - anchors { - left: acOutBoxConnection.left - bottom: acOutConnection.verticalCenter - top: pvInverterOnAcOut.top; topMargin: 8 - } - } - - // DC connection from multi - OverviewConnection { - ballCount: 1 - path: straight - active: root.active - value: flow(sys.vebusDc.power) - endPointVisible: false - - anchors { - right: dcConnection.right; - top: multi.bottom; topMargin: -10 - bottom: dcConnection.top; - } - } - - // Battery to DC connection - OverviewConnection { - ballCount: 3 - path: straight - active: root.active - value: Utils.sign(noNoise(sys.pvCharger.power) + noNoise(sys.vebusDc.power)) - startPointVisible: false - - anchors { - left: dcConnection.left; - top: dcConnection.verticalCenter - right: battery.right; rightMargin: 10 - } - } - - // Solar charger to DC connection - OverviewConnection { - ballCount: 3 - path: straight - active: root.active && blueSolarCharger.visible - value: flow(sys.pvCharger.power) - endPointVisible: false - - anchors { - right: dcConnection.right; - top: dcConnection.top - left: blueSolarCharger.left; leftMargin: 10 - } - } - - Item { - id: dcConnection - anchors { - horizontalCenter: multi.horizontalCenter - top: multi.bottom; topMargin: 10 - } - } -} diff --git a/FileSets/v3.01/OverviewGridParallel.qml.orig b/FileSets/v3.01/OverviewGridParallel.qml.orig deleted file mode 100644 index 44688485..00000000 --- a/FileSets/v3.01/OverviewGridParallel.qml.orig +++ /dev/null @@ -1,481 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -OverviewPage { - id: root - - property variant sys: theSystem - property bool hasAcOutSystem: _hasAcOutSystem.value === 1 - - title: qsTr("Overview") - - VBusItem { - id: _hasAcOutSystem - bind: "com.victronenergy.settings/Settings/SystemSetup/HasAcOutSystem" - } - - OverviewBox { - id: acInBox - - width: 148 - height: 100 - title: getAcSourceName(sys.acSource) - titleColor: "#E74c3c" - color: "#C0392B" - anchors { - top: root.top; topMargin: 1 - left: parent.left; leftMargin: 5 - } - - values: OverviewAcValues { - connection: sys.acInput - } - - MbIcon { - iconId: getAcSourceIcon(sys.acSource) - anchors { - bottom: parent.bottom - left: parent.left; leftMargin: 2 - } - opacity: 0.5 - } - } - - OverviewBox { - id: acLoadBox - title: qsTr("AC Loads") - color: "#27AE60" - titleColor: "#2ECC71" - width: 148 - height: 100 - - anchors { - left: acInBox.right - leftMargin: hasAcOutSystem ? 10 : 174 - top: root.top; topMargin: 1 - } - - values: OverviewAcValues { - connection: sys.acInLoad - } - } - - OverviewBox { - id: acOutputBox - title: qsTr("Critical Loads") - color: "#157894" - titleColor: "#419FB9" - height: 100 - width: 148 - visible: hasAcOutSystem - anchors { - right: root.right; rightMargin: 5 - top: root.top; topMargin: 17 - } - - values: OverviewAcValues { - connection: sys.acOutLoad - } - } - - Multi { - id: multi - iconId: "overview-inverter-short" - anchors { - horizontalCenter: parent.horizontalCenter - bottom: root.bottom; bottomMargin: 39 - } - } - - // invisible item to connection all AC connections to.. - Item { - id: acBus - height: 10 - anchors { - left: acInBox.left; leftMargin: hasAcOutSystem ? 5 : acInBox.width - 5 - right: acLoadBox.right; rightMargin: 2 - bottom: acInBox.bottom; bottomMargin: -15 - } - } - - Battery { - id: battery - - soc: sys.battery.soc.valid ? sys.battery.soc.value : 0 - height: pvInverterOnGrid.visible ? 81 : 101 - width: 145 - - anchors { - bottom: parent.bottom; bottomMargin: 5; - left:parent.left; leftMargin: 5 - } - values: Column { - y: pvInverterOnGrid.visible ? 0 : 8 - width: parent.width - - TileText { - text: sys.battery.soc.valid ? sys.battery.soc.value.toFixed(0) : "--" - font.pixelSize: 30 - - Text { - anchors { - bottom: parent.bottom; bottomMargin: 4 - horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: parent.paintedWidth / 2 + 5 - } - visible: sys.battery.soc.valid - text: "%" - color: "white" - font.bold: true - font.pixelSize: 12 - } - } - TileText { - text: sys.battery.power.format(0) - } - TileText { - text: sys.battery.voltage.format(1) + " " + sys.battery.current.format(1) - } - } - } - - // PV inverter on AC in, AC Output ignored - OverviewSolarInverter { - id: pvInverterOnGridNoAcOut - title: qsTr("PV Inverter") - width: 154 - height: 100 - visible: sys.pvOnGrid.power.valid && !hasAcOutSystem - showInverterIcon: false - values: TileText { - y: 2 - text: sys.pvOnGrid.power.format(0) - font.pixelSize: 25 - } - anchors { - top: root.top; topMargin: 1 - horizontalCenter: root.horizontalCenter - } - } - - OverviewSolarInverter { - id: pvInverterOnGrid - title: qsTr("PV Inverter") - width: 148 - height: 60 - visible: sys.pvOnGrid.power.valid && hasAcOutSystem - showInverterIcon: false - values: TileText { - y: 2 - text: sys.pvOnGrid.power.format(0) - font.pixelSize: 20 - } - anchors { - bottom: battery.top; bottomMargin: 5 - left: root.left; leftMargin: 5 - } - } - - OverviewSolarInverter { - id: pvInverterOnAcOut - title: qsTr("PV Inverter") - width: 148 - height: 60 - visible: sys.pvOnAcOut.power.valid - showInverterIcon: false - - values: TileText { - y: 2 - text: sys.pvOnAcOut.power.format(0) - font.pixelSize: 20 - } - anchors { - bottom: blueSolarCharger.top; bottomMargin: 5 - right: parent.right; rightMargin: 5 - } - } - - OverviewSolarCharger { - id: blueSolarCharger - title: qsTr("PV Charger") - width: 148 - height: 60 - visible: sys.pvCharger.power.valid - showChargerIcon: false - - anchors { - right: root.right; rightMargin: 5 - bottom: root.bottom; bottomMargin: 5; - } - - values: TileText { - y: 2 - text: sys.pvCharger.power.format(0) - font.pixelSize: 20 - } - } - - OverviewEssReason { - anchors { - bottom: parent.bottom; bottomMargin: 5 - horizontalCenter: parent.horizontalCenter - } - } - - // AC source power flow - OverviewConnection { - id: acSource - ballCount: 4 - path: corner - active: root.active && hasAcOutSystem - value: flow(sys.acInput ? sys.acInput.power : undefined) * -1 - startPointVisible: false - - anchors { - right: acInBox.left; rightMargin: -9 - left: pvInverterOnGridConnection.horizontalCenter - bottom: acInBox.bottom; bottomMargin: 8 - top: acBus.verticalCenter - } - } - - // Coupled AC sources - OverviewConnection { - id: coupledAcConnection - - property VBusItem coupled: VBusItem { - property double gridPower: sys.acInput.power.valid ? sys.acInput.power.value : 0 - property double pvPower: sys.pvOnGrid.power.valid ? sys.pvOnGrid.power.value : 0 - value: gridPower + pvPower - } - - ballCount: 1 - path: straight - active: root.active && hasAcOutSystem - value: flow(coupled) - startPointVisible: false - endPointVisible: false - - anchors { - left: pvInverterOnGridConnection.right - right: vebusConnection.left - top: acBus.verticalCenter - bottom: acBus.verticalCenter - } - } - - // AC source power flow, ignored AC output - OverviewConnection { - id: acSourceNoAcOut - ballCount: 5 - path: corner - active: root.active && !hasAcOutSystem - value: acSource.value - startPointVisible: false - - anchors { - right: acInBox.left; rightMargin: -9 - left: pvInverterOnGridConnectionNoAcOut.horizontalCenter - bottom: acInBox.bottom; bottomMargin: 8 - top: acBus.verticalCenter - } - } - - // Coupled AC sources, ignored AC output - OverviewConnection { - id: coupledAcConnectionNoAcOut - - ballCount: 1 - path: straight - active: root.active && !hasAcOutSystem - value: coupledAcConnection.value - startPointVisible: false - endPointVisible: false - - anchors { - left: pvInverterOnGridConnectionNoAcOut.right - right: vebusConnection.left - top: acBus.verticalCenter - bottom: acBus.verticalCenter - } - } - - // Grid inverter power flow, ignored AC output - OverviewConnection { - id: pvInverterOnGridConnectionNoAcOut - ballCount: 1 - path: straight - active: root.active && pvInverterOnGridNoAcOut.visible - value: flow(sys.pvOnGrid ? sys.pvOnGrid.power : undefined) - startPointVisible: true - endPointVisible: false - - anchors { - top: pvInverterOnGridNoAcOut.bottom; topMargin: -8 - bottom: acBus.verticalCenter - left: pvInverterOnGridNoAcOut.left; leftMargin: 8 - right: pvInverterOnGridNoAcOut.left; rightMargin: -8 - } - } - - // Grid inverter power flow - OverviewConnection { - id: pvInverterOnGridConnection - ballCount: 1 - path: straight - active: root.active && pvInverterOnGrid.visible - value: flow(sys.pvOnGrid ? sys.pvOnGrid.power : undefined) * -1 - startPointVisible: false - - anchors { - top: acBus.verticalCenter - bottom: pvInverterOnGrid.top; bottomMargin: -8 - left: pvInverterOnGrid.right; leftMargin: -8 - } - } - - // power to loads - OverviewConnection { - id: loadConnection - ballCount: hasAcOutSystem ? 3 : 5 - path: corner - active: root.active - value: flow(sys.acInLoad.power) - startPointVisible: false - endPointVisible: true - - anchors { - right: acLoadBox.right; rightMargin: hasAcOutSystem ? 10 : acLoadBox.width - 10 - left: vebusConnection.horizontalCenter - top: acBus.verticalCenter - bottom: acLoadBox.bottom; bottomMargin: 8 - } - } - - // Towards vebus system - OverviewConnection { - id: vebusConnection - - property VBusItem vebusAcPower: VBusItem { bind: [sys.vebusPrefix, "/Ac/ActiveIn/P"] } - - ballCount: 1 - path: straight - active: root.active - value: flow(vebusAcPower) - startPointVisible: false - endPointVisible: true - - anchors { - left: multi.left; leftMargin: 8 - top: acBus.verticalCenter - bottom: multi.top; bottomMargin: -7 - } - } - - // AC out connection - OverviewConnection { - id: acOutConnection - - property double pvInverterOnAcOutPower: sys.pvOnAcOut.power.valid ? sys.pvOnAcOut.power.value : 0 - property double acOutLoad: sys.acOutLoad.power.valid ? sys.acOutLoad.power.value : 0 - property VBusItem vebusAcOutPower: VBusItem { value: acOutConnection.acOutLoad - acOutConnection.pvInverterOnAcOutPower } - - ballCount: 1 - path: straight - active: root.active && (hasAcOutSystem || pvInverterOnAcOut.visible) - value: flow(vebusAcOutPower) - endPointVisible: false - - anchors { - left: multi.right; leftMargin: -8 - right: acOutBoxConnection.left - top: multi.top; topMargin: 8 - } - } - - // UPS conenction - OverviewConnection { - id: acOutBoxConnection - - ballCount: 1 - path: straight - active: root.active && hasAcOutSystem - value: flow(sys.acOutLoad.power) - startPointVisible: false - - anchors { - left: acOutputBox.left; leftMargin: 10 - top: acOutConnection.verticalCenter - bottom: acOutputBox.bottom; bottomMargin: 9 - } - } - - // PV Inverter on AC out connection - OverviewConnection { - id: pvOnAcOutConnection - - ballCount: 1 - path: straight - active: root.active && pvInverterOnAcOut.visible - value: flow(sys.pvOnAcOut.power) - endPointVisible: false - - anchors { - left: acOutBoxConnection.left - bottom: acOutConnection.verticalCenter - top: pvInverterOnAcOut.top; topMargin: 8 - } - } - - // DC connection from multi - OverviewConnection { - ballCount: 1 - path: straight - active: root.active - value: flow(sys.vebusDc.power) - endPointVisible: false - - anchors { - right: dcConnection.right; - top: multi.bottom; topMargin: -10 - bottom: dcConnection.top; - } - } - - // Battery to DC connection - OverviewConnection { - ballCount: 3 - path: straight - active: root.active - value: Utils.sign(noNoise(sys.pvCharger.power) + noNoise(sys.vebusDc.power)) - startPointVisible: false - - anchors { - left: dcConnection.left; - top: dcConnection.verticalCenter - right: battery.right; rightMargin: 10 - } - } - - // Solar charger to DC connection - OverviewConnection { - ballCount: 3 - path: straight - active: root.active && blueSolarCharger.visible - value: flow(sys.pvCharger.power) - endPointVisible: false - - anchors { - right: dcConnection.right; - top: dcConnection.top - left: blueSolarCharger.left; leftMargin: 10 - } - } - - Item { - id: dcConnection - anchors { - horizontalCenter: multi.horizontalCenter - top: multi.bottom; topMargin: 10 - } - } -} diff --git a/FileSets/v3.01/OverviewHub.qml b/FileSets/v3.01/OverviewHub.qml deleted file mode 100644 index 54d81dda..00000000 --- a/FileSets/v3.01/OverviewHub.qml +++ /dev/null @@ -1,315 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -OverviewPage { - id: root - -////// GuiMods — DarkMode - property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } - property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 - - property variant sys: theSystem - property bool hasAcSolarOnAcIn1: sys.pvOnAcIn1.power.valid - property bool hasAcSolarOnAcIn2: sys.pvOnAcIn2.power.valid - property bool hasAcSolarOnIn: hasAcSolarOnAcIn1 || hasAcSolarOnAcIn2 - property bool hasAcSolarOnOut: sys.pvOnAcOut.power.valid - property bool hasAcSolar: hasAcSolarOnIn || hasAcSolarOnOut - property bool hasDcSolar: sys.pvCharger.power.valid - property bool hasDcAndAcSolar: hasAcSolar && hasDcSolar - - title: qsTr("Overview") - - OverviewBox { - id: acInBox - - width: 148 - height: showStatusBar ? 100 : 120 - title: getAcSourceName(sys.acSource) -////// GuiMods — DarkMode - titleColor: !darkMode ? "#E74c3c" : "#73261E" - color: !darkMode ? "#C0392B" : "#601C15" - - anchors { - top: multi.top - left: parent.left; leftMargin: 10 - } - - values: OverviewAcValues { - connection: sys.acInput - } - - MbIcon { - iconId: getAcSourceIcon(sys.acSource) - anchors { - bottom: parent.bottom - left: parent.left; leftMargin: 2 - } - opacity: 0.5 - } - } - - Multi { - id: multi - anchors { - horizontalCenter: parent.horizontalCenter - top: parent.top; topMargin: 5 - } - } - - OverviewBox { - id: acLoadBox - title: qsTr("AC Loads") -////// GuiMods — DarkMode - color: !darkMode ? "#27AE60" : "#135730" - titleColor: !darkMode ? "#2ECC71" : "#176638" - width: 148 - height: showStatusBar ? 100 : 120 - - anchors { - right: parent.right; rightMargin: 10 - top: multi.top - } - - values: OverviewAcValues { - connection: sys.acLoad - } - } - - Battery { - id: battery - - soc: sys.battery.soc.valid ? sys.battery.soc.value : 0 - - anchors { - bottom: parent.bottom; bottomMargin: 5; - left: parent.left; leftMargin: 10 - } - values: Column { - width: parent.width - - TileText { - // Use value here instead of format() because format adds the unit to the number and we - // show the percentage symbol in a separated smaller text. - text: sys.battery.soc.value === undefined ? "--" : sys.battery.soc.value.toFixed(0) - font.pixelSize: 40 - - Text { - anchors { - bottom: parent.bottom; bottomMargin: 9 - horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: parent.paintedWidth / 2 + 5 - } - visible: sys.battery.soc.valid - text: "%" - color: "white" - font.bold: true - font.pixelSize: 12 - } - } - TileText { - text: sys.battery.power.format(0) - } - TileText { - text: sys.battery.voltage.format(1) + " " + sys.battery.current.format(1) - } - } - } - - OverviewBox { - id: dcSystemBox - width: 105 - height: 45 - visible: sys.dcSystem.power.valid - title: qsTr("DC Power") - - anchors { - horizontalCenter: multi.horizontalCenter - bottom: parent.bottom; bottomMargin: 5 - } - - values: TileText { - anchors.centerIn: parent - text: sys.dcSystem.power.format(0) - } - } - - OverviewSolarCharger { - id: blueSolarCharger - - height: hasDcAndAcSolar ? 65 : 114 - width: 148 - title: qsTr("PV Charger") - showChargerIcon: !hasDcAndAcSolar - visible: hasDcSolar || hasDcAndAcSolar - - anchors { - right: root.right; rightMargin: 10 - bottom: root.bottom; bottomMargin: 5; - } - - values: TileText { - y: 5 - text: sys.pvCharger.power.format(0) - font.pixelSize: 20 - } - } - - OverviewSolarInverter { - id: pvInverter - height: hasDcAndAcSolar ? 65 : 115 - width: 148 - title: qsTr("PV Inverter") - showInverterIcon: !hasDcAndAcSolar - visible: hasAcSolar - - anchors { - right: root.right; rightMargin: 10; - bottom: root.bottom; bottomMargin: hasDcAndAcSolar ? 75 : 5 - } - - OverviewAcValues { - connection: hasAcSolarOnOut ? sys.pvOnAcOut : hasAcSolarOnAcIn1 ? sys.pvOnAcIn1 : sys.pvOnAcIn2 - visible: !coupledPvAc.visible - } - - TileText { - id: coupledPvAc - - property double pvInverterOnAcOut: sys.pvOnAcOut.power.valid ? sys.pvOnAcOut.power.value : 0 - property double pvInverterOnAcIn1: sys.pvOnAcIn1.power.valid ? sys.pvOnAcIn1.power.value : 0 - property double pvInverterOnAcIn2: sys.pvOnAcIn2.power.valid ? sys.pvOnAcIn2.power.value : 0 - - y: 5 - text: (pvInverterOnAcOut + pvInverterOnAcIn1 + pvInverterOnAcIn2).toFixed(0) + "W" - font.pixelSize: hasDcAndAcSolar ? 20 : 25 - visible: hasDcAndAcSolar || (hasAcSolarOnIn && hasAcSolarOnOut) || (hasAcSolarOnAcIn1 && hasAcSolarOnAcIn2) - } - } - - OverviewEssReason { - anchors { - bottom: parent.bottom; bottomMargin: dcSystemBox.visible ? battery.height + 15 : 5 - horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: dcSystemBox.visible ? -(root.width / 2 - battery.width / 2 - 10) : 0 - } - } - - OverviewConnection { - id: acInToMulti - ballCount: 2 - path: straight - active: root.active - value: flow(sys.acInput ? sys.acInput.power : 0) - - anchors { - left: acInBox.right; leftMargin: -10; top: multi.verticalCenter; - right: multi.left; rightMargin: -10; bottom: multi.verticalCenter - } - } - - OverviewConnection { - id: multiToAcLoads - ballCount: 2 - path: straight - active: root.active - value: flow(sys.acLoad.power) - - anchors { - left: multi.right; leftMargin: -10; - top: multi.verticalCenter - right: acLoadBox.left; rightMargin: -10 - bottom: multi.verticalCenter - } - } - - OverviewConnection { - id: pvInverterToMulti - - property int hasDcAndAcFlow: Utils.sign(noNoise(sys.pvOnAcOut.power) + noNoise(sys.pvOnAcIn1.power) + noNoise(sys.pvOnAcIn2.power)) - - ballCount: 4 - path: corner - active: root.active && hasAcSolar - value: hasDcAndAcSolar ? hasDcAndAcFlow : flow(sys.pvOnAcOut.power) - - anchors { - left: pvInverter.left; leftMargin: 8 - top: pvInverter.verticalCenter; topMargin: hasDcAndAcSolar ? 1 : 0 - right: multi.horizontalCenter; rightMargin: -20 - bottom: multi.bottom; bottomMargin: 10 - } - } - - // invisible anchor point to connect the chargers to the battery - Item { - id: dcConnect - anchors { - left: multi.horizontalCenter; leftMargin: hasAcSolar ? -20 : 0 - bottom: dcSystemBox.top; bottomMargin: 10 - } - } - - OverviewConnection { - id: multiToDcConnect - ballCount: 3 - path: straight - active: root.active - value: -flow(sys.vebusDc.power); - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: dcConnect.left - bottom: multi.bottom; bottomMargin: 10 - } - } - - OverviewConnection { - id: blueSolarChargerDcConnect - ballCount: 3 - path: straight - active: root.active && hasDcSolar - value: -flow(sys.pvCharger.power) - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: blueSolarCharger.left; rightMargin: -8 - bottom: dcConnect.top; - } - } - - OverviewConnection { - id: chargersToBattery - ballCount: 3 - path: straight - active: root.active - value: Utils.sign(noNoise(sys.pvCharger.power) + noNoise(sys.vebusDc.power)) - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: battery.right; rightMargin: 10 - bottom: dcConnect.top - } - } - - OverviewConnection { - id: batteryToDcSystem - ballCount: 2 - path: straight - active: root.active && sys.dcSystem.power.valid - value: flow(sys.dcSystem.power) - - anchors { - left: battery.right; leftMargin: -10 - top: dcSystemBox.verticalCenter; - right: dcSystemBox.left; rightMargin: -10 - bottom: dcSystemBox.verticalCenter - } - } -} diff --git a/FileSets/v3.01/OverviewHub.qml.orig b/FileSets/v3.01/OverviewHub.qml.orig deleted file mode 100644 index 4418c508..00000000 --- a/FileSets/v3.01/OverviewHub.qml.orig +++ /dev/null @@ -1,309 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -OverviewPage { - id: root - - property variant sys: theSystem - property bool hasAcSolarOnAcIn1: sys.pvOnAcIn1.power.valid - property bool hasAcSolarOnAcIn2: sys.pvOnAcIn2.power.valid - property bool hasAcSolarOnIn: hasAcSolarOnAcIn1 || hasAcSolarOnAcIn2 - property bool hasAcSolarOnOut: sys.pvOnAcOut.power.valid - property bool hasAcSolar: hasAcSolarOnIn || hasAcSolarOnOut - property bool hasDcSolar: sys.pvCharger.power.valid - property bool hasDcAndAcSolar: hasAcSolar && hasDcSolar - - title: qsTr("Overview") - - OverviewBox { - id: acInBox - - width: 148 - height: showStatusBar ? 100 : 120 - title: getAcSourceName(sys.acSource) - titleColor: "#E74c3c" - color: "#C0392B" - - anchors { - top: multi.top - left: parent.left; leftMargin: 10 - } - - values: OverviewAcValues { - connection: sys.acInput - } - - MbIcon { - iconId: getAcSourceIcon(sys.acSource) - anchors { - bottom: parent.bottom - left: parent.left; leftMargin: 2 - } - opacity: 0.5 - } - } - - Multi { - id: multi - anchors { - horizontalCenter: parent.horizontalCenter - top: parent.top; topMargin: 5 - } - } - - OverviewBox { - id: acLoadBox - title: qsTr("AC Loads") - color: "#27AE60" - titleColor: "#2ECC71" - width: 148 - height: showStatusBar ? 100 : 120 - - anchors { - right: parent.right; rightMargin: 10 - top: multi.top - } - - values: OverviewAcValues { - connection: sys.acLoad - } - } - - Battery { - id: battery - - soc: sys.battery.soc.valid ? sys.battery.soc.value : 0 - - anchors { - bottom: parent.bottom; bottomMargin: 5; - left: parent.left; leftMargin: 10 - } - values: Column { - width: parent.width - - TileText { - // Use value here instead of format() because format adds the unit to the number and we - // show the percentage symbol in a separated smaller text. - text: sys.battery.soc.value === undefined ? "--" : sys.battery.soc.value.toFixed(0) - font.pixelSize: 40 - - Text { - anchors { - bottom: parent.bottom; bottomMargin: 9 - horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: parent.paintedWidth / 2 + 5 - } - visible: sys.battery.soc.valid - text: "%" - color: "white" - font.bold: true - font.pixelSize: 12 - } - } - TileText { - text: sys.battery.power.format(0) - } - TileText { - text: sys.battery.voltage.format(1) + " " + sys.battery.current.format(1) - } - } - } - - OverviewBox { - id: dcSystemBox - width: 105 - height: 45 - visible: sys.dcSystem.power.valid - title: qsTr("DC Power") - - anchors { - horizontalCenter: multi.horizontalCenter - bottom: parent.bottom; bottomMargin: 5 - } - - values: TileText { - anchors.centerIn: parent - text: sys.dcSystem.power.format(0) - } - } - - OverviewSolarCharger { - id: blueSolarCharger - - height: hasDcAndAcSolar ? 65 : 114 - width: 148 - title: qsTr("PV Charger") - showChargerIcon: !hasDcAndAcSolar - visible: hasDcSolar || hasDcAndAcSolar - - anchors { - right: root.right; rightMargin: 10 - bottom: root.bottom; bottomMargin: 5; - } - - values: TileText { - y: 5 - text: sys.pvCharger.power.format(0) - font.pixelSize: 20 - } - } - - OverviewSolarInverter { - id: pvInverter - height: hasDcAndAcSolar ? 65 : 115 - width: 148 - title: qsTr("PV Inverter") - showInverterIcon: !hasDcAndAcSolar - visible: hasAcSolar - - anchors { - right: root.right; rightMargin: 10; - bottom: root.bottom; bottomMargin: hasDcAndAcSolar ? 75 : 5 - } - - OverviewAcValues { - connection: hasAcSolarOnOut ? sys.pvOnAcOut : hasAcSolarOnAcIn1 ? sys.pvOnAcIn1 : sys.pvOnAcIn2 - visible: !coupledPvAc.visible - } - - TileText { - id: coupledPvAc - - property double pvInverterOnAcOut: sys.pvOnAcOut.power.valid ? sys.pvOnAcOut.power.value : 0 - property double pvInverterOnAcIn1: sys.pvOnAcIn1.power.valid ? sys.pvOnAcIn1.power.value : 0 - property double pvInverterOnAcIn2: sys.pvOnAcIn2.power.valid ? sys.pvOnAcIn2.power.value : 0 - - y: 5 - text: (pvInverterOnAcOut + pvInverterOnAcIn1 + pvInverterOnAcIn2).toFixed(0) + "W" - font.pixelSize: hasDcAndAcSolar ? 20 : 25 - visible: hasDcAndAcSolar || (hasAcSolarOnIn && hasAcSolarOnOut) || (hasAcSolarOnAcIn1 && hasAcSolarOnAcIn2) - } - } - - OverviewEssReason { - anchors { - bottom: parent.bottom; bottomMargin: dcSystemBox.visible ? battery.height + 15 : 5 - horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: dcSystemBox.visible ? -(root.width / 2 - battery.width / 2 - 10) : 0 - } - } - - OverviewConnection { - id: acInToMulti - ballCount: 2 - path: straight - active: root.active - value: flow(sys.acInput ? sys.acInput.power : 0) - - anchors { - left: acInBox.right; leftMargin: -10; top: multi.verticalCenter; - right: multi.left; rightMargin: -10; bottom: multi.verticalCenter - } - } - - OverviewConnection { - id: multiToAcLoads - ballCount: 2 - path: straight - active: root.active - value: flow(sys.acLoad.power) - - anchors { - left: multi.right; leftMargin: -10; - top: multi.verticalCenter - right: acLoadBox.left; rightMargin: -10 - bottom: multi.verticalCenter - } - } - - OverviewConnection { - id: pvInverterToMulti - - property int hasDcAndAcFlow: Utils.sign(noNoise(sys.pvOnAcOut.power) + noNoise(sys.pvOnAcIn1.power) + noNoise(sys.pvOnAcIn2.power)) - - ballCount: 4 - path: corner - active: root.active && hasAcSolar - value: hasDcAndAcSolar ? hasDcAndAcFlow : flow(sys.pvOnAcOut.power) - - anchors { - left: pvInverter.left; leftMargin: 8 - top: pvInverter.verticalCenter; topMargin: hasDcAndAcSolar ? 1 : 0 - right: multi.horizontalCenter; rightMargin: -20 - bottom: multi.bottom; bottomMargin: 10 - } - } - - // invisible anchor point to connect the chargers to the battery - Item { - id: dcConnect - anchors { - left: multi.horizontalCenter; leftMargin: hasAcSolar ? -20 : 0 - bottom: dcSystemBox.top; bottomMargin: 10 - } - } - - OverviewConnection { - id: multiToDcConnect - ballCount: 3 - path: straight - active: root.active - value: -flow(sys.vebusDc.power); - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: dcConnect.left - bottom: multi.bottom; bottomMargin: 10 - } - } - - OverviewConnection { - id: blueSolarChargerDcConnect - ballCount: 3 - path: straight - active: root.active && hasDcSolar - value: -flow(sys.pvCharger.power) - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: blueSolarCharger.left; rightMargin: -8 - bottom: dcConnect.top; - } - } - - OverviewConnection { - id: chargersToBattery - ballCount: 3 - path: straight - active: root.active - value: Utils.sign(noNoise(sys.pvCharger.power) + noNoise(sys.vebusDc.power)) - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: battery.right; rightMargin: 10 - bottom: dcConnect.top - } - } - - OverviewConnection { - id: batteryToDcSystem - ballCount: 2 - path: straight - active: root.active && sys.dcSystem.power.valid - value: flow(sys.dcSystem.power) - - anchors { - left: battery.right; leftMargin: -10 - top: dcSystemBox.verticalCenter; - right: dcSystemBox.left; rightMargin: -10 - bottom: dcSystemBox.verticalCenter - } - } -} diff --git a/FileSets/v3.01/OverviewHubEnhanced.qml b/FileSets/v3.01/OverviewHubEnhanced.qml deleted file mode 100644 index e703e4da..00000000 --- a/FileSets/v3.01/OverviewHubEnhanced.qml +++ /dev/null @@ -1,1508 +0,0 @@ -////// MODIFIED to show: -////// tanks in a row along bottom -////// PV voltage and current and DC power current (up to 2 MPPTs with tanks and temps or 3 without) -////// PV inverter power (up to 2 with tanks and temps or 3 without) -////// voltage, current, frequency in AC tiles (plus current limit for AC input) -////// time of day -////// current in DC Loads -////// remaining time in Battery tile -////// bar graphs on AC in/out and Multi -////// detail pages for all tiles -////// bar gauge on PV Charger tile -////// add support for VE.Direct inverters - -import QtQuick 1.1 -import "utils.js" as Utils -////// ADDED to show tanks -import com.victron.velib 1.0 -import "timeToGo.js" as TTG -import "enhancedFormat.js" as EnhFmt - -OverviewPage { - id: root - - property variant sys: theSystem - - property string systemPrefix: "com.victronenergy.system" - property string guiModsPrefix: "com.victronenergy.settings/Settings/GuiMods" - -////// GuiMods — DarkMode - property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } - property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 - - VBusItem { id: vebusService; bind: Utils.path(systemPrefix, "/VebusService") } - property bool isMulti: vebusService.valid - property string veDirectInverterService: "" - property string inverterService: vebusService.valid ? vebusService.value : veDirectInverterService - - VBusItem { id: replaceAcInItem; bind: Utils.path(guiModsPrefix, "/ReplaceInactiveAcIn") } - property bool hasAlternator: sys.alternator.power.valid - property bool replaceAcIn: replaceAcInItem.valid && replaceAcInItem.value == 1 && hasAlternator && (sys.acSource == 0 || sys.acSource == 240) - property bool showAcInput: ((isMulti || sys.acInput.power.valid) && ! replaceAcIn) || showAllTiles - property bool showAlternator: !showAcInput && hasAlternator - property double alternatorFlow: showAlternator ? noNoise (sys.alternator.power) : 0 - property bool showAcLoads: isMulti || sys.acLoad.power.valid || veDirectInverterService != "" - property bool showDcSystem: (hasDcSystemItem.valid && hasDcSystemItem.value > 0) || showAllTiles - property bool hasInverter: false - property bool showInverter: hasInverter || inverterService != "" || showAllTiles - - property bool hasAcSolarOnAcIn1: sys.pvOnAcIn1.power.valid - property bool hasAcSolarOnAcIn2: sys.pvOnAcIn2.power.valid - property bool hasAcSolarOnIn: hasAcSolarOnAcIn1 || hasAcSolarOnAcIn2 - property bool hasAcSolarOnOut: sys.pvOnAcOut.power.valid - property bool hasAcSolar: hasAcSolarOnIn || hasAcSolarOnOut - property bool hasDcSolar: sys.pvCharger.power.valid - property bool hasDcAndAcSolar: hasAcSolar && hasDcSolar - property bool showDcAndAcSolar: hasDcAndAcSolar || showAllTiles - property bool showDcSolar: hasDcSolar || showAllTiles - property bool showAcSolar: hasAcSolar || showAllTiles -////// ADDED to show tanks - property int bottomOffset: 45 - property string settingsBindPreffix: "com.victronenergy.settings" - property string pumpBindPreffix: "com.victronenergy.pump.startstop0" - property int numberOfTemps: 0 -//////// added/modified for control show/hide gauges, tanks and temps from menus - property int tankCount: showTanksEnable ? tankModel.rowCount : 0 - property int tempCount: showTempsEnable ? numberOfTemps : 0 - property int tankTempCount: tankCount + tempCount - property bool showTanks: showTanksEnable ? showStatusBar ? false : tankCount > 0 ? true : false : false - property bool showTemps: showTempsEnable ? showStatusBar ? false : tempCount > 0 ? true : false : false - property bool showTanksTemps: showTanks || showTemps - property int compactThreshold: 45 // height below this will be compacted vertically - property int batteryHeight: 91 - property bool compact: showTanks && showTemps && tankTempCount > 4 - property int tanksHeight: compact ? 22 : 45 - - property int leftTileCount: (showAcInput ? 1 : 0) + (showAlternator ? 1 : 0) + (showAlternator ? 1 : 0) - -//////// add for PV CHARGER voltage and current - property string pvChargerPrefix1: "" - property string pvChargerPrefix2: "" - property string pvChargerPrefix3: "" - property string pvChargerPrefix4: "" - property string pvChargerPrefix5: "" - property string pvChargerPrefix6: "" - property string pvChargerPrefix7: "" - property int numberOfPvChargers: 0 - property int pvChargerRows: showTanksTemps ? 4 : 7 - property int pvRowsPerCharger: Math.max ( 1, Math.min (pvChargerRows / numberOfPvChargers, 3)) - property bool pvChargerCompact: pvRowsPerCharger < 3 ? true : false - property bool pvShowDetails: pvRowsPerCharger >= 2 ? true : false - -//////// add for PV INVERTER power - property string pvInverterPrefix1: "" - property string pvInverterPrefix2: "" - property string pvInverterPrefix3: "" - property int numberOfPvInverters: 0 - -//////// add for alternator - alternator replaces AC in if AC in is not present - property string alternatorPrefix1: "" - property string alternatorPrefix2: "" - property int numberOfAlternators: 0 - VBusItem { id: alternatorName1; bind: Utils.path(alternatorPrefix1, "/CustomName") } - VBusItem { id: alternatorPower1; bind: Utils.path(alternatorPrefix1, "/Dc/0/Power") } - VBusItem { id: alternatorVoltage1; bind: Utils.path(alternatorPrefix1, "/Dc/0/Voltage") } - VBusItem { id: alternatorCurrent1; bind: Utils.path(alternatorPrefix1, "/Dc/0/Current") } - VBusItem { id: alternatorName2; bind: Utils.path(alternatorPrefix2, "/CustomName") } - VBusItem { id: alternatorPower2; bind: Utils.path(alternatorPrefix2, "/Dc/0/Power") } - -//////// added for control show/hide gauges, tanks and temps from menus - VBusItem { id: showGaugesItem; bind: Utils.path(guiModsPrefix, "/ShowGauges") } - property bool showGauges: showGaugesItem.valid ? showGaugesItem.value === 1 ? true : false : false - VBusItem { id: showTanksItem; bind: Utils.path(guiModsPrefix, "/ShowEnhancedFlowOverviewTanks") } - property bool showTanksEnable: showTanksItem.valid ? showTanksItem.value === 1 ? true : false : false - VBusItem { id: showTempsItem; bind: Utils.path(guiModsPrefix, "/ShowEnhancedFlowOverviewTemps") } - property bool showTempsEnable: showTempsItem.valid ? showTempsItem.value === 1 ? true : false : false - -//////// added to show/dim tiles - VBusItem { id: showInactiveTilesItem; bind: Utils.path(guiModsPrefix, "/ShowInactiveFlowTiles") } - property real disabledTileOpacity: (showInactiveTiles && showInactiveTilesItem.value === 1) ? 0.3 : 1 - property bool showInactiveTiles: showInactiveTilesItem.valid && showInactiveTilesItem.value >= 1 - - VBusItem { id: showBatteryTempItem; bind: Utils.path(guiModsPrefix, "/ShowBatteryTempOnFlows") } - property bool showBatteryTemp: showBatteryTempItem.valid && showBatteryTempItem.value == 1 - - // for debug, ignore validity checks so all tiles and their flow lines will show - property bool showAllTiles: showInactiveTilesItem.valid && showInactiveTilesItem.value == 3 - -//////// added to control time display - VBusItem { id: timeFormatItem; bind: Utils.path(guiModsPrefix, "/TimeFormat") } - property string timeFormat: getTimeFormat () - - function getTimeFormat () - { - if (!timeFormatItem.valid || timeFormatItem.value === 0) - return "" - else if (timeFormatItem.value === 2) - return "h:mm ap" - else - return "hh:mm" - } - -//////// add to display individual PV charger power - VBusItem { id: pvName1; bind: Utils.path(pvChargerPrefix1, "/CustomName") } - VBusItem { id: pvPower1; bind: Utils.path(pvChargerPrefix1, "/Yield/Power") } - VBusItem { id: pvVoltage1; bind: Utils.path(pvChargerPrefix1, "/Pv/V") } - VBusItem { id: pvCurrent1; bind: Utils.path(pvChargerPrefix1, "/Pv/I") } - VBusItem { id: pv1NrTrackers; bind: Utils.path(pvChargerPrefix1, "/NrOfTrackers") } - VBusItem { id: pvName2; bind: Utils.path(pvChargerPrefix2, "/CustomName") } - VBusItem { id: pvPower2; bind: Utils.path(pvChargerPrefix2, "/Yield/Power") } - VBusItem { id: pvVoltage2; bind: Utils.path(pvChargerPrefix2, "/Pv/V") } - VBusItem { id: pvCurrent2; bind: Utils.path(pvChargerPrefix2, "/Pv/I") } - VBusItem { id: pv2NrTrackers; bind: Utils.path(pvChargerPrefix2, "/NrOfTrackers") } - VBusItem { id: pvName3; bind: Utils.path(pvChargerPrefix3, "/CustomName") } - VBusItem { id: pvPower3; bind: Utils.path(pvChargerPrefix3, "/Yield/Power") } - VBusItem { id: pvVoltage3; bind: Utils.path(pvChargerPrefix3, "/Pv/V") } - VBusItem { id: pvCurrent3; bind: Utils.path(pvChargerPrefix3, "/Pv/I") } - VBusItem { id: pv3NrTrackers; bind: Utils.path(pvChargerPrefix3, "/NrOfTrackers") } - VBusItem { id: pvName4; bind: Utils.path(pvChargerPrefix4, "/CustomName") } - VBusItem { id: pvPower4; bind: Utils.path(pvChargerPrefix4, "/Yield/Power") } - VBusItem { id: pvName5; bind: Utils.path(pvChargerPrefix5, "/CustomName") } - VBusItem { id: pvPower5; bind: Utils.path(pvChargerPrefix5, "/Yield/Power") } - VBusItem { id: pvName6; bind: Utils.path(pvChargerPrefix6, "/CustomName") } - VBusItem { id: pvPower6; bind: Utils.path(pvChargerPrefix6, "/Yield/Power") } - VBusItem { id: pvName7; bind: Utils.path(pvChargerPrefix7, "/CustomName") } - VBusItem { id: pvPower7; bind: Utils.path(pvChargerPrefix7, "/Yield/Power") } - - VBusItem { id: timeToGo; bind: Utils.path("com.victronenergy.system","/Dc/Battery/TimeToGo") } - -//////// add to display PV Inverter power - VBusItem { id: pvInverterPower1; bind: Utils.path(pvInverterPrefix1, "/Ac/Power") } - VBusItem { id: pvInverterL1Power1; bind: Utils.path(pvInverterPrefix1, "/Ac/L1/Power") } - VBusItem { id: pvInverterL2Power1; bind: Utils.path(pvInverterPrefix1, "/Ac/L2/Power") } - VBusItem { id: pvInverterL3Power1; bind: Utils.path(pvInverterPrefix1, "/Ac/L3/Power") } - VBusItem { id: pvInverterName1; bind: Utils.path(pvInverterPrefix1, "/CustomName") } - VBusItem { id: pvInverterPower2; bind: Utils.path(pvInverterPrefix2, "/Ac/Power") } - VBusItem { id: pvInverterName2; bind: Utils.path(pvInverterPrefix2, "/CustomName") } - VBusItem { id: pvInverterPower3; bind: Utils.path(pvInverterPrefix3, "/Ac/Power") } - VBusItem { id: pvInverterName3; bind: Utils.path(pvInverterPrefix3, "/CustomName") } - -//////// add to display AC input ignored - VBusItem { id: ignoreAcInput1; bind: Utils.path(inverterService, "/Ac/State/IgnoreAcIn1") } - VBusItem { id: ignoreAcInput2; bind: Utils.path(inverterService, "/Ac/State/IgnoreAcIn2") } - VBusItem { id: acActiveInput; bind: Utils.path(inverterService, "/Ac/ActiveIn/ActiveInput") } - - VBusItem { id: hasDcSystemItem; bind: "com.victronenergy.settings/Settings/SystemSetup/HasDcSystem" } - - //Component.onCompleted: { discoverServices(); showHelp () } - onActiveChanged: - { - if (root.active) - { - discoverServices() - showHelp () - } - } - - title: qsTr("Simple Overview") - - OverviewBox { - id: acInBox -////// GuiMods — DarkMode - titleColor: !darkMode ? "#E74c3c" : "#73261E" - color: !darkMode ? "#C0392B" : "#601C15" - opacity: showAcInput ? 1 : disabledTileOpacity - visible: showAcInput || showInactiveTiles - width: 148 - height: showStatusBar ? 100 : 120 - title: - { - // input 1 is active - if (acActiveInput.value == 0) - { - if (ignoreAcInput1.valid && ignoreAcInput1.value == 1) - return qsTr ("AC In 1 Ignored") - else - return getAcSourceName(sys.acSource) - } - // input 2 is active - else if (acActiveInput.value == 1) - { - if (ignoreAcInput2.valid && ignoreAcInput2.value == 1) - return qsTr ("AC In 2 Ignored") - else - return getAcSourceName(sys.acSource) - } - else - return "no input" - } - anchors { - top: multi.top - left: parent.left; leftMargin: 10 - } - - values: OverviewAcValuesEnhanced { - connection: sys.acInput - } - - MbIcon { - iconId: getAcSourceIcon(sys.acSource) - anchors { - bottom: parent.bottom - left: parent.left; leftMargin: 2 - } - opacity: 0.5 - } -////// add power bar graph - PowerGauge - { - id: acInBar - width: parent.width - height: 12 - anchors - { - top: parent.top; topMargin: 16 - horizontalCenter: parent.horizontalCenter - } - connection: sys.acInput - useInputCurrentLimit: true - maxForwardPowerParameter: "" - maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxFeedInPower" - visible: showGauges && showAcInput - } - DetailTarget { id: acInputTarget; detailsPage: "DetailAcInput.qml" } - } - - - //// add alternator if AC input not present - OverviewBox { - id: alternatorBox - title: qsTr ("Alternator") - color: !darkMode ? "#157894" : "#0a3c4a" - titleColor: !darkMode ? "#419FB9" : "#204f5c" - opacity: showAlternator ? 1 : disabledTileOpacity - visible: showAlternator || showInactiveTiles && ! acInBox.visible - width: 148 - height: showStatusBar ? 100 : 120 - anchors.fill: acInBox - values: Column - { - width: parent.width - TileText - { - text: " " - font.pixelSize: 6 - } - TileText - { - text: EnhFmt.formatVBusItem (sys.alternator.power, "W") - font.pixelSize: 19 - } - TileText - { - text: alternatorName1.valid ? alternatorName1.value : "-" - visible: showAlternator && numberOfAlternators >= 1 - } - TileText - { - text: EnhFmt.formatVBusItem (alternatorPower1, "W") - font.pixelSize: 15 - visible: showAlternator && numberOfAlternators > 1 - } - TileText { - text: EnhFmt.formatVBusItem (alternatorVoltage1, "V") - font.pixelSize: 15 - visible: showAlternator && numberOfAlternators == 1 - } - TileText { - text: EnhFmt.formatVBusItem (alternatorCurrent1, "A") - font.pixelSize: 15 - visible: showAlternator && numberOfAlternators == 1 - } - TileText - { - text: alternatorName2.valid ? alternatorName2.value : "-" - visible: showAlternator && numberOfAlternators >= 2 - } - TileText - { - text: EnhFmt.formatVBusItem (alternatorPower1, "W") - font.pixelSize: 15 - visible: showAlternator && numberOfAlternators >= 2 - } - } - - PowerGauge - { - id: alternatorBar - width: parent.width - height: 12 - anchors - { - top: parent.top; topMargin: 16 - horizontalCenter: parent.horizontalCenter - } - connection: sys.alternator - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxAlternatorPower" - visible: showGauges && showAlternator - } - DetailTarget { id: alternatorTarget; detailsPage: "DetailAlternator.qml" } - } - - MultiEnhanced { - id: multi - anchors { - horizontalCenter: parent.horizontalCenter - top: parent.top; topMargin: 3 - } - opacity: showInverter ? 1 : disabledTileOpacity - visible: showInverter || showInactiveTiles - inverterService: root.inverterService -////// add power bar graph - PowerGaugeMulti - { - id: multiBar - width: multi.width - height: 12 - anchors - { - top: parent.top; topMargin: 23 - horizontalCenter: parent.horizontalCenter - } - inverterService: root.inverterService - visible: showGauges && showInverter - } - DetailTarget { id: multiTarget; detailsPage: "DetailInverter.qml"; width: 60; height: 60 } - } - -////// ADDED to show time inside inverter icon - Timer { - id: wallClock - running: timeFormat != "" - repeat: true - interval: 1000 - triggeredOnStart: true - onTriggered: time = Qt.formatDateTime(new Date(), timeFormat) - property string time - } - TileText - { - text: wallClock.time - font.pixelSize: 18 - color: showInverter || darkMode ? "white" : "black" - anchors - { - top: multi.top; topMargin: 96 - horizontalCenter: multi.horizontalCenter - } - visible: wallClock.running - } - - OverviewBox { - id: acLoadBox - visible: showAcLoads || showInactiveTiles - opacity: showAcLoads ? 1 : disabledTileOpacity - title: qsTr("AC Loads") -////// GuiMods — DarkMode - color: !darkMode ? "#27AE60" : "#135730" - titleColor: !darkMode ? "#2ECC71" : "#176638" - width: 148 - height: showStatusBar ? 80 : 102 - - anchors { - right: parent.right; rightMargin: 10 - top: multi.top - } - - values: OverviewAcValuesEnhanced { - connection: sys.acLoad - } -////// add power bar graph - PowerGauge - { - id: acLoadBar - width: parent.width - height: 12 - anchors - { - top: parent.top; topMargin: 16 - horizontalCenter: parent.horizontalCenter - } - connection: sys.acLoad - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputMaxPower" - visible: showGauges && showAcLoads - } - DetailTarget { id: loadsOnOutputTarget; detailsPage: "DetailLoadsCombined.qml" } - } - - Battery { - id: battery - width: acInBox.width - soc: sys.battery.soc.valid ? sys.battery.soc.value : 0 -////// add battery current bar graph - PowerGaugeBattery - { - id: batteryBar - width: parent.width - height: 10 - anchors - { - top: parent.top; topMargin: 52 - horizontalCenter: parent.horizontalCenter - } - visible: showGauges - } - -////// MODIFIED to show tanks - height: batteryHeight + 5 - anchors { - bottom: parent.bottom; bottomMargin: showTanksTemps ? bottomOffset + 3 : 5; - left: parent.left; leftMargin: 10 - } - values: Column { - width: parent.width - - TileText { - text: sys.battery.soc.value === undefined ? "--" : sys.battery.soc.format (0) - font.pixelSize: 25 - } - TileText { - text: sys.battery.power.format(0) - } - TileText { - text: " " - font.pixelSize: 6 - } - TileText { - text: EnhFmt.formatVBusItem (sys.battery.voltage, "V ", 2) - + EnhFmt.formatVBusItem (sys.battery.current, "A") - } - TileText { - text: timeToGo.valid ? qsTr ("Remain: ") + TTG.formatTimeToGo (timeToGo) : qsTr (" ") - } - } - DetailTarget { id: batteryTarget; detailsPage: "DetailBattery.qml" } - } - - VBusItem { id: dcSystemNameItem; bind: Utils.path(settingsBindPreffix, "/Settings/GuiMods/CustomDcSystemName") } - - OverviewBox { - id: dcSystemBox -////// wider to make room for current - width: multi.width + 20 - height: 45 - opacity: showDcSystem ? 1 : disabledTileOpacity - visible: showDcSystem || showInactiveTiles - title: dcSystemNameItem.valid && dcSystemNameItem.value != "" ? dcSystemNameItem.value : qsTr ("DC System") - - anchors { - horizontalCenter: multi.horizontalCenter - horizontalCenterOffset: 2 -////// MODIFIED to show tanks - bottom: parent.bottom; bottomMargin: showTanksTemps ? bottomOffset + 3 : 5 - } - - values: - [ - TileText - { - width: parent.width - anchors - { - horizontalCenter: parent.horizontalCenter - bottom: parent.bottom; bottomMargin: 0 - } - ////// modified to show current - text: - { - if (showDcSystem) - { - var current = "" - if (sys.dcSystem.power.valid && sys.battery.voltage.valid) - current = " " + EnhFmt.formatValue (sys.dcSystem.power.value / sys.battery.voltage.value, "A") - return EnhFmt.formatVBusItem (sys.dcSystem.power) + current - } - else - return "--" - } - } - ] - PowerGauge - { - id: dcSystemGauge - width: parent.width - height: 8 - anchors - { - top: parent.top; topMargin: 19 - left: parent.left; leftMargin: 18 - right: parent.right - } - connection: sys.dcSystem - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/DcSystemMaxLoad" - maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/DcSystemMaxCharge" - showLabels: true - visible: showGauges && showDcSystem - - } - DetailTarget { id: dcSystemTarget; detailsPage: "DetailDcSystem.qml" } - } - - property int pvOffset1: 27 - property int pvRowSpacing: 16 - property int pvOffset2: pvOffset1 + pvRowSpacing * pvRowsPerCharger - property int pvOffset3: pvOffset2 + pvRowSpacing * pvRowsPerCharger - property int pvOffset4: pvOffset3 + pvRowSpacing * pvRowsPerCharger - property int pvOffset5: pvOffset4 + pvRowSpacing * pvRowsPerCharger - property int pvOffset6: pvOffset5 + pvRowSpacing * pvRowsPerCharger - property int pvOffset7: pvOffset6 + pvRowSpacing * pvRowsPerCharger - -////// replaced OverviewSolarCharger with OverviewBox - OverviewBox { - id: pvChargerBox - title: qsTr("PV Charger") -////// GuiMods — DarkMode - titleColor: !darkMode ? "#F4B350" : "#7A5928" - color: !darkMode ? "#F39C12" : "#794E09" - visible: hasDcSolar || showInactiveTiles - opacity: hasDcSolar ? 1 : disabledTileOpacity - -////// MODIFIED to show tanks & provide extra space if not - height: - { - var availableHeight = root.height - 3 - acLoadBox.height - 5 - (showTanksTemps ? bottomOffset + 3 : 5) - if (showDcAndAcSolar) - return ((availableHeight - 5) / 2) + 4 - else if (showDcSolar) - return availableHeight - else - return 0 - } - width: 148 - - anchors { - right: root.right; rightMargin: 10 - bottom: parent.bottom; bottomMargin: showTanksTemps ? bottomOffset + 3 : 5 - } - -////// moved sun icon here from OverviewSolarChager so it can be put below text, etc - MbIcon { - iconId: "overview-sun" - anchors { - bottom: parent.bottom - right: parent.right; rightMargin: 2 - } - opacity: 0.5 - visible: ! showDcAndAcSolar - } - -//////// modified to add power for individual PV charger info - values: - [ - TileText { - y: 8 - text: EnhFmt.formatVBusItem (sys.pvCharger.power) - font.pixelSize: 19 - }, - MarqueeEnhanced - { - y: pvOffset1 - id: pv1Name - // ofset left margin for this row if showing tanks/temps - width: - { - if (pvChargerCompact) - { - if (showTanksTemps) - return ((parent.width / 2) - 15) - else - return ((parent.width / 2) - 5) - } - else - return (parent.width - 10) - } - anchors.left: parent.left; anchors.leftMargin: (showTanksTemps && pvChargerCompact) ? 15 : 5 - height: 15 - text: pvName1.valid ? pvName1.value : "pv 1" - textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter - fontSize: 15 - Connections { target: scrollTimer; onTriggered: pv1Name.doScroll() } - scroll: false - visible: numberOfPvChargers >= 1 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset1 + (pvChargerCompact ? 0 : pvRowSpacing) - text: EnhFmt.formatVBusItem (pvPower1, "W") - horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter - anchors.right: parent.right; anchors.rightMargin: 5 - font.pixelSize: 15 - visible: numberOfPvChargers >= 1 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset1 + pvRowSpacing * (pvChargerCompact ? 1 : 2) - text: - { - var voltageText, currentText - if (root.numberOfPvChargers < 1) - return " " - else - { - if (pv1NrTrackers.valid && pv1NrTrackers.value > 1) - return qsTr ("multiple trackers") - else if (pvVoltage1.valid) - voltageText = EnhFmt.formatVBusItem (pvVoltage1, "V") - else - voltageText = "??V" - if (pvCurrent1.valid) - currentText = EnhFmt.formatVBusItem (pvCurrent1, "A") - else if (pvPower1.valid) - currentText = EnhFmt.formatValue ((pvPower1.value / pvVoltage1.value), "A") - else - currentText = "??A" - return voltageText + " " + currentText - } - } - font.pixelSize: 15 - visible: pvShowDetails && numberOfPvChargers >= 1 - }, - MarqueeEnhanced - { - y: pvOffset2 - id: pv2Name - width: pvChargerCompact ? ((parent.width / 2) - 5) : parent.width - 10 - anchors.left: parent.left; anchors.leftMargin: 5 - height: 15 - text: pvName2.valid ? pvName2.value : "pv 2" - textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter - fontSize: 15 - Connections { target: scrollTimer; onTriggered: pv2Name.doScroll() } - scroll: false - visible: numberOfPvChargers >= 2 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset2 + (pvChargerCompact ? 0 : pvRowSpacing) - text: EnhFmt.formatVBusItem (pvPower2, "W") - horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter - anchors.right: parent.right; anchors.rightMargin: 5 - font.pixelSize: 15 - visible: numberOfPvChargers >= 2 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset2 + pvRowSpacing * (pvChargerCompact ? 1 : 2) - text: - { - var voltageText, currentText - if (root.numberOfPvChargers < 2) - return " " - else - { - if (pv2NrTrackers.valid && pv2NrTrackers.value > 1) - return qsTr ("multiple trackers") - else if (pvVoltage2.valid) - voltageText = EnhFmt.formatVBusItem (pvVoltage2, "V") - else - voltageText = "??V" - if (pvCurrent2.valid) - currentText = EnhFmt.formatVBusItem (pvCurrent2, "A") - else if (pvPower2.valid) - currentText = EnhFmt.formatValue ((pvPower2.value / pvVoltage2.value), "A") - else - currentText = "??A" - return voltageText + " " + currentText - } - } - font.pixelSize: 15 - visible: pvShowDetails && numberOfPvChargers >= 2 - }, - MarqueeEnhanced - { - y: pvOffset3 - id: pv3Name - width: pvChargerCompact ? ((parent.width / 2) - 5) : parent.width - 10 - anchors.left: parent.left; anchors.leftMargin: 5 - height: 15 - text: pvName3.valid ? pvName3.value : "pv 3" - textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter - fontSize: 15 - Connections { target: scrollTimer; onTriggered: pv3Name.doScroll() } - scroll: false - visible: numberOfPvChargers >= 3 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset3 + (pvChargerCompact ? 0 : pvRowSpacing) - text: EnhFmt.formatVBusItem (pvPower3, "W") - anchors.right: parent.right; anchors.rightMargin: 5 - horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter - font.pixelSize: 15 - visible: numberOfPvChargers >= 3 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset3 + pvRowSpacing * (pvChargerCompact ? 1 : 2) - text: - { - var voltageText, currentText - if (root.numberOfPvChargers < 3) - return " " - else - { - if (pv3NrTrackers.valid && pv3NrTrackers.value > 1) - return qsTr ("multiple trackers") - else if (pvVoltage3.valid) - voltageText = EnhFmt.formatVBusItem (pvVoltage3, "V") - else - voltageText = "??V" - if (pvCurrent3.valid) - currentText = EnhFmt.formatVBusItem (pvCurrent3, "A") - else if (pvPower3.valid) - currentText = EnhFmt.formatValue ((pvPower3.value / pvVoltage3.value), "A") - else - currentText = "??A" - return voltageText + " " + currentText - } - } - font.pixelSize: 15 - visible: pvShowDetails && numberOfPvChargers >= 2 - }, - MarqueeEnhanced - { - y: pvOffset4 - id: pv4Name - // ofset left margin for this row if NOT showing tanks/temps - width: - { - if (pvChargerCompact) - { - if (! showTanksTemps) - return ((parent.width / 2) - 15) - else - return ((parent.width / 2) - 5) - } - else - return (parent.width - 10) - } - anchors.left: parent.left; anchors.leftMargin: ( ! showTanksTemps && pvChargerCompact) ? 15 : 5 - height: 15 - text: pvName4.valid ? pvName4.value : "pv 4" - textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter - fontSize: 15 - Connections { target: scrollTimer; onTriggered: pv4Name.doScroll() } - scroll: false - visible: numberOfPvChargers >= 4 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset4 + (pvChargerCompact ? 0 : pvRowSpacing) - text: EnhFmt.formatVBusItem (pvPower4, "W") - anchors.right: parent.right; anchors.rightMargin: 5 - horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter - font.pixelSize: 15 - visible: numberOfPvChargers >= 4 && ! showDcAndAcSolar - }, - MarqueeEnhanced - { - y: pvOffset5 - id: pv5Name - width: pvChargerCompact ? ((parent.width / 2) - 5) : parent.width - 10 - anchors.left: parent.left; anchors.leftMargin: 5 - height: 15 - text: pvName5.valid ? pvName5.value : "pv 5" - textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter - fontSize: 15 - Connections { target: scrollTimer; onTriggered: pv5Name.doScroll() } - scroll: false - visible: numberOfPvChargers >= 5 && pvChargerRows >= 5 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset5 + (pvChargerCompact ? 0 : pvRowSpacing) - text: EnhFmt.formatVBusItem (pvPower5, "W") - anchors.right: parent.right; anchors.rightMargin: 5 - horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter - font.pixelSize: 15 - visible: numberOfPvChargers >= 5 && pvChargerRows >= 5 && ! showDcAndAcSolar - }, - MarqueeEnhanced - { - y: pvOffset6 - id: pv6Name - width: pvChargerCompact ? ((parent.width / 2) - 5) : parent.width - 10 - anchors.left: parent.left; anchors.leftMargin: 5 - height: 15 - text: pvName6.valid ? pvName6.value : "pv 6" - textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter - fontSize: 15 - Connections { target: scrollTimer; onTriggered: pv6Name.doScroll() } - scroll: false - visible: numberOfPvChargers >= 6 && pvChargerRows >= 6 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset6 + (pvChargerCompact ? 0 : pvRowSpacing) - text: EnhFmt.formatVBusItem (pvPower6, "W") - anchors.right: parent.right; anchors.rightMargin: 5 - horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter - font.pixelSize: 15 - visible: numberOfPvChargers >= 6 && pvChargerRows >= 6 && ! showDcAndAcSolar - }, - MarqueeEnhanced - { - y: pvOffset7 - id: pv7Name - width: pvChargerCompact ? ((parent.width / 2) - 5) : parent.width - 10 - anchors.left: parent.left; anchors.leftMargin: 5 - height: 15 - text: pvName7.valid ? pvName7.value : "pv 7" - textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter - fontSize: 15 - Connections { target: scrollTimer; onTriggered: pv6Name.doScroll() } - scroll: false - visible: numberOfPvChargers >= 7 && pvChargerRows >= 7 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset7 + (pvChargerCompact ? 0 : pvRowSpacing) - text: EnhFmt.formatVBusItem (pvPower7, "W") - anchors.right: parent.right; anchors.rightMargin: 5 - horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter - font.pixelSize: 15 - visible: numberOfPvChargers >= 7 && pvChargerRows >= 7 && ! showDcAndAcSolar - } - ] -////// add power bar graph - PowerGauge - { - id: pvChargerBar - width: parent.width - (showDcAndAcSolar && ! showTanksTemps ? 20 : 0) - height: 10 - anchors - { - top: parent.top; topMargin: 19 - right: parent.right; rightMargin: 0.5 - } - connection: sys.pvCharger - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvChargerMaxPower" - visible: showGauges && showDcSolar - } - DetailTarget { id: pvChargerTarget; detailsPage: "DetailPvCharger.qml" } - } - -////// replaced OverviewSolarInverter with OverviewBox - OverviewBox { - id: pvInverter - title: qsTr("PV Inverter") -////// GuiMods — DarkMode - titleColor: !darkMode ? "#F4B350" : "#7A5928" - color: !darkMode ? "#F39C12" : "#794E09" - visible: hasAcSolar || showInactiveTiles - opacity: hasAcSolar ? 1 : disabledTileOpacity - -////// MODIFIED to show tanks & provide extra space if not - height: - { - var availableHeight = root.height - 3 - acLoadBox.height -5 - availableHeight -= (showTanksTemps ? bottomOffset + 3 : 5) - if (showDcAndAcSolar) - availableHeight -= pvChargerBox.height + 5 - if (showAcSolar) - return availableHeight - else - return 0 - } - width: 148 - - anchors { - right: root.right; rightMargin: 10; - bottom: showDcAndAcSolar ? pvChargerBox.top : root.bottom - bottomMargin: showDcAndAcSolar ? 5 : showTanksTemps ? bottomOffset + 3 : 5 - } - - values: - [ - TileText { - id: coupledPvAc - - property double pvInverterOnAcOut: sys.pvOnAcOut.power.valid ? sys.pvOnAcOut.power.value : 0 - property double pvInverterOnAcIn1: sys.pvOnAcIn1.power.valid ? sys.pvOnAcIn1.power.value : 0 - property double pvInverterOnAcIn2: sys.pvOnAcIn2.power.valid ? sys.pvOnAcIn2.power.value : 0 - property bool powerValid: sys.pvOnAcOut.power.valid || sys.pvOnAcIn1.power.valid || sys.pvOnAcIn2.power.valid - - y: 10 - text: powerValid ? EnhFmt.formatValue (pvInverterOnAcOut + pvInverterOnAcIn1 + pvInverterOnAcIn2, "W") : "" - font.pixelSize: 19 - visible: showAcSolar - }, -//////// add individual PV inverter powers - TileText { - y: 31 - text: pvInverterName1.valid ? pvInverterName1.value : "-" - visible: !showDcAndAcSolar && numberOfPvInverters >= 2 - }, - TileText { - y: 47 - text: EnhFmt.formatVBusItem (pvInverterPower1, "W") - font.pixelSize: 15 - visible: !showDcAndAcSolar && numberOfPvInverters >= 2 - }, - TileText { - y: 63 - text: pvInverterName2.valid ? pvInverterName2.value : "-" - visible: !showDcAndAcSolar && numberOfPvInverters >= 2 - }, - TileText { - y: 77 - text: EnhFmt.formatVBusItem (pvInverterPower2, "W") - font.pixelSize: 15 - visible: !showDcAndAcSolar && numberOfPvInverters >= 2 - }, - TileText { - y: 93 - text: pvInverterName3.valid ? pvInverterName3.value : "-" - visible: !showDcAndAcSolar && numberOfPvInverters >=3 && ! showTanksTemps - }, - TileText { - y: 107 - text: EnhFmt.formatVBusItem (pvInverterPower3, "W") - font.pixelSize: 15 - visible: !showDcAndAcSolar && numberOfPvInverters >=3 && ! showTanksTemps - }, - TileText { - y: 31 - text: qsTr ("L1: ") + EnhFmt.formatVBusItem (pvInverterL1Power1, "W") - visible: !showDcAndAcSolar && numberOfPvInverters == 1 && pvInverterL1Power1.valid && (pvInverterL2Power1.valid || pvInverterL3Power1.valid) - }, - TileText { - y: 47 - text: qsTr ("L2: ") + EnhFmt.formatVBusItem (pvInverterL2Power1, "W") - visible: !showDcAndAcSolar && numberOfPvInverters == 1 && pvInverterL2Power1.valid - }, - TileText { - y: 63 - text: qsTr ("L3: ") + EnhFmt.formatVBusItem (pvInverterL3Power1, "W") - visible: !showDcAndAcSolar && numberOfPvInverters == 1 && pvInverterL3Power1.valid - } - ] -////// add power bar graph -////// only shows one of possibly 3 PV inverter locations !!!!!!!!!!!!!!!!!!!!! - PowerGauge - { - id: pvInverterBar - width: parent.width - height: 12 - anchors - { - top: parent.top; topMargin: 19 - horizontalCenter: parent.horizontalCenter - } - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvOnOutputMaxPower" - maxForwardPowerParameter2: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvOnGridMaxPower" - connection: sys.pvOnAcOut - connection2: sys.pvOnGrid - visible: showGauges && showAcSolar - } - DetailTarget { id: pvInverterTarget; detailsPage: "DetailPvInverter.qml" } - } - - OverviewConnection { - id: acInToMulti - visible: showAcInput - ballCount: 2 - path: straight - active: root.active && showAcInput && showInverter - value: flow(sys.acInput ? sys.acInput.power : 0) - - anchors { - left: acInBox.right; leftMargin: -10 - right: multi.left; rightMargin: -10; bottom: acInBox.bottom; bottomMargin: 25 - } - } - - OverviewConnection { - id: multiToAcLoads - ballCount: 2 - path: straight - active: root.active && ( showAcLoads && showInverter ) - value: flow(sys.acLoad.power) - - anchors { - left: multi.right; leftMargin: -10; - right: acLoadBox.left; rightMargin: -10 - bottom: acLoadBox.bottom; bottomMargin: 8 - } - } - - OverviewConnection { - id: pvInverterToMulti - ballCount: 3 - path: corner - active: root.active && showAcSolar && showInverter - value: Utils.sign(noNoise(sys.pvOnAcOut.power) + noNoise(sys.pvOnAcIn1.power) + noNoise(sys.pvOnAcIn2.power)) - - anchors { - left: pvInverter.left; leftMargin: 8 - top: pvInverter.verticalCenter; topMargin: showDcAndAcSolar ? 10 : 0 - right: multi.horizontalCenter; rightMargin: -20 - bottom: multi.bottom; bottomMargin: 10 - } - } - - // invisible anchor point to connect the chargers to the battery - Item { - id: dcConnect - anchors { - left: multi.horizontalCenter; leftMargin: showAcSolar ? -20 : 0 - bottom: dcSystemBox.top; bottomMargin: showDcAndAcSolar ? 7 : 10 - } - } - - OverviewConnection - { - id: dcBus2 - ballCount: 2 - path: straight - active: root.active && ( showInverter || showDcSolar ) - value: -Utils.sign (noNoise (sys.pvCharger.power) + noNoise (sys.vebusDc.power)) - startPointVisible: false - endPointVisible: false - - anchors { - right: dcConnect.left - top: dcConnect.top - - left: multi.left; leftMargin: -10 - bottom: dcConnect.top - } - } - - OverviewConnection - { - id: alternatorToDcBus2 - ballCount: 3 - path: corner - active: root.active && showAlternator - value: Utils.sign (alternatorFlow) - endPointVisible: false - anchors - { - left: alternatorBox.right; leftMargin: -10 - top: alternatorBox.bottom; topMargin: -15 - - right: dcBus2.left - bottom: dcBus2.bottom - } - } - - OverviewConnection { - id: multiToDcConnect - ballCount: showTanksTemps ? 2 : 4 - path: straight - active: root.active && showInverter - value: -flow(sys.vebusDc.power); - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: dcConnect.left - bottom: multi.bottom; bottomMargin: 10 - } - } - - OverviewConnection { - id: pvChargerBoxDcConnect - ballCount: 3 - path: straight - active: root.active && showDcSolar - value: -flow(sys.pvCharger.power) - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: pvChargerBox.left; rightMargin: -8 - bottom: dcConnect.top; - } - } - - OverviewConnection { - id: batteryToDcBus2 - ballCount: 1 - path: straight - active: root.active && ( showInverter || showDcSolar ) - value: Utils.sign(noNoise(sys.pvCharger.power) + noNoise(sys.vebusDc.power) + alternatorFlow) - startPointVisible: false - - anchors { - left: dcBus2.left - top: dcBus2.top - - right: battery.right; rightMargin: 10 - bottom: dcBus2.top - } - } - - OverviewConnection { - id: batteryToDcSystem - ballCount: 2 - path: straight - active: root.active && showDcSystem - value: flow(sys.dcSystem.power) - - anchors { - left: battery.right; leftMargin: -10 - top: dcSystemBox.verticalCenter; - right: dcSystemBox.left; rightMargin: -10 - bottom: dcSystemBox.verticalCenter - } - } -////// moved order so it covers connections -////// moved to under Multi - OverviewEssReason { - anchors { - top: multi.bottom; topMargin: 7 - horizontalCenter: parent.horizontalCenter - } - } - -////// ADDED to show tanks & temps - // Synchronise tank name text scroll start and PV Charger name scroll - Timer - { - id: scrollTimer - interval: 15000 - repeat: true - running: root.active - } - ListView - { - id: tanksColum - - visible: showTanks - width: compact ? root.width : root.width * tankCount / tankTempCount - property int tileWidth: width / Math.min (count, 5.2) - height: root.tanksHeight - anchors - { - bottom: root.bottom - left: root.left - } - - // flickable list if more than will fit across bottom of screen - interactive: count > 4 ? true : false - orientation: ListView.Horizontal - - model: TankModel { id: tankModel } - delegate: TileTankEnhanced { - // Without an intermediate assignment this will trigger a binding loop warning. - property variant theService: DBusServices.get(buddy.id) - service: theService - width: tanksColum.tileWidth - height: root.tanksHeight - pumpBindPrefix: root.pumpBindPreffix - compact: root.compact - Connections { - target: scrollTimer - onTriggered: doScroll() - } - } - Tile { - title: qsTr("TANKS") - anchors.fill: parent - values: TileText { - text: qsTr("") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - - ListView - { - id: tempsColumn - - visible: showTemps - width: compact ? root.width : root.width * tempCount / tankTempCount - property int tileWidth: width / Math.min (count, 5.2) - height: root.tanksHeight - anchors - { - bottom: root.bottom - bottomMargin: compact ? root.tanksHeight : 0 - right: root.right - } - - // make list flickable if more tiles than will fit completely - interactive: count > 4 ? true : false - orientation: ListView.Horizontal - - model: tempsModel - delegate: TileTemp - { - width: tempsColumn.tileWidth - height: tempsColumn.height - compact: root.compact - Connections - { - target: scrollTimer - onTriggered: doScroll() - } - } - Tile - { - title: qsTr("TEMPS") - anchors.fill: parent - values: TileText - { - text: qsTr("") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - ListModel { id: tempsModel } - - // When new service is found add resources as appropriate - Connections - { - target: DBusServices - onDbusServiceFound: addService(service) - } - - // hack to get value(s) from within a loop inside a function when service is changing - property string tempServiceName: "" - property VBusItem temperatureItem: VBusItem { bind: Utils.path(tempServiceName, "/Dc/0/Temperature") } - - function addService(service) - { - switch (service.type) - { -//////// add for temp sensors - case DBusService.DBUS_SERVICE_TEMPERATURE_SENSOR: - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - break;; - case DBusService.DBUS_SERVICE_MULTI: - hasInverter = true - root.tempServiceName = service.name - if (temperatureItem.valid && showBatteryTemp) - { - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - } - break;; -//////// add for VE.Direct inverters - case DBusService.DBUS_SERVICE_INVERTER: - hasInverter = true - if (veDirectInverterService == "") - veDirectInverterService = service.name; - break;; - -//////// add for PV CHARGER voltage and current display - case DBusService.DBUS_SERVICE_SOLAR_CHARGER: - case DBusService.DBUS_SERVICE_MULTI_RS: - if ( service.type == DBusService.DBUS_SERVICE_MULTI_RS ) - hasInverter = true - numberOfPvChargers++ - if (numberOfPvChargers === 1) - pvChargerPrefix1 = service.name; - else if (numberOfPvChargers === 2) - pvChargerPrefix2 = service.name; - else if (numberOfPvChargers === 3) - pvChargerPrefix3 = service.name; - else if (numberOfPvChargers === 4) - pvChargerPrefix4 = service.name; - else if (numberOfPvChargers === 5) - pvChargerPrefix5 = service.name; - else if (numberOfPvChargers === 6) - pvChargerPrefix6 = service.name; - else if (numberOfPvChargers === 7) - pvChargerPrefix7 = service.name; - break;; - -//////// add for PV INVERTER power display - case DBusService.DBUS_SERVICE_PV_INVERTER: - numberOfPvInverters++ - if (numberOfPvInverters === 1) - pvInverterPrefix1 = service.name; - else if (numberOfPvInverters === 2) - pvInverterPrefix2 = service.name; - else if (numberOfPvInverters === 3) - pvInverterPrefix3 = service.name; - break;; - case DBusService.DBUS_SERVICE_BATTERY: - root.tempServiceName = service.name - if (temperatureItem.valid && showBatteryTemp) - { - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - } - break;; -//////// add for alternator - case DBusService.DBUS_SERVICE_ALTERNATOR: - numberOfAlternators++ - if (numberOfAlternators === 1) - alternatorPrefix1 = service.name; - else if (numberOfAlternators === 2) - alternatorPrefix2 = service.name; - break;; - } - } - - // Detect available services of interest - function discoverServices() - { - numberOfTemps = 0 - numberOfPvChargers = 0 - numberOfPvInverters = 0 - numberOfAlternators = 0 - veDirectInverterService = "" - hasInverter = false - pvChargerPrefix1 = "" - pvChargerPrefix2 = "" - pvChargerPrefix3 = "" - pvChargerPrefix4 = "" - pvChargerPrefix5 = "" - pvChargerPrefix6 = "" - pvChargerPrefix7 = "" - pvInverterPrefix1 = "" - pvInverterPrefix2 = "" - pvInverterPrefix3 = "" - alternatorPrefix1 = "" - alternatorPrefix2 = "" - tempsModel.clear() - for (var i = 0; i < DBusServices.count; i++) - { - addService(DBusServices.at(i)) - } - } - -// Details targets - - // help message shown when menu is first drawn - Rectangle - { - id: helpBox - color: "white" - width: multi.width - height: 32 -////// GuiMods — DarkMode - opacity: !darkMode ? 0.7 : 0.85 - anchors - { - top: multi.bottom; topMargin: 1 - horizontalCenter: root.horizontalCenter - } - visible: false - TileText - { - text: qsTr ( "Tap tile center for detail at any time" ) - color: "black" - anchors.fill: helpBox - wrapMode: Text.WordWrap - font.pixelSize: 12 - visible: parent.visible - } - } - - //// hard key handler - // used to press buttons when touch isn't available - // UP and DOWN buttons cycle through the list of touch areas - // "space" button is used to simulate a touch on the area - // target must be highlighted so that other uses of "space" - // will still occur - - // list of all details touchable areas - property variant targetList: - [ - acInputTarget, alternatorTarget, batteryTarget, - multiTarget, dcSystemTarget, - loadsOnOutputTarget, pvInverterTarget, pvChargerTarget - ] - - property int selectedTarget: 0 - - Timer - { - id: targetTimer - interval: 5000 - repeat: false - running: false - onTriggered: { hideAllTargets () } - } - - Keys.forwardTo: [keyHandler] - Item - { - id: keyHandler - Keys.onUpPressed: - { - nextTarget (-1) - event.accepted = true - } - - Keys.onDownPressed: - { - nextTarget (+1) - event.accepted = true - } - Keys.onSpacePressed: - { - if (targetTimer.running) - { - var foo // hack to make clicked() work - bar.clicked (foo) - event.accepted = true - } - else - event.accepted = false - } - } - // hack to make clicked() work - property variant bar: targetList[selectedTarget] - - function nextTarget (increment) - { - // make one pass through all possible targets to find an enabled one - // if found, that's the new selectedTarget, - // if not selectedTarget does not change - var newIndex = selectedTarget - for (var i = 0; i < targetList.length; i++) - { - if (( ! targetTimer.running || helpBox.visible) && targetList[newIndex].enabled) - { - highlightSelectedTarget () - return - } - newIndex += increment - if (newIndex >= targetList.length) - newIndex = 0 - else if (newIndex < 0) - newIndex = targetList.length - 1 - if (targetList[newIndex].enabled) - { - selectedTarget = newIndex - highlightSelectedTarget () - break - } - } - } - - function showHelp () - { - for (var i = 0; i < targetList.length; i++) - { - targetList[i].targetVisible = true - } - helpBox.visible = true - targetTimer.restart () - } - function hideAllTargets () - { - for (var i = 0; i < targetList.length; i++) - { - targetList[i].targetVisible = false - } - helpBox.visible = false - } - function highlightSelectedTarget () - { - for (var i = 0; i < targetList.length; i++) - { - if (targetList[i] == targetList[selectedTarget]) - targetList[i].targetVisible = true - else - targetList[i].targetVisible = false - } - helpBox.visible = false - targetTimer.restart () - } -} diff --git a/FileSets/v3.01/OverviewHubEnhanced.qml.orig b/FileSets/v3.01/OverviewHubEnhanced.qml.orig deleted file mode 100644 index 4418c508..00000000 --- a/FileSets/v3.01/OverviewHubEnhanced.qml.orig +++ /dev/null @@ -1,309 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -OverviewPage { - id: root - - property variant sys: theSystem - property bool hasAcSolarOnAcIn1: sys.pvOnAcIn1.power.valid - property bool hasAcSolarOnAcIn2: sys.pvOnAcIn2.power.valid - property bool hasAcSolarOnIn: hasAcSolarOnAcIn1 || hasAcSolarOnAcIn2 - property bool hasAcSolarOnOut: sys.pvOnAcOut.power.valid - property bool hasAcSolar: hasAcSolarOnIn || hasAcSolarOnOut - property bool hasDcSolar: sys.pvCharger.power.valid - property bool hasDcAndAcSolar: hasAcSolar && hasDcSolar - - title: qsTr("Overview") - - OverviewBox { - id: acInBox - - width: 148 - height: showStatusBar ? 100 : 120 - title: getAcSourceName(sys.acSource) - titleColor: "#E74c3c" - color: "#C0392B" - - anchors { - top: multi.top - left: parent.left; leftMargin: 10 - } - - values: OverviewAcValues { - connection: sys.acInput - } - - MbIcon { - iconId: getAcSourceIcon(sys.acSource) - anchors { - bottom: parent.bottom - left: parent.left; leftMargin: 2 - } - opacity: 0.5 - } - } - - Multi { - id: multi - anchors { - horizontalCenter: parent.horizontalCenter - top: parent.top; topMargin: 5 - } - } - - OverviewBox { - id: acLoadBox - title: qsTr("AC Loads") - color: "#27AE60" - titleColor: "#2ECC71" - width: 148 - height: showStatusBar ? 100 : 120 - - anchors { - right: parent.right; rightMargin: 10 - top: multi.top - } - - values: OverviewAcValues { - connection: sys.acLoad - } - } - - Battery { - id: battery - - soc: sys.battery.soc.valid ? sys.battery.soc.value : 0 - - anchors { - bottom: parent.bottom; bottomMargin: 5; - left: parent.left; leftMargin: 10 - } - values: Column { - width: parent.width - - TileText { - // Use value here instead of format() because format adds the unit to the number and we - // show the percentage symbol in a separated smaller text. - text: sys.battery.soc.value === undefined ? "--" : sys.battery.soc.value.toFixed(0) - font.pixelSize: 40 - - Text { - anchors { - bottom: parent.bottom; bottomMargin: 9 - horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: parent.paintedWidth / 2 + 5 - } - visible: sys.battery.soc.valid - text: "%" - color: "white" - font.bold: true - font.pixelSize: 12 - } - } - TileText { - text: sys.battery.power.format(0) - } - TileText { - text: sys.battery.voltage.format(1) + " " + sys.battery.current.format(1) - } - } - } - - OverviewBox { - id: dcSystemBox - width: 105 - height: 45 - visible: sys.dcSystem.power.valid - title: qsTr("DC Power") - - anchors { - horizontalCenter: multi.horizontalCenter - bottom: parent.bottom; bottomMargin: 5 - } - - values: TileText { - anchors.centerIn: parent - text: sys.dcSystem.power.format(0) - } - } - - OverviewSolarCharger { - id: blueSolarCharger - - height: hasDcAndAcSolar ? 65 : 114 - width: 148 - title: qsTr("PV Charger") - showChargerIcon: !hasDcAndAcSolar - visible: hasDcSolar || hasDcAndAcSolar - - anchors { - right: root.right; rightMargin: 10 - bottom: root.bottom; bottomMargin: 5; - } - - values: TileText { - y: 5 - text: sys.pvCharger.power.format(0) - font.pixelSize: 20 - } - } - - OverviewSolarInverter { - id: pvInverter - height: hasDcAndAcSolar ? 65 : 115 - width: 148 - title: qsTr("PV Inverter") - showInverterIcon: !hasDcAndAcSolar - visible: hasAcSolar - - anchors { - right: root.right; rightMargin: 10; - bottom: root.bottom; bottomMargin: hasDcAndAcSolar ? 75 : 5 - } - - OverviewAcValues { - connection: hasAcSolarOnOut ? sys.pvOnAcOut : hasAcSolarOnAcIn1 ? sys.pvOnAcIn1 : sys.pvOnAcIn2 - visible: !coupledPvAc.visible - } - - TileText { - id: coupledPvAc - - property double pvInverterOnAcOut: sys.pvOnAcOut.power.valid ? sys.pvOnAcOut.power.value : 0 - property double pvInverterOnAcIn1: sys.pvOnAcIn1.power.valid ? sys.pvOnAcIn1.power.value : 0 - property double pvInverterOnAcIn2: sys.pvOnAcIn2.power.valid ? sys.pvOnAcIn2.power.value : 0 - - y: 5 - text: (pvInverterOnAcOut + pvInverterOnAcIn1 + pvInverterOnAcIn2).toFixed(0) + "W" - font.pixelSize: hasDcAndAcSolar ? 20 : 25 - visible: hasDcAndAcSolar || (hasAcSolarOnIn && hasAcSolarOnOut) || (hasAcSolarOnAcIn1 && hasAcSolarOnAcIn2) - } - } - - OverviewEssReason { - anchors { - bottom: parent.bottom; bottomMargin: dcSystemBox.visible ? battery.height + 15 : 5 - horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: dcSystemBox.visible ? -(root.width / 2 - battery.width / 2 - 10) : 0 - } - } - - OverviewConnection { - id: acInToMulti - ballCount: 2 - path: straight - active: root.active - value: flow(sys.acInput ? sys.acInput.power : 0) - - anchors { - left: acInBox.right; leftMargin: -10; top: multi.verticalCenter; - right: multi.left; rightMargin: -10; bottom: multi.verticalCenter - } - } - - OverviewConnection { - id: multiToAcLoads - ballCount: 2 - path: straight - active: root.active - value: flow(sys.acLoad.power) - - anchors { - left: multi.right; leftMargin: -10; - top: multi.verticalCenter - right: acLoadBox.left; rightMargin: -10 - bottom: multi.verticalCenter - } - } - - OverviewConnection { - id: pvInverterToMulti - - property int hasDcAndAcFlow: Utils.sign(noNoise(sys.pvOnAcOut.power) + noNoise(sys.pvOnAcIn1.power) + noNoise(sys.pvOnAcIn2.power)) - - ballCount: 4 - path: corner - active: root.active && hasAcSolar - value: hasDcAndAcSolar ? hasDcAndAcFlow : flow(sys.pvOnAcOut.power) - - anchors { - left: pvInverter.left; leftMargin: 8 - top: pvInverter.verticalCenter; topMargin: hasDcAndAcSolar ? 1 : 0 - right: multi.horizontalCenter; rightMargin: -20 - bottom: multi.bottom; bottomMargin: 10 - } - } - - // invisible anchor point to connect the chargers to the battery - Item { - id: dcConnect - anchors { - left: multi.horizontalCenter; leftMargin: hasAcSolar ? -20 : 0 - bottom: dcSystemBox.top; bottomMargin: 10 - } - } - - OverviewConnection { - id: multiToDcConnect - ballCount: 3 - path: straight - active: root.active - value: -flow(sys.vebusDc.power); - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: dcConnect.left - bottom: multi.bottom; bottomMargin: 10 - } - } - - OverviewConnection { - id: blueSolarChargerDcConnect - ballCount: 3 - path: straight - active: root.active && hasDcSolar - value: -flow(sys.pvCharger.power) - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: blueSolarCharger.left; rightMargin: -8 - bottom: dcConnect.top; - } - } - - OverviewConnection { - id: chargersToBattery - ballCount: 3 - path: straight - active: root.active - value: Utils.sign(noNoise(sys.pvCharger.power) + noNoise(sys.vebusDc.power)) - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: battery.right; rightMargin: 10 - bottom: dcConnect.top - } - } - - OverviewConnection { - id: batteryToDcSystem - ballCount: 2 - path: straight - active: root.active && sys.dcSystem.power.valid - value: flow(sys.dcSystem.power) - - anchors { - left: battery.right; leftMargin: -10 - top: dcSystemBox.verticalCenter; - right: dcSystemBox.left; rightMargin: -10 - bottom: dcSystemBox.verticalCenter - } - } -} diff --git a/FileSets/v3.01/OverviewMobileEnhanced.qml b/FileSets/v3.01/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.01/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.01/OverviewSolarCharger.qml b/FileSets/v3.01/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v3.01/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.01/OverviewSolarInverter.qml b/FileSets/v3.01/OverviewSolarInverter.qml deleted file mode 120000 index 4048703e..00000000 --- a/FileSets/v3.01/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.01/OverviewTankDelegate.qml b/FileSets/v3.01/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v3.01/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.01/OverviewTanks.qml b/FileSets/v3.01/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v3.01/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.01/OverviewTanksTempsDigInputs.qml b/FileSets/v3.01/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.01/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.01/PageGenerator.qml b/FileSets/v3.01/PageGenerator.qml deleted file mode 100644 index 7cd75d2d..00000000 --- a/FileSets/v3.01/PageGenerator.qml +++ /dev/null @@ -1,226 +0,0 @@ -//// added service interval -//// changed total time to hours (from varilable format) - -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: root - title: qsTr("Generator start/stop") - property string settingsBindPrefix - property string startStopBindPrefix - property alias startStopModel: _startStopModel - property bool allowDisableAutostart: true - property VBusItem activeCondition: VBusItem { bind: Utils.path(startStopBindPrefix, "/RunningByCondition") } - property VBusItem generatorState: VBusItem { bind: Utils.path(startStopBindPrefix, "/State") } - property VBusItem runningTime: VBusItem { bind: Utils.path(startStopBindPrefix, "/Runtime") } - property VBusItem historicalData: VBusItem { bind: Utils.path(settingsBindPrefix, "/AccumulatedDaily") } - -//// added service interval - VBusItem { id: generatorServiceInterval; bind: Utils.path(settingsBindPrefix, "/ServiceInterval") } - VBusItem { id: timeSinceService; bind: Utils.path(settingsBindPrefix, "/TimeSinceService") } - property bool serviceIntervalValid: timeSinceService.valid && generatorServiceInterval.valid && generatorServiceInterval.value > 0 - property bool serviceOverdue: serviceIntervalValid && timeSinceService.value > generatorServiceInterval.value - -//// changed total time to hours (from varilable format) - function formatTime (time) - { - if (time >= 3600) - return (time / 3600).toFixed(0) + " h" - else - return (time / 60).toFixed(0) + " m" - } - - - function getState() - { - switch(generatorState.value) { - case 10: - return qsTr("Error") - case 2: - return qsTr("Warm-up") - case 3: - return qsTr("Cool-down") - } - - switch(activeCondition.value) { - case 'soc': - return qsTr("Running by SOC condition") - case 'acload': - return qsTr("Running by AC Load condition") - case 'batterycurrent': - return qsTr("Running by battery current condition") - case 'batteryvoltage': - return qsTr("Running by battery voltage condition") - case 'inverterhightemp': - return qsTr("Running by inverter high temperature") - case 'inverteroverload': - return qsTr("Running by inverter overload") - case 'testrun': - return qsTr("Test run") - case 'lossofcommunication': - return qsTr("Running by loss of communication") - case 'manual': - return qsTr("Manually started") - default: - return qsTr("Stopped") - } - } - - model: startStopModel - - function formatError(text, value) - { - return "#" + value.toString() + " " + text - } - - VisibleItemModel { - id: _startStopModel - - MbItemValue { - description: qsTr("State") - item.text: activeCondition.valid ? getState() : '---' - } - - MbItemOptions { - id: _gensetStatus - description: qsTr("Error") - bind: Utils.path(startStopBindPrefix, "/Error") - readonly: true - show: valid - possibleValues: [ - MbOption { description: qsTr("No error"); value: 0 }, - MbOption { description: formatError(qsTr("Remote switch control disabled"), 1); value: 1 }, - MbOption { description: formatError(qsTr("Generator in fault condition"), 2); value: 2 }, - MbOption { description: formatError(qsTr("Generator not detected at AC input"), 3); value: 3 } - ] - } - - MbItemValue { - description: qsTr("Run time") - item.text: runningTime.valid ? Utils.secondsToNoSecsString(runningTime.value) : "0" - show: generatorState.value in [1, 2, 3] // Running, Warm-up, Cool-down - } - - MbItemValue { - description: qsTr("Total run time") - show: item.valid - item { - bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") -//// changed total time to hours (from varilable format) - text: formatTime (item.value) - } - } - - MbItemValue { - description: qsTr("Accumulated running time since last test run") - show: user.accessLevel >= User.AccessService && nextTestRun.show - backgroundColor: style.backgroundColorService - item { - text: Utils.secondsToNoSecsString(item.value) - bind: Utils.path(startStopBindPrefix, "/TestRunIntervalRuntime") - } - } - - MbItemValue { - id: nextTestRun - description: qsTr("Time to next test run") - show: item.valid && item.value > 0 - item { - text: { - var remainingTime = item.value - new Date().getTime() / 1000 - if (remainingTime > 0) - return Utils.secondsToNoSecsString(remainingTime).toString() - return qsTr("Running now") - } - bind: Utils.path(startStopBindPrefix, "/NextTestRun") - } - } - -//// added service interval - MbItemValue { - id: serviceTime - description: serviceOverdue ? qsTr("Service OVERDUE") : qsTr("Time to next service") - show: serviceIntervalValid - item - { - text: formatTime (Math.abs (generatorServiceInterval.value - timeSinceService.value)) - } - } - - MbSwitch { - name: qsTr("Auto start functionality") - bind: Utils.path(settingsBindPrefix, "/AutoStartEnabled") - show: allowDisableAutostart - } - - MbSubMenu { - description: qsTr("Manual start") - subpage: Component { - MbPage { - id: manualStartPage - title: qsTr("Manual start") - model: VisibleItemModel { - MbSwitch { - id: manualSwitch - name: qsTr("Start generator") - bind: Utils.path(startStopBindPrefix, "/ManualStart") - writeAccessLevel: User.AccessUser - onCheckedChanged: { - if (manualStartPage.active) { - if (!checked) - toast.createToast(qsTr("Stopping, generator will continue running if other conditions are reached"), 3000) - if (checked && stopTimer.value == 0) - toast.createToast(qsTr("Starting, generator won't stop till user intervention"), 5000) - if (checked && stopTimer.value > 0) - toast.createToast(qsTr("Starting. The generator will stop in %1, unless other conditions keep it running").arg(Utils.secondsToString(stopTimer.value)), 5000) - } - } - - VBusItem { - id: stopTimer - bind: Utils.path(startStopBindPrefix, "/ManualStartTimer") - } - } - - MbEditBoxTime { - description: qsTr("Run for (hh:mm)") - readonly: manualSwitch.checked - item.bind: Utils.path(startStopBindPrefix, "/ManualStartTimer") - writeAccessLevel: User.AccessUser - } - } - } - } - } - - MbSubMenu { - description: qsTr("Daily run time") - subpage: MbPage { - // Invert the order - property variant keys: historicalData.valid ? - Object.keys(JSON.parse(historicalData.value)).reverse() : 0 - - title: qsTr("Daily run time") - focus: active - model: keys - delegate: MbItemValue { - description: Qt.formatDate(new Date(parseInt(keys[index]) * 1000), "dd-MM-yyyy"); - item.text: Utils.secondsToNoSecsString(JSON.parse(historicalData.value)[keys[index]]) - } - } - } - - MbSubMenu { - id: conditions - description: qsTr("Settings") - subpage: Component { - PageSettingsGenerator { - settingsBindPrefix: root.settingsBindPrefix - startStopBindPrefix: root.startStopBindPrefix - } - } - } - } -} diff --git a/FileSets/v3.01/PageGenerator.qml.orig b/FileSets/v3.01/PageGenerator.qml.orig deleted file mode 100644 index 73fed5a5..00000000 --- a/FileSets/v3.01/PageGenerator.qml.orig +++ /dev/null @@ -1,194 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: root - title: qsTr("Generator start/stop") - property string settingsBindPrefix - property string startStopBindPrefix - property alias startStopModel: _startStopModel - property bool allowDisableAutostart: true - property VBusItem activeCondition: VBusItem { bind: Utils.path(startStopBindPrefix, "/RunningByCondition") } - property VBusItem generatorState: VBusItem { bind: Utils.path(startStopBindPrefix, "/State") } - property VBusItem runningTime: VBusItem { bind: Utils.path(startStopBindPrefix, "/Runtime") } - property VBusItem historicalData: VBusItem { bind: Utils.path(settingsBindPrefix, "/AccumulatedDaily") } - - function getState() - { - switch(generatorState.value) { - case 10: - return qsTr("Error") - case 2: - return qsTr("Warm-up") - case 3: - return qsTr("Cool-down") - } - - switch(activeCondition.value) { - case 'soc': - return qsTr("Running by SOC condition") - case 'acload': - return qsTr("Running by AC Load condition") - case 'batterycurrent': - return qsTr("Running by battery current condition") - case 'batteryvoltage': - return qsTr("Running by battery voltage condition") - case 'inverterhightemp': - return qsTr("Running by inverter high temperature") - case 'inverteroverload': - return qsTr("Running by inverter overload") - case 'testrun': - return qsTr("Test run") - case 'lossofcommunication': - return qsTr("Running by loss of communication") - case 'manual': - return qsTr("Manually started") - default: - return qsTr("Stopped") - } - } - - model: startStopModel - - function formatError(text, value) - { - return "#" + value.toString() + " " + text - } - - VisibleItemModel { - id: _startStopModel - - MbItemValue { - description: qsTr("State") - item.text: activeCondition.valid ? getState() : '---' - } - - MbItemOptions { - id: _gensetStatus - description: qsTr("Error") - bind: Utils.path(startStopBindPrefix, "/Error") - readonly: true - show: valid - possibleValues: [ - MbOption { description: qsTr("No error"); value: 0 }, - MbOption { description: formatError(qsTr("Remote switch control disabled"), 1); value: 1 }, - MbOption { description: formatError(qsTr("Generator in fault condition"), 2); value: 2 }, - MbOption { description: formatError(qsTr("Generator not detected at AC input"), 3); value: 3 } - ] - } - - MbItemValue { - description: qsTr("Run time") - item.text: runningTime.valid ? Utils.secondsToNoSecsString(runningTime.value) : "0" - show: generatorState.value in [1, 2, 3] // Running, Warm-up, Cool-down - } - - MbItemValue { - description: qsTr("Total run time") - item { - bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") - text: Utils.secondsToNoSecsString(item.value) - } - } - - MbItemValue { - description: qsTr("Accumulated running time since last test run") - show: user.accessLevel >= User.AccessService && nextTestRun.show - backgroundColor: style.backgroundColorService - item { - text: Utils.secondsToNoSecsString(item.value) - bind: Utils.path(startStopBindPrefix, "/TestRunIntervalRuntime") - } - } - - MbItemValue { - id: nextTestRun - description: qsTr("Time to next test run") - show: item.valid && item.value > 0 - item { - text: { - var remainingTime = item.value - new Date().getTime() / 1000 - if (remainingTime > 0) - return Utils.secondsToNoSecsString(remainingTime).toString() - return qsTr("Running now") - } - bind: Utils.path(startStopBindPrefix, "/NextTestRun") - } - } - - MbSwitch { - name: qsTr("Auto start functionality") - bind: Utils.path(settingsBindPrefix, "/AutoStartEnabled") - show: allowDisableAutostart - } - - MbSubMenu { - description: qsTr("Manual start") - subpage: Component { - MbPage { - id: manualStartPage - title: qsTr("Manual start") - model: VisibleItemModel { - MbSwitch { - id: manualSwitch - name: qsTr("Start generator") - bind: Utils.path(startStopBindPrefix, "/ManualStart") - writeAccessLevel: User.AccessUser - onCheckedChanged: { - if (manualStartPage.active) { - if (!checked) - toast.createToast(qsTr("Stopping, generator will continue running if other conditions are reached"), 3000) - if (checked && stopTimer.value == 0) - toast.createToast(qsTr("Starting, generator won't stop till user intervention"), 5000) - if (checked && stopTimer.value > 0) - toast.createToast(qsTr("Starting. The generator will stop in %1, unless other conditions keep it running").arg(Utils.secondsToString(stopTimer.value)), 5000) - } - } - - VBusItem { - id: stopTimer - bind: Utils.path(startStopBindPrefix, "/ManualStartTimer") - } - } - - MbEditBoxTime { - description: qsTr("Run for (hh:mm)") - readonly: manualSwitch.checked - item.bind: Utils.path(startStopBindPrefix, "/ManualStartTimer") - writeAccessLevel: User.AccessUser - } - } - } - } - } - - MbSubMenu { - description: qsTr("Daily run time") - subpage: MbPage { - // Invert the order - property variant keys: historicalData.valid ? - Object.keys(JSON.parse(historicalData.value)).reverse() : 0 - - title: qsTr("Daily run time") - focus: active - model: keys - delegate: MbItemValue { - description: Qt.formatDate(new Date(parseInt(keys[index]) * 1000), "dd-MM-yyyy"); - item.text: Utils.secondsToNoSecsString(JSON.parse(historicalData.value)[keys[index]]) - } - } - } - - MbSubMenu { - id: conditions - description: qsTr("Settings") - subpage: Component { - PageSettingsGenerator { - settingsBindPrefix: root.settingsBindPrefix - startStopBindPrefix: root.startStopBindPrefix - } - } - } - } -} diff --git a/FileSets/v3.01/PageMain.qml b/FileSets/v3.01/PageMain.qml deleted file mode 120000 index 2f68fb1c..00000000 --- a/FileSets/v3.01/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.14/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.01/PageSettingsGenerator.qml b/FileSets/v3.01/PageSettingsGenerator.qml deleted file mode 100644 index dbf50e88..00000000 --- a/FileSets/v3.01/PageSettingsGenerator.qml +++ /dev/null @@ -1,219 +0,0 @@ -//// GuiMods -//// addd service interval and reset -//// added link to external state enable - -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: root - title: qsTr("Generator start/stop settings") - property string settingsBindPrefix - property string startStopBindPrefix - property VBusItem acIn1Source: VBusItem { bind: "com.victronenergy.settings/Settings/SystemSetup/AcInput1" } - property VBusItem acIn2Source: VBusItem { bind: "com.victronenergy.settings/Settings/SystemSetup/AcInput2" } - property VBusItem capabilities: VBusItem { bind: Utils.path(startStopBindPrefix, "/Capabilities") } - property int warmupCapability: 1 - - model: VisibleItemModel { - - MbSubMenu { - id: conditions - description: qsTr("Conditions") - subpage: - Component { - PageGeneratorConditions { - title: qsTr("Conditions") - bindPrefix: root.settingsBindPrefix - startStopBindPrefix: root.startStopBindPrefix - } - } - } - - MbSpinBox { - description: qsTr("Minimum run time") - item { - bind: Utils.path(settingsBindPrefix, "/MinimumRuntime") - unit: "m" - decimals: 0 - step: 1 - } - } - - MbSpinBox { - description: qsTr("Warm-up time") - show: capabilities.value & warmupCapability - item { - bind: Utils.path(settingsBindPrefix, "/WarmUpTime") - unit: "s" - decimals: 0 - step: 10 - } - } - - MbSpinBox { - description: qsTr("Cool-down time") - show: capabilities.value & warmupCapability - item { - bind: Utils.path(settingsBindPrefix, "/CoolDownTime") - unit: "s" - decimals: 0 - step: 10 - } - } - //// GuiMods - MbSpinBox { - description: qsTr("Post-cool-down time") - show: capabilities.value & warmupCapability - item { - bind: Utils.path(settingsBindPrefix, "/PostCoolDownTime") - unit: "s" - decimals: 0 - step: 5 - } - } - - MbSwitch { -//// GuiMods - id: detectGeneratorAtAcIn - - property bool generatorIsSet: acIn1Source.value === 2 || acIn2Source.value === 2 - name: qsTr("Detect generator at AC input") - bind: Utils.path(settingsBindPrefix, "/Alarms/NoGeneratorAtAcIn") - enabled: valid && (generatorIsSet || checked) - onClicked: { - if (!checked) { - if (!generatorIsSet) { - toast.createToast(qsTr("None of the AC inputs is set to generator. Go to the system setup page and set the correct " + - "AC input to generator in order to enable this functionality."), 10000, "icon-info-active") - } else { - toast.createToast(qsTr("An alarm will be triggered when no power from the generator is detected at the inverter AC input. " + - "Make sure that the correct AC input is set to generator on the system setup page."), 12000, "icon-info-active") - } - } - } - } -//// GuiMods - MbSwitch { - name: qsTr("Link to external running state") - bind: Utils.path(settingsBindPrefix, "/LinkToExternalStatus") - onClicked: - { - if (!checked) - toast.createToast(qsTr("Manual run will be synchronized with the generaror 'is running digital input' or AC input"), 10000, "icon-info-active") - } - } - - MbSwitch { - id: timeZones - name: qsTr("Quiet hours") - bind: Utils.path(settingsBindPrefix, "/QuietHours/Enabled") - enabled: valid - writeAccessLevel: User.AccessUser - } - - MbEditBoxTime { - description: qsTr("Quiet hours start time") - item.bind: Utils.path(settingsBindPrefix, "/QuietHours/StartTime") - show: timeZones.checked - writeAccessLevel: User.AccessUser - } - - MbEditBoxTime { - description: qsTr("Quiet hours end time") - item.bind: Utils.path(settingsBindPrefix, "/QuietHours/EndTime") - show: timeZones.checked - writeAccessLevel: User.AccessUser - } - - MbOK { - description: qsTr("Reset daily run time counters") - value: qsTr("Press to reset") - enabled: true - editable: enabled - onClicked: { - if (state.value === 0) { - var now = new Date() - var today = new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate())) - var todayInSeconds = today.getTime() / 1000 - resetDaily.setValue('{"%1" : 0}'.arg(todayInSeconds.toString())) - toast.createToast(qsTr("The daily runtime counter has been reset")) - } else if (state.value === 1) { - toast.createToast(qsTr("It is not possible to modify the counters while the generator is running")) - } - } - - VBusItem { - id: resetDaily - bind: Utils.path(settingsBindPrefix, "/AccumulatedDaily") - } - } - - MbEditBox { - id: setTotalRunTime - description: qsTr("Generator total run time (hours)") - item { - bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") - text: Math.round(item.value / 60 / 60) - } -//// added to avoid full keyboard - numericOnlyLayout: true - matchString: "0123456789" - maximumLength: 6 - ignoreChars: "h" - enabled: state.value === 0 - - function editTextToValue() { - return parseInt(_editText, 10) * 60 * 60 - } - - Keys.onSpacePressed: { - if (!enabled) - toast.createToast(qsTr("It is not possible to modify the counters while the generator is running")) - } - } - -//// GuiMods - MbEditBox - { - id: serviceInterval - description: qsTr("Generator service interval (hours)") - item { - bind: Utils.path(settingsBindPrefix, "/ServiceInterval") - text: Math.round(item.value / 60 / 60) - } - numericOnlyLayout: true - matchString: "0123456789" - maximumLength: 6 - ignoreChars: "h" - - function editTextToValue() { - return parseInt(_editText, 10) * 60 * 60 - } - } - MbOK - { - description: qsTr("Reset service timer") - value: qsTr("Press to reset") - show: timeSinceService.valid && timeSinceService.value > 0 - editable: true - VBusItem - { - id: timeSinceService - bind: Utils.path(settingsBindPrefix, "/TimeSinceService") - } - - function clicked() - { - timeSinceService.setValue (0) - toast.createToast(qsTr("the service timer has been reset to ") + (serviceInterval.item.value / 3600).toFixed (0) + "h") - } - } - } - - VBusItem { - id: state - bind: Utils.path(startStopBindPrefix, "/State") - } -} diff --git a/FileSets/v3.01/PageSettingsGenerator.qml.orig b/FileSets/v3.01/PageSettingsGenerator.qml.orig deleted file mode 100644 index 97754bb7..00000000 --- a/FileSets/v3.01/PageSettingsGenerator.qml.orig +++ /dev/null @@ -1,152 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: root - title: qsTr("Generator start/stop settings") - property string settingsBindPrefix - property string startStopBindPrefix - property VBusItem acIn1Source: VBusItem { bind: "com.victronenergy.settings/Settings/SystemSetup/AcInput1" } - property VBusItem acIn2Source: VBusItem { bind: "com.victronenergy.settings/Settings/SystemSetup/AcInput2" } - property VBusItem capabilities: VBusItem { bind: Utils.path(startStopBindPrefix, "/Capabilities") } - property int warmupCapability: 1 - - model: VisibleItemModel { - - MbSubMenu { - id: conditions - description: qsTr("Conditions") - subpage: - Component { - PageGeneratorConditions { - title: qsTr("Conditions") - bindPrefix: root.settingsBindPrefix - startStopBindPrefix: root.startStopBindPrefix - } - } - } - - MbSpinBox { - description: qsTr("Minimum run time") - item { - bind: Utils.path(settingsBindPrefix, "/MinimumRuntime") - unit: "m" - decimals: 0 - step: 1 - } - } - - MbSpinBox { - description: qsTr("Warm-up time") - show: capabilities.value & warmupCapability - item { - bind: Utils.path(settingsBindPrefix, "/WarmUpTime") - unit: "s" - decimals: 0 - step: 10 - } - } - - MbSpinBox { - description: qsTr("Cool-down time") - show: capabilities.value & warmupCapability - item { - bind: Utils.path(settingsBindPrefix, "/CoolDownTime") - unit: "s" - decimals: 0 - step: 10 - } - } - - MbSwitch { - property bool generatorIsSet: acIn1Source.value === 2 || acIn2Source.value === 2 - name: qsTr("Detect generator at AC input") - bind: Utils.path(settingsBindPrefix, "/Alarms/NoGeneratorAtAcIn") - enabled: valid && (generatorIsSet || checked) - onClicked: { - if (!checked) { - if (!generatorIsSet) { - toast.createToast(qsTr("None of the AC inputs is set to generator. Go to the system setup page and set the correct " + - "AC input to generator in order to enable this functionality."), 10000, "icon-info-active") - } else { - toast.createToast(qsTr("An alarm will be triggered when no power from the generator is detected at the inverter AC input. " + - "Make sure that the correct AC input is set to generator on the system setup page."), 12000, "icon-info-active") - } - } - } - } - - MbSwitch { - id: timeZones - name: qsTr("Quiet hours") - bind: Utils.path(settingsBindPrefix, "/QuietHours/Enabled") - enabled: valid - writeAccessLevel: User.AccessUser - } - - MbEditBoxTime { - description: qsTr("Quiet hours start time") - item.bind: Utils.path(settingsBindPrefix, "/QuietHours/StartTime") - show: timeZones.checked - writeAccessLevel: User.AccessUser - } - - MbEditBoxTime { - description: qsTr("Quiet hours end time") - item.bind: Utils.path(settingsBindPrefix, "/QuietHours/EndTime") - show: timeZones.checked - writeAccessLevel: User.AccessUser - } - - MbOK { - description: qsTr("Reset daily run time counters") - value: qsTr("Press to reset") - enabled: true - editable: enabled - onClicked: { - if (state.value === 0) { - var now = new Date() - var today = new Date(Date.UTC(now.getFullYear(), now.getMonth(), now.getDate())) - var todayInSeconds = today.getTime() / 1000 - resetDaily.setValue('{"%1" : 0}'.arg(todayInSeconds.toString())) - toast.createToast(qsTr("The daily runtime counter has been reset")) - } else if (state.value === 1) { - toast.createToast(qsTr("It is not possible to modify the counters while the generator is running")) - } - } - - VBusItem { - id: resetDaily - bind: Utils.path(settingsBindPrefix, "/AccumulatedDaily") - } - } - - MbEditBox { - id: setTotalRunTime - description: qsTr("Generator total run time (hours)") - item { - bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") - text: Math.round(item.value / 60 / 60) - } - matchString: "0123456789" - maximumLength: 6 - ignoreChars: "h" - enabled: state.value === 0 - - function editTextToValue() { - return parseInt(_editText, 10) * 60 * 60 - } - - Keys.onSpacePressed: { - if (!enabled) - toast.createToast(qsTr("It is not possible to modify the counters while the generator is running")) - } - } - } - - VBusItem { - id: state - bind: Utils.path(startStopBindPrefix, "/State") - } -} diff --git a/FileSets/v3.01/PageSettingsGuiMods.qml b/FileSets/v3.01/PageSettingsGuiMods.qml deleted file mode 100644 index 2de19b26..00000000 --- a/FileSets/v3.01/PageSettingsGuiMods.qml +++ /dev/null @@ -1,291 +0,0 @@ -/////// new menu for all Gui Mods - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 - -MbPage { - id: root - title: qsTr("Gui Mods") - property string bindPrefixGuiMods: "com.victronenergy.settings/Settings/GuiMods" - property string bindPrefix: "com.victronenergy.settings/Settings/Gui" - property VBusItem systemScaleItem: VBusItem { bind: "com.victronenergy.settings/Settings/System/Units/Temperature" } - - property bool showFlowParams: flowOverview.item.valid && flowOverview.item.value >= 1 - property bool showComplexParams: flowOverview.item.valid && flowOverview.item.value >= 2 - property bool showAcCoupledParams: flowOverview.item.valid && flowOverview.item.value == 3 - - model: VisibleItemModel - { - - MbSwitch - { - id: showTileOverview - bind: Utils.path (bindPrefixGuiMods, "/ShowTileOverview") - name: qsTr ("Show Tile Overview") - writeAccessLevel: User.AccessUser - } - - MbSwitch - { - id: moveSettings - bind: Utils.path (bindPrefixGuiMods, "/MoveSettings") - name: qsTr ("Move Settings to top of Device List") - writeAccessLevel: User.AccessUser - } - - MbSwitch { - id: relayOverview - bind: Utils.path (bindPrefixGuiMods, "/ShowRelayOverview") - name: qsTr ("Show Relay overview") - writeAccessLevel: User.AccessUser - } - MbSwitch { - id: tanksTempsOverview - bind: Utils.path (bindPrefixGuiMods, "/ShowTanksTempsDigIn") - name: qsTr ("Show Tanks, Temps, Digital Input overview") - writeAccessLevel: User.AccessUser - } - - MbSwitch - { - id: useEnhGeneratorOverview - bind: Utils.path (bindPrefixGuiMods, "/UseEnhancedGeneratorOverview") - name: qsTr ("Use Enhanced Generator Overview") - writeAccessLevel: User.AccessUser - } - - // duplicate mobile overview on/off here for convenience - MbSwitch { - id: mobileOverview - bind: Utils.path (bindPrefix, "/MobileOverview") - name: qsTr ("Show boat & motorhome overview") - writeAccessLevel: User.AccessUser - } - MbSwitch - { - id: useEnhMobileOverview - bind: Utils.path (bindPrefixGuiMods, "/UseEnhancedMobileOverview") - name: qsTr ("Use Enhanced Mobile Overview") - // When enabled set Enhanced OverviewMobile as default overview - onClicked: - { - if (!checked) - { - // also enable Mobile Overview when turning on use enhanced Mobile Overview - showMobileOverview.setValue (1) - } - } - VBusItem { id: showMobileOverview; bind: Utils.path (bindPrefix, "/MobileOverview") } - writeAccessLevel: User.AccessUser - } - MbItemOptions - { - id: flowOverview - description: qsTr("Flow overview") - bind: Utils.path (bindPrefixGuiMods, "/FlowOverview") - possibleValues: - [ - MbOption {description: qsTr("Victron stock"); value: 0}, - MbOption {description: qsTr("GuiMods simple"); value: 1}, - MbOption {description: qsTr("GuiMods DC Coupled"); value: 2}, - MbOption {description: qsTr("GuiMods AC Coupled"); value: 3} - ] - } - - MbSwitch - { - id: combineLoads - bind: Utils.path (bindPrefixGuiMods, "/EnhancedFlowCombineLoads") - name: qsTr ("Combine AC input/ouput loads") - show: root.showAcCoupledParams - writeAccessLevel: User.AccessInstaller - } - MbSwitch - { - id: showLoadsOnInput - bind: Utils.path (bindPrefixGuiMods, "/ShowEnhancedFlowLoadsOnInput") - name: qsTr ("Show Loads On Input") - show: root.showAcCoupledParams && ! combineLoads.checked - writeAccessLevel: User.AccessInstaller - } - - MbSwitch - { - id: showTanks - bind: Utils.path (bindPrefixGuiMods, "/ShowEnhancedFlowOverviewTanks") - name: qsTr ("Show tanks on Flow Overview") - show: root.showFlowParams - writeAccessLevel: User.AccessUser - } - MbItemOptions - { - id: tankFormat - description: qsTr("Tank bar format") - bind: Utils.path (bindPrefixGuiMods, "/TankBarFormat") - possibleValues: - [ - MbOption {description: qsTr("%"); value: 1}, - MbOption {description: qsTr("units"); value: 2}, - MbOption {description: qsTr("% + units"); value: 0} - ] - } - MbSwitch - { - id: showTemps - bind: Utils.path (bindPrefixGuiMods, "/ShowEnhancedFlowOverviewTemps") - name: qsTr ("Show temperatures on Flow Overview") - show: root.showFlowParams - writeAccessLevel: User.AccessUser - } - MbSwitch - { - id: showBatteryTemps - bind: Utils.path (bindPrefixGuiMods, "/ShowBatteryTempOnFlows") - name: qsTr ("Show battery temperature on Flow Overview") - show: showTemps.item.value == 1 - writeAccessLevel: User.AccessUser - } - MbSwitch - { - id: shortenTankNames - bind: Utils.path (bindPrefixGuiMods, "/ShortenTankNames") - name: qsTr ("Shorten tank names") - writeAccessLevel: User.AccessUser - } - MbEditBox { - id: dcSystemName - description: qsTr("DC System tile name") - item.bind: Utils.path (bindPrefixGuiMods, "/CustomDcSystemName") - maximumLength: 32 - enableSpaceBar: true - } - - MbSwitch - { - id: replaceInactiveAcIn - bind: Utils.path (bindPrefixGuiMods, "/ReplaceInactiveAcIn") - name: qsTr ("Replace AC in if inactive") - writeAccessLevel: User.AccessUser - } - - MbSpinBox { - description: qsTr ("AC Input Limit Preset 1") - item - { - bind: Utils.path (bindPrefixGuiMods, "/AcCurrentLimit/Preset1") - unit: "A" - decimals: 0 - step: 1 - min: 0 - max: 999 - } - writeAccessLevel: User.AccessUser - } - - MbSpinBox { - description: qsTr ("AC Input Limit Preset 2") - item - { - bind: Utils.path (bindPrefixGuiMods, "/AcCurrentLimit/Preset2") - unit: "A" - decimals: 0 - step: 1 - min: 0 - max: 999 - } - writeAccessLevel: User.AccessUser - } - - MbSpinBox { - description: qsTr ("AC Input Limit Preset 3") - item - { - bind: Utils.path (bindPrefixGuiMods, "/AcCurrentLimit/Preset3") - unit: "A" - decimals: 0 - step: 1 - min: 0 - max: 999 - } - writeAccessLevel: User.AccessUser - } - - MbSpinBox { - description: qsTr ("AC Input Limit Preset 4") - item - { - bind: Utils.path (bindPrefixGuiMods, "/AcCurrentLimit/Preset4") - unit: "A" - decimals: 0 - step: 1 - min: 0 - max: 999 - } - writeAccessLevel: User.AccessUser - } - - MbItemOptions - { - id: tempScale - description: qsTr ("Temperature scale") - bind: Utils.path (bindPrefixGuiMods, "/TemperatureScale") - show: ! systemScaleItem.valid - possibleValues: - [ - MbOption { description: "°C"; value: 1 }, - MbOption { description: "°F"; value: 2 }, - MbOption { description: qsTr("both °C & °F"); value: 0 } - ] - writeAccessLevel: User.AccessUser - } - - MbSpinBox { - description: qsTr ("Watt / Kilowatt threshold") - item - { - bind: Utils.path (bindPrefixGuiMods, "/KilowattThreshold") - unit: "W" - decimals: 0 - step: 100 - min: 1000 - max: 10000 - } - writeAccessLevel: User.AccessUser - } - - MbItemOptions - { - id: timeFormat - description: qsTr ("Time format") - bind: Utils.path (bindPrefixGuiMods, "/TimeFormat") - possibleValues: - [ - MbOption { description: qsTr("24 hour"); value: 1 }, - MbOption { description: qsTr("12 hour AM/PM"); value: 2 }, - MbOption { description: qsTr("don't show time"); value: 0 } - ] - writeAccessLevel: User.AccessUser - } - MbItemOptions - { - id: inactiveFlowTiles - description: qsTr ("Inactive Tiles on Flow Overview") - bind: Utils.path (bindPrefixGuiMods, "/ShowInactiveFlowTiles") - show: root.showFlowParams - possibleValues: - [ - MbOption { description: qsTr("Show Dimmed"); value: 1 }, - MbOption { description: qsTr("Show Full"); value: 2 }, - MbOption { description: qsTr("Hide"); value: 0 } - ] - writeAccessLevel: User.AccessUser - } - MbSubMenu - { - description: qsTr("Power Gauges") - subpage: Component { PageSettingsGuiModsGauges {} } - show: root.showFlowParams - } - } -} diff --git a/FileSets/v3.01/PageSettingsGuiMods.qml.orig b/FileSets/v3.01/PageSettingsGuiMods.qml.orig deleted file mode 100644 index 034aa525..00000000 --- a/FileSets/v3.01/PageSettingsGuiMods.qml.orig +++ /dev/null @@ -1,346 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - property string cgwacsPath: "com.victronenergy.settings/Settings/CGwacs" - property string settingsPrefix: "com.victronenergy.settings" - property string batteryLifePath: cgwacsPath + "/BatteryLife" - // Hub4Mode - property int hub4PhaseCompensation: 1 - property int hub4PhaseSplit: 2 - property int hub4Disabled: 3 - // BatteryLifeState - property int batteryLifeStateDisabled: 0 - property int batteryLifeStateRestart: 1 - property int batteryLifeStateDefault: 2 - property int batteryLifeStateAbsorption: 3 - property int batteryLifeStateFloat: 4 - property int batteryLifeStateDischarged: 5 - property int batteryLifeStateForceCharge: 6 - property int batteryLifeStateSustain: 7 - property int batteryLifeStateLowSocCharge: 8 - property int batteryKeepCharged: 9 - property int batterySocGuardDefault: 10 - property int batterySocGuardDischarged: 11 - property int batterySocGuardLowSocCharge: 12 - - property VBusItem systemType: VBusItem { bind: "com.victronenergy.system/SystemType" } - property VBusItem gridSetpoint: VBusItem { bind: "com.victronenergy.settings/Settings/CGwacs/AcPowerSetPoint" } - property VBusItem maxChargePowerItem: VBusItem { bind: Utils.path(cgwacsPath, "/MaxChargePower") } - property VBusItem maxDischargePowerItem: VBusItem { bind: Utils.path(cgwacsPath, "/MaxDischargePower") } - property VBusItem socLimitItem: VBusItem { bind: Utils.path(batteryLifePath, "/SocLimit") } - property VBusItem minSocLimitItem: VBusItem { bind: Utils.path(batteryLifePath, "/MinimumSocLimit") } - property VBusItem stateItem: VBusItem { bind: Utils.path(batteryLifePath, "/State") } - property VBusItem hub4Mode: VBusItem { bind: Utils.path(cgwacsPath, "/Hub4Mode") } - property VBusItem maxChargeCurrentControl: VBusItem { bind: "com.victronenergy.system/Control/MaxChargeCurrent" } - property VBusItem scheduleSoc: VBusItem { bind: "com.victronenergy.system/Control/ScheduledSoc" } - property VBusItem peakshaveItem: VBusItem { bind: Utils.path("com.victronenergy.settings", "/Settings/CGwacs/AlwaysPeakShave") } - - title: systemType.value === "Hub-4" ? systemType.value : qsTr("ESS") - model: systemType.value === "ESS" || systemType.value === "Hub-4" ? hub4Settings : noHub4 - - VisibleItemModel { - id: noHub4 - - MbItemText { - text: qsTr("No ESS Assistant found") - } - } - - function isBatteryLifeActive(state) { - switch (state) { - case batteryLifeStateRestart: - case batteryLifeStateDefault: - case batteryLifeStateAbsorption: - case batteryLifeStateFloat: - case batteryLifeStateDischarged: - case batteryLifeStateForceCharge: - case batteryLifeStateSustain: - case batteryLifeStateLowSocCharge: - return true - default: - return false - } - } - - function isBatterySocGuardActive(state) { - switch (state) { - case batterySocGuardDefault: - case batterySocGuardDischarged: - case batterySocGuardLowSocCharge: - return true - default: - return false - } - } - - VisibleItemModel { - id: hub4Settings - - MbItemOptions { - function getLocalValue(hub4Mode, state) { - if (hub4Mode === undefined || state === undefined) - return undefined - if (hub4Mode === hub4Disabled) - return 3 - if (isBatteryLifeActive(state)) - return 0 - if (isBatterySocGuardActive(state)) - return 1 - if (state === batteryKeepCharged) - return 2 - return 0 - } - - description: qsTr("Mode") - localValue: getLocalValue(hub4Mode.value, stateItem.value) - possibleValues:[ - MbOption { description: qsTr("Optimized (with BatteryLife)"); value: 0 }, - MbOption { description: qsTr("Optimized (without BatteryLife)"); value: 1 }, - MbOption { description: qsTr("Keep batteries charged"); value: 2 }, - MbOption { description: qsTr("External control"); value: 3 } - ] - onLocalValueChanged: { - if (localValue === undefined) - return - // Hub 4 mode - if (localValue === 3 && hub4Mode.value !== hub4Disabled) { - hub4Mode.setValue(hub4Disabled) - } else if (localValue !== 3 && hub4Mode.value === hub4Disabled) { - hub4Mode.setValue(hub4PhaseCompensation) - } - // BatteryLife state - switch (localValue) { - case 0: - if (!isBatteryLifeActive(stateItem.value)) - stateItem.setValue(batteryLifeStateRestart) - break - case 1: - if (!isBatterySocGuardActive(stateItem.value)) - stateItem.setValue(batterySocGuardDefault) - break - case 2: - stateItem.setValue(batteryKeepCharged) - break - case 3: - stateItem.setValue(batteryLifeStateDisabled) - break - } - } - } - - MbItemOptions { - id: withoutGridMeter - description: qsTr("Grid metering") - bind: Utils.path(cgwacsPath, '/RunWithoutGridMeter') - show: hub4Mode.value !== hub4Disabled - enabled: userHasWriteAccess - possibleValues:[ - MbOption { description: qsTr("External meter"); value: 0 }, - MbOption { description: qsTr("Inverter/Charger"); value: 1 } - ] - } - - MbSwitch { - bind: Utils.path(settingsPrefix, "/Settings/SystemSetup/HasAcOutSystem") - name: qsTr("Inverter AC output in use") - show: withoutGridMeter.value == 0 - } - - - MbItemOptions { - description: qsTr("Multiphase regulation") - bind: hub4Mode.bind - show: hub4Mode.value !== hub4Disabled && stateItem.value !== batteryKeepCharged - enabled: userHasWriteAccess - possibleValues:[ - MbOption { description: qsTr("Total of all phases"); value: hub4PhaseCompensation }, - MbOption { description: qsTr("Individual phase"); value: hub4PhaseSplit } - ] - onOptionSelected: { - if (newValue === hub4PhaseSplit) { - toast.createToast(qsTr("Each phase is regulated to individually achieve the grid setpoint (system efficiency is decreased).\n\n" + - "CAUTION: Use only if required by the utility provider"), 15000); - } else if (newValue === hub4PhaseCompensation) { - toast.createToast(qsTr("The total of all phases is intelligently regulated to achieve the grid setpoint (system efficiency is optimised).\n\n" + - "Use unless prohibited by the utility provider"), 15000); - } - } - } - - MbSpinBox { - id: minSocLimit - description: qsTr("Minimum SOC (unless grid fails)") - enabled: userHasWriteAccess - show: hub4Mode.value !== hub4Disabled && stateItem.value !== batteryKeepCharged - item { - bind: Utils.path(batteryLifePath, "/MinimumSocLimit") - decimals: 0 - unit: "%" - min: 0 - max: 100 - step: 5 - } - } - - MbItemValue { - id: socLimit - description: qsTr("Active SOC limit") - show: hub4Mode.value !== hub4Disabled && isBatteryLifeActive(stateItem.value) - item { - value: Math.max(minSocLimitItem.value, socLimitItem.value) - unit: '%' - } - } - - MbItemOptions { - description: qsTr("Peak shaving") - show: hub4Mode.value !== hub4Disabled - readonly: stateItem.value === batteryKeepCharged - possibleValues:[ - MbOption { description: qsTr("Above minimum SOC only"); value: 0 }, - MbOption { description: qsTr("Always"); value: 1 } - ] - value: stateItem.value === batteryKeepCharged ? 1 : peakshaveItem.value - onOptionSelected: { - peakshaveItem.setValue(newValue) - if (newValue === 1) { - toast.createToast(qsTr("Use this option for peak shaving.\n\n" + - "The peak shaving threshold is set using the AC input current limit setting.\n\n" + - "See documentation for further information."), 10000); - } else { - toast.createToast(qsTr("Use this option in systems that do not perform peak shaving."), 10000); - } - } - } - - MbItemOptions { - description: qsTr("BatteryLife state") - value: stateItem.value - readonly: true - show: hub4Mode.value !== hub4Disabled && isBatteryLifeActive(stateItem.value) - possibleValues:[ - // Values below taken from MaintenanceState enum in dbus-cgwacs - MbOption { description: qsTr("Self-consumption"); value: 2 }, - MbOption { description: qsTr("Self-consumption"); value: 3 }, - MbOption { description: qsTr("Self-consumption"); value: 4 }, - MbOption { description: qsTr("Discharge disabled"); value: 5 }, - MbOption { description: qsTr("Slow charge"); value: 6 }, - MbOption { description: qsTr("Sustain"); value: 7 }, - MbOption { description: qsTr("Recharge"); value: 8 } - ] - } - - MbSwitch { - id: maxChargePowerSwitch - name: qsTr("Limit charge power") - checked: maxChargePowerItem.value >= 0 - enabled: userHasWriteAccess - show: hub4Mode.value !== hub4Disabled && !(maxChargeCurrentControl.valid && maxChargeCurrentControl.value) - onCheckedChanged: { - if (checked && maxChargePowerItem.value < 0) - maxChargePowerItem.setValue(1000) - else if (!checked && maxChargePowerItem.value >= 0) - maxChargePowerItem.setValue(-1) - } - } - - MbSpinBox { - id: maxChargePower - description: qsTr("Maximum charge power") - enabled: userHasWriteAccess - show: maxChargePowerSwitch.show && maxChargePowerSwitch.checked - item { - bind: Utils.path(cgwacsPath, "/MaxChargePower") - decimals: 0 - unit: "W" - min: 0 - max: 200000 - step: 50 - } - } - - MbSwitch { - id: maxInverterPowerSwitch - name: qsTr("Limit inverter power") - checked: maxDischargePowerItem.value >= 0 - enabled: userHasWriteAccess - show: hub4Mode.value !== hub4Disabled && stateItem.value !== batteryKeepCharged - onCheckedChanged: { - if (checked && maxDischargePowerItem.value < 0) - maxDischargePowerItem.setValue(1000) - else if (!checked && maxDischargePowerItem.value >= 0) - maxDischargePowerItem.setValue(-1) - } - } - - MbSpinBox { - id: maxDischargePower - description: qsTr("Maximum inverter power") - enabled: userHasWriteAccess - show: maxInverterPowerSwitch.show && maxInverterPowerSwitch.checked - item { - bind: Utils.path(cgwacsPath, "/MaxDischargePower") - decimals: 0 - unit: "W" - min: 0 - max: 300000 - step: 50 - } - } - - MbSpinBox { - description: qsTr("Grid setpoint") - show: hub4Mode.value !== hub4Disabled && stateItem.value !== batteryKeepCharged - enabled: userHasWriteAccess - item { - bind: "com.victronenergy.settings/Settings/CGwacs/AcPowerSetPoint" - decimals: 0 - unit: "W" - step: 10 - } - } - - MbSubMenu { - id: feedinSetupItem - description: qsTr("Grid feed-in") - show: hub4Mode.value !== hub4Disabled - subpage: Component { - PageSettingsHub4Feedin { - title: feedinSetupItem.description - } - } - } - - MbSubMenu { - id: scheduleSettings - property string bindPrefix: "com.victronenergy.settings/Settings/CGwacs/BatteryLife/Schedule/Charge/" - description: qsTr("Scheduled charge levels") - show: hub4Mode.value !== hub4Disabled && stateItem.value !== batteryKeepCharged - item: VBusItem { value: scheduleSoc.valid ? qsTr("Active (%1)").arg(scheduleSoc.text) : qsTr("Inactive") } - subpage: Component { - MbPage { - title: scheduleSettings.description - model: VisibleItemModel { - ChargeScheduleItem { bindPrefix: scheduleSettings.bindPrefix; scheduleNumber: 0 } - ChargeScheduleItem { bindPrefix: scheduleSettings.bindPrefix; scheduleNumber: 1 } - ChargeScheduleItem { bindPrefix: scheduleSettings.bindPrefix; scheduleNumber: 2 } - ChargeScheduleItem { bindPrefix: scheduleSettings.bindPrefix; scheduleNumber: 3 } - ChargeScheduleItem { bindPrefix: scheduleSettings.bindPrefix; scheduleNumber: 4 } - } - } - } - } - - MbSubMenu { - id: deviceItem - description: qsTr("Debug") - show: hub4Mode.value !== hub4Disabled && user.accessLevel >= User.AccessService - backgroundColor: style.backgroundColorService - subpage: Component { - PageHub4Debug { } - } - } - } -} diff --git a/FileSets/v3.01/PageSettingsRelay.qml b/FileSets/v3.01/PageSettingsRelay.qml deleted file mode 120000 index 1b7ab4e1..00000000 --- a/FileSets/v3.01/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.22/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.01/PowerGauge.qml b/FileSets/v3.01/PowerGauge.qml deleted file mode 100644 index 3a3016dd..00000000 --- a/FileSets/v3.01/PowerGauge.qml +++ /dev/null @@ -1,317 +0,0 @@ -// displays value as a bar surrounded by three range regions -// use for I/O, PV inverter & charger - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 - -Item { - id: root - -////// GuiMods — DarkMode - property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } - property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 - - property variant connection - // connection2 accommodates combined PV inverter AC input and AC output - property variant connection2: undefined - property bool includeConnection2: connection2 != undefined - - property bool reversePower: false - property bool useInputCurrentLimit: false - property variant endLabelFontSize: 16 - property color endLabelBackgroundColor: "transparent" - - property int phaseCount1: root.connection == undefined ? 0 : root.connection.l1AndL2OutShorted ? 1 : connection.phaseCount != undefined && connection.phaseCount.valid ? connection.phaseCount.value : 1 - property int phaseCount2: root.connection2 == undefined ? 0 : root.connection2.l1AndL2OutShorted ? 1 : connection2.phaseCount != undefined && connection2.phaseCount.valid ? connection2.phaseCount.value : 1 - property int phaseCount: includeConnection2 ? Math.max (phaseCount1, phaseCount2) : phaseCount1 - - - property string maxForwardPowerParameter: "" - VBusItem { id: maxForwardLimitItem; bind: root.maxForwardPowerParameter } - property string maxForwardPowerParameter2: "" - VBusItem { id: maxForwardLimitItem2; bind: root.maxForwardPowerParameter2 } - - property string maxReversePowerParameter: "" - VBusItem { id: maxReverseLimitItem; bind: root.maxReversePowerParameter } - - property real inPowerLimit: sys.acInput.inCurrentLimit.valid ? sys.acInput.inCurrentLimit.value * sys.acInput.voltageL1.value : 0 - - property real maxForwardPower1: maxForwardLimitItem.valid ? maxForwardLimitItem.value : 0 - property real maxForwardPower2: maxForwardLimitItem2.valid ? maxForwardLimitItem2.value : 0 - property real maxForwardLimit: useInputCurrentLimit ? inPowerLimit : maxForwardPower1 + maxForwardPower2 - property real maxReverseLimit: maxReverseLimitItem.valid ? maxReverseLimitItem.value : 0 - // overload range is 10% of forward to reverse limits - property real overload: (maxForwardLimit + maxReverseLimit) * 0.1 - property real maxForwardDisplayed: maxForwardLimit > 0 ? maxForwardLimit + overload : 0 - property real maxReverseDisplayed: maxReverseLimit > 0 ? maxReverseLimit + overload : 0 - property real totalPowerDisplayed: maxForwardDisplayed + maxReverseDisplayed - - property bool showLabels: false - property variant endLabelColor: "white" - property real labelOffset: 15 - property real showLeftLabel: showGauge && showLabels && maxReverseLimit != 0 - property bool showRightLabel: showGauge && showLabels && maxForwardLimit != 0 - property int labelCount: (showLeftLabel ? 1 : 0) + (showRightLabel ? 1 : 0) - - property bool showGauge: root.connection != undefined && totalPowerDisplayed > 0 && phaseCount > 0 - property real scaleFactor: showGauge ? (root.width - (labelCount * labelOffset)) / totalPowerDisplayed : 0 - property real zeroOffset: showGauge ? ( maxReverseDisplayed * scaleFactor + (showLeftLabel ? labelOffset : 0 )) : 0 - - property int barSpacing: phaseCount > 0 ? Math.max (height / (phaseCount + 1), 2) : 0 - property int barHeight: barSpacing < 3 ? barSpacing : barSpacing - 1 - property int firstBarVertPos: (height - barSpacing * phaseCount) / 2 - property real bar1offset - property real bar2offset - property real bar3offset - - property color bar1color: "black" - property color bar2color: "black" - property color bar3color: "black" - - // left end label - Rectangle - { - anchors.fill: leftlabelText - color: endLabelBackgroundColor - visible: showLeftLabel - } - TileText - { - id: leftlabelText - text: "S" - color: endLabelColor - font.pixelSize: endLabelFontSize - width: labelOffset - anchors - { - verticalCenter: root.verticalCenter - verticalCenterOffset: 1 - left: root.left - } - visible: showLeftLabel - } - // right end label - Rectangle - { - anchors.fill: rightLabelText - color: endLabelBackgroundColor - visible: showRightLabel - } - TileText - { - id: rightLabelText - text: "C" - color: endLabelColor - font.pixelSize: endLabelFontSize - width: labelOffset - anchors - { - verticalCenter: leftlabelText.verticalCenter - right: root.right - } - visible: showRightLabel - } - // overload range Left - Rectangle - { - id: overloadLeft - width: showGauge ? scaleFactor * (maxReverseDisplayed - maxReverseLimit) : 0 - height: root.height - clip: true -////// GuiMods — DarkMode - color: !darkMode ? "#ffb3b3" : "#bf8686" - visible: showGauge - anchors - { - top: root.top - left: root.left; leftMargin: showLeftLabel ? labelOffset : 0 - } - } - // OK range (both left and right in a single rectangle) - Rectangle - { - id: okRange - width: showGauge ? scaleFactor * (maxForwardLimit + maxReverseLimit) : 0 - height: root.height - clip: true -////// GuiMods — DarkMode - color: !darkMode ? "#99ff99" : "#73bf73" - visible: showGauge - anchors - { - top: root.top - left: overloadLeft.right - } - } - // overload range right - Rectangle - { - id: overloadRight - width: showGauge ? scaleFactor * (maxForwardDisplayed - maxForwardLimit) : 0 - height: root.height - clip: true -////// GuiMods — DarkMode - color: !darkMode ? "#ffb3b3" : "#bf8686" - visible: showGauge - anchors - { - top: root.top - left: okRange.right - } - } - - // actual bars - Rectangle - { - id: bar1 - width: phaseCount >= 1 ? calculateBar1width () : 0 - height: barHeight - clip: true - color: root.bar1color - anchors - { - top: root.top; topMargin: firstBarVertPos - left: root.left; leftMargin: root.bar1offset - - } - visible: showGauge && phaseCount >= 1 - } - Rectangle - { - id: bar2 - width: phaseCount >= 2 ? calculateBar2width () : 0 - height: barHeight - clip: true - color: root.bar2color - anchors - { - top: root.top; topMargin: firstBarVertPos + barSpacing - left: root.left; leftMargin: root.bar2offset - } - visible: showGauge && phaseCount >= 2 - } - Rectangle - { - id: bar3 - width: phaseCount >= 3 ? calculateBar3width () : 0 - height: barHeight - clip: true - color: root.bar3color - anchors - { - top: root.top; topMargin: firstBarVertPos + barSpacing * 2 - left: root.left; leftMargin: root.bar3offset - } - visible: showGauge && phaseCount >= 3 - } - - // zero line - draw last so it's on top - Rectangle - { - id: zeroLine - width: 1 - height: root.height - clip: true - color: "black" - visible: showGauge && maxReverseLimit > 0 - anchors - { - top: root.top - left: root.left - leftMargin: zeroOffset - } - } - - function calculateBar1width () - { - var currentValue, barWidth - if (root.connection.powerL1 != undefined) - currentValue += root.connection.powerL1.valid ? root.connection.powerL1.value : 0 - else if (root.connection.power != undefined) - currentValue += root.connection.power.valid ? root.connection.power.value : 0 - if (includeConnection2) - { - if (root.connection2.powerL1 != undefined) - currentValue += root.connection2.powerL1.valid ? root.connection2.powerL1.value : 0 - else if (root.connection2.power != undefined) - currentValue += root.connection2.power.valid ? root.connection2.power.value : 0 - } - - if (reversePower) - currentValue = -currentValue - - root.bar1color = getBarColor (currentValue) - barWidth = Math.min ( Math.max (currentValue, -maxReverseDisplayed), maxForwardDisplayed) * scaleFactor - // left of bar is at 0 point - if (barWidth >= 0) - { - root.bar1offset = zeroOffset - return barWidth - } - // RIGHT of bar is at 0 point - else - { - root.bar1offset = zeroOffset + barWidth - return -barWidth - } - } - function calculateBar2width () - { - var currentValue, barWidth - currentValue = root.connection.powerL2.valid ? root.connection.powerL2.value : 0 - if (includeConnection2) - currentValue += root.connection2.powerL2.valid ? root.connection2.powerL2.value : 0 - - if (reversePower) - currentValue = -currentValue - root.bar2color = getBarColor (currentValue) - barWidth = Math.min ( Math.max (currentValue, -maxReverseDisplayed), maxForwardDisplayed) * scaleFactor - // left of bar is at 0 point - if (barWidth >= 0) - { - root.bar2offset = zeroOffset - return barWidth - } - // RIGHT of bar is at 0 point - else - { - root.bar2offset = zeroOffset + barWidth - return -barWidth - } - } - function calculateBar3width () - { - var currentValue, barWidth - currentValue = root.connection.powerL3.valid ? root.connection.powerL3.value : 0 - if (includeConnection2) - currentValue += root.connection2.powerL3.valid ? root.connection2.powerL3.value : 0 - - if (reversePower) - currentValue = -currentValue - root.bar3color = getBarColor (currentValue) - barWidth = Math.min ( Math.max (currentValue, -maxReverseDisplayed), maxForwardDisplayed) * scaleFactor - // left of bar is at 0 point - if (barWidth >= 0) - { - root.bar3offset = zeroOffset - return barWidth - } - // RIGHT of bar is at 0 point - else - { - root.bar3offset = zeroOffset + barWidth - return -barWidth - } - } - - function getBarColor (currentValue) - { - if (currentValue > maxForwardLimit || currentValue < -maxReverseLimit) -////// GuiMods — DarkMode - return !darkMode ? "#ff0000" : "#bf0000" - else -////// GuiMods — DarkMode - return !darkMode ? "#008000" : "#006000" - } -} diff --git a/FileSets/v3.01/PowerGauge.qml.orig b/FileSets/v3.01/PowerGauge.qml.orig deleted file mode 100644 index daca5afc..00000000 --- a/FileSets/v3.01/PowerGauge.qml.orig +++ /dev/null @@ -1,167 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -Item { - id: root - - property string systemPrefix: "com.victronenergy.system" - property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" - - property variant battery: _battery - property alias dcSystem: _dcSystem - property alias pvCharger: _pvCharger - property alias pvOnAcIn1: _pvOnAcIn1 - property alias pvOnAcIn2: _pvOnAcIn2 - property alias pvOnAcOut: _pvOnAcOut - property alias vebusDc: _vebusDc - property alias acLoad: _acLoad - property alias acInLoad: _acInLoad - property alias acOutLoad: _acOutLoad - property alias grid: _grid - property alias genset: _genset - property alias acInput: _activein - property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } - property variant acSource: _acSource.value - - property alias pvOnGrid: _pvOnAcIn2 - - property int batteryStateIdle: 0 - property int batteryStateCharging: 1 - property int batteryStateDischarging: 2 - - property int acSourceNotAvailable: 0 - property int acSourceGrid: 1 - property int acSourceGenset: 2 - property int acSourceShore: 3 // same as grid - - property alias pvInvertersProductIds: _pvInvertersProductIds - property alias batteryProductId: _batteryProductId - - VBusItem { - id: _pvInvertersProductIds - bind: Utils.path(systemPrefix, "/PvInvertersProductIds") - } - - VBusItem { - id: _batteryProductId - bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") - } - - VBusItem { - id: _vebusService - bind: Utils.path(systemPrefix, "/VebusService") - } - - QtObject { - id: _pvCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} - } - - ObjectAcConnection { - id: _pvOnAcOut - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") - } - - ObjectAcConnection { - id: _pvOnAcIn1 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") - } - - ObjectAcConnection { - id: _pvOnAcIn2 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") - } - - ObjectAcConnection { - id: _genset - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") - } - - VBusItem { - id: _acSource - bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") - } - - /* - * Single Multis that can be split-phase reports NrOfPhases of 2 - * When L2 is disconnected from the input the output L1 and L2 - * are shorted. This item indicates if L2 is passed through - * from AC-in to AC-out. - * 1: L2 is being passed through from AC-in to AC-out. - * 0: L1 and L2 are shorted together. - * invalid: The unit is configured in such way that its L2 output is not used. - */ - - VBusItem { - id: _splitPhaseL2Passthru - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2Passthru") - } - - ObjectAcConnection { - id: _grid - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") - } - - ObjectAcConnection { - id: _activein - bindPrefix: Utils.path(systemPrefix, "/Ac/ActiveIn") - } - - ObjectAcConnection { - id: _acLoad - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") - } - - ObjectAcConnection { - id: _acOutLoad - splitPhaseL2PassthruDisabled:_splitPhaseL2Passthru.value === 0 - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") - } - - ObjectAcConnection { - id: _acInLoad - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") - } - - ObjectAcConnection { - id: _acUnknown - } - - QtObject { - id: _vebusDc - /* - * property VBusItem power: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Power"); unit: "W"} - * DONE: can interface doesn't support this yet! TODO use it...? - */ - property VBusItem current: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Current"); unit: "A"} - property VBusItem voltage: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Voltage"); unit: "V"} - property VBusItem power: VBusItem { - value: _vebusDc.current.valid && _vebusDc.voltage.valid ? - _vebusDc.current.value * _vebusDc.voltage.value : - undefined - unit: "W" - } - } - - QtObject { - id: _battery - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} - property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} - property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} - property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} - - // Get the battery charge state, see batteryState properties - property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} - } - - QtObject { - id: _dcSystem - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} - } -} diff --git a/FileSets/v3.01/Tile.qml b/FileSets/v3.01/Tile.qml deleted file mode 120000 index 0558cecf..00000000 --- a/FileSets/v3.01/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.01/TileDigIn.qml.orig b/FileSets/v3.01/TileDigIn.qml.orig deleted file mode 100755 index d9c90083..00000000 --- a/FileSets/v3.01/TileDigIn.qml.orig +++ /dev/null @@ -1,584 +0,0 @@ -#!/usr/bin/python3 -u - -import sys, os -import signal -from threading import Thread -from select import select, epoll, EPOLLPRI -from functools import partial -from collections import namedtuple -from argparse import ArgumentParser -import traceback -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) - -from dbus.mainloop.glib import DBusGMainLoop -import dbus -from gi.repository import GLib -from vedbus import VeDbusService, VeDbusItemImport -from settingsdevice import SettingsDevice - -VERSION = '0.19' -MAXCOUNT = 2**31-1 -SAVEINTERVAL = 60000 - -INPUT_FUNCTION_COUNTER = 1 -INPUT_FUNCTION_INPUT = 2 - -Translation = namedtuple('Translation', ['no', 'yes']) - -# Only append at the end -INPUTTYPES = [ - 'Disabled', - 'Pulse meter', - 'Door', - 'Bilge pump', - 'Bilge alarm', - 'Burglar alarm', - 'Smoke alarm', - 'Fire alarm', - 'CO2 alarm', - 'Generator', - 'Generic I/O', - 'Touch enable', -] - -# Translations. The text will be used only for GetText, it will be translated -# in the gui. -TRANSLATIONS = [ - Translation('low', 'high'), - Translation('off', 'on'), - Translation('no', 'yes'), - Translation('open', 'closed'), - Translation('ok', 'alarm'), - Translation('running', 'stopped') -] - -class SystemBus(dbus.bus.BusConnection): - def __new__(cls): - return dbus.bus.BusConnection.__new__(cls, dbus.bus.BusConnection.TYPE_SYSTEM) - -class SessionBus(dbus.bus.BusConnection): - def __new__(cls): - return dbus.bus.BusConnection.__new__(cls, dbus.bus.BusConnection.TYPE_SESSION) - -class BasePulseCounter(object): - pass - -class DebugPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - - def register(self, path, gpio): - self.gpiomap[gpio] = None - return 0 - - def unregister(self, gpio): - del self.gpiomap[gpio] - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - from itertools import cycle - from time import sleep - for level in cycle([0, 1]): - for gpio in list(self.gpiomap.keys()): - yield gpio, level - sleep(0.25/len(self.gpiomap)) - -class EpollPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - self.states = {} - self.ob = epoll() - - def register(self, path, gpio): - path = os.path.realpath(path) - - # Set up gpio for rising edge interrupts - with open(os.path.join(path, 'edge'), 'ab') as fp: - fp.write(b'both') - - fp = open(os.path.join(path, 'value'), 'rb') - level = int(fp.read()) # flush it in case it's high at startup - self.gpiomap[gpio] = fp - self.states[gpio] = level - self.ob.register(fp, EPOLLPRI) - return level - - def unregister(self, gpio): - fp = self.gpiomap[gpio] - self.ob.unregister(fp) - del self.gpiomap[gpio] - del self.states[gpio] - fp.close() - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - while True: - # We have a timeout of 1 second on the poll, because poll() only - # looks at files in the epoll object at the time poll() was called. - # The timeout means we let other files (added via calls to - # register/unregister) into the loop at least that often. - self.ob.poll(1) - - # When coming out of the epoll call, we read all the gpios to make - # sure we didn't miss any edges. This is a safety fallback that - # ensures everything is up to date once a second, but - # edge-triggered results are handled immediately. - # NOTE: There has not been a report of a missed interrupt yet. - # Belts and suspenders. - for gpio, fp in list(self.gpiomap.items()): - os.lseek(fp.fileno(), 0, os.SEEK_SET) - v = int(os.read(fp.fileno(), 1)) - if v != self.states[gpio]: - self.states[gpio] = v - yield gpio, v - -class PollingPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - - def register(self, path, gpio): - path = os.path.realpath(path) - - fp = open(os.path.join(path, 'value'), 'rb') - level = int(fp.read()) - self.gpiomap[gpio] = [fp, level] - return level - - def unregister(self, gpio): - del self.gpiomap[gpio] - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - from itertools import cycle - from time import sleep - while True: - for gpio, (fp, level) in list(self.gpiomap.items()): - fp.seek(0, os.SEEK_SET) - v = int(fp.read()) - if v != level: - self.gpiomap[gpio][1] = v - yield gpio, v - sleep(1) - -class HandlerMaker(type): - """ Meta-class for keeping track of all extended classes. """ - def __init__(cls, name, bases, attrs): - if not hasattr(cls, 'handlers'): - cls.handlers = {} - else: - cls.handlers[cls.type_id] = cls - -class PinHandler(object, metaclass=HandlerMaker): - product_id = 0xFFFF - _product_name = 'Generic GPIO' - dbus_name = "digital" - def __init__(self, bus, base, path, gpio, settings): - self.gpio = gpio - self.path = path - self.bus = bus - self.settings = settings - self._level = 0 # Remember last state - - self.service = VeDbusService( - "{}.{}.input{:02d}".format(base, self.dbus_name, gpio), bus=bus) - - # Add objects required by ve-api - self.service.add_path('/Mgmt/ProcessName', __file__) - self.service.add_path('/Mgmt/ProcessVersion', VERSION) - self.service.add_path('/Mgmt/Connection', path) - self.service.add_path('/DeviceInstance', gpio) - self.service.add_path('/ProductId', self.product_id) - self.service.add_path('/ProductName', self.product_name) - self.service.add_path('/Connected', 1) - - # Custom name setting - def _change_name(p, v): - # This should fire a change event that will update product_name - # below. - settings['name'] = v - return True - - self.service.add_path('/CustomName', settings['name'], writeable=True, - onchangecallback=_change_name) - - # We'll count the pulses for all types of services - self.service.add_path('/Count', value=settings['count']) - - @property - def product_name(self): - return self.settings['name'] or self._product_name - - @product_name.setter - def product_name(self, v): - # Some pin types don't have an associated service (Disabled pins for - # example) - if self.service is not None: - self.service['/ProductName'] = v or self._product_name - - def deactivate(self): - self.save_count() - self.service.__del__() - del self.service - self.service = None - - @property - def level(self): - return self._level - - @level.setter - def level(self, l): - self._level = int(bool(l)) - - def toggle(self, level): - raise NotImplementedError - - def _toggle(self, level, service): - # Only increment Count on rising edge. - if level and level != self._level: - service['/Count'] = (service['/Count']+1) % MAXCOUNT - self._level = level - - def refresh(self): - """ Toggle state to last remembered state. This is called if settings - are changed so the Service can recalculate paths. """ - self.toggle(self._level) - - def save_count(self): - if self.service is not None: - self.settings['count'] = self.count - - @property - def active(self): - return self.service is not None - - @property - def count(self): - return self.service['/Count'] - - @count.setter - def count(self, v): - self.service['/Count'] = v - - @classmethod - def createHandler(cls, _type, *args, **kwargs): - if _type in cls.handlers: - return cls.handlers[_type](*args, **kwargs) - return None - - -class NopPin(object): - """ Mixin for a pin with empty behaviour. Mix in BEFORE PinHandler so that - __init__ overrides the base behaviour. """ - def __init__(self, bus, base, path, gpio, settings): - self.service = None - self.bus = bus - self.settings = settings - self._level = 0 # Remember last state - - def deactivate(self): - pass - - def toggle(self, level): - self._level = level - - def save_count(self): - # Do nothing - pass - - @property - def count(self): - return self.settings['count'] - - @count.setter - def count(self, v): - pass - - def refresh(self): - pass - - -class DisabledPin(NopPin, PinHandler): - """ Place holder for a disabled pin. """ - _product_name = 'Disabled' - type_id = 0 - - -class VolumeCounter(PinHandler): - product_id = 0xA165 - _product_name = "Generic pulse meter" - dbus_name = "pulsemeter" - type_id = 1 - - def __init__(self, bus, base, path, gpio, settings): - super(VolumeCounter, self).__init__(bus, base, path, gpio, settings) - self.service.add_path('/Aggregate', value=self.count*self.rate, - gettextcallback=lambda p, v: (str(v) + ' cubic meter')) - - @property - def rate(self): - return self.settings['rate'] - - def toggle(self, level): - with self.service as s: - super(VolumeCounter, self)._toggle(level, s) - s['/Aggregate'] = self.count * self.rate - -class TouchEnable(NopPin, PinHandler): - """ The pin is used to enable/disable the Touch screen when toggled. - No dbus-service is created. """ - _product_name = 'TouchEnable' - type_id = 11 - - def __init__(self, *args, **kwargs): - super(TouchEnable, self).__init__(*args, **kwargs) - self.item = VeDbusItemImport(self.bus, - "com.victronenergy.settings", "/Settings/Gui/TouchEnabled") - - def toggle(self, level): - super(TouchEnable, self).toggle(level) - - # Toggle the touch-enable setting on the downward edge. - # Level is expected to be high with the switch open, and - # pulled low when pushed. - if level == 0: - enabled = bool(self.item.get_value()) - self.item.set_value(int(not enabled)) - - def deactivate(self): - # Always re-enable touch when the pin is deactivated. - # This adds another layer of protection against accidental - # lockout. - self.item.set_value(1) - del self.item - -class PinAlarm(PinHandler): - product_id = 0xA166 - _product_name = "Generic digital input" - dbus_name = "digitalinput" - type_id = 0xFF - translation = 0 # low, high - - def __init__(self, bus, base, path, gpio, settings): - super(PinAlarm, self).__init__(bus, base, path, gpio, settings) - self.service.add_path('/InputState', value=0) - self.service.add_path('/State', value=self.get_state(0), - gettextcallback=lambda p, v: TRANSLATIONS[v//2][v%2]) - self.service.add_path('/Alarm', value=self.get_alarm_state(0)) - - # Also expose the type - self.service.add_path('/Type', value=self.type_id, - gettextcallback=lambda p, v: INPUTTYPES[v]) - - def toggle(self, level): - with self.service as s: - super(PinAlarm, self)._toggle(level, s) - s['/InputState'] = bool(level)*1 - s['/State'] = self.get_state(level) - # Ensure that the alarm flag resets if the /AlarmSetting config option - # disappears. - s['/Alarm'] = self.get_alarm_state(level) - - def get_state(self, level): - state = level ^ self.settings['invert'] - return 2 * self.translation + state - - def get_alarm_state(self, level): - return 2 * bool( - (level ^ self.settings['invertalarm']) and self.settings['alarm']) - - -# Various types of things we might want to monitor -class DoorSensor(PinAlarm): - _product_name = "Door alarm" - type_id = 2 - translation = 3 # open, closed - -class BilgePump(PinAlarm): - _product_name = "Bilge pump" - type_id = 3 - translation = 1 # off, on - -class BilgeAlarm(PinAlarm): - _product_name = "Bilge alarm" - type_id = 4 - translation = 4 # ok, alarm - -class BurglarAlarm(PinAlarm): - _product_name = "Burglar alarm" - type_id = 5 - translation = 4 # ok, alarm - -class SmokeAlarm(PinAlarm): - _product_name = "Smoke alarm" - type_id = 6 - translation = 4 # ok, alarm - -class FireAlarm(PinAlarm): - _product_name = "Fire alarm" - type_id = 7 - translation = 4 # ok, alarm - -class CO2Alarm(PinAlarm): - _product_name = "CO2 alarm" - type_id = 8 - translation = 4 # ok, alarm - -class Generator(PinAlarm): - _product_name = "Generator" - type_id = 9 - translation = 5 # running, stopped - -class GenericIO(PinAlarm): - _product_name = "Generic I/O" - type_id = 10 - translation = 0 # low, high - - -def dbusconnection(): - return SessionBus() if 'DBUS_SESSION_BUS_ADDRESS' in os.environ else SystemBus() - - -def main(): - parser = ArgumentParser(description=sys.argv[0]) - parser.add_argument('--servicebase', - help='Base service name on dbus, default is com.victronenergy', - default='com.victronenergy') - parser.add_argument('--poll', - help='Use a different kind of polling. Options are epoll, dumb and debug', - default='epoll') - parser.add_argument('inputs', nargs='+', help='Path to digital input') - args = parser.parse_args() - - PulseCounter = { - 'debug': DebugPulseCounter, - 'poll': PollingPulseCounter, - }.get(args.poll, EpollPulseCounter) - - DBusGMainLoop(set_as_default=True) - - # Keep track of enabled services - services = {} - inputs = dict(enumerate(args.inputs, 1)) - pulses = PulseCounter() # callable that iterates over pulses - - def register_gpio(path, gpio, bus, settings): - _type = settings['inputtype'] - print ("Registering GPIO {} for type {}".format(gpio, _type)) - - handler = PinHandler.createHandler(_type, - bus, args.servicebase, path, gpio, settings) - services[gpio] = handler - - # Only monitor if enabled - if _type > 0: - handler.level = pulses.register(path, gpio) - handler.refresh() - - def unregister_gpio(gpio): - print ("unRegistering GPIO {}".format(gpio)) - pulses.unregister(gpio) - services[gpio].deactivate() - - def handle_setting_change(inp, setting, old, new): - # This handler may also be called if some attribute of a setting - # is changed, but not the value. Bail if the value is unchanged. - if old == new: - return - - if setting == 'inputtype': - if new: - # Get current bus and settings objects, to be reused - service = services[inp] - bus, settings = service.bus, service.settings - - # Input enabled. If already enabled, unregister the old one first. - if pulses.registered(inp): - unregister_gpio(inp) - - # Before registering the new input, reset its settings to defaults - settings['count'] = 0 - settings['invert'] = 0 - settings['invertalarm'] = 0 - settings['alarm'] = 0 - - # Register it - register_gpio(inputs[inp], inp, bus, settings) - elif old: - # Input disabled - unregister_gpio(inp) - elif setting in ('rate', 'invert', 'alarm', 'invertalarm'): - services[inp].refresh() - elif setting == 'name': - services[inp].product_name = new - elif setting == 'count': - # Don't want this triggered on a period save, so only execute - # if it has changed. - v = int(new) - s = services[inp] - if s.count != v: - s.count = v - s.refresh() - - for inp, pth in inputs.items(): - supported_settings = { - 'inputtype': ['/Settings/DigitalInput/{}/Type'.format(inp), 0, 0, len(INPUTTYPES)-1], - 'rate': ['/Settings/DigitalInput/{}/Multiplier'.format(inp), 0.001, 0, 1.0], - 'count': ['/Settings/DigitalInput/{}/Count'.format(inp), 0, 0, MAXCOUNT, 1], - 'invert': ['/Settings/DigitalInput/{}/InvertTranslation'.format(inp), 0, 0, 1], - 'invertalarm': ['/Settings/DigitalInput/{}/InvertAlarm'.format(inp), 0, 0, 1], - 'alarm': ['/Settings/DigitalInput/{}/AlarmSetting'.format(inp), 0, 0, 1], - 'name': ['/Settings/DigitalInput/{}/CustomName'.format(inp), '', '', ''], - } - bus = dbusconnection() - sd = SettingsDevice(bus, supported_settings, partial(handle_setting_change, inp), timeout=10) - register_gpio(pth, inp, bus, sd) - - def poll(mainloop): - from time import time - idx = 0 - - try: - for inp, level in pulses(): - # epoll object only resyncs once a second. We may receive - # a pulse for something that's been deregistered. - try: - services[inp].toggle(level) - except KeyError: - continue - except: - traceback.print_exc() - mainloop.quit() - - # Need to run the gpio polling in separate thread. Pass in the mainloop so - # the thread can kill us if there is an exception. - mainloop = GLib.MainLoop() - - poller = Thread(target=lambda: poll(mainloop)) - poller.daemon = True - poller.start() - - # Periodically save the counter - def save_counters(): - for inp in inputs: - services[inp].save_count() - return True - GLib.timeout_add(SAVEINTERVAL, save_counters) - - # Save counter on shutdown - signal.signal(signal.SIGTERM, lambda *args: sys.exit(0)) - - try: - mainloop.run() - except KeyboardInterrupt: - pass - finally: - save_counters() - -if __name__ == "__main__": - main() diff --git a/FileSets/v3.01/TileRelay.qml b/FileSets/v3.01/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.01/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.01/TileText.qml b/FileSets/v3.01/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v3.01/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.01/dbus_digitalinputs.py b/FileSets/v3.01/dbus_digitalinputs.py deleted file mode 100755 index 2ee09d55..00000000 --- a/FileSets/v3.01/dbus_digitalinputs.py +++ /dev/null @@ -1,596 +0,0 @@ -#!/usr/bin/python3 -u - -#### modified for ExtTransferSwitch package - -import sys, os -import signal -from threading import Thread -from select import select, epoll, EPOLLPRI -from functools import partial -from collections import namedtuple -from argparse import ArgumentParser -import traceback -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) - -from dbus.mainloop.glib import DBusGMainLoop -import dbus -from gi.repository import GLib -from vedbus import VeDbusService, VeDbusItemImport -from settingsdevice import SettingsDevice - -VERSION = '0.19' -MAXCOUNT = 2**31-1 -SAVEINTERVAL = 60000 - -INPUT_FUNCTION_COUNTER = 1 -INPUT_FUNCTION_INPUT = 2 - -Translation = namedtuple('Translation', ['no', 'yes']) - -# Only append at the end -INPUTTYPES = [ - 'Disabled', - 'Pulse meter', - 'Door', - 'Bilge pump', - 'Bilge alarm', - 'Burglar alarm', - 'Smoke alarm', - 'Fire alarm', - 'CO2 alarm', - 'Generator', - 'Generic I/O', - 'Touch enable', -#### added for ExtTransferSwitch package -- must be LAST in the list - 'Transfer switch' -] - -# Translations. The text will be used only for GetText, it will be translated -# in the gui. -TRANSLATIONS = [ - Translation('low', 'high'), - Translation('off', 'on'), - Translation('no', 'yes'), - Translation('open', 'closed'), - Translation('ok', 'alarm'), - Translation('running', 'stopped'), -#### added for ExtTransferSwitch package - Translation('on generator', 'on grid') -] - -class SystemBus(dbus.bus.BusConnection): - def __new__(cls): - return dbus.bus.BusConnection.__new__(cls, dbus.bus.BusConnection.TYPE_SYSTEM) - -class SessionBus(dbus.bus.BusConnection): - def __new__(cls): - return dbus.bus.BusConnection.__new__(cls, dbus.bus.BusConnection.TYPE_SESSION) - -class BasePulseCounter(object): - pass - -class DebugPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - - def register(self, path, gpio): - self.gpiomap[gpio] = None - return 0 - - def unregister(self, gpio): - del self.gpiomap[gpio] - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - from itertools import cycle - from time import sleep - for level in cycle([0, 1]): - for gpio in list(self.gpiomap.keys()): - yield gpio, level - sleep(0.25/len(self.gpiomap)) - -class EpollPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - self.states = {} - self.ob = epoll() - - def register(self, path, gpio): - path = os.path.realpath(path) - - # Set up gpio for rising edge interrupts - with open(os.path.join(path, 'edge'), 'ab') as fp: - fp.write(b'both') - - fp = open(os.path.join(path, 'value'), 'rb') - level = int(fp.read()) # flush it in case it's high at startup - self.gpiomap[gpio] = fp - self.states[gpio] = level - self.ob.register(fp, EPOLLPRI) - return level - - def unregister(self, gpio): - fp = self.gpiomap[gpio] - self.ob.unregister(fp) - del self.gpiomap[gpio] - del self.states[gpio] - fp.close() - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - while True: - # We have a timeout of 1 second on the poll, because poll() only - # looks at files in the epoll object at the time poll() was called. - # The timeout means we let other files (added via calls to - # register/unregister) into the loop at least that often. - self.ob.poll(1) - - # When coming out of the epoll call, we read all the gpios to make - # sure we didn't miss any edges. This is a safety fallback that - # ensures everything is up to date once a second, but - # edge-triggered results are handled immediately. - # NOTE: There has not been a report of a missed interrupt yet. - # Belts and suspenders. - for gpio, fp in list(self.gpiomap.items()): - os.lseek(fp.fileno(), 0, os.SEEK_SET) - v = int(os.read(fp.fileno(), 1)) - if v != self.states[gpio]: - self.states[gpio] = v - yield gpio, v - -class PollingPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - - def register(self, path, gpio): - path = os.path.realpath(path) - - fp = open(os.path.join(path, 'value'), 'rb') - level = int(fp.read()) - self.gpiomap[gpio] = [fp, level] - return level - - def unregister(self, gpio): - del self.gpiomap[gpio] - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - from itertools import cycle - from time import sleep - while True: - for gpio, (fp, level) in list(self.gpiomap.items()): - fp.seek(0, os.SEEK_SET) - v = int(fp.read()) - if v != level: - self.gpiomap[gpio][1] = v - yield gpio, v - sleep(1) - -class HandlerMaker(type): - """ Meta-class for keeping track of all extended classes. """ - def __init__(cls, name, bases, attrs): - if not hasattr(cls, 'handlers'): - cls.handlers = {} - else: - cls.handlers[cls.type_id] = cls - -class PinHandler(object, metaclass=HandlerMaker): - product_id = 0xFFFF - _product_name = 'Generic GPIO' - dbus_name = "digital" - def __init__(self, bus, base, path, gpio, settings): - self.gpio = gpio - self.path = path - self.bus = bus - self.settings = settings - self._level = 0 # Remember last state - - self.service = VeDbusService( - "{}.{}.input{:02d}".format(base, self.dbus_name, gpio), bus=bus) - - # Add objects required by ve-api - self.service.add_path('/Mgmt/ProcessName', __file__) - self.service.add_path('/Mgmt/ProcessVersion', VERSION) - self.service.add_path('/Mgmt/Connection', path) - self.service.add_path('/DeviceInstance', gpio) - self.service.add_path('/ProductId', self.product_id) - self.service.add_path('/ProductName', self.product_name) - self.service.add_path('/Connected', 1) - - # Custom name setting - def _change_name(p, v): - # This should fire a change event that will update product_name - # below. - settings['name'] = v - return True - - self.service.add_path('/CustomName', settings['name'], writeable=True, - onchangecallback=_change_name) - - # We'll count the pulses for all types of services - self.service.add_path('/Count', value=settings['count']) - - @property - def product_name(self): - return self.settings['name'] or self._product_name - - @product_name.setter - def product_name(self, v): - # Some pin types don't have an associated service (Disabled pins for - # example) - if self.service is not None: - self.service['/ProductName'] = v or self._product_name - - def deactivate(self): - self.save_count() - self.service.__del__() - del self.service - self.service = None - - @property - def level(self): - return self._level - - @level.setter - def level(self, l): - self._level = int(bool(l)) - - def toggle(self, level): - raise NotImplementedError - - def _toggle(self, level, service): - # Only increment Count on rising edge. - if level and level != self._level: - service['/Count'] = (service['/Count']+1) % MAXCOUNT - self._level = level - - def refresh(self): - """ Toggle state to last remembered state. This is called if settings - are changed so the Service can recalculate paths. """ - self.toggle(self._level) - - def save_count(self): - if self.service is not None: - self.settings['count'] = self.count - - @property - def active(self): - return self.service is not None - - @property - def count(self): - return self.service['/Count'] - - @count.setter - def count(self, v): - self.service['/Count'] = v - - @classmethod - def createHandler(cls, _type, *args, **kwargs): - if _type in cls.handlers: - return cls.handlers[_type](*args, **kwargs) - return None - - -class NopPin(object): - """ Mixin for a pin with empty behaviour. Mix in BEFORE PinHandler so that - __init__ overrides the base behaviour. """ - def __init__(self, bus, base, path, gpio, settings): - self.service = None - self.bus = bus - self.settings = settings - self._level = 0 # Remember last state - - def deactivate(self): - pass - - def toggle(self, level): - self._level = level - - def save_count(self): - # Do nothing - pass - - @property - def count(self): - return self.settings['count'] - - @count.setter - def count(self, v): - pass - - def refresh(self): - pass - - -class DisabledPin(NopPin, PinHandler): - """ Place holder for a disabled pin. """ - _product_name = 'Disabled' - type_id = 0 - - -class VolumeCounter(PinHandler): - product_id = 0xA165 - _product_name = "Generic pulse meter" - dbus_name = "pulsemeter" - type_id = 1 - - def __init__(self, bus, base, path, gpio, settings): - super(VolumeCounter, self).__init__(bus, base, path, gpio, settings) - self.service.add_path('/Aggregate', value=self.count*self.rate, - gettextcallback=lambda p, v: (str(v) + ' cubic meter')) - - @property - def rate(self): - return self.settings['rate'] - - def toggle(self, level): - with self.service as s: - super(VolumeCounter, self)._toggle(level, s) - s['/Aggregate'] = self.count * self.rate - -class TouchEnable(NopPin, PinHandler): - """ The pin is used to enable/disable the Touch screen when toggled. - No dbus-service is created. """ - _product_name = 'TouchEnable' - type_id = 11 - - def __init__(self, *args, **kwargs): - super(TouchEnable, self).__init__(*args, **kwargs) - self.item = VeDbusItemImport(self.bus, - "com.victronenergy.settings", "/Settings/Gui/TouchEnabled") - - def toggle(self, level): - super(TouchEnable, self).toggle(level) - - # Toggle the touch-enable setting on the downward edge. - # Level is expected to be high with the switch open, and - # pulled low when pushed. - if level == 0: - enabled = bool(self.item.get_value()) - self.item.set_value(int(not enabled)) - - def deactivate(self): - # Always re-enable touch when the pin is deactivated. - # This adds another layer of protection against accidental - # lockout. - self.item.set_value(1) - del self.item - -class PinAlarm(PinHandler): - product_id = 0xA166 - _product_name = "Generic digital input" - dbus_name = "digitalinput" - type_id = 0xFF - translation = 0 # low, high - - def __init__(self, bus, base, path, gpio, settings): - super(PinAlarm, self).__init__(bus, base, path, gpio, settings) - self.service.add_path('/InputState', value=0) - self.service.add_path('/State', value=self.get_state(0), - gettextcallback=lambda p, v: TRANSLATIONS[v//2][v%2]) - self.service.add_path('/Alarm', value=self.get_alarm_state(0)) - - # Also expose the type - self.service.add_path('/Type', value=self.type_id, - gettextcallback=lambda p, v: INPUTTYPES[v]) - - def toggle(self, level): - with self.service as s: - super(PinAlarm, self)._toggle(level, s) - s['/InputState'] = bool(level)*1 - s['/State'] = self.get_state(level) - # Ensure that the alarm flag resets if the /AlarmSetting config option - # disappears. - s['/Alarm'] = self.get_alarm_state(level) - - def get_state(self, level): - state = level ^ self.settings['invert'] - return 2 * self.translation + state - - def get_alarm_state(self, level): - return 2 * bool( - (level ^ self.settings['invertalarm']) and self.settings['alarm']) - - -# Various types of things we might want to monitor -class DoorSensor(PinAlarm): - _product_name = "Door alarm" - type_id = 2 - translation = 3 # open, closed - -class BilgePump(PinAlarm): - _product_name = "Bilge pump" - type_id = 3 - translation = 1 # off, on - -class BilgeAlarm(PinAlarm): - _product_name = "Bilge alarm" - type_id = 4 - translation = 4 # ok, alarm - -class BurglarAlarm(PinAlarm): - _product_name = "Burglar alarm" - type_id = 5 - translation = 4 # ok, alarm - -class SmokeAlarm(PinAlarm): - _product_name = "Smoke alarm" - type_id = 6 - translation = 4 # ok, alarm - -class FireAlarm(PinAlarm): - _product_name = "Fire alarm" - type_id = 7 - translation = 4 # ok, alarm - -class CO2Alarm(PinAlarm): - _product_name = "CO2 alarm" - type_id = 8 - translation = 4 # ok, alarm - -class Generator(PinAlarm): - _product_name = "Generator" - type_id = 9 - translation = 5 # running, stopped - -class GenericIO(PinAlarm): - _product_name = "Generic I/O" - type_id = 10 - translation = 0 # low, high - -#### added for ExtTransferSwitch package -class TransferSwitch(PinAlarm): - _product_name = "External AC Input transfer switch" - type_id = 12 - translation = 6 # Grid In / Generator In - - -def dbusconnection(): - return SessionBus() if 'DBUS_SESSION_BUS_ADDRESS' in os.environ else SystemBus() - - -def main(): - parser = ArgumentParser(description=sys.argv[0]) - parser.add_argument('--servicebase', - help='Base service name on dbus, default is com.victronenergy', - default='com.victronenergy') - parser.add_argument('--poll', - help='Use a different kind of polling. Options are epoll, dumb and debug', - default='epoll') - parser.add_argument('inputs', nargs='+', help='Path to digital input') - args = parser.parse_args() - - PulseCounter = { - 'debug': DebugPulseCounter, - 'poll': PollingPulseCounter, - }.get(args.poll, EpollPulseCounter) - - DBusGMainLoop(set_as_default=True) - - # Keep track of enabled services - services = {} - inputs = dict(enumerate(args.inputs, 1)) - pulses = PulseCounter() # callable that iterates over pulses - - def register_gpio(path, gpio, bus, settings): - _type = settings['inputtype'] - print ("Registering GPIO {} for type {}".format(gpio, _type)) - - handler = PinHandler.createHandler(_type, - bus, args.servicebase, path, gpio, settings) - services[gpio] = handler - - # Only monitor if enabled - if _type > 0: - handler.level = pulses.register(path, gpio) - handler.refresh() - - def unregister_gpio(gpio): - print ("unRegistering GPIO {}".format(gpio)) - pulses.unregister(gpio) - services[gpio].deactivate() - - def handle_setting_change(inp, setting, old, new): - # This handler may also be called if some attribute of a setting - # is changed, but not the value. Bail if the value is unchanged. - if old == new: - return - - if setting == 'inputtype': - if new: - # Get current bus and settings objects, to be reused - service = services[inp] - bus, settings = service.bus, service.settings - - # Input enabled. If already enabled, unregister the old one first. - if pulses.registered(inp): - unregister_gpio(inp) - - # Before registering the new input, reset its settings to defaults - settings['count'] = 0 - settings['invert'] = 0 - settings['invertalarm'] = 0 - settings['alarm'] = 0 - - # Register it - register_gpio(inputs[inp], inp, bus, settings) - elif old: - # Input disabled - unregister_gpio(inp) - elif setting in ('rate', 'invert', 'alarm', 'invertalarm'): - services[inp].refresh() - elif setting == 'name': - services[inp].product_name = new - elif setting == 'count': - # Don't want this triggered on a period save, so only execute - # if it has changed. - v = int(new) - s = services[inp] - if s.count != v: - s.count = v - s.refresh() - - for inp, pth in inputs.items(): - supported_settings = { - 'inputtype': ['/Settings/DigitalInput/{}/Type'.format(inp), 0, 0, len(INPUTTYPES)-1], - 'rate': ['/Settings/DigitalInput/{}/Multiplier'.format(inp), 0.001, 0, 1.0], - 'count': ['/Settings/DigitalInput/{}/Count'.format(inp), 0, 0, MAXCOUNT, 1], - 'invert': ['/Settings/DigitalInput/{}/InvertTranslation'.format(inp), 0, 0, 1], - 'invertalarm': ['/Settings/DigitalInput/{}/InvertAlarm'.format(inp), 0, 0, 1], - 'alarm': ['/Settings/DigitalInput/{}/AlarmSetting'.format(inp), 0, 0, 1], - 'name': ['/Settings/DigitalInput/{}/CustomName'.format(inp), '', '', ''], - } - bus = dbusconnection() - sd = SettingsDevice(bus, supported_settings, partial(handle_setting_change, inp), timeout=10) - register_gpio(pth, inp, bus, sd) - - def poll(mainloop): - from time import time - idx = 0 - - try: - for inp, level in pulses(): - # epoll object only resyncs once a second. We may receive - # a pulse for something that's been deregistered. - try: - services[inp].toggle(level) - except KeyError: - continue - except: - traceback.print_exc() - mainloop.quit() - - # Need to run the gpio polling in separate thread. Pass in the mainloop so - # the thread can kill us if there is an exception. - mainloop = GLib.MainLoop() - - poller = Thread(target=lambda: poll(mainloop)) - poller.daemon = True - poller.start() - - # Periodically save the counter - def save_counters(): - for inp in inputs: - services[inp].save_count() - return True - GLib.timeout_add(SAVEINTERVAL, save_counters) - - # Save counter on shutdown - signal.signal(signal.SIGTERM, lambda *args: sys.exit(0)) - - try: - mainloop.run() - except KeyboardInterrupt: - pass - finally: - save_counters() - -if __name__ == "__main__": - main() diff --git a/FileSets/v3.01/dbus_digitalinputs.py.orig b/FileSets/v3.01/dbus_digitalinputs.py.orig deleted file mode 100755 index d9c90083..00000000 --- a/FileSets/v3.01/dbus_digitalinputs.py.orig +++ /dev/null @@ -1,584 +0,0 @@ -#!/usr/bin/python3 -u - -import sys, os -import signal -from threading import Thread -from select import select, epoll, EPOLLPRI -from functools import partial -from collections import namedtuple -from argparse import ArgumentParser -import traceback -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) - -from dbus.mainloop.glib import DBusGMainLoop -import dbus -from gi.repository import GLib -from vedbus import VeDbusService, VeDbusItemImport -from settingsdevice import SettingsDevice - -VERSION = '0.19' -MAXCOUNT = 2**31-1 -SAVEINTERVAL = 60000 - -INPUT_FUNCTION_COUNTER = 1 -INPUT_FUNCTION_INPUT = 2 - -Translation = namedtuple('Translation', ['no', 'yes']) - -# Only append at the end -INPUTTYPES = [ - 'Disabled', - 'Pulse meter', - 'Door', - 'Bilge pump', - 'Bilge alarm', - 'Burglar alarm', - 'Smoke alarm', - 'Fire alarm', - 'CO2 alarm', - 'Generator', - 'Generic I/O', - 'Touch enable', -] - -# Translations. The text will be used only for GetText, it will be translated -# in the gui. -TRANSLATIONS = [ - Translation('low', 'high'), - Translation('off', 'on'), - Translation('no', 'yes'), - Translation('open', 'closed'), - Translation('ok', 'alarm'), - Translation('running', 'stopped') -] - -class SystemBus(dbus.bus.BusConnection): - def __new__(cls): - return dbus.bus.BusConnection.__new__(cls, dbus.bus.BusConnection.TYPE_SYSTEM) - -class SessionBus(dbus.bus.BusConnection): - def __new__(cls): - return dbus.bus.BusConnection.__new__(cls, dbus.bus.BusConnection.TYPE_SESSION) - -class BasePulseCounter(object): - pass - -class DebugPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - - def register(self, path, gpio): - self.gpiomap[gpio] = None - return 0 - - def unregister(self, gpio): - del self.gpiomap[gpio] - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - from itertools import cycle - from time import sleep - for level in cycle([0, 1]): - for gpio in list(self.gpiomap.keys()): - yield gpio, level - sleep(0.25/len(self.gpiomap)) - -class EpollPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - self.states = {} - self.ob = epoll() - - def register(self, path, gpio): - path = os.path.realpath(path) - - # Set up gpio for rising edge interrupts - with open(os.path.join(path, 'edge'), 'ab') as fp: - fp.write(b'both') - - fp = open(os.path.join(path, 'value'), 'rb') - level = int(fp.read()) # flush it in case it's high at startup - self.gpiomap[gpio] = fp - self.states[gpio] = level - self.ob.register(fp, EPOLLPRI) - return level - - def unregister(self, gpio): - fp = self.gpiomap[gpio] - self.ob.unregister(fp) - del self.gpiomap[gpio] - del self.states[gpio] - fp.close() - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - while True: - # We have a timeout of 1 second on the poll, because poll() only - # looks at files in the epoll object at the time poll() was called. - # The timeout means we let other files (added via calls to - # register/unregister) into the loop at least that often. - self.ob.poll(1) - - # When coming out of the epoll call, we read all the gpios to make - # sure we didn't miss any edges. This is a safety fallback that - # ensures everything is up to date once a second, but - # edge-triggered results are handled immediately. - # NOTE: There has not been a report of a missed interrupt yet. - # Belts and suspenders. - for gpio, fp in list(self.gpiomap.items()): - os.lseek(fp.fileno(), 0, os.SEEK_SET) - v = int(os.read(fp.fileno(), 1)) - if v != self.states[gpio]: - self.states[gpio] = v - yield gpio, v - -class PollingPulseCounter(BasePulseCounter): - def __init__(self): - self.gpiomap = {} - - def register(self, path, gpio): - path = os.path.realpath(path) - - fp = open(os.path.join(path, 'value'), 'rb') - level = int(fp.read()) - self.gpiomap[gpio] = [fp, level] - return level - - def unregister(self, gpio): - del self.gpiomap[gpio] - - def registered(self, gpio): - return gpio in self.gpiomap - - def __call__(self): - from itertools import cycle - from time import sleep - while True: - for gpio, (fp, level) in list(self.gpiomap.items()): - fp.seek(0, os.SEEK_SET) - v = int(fp.read()) - if v != level: - self.gpiomap[gpio][1] = v - yield gpio, v - sleep(1) - -class HandlerMaker(type): - """ Meta-class for keeping track of all extended classes. """ - def __init__(cls, name, bases, attrs): - if not hasattr(cls, 'handlers'): - cls.handlers = {} - else: - cls.handlers[cls.type_id] = cls - -class PinHandler(object, metaclass=HandlerMaker): - product_id = 0xFFFF - _product_name = 'Generic GPIO' - dbus_name = "digital" - def __init__(self, bus, base, path, gpio, settings): - self.gpio = gpio - self.path = path - self.bus = bus - self.settings = settings - self._level = 0 # Remember last state - - self.service = VeDbusService( - "{}.{}.input{:02d}".format(base, self.dbus_name, gpio), bus=bus) - - # Add objects required by ve-api - self.service.add_path('/Mgmt/ProcessName', __file__) - self.service.add_path('/Mgmt/ProcessVersion', VERSION) - self.service.add_path('/Mgmt/Connection', path) - self.service.add_path('/DeviceInstance', gpio) - self.service.add_path('/ProductId', self.product_id) - self.service.add_path('/ProductName', self.product_name) - self.service.add_path('/Connected', 1) - - # Custom name setting - def _change_name(p, v): - # This should fire a change event that will update product_name - # below. - settings['name'] = v - return True - - self.service.add_path('/CustomName', settings['name'], writeable=True, - onchangecallback=_change_name) - - # We'll count the pulses for all types of services - self.service.add_path('/Count', value=settings['count']) - - @property - def product_name(self): - return self.settings['name'] or self._product_name - - @product_name.setter - def product_name(self, v): - # Some pin types don't have an associated service (Disabled pins for - # example) - if self.service is not None: - self.service['/ProductName'] = v or self._product_name - - def deactivate(self): - self.save_count() - self.service.__del__() - del self.service - self.service = None - - @property - def level(self): - return self._level - - @level.setter - def level(self, l): - self._level = int(bool(l)) - - def toggle(self, level): - raise NotImplementedError - - def _toggle(self, level, service): - # Only increment Count on rising edge. - if level and level != self._level: - service['/Count'] = (service['/Count']+1) % MAXCOUNT - self._level = level - - def refresh(self): - """ Toggle state to last remembered state. This is called if settings - are changed so the Service can recalculate paths. """ - self.toggle(self._level) - - def save_count(self): - if self.service is not None: - self.settings['count'] = self.count - - @property - def active(self): - return self.service is not None - - @property - def count(self): - return self.service['/Count'] - - @count.setter - def count(self, v): - self.service['/Count'] = v - - @classmethod - def createHandler(cls, _type, *args, **kwargs): - if _type in cls.handlers: - return cls.handlers[_type](*args, **kwargs) - return None - - -class NopPin(object): - """ Mixin for a pin with empty behaviour. Mix in BEFORE PinHandler so that - __init__ overrides the base behaviour. """ - def __init__(self, bus, base, path, gpio, settings): - self.service = None - self.bus = bus - self.settings = settings - self._level = 0 # Remember last state - - def deactivate(self): - pass - - def toggle(self, level): - self._level = level - - def save_count(self): - # Do nothing - pass - - @property - def count(self): - return self.settings['count'] - - @count.setter - def count(self, v): - pass - - def refresh(self): - pass - - -class DisabledPin(NopPin, PinHandler): - """ Place holder for a disabled pin. """ - _product_name = 'Disabled' - type_id = 0 - - -class VolumeCounter(PinHandler): - product_id = 0xA165 - _product_name = "Generic pulse meter" - dbus_name = "pulsemeter" - type_id = 1 - - def __init__(self, bus, base, path, gpio, settings): - super(VolumeCounter, self).__init__(bus, base, path, gpio, settings) - self.service.add_path('/Aggregate', value=self.count*self.rate, - gettextcallback=lambda p, v: (str(v) + ' cubic meter')) - - @property - def rate(self): - return self.settings['rate'] - - def toggle(self, level): - with self.service as s: - super(VolumeCounter, self)._toggle(level, s) - s['/Aggregate'] = self.count * self.rate - -class TouchEnable(NopPin, PinHandler): - """ The pin is used to enable/disable the Touch screen when toggled. - No dbus-service is created. """ - _product_name = 'TouchEnable' - type_id = 11 - - def __init__(self, *args, **kwargs): - super(TouchEnable, self).__init__(*args, **kwargs) - self.item = VeDbusItemImport(self.bus, - "com.victronenergy.settings", "/Settings/Gui/TouchEnabled") - - def toggle(self, level): - super(TouchEnable, self).toggle(level) - - # Toggle the touch-enable setting on the downward edge. - # Level is expected to be high with the switch open, and - # pulled low when pushed. - if level == 0: - enabled = bool(self.item.get_value()) - self.item.set_value(int(not enabled)) - - def deactivate(self): - # Always re-enable touch when the pin is deactivated. - # This adds another layer of protection against accidental - # lockout. - self.item.set_value(1) - del self.item - -class PinAlarm(PinHandler): - product_id = 0xA166 - _product_name = "Generic digital input" - dbus_name = "digitalinput" - type_id = 0xFF - translation = 0 # low, high - - def __init__(self, bus, base, path, gpio, settings): - super(PinAlarm, self).__init__(bus, base, path, gpio, settings) - self.service.add_path('/InputState', value=0) - self.service.add_path('/State', value=self.get_state(0), - gettextcallback=lambda p, v: TRANSLATIONS[v//2][v%2]) - self.service.add_path('/Alarm', value=self.get_alarm_state(0)) - - # Also expose the type - self.service.add_path('/Type', value=self.type_id, - gettextcallback=lambda p, v: INPUTTYPES[v]) - - def toggle(self, level): - with self.service as s: - super(PinAlarm, self)._toggle(level, s) - s['/InputState'] = bool(level)*1 - s['/State'] = self.get_state(level) - # Ensure that the alarm flag resets if the /AlarmSetting config option - # disappears. - s['/Alarm'] = self.get_alarm_state(level) - - def get_state(self, level): - state = level ^ self.settings['invert'] - return 2 * self.translation + state - - def get_alarm_state(self, level): - return 2 * bool( - (level ^ self.settings['invertalarm']) and self.settings['alarm']) - - -# Various types of things we might want to monitor -class DoorSensor(PinAlarm): - _product_name = "Door alarm" - type_id = 2 - translation = 3 # open, closed - -class BilgePump(PinAlarm): - _product_name = "Bilge pump" - type_id = 3 - translation = 1 # off, on - -class BilgeAlarm(PinAlarm): - _product_name = "Bilge alarm" - type_id = 4 - translation = 4 # ok, alarm - -class BurglarAlarm(PinAlarm): - _product_name = "Burglar alarm" - type_id = 5 - translation = 4 # ok, alarm - -class SmokeAlarm(PinAlarm): - _product_name = "Smoke alarm" - type_id = 6 - translation = 4 # ok, alarm - -class FireAlarm(PinAlarm): - _product_name = "Fire alarm" - type_id = 7 - translation = 4 # ok, alarm - -class CO2Alarm(PinAlarm): - _product_name = "CO2 alarm" - type_id = 8 - translation = 4 # ok, alarm - -class Generator(PinAlarm): - _product_name = "Generator" - type_id = 9 - translation = 5 # running, stopped - -class GenericIO(PinAlarm): - _product_name = "Generic I/O" - type_id = 10 - translation = 0 # low, high - - -def dbusconnection(): - return SessionBus() if 'DBUS_SESSION_BUS_ADDRESS' in os.environ else SystemBus() - - -def main(): - parser = ArgumentParser(description=sys.argv[0]) - parser.add_argument('--servicebase', - help='Base service name on dbus, default is com.victronenergy', - default='com.victronenergy') - parser.add_argument('--poll', - help='Use a different kind of polling. Options are epoll, dumb and debug', - default='epoll') - parser.add_argument('inputs', nargs='+', help='Path to digital input') - args = parser.parse_args() - - PulseCounter = { - 'debug': DebugPulseCounter, - 'poll': PollingPulseCounter, - }.get(args.poll, EpollPulseCounter) - - DBusGMainLoop(set_as_default=True) - - # Keep track of enabled services - services = {} - inputs = dict(enumerate(args.inputs, 1)) - pulses = PulseCounter() # callable that iterates over pulses - - def register_gpio(path, gpio, bus, settings): - _type = settings['inputtype'] - print ("Registering GPIO {} for type {}".format(gpio, _type)) - - handler = PinHandler.createHandler(_type, - bus, args.servicebase, path, gpio, settings) - services[gpio] = handler - - # Only monitor if enabled - if _type > 0: - handler.level = pulses.register(path, gpio) - handler.refresh() - - def unregister_gpio(gpio): - print ("unRegistering GPIO {}".format(gpio)) - pulses.unregister(gpio) - services[gpio].deactivate() - - def handle_setting_change(inp, setting, old, new): - # This handler may also be called if some attribute of a setting - # is changed, but not the value. Bail if the value is unchanged. - if old == new: - return - - if setting == 'inputtype': - if new: - # Get current bus and settings objects, to be reused - service = services[inp] - bus, settings = service.bus, service.settings - - # Input enabled. If already enabled, unregister the old one first. - if pulses.registered(inp): - unregister_gpio(inp) - - # Before registering the new input, reset its settings to defaults - settings['count'] = 0 - settings['invert'] = 0 - settings['invertalarm'] = 0 - settings['alarm'] = 0 - - # Register it - register_gpio(inputs[inp], inp, bus, settings) - elif old: - # Input disabled - unregister_gpio(inp) - elif setting in ('rate', 'invert', 'alarm', 'invertalarm'): - services[inp].refresh() - elif setting == 'name': - services[inp].product_name = new - elif setting == 'count': - # Don't want this triggered on a period save, so only execute - # if it has changed. - v = int(new) - s = services[inp] - if s.count != v: - s.count = v - s.refresh() - - for inp, pth in inputs.items(): - supported_settings = { - 'inputtype': ['/Settings/DigitalInput/{}/Type'.format(inp), 0, 0, len(INPUTTYPES)-1], - 'rate': ['/Settings/DigitalInput/{}/Multiplier'.format(inp), 0.001, 0, 1.0], - 'count': ['/Settings/DigitalInput/{}/Count'.format(inp), 0, 0, MAXCOUNT, 1], - 'invert': ['/Settings/DigitalInput/{}/InvertTranslation'.format(inp), 0, 0, 1], - 'invertalarm': ['/Settings/DigitalInput/{}/InvertAlarm'.format(inp), 0, 0, 1], - 'alarm': ['/Settings/DigitalInput/{}/AlarmSetting'.format(inp), 0, 0, 1], - 'name': ['/Settings/DigitalInput/{}/CustomName'.format(inp), '', '', ''], - } - bus = dbusconnection() - sd = SettingsDevice(bus, supported_settings, partial(handle_setting_change, inp), timeout=10) - register_gpio(pth, inp, bus, sd) - - def poll(mainloop): - from time import time - idx = 0 - - try: - for inp, level in pulses(): - # epoll object only resyncs once a second. We may receive - # a pulse for something that's been deregistered. - try: - services[inp].toggle(level) - except KeyError: - continue - except: - traceback.print_exc() - mainloop.quit() - - # Need to run the gpio polling in separate thread. Pass in the mainloop so - # the thread can kill us if there is an exception. - mainloop = GLib.MainLoop() - - poller = Thread(target=lambda: poll(mainloop)) - poller.daemon = True - poller.start() - - # Periodically save the counter - def save_counters(): - for inp in inputs: - services[inp].save_count() - return True - GLib.timeout_add(SAVEINTERVAL, save_counters) - - # Save counter on shutdown - signal.signal(signal.SIGTERM, lambda *args: sys.exit(0)) - - try: - mainloop.run() - except KeyboardInterrupt: - pass - finally: - save_counters() - -if __name__ == "__main__": - main() diff --git a/FileSets/v3.01/dbus_generator.py b/FileSets/v3.01/dbus_generator.py deleted file mode 100755 index 2ad50efe..00000000 --- a/FileSets/v3.01/dbus_generator.py +++ /dev/null @@ -1,348 +0,0 @@ -#!/usr/bin/python3 -u -# -*- coding: utf-8 -*- - -#### GuiMods -#### This file has been modified to allow the generator running state derived from the generator digital input -#### or the genset AC input -#### If the incoming generator state changes, the manual start state is updated -#### time accumulation is suspended when the generator is not running -#### A switch in the generator settings menucontrols whethter the incoming state affects manual start or time accumulaiton -#### It is now possible to start the generator manually and have it stop automatically based on the preset conditions -#### for automaitc start / stop -#### A service interval timer was added so the accumulated run time does not need to be reset, -#### providing total run time for the generator -#### Search for #### GuiMods to find changes - -from dbus.mainloop.glib import DBusGMainLoop -import dbus -import argparse -import sys -import os -import signal -from gi.repository import GLib - -# Victron packages -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) -from vedbus import VeDbusService -from ve_utils import exit_on_error -from dbusmonitor import DbusMonitor -from settingsdevice import SettingsDevice -from logger import setup_logging -import logging -from gen_utils import dummy -import time -import relay -import fischerpanda -from version import softwareversion - -class Generator(object): - def __init__(self): - self._exit = False - self._instances = {} - self._modules = [relay, fischerpanda] - - # Common dbus services/path - commondbustree = { - 'com.victronenergy.settings': { - '/Settings/System/TimeZone': dummy, - '/Settings/SystemSetup/AcInput1': dummy, - '/Settings/SystemSetup/AcInput2': dummy, - - '/Settings/Relay/Polarity': dummy - }, - 'com.victronenergy.battery': { - '/Dc/0/Voltage': dummy, - '/Dc/0/Current': dummy, - '/Dc/1/Voltage': dummy, - '/Dc/1/Current': dummy, - '/Soc': dummy - }, - 'com.victronenergy.vebus': { - '/Ac/Out/L1/P': dummy, - '/Ac/Out/L2/P': dummy, - '/Ac/Out/L3/P': dummy, - '/Alarms/L1/Overload': dummy, - '/Alarms/L2/Overload': dummy, - '/Alarms/L3/Overload': dummy, - '/Alarms/L1/HighTemperature': dummy, - '/Alarms/L2/HighTemperature': dummy, - '/Alarms/L3/HighTemperature': dummy, - '/Alarms/HighTemperature': dummy, - '/Alarms/Overload': dummy, - '/Ac/ActiveIn/ActiveInput': dummy, - '/Ac/ActiveIn/Connected': dummy, - '/Dc/0/Voltage': dummy, - '/Dc/0/Current': dummy, - '/Dc/1/Voltage': dummy, - '/Dc/1/Current': dummy, - '/Soc': dummy, - '/Ac/State/AcIn1Available': dummy, - '/Ac/State/AcIn2Available': dummy, - '/Ac/Control/IgnoreAcIn1': dummy, - '/Ac/Control/IgnoreAcIn2': dummy - }, - 'com.victronenergy.system': { - '/Ac/ConsumptionOnInput/L1/Power': dummy, - '/Ac/ConsumptionOnInput/L2/Power': dummy, - '/Ac/ConsumptionOnInput/L3/Power': dummy, - '/Ac/ConsumptionOnOutput/L1/Power': dummy, - '/Ac/ConsumptionOnOutput/L2/Power': dummy, - '/Ac/ConsumptionOnOutput/L3/Power': dummy, - '/Dc/Pv/Power': dummy, - '/AutoSelectedBatteryMeasurement': dummy, - '/Ac/ActiveIn/Source': dummy, - '/VebusService': dummy, - '/Dc/Battery/Voltage': dummy, - '/Dc/Battery/Current': dummy, - '/Dc/Battery/Soc': dummy, -#### GuiMods - '/Ac/Genset/Frequency': dummy, - '/Ac/In/NumberOfAcInputs': dummy - } - } - - # Settings base - settingsbase = { - 'autostart': ['/Settings/{0}/AutoStartEnabled', 0, 0, 1], - 'batterymeasurement': ['/Settings/{0}/Service', '', 0, 0], - 'accumulateddaily': ['/Settings/{0}/AccumulatedDaily', '', 0, 0, True], - 'accumulatedtotal': ['/Settings/{0}/AccumulatedTotal', 0, 0, 0, True], -#### GuiMods - 'timeSinceService': ['/Settings/{0}/TimeSinceService', 0, 0, 0, True], - 'linkManualStartToExternal': ['/Settings/{0}/LinkToExternalStatus', 0, 0, 0, True], - - 'batterymeasurement': ['/Settings/{0}/BatteryService', 'default', 0, 0], - 'minimumruntime': ['/Settings/{0}/MinimumRuntime', 0, 0, 86400], # minutes - 'stoponac1enabled': ['/Settings/{0}/StopWhenAc1Available', 0, 0, 1], - 'stoponac2enabled': ['/Settings/{0}/StopWhenAc2Available', 0, 0, 1], - # On permanent loss of communication: 0 = Stop, 1 = Start, 2 = keep running - 'onlosscommunication': ['/Settings/{0}/OnLossCommunication', 0, 0, 2], - # Quiet hours - 'quiethoursenabled': ['/Settings/{0}/QuietHours/Enabled', 0, 0, 1], - 'quiethoursstarttime': ['/Settings/{0}/QuietHours/StartTime', 75600, 0, 86400], - 'quiethoursendtime': ['/Settings/{0}/QuietHours/EndTime', 21600, 0, 86400], - # SOC - 'socenabled': ['/Settings/{0}/Soc/Enabled', 0, 0, 1], - 'socstart': ['/Settings/{0}/Soc/StartValue', 80, 0, 100], - 'socstop': ['/Settings/{0}/Soc/StopValue', 90, 0, 100], - 'qh_socstart': ['/Settings/{0}/Soc/QuietHoursStartValue', 90, 0, 100], - 'qh_socstop': ['/Settings/{0}/Soc/QuietHoursStopValue', 90, 0, 100], - # Voltage - 'batteryvoltageenabled': ['/Settings/{0}/BatteryVoltage/Enabled', 0, 0, 1], - 'batteryvoltagestart': ['/Settings/{0}/BatteryVoltage/StartValue', 11.5, 0, 150], - 'batteryvoltagestop': ['/Settings/{0}/BatteryVoltage/StopValue', 12.4, 0, 150], - 'batteryvoltagestarttimer': ['/Settings/{0}/BatteryVoltage/StartTimer', 20, 0, 10000], - 'batteryvoltagestoptimer': ['/Settings/{0}/BatteryVoltage/StopTimer', 20, 0, 10000], - 'qh_batteryvoltagestart': ['/Settings/{0}/BatteryVoltage/QuietHoursStartValue', 11.9, 0, 100], - 'qh_batteryvoltagestop': ['/Settings/{0}/BatteryVoltage/QuietHoursStopValue', 12.4, 0, 100], - # Current - 'batterycurrentenabled': ['/Settings/{0}/BatteryCurrent/Enabled', 0, 0, 1], - 'batterycurrentstart': ['/Settings/{0}/BatteryCurrent/StartValue', 10.5, 0.5, 10000], - 'batterycurrentstop': ['/Settings/{0}/BatteryCurrent/StopValue', 5.5, 0, 10000], - 'batterycurrentstarttimer': ['/Settings/{0}/BatteryCurrent/StartTimer', 20, 0, 10000], - 'batterycurrentstoptimer': ['/Settings/{0}/BatteryCurrent/StopTimer', 20, 0, 10000], - 'qh_batterycurrentstart': ['/Settings/{0}/BatteryCurrent/QuietHoursStartValue', 20.5, 0, 10000], - 'qh_batterycurrentstop': ['/Settings/{0}/BatteryCurrent/QuietHoursStopValue', 15.5, 0, 10000], - # AC load - 'acloadenabled': ['/Settings/{0}/AcLoad/Enabled', 0, 0, 1], - # Measuerement, 0 = Total AC consumption, 1 = AC on inverter output, 2 = Single phase - 'acloadmeasurement': ['/Settings/{0}/AcLoad/Measurement', 0, 0, 100], - 'acloadstart': ['/Settings/{0}/AcLoad/StartValue', 1600, 5, 1000000], - 'acloadstop': ['/Settings/{0}/AcLoad/StopValue', 800, 0, 1000000], - 'acloadstarttimer': ['/Settings/{0}/AcLoad/StartTimer', 20, 0, 10000], - 'acloadstoptimer': ['/Settings/{0}/AcLoad/StopTimer', 20, 0, 10000], - 'qh_acloadstart': ['/Settings/{0}/AcLoad/QuietHoursStartValue', 1900, 0, 1000000], - 'qh_acloadstop': ['/Settings/{0}/AcLoad/QuietHoursStopValue', 1200, 0, 1000000], - # VE.Bus high temperature - 'inverterhightempenabled': ['/Settings/{0}/InverterHighTemp/Enabled', 0, 0, 1], - 'inverterhightempstarttimer': ['/Settings/{0}/InverterHighTemp/StartTimer', 20, 0, 10000], - 'inverterhightempstoptimer': ['/Settings/{0}/InverterHighTemp/StopTimer', 20, 0, 10000], - # VE.Bus overload - 'inverteroverloadenabled': ['/Settings/{0}/InverterOverload/Enabled', 0, 0, 1], - 'inverteroverloadstarttimer': ['/Settings/{0}/InverterOverload/StartTimer', 20, 0, 10000], - 'inverteroverloadstoptimer': ['/Settings/{0}/InverterOverload/StopTimer', 20, 0, 10000], - # TestRun - 'testrunenabled': ['/Settings/{0}/TestRun/Enabled', 0, 0, 1], - 'testrunstartdate': ['/Settings/{0}/TestRun/StartDate', 1483228800, 0, 10000000000.1], - 'testrunstarttimer': ['/Settings/{0}/TestRun/StartTime', 54000, 0, 86400], - 'testruninterval': ['/Settings/{0}/TestRun/Interval', 28, 1, 365], - 'testrunruntime': ['/Settings/{0}/TestRun/Duration', 7200, 1, 86400], - 'testrunskipruntime': ['/Settings/{0}/TestRun/SkipRuntime', 0, 0, 100000], - 'testruntillbatteryfull': ['/Settings/{0}/TestRun/RunTillBatteryFull', 0, 0, 1], - # Alarms - 'nogeneratoratacinalarm': ['/Settings/{0}/Alarms/NoGeneratorAtAcIn', 0, 0, 1], - # Warm-up and Cool-down - 'warmuptime': ['/Settings/{0}/WarmUpTime', 0, 0, 600], - 'cooldowntime': ['/Settings/{0}/CoolDownTime', 0, 0, 600], -#### GuiMods warm-up / cool-down - ignore AC to allow generator to stop - 'postcooldowntime': ['/Settings/{0}/PostCoolDownTime', 15, 0, 600] - } - - settings = {} - dbus_tree = dict(commondbustree) - - for m in self._modules: - # Create settings for each module - # Settings are created under the module prefix, for example: - # /Settings/Generator0/AcLoad/Enabled - # /Settings/FischerPanda0/AcLoad/Enabled - for s in settingsbase: - v = settingsbase[s][:] # Copy - v[0] = v[0].format(m.name) - settings[s + m.name] = v - - # Get all services/paths that must be monitored - # There are a base of common services/pathas that must be monitored - # for the correct function such as battery monitors of vebus devices - # and a extra ones that is only used by a certain module, these - # are mainly the "remote switch". - for i in m.monitoring: - if i in commondbustree: - for s in m.monitoring[i]: - dbus_tree[i][s] = m.monitoring[i][s] - else: - dbus_tree[i] = m.monitoring[i] - - # Create settings device which is shared - self._settings = self._create_settings(settings, self._handlechangedsetting) - - # Create dbusmonitor, this is shared by all the instances - self._dbusmonitor = self._create_dbus_monitor(dbus_tree, valueChangedCallback=self._dbus_value_changed, - deviceAddedCallback=self._device_added, deviceRemovedCallback=self._device_removed) - - # Set timezone to user selected timezone - tz = self._dbusmonitor.get_value('com.victronenergy.settings', '/Settings/System/TimeZone') - os.environ['TZ'] = tz if tz else 'UTC' - time.tzset() - - # Call device_added for all existing devices at startup. - for service, instance in self._dbusmonitor.get_service_list().items(): - self._device_added(service, instance) - - GLib.timeout_add(1000, exit_on_error, self._handletimertick) - - def _handlechangedsetting(self, setting, oldvalue, newvalue): - for i in self._instances: - self._instances[i].handlechangedsetting(setting, oldvalue, newvalue) - - def _device_added(self, dbusservicename, instance): - # If settings check built-in relays - if dbusservicename == 'com.victronenergy.settings': - self._handle_builtin_relay('/Settings/Relay/Function') - - self._add_device(dbusservicename) - - for i in self._instances: - self._instances[i].device_added(dbusservicename, instance) - - def _dbus_value_changed(self, dbusServiceName, dbusPath, options, changes, deviceInstance): - # Track built-in relays - if "/Settings/Relay/Function" in dbusPath: - self._handle_builtin_relay(dbusPath) - - # Some devices like Fischer Panda gensets doesn't disappear from dbus - # when disconnected so check '/Connected' value to add or remove start/stop - # for that device - if dbusPath == "/Connected": - if self._dbusmonitor.get_value(dbusServiceName, dbusPath) == 0: - self._remove_device(dbusServiceName) - else: - self._add_device(dbusServiceName) - - # Update env timezone when setting changes - if (dbusServiceName, dbusPath) == ('com.victronenergy.settings', '/Settings/System/TimeZone'): - os.environ['TZ'] = changes['Value'] if changes['Value'] else 'UTC' - time.tzset() - - for i in self._instances: - self._instances[i].dbus_value_changed(dbusServiceName, dbusPath, options, changes, deviceInstance) - - def _device_removed(self, dbusservicename, instance): - if dbusservicename == 'com.victronenergy.settings': - self._handle_builtin_relay('/Settings/Relay/Function') - for i in self._instances: - self._instances[i].device_removed(dbusservicename, instance) - self._remove_device(dbusservicename) - - def _create_dbus_monitor(self, *args, **kwargs): - return DbusMonitor(*args, **kwargs) - - def _create_settings(self, *args, **kwargs): - bus = dbus.SessionBus() if 'DBUS_SESSION_BUS_ADDRESS' in os.environ else dbus.SystemBus() - return SettingsDevice(bus, *args, timeout=10, **kwargs) - - def _add_device(self, service): - for i in self._modules: - # Check if module can handle this service - if i.remoteprefix not in service: - continue - # Check and create start/stop instance for the device - if i.check_device(self._dbusmonitor, service): - self._instances[service] = i.create(self._dbusmonitor, - service, self._settings, i.device_instance) - - def _handle_builtin_relay(self, dbuspath): - function = self._dbusmonitor.get_value('com.victronenergy.settings', dbuspath) - relaynr = 'generator0' - relayservice = 'com.victronenergy.system' - - # Create a instance if relay function is set to 1 (gen. start/stop) - # otherwise remove the instance if exists - if function == 1: - self._instances[relaynr] = relay.create(self._dbusmonitor, - relayservice, - self._settings, relay.device_instance) - elif relaynr in self._instances: - self._instances[relaynr].remove() - del self._instances[relaynr] - - def _remove_device(self, servicename): - if servicename in self._instances: - if self._instances[servicename] is not None: - self._instances[servicename].remove() - del self._instances[servicename] - - def terminate(self, signum, frame): - # Remove instances before exiting, remote services might need to perform actions before releasing control - # of the switch - for i in self._instances: - self._instances[i].remove() - os._exit(0) - - def _handletimertick(self): - # try catch, to make sure that we kill ourselves on an error. Without this try-catch, there would - # be an error written to stdout, and then the timer would not be restarted, resulting in a dead- - # lock waiting for manual intervention -> not good! - try: - for i in self._instances: - self._instances[i].tick() - except: - self._instances[i].remove() - import traceback - traceback.print_exc() - sys.exit(1) - return True - -if __name__ == '__main__': - # Argument parsing - parser = argparse.ArgumentParser( - description='Start and stop a generator based on conditions' - ) - - parser.add_argument('-d', '--debug', help='set logging level to debug', - action='store_true') - args = parser.parse_args() - - print ('-------- dbus_generator, v' + softwareversion + ' is starting up --------') - - logger = setup_logging(args.debug) - - # Have a mainloop, so we can send/receive asynchronous calls to and from dbus - DBusGMainLoop(set_as_default=True) - - generator = Generator() - signal.signal(signal.SIGTERM, generator.terminate) - - # Start and run the mainloop - mainloop = GLib.MainLoop() - mainloop.run() diff --git a/FileSets/v3.01/dbus_generator.py.orig b/FileSets/v3.01/dbus_generator.py.orig deleted file mode 100755 index 2e6ac77c..00000000 --- a/FileSets/v3.01/dbus_generator.py.orig +++ /dev/null @@ -1,326 +0,0 @@ -#!/usr/bin/python3 -u -# -*- coding: utf-8 -*- - -from dbus.mainloop.glib import DBusGMainLoop -import dbus -import argparse -import sys -import os -import signal -from gi.repository import GLib - -# Victron packages -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) -from vedbus import VeDbusService -from ve_utils import exit_on_error -from dbusmonitor import DbusMonitor -from settingsdevice import SettingsDevice -from logger import setup_logging -import logging -from gen_utils import dummy -import time -import relay -import fischerpanda -from version import softwareversion - -class Generator(object): - def __init__(self): - self._exit = False - self._instances = {} - self._modules = [relay, fischerpanda] - - # Common dbus services/path - commondbustree = { - 'com.victronenergy.settings': { - '/Settings/System/TimeZone': dummy, - '/Settings/SystemSetup/AcInput1': dummy, - '/Settings/SystemSetup/AcInput2': dummy, - '/Settings/Relay/Polarity': dummy - }, - 'com.victronenergy.battery': { - '/Dc/0/Voltage': dummy, - '/Dc/0/Current': dummy, - '/Dc/1/Voltage': dummy, - '/Dc/1/Current': dummy, - '/Soc': dummy - }, - 'com.victronenergy.vebus': { - '/Ac/Out/L1/P': dummy, - '/Ac/Out/L2/P': dummy, - '/Ac/Out/L3/P': dummy, - '/Alarms/L1/Overload': dummy, - '/Alarms/L2/Overload': dummy, - '/Alarms/L3/Overload': dummy, - '/Alarms/L1/HighTemperature': dummy, - '/Alarms/L2/HighTemperature': dummy, - '/Alarms/L3/HighTemperature': dummy, - '/Alarms/HighTemperature': dummy, - '/Alarms/Overload': dummy, - '/Ac/ActiveIn/ActiveInput': dummy, - '/Ac/ActiveIn/Connected': dummy, - '/Dc/0/Voltage': dummy, - '/Dc/0/Current': dummy, - '/Dc/1/Voltage': dummy, - '/Dc/1/Current': dummy, - '/Soc': dummy, - '/Ac/State/AcIn1Available': dummy, - '/Ac/State/AcIn2Available': dummy, - '/Ac/Control/IgnoreAcIn1': dummy, - '/Ac/Control/IgnoreAcIn2': dummy - }, - 'com.victronenergy.system': { - '/Ac/ConsumptionOnInput/L1/Power': dummy, - '/Ac/ConsumptionOnInput/L2/Power': dummy, - '/Ac/ConsumptionOnInput/L3/Power': dummy, - '/Ac/ConsumptionOnOutput/L1/Power': dummy, - '/Ac/ConsumptionOnOutput/L2/Power': dummy, - '/Ac/ConsumptionOnOutput/L3/Power': dummy, - '/Dc/Pv/Power': dummy, - '/AutoSelectedBatteryMeasurement': dummy, - '/Ac/ActiveIn/Source': dummy, - '/VebusService': dummy, - '/Dc/Battery/Voltage': dummy, - '/Dc/Battery/Current': dummy, - '/Dc/Battery/Soc': dummy - } - } - - # Settings base - settingsbase = { - 'autostart': ['/Settings/{0}/AutoStartEnabled', 0, 0, 1], - 'batterymeasurement': ['/Settings/{0}/Service', '', 0, 0], - 'accumulateddaily': ['/Settings/{0}/AccumulatedDaily', '', 0, 0, True], - 'accumulatedtotal': ['/Settings/{0}/AccumulatedTotal', 0, 0, 0, True], - 'batterymeasurement': ['/Settings/{0}/BatteryService', 'default', 0, 0], - 'minimumruntime': ['/Settings/{0}/MinimumRuntime', 0, 0, 86400], # minutes - 'stoponac1enabled': ['/Settings/{0}/StopWhenAc1Available', 0, 0, 1], - 'stoponac2enabled': ['/Settings/{0}/StopWhenAc2Available', 0, 0, 1], - # On permanent loss of communication: 0 = Stop, 1 = Start, 2 = keep running - 'onlosscommunication': ['/Settings/{0}/OnLossCommunication', 0, 0, 2], - # Quiet hours - 'quiethoursenabled': ['/Settings/{0}/QuietHours/Enabled', 0, 0, 1], - 'quiethoursstarttime': ['/Settings/{0}/QuietHours/StartTime', 75600, 0, 86400], - 'quiethoursendtime': ['/Settings/{0}/QuietHours/EndTime', 21600, 0, 86400], - # SOC - 'socenabled': ['/Settings/{0}/Soc/Enabled', 0, 0, 1], - 'socstart': ['/Settings/{0}/Soc/StartValue', 80, 0, 100], - 'socstop': ['/Settings/{0}/Soc/StopValue', 90, 0, 100], - 'qh_socstart': ['/Settings/{0}/Soc/QuietHoursStartValue', 90, 0, 100], - 'qh_socstop': ['/Settings/{0}/Soc/QuietHoursStopValue', 90, 0, 100], - # Voltage - 'batteryvoltageenabled': ['/Settings/{0}/BatteryVoltage/Enabled', 0, 0, 1], - 'batteryvoltagestart': ['/Settings/{0}/BatteryVoltage/StartValue', 11.5, 0, 150], - 'batteryvoltagestop': ['/Settings/{0}/BatteryVoltage/StopValue', 12.4, 0, 150], - 'batteryvoltagestarttimer': ['/Settings/{0}/BatteryVoltage/StartTimer', 20, 0, 10000], - 'batteryvoltagestoptimer': ['/Settings/{0}/BatteryVoltage/StopTimer', 20, 0, 10000], - 'qh_batteryvoltagestart': ['/Settings/{0}/BatteryVoltage/QuietHoursStartValue', 11.9, 0, 100], - 'qh_batteryvoltagestop': ['/Settings/{0}/BatteryVoltage/QuietHoursStopValue', 12.4, 0, 100], - # Current - 'batterycurrentenabled': ['/Settings/{0}/BatteryCurrent/Enabled', 0, 0, 1], - 'batterycurrentstart': ['/Settings/{0}/BatteryCurrent/StartValue', 10.5, 0.5, 10000], - 'batterycurrentstop': ['/Settings/{0}/BatteryCurrent/StopValue', 5.5, 0, 10000], - 'batterycurrentstarttimer': ['/Settings/{0}/BatteryCurrent/StartTimer', 20, 0, 10000], - 'batterycurrentstoptimer': ['/Settings/{0}/BatteryCurrent/StopTimer', 20, 0, 10000], - 'qh_batterycurrentstart': ['/Settings/{0}/BatteryCurrent/QuietHoursStartValue', 20.5, 0, 10000], - 'qh_batterycurrentstop': ['/Settings/{0}/BatteryCurrent/QuietHoursStopValue', 15.5, 0, 10000], - # AC load - 'acloadenabled': ['/Settings/{0}/AcLoad/Enabled', 0, 0, 1], - # Measuerement, 0 = Total AC consumption, 1 = AC on inverter output, 2 = Single phase - 'acloadmeasurement': ['/Settings/{0}/AcLoad/Measurement', 0, 0, 100], - 'acloadstart': ['/Settings/{0}/AcLoad/StartValue', 1600, 5, 1000000], - 'acloadstop': ['/Settings/{0}/AcLoad/StopValue', 800, 0, 1000000], - 'acloadstarttimer': ['/Settings/{0}/AcLoad/StartTimer', 20, 0, 10000], - 'acloadstoptimer': ['/Settings/{0}/AcLoad/StopTimer', 20, 0, 10000], - 'qh_acloadstart': ['/Settings/{0}/AcLoad/QuietHoursStartValue', 1900, 0, 1000000], - 'qh_acloadstop': ['/Settings/{0}/AcLoad/QuietHoursStopValue', 1200, 0, 1000000], - # VE.Bus high temperature - 'inverterhightempenabled': ['/Settings/{0}/InverterHighTemp/Enabled', 0, 0, 1], - 'inverterhightempstarttimer': ['/Settings/{0}/InverterHighTemp/StartTimer', 20, 0, 10000], - 'inverterhightempstoptimer': ['/Settings/{0}/InverterHighTemp/StopTimer', 20, 0, 10000], - # VE.Bus overload - 'inverteroverloadenabled': ['/Settings/{0}/InverterOverload/Enabled', 0, 0, 1], - 'inverteroverloadstarttimer': ['/Settings/{0}/InverterOverload/StartTimer', 20, 0, 10000], - 'inverteroverloadstoptimer': ['/Settings/{0}/InverterOverload/StopTimer', 20, 0, 10000], - # TestRun - 'testrunenabled': ['/Settings/{0}/TestRun/Enabled', 0, 0, 1], - 'testrunstartdate': ['/Settings/{0}/TestRun/StartDate', 1483228800, 0, 10000000000.1], - 'testrunstarttimer': ['/Settings/{0}/TestRun/StartTime', 54000, 0, 86400], - 'testruninterval': ['/Settings/{0}/TestRun/Interval', 28, 1, 365], - 'testrunruntime': ['/Settings/{0}/TestRun/Duration', 7200, 1, 86400], - 'testrunskipruntime': ['/Settings/{0}/TestRun/SkipRuntime', 0, 0, 100000], - 'testruntillbatteryfull': ['/Settings/{0}/TestRun/RunTillBatteryFull', 0, 0, 1], - # Alarms - 'nogeneratoratacinalarm': ['/Settings/{0}/Alarms/NoGeneratorAtAcIn', 0, 0, 1], - # Warm-up and Cool-down - 'warmuptime': ['/Settings/{0}/WarmUpTime', 0, 0, 600], - 'cooldowntime': ['/Settings/{0}/CoolDownTime', 0, 0, 600] - } - - settings = {} - dbus_tree = dict(commondbustree) - - for m in self._modules: - # Create settings for each module - # Settings are created under the module prefix, for example: - # /Settings/Generator0/AcLoad/Enabled - # /Settings/FischerPanda0/AcLoad/Enabled - for s in settingsbase: - v = settingsbase[s][:] # Copy - v[0] = v[0].format(m.name) - settings[s + m.name] = v - - # Get all services/paths that must be monitored - # There are a base of common services/pathas that must be monitored - # for the correct function such as battery monitors of vebus devices - # and a extra ones that is only used by a certain module, these - # are mainly the "remote switch". - for i in m.monitoring: - if i in commondbustree: - for s in m.monitoring[i]: - dbus_tree[i][s] = m.monitoring[i][s] - else: - dbus_tree[i] = m.monitoring[i] - - # Create settings device which is shared - self._settings = self._create_settings(settings, self._handlechangedsetting) - - # Create dbusmonitor, this is shared by all the instances - self._dbusmonitor = self._create_dbus_monitor(dbus_tree, valueChangedCallback=self._dbus_value_changed, - deviceAddedCallback=self._device_added, deviceRemovedCallback=self._device_removed) - - # Set timezone to user selected timezone - tz = self._dbusmonitor.get_value('com.victronenergy.settings', '/Settings/System/TimeZone') - os.environ['TZ'] = tz if tz else 'UTC' - time.tzset() - - # Call device_added for all existing devices at startup. - for service, instance in self._dbusmonitor.get_service_list().items(): - self._device_added(service, instance) - - GLib.timeout_add(1000, exit_on_error, self._handletimertick) - - def _handlechangedsetting(self, setting, oldvalue, newvalue): - for i in self._instances: - self._instances[i].handlechangedsetting(setting, oldvalue, newvalue) - - def _device_added(self, dbusservicename, instance): - # If settings check built-in relays - if dbusservicename == 'com.victronenergy.settings': - self._handle_builtin_relay('/Settings/Relay/Function') - - self._add_device(dbusservicename) - - for i in self._instances: - self._instances[i].device_added(dbusservicename, instance) - - def _dbus_value_changed(self, dbusServiceName, dbusPath, options, changes, deviceInstance): - # Track built-in relays - if "/Settings/Relay/Function" in dbusPath: - self._handle_builtin_relay(dbusPath) - - # Some devices like Fischer Panda gensets doesn't disappear from dbus - # when disconnected so check '/Connected' value to add or remove start/stop - # for that device - if dbusPath == "/Connected": - if self._dbusmonitor.get_value(dbusServiceName, dbusPath) == 0: - self._remove_device(dbusServiceName) - else: - self._add_device(dbusServiceName) - - # Update env timezone when setting changes - if (dbusServiceName, dbusPath) == ('com.victronenergy.settings', '/Settings/System/TimeZone'): - os.environ['TZ'] = changes['Value'] if changes['Value'] else 'UTC' - time.tzset() - - for i in self._instances: - self._instances[i].dbus_value_changed(dbusServiceName, dbusPath, options, changes, deviceInstance) - - def _device_removed(self, dbusservicename, instance): - if dbusservicename == 'com.victronenergy.settings': - self._handle_builtin_relay('/Settings/Relay/Function') - for i in self._instances: - self._instances[i].device_removed(dbusservicename, instance) - self._remove_device(dbusservicename) - - def _create_dbus_monitor(self, *args, **kwargs): - return DbusMonitor(*args, **kwargs) - - def _create_settings(self, *args, **kwargs): - bus = dbus.SessionBus() if 'DBUS_SESSION_BUS_ADDRESS' in os.environ else dbus.SystemBus() - return SettingsDevice(bus, *args, timeout=10, **kwargs) - - def _add_device(self, service): - for i in self._modules: - # Check if module can handle this service - if i.remoteprefix not in service: - continue - # Check and create start/stop instance for the device - if i.check_device(self._dbusmonitor, service): - self._instances[service] = i.create(self._dbusmonitor, - service, self._settings, i.device_instance) - - def _handle_builtin_relay(self, dbuspath): - function = self._dbusmonitor.get_value('com.victronenergy.settings', dbuspath) - relaynr = 'generator0' - relayservice = 'com.victronenergy.system' - - # Create a instance if relay function is set to 1 (gen. start/stop) - # otherwise remove the instance if exists - if function == 1: - self._instances[relaynr] = relay.create(self._dbusmonitor, - relayservice, - self._settings, relay.device_instance) - elif relaynr in self._instances: - self._instances[relaynr].remove() - del self._instances[relaynr] - - def _remove_device(self, servicename): - if servicename in self._instances: - if self._instances[servicename] is not None: - self._instances[servicename].remove() - del self._instances[servicename] - - def terminate(self, signum, frame): - # Remove instances before exiting, remote services might need to perform actions before releasing control - # of the switch - for i in self._instances: - self._instances[i].remove() - os._exit(0) - - def _handletimertick(self): - # try catch, to make sure that we kill ourselves on an error. Without this try-catch, there would - # be an error written to stdout, and then the timer would not be restarted, resulting in a dead- - # lock waiting for manual intervention -> not good! - try: - for i in self._instances: - self._instances[i].tick() - except: - self._instances[i].remove() - import traceback - traceback.print_exc() - sys.exit(1) - return True - -if __name__ == '__main__': - # Argument parsing - parser = argparse.ArgumentParser( - description='Start and stop a generator based on conditions' - ) - - parser.add_argument('-d', '--debug', help='set logging level to debug', - action='store_true') - args = parser.parse_args() - - print ('-------- dbus_generator, v' + softwareversion + ' is starting up --------') - - logger = setup_logging(args.debug) - - # Have a mainloop, so we can send/receive asynchronous calls to and from dbus - DBusGMainLoop(set_as_default=True) - - generator = Generator() - signal.signal(signal.SIGTERM, generator.terminate) - - # Start and run the mainloop - mainloop = GLib.MainLoop() - mainloop.run() diff --git a/FileSets/v3.01/startstop.py b/FileSets/v3.01/startstop.py deleted file mode 100644 index db452ba2..00000000 --- a/FileSets/v3.01/startstop.py +++ /dev/null @@ -1,1463 +0,0 @@ -#!/usr/bin/python -u -# -*- coding: utf-8 -*- - -#### GuiMods -#### This file has been modified to allow the generator running state derived from the generator digital input -#### or the genset AC input -#### If the incoming generator state changes, the manual start state is updated -#### time accumulation is suspended when the generator is not running -#### A switch in the generator settings menucontrols whethter the incoming state affects manual start or time accumulaiton -#### It is now possible to start the generator manually and have it stop automatically based on the preset conditions -#### for automaitc start / stop -#### A service interval timer was added so the accumulated run time does not need to be reset, -#### providing total run time for the generator -#### warm-up and cool-down periods have been modified in order to work well with an external transfer switch -#### selecting grid or generator ahead of a MultiPlus input. -#### Search for #### GuiMods to find changes - -# Function -# dbus_generator monitors the dbus for batteries (com.victronenergy.battery.*) and -# vebus com.victronenergy.vebus.* -# Battery and vebus monitors can be configured through the gui. -# It then monitors SOC, AC loads, battery current and battery voltage,to auto start/stop the generator based -# on the configuration settings. Generator can be started manually or periodically setting a tes trun period. -# Time zones function allows to use different values for the conditions along the day depending on time - -import dbus -import datetime -import calendar -import time -import sys -import json -import os -import logging -from collections import OrderedDict -import monotonic_time -from gen_utils import SettingsPrefix, Errors, States, enum -from gen_utils import create_dbus_service -# Victron packages -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) -from ve_utils import exit_on_error -from settingsdevice import SettingsDevice - -RunningConditions = enum( - Stopped = 0, - Manual = 1, - TestRun = 2, - LossOfCommunication = 3, - Soc = 4, - Acload = 5, - BatteryCurrent = 6, - BatteryVoltage = 7, - InverterHighTemp = 8, - InverterOverload = 9, - StopOnAc1 = 10) - -Capabilities = enum( - WarmupCooldown = 1 -) - -SYSTEM_SERVICE = 'com.victronenergy.system' -BATTERY_PREFIX = '/Dc/Battery' -HISTORY_DAYS = 30 - -def safe_max(args): - try: - return max(x for x in args if x is not None) - except ValueError: - return None - -class Condition(object): - def __init__(self, parent): - self.parent = parent - self.reached = False - self.start_timer = 0 - self.stop_timer = 0 - self.valid = True - self.enabled = False - self.retries = 0 - - def __getitem__(self, key): - try: - return getattr(self, key) - except AttributeError: - raise KeyError(key) - - def __setitem__(self, key, value): - setattr(self, key, value) - - def get_value(self): - raise NotImplementedError("get_value") - - @property - def vebus_service(self): - return self.parent._vebusservice if self.parent._vebusservice else '' - - @property - def monitor(self): - return self.parent._dbusmonitor - -class SocCondition(Condition): - name = 'soc' - monitoring = 'battery' - boolean = False - timed = False - - def get_value(self): - return self.parent._get_battery().soc - -class AcLoadCondition(Condition): - name = 'acload' - monitoring = 'vebus' - boolean = False - timed = True - - def get_value(self): - loadOnAcOut = [] - totalConsumption = [] - - for phase in ['L1', 'L2', 'L3']: - # Get the values directly from the inverter, systemcalc doesn't provide raw inverted power - loadOnAcOut.append(self.monitor.get_value(self.vebus_service, ('/Ac/Out/%s/P' % phase))) - - # Calculate total consumption, '/Ac/Consumption/%s/Power' is deprecated - c_i = self.monitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnInput/%s/Power' % phase)) - c_o = self.monitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnOutput/%s/Power' % phase)) - totalConsumption.append(sum(filter(None, (c_i, c_o)))) - - # Invalidate if vebus is not available - if loadOnAcOut[0] == None: - return None - - # Total consumption - if self.parent._settings['acloadmeasurement'] == 0: - return sum(filter(None, totalConsumption)) - - # Load on inverter AC out - if self.parent._settings['acloadmeasurement'] == 1: - return sum(filter(None, loadOnAcOut)) - - # Highest phase load - if self.parent._settings['acloadmeasurement'] == 2: - return safe_max(loadOnAcOut) - -class BatteryCurrentCondition(Condition): - name = 'batterycurrent' - monitoring = 'battery' - boolean = False - timed = True - - def get_value(self): - c = self.parent._get_battery().current - if c is not None: - c *= -1 - return c - -class BatteryVoltageCondition(Condition): - name = 'batteryvoltage' - monitoring = 'battery' - boolean = False - timed = True - - def get_value(self): - return self.parent._get_battery().voltage - -class InverterTempCondition(Condition): - name = 'inverterhightemp' - monitoring = 'vebus' - boolean = True - timed = True - - def get_value(self): - v = self.monitor.get_value(self.vebus_service, - '/Alarms/HighTemperature') - - # When multi is connected to CAN-bus, alarms are published to - # /Alarms/HighTemperature... but when connected to vebus alarms are - # splitted in three phases and published to /Alarms/LX/HighTemperature... - if v is None: - inverterHighTemp = [] - for phase in ['L1', 'L2', 'L3']: - # Inverter alarms must be fetched directly from the inverter service - inverterHighTemp.append(self.monitor.get_value(self.vebus_service, ('/Alarms/%s/HighTemperature' % phase))) - return safe_max(inverterHighTemp) - return v - -class InverterOverloadCondition(Condition): - name = 'inverteroverload' - monitoring = 'vebus' - boolean = True - timed = True - - def get_value(self): - v = self.monitor.get_value(self.vebus_service, - '/Alarms/Overload') - - # When multi is connected to CAN-bus, alarms are published to - # /Alarms/Overload... but when connected to vebus alarms are - # splitted in three phases and published to /Alarms/LX/Overload... - if v is None: - inverterOverload = [] - for phase in ['L1', 'L2', 'L3']: - # Inverter alarms must be fetched directly from the inverter service - inverterOverload.append(self.monitor.get_value(self.vebus_service, ('/Alarms/%s/Overload' % phase))) - return safe_max(inverterOverload) - return v - -class StopOnAc1Condition(Condition): - name = 'stoponac1' - monitoring = 'vebus' - boolean = True - timed = False - - def get_value(self): - # AC input 1 - available = self.monitor.get_value(self.vebus_service, - '/Ac/State/AcIn1Available') - if available is None: - # Not supported in firmware, fall back to old behaviour - activein = self.monitor.get_value(self.vebus_service, - '/Ac/ActiveIn/ActiveInput') - - # Active input is connected - connected = self.monitor.get_value(self.vebus_service, - '/Ac/ActiveIn/Connected') - if None not in (activein, connected): - return activein == 0 and connected == 1 - return None - - return bool(available) - -class StopOnAc2Condition(Condition): - name = 'stoponac2' - monitoring = 'vebus' - boolean = True - timed = False - - def get_value(self): - # AC input 2 available (used when grid is on AC-in-2) - available = self.monitor.get_value(self.vebus_service, - '/Ac/State/AcIn2Available') - - return None if available is None else bool(available) - -class Battery(object): - def __init__(self, monitor, service, prefix): - self.monitor = monitor - self.service = service - self.prefix = prefix - - @property - def voltage(self): - return self.monitor.get_value(self.service, self.prefix + '/Voltage') - - @property - def current(self): - return self.monitor.get_value(self.service, self.prefix + '/Current') - - @property - def soc(self): - # Soc from the device doesn't have the '/Dc/0' prefix like the current and voltage do, but it does - # have the same prefix on systemcalc - return self.monitor.get_value(self.service, (BATTERY_PREFIX if self.prefix == BATTERY_PREFIX else '') + '/Soc') - -class StartStop(object): - _driver = None - def __init__(self, instance): -#### GuiMods - self._currentTime = 0 - self._last_update_mtime = 0 - self._accumulatedRunTime = 0 - self._digitalInputTypeObject = None - self._generatorInputStateObject = 0 - self._lastState = 0 - self._externalOverride = False - self._externalOverrideDelay = 99 - self._lastExternalOverride = False - self._searchDelay = 99 - self._linkToExternalState = False - - self._dbusservice = None - self._settings = None - self._dbusmonitor = None - self._remoteservice = None - self._name = None - self._enabled = False - self._instance = instance - - # One second per retry - self.RETRIES_ON_ERROR = 300 - self._testrun_soc_retries = 0 - self._last_counters_check = 0 - -#### GuiMods warm-up / cool-down - self._warmUpEndTime = 0 - self._coolDownEndTime = 0 - self._postCoolDownEndTime = 0 - self._ac1isIgnored = False - self._ac2isIgnored = False - self._activeAcInIsIgnored = False - self._acInIsGenerator = False - self._generatorAcInput = 0 - - self._manualstarttimer = 0 - self._last_runtime_update = 0 - self._timer_runnning = 0 - - # Manual battery service selection is deprecated in favour - # of getting the values directly from systemcalc, we keep - # manual selected services handling for compatibility reasons. - self._vebusservice = None - self._errorstate = 0 - self._battery_service = None - self._battery_prefix = None - - self._acpower_inverter_input = { - 'timeout': 0, - 'unabletostart': False - } - - # Order is important. Conditions are evaluated in the order listed. - self._condition_stack = OrderedDict({ - SocCondition.name: SocCondition(self), - AcLoadCondition.name: AcLoadCondition(self), - BatteryCurrentCondition.name: BatteryCurrentCondition(self), - BatteryVoltageCondition.name: BatteryVoltageCondition(self), - InverterTempCondition.name: InverterTempCondition(self), - InverterOverloadCondition.name: InverterOverloadCondition(self), - StopOnAc1Condition.name: StopOnAc1Condition(self), - StopOnAc2Condition.name: StopOnAc2Condition(self) - }) - - def set_sources(self, dbusmonitor, settings, name, remoteservice): - self._settings = SettingsPrefix(settings, name) - self._dbusmonitor = dbusmonitor - self._remoteservice = remoteservice - self._name = name - - self.log_info('Start/stop instance created for %s.' % self._remoteservice) - self._remote_setup() - - def _create_service(self): - self._dbusservice = self._create_dbus_service() - - # The driver used for this start/stop service - self._dbusservice.add_path('/Type', value=self._driver) - # State: None = invalid, 0 = stopped, 1 = running, 2=Warm-up, 3=Cool-down - self._dbusservice.add_path('/State', value=None, gettextcallback=lambda p, v: States.get_description(v)) - # RunningByConditionCode: Numeric Companion to /RunningByCondition below, but - # also encompassing a Stopped state. - self._dbusservice.add_path('/RunningByConditionCode', value=None) - # Error - self._dbusservice.add_path('/Error', value=None, gettextcallback=lambda p, v: Errors.get_description(v)) - # Condition that made the generator start - self._dbusservice.add_path('/RunningByCondition', value=None) - # Runtime - self._dbusservice.add_path('/Runtime', value=None, gettextcallback=self._seconds_to_text) - # Today runtime - self._dbusservice.add_path('/TodayRuntime', value=None, gettextcallback=self._seconds_to_text) - # Test run runtime - self._dbusservice.add_path('/TestRunIntervalRuntime', value=None , gettextcallback=self._seconds_to_text) - # Next test run date, values is 0 for test run disabled - self._dbusservice.add_path('/NextTestRun', value=None, gettextcallback=lambda p, v: datetime.datetime.fromtimestamp(v).strftime('%c')) - # Next test run is needed 1, not needed 0 - self._dbusservice.add_path('/SkipTestRun', value=None) - # Manual start - self._dbusservice.add_path('/ManualStart', value=None, writeable=True) - # Manual start timer - self._dbusservice.add_path('/ManualStartTimer', value=None, writeable=True) - # Silent mode active - self._dbusservice.add_path('/QuietHours', value=None) - # Alarms - self._dbusservice.add_path('/Alarms/NoGeneratorAtAcIn', value=None) - # Autostart - self._dbusservice.add_path('/AutoStartEnabled', value=None, writeable=True, onchangecallback=self._set_autostart) - # Accumulated runtime - self._dbusservice.add_path('/AccumulatedRuntime', value=None) - # Capabilities, where we can add bits - self._dbusservice.add_path('/Capabilities', value=0) - - # We need to set the values after creating the paths to trigger the 'onValueChanged' event for the gui - # otherwise the gui will report the paths as invalid if we remove and recreate the paths without - # restarting the dbusservice. - self._dbusservice['/State'] = 0 - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped - self._dbusservice['/Error'] = 0 - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/Runtime'] = 0 - self._dbusservice['/TodayRuntime'] = 0 - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - self._dbusservice['/NextTestRun'] = None - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/ManualStart'] = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._dbusservice['/QuietHours'] = 0 - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - self._dbusservice['/AutoStartEnabled'] = self._settings['autostart'] - self._dbusservice['/AccumulatedRuntime'] = int(self._settings['accumulatedtotal']) - -#### GuiMods - # generator input running state - self._dbusservice.add_path('/GeneratorRunningState', value=None) - # external override active - self._dbusservice.add_path('/ExternalOverride', value=None) - self._dbusservice['/GeneratorRunningState'] = "?" - self._dbusservice['/ExternalOverride'] = False - self._ignoreAutoStartCondition = False - - @property - def capabilities(self): - return self._dbusservice['/Capabilities'] - - def _set_autostart(self, path, value): - if 0 <= value <= 1: - self._settings['autostart'] = int(value) - return True - return False - - def enable(self): - if self._enabled: - return - self.log_info('Enabling auto start/stop and taking control of remote switch') - self._create_service() - self._determineservices() - self._update_remote_switch() - # If cooldown or warmup is enabled, the Quattro may be left in a bad - # state if there is an unfortunate crash or a reboot. Set the ignore_ac - # flag to a sane value on startup. - if self._settings['cooldowntime'] > 0 or \ - self._settings['warmuptime'] > 0: - self._set_ignore_ac1(False) - self._set_ignore_ac2(False) - self._enabled = True - - def disable(self): - if not self._enabled: - return - self.log_info('Disabling auto start/stop, releasing control of remote switch') - self._remove_service() - self._enabled = False - - def remove(self): - self.disable() - self.log_info('Removed from start/stop instances') - - def _remove_service(self): - self._dbusservice.__del__() - self._dbusservice = None - - def device_added(self, dbusservicename, instance): - self._determineservices() - - def device_removed(self, dbusservicename, instance): - self._determineservices() - - def get_error(self): - return self._dbusservice['/Error'] - - def set_error(self, errorn): - self._dbusservice['/Error'] = errorn - - def clear_error(self): - self._dbusservice['/Error'] = Errors.NONE - - def dbus_value_changed(self, dbusServiceName, dbusPath, options, changes, deviceInstance): - if self._dbusservice is None: - return - - # AcIn1Available is needed to determine capabilities, but may - # only show up later. So we have to wait for it here. - if self._vebusservice is not None and \ - dbusServiceName == self._vebusservice and \ - dbusPath == '/Ac/State/AcIn1Available': - self._set_capabilities() - - if dbusServiceName != 'com.victronenergy.system': - return - if dbusPath == '/AutoSelectedBatteryMeasurement' and self._settings['batterymeasurement'] == 'default': - self._determineservices() - - if dbusPath == '/VebusService': - self._determineservices() - - def handlechangedsetting(self, setting, oldvalue, newvalue): - if self._dbusservice is None: - return - if self._name not in setting: - # Not our setting - return - - s = self._settings.removeprefix(setting) - - if s == 'batterymeasurement': - self._determineservices() - # Reset retries and valid if service changes - for condition in self._condition_stack.values(): - if condition['monitoring'] == 'battery': - condition['valid'] = True - condition['retries'] = 0 - - if s == 'autostart': - self.log_info('Autostart function %s.' % ('enabled' if newvalue == 1 else 'disabled')) - self._dbusservice['/AutoStartEnabled'] = self._settings['autostart'] - - if self._dbusservice is not None and s == 'testruninterval': - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime( - self._settings['testruninterval']) - - def _seconds_to_text(self, path, value): - m, s = divmod(value, 60) - h, m = divmod(m, 60) - return '%dh, %dm, %ds' % (h, m, s) - - def log_info(self, msg): - logging.info(self._name + ': %s' % msg) - - - def tick(self): - if not self._enabled: - return - -#### GuiMods warm-up / cool-down - # determine which AC input is connected to the generator - try: - if self._dbusmonitor.get_value ('com.victronenergy.settings', '/Settings/SystemSetup/AcInput1') == 2: - self._generatorAcInput = 1 - elif self._dbusmonitor.get_value (SYSTEM_SERVICE, '/Ac/In/NumberOfAcInputs') >= 2 \ - and self._dbusmonitor.get_value ('com.victronenergy.settings', '/Settings/SystemSetup/AcInput2') == 2: - self._generatorAcInput = 2 - # no generator input found - else: - self._generatorAcInput = 0 - except: - self._generatorAcInput = 0 - - -#### GuiMods warm-up / cool-down - self._currentTime = self._get_monotonic_seconds () - - self._check_remote_status() -#### GuiMods - self._linkToExternalState = self._settings['linkManualStartToExternal'] == 1 - self._processGeneratorRunDetection () - - self._evaluate_startstop_conditions() - self._detect_generator_at_acinput() - -#### GuiMods warm-up / cool-down - state = self._dbusservice['/State'] - running = state in (States.WARMUP, States.COOLDOWN, States.RUNNING) - - # shed load for active generator input in warm-up and cool-down - # note that external transfer switch might change the state of on generator - # so this needs to be checked and load adjusted every pass - # restore load for sources no longer in use or if state is not in warm-up/cool-down - # restoring load is delayed 1following end of cool-down - # to allow the generator to actually stop producing power - if state in (States.WARMUP, States.COOLDOWN) or self._currentTime < self._postCoolDownEndTime: - self._ignore_ac (True) - else: - self._ignore_ac (False) - - # update cool down end time while running and generator has the load - # this is done because acInIsGenerator may change by an external transfer switch - # and the input type changed by the ExtTransferSwitch service - if running and not self._activeAcInIsIgnored and self._acInIsGenerator: - self._coolDownEndTime = self._currentTime + self._settings['cooldowntime'] -#### end GuiMods warm-up / cool-down - - - def _evaluate_startstop_conditions(self): - if self.get_error() != Errors.NONE: - # First evaluation after an error, log it - if self._errorstate == 0: - self._errorstate = 1 - self._dbusservice['/State'] = States.ERROR - self.log_info('Error: #%i - %s, stop controlling remote.' % - (self.get_error(), - Errors.get_description(self.get_error()))) - elif self._errorstate == 1: - # Error cleared - self._errorstate = 0 - self.log_info('Error state cleared, taking control of remote switch.') - - start = False - startbycondition = None - activecondition = self._dbusservice['/RunningByCondition'] - today = calendar.timegm(datetime.date.today().timetuple()) - self._timer_runnning = False - connection_lost = False - - self._check_quiet_hours() - - # New day, register it - if self._last_counters_check < today and self._dbusservice['/State'] == States.STOPPED: - self._last_counters_check = today - self._update_accumulated_time() - - # Update current and accumulated runtime. -#### GuiMods - self._accumulateRunTime () - -#### GuiMods - # A negative /ManualStartTimer is used by the GUI to signal the generator should start now - # but stop when all auto stop conditions have been met - # so we skip manual start evaluation if this is the case - # and set a flag for use below to ignore auto start conditions - # the generator is actually started by the auto start/stop logic below - if self._dbusservice['/ManualStartTimer'] < 0 and self._dbusservice['/ManualStart'] == 1: - self._dbusservice['/ManualStartTimer'] = 0 - self._dbusservice['/ManualStart'] = 0 - self._ignoreAutoStartCondition = True - else: - self._ignoreAutoStartCondition = False - if self._evaluate_manual_start(): - startbycondition = 'manual' - start = True - - # Conditions will only be evaluated if the autostart functionality is enabled - if self._settings['autostart'] == 1: - - if self._evaluate_testrun_condition(): - startbycondition = 'testrun' - start = True - - # Evaluate value conditions - for condition, data in self._condition_stack.items(): - # Don't short-circuit this, _evaluate_condition sets .reached - start = self._evaluate_condition(data) or start - startbycondition = condition if start and startbycondition is None else startbycondition - # Connection lost is set to true if the number of retries of one or more enabled conditions - # >= RETRIES_ON_ERROR - if data.enabled: - connection_lost = data.retries >= self.RETRIES_ON_ERROR - - if startbycondition not in ['manual', 'testrun']: - if self._condition_stack[StopOnAc1Condition.name].reached or \ - self._condition_stack[StopOnAc2Condition.name].reached: - start = False - if self._dbusservice['/State'] in (States.RUNNING, States.WARMUP) and activecondition not in ['manual', 'testrun']: - self.log_info('AC input available, stopping') - - # If none condition is reached check if connection is lost and start/keep running the generator - # depending on '/OnLossCommunication' setting - if not start and connection_lost: - # Start always - if self._settings['onlosscommunication'] == 1: - start = True - startbycondition = 'lossofcommunication' - # Keep running if generator already started - if self._dbusservice['/State'] in (States.RUNNING, States.WARMUP) and self._settings['onlosscommunication'] == 2: - start = True - startbycondition = 'lossofcommunication' - -#### GuiMods - ## auto start disabled and generator is stopped - clear the 'reached' flags - elif self._dbusservice['/State'] == States.STOPPED: - for condition, data in self._condition_stack.items(): - self._reset_condition(data) - - if not start and self._errorstate: - self._stop_generator() - - if self._errorstate: - return - - if start: - self._start_generator(startbycondition) -#### GuiMods - # bypass the minimum run time check if External Override is active - elif (self._dbusservice['/Runtime'] >= self._settings['minimumruntime'] * 60 - or activecondition == 'manual') or self._dbusservice['/ExternalOverride']: - self._stop_generator() - -#### GuiMods warm-up / cool-down - rewrote so acInIsGenerator is updated even if alarm is disabled - def _detect_generator_at_acinput(self): -#### GuiMods warm-up / cool-down - self._acInIsGenerator = False # covers all conditions that result in a return - - state = self._dbusservice['/State'] - if state == States.STOPPED: - self._reset_acpower_inverter_input() - return - - vebus_service = self._vebusservice if self._vebusservice else '' - activein_state = self._dbusmonitor.get_value( - vebus_service, '/Ac/ActiveIn/Connected') - - # Path not supported, skip evaluation - if activein_state == None: - return - - # Sources 0 = Not available, 1 = Grid, 2 = Generator, 3 = Shore - generator_acsource = self._dbusmonitor.get_value( - SYSTEM_SERVICE, '/Ac/ActiveIn/Source') == 2 - # Not connected = 0, connected = 1 - activein_connected = activein_state == 1 - -#### GuiMods warm-up / cool-down - if self._settings['nogeneratoratacinalarm'] == 0: - processAlarm = False - self._reset_acpower_inverter_input() - else: - processAlarm = True - - if generator_acsource and activein_connected: -#### GuiMods warm-up / cool-down - self._acInIsGenerator = True -#### GuiMods warm-up / cool-down - if processAlarm and self._acpower_inverter_input['unabletostart']: - self.log_info('Generator detected at inverter AC input, alarm removed') - self._reset_acpower_inverter_input() -#### GuiMods warm-up / cool-down - elif not processAlarm: - self._reset_acpower_inverter_input() - return - elif self._acpower_inverter_input['timeout'] < self.RETRIES_ON_ERROR: - self._acpower_inverter_input['timeout'] += 1 - elif not self._acpower_inverter_input['unabletostart']: - self._acpower_inverter_input['unabletostart'] = True - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 2 - self.log_info('Generator not detected at inverter AC input, triggering alarm') - - - def _reset_acpower_inverter_input(self, clear_error=True): - if self._acpower_inverter_input['timeout'] != 0: - self._acpower_inverter_input['timeout'] = 0 - - if self._acpower_inverter_input['unabletostart'] != 0: - self._acpower_inverter_input['unabletostart'] = 0 - - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - - def _reset_condition(self, condition): - condition['reached'] = False - if condition['timed']: - condition['start_timer'] = 0 - condition['stop_timer'] = 0 - - def _check_condition(self, condition, value): - name = condition['name'] - - if self._settings[name + 'enabled'] == 0: - if condition['enabled']: - condition['enabled'] = False - self.log_info('Disabling (%s) condition' % name) - condition['retries'] = 0 - condition['valid'] = True - self._reset_condition(condition) - return False - - elif not condition['enabled']: - condition['enabled'] = True - self.log_info('Enabling (%s) condition' % name) - - if (condition['monitoring'] == 'battery') and (self._settings['batterymeasurement'] == 'nobattery'): - # If no battery monitor is selected reset the condition - self._reset_condition(condition) - return False - - if value is None and condition['valid']: - if condition['retries'] >= self.RETRIES_ON_ERROR: - logging.info('Error getting (%s) value, skipping evaluation till get a valid value' % name) - self._reset_condition(condition) - self._comunnication_lost = True - condition['valid'] = False - else: - condition['retries'] += 1 - if condition['retries'] == 1 or (condition['retries'] % 10) == 0: - self.log_info('Error getting (%s) value, retrying(#%i)' % (name, condition['retries'])) - return False - - elif value is not None and not condition['valid']: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['valid'] = True - condition['retries'] = 0 - - # Reset retries if value is valid - if value is not None and condition['retries'] > 0: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['retries'] = 0 - - return condition['valid'] - - def _evaluate_condition(self, condition): - name = condition['name'] - value = condition.get_value() - setting = ('qh_' if self._dbusservice['/QuietHours'] == 1 else '') + name - startvalue = self._settings[setting + 'start'] if not condition['boolean'] else 1 - stopvalue = self._settings[setting + 'stop'] if not condition['boolean'] else 0 - - # Check if the condition has to be evaluated - if not self._check_condition(condition, value): - # If generator is started by this condition and value is invalid - # wait till RETRIES_ON_ERROR to skip the condition - if condition['reached'] and condition['retries'] <= self.RETRIES_ON_ERROR: - if condition['retries'] > 0: - return True - - return False - - # As this is a generic evaluation method, we need to know how to compare the values - # first check if start value should be greater than stop value and then compare - start_is_greater = startvalue > stopvalue - -#### GuiMods - stop = value <= stopvalue if start_is_greater else value >= stopvalue - # when starting manually and stopping based on auto stop values, - # start if stop condition is not satisfied - if self._ignoreAutoStartCondition: - start = not stop - else: - # When the condition is already reached only the stop value can set it to False - start = condition['reached'] or (value >= startvalue if start_is_greater else value <= startvalue) - - # Timed conditions must start/stop after the condition has been reached for a minimum - # time. - if condition['timed']: - if not condition['reached'] and start: - condition['start_timer'] += time.time() if condition['start_timer'] == 0 else 0 - start = time.time() - condition['start_timer'] >= self._settings[name + 'starttimer'] - condition['stop_timer'] *= int(not start) - self._timer_runnning = True - else: - condition['start_timer'] = 0 - - if condition['reached'] and stop: - condition['stop_timer'] += time.time() if condition['stop_timer'] == 0 else 0 - stop = time.time() - condition['stop_timer'] >= self._settings[name + 'stoptimer'] - condition['stop_timer'] *= int(not stop) - self._timer_runnning = True - else: - condition['stop_timer'] = 0 - - condition['reached'] = start and not stop - return condition['reached'] - - def _evaluate_manual_start(self): - if self._dbusservice['/ManualStart'] == 0: - if self._dbusservice['/RunningByCondition'] == 'manual': - self._dbusservice['/ManualStartTimer'] = 0 - return False - - start = True - # If /ManualStartTimer has a value greater than zero will use it to set a stop timer. - # If no timer is set, the generator will not stop until the user stops it manually. - # Once started by manual start, each evaluation the timer is decreased -#### GuiMods - if self._dbusservice['/ManualStartTimer'] > 0: - self._manualstarttimer += time.time() if self._manualstarttimer == 0 else 0 - self._dbusservice['/ManualStartTimer'] -= int(time.time()) - int(self._manualstarttimer) - self._manualstarttimer = time.time() - start = self._dbusservice['/ManualStartTimer'] > 0 - self._dbusservice['/ManualStart'] = int(start) - # Reset if timer is finished - self._manualstarttimer *= int(start) - self._dbusservice['/ManualStartTimer'] *= int(start) - - return start - - def _evaluate_testrun_condition(self): - if self._settings['testrunenabled'] == 0: - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/NextTestRun'] = None - return False - - today = datetime.date.today() - yesterday = today - datetime.timedelta(days=1) # Should deal well with DST - now = time.time() - runtillbatteryfull = self._settings['testruntillbatteryfull'] == 1 - soc = self._condition_stack['soc'].get_value() - batteryisfull = runtillbatteryfull and soc == 100 - duration = 60 if runtillbatteryfull else self._settings['testrunruntime'] - - try: - startdate = datetime.date.fromtimestamp(self._settings['testrunstartdate']) - _starttime = time.mktime(yesterday.timetuple()) + self._settings['testrunstarttimer'] - - # today might in fact still be yesterday, if this test run started - # before midnight and finishes after. If `now` still falls in - # yesterday's window, then by the temporal anthropic principle, - # which I just made up but loosely states that time must have - # these properties for observers to exist, it must be yesterday - # because we are here to observe it. - if _starttime <= now <= _starttime + duration: - today = yesterday - starttime = _starttime - else: - starttime = time.mktime(today.timetuple()) + self._settings['testrunstarttimer'] - except ValueError: - logging.debug('Invalid dates, skipping testrun') - return False - - # If start date is in the future set as NextTestRun and stop evaluating - if startdate > today: - self._dbusservice['/NextTestRun'] = time.mktime(startdate.timetuple()) - return False - - start = False - # If the accumulated runtime during the tes trun interval is greater than '/TestRunIntervalRuntime' - # the tes trun must be skipped - needed = (self._settings['testrunskipruntime'] > self._dbusservice['/TestRunIntervalRuntime'] - or self._settings['testrunskipruntime'] == 0) - self._dbusservice['/SkipTestRun'] = int(not needed) - - interval = self._settings['testruninterval'] - stoptime = starttime + duration - elapseddays = (today - startdate).days - mod = elapseddays % interval - - start = not bool(mod) and starttime <= now <= stoptime - - if runtillbatteryfull: - if soc is not None: - self._testrun_soc_retries = 0 - start = (start or self._dbusservice['/RunningByCondition'] == 'testrun') and not batteryisfull - elif self._dbusservice['/RunningByCondition'] == 'testrun': - if self._testrun_soc_retries < self.RETRIES_ON_ERROR: - self._testrun_soc_retries += 1 - start = True - if (self._testrun_soc_retries % 10) == 0: - self.log_info('Test run failed to get SOC value, retrying(#%i)' % self._testrun_soc_retries) - else: - self.log_info('Failed to get SOC after %i retries, terminating test run condition' % self._testrun_soc_retries) - start = False - else: - start = False - - if not bool(mod) and (now <= stoptime): - self._dbusservice['/NextTestRun'] = starttime - else: - self._dbusservice['/NextTestRun'] = (time.mktime((today + datetime.timedelta(days=interval - mod)).timetuple()) + - self._settings['testrunstarttimer']) - return start and needed - - def _check_quiet_hours(self): - active = False - if self._settings['quiethoursenabled'] == 1: - # Seconds after today 00:00 - timeinseconds = time.time() - time.mktime(datetime.date.today().timetuple()) - quiethoursstart = self._settings['quiethoursstarttime'] - quiethoursend = self._settings['quiethoursendtime'] - - # Check if the current time is between the start time and end time - if quiethoursstart < quiethoursend: - active = quiethoursstart <= timeinseconds and timeinseconds < quiethoursend - else: # End time is lower than start time, example Start: 21:00, end: 08:00 - active = not (quiethoursend < timeinseconds and timeinseconds < quiethoursstart) - - if self._dbusservice['/QuietHours'] == 0 and active: - self.log_info('Entering to quiet mode') - - elif self._dbusservice['/QuietHours'] == 1 and not active: - self.log_info('Leaving quiet mode') - - self._dbusservice['/QuietHours'] = int(active) - - return active - - def _update_accumulated_time(self): - seconds = self._dbusservice['/Runtime'] - accumulated = seconds - self._last_runtime_update - - self._settings['accumulatedtotal'] = accumulatedtotal = int(self._settings['accumulatedtotal']) + accumulated -#### GuiMods - self._settings['timeSinceService'] = int(self._settings['timeSinceService']) + accumulated - # Using calendar to get timestamp in UTC, not local time - today_date = str(calendar.timegm(datetime.date.today().timetuple())) - - # If something goes wrong getting the json string create a new one - try: - accumulated_days = json.loads(self._settings['accumulateddaily']) - except ValueError: - accumulated_days = {today_date: 0} - - if (today_date in accumulated_days): - accumulated_days[today_date] += accumulated - else: - accumulated_days[today_date] = accumulated - - self._last_runtime_update = seconds - - # Keep the historical with a maximum of HISTORY_DAYS - while len(accumulated_days) > HISTORY_DAYS: - accumulated_days.pop(min(accumulated_days.keys()), None) - - # Upadate settings - self._settings['accumulateddaily'] = json.dumps(accumulated_days, sort_keys=True) - self._dbusservice['/TodayRuntime'] = self._interval_runtime(0) - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - self._dbusservice['/AccumulatedRuntime'] = accumulatedtotal - - def _interval_runtime(self, days): - summ = 0 - try: - daily_record = json.loads(self._settings['accumulateddaily']) - except ValueError: - return 0 - - for i in range(days + 1): - previous_day = calendar.timegm((datetime.date.today() - datetime.timedelta(days=i)).timetuple()) - if str(previous_day) in daily_record.keys(): - summ += daily_record[str(previous_day)] if str(previous_day) in daily_record.keys() else 0 - - return summ - - def _interval_runtime(self, days): - summ = 0 - try: - daily_record = json.loads(self._settings['accumulateddaily']) - except ValueError: - return 0 - - for i in range(days + 1): - previous_day = calendar.timegm((datetime.date.today() - datetime.timedelta(days=i)).timetuple()) - if str(previous_day) in daily_record.keys(): - summ += daily_record[str(previous_day)] if str(previous_day) in daily_record.keys() else 0 - - return summ - - def _get_battery(self): - if self._settings['batterymeasurement'] == 'default': - return Battery(self._dbusmonitor, SYSTEM_SERVICE, BATTERY_PREFIX) - - return Battery(self._dbusmonitor, - self._battery_service if self._battery_service else '', - self._battery_prefix if self._battery_prefix else '') - - def _set_capabilities(self): - # Update capabilities - # The ability to ignore AC1/AC2 came in at the same time as - # AC availability and is used to detect it here. - readout_supported = self._dbusmonitor.get_value(self._vebusservice, - '/Ac/State/AcIn1Available') is not None - self._dbusservice['/Capabilities'] |= ( - Capabilities.WarmupCooldown if readout_supported else 0) - - def _determineservices(self): - # batterymeasurement is either 'default' or 'com_victronenergy_battery_288/Dc/0'. - # In case it is set to default, we use the AutoSelected battery - # measurement, given by SystemCalc. - batterymeasurement = None - newbatteryservice = None - batteryprefix = '' - selectedbattery = self._settings['batterymeasurement'] - vebusservice = None - - if selectedbattery == 'default': - batterymeasurement = 'default' - elif len(selectedbattery.split('/', 1)) == 2: # Only very basic sanity checking.. - batterymeasurement = self._settings['batterymeasurement'] - elif selectedbattery == 'nobattery': - batterymeasurement = None - else: - # Exception: unexpected value for batterymeasurement - pass - - if batterymeasurement and batterymeasurement != 'default': - batteryprefix = '/' + batterymeasurement.split('/', 1)[1] - - # Get the current battery servicename - if self._battery_service: - oldservice = self._battery_service - else: - oldservice = None - - if batterymeasurement != 'default': - battery_instance = int(batterymeasurement.split('_', 3)[3].split('/')[0]) - service_type = None - - if 'vebus' in batterymeasurement: - service_type = 'vebus' - elif 'battery' in batterymeasurement: - service_type = 'battery' - - newbatteryservice = self._get_servicename_by_instance(battery_instance, service_type) - elif batterymeasurement == 'default': - newbatteryservice = 'default' - - if newbatteryservice and newbatteryservice != oldservice: - if selectedbattery == 'default': - self.log_info('Getting battery values from systemcalc.') - if selectedbattery == 'nobattery': - self.log_info('Battery monitoring disabled! Stop evaluating related conditions') - self._battery_service = None - self._battery_prefix = None - self.log_info('Battery service we need (%s) found! Using it for generator start/stop' % batterymeasurement) - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - elif not newbatteryservice and newbatteryservice != oldservice: - self.log_info('Error getting battery service!') - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - - # Get the default VE.Bus service - vebusservice = self._dbusmonitor.get_value('com.victronenergy.system', '/VebusService') - if vebusservice: - if self._vebusservice != vebusservice: - self._vebusservice = vebusservice - self._set_capabilities() - self.log_info('Vebus service (%s) found! Using it for generator start/stop' % vebusservice) - else: - if self._vebusservice is not None: - self.log_info('Vebus service (%s) dissapeared! Stop evaluating related conditions' % self._vebusservice) - else: - self.log_info('Error getting Vebus service!') - self._vebusservice = None - - def _get_servicename_by_instance(self, instance, service_type=None): - sv = None - services = self._dbusmonitor.get_service_list() - - for service in services: - if service_type and service_type not in service: - continue - - if services[service] == instance: - sv = service - break - - return sv - - def _get_monotonic_seconds(self): - return monotonic_time.monotonic_time().to_seconds_double() - - def _start_generator(self, condition): - state = self._dbusservice['/State'] - remote_running = self._get_remote_switch_state() - - # This function will start the generator in the case generator not - # already running. When differs, the RunningByCondition is updated - running = state in (States.WARMUP, States.COOLDOWN, States.RUNNING) - if not (running and remote_running): # STOPPED, ERROR -#### GuiMods warm-up / cool-down - self.log_info('Starting generator by %s condition' % condition) - # if there is a warmup time specified, always go through warm-up state - # regardless of AC input in use - warmUpPeriod = self._settings['warmuptime'] - if warmUpPeriod > 0: - self._warmUpEndTime = self._currentTime + warmUpPeriod - self.log_info ("starting warm-up") - self._dbusservice['/State'] = States.WARMUP - # no warm-up go directly to running - else: - self._dbusservice['/State'] = States.RUNNING - self._warmUpEndTime = 0 - - self._coolDownEndTime = 0 - self._postCoolDownEndTime = 0 - - self._update_remote_switch() - else: # WARMUP, COOLDOWN, RUNNING - if state == States.COOLDOWN: - # Start request during cool-down run, go back to RUNNING - self.log_info ("abprting cool-down - returning to running") - self._dbusservice['/State'] = States.RUNNING - - # these checks are done for each tick () whle generator is running - if state == States.WARMUP: - if self._currentTime > self._warmUpEndTime: - self.log_info ("warm-up complete") - self._dbusservice['/State'] = States.RUNNING -#### end GuiMods warm-up / cool-down - - # Update the RunningByCondition - if self._dbusservice['/RunningByCondition'] != condition: - self.log_info('Generator previously running by %s condition is now running by %s condition' - % (self._dbusservice['/RunningByCondition'], condition)) - - self._dbusservice['/RunningByCondition'] = condition - self._dbusservice['/RunningByConditionCode'] = RunningConditions.lookup(condition) - - - - def _stop_generator(self): - state = self._dbusservice['/State'] - remote_running = self._get_remote_switch_state() - running = state in (States.WARMUP, States.COOLDOWN, States.RUNNING) - - if running or remote_running: -#### GuiMods warm-up / cool-down - # run for cool-down period before stopping - # cooldown end time is updated while generator is running - # and generator feeds Multi AC input - if self._currentTime < self._coolDownEndTime: - if state != States.COOLDOWN: - self._dbusservice['/State'] = States.COOLDOWN - self.log_info ("starting cool-down") - return - - # When we arrive here, a stop command was given and cool-down period has elapesed - if state == States.COOLDOWN: - self.log_info ("cool-down complete") - # delay restoring load to give generator a chance to stop - self._postCoolDownEndTime = self._currentTime + self._settings['postcooldowntime'] - self._dbusservice['/State'] = States.STOPPED - self._update_remote_switch() -#### end GuiMods warm-up / cool-down - - self.log_info('Stopping generator that was running by %s condition' % - str(self._dbusservice['/RunningByCondition'])) - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped - - self._accumulateRunTime () - - self._starttime = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._manualstarttimer = 0 - self._last_runtime_update = 0 - - - # This is here so the Multi/Quattro can be told to disconnect AC-in, - # so that we can do warm-up and cool-down. -#### GuiMods warm-up / cool-down - # there may be two AC inputs (Quattro). process both - - def _ignore_ac (self, state): - self._activeAcInIsIgnored = state - state1 = False - state2 = False - if self._generatorAcInput == 1: - state1 = state - elif self._generatorAcInput == 2: - state2 = state - - if state1 != self._ac1isIgnored: - if state1: - self.log_info ("shedding load - AC input 1") - else: - self.log_info ("restoring load - AC input 1") - self._set_ignore_ac1 (state1) - self._ac1isIgnored = state1 - - if state2 != self._ac2isIgnored: - if state2: - self.log_info ("shedding load - AC input 2") - else: - self.log_info ("restoring load - AC input 2") - self._set_ignore_ac2 (state2) - self._ac2isIgnored = state2 - - - def _set_ignore_ac1(self, ignore): - if self._vebusservice is not None: - self._dbusmonitor.set_value_async(self._vebusservice, '/Ac/Control/IgnoreAcIn1', dbus.Int32(ignore, variant_level=1)) - - def _set_ignore_ac2(self, ignore): - if self._vebusservice is not None: - self._dbusmonitor.set_value_async(self._vebusservice, '/Ac/Control/IgnoreAcIn2', dbus.Int32(ignore, variant_level=1)) - - def _update_remote_switch(self): - # Engine should be started in these states - v = self._dbusservice['/State'] in (States.RUNNING, States.WARMUP, States.COOLDOWN) - self._set_remote_switch_state(dbus.Int32(v, variant_level=1)) - - def _get_remote_switch_state(self): - raise Exception('This function should be overridden') - - def _set_remote_switch_state(self, value): - raise Exception('This function should be overridden') - - # Check the remote status, for example errors - def _check_remote_status(self): - raise Exception('This function should be overridden') - - def _remote_setup(self): - raise Exception('This function should be overridden') - - def _create_dbus_monitor(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_settings(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_dbus_service(self): - return create_dbus_service(self._instance) - -#### GuiMods - -# this function connects the generator digital input (if any) -# OR the generator AC input detection -# to the generator /ManualStart and updates dbus paths used by the GUI -# -# if the generator digital input changes from stopped to running -# AND no run conditions are active, a manual start is innitiated -# -# if the generator digital input changes from running to stopped -# AND a manual start is active, a manual stop is innitiated -# -# /GeneratorRunningState provides the input running state from the digital input to the GUI -# R = running -# S = stopped -# ? = unknown (no digital input found) -# -# /ExternalOverride is used by the GUI to alert the user when there is a conflict -# between the generator running state and the state Venus -# /ExternalOverride is True if /GeneratorRunningState is S -# AND the /RunningCondition is not stopped (which includes a manual run) -# activation is delayed 5 seconds to allow transitions to settle -# -# we must first find the geneator digital input, if it exists at all -# we serche all dBus services looking for a digital input with type generator (9) -# the search only occurs every 10 seconds -# - - def _processGeneratorRunDetection (self): - TheBus = dbus.SystemBus() - generatorState = self._dbusservice['/State'] - try: - # current input service is no longer valid - # search for a new one only every 10 seconds to avoid unnecessary processing - if (self._digitalInputTypeObject == None or self._digitalInputTypeObject.GetValue() != 9) and self._searchDelay > 10: - newInputService = "" - for service in TheBus.list_names(): - # found a digital input servic, now check the type - if service.startswith ("com.victronenergy.digitalinput"): - self._digitalInputTypeObject = TheBus.get_object (service, '/Type') - # found it! - if self._digitalInputTypeObject.GetValue() == 9: - newInputService = service - break - - # found new service - get objects for use later - if newInputService != "": - self.log_info ("Found generator digital input service at %s" % newInputService) - self._generatorInputStateObject = TheBus.get_object(newInputService, '/State') - else: - if self._generatorInputStateObject != None: - self.log_info ("Generator digital input service NOT found") - self._generatorInputStateObject = None - self._digitalInputTypeObject = None - self._searchDelay = 0 # start delay timer - - # if serch delay timer is active, increment it now - if self._searchDelay <= 10: - self._searchDelay += 1 - - - # collect generator input states - inputState = '?' - # if generator digital input is present, use that - if self._generatorInputStateObject != None: - inputState = self._generatorInputStateObject.GetValue () - if inputState == 10: - inputState = 'R' - elif inputState == 11: - inputState = 'S' - # otherwise use generator AC input to determine running state - else: - # use frequency as the test for generator running - if self._generatorAcInput > 0: - try: - if self._dbusmonitor.get_value (SYSTEM_SERVICE, '/Ac/Genset/Frequency') > 20: - inputState = 'R' - else: - inputState = 'S' - except: - inputState = '?' - - # update /GeneratorRunningState - if inputState != self._lastState: - self._dbusservice['/GeneratorRunningState'] = inputState - - # forward input state changes to /ManualStart - if self._linkToExternalState: - if inputState == "R" and generatorState == States.STOPPED: - self.log_info ("generator was started externally - syncing ManualStart state") - self._dbusservice['/ManualStart'] = 1 - elif inputState == "S" and self._dbusservice['/ManualStart'] == 1 \ - and generatorState in (States.RUNNING, States.WARMUP, States.COOLDOWN): - self.log_info ("generator was stopped externally - syncing ManualStart state") - self._dbusservice['/ManualStart'] = 0 - - # update /ExternalOverride - if inputState == "S" and self._linkToExternalState and generatorState == States.RUNNING: - if self._externalOverrideDelay > 5: - self._externalOverride = True - else: - self._externalOverrideDelay += 1 - else: - self._externalOverride = False - self._externalOverrideDelay = 0 - - if self._externalOverride != self._lastExternalOverride: - self._dbusservice['/ExternalOverride'] = self._externalOverride - self._lastExternalOverride = self._externalOverride - - except dbus.DBusException: - self.log_info ("dbus exception - generator digital input no longer valid") - self._generatorInputStateObject = None - self._digitalInputTypeObject = None - inputState = 0 - - self._lastState = inputState - - -# -# control the accumulaiton of run time based on generator input Running state -# if the internal state is RUNNING run time is accumulated in self._accumulatedRunTime -# run time is accumulated if the generator's running state is known to be running or -# if the generator running state can't be determined -# the accumulated time dBus parameter and daily and total time accumulators are updated -# only once everh 60 seconds to minimize processor load -# if the internal state is STOPPED, one last dBus, daily and total time updates are done -# then the current time accumulator is cleared - - def _accumulateRunTime (self): - - # grab running state from dBus once, use it many timed below - - if self._dbusservice['/State'] in (States.RUNNING, States.WARMUP, States.COOLDOWN): - internalRun = True - else: - internalRun = False - - # if internal state is running, accumulate time if generator is running - if internalRun: - accumuateTime = True - # start new accumulation if not done prevously - if self._last_accumulate_time == 0: - self._last_accumulate_time = self._currentTime - - # if link to external state is enabled, don't accumulate time if running state is stopped - # (accumulate if R or ?) - if self._linkToExternalState: - try: - if self._dbusservice['/GeneratorRunningState'] == 'S': - accumuateTime = False - - # if no Forwarder service, allow accumulation - except dbus.DBusException: - self.log_info ("dBus exception in startstop.py") - - # internal state STOPPED so don't add new time to the accumulation - # but there may be time already accumulated that needs to be added to daily and total accumulations - else: - accumuateTime = False - - # accumulate run time if we passed all the tests above - if accumuateTime: - self._accumulatedRunTime += self._currentTime - self._last_accumulate_time - self._last_accumulate_time = self._currentTime - - # dbus and settings updates trigger time-intensive processing so only do this once every 60 seconds - doUpdate = False - if internalRun: - if self._currentTime - self._last_update_mtime >= 60: - doUpdate = True - self._last_update_mtime = self._currentTime - # it is also done one last time when state is no longer RUNNING - elif self._last_update_mtime != 0: - doUpdate = True - - if doUpdate: - self._update_accumulated_time() - - # stopped - clear the current time accumulator - if internalRun == False: - self._last_update_mtime = 0 - self._accumulatedRunTime = 0 - self._last_accumulate_time = 0 - - self._dbusservice['/Runtime'] = int(self._accumulatedRunTime) diff --git a/FileSets/v3.01/startstop.py.orig b/FileSets/v3.01/startstop.py.orig deleted file mode 100644 index 39998d26..00000000 --- a/FileSets/v3.01/startstop.py.orig +++ /dev/null @@ -1,1112 +0,0 @@ -#!/usr/bin/python -u -# -*- coding: utf-8 -*- - -# Function -# dbus_generator monitors the dbus for batteries (com.victronenergy.battery.*) and -# vebus com.victronenergy.vebus.* -# Battery and vebus monitors can be configured through the gui. -# It then monitors SOC, AC loads, battery current and battery voltage,to auto start/stop the generator based -# on the configuration settings. Generator can be started manually or periodically setting a tes trun period. -# Time zones function allows to use different values for the conditions along the day depending on time - -import dbus -import datetime -import calendar -import time -import sys -import json -import os -import logging -from collections import OrderedDict -import monotonic_time -from gen_utils import SettingsPrefix, Errors, States, enum -from gen_utils import create_dbus_service -# Victron packages -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) -from ve_utils import exit_on_error -from settingsdevice import SettingsDevice - -RunningConditions = enum( - Stopped = 0, - Manual = 1, - TestRun = 2, - LossOfCommunication = 3, - Soc = 4, - Acload = 5, - BatteryCurrent = 6, - BatteryVoltage = 7, - InverterHighTemp = 8, - InverterOverload = 9, - StopOnAc1 = 10) - -Capabilities = enum( - WarmupCooldown = 1 -) - -SYSTEM_SERVICE = 'com.victronenergy.system' -BATTERY_PREFIX = '/Dc/Battery' -HISTORY_DAYS = 30 - -def safe_max(args): - try: - return max(x for x in args if x is not None) - except ValueError: - return None - -class Condition(object): - def __init__(self, parent): - self.parent = parent - self.reached = False - self.start_timer = 0 - self.stop_timer = 0 - self.valid = True - self.enabled = False - self.retries = 0 - - def __getitem__(self, key): - try: - return getattr(self, key) - except AttributeError: - raise KeyError(key) - - def __setitem__(self, key, value): - setattr(self, key, value) - - def get_value(self): - raise NotImplementedError("get_value") - - @property - def vebus_service(self): - return self.parent._vebusservice if self.parent._vebusservice else '' - - @property - def monitor(self): - return self.parent._dbusmonitor - -class SocCondition(Condition): - name = 'soc' - monitoring = 'battery' - boolean = False - timed = False - - def get_value(self): - return self.parent._get_battery().soc - -class AcLoadCondition(Condition): - name = 'acload' - monitoring = 'vebus' - boolean = False - timed = True - - def get_value(self): - loadOnAcOut = [] - totalConsumption = [] - - for phase in ['L1', 'L2', 'L3']: - # Get the values directly from the inverter, systemcalc doesn't provide raw inverted power - loadOnAcOut.append(self.monitor.get_value(self.vebus_service, ('/Ac/Out/%s/P' % phase))) - - # Calculate total consumption, '/Ac/Consumption/%s/Power' is deprecated - c_i = self.monitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnInput/%s/Power' % phase)) - c_o = self.monitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnOutput/%s/Power' % phase)) - totalConsumption.append(sum(filter(None, (c_i, c_o)))) - - # Invalidate if vebus is not available - if loadOnAcOut[0] == None: - return None - - # Total consumption - if self.parent._settings['acloadmeasurement'] == 0: - return sum(filter(None, totalConsumption)) - - # Load on inverter AC out - if self.parent._settings['acloadmeasurement'] == 1: - return sum(filter(None, loadOnAcOut)) - - # Highest phase load - if self.parent._settings['acloadmeasurement'] == 2: - return safe_max(loadOnAcOut) - -class BatteryCurrentCondition(Condition): - name = 'batterycurrent' - monitoring = 'battery' - boolean = False - timed = True - - def get_value(self): - c = self.parent._get_battery().current - if c is not None: - c *= -1 - return c - -class BatteryVoltageCondition(Condition): - name = 'batteryvoltage' - monitoring = 'battery' - boolean = False - timed = True - - def get_value(self): - return self.parent._get_battery().voltage - -class InverterTempCondition(Condition): - name = 'inverterhightemp' - monitoring = 'vebus' - boolean = True - timed = True - - def get_value(self): - v = self.monitor.get_value(self.vebus_service, - '/Alarms/HighTemperature') - - # When multi is connected to CAN-bus, alarms are published to - # /Alarms/HighTemperature... but when connected to vebus alarms are - # splitted in three phases and published to /Alarms/LX/HighTemperature... - if v is None: - inverterHighTemp = [] - for phase in ['L1', 'L2', 'L3']: - # Inverter alarms must be fetched directly from the inverter service - inverterHighTemp.append(self.monitor.get_value(self.vebus_service, ('/Alarms/%s/HighTemperature' % phase))) - return safe_max(inverterHighTemp) - return v - -class InverterOverloadCondition(Condition): - name = 'inverteroverload' - monitoring = 'vebus' - boolean = True - timed = True - - def get_value(self): - v = self.monitor.get_value(self.vebus_service, - '/Alarms/Overload') - - # When multi is connected to CAN-bus, alarms are published to - # /Alarms/Overload... but when connected to vebus alarms are - # splitted in three phases and published to /Alarms/LX/Overload... - if v is None: - inverterOverload = [] - for phase in ['L1', 'L2', 'L3']: - # Inverter alarms must be fetched directly from the inverter service - inverterOverload.append(self.monitor.get_value(self.vebus_service, ('/Alarms/%s/Overload' % phase))) - return safe_max(inverterOverload) - return v - -class StopOnAc1Condition(Condition): - name = 'stoponac1' - monitoring = 'vebus' - boolean = True - timed = False - - def get_value(self): - # AC input 1 - available = self.monitor.get_value(self.vebus_service, - '/Ac/State/AcIn1Available') - if available is None: - # Not supported in firmware, fall back to old behaviour - activein = self.monitor.get_value(self.vebus_service, - '/Ac/ActiveIn/ActiveInput') - - # Active input is connected - connected = self.monitor.get_value(self.vebus_service, - '/Ac/ActiveIn/Connected') - if None not in (activein, connected): - return activein == 0 and connected == 1 - return None - - return bool(available) - -class StopOnAc2Condition(Condition): - name = 'stoponac2' - monitoring = 'vebus' - boolean = True - timed = False - - def get_value(self): - # AC input 2 available (used when grid is on AC-in-2) - available = self.monitor.get_value(self.vebus_service, - '/Ac/State/AcIn2Available') - - return None if available is None else bool(available) - -class Battery(object): - def __init__(self, monitor, service, prefix): - self.monitor = monitor - self.service = service - self.prefix = prefix - - @property - def voltage(self): - return self.monitor.get_value(self.service, self.prefix + '/Voltage') - - @property - def current(self): - return self.monitor.get_value(self.service, self.prefix + '/Current') - - @property - def soc(self): - # Soc from the device doesn't have the '/Dc/0' prefix like the current and voltage do, but it does - # have the same prefix on systemcalc - return self.monitor.get_value(self.service, (BATTERY_PREFIX if self.prefix == BATTERY_PREFIX else '') + '/Soc') - -class StartStop(object): - _driver = None - def __init__(self, instance): - self._dbusservice = None - self._settings = None - self._dbusmonitor = None - self._remoteservice = None - self._name = None - self._enabled = False - self._instance = instance - - # One second per retry - self.RETRIES_ON_ERROR = 300 - self._testrun_soc_retries = 0 - self._last_counters_check = 0 - - self._starttime = 0 - self._stoptime = 0 # Used for cooldown - self._manualstarttimer = 0 - self._last_runtime_update = 0 - self._timer_runnning = 0 - - # Manual battery service selection is deprecated in favour - # of getting the values directly from systemcalc, we keep - # manual selected services handling for compatibility reasons. - self._vebusservice = None - self._errorstate = 0 - self._battery_service = None - self._battery_prefix = None - - self._acpower_inverter_input = { - 'timeout': 0, - 'unabletostart': False - } - - # Order is important. Conditions are evaluated in the order listed. - self._condition_stack = OrderedDict({ - SocCondition.name: SocCondition(self), - AcLoadCondition.name: AcLoadCondition(self), - BatteryCurrentCondition.name: BatteryCurrentCondition(self), - BatteryVoltageCondition.name: BatteryVoltageCondition(self), - InverterTempCondition.name: InverterTempCondition(self), - InverterOverloadCondition.name: InverterOverloadCondition(self), - StopOnAc1Condition.name: StopOnAc1Condition(self), - StopOnAc2Condition.name: StopOnAc2Condition(self) - }) - - def set_sources(self, dbusmonitor, settings, name, remoteservice): - self._settings = SettingsPrefix(settings, name) - self._dbusmonitor = dbusmonitor - self._remoteservice = remoteservice - self._name = name - - self.log_info('Start/stop instance created for %s.' % self._remoteservice) - self._remote_setup() - - def _create_service(self): - self._dbusservice = self._create_dbus_service() - - # The driver used for this start/stop service - self._dbusservice.add_path('/Type', value=self._driver) - # State: None = invalid, 0 = stopped, 1 = running, 2=Warm-up, 3=Cool-down - self._dbusservice.add_path('/State', value=None, gettextcallback=lambda p, v: States.get_description(v)) - # RunningByConditionCode: Numeric Companion to /RunningByCondition below, but - # also encompassing a Stopped state. - self._dbusservice.add_path('/RunningByConditionCode', value=None) - # Error - self._dbusservice.add_path('/Error', value=None, gettextcallback=lambda p, v: Errors.get_description(v)) - # Condition that made the generator start - self._dbusservice.add_path('/RunningByCondition', value=None) - # Runtime - self._dbusservice.add_path('/Runtime', value=None, gettextcallback=self._seconds_to_text) - # Today runtime - self._dbusservice.add_path('/TodayRuntime', value=None, gettextcallback=self._seconds_to_text) - # Test run runtime - self._dbusservice.add_path('/TestRunIntervalRuntime', value=None , gettextcallback=self._seconds_to_text) - # Next test run date, values is 0 for test run disabled - self._dbusservice.add_path('/NextTestRun', value=None, gettextcallback=lambda p, v: datetime.datetime.fromtimestamp(v).strftime('%c')) - # Next test run is needed 1, not needed 0 - self._dbusservice.add_path('/SkipTestRun', value=None) - # Manual start - self._dbusservice.add_path('/ManualStart', value=None, writeable=True) - # Manual start timer - self._dbusservice.add_path('/ManualStartTimer', value=None, writeable=True) - # Silent mode active - self._dbusservice.add_path('/QuietHours', value=None) - # Alarms - self._dbusservice.add_path('/Alarms/NoGeneratorAtAcIn', value=None) - # Autostart - self._dbusservice.add_path('/AutoStartEnabled', value=None, writeable=True, onchangecallback=self._set_autostart) - # Accumulated runtime - self._dbusservice.add_path('/AccumulatedRuntime', value=None) - # Capabilities, where we can add bits - self._dbusservice.add_path('/Capabilities', value=0) - - # We need to set the values after creating the paths to trigger the 'onValueChanged' event for the gui - # otherwise the gui will report the paths as invalid if we remove and recreate the paths without - # restarting the dbusservice. - self._dbusservice['/State'] = 0 - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped - self._dbusservice['/Error'] = 0 - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/Runtime'] = 0 - self._dbusservice['/TodayRuntime'] = 0 - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - self._dbusservice['/NextTestRun'] = None - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/ManualStart'] = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._dbusservice['/QuietHours'] = 0 - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - self._dbusservice['/AutoStartEnabled'] = self._settings['autostart'] - self._dbusservice['/AccumulatedRuntime'] = int(self._settings['accumulatedtotal']) - - @property - def capabilities(self): - return self._dbusservice['/Capabilities'] - - def _set_autostart(self, path, value): - if 0 <= value <= 1: - self._settings['autostart'] = int(value) - return True - return False - - def enable(self): - if self._enabled: - return - self.log_info('Enabling auto start/stop and taking control of remote switch') - self._create_service() - self._determineservices() - self._update_remote_switch() - # If cooldown or warmup is enabled, the Quattro may be left in a bad - # state if there is an unfortunate crash or a reboot. Set the ignore_ac - # flag to a sane value on startup. - if self._settings['cooldowntime'] > 0 or \ - self._settings['warmuptime'] > 0: - self._set_ignore_ac1(False) - self._set_ignore_ac2(False) - self._enabled = True - - def disable(self): - if not self._enabled: - return - self.log_info('Disabling auto start/stop, releasing control of remote switch') - self._remove_service() - self._enabled = False - - def remove(self): - self.disable() - self.log_info('Removed from start/stop instances') - - def _remove_service(self): - self._dbusservice.__del__() - self._dbusservice = None - - def device_added(self, dbusservicename, instance): - self._determineservices() - - def device_removed(self, dbusservicename, instance): - self._determineservices() - - def get_error(self): - return self._dbusservice['/Error'] - - def set_error(self, errorn): - self._dbusservice['/Error'] = errorn - - def clear_error(self): - self._dbusservice['/Error'] = Errors.NONE - - def dbus_value_changed(self, dbusServiceName, dbusPath, options, changes, deviceInstance): - if self._dbusservice is None: - return - - # AcIn1Available is needed to determine capabilities, but may - # only show up later. So we have to wait for it here. - if self._vebusservice is not None and \ - dbusServiceName == self._vebusservice and \ - dbusPath == '/Ac/State/AcIn1Available': - self._set_capabilities() - - if dbusServiceName != 'com.victronenergy.system': - return - if dbusPath == '/AutoSelectedBatteryMeasurement' and self._settings['batterymeasurement'] == 'default': - self._determineservices() - - if dbusPath == '/VebusService': - self._determineservices() - - def handlechangedsetting(self, setting, oldvalue, newvalue): - if self._dbusservice is None: - return - if self._name not in setting: - # Not our setting - return - - s = self._settings.removeprefix(setting) - - if s == 'batterymeasurement': - self._determineservices() - # Reset retries and valid if service changes - for condition in self._condition_stack.values(): - if condition['monitoring'] == 'battery': - condition['valid'] = True - condition['retries'] = 0 - - if s == 'autostart': - self.log_info('Autostart function %s.' % ('enabled' if newvalue == 1 else 'disabled')) - self._dbusservice['/AutoStartEnabled'] = self._settings['autostart'] - - if self._dbusservice is not None and s == 'testruninterval': - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime( - self._settings['testruninterval']) - - def _seconds_to_text(self, path, value): - m, s = divmod(value, 60) - h, m = divmod(m, 60) - return '%dh, %dm, %ds' % (h, m, s) - - def log_info(self, msg): - logging.info(self._name + ': %s' % msg) - - def tick(self): - if not self._enabled: - return - self._check_remote_status() - self._evaluate_startstop_conditions() - self._detect_generator_at_acinput() - - def _evaluate_startstop_conditions(self): - if self.get_error() != Errors.NONE: - # First evaluation after an error, log it - if self._errorstate == 0: - self._errorstate = 1 - self._dbusservice['/State'] = States.ERROR - self.log_info('Error: #%i - %s, stop controlling remote.' % - (self.get_error(), - Errors.get_description(self.get_error()))) - elif self._errorstate == 1: - # Error cleared - self._errorstate = 0 - self.log_info('Error state cleared, taking control of remote switch.') - - start = False - startbycondition = None - activecondition = self._dbusservice['/RunningByCondition'] - today = calendar.timegm(datetime.date.today().timetuple()) - self._timer_runnning = False - connection_lost = False - - self._check_quiet_hours() - - # New day, register it - if self._last_counters_check < today and self._dbusservice['/State'] == States.STOPPED: - self._last_counters_check = today - self._update_accumulated_time() - - # Update current and accumulated runtime. - # By performance reasons, accumulated runtime is only updated - # once per 60s. When the generator stops is also updated. - if self._dbusservice['/State'] in (States.RUNNING, States.WARMUP, States.COOLDOWN): - mtime = monotonic_time.monotonic_time().to_seconds_double() - if (mtime - self._starttime) - self._last_runtime_update >= 60: - self._dbusservice['/Runtime'] = int(mtime - self._starttime) - self._update_accumulated_time() - elif self._last_runtime_update == 0: - self._dbusservice['/Runtime'] = int(mtime - self._starttime) - - - if self._evaluate_manual_start(): - startbycondition = 'manual' - start = True - - # Conditions will only be evaluated if the autostart functionality is enabled - if self._settings['autostart'] == 1: - - if self._evaluate_testrun_condition(): - startbycondition = 'testrun' - start = True - - # Evaluate value conditions - for condition, data in self._condition_stack.items(): - # Don't short-circuit this, _evaluate_condition sets .reached - start = self._evaluate_condition(data) or start - startbycondition = condition if start and startbycondition is None else startbycondition - # Connection lost is set to true if the number of retries of one or more enabled conditions - # >= RETRIES_ON_ERROR - if data.enabled: - connection_lost = data.retries >= self.RETRIES_ON_ERROR - - if startbycondition not in ['manual', 'testrun']: - if self._condition_stack[StopOnAc1Condition.name].reached or \ - self._condition_stack[StopOnAc2Condition.name].reached: - start = False - if self._dbusservice['/State'] in (States.RUNNING, States.WARMUP) and activecondition not in ['manual', 'testrun']: - self.log_info('AC input available, stopping') - - # If none condition is reached check if connection is lost and start/keep running the generator - # depending on '/OnLossCommunication' setting - if not start and connection_lost: - # Start always - if self._settings['onlosscommunication'] == 1: - start = True - startbycondition = 'lossofcommunication' - # Keep running if generator already started - if self._dbusservice['/State'] in (States.RUNNING, States.WARMUP) and self._settings['onlosscommunication'] == 2: - start = True - startbycondition = 'lossofcommunication' - - if not start and self._errorstate: - self._stop_generator() - - if self._errorstate: - return - - if start: - self._start_generator(startbycondition) - elif (self._dbusservice['/Runtime'] >= self._settings['minimumruntime'] * 60 - or activecondition == 'manual'): - self._stop_generator() - - def _detect_generator_at_acinput(self): - state = self._dbusservice['/State'] - - if state == States.STOPPED: - self._reset_acpower_inverter_input() - return - - if self._settings['nogeneratoratacinalarm'] == 0: - self._reset_acpower_inverter_input() - return - - vebus_service = self._vebusservice if self._vebusservice else '' - activein_state = self._dbusmonitor.get_value( - vebus_service, '/Ac/ActiveIn/Connected') - - # Path not supported, skip evaluation - if activein_state == None: - return - - # Sources 0 = Not available, 1 = Grid, 2 = Generator, 3 = Shore - generator_acsource = self._dbusmonitor.get_value( - SYSTEM_SERVICE, '/Ac/ActiveIn/Source') == 2 - # Not connected = 0, connected = 1 - activein_connected = activein_state == 1 - - if generator_acsource and activein_connected: - if self._acpower_inverter_input['unabletostart']: - self.log_info('Generator detected at inverter AC input, alarm removed') - self._reset_acpower_inverter_input() - elif self._acpower_inverter_input['timeout'] < self.RETRIES_ON_ERROR: - self._acpower_inverter_input['timeout'] += 1 - elif not self._acpower_inverter_input['unabletostart']: - self._acpower_inverter_input['unabletostart'] = True - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 2 - self.log_info('Generator not detected at inverter AC input, triggering alarm') - - def _reset_acpower_inverter_input(self, clear_error=True): - if self._acpower_inverter_input['timeout'] != 0: - self._acpower_inverter_input['timeout'] = 0 - - if self._acpower_inverter_input['unabletostart'] != 0: - self._acpower_inverter_input['unabletostart'] = 0 - - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - - def _reset_condition(self, condition): - condition['reached'] = False - if condition['timed']: - condition['start_timer'] = 0 - condition['stop_timer'] = 0 - - def _check_condition(self, condition, value): - name = condition['name'] - - if self._settings[name + 'enabled'] == 0: - if condition['enabled']: - condition['enabled'] = False - self.log_info('Disabling (%s) condition' % name) - condition['retries'] = 0 - condition['valid'] = True - self._reset_condition(condition) - return False - - elif not condition['enabled']: - condition['enabled'] = True - self.log_info('Enabling (%s) condition' % name) - - if (condition['monitoring'] == 'battery') and (self._settings['batterymeasurement'] == 'nobattery'): - # If no battery monitor is selected reset the condition - self._reset_condition(condition) - return False - - if value is None and condition['valid']: - if condition['retries'] >= self.RETRIES_ON_ERROR: - logging.info('Error getting (%s) value, skipping evaluation till get a valid value' % name) - self._reset_condition(condition) - self._comunnication_lost = True - condition['valid'] = False - else: - condition['retries'] += 1 - if condition['retries'] == 1 or (condition['retries'] % 10) == 0: - self.log_info('Error getting (%s) value, retrying(#%i)' % (name, condition['retries'])) - return False - - elif value is not None and not condition['valid']: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['valid'] = True - condition['retries'] = 0 - - # Reset retries if value is valid - if value is not None and condition['retries'] > 0: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['retries'] = 0 - - return condition['valid'] - - def _evaluate_condition(self, condition): - name = condition['name'] - value = condition.get_value() - setting = ('qh_' if self._dbusservice['/QuietHours'] == 1 else '') + name - startvalue = self._settings[setting + 'start'] if not condition['boolean'] else 1 - stopvalue = self._settings[setting + 'stop'] if not condition['boolean'] else 0 - - # Check if the condition has to be evaluated - if not self._check_condition(condition, value): - # If generator is started by this condition and value is invalid - # wait till RETRIES_ON_ERROR to skip the condition - if condition['reached'] and condition['retries'] <= self.RETRIES_ON_ERROR: - if condition['retries'] > 0: - return True - - return False - - # As this is a generic evaluation method, we need to know how to compare the values - # first check if start value should be greater than stop value and then compare - start_is_greater = startvalue > stopvalue - - # When the condition is already reached only the stop value can set it to False - start = condition['reached'] or (value >= startvalue if start_is_greater else value <= startvalue) - stop = value <= stopvalue if start_is_greater else value >= stopvalue - - # Timed conditions must start/stop after the condition has been reached for a minimum - # time. - if condition['timed']: - if not condition['reached'] and start: - condition['start_timer'] += time.time() if condition['start_timer'] == 0 else 0 - start = time.time() - condition['start_timer'] >= self._settings[name + 'starttimer'] - condition['stop_timer'] *= int(not start) - self._timer_runnning = True - else: - condition['start_timer'] = 0 - - if condition['reached'] and stop: - condition['stop_timer'] += time.time() if condition['stop_timer'] == 0 else 0 - stop = time.time() - condition['stop_timer'] >= self._settings[name + 'stoptimer'] - condition['stop_timer'] *= int(not stop) - self._timer_runnning = True - else: - condition['stop_timer'] = 0 - - condition['reached'] = start and not stop - return condition['reached'] - - def _evaluate_manual_start(self): - if self._dbusservice['/ManualStart'] == 0: - if self._dbusservice['/RunningByCondition'] == 'manual': - self._dbusservice['/ManualStartTimer'] = 0 - return False - - start = True - # If /ManualStartTimer has a value greater than zero will use it to set a stop timer. - # If no timer is set, the generator will not stop until the user stops it manually. - # Once started by manual start, each evaluation the timer is decreased - if self._dbusservice['/ManualStartTimer'] != 0: - self._manualstarttimer += time.time() if self._manualstarttimer == 0 else 0 - self._dbusservice['/ManualStartTimer'] -= int(time.time()) - int(self._manualstarttimer) - self._manualstarttimer = time.time() - start = self._dbusservice['/ManualStartTimer'] > 0 - self._dbusservice['/ManualStart'] = int(start) - # Reset if timer is finished - self._manualstarttimer *= int(start) - self._dbusservice['/ManualStartTimer'] *= int(start) - - return start - - def _evaluate_testrun_condition(self): - if self._settings['testrunenabled'] == 0: - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/NextTestRun'] = None - return False - - today = datetime.date.today() - yesterday = today - datetime.timedelta(days=1) # Should deal well with DST - now = time.time() - runtillbatteryfull = self._settings['testruntillbatteryfull'] == 1 - soc = self._condition_stack['soc'].get_value() - batteryisfull = runtillbatteryfull and soc == 100 - duration = 60 if runtillbatteryfull else self._settings['testrunruntime'] - - try: - startdate = datetime.date.fromtimestamp(self._settings['testrunstartdate']) - _starttime = time.mktime(yesterday.timetuple()) + self._settings['testrunstarttimer'] - - # today might in fact still be yesterday, if this test run started - # before midnight and finishes after. If `now` still falls in - # yesterday's window, then by the temporal anthropic principle, - # which I just made up but loosely states that time must have - # these properties for observers to exist, it must be yesterday - # because we are here to observe it. - if _starttime <= now <= _starttime + duration: - today = yesterday - starttime = _starttime - else: - starttime = time.mktime(today.timetuple()) + self._settings['testrunstarttimer'] - except ValueError: - logging.debug('Invalid dates, skipping testrun') - return False - - # If start date is in the future set as NextTestRun and stop evaluating - if startdate > today: - self._dbusservice['/NextTestRun'] = time.mktime(startdate.timetuple()) - return False - - start = False - # If the accumulated runtime during the tes trun interval is greater than '/TestRunIntervalRuntime' - # the tes trun must be skipped - needed = (self._settings['testrunskipruntime'] > self._dbusservice['/TestRunIntervalRuntime'] - or self._settings['testrunskipruntime'] == 0) - self._dbusservice['/SkipTestRun'] = int(not needed) - - interval = self._settings['testruninterval'] - stoptime = starttime + duration - elapseddays = (today - startdate).days - mod = elapseddays % interval - - start = not bool(mod) and starttime <= now <= stoptime - - if runtillbatteryfull: - if soc is not None: - self._testrun_soc_retries = 0 - start = (start or self._dbusservice['/RunningByCondition'] == 'testrun') and not batteryisfull - elif self._dbusservice['/RunningByCondition'] == 'testrun': - if self._testrun_soc_retries < self.RETRIES_ON_ERROR: - self._testrun_soc_retries += 1 - start = True - if (self._testrun_soc_retries % 10) == 0: - self.log_info('Test run failed to get SOC value, retrying(#%i)' % self._testrun_soc_retries) - else: - self.log_info('Failed to get SOC after %i retries, terminating test run condition' % self._testrun_soc_retries) - start = False - else: - start = False - - if not bool(mod) and (now <= stoptime): - self._dbusservice['/NextTestRun'] = starttime - else: - self._dbusservice['/NextTestRun'] = (time.mktime((today + datetime.timedelta(days=interval - mod)).timetuple()) + - self._settings['testrunstarttimer']) - return start and needed - - def _check_quiet_hours(self): - active = False - if self._settings['quiethoursenabled'] == 1: - # Seconds after today 00:00 - timeinseconds = time.time() - time.mktime(datetime.date.today().timetuple()) - quiethoursstart = self._settings['quiethoursstarttime'] - quiethoursend = self._settings['quiethoursendtime'] - - # Check if the current time is between the start time and end time - if quiethoursstart < quiethoursend: - active = quiethoursstart <= timeinseconds and timeinseconds < quiethoursend - else: # End time is lower than start time, example Start: 21:00, end: 08:00 - active = not (quiethoursend < timeinseconds and timeinseconds < quiethoursstart) - - if self._dbusservice['/QuietHours'] == 0 and active: - self.log_info('Entering to quiet mode') - - elif self._dbusservice['/QuietHours'] == 1 and not active: - self.log_info('Leaving quiet mode') - - self._dbusservice['/QuietHours'] = int(active) - - return active - - def _update_accumulated_time(self): - seconds = self._dbusservice['/Runtime'] - accumulated = seconds - self._last_runtime_update - - self._settings['accumulatedtotal'] = accumulatedtotal = int(self._settings['accumulatedtotal']) + accumulated - # Using calendar to get timestamp in UTC, not local time - today_date = str(calendar.timegm(datetime.date.today().timetuple())) - - # If something goes wrong getting the json string create a new one - try: - accumulated_days = json.loads(self._settings['accumulateddaily']) - except ValueError: - accumulated_days = {today_date: 0} - - if (today_date in accumulated_days): - accumulated_days[today_date] += accumulated - else: - accumulated_days[today_date] = accumulated - - self._last_runtime_update = seconds - - # Keep the historical with a maximum of HISTORY_DAYS - while len(accumulated_days) > HISTORY_DAYS: - accumulated_days.pop(min(accumulated_days.keys()), None) - - # Upadate settings - self._settings['accumulateddaily'] = json.dumps(accumulated_days, sort_keys=True) - self._dbusservice['/TodayRuntime'] = self._interval_runtime(0) - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - self._dbusservice['/AccumulatedRuntime'] = accumulatedtotal - - def _interval_runtime(self, days): - summ = 0 - try: - daily_record = json.loads(self._settings['accumulateddaily']) - except ValueError: - return 0 - - for i in range(days + 1): - previous_day = calendar.timegm((datetime.date.today() - datetime.timedelta(days=i)).timetuple()) - if str(previous_day) in daily_record.keys(): - summ += daily_record[str(previous_day)] if str(previous_day) in daily_record.keys() else 0 - - return summ - - def _get_battery(self): - if self._settings['batterymeasurement'] == 'default': - return Battery(self._dbusmonitor, SYSTEM_SERVICE, BATTERY_PREFIX) - - return Battery(self._dbusmonitor, - self._battery_service if self._battery_service else '', - self._battery_prefix if self._battery_prefix else '') - - def _set_capabilities(self): - # Update capabilities - # The ability to ignore AC1/AC2 came in at the same time as - # AC availability and is used to detect it here. - readout_supported = self._dbusmonitor.get_value(self._vebusservice, - '/Ac/State/AcIn1Available') is not None - self._dbusservice['/Capabilities'] |= ( - Capabilities.WarmupCooldown if readout_supported else 0) - - def _determineservices(self): - # batterymeasurement is either 'default' or 'com_victronenergy_battery_288/Dc/0'. - # In case it is set to default, we use the AutoSelected battery - # measurement, given by SystemCalc. - batterymeasurement = None - newbatteryservice = None - batteryprefix = '' - selectedbattery = self._settings['batterymeasurement'] - vebusservice = None - - if selectedbattery == 'default': - batterymeasurement = 'default' - elif len(selectedbattery.split('/', 1)) == 2: # Only very basic sanity checking.. - batterymeasurement = self._settings['batterymeasurement'] - elif selectedbattery == 'nobattery': - batterymeasurement = None - else: - # Exception: unexpected value for batterymeasurement - pass - - if batterymeasurement and batterymeasurement != 'default': - batteryprefix = '/' + batterymeasurement.split('/', 1)[1] - - # Get the current battery servicename - if self._battery_service: - oldservice = self._battery_service - else: - oldservice = None - - if batterymeasurement != 'default': - battery_instance = int(batterymeasurement.split('_', 3)[3].split('/')[0]) - service_type = None - - if 'vebus' in batterymeasurement: - service_type = 'vebus' - elif 'battery' in batterymeasurement: - service_type = 'battery' - - newbatteryservice = self._get_servicename_by_instance(battery_instance, service_type) - elif batterymeasurement == 'default': - newbatteryservice = 'default' - - if newbatteryservice and newbatteryservice != oldservice: - if selectedbattery == 'default': - self.log_info('Getting battery values from systemcalc.') - if selectedbattery == 'nobattery': - self.log_info('Battery monitoring disabled! Stop evaluating related conditions') - self._battery_service = None - self._battery_prefix = None - self.log_info('Battery service we need (%s) found! Using it for generator start/stop' % batterymeasurement) - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - elif not newbatteryservice and newbatteryservice != oldservice: - self.log_info('Error getting battery service!') - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - - # Get the default VE.Bus service - vebusservice = self._dbusmonitor.get_value('com.victronenergy.system', '/VebusService') - if vebusservice: - if self._vebusservice != vebusservice: - self._vebusservice = vebusservice - self._set_capabilities() - self.log_info('Vebus service (%s) found! Using it for generator start/stop' % vebusservice) - else: - if self._vebusservice is not None: - self.log_info('Vebus service (%s) dissapeared! Stop evaluating related conditions' % self._vebusservice) - else: - self.log_info('Error getting Vebus service!') - self._vebusservice = None - - def _get_servicename_by_instance(self, instance, service_type=None): - sv = None - services = self._dbusmonitor.get_service_list() - - for service in services: - if service_type and service_type not in service: - continue - - if services[service] == instance: - sv = service - break - - return sv - - def _get_monotonic_seconds(self): - return monotonic_time.monotonic_time().to_seconds_double() - - def _start_generator(self, condition): - state = self._dbusservice['/State'] - remote_running = self._get_remote_switch_state() - - # This function will start the generator in the case generator not - # already running. When differs, the RunningByCondition is updated - running = state in (States.WARMUP, States.COOLDOWN, States.RUNNING) - if not (running and remote_running): # STOPPED, ERROR - if self._settings['warmuptime'] > 0: - # Remove load while warming up - if self._ac1_is_generator: - self._set_ignore_ac1(True) - if self._ac2_is_generator: - self._set_ignore_ac2(True) - self._dbusservice['/State'] = States.WARMUP - else: - self._dbusservice['/State'] = States.RUNNING - - self._update_remote_switch() - self._starttime = monotonic_time.monotonic_time().to_seconds_double() - self.log_info('Starting generator by %s condition' % condition) - else: # WARMUP, COOLDOWN, RUNNING - if state == States.WARMUP: - if monotonic_time.monotonic_time().to_seconds_double() - self._starttime > self._settings['warmuptime']: - self._set_ignore_ac1(False) # Release load onto Generator - self._set_ignore_ac2(False) - self._dbusservice['/State'] = States.RUNNING - elif state == States.COOLDOWN: - # Start request during cool-down run, go back to RUNNING - self._set_ignore_ac1(False) # Put load back onto Generator - self._set_ignore_ac2(False) - self._dbusservice['/State'] = States.RUNNING - - # Update the RunningByCondition - if self._dbusservice['/RunningByCondition'] != condition: - self.log_info('Generator previously running by %s condition is now running by %s condition' - % (self._dbusservice['/RunningByCondition'], condition)) - - self._dbusservice['/RunningByCondition'] = condition - self._dbusservice['/RunningByConditionCode'] = RunningConditions.lookup(condition) - - def _stop_generator(self): - state = self._dbusservice['/State'] - remote_running = self._get_remote_switch_state() - running = state in (States.WARMUP, States.COOLDOWN, States.RUNNING) - - if running or remote_running: - if self._settings['cooldowntime'] > 0: - if state == States.RUNNING: - self._dbusservice['/State'] = States.COOLDOWN - self._stoptime = monotonic_time.monotonic_time().to_seconds_double() - - # Remove load from Generator - if self._ac1_is_generator: - self._set_ignore_ac1(True) - if self._ac2_is_generator: - self._set_ignore_ac2(True) - - return - elif state == States.COOLDOWN: - if monotonic_time.monotonic_time().to_seconds_double() - \ - self._stoptime <= self._settings['cooldowntime']: - return # Don't stop engine yet - - # When we arrive here, a stop command was given during warmup, the - # cooldown timer expired, no cooldown was configured. Stop - # immediately. - self._dbusservice['/State'] = States.STOPPED - self._update_remote_switch() - self._set_ignore_ac1(False) - self._set_ignore_ac2(False) - self.log_info('Stopping generator that was running by %s condition' % - str(self._dbusservice['/RunningByCondition'])) - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped - self._update_accumulated_time() - self._starttime = 0 - self._dbusservice['/Runtime'] = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._manualstarttimer = 0 - self._last_runtime_update = 0 - - @property - def _ac1_is_generator(self): - return self._dbusmonitor.get_value('com.victronenergy.settings', - '/Settings/SystemSetup/AcInput1') == 2 - - @property - def _ac2_is_generator(self): - return self._dbusmonitor.get_value('com.victronenergy.settings', - '/Settings/SystemSetup/AcInput2') == 2 - - def _set_ignore_ac1(self, ignore): - # This is here so the Multi/Quattro can be told to disconnect AC-in, - # so that we can do warm-up and cool-down. - if self._vebusservice is not None: - self._dbusmonitor.set_value_async(self._vebusservice, '/Ac/Control/IgnoreAcIn1', dbus.Int32(ignore, variant_level=1)) - - def _set_ignore_ac2(self, ignore): - if self._vebusservice is not None: - self._dbusmonitor.set_value_async(self._vebusservice, '/Ac/Control/IgnoreAcIn2', dbus.Int32(ignore, variant_level=1)) - - def _update_remote_switch(self): - # Engine should be started in these states - v = self._dbusservice['/State'] in (States.RUNNING, States.WARMUP, States.COOLDOWN) - self._set_remote_switch_state(dbus.Int32(v, variant_level=1)) - - def _get_remote_switch_state(self): - raise Exception('This function should be overridden') - - def _set_remote_switch_state(self, value): - raise Exception('This function should be overridden') - - # Check the remote status, for example errors - def _check_remote_status(self): - raise Exception('This function should be overridden') - - def _remote_setup(self): - raise Exception('This function should be overridden') - - def _create_dbus_monitor(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_settings(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_dbus_service(self): - return create_dbus_service(self._instance) diff --git a/FileSets/v3.01/styles.css b/FileSets/v3.01/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v3.01/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v3.10/DetailAcInput.qml b/FileSets/v3.10/DetailAcInput.qml index d315e33a..c5cc199a 120000 --- a/FileSets/v3.10/DetailAcInput.qml +++ b/FileSets/v3.10/DetailAcInput.qml @@ -1 +1 @@ -../v3.40~8/DetailAcInput.qml \ No newline at end of file +../v3.34/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.10/DetailInverter.qml b/FileSets/v3.10/DetailInverter.qml index 2d924d7f..f204e4ff 120000 --- a/FileSets/v3.10/DetailInverter.qml +++ b/FileSets/v3.10/DetailInverter.qml @@ -1 +1 @@ -../v3.40~8/DetailInverter.qml \ No newline at end of file +../v3.34/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.10/DetailLoadsCombined.qml b/FileSets/v3.10/DetailLoadsCombined.qml index 58c63979..6b779a0c 120000 --- a/FileSets/v3.10/DetailLoadsCombined.qml +++ b/FileSets/v3.10/DetailLoadsCombined.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsCombined.qml \ No newline at end of file +../v3.34/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.10/DetailLoadsOnInput.qml b/FileSets/v3.10/DetailLoadsOnInput.qml index 5fb19084..27189b29 120000 --- a/FileSets/v3.10/DetailLoadsOnInput.qml +++ b/FileSets/v3.10/DetailLoadsOnInput.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsOnInput.qml \ No newline at end of file +../v3.34/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.10/DetailLoadsOnOutput.qml b/FileSets/v3.10/DetailLoadsOnOutput.qml index 9fdfdf28..656cbc0b 120000 --- a/FileSets/v3.10/DetailLoadsOnOutput.qml +++ b/FileSets/v3.10/DetailLoadsOnOutput.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsOnOutput.qml \ No newline at end of file +../v3.34/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.10/HubData.qml b/FileSets/v3.10/HubData.qml index b88f1965..486b4d89 120000 --- a/FileSets/v3.10/HubData.qml +++ b/FileSets/v3.10/HubData.qml @@ -1 +1 @@ -../v3.40~8/HubData.qml \ No newline at end of file +../v3.34/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.10/ObjectAcConnection.qml b/FileSets/v3.10/ObjectAcConnection.qml index cab7f2d4..bfe9c72c 120000 --- a/FileSets/v3.10/ObjectAcConnection.qml +++ b/FileSets/v3.10/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file +../v3.40/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.10/OverviewAcValuesEnhanced.qml b/FileSets/v3.10/OverviewAcValuesEnhanced.qml index 6d1e56b5..ba6bd7b3 120000 --- a/FileSets/v3.10/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.10/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.10/OverviewFlowComplex.qml b/FileSets/v3.10/OverviewFlowComplex.qml index 296ff4b1..ab0160fa 120000 --- a/FileSets/v3.10/OverviewFlowComplex.qml +++ b/FileSets/v3.10/OverviewFlowComplex.qml @@ -1 +1 @@ -../v3.40~8/OverviewFlowComplex.qml \ No newline at end of file +../v3.34/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.10/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.10/OverviewGeneratorRelayEnhanced.qml index 1c9b530f..83089971 120000 --- a/FileSets/v3.10/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.10/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.10/OverviewGridParallel.qml b/FileSets/v3.10/OverviewGridParallel.qml index 3d1f0720..9113c998 120000 --- a/FileSets/v3.10/OverviewGridParallel.qml +++ b/FileSets/v3.10/OverviewGridParallel.qml @@ -1 +1 @@ -../v3.40~8/OverviewGridParallel.qml \ No newline at end of file +../v3.34/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.10/OverviewHub.qml b/FileSets/v3.10/OverviewHub.qml index 83bae2bd..fa34d88b 120000 --- a/FileSets/v3.10/OverviewHub.qml +++ b/FileSets/v3.10/OverviewHub.qml @@ -1 +1 @@ -../v3.40~8/OverviewHub.qml \ No newline at end of file +../v3.34/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.10/OverviewHubEnhanced.qml b/FileSets/v3.10/OverviewHubEnhanced.qml index 905200b7..857d9f2f 120000 --- a/FileSets/v3.10/OverviewHubEnhanced.qml +++ b/FileSets/v3.10/OverviewHubEnhanced.qml @@ -1 +1 @@ -../v3.40~8/OverviewHubEnhanced.qml \ No newline at end of file +../v3.34/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.10/OverviewMobileEnhanced.qml b/FileSets/v3.10/OverviewMobileEnhanced.qml index ea719476..a316f85d 120000 --- a/FileSets/v3.10/OverviewMobileEnhanced.qml +++ b/FileSets/v3.10/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.10/OverviewTanksTempsDigInputs.qml b/FileSets/v3.10/OverviewTanksTempsDigInputs.qml index 47c4f55e..3e684a7f 120000 --- a/FileSets/v3.10/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.10/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.10/PowerGauge.qml b/FileSets/v3.10/PowerGauge.qml index cfdf038d..afbecdae 120000 --- a/FileSets/v3.10/PowerGauge.qml +++ b/FileSets/v3.10/PowerGauge.qml @@ -1 +1 @@ -../v3.40~8/PowerGauge.qml \ No newline at end of file +../v3.34/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.10/TileDigIn.qml b/FileSets/v3.10/TileDigIn.qml index 44616f30..5cd386d6 120000 --- a/FileSets/v3.10/TileDigIn.qml +++ b/FileSets/v3.10/TileDigIn.qml @@ -1 +1 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file +../v3.40/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.10/TileRelay.qml b/FileSets/v3.10/TileRelay.qml index 9f83152f..9a8e9d15 120000 --- a/FileSets/v3.10/TileRelay.qml +++ b/FileSets/v3.10/TileRelay.qml @@ -1 +1 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file +../v3.40/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.10/dbus_digitalinputs.py b/FileSets/v3.10/dbus_digitalinputs.py index e74da5b6..54c5335d 120000 --- a/FileSets/v3.10/dbus_digitalinputs.py +++ b/FileSets/v3.10/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file +../v3.40/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.11/DetailAcInput.qml b/FileSets/v3.11/DetailAcInput.qml index d315e33a..c5cc199a 120000 --- a/FileSets/v3.11/DetailAcInput.qml +++ b/FileSets/v3.11/DetailAcInput.qml @@ -1 +1 @@ -../v3.40~8/DetailAcInput.qml \ No newline at end of file +../v3.34/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.11/DetailInverter.qml b/FileSets/v3.11/DetailInverter.qml index 2d924d7f..f204e4ff 120000 --- a/FileSets/v3.11/DetailInverter.qml +++ b/FileSets/v3.11/DetailInverter.qml @@ -1 +1 @@ -../v3.40~8/DetailInverter.qml \ No newline at end of file +../v3.34/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.11/DetailLoadsCombined.qml b/FileSets/v3.11/DetailLoadsCombined.qml index 58c63979..6b779a0c 120000 --- a/FileSets/v3.11/DetailLoadsCombined.qml +++ b/FileSets/v3.11/DetailLoadsCombined.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsCombined.qml \ No newline at end of file +../v3.34/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.11/DetailLoadsOnInput.qml b/FileSets/v3.11/DetailLoadsOnInput.qml index 5fb19084..27189b29 120000 --- a/FileSets/v3.11/DetailLoadsOnInput.qml +++ b/FileSets/v3.11/DetailLoadsOnInput.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsOnInput.qml \ No newline at end of file +../v3.34/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.11/DetailLoadsOnOutput.qml b/FileSets/v3.11/DetailLoadsOnOutput.qml index 9fdfdf28..656cbc0b 120000 --- a/FileSets/v3.11/DetailLoadsOnOutput.qml +++ b/FileSets/v3.11/DetailLoadsOnOutput.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsOnOutput.qml \ No newline at end of file +../v3.34/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.11/HubData.qml b/FileSets/v3.11/HubData.qml index b88f1965..486b4d89 120000 --- a/FileSets/v3.11/HubData.qml +++ b/FileSets/v3.11/HubData.qml @@ -1 +1 @@ -../v3.40~8/HubData.qml \ No newline at end of file +../v3.34/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.11/ObjectAcConnection.qml b/FileSets/v3.11/ObjectAcConnection.qml index cab7f2d4..bfe9c72c 120000 --- a/FileSets/v3.11/ObjectAcConnection.qml +++ b/FileSets/v3.11/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file +../v3.40/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.11/OverviewAcValuesEnhanced.qml b/FileSets/v3.11/OverviewAcValuesEnhanced.qml index 6d1e56b5..ba6bd7b3 120000 --- a/FileSets/v3.11/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.11/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.11/OverviewFlowComplex.qml b/FileSets/v3.11/OverviewFlowComplex.qml index 296ff4b1..ab0160fa 120000 --- a/FileSets/v3.11/OverviewFlowComplex.qml +++ b/FileSets/v3.11/OverviewFlowComplex.qml @@ -1 +1 @@ -../v3.40~8/OverviewFlowComplex.qml \ No newline at end of file +../v3.34/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.11/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.11/OverviewGeneratorRelayEnhanced.qml index 1c9b530f..83089971 120000 --- a/FileSets/v3.11/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.11/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.11/OverviewGridParallel.qml b/FileSets/v3.11/OverviewGridParallel.qml index 3d1f0720..9113c998 120000 --- a/FileSets/v3.11/OverviewGridParallel.qml +++ b/FileSets/v3.11/OverviewGridParallel.qml @@ -1 +1 @@ -../v3.40~8/OverviewGridParallel.qml \ No newline at end of file +../v3.34/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.11/OverviewHub.qml b/FileSets/v3.11/OverviewHub.qml index 83bae2bd..fa34d88b 120000 --- a/FileSets/v3.11/OverviewHub.qml +++ b/FileSets/v3.11/OverviewHub.qml @@ -1 +1 @@ -../v3.40~8/OverviewHub.qml \ No newline at end of file +../v3.34/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.11/OverviewHubEnhanced.qml b/FileSets/v3.11/OverviewHubEnhanced.qml index 905200b7..857d9f2f 120000 --- a/FileSets/v3.11/OverviewHubEnhanced.qml +++ b/FileSets/v3.11/OverviewHubEnhanced.qml @@ -1 +1 @@ -../v3.40~8/OverviewHubEnhanced.qml \ No newline at end of file +../v3.34/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.11/OverviewMobileEnhanced.qml b/FileSets/v3.11/OverviewMobileEnhanced.qml index ea719476..a316f85d 120000 --- a/FileSets/v3.11/OverviewMobileEnhanced.qml +++ b/FileSets/v3.11/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.11/OverviewTanksTempsDigInputs.qml b/FileSets/v3.11/OverviewTanksTempsDigInputs.qml index 47c4f55e..3e684a7f 120000 --- a/FileSets/v3.11/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.11/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.11/PowerGauge.qml b/FileSets/v3.11/PowerGauge.qml index cfdf038d..afbecdae 120000 --- a/FileSets/v3.11/PowerGauge.qml +++ b/FileSets/v3.11/PowerGauge.qml @@ -1 +1 @@ -../v3.40~8/PowerGauge.qml \ No newline at end of file +../v3.34/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.11/TileDigIn.qml b/FileSets/v3.11/TileDigIn.qml index 44616f30..5cd386d6 120000 --- a/FileSets/v3.11/TileDigIn.qml +++ b/FileSets/v3.11/TileDigIn.qml @@ -1 +1 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file +../v3.40/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.11/TileRelay.qml b/FileSets/v3.11/TileRelay.qml index 9f83152f..9a8e9d15 120000 --- a/FileSets/v3.11/TileRelay.qml +++ b/FileSets/v3.11/TileRelay.qml @@ -1 +1 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file +../v3.40/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.11/dbus_digitalinputs.py b/FileSets/v3.11/dbus_digitalinputs.py index e74da5b6..54c5335d 120000 --- a/FileSets/v3.11/dbus_digitalinputs.py +++ b/FileSets/v3.11/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file +../v3.40/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.12/DetailAcInput.qml b/FileSets/v3.12/DetailAcInput.qml index d315e33a..c5cc199a 120000 --- a/FileSets/v3.12/DetailAcInput.qml +++ b/FileSets/v3.12/DetailAcInput.qml @@ -1 +1 @@ -../v3.40~8/DetailAcInput.qml \ No newline at end of file +../v3.34/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.12/DetailInverter.qml b/FileSets/v3.12/DetailInverter.qml index 2d924d7f..f204e4ff 120000 --- a/FileSets/v3.12/DetailInverter.qml +++ b/FileSets/v3.12/DetailInverter.qml @@ -1 +1 @@ -../v3.40~8/DetailInverter.qml \ No newline at end of file +../v3.34/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.12/DetailLoadsCombined.qml b/FileSets/v3.12/DetailLoadsCombined.qml index 58c63979..6b779a0c 120000 --- a/FileSets/v3.12/DetailLoadsCombined.qml +++ b/FileSets/v3.12/DetailLoadsCombined.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsCombined.qml \ No newline at end of file +../v3.34/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.12/DetailLoadsOnInput.qml b/FileSets/v3.12/DetailLoadsOnInput.qml index 5fb19084..27189b29 120000 --- a/FileSets/v3.12/DetailLoadsOnInput.qml +++ b/FileSets/v3.12/DetailLoadsOnInput.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsOnInput.qml \ No newline at end of file +../v3.34/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.12/DetailLoadsOnOutput.qml b/FileSets/v3.12/DetailLoadsOnOutput.qml index 9fdfdf28..656cbc0b 120000 --- a/FileSets/v3.12/DetailLoadsOnOutput.qml +++ b/FileSets/v3.12/DetailLoadsOnOutput.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsOnOutput.qml \ No newline at end of file +../v3.34/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.12/HubData.qml b/FileSets/v3.12/HubData.qml index b88f1965..486b4d89 120000 --- a/FileSets/v3.12/HubData.qml +++ b/FileSets/v3.12/HubData.qml @@ -1 +1 @@ -../v3.40~8/HubData.qml \ No newline at end of file +../v3.34/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.12/ObjectAcConnection.qml b/FileSets/v3.12/ObjectAcConnection.qml index cab7f2d4..bfe9c72c 120000 --- a/FileSets/v3.12/ObjectAcConnection.qml +++ b/FileSets/v3.12/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file +../v3.40/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.12/OverviewAcValuesEnhanced.qml b/FileSets/v3.12/OverviewAcValuesEnhanced.qml index 6d1e56b5..ba6bd7b3 120000 --- a/FileSets/v3.12/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.12/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.12/OverviewFlowComplex.qml b/FileSets/v3.12/OverviewFlowComplex.qml index 296ff4b1..ab0160fa 120000 --- a/FileSets/v3.12/OverviewFlowComplex.qml +++ b/FileSets/v3.12/OverviewFlowComplex.qml @@ -1 +1 @@ -../v3.40~8/OverviewFlowComplex.qml \ No newline at end of file +../v3.34/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.12/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.12/OverviewGeneratorRelayEnhanced.qml index 1c9b530f..83089971 120000 --- a/FileSets/v3.12/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.12/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.12/OverviewGridParallel.qml b/FileSets/v3.12/OverviewGridParallel.qml index 3d1f0720..9113c998 120000 --- a/FileSets/v3.12/OverviewGridParallel.qml +++ b/FileSets/v3.12/OverviewGridParallel.qml @@ -1 +1 @@ -../v3.40~8/OverviewGridParallel.qml \ No newline at end of file +../v3.34/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.12/OverviewHub.qml b/FileSets/v3.12/OverviewHub.qml index 83bae2bd..fa34d88b 120000 --- a/FileSets/v3.12/OverviewHub.qml +++ b/FileSets/v3.12/OverviewHub.qml @@ -1 +1 @@ -../v3.40~8/OverviewHub.qml \ No newline at end of file +../v3.34/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.12/OverviewHubEnhanced.qml b/FileSets/v3.12/OverviewHubEnhanced.qml index 905200b7..857d9f2f 120000 --- a/FileSets/v3.12/OverviewHubEnhanced.qml +++ b/FileSets/v3.12/OverviewHubEnhanced.qml @@ -1 +1 @@ -../v3.40~8/OverviewHubEnhanced.qml \ No newline at end of file +../v3.34/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.12/OverviewMobileEnhanced.qml b/FileSets/v3.12/OverviewMobileEnhanced.qml index ea719476..a316f85d 120000 --- a/FileSets/v3.12/OverviewMobileEnhanced.qml +++ b/FileSets/v3.12/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.12/OverviewTanksTempsDigInputs.qml b/FileSets/v3.12/OverviewTanksTempsDigInputs.qml index 47c4f55e..3e684a7f 120000 --- a/FileSets/v3.12/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.12/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.12/PowerGauge.qml b/FileSets/v3.12/PowerGauge.qml index cfdf038d..afbecdae 120000 --- a/FileSets/v3.12/PowerGauge.qml +++ b/FileSets/v3.12/PowerGauge.qml @@ -1 +1 @@ -../v3.40~8/PowerGauge.qml \ No newline at end of file +../v3.34/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.12/TileDigIn.qml b/FileSets/v3.12/TileDigIn.qml index 44616f30..5cd386d6 120000 --- a/FileSets/v3.12/TileDigIn.qml +++ b/FileSets/v3.12/TileDigIn.qml @@ -1 +1 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file +../v3.40/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.12/TileRelay.qml b/FileSets/v3.12/TileRelay.qml index 9f83152f..9a8e9d15 120000 --- a/FileSets/v3.12/TileRelay.qml +++ b/FileSets/v3.12/TileRelay.qml @@ -1 +1 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file +../v3.40/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.12/dbus_digitalinputs.py b/FileSets/v3.12/dbus_digitalinputs.py index e74da5b6..54c5335d 120000 --- a/FileSets/v3.12/dbus_digitalinputs.py +++ b/FileSets/v3.12/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file +../v3.40/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.13/DetailAcInput.qml b/FileSets/v3.13/DetailAcInput.qml index d315e33a..c5cc199a 120000 --- a/FileSets/v3.13/DetailAcInput.qml +++ b/FileSets/v3.13/DetailAcInput.qml @@ -1 +1 @@ -../v3.40~8/DetailAcInput.qml \ No newline at end of file +../v3.34/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.13/DetailInverter.qml b/FileSets/v3.13/DetailInverter.qml index 2d924d7f..f204e4ff 120000 --- a/FileSets/v3.13/DetailInverter.qml +++ b/FileSets/v3.13/DetailInverter.qml @@ -1 +1 @@ -../v3.40~8/DetailInverter.qml \ No newline at end of file +../v3.34/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.13/DetailLoadsCombined.qml b/FileSets/v3.13/DetailLoadsCombined.qml index 58c63979..6b779a0c 120000 --- a/FileSets/v3.13/DetailLoadsCombined.qml +++ b/FileSets/v3.13/DetailLoadsCombined.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsCombined.qml \ No newline at end of file +../v3.34/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.13/DetailLoadsOnInput.qml b/FileSets/v3.13/DetailLoadsOnInput.qml index 5fb19084..27189b29 120000 --- a/FileSets/v3.13/DetailLoadsOnInput.qml +++ b/FileSets/v3.13/DetailLoadsOnInput.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsOnInput.qml \ No newline at end of file +../v3.34/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.13/DetailLoadsOnOutput.qml b/FileSets/v3.13/DetailLoadsOnOutput.qml index 9fdfdf28..656cbc0b 120000 --- a/FileSets/v3.13/DetailLoadsOnOutput.qml +++ b/FileSets/v3.13/DetailLoadsOnOutput.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsOnOutput.qml \ No newline at end of file +../v3.34/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.13/HubData.qml b/FileSets/v3.13/HubData.qml index b88f1965..486b4d89 120000 --- a/FileSets/v3.13/HubData.qml +++ b/FileSets/v3.13/HubData.qml @@ -1 +1 @@ -../v3.40~8/HubData.qml \ No newline at end of file +../v3.34/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.13/ObjectAcConnection.qml b/FileSets/v3.13/ObjectAcConnection.qml index cab7f2d4..bfe9c72c 120000 --- a/FileSets/v3.13/ObjectAcConnection.qml +++ b/FileSets/v3.13/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file +../v3.40/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.13/OverviewAcValuesEnhanced.qml b/FileSets/v3.13/OverviewAcValuesEnhanced.qml index 6d1e56b5..ba6bd7b3 120000 --- a/FileSets/v3.13/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.13/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.13/OverviewFlowComplex.qml b/FileSets/v3.13/OverviewFlowComplex.qml index 296ff4b1..ab0160fa 120000 --- a/FileSets/v3.13/OverviewFlowComplex.qml +++ b/FileSets/v3.13/OverviewFlowComplex.qml @@ -1 +1 @@ -../v3.40~8/OverviewFlowComplex.qml \ No newline at end of file +../v3.34/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.13/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.13/OverviewGeneratorRelayEnhanced.qml index 1c9b530f..83089971 120000 --- a/FileSets/v3.13/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.13/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.13/OverviewGridParallel.qml b/FileSets/v3.13/OverviewGridParallel.qml index 3d1f0720..9113c998 120000 --- a/FileSets/v3.13/OverviewGridParallel.qml +++ b/FileSets/v3.13/OverviewGridParallel.qml @@ -1 +1 @@ -../v3.40~8/OverviewGridParallel.qml \ No newline at end of file +../v3.34/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.13/OverviewHub.qml b/FileSets/v3.13/OverviewHub.qml index 83bae2bd..fa34d88b 120000 --- a/FileSets/v3.13/OverviewHub.qml +++ b/FileSets/v3.13/OverviewHub.qml @@ -1 +1 @@ -../v3.40~8/OverviewHub.qml \ No newline at end of file +../v3.34/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.13/OverviewHubEnhanced.qml b/FileSets/v3.13/OverviewHubEnhanced.qml index 905200b7..857d9f2f 120000 --- a/FileSets/v3.13/OverviewHubEnhanced.qml +++ b/FileSets/v3.13/OverviewHubEnhanced.qml @@ -1 +1 @@ -../v3.40~8/OverviewHubEnhanced.qml \ No newline at end of file +../v3.34/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.13/OverviewMobileEnhanced.qml b/FileSets/v3.13/OverviewMobileEnhanced.qml index ea719476..a316f85d 120000 --- a/FileSets/v3.13/OverviewMobileEnhanced.qml +++ b/FileSets/v3.13/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.13/OverviewTanksTempsDigInputs.qml b/FileSets/v3.13/OverviewTanksTempsDigInputs.qml index 47c4f55e..3e684a7f 120000 --- a/FileSets/v3.13/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.13/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.13/PowerGauge.qml b/FileSets/v3.13/PowerGauge.qml index cfdf038d..afbecdae 120000 --- a/FileSets/v3.13/PowerGauge.qml +++ b/FileSets/v3.13/PowerGauge.qml @@ -1 +1 @@ -../v3.40~8/PowerGauge.qml \ No newline at end of file +../v3.34/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.13/TileDigIn.qml b/FileSets/v3.13/TileDigIn.qml index 44616f30..5cd386d6 120000 --- a/FileSets/v3.13/TileDigIn.qml +++ b/FileSets/v3.13/TileDigIn.qml @@ -1 +1 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file +../v3.40/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.13/TileRelay.qml b/FileSets/v3.13/TileRelay.qml index 9f83152f..9a8e9d15 120000 --- a/FileSets/v3.13/TileRelay.qml +++ b/FileSets/v3.13/TileRelay.qml @@ -1 +1 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file +../v3.40/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.13/dbus_digitalinputs.py b/FileSets/v3.13/dbus_digitalinputs.py index e74da5b6..54c5335d 120000 --- a/FileSets/v3.13/dbus_digitalinputs.py +++ b/FileSets/v3.13/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file +../v3.40/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.14/DetailAcInput.qml b/FileSets/v3.14/DetailAcInput.qml index d315e33a..c5cc199a 120000 --- a/FileSets/v3.14/DetailAcInput.qml +++ b/FileSets/v3.14/DetailAcInput.qml @@ -1 +1 @@ -../v3.40~8/DetailAcInput.qml \ No newline at end of file +../v3.34/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.14/DetailInverter.qml b/FileSets/v3.14/DetailInverter.qml index 2d924d7f..f204e4ff 120000 --- a/FileSets/v3.14/DetailInverter.qml +++ b/FileSets/v3.14/DetailInverter.qml @@ -1 +1 @@ -../v3.40~8/DetailInverter.qml \ No newline at end of file +../v3.34/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.14/DetailLoadsCombined.qml b/FileSets/v3.14/DetailLoadsCombined.qml index 58c63979..6b779a0c 120000 --- a/FileSets/v3.14/DetailLoadsCombined.qml +++ b/FileSets/v3.14/DetailLoadsCombined.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsCombined.qml \ No newline at end of file +../v3.34/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.14/DetailLoadsOnInput.qml b/FileSets/v3.14/DetailLoadsOnInput.qml index 5fb19084..27189b29 120000 --- a/FileSets/v3.14/DetailLoadsOnInput.qml +++ b/FileSets/v3.14/DetailLoadsOnInput.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsOnInput.qml \ No newline at end of file +../v3.34/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.14/DetailLoadsOnOutput.qml b/FileSets/v3.14/DetailLoadsOnOutput.qml index 9fdfdf28..656cbc0b 120000 --- a/FileSets/v3.14/DetailLoadsOnOutput.qml +++ b/FileSets/v3.14/DetailLoadsOnOutput.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsOnOutput.qml \ No newline at end of file +../v3.34/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.14/HubData.qml b/FileSets/v3.14/HubData.qml index b88f1965..486b4d89 120000 --- a/FileSets/v3.14/HubData.qml +++ b/FileSets/v3.14/HubData.qml @@ -1 +1 @@ -../v3.40~8/HubData.qml \ No newline at end of file +../v3.34/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.14/ObjectAcConnection.qml b/FileSets/v3.14/ObjectAcConnection.qml index cab7f2d4..bfe9c72c 120000 --- a/FileSets/v3.14/ObjectAcConnection.qml +++ b/FileSets/v3.14/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file +../v3.40/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.14/OverviewAcValuesEnhanced.qml b/FileSets/v3.14/OverviewAcValuesEnhanced.qml index 6d1e56b5..ba6bd7b3 120000 --- a/FileSets/v3.14/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.14/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.14/OverviewFlowComplex.qml b/FileSets/v3.14/OverviewFlowComplex.qml index 296ff4b1..ab0160fa 120000 --- a/FileSets/v3.14/OverviewFlowComplex.qml +++ b/FileSets/v3.14/OverviewFlowComplex.qml @@ -1 +1 @@ -../v3.40~8/OverviewFlowComplex.qml \ No newline at end of file +../v3.34/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.14/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.14/OverviewGeneratorRelayEnhanced.qml index 1c9b530f..83089971 120000 --- a/FileSets/v3.14/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.14/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.14/OverviewGridParallel.qml b/FileSets/v3.14/OverviewGridParallel.qml index 3d1f0720..9113c998 120000 --- a/FileSets/v3.14/OverviewGridParallel.qml +++ b/FileSets/v3.14/OverviewGridParallel.qml @@ -1 +1 @@ -../v3.40~8/OverviewGridParallel.qml \ No newline at end of file +../v3.34/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.14/OverviewHub.qml b/FileSets/v3.14/OverviewHub.qml index 83bae2bd..fa34d88b 120000 --- a/FileSets/v3.14/OverviewHub.qml +++ b/FileSets/v3.14/OverviewHub.qml @@ -1 +1 @@ -../v3.40~8/OverviewHub.qml \ No newline at end of file +../v3.34/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.14/OverviewHubEnhanced.qml b/FileSets/v3.14/OverviewHubEnhanced.qml index 905200b7..857d9f2f 120000 --- a/FileSets/v3.14/OverviewHubEnhanced.qml +++ b/FileSets/v3.14/OverviewHubEnhanced.qml @@ -1 +1 @@ -../v3.40~8/OverviewHubEnhanced.qml \ No newline at end of file +../v3.34/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.14/OverviewMobileEnhanced.qml b/FileSets/v3.14/OverviewMobileEnhanced.qml index ea719476..a316f85d 120000 --- a/FileSets/v3.14/OverviewMobileEnhanced.qml +++ b/FileSets/v3.14/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.14/OverviewTanksTempsDigInputs.qml b/FileSets/v3.14/OverviewTanksTempsDigInputs.qml index 47c4f55e..3e684a7f 120000 --- a/FileSets/v3.14/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.14/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.14/PowerGauge.qml b/FileSets/v3.14/PowerGauge.qml index cfdf038d..afbecdae 120000 --- a/FileSets/v3.14/PowerGauge.qml +++ b/FileSets/v3.14/PowerGauge.qml @@ -1 +1 @@ -../v3.40~8/PowerGauge.qml \ No newline at end of file +../v3.34/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.14/TileDigIn.qml b/FileSets/v3.14/TileDigIn.qml index 44616f30..5cd386d6 120000 --- a/FileSets/v3.14/TileDigIn.qml +++ b/FileSets/v3.14/TileDigIn.qml @@ -1 +1 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file +../v3.40/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.14/TileRelay.qml b/FileSets/v3.14/TileRelay.qml index 9f83152f..9a8e9d15 120000 --- a/FileSets/v3.14/TileRelay.qml +++ b/FileSets/v3.14/TileRelay.qml @@ -1 +1 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file +../v3.40/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.14/dbus_digitalinputs.py b/FileSets/v3.14/dbus_digitalinputs.py index e74da5b6..54c5335d 120000 --- a/FileSets/v3.14/dbus_digitalinputs.py +++ b/FileSets/v3.14/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file +../v3.40/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.20/DetailAcInput.qml b/FileSets/v3.20/DetailAcInput.qml index d315e33a..c5cc199a 120000 --- a/FileSets/v3.20/DetailAcInput.qml +++ b/FileSets/v3.20/DetailAcInput.qml @@ -1 +1 @@ -../v3.40~8/DetailAcInput.qml \ No newline at end of file +../v3.34/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.20/DetailInverter.qml b/FileSets/v3.20/DetailInverter.qml index 2d924d7f..f204e4ff 120000 --- a/FileSets/v3.20/DetailInverter.qml +++ b/FileSets/v3.20/DetailInverter.qml @@ -1 +1 @@ -../v3.40~8/DetailInverter.qml \ No newline at end of file +../v3.34/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.20/DetailLoadsCombined.qml b/FileSets/v3.20/DetailLoadsCombined.qml index 58c63979..6b779a0c 120000 --- a/FileSets/v3.20/DetailLoadsCombined.qml +++ b/FileSets/v3.20/DetailLoadsCombined.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsCombined.qml \ No newline at end of file +../v3.34/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.20/DetailLoadsOnInput.qml b/FileSets/v3.20/DetailLoadsOnInput.qml index 5fb19084..27189b29 120000 --- a/FileSets/v3.20/DetailLoadsOnInput.qml +++ b/FileSets/v3.20/DetailLoadsOnInput.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsOnInput.qml \ No newline at end of file +../v3.34/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.20/DetailLoadsOnOutput.qml b/FileSets/v3.20/DetailLoadsOnOutput.qml index 9fdfdf28..656cbc0b 120000 --- a/FileSets/v3.20/DetailLoadsOnOutput.qml +++ b/FileSets/v3.20/DetailLoadsOnOutput.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsOnOutput.qml \ No newline at end of file +../v3.34/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.20/HubData.qml b/FileSets/v3.20/HubData.qml index b88f1965..486b4d89 120000 --- a/FileSets/v3.20/HubData.qml +++ b/FileSets/v3.20/HubData.qml @@ -1 +1 @@ -../v3.40~8/HubData.qml \ No newline at end of file +../v3.34/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.20/ObjectAcConnection.qml b/FileSets/v3.20/ObjectAcConnection.qml index cab7f2d4..bfe9c72c 120000 --- a/FileSets/v3.20/ObjectAcConnection.qml +++ b/FileSets/v3.20/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file +../v3.40/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.20/OverviewAcValuesEnhanced.qml b/FileSets/v3.20/OverviewAcValuesEnhanced.qml index 6d1e56b5..ba6bd7b3 120000 --- a/FileSets/v3.20/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.20/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.20/OverviewFlowComplex.qml b/FileSets/v3.20/OverviewFlowComplex.qml index 296ff4b1..ab0160fa 120000 --- a/FileSets/v3.20/OverviewFlowComplex.qml +++ b/FileSets/v3.20/OverviewFlowComplex.qml @@ -1 +1 @@ -../v3.40~8/OverviewFlowComplex.qml \ No newline at end of file +../v3.34/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.20/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.20/OverviewGeneratorRelayEnhanced.qml index 1c9b530f..83089971 120000 --- a/FileSets/v3.20/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.20/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.20/OverviewGridParallel.qml b/FileSets/v3.20/OverviewGridParallel.qml index 3d1f0720..9113c998 120000 --- a/FileSets/v3.20/OverviewGridParallel.qml +++ b/FileSets/v3.20/OverviewGridParallel.qml @@ -1 +1 @@ -../v3.40~8/OverviewGridParallel.qml \ No newline at end of file +../v3.34/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.20/OverviewHub.qml b/FileSets/v3.20/OverviewHub.qml index 83bae2bd..fa34d88b 120000 --- a/FileSets/v3.20/OverviewHub.qml +++ b/FileSets/v3.20/OverviewHub.qml @@ -1 +1 @@ -../v3.40~8/OverviewHub.qml \ No newline at end of file +../v3.34/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.20/OverviewHubEnhanced.qml b/FileSets/v3.20/OverviewHubEnhanced.qml index 905200b7..857d9f2f 120000 --- a/FileSets/v3.20/OverviewHubEnhanced.qml +++ b/FileSets/v3.20/OverviewHubEnhanced.qml @@ -1 +1 @@ -../v3.40~8/OverviewHubEnhanced.qml \ No newline at end of file +../v3.34/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.20/OverviewMobileEnhanced.qml b/FileSets/v3.20/OverviewMobileEnhanced.qml index ea719476..a316f85d 120000 --- a/FileSets/v3.20/OverviewMobileEnhanced.qml +++ b/FileSets/v3.20/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.20/OverviewTanksTempsDigInputs.qml b/FileSets/v3.20/OverviewTanksTempsDigInputs.qml index 47c4f55e..3e684a7f 120000 --- a/FileSets/v3.20/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.20/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.20/PageSettingsGenerator.qml b/FileSets/v3.20/PageSettingsGenerator.qml index 15dd8f85..2cb42f6b 120000 --- a/FileSets/v3.20/PageSettingsGenerator.qml +++ b/FileSets/v3.20/PageSettingsGenerator.qml @@ -1 +1 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file +../v3.40/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.20/PowerGauge.qml b/FileSets/v3.20/PowerGauge.qml index cfdf038d..afbecdae 120000 --- a/FileSets/v3.20/PowerGauge.qml +++ b/FileSets/v3.20/PowerGauge.qml @@ -1 +1 @@ -../v3.40~8/PowerGauge.qml \ No newline at end of file +../v3.34/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.20/TileDigIn.qml b/FileSets/v3.20/TileDigIn.qml index 44616f30..5cd386d6 120000 --- a/FileSets/v3.20/TileDigIn.qml +++ b/FileSets/v3.20/TileDigIn.qml @@ -1 +1 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file +../v3.40/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.20/TileRelay.qml b/FileSets/v3.20/TileRelay.qml index 9f83152f..9a8e9d15 120000 --- a/FileSets/v3.20/TileRelay.qml +++ b/FileSets/v3.20/TileRelay.qml @@ -1 +1 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file +../v3.40/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.20/dbus_digitalinputs.py b/FileSets/v3.20/dbus_digitalinputs.py index e74da5b6..54c5335d 120000 --- a/FileSets/v3.20/dbus_digitalinputs.py +++ b/FileSets/v3.20/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file +../v3.40/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.20/dbus_generator.py b/FileSets/v3.20/dbus_generator.py index 0cd84ca3..fc553c91 120000 --- a/FileSets/v3.20/dbus_generator.py +++ b/FileSets/v3.20/dbus_generator.py @@ -1 +1 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file +../v3.40/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.21/DetailAcInput.qml b/FileSets/v3.21/DetailAcInput.qml index d315e33a..c5cc199a 120000 --- a/FileSets/v3.21/DetailAcInput.qml +++ b/FileSets/v3.21/DetailAcInput.qml @@ -1 +1 @@ -../v3.40~8/DetailAcInput.qml \ No newline at end of file +../v3.34/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.21/DetailInverter.qml b/FileSets/v3.21/DetailInverter.qml index 2d924d7f..f204e4ff 120000 --- a/FileSets/v3.21/DetailInverter.qml +++ b/FileSets/v3.21/DetailInverter.qml @@ -1 +1 @@ -../v3.40~8/DetailInverter.qml \ No newline at end of file +../v3.34/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.21/DetailLoadsCombined.qml b/FileSets/v3.21/DetailLoadsCombined.qml index 58c63979..6b779a0c 120000 --- a/FileSets/v3.21/DetailLoadsCombined.qml +++ b/FileSets/v3.21/DetailLoadsCombined.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsCombined.qml \ No newline at end of file +../v3.34/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.21/DetailLoadsOnInput.qml b/FileSets/v3.21/DetailLoadsOnInput.qml index 5fb19084..27189b29 120000 --- a/FileSets/v3.21/DetailLoadsOnInput.qml +++ b/FileSets/v3.21/DetailLoadsOnInput.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsOnInput.qml \ No newline at end of file +../v3.34/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.21/DetailLoadsOnOutput.qml b/FileSets/v3.21/DetailLoadsOnOutput.qml index 9fdfdf28..656cbc0b 120000 --- a/FileSets/v3.21/DetailLoadsOnOutput.qml +++ b/FileSets/v3.21/DetailLoadsOnOutput.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsOnOutput.qml \ No newline at end of file +../v3.34/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.21/HubData.qml b/FileSets/v3.21/HubData.qml index b88f1965..486b4d89 120000 --- a/FileSets/v3.21/HubData.qml +++ b/FileSets/v3.21/HubData.qml @@ -1 +1 @@ -../v3.40~8/HubData.qml \ No newline at end of file +../v3.34/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.21/ObjectAcConnection.qml b/FileSets/v3.21/ObjectAcConnection.qml index cab7f2d4..bfe9c72c 120000 --- a/FileSets/v3.21/ObjectAcConnection.qml +++ b/FileSets/v3.21/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file +../v3.40/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.21/OverviewAcValuesEnhanced.qml b/FileSets/v3.21/OverviewAcValuesEnhanced.qml index 6d1e56b5..ba6bd7b3 120000 --- a/FileSets/v3.21/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.21/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.21/OverviewFlowComplex.qml b/FileSets/v3.21/OverviewFlowComplex.qml index 296ff4b1..ab0160fa 120000 --- a/FileSets/v3.21/OverviewFlowComplex.qml +++ b/FileSets/v3.21/OverviewFlowComplex.qml @@ -1 +1 @@ -../v3.40~8/OverviewFlowComplex.qml \ No newline at end of file +../v3.34/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.21/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.21/OverviewGeneratorRelayEnhanced.qml index 1c9b530f..83089971 120000 --- a/FileSets/v3.21/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.21/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.21/OverviewGridParallel.qml b/FileSets/v3.21/OverviewGridParallel.qml index 3d1f0720..9113c998 120000 --- a/FileSets/v3.21/OverviewGridParallel.qml +++ b/FileSets/v3.21/OverviewGridParallel.qml @@ -1 +1 @@ -../v3.40~8/OverviewGridParallel.qml \ No newline at end of file +../v3.34/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.21/OverviewHub.qml b/FileSets/v3.21/OverviewHub.qml index 83bae2bd..fa34d88b 120000 --- a/FileSets/v3.21/OverviewHub.qml +++ b/FileSets/v3.21/OverviewHub.qml @@ -1 +1 @@ -../v3.40~8/OverviewHub.qml \ No newline at end of file +../v3.34/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.21/OverviewHubEnhanced.qml b/FileSets/v3.21/OverviewHubEnhanced.qml index 905200b7..857d9f2f 120000 --- a/FileSets/v3.21/OverviewHubEnhanced.qml +++ b/FileSets/v3.21/OverviewHubEnhanced.qml @@ -1 +1 @@ -../v3.40~8/OverviewHubEnhanced.qml \ No newline at end of file +../v3.34/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.21/OverviewMobileEnhanced.qml b/FileSets/v3.21/OverviewMobileEnhanced.qml index ea719476..a316f85d 120000 --- a/FileSets/v3.21/OverviewMobileEnhanced.qml +++ b/FileSets/v3.21/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.21/OverviewTanksTempsDigInputs.qml b/FileSets/v3.21/OverviewTanksTempsDigInputs.qml index 47c4f55e..3e684a7f 120000 --- a/FileSets/v3.21/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.21/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.21/PageSettingsGenerator.qml b/FileSets/v3.21/PageSettingsGenerator.qml index 15dd8f85..2cb42f6b 120000 --- a/FileSets/v3.21/PageSettingsGenerator.qml +++ b/FileSets/v3.21/PageSettingsGenerator.qml @@ -1 +1 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file +../v3.40/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.21/PowerGauge.qml b/FileSets/v3.21/PowerGauge.qml index cfdf038d..afbecdae 120000 --- a/FileSets/v3.21/PowerGauge.qml +++ b/FileSets/v3.21/PowerGauge.qml @@ -1 +1 @@ -../v3.40~8/PowerGauge.qml \ No newline at end of file +../v3.34/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.21/TileDigIn.qml b/FileSets/v3.21/TileDigIn.qml index 44616f30..5cd386d6 120000 --- a/FileSets/v3.21/TileDigIn.qml +++ b/FileSets/v3.21/TileDigIn.qml @@ -1 +1 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file +../v3.40/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.21/TileRelay.qml b/FileSets/v3.21/TileRelay.qml index 9f83152f..9a8e9d15 120000 --- a/FileSets/v3.21/TileRelay.qml +++ b/FileSets/v3.21/TileRelay.qml @@ -1 +1 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file +../v3.40/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.21/dbus_digitalinputs.py b/FileSets/v3.21/dbus_digitalinputs.py index e74da5b6..54c5335d 120000 --- a/FileSets/v3.21/dbus_digitalinputs.py +++ b/FileSets/v3.21/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file +../v3.40/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.21/dbus_generator.py b/FileSets/v3.21/dbus_generator.py index 0cd84ca3..fc553c91 120000 --- a/FileSets/v3.21/dbus_generator.py +++ b/FileSets/v3.21/dbus_generator.py @@ -1 +1 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file +../v3.40/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.22/DetailAcInput.qml b/FileSets/v3.22/DetailAcInput.qml index d315e33a..c5cc199a 120000 --- a/FileSets/v3.22/DetailAcInput.qml +++ b/FileSets/v3.22/DetailAcInput.qml @@ -1 +1 @@ -../v3.40~8/DetailAcInput.qml \ No newline at end of file +../v3.34/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.22/DetailInverter.qml b/FileSets/v3.22/DetailInverter.qml index 2d924d7f..f204e4ff 120000 --- a/FileSets/v3.22/DetailInverter.qml +++ b/FileSets/v3.22/DetailInverter.qml @@ -1 +1 @@ -../v3.40~8/DetailInverter.qml \ No newline at end of file +../v3.34/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.22/DetailLoadsCombined.qml b/FileSets/v3.22/DetailLoadsCombined.qml index 58c63979..6b779a0c 120000 --- a/FileSets/v3.22/DetailLoadsCombined.qml +++ b/FileSets/v3.22/DetailLoadsCombined.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsCombined.qml \ No newline at end of file +../v3.34/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.22/DetailLoadsOnInput.qml b/FileSets/v3.22/DetailLoadsOnInput.qml index 5fb19084..27189b29 120000 --- a/FileSets/v3.22/DetailLoadsOnInput.qml +++ b/FileSets/v3.22/DetailLoadsOnInput.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsOnInput.qml \ No newline at end of file +../v3.34/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.22/DetailLoadsOnOutput.qml b/FileSets/v3.22/DetailLoadsOnOutput.qml index 9fdfdf28..656cbc0b 120000 --- a/FileSets/v3.22/DetailLoadsOnOutput.qml +++ b/FileSets/v3.22/DetailLoadsOnOutput.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsOnOutput.qml \ No newline at end of file +../v3.34/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.22/HubData.qml b/FileSets/v3.22/HubData.qml index b88f1965..486b4d89 120000 --- a/FileSets/v3.22/HubData.qml +++ b/FileSets/v3.22/HubData.qml @@ -1 +1 @@ -../v3.40~8/HubData.qml \ No newline at end of file +../v3.34/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.22/ObjectAcConnection.qml b/FileSets/v3.22/ObjectAcConnection.qml index cab7f2d4..bfe9c72c 120000 --- a/FileSets/v3.22/ObjectAcConnection.qml +++ b/FileSets/v3.22/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file +../v3.40/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.22/OverviewAcValuesEnhanced.qml b/FileSets/v3.22/OverviewAcValuesEnhanced.qml index 6d1e56b5..ba6bd7b3 120000 --- a/FileSets/v3.22/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.22/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.22/OverviewFlowComplex.qml b/FileSets/v3.22/OverviewFlowComplex.qml index 296ff4b1..ab0160fa 120000 --- a/FileSets/v3.22/OverviewFlowComplex.qml +++ b/FileSets/v3.22/OverviewFlowComplex.qml @@ -1 +1 @@ -../v3.40~8/OverviewFlowComplex.qml \ No newline at end of file +../v3.34/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.22/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.22/OverviewGeneratorRelayEnhanced.qml index 1c9b530f..83089971 120000 --- a/FileSets/v3.22/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.22/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.22/OverviewGridParallel.qml b/FileSets/v3.22/OverviewGridParallel.qml index 3d1f0720..9113c998 120000 --- a/FileSets/v3.22/OverviewGridParallel.qml +++ b/FileSets/v3.22/OverviewGridParallel.qml @@ -1 +1 @@ -../v3.40~8/OverviewGridParallel.qml \ No newline at end of file +../v3.34/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.22/OverviewHub.qml b/FileSets/v3.22/OverviewHub.qml index 83bae2bd..fa34d88b 120000 --- a/FileSets/v3.22/OverviewHub.qml +++ b/FileSets/v3.22/OverviewHub.qml @@ -1 +1 @@ -../v3.40~8/OverviewHub.qml \ No newline at end of file +../v3.34/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.22/OverviewHubEnhanced.qml b/FileSets/v3.22/OverviewHubEnhanced.qml index 905200b7..857d9f2f 120000 --- a/FileSets/v3.22/OverviewHubEnhanced.qml +++ b/FileSets/v3.22/OverviewHubEnhanced.qml @@ -1 +1 @@ -../v3.40~8/OverviewHubEnhanced.qml \ No newline at end of file +../v3.34/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.22/OverviewMobileEnhanced.qml b/FileSets/v3.22/OverviewMobileEnhanced.qml index ea719476..a316f85d 120000 --- a/FileSets/v3.22/OverviewMobileEnhanced.qml +++ b/FileSets/v3.22/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.22/OverviewTanksTempsDigInputs.qml b/FileSets/v3.22/OverviewTanksTempsDigInputs.qml index 47c4f55e..3e684a7f 120000 --- a/FileSets/v3.22/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.22/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.22/PageSettingsGenerator.qml b/FileSets/v3.22/PageSettingsGenerator.qml index 15dd8f85..2cb42f6b 120000 --- a/FileSets/v3.22/PageSettingsGenerator.qml +++ b/FileSets/v3.22/PageSettingsGenerator.qml @@ -1 +1 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file +../v3.40/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.22/PowerGauge.qml b/FileSets/v3.22/PowerGauge.qml index cfdf038d..afbecdae 120000 --- a/FileSets/v3.22/PowerGauge.qml +++ b/FileSets/v3.22/PowerGauge.qml @@ -1 +1 @@ -../v3.40~8/PowerGauge.qml \ No newline at end of file +../v3.34/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.22/TileDigIn.qml b/FileSets/v3.22/TileDigIn.qml index 44616f30..5cd386d6 120000 --- a/FileSets/v3.22/TileDigIn.qml +++ b/FileSets/v3.22/TileDigIn.qml @@ -1 +1 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file +../v3.40/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.22/TileRelay.qml b/FileSets/v3.22/TileRelay.qml index 9f83152f..9a8e9d15 120000 --- a/FileSets/v3.22/TileRelay.qml +++ b/FileSets/v3.22/TileRelay.qml @@ -1 +1 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file +../v3.40/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.22/dbus_digitalinputs.py b/FileSets/v3.22/dbus_digitalinputs.py index e74da5b6..54c5335d 120000 --- a/FileSets/v3.22/dbus_digitalinputs.py +++ b/FileSets/v3.22/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file +../v3.40/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.22/dbus_generator.py b/FileSets/v3.22/dbus_generator.py index 0cd84ca3..fc553c91 120000 --- a/FileSets/v3.22/dbus_generator.py +++ b/FileSets/v3.22/dbus_generator.py @@ -1 +1 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file +../v3.40/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.30/DetailAcInput.qml b/FileSets/v3.30/DetailAcInput.qml index d315e33a..c5cc199a 120000 --- a/FileSets/v3.30/DetailAcInput.qml +++ b/FileSets/v3.30/DetailAcInput.qml @@ -1 +1 @@ -../v3.40~8/DetailAcInput.qml \ No newline at end of file +../v3.34/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.30/DetailInverter.qml b/FileSets/v3.30/DetailInverter.qml index 2d924d7f..f204e4ff 120000 --- a/FileSets/v3.30/DetailInverter.qml +++ b/FileSets/v3.30/DetailInverter.qml @@ -1 +1 @@ -../v3.40~8/DetailInverter.qml \ No newline at end of file +../v3.34/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.30/DetailLoadsCombined.qml b/FileSets/v3.30/DetailLoadsCombined.qml index 58c63979..6b779a0c 120000 --- a/FileSets/v3.30/DetailLoadsCombined.qml +++ b/FileSets/v3.30/DetailLoadsCombined.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsCombined.qml \ No newline at end of file +../v3.34/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.30/DetailLoadsOnInput.qml b/FileSets/v3.30/DetailLoadsOnInput.qml index 5fb19084..27189b29 120000 --- a/FileSets/v3.30/DetailLoadsOnInput.qml +++ b/FileSets/v3.30/DetailLoadsOnInput.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsOnInput.qml \ No newline at end of file +../v3.34/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.30/DetailLoadsOnOutput.qml b/FileSets/v3.30/DetailLoadsOnOutput.qml index 9fdfdf28..656cbc0b 120000 --- a/FileSets/v3.30/DetailLoadsOnOutput.qml +++ b/FileSets/v3.30/DetailLoadsOnOutput.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsOnOutput.qml \ No newline at end of file +../v3.34/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.30/HubData.qml b/FileSets/v3.30/HubData.qml index b88f1965..486b4d89 120000 --- a/FileSets/v3.30/HubData.qml +++ b/FileSets/v3.30/HubData.qml @@ -1 +1 @@ -../v3.40~8/HubData.qml \ No newline at end of file +../v3.34/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.30/ObjectAcConnection.qml b/FileSets/v3.30/ObjectAcConnection.qml index cab7f2d4..bfe9c72c 120000 --- a/FileSets/v3.30/ObjectAcConnection.qml +++ b/FileSets/v3.30/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file +../v3.40/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.30/OverviewAcValuesEnhanced.qml b/FileSets/v3.30/OverviewAcValuesEnhanced.qml index 6d1e56b5..ba6bd7b3 120000 --- a/FileSets/v3.30/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.30/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.30/OverviewFlowComplex.qml b/FileSets/v3.30/OverviewFlowComplex.qml index 296ff4b1..ab0160fa 120000 --- a/FileSets/v3.30/OverviewFlowComplex.qml +++ b/FileSets/v3.30/OverviewFlowComplex.qml @@ -1 +1 @@ -../v3.40~8/OverviewFlowComplex.qml \ No newline at end of file +../v3.34/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.30/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.30/OverviewGeneratorRelayEnhanced.qml index 1c9b530f..83089971 120000 --- a/FileSets/v3.30/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.30/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.30/OverviewGridParallel.qml b/FileSets/v3.30/OverviewGridParallel.qml index 3d1f0720..9113c998 120000 --- a/FileSets/v3.30/OverviewGridParallel.qml +++ b/FileSets/v3.30/OverviewGridParallel.qml @@ -1 +1 @@ -../v3.40~8/OverviewGridParallel.qml \ No newline at end of file +../v3.34/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.30/OverviewHub.qml b/FileSets/v3.30/OverviewHub.qml index 83bae2bd..fa34d88b 120000 --- a/FileSets/v3.30/OverviewHub.qml +++ b/FileSets/v3.30/OverviewHub.qml @@ -1 +1 @@ -../v3.40~8/OverviewHub.qml \ No newline at end of file +../v3.34/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.30/OverviewHubEnhanced.qml b/FileSets/v3.30/OverviewHubEnhanced.qml index 905200b7..857d9f2f 120000 --- a/FileSets/v3.30/OverviewHubEnhanced.qml +++ b/FileSets/v3.30/OverviewHubEnhanced.qml @@ -1 +1 @@ -../v3.40~8/OverviewHubEnhanced.qml \ No newline at end of file +../v3.34/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.30/OverviewMobileEnhanced.qml b/FileSets/v3.30/OverviewMobileEnhanced.qml index ea719476..a316f85d 120000 --- a/FileSets/v3.30/OverviewMobileEnhanced.qml +++ b/FileSets/v3.30/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.30/OverviewTanksTempsDigInputs.qml b/FileSets/v3.30/OverviewTanksTempsDigInputs.qml index 47c4f55e..3e684a7f 120000 --- a/FileSets/v3.30/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.30/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.30/PageSettingsGenerator.qml b/FileSets/v3.30/PageSettingsGenerator.qml index 15dd8f85..2cb42f6b 120000 --- a/FileSets/v3.30/PageSettingsGenerator.qml +++ b/FileSets/v3.30/PageSettingsGenerator.qml @@ -1 +1 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file +../v3.40/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.30/PageSettingsGuiMods.qml b/FileSets/v3.30/PageSettingsGuiMods.qml index e831a7a4..191ce2c0 120000 --- a/FileSets/v3.30/PageSettingsGuiMods.qml +++ b/FileSets/v3.30/PageSettingsGuiMods.qml @@ -1 +1 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file +../v3.40/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.30/PageSettingsRelay.qml b/FileSets/v3.30/PageSettingsRelay.qml index 156aadac..f3f8e29c 120000 --- a/FileSets/v3.30/PageSettingsRelay.qml +++ b/FileSets/v3.30/PageSettingsRelay.qml @@ -1 +1 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file +../v3.40/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.30/PowerGauge.qml b/FileSets/v3.30/PowerGauge.qml index cfdf038d..afbecdae 120000 --- a/FileSets/v3.30/PowerGauge.qml +++ b/FileSets/v3.30/PowerGauge.qml @@ -1 +1 @@ -../v3.40~8/PowerGauge.qml \ No newline at end of file +../v3.34/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.30/TileDigIn.qml b/FileSets/v3.30/TileDigIn.qml index 44616f30..5cd386d6 120000 --- a/FileSets/v3.30/TileDigIn.qml +++ b/FileSets/v3.30/TileDigIn.qml @@ -1 +1 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file +../v3.40/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.30/TileRelay.qml b/FileSets/v3.30/TileRelay.qml index 9f83152f..9a8e9d15 120000 --- a/FileSets/v3.30/TileRelay.qml +++ b/FileSets/v3.30/TileRelay.qml @@ -1 +1 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file +../v3.40/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.30/dbus_digitalinputs.py b/FileSets/v3.30/dbus_digitalinputs.py index e74da5b6..54c5335d 120000 --- a/FileSets/v3.30/dbus_digitalinputs.py +++ b/FileSets/v3.30/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file +../v3.40/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.30/dbus_generator.py b/FileSets/v3.30/dbus_generator.py index 0cd84ca3..fc553c91 120000 --- a/FileSets/v3.30/dbus_generator.py +++ b/FileSets/v3.30/dbus_generator.py @@ -1 +1 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file +../v3.40/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.31/DetailAcInput.qml b/FileSets/v3.31/DetailAcInput.qml index d315e33a..c5cc199a 120000 --- a/FileSets/v3.31/DetailAcInput.qml +++ b/FileSets/v3.31/DetailAcInput.qml @@ -1 +1 @@ -../v3.40~8/DetailAcInput.qml \ No newline at end of file +../v3.34/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.31/DetailInverter.qml b/FileSets/v3.31/DetailInverter.qml index 2d924d7f..f204e4ff 120000 --- a/FileSets/v3.31/DetailInverter.qml +++ b/FileSets/v3.31/DetailInverter.qml @@ -1 +1 @@ -../v3.40~8/DetailInverter.qml \ No newline at end of file +../v3.34/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.31/DetailLoadsCombined.qml b/FileSets/v3.31/DetailLoadsCombined.qml index 58c63979..6b779a0c 120000 --- a/FileSets/v3.31/DetailLoadsCombined.qml +++ b/FileSets/v3.31/DetailLoadsCombined.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsCombined.qml \ No newline at end of file +../v3.34/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.31/DetailLoadsOnInput.qml b/FileSets/v3.31/DetailLoadsOnInput.qml index 5fb19084..27189b29 120000 --- a/FileSets/v3.31/DetailLoadsOnInput.qml +++ b/FileSets/v3.31/DetailLoadsOnInput.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsOnInput.qml \ No newline at end of file +../v3.34/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.31/DetailLoadsOnOutput.qml b/FileSets/v3.31/DetailLoadsOnOutput.qml index 9fdfdf28..656cbc0b 120000 --- a/FileSets/v3.31/DetailLoadsOnOutput.qml +++ b/FileSets/v3.31/DetailLoadsOnOutput.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsOnOutput.qml \ No newline at end of file +../v3.34/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.31/HubData.qml b/FileSets/v3.31/HubData.qml index b88f1965..486b4d89 120000 --- a/FileSets/v3.31/HubData.qml +++ b/FileSets/v3.31/HubData.qml @@ -1 +1 @@ -../v3.40~8/HubData.qml \ No newline at end of file +../v3.34/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.31/ObjectAcConnection.qml b/FileSets/v3.31/ObjectAcConnection.qml index cab7f2d4..bfe9c72c 120000 --- a/FileSets/v3.31/ObjectAcConnection.qml +++ b/FileSets/v3.31/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file +../v3.40/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.31/OverviewAcValuesEnhanced.qml b/FileSets/v3.31/OverviewAcValuesEnhanced.qml index 6d1e56b5..ba6bd7b3 120000 --- a/FileSets/v3.31/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.31/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.31/OverviewFlowComplex.qml b/FileSets/v3.31/OverviewFlowComplex.qml index 296ff4b1..ab0160fa 120000 --- a/FileSets/v3.31/OverviewFlowComplex.qml +++ b/FileSets/v3.31/OverviewFlowComplex.qml @@ -1 +1 @@ -../v3.40~8/OverviewFlowComplex.qml \ No newline at end of file +../v3.34/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.31/OverviewGeneratorEnhanced.qml b/FileSets/v3.31/OverviewGeneratorEnhanced.qml deleted file mode 120000 index da5507a7..00000000 --- a/FileSets/v3.31/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.31/OverviewGeneratorEnhanced.qml b/FileSets/v3.31/OverviewGeneratorEnhanced.qml new file mode 100644 index 00000000..0c189315 --- /dev/null +++ b/FileSets/v3.31/OverviewGeneratorEnhanced.qml @@ -0,0 +1,547 @@ +// GuiMods enhanced generator overview +// This file has been modified to: +// add Auto Start display and control +// show voltage, current, frequency, and power gauge in AC input tile +// show the generator running state inside the icon top left +// show a warning when the generator digital input and expected generator state disagree +// move current run time to separate tile + +import QtQuick 1.1 +import "utils.js" as Utils +import "enhancedFormat.js" as EnhFmt + +OverviewPage { + id: root + + property string settingsBindPrefix + property string bindPrefix + property variant sys: theSystem +//////// added to show alternator in place of inactive genset + property string guiModsPrefix: "com.victronenergy.settings/Settings/GuiMods" + VBusItem { id: replaceAcInItem; bind: Utils.path(guiModsPrefix, "/ReplaceInactiveAcIn") } + property bool hasAlternator: sys.alternator.power.valid + property bool showAlternator: replaceAcInItem.valid && replaceAcInItem.value == 1 && hasAlternator && ! sys.genset.power.valid + property bool showAcIn: ! showAlternator + + property string icon: "overview-generator" + property VBusItem state: VBusItem { bind: Utils.path(bindPrefix, "/State") } + property VBusItem error: VBusItem { bind: Utils.path(bindPrefix, "/Error") } + property VBusItem runningTime: VBusItem { bind: Utils.path(bindPrefix, "/Runtime") } + property VBusItem runningBy: VBusItem { bind: Utils.path(bindPrefix, "/RunningByConditionCode") } + VBusItem { id: totalAcummulatedTime; bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") } + VBusItem { id: totalAccumulatedTimeOffset; bind: Utils.path(settingsBindPrefix, "/AccumulatedTotalOffset") } + property VBusItem quietHours: VBusItem { bind: Utils.path(bindPrefix, "/QuietHours") } + property VBusItem testRunDuration: VBusItem { bind: Utils.path(settingsBindPrefix, "/TestRun/Duration") } + property VBusItem nextTestRun: VBusItem { bind: Utils.path(bindPrefix, "/NextTestRun") } + property VBusItem skipTestRun: VBusItem { bind: Utils.path(bindPrefix, "/SkipTestRun") } + + property VBusItem todayRuntime: VBusItem { bind: Utils.path(bindPrefix, "/TodayRuntime") } + property VBusItem manualTimer: VBusItem { bind: Utils.path(bindPrefix, "/ManualStartTimer") } + property VBusItem autoStart: VBusItem { bind: Utils.path(settingsBindPrefix, "/AutoStartEnabled") } + + property bool errors: ! state.valid || state.value == 10 + + property VBusItem externalOverrideItem: VBusItem { bind: Utils.path(bindPrefix, "/ExternalOverride") } + property bool externalOverride: externalOverrideItem.valid && externalOverrideItem.value == 1 && ! errors + property VBusItem runningState: VBusItem { bind: Utils.path(bindPrefix, "/GeneratorRunningState") } + + VBusItem { id: showGaugesItem; bind: Utils.path(guiModsPrefix, "/ShowGauges") } + property bool showGauges: showGaugesItem.valid ? showGaugesItem.value === 1 ? true : false : false + property bool editMode: autoRunTile.editMode || manualTile.editMode + + VBusItem { id: serviceInterval; bind: Utils.path(settingsBindPrefix, "/ServiceInterval") } + VBusItem { id: serviceCounterItem; bind: Utils.path(bindPrefix, "/ServiceCounter") } + property bool showServiceInfo: serviceCounterItem.valid && serviceInterval.valid && serviceInterval.value > 0 + property bool serviceOverdue: showServiceInfo && serviceCounterItem.value < 0 + +//////// add to display AC input ignored + VBusItem { id: ignoreAcInput1; bind: Utils.path(sys.vebusPrefix, "/Ac/State/IgnoreAcIn1") } + VBusItem { id: ignoreAcInput2; bind: Utils.path(sys.vebusPrefix, "/Ac/State/IgnoreAcIn2") } + VBusItem { id: acActiveInput; bind: Utils.path(sys.vebusPrefix, "/Ac/ActiveIn/ActiveInput") } + VBusItem { id: ac1source; bind: Utils.path("com.victronenergy.settings", "/Settings/SystemSetup/AcInput1") } + VBusItem { id: ac2source; bind: Utils.path("com.victronenergy.settings", "/Settings/SystemSetup/AcInput2") } + + title: qsTr("Generator") + + property bool autoStartSelected: false + + Component.onCompleted: + { + setFocusManual () + } + + Keys.forwardTo: [keyHandler] + Item + { + id: keyHandler + Keys.onUpPressed: + { + setFocusAuto () + event.accepted = true + } + Keys.onDownPressed: + { + setFocusManual () + event.accepted = true + } + // prevents page changes while timers are running + //// Keys.onReturnPressed: event.accepted = manualTile.startCountdown || autoRunTile.startCountdown + //// Keys.onEscapePressed: event.accepted = manualTile.startCountdown || autoRunTile.startCountdown + } + + function setFocusManual () + { + autoStartSelected = false + } + + function setFocusAuto () + { + autoStartSelected = true + } + + function formatTime (time) + { + if (time >= 3600) + return (time / 3600).toFixed(0) + " h" + else + return (time / 60).toFixed(0) + " m" + } + + function stateDescription() + { + if (!state.valid) + return qsTr ("") + else if (state.value === 10) + { + switch(error.value) + { + case 1: + return qsTr("Error: Remote switch control disabled") + case 2: + return qsTr("Error: Generator in fault condition") + case 3: + return qsTr("Error: Generator not detected at AC input") + default: + return qsTr("Error") + } + } + else + { + var condition = "" + var running = true + var manual = false + switch (runningBy.value) + { + case 0: // stopped + condition = "" + running = false + break;; + case 1: + manual = true + condition = "" + break;; + case 2: + condition = qsTr("Test run") + break;; + case 3: + condition = qsTr("Loss of communication") + break;; + case 4: + condition = qsTr("SOC") + break;; + case 5: + condition = qsTr("AC load") + break;; + case 6: + condition = qsTr("Battery current") + break;; + case 7: + condition = qsTr("Battery voltage") + break;; + case 8: + condition = qsTr("Inverter temperature") + break;; + case 9: + condition = qsTr("Inverter overload") + break;; + default: + condition = qsTr("???") + break;; + } + + if (externalOverride) + { + if (running && ! manual) + return qsTr ("auto pending: ") + condition + else + return " " + } + else if (manual) + { + if (manualTimer.valid && manualTimer.value > 0) + return qsTr("Timed run") + else + return qsTr("Manual run") + } + else if (running) + return qsTr ("auto run: ") + condition + else + return " " + } + } + + function getNextTestRun() + { + if ( ! root.state.valid) + return "" + if (!nextTestRun.value) + return qsTr("No test run programmed") + + var todayDate = new Date() + var nextDate = new Date(nextTestRun.value * 1000) + var nextDateEnd = new Date(nextDate.getTime()) + var message = "" + // blank "next run" if test run is active + if (runningBy.value == 2) + return " " + else if (todayDate.getDate() == nextDate.getDate() && todayDate.getMonth() == nextDate.getMonth()) + { + message = qsTr("Next test run today %1").arg( + Qt.formatDateTime(nextDate, "hh:mm").toString()) + } + else + { + message = qsTr("Next test run on %1").arg( + Qt.formatDateTime(nextDate, "dd/MM/yyyy").toString()) + nextDateEnd.setSeconds(testRunDuration.value) } + + if (skipTestRun.value === 1) + message += qsTr(" \(skipped\)") + + return message + } + + Tile { + id: imageTile + width: 180 + height: 136 + MbIcon { + id: generator + iconId: icon + anchors.centerIn: parent + } + anchors { top: parent.top; left: parent.left } + values: [ + // spacer + TileText { + width: imageTile.width - 5 + text: " " + font.pixelSize: 62 + }, + TileText { + width: imageTile.width - 5 + text: runningState.valid ? runningState.value == "R" ? "Running " : runningState.value == "S" ? "Stopped " : "" : "" + } + ] + } + + Tile { + id: statusTile + height: imageTile.height + color: "#4789d0" + anchors { top: parent.top; left: imageTile.right; right: root.right } + title: qsTr("STATUS") + values: [ + TileText + { + width: statusTile.width - 5 + color: externalOverride ? "yellow" : "white" + text: + { + var runPrefix + var message + if ( ! root.state.valid) + return qsTr ("Generator not connected") + else if (root.state.value === 2) + runPrefix = qsTr("Warming up for ") + else + runPrefix = qsTr ("Running for ") + if (!root.state.valid) + message = "" + else if (externalOverride) + message = qsTr("External Override - stopped") + else if (root.state.value === 3) + message = qsTr("Cool-down") + else if (root.state.value === 4) + message = qsTr("Stopping") + else if (runningBy.value == 0) + message = qsTr ("Stopped") + else if ( ! runningTime.valid) + message = runPrefix + "??" + else + { + message = runPrefix + formatTime (runningTime.value) + if (manualTimer.valid && manualTimer.value > 0) + message += qsTr (" ends in ") + formatTime (manualTimer.value) + } + return message + } + }, + Rectangle + { + width: parent.width + height: 3 + color: "transparent" + }, + TileTextMultiLine + { + text: stateDescription() + width: statusTile.width - 5 + }, + Rectangle + { + width: parent.width + height: 3 + color: "transparent" + }, + TileText + { + text: qsTr("\nQuiet hours"); + width: statusTile.width - 5 + font.bold: runningBy.valid && runningBy.value != 0 + color: font.bold ? "yellow" : "white" + visible: quietHours.value === 1 + }, + Rectangle + { + width: parent.width + height: 3 + color: "transparent" + }, + TileTextMultiLine + { + width: statusTile.width - 5 + text: getNextTestRun() + } + ] + } + + Tile { + id: acInTile + title: qsTr("GENERATOR POWER") + width: 150 + height: 136 + color: "#82acde" + anchors { top: imageTile.bottom; left: parent.left } + visible: showAcIn + values: + [ + OverviewAcValuesEnhanced + { + connection: sys.genset + visible: sys.genset.power.valid + }, + TileText + { + width: acInTile.width - 5 + text: + { + if (ac1source.valid && ac1source.value == 2) + { + if (ignoreAcInput1.valid && ignoreAcInput1.value == 1) + return qsTr ("\nAC In Ignored\nduring\ngenerator\nstart / stop") + else + return "" + } + else if (ac2source.valid && ac2source.value == 2) + { + if (ignoreAcInput2.valid && ignoreAcInput2.value == 1) + return qsTr ("\nAC In Ignored\nduring\ngenerator\nstart / stop") + else + return "" + } + else + return qsTr ("\nAC In\nis not\ngenerator") + } + visible: !sys.genset.power.valid + } + ] +////// add power bar graph + PowerGauge + { + id: acInBar + width: parent.width + height: 12 + anchors + { + top: parent.top; topMargin: 20 + horizontalCenter: parent.horizontalCenter + } + connection: sys.genset + useInputCurrentLimit: true + maxForwardPowerParameter: "" + maxReversePowerParameter: "" + visible: showGauges && sys.genset.power.valid + } + } + +//////// added to show alternator in place of AC generator + Tile { + id: alternatorTile + title: qsTr("ALTERNATOR POWER") + color: "#157894" + anchors.fill: acInTile + visible: showAlternator + values: + [ + TileText + { + text: EnhFmt.formatVBusItem (sys.alternator.power, "W") + font.pixelSize: 22 + } + ] +////// add power bar graph + PowerGauge + { + id: alternatorGauge + width: parent.width + height: 12 + anchors + { + top: parent.top; topMargin: 20 + horizontalCenter: parent.horizontalCenter + } + connection: sys.alternator + maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxAlternatorPower" + visible: showGauges && showAlternator + } + } + + Tile { + id: runTimeTile + title: qsTr("RUN TIMES") + width: 140 + anchors { top: acInTile.top; bottom: parent.bottom; left: acInTile.right } + values: [ + TileText + { + width: runTimeTile.width - 5 + text: qsTr ("Today") + }, + TileText { + width: runTimeTile.width - 5 + text: todayRuntime.valid ? formatTime (todayRuntime.value) : "--" + }, + Rectangle + { + width: parent.width + height: 3 + color: "transparent" + }, + TileText + { + width: runTimeTile.width - 5 + text: qsTr ("Accumulated") + }, + TileText + { + width: runTimeTile.width - 5 + text: + { + if ( ! totalAcummulatedTime.valid) + return "--" + else if (totalAccumulatedTimeOffset.valid ) + return formatTime (totalAcummulatedTime.value - totalAccumulatedTimeOffset.value) + else + return formatTime (totalAcummulatedTime.value) + } + }, + Rectangle + { + width: parent.width + height: 3 + color: "transparent" + }, + TileText + { + width: runTimeTile.width - 5 + visible: showServiceInfo + color: serviceOverdue ? "red" : "white" + text: serviceOverdue ? qsTr ("Service OVERDUE") : qsTr ("Service in") + }, + TileText + { + width: runTimeTile.width - 5 + visible: showServiceInfo + color: serviceOverdue ? "red" : "white" + text: formatTime (Math.abs (serviceCounterItem.value)) + } + ] + } + + TileAutoRunEnhanced + { + id: autoRunTile + bindPrefix: root.bindPrefix + focus: root.active && autoStartSelected + connected: state.valid + tileHeight: acInTile.height / 2 + anchors { + bottom: parent.bottom; bottomMargin: tileHeight + left: runTimeTile.right + right: parent.right + } + } + + TileManualStartEnhanced + { + id: manualTile + bindPrefix: root.bindPrefix + focus: root.active && ! autoStartSelected + connected: state.valid + tileHeight: acInTile.height / 2 + anchors { + bottom: parent.bottom + left: runTimeTile.right + right: parent.right + } + } + + // mouse areas must be AFTER their associated objects so those objects can catch mouse events + // rejected by these areas + // mouse targets need to be disabled while changes are pending + MouseArea { + id: autoRunTarget + anchors.fill: autoRunTile + enabled: root.active && ! editMode + onPressed: + { + if ( ! root.autoStartSelected ) + { + setFocusAuto () + mouse.accepted = true + } + else + { + mouse.accepted = false + } + } + } + MouseArea { + id: manualStartTarget + anchors.fill: manualTile + enabled: root.active && ! editMode + onPressed: + { + if ( root.autoStartSelected ) + { + setFocusManual () + mouse.accepted = true + } + else + { + mouse.accepted = false + } + } + } +} diff --git a/FileSets/v3.40~21/OverviewGeneratorEnhanced.qml.orig b/FileSets/v3.31/OverviewGeneratorEnhanced.qml.orig similarity index 100% rename from FileSets/v3.40~21/OverviewGeneratorEnhanced.qml.orig rename to FileSets/v3.31/OverviewGeneratorEnhanced.qml.orig diff --git a/FileSets/v3.31/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.31/OverviewGeneratorRelayEnhanced.qml index 1c9b530f..83089971 120000 --- a/FileSets/v3.31/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.31/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.31/OverviewGridParallel.qml b/FileSets/v3.31/OverviewGridParallel.qml index 3d1f0720..9113c998 120000 --- a/FileSets/v3.31/OverviewGridParallel.qml +++ b/FileSets/v3.31/OverviewGridParallel.qml @@ -1 +1 @@ -../v3.40~8/OverviewGridParallel.qml \ No newline at end of file +../v3.34/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.31/OverviewHub.qml b/FileSets/v3.31/OverviewHub.qml index 83bae2bd..fa34d88b 120000 --- a/FileSets/v3.31/OverviewHub.qml +++ b/FileSets/v3.31/OverviewHub.qml @@ -1 +1 @@ -../v3.40~8/OverviewHub.qml \ No newline at end of file +../v3.34/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.31/OverviewHubEnhanced.qml b/FileSets/v3.31/OverviewHubEnhanced.qml index 905200b7..857d9f2f 120000 --- a/FileSets/v3.31/OverviewHubEnhanced.qml +++ b/FileSets/v3.31/OverviewHubEnhanced.qml @@ -1 +1 @@ -../v3.40~8/OverviewHubEnhanced.qml \ No newline at end of file +../v3.34/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.31/OverviewMobileEnhanced.qml b/FileSets/v3.31/OverviewMobileEnhanced.qml index ea719476..a316f85d 120000 --- a/FileSets/v3.31/OverviewMobileEnhanced.qml +++ b/FileSets/v3.31/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.31/OverviewTanksTempsDigInputs.qml b/FileSets/v3.31/OverviewTanksTempsDigInputs.qml index 47c4f55e..3e684a7f 120000 --- a/FileSets/v3.31/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.31/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.31/PageGenerator.qml b/FileSets/v3.31/PageGenerator.qml deleted file mode 120000 index efbafddf..00000000 --- a/FileSets/v3.31/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.31/PageGenerator.qml b/FileSets/v3.31/PageGenerator.qml new file mode 100644 index 00000000..c9670db0 --- /dev/null +++ b/FileSets/v3.31/PageGenerator.qml @@ -0,0 +1,223 @@ +//// changed total time to hours (from varilable format) + +import QtQuick 1.1 +import com.victron.velib 1.0 +import "utils.js" as Utils + +MbPage { + id: root + title: qsTr("Generator start/stop") + property string settingsBindPrefix + property string startStopBindPrefix + property alias startStopModel: _startStopModel + property bool allowDisableAutostart: true + property VBusItem activeCondition: VBusItem { bind: Utils.path(startStopBindPrefix, "/RunningByCondition") } + property VBusItem generatorState: VBusItem { bind: Utils.path(startStopBindPrefix, "/State") } + property VBusItem runningTime: VBusItem { bind: Utils.path(startStopBindPrefix, "/Runtime") } + property VBusItem historicalData: VBusItem { bind: Utils.path(settingsBindPrefix, "/AccumulatedDaily") } + +//// changed total time to hours (from varilable format) + function formatTime (time) + { + if (time >= 3600) + return (time / 3600).toFixed(0) + " h" + else + return (time / 60).toFixed(0) + " m" + } + + + function getState() + { + switch(generatorState.value) { + case 10: + return qsTr("Error") + case 2: + return qsTr("Warm-up") + case 3: + return qsTr("Cool-down") + case 4: + return qsTr("Stopping") + } + + switch(activeCondition.value) { + case 'soc': + return qsTr("Running by SOC condition") + case 'acload': + return qsTr("Running by AC Load condition") + case 'batterycurrent': + return qsTr("Running by battery current condition") + case 'batteryvoltage': + return qsTr("Running by battery voltage condition") + case 'inverterhightemp': + return qsTr("Running by inverter high temperature") + case 'inverteroverload': + return qsTr("Running by inverter overload") + case 'testrun': + return qsTr("Test run") + case 'lossofcommunication': + return qsTr("Running by loss of communication") + case 'manual': + return qsTr("Manually started") + default: + return qsTr("Stopped") + } + } + + model: startStopModel + + function formatError(text, value) + { + return "#" + value.toString() + " " + text + } + + VisibleItemModel { + id: _startStopModel + + MbItemValue { + description: qsTr("State") + item.text: activeCondition.valid ? getState() : '---' + } + + MbItemOptions { + id: _gensetStatus + description: qsTr("Error") + bind: Utils.path(startStopBindPrefix, "/Error") + readonly: true + show: valid + possibleValues: [ + MbOption { description: qsTr("No error"); value: 0 }, + MbOption { description: formatError(qsTr("Remote switch control disabled"), 1); value: 1 }, + MbOption { description: formatError(qsTr("Generator in fault condition"), 2); value: 2 }, + MbOption { description: formatError(qsTr("Generator not detected at AC input"), 3); value: 3 } + ] + } + + MbItemValue { + description: qsTr("Run time") + item.text: runningTime.valid ? Utils.secondsToNoSecsString(runningTime.value) : "0" + show: generatorState.value in [1, 2, 3] // Running, Warm-up, Cool-down + } + + MbItemValue { + description: qsTr("Total run time") + show: item.valid + item { + bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") +//// changed total time to hours (from varilable format) + text: formatTime (item.value - accumulatedTotalOffset.value) + } + VBusItem { + id: accumulatedTotalOffset + bind: Utils.path(settingsBindPrefix, "/AccumulatedTotalOffset") + } + } + + MbItemValue { + description: qsTr("Time to service") + show: item.valid + item { + bind: Utils.path(startStopBindPrefix, "/ServiceCounter") + text: qsTr("%1h").arg((item.value / 60 / 60).toFixed(0)) + } + } + + MbItemValue { + description: qsTr("Accumulated running time since last test run") + show: user.accessLevel >= User.AccessService && nextTestRun.show + backgroundColor: style.backgroundColorService + item { + text: Utils.secondsToNoSecsString(item.value) + bind: Utils.path(startStopBindPrefix, "/TestRunIntervalRuntime") + } + } + + MbItemValue { + id: nextTestRun + description: qsTr("Time to next test run") + show: item.valid && item.value > 0 + item { + text: { + var remainingTime = item.value - new Date().getTime() / 1000 + if (remainingTime > 0) + return Utils.secondsToNoSecsString(remainingTime).toString() + return qsTr("Running now") + } + bind: Utils.path(startStopBindPrefix, "/NextTestRun") + } + } + + MbSwitch { + name: qsTr("Auto start functionality") + bind: Utils.path(startStopBindPrefix, "/AutoStartEnabled") + show: allowDisableAutostart + } + + MbSubMenu { + description: qsTr("Manual start") + subpage: Component { + MbPage { + id: manualStartPage + title: qsTr("Manual start") + model: VisibleItemModel { + MbSwitch { + id: manualSwitch + name: qsTr("Start generator") + bind: Utils.path(startStopBindPrefix, "/ManualStart") + writeAccessLevel: User.AccessUser + onCheckedChanged: { + if (manualStartPage.active) { + if (!checked) + toast.createToast(qsTr("Stopping, generator will continue running if other conditions are reached"), 3000) + if (checked && stopTimer.value == 0) + toast.createToast(qsTr("Starting, generator won't stop till user intervention"), 5000) + if (checked && stopTimer.value > 0) + toast.createToast(qsTr("Starting. The generator will stop in %1, unless other conditions keep it running").arg(Utils.secondsToString(stopTimer.value)), 5000) + } + } + + VBusItem { + id: stopTimer + bind: Utils.path(startStopBindPrefix, "/ManualStartTimer") + } + } + + MbEditBoxTime { + description: qsTr("Run for (hh:mm)") + readonly: manualSwitch.checked + item.bind: Utils.path(startStopBindPrefix, "/ManualStartTimer") + writeAccessLevel: User.AccessUser + } + } + } + } + } + + MbSubMenu { + description: qsTr("Daily run time") + subpage: MbPage { + // Invert the order + property variant keys: historicalData.valid ? + Object.keys(JSON.parse(historicalData.value)).reverse() : 0 + + title: qsTr("Daily run time") + focus: active + model: keys + delegate: MbItemValue { + description: Qt.formatDate(new Date(parseInt(keys[index]) * 1000), "dd-MM-yyyy"); + item.text: Utils.secondsToNoSecsString(JSON.parse(historicalData.value)[keys[index]]) + } + } + } + + MbSubMenu { + id: conditions + description: qsTr("Settings") + subpage: Component { + PageSettingsGenerator { + settingsBindPrefix: root.settingsBindPrefix + startStopBindPrefix: root.startStopBindPrefix + } + } + } + } +} diff --git a/FileSets/v3.40~21/PageGenerator.qml.orig b/FileSets/v3.31/PageGenerator.qml.orig similarity index 100% rename from FileSets/v3.40~21/PageGenerator.qml.orig rename to FileSets/v3.31/PageGenerator.qml.orig diff --git a/FileSets/v3.31/PageSettingsGenerator.qml b/FileSets/v3.31/PageSettingsGenerator.qml index 15dd8f85..2cb42f6b 120000 --- a/FileSets/v3.31/PageSettingsGenerator.qml +++ b/FileSets/v3.31/PageSettingsGenerator.qml @@ -1 +1 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file +../v3.40/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.31/PageSettingsGuiMods.qml b/FileSets/v3.31/PageSettingsGuiMods.qml index e831a7a4..191ce2c0 120000 --- a/FileSets/v3.31/PageSettingsGuiMods.qml +++ b/FileSets/v3.31/PageSettingsGuiMods.qml @@ -1 +1 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file +../v3.40/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.31/PageSettingsRelay.qml b/FileSets/v3.31/PageSettingsRelay.qml index 156aadac..f3f8e29c 120000 --- a/FileSets/v3.31/PageSettingsRelay.qml +++ b/FileSets/v3.31/PageSettingsRelay.qml @@ -1 +1 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file +../v3.40/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.31/PowerGauge.qml b/FileSets/v3.31/PowerGauge.qml index cfdf038d..afbecdae 120000 --- a/FileSets/v3.31/PowerGauge.qml +++ b/FileSets/v3.31/PowerGauge.qml @@ -1 +1 @@ -../v3.40~8/PowerGauge.qml \ No newline at end of file +../v3.34/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.31/TileDigIn.qml b/FileSets/v3.31/TileDigIn.qml index 44616f30..5cd386d6 120000 --- a/FileSets/v3.31/TileDigIn.qml +++ b/FileSets/v3.31/TileDigIn.qml @@ -1 +1 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file +../v3.40/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.31/TileRelay.qml b/FileSets/v3.31/TileRelay.qml index 9f83152f..9a8e9d15 120000 --- a/FileSets/v3.31/TileRelay.qml +++ b/FileSets/v3.31/TileRelay.qml @@ -1 +1 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file +../v3.40/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.31/dbus_digitalinputs.py b/FileSets/v3.31/dbus_digitalinputs.py index e74da5b6..54c5335d 120000 --- a/FileSets/v3.31/dbus_digitalinputs.py +++ b/FileSets/v3.31/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file +../v3.40/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.31/dbus_generator.py b/FileSets/v3.31/dbus_generator.py index 0cd84ca3..fc553c91 120000 --- a/FileSets/v3.31/dbus_generator.py +++ b/FileSets/v3.31/dbus_generator.py @@ -1 +1 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file +../v3.40/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.33/DetailAcInput.qml b/FileSets/v3.33/DetailAcInput.qml index d315e33a..c5cc199a 120000 --- a/FileSets/v3.33/DetailAcInput.qml +++ b/FileSets/v3.33/DetailAcInput.qml @@ -1 +1 @@ -../v3.40~8/DetailAcInput.qml \ No newline at end of file +../v3.34/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.33/DetailInverter.qml b/FileSets/v3.33/DetailInverter.qml index 2d924d7f..f204e4ff 120000 --- a/FileSets/v3.33/DetailInverter.qml +++ b/FileSets/v3.33/DetailInverter.qml @@ -1 +1 @@ -../v3.40~8/DetailInverter.qml \ No newline at end of file +../v3.34/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.33/DetailLoadsCombined.qml b/FileSets/v3.33/DetailLoadsCombined.qml index 58c63979..6b779a0c 120000 --- a/FileSets/v3.33/DetailLoadsCombined.qml +++ b/FileSets/v3.33/DetailLoadsCombined.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsCombined.qml \ No newline at end of file +../v3.34/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.33/DetailLoadsOnInput.qml b/FileSets/v3.33/DetailLoadsOnInput.qml index 5fb19084..27189b29 120000 --- a/FileSets/v3.33/DetailLoadsOnInput.qml +++ b/FileSets/v3.33/DetailLoadsOnInput.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsOnInput.qml \ No newline at end of file +../v3.34/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.33/DetailLoadsOnOutput.qml b/FileSets/v3.33/DetailLoadsOnOutput.qml index 9fdfdf28..656cbc0b 120000 --- a/FileSets/v3.33/DetailLoadsOnOutput.qml +++ b/FileSets/v3.33/DetailLoadsOnOutput.qml @@ -1 +1 @@ -../v3.40~8/DetailLoadsOnOutput.qml \ No newline at end of file +../v3.34/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.33/HubData.qml b/FileSets/v3.33/HubData.qml index b88f1965..486b4d89 120000 --- a/FileSets/v3.33/HubData.qml +++ b/FileSets/v3.33/HubData.qml @@ -1 +1 @@ -../v3.40~8/HubData.qml \ No newline at end of file +../v3.34/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.33/ObjectAcConnection.qml b/FileSets/v3.33/ObjectAcConnection.qml index cab7f2d4..bfe9c72c 120000 --- a/FileSets/v3.33/ObjectAcConnection.qml +++ b/FileSets/v3.33/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file +../v3.40/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.33/OverviewAcValuesEnhanced.qml b/FileSets/v3.33/OverviewAcValuesEnhanced.qml index 6d1e56b5..ba6bd7b3 120000 --- a/FileSets/v3.33/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.33/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.33/OverviewFlowComplex.qml b/FileSets/v3.33/OverviewFlowComplex.qml index 296ff4b1..ab0160fa 120000 --- a/FileSets/v3.33/OverviewFlowComplex.qml +++ b/FileSets/v3.33/OverviewFlowComplex.qml @@ -1 +1 @@ -../v3.40~8/OverviewFlowComplex.qml \ No newline at end of file +../v3.34/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.33/OverviewGeneratorEnhanced.qml b/FileSets/v3.33/OverviewGeneratorEnhanced.qml index 24bc6f1b..5d2ad08e 120000 --- a/FileSets/v3.33/OverviewGeneratorEnhanced.qml +++ b/FileSets/v3.33/OverviewGeneratorEnhanced.qml @@ -1 +1 @@ -../v3.34/OverviewGeneratorEnhanced.qml \ No newline at end of file +../v3.40/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.33/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.33/OverviewGeneratorRelayEnhanced.qml index 1c9b530f..83089971 120000 --- a/FileSets/v3.33/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.33/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.33/OverviewGridParallel.qml b/FileSets/v3.33/OverviewGridParallel.qml index 3d1f0720..9113c998 120000 --- a/FileSets/v3.33/OverviewGridParallel.qml +++ b/FileSets/v3.33/OverviewGridParallel.qml @@ -1 +1 @@ -../v3.40~8/OverviewGridParallel.qml \ No newline at end of file +../v3.34/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.33/OverviewHub.qml b/FileSets/v3.33/OverviewHub.qml index 83bae2bd..fa34d88b 120000 --- a/FileSets/v3.33/OverviewHub.qml +++ b/FileSets/v3.33/OverviewHub.qml @@ -1 +1 @@ -../v3.40~8/OverviewHub.qml \ No newline at end of file +../v3.34/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.33/OverviewHubEnhanced.qml b/FileSets/v3.33/OverviewHubEnhanced.qml index 905200b7..857d9f2f 120000 --- a/FileSets/v3.33/OverviewHubEnhanced.qml +++ b/FileSets/v3.33/OverviewHubEnhanced.qml @@ -1 +1 @@ -../v3.40~8/OverviewHubEnhanced.qml \ No newline at end of file +../v3.34/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.33/OverviewMobileEnhanced.qml b/FileSets/v3.33/OverviewMobileEnhanced.qml index ea719476..a316f85d 120000 --- a/FileSets/v3.33/OverviewMobileEnhanced.qml +++ b/FileSets/v3.33/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.33/OverviewTanksTempsDigInputs.qml b/FileSets/v3.33/OverviewTanksTempsDigInputs.qml index 47c4f55e..3e684a7f 120000 --- a/FileSets/v3.33/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.33/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.33/PageGenerator.qml b/FileSets/v3.33/PageGenerator.qml index bd3a4634..4c7f9a19 120000 --- a/FileSets/v3.33/PageGenerator.qml +++ b/FileSets/v3.33/PageGenerator.qml @@ -1 +1 @@ -../v3.34/PageGenerator.qml \ No newline at end of file +../v3.40/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.33/PageSettingsGenerator.qml b/FileSets/v3.33/PageSettingsGenerator.qml index 15dd8f85..2cb42f6b 120000 --- a/FileSets/v3.33/PageSettingsGenerator.qml +++ b/FileSets/v3.33/PageSettingsGenerator.qml @@ -1 +1 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file +../v3.40/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.33/PageSettingsGuiMods.qml b/FileSets/v3.33/PageSettingsGuiMods.qml index e831a7a4..191ce2c0 120000 --- a/FileSets/v3.33/PageSettingsGuiMods.qml +++ b/FileSets/v3.33/PageSettingsGuiMods.qml @@ -1 +1 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file +../v3.40/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.33/PageSettingsRelay.qml b/FileSets/v3.33/PageSettingsRelay.qml index 156aadac..f3f8e29c 120000 --- a/FileSets/v3.33/PageSettingsRelay.qml +++ b/FileSets/v3.33/PageSettingsRelay.qml @@ -1 +1 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file +../v3.40/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.33/PowerGauge.qml b/FileSets/v3.33/PowerGauge.qml index cfdf038d..afbecdae 120000 --- a/FileSets/v3.33/PowerGauge.qml +++ b/FileSets/v3.33/PowerGauge.qml @@ -1 +1 @@ -../v3.40~8/PowerGauge.qml \ No newline at end of file +../v3.34/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.33/TileDigIn.qml b/FileSets/v3.33/TileDigIn.qml index 44616f30..5cd386d6 120000 --- a/FileSets/v3.33/TileDigIn.qml +++ b/FileSets/v3.33/TileDigIn.qml @@ -1 +1 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file +../v3.40/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.33/TileRelay.qml b/FileSets/v3.33/TileRelay.qml index 9f83152f..9a8e9d15 120000 --- a/FileSets/v3.33/TileRelay.qml +++ b/FileSets/v3.33/TileRelay.qml @@ -1 +1 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file +../v3.40/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.33/dbus_digitalinputs.py b/FileSets/v3.33/dbus_digitalinputs.py index e74da5b6..54c5335d 120000 --- a/FileSets/v3.33/dbus_digitalinputs.py +++ b/FileSets/v3.33/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file +../v3.40/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.33/dbus_generator.py b/FileSets/v3.33/dbus_generator.py index 0cd84ca3..fc553c91 120000 --- a/FileSets/v3.33/dbus_generator.py +++ b/FileSets/v3.33/dbus_generator.py @@ -1 +1 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file +../v3.40/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.34/DetailAcInput.qml b/FileSets/v3.34/DetailAcInput.qml deleted file mode 120000 index d315e33a..00000000 --- a/FileSets/v3.34/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.34/DetailAcInput.qml b/FileSets/v3.34/DetailAcInput.qml new file mode 100644 index 00000000..d2865e4a --- /dev/null +++ b/FileSets/v3.34/DetailAcInput.qml @@ -0,0 +1,606 @@ +////// detail page for setting input current limit +////// and displaying AC input details +////// pushed from Flow overview + +import QtQuick 1.1 +import "utils.js" as Utils +import com.victron.velib 1.0 +import "enhancedFormat.js" as EnhFmt + +MbPage { + id: root + + title: "AC Input detail" + + property variant sys: theSystem + property string systemPrefix: "com.victronenergy.system" + property string settingsPrefix: "com.victronenergy.settings" + + property int fontPixelSize: 18 + property color buttonColor: "#979797" + property color pressedColor: "#d3d3d3" + property color backgroundColor: "#b3b3b3" + + property int buttonHeight: 40 + + property int dataColumns: 4 + property int rowTitleWidth: 100 + property int totalDataWidth: 340 - rowTitleWidth + property int tableColumnWidth: totalDataWidth / dataColumns + + property int legColumnWidth: phaseCount <= 1 ? tableColumnWidth * 3 : tableColumnWidth * 3 / phaseCount + + property int phaseCount: sys.acInput.phaseCount.valid ? sys.acInput.phaseCount.value : 0 + + VBusItem { id: vebusServiceItem; bind: Utils.path(systemPrefix, "/VebusService") } + property string inverterService: vebusServiceItem.valid ? vebusServiceItem.value : "" + property bool splitPhasePassthruDisabled: sys.acInput.splitPhaseL2PassthruDisabled + + property real actualCurrentLimit: 0 + property real newCurrentLimit: 0 + + VBusItem { id: acLimitPreset1Item; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/AcCurrentLimit/Preset1") } + VBusItem { id: acLimitPreset2Item; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/AcCurrentLimit/Preset2") } + VBusItem { id: acLimitPreset3Item; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/AcCurrentLimit/Preset3") } + VBusItem { id: acLimitPreset4Item; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/AcCurrentLimit/Preset4") } + property real acLimitPreset1: acLimitPreset1Item.valid ? acLimitPreset1Item.value : 0 + property real acLimitPreset2: acLimitPreset2Item.valid ? acLimitPreset2Item.value : 0 + property real acLimitPreset3: acLimitPreset3Item.valid ? acLimitPreset3Item.value : 0 + property real acLimitPreset4: acLimitPreset4Item.valid ? acLimitPreset4Item.value : 0 + + property bool currentLimitIsAdjustable: currentLimitIsAdjustableItem.valid && currentLimitIsAdjustableItem.value == 1 && currentLimitItem.valid + + Component.onCompleted: { getActualCurrent () } + + VBusItem + { + id: currentLimitIsAdjustableItem + bind: Utils.path(inverterService, "/Ac/ActiveIn/CurrentLimitIsAdjustable") + onValueChanged: getActualCurrent () + onValidChanged: getActualCurrent () + } + VBusItem + { + id: currentLimitItem + bind: Utils.path(inverterService, "/Ac/ActiveIn/CurrentLimit") + onValueChanged: getActualCurrent () + onValidChanged: getActualCurrent () + } + VBusItem { id: activeInputItem; bind: Utils.path(inverterService, "/Ac/ActiveIn/ActiveInput") } + VBusItem { id: numberOfAcInputs; bind: Utils.path(inverterService, "/Ac/In/NumberOfAcInputs") } + VBusItem { id: activeSourceItem; bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") } + VBusItem { id: acIn1sourceItem; bind: Utils.path(settingsPrefix, "/Settings/SystemSetup/AcInput1") } + VBusItem { id: acIn2sourceItem; bind: Utils.path(settingsPrefix, "/Settings/SystemSetup/AcInput2") } + property int activeSource: activeSourceItem.valid ? activeSourceItem.value : 0 + property int acIn1source: acIn1sourceItem.valid ? acIn1sourceItem.value : 0 + property int acIn2source: acIn2sourceItem.valid ? acIn2sourceItem.value : 0 + property int activeInput: activeInputItem.valid && activeInputItem.value == 1 ? 2 : 1 + property bool hasTwoInputs: numberOfAcInputs.valid && numberOfAcInputs.value == 2 + + property variant acSourceName: [qsTr("---"), qsTr("Grid"), qsTr("Generator"), qsTr("Shore")] + + // background + Rectangle + { + anchors + { + fill: parent + } + color: root.backgroundColor + } + + Row + { + spacing: 5 + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + width: parent.width - 6 + Column + { + spacing: 2 + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Total Power") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.acInput.power, "W") + } + PowerGauge + { + id: gauge + width: totalDataWidth - tableColumnWidth + height: 15 + connection: sys.acInput + useInputCurrentLimit: true + maxForwardPowerParameter: "" // handled internally - uses input current limit and AC input voltage + maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxFeedInPower" + } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth + tableColumnWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Active Source") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: totalDataWidth - tableColumnWidth; horizontalAlignment: Text.AlignHCenter + text: + { + if (activeSource == 240) + return quTr ("no input") + else if (hasTwoInputs) + return acSourceName[activeSource] + " (AC in " + activeInput + ")" + else + return acSourceName[activeSource] + } + } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: "L1" } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: "L2"; visible: phaseCount >= 2 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: "L3"; visible: phaseCount >= 3 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter + text: qsTr ("Freq") } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Power") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.acInput.powerL1, "W") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.acInput.powerL2, "W"); visible: phaseCount >= 2 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.acInput.powerL3, "W"); visible: phaseCount >= 3 } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Voltage / Freq") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.acInput.voltageL1, "V") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.acInput.voltageL2, "V"); visible: phaseCount >= 2 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.acInput.voltageL3, "V"); visible: phaseCount >= 3 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.acInput.frequency, "Hz") } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Current") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.acInput.currentL1, "A") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.acInput.currentL2, "A"); visible: phaseCount >= 2 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.acInput.currentL3, "A"); visible: phaseCount >= 3 } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("CurrentLimit") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: totalDataWidth; horizontalAlignment: Text.AlignHCenter + text: + { + var newText + if (newCurrentLimit != actualCurrentLimit) + newText = qsTr(" New ") + newCurrentLimit.toFixed (1) + " A" + else + newText = "" + return currentLimitItem.valid ? currentLimitItem.value.toFixed (1) + " A" + newText: "--" } + } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter + text: "L2 values included in L1" + visible: splitPhasePassthruDisabled } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter + text: qsTr("Avaliable Sources") } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: "L1" } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: "L2"; visible: phaseCount >= 2 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: "L3"; visible: phaseCount >= 3 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter + text: qsTr ("Freq") } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: 20; horizontalAlignment: Text.AlignHCenter + text: activeSource == 1 || activeSource == 3 ? ">" : "" } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth - 20; horizontalAlignment: Text.AlignRight + text: + { + if (acIn1source == 3 || acIn2source == 3) + return acSourceName[3] + else + return acSourceName[1] + } + } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.grid.voltageL1, "V") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.grid.voltageL2, "V"); visible: phaseCount >= 2 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.grid.voltageL3, "V"); visible: phaseCount >= 3 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.grid.frequency, "Hz") } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: 20; horizontalAlignment: Text.AlignHCenter + text: activeSource == 2 ? ">" : "" } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth - 20; horizontalAlignment: Text.AlignRight + text: acSourceName[2] } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.genset.voltageL1, "V") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.genset.voltageL2, "V"); visible: phaseCount >= 2 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.genset.voltageL3, "V"); visible: phaseCount >= 3 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.genset.frequency, "Hz") } + } + } + Column + { + id: currentButtonColumn + width: 128 + spacing: 4 + + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: currentButtonColumn.width; horizontalAlignment: Text.AlignHCenter + text: qsTr("Current Limit") } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: currentButtonColumn.width; horizontalAlignment: Text.AlignHCenter + text: qsTr("is not adjustable")} + visible: !currentLimitIsAdjustable + } + Row + { + visible: currentLimitIsAdjustable + width: (parent.width / 2) - 2 + spacing: 4 + DetailButton + { + id: preset1button + baseColor: newCurrentLimit === acLimitPreset1 ? "black" : root.buttonColor + pressedColor: root.pressedColor + opacity: acLimitPreset1 === 0 ? 0.001 : 1 + height: 40 + width: parent.width + onClicked: setNewValue (acLimitPreset1) + enabled: acLimitPreset1 === 0 ? false : true + content: TileText + { + text: qsTr(acLimitPreset1 + " A"); font.bold: true; + color: "white" + } + } + DetailButton + { + id: preset2button + baseColor: newCurrentLimit === acLimitPreset2 ? "black" : root.buttonColor + pressedColor: root.pressedColor + opacity: acLimitPreset2 === 0 ? 0.001 : 1 + height: 40 + width: parent.width + onClicked: setNewValue (acLimitPreset2) + enabled: acLimitPreset2 === 0 ? false : true + content: TileText + { + text: qsTr(acLimitPreset2 + " A"); font.bold: true; + color: "white" + } + } + } + Row + { + visible: currentLimitIsAdjustable + width: (parent.width / 2) - 2 + spacing: 4 + DetailButton + { + id: preset3button + baseColor: newCurrentLimit === acLimitPreset3 ? "black" : root.buttonColor + pressedColor: root.pressedColor + opacity: acLimitPreset3 === 0 ? 0.001 : 1 + height: 40 + width: parent.width + onClicked: setNewValue (acLimitPreset3) + enabled: acLimitPreset3 === 0 ? false : true + content: TileText + { + text: qsTr(acLimitPreset3 + " A"); font.bold: true; + color: "white" + } + } + DetailButton + { + visible: currentLimitIsAdjustable + id: preset4button + baseColor: newCurrentLimit === acLimitPreset4 ? "black" : root.buttonColor + pressedColor: root.pressedColor + opacity: acLimitPreset4 === 0 ? 0.001 : 1 + height: 40 + width: parent.width + onClicked: setNewValue (acLimitPreset4) + enabled: acLimitPreset4 === 0 ? false : true + content: TileText + { + text: qsTr(acLimitPreset4 + " A"); font.bold: true; + color: "white" + } + } + } + Row + { + visible: currentLimitIsAdjustable + width: (parent.width / 2) - 2 + spacing: 4 + DetailButton + { + id: trimMinus + baseColor: root.buttonColor + pressedColor: root.pressedColor + height: 40 + width: parent.width + enablePressAndHold: true + onClicked: trimNewValue (-1) + enabled: newCurrentLimit === acLimitPreset4 ? false : true + content: TileText + { + text: qsTr("-1 A"); font.bold: true; + color: "white" + } + } + DetailButton + { + id: trimPlus + baseColor: root.buttonColor + pressedColor: root.pressedColor + height: 40 + width: parent.width + enablePressAndHold: true + onClicked: trimNewValue (+1) + content: TileText + { + text: qsTr("+1 A"); font.bold: true; + color: "white" + } + } + } + Row + { + visible: currentLimitIsAdjustable + width: parent.width + spacing: 4 + DetailButton + { + id: acceptButton + baseColor: root.buttonColor + pressedColor: root.pressedColor + height: 40 + width: parent.width + onClicked: accept() + content: TileText { text: qsTr ("Accept New"); + font.bold: true; color: newCurrentLimit !== actualCurrentLimit ? "white" : "#d9d9d9" } + } + } + } + } + + function setNewValue (newValue) + { + if (currentLimitIsAdjustable) + newCurrentLimit = newValue + } + + function trimNewValue (trimValue) + { + if (!currentLimitIsAdjustable) + return + + newCurrentLimit += trimValue + if (newCurrentLimit < 0) + newCurrentLimit = 0 + } + + function cancel () + { + newCurrentLimit = actualCurrentLimit + pageStack.pop() + } + + function accept () + { + if (currentLimitIsAdjustable) + { + currentLimitItem.setValue (newCurrentLimit) + pageStack.pop() // return to main screen after changing input current limit + } + } + + function getActualCurrent () + { + actualCurrentLimit = currentLimitItem.valid ? currentLimitItem.value : 0 + newCurrentLimit = actualCurrentLimit + } + + // When new service is found check if is a tank sensor + Connections + { + target: DBusServices + onDbusServiceFound: addService(service) + } + + //// hard key handler + // used to press buttons when touch isn't available + // UP and DOWN buttons cycle through the list of buttons + // "space" button is used to simulate a button press + // button must be highlighted so that other uses of "space" + // will still occur + + // list of buttons to be accessed via hard buttons + property variant buttonList: + [ + preset1button, preset2button, preset3button, preset4button, trimMinus, trimPlus, acceptButton + ] + + property int buttonIndex: 0 + + Timer + { + id: targetTimer + interval: 5000 + repeat: false + running: false + onTriggered: { clearHighlight () } + } + + Keys.forwardTo: [keyHandler] + + Item + { + id: keyHandler + Keys.onDownPressed: + { + nextTarget (+1) + event.accepted = true + } + + Keys.onUpPressed: + { + nextTarget (-1) + event.accepted = true + } + } + + function nextTarget (increment) + { + // make one pass through all possible targets to find an enabled one + // if found, that's the new selectedTarget, + // if not selectedTarget does not change + var newIndex = buttonIndex + for (var i = 0; i < buttonList.length; i++) + { + // just restore highlight if not visible + if ( ! targetTimer.running && buttonList[newIndex].visible) + { + setActiveButton (buttonIndex) + return + } + newIndex += increment + if (newIndex >= buttonList.length) + newIndex = 0 + else if (newIndex < 0) + newIndex = buttonList.length - 1 + if (buttonList[newIndex].visible) + { + setActiveButton (newIndex) + break + } + } + } + + // Keys.onSpacePressed doesn't work - stolen by pageHandler + // so build a custom page handler so "space" can be used to press a button + pageToolbarHandler: detailToolbarHandler + ToolbarHandlerPages + { + id: detailToolbarHandler + isDefault: true + function centerAction() + { + acceptSpaceButton () + } + } + + function acceptSpaceButton () + { + if (targetTimer.running) + { + buttonList[buttonIndex].clicked () + } + } + + function setActiveButton (newIndex) + { + buttonIndex = newIndex + for (var i = 0; i < buttonList.length; i++) + if (i == newIndex) + buttonList[i].highlight = true + else + buttonList[i].highlight = false + targetTimer.restart () + } + + function clearHighlight () + { + for (var i = 0; i < buttonList.length; i++) + buttonList[i].highlight = false + } +} diff --git a/FileSets/v3.40~8/DetailAcInput.qml.orig b/FileSets/v3.34/DetailAcInput.qml.orig similarity index 100% rename from FileSets/v3.40~8/DetailAcInput.qml.orig rename to FileSets/v3.34/DetailAcInput.qml.orig diff --git a/FileSets/v3.34/DetailInverter.qml b/FileSets/v3.34/DetailInverter.qml deleted file mode 120000 index 2d924d7f..00000000 --- a/FileSets/v3.34/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.34/DetailInverter.qml b/FileSets/v3.34/DetailInverter.qml new file mode 100644 index 00000000..fd7e9def --- /dev/null +++ b/FileSets/v3.34/DetailInverter.qml @@ -0,0 +1,653 @@ +////// detail page for setting inverter mode +////// and displaying inverter details +////// pushed from Flow overview + +import QtQuick 1.1 +import "utils.js" as Utils +import com.victron.velib 1.0 +import "enhancedFormat.js" as EnhFmt + +MbPage { + id: root + + title: "Inverter detail" + + property variant sys: theSystem + property string systemPrefix: "com.victronenergy.system" + + property int fontPixelSize: 18 + property color buttonColor: "#979797" + property color pressedColor: "#d3d3d3" + property color backgroundColor: "#b3b3b3" + + property int inverterMode: inverterModeItem.valid ? inverterModeItem.value : 0 + property bool editable: inverterService != "" && inverterModeItem.valid + + property int buttonHeight: 40 + property int buttonWidth: 72 + property int buttonAreaWidth: buttonWidth * 2 + 4 + + property int rowTitleWidth: 132 + property int dataColumns: 3 + property int totalDataWidth: root.width - rowTitleWidth - buttonAreaWidth - 12 + property int tableColumnWidth: totalDataWidth / dataColumns + property int legColumnWidth: phaseCount <= 1 ? totalDataWidth : totalDataWidth / phaseCount + + property int numberOfMultis: 0 + property int numberOfInverters: 0 + property string inverterService: "" + property bool isInverter: numberOfMultis === 0 && numberOfInverters === 1 + + Component.onCompleted: { discoverServices(); highlightMode () } + + property bool showChargePriority: numberOfMultis > 0 && sys.preferRenewableEnergy.valid + property bool preferRenewableEnergy: showChargePriority && sys.preferRenewableEnergy.value == 1 + property bool autoReturnToRenewable: sys.remoteGeneratorSelected.valid + property bool acInIsGenerator: sys.acSource == 2 + + VBusItem + { + id: inverterModeItem + bind: Utils.path(inverterService, "/Mode") + onValidChanged: highlightMode () + onValueChanged: highlightMode () + } + property VBusItem systemState: VBusItem { bind: Utils.path(systemPrefix, "/SystemState/State") } + SystemState + { + id: vebusState + bind: systemState.valid ? Utils.path(systemPrefix, "/SystemState/State") : Utils.path(inverterService, "/State") + } + VBusItem { id: pInL1; bind: Utils.path(inverterService, "/Ac/ActiveIn/L1/P") } + VBusItem { id: pInL2; bind: Utils.path(inverterService, "/Ac/ActiveIn/L2/P") } + VBusItem { id: pInL3; bind: Utils.path(inverterService, "/Ac/ActiveIn/L2/P") } + VBusItem { id: vInL1; bind: Utils.path(inverterService, "/Ac/ActiveIn/L1/V") } + VBusItem { id: vInL2; bind: Utils.path(inverterService, "/Ac/ActiveIn/L2/V") } + VBusItem { id: vInL3; bind: Utils.path(inverterService, "/Ac/ActiveIn/L3/V") } + VBusItem { id: iInL1; bind: Utils.path(inverterService, "/Ac/ActiveIn/L1/I") } + VBusItem { id: iInL2; bind: Utils.path(inverterService, "/Ac/ActiveIn/L2/I") } + VBusItem { id: iInL3; bind: Utils.path(inverterService, "/Ac/ActiveIn/L3/I") } + VBusItem { id: pOutL1; bind: Utils.path(inverterService, "/Ac/Out/L1/P") } + VBusItem { id: pOutL2; bind: Utils.path(inverterService, "/Ac/Out/L2/P") } + VBusItem { id: pOutL3; bind: Utils.path(inverterService, "/Ac/Out/L3/P") } + VBusItem { id: vOutL1; bind: Utils.path(inverterService, "/Ac/Out/L1/V") } + VBusItem { id: vOutL2; bind: Utils.path(inverterService, "/Ac/Out/L2/V") } + VBusItem { id: vOutL3; bind: Utils.path(inverterService, "/Ac/Out/L3/V") } + VBusItem { id: iOutL1; bind: Utils.path(inverterService, "/Ac/Out/L1/I") } + VBusItem { id: iOutL2; bind: Utils.path(inverterService, "/Ac/Out/L2/I") } + VBusItem { id: iOutL3; bind: Utils.path(inverterService, "/Ac/Out/L3/I") } + VBusItem { id: fInL1; bind: Utils.path(inverterService, "/Ac/ActiveIn/L1/F") } + VBusItem { id: fOutL1; bind: Utils.path(inverterService, "/Ac/Out/L1/F") } + VBusItem { id: dcPower; bind: Utils.path(inverterService, "/Dc/0/Power") } + VBusItem { id: dcCurrent; bind: Utils.path(inverterService, "/Dc/0/Current") } + VBusItem { id: _l2L1OutSummed; bind: Utils.path(inverterService, "/Ac/State/SplitPhaseL2L1OutSummed") } + VBusItem { id: phaseCountItem; bind: Utils.path(inverterService, "/Ac/NumberOfPhases") } + + property bool noL2inverter: _l2L1OutSummed.valid + property bool l2AndL1OutSummed: noL2inverter && _l2L1OutSummed.value === 1 + property int phaseCount: phaseCountItem.valid ? phaseCountItem.value : 0 + + // background + Rectangle + { + anchors + { + fill: parent + } + color: root.backgroundColor + } + + Column + { + spacing: 2 + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left; anchors.leftMargin: 3 + Row + { + PowerGaugeMulti + { + id: gauge + width: rowTitleWidth + totalDataWidth + height: 15 + inverterService: root.inverterService + } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Total Power") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: totalDataWidth; horizontalAlignment: Text.AlignHCenter + text: + { + var total = 0 + var totalValid = false + if (pOutL1.valid && pInL1.valid) + { + total += pOutL1.value - pInL1.value + totalValid = true + } + if (pOutL2.valid && pInL2.valid) + { + total += pOutL2.value - pInL2.value + totalValid = true + } + if (pOutL3.valid && pInL3.valid) + { + total += pOutL3.value - pInL3.value + totalValid = true + } + if (totalValid) + return EnhFmt.formatValue (total, "W") + else + return "--" + } + } + visible: phaseCount >= 2 + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("State") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: totalDataWidth; horizontalAlignment: Text.AlignHCenter + text: vebusState.text } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: "" } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: "L1" } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: "L2" } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: "L3"; visible: phaseCount >= 3 } + visible: phaseCount >= 2 + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Power") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: formatValueDiff (pOutL1, pInL1, "W") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: + { + if (l2AndL1OutSummed) + return "< < <" + else if (noL2inverter) + return qsTr("none") + else + return formatValueDiff (pOutL2, pInL2, "W") + } + visible: phaseCount >= 2 + } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: formatValueDiff (pOutL3, pInL3, "W"); visible: phaseCount >= 3 } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Input Voltage") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (vInL1, "V") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (vInL2, "V"); visible: phaseCount >= 2 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (vInL3, "V"); visible: phaseCount >= 3 } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Output Voltage") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (vOutL1, "V") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (vOutL2, "V"); visible: phaseCount >= 2 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (vOutL3, "V"); visible: phaseCount >= 3 } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Input Current") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (iInL1, "A") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (iInL2, "A"); visible: phaseCount >= 2 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (iInL3, "A"); visible: phaseCount >= 3 } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Output Current") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (iOutL1, "A") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: l2AndL1OutSummed ? "< < <" : EnhFmt.formatVBusItem (iOutL2, "A"); visible: phaseCount >= 2 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (iOutL3, "A"); visible: phaseCount >= 3 } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Frequency In / Out") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: totalDataWidth / 2; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (fInL1, "Hz") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: totalDataWidth / 2; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (fOutL1, "Hz") } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("DC Power / Current") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: totalDataWidth * 0.4; horizontalAlignment: Text.AlignHCenter + text: + { + if (! dcPower.valid) + return "" + else if (dcPower.value > 0) + return qsTr ("supplying") + else if (dcPower.value < 0) + return qsTr ("consuming") + else + return "" + } + } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: totalDataWidth * 0.3; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (dcPower, "W") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: totalDataWidth * 0.3; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (dcCurrent, "A") } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter + text: l2AndL1OutSummed ? qsTr ("L2 Output values included in L1") : qsTr ("L2 AC out from AC in (no inverter)") + visible: noL2inverter + } + } + } + Column + { + id: inverterModeButtonArea + width: root.buttonAreaWidth + anchors.top: parent.top; anchors.topMargin: 3 + anchors.right: parent.right; anchors.rightMargin: 3 + spacing: 4 + + Row + { + Text + { + font.pixelSize: 12; color: "black" + width: root.buttonAreaWidth; horizontalAlignment: Text.AlignHCenter + text: qsTr("Inverter mode") + visible: showChargePriority + } + } + Row + { + spacing: 4 + DetailButton + { + id: onButton + baseColor: inverterMode === 3 ? "green" : "#e6ffe6" + pressedColor: root.pressedColor + height: root.buttonHeight + width: root.buttonWidth + visible: !isInverter + onClicked: changeMode(3) + content: TileText + { + text: qsTr("On"); font.bold: true; + color: inverterMode === 3 ? "white" : "gray" + } + } + DetailButton + { + id: offButton + baseColor: inverterMode === 4 ? "black" : "#e6e6e6" + pressedColor: root.pressedColor + height: root.buttonHeight + width: root.buttonWidth + onClicked: changeMode(4) + content: TileText + { + text: qsTr("Off"); font.bold: true; + color: inverterMode === 4 ? "white" : "gray" + } + } + } + Row + { + spacing: 4 + DetailButton + { + id: invertOnlyButton + baseColor: inverterMode === 2 ? "blue" : "#ccccff" + pressedColor: root.pressedColor + height: root.buttonHeight + width: root.buttonWidth + onClicked: changeMode(2) + content: TileText + { + text: isInverter ? qsTr("On") : qsTr("Inverter\nOnly"); font.bold: true; + color: inverterMode === 2 ? "white" : "gray" + } + } + DetailButton + { + id: chargeOnlyButton + baseColor: inverterMode === 1 ? "orange" : "#ffedcc" + pressedColor: root.pressedColor + height: root.buttonHeight + width: root.buttonWidth + visible: !isInverter + onClicked: changeMode(1) + content: TileText + { + text: qsTr("Charger\nOnly"); font.bold: true; + color: inverterMode === 1 ? "white" : "gray" + } + } + DetailButton + { + id: ecoButton + baseColor: inverterMode === 5 ? "orange" : "#ffedcc" + pressedColor: root.pressedColor + height: root.buttonHeight + width: root.buttonWidth + visible: isInverter + onClicked: changeMode(5) + content: TileText + { + text: qsTr("Eco"); font.bold: true; + color: inverterMode === 5 ? "white" : "black" + } + } + } + } + Column + { + id: chargePriorityButtonArea + width: root.buttonAreaWidth + anchors.bottom: parent.bottom; anchors.bottomMargin: 3 + anchors.right: parent.right; anchors.rightMargin: 3 + spacing: 4 + + Row + { + Text + { + font.pixelSize: 12; color: "black" + width: root.buttonAreaWidth; horizontalAlignment: Text.AlignHCenter + text: qsTr("Charge priority") + visible: showChargePriority + } + } + Row + { + spacing: 4 + DetailButton + { + id: acPriorityButton + baseColor: ! preferRenewableEnergy && ! acInIsGenerator ? "orange" : "#ffedcc" + pressedColor: root.pressedColor + height: root.buttonHeight + width: root.buttonWidth + onClicked: { if (! acInIsGenerator) sys.preferRenewableEnergy.setValue (0)} + visible: showChargePriority + content: TileText + { + text: "Grid"; font.bold: true + color: ! preferRenewableEnergy && ! acInIsGenerator ? "white" : "gray" + } + } + DetailButton + { + id: renewablePriorityButton + baseColor: preferRenewableEnergy && ! acInIsGenerator ? "green" : "#e6ffe6" + pressedColor: root.pressedColor + height: root.buttonHeight + width: root.buttonWidth + visible: showChargePriority + onClicked: { if (! acInIsGenerator) sys.preferRenewableEnergy.setValue (1)} + content: TileText + { + text: qsTr("Renew\nable"); font.bold: true + color: preferRenewableEnergy && ! acInIsGenerator ? "white" : "gray" + } + } + } + Row + { + Text + { + font.pixelSize: 12; color: "black" + width: root.buttonAreaWidth; horizontalAlignment: Text.AlignHCenter + text: + { + if (acInIsGenerator) + return qsTr ("Generator active\nno priority") + else if (autoReturnToRenewable && ! preferRenewableEnergy) + return qsTr ("returns to Renewable\n at 100% SOC") + else return "\n" + } + visible: showChargePriority + } + } + } + + + function changeMode(newMode) + { + if (editable) + { + inverterModeItem.setValue(newMode) + pageStack.pop() // return to flow screen after changing inverter mode + } + } + + function cancel() + { + pageStack.pop() + } + + function highlightMode () + { + if (editable) + inverterMode = inverterModeItem.value + else + inverterMode = 0 + } + + + // When new service is found check if is a tank sensor + Connections + { + target: DBusServices + onDbusServiceFound: addService(service) + } + + function addService(service) + { + switch (service.type) + { + case DBusService.DBUS_SERVICE_MULTI: + case DBusService.DBUS_SERVICE_MULTI_RS: + numberOfMultis++ + if (numberOfMultis === 1) + inverterService = service.name; + break;; + case DBusService.DBUS_SERVICE_INVERTER: + numberOfInverters++ + if (numberOfInverters === 1 && numberOfMultis === 0) + inverterService = service.name; + break;; + } + } + + // Detect available services of interest + function discoverServices() + { + numberOfMultis = 0 + numberOfInverters = 0 + inverterService = "" + for (var i = 0; i < DBusServices.count; i++) + { + addService(DBusServices.at(i)) + } + } + + function formatValueDiff (item1, item2, unit) + { + if (item1.valid && item2.valid) + return EnhFmt.formatValue (item1.value - item2.value, unit) + else + return "--" + } + + + //// hard key handler + // used to press buttons when touch isn't available + // UP and DOWN buttons cycle through the list of buttons + // "space" button is used to simulate a button press + // button must be highlighted so that other uses of "space" + // will still occur + + // list of buttons to be accessed via hard buttons + property variant buttonList: + [ + onButton, offButton, invertOnlyButton, chargeOnlyButton, ecoButton + ] + + property int buttonIndex: 0 + + Timer + { + id: targetTimer + interval: 5000 + repeat: false + running: false + onTriggered: { clearHighlight () } + } + + Keys.forwardTo: [keyHandler] + + Item + { + id: keyHandler + Keys.onDownPressed: + { + nextTarget (+1) + event.accepted = true + } + + Keys.onUpPressed: + { + nextTarget (-1) + event.accepted = true + } + } + + function nextTarget (increment) + { + // make one pass through all possible targets to find an enabled one + // if found, that's the new selectedTarget, + // if not selectedTarget does not change + var newIndex = buttonIndex + for (var i = 0; i < buttonList.length; i++) + { + // just restore highlight if not visible + if ( ! targetTimer.running && buttonList[newIndex].visible) + { + setActiveButton (buttonIndex) + return + } + newIndex += increment + if (newIndex >= buttonList.length) + newIndex = 0 + else if (newIndex < 0) + newIndex = buttonList.length - 1 + if (buttonList[newIndex].visible) + { + setActiveButton (newIndex) + break + } + } + } + + // Keys.onSpacePressed doesn't work - stolen by pageHandler + // so build a custom page handler so "space" can be used to press a button + pageToolbarHandler: detailToolbarHandler + ToolbarHandlerPages + { + id: detailToolbarHandler + isDefault: true + function centerAction() + { + acceptSpaceButton () + } + } + + function acceptSpaceButton () + { + if (targetTimer.running) + { + buttonList[buttonIndex].clicked () + } + } + + function setActiveButton (newIndex) + { + buttonIndex = newIndex + for (var i = 0; i < buttonList.length; i++) + if (i == newIndex) + buttonList[i].highlight = true + else + buttonList[i].highlight = false + targetTimer.restart () + } + + function clearHighlight () + { + for (var i = 0; i < buttonList.length; i++) + buttonList[i].highlight = false + } +} diff --git a/FileSets/v3.40~8/DetailInverter.qml.orig b/FileSets/v3.34/DetailInverter.qml.orig similarity index 100% rename from FileSets/v3.40~8/DetailInverter.qml.orig rename to FileSets/v3.34/DetailInverter.qml.orig diff --git a/FileSets/v3.34/DetailLoadsCombined.qml b/FileSets/v3.34/DetailLoadsCombined.qml deleted file mode 120000 index 58c63979..00000000 --- a/FileSets/v3.34/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.34/DetailLoadsCombined.qml b/FileSets/v3.34/DetailLoadsCombined.qml new file mode 100644 index 00000000..5909cb10 --- /dev/null +++ b/FileSets/v3.34/DetailLoadsCombined.qml @@ -0,0 +1,146 @@ +////// detail page for displaying critical AC output details +////// pushed from Flow overview + +import QtQuick 1.1 +import "utils.js" as Utils +import com.victron.velib 1.0 +import "enhancedFormat.js" as EnhFmt + +MbPage { + id: root + + title: qsTr ("AC Loads detail") + + property variant sys: theSystem + property string systemPrefix: "com.victronenergy.system" + + property int fontPixelSize: 18 + property color backgroundColor: "#b3b3b3" + + property int dataColumns: 3 + property int rowTitleWidth: 130 + property int totalDataWidth: root.width - rowTitleWidth - 20 + property int tableColumnWidth: totalDataWidth / dataColumns + property int legColumnWidth: phaseCount <= 1 ? totalDataWidth : totalDataWidth / phaseCount + + property int phaseCount: sys.acLoad.phaseCount.valid ? sys.acLoad.phaseCount.value : 0 + + VBusItem { id: vebusServiceItem; bind: Utils.path(systemPrefix, "/VebusService") } + property string inverterService: vebusServiceItem.valid ? vebusServiceItem.value : "" + property bool l2AndL1OutSummed: sys.acLoad.l2AndL1OutSummed + + // background + Rectangle + { + anchors + { + fill: parent + } + color: root.backgroundColor + } + + Row + { + spacing: 5 + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + Column + { + spacing: 2 + Row + { + Text { id: totalLabel; font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Total Power") } + Text { id: totalPower; font.pixelSize: 12; font.bold: true; color: "black" + width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.acLoad.power, "W") + } + PowerGauge + { + id: gauge + width: (root.width * 0.9) - totalLabel.width - totalPower.width + height: 15 + maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputMaxPower" + connection: sys.acLoad + } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: "" } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: "L1" } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: "L2"; visible: phaseCount >= 2 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: "L3"; visible: phaseCount >= 3 } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Power") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.acLoad.powerL1, "W") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: l2AndL1OutSummed ? "< < <" : EnhFmt.formatVBusItem (sys.acLoad.powerL2, "W"); visible: phaseCount >= 2 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.acLoad.powerL3, "W"); visible: phaseCount >= 3 } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Voltage") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.acLoad.voltageL1, "V") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: l2AndL1OutSummed ? "< < <" : EnhFmt.formatVBusItem (sys.acLoad.voltageL2, "V"); visible: phaseCount >= 2 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.acLoad.voltageL3, "V"); visible: phaseCount >= 3 } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Current") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.acLoad.currentL1, "A") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: l2AndL1OutSummed ? "< < <" : EnhFmt.formatVBusItem (sys.acLoad.currentL2, "A"); visible: phaseCount >= 2 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.acLoad.currentL3, "A"); visible: phaseCount >= 3 } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Frequency") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: totalDataWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.acLoad.frequency, "Hz") } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter + text: "L2 values included in L1" + visible: l2AndL1OutSummed } + } + } + } +} diff --git a/FileSets/v3.40~8/DetailLoadsCombined.qml.orig b/FileSets/v3.34/DetailLoadsCombined.qml.orig similarity index 100% rename from FileSets/v3.40~8/DetailLoadsCombined.qml.orig rename to FileSets/v3.34/DetailLoadsCombined.qml.orig diff --git a/FileSets/v3.34/DetailLoadsOnInput.qml b/FileSets/v3.34/DetailLoadsOnInput.qml deleted file mode 120000 index 5fb19084..00000000 --- a/FileSets/v3.34/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.34/DetailLoadsOnInput.qml b/FileSets/v3.34/DetailLoadsOnInput.qml new file mode 100644 index 00000000..999a62ac --- /dev/null +++ b/FileSets/v3.34/DetailLoadsOnInput.qml @@ -0,0 +1,146 @@ +////// detail page for displaying non-critical AC output details +////// pushed from Flow overview + +import QtQuick 1.1 +import "utils.js" as Utils +import com.victron.velib 1.0 +import "enhancedFormat.js" as EnhFmt + +MbPage { + id: root + + title: "Loads on AC Input Detail" + + property variant sys: theSystem + property string systemPrefix: "com.victronenergy.system" + + property int fontPixelSize: 18 + property color backgroundColor: "#b3b3b3" + + property int dataColumns: 3 + property int rowTitleWidth: 130 + property int totalDataWidth: root.width - rowTitleWidth - 20 + property int tableColumnWidth: totalDataWidth / dataColumns + property int legColumnWidth: phaseCount <= 1 ? totalDataWidth : totalDataWidth / phaseCount + + property int phaseCount: sys.acInLoad.phaseCount.valid ? sys.acInLoad.phaseCount.value : 0 + + VBusItem { id: vebusServiceItem; bind: Utils.path(systemPrefix, "/VebusService") } + property string inverterService: vebusServiceItem.valid ? vebusServiceItem.value : "" + property bool splitPhasePassthruDisabled: sys.acInput.splitPhasePassthruDisabled + + // background + Rectangle + { + anchors + { + fill: parent + } + color: root.backgroundColor + } + + Row + { + spacing: 5 + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + Column + { + spacing: 2 + Row + { + Text { id: totalLabel; font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Total Power") } + Text { id: totalPower; font.pixelSize: 12; font.bold: true; color: "black" + width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.acInLoad.power, "W") + } + PowerGauge + { + id: gauge + width: (root.width * 0.9) - totalLabel.width - totalPower.width + height: 15 + maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputMaxPower" + connection: sys.acInLoad + } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: "" } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: "L1" } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: "L2"; visible: phaseCount >= 2 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: "L3"; visible: phaseCount >= 3 } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Power") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.acInLoad.powerL1, "W") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.acInLoad.powerL2, "W"); visible: phaseCount >= 2 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.acInLoad.powerL3, "W"); visible: phaseCount >= 3 } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Voltage") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.acInLoad.voltageL1, "V") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.acInLoad.voltageL2, "V"); visible: phaseCount >= 2 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.acInLoad.voltageL3, "V"); visible: phaseCount >= 3 } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Current") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.acInLoad.currentL1, "A") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.acInLoad.currentL2, "A"); visible: phaseCount >= 2 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.acInLoad.currentL3, "A"); visible: phaseCount >= 3 } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Frequency") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: totalDataWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (sys.acInLoad.frequency, "Hz") } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter + text: "L2 values included in L1" + visible: splitPhasePassthruDisabled } + } + } + } +} diff --git a/FileSets/v3.40~8/DetailLoadsOnInput.qml.orig b/FileSets/v3.34/DetailLoadsOnInput.qml.orig similarity index 100% rename from FileSets/v3.40~8/DetailLoadsOnInput.qml.orig rename to FileSets/v3.34/DetailLoadsOnInput.qml.orig diff --git a/FileSets/v3.34/DetailLoadsOnOutput.qml b/FileSets/v3.34/DetailLoadsOnOutput.qml deleted file mode 120000 index 9fdfdf28..00000000 --- a/FileSets/v3.34/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.34/DetailLoadsOnOutput.qml b/FileSets/v3.34/DetailLoadsOnOutput.qml new file mode 100644 index 00000000..2092989c --- /dev/null +++ b/FileSets/v3.34/DetailLoadsOnOutput.qml @@ -0,0 +1,151 @@ +////// detail page for displaying critical AC output details +////// pushed from Flow overview + +import QtQuick 1.1 +import "utils.js" as Utils +import com.victron.velib 1.0 +import "enhancedFormat.js" as EnhFmt + +MbPage { + id: root + + title: combineAcLoads ? qsTr ("AC Loads detail") : qsTr ("Loads on AC Output detail") + + property variant sys: theSystem + property string systemPrefix: "com.victronenergy.system" + property string settingsPrefix: "com.victronenergy.settings" + + property int fontPixelSize: 18 + property color backgroundColor: "#b3b3b3" + + property int dataColumns: 3 + property int rowTitleWidth: 130 + property int totalDataWidth: root.width - rowTitleWidth - 20 + property int tableColumnWidth: totalDataWidth / dataColumns + property int legColumnWidth: phaseCount <= 1 ? totalDataWidth : totalDataWidth / phaseCount + + property int phaseCount: outputLoad.phaseCount.valid ? outputLoad.phaseCount.value : 0 + + VBusItem { id: vebusServiceItem; bind: Utils.path(systemPrefix, "/VebusService") } + property string inverterService: vebusServiceItem.valid ? vebusServiceItem.value : "" + property bool l2AndL1OutSummed: sys.acLoad.l2AndL1OutSummed + + VBusItem { id: _combineAcLoads; bind: "com.victronenergy.settings/Settings/GuiMods/EnhancedFlowCombineLoads" } + property bool combineAcLoads: _combineAcLoads.valid && _combineAcLoads.value === 1 + property variant outputLoad: combineAcLoads ? sys.acLoad : sys.acOutLoad + + // background + Rectangle + { + anchors + { + fill: parent + } + color: root.backgroundColor + } + + Row + { + spacing: 5 + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + Column + { + spacing: 2 + Row + { + Text { id: totalLabel; font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Total Power") } + Text { id: totalPower; font.pixelSize: 12; font.bold: true; color: "black" + width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (outputLoad.power, "W") + } + PowerGauge + { + id: gauge + width: (root.width * 0.9) - totalLabel.width - totalPower.width + height: 15 + maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputMaxPower" + connection: outputLoad + } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: "" } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: "L1" } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: "L2"; visible: phaseCount >= 2 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: "L3"; visible: phaseCount >= 3 } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Power") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (outputLoad.powerL1, "W") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: l2AndL1OutSummed ? "< < <" : EnhFmt.formatVBusItem (outputLoad.powerL2, "W"); visible: phaseCount >= 2 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (outputLoad.powerL3, "W"); visible: phaseCount >= 3 } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Voltage") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (outputLoad.voltageL1, "V") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: l2AndL1OutSummed ? "< < <" : EnhFmt.formatVBusItem (outputLoad.voltageL2, "V"); visible: phaseCount >= 2 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (outputLoad.voltageL3, "V"); visible: phaseCount >= 3 } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Current") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (outputLoad.currentL1, "A") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: l2AndL1OutSummed ? "< < <" : EnhFmt.formatVBusItem (outputLoad.currentL2, "A"); visible: phaseCount >= 2 } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: legColumnWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (outputLoad.currentL3, "A"); visible: phaseCount >= 3 } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth; horizontalAlignment: Text.AlignRight + text: qsTr("Frequency") } + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: totalDataWidth; horizontalAlignment: Text.AlignHCenter + text: EnhFmt.formatVBusItem (outputLoad.frequency, "Hz") } + } + Row + { + Text { font.pixelSize: 12; font.bold: true; color: "black" + width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter + text: "L2 values included in L1" + visible: l2AndL1OutSummed } + } + } + } +} diff --git a/FileSets/v3.40~8/DetailLoadsOnOutput.qml.orig b/FileSets/v3.34/DetailLoadsOnOutput.qml.orig similarity index 100% rename from FileSets/v3.40~8/DetailLoadsOnOutput.qml.orig rename to FileSets/v3.34/DetailLoadsOnOutput.qml.orig diff --git a/FileSets/v3.34/HubData.qml b/FileSets/v3.34/HubData.qml deleted file mode 120000 index b88f1965..00000000 --- a/FileSets/v3.34/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.34/HubData.qml b/FileSets/v3.34/HubData.qml new file mode 100644 index 00000000..5e375f49 --- /dev/null +++ b/FileSets/v3.34/HubData.qml @@ -0,0 +1,273 @@ +//////// modified for VE.Direct inverter support +//////// modified for grid/genset meter +//////// added alternator, AC charger, wind generator + +import QtQuick 1.1 +import com.victron.velib 1.0 +import "utils.js" as Utils + +Item { + id: root + + property variant sys: theSystem + + property string systemPrefix: "com.victronenergy.system" + property string settingsPrefix: "com.victronenergy.settings" + property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" + +//////// add to support VE.Direct inverters + property string inverterService: "" +//////// add for grid/genset meters + property string gridMeterService: "" + property string gensetService: "" + + property variant battery: _battery + property alias dcSystem: _dcSystem + property alias alternator: _alternator + property alias windGenerator: _windGenerator + property alias fuelCell: _fuelCell + property alias acCharger: _acCharger + property alias pvCharger: _pvCharger + property alias pvOnAcIn1: _pvOnAcIn1 + property alias pvOnAcIn2: _pvOnAcIn2 + property alias pvOnAcOut: _pvOnAcOut + property alias vebusDc: _vebusDc + property alias acLoad: _acLoad + property alias acInLoad: _acInLoad + property alias acOutLoad: _acOutLoad + property alias grid: _grid + property alias acInput: _activein + property alias genset: _genset + property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } + property variant acSource: _acSource.value + property VBusItem preferRenewableEnergy: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/PreferRenewableEnergy") } + property VBusItem remoteGeneratorSelected: VBusItem { bind: Utils.path(vebusPrefix, "/Ac/State/RemoteGeneratorSelected") } + + property alias pvOnGrid: _pvOnAcIn2 + + property int batteryStateIdle: 0 + property int batteryStateCharging: 1 + property int batteryStateDischarging: 2 + + property int acSourceNotAvailable: 0 + property int acSourceGrid: 1 + property int acSourceGenset: 2 + property int acSourceShore: 3 // same as grid + + property alias pvInvertersProductIds: _pvInvertersProductIds + property alias batteryProductId: _batteryProductId + + VBusItem { + id: _pvInvertersProductIds + bind: Utils.path(systemPrefix, "/PvInvertersProductIds") + } + + VBusItem { + id: _batteryProductId + bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") + } + + VBusItem { + id: _vebusService + bind: Utils.path(systemPrefix, "/VebusService") + } + + QtObject { + id: _pvCharger + property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} + } + +//////// added alternator + QtObject { + id: _alternator + property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Alternator/Power"); unit: "W"} + } + +//////// added AC charger + QtObject { + id: _acCharger + property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Charger/Power"); unit: "W"} + } + +//////// added wind generator + QtObject { + id: _windGenerator + property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/WindGenerator/Power"); unit: "W"} + } + +//////// added fuel cell + QtObject { + id: _fuelCell + property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/FuelCell/Power"); unit: "W"} + } + + ObjectAcConnection { + id: _pvOnAcOut + bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") + } + + ObjectAcConnection { + id: _pvOnAcIn1 + bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") + } + + ObjectAcConnection { + id: _pvOnAcIn2 + bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") + } + + ObjectAcConnection { + id: _genset + splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 + bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") +//////// modified for VE.Direct inverter support + inverterSource: "/Ac/ActiveIn" + inverterService: sys.vebusPrefix != "" ? sys.vebusPrefix : root.inverterService + } + + VBusItem { + id: _acSource + bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") + } + + /* + * Single Multis that can be split-phase reports NrOfPhases of 2 + * When L2 is disconnected from the input the output L1 and L2 + * are shorted. This item indicates if L2 is passed through + * from AC-in to AC-out. + * 1: L2 is being passed through from AC-in to AC-out. + * 0: L1 and L2 are shorted together. + * invalid: The unit is configured in such way that its L2 output is not used. + */ + + VBusItem { + id: _splitPhaseL2Passthru + bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2Passthru") + } + + VBusItem { + id: _l2L1OutSummed + bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2L1OutSummed") + } + + + ObjectAcConnection { + id: _grid + splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 + bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") +//////// modified for VE.Direct inverter support + inverterSource: "/Ac/ActiveIn" + inverterService: sys.vebusPrefix != "" ? sys.vebusPrefix : root.inverterService + } + + ObjectAcConnection { + id: _activein + splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 + bindPrefix: Utils.path(systemPrefix, "/Ac/ActiveIn") +//////// modified for VE.Direct inverter support + inverterSource: "/Ac/ActiveIn" + inverterService: sys.vebusPrefix != "" ? sys.vebusPrefix : root.inverterService + } + + ObjectAcConnection { + id: _acLoad + l2AndL1OutSummed: _l2L1OutSummed.valid && (_l2L1OutSummed.value !== 0) + isAcOutput: true + bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") +//////// modified for VE.Direct inverter support + inverterSource: "/Ac/Out" + inverterService: sys.vebusPrefix != "" ? sys.vebusPrefix : root.inverterService + } + + ObjectAcConnection { + id: _acOutLoad + l2AndL1OutSummed: _l2L1OutSummed.valid && (_l2L1OutSummed.value !== 0) + isAcOutput: true + bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") + } + + ObjectAcConnection { + id: _acInLoad + splitPhaseL2PassthruDisabled:_splitPhaseL2Passthru.value === 0 + bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") + } + + ObjectAcConnection { + id: _acUnknown + } + + QtObject { + id: _vebusDc + /* + * property VBusItem power: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Power"); unit: "W"} + * DONE: can interface doesn't support this yet! TODO use it...? + */ + property VBusItem current: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Current"); unit: "A"} + property VBusItem voltage: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Voltage"); unit: "V"} + property VBusItem power: VBusItem { + value: _vebusDc.current.valid && _vebusDc.voltage.valid ? + _vebusDc.current.value * _vebusDc.voltage.value : + undefined + unit: "W" + } + } + + QtObject { + id: _battery + property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} + property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} + property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} + property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} + + // Get the battery charge state, see batteryState properties + property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} + } + + QtObject { + id: _dcSystem + property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} + } + +//////// add to support for adjustable watt / killowatt display switching + VBusItem { id: kwThresholdItem; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/KilowattThreshold") } + property int kilowattThreshold: kwThresholdItem.valid ? kwThresholdItem.value : 1000 + +//////// add to support VE.Direct inverters +//////// and grid/genset meters + Component.onCompleted: discoverServices() + + // When new service is found check if is a tank sensor + Connections + { + target: DBusServices + onDbusServiceFound: addService(service) + } + function addService(service) + { + switch (service.type) + { + case DBusService.DBUS_SERVICE_INVERTER: + if (inverterService === "") + inverterService = service.name; + break;; + case DBusService.DBUS_SERVICE_GRIDMETER: + if (gridMeterService === "") + gridMeterService = service.name; + break;; + case DBusService.DBUS_SERVICE_GENSET: + if (gensetService === "") + gensetService = service.name; + break;; + } + } + + // Check available services inverter services + function discoverServices() + { + inverterService = "" + gridMeterService = "" + gensetService = "" + for (var i = 0; i < DBusServices.count; i++) + addService(DBusServices.at(i)) + } +} diff --git a/FileSets/v3.40~8/HubData.qml.orig b/FileSets/v3.34/HubData.qml.orig similarity index 100% rename from FileSets/v3.40~8/HubData.qml.orig rename to FileSets/v3.34/HubData.qml.orig diff --git a/FileSets/v3.34/ObjectAcConnection.qml b/FileSets/v3.34/ObjectAcConnection.qml index cab7f2d4..bfe9c72c 120000 --- a/FileSets/v3.34/ObjectAcConnection.qml +++ b/FileSets/v3.34/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file +../v3.40/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.34/OverviewAcValuesEnhanced.qml b/FileSets/v3.34/OverviewAcValuesEnhanced.qml index 6d1e56b5..ba6bd7b3 120000 --- a/FileSets/v3.34/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.34/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.34/OverviewFlowComplex.qml b/FileSets/v3.34/OverviewFlowComplex.qml deleted file mode 120000 index 296ff4b1..00000000 --- a/FileSets/v3.34/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.34/OverviewFlowComplex.qml b/FileSets/v3.34/OverviewFlowComplex.qml new file mode 100644 index 00000000..c1fa7bb5 --- /dev/null +++ b/FileSets/v3.34/OverviewFlowComplex.qml @@ -0,0 +1,1549 @@ +///// Enhanced DC Coupled / AC Coupled Overview for GuiMods + +import QtQuick 1.1 +import "utils.js" as Utils +import com.victron.velib 1.0 +import "timeToGo.js" as TTG +import "enhancedFormat.js" as EnhFmt + +OverviewPage { + id: root + +////// GuiMods — DarkMode + property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } + property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 + + VBusItem { id: flowOverviewItem; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/FlowOverview") } + property bool dcCoupled: flowOverviewItem.valid && flowOverviewItem.value == 2 + + VBusItem { id: showInactiveTilesItem; bind: Utils.path(guiModsPrefix, "/ShowInactiveFlowTiles") } + property real disabledTileOpacity: (showInactiveTiles && showInactiveTilesItem.value === 1) ? 0.3 : 1 + property bool showInactiveTiles: showInactiveTilesItem.valid && showInactiveTilesItem.value >= 1 + property bool showInactiveFlow: showInactiveTilesItem.valid && showInactiveTilesItem.value == 3 + + property variant sys: theSystem + property string systemPrefix: "com.victronenergy.system" + property string settingsPrefix: "com.victronenergy.settings" + property color detailColor: "#b3b3b3" + property real laneWidth: (root.width - inOutTileWidth * 2 - battery.width) / 3 + + property int inOutTileHeight: (root.height - topOffset - bottomOffset - 3 * 5) / 4 + property int inOutTileWidth: 145 + VBusItem { id: timeToGo; bind: Utils.path(systemPrefix, "/Dc/Battery/TimeToGo") } + + VBusItem { id: vebusService; bind: Utils.path(systemPrefix, "/VebusService") } + property bool isMulti: vebusService.valid + property string veDirectInverterService: "" + property string inverterService: vebusService.valid ? vebusService.value : veDirectInverterService + + property bool combineAcLoads: dcCoupled || _combineAcLoads.valid && _combineAcLoads.value === 1 + property variant outputLoad: combineAcLoads ? sys.acLoad : sys.acOutLoad + + // for debug, ignore validity checks so all tiles and their flow lines will show + property bool showAllTiles: showInactiveTilesItem.valid && showInactiveTilesItem.value == 3 + + property bool hasInverter: false + property bool showInverter: hasInverter || inverterService != "" || showAllTiles + + property bool showLoadsOnOutput: showInverter || outputLoad.power.valid + property bool showAcInput: isMulti || sys.acInput.power.valid || showAllTiles + property bool hasLoadsOnInput: showAcInput && ! combineAcLoads && (! loadsOnInputItem.valid || loadsOnInputItem.value === 1) + property bool showLoadsOnInput: !dcCoupled && hasLoadsOnInput + property bool hasPvOnInput: sys.pvOnGrid.power.valid + property bool showPvOnInput: (!dcCoupled || !hasAcCharger) && hasPvOnInput + property bool hasPvOnOutput: sys.pvOnAcOut.power.valid + property bool showPvOnOutput: (!dcCoupled || !hasFuelCell) && hasPvOnOutput + property bool showPvCharger: sys.pvCharger.power.valid + property bool showDcSystem: (hasDcSystemItem.valid && hasDcSystemItem.value > 0) || showAllTiles + property bool showAlternator: (dcCoupled || !hasLoadsOnInput) && sys.alternator.power.valid + property bool hasFuelCell: sys.fuelCell.power.valid + property bool showFuelCell: (dcCoupled || !hasPvOnOutput) && hasFuelCell + property bool showWindGen: sys.windGenerator.power.valid + property bool hasAcCharger: sys.acCharger != undefined && sys.acCharger.power.valid + property bool showAcCharger: (dcCoupled || !hasPvOnInput) && hasAcCharger + + VBusItem { id: motorDrivePowerItem; bind: Utils.path(systemPrefix, "/Dc/MotorDrive/Power") } + property bool showMotorDrive: (dcCoupled || !hasLoadsOnInput) && ! showAlternator && motorDrivePowerItem.valid + + property int bottomOffset: showTanksTemps ? 45 : 5 + property int topOffset: showTanksTemps ? 1 : 5 + property string settingsBindPreffix: "com.victronenergy.settings" + property string pumpBindPreffix: "com.victronenergy.pump.startstop0" + property int numberOfTemps: 0 + + property int tankCount: showTanksEnable ? tankModel.rowCount : 0 + property int tempCount: showTempsEnable ? numberOfTemps : 0 + property int tankTempCount: tankCount + tempCount + property bool showTanks: showTanksEnable ? showStatusBar ? false : tankCount > 0 ? true : false : false + property bool showTemps: showTempsEnable ? showStatusBar ? false : tempCount > 0 ? true : false : false + property bool showTanksTemps: showTanks || showTemps + property int compactThreshold: 45 // height below this will be compacted vertically + property int batteryHeight: 91 + property bool compact: showTanks && showTemps && tankTempCount > 4 + property int tanksHeight: compact ? 22 : 45 + + VBusItem { id: ignoreAcInput1; bind: Utils.path(inverterService, "/Ac/State/IgnoreAcIn1") } + VBusItem { id: ignoreAcInput2; bind: Utils.path(inverterService, "/Ac/State/IgnoreAcIn2") } + VBusItem { id: acActiveInput; bind: Utils.path(inverterService, "/Ac/ActiveIn/ActiveInput") } + + property string guiModsPrefix: "com.victronenergy.settings/Settings/GuiMods" + VBusItem { id: showGaugesItem; bind: Utils.path(guiModsPrefix, "/ShowGauges") } + property bool showGauges: showGaugesItem.valid ? showGaugesItem.value === 1 ? true : false : false + VBusItem { id: showTanksItem; bind: Utils.path(guiModsPrefix, "/ShowEnhancedFlowOverviewTanks") } + property bool showTanksEnable: showTanksItem.valid ? showTanksItem.value === 1 ? true : false : false + VBusItem { id: showTempsItem; bind: Utils.path(guiModsPrefix, "/ShowEnhancedFlowOverviewTemps") } + property bool showTempsEnable: showTempsItem.valid ? showTempsItem.value === 1 ? true : false : false + + VBusItem { id: hasDcSystemItem; bind: "com.victronenergy.settings/Settings/SystemSetup/HasDcSystem" } + + VBusItem { id: timeFormatItem; bind: Utils.path(guiModsPrefix, "/TimeFormat") } + property string timeFormat: getTimeFormat () + + property double acInputFlow: showAcInput ? noNoise (sys.acInput.power) : 0 + property VBusItem vebusAcPower: VBusItem { bind: [sys.vebusPrefix, "/Ac/ActiveIn/P"] } + property double multiAcInputFlow: isMulti ? -noNoise (vebusAcPower) : 0 + property double pvOnInputFlow: showPvOnInput ? noNoise (sys.pvOnGrid.power) : 0 + property double loadsOnInputFlow: sys.acInLoad.power.valid ? -noNoise (sys.acInLoad.power) : 0 + property double pvInverterOnAcOutFlow: showPvOnOutput && sys.pvOnAcOut.power.valid ? noNoise (sys.pvOnAcOut.power) : 0 + property double acOutLoadFlow: sys.acOutLoad.power.valid ? -noNoise (sys.acOutLoad.power) : 0 + + property double pvChargerFlow: showPvCharger ? noNoise (sys.pvCharger.power) : 0 + property double dcSystemFlow: showDcSystem ? -noNoise (sys.dcSystem.power) : 0 + property double alternatorFlow: showAlternator ? noNoise (sys.alternator.power) : 0 + property double motorDriveFlow: showMotorDrive ? noNoise (motorDrivePowerItem) : 0 + property double inverterDcFlow: showInverter ? noNoise (sys.vebusDc.power) : 0 + property double batteryFlow: noNoise (sys.battery.power) + property double windGenFlow: noNoise (sys.windGenerator.power) + property double acChargerFlow: noNoise (sys.acCharger.power) + property double fuelCellFlow: noNoise (sys.fuelCell.power) + + VBusItem { id: showBatteryTempItem; bind: Utils.path(guiModsPrefix, "/ShowBatteryTempOnFlows") } + property bool showBatteryTemp: showBatteryTempItem.valid && showBatteryTempItem.value == 1 + + + function getTimeFormat () + { + if (!timeFormatItem.valid || timeFormatItem.value === 0) + return "" + else if (timeFormatItem.value === 2) + return "h:mm ap" + else + return "hh:mm" + } + + //Component.onCompleted: { discoverServices(); showHelp () } + onActiveChanged: + { + if (root.active) + { + discoverServices() + showHelp () + } + } + + title: dcCoupled ? qsTr("DC Coupled overview") : qsTr("AC Coupled overview") + + VBusItem { id: loadsOnInputItem; bind: "com.victronenergy.settings/Settings/GuiMods/ShowEnhancedFlowLoadsOnInput" } + VBusItem { id: _combineAcLoads; bind: "com.victronenergy.settings/Settings/GuiMods/EnhancedFlowCombineLoads" } + + OverviewBox { + id: acInBox + opacity: showAcInput ? 1 : disabledTileOpacity + visible: showAcInput || showInactiveTiles + width: inOutTileWidth + height: inOutTileHeight + title: + { + // input 1 is active + if (acActiveInput.value == 0) + { + if (ignoreAcInput1.valid && ignoreAcInput1.value == 1) + return qsTr ("AC In 1 Ignored") + else + return getAcSourceName(sys.acSource) + } + // input 2 is active + else if (acActiveInput.value == 1) + { + if (ignoreAcInput2.valid && ignoreAcInput2.value == 1) + return qsTr ("AC In 2 Ignored") + else + return getAcSourceName(sys.acSource) + } + else + return "no input" + } +////// GuiMods — DarkMode + titleColor: !darkMode ? "#E74c3c" : "#73261E" + color: !darkMode ? "#C0392B" : "#601C15" + anchors { + top: root.top; topMargin: topOffset + left: parent.left; leftMargin: 5 + } + values: TileText { + y: 13 + text: EnhFmt.formatVBusItem (sys.acInput.power) + font.pixelSize: 17 + visible: showAcInput + } + + MbIcon { + iconId: getAcSourceIcon(sys.acSource) + anchors { + bottom: parent.bottom + left: parent.left; leftMargin: 2 + } + opacity: 0.5 + } + PowerGauge + { + id: acInGauge + width: parent.width + height: 15 + anchors + { + top: parent.top; topMargin: 18 + horizontalCenter: parent.horizontalCenter + } + connection: sys.acInput + useInputCurrentLimit: true + maxForwardPowerParameter: "" + maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxFeedInPower" + visible: showGauges && showAcInput + } + DetailTarget { id: acInputTarget; detailsPage: "DetailAcInput.qml" } + } + + OverviewBox + { + id: pvInverterOnInput +////// GuiMods — DarkMode + titleColor: !darkMode ? "#F4B350" : "#7A5928" + color: !darkMode ? "#F39C12" : "#794E09" + title: qsTr("PV on Input") + width: inOutTileWidth + height: inOutTileHeight + visible: showPvOnInput || (showInactiveTiles && !dcCoupled) + opacity: showPvOnInput ? 1 : disabledTileOpacity + MbIcon + { + source: + { + var ids = sys.pvInvertersProductIds.text + if (ids.indexOf(0xA142) > -1) + return "image://theme/overview-fronius-logo" + return "" + } + visible: showPvOnInput + opacity: 0.3 + anchors { + bottom: parent.bottom + left: parent.left + margins: 2 + } + } + values: TileText { + y: 11 + text: EnhFmt.formatVBusItem (sys.pvOnGrid.power) + font.pixelSize: 17 + visible: showPvOnInput + } + anchors { + top: acInBox.bottom + topMargin: 5 + left: acInBox.left + } + PowerGauge + { + id: pvInverterOnInputGauge + width: parent.width + height: 15 + anchors + { + top: parent.top; topMargin: 18 + horizontalCenter: parent.horizontalCenter + } + connection: sys.pvOnGrid + maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvOnGridMaxPower" + visible: showGauges && showPvOnInput + } + DetailTarget { id: pvOnInputTarget; detailsPage: "DetailPvInverter.qml" } + } + + OverviewBox { + id: acLoadOnInputBox + title: qsTr("AC In Loads") +////// GuiMods — DarkMode + color: !darkMode ? "#27AE60" : "#135730" + titleColor: !darkMode ? "#2ECC71" : "#176638" + width: inOutTileWidth + height: inOutTileHeight + opacity: showLoadsOnInput ? 1 : disabledTileOpacity + visible: showLoadsOnInput || (showInactiveTiles && !dcCoupled) + anchors { + top: pvInverterOnInput.bottom + topMargin: 5 + left: acInBox.left + } + values: TileText { + y: 13 + text: EnhFmt.formatVBusItem (sys.acInLoad.power) + font.pixelSize: 17 + visible: showLoadsOnInput + } + PowerGauge + { + id: acInLoadGauge + width: parent.width + height: 15 + anchors + { + top: parent.top; topMargin: 18 + horizontalCenter: parent.horizontalCenter + } + connection: sys.acInLoad + maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputNonCriticalMaxPower" + visible: showGauges && showLoadsOnInput + } + DetailTarget { id: acLoadsOnInputTarget; detailsPage: "DetailLoadsOnInput.qml" } + } + + // check inverter to see if AC out 2 exists and hide noncritical loads if so + VBusItem { id: inverterOut2Item; bind: Utils.path(root.inverterService, "/Ac/Out/L2/V") } + + OverviewBox { + id: acOutputBox + title: combineAcLoads ? qsTr ("AC Loads") : qsTr ("AC Out Loads") +////// GuiMods — DarkMode + color: !darkMode ? "#27AE60" : "#135730" + titleColor: !darkMode ? "#2ECC71" : "#176638" + height: inOutTileHeight + width: inOutTileWidth + opacity: showLoadsOnOutput ? 1 : disabledTileOpacity + visible: showLoadsOnOutput || showInactiveTiles + anchors { + right: root.right; rightMargin: 5 + top: root.top; topMargin: topOffset + } + + values: TileText { + y: 13 + text: EnhFmt.formatVBusItem (outputLoad.power) + font.pixelSize: 17 + visible: showLoadsOnOutput + } + PowerGauge + { + id: acOutLoadGauge + width: parent.width + height: 15 + anchors + { + top: parent.top; topMargin: 18 + horizontalCenter: parent.horizontalCenter + } + connection: outputLoad + maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputMaxPower" + visible: showGauges && showLoadsOnOutput + } + DetailTarget { id: acLoadsOnOutputTarget; detailsPage: "DetailLoadsOnOutput.qml" } + } + Timer { + id: wallClock + running: timeFormat != "" + repeat: true + + interval: 1000 + triggeredOnStart: true + onTriggered: time = Qt.formatDateTime(new Date(), timeFormat) + + property string time + } + + MultiEnhancedGP { + id: multi + iconId: "overview-inverter-short" + opacity: showInverter ? 1 : disabledTileOpacity + visible: showInverter || showInactiveTiles + anchors { + horizontalCenter: parent.horizontalCenter + top: acInBox.top + } + inverterService: root.inverterService + PowerGaugeMulti + { + id: multiGauge + width: multi.width + height: 13 + anchors + { + top: parent.top; topMargin: 21 + horizontalCenter: multi.horizontalCenter + } + inverterService: root.inverterService + visible: showGauges && showInverter + } + DetailTarget { id: multiTarget; detailsPage: "DetailInverter.qml"; width: 60; height: 60 } + } + TileText + { + text: wallClock.time + color: showInverter || darkMode ? "white" : "black" + width: inOutTileWidth + wrapMode: Text.WordWrap + font.pixelSize: 16 + anchors + { + bottom: multi.bottom; bottomMargin: 1 + horizontalCenter: multi.horizontalCenter; + horizontalCenterOffset: multiDcConnector.active ? -10 : 0 + } + visible: wallClock.running + } + + Battery { + id: battery + width: 145 + height: 96 + anchors { + bottom: parent.bottom; bottomMargin: bottomOffset; + right: acOutputBox.left; rightMargin: laneWidth + } + soc: sys.battery.soc.valid ? sys.battery.soc.value : 0 +////// add battery current bar graph + PowerGaugeBattery + { + id: batteryBar + width: parent.width + height: 10 + anchors + { + top: parent.top; topMargin: 52 + horizontalCenter: parent.horizontalCenter + } + visible: showGauges + } + values: Column { + width: parent.width + + TileText { + text: sys.battery.soc.value === undefined ? "--" : sys.battery.soc.format (0) + font.pixelSize: 25 + } + TileText { + text: EnhFmt.formatVBusItem (sys.battery.power, "W") + } + TileText { + text: " " + font.pixelSize: 6 + } + TileText { + text: EnhFmt.formatVBusItem (sys.battery.voltage, "V ", 2) + + EnhFmt.formatVBusItem (sys.battery.current, "A") + } + TileText { + text: timeToGo.valid ? qsTr ("Remain: ") + TTG.formatTimeToGo (timeToGo) : qsTr (" ") + } + } + DetailTarget { id: batteryTarget; detailsPage: "DetailBattery.qml" } + } + + OverviewBox + { + id: pvInverterOnAcOut +////// GuiMods — DarkMode + titleColor: !darkMode ? "#F4B350" : "#7A5928" + color: !darkMode ? "#F39C12" : "#794E09" + title: qsTr("PV on Output") + width: inOutTileWidth + height: inOutTileHeight + opacity: showPvOnOutput ? 1 : disabledTileOpacity + visible: showPvOnOutput || (showInactiveTiles && !dcCoupled) + MbIcon + { + source: + { + var ids = sys.pvInvertersProductIds.text + if (ids.indexOf(0xA142) > -1) + return "image://theme/overview-fronius-logo" + return "" + } + visible: showPvOnOutput + opacity: 0.3 + anchors { + bottom: parent.bottom + right: parent.right + margins: 2 + } + } + + values: TileText { + y: 11 + text: EnhFmt.formatVBusItem (sys.pvOnAcOut.power) + font.pixelSize: 17 + visible: showPvOnOutput + } + anchors { + top: acOutputBox.bottom + topMargin: 5 + right: acOutputBox.right + } + PowerGauge + { + id: pvInverterOnAcOutGauge + width: parent.width + height: 15 + anchors + { + top: parent.top; topMargin: 18 + horizontalCenter: parent.horizontalCenter + } + connection: sys.pvOnAcOut + maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvOnOutputMaxPower" + visible: showGauges && showPvOnOutput + } + DetailTarget { id: pvOnOutputTarget; detailsPage: "DetailPvInverter.qml" } + } + + OverviewBox + { + id: acChargerBox + title: qsTr ("AC Charger") +////// GuiMods — DarkMode + color: !darkMode ? "#157894" : "#0a3c4a" + titleColor: !darkMode ? "#419FB9" : "#204f5c" + height: inOutTileHeight + width: inOutTileWidth + opacity: showAcCharger ? 1 : disabledTileOpacity + visible: showAcCharger || (showInactiveTiles && dcCoupled) + anchors + { + left: root.left; leftMargin: 5 + bottom: alternatorBox.top; bottomMargin: 5 + } + values: TileText { + text: EnhFmt.formatVBusItem (sys.acCharger.power) + font.pixelSize: 17 + visible: showAcCharger + anchors + { + bottom: parent.bottom; bottomMargin: 0 + horizontalCenter: parent.horizontalCenter + } + } + PowerGauge + { + id: acChargerGauge + width: parent.width + height: 10 + anchors + { + top: parent.top; topMargin: 20 + horizontalCenter: parent.horizontalCenter + } + connection: sys.acCharger + reversePower: true + maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxAcChargerPower" + visible: showGauges && showAcCharger + } + DetailTarget { id: acChargerTarget; detailsPage: "DetailAcCharger.qml" } + } + + OverviewBox + { + id: alternatorBox + title: qsTr ("Alternator") +////// GuiMods — DarkMode + color: !darkMode ? "#157894" : "#0a3c4a" + titleColor: !darkMode ? "#419FB9" : "#204f5c" + height: inOutTileHeight + width: inOutTileWidth + opacity: showAlternator ? 1 : disabledTileOpacity + visible: showAlternator || (showInactiveTiles && dcCoupled) + anchors + { + left: root.left; leftMargin: 5 + bottom: pvChargerBox.top; bottomMargin: 5 + } + values: TileText { + text: EnhFmt.formatVBusItem (sys.alternator.power) + font.pixelSize: 17 + visible: showAlternator + anchors + { + bottom: parent.bottom; bottomMargin: 0 + horizontalCenter: parent.horizontalCenter + } + } + PowerGauge + { + id: alternatorGauge + width: parent.width + height: 10 + anchors + { + top: parent.top; topMargin: 20 + horizontalCenter: parent.horizontalCenter + } + connection: sys.alternator + maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxAlternatorPower" + visible: showGauges && showAlternator + } + DetailTarget { id: alternatorTarget; detailsPage: "DetailAlternator.qml" } + } + + OverviewBox + { + id: motorDriveBox + title: qsTr ("Motor Drive") +////// GuiMods — DarkMode + color: !darkMode ? "#157894" : "#0a3c4a" + titleColor: !darkMode ? "#419FB9" : "#204f5c" + height: inOutTileHeight + width: inOutTileWidth + opacity: showMotorDrive ? 1 : disabledTileOpacity + visible: showMotorDrive + anchors + { + left: root.left; leftMargin: 5 + bottom: pvChargerBox.top; bottomMargin: 5 + } + values: TileText { + text: EnhFmt.formatVBusItem (motorDrivePowerItem) + font.pixelSize: 17 + visible: showMotorDrive + anchors + { + bottom: parent.bottom; bottomMargin: 0 + horizontalCenter: parent.horizontalCenter + } + } + PowerGauge + { + id: motorDriveGauge + width: parent.width + height: 10 + anchors + { + top: parent.top; topMargin: 20 + horizontalCenter: parent.horizontalCenter + } + connection: motorDrivePowerItem + maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxMotorDriveLoad" + maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxMotorDriveCharge" + visible: showGauges && showMotorDrive + showLabels: true + } + DetailTarget { id: motorDriveTarget; detailsPage: "DetailMotorDrive.qml" } + } + + VBusItem { id: dcSystemNameItem; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/CustomDcSystemName") } + + OverviewBox { + id: dcSystemBox + width: inOutTileWidth + height: inOutTileHeight + opacity: showDcSystem ? 1 : disabledTileOpacity + visible: showDcSystem || showInactiveTiles + title: dcSystemNameItem.valid && dcSystemNameItem.value != "" ? dcSystemNameItem.value : qsTr ("DC System") + anchors + { + right: root.right; rightMargin: 5 + bottom: parent.bottom + bottomMargin: bottomOffset + } + values: TileText { + text: EnhFmt.formatVBusItem (sys.dcSystem.power) + font.pixelSize: 17 + visible: showDcSystem + anchors + { + bottom: parent.bottom; bottomMargin: 0 + horizontalCenter: parent.horizontalCenter + } + } + PowerGauge + { + id: dcSystemGauge + width: parent.width + height: 10 + anchors + { + top: parent.top; topMargin: 20 + horizontalCenter: parent.horizontalCenter + } + connection: sys.dcSystem + maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/DcSystemMaxLoad" + maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/DcSystemMaxCharge" + showLabels: true + visible: showGauges && showDcSystem + } + DetailTarget { id: dcSystemTarget; detailsPage: "DetailDcSystem.qml" } + } + + OverviewBox { + id: fuelCellBox +////// GuiMods — DarkMode + color: !darkMode ? "#157894" : "#0a3c4a" + titleColor: !darkMode ? "#419FB9" : "#204f5c" + width: inOutTileWidth + height: inOutTileHeight + opacity: showFuelCell ? 1 : disabledTileOpacity + visible: showFuelCell || (showInactiveTiles && dcCoupled) + title: qsTr ("Fuel Cell") + anchors { + left: windGenBox.left + bottom: windGenBox.top; bottomMargin: 5 + } + values: TileText { + text: EnhFmt.formatVBusItem (sys.fuelCell.power) + font.pixelSize: 17 + visible: fuelCellBox.visible + anchors + { + bottom: parent.bottom; bottomMargin: 0 + horizontalCenter: parent.horizontalCenter + } + } + PowerGauge + { + id: fuelCellGauge + width: parent.width + height: 10 + anchors + { + top: parent.top; topMargin: 20 + horizontalCenter: parent.horizontalCenter + } + connection: sys.fuelCell + maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxFuelCellPower" + visible: showGauges && fuelCellBox.visible + } + DetailTarget { id: fuelCellTarget; detailsPage: "DetailFuelCell.qml" } + } + + OverviewBox { + id: windGenBox +////// GuiMods — DarkMode + color: !darkMode ? "#157894" : "#0a3c4a" + titleColor: !darkMode ? "#419FB9" : "#204f5c" + width: inOutTileWidth + height: inOutTileHeight + opacity: showWindGen ? 1 : disabledTileOpacity + visible: showWindGen || showInactiveTiles + title: qsTr ("Wind Generator") + anchors + { + right: dcSystemBox.right + bottom: dcSystemBox.top; bottomMargin: 5 + } + values: TileText { + text: EnhFmt.formatVBusItem (sys.windGenerator.power) + font.pixelSize: 17 + visible: showWindGen + anchors + { + bottom: parent.bottom; bottomMargin: 0 + horizontalCenter: parent.horizontalCenter + } + } + PowerGauge + { + id: windGenGauge + width: parent.width + height: 10 + anchors + { + top: parent.top; topMargin: 20 + horizontalCenter: parent.horizontalCenter + } + connection: sys.windGenerator + maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxWindGenPower" + visible: showGauges && showWindGen + } + DetailTarget { id: windGenTarget; detailsPage: "DetailWindGen.qml" } + } + + OverviewBox { + id: pvChargerBox + title: qsTr("PV Charger") +////// GuiMods — DarkMode + titleColor: !darkMode ? "#F4B350" : "#7A5928" + color: !darkMode ? "#F39C12" : "#794E09" + width: inOutTileWidth + height: inOutTileHeight + opacity: showPvCharger ? 1 : disabledTileOpacity + visible: showPvCharger || showInactiveTiles + anchors + { + left: root.left; leftMargin: 5 + bottom: parent.bottom; bottomMargin: bottomOffset + } + values: TileText { + y: 12 + text: EnhFmt.formatVBusItem (sys.pvCharger.power) + font.pixelSize: 17 + } + // moved sun icon here from OverviewSolarChager so it can be put below text, etc + MbIcon { + iconId: "overview-sun" + anchors { + bottom: parent.bottom + right: parent.right; rightMargin: 2 + } + opacity: 0.5 + } + + PowerGauge + { + id: pvChargerGauge + width: parent.width + height: 10 + anchors + { + top: parent.top; topMargin: 20 + horizontalCenter: parent.horizontalCenter + } + connection: sys.pvCharger + maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvChargerMaxPower" + visible: showGauges && showPvCharger + } + DetailTarget { id: pvChargerTarget; detailsPage: "DetailPvCharger.qml" } + } + + // move ESS reason to Battery details page + + // invisible item to connection all AC input connections to.. + Item { + id: acInBus + width: laneWidth + anchors { + left: acInBox.right; + top: multi.top; topMargin: multi.height / 2 + 10 + bottom: pvInverterOnInput.bottom; bottomMargin: 8 + } + } + Item { + id: dcLaneLeft + width: laneWidth + anchors { + right: battery.left; + top: multi.top; topMargin: multi.height / 2 + 10 + bottom: dcSystemBox.bottom; bottomMargin: 8 + } + } + Item { + id: dcLaneRight + width: laneWidth * 0.8 + anchors { + left: battery.right; + + top: dcLaneLeft.top + bottom: dcLaneLeft.bottom + } + } + Item { + id: dcLaneTop + anchors { + left: battery.left + right: battery.right + top: multi.bottom; + bottom: battery.top + } + } + + OverviewConnection { + id: multiAcInFlow + ballCount: 1 + path: straight + active: root.active && ( showAcInput || showPvOnInput || showLoadsOnInput ) + value: -Utils.sign (multiAcInputFlow) + startPointVisible: false + endPointVisible: true + + anchors { + left: acInBus.horizontalCenter; leftMargin: -0.5 + right: multi.left; rightMargin: -8 + bottom: acInBus.top + } + } + + // AC source power flow + OverviewConnection { + id: acSource + ballCount: 1 + path: corner + active: root.active && showAcInput + value: Utils.sign (acInputFlow) + startPointVisible: true + endPointVisible: false + + anchors { + left: acInBox.right; leftMargin: -8 + right: acInBus.horizontalCenter + top: acInBox.bottom; topMargin: -8 + bottom: acInBus.top + } + } + + // Coupled AC sources + OverviewConnection { + id: coupledAcConnection + ballCount: 1 + path: straight + active: root.active && ((showLoadsOnInput && showPvOnInput) || (!dcCoupled && showInactiveFlow)) + value: -Utils.sign (pvOnInputFlow + loadsOnInputFlow) + startPointVisible: false + endPointVisible: false + + anchors { + right: acInBus.horizontalCenter + rightMargin: 0.5 // makes this line up with others + top: acInBus.top + bottom: acInBus.bottom + } + } + + // Grid inverter power flow + OverviewConnection { + id: pvInverterOnInputConnection + ballCount: showLoadsOnInput ? 1 : 2 + path: showLoadsOnInput || (!dcCoupled && showInactiveFlow) ? straight : corner + active: root.active && (showPvOnInput || (!dcCoupled && showInactiveFlow)) + value: Utils.sign (pvOnInputFlow) + startPointVisible: true + endPointVisible: false + + anchors { + left: pvInverterOnInput.right; leftMargin: -8 + right: acInBus.horizontalCenter + top: pvInverterOnInput.bottom; topMargin: -8 + bottom: showLoadsOnInput || (!dcCoupled && showInactiveFlow) ? pvInverterOnInput.bottom : multiAcInFlow.verticalCenter + bottomMargin: showLoadsOnInput || (!dcCoupled && showInactiveFlow) ? 8 : 0 + } + } + + // power to loads on input + OverviewConnection { + id: loadsOnInput + ballCount: 1 + path: corner + active: root.active && (showLoadsOnInput || (!dcCoupled && showInactiveFlow)) + value: Utils.sign (loadsOnInputFlow) + startPointVisible: true + endPointVisible: false + + anchors { + left: acLoadOnInputBox.right; leftMargin: -8 + right: acInBus.horizontalCenter + rightMargin: 0.5 // makes this line up with others + top: acLoadOnInputBox.top; topMargin: 8 + bottom: showPvOnInput|| (!dcCoupled && showInactiveFlow) ? acInBus.bottom : acInBus.top + } + } + + // invisible item to connection all AC output connections to.. + Item { + id: acOutNode + height: 6 + anchors { + left: multi.right + right: acOutputBox.left + verticalCenter: acInBus.top + } + } + + // AC out connection + OverviewConnection { + id: multiAcOutConnection + + ballCount: 1 + path: straight + active: root.active && ((showLoadsOnOutput || showPvOnOutput) || (!dcCoupled && showInactiveFlow)) + value: -Utils.sign (acOutLoadFlow + pvInverterOnAcOutFlow) + endPointVisible: false + + anchors { + left: multi.right; leftMargin: -8 + right: acOutNode.horizontalCenter + top: acOutNode.verticalCenter + } + } + + // loads on output conenction + OverviewConnection { + id: acOutBoxConnection + + ballCount: 1 + path: corner + active: root.active && (showLoadsOnOutput || (!dcCoupled && showInactiveFlow)) + value: Utils.sign (acOutLoadFlow) + startPointVisible: true + endPointVisible: false + + anchors { + right: acOutNode.horizontalCenter + rightMargin: -0.5 // makes this line up with others + left: acOutputBox.left; leftMargin: 8 + top: acOutputBox.bottom; topMargin: -8 + bottom: acOutNode.verticalCenter + } + } + + // PV Inverter on AC out connection + OverviewConnection { + id: pvOnAcOutConnection + + ballCount: 2 + path: corner + active: root.active && (showPvOnOutput || (!dcCoupled && showInactiveFlow)) + value: Utils.sign (pvInverterOnAcOutFlow) + startPointVisible: true + endPointVisible: false + + anchors { + left: pvInverterOnAcOut.left; leftMargin: 8 + top: pvInverterOnAcOut.bottom; topMargin: -8 + right: acOutNode.horizontalCenter + bottom: acOutNode.verticalCenter + } + } + + // invisible summing point for all DC connections + Item { + id: dcNode + height: 10 + width: 10 + anchors { + horizontalCenter: batteryDcConnector.horizontalCenter + verticalCenter: dcLaneTop.verticalCenter + } + } + + // DC bus segments + OverviewConnection { + id: dcBus1 + ballCount: 1 + path: straight + active: root.active && ((showAlternator || showMotorDrive || showPvCharger) || (dcCoupled && showInactiveFlow)) + value: -Utils.sign (alternatorFlow + motorDriveFlow + pvChargerFlow) + startPointVisible: false + endPointVisible: false + + anchors { + right: dcLaneLeft.horizontalCenter + rightMargin: 0.5 // makes this line up with others + bottom: alternatorConnection.verticalCenter + top: dcLaneTop.verticalCenter + } + } + OverviewConnection { + id: dcBus2 + ballCount: 1 + path: straight + active: root.active && ((showAlternator || showMotorDrive || showAcCharger || showPvCharger) || (dcCoupled && showInactiveFlow)) + value: Utils.sign (alternatorFlow + motorDriveFlow + pvChargerFlow + acChargerFlow) + startPointVisible: false + endPointVisible: false + + anchors { + left: dcLaneLeft.horizontalCenter + right: dcBus3.left + bottom: dcLaneTop.verticalCenter + } + } + OverviewConnection { + id: dcBus3 + ballCount: 2 + path: straight + active: root.active && ((showInverter || showFuelCell || showWindGen || showDcSystem) || showInactiveFlow) + value: -Utils.sign (inverterDcFlow + fuelCellFlow + windGenFlow + dcSystemFlow) + startPointVisible: false + endPointVisible: false + + anchors { + left: batteryDcConnector.horizontalCenter + right: multiDcConnector.horizontalCenter + bottom: dcLaneTop.verticalCenter + } + } + OverviewConnection { + id: dcBus4 + ballCount: 1 + path: straight + active: root.active && ((showFuelCell || showWindGen || showDcSystem) || showInactiveFlow) + value: -Utils.sign (fuelCellFlow + windGenFlow + dcSystemFlow) + startPointVisible: false + endPointVisible: false + + anchors { + left: multiDcConnector.horizontalCenter + right: dcLaneRight.horizontalCenter + bottom: dcLaneTop.verticalCenter + } + } + OverviewConnection { + id: dcBus5 + ballCount: 1 + path: straight + active: root.active && ((showWindGen || showDcSystem) || showInactiveFlow) + value: -Utils.sign (windGenFlow + dcSystemFlow) + startPointVisible: false + endPointVisible: false + + anchors { + left: dcLaneRight.horizontalCenter + top: dcLaneTop.verticalCenter + bottom: windGenConnection.verticalCenter + } + } + + + // DC connection multi to bus + OverviewConnection { + id: multiDcConnector + ballCount: 1 + path: straight + active: root.active && (showInverter || showInactiveFlow) + value: Utils.sign (inverterDcFlow) + startPointVisible: true + endPointVisible: false + + anchors { + right: multi.right; rightMargin: 25 + top: multi.bottom; topMargin: -8 + bottom: dcLaneTop.verticalCenter + } + } + // DC connection battery to bus + OverviewConnection { + id: batteryDcConnector + ballCount: 1 + path: straight + active: root.active && ((sys.battery.soc.valid || showDcSystem) || (dcCoupled && showInactiveFlow)) + value: -Utils.sign (batteryFlow) + startPointVisible: true + endPointVisible: false + + anchors { + left: battery.left; leftMargin: 30 + top: battery.top; topMargin: 15 + bottom: dcLaneTop.verticalCenter + } + } + + // AC charger to DC bus + OverviewConnection + { + id: acChargerConnection + ballCount: 1 + path: corner + active: root.active && (showAcCharger || (dcCoupled && showInactiveFlow)) + value: Utils.sign (acChargerFlow) + startPointVisible: true + endPointVisible: false + anchors + { + left: acChargerBox.right; leftMargin: -8 + top: acChargerBox.bottom; topMargin: -8 + right: dcLaneLeft.horizontalCenter + bottom: dcLaneTop.verticalCenter + } + } + + // Alternator to bus + OverviewConnection + { + id: alternatorConnection + ballCount: 1 + path: straight + active: root.active && (showAlternator || showMotorDrive || (dcCoupled && showInactiveFlow)) + value: Utils.sign (alternatorFlow + motorDriveFlow) + startPointVisible: true + endPointVisible: false + anchors + { + left: alternatorBox.right; leftMargin: -8 + top: alternatorBox.bottom; topMargin: -8 + right: dcLaneLeft.horizontalCenter + } + } + + // DC system to DC bus + OverviewConnection + { + id: dcSystemConnection + ballCount: 2 + path: corner + active: root.active && (showDcSystem || (dcCoupled && showInactiveFlow)) + value: Utils.sign (dcSystemFlow) + endPointVisible: false + anchors + { + left: dcSystemBox.left; leftMargin: 8 + top: dcSystemBox.bottom; topMargin: -8 + right: dcLaneRight.horizontalCenter + rightMargin: -0.5 // makes this line up with others + bottom: windGenConnection.verticalCenter + } + } + + + // other DC connection to DC right bus + OverviewConnection + { + id: fuelCellConnection + ballCount: 2 + path: corner + active: root.active && (showFuelCell || (dcCoupled && showInactiveFlow)) + value: Utils.sign (fuelCellFlow) + startPointVisible: true + endPointVisible: false + anchors + { + left: fuelCellBox.left; leftMargin: 8 + top: fuelCellBox.bottom; topMargin: -8 + right: dcLaneRight.horizontalCenter + rightMargin: -0.5 // makes this line up with others + bottom: dcLaneTop.verticalCenter + } + } + + // Wind Gen DC right bus + OverviewConnection + { + id: windGenConnection + ballCount: 1 + path: straight + active: root.active && (showWindGen || showInactiveFlow) + value: Utils.sign (windGenFlow) + startPointVisible: true + endPointVisible: false + anchors + { + left: windGenBox.left; leftMargin: 8 + top: windGenBox.bottom; topMargin: -8 + right: dcLaneRight.horizontalCenter + } + } + + // Solar charger to DC right bus + OverviewConnection + { + id: pvChargerConnection + ballCount: 2 + path: corner + active: root.active && (showPvCharger || showInactiveFlow) + value: Utils.sign (pvChargerFlow) + startPointVisible: true + endPointVisible: false + anchors + { + left: pvChargerBox.right; leftMargin: -8 + top: pvChargerBox.bottom; topMargin: -8 + right: dcLaneLeft.horizontalCenter + bottom: alternatorConnection.top + } + } + + // Synchronise tank name text scroll start + Timer + { + id: scrollTimer + interval: 15000 + repeat: true + running: root.active + } + + ListView + { + id: tanksColum + + visible: showTanks + width: compact ? root.width : root.width * tankCount / tankTempCount + property int tileWidth: width / Math.min (count, 5.2) + height: root.tanksHeight + anchors + { + bottom: root.bottom + left: root.left + } + + // flickable list if more than will fit across bottom of screen + interactive: count > 4 ? true : false + orientation: ListView.Horizontal + + model: TankModel { id: tankModel } + delegate: TileTankEnhanced { + // Without an intermediate assignment this will trigger a binding loop warning. + property variant theService: DBusServices.get(buddy.id) + service: theService + width: tanksColum.tileWidth + height: root.tanksHeight + pumpBindPrefix: root.pumpBindPreffix + compact: root.compact + Connections { + target: scrollTimer + onTriggered: doScroll() + } + } + Tile { + title: qsTr("tanks") + anchors.fill: parent + values: TileText { + text: qsTr("") + width: parent.width + wrapMode: Text.WordWrap + } + z: -1 + } + } + + ListView + { + id: tempsColumn + + visible: showTemps + width: compact ? root.width : root.width * tempCount / tankTempCount + property int tileWidth: width / Math.min (count, 5.2) + height: root.tanksHeight + anchors + { + bottom: root.bottom + bottomMargin: compact ? root.tanksHeight : 0 + right: root.right + } + + // make list flickable if more tiles than will fit completely + interactive: count > 4 ? true : false + orientation: ListView.Horizontal + + model: tempsModel + delegate: TileTemp + { + width: tempsColumn.tileWidth + height: tempsColumn.height + compact: root.compact + Connections + { + target: scrollTimer + onTriggered: doScroll() + } + } + Tile + { + title: qsTr("TEMPS") + anchors.fill: parent + values: TileText + { + text: qsTr("") + width: parent.width + wrapMode: Text.WordWrap + } + z: -1 + } + } + ListModel { id: tempsModel } + + // When new service is found check if is a tank sensor + Connections + { + target: DBusServices + onDbusServiceFound: addService(service) + } + + // hack to get value(s) from within a loop inside a function when service is changing + property string tempServiceName: "" + property VBusItem temperatureItem: VBusItem { bind: Utils.path(tempServiceName, "/Dc/0/Temperature") } + + function addService(service) + { + switch (service.type) + { + case DBusService.DBUS_SERVICE_TEMPERATURE_SENSOR: + numberOfTemps++ + tempsModel.append({serviceName: service.name}) + break;; + + case DBusService.DBUS_SERVICE_MULTI: + hasInverter = true + root.tempServiceName = service.name + if (temperatureItem.valid && showBatteryTemp) + { + numberOfTemps++ + tempsModel.append({serviceName: service.name}) + } + break;; + case DBusService.DBUS_SERVICE_MULTI_RS: + hasInverter = true + break;; + case DBusService.DBUS_SERVICE_INVERTER: + hasInverter = true + if (veDirectInverterService == "") + veDirectInverterService = service.name; + break;; + case DBusService.DBUS_SERVICE_BATTERY: + root.tempServiceName = service.name + if (temperatureItem.valid && showBatteryTemp) + { + numberOfTemps++ + tempsModel.append({serviceName: service.name}) + } + break;; + } + } + + // Detect available services of interest + function discoverServices() + { + numberOfTemps = 0 + tempsModel.clear() + veDirectInverterService = "" + hasInverter = false + for (var i = 0; i < DBusServices.count; i++) + { + addService(DBusServices.at(i)) + } + } + VBusItem { id: incomingTankName; + bind: Utils.path(settingsBindPreffix, "/Settings/Devices/TankRepeater/IncomingTankService") } + + // help message shown when menu is first drawn + Rectangle + { + id: helpBox + color: "white" + width: multi.width + height: 32 + opacity: 0.7 + anchors + { + verticalCenter: dcLaneTop.verticalCenter + horizontalCenter: root.horizontalCenter + } + visible: false + } + TileText + { + text: qsTr ( "Tap tile center for detail at any time" ) + color: "black" + anchors.fill: helpBox + wrapMode: Text.WordWrap + font.pixelSize: 12 + visible: helpBox.visible + } + + //// hard key handler + // used to press buttons when touch isn't available + // UP and DOWN buttons cycle through the list of touch areas + // "space" button is used to simulate a touch on the area + // target must be highlighted so that other uses of "space" + // will still occur + + // list of all details touchable areas + property variant targetList: + [ + acInputTarget, pvOnInputTarget, acLoadsOnInputTarget, + acChargerTarget, alternatorTarget, motorDriveTarget, pvChargerTarget, + multiTarget, batteryTarget, + acLoadsOnOutputTarget, pvOnOutputTarget, fuelCellTarget, windGenTarget, dcSystemTarget + ] + + property int selectedTarget: 0 + + Timer + { + id: targetTimer + interval: 5000 + repeat: false + running: false + onTriggered: { hideAllTargets () } + } + + Keys.forwardTo: [keyHandler] + Item + { + id: keyHandler + Keys.onUpPressed: + { + nextTarget (-1) + event.accepted = true + } + + Keys.onDownPressed: + { + nextTarget (+1) + event.accepted = true + } + Keys.onSpacePressed: + { + if (targetTimer.running) + { + var foo // hack to make clicked() work + bar.clicked (foo) + event.accepted = true + } + else + event.accepted = false + } + } + // hack to make clicked() work + property variant bar: targetList[selectedTarget] + + function nextTarget (increment) + { + // make one pass through all possible targets to find an enabled one + // if found, that's the new selectedTarget, + // if not selectedTarget does not change + var newIndex = selectedTarget + for (var i = 0; i < targetList.length; i++) + { + if (( ! targetTimer.running || helpBox.visible) && targetList[newIndex].enabled) + { + highlightSelectedTarget () + return + } + newIndex += increment + if (newIndex >= targetList.length) + newIndex = 0 + else if (newIndex < 0) + newIndex = targetList.length - 1 + if (targetList[newIndex].enabled) + { + selectedTarget = newIndex + highlightSelectedTarget () + break + } + } + } + + function showHelp () + { + for (var i = 0; i < targetList.length; i++) + { + targetList[i].targetVisible = true + } + helpBox.visible = true + targetTimer.restart () + } + function hideAllTargets () + { + for (var i = 0; i < targetList.length; i++) + { + targetList[i].targetVisible = false + } + helpBox.visible = false + } + function highlightSelectedTarget () + { + for (var i = 0; i < targetList.length; i++) + { + if (targetList[i] == targetList[selectedTarget]) + targetList[i].targetVisible = true + else + targetList[i].targetVisible = false + } + helpBox.visible = false + targetTimer.restart () + } +} diff --git a/FileSets/v3.40~8/OverviewFlowComplex.qml.orig b/FileSets/v3.34/OverviewFlowComplex.qml.orig similarity index 100% rename from FileSets/v3.40~8/OverviewFlowComplex.qml.orig rename to FileSets/v3.34/OverviewFlowComplex.qml.orig diff --git a/FileSets/v3.34/OverviewGeneratorEnhanced.qml b/FileSets/v3.34/OverviewGeneratorEnhanced.qml deleted file mode 100644 index 0c189315..00000000 --- a/FileSets/v3.34/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1,547 +0,0 @@ -// GuiMods enhanced generator overview -// This file has been modified to: -// add Auto Start display and control -// show voltage, current, frequency, and power gauge in AC input tile -// show the generator running state inside the icon top left -// show a warning when the generator digital input and expected generator state disagree -// move current run time to separate tile - -import QtQuick 1.1 -import "utils.js" as Utils -import "enhancedFormat.js" as EnhFmt - -OverviewPage { - id: root - - property string settingsBindPrefix - property string bindPrefix - property variant sys: theSystem -//////// added to show alternator in place of inactive genset - property string guiModsPrefix: "com.victronenergy.settings/Settings/GuiMods" - VBusItem { id: replaceAcInItem; bind: Utils.path(guiModsPrefix, "/ReplaceInactiveAcIn") } - property bool hasAlternator: sys.alternator.power.valid - property bool showAlternator: replaceAcInItem.valid && replaceAcInItem.value == 1 && hasAlternator && ! sys.genset.power.valid - property bool showAcIn: ! showAlternator - - property string icon: "overview-generator" - property VBusItem state: VBusItem { bind: Utils.path(bindPrefix, "/State") } - property VBusItem error: VBusItem { bind: Utils.path(bindPrefix, "/Error") } - property VBusItem runningTime: VBusItem { bind: Utils.path(bindPrefix, "/Runtime") } - property VBusItem runningBy: VBusItem { bind: Utils.path(bindPrefix, "/RunningByConditionCode") } - VBusItem { id: totalAcummulatedTime; bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") } - VBusItem { id: totalAccumulatedTimeOffset; bind: Utils.path(settingsBindPrefix, "/AccumulatedTotalOffset") } - property VBusItem quietHours: VBusItem { bind: Utils.path(bindPrefix, "/QuietHours") } - property VBusItem testRunDuration: VBusItem { bind: Utils.path(settingsBindPrefix, "/TestRun/Duration") } - property VBusItem nextTestRun: VBusItem { bind: Utils.path(bindPrefix, "/NextTestRun") } - property VBusItem skipTestRun: VBusItem { bind: Utils.path(bindPrefix, "/SkipTestRun") } - - property VBusItem todayRuntime: VBusItem { bind: Utils.path(bindPrefix, "/TodayRuntime") } - property VBusItem manualTimer: VBusItem { bind: Utils.path(bindPrefix, "/ManualStartTimer") } - property VBusItem autoStart: VBusItem { bind: Utils.path(settingsBindPrefix, "/AutoStartEnabled") } - - property bool errors: ! state.valid || state.value == 10 - - property VBusItem externalOverrideItem: VBusItem { bind: Utils.path(bindPrefix, "/ExternalOverride") } - property bool externalOverride: externalOverrideItem.valid && externalOverrideItem.value == 1 && ! errors - property VBusItem runningState: VBusItem { bind: Utils.path(bindPrefix, "/GeneratorRunningState") } - - VBusItem { id: showGaugesItem; bind: Utils.path(guiModsPrefix, "/ShowGauges") } - property bool showGauges: showGaugesItem.valid ? showGaugesItem.value === 1 ? true : false : false - property bool editMode: autoRunTile.editMode || manualTile.editMode - - VBusItem { id: serviceInterval; bind: Utils.path(settingsBindPrefix, "/ServiceInterval") } - VBusItem { id: serviceCounterItem; bind: Utils.path(bindPrefix, "/ServiceCounter") } - property bool showServiceInfo: serviceCounterItem.valid && serviceInterval.valid && serviceInterval.value > 0 - property bool serviceOverdue: showServiceInfo && serviceCounterItem.value < 0 - -//////// add to display AC input ignored - VBusItem { id: ignoreAcInput1; bind: Utils.path(sys.vebusPrefix, "/Ac/State/IgnoreAcIn1") } - VBusItem { id: ignoreAcInput2; bind: Utils.path(sys.vebusPrefix, "/Ac/State/IgnoreAcIn2") } - VBusItem { id: acActiveInput; bind: Utils.path(sys.vebusPrefix, "/Ac/ActiveIn/ActiveInput") } - VBusItem { id: ac1source; bind: Utils.path("com.victronenergy.settings", "/Settings/SystemSetup/AcInput1") } - VBusItem { id: ac2source; bind: Utils.path("com.victronenergy.settings", "/Settings/SystemSetup/AcInput2") } - - title: qsTr("Generator") - - property bool autoStartSelected: false - - Component.onCompleted: - { - setFocusManual () - } - - Keys.forwardTo: [keyHandler] - Item - { - id: keyHandler - Keys.onUpPressed: - { - setFocusAuto () - event.accepted = true - } - Keys.onDownPressed: - { - setFocusManual () - event.accepted = true - } - // prevents page changes while timers are running - //// Keys.onReturnPressed: event.accepted = manualTile.startCountdown || autoRunTile.startCountdown - //// Keys.onEscapePressed: event.accepted = manualTile.startCountdown || autoRunTile.startCountdown - } - - function setFocusManual () - { - autoStartSelected = false - } - - function setFocusAuto () - { - autoStartSelected = true - } - - function formatTime (time) - { - if (time >= 3600) - return (time / 3600).toFixed(0) + " h" - else - return (time / 60).toFixed(0) + " m" - } - - function stateDescription() - { - if (!state.valid) - return qsTr ("") - else if (state.value === 10) - { - switch(error.value) - { - case 1: - return qsTr("Error: Remote switch control disabled") - case 2: - return qsTr("Error: Generator in fault condition") - case 3: - return qsTr("Error: Generator not detected at AC input") - default: - return qsTr("Error") - } - } - else - { - var condition = "" - var running = true - var manual = false - switch (runningBy.value) - { - case 0: // stopped - condition = "" - running = false - break;; - case 1: - manual = true - condition = "" - break;; - case 2: - condition = qsTr("Test run") - break;; - case 3: - condition = qsTr("Loss of communication") - break;; - case 4: - condition = qsTr("SOC") - break;; - case 5: - condition = qsTr("AC load") - break;; - case 6: - condition = qsTr("Battery current") - break;; - case 7: - condition = qsTr("Battery voltage") - break;; - case 8: - condition = qsTr("Inverter temperature") - break;; - case 9: - condition = qsTr("Inverter overload") - break;; - default: - condition = qsTr("???") - break;; - } - - if (externalOverride) - { - if (running && ! manual) - return qsTr ("auto pending: ") + condition - else - return " " - } - else if (manual) - { - if (manualTimer.valid && manualTimer.value > 0) - return qsTr("Timed run") - else - return qsTr("Manual run") - } - else if (running) - return qsTr ("auto run: ") + condition - else - return " " - } - } - - function getNextTestRun() - { - if ( ! root.state.valid) - return "" - if (!nextTestRun.value) - return qsTr("No test run programmed") - - var todayDate = new Date() - var nextDate = new Date(nextTestRun.value * 1000) - var nextDateEnd = new Date(nextDate.getTime()) - var message = "" - // blank "next run" if test run is active - if (runningBy.value == 2) - return " " - else if (todayDate.getDate() == nextDate.getDate() && todayDate.getMonth() == nextDate.getMonth()) - { - message = qsTr("Next test run today %1").arg( - Qt.formatDateTime(nextDate, "hh:mm").toString()) - } - else - { - message = qsTr("Next test run on %1").arg( - Qt.formatDateTime(nextDate, "dd/MM/yyyy").toString()) - nextDateEnd.setSeconds(testRunDuration.value) } - - if (skipTestRun.value === 1) - message += qsTr(" \(skipped\)") - - return message - } - - Tile { - id: imageTile - width: 180 - height: 136 - MbIcon { - id: generator - iconId: icon - anchors.centerIn: parent - } - anchors { top: parent.top; left: parent.left } - values: [ - // spacer - TileText { - width: imageTile.width - 5 - text: " " - font.pixelSize: 62 - }, - TileText { - width: imageTile.width - 5 - text: runningState.valid ? runningState.value == "R" ? "Running " : runningState.value == "S" ? "Stopped " : "" : "" - } - ] - } - - Tile { - id: statusTile - height: imageTile.height - color: "#4789d0" - anchors { top: parent.top; left: imageTile.right; right: root.right } - title: qsTr("STATUS") - values: [ - TileText - { - width: statusTile.width - 5 - color: externalOverride ? "yellow" : "white" - text: - { - var runPrefix - var message - if ( ! root.state.valid) - return qsTr ("Generator not connected") - else if (root.state.value === 2) - runPrefix = qsTr("Warming up for ") - else - runPrefix = qsTr ("Running for ") - if (!root.state.valid) - message = "" - else if (externalOverride) - message = qsTr("External Override - stopped") - else if (root.state.value === 3) - message = qsTr("Cool-down") - else if (root.state.value === 4) - message = qsTr("Stopping") - else if (runningBy.value == 0) - message = qsTr ("Stopped") - else if ( ! runningTime.valid) - message = runPrefix + "??" - else - { - message = runPrefix + formatTime (runningTime.value) - if (manualTimer.valid && manualTimer.value > 0) - message += qsTr (" ends in ") + formatTime (manualTimer.value) - } - return message - } - }, - Rectangle - { - width: parent.width - height: 3 - color: "transparent" - }, - TileTextMultiLine - { - text: stateDescription() - width: statusTile.width - 5 - }, - Rectangle - { - width: parent.width - height: 3 - color: "transparent" - }, - TileText - { - text: qsTr("\nQuiet hours"); - width: statusTile.width - 5 - font.bold: runningBy.valid && runningBy.value != 0 - color: font.bold ? "yellow" : "white" - visible: quietHours.value === 1 - }, - Rectangle - { - width: parent.width - height: 3 - color: "transparent" - }, - TileTextMultiLine - { - width: statusTile.width - 5 - text: getNextTestRun() - } - ] - } - - Tile { - id: acInTile - title: qsTr("GENERATOR POWER") - width: 150 - height: 136 - color: "#82acde" - anchors { top: imageTile.bottom; left: parent.left } - visible: showAcIn - values: - [ - OverviewAcValuesEnhanced - { - connection: sys.genset - visible: sys.genset.power.valid - }, - TileText - { - width: acInTile.width - 5 - text: - { - if (ac1source.valid && ac1source.value == 2) - { - if (ignoreAcInput1.valid && ignoreAcInput1.value == 1) - return qsTr ("\nAC In Ignored\nduring\ngenerator\nstart / stop") - else - return "" - } - else if (ac2source.valid && ac2source.value == 2) - { - if (ignoreAcInput2.valid && ignoreAcInput2.value == 1) - return qsTr ("\nAC In Ignored\nduring\ngenerator\nstart / stop") - else - return "" - } - else - return qsTr ("\nAC In\nis not\ngenerator") - } - visible: !sys.genset.power.valid - } - ] -////// add power bar graph - PowerGauge - { - id: acInBar - width: parent.width - height: 12 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.genset - useInputCurrentLimit: true - maxForwardPowerParameter: "" - maxReversePowerParameter: "" - visible: showGauges && sys.genset.power.valid - } - } - -//////// added to show alternator in place of AC generator - Tile { - id: alternatorTile - title: qsTr("ALTERNATOR POWER") - color: "#157894" - anchors.fill: acInTile - visible: showAlternator - values: - [ - TileText - { - text: EnhFmt.formatVBusItem (sys.alternator.power, "W") - font.pixelSize: 22 - } - ] -////// add power bar graph - PowerGauge - { - id: alternatorGauge - width: parent.width - height: 12 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.alternator - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxAlternatorPower" - visible: showGauges && showAlternator - } - } - - Tile { - id: runTimeTile - title: qsTr("RUN TIMES") - width: 140 - anchors { top: acInTile.top; bottom: parent.bottom; left: acInTile.right } - values: [ - TileText - { - width: runTimeTile.width - 5 - text: qsTr ("Today") - }, - TileText { - width: runTimeTile.width - 5 - text: todayRuntime.valid ? formatTime (todayRuntime.value) : "--" - }, - Rectangle - { - width: parent.width - height: 3 - color: "transparent" - }, - TileText - { - width: runTimeTile.width - 5 - text: qsTr ("Accumulated") - }, - TileText - { - width: runTimeTile.width - 5 - text: - { - if ( ! totalAcummulatedTime.valid) - return "--" - else if (totalAccumulatedTimeOffset.valid ) - return formatTime (totalAcummulatedTime.value - totalAccumulatedTimeOffset.value) - else - return formatTime (totalAcummulatedTime.value) - } - }, - Rectangle - { - width: parent.width - height: 3 - color: "transparent" - }, - TileText - { - width: runTimeTile.width - 5 - visible: showServiceInfo - color: serviceOverdue ? "red" : "white" - text: serviceOverdue ? qsTr ("Service OVERDUE") : qsTr ("Service in") - }, - TileText - { - width: runTimeTile.width - 5 - visible: showServiceInfo - color: serviceOverdue ? "red" : "white" - text: formatTime (Math.abs (serviceCounterItem.value)) - } - ] - } - - TileAutoRunEnhanced - { - id: autoRunTile - bindPrefix: root.bindPrefix - focus: root.active && autoStartSelected - connected: state.valid - tileHeight: acInTile.height / 2 - anchors { - bottom: parent.bottom; bottomMargin: tileHeight - left: runTimeTile.right - right: parent.right - } - } - - TileManualStartEnhanced - { - id: manualTile - bindPrefix: root.bindPrefix - focus: root.active && ! autoStartSelected - connected: state.valid - tileHeight: acInTile.height / 2 - anchors { - bottom: parent.bottom - left: runTimeTile.right - right: parent.right - } - } - - // mouse areas must be AFTER their associated objects so those objects can catch mouse events - // rejected by these areas - // mouse targets need to be disabled while changes are pending - MouseArea { - id: autoRunTarget - anchors.fill: autoRunTile - enabled: root.active && ! editMode - onPressed: - { - if ( ! root.autoStartSelected ) - { - setFocusAuto () - mouse.accepted = true - } - else - { - mouse.accepted = false - } - } - } - MouseArea { - id: manualStartTarget - anchors.fill: manualTile - enabled: root.active && ! editMode - onPressed: - { - if ( root.autoStartSelected ) - { - setFocusManual () - mouse.accepted = true - } - else - { - mouse.accepted = false - } - } - } -} diff --git a/FileSets/v3.34/OverviewGeneratorEnhanced.qml b/FileSets/v3.34/OverviewGeneratorEnhanced.qml new file mode 120000 index 00000000..5d2ad08e --- /dev/null +++ b/FileSets/v3.34/OverviewGeneratorEnhanced.qml @@ -0,0 +1 @@ +../v3.40/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.34/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.34/OverviewGeneratorRelayEnhanced.qml index 1c9b530f..83089971 120000 --- a/FileSets/v3.34/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.34/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.34/OverviewGridParallel.qml b/FileSets/v3.34/OverviewGridParallel.qml deleted file mode 120000 index 3d1f0720..00000000 --- a/FileSets/v3.34/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.34/OverviewGridParallel.qml b/FileSets/v3.34/OverviewGridParallel.qml new file mode 100644 index 00000000..6e79cb8b --- /dev/null +++ b/FileSets/v3.34/OverviewGridParallel.qml @@ -0,0 +1,490 @@ +import QtQuick 1.1 +import "utils.js" as Utils + +OverviewPage { + id: root + +////// GuiMods — DarkMode + property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } + property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 + + property variant sys: theSystem + property bool hasAcOutSystem: _hasAcOutSystem.value === 1 + + title: qsTr("Overview") + + VBusItem { + id: _hasAcOutSystem + bind: "com.victronenergy.settings/Settings/SystemSetup/HasAcOutSystem" + } + + OverviewBox { + id: acInBox + + width: 148 + height: 100 + title: getAcSourceName(sys.acSource) +////// GuiMods — DarkMode + titleColor: !darkMode ? "#E74c3c" : "#73261E" + color: !darkMode ? "#C0392B" : "#601C15" + anchors { + top: root.top; topMargin: 1 + left: parent.left; leftMargin: 5 + } + + values: OverviewAcValues { + connection: sys.acInput + } + + MbIcon { + iconId: getAcSourceIcon(sys.acSource) + anchors { + bottom: parent.bottom + left: parent.left; leftMargin: 2 + } + opacity: 0.5 + } + } + + OverviewBox { + id: acLoadBox + title: qsTr("AC Loads") +////// GuiMods — DarkMode + color: !darkMode ? "#27AE60" : "#135730" + titleColor: !darkMode ? "#2ECC71" : "#176638" + width: 148 + height: 100 + + anchors { + left: acInBox.right + leftMargin: hasAcOutSystem ? 10 : 174 + top: root.top; topMargin: 1 + } + + values: OverviewAcValues { + connection: sys.acInLoad + } + } + + OverviewBox { + id: acOutputBox + title: qsTr("Critical Loads") +////// GuiMods — DarkMode + color: !darkMode ? "#157894" : "#0a3c4a" + titleColor: !darkMode ? "#419FB9" : "#204f5c" + height: 100 + width: 148 + visible: hasAcOutSystem + anchors { + right: root.right; rightMargin: 5 + top: root.top; topMargin: 17 + } + + values: OverviewAcValues { + connection: sys.acOutLoad + } + } + + Multi { + id: multi + iconId: "overview-inverter-short" + anchors { + horizontalCenter: parent.horizontalCenter + bottom: root.bottom; bottomMargin: 39 + } + } + + // invisible item to connection all AC connections to.. + Item { + id: acBus + height: 10 + anchors { + left: acInBox.left; leftMargin: hasAcOutSystem ? 5 : acInBox.width - 5 + right: acLoadBox.right; rightMargin: 2 + bottom: acInBox.bottom; bottomMargin: -15 + } + } + + Battery { + id: battery + + soc: sys.battery.soc.valid ? sys.battery.soc.value : 0 + preferRenewable: sys.preferRenewableEnergy.valid + preferRenewableOverride: sys.preferRenewableEnergy.value === 0 + height: pvInverterOnGrid.visible ? 81 : 101 + width: 145 + + anchors { + bottom: parent.bottom; bottomMargin: 5; + left:parent.left; leftMargin: 5 + } + values: Column { + y: pvInverterOnGrid.visible ? 0 : 8 + width: parent.width + + TileText { + text: sys.battery.soc.valid ? sys.battery.soc.value.toFixed(0) : "--" + font.pixelSize: 30 + + Text { + anchors { + bottom: parent.bottom; bottomMargin: 4 + horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: parent.paintedWidth / 2 + 5 + } + visible: sys.battery.soc.valid + text: "%" + color: "white" + font.bold: true + font.pixelSize: 12 + } + } + TileText { + text: sys.battery.power.format(0) + } + TileText { + text: sys.battery.voltage.format(1) + " " + sys.battery.current.format(1) + } + } + } + + // PV inverter on AC in, AC Output ignored + OverviewSolarInverter { + id: pvInverterOnGridNoAcOut + title: qsTr("PV Inverter") + width: 154 + height: 100 + visible: sys.pvOnGrid.power.valid && !hasAcOutSystem + showInverterIcon: false + values: TileText { + y: 2 + text: sys.pvOnGrid.power.format(0) + font.pixelSize: 25 + } + anchors { + top: root.top; topMargin: 1 + horizontalCenter: root.horizontalCenter + } + } + + OverviewSolarInverter { + id: pvInverterOnGrid + title: qsTr("PV Inverter") + width: 148 + height: 60 + visible: sys.pvOnGrid.power.valid && hasAcOutSystem + showInverterIcon: false + values: TileText { + y: 2 + text: sys.pvOnGrid.power.format(0) + font.pixelSize: 20 + } + anchors { + bottom: battery.top; bottomMargin: 5 + left: root.left; leftMargin: 5 + } + } + + OverviewSolarInverter { + id: pvInverterOnAcOut + title: qsTr("PV Inverter") + width: 148 + height: 60 + visible: sys.pvOnAcOut.power.valid + showInverterIcon: false + + values: TileText { + y: 2 + text: sys.pvOnAcOut.power.format(0) + font.pixelSize: 20 + } + anchors { + bottom: blueSolarCharger.top; bottomMargin: 5 + right: parent.right; rightMargin: 5 + } + } + + OverviewSolarCharger { + id: blueSolarCharger + title: qsTr("PV Charger") + width: 148 + height: 60 + visible: sys.pvCharger.power.valid + showChargerIcon: false + + anchors { + right: root.right; rightMargin: 5 + bottom: root.bottom; bottomMargin: 5; + } + + values: TileText { + y: 2 + text: sys.pvCharger.power.format(0) + font.pixelSize: 20 + } + } + + OverviewEssReason { + anchors { + bottom: parent.bottom; bottomMargin: 5 + horizontalCenter: parent.horizontalCenter + } + } + + // AC source power flow + OverviewConnection { + id: acSource + ballCount: 4 + path: corner + active: root.active && hasAcOutSystem + value: flow(sys.acInput ? sys.acInput.power : undefined) * -1 + startPointVisible: false + + anchors { + right: acInBox.left; rightMargin: -9 + left: pvInverterOnGridConnection.horizontalCenter + bottom: acInBox.bottom; bottomMargin: 8 + top: acBus.verticalCenter + } + } + + // Coupled AC sources + OverviewConnection { + id: coupledAcConnection + + property VBusItem coupled: VBusItem { + property double gridPower: sys.acInput.power.valid ? sys.acInput.power.value : 0 + property double pvPower: sys.pvOnGrid.power.valid ? sys.pvOnGrid.power.value : 0 + value: gridPower + pvPower + } + + ballCount: 1 + path: straight + active: root.active && hasAcOutSystem + value: flow(coupled) + startPointVisible: false + endPointVisible: false + + anchors { + left: pvInverterOnGridConnection.right + right: vebusConnection.left + top: acBus.verticalCenter + bottom: acBus.verticalCenter + } + } + + // AC source power flow, ignored AC output + OverviewConnection { + id: acSourceNoAcOut + ballCount: 5 + path: corner + active: root.active && !hasAcOutSystem + value: acSource.value + startPointVisible: false + + anchors { + right: acInBox.left; rightMargin: -9 + left: pvInverterOnGridConnectionNoAcOut.horizontalCenter + bottom: acInBox.bottom; bottomMargin: 8 + top: acBus.verticalCenter + } + } + + // Coupled AC sources, ignored AC output + OverviewConnection { + id: coupledAcConnectionNoAcOut + + ballCount: 1 + path: straight + active: root.active && !hasAcOutSystem + value: coupledAcConnection.value + startPointVisible: false + endPointVisible: false + + anchors { + left: pvInverterOnGridConnectionNoAcOut.right + right: vebusConnection.left + top: acBus.verticalCenter + bottom: acBus.verticalCenter + } + } + + // Grid inverter power flow, ignored AC output + OverviewConnection { + id: pvInverterOnGridConnectionNoAcOut + ballCount: 1 + path: straight + active: root.active && pvInverterOnGridNoAcOut.visible + value: flow(sys.pvOnGrid ? sys.pvOnGrid.power : undefined) + startPointVisible: true + endPointVisible: false + + anchors { + top: pvInverterOnGridNoAcOut.bottom; topMargin: -8 + bottom: acBus.verticalCenter + left: pvInverterOnGridNoAcOut.left; leftMargin: 8 + right: pvInverterOnGridNoAcOut.left; rightMargin: -8 + } + } + + // Grid inverter power flow + OverviewConnection { + id: pvInverterOnGridConnection + ballCount: 1 + path: straight + active: root.active && pvInverterOnGrid.visible + value: flow(sys.pvOnGrid ? sys.pvOnGrid.power : undefined) * -1 + startPointVisible: false + + anchors { + top: acBus.verticalCenter + bottom: pvInverterOnGrid.top; bottomMargin: -8 + left: pvInverterOnGrid.right; leftMargin: -8 + } + } + + // power to loads + OverviewConnection { + id: loadConnection + ballCount: hasAcOutSystem ? 3 : 5 + path: corner + active: root.active + value: flow(sys.acInLoad.power) + startPointVisible: false + endPointVisible: true + + anchors { + right: acLoadBox.right; rightMargin: hasAcOutSystem ? 10 : acLoadBox.width - 10 + left: vebusConnection.horizontalCenter + top: acBus.verticalCenter + bottom: acLoadBox.bottom; bottomMargin: 8 + } + } + + // Towards vebus system + OverviewConnection { + id: vebusConnection + + property VBusItem vebusAcPower: VBusItem { bind: [sys.vebusPrefix, "/Ac/ActiveIn/P"] } + + ballCount: 1 + path: straight + active: root.active + value: flow(vebusAcPower) + startPointVisible: false + endPointVisible: true + + anchors { + left: multi.left; leftMargin: 8 + top: acBus.verticalCenter + bottom: multi.top; bottomMargin: -7 + } + } + + // AC out connection + OverviewConnection { + id: acOutConnection + + property double pvInverterOnAcOutPower: sys.pvOnAcOut.power.valid ? sys.pvOnAcOut.power.value : 0 + property double acOutLoad: sys.acOutLoad.power.valid ? sys.acOutLoad.power.value : 0 + property VBusItem vebusAcOutPower: VBusItem { value: acOutConnection.acOutLoad - acOutConnection.pvInverterOnAcOutPower } + + ballCount: 1 + path: straight + active: root.active && (hasAcOutSystem || pvInverterOnAcOut.visible) + value: flow(vebusAcOutPower) + endPointVisible: false + + anchors { + left: multi.right; leftMargin: -8 + right: acOutBoxConnection.left + top: multi.top; topMargin: 8 + } + } + + // UPS conenction + OverviewConnection { + id: acOutBoxConnection + + ballCount: 1 + path: straight + active: root.active && hasAcOutSystem + value: flow(sys.acOutLoad.power) + startPointVisible: false + + anchors { + left: acOutputBox.left; leftMargin: 10 + top: acOutConnection.verticalCenter + bottom: acOutputBox.bottom; bottomMargin: 9 + } + } + + // PV Inverter on AC out connection + OverviewConnection { + id: pvOnAcOutConnection + + ballCount: 1 + path: straight + active: root.active && pvInverterOnAcOut.visible + value: flow(sys.pvOnAcOut.power) + endPointVisible: false + + anchors { + left: acOutBoxConnection.left + bottom: acOutConnection.verticalCenter + top: pvInverterOnAcOut.top; topMargin: 8 + } + } + + // DC connection from multi + OverviewConnection { + ballCount: 1 + path: straight + active: root.active + value: flow(sys.vebusDc.power) + endPointVisible: false + + anchors { + right: dcConnection.right; + top: multi.bottom; topMargin: -10 + bottom: dcConnection.top; + } + } + + // Battery to DC connection + OverviewConnection { + ballCount: 3 + path: straight + active: root.active + value: Utils.sign(noNoise(sys.pvCharger.power) + noNoise(sys.vebusDc.power)) + startPointVisible: false + + anchors { + left: dcConnection.left; + top: dcConnection.verticalCenter + right: battery.right; rightMargin: 10 + } + } + + // Solar charger to DC connection + OverviewConnection { + ballCount: 3 + path: straight + active: root.active && blueSolarCharger.visible + value: flow(sys.pvCharger.power) + endPointVisible: false + + anchors { + right: dcConnection.right; + top: dcConnection.top + left: blueSolarCharger.left; leftMargin: 10 + } + } + + Item { + id: dcConnection + anchors { + horizontalCenter: multi.horizontalCenter + top: multi.bottom; topMargin: 10 + } + } +} diff --git a/FileSets/v3.40~8/OverviewGridParallel.qml.orig b/FileSets/v3.34/OverviewGridParallel.qml.orig similarity index 100% rename from FileSets/v3.40~8/OverviewGridParallel.qml.orig rename to FileSets/v3.34/OverviewGridParallel.qml.orig diff --git a/FileSets/v3.34/OverviewHub.qml b/FileSets/v3.34/OverviewHub.qml deleted file mode 120000 index 83bae2bd..00000000 --- a/FileSets/v3.34/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.34/OverviewHub.qml b/FileSets/v3.34/OverviewHub.qml new file mode 100644 index 00000000..54d81dda --- /dev/null +++ b/FileSets/v3.34/OverviewHub.qml @@ -0,0 +1,315 @@ +import QtQuick 1.1 +import "utils.js" as Utils + +OverviewPage { + id: root + +////// GuiMods — DarkMode + property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } + property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 + + property variant sys: theSystem + property bool hasAcSolarOnAcIn1: sys.pvOnAcIn1.power.valid + property bool hasAcSolarOnAcIn2: sys.pvOnAcIn2.power.valid + property bool hasAcSolarOnIn: hasAcSolarOnAcIn1 || hasAcSolarOnAcIn2 + property bool hasAcSolarOnOut: sys.pvOnAcOut.power.valid + property bool hasAcSolar: hasAcSolarOnIn || hasAcSolarOnOut + property bool hasDcSolar: sys.pvCharger.power.valid + property bool hasDcAndAcSolar: hasAcSolar && hasDcSolar + + title: qsTr("Overview") + + OverviewBox { + id: acInBox + + width: 148 + height: showStatusBar ? 100 : 120 + title: getAcSourceName(sys.acSource) +////// GuiMods — DarkMode + titleColor: !darkMode ? "#E74c3c" : "#73261E" + color: !darkMode ? "#C0392B" : "#601C15" + + anchors { + top: multi.top + left: parent.left; leftMargin: 10 + } + + values: OverviewAcValues { + connection: sys.acInput + } + + MbIcon { + iconId: getAcSourceIcon(sys.acSource) + anchors { + bottom: parent.bottom + left: parent.left; leftMargin: 2 + } + opacity: 0.5 + } + } + + Multi { + id: multi + anchors { + horizontalCenter: parent.horizontalCenter + top: parent.top; topMargin: 5 + } + } + + OverviewBox { + id: acLoadBox + title: qsTr("AC Loads") +////// GuiMods — DarkMode + color: !darkMode ? "#27AE60" : "#135730" + titleColor: !darkMode ? "#2ECC71" : "#176638" + width: 148 + height: showStatusBar ? 100 : 120 + + anchors { + right: parent.right; rightMargin: 10 + top: multi.top + } + + values: OverviewAcValues { + connection: sys.acLoad + } + } + + Battery { + id: battery + + soc: sys.battery.soc.valid ? sys.battery.soc.value : 0 + + anchors { + bottom: parent.bottom; bottomMargin: 5; + left: parent.left; leftMargin: 10 + } + values: Column { + width: parent.width + + TileText { + // Use value here instead of format() because format adds the unit to the number and we + // show the percentage symbol in a separated smaller text. + text: sys.battery.soc.value === undefined ? "--" : sys.battery.soc.value.toFixed(0) + font.pixelSize: 40 + + Text { + anchors { + bottom: parent.bottom; bottomMargin: 9 + horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: parent.paintedWidth / 2 + 5 + } + visible: sys.battery.soc.valid + text: "%" + color: "white" + font.bold: true + font.pixelSize: 12 + } + } + TileText { + text: sys.battery.power.format(0) + } + TileText { + text: sys.battery.voltage.format(1) + " " + sys.battery.current.format(1) + } + } + } + + OverviewBox { + id: dcSystemBox + width: 105 + height: 45 + visible: sys.dcSystem.power.valid + title: qsTr("DC Power") + + anchors { + horizontalCenter: multi.horizontalCenter + bottom: parent.bottom; bottomMargin: 5 + } + + values: TileText { + anchors.centerIn: parent + text: sys.dcSystem.power.format(0) + } + } + + OverviewSolarCharger { + id: blueSolarCharger + + height: hasDcAndAcSolar ? 65 : 114 + width: 148 + title: qsTr("PV Charger") + showChargerIcon: !hasDcAndAcSolar + visible: hasDcSolar || hasDcAndAcSolar + + anchors { + right: root.right; rightMargin: 10 + bottom: root.bottom; bottomMargin: 5; + } + + values: TileText { + y: 5 + text: sys.pvCharger.power.format(0) + font.pixelSize: 20 + } + } + + OverviewSolarInverter { + id: pvInverter + height: hasDcAndAcSolar ? 65 : 115 + width: 148 + title: qsTr("PV Inverter") + showInverterIcon: !hasDcAndAcSolar + visible: hasAcSolar + + anchors { + right: root.right; rightMargin: 10; + bottom: root.bottom; bottomMargin: hasDcAndAcSolar ? 75 : 5 + } + + OverviewAcValues { + connection: hasAcSolarOnOut ? sys.pvOnAcOut : hasAcSolarOnAcIn1 ? sys.pvOnAcIn1 : sys.pvOnAcIn2 + visible: !coupledPvAc.visible + } + + TileText { + id: coupledPvAc + + property double pvInverterOnAcOut: sys.pvOnAcOut.power.valid ? sys.pvOnAcOut.power.value : 0 + property double pvInverterOnAcIn1: sys.pvOnAcIn1.power.valid ? sys.pvOnAcIn1.power.value : 0 + property double pvInverterOnAcIn2: sys.pvOnAcIn2.power.valid ? sys.pvOnAcIn2.power.value : 0 + + y: 5 + text: (pvInverterOnAcOut + pvInverterOnAcIn1 + pvInverterOnAcIn2).toFixed(0) + "W" + font.pixelSize: hasDcAndAcSolar ? 20 : 25 + visible: hasDcAndAcSolar || (hasAcSolarOnIn && hasAcSolarOnOut) || (hasAcSolarOnAcIn1 && hasAcSolarOnAcIn2) + } + } + + OverviewEssReason { + anchors { + bottom: parent.bottom; bottomMargin: dcSystemBox.visible ? battery.height + 15 : 5 + horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: dcSystemBox.visible ? -(root.width / 2 - battery.width / 2 - 10) : 0 + } + } + + OverviewConnection { + id: acInToMulti + ballCount: 2 + path: straight + active: root.active + value: flow(sys.acInput ? sys.acInput.power : 0) + + anchors { + left: acInBox.right; leftMargin: -10; top: multi.verticalCenter; + right: multi.left; rightMargin: -10; bottom: multi.verticalCenter + } + } + + OverviewConnection { + id: multiToAcLoads + ballCount: 2 + path: straight + active: root.active + value: flow(sys.acLoad.power) + + anchors { + left: multi.right; leftMargin: -10; + top: multi.verticalCenter + right: acLoadBox.left; rightMargin: -10 + bottom: multi.verticalCenter + } + } + + OverviewConnection { + id: pvInverterToMulti + + property int hasDcAndAcFlow: Utils.sign(noNoise(sys.pvOnAcOut.power) + noNoise(sys.pvOnAcIn1.power) + noNoise(sys.pvOnAcIn2.power)) + + ballCount: 4 + path: corner + active: root.active && hasAcSolar + value: hasDcAndAcSolar ? hasDcAndAcFlow : flow(sys.pvOnAcOut.power) + + anchors { + left: pvInverter.left; leftMargin: 8 + top: pvInverter.verticalCenter; topMargin: hasDcAndAcSolar ? 1 : 0 + right: multi.horizontalCenter; rightMargin: -20 + bottom: multi.bottom; bottomMargin: 10 + } + } + + // invisible anchor point to connect the chargers to the battery + Item { + id: dcConnect + anchors { + left: multi.horizontalCenter; leftMargin: hasAcSolar ? -20 : 0 + bottom: dcSystemBox.top; bottomMargin: 10 + } + } + + OverviewConnection { + id: multiToDcConnect + ballCount: 3 + path: straight + active: root.active + value: -flow(sys.vebusDc.power); + startPointVisible: false + + anchors { + left: dcConnect.left + top: dcConnect.top + + right: dcConnect.left + bottom: multi.bottom; bottomMargin: 10 + } + } + + OverviewConnection { + id: blueSolarChargerDcConnect + ballCount: 3 + path: straight + active: root.active && hasDcSolar + value: -flow(sys.pvCharger.power) + startPointVisible: false + + anchors { + left: dcConnect.left + top: dcConnect.top + + right: blueSolarCharger.left; rightMargin: -8 + bottom: dcConnect.top; + } + } + + OverviewConnection { + id: chargersToBattery + ballCount: 3 + path: straight + active: root.active + value: Utils.sign(noNoise(sys.pvCharger.power) + noNoise(sys.vebusDc.power)) + startPointVisible: false + + anchors { + left: dcConnect.left + top: dcConnect.top + + right: battery.right; rightMargin: 10 + bottom: dcConnect.top + } + } + + OverviewConnection { + id: batteryToDcSystem + ballCount: 2 + path: straight + active: root.active && sys.dcSystem.power.valid + value: flow(sys.dcSystem.power) + + anchors { + left: battery.right; leftMargin: -10 + top: dcSystemBox.verticalCenter; + right: dcSystemBox.left; rightMargin: -10 + bottom: dcSystemBox.verticalCenter + } + } +} diff --git a/FileSets/v3.40~8/OverviewHub.qml.orig b/FileSets/v3.34/OverviewHub.qml.orig similarity index 100% rename from FileSets/v3.40~8/OverviewHub.qml.orig rename to FileSets/v3.34/OverviewHub.qml.orig diff --git a/FileSets/v3.34/OverviewHubEnhanced.qml b/FileSets/v3.34/OverviewHubEnhanced.qml deleted file mode 120000 index 905200b7..00000000 --- a/FileSets/v3.34/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.34/OverviewHubEnhanced.qml b/FileSets/v3.34/OverviewHubEnhanced.qml new file mode 100644 index 00000000..23865ec1 --- /dev/null +++ b/FileSets/v3.34/OverviewHubEnhanced.qml @@ -0,0 +1,1505 @@ +////// MODIFIED to show: +////// tanks in a row along bottom +////// PV voltage and current and DC power current (up to 2 MPPTs with tanks and temps or 3 without) +////// PV inverter power (up to 2 with tanks and temps or 3 without) +////// voltage, current, frequency in AC tiles (plus current limit for AC input) +////// time of day +////// current in DC Loads +////// remaining time in Battery tile +////// bar graphs on AC in/out and Multi +////// detail pages for all tiles +////// bar gauge on PV Charger tile +////// add support for VE.Direct inverters + +import QtQuick 1.1 +import "utils.js" as Utils +////// ADDED to show tanks +import com.victron.velib 1.0 +import "timeToGo.js" as TTG +import "enhancedFormat.js" as EnhFmt + +OverviewPage { + id: root + + property variant sys: theSystem + + property string systemPrefix: "com.victronenergy.system" + property string guiModsPrefix: "com.victronenergy.settings/Settings/GuiMods" + +////// GuiMods — DarkMode + property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } + property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 + + VBusItem { id: vebusService; bind: Utils.path(systemPrefix, "/VebusService") } + property bool isMulti: vebusService.valid + property string veDirectInverterService: "" + property string inverterService: vebusService.valid ? vebusService.value : veDirectInverterService + + VBusItem { id: replaceAcInItem; bind: Utils.path(guiModsPrefix, "/ReplaceInactiveAcIn") } + property bool hasAlternator: sys.alternator.power.valid + property bool replaceAcIn: replaceAcInItem.valid && replaceAcInItem.value == 1 && hasAlternator && (sys.acSource == 0 || sys.acSource == 240) + property bool showAcInput: ((isMulti || sys.acInput.power.valid) && ! replaceAcIn) || showAllTiles + property bool showAlternator: !showAcInput && hasAlternator + property double alternatorFlow: showAlternator ? noNoise (sys.alternator.power) : 0 + property bool showAcLoads: isMulti || sys.acLoad.power.valid || veDirectInverterService != "" + property bool showDcSystem: (hasDcSystemItem.valid && hasDcSystemItem.value > 0) || showAllTiles + property bool hasInverter: false + property bool showInverter: hasInverter || inverterService != "" || showAllTiles + + property bool hasAcSolarOnAcIn1: sys.pvOnAcIn1.power.valid + property bool hasAcSolarOnAcIn2: sys.pvOnAcIn2.power.valid + property bool hasAcSolarOnIn: hasAcSolarOnAcIn1 || hasAcSolarOnAcIn2 + property bool hasAcSolarOnOut: sys.pvOnAcOut.power.valid + property bool hasAcSolar: hasAcSolarOnIn || hasAcSolarOnOut + property bool hasDcSolar: sys.pvCharger.power.valid + property bool hasDcAndAcSolar: hasAcSolar && hasDcSolar + property bool showDcAndAcSolar: hasDcAndAcSolar || showAllTiles + property bool showDcSolar: hasDcSolar || showAllTiles + property bool showAcSolar: hasAcSolar || showAllTiles +////// ADDED to show tanks + property int bottomOffset: 45 + property string settingsBindPreffix: "com.victronenergy.settings" + property string pumpBindPreffix: "com.victronenergy.pump.startstop0" + property int numberOfTemps: 0 +//////// added/modified for control show/hide gauges, tanks and temps from menus + property int tankCount: showTanksEnable ? tankModel.rowCount : 0 + property int tempCount: showTempsEnable ? numberOfTemps : 0 + property int tankTempCount: tankCount + tempCount + property bool showTanks: showTanksEnable ? showStatusBar ? false : tankCount > 0 ? true : false : false + property bool showTemps: showTempsEnable ? showStatusBar ? false : tempCount > 0 ? true : false : false + property bool showTanksTemps: showTanks || showTemps + property int compactThreshold: 45 // height below this will be compacted vertically + property bool compact: showTanks && showTemps && tankTempCount > 4 + property int tanksHeight: compact ? 22 : 45 + + property int leftTileCount: (showAcInput ? 1 : 0) + (showAlternator ? 1 : 0) + (showAlternator ? 1 : 0) + +//////// add for PV CHARGER voltage and current + property string pvChargerPrefix1: "" + property string pvChargerPrefix2: "" + property string pvChargerPrefix3: "" + property string pvChargerPrefix4: "" + property string pvChargerPrefix5: "" + property string pvChargerPrefix6: "" + property string pvChargerPrefix7: "" + property int numberOfPvChargers: 0 + property int pvChargerRows: showTanksTemps ? 4 : 7 + property int pvRowsPerCharger: Math.max ( 1, Math.min (pvChargerRows / numberOfPvChargers, 3)) + property bool pvChargerCompact: pvRowsPerCharger < 3 ? true : false + property bool pvShowDetails: pvRowsPerCharger >= 2 ? true : false + +//////// add for PV INVERTER power + property string pvInverterPrefix1: "" + property string pvInverterPrefix2: "" + property string pvInverterPrefix3: "" + property int numberOfPvInverters: 0 + +//////// add for alternator - alternator replaces AC in if AC in is not present + property string alternatorPrefix1: "" + property string alternatorPrefix2: "" + property int numberOfAlternators: 0 + VBusItem { id: alternatorName1; bind: Utils.path(alternatorPrefix1, "/CustomName") } + VBusItem { id: alternatorPower1; bind: Utils.path(alternatorPrefix1, "/Dc/0/Power") } + VBusItem { id: alternatorVoltage1; bind: Utils.path(alternatorPrefix1, "/Dc/0/Voltage") } + VBusItem { id: alternatorCurrent1; bind: Utils.path(alternatorPrefix1, "/Dc/0/Current") } + VBusItem { id: alternatorName2; bind: Utils.path(alternatorPrefix2, "/CustomName") } + VBusItem { id: alternatorPower2; bind: Utils.path(alternatorPrefix2, "/Dc/0/Power") } + +//////// added for control show/hide gauges, tanks and temps from menus + VBusItem { id: showGaugesItem; bind: Utils.path(guiModsPrefix, "/ShowGauges") } + property bool showGauges: showGaugesItem.valid ? showGaugesItem.value === 1 ? true : false : false + VBusItem { id: showTanksItem; bind: Utils.path(guiModsPrefix, "/ShowEnhancedFlowOverviewTanks") } + property bool showTanksEnable: showTanksItem.valid ? showTanksItem.value === 1 ? true : false : false + VBusItem { id: showTempsItem; bind: Utils.path(guiModsPrefix, "/ShowEnhancedFlowOverviewTemps") } + property bool showTempsEnable: showTempsItem.valid ? showTempsItem.value === 1 ? true : false : false + +//////// added to show/dim tiles + VBusItem { id: showInactiveTilesItem; bind: Utils.path(guiModsPrefix, "/ShowInactiveFlowTiles") } + property real disabledTileOpacity: (showInactiveTiles && showInactiveTilesItem.value === 1) ? 0.3 : 1 + property bool showInactiveTiles: showInactiveTilesItem.valid && showInactiveTilesItem.value >= 1 + + VBusItem { id: showBatteryTempItem; bind: Utils.path(guiModsPrefix, "/ShowBatteryTempOnFlows") } + property bool showBatteryTemp: showBatteryTempItem.valid && showBatteryTempItem.value == 1 + + // for debug, ignore validity checks so all tiles and their flow lines will show + property bool showAllTiles: showInactiveTilesItem.valid && showInactiveTilesItem.value == 3 + +//////// added to control time display + VBusItem { id: timeFormatItem; bind: Utils.path(guiModsPrefix, "/TimeFormat") } + property string timeFormat: getTimeFormat () + + function getTimeFormat () + { + if (!timeFormatItem.valid || timeFormatItem.value === 0) + return "" + else if (timeFormatItem.value === 2) + return "h:mm ap" + else + return "hh:mm" + } + +//////// add to display individual PV charger power + VBusItem { id: pvName1; bind: Utils.path(pvChargerPrefix1, "/CustomName") } + VBusItem { id: pvPower1; bind: Utils.path(pvChargerPrefix1, "/Yield/Power") } + VBusItem { id: pvVoltage1; bind: Utils.path(pvChargerPrefix1, "/Pv/V") } + VBusItem { id: pvCurrent1; bind: Utils.path(pvChargerPrefix1, "/Pv/I") } + VBusItem { id: pv1NrTrackers; bind: Utils.path(pvChargerPrefix1, "/NrOfTrackers") } + VBusItem { id: pvName2; bind: Utils.path(pvChargerPrefix2, "/CustomName") } + VBusItem { id: pvPower2; bind: Utils.path(pvChargerPrefix2, "/Yield/Power") } + VBusItem { id: pvVoltage2; bind: Utils.path(pvChargerPrefix2, "/Pv/V") } + VBusItem { id: pvCurrent2; bind: Utils.path(pvChargerPrefix2, "/Pv/I") } + VBusItem { id: pv2NrTrackers; bind: Utils.path(pvChargerPrefix2, "/NrOfTrackers") } + VBusItem { id: pvName3; bind: Utils.path(pvChargerPrefix3, "/CustomName") } + VBusItem { id: pvPower3; bind: Utils.path(pvChargerPrefix3, "/Yield/Power") } + VBusItem { id: pvVoltage3; bind: Utils.path(pvChargerPrefix3, "/Pv/V") } + VBusItem { id: pvCurrent3; bind: Utils.path(pvChargerPrefix3, "/Pv/I") } + VBusItem { id: pv3NrTrackers; bind: Utils.path(pvChargerPrefix3, "/NrOfTrackers") } + VBusItem { id: pvName4; bind: Utils.path(pvChargerPrefix4, "/CustomName") } + VBusItem { id: pvPower4; bind: Utils.path(pvChargerPrefix4, "/Yield/Power") } + VBusItem { id: pvName5; bind: Utils.path(pvChargerPrefix5, "/CustomName") } + VBusItem { id: pvPower5; bind: Utils.path(pvChargerPrefix5, "/Yield/Power") } + VBusItem { id: pvName6; bind: Utils.path(pvChargerPrefix6, "/CustomName") } + VBusItem { id: pvPower6; bind: Utils.path(pvChargerPrefix6, "/Yield/Power") } + VBusItem { id: pvName7; bind: Utils.path(pvChargerPrefix7, "/CustomName") } + VBusItem { id: pvPower7; bind: Utils.path(pvChargerPrefix7, "/Yield/Power") } + + VBusItem { id: timeToGo; bind: Utils.path("com.victronenergy.system","/Dc/Battery/TimeToGo") } + +//////// add to display PV Inverter power + VBusItem { id: pvInverterPower1; bind: Utils.path(pvInverterPrefix1, "/Ac/Power") } + VBusItem { id: pvInverterL1Power1; bind: Utils.path(pvInverterPrefix1, "/Ac/L1/Power") } + VBusItem { id: pvInverterL2Power1; bind: Utils.path(pvInverterPrefix1, "/Ac/L2/Power") } + VBusItem { id: pvInverterL3Power1; bind: Utils.path(pvInverterPrefix1, "/Ac/L3/Power") } + VBusItem { id: pvInverterName1; bind: Utils.path(pvInverterPrefix1, "/CustomName") } + VBusItem { id: pvInverterPower2; bind: Utils.path(pvInverterPrefix2, "/Ac/Power") } + VBusItem { id: pvInverterName2; bind: Utils.path(pvInverterPrefix2, "/CustomName") } + VBusItem { id: pvInverterPower3; bind: Utils.path(pvInverterPrefix3, "/Ac/Power") } + VBusItem { id: pvInverterName3; bind: Utils.path(pvInverterPrefix3, "/CustomName") } + +//////// add to display AC input ignored + VBusItem { id: ignoreAcInput1; bind: Utils.path(inverterService, "/Ac/State/IgnoreAcIn1") } + VBusItem { id: ignoreAcInput2; bind: Utils.path(inverterService, "/Ac/State/IgnoreAcIn2") } + VBusItem { id: acActiveInput; bind: Utils.path(inverterService, "/Ac/ActiveIn/ActiveInput") } + + VBusItem { id: hasDcSystemItem; bind: "com.victronenergy.settings/Settings/SystemSetup/HasDcSystem" } + + //Component.onCompleted: { discoverServices(); showHelp () } + onActiveChanged: + { + if (root.active) + { + discoverServices() + showHelp () + } + } + + title: qsTr("Simple Overview") + + OverviewBox { + id: acInBox +////// GuiMods — DarkMode + titleColor: !darkMode ? "#E74c3c" : "#73261E" + color: !darkMode ? "#C0392B" : "#601C15" + opacity: showAcInput ? 1 : disabledTileOpacity + visible: showAcInput || showInactiveTiles + width: 148 + height: showStatusBar ? 100 : 120 + title: + { + // input 1 is active + if (acActiveInput.value == 0) + { + if (ignoreAcInput1.valid && ignoreAcInput1.value == 1) + return qsTr ("AC In 1 Ignored") + else + return getAcSourceName(sys.acSource) + } + // input 2 is active + else if (acActiveInput.value == 1) + { + if (ignoreAcInput2.valid && ignoreAcInput2.value == 1) + return qsTr ("AC In 2 Ignored") + else + return getAcSourceName(sys.acSource) + } + else + return "no input" + } + anchors { + top: multi.top + left: parent.left; leftMargin: 10 + } + + values: OverviewAcValuesEnhanced { + connection: sys.acInput + } + + MbIcon { + iconId: getAcSourceIcon(sys.acSource) + anchors { + bottom: parent.bottom + left: parent.left; leftMargin: 2 + } + opacity: 0.5 + } +////// add power bar graph + PowerGauge + { + id: acInBar + width: parent.width + height: 12 + anchors + { + top: parent.top; topMargin: 16 + horizontalCenter: parent.horizontalCenter + } + connection: sys.acInput + useInputCurrentLimit: true + maxForwardPowerParameter: "" + maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxFeedInPower" + visible: showGauges && showAcInput + } + DetailTarget { id: acInputTarget; detailsPage: "DetailAcInput.qml" } + } + + + //// add alternator if AC input not present + OverviewBox { + id: alternatorBox + title: qsTr ("Alternator") + color: !darkMode ? "#157894" : "#0a3c4a" + titleColor: !darkMode ? "#419FB9" : "#204f5c" + opacity: showAlternator ? 1 : disabledTileOpacity + visible: showAlternator || showInactiveTiles && ! acInBox.visible + width: 148 + height: showStatusBar ? 100 : 120 + anchors.fill: acInBox + values: Column + { + width: parent.width + TileText + { + text: " " + font.pixelSize: 6 + } + TileText + { + text: EnhFmt.formatVBusItem (sys.alternator.power, "W") + font.pixelSize: 19 + } + TileText + { + text: alternatorName1.valid ? alternatorName1.value : "-" + visible: showAlternator && numberOfAlternators >= 1 + } + TileText + { + text: EnhFmt.formatVBusItem (alternatorPower1, "W") + font.pixelSize: 15 + visible: showAlternator && numberOfAlternators > 1 + } + TileText { + text: EnhFmt.formatVBusItem (alternatorVoltage1, "V") + font.pixelSize: 15 + visible: showAlternator && numberOfAlternators == 1 + } + TileText { + text: EnhFmt.formatVBusItem (alternatorCurrent1, "A") + font.pixelSize: 15 + visible: showAlternator && numberOfAlternators == 1 + } + TileText + { + text: alternatorName2.valid ? alternatorName2.value : "-" + visible: showAlternator && numberOfAlternators >= 2 + } + TileText + { + text: EnhFmt.formatVBusItem (alternatorPower1, "W") + font.pixelSize: 15 + visible: showAlternator && numberOfAlternators >= 2 + } + } + + PowerGauge + { + id: alternatorBar + width: parent.width + height: 12 + anchors + { + top: parent.top; topMargin: 16 + horizontalCenter: parent.horizontalCenter + } + connection: sys.alternator + maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxAlternatorPower" + visible: showGauges && showAlternator + } + DetailTarget { id: alternatorTarget; detailsPage: "DetailAlternator.qml" } + } + + MultiEnhanced { + id: multi + anchors { + horizontalCenter: parent.horizontalCenter + top: parent.top; topMargin: 3 + } + inverterService: root.inverterService + opacity: showInverter ? 1 : disabledTileOpacity + visible: showInverter || showInactiveTiles +////// add power bar graph + PowerGaugeMulti + { + id: multiBar + width: multi.width + height: 12 + anchors + { + top: parent.top; topMargin: 23 + horizontalCenter: parent.horizontalCenter + } + inverterService: root.inverterService + visible: showGauges && showInverter + } + DetailTarget { id: multiTarget; detailsPage: "DetailInverter.qml"; width: 60; height: 60 } + } + +////// ADDED to show time inside inverter icon + Timer { + id: wallClock + running: timeFormat != "" + repeat: true + interval: 1000 + triggeredOnStart: true + onTriggered: time = Qt.formatDateTime(new Date(), timeFormat) + property string time + } + TileText + { + text: wallClock.time + font.pixelSize: 18 + color: showInverter || darkMode ? "white" : "black" + anchors + { + top: multi.top; topMargin: 96 + horizontalCenter: multi.horizontalCenter + } + visible: wallClock.running + } + + OverviewBox { + id: acLoadBox + visible: showAcLoads || showInactiveTiles + opacity: showAcLoads ? 1 : disabledTileOpacity + title: qsTr("AC Loads") +////// GuiMods — DarkMode + color: !darkMode ? "#27AE60" : "#135730" + titleColor: !darkMode ? "#2ECC71" : "#176638" + width: 148 + height: showStatusBar ? 80 : 102 + + anchors { + right: parent.right; rightMargin: 10 + top: multi.top + } + + values: OverviewAcValuesEnhanced { + connection: sys.acLoad + } +////// add power bar graph + PowerGauge + { + id: acLoadBar + width: parent.width + height: 12 + anchors + { + top: parent.top; topMargin: 16 + horizontalCenter: parent.horizontalCenter + } + connection: sys.acLoad + maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputMaxPower" + visible: showGauges && showAcLoads + } + DetailTarget { id: loadsOnOutputTarget; detailsPage: "DetailLoadsCombined.qml" } + } + + Battery { + id: battery + width: acInBox.width + height: 96 + anchors { + bottom: parent.bottom; bottomMargin: showTanksTemps ? bottomOffset + 3 : 5; + left: parent.left; leftMargin: 10 + } + soc: sys.battery.soc.valid ? sys.battery.soc.value : 0 +////// add battery current bar graph + PowerGaugeBattery + { + id: batteryBar + width: parent.width + height: 10 + anchors + { + top: parent.top; topMargin: 52 + horizontalCenter: parent.horizontalCenter + } + visible: showGauges + } + + values: Column { + width: parent.width + + TileText { + text: sys.battery.soc.value === undefined ? "--" : sys.battery.soc.format (0) + font.pixelSize: 25 + } + TileText { + text: EnhFmt.formatVBusItem (sys.battery.power, "W") + } + TileText { + text: " " + font.pixelSize: 6 + } + TileText { + text: EnhFmt.formatVBusItem (sys.battery.voltage, "V ", 2) + + EnhFmt.formatVBusItem (sys.battery.current, "A") + } + TileText { + text: timeToGo.valid ? qsTr ("Remain: ") + TTG.formatTimeToGo (timeToGo) : qsTr (" ") + } + } + DetailTarget { id: batteryTarget; detailsPage: "DetailBattery.qml" } + } + + VBusItem { id: dcSystemNameItem; bind: Utils.path(settingsBindPreffix, "/Settings/GuiMods/CustomDcSystemName") } + + OverviewBox { + id: dcSystemBox +////// wider to make room for current + width: multi.width + 20 + height: 45 + opacity: showDcSystem ? 1 : disabledTileOpacity + visible: showDcSystem || showInactiveTiles + title: dcSystemNameItem.valid && dcSystemNameItem.value != "" ? dcSystemNameItem.value : qsTr ("DC System") + + anchors { + horizontalCenter: multi.horizontalCenter + horizontalCenterOffset: 2 +////// MODIFIED to show tanks + bottom: parent.bottom; bottomMargin: showTanksTemps ? bottomOffset + 3 : 5 + } + + values: + [ + TileText + { + width: parent.width + anchors + { + horizontalCenter: parent.horizontalCenter + bottom: parent.bottom; bottomMargin: 0 + } + ////// modified to show current + text: + { + if (showDcSystem) + { + var current = "" + if (sys.dcSystem.power.valid && sys.battery.voltage.valid) + current = " " + EnhFmt.formatValue (sys.dcSystem.power.value / sys.battery.voltage.value, "A") + return EnhFmt.formatVBusItem (sys.dcSystem.power) + current + } + else + return "--" + } + } + ] + PowerGauge + { + id: dcSystemGauge + width: parent.width + height: 8 + anchors + { + top: parent.top; topMargin: 19 + left: parent.left; leftMargin: 18 + right: parent.right + } + connection: sys.dcSystem + maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/DcSystemMaxLoad" + maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/DcSystemMaxCharge" + showLabels: true + visible: showGauges && showDcSystem + + } + DetailTarget { id: dcSystemTarget; detailsPage: "DetailDcSystem.qml" } + } + + property int pvOffset1: 27 + property int pvRowSpacing: 16 + property int pvOffset2: pvOffset1 + pvRowSpacing * pvRowsPerCharger + property int pvOffset3: pvOffset2 + pvRowSpacing * pvRowsPerCharger + property int pvOffset4: pvOffset3 + pvRowSpacing * pvRowsPerCharger + property int pvOffset5: pvOffset4 + pvRowSpacing * pvRowsPerCharger + property int pvOffset6: pvOffset5 + pvRowSpacing * pvRowsPerCharger + property int pvOffset7: pvOffset6 + pvRowSpacing * pvRowsPerCharger + +////// replaced OverviewSolarCharger with OverviewBox + OverviewBox { + id: pvChargerBox + title: qsTr("PV Charger") +////// GuiMods — DarkMode + titleColor: !darkMode ? "#F4B350" : "#7A5928" + color: !darkMode ? "#F39C12" : "#794E09" + visible: hasDcSolar || showInactiveTiles + opacity: hasDcSolar ? 1 : disabledTileOpacity + +////// MODIFIED to show tanks & provide extra space if not + height: + { + var availableHeight = root.height - 3 - acLoadBox.height - 5 - (showTanksTemps ? bottomOffset + 3 : 5) + if (showDcAndAcSolar) + return ((availableHeight - 5) / 2) + 4 + else if (showDcSolar) + return availableHeight + else + return 0 + } + width: 148 + + anchors { + right: root.right; rightMargin: 10 + bottom: parent.bottom; bottomMargin: showTanksTemps ? bottomOffset + 3 : 5 + } + +////// moved sun icon here from OverviewSolarChager so it can be put below text, etc + MbIcon { + iconId: "overview-sun" + anchors { + bottom: parent.bottom + right: parent.right; rightMargin: 2 + } + opacity: 0.5 + visible: ! showDcAndAcSolar + } + +//////// modified to add power for individual PV charger info + values: + [ + TileText { + y: 8 + text: EnhFmt.formatVBusItem (sys.pvCharger.power) + font.pixelSize: 19 + }, + MarqueeEnhanced + { + y: pvOffset1 + id: pv1Name + // ofset left margin for this row if showing tanks/temps + width: + { + if (pvChargerCompact) + { + if (showTanksTemps) + return ((parent.width / 2) - 15) + else + return ((parent.width / 2) - 5) + } + else + return (parent.width - 10) + } + anchors.left: parent.left; anchors.leftMargin: (showTanksTemps && pvChargerCompact) ? 15 : 5 + height: 15 + text: pvName1.valid ? pvName1.value : "pv 1" + textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter + fontSize: 15 + Connections { target: scrollTimer; onTriggered: pv1Name.doScroll() } + scroll: false + visible: numberOfPvChargers >= 1 && ! showDcAndAcSolar + }, + TileText { + y: pvOffset1 + (pvChargerCompact ? 0 : pvRowSpacing) + text: EnhFmt.formatVBusItem (pvPower1, "W") + horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter + anchors.right: parent.right; anchors.rightMargin: 5 + font.pixelSize: 15 + visible: numberOfPvChargers >= 1 && ! showDcAndAcSolar + }, + TileText { + y: pvOffset1 + pvRowSpacing * (pvChargerCompact ? 1 : 2) + text: + { + var voltageText, currentText + if (root.numberOfPvChargers < 1) + return " " + else + { + if (pv1NrTrackers.valid && pv1NrTrackers.value > 1) + return qsTr ("multiple trackers") + else if (pvVoltage1.valid) + voltageText = EnhFmt.formatVBusItem (pvVoltage1, "V") + else + voltageText = "??V" + if (pvCurrent1.valid) + currentText = EnhFmt.formatVBusItem (pvCurrent1, "A") + else if (pvPower1.valid) + currentText = EnhFmt.formatValue ((pvPower1.value / pvVoltage1.value), "A") + else + currentText = "??A" + return voltageText + " " + currentText + } + } + font.pixelSize: 15 + visible: pvShowDetails && numberOfPvChargers >= 1 + }, + MarqueeEnhanced + { + y: pvOffset2 + id: pv2Name + width: pvChargerCompact ? ((parent.width / 2) - 5) : parent.width - 10 + anchors.left: parent.left; anchors.leftMargin: 5 + height: 15 + text: pvName2.valid ? pvName2.value : "pv 2" + textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter + fontSize: 15 + Connections { target: scrollTimer; onTriggered: pv2Name.doScroll() } + scroll: false + visible: numberOfPvChargers >= 2 && ! showDcAndAcSolar + }, + TileText { + y: pvOffset2 + (pvChargerCompact ? 0 : pvRowSpacing) + text: EnhFmt.formatVBusItem (pvPower2, "W") + horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter + anchors.right: parent.right; anchors.rightMargin: 5 + font.pixelSize: 15 + visible: numberOfPvChargers >= 2 && ! showDcAndAcSolar + }, + TileText { + y: pvOffset2 + pvRowSpacing * (pvChargerCompact ? 1 : 2) + text: + { + var voltageText, currentText + if (root.numberOfPvChargers < 2) + return " " + else + { + if (pv2NrTrackers.valid && pv2NrTrackers.value > 1) + return qsTr ("multiple trackers") + else if (pvVoltage2.valid) + voltageText = EnhFmt.formatVBusItem (pvVoltage2, "V") + else + voltageText = "??V" + if (pvCurrent2.valid) + currentText = EnhFmt.formatVBusItem (pvCurrent2, "A") + else if (pvPower2.valid) + currentText = EnhFmt.formatValue ((pvPower2.value / pvVoltage2.value), "A") + else + currentText = "??A" + return voltageText + " " + currentText + } + } + font.pixelSize: 15 + visible: pvShowDetails && numberOfPvChargers >= 2 + }, + MarqueeEnhanced + { + y: pvOffset3 + id: pv3Name + width: pvChargerCompact ? ((parent.width / 2) - 5) : parent.width - 10 + anchors.left: parent.left; anchors.leftMargin: 5 + height: 15 + text: pvName3.valid ? pvName3.value : "pv 3" + textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter + fontSize: 15 + Connections { target: scrollTimer; onTriggered: pv3Name.doScroll() } + scroll: false + visible: numberOfPvChargers >= 3 && ! showDcAndAcSolar + }, + TileText { + y: pvOffset3 + (pvChargerCompact ? 0 : pvRowSpacing) + text: EnhFmt.formatVBusItem (pvPower3, "W") + anchors.right: parent.right; anchors.rightMargin: 5 + horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter + font.pixelSize: 15 + visible: numberOfPvChargers >= 3 && ! showDcAndAcSolar + }, + TileText { + y: pvOffset3 + pvRowSpacing * (pvChargerCompact ? 1 : 2) + text: + { + var voltageText, currentText + if (root.numberOfPvChargers < 3) + return " " + else + { + if (pv3NrTrackers.valid && pv3NrTrackers.value > 1) + return qsTr ("multiple trackers") + else if (pvVoltage3.valid) + voltageText = EnhFmt.formatVBusItem (pvVoltage3, "V") + else + voltageText = "??V" + if (pvCurrent3.valid) + currentText = EnhFmt.formatVBusItem (pvCurrent3, "A") + else if (pvPower3.valid) + currentText = EnhFmt.formatValue ((pvPower3.value / pvVoltage3.value), "A") + else + currentText = "??A" + return voltageText + " " + currentText + } + } + font.pixelSize: 15 + visible: pvShowDetails && numberOfPvChargers >= 2 + }, + MarqueeEnhanced + { + y: pvOffset4 + id: pv4Name + // ofset left margin for this row if NOT showing tanks/temps + width: + { + if (pvChargerCompact) + { + if (! showTanksTemps) + return ((parent.width / 2) - 15) + else + return ((parent.width / 2) - 5) + } + else + return (parent.width - 10) + } + anchors.left: parent.left; anchors.leftMargin: ( ! showTanksTemps && pvChargerCompact) ? 15 : 5 + height: 15 + text: pvName4.valid ? pvName4.value : "pv 4" + textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter + fontSize: 15 + Connections { target: scrollTimer; onTriggered: pv4Name.doScroll() } + scroll: false + visible: numberOfPvChargers >= 4 && ! showDcAndAcSolar + }, + TileText { + y: pvOffset4 + (pvChargerCompact ? 0 : pvRowSpacing) + text: EnhFmt.formatVBusItem (pvPower4, "W") + anchors.right: parent.right; anchors.rightMargin: 5 + horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter + font.pixelSize: 15 + visible: numberOfPvChargers >= 4 && ! showDcAndAcSolar + }, + MarqueeEnhanced + { + y: pvOffset5 + id: pv5Name + width: pvChargerCompact ? ((parent.width / 2) - 5) : parent.width - 10 + anchors.left: parent.left; anchors.leftMargin: 5 + height: 15 + text: pvName5.valid ? pvName5.value : "pv 5" + textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter + fontSize: 15 + Connections { target: scrollTimer; onTriggered: pv5Name.doScroll() } + scroll: false + visible: numberOfPvChargers >= 5 && pvChargerRows >= 5 && ! showDcAndAcSolar + }, + TileText { + y: pvOffset5 + (pvChargerCompact ? 0 : pvRowSpacing) + text: EnhFmt.formatVBusItem (pvPower5, "W") + anchors.right: parent.right; anchors.rightMargin: 5 + horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter + font.pixelSize: 15 + visible: numberOfPvChargers >= 5 && pvChargerRows >= 5 && ! showDcAndAcSolar + }, + MarqueeEnhanced + { + y: pvOffset6 + id: pv6Name + width: pvChargerCompact ? ((parent.width / 2) - 5) : parent.width - 10 + anchors.left: parent.left; anchors.leftMargin: 5 + height: 15 + text: pvName6.valid ? pvName6.value : "pv 6" + textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter + fontSize: 15 + Connections { target: scrollTimer; onTriggered: pv6Name.doScroll() } + scroll: false + visible: numberOfPvChargers >= 6 && pvChargerRows >= 6 && ! showDcAndAcSolar + }, + TileText { + y: pvOffset6 + (pvChargerCompact ? 0 : pvRowSpacing) + text: EnhFmt.formatVBusItem (pvPower6, "W") + anchors.right: parent.right; anchors.rightMargin: 5 + horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter + font.pixelSize: 15 + visible: numberOfPvChargers >= 6 && pvChargerRows >= 6 && ! showDcAndAcSolar + }, + MarqueeEnhanced + { + y: pvOffset7 + id: pv7Name + width: pvChargerCompact ? ((parent.width / 2) - 5) : parent.width - 10 + anchors.left: parent.left; anchors.leftMargin: 5 + height: 15 + text: pvName7.valid ? pvName7.value : "pv 7" + textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter + fontSize: 15 + Connections { target: scrollTimer; onTriggered: pv6Name.doScroll() } + scroll: false + visible: numberOfPvChargers >= 7 && pvChargerRows >= 7 && ! showDcAndAcSolar + }, + TileText { + y: pvOffset7 + (pvChargerCompact ? 0 : pvRowSpacing) + text: EnhFmt.formatVBusItem (pvPower7, "W") + anchors.right: parent.right; anchors.rightMargin: 5 + horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter + font.pixelSize: 15 + visible: numberOfPvChargers >= 7 && pvChargerRows >= 7 && ! showDcAndAcSolar + } + ] +////// add power bar graph + PowerGauge + { + id: pvChargerBar + width: parent.width - (showDcAndAcSolar && ! showTanksTemps ? 20 : 0) + height: 10 + anchors + { + top: parent.top; topMargin: 19 + right: parent.right; rightMargin: 0.5 + } + connection: sys.pvCharger + maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvChargerMaxPower" + visible: showGauges && showDcSolar + } + DetailTarget { id: pvChargerTarget; detailsPage: "DetailPvCharger.qml" } + } + +////// replaced OverviewSolarInverter with OverviewBox + OverviewBox { + id: pvInverter + title: qsTr("PV Inverter") +////// GuiMods — DarkMode + titleColor: !darkMode ? "#F4B350" : "#7A5928" + color: !darkMode ? "#F39C12" : "#794E09" + visible: hasAcSolar || showInactiveTiles + opacity: hasAcSolar ? 1 : disabledTileOpacity + +////// MODIFIED to show tanks & provide extra space if not + height: + { + var availableHeight = root.height - 3 - acLoadBox.height -5 + availableHeight -= (showTanksTemps ? bottomOffset + 3 : 5) + if (showDcAndAcSolar) + availableHeight -= pvChargerBox.height + 5 + if (showAcSolar) + return availableHeight + else + return 0 + } + width: 148 + + anchors { + right: root.right; rightMargin: 10; + bottom: showDcAndAcSolar ? pvChargerBox.top : root.bottom + bottomMargin: showDcAndAcSolar ? 5 : showTanksTemps ? bottomOffset + 3 : 5 + } + + values: + [ + TileText { + id: coupledPvAc + + property double pvInverterOnAcOut: sys.pvOnAcOut.power.valid ? sys.pvOnAcOut.power.value : 0 + property double pvInverterOnAcIn1: sys.pvOnAcIn1.power.valid ? sys.pvOnAcIn1.power.value : 0 + property double pvInverterOnAcIn2: sys.pvOnAcIn2.power.valid ? sys.pvOnAcIn2.power.value : 0 + property bool powerValid: sys.pvOnAcOut.power.valid || sys.pvOnAcIn1.power.valid || sys.pvOnAcIn2.power.valid + + y: 10 + text: powerValid ? EnhFmt.formatValue (pvInverterOnAcOut + pvInverterOnAcIn1 + pvInverterOnAcIn2, "W") : "" + font.pixelSize: 19 + visible: showAcSolar + }, +//////// add individual PV inverter powers + TileText { + y: 31 + text: pvInverterName1.valid ? pvInverterName1.value : "-" + visible: !showDcAndAcSolar && numberOfPvInverters >= 2 + }, + TileText { + y: 47 + text: EnhFmt.formatVBusItem (pvInverterPower1, "W") + font.pixelSize: 15 + visible: !showDcAndAcSolar && numberOfPvInverters >= 2 + }, + TileText { + y: 63 + text: pvInverterName2.valid ? pvInverterName2.value : "-" + visible: !showDcAndAcSolar && numberOfPvInverters >= 2 + }, + TileText { + y: 77 + text: EnhFmt.formatVBusItem (pvInverterPower2, "W") + font.pixelSize: 15 + visible: !showDcAndAcSolar && numberOfPvInverters >= 2 + }, + TileText { + y: 93 + text: pvInverterName3.valid ? pvInverterName3.value : "-" + visible: !showDcAndAcSolar && numberOfPvInverters >=3 && ! showTanksTemps + }, + TileText { + y: 107 + text: EnhFmt.formatVBusItem (pvInverterPower3, "W") + font.pixelSize: 15 + visible: !showDcAndAcSolar && numberOfPvInverters >=3 && ! showTanksTemps + }, + TileText { + y: 31 + text: qsTr ("L1: ") + EnhFmt.formatVBusItem (pvInverterL1Power1, "W") + visible: !showDcAndAcSolar && numberOfPvInverters == 1 && pvInverterL1Power1.valid && (pvInverterL2Power1.valid || pvInverterL3Power1.valid) + }, + TileText { + y: 47 + text: qsTr ("L2: ") + EnhFmt.formatVBusItem (pvInverterL2Power1, "W") + visible: !showDcAndAcSolar && numberOfPvInverters == 1 && pvInverterL2Power1.valid + }, + TileText { + y: 63 + text: qsTr ("L3: ") + EnhFmt.formatVBusItem (pvInverterL3Power1, "W") + visible: !showDcAndAcSolar && numberOfPvInverters == 1 && pvInverterL3Power1.valid + } + ] +////// add power bar graph + PowerGauge + { + id: pvInverterBar + width: parent.width + height: 12 + anchors + { + top: parent.top; topMargin: 19 + horizontalCenter: parent.horizontalCenter + } + maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvOnOutputMaxPower" + maxForwardPowerParameter2: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvOnGridMaxPower" + connection: sys.pvOnAcOut + connection2: sys.pvOnGrid + visible: showGauges && showAcSolar + } + DetailTarget { id: pvInverterTarget; detailsPage: "DetailPvInverter.qml" } + } + + OverviewConnection { + id: acInToMulti + visible: showAcInput + ballCount: 2 + path: straight + active: root.active && showAcInput && showInverter + value: flow(sys.acInput ? sys.acInput.power : 0) + + anchors { + left: acInBox.right; leftMargin: -10 + right: multi.left; rightMargin: -10; bottom: acInBox.bottom; bottomMargin: 25 + } + } + + OverviewConnection { + id: multiToAcLoads + ballCount: 2 + path: straight + active: root.active && ( showAcLoads && showInverter ) + value: flow(sys.acLoad.power) + + anchors { + left: multi.right; leftMargin: -10; + right: acLoadBox.left; rightMargin: -10 + bottom: acLoadBox.bottom; bottomMargin: 8 + } + } + + OverviewConnection { + id: pvInverterToMulti + ballCount: 3 + path: corner + active: root.active && showAcSolar && showInverter + value: Utils.sign(noNoise(sys.pvOnAcOut.power) + noNoise(sys.pvOnAcIn1.power) + noNoise(sys.pvOnAcIn2.power)) + + anchors { + left: pvInverter.left; leftMargin: 8 + top: pvInverter.verticalCenter; topMargin: showDcAndAcSolar ? 10 : 0 + right: multi.horizontalCenter; rightMargin: -20 + bottom: multi.bottom; bottomMargin: 10 + } + } + + // invisible anchor point to connect the chargers to the battery + Item { + id: dcConnect + anchors { + left: multi.horizontalCenter; leftMargin: showAcSolar ? -20 : 0 + bottom: dcSystemBox.top; bottomMargin: showDcAndAcSolar ? 7 : 10 + } + } + + OverviewConnection + { + id: dcBus2 + ballCount: 2 + path: straight + active: root.active && ( showInverter || showDcSolar ) + value: -Utils.sign (noNoise (sys.pvCharger.power) + noNoise (sys.vebusDc.power)) + startPointVisible: false + endPointVisible: false + + anchors { + right: dcConnect.left + top: dcConnect.top + + left: multi.left; leftMargin: -10 + bottom: dcConnect.top + } + } + + OverviewConnection + { + id: alternatorToDcBus2 + ballCount: 3 + path: corner + active: root.active && showAlternator + value: Utils.sign (alternatorFlow) + endPointVisible: false + anchors + { + left: alternatorBox.right; leftMargin: -10 + top: alternatorBox.bottom; topMargin: -15 + + right: dcBus2.left + bottom: dcBus2.bottom + } + } + + OverviewConnection { + id: multiToDcConnect + ballCount: showTanksTemps ? 2 : 4 + path: straight + active: root.active && showInverter + value: -flow(sys.vebusDc.power); + startPointVisible: false + + anchors { + left: dcConnect.left + top: dcConnect.top + + right: dcConnect.left + bottom: multi.bottom; bottomMargin: 10 + } + } + + OverviewConnection { + id: pvChargerBoxDcConnect + ballCount: 3 + path: straight + active: root.active && showDcSolar + value: -flow(sys.pvCharger.power) + startPointVisible: false + + anchors { + left: dcConnect.left + top: dcConnect.top + + right: pvChargerBox.left; rightMargin: -8 + bottom: dcConnect.top; + } + } + + OverviewConnection { + id: batteryToDcBus2 + ballCount: 1 + path: straight + active: root.active && ( showInverter || showDcSolar ) + value: Utils.sign(noNoise(sys.pvCharger.power) + noNoise(sys.vebusDc.power) + alternatorFlow) + startPointVisible: false + + anchors { + left: dcBus2.left + top: dcBus2.top + + right: battery.right; rightMargin: 10 + bottom: dcBus2.top + } + } + + OverviewConnection { + id: batteryToDcSystem + ballCount: 2 + path: straight + active: root.active && showDcSystem + value: flow(sys.dcSystem.power) + + anchors { + left: battery.right; leftMargin: -10 + top: dcSystemBox.verticalCenter; + right: dcSystemBox.left; rightMargin: -10 + bottom: dcSystemBox.verticalCenter + } + } +////// moved order so it covers connections +////// moved to under Multi + OverviewEssReason { + anchors { + top: multi.bottom; topMargin: 7 + horizontalCenter: parent.horizontalCenter + } + } + +////// ADDED to show tanks & temps + // Synchronise tank name text scroll start and PV Charger name scroll + Timer + { + id: scrollTimer + interval: 15000 + repeat: true + running: root.active + } + ListView + { + id: tanksColum + + visible: showTanks + width: compact ? root.width : root.width * tankCount / tankTempCount + property int tileWidth: width / Math.min (count, 5.2) + height: root.tanksHeight + anchors + { + bottom: root.bottom + left: root.left + } + + // flickable list if more than will fit across bottom of screen + interactive: count > 4 ? true : false + orientation: ListView.Horizontal + + model: TankModel { id: tankModel } + delegate: TileTankEnhanced { + // Without an intermediate assignment this will trigger a binding loop warning. + property variant theService: DBusServices.get(buddy.id) + service: theService + width: tanksColum.tileWidth + height: root.tanksHeight + pumpBindPrefix: root.pumpBindPreffix + compact: root.compact + Connections { + target: scrollTimer + onTriggered: doScroll() + } + } + Tile { + title: qsTr("TANKS") + anchors.fill: parent + values: TileText { + text: qsTr("") + width: parent.width + wrapMode: Text.WordWrap + } + z: -1 + } + } + + ListView + { + id: tempsColumn + + visible: showTemps + width: compact ? root.width : root.width * tempCount / tankTempCount + property int tileWidth: width / Math.min (count, 5.2) + height: root.tanksHeight + anchors + { + bottom: root.bottom + bottomMargin: compact ? root.tanksHeight : 0 + right: root.right + } + + // make list flickable if more tiles than will fit completely + interactive: count > 4 ? true : false + orientation: ListView.Horizontal + + model: tempsModel + delegate: TileTemp + { + width: tempsColumn.tileWidth + height: tempsColumn.height + compact: root.compact + Connections + { + target: scrollTimer + onTriggered: doScroll() + } + } + Tile + { + title: qsTr("TEMPS") + anchors.fill: parent + values: TileText + { + text: qsTr("") + width: parent.width + wrapMode: Text.WordWrap + } + z: -1 + } + } + ListModel { id: tempsModel } + + // When new service is found add resources as appropriate + Connections + { + target: DBusServices + onDbusServiceFound: addService(service) + } + + // hack to get value(s) from within a loop inside a function when service is changing + property string tempServiceName: "" + property VBusItem temperatureItem: VBusItem { bind: Utils.path(tempServiceName, "/Dc/0/Temperature") } + + function addService(service) + { + switch (service.type) + { +//////// add for temp sensors + case DBusService.DBUS_SERVICE_TEMPERATURE_SENSOR: + numberOfTemps++ + tempsModel.append({serviceName: service.name}) + break;; + case DBusService.DBUS_SERVICE_MULTI: + hasInverter = true + root.tempServiceName = service.name + if (temperatureItem.valid && showBatteryTemp) + { + numberOfTemps++ + tempsModel.append({serviceName: service.name}) + } + break;; +//////// add for VE.Direct inverters + case DBusService.DBUS_SERVICE_INVERTER: + hasInverter = true + if (veDirectInverterService == "") + veDirectInverterService = service.name; + break;; + +//////// add for PV CHARGER voltage and current display + case DBusService.DBUS_SERVICE_SOLAR_CHARGER: + case DBusService.DBUS_SERVICE_MULTI_RS: + if ( service.type == DBusService.DBUS_SERVICE_MULTI_RS ) + hasInverter = true + numberOfPvChargers++ + if (numberOfPvChargers === 1) + pvChargerPrefix1 = service.name; + else if (numberOfPvChargers === 2) + pvChargerPrefix2 = service.name; + else if (numberOfPvChargers === 3) + pvChargerPrefix3 = service.name; + else if (numberOfPvChargers === 4) + pvChargerPrefix4 = service.name; + else if (numberOfPvChargers === 5) + pvChargerPrefix5 = service.name; + else if (numberOfPvChargers === 6) + pvChargerPrefix6 = service.name; + else if (numberOfPvChargers === 7) + pvChargerPrefix7 = service.name; + break;; + +//////// add for PV INVERTER power display + case DBusService.DBUS_SERVICE_PV_INVERTER: + numberOfPvInverters++ + if (numberOfPvInverters === 1) + pvInverterPrefix1 = service.name; + else if (numberOfPvInverters === 2) + pvInverterPrefix2 = service.name; + else if (numberOfPvInverters === 3) + pvInverterPrefix3 = service.name; + break;; + case DBusService.DBUS_SERVICE_BATTERY: + root.tempServiceName = service.name + if (temperatureItem.valid && showBatteryTemp) + { + numberOfTemps++ + tempsModel.append({serviceName: service.name}) + } + break;; +//////// add for alternator + case DBusService.DBUS_SERVICE_ALTERNATOR: + numberOfAlternators++ + if (numberOfAlternators === 1) + alternatorPrefix1 = service.name; + else if (numberOfAlternators === 2) + alternatorPrefix2 = service.name; + break;; + } + } + + // Detect available services of interest + function discoverServices() + { + numberOfTemps = 0 + numberOfPvChargers = 0 + numberOfPvInverters = 0 + numberOfAlternators = 0 + veDirectInverterService = "" + hasInverter = false + pvChargerPrefix1 = "" + pvChargerPrefix2 = "" + pvChargerPrefix3 = "" + pvChargerPrefix4 = "" + pvChargerPrefix5 = "" + pvChargerPrefix6 = "" + pvChargerPrefix7 = "" + pvInverterPrefix1 = "" + pvInverterPrefix2 = "" + pvInverterPrefix3 = "" + alternatorPrefix1 = "" + alternatorPrefix2 = "" + tempsModel.clear() + for (var i = 0; i < DBusServices.count; i++) + { + addService(DBusServices.at(i)) + } + } + +// Details targets + + // help message shown when menu is first drawn + Rectangle + { + id: helpBox + color: "white" + width: multi.width + height: 32 +////// GuiMods — DarkMode + opacity: !darkMode ? 0.7 : 0.85 + anchors + { + top: multi.bottom; topMargin: 1 + horizontalCenter: root.horizontalCenter + } + visible: false + TileText + { + text: qsTr ( "Tap tile center for detail at any time" ) + color: "black" + anchors.fill: helpBox + wrapMode: Text.WordWrap + font.pixelSize: 12 + visible: parent.visible + } + } + + //// hard key handler + // used to press buttons when touch isn't available + // UP and DOWN buttons cycle through the list of touch areas + // "space" button is used to simulate a touch on the area + // target must be highlighted so that other uses of "space" + // will still occur + + // list of all details touchable areas + property variant targetList: + [ + acInputTarget, alternatorTarget, batteryTarget, + multiTarget, dcSystemTarget, + loadsOnOutputTarget, pvInverterTarget, pvChargerTarget + ] + + property int selectedTarget: 0 + + Timer + { + id: targetTimer + interval: 5000 + repeat: false + running: false + onTriggered: { hideAllTargets () } + } + + Keys.forwardTo: [keyHandler] + Item + { + id: keyHandler + Keys.onUpPressed: + { + nextTarget (-1) + event.accepted = true + } + + Keys.onDownPressed: + { + nextTarget (+1) + event.accepted = true + } + Keys.onSpacePressed: + { + if (targetTimer.running) + { + var foo // hack to make clicked() work + bar.clicked (foo) + event.accepted = true + } + else + event.accepted = false + } + } + // hack to make clicked() work + property variant bar: targetList[selectedTarget] + + function nextTarget (increment) + { + // make one pass through all possible targets to find an enabled one + // if found, that's the new selectedTarget, + // if not selectedTarget does not change + var newIndex = selectedTarget + for (var i = 0; i < targetList.length; i++) + { + if (( ! targetTimer.running || helpBox.visible) && targetList[newIndex].enabled) + { + highlightSelectedTarget () + return + } + newIndex += increment + if (newIndex >= targetList.length) + newIndex = 0 + else if (newIndex < 0) + newIndex = targetList.length - 1 + if (targetList[newIndex].enabled) + { + selectedTarget = newIndex + highlightSelectedTarget () + break + } + } + } + + function showHelp () + { + for (var i = 0; i < targetList.length; i++) + { + targetList[i].targetVisible = true + } + helpBox.visible = true + targetTimer.restart () + } + function hideAllTargets () + { + for (var i = 0; i < targetList.length; i++) + { + targetList[i].targetVisible = false + } + helpBox.visible = false + } + function highlightSelectedTarget () + { + for (var i = 0; i < targetList.length; i++) + { + if (targetList[i] == targetList[selectedTarget]) + targetList[i].targetVisible = true + else + targetList[i].targetVisible = false + } + helpBox.visible = false + targetTimer.restart () + } +} diff --git a/FileSets/v3.40~8/OverviewHubEnhanced.qml.orig b/FileSets/v3.34/OverviewHubEnhanced.qml.orig similarity index 100% rename from FileSets/v3.40~8/OverviewHubEnhanced.qml.orig rename to FileSets/v3.34/OverviewHubEnhanced.qml.orig diff --git a/FileSets/v3.34/OverviewMobileEnhanced.qml b/FileSets/v3.34/OverviewMobileEnhanced.qml index ea719476..a316f85d 120000 --- a/FileSets/v3.34/OverviewMobileEnhanced.qml +++ b/FileSets/v3.34/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.34/OverviewTanksTempsDigInputs.qml b/FileSets/v3.34/OverviewTanksTempsDigInputs.qml index 47c4f55e..3e684a7f 120000 --- a/FileSets/v3.34/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.34/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.34/PageGenerator.qml b/FileSets/v3.34/PageGenerator.qml deleted file mode 100644 index edad721c..00000000 --- a/FileSets/v3.34/PageGenerator.qml +++ /dev/null @@ -1,159 +0,0 @@ -//// changed total time to hours (from varilable format) - -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: generator - title: qsTr("Generator start/stop") - property string settingsBindPrefix - property string startStopBindPrefix - property alias startStopModel: _startStopModel - property VBusItem activeCondition: VBusItem { bind: Utils.path(startStopBindPrefix, "/RunningByCondition") } - property VBusItem generatorState: VBusItem { bind: Utils.path(startStopBindPrefix, "/State") } - property VBusItem runningTime: VBusItem { bind: Utils.path(startStopBindPrefix, "/Runtime") } - property VBusItem historicalData: VBusItem { bind: Utils.path(settingsBindPrefix, "/AccumulatedDaily") } - - FnGeneratorStates { - id: genState - } - -//// changed total time to hours (from varilable format) - function formatTime (time) - { - if (time >= 3600) - return (time / 3600).toFixed(0) + " h" - else - return (time / 60).toFixed(0) + " m" - } - - model: startStopModel - - function formatError(text, value) - { - return "#" + value.toString() + " " + text - } - - VisibleItemModel { - id: _startStopModel - - MbItemValue { - description: qsTr("State") - show: startStopBindPrefix === "com.victronenergy.generator.startstop0" - item.text: activeCondition.valid ? genState.getState(generatorState.value, activeCondition.value) : '---' - } - - MbItemOptions { - id: _gensetStatus - description: qsTr("Error") - bind: Utils.path(startStopBindPrefix, "/Error") - readonly: true - show: valid && startStopBindPrefix === "com.victronenergy.generator.startstop0" - possibleValues: [ - MbOption { description: qsTr("No error"); value: 0 }, - MbOption { description: formatError(qsTr("Remote switch control disabled"), 1); value: 1 }, - MbOption { description: formatError(qsTr("Generator in fault condition"), 2); value: 2 }, - MbOption { description: formatError(qsTr("Generator not detected at AC input"), 3); value: 3 } - ] - } - - MbItemValue { - description: qsTr("Run time") - item.text: runningTime.valid ? Utils.secondsToNoSecsString(runningTime.value) : "0" - show: generatorState.value in [1, 2, 3] // Running, Warm-up, Cool-down - } - - MbItemValue { - description: qsTr("Total run time") - item { - bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") - //// changed total time to hours (from varilable format) - text: formatTime (item.value - accumulatedTotalOffset.value) - } - VBusItem { - id: accumulatedTotalOffset - bind: Utils.path(settingsBindPrefix, "/AccumulatedTotalOffset") - } - } - - MbItemValue { - description: qsTr("Time to service") - show: item.valid - item { - bind: Utils.path(startStopBindPrefix, "/ServiceCounter") - text: qsTr("%1h").arg((item.value / 60 / 60).toFixed(0)) - } - } - - MbItemValue { - description: qsTr("Accumulated running time since last test run") - show: user.accessLevel >= User.AccessService && nextTestRun.show - backgroundColor: style.backgroundColorService - item { - text: Utils.secondsToNoSecsString(item.value) - bind: Utils.path(startStopBindPrefix, "/TestRunIntervalRuntime") - } - } - - MbItemValue { - id: nextTestRun - description: qsTr("Time to next test run") - show: item.valid && item.value > 0 - item { - text: { - var remainingTime = item.value - new Date().getTime() / 1000 - if (remainingTime > 0) - return Utils.secondsToNoSecsString(remainingTime).toString() - return qsTr("Running now") - } - bind: Utils.path(startStopBindPrefix, "/NextTestRun") - } - } - - MbSwitch { - name: qsTr("Auto start functionality") - bind: Utils.path(startStopBindPrefix, "/AutoStartEnabled") - show: startStopBindPrefix === "com.victronenergy.generator.startstop0" - } - - MbSubMenu { - description: qsTr("Manual start") - show: startStopBindPrefix === "com.victronenergy.generator.startstop0" - subpage: - Component { - PageGeneratorManualStart { - startStopBindPrefix: generator.startStopBindPrefix - } - } - } - - MbSubMenu { - description: qsTr("Daily run time") - subpage: MbPage { - // Invert the order - property variant keys: historicalData.valid ? - Object.keys(JSON.parse(historicalData.value)).reverse() : 0 - - title: qsTr("Daily run time") - focus: active - model: keys - delegate: MbItemValue { - description: Qt.formatDate(new Date(parseInt(keys[index]) * 1000), "dd-MM-yyyy"); - item.text: Utils.secondsToNoSecsString(JSON.parse(historicalData.value)[keys[index]]) - } - } - } - - MbSubMenu { - id: conditions - description: qsTr("Settings") - subpage: Component { - PageSettingsGenerator { - settingsBindPrefix: generator.settingsBindPrefix - startStopBindPrefix: generator.startStopBindPrefix - } - } - } - } -} diff --git a/FileSets/v3.34/PageGenerator.qml b/FileSets/v3.34/PageGenerator.qml new file mode 120000 index 00000000..4c7f9a19 --- /dev/null +++ b/FileSets/v3.34/PageGenerator.qml @@ -0,0 +1 @@ +../v3.40/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.34/PageSettingsGenerator.qml b/FileSets/v3.34/PageSettingsGenerator.qml index 15dd8f85..2cb42f6b 120000 --- a/FileSets/v3.34/PageSettingsGenerator.qml +++ b/FileSets/v3.34/PageSettingsGenerator.qml @@ -1 +1 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file +../v3.40/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.34/PageSettingsGuiMods.qml b/FileSets/v3.34/PageSettingsGuiMods.qml index e831a7a4..191ce2c0 120000 --- a/FileSets/v3.34/PageSettingsGuiMods.qml +++ b/FileSets/v3.34/PageSettingsGuiMods.qml @@ -1 +1 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file +../v3.40/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.34/PageSettingsRelay.qml b/FileSets/v3.34/PageSettingsRelay.qml index 156aadac..f3f8e29c 120000 --- a/FileSets/v3.34/PageSettingsRelay.qml +++ b/FileSets/v3.34/PageSettingsRelay.qml @@ -1 +1 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file +../v3.40/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.34/PowerGauge.qml b/FileSets/v3.34/PowerGauge.qml deleted file mode 120000 index cfdf038d..00000000 --- a/FileSets/v3.34/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.34/PowerGauge.qml b/FileSets/v3.34/PowerGauge.qml new file mode 100644 index 00000000..fb5c55f2 --- /dev/null +++ b/FileSets/v3.34/PowerGauge.qml @@ -0,0 +1,320 @@ +// displays value as a bar surrounded by three range regions +// use for I/O, PV inverter & charger + +import QtQuick 1.1 +import "utils.js" as Utils +import com.victron.velib 1.0 + +Item { + id: root + +////// GuiMods — DarkMode + property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } + property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 + + property variant connection + // connection2 accommodates combined PV inverter AC input and AC output + property variant connection2: undefined + property bool includeConnection2: connection2 != undefined + + property bool reversePower: false + property bool useInputCurrentLimit: false + property variant endLabelFontSize: 16 + property color endLabelBackgroundColor: "transparent" + + property int reportedPhaseCount1: connection == undefined ? 0 : connection.phaseCount == undefined || ! connection.phaseCount.valid ? 1 : connection.phaseCount.value + property int phaseCount1: reportedPhaseCount1 < 2 ? reportedPhaseCount1 : (connection.isAcOutput ? connection.l2AndL1OutSummed : connection.splitPhaseL2PassthruDisabled) ? 1 : connection.phaseCount.value + + property int reportedPhaseCount2: connection2 == undefined ? 0 : connection2.phaseCount == undefined || ! connection2.phaseCount.valid ? 1 : connection2.phaseCount.value + property int phaseCount2: reportedPhaseCount2 < 2 ? reportedPhaseCount2 : (connection2.isAcOutput ? connection2.l2AndL1OutSummed : connection2.splitPhaseL2PassthruDisabled) ? 1 : connection2.phaseCount.value + + property int phaseCount: includeConnection2 ? Math.max (phaseCount1, phaseCount2) : phaseCount1 + + property string maxForwardPowerParameter: "" + VBusItem { id: maxForwardLimitItem; bind: root.maxForwardPowerParameter } + property string maxForwardPowerParameter2: "" + VBusItem { id: maxForwardLimitItem2; bind: root.maxForwardPowerParameter2 } + + property string maxReversePowerParameter: "" + VBusItem { id: maxReverseLimitItem; bind: root.maxReversePowerParameter } + + property real inPowerLimit: sys.acInput.inCurrentLimit.valid ? sys.acInput.inCurrentLimit.value * sys.acInput.voltageL1.value : 0 + + property real maxForwardPower1: maxForwardLimitItem.valid ? maxForwardLimitItem.value : 0 + property real maxForwardPower2: maxForwardLimitItem2.valid ? maxForwardLimitItem2.value : 0 + property real maxForwardLimit: useInputCurrentLimit ? inPowerLimit : maxForwardPower1 + maxForwardPower2 + property real maxReverseLimit: maxReverseLimitItem.valid ? maxReverseLimitItem.value : 0 + // overload range is 10% of forward to reverse limits + property real overload: (maxForwardLimit + maxReverseLimit) * 0.1 + property real maxForwardDisplayed: maxForwardLimit > 0 ? maxForwardLimit + overload : 0 + property real maxReverseDisplayed: maxReverseLimit > 0 ? maxReverseLimit + overload : 0 + property real totalPowerDisplayed: maxForwardDisplayed + maxReverseDisplayed + + property bool showLabels: false + property variant endLabelColor: "white" + property real labelOffset: 15 + property real showLeftLabel: showGauge && showLabels && maxReverseLimit != 0 + property bool showRightLabel: showGauge && showLabels && maxForwardLimit != 0 + property int labelCount: (showLeftLabel ? 1 : 0) + (showRightLabel ? 1 : 0) + + property bool showGauge: root.connection != undefined && totalPowerDisplayed > 0 && phaseCount > 0 + property real scaleFactor: showGauge ? (root.width - (labelCount * labelOffset)) / totalPowerDisplayed : 0 + property real zeroOffset: showGauge ? ( maxReverseDisplayed * scaleFactor + (showLeftLabel ? labelOffset : 0 )) : 0 + + property int barSpacing: phaseCount > 0 ? Math.max (height / (phaseCount + 1), 2) : 0 + property int barHeight: barSpacing < 3 ? barSpacing : barSpacing - 1 + property int firstBarVertPos: (height - barSpacing * phaseCount) / 2 + property real bar1offset + property real bar2offset + property real bar3offset + + property color bar1color: "black" + property color bar2color: "black" + property color bar3color: "black" + + // left end label + Rectangle + { + anchors.fill: leftlabelText + color: endLabelBackgroundColor + visible: showLeftLabel + } + TileText + { + id: leftlabelText + text: "S" + color: endLabelColor + font.pixelSize: endLabelFontSize + width: labelOffset + anchors + { + verticalCenter: root.verticalCenter + verticalCenterOffset: 1 + left: root.left + } + visible: showLeftLabel + } + // right end label + Rectangle + { + anchors.fill: rightLabelText + color: endLabelBackgroundColor + visible: showRightLabel + } + TileText + { + id: rightLabelText + text: "C" + color: endLabelColor + font.pixelSize: endLabelFontSize + width: labelOffset + anchors + { + verticalCenter: leftlabelText.verticalCenter + right: root.right + } + visible: showRightLabel + } + // overload range Left + Rectangle + { + id: overloadLeft + width: showGauge ? scaleFactor * (maxReverseDisplayed - maxReverseLimit) : 0 + height: root.height + clip: true +////// GuiMods — DarkMode + color: !darkMode ? "#ffb3b3" : "#bf8686" + visible: showGauge + anchors + { + top: root.top + left: root.left; leftMargin: showLeftLabel ? labelOffset : 0 + } + } + // OK range (both left and right in a single rectangle) + Rectangle + { + id: okRange + width: showGauge ? scaleFactor * (maxForwardLimit + maxReverseLimit) : 0 + height: root.height + clip: true +////// GuiMods — DarkMode + color: !darkMode ? "#99ff99" : "#73bf73" + visible: showGauge + anchors + { + top: root.top + left: overloadLeft.right + } + } + // overload range right + Rectangle + { + id: overloadRight + width: showGauge ? scaleFactor * (maxForwardDisplayed - maxForwardLimit) : 0 + height: root.height + clip: true +////// GuiMods — DarkMode + color: !darkMode ? "#ffb3b3" : "#bf8686" + visible: showGauge + anchors + { + top: root.top + left: okRange.right + } + } + + // actual bars + Rectangle + { + id: bar1 + width: phaseCount >= 1 ? calculateBar1width () : 0 + height: barHeight + clip: true + color: root.bar1color + anchors + { + top: root.top; topMargin: firstBarVertPos + left: root.left; leftMargin: root.bar1offset + + } + visible: showGauge && phaseCount >= 1 + } + Rectangle + { + id: bar2 + width: phaseCount >= 2 ? calculateBar2width () : 0 + height: barHeight + clip: true + color: root.bar2color + anchors + { + top: root.top; topMargin: firstBarVertPos + barSpacing + left: root.left; leftMargin: root.bar2offset + } + visible: showGauge && phaseCount >= 2 + } + Rectangle + { + id: bar3 + width: phaseCount >= 3 ? calculateBar3width () : 0 + height: barHeight + clip: true + color: root.bar3color + anchors + { + top: root.top; topMargin: firstBarVertPos + barSpacing * 2 + left: root.left; leftMargin: root.bar3offset + } + visible: showGauge && phaseCount >= 3 + } + + // zero line - draw last so it's on top + Rectangle + { + id: zeroLine + width: 1 + height: root.height + clip: true + color: "black" + visible: showGauge && maxReverseLimit > 0 + anchors + { + top: root.top + left: root.left + leftMargin: zeroOffset + } + } + + function calculateBar1width () + { + var currentValue = 0.0, barWidth + if (root.connection.powerL1 != undefined) + currentValue += root.connection.powerL1.valid ? root.connection.powerL1.value : 0 + else if (root.connection.power != undefined) + currentValue += root.connection.power.valid ? root.connection.power.value : 0 + if (includeConnection2) + { + if (root.connection2.powerL1 != undefined) + currentValue += root.connection2.powerL1.valid ? root.connection2.powerL1.value : 0 + else if (root.connection2.power != undefined) + currentValue += root.connection2.power.valid ? root.connection2.power.value : 0 + } + + if (reversePower) + currentValue = -currentValue + + root.bar1color = getBarColor (currentValue) + barWidth = Math.min ( Math.max (currentValue, -maxReverseDisplayed), maxForwardDisplayed) * scaleFactor + // left of bar is at 0 point + if (barWidth >= 0) + { + root.bar1offset = zeroOffset + return barWidth + } + // RIGHT of bar is at 0 point + else + { + root.bar1offset = zeroOffset + barWidth + return -barWidth + } + } + function calculateBar2width () + { + var currentValue, barWidth + currentValue = root.connection.powerL2.valid ? root.connection.powerL2.value : 0 + if (includeConnection2) + currentValue += root.connection2.powerL2.valid ? root.connection2.powerL2.value : 0 + + if (reversePower) + currentValue = -currentValue + root.bar2color = getBarColor (currentValue) + barWidth = Math.min ( Math.max (currentValue, -maxReverseDisplayed), maxForwardDisplayed) * scaleFactor + // left of bar is at 0 point + if (barWidth >= 0) + { + root.bar2offset = zeroOffset + return barWidth + } + // RIGHT of bar is at 0 point + else + { + root.bar2offset = zeroOffset + barWidth + return -barWidth + } + } + function calculateBar3width () + { + var currentValue, barWidth + currentValue = root.connection.powerL3.valid ? root.connection.powerL3.value : 0 + if (includeConnection2) + currentValue += root.connection2.powerL3.valid ? root.connection2.powerL3.value : 0 + + if (reversePower) + currentValue = -currentValue + root.bar3color = getBarColor (currentValue) + barWidth = Math.min ( Math.max (currentValue, -maxReverseDisplayed), maxForwardDisplayed) * scaleFactor + // left of bar is at 0 point + if (barWidth >= 0) + { + root.bar3offset = zeroOffset + return barWidth + } + // RIGHT of bar is at 0 point + else + { + root.bar3offset = zeroOffset + barWidth + return -barWidth + } + } + + function getBarColor (currentValue) + { + if (currentValue > maxForwardLimit || currentValue < -maxReverseLimit) +////// GuiMods — DarkMode + return !darkMode ? "#ff0000" : "#bf0000" + else +////// GuiMods — DarkMode + return !darkMode ? "#008000" : "#006000" + } +} diff --git a/FileSets/v3.40~8/PowerGauge.qml.orig b/FileSets/v3.34/PowerGauge.qml.orig similarity index 100% rename from FileSets/v3.40~8/PowerGauge.qml.orig rename to FileSets/v3.34/PowerGauge.qml.orig diff --git a/FileSets/v3.34/TileDigIn.qml b/FileSets/v3.34/TileDigIn.qml index 44616f30..5cd386d6 120000 --- a/FileSets/v3.34/TileDigIn.qml +++ b/FileSets/v3.34/TileDigIn.qml @@ -1 +1 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file +../v3.40/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.34/TileRelay.qml b/FileSets/v3.34/TileRelay.qml index 9f83152f..9a8e9d15 120000 --- a/FileSets/v3.34/TileRelay.qml +++ b/FileSets/v3.34/TileRelay.qml @@ -1 +1 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file +../v3.40/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.34/dbus_digitalinputs.py b/FileSets/v3.34/dbus_digitalinputs.py index e74da5b6..54c5335d 120000 --- a/FileSets/v3.34/dbus_digitalinputs.py +++ b/FileSets/v3.34/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file +../v3.40/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.34/dbus_generator.py b/FileSets/v3.34/dbus_generator.py index 0cd84ca3..fc553c91 120000 --- a/FileSets/v3.34/dbus_generator.py +++ b/FileSets/v3.34/dbus_generator.py @@ -1 +1 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file +../v3.40/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.34/startstop.py b/FileSets/v3.34/startstop.py deleted file mode 120000 index c18bce2d..00000000 --- a/FileSets/v3.34/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~37/startstop.py \ No newline at end of file diff --git a/FileSets/v3.34/startstop.py b/FileSets/v3.34/startstop.py new file mode 100644 index 00000000..fcb79154 --- /dev/null +++ b/FileSets/v3.34/startstop.py @@ -0,0 +1,1566 @@ +#!/usr/bin/python -u +# -*- coding: utf-8 -*- + +#### GuiMods +#### This file has been modified to allow the generator running state derived from the generator digital input +#### or the genset AC input +#### If the incoming generator state changes, the manual start state is updated +#### time accumulation is suspended when the generator is not running +#### A switch in the generator settings menucontrols whethter the incoming state affects manual start or time accumulaiton +#### It is now possible to start the generator manually and have it stop automatically based on the preset conditions +#### for automaitc start / stop +#### A service interval timer was added so the accumulated run time does not need to be reset, +#### providing total run time for the generator +#### warm-up and cool-down periods have been modified in order to work well with an external transfer switch +#### selecting grid or generator ahead of a MultiPlus input. +#### Search for #### GuiMods to find changes + +# Function +# dbus_generator monitors the dbus for batteries (com.victronenergy.battery.*) and +# vebus com.victronenergy.vebus.* +# Battery and vebus monitors can be configured through the gui. +# It then monitors SOC, AC loads, battery current and battery voltage,to auto start/stop the generator based +# on the configuration settings. Generator can be started manually or periodically setting a tes trun period. +# Time zones function allows to use different values for the conditions along the day depending on time + +import dbus +import datetime +import calendar +import time +import sys +import json +import os +import logging +from collections import OrderedDict +import monotonic_time +from gen_utils import SettingsPrefix, Errors, States, enum +from gen_utils import create_dbus_service +# Victron packages +sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) +from ve_utils import exit_on_error +from settingsdevice import SettingsDevice + +RunningConditions = enum( + Stopped = 0, + Manual = 1, + TestRun = 2, + LossOfCommunication = 3, + Soc = 4, + Acload = 5, + BatteryCurrent = 6, + BatteryVoltage = 7, + InverterHighTemp = 8, + InverterOverload = 9, + StopOnAc1 = 10, + StopOnAc2 = 11) + +Capabilities = enum( + WarmupCooldown = 1 +) + +SYSTEM_SERVICE = 'com.victronenergy.system' +BATTERY_PREFIX = '/Dc/Battery' +HISTORY_DAYS = 30 +AUTOSTART_DISABLED_ALARM_TIME = 600 + +def safe_max(args): + try: + return max(x for x in args if x is not None) + except ValueError: + return None + +class Condition(object): + def __init__(self, parent): + self.parent = parent + self.reached = False + self.start_timer = 0 + self.stop_timer = 0 + self.valid = True + self.enabled = False + self.retries = 0 + + def __getitem__(self, key): + try: + return getattr(self, key) + except AttributeError: + raise KeyError(key) + + def __setitem__(self, key, value): + setattr(self, key, value) + + def get_value(self): + raise NotImplementedError("get_value") + + @property + def vebus_service(self): + return self.parent._vebusservice if self.parent._vebusservice else '' + + @property + def monitor(self): + return self.parent._dbusmonitor + +class SocCondition(Condition): + name = 'soc' + monitoring = 'battery' + boolean = False + timed = True + + def get_value(self): + return self.parent._get_battery().soc + +class AcLoadCondition(Condition): + name = 'acload' + monitoring = 'vebus' + boolean = False + timed = True + + def get_value(self): + loadOnAcOut = [] + totalConsumption = [] + + for phase in ['L1', 'L2', 'L3']: + # Get the values directly from the inverter, systemcalc doesn't provide raw inverted power + loadOnAcOut.append(self.monitor.get_value(self.vebus_service, ('/Ac/Out/%s/P' % phase))) + + # Calculate total consumption, '/Ac/Consumption/%s/Power' is deprecated + c_i = self.monitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnInput/%s/Power' % phase)) + c_o = self.monitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnOutput/%s/Power' % phase)) + totalConsumption.append(sum(filter(None, (c_i, c_o)))) + + # Invalidate if vebus is not available + if loadOnAcOut[0] == None: + return None + + # Total consumption + if self.parent._settings['acloadmeasurement'] == 0: + return sum(filter(None, totalConsumption)) + + # Load on inverter AC out + if self.parent._settings['acloadmeasurement'] == 1: + return sum(filter(None, loadOnAcOut)) + + # Highest phase load + if self.parent._settings['acloadmeasurement'] == 2: + return safe_max(loadOnAcOut) + +class BatteryCurrentCondition(Condition): + name = 'batterycurrent' + monitoring = 'battery' + boolean = False + timed = True + + def get_value(self): + c = self.parent._get_battery().current + if c is not None: + c *= -1 + return c + +class BatteryVoltageCondition(Condition): + name = 'batteryvoltage' + monitoring = 'battery' + boolean = False + timed = True + + def get_value(self): + return self.parent._get_battery().voltage + +class InverterTempCondition(Condition): + name = 'inverterhightemp' + monitoring = 'vebus' + boolean = True + timed = True + + def get_value(self): + v = self.monitor.get_value(self.vebus_service, + '/Alarms/HighTemperature') + + # When multi is connected to CAN-bus, alarms are published to + # /Alarms/HighTemperature... but when connected to vebus alarms are + # splitted in three phases and published to /Alarms/LX/HighTemperature... + if v is None: + inverterHighTemp = [] + for phase in ['L1', 'L2', 'L3']: + # Inverter alarms must be fetched directly from the inverter service + inverterHighTemp.append(self.monitor.get_value(self.vebus_service, ('/Alarms/%s/HighTemperature' % phase))) + return safe_max(inverterHighTemp) + return v + +class InverterOverloadCondition(Condition): + name = 'inverteroverload' + monitoring = 'vebus' + boolean = True + timed = True + + def get_value(self): + v = self.monitor.get_value(self.vebus_service, + '/Alarms/Overload') + + # When multi is connected to CAN-bus, alarms are published to + # /Alarms/Overload... but when connected to vebus alarms are + # splitted in three phases and published to /Alarms/LX/Overload... + if v is None: + inverterOverload = [] + for phase in ['L1', 'L2', 'L3']: + # Inverter alarms must be fetched directly from the inverter service + inverterOverload.append(self.monitor.get_value(self.vebus_service, ('/Alarms/%s/Overload' % phase))) + return safe_max(inverterOverload) + return v + +class StopOnAc1Condition(Condition): + name = 'stoponac1' + monitoring = 'vebus' + boolean = True + timed = False + + def get_value(self): + # AC input 1 + available = self.monitor.get_value(self.vebus_service, + '/Ac/State/AcIn1Available') + if available is None: + # Not supported in firmware, fall back to old behaviour + activein = self.monitor.get_value(self.vebus_service, + '/Ac/ActiveIn/ActiveInput') + + # Active input is connected + connected = self.monitor.get_value(self.vebus_service, + '/Ac/ActiveIn/Connected') + if None not in (activein, connected): + return activein == 0 and connected == 1 + return None + + return bool(available) + +class StopOnAc2Condition(Condition): + name = 'stoponac2' + monitoring = 'vebus' + boolean = True + timed = False + + def get_value(self): + # AC input 2 available (used when grid is on AC-in-2) + available = self.monitor.get_value(self.vebus_service, + '/Ac/State/AcIn2Available') + + return None if available is None else bool(available) + +class Battery(object): + def __init__(self, monitor, service, prefix): + self.monitor = monitor + self.service = service + self.prefix = prefix + + @property + def voltage(self): + return self.monitor.get_value(self.service, self.prefix + '/Voltage') + + @property + def current(self): + return self.monitor.get_value(self.service, self.prefix + '/Current') + + @property + def soc(self): + # Soc from the device doesn't have the '/Dc/0' prefix like the current and voltage do, but it does + # have the same prefix on systemcalc + return self.monitor.get_value(self.service, (BATTERY_PREFIX if self.prefix == BATTERY_PREFIX else '') + '/Soc') + +class StartStop(object): + _driver = None + def __init__(self, instance): +#### GuiMods + logging.info ("GuiMods version of startstop.py") + self._currentTime = 0 + self._last_update_mtime = 0 + self._accumulatedRunTime = 0 + self._digitalInputTypeObject = None + self._generatorInputStateObject = 0 + self._lastState = 0 + self._externalOverride = False + self._externalOverrideDelay = 99 + self._lastExternalOverride = False + self._searchDelay = 99 + self._linkToExternalState = False +#### GuiMods warm-up / cool-down + self._warmUpEndTime = 0 + self._coolDownEndTime = 0 + self._ac1isIgnored = False + self._ac2isIgnored = False + self._activeAcInIsIgnored = False + self._acInIsGenerator = False + + self._dbusservice = None + self._settings = None + self._dbusmonitor = None + self._remoteservice = None + self._name = None + self._enabled = False + self._instance = instance + + # One second per retry + self.RETRIES_ON_ERROR = 300 + self._testrun_soc_retries = 0 + self._last_counters_check = 0 + + self._starttime = 0 + self._stoptime = 0 # Used for cooldown + self._manualstarttimer = 0 + self._last_runtime_update = 0 + self._timer_runnning = 0 + + # The installer left autostart disabled + self._autostart_last_time = self._get_monotonic_seconds() + self._remote_start_mode_last_time = self._get_monotonic_seconds() + + + # Manual battery service selection is deprecated in favour + # of getting the values directly from systemcalc, we keep + # manual selected services handling for compatibility reasons. + self._vebusservice = None + self._errorstate = 0 + self._battery_service = None + self._battery_prefix = None + + self._acpower_inverter_input = { + 'timeout': 0, + 'unabletostart': False + } + + # Order is important. Conditions are evaluated in the order listed. + self._condition_stack = OrderedDict({ + SocCondition.name: SocCondition(self), + AcLoadCondition.name: AcLoadCondition(self), + BatteryCurrentCondition.name: BatteryCurrentCondition(self), + BatteryVoltageCondition.name: BatteryVoltageCondition(self), + InverterTempCondition.name: InverterTempCondition(self), + InverterOverloadCondition.name: InverterOverloadCondition(self), + StopOnAc1Condition.name: StopOnAc1Condition(self), + StopOnAc2Condition.name: StopOnAc2Condition(self) + }) + + def set_sources(self, dbusmonitor, settings, name, remoteservice): + self._settings = SettingsPrefix(settings, name) + self._dbusmonitor = dbusmonitor + self._remoteservice = remoteservice + self._name = name + + self.log_info('Start/stop instance created for %s.' % self._remoteservice) + self._remote_setup() + + def _create_service(self): + self._dbusservice = self._create_dbus_service() + + # The driver used for this start/stop service + self._dbusservice.add_path('/Type', value=self._driver) + # State: None = invalid, 0 = stopped, 1 = running, 2=Warm-up, 3=Cool-down + self._dbusservice.add_path('/State', value=None, gettextcallback=lambda p, v: States.get_description(v)) + # RunningByConditionCode: Numeric Companion to /RunningByCondition below, but + # also encompassing a Stopped state. + self._dbusservice.add_path('/RunningByConditionCode', value=None) + # Error + self._dbusservice.add_path('/Error', value=None, gettextcallback=lambda p, v: Errors.get_description(v)) + # Condition that made the generator start + self._dbusservice.add_path('/RunningByCondition', value=None) + # Runtime + self._dbusservice.add_path('/Runtime', value=None, gettextcallback=self._seconds_to_text) + # Today runtime + self._dbusservice.add_path('/TodayRuntime', value=None, gettextcallback=self._seconds_to_text) + # Test run runtime + self._dbusservice.add_path('/TestRunIntervalRuntime', value=None , gettextcallback=self._seconds_to_text) + # Next test run date, values is 0 for test run disabled + self._dbusservice.add_path('/NextTestRun', value=None, gettextcallback=lambda p, v: datetime.datetime.fromtimestamp(v).strftime('%c')) + # Next test run is needed 1, not needed 0 + self._dbusservice.add_path('/SkipTestRun', value=None) + # Manual start + self._dbusservice.add_path('/ManualStart', value=None, writeable=True) + # Manual start timer + self._dbusservice.add_path('/ManualStartTimer', value=None, writeable=True) + # Silent mode active + self._dbusservice.add_path('/QuietHours', value=None) + # Alarms + self._dbusservice.add_path('/Alarms/NoGeneratorAtAcIn', value=None) + self._dbusservice.add_path('/Alarms/ServiceIntervalExceeded', value=None) + self._dbusservice.add_path('/Alarms/AutoStartDisabled', value=None) + self._dbusservice.add_path('/Alarms/RemoteStartModeDisabled', value=None) + # Autostart + self._dbusservice.add_path('/AutoStartEnabled', value=None, writeable=True, onchangecallback=self._set_autostart) + # Accumulated runtime + self._dbusservice.add_path('/AccumulatedRuntime', value=None) + # Service interval + self._dbusservice.add_path('/ServiceInterval', value=None) + # Capabilities, where we can add bits + self._dbusservice.add_path('/Capabilities', value=0) + # Service countdown, calculated by running time and service interval + self._dbusservice.add_path('/ServiceCounter', value=None) + self._dbusservice.add_path('/ServiceCounterReset', value=None, writeable=True, onchangecallback=self._reset_service_counter) + # Publish what service we're controlling, and the productid + self._dbusservice.add_path('/GensetService', value=self._remoteservice) + self._dbusservice.add_path('/GensetInstance', + value=self._dbusmonitor.get_value(self._remoteservice, '/DeviceInstance')) + self._dbusservice.add_path('/GensetProductId', + value=self._dbusmonitor.get_value(self._remoteservice, '/ProductId')) + + # We need to set the values after creating the paths to trigger the 'onValueChanged' event for the gui + # otherwise the gui will report the paths as invalid if we remove and recreate the paths without + # restarting the dbusservice. + self._dbusservice['/State'] = 0 + self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped + self._dbusservice['/Error'] = 0 + self._dbusservice['/RunningByCondition'] = '' + self._dbusservice['/Runtime'] = 0 + self._dbusservice['/TodayRuntime'] = 0 + self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) + self._dbusservice['/NextTestRun'] = None + self._dbusservice['/SkipTestRun'] = None + self._dbusservice['/ProductName'] = "Generator start/stop" + self._dbusservice['/ManualStart'] = 0 + self._dbusservice['/ManualStartTimer'] = 0 + self._dbusservice['/QuietHours'] = 0 + self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 + self._dbusservice['/Alarms/ServiceIntervalExceeded'] = 0 + self._dbusservice['/Alarms/AutoStartDisabled'] = 0 # GX auto start/stop + self._dbusservice['/Alarms/RemoteStartModeDisabled'] = 0 # Genset remote start mode + self._dbusservice['/AutoStartEnabled'] = self._settings['autostart'] + self._dbusservice['/AccumulatedRuntime'] = int(self._settings['accumulatedtotal']) + self._dbusservice['/ServiceInterval'] = int(self._settings['serviceinterval']) + self._dbusservice['/ServiceCounter'] = None + self._dbusservice['/ServiceCounterReset'] = 0 + +#### GuiMods + # generator input running state + self._dbusservice.add_path('/GeneratorRunningState', value=None) + # external override active + self._dbusservice.add_path('/ExternalOverride', value=None) + self._dbusservice['/GeneratorRunningState'] = "?" + self._dbusservice['/ExternalOverride'] = False + self._ignoreAutoStartCondition = False + + + @property + def capabilities(self): + return self._dbusservice['/Capabilities'] + + def _set_autostart(self, path, value): + if 0 <= value <= 1: + self._settings['autostart'] = int(value) + return True + return False + + def enable(self): + if self._enabled: + return + self.log_info('Enabling auto start/stop and taking control of remote switch') + self._create_service() + self._determineservices() + self._update_remote_switch() + # If cooldown or warmup is enabled, the Quattro may be left in a bad + # state if there is an unfortunate crash or a reboot. Set the ignore_ac + # flag to a sane value on startup. + if self._settings['cooldowntime'] > 0 or \ + self._settings['warmuptime'] > 0: + self._set_ignore_ac(False) ########### + self._enabled = True + + def disable(self): + if not self._enabled: + return + self.log_info('Disabling auto start/stop, releasing control of remote switch') + self._remove_service() + self._enabled = False + + def remove(self): + self.disable() + self.log_info('Removed from start/stop instances') + + def _remove_service(self): + self._dbusservice.__del__() + self._dbusservice = None + + def device_added(self, dbusservicename, instance): + self._determineservices() + + def device_removed(self, dbusservicename, instance): + self._determineservices() + + def get_error(self): + return self._dbusservice['/Error'] + + def set_error(self, errorn): + self._dbusservice['/Error'] = errorn + + def clear_error(self): + self._dbusservice['/Error'] = Errors.NONE + + def dbus_value_changed(self, dbusServiceName, dbusPath, options, changes, deviceInstance): + if self._dbusservice is None: + return + + # AcIn1Available is needed to determine capabilities, but may + # only show up later. So we have to wait for it here. + if self._vebusservice is not None and \ + dbusServiceName == self._vebusservice and \ + dbusPath == '/Ac/State/AcIn1Available': + self._set_capabilities() + + if dbusServiceName != 'com.victronenergy.system': + return + if dbusPath == '/AutoSelectedBatteryMeasurement' and self._settings['batterymeasurement'] == 'default': + self._determineservices() + + if dbusPath == '/VebusService': + self._determineservices() + + def handlechangedsetting(self, setting, oldvalue, newvalue): + if self._dbusservice is None: + return + if self._name not in setting: + # Not our setting + return + + s = self._settings.removeprefix(setting) + + if s == 'batterymeasurement': + self._determineservices() + # Reset retries and valid if service changes + for condition in self._condition_stack.values(): + if condition['monitoring'] == 'battery': + condition['valid'] = True + condition['retries'] = 0 + + if s == 'autostart': + self.log_info('Autostart function %s.' % ('enabled' if newvalue == 1 else 'disabled')) + self._dbusservice['/AutoStartEnabled'] = self._settings['autostart'] + + if self._dbusservice is not None and s == 'testruninterval': + self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime( + self._settings['testruninterval']) + + if s == 'serviceinterval': + try: + self._dbusservice['/ServiceInterval'] = int(newvalue) + except TypeError: + pass + if newvalue == 0: + self._dbusservice['/ServiceCounter'] = None + else: + self._update_accumulated_time() + if s == 'lastservicereset': + self._update_accumulated_time() + + def _reset_service_counter(self, path, value): + if (path == '/ServiceCounterReset' and value == int(1) and self._dbusservice['/AccumulatedRuntime']): + self._settings['lastservicereset'] = self._dbusservice['/AccumulatedRuntime'] + self._update_accumulated_time() + self.log_info('Service counter reset triggered.') + + return True + + def _seconds_to_text(self, path, value): + m, s = divmod(value, 60) + h, m = divmod(m, 60) + return '%dh, %dm, %ds' % (h, m, s) + + def log_info(self, msg): + logging.info(self._name + ': %s' % msg) + + def tick(self): + if not self._enabled: + return + +#### GuiMods warm-up / cool-down + self._currentTime = self._get_monotonic_seconds () + + self._check_remote_status() +#### GuiMods + self._linkToExternalState = self._settings['linkManualStartToExternal'] == 1 + self._processGeneratorRunDetection () + + self._evaluate_startstop_conditions() + self._evaluate_autostart_disabled_alarm() + self._detect_generator_at_acinput() + if self._dbusservice['/ServiceCounterReset'] == 1: + self._dbusservice['/ServiceCounterReset'] = 0 + +#### GuiMods warm-up / cool-down + state = self._dbusservice['/State'] + + # shed load for active generator input in warm-up and cool-down + # note that external transfer switch might change the state of on generator + # so this needs to be checked and load adjusted every pass + # restore load for sources no longer in use or if state is not in warm-up/cool-down + # restoring load is delayed 1following end of cool-down + # to allow the generator to actually stop producing power + if state in (States.WARMUP, States.COOLDOWN, States.STOPPING): + self._set_ignore_ac (True) + else: + self._set_ignore_ac (False) + + # update cool down end time while running and generator has the load + # this is done because acInIsGenerator may change by an external transfer switch + # and we want an accurate picture of the cool down end time + # based on the last time the generatot was loaded + if state == States.RUNNING and self._acInIsGenerator: + self._coolDownEndTime = self._currentTime + self._settings['cooldowntime'] +#### end GuiMods warm-up / cool-down + + + def _evaluate_startstop_conditions(self): + if self.get_error() != Errors.NONE: + # First evaluation after an error, log it + if self._errorstate == 0: + self._errorstate = 1 + self._dbusservice['/State'] = States.ERROR + self.log_info('Error: #%i - %s, stop controlling remote.' % + (self.get_error(), + Errors.get_description(self.get_error()))) + elif self._errorstate == 1: + # Error cleared + self._errorstate = 0 + self._dbusservice['/State'] = States.STOPPED + self.log_info('Error state cleared, taking control of remote switch.') + + start = False + startbycondition = None + activecondition = self._dbusservice['/RunningByCondition'] + today = calendar.timegm(datetime.date.today().timetuple()) + self._timer_runnning = False + connection_lost = False + running = self._dbusservice['/State'] in (States.RUNNING, States.WARMUP) + + self._check_quiet_hours() + + # New day, register it + if self._last_counters_check < today and self._dbusservice['/State'] == States.STOPPED: + self._last_counters_check = today + self._update_accumulated_time() + + # Update current and accumulated runtime. +#### GuiMods + self._accumulateRunTime () + +#### GuiMods + # A negative /ManualStartTimer is used by the GUI to signal the generator should start now + # but stop when all auto stop conditions have been met + # so we skip manual start evaluation if this is the case + # and set a flag for use below to ignore auto start conditions + # the generator is actually started by the auto start/stop logic below + if self._dbusservice['/ManualStartTimer'] < 0 and self._dbusservice['/ManualStart'] == 1: + self._dbusservice['/ManualStartTimer'] = 0 + self._dbusservice['/ManualStart'] = 0 + self._ignoreAutoStartCondition = True + + else: + self._ignoreAutoStartCondition = False + if self._evaluate_manual_start(): + startbycondition = 'manual' + start = True + + # Conditions will only be evaluated if the autostart functionality is enabled + if self._settings['autostart'] == 1: + + if self._evaluate_testrun_condition(): + startbycondition = 'testrun' + start = True + + # Evaluate stop on AC IN conditions first, when this conditions are enabled and reached the generator + # will stop as soon as AC IN in active. Manual and testrun conditions will make the generator start + # or keep it running. + stop_on_ac_reached = (self._evaluate_condition(self._condition_stack[StopOnAc1Condition.name]) or + self._evaluate_condition(self._condition_stack[StopOnAc2Condition.name])) + stop_by_ac1_ac2 = startbycondition not in ['manual', 'testrun'] and stop_on_ac_reached + + if stop_by_ac1_ac2 and running and activecondition not in ['manual', 'testrun']: + self.log_info('AC input available, stopping') + + # Evaluate value conditions + for condition, data in self._condition_stack.items(): + # Do not evaluate rest of conditions if generator is configured to stop + # when AC IN is available + if stop_by_ac1_ac2: + start = False + if running: + self._reset_condition(data) + continue + else: + break + + # Don't short-circuit this, _evaluate_condition sets .reached + start = self._evaluate_condition(data) or start + startbycondition = condition if start and startbycondition is None else startbycondition + # Connection lost is set to true if the number of retries of one or more enabled conditions + # >= RETRIES_ON_ERROR + if data.enabled: + connection_lost = data.retries >= self.RETRIES_ON_ERROR + + # If none condition is reached check if connection is lost and start/keep running the generator + # depending on '/OnLossCommunication' setting + if not start and connection_lost: + # Start always + if self._settings['onlosscommunication'] == 1: + start = True + startbycondition = 'lossofcommunication' + # Keep running if generator already started + if running and self._settings['onlosscommunication'] == 2: + start = True + startbycondition = 'lossofcommunication' + +#### GuiMods + ## auto start disabled and generator is stopped - clear the 'reached' flags + elif self._dbusservice['/State'] == States.STOPPED: + for condition, data in self._condition_stack.items(): + self._reset_condition(data) + + if not start and self._errorstate: + self._stop_generator() + + if self._errorstate: + return + + if start: + self._start_generator(startbycondition) +#### GuiMods + # bypass the minimum run time check if External Override is active + elif (self._dbusservice['/Runtime'] >= self._settings['minimumruntime'] * 60 + or activecondition == 'manual') or self._dbusservice['/ExternalOverride']: + self._stop_generator() + + def _evaluate_autostart_disabled_alarm(self): + + if self._settings['autostartdisabledalarm'] == 0: + self._autostart_last_time = self._get_monotonic_seconds() + self._remote_start_mode_last_time = self._get_monotonic_seconds() + if self._dbusservice['/Alarms/AutoStartDisabled'] != 0: + self._dbusservice['/Alarms/AutoStartDisabled'] = 0 + if self._dbusservice['/Alarms/RemoteStartModeDisabled'] != 0: + self._dbusservice['/Alarms/RemoteStartModeDisabled'] = 0 + return + + # GX auto start/stop alarm + if self._settings['autostart'] == 1: + self._autostart_last_time = self._get_monotonic_seconds() + if self._dbusservice['/Alarms/AutoStartDisabled'] != 0: + self._dbusservice['/Alarms/AutoStartDisabled'] = 0 + else: + timedisabled = self._get_monotonic_seconds() - self._autostart_last_time + if timedisabled > AUTOSTART_DISABLED_ALARM_TIME and self._dbusservice['/Alarms/AutoStartDisabled'] != 2: + self.log_info("Autostart was left for more than %i seconds, triggering alarm." % int(timedisabled)) + self._dbusservice['/Alarms/AutoStartDisabled'] = 2 + + # Genset remote start mode alarm + if self.get_error() != Errors.REMOTEDISABLED: + self._remote_start_mode_last_time = self._get_monotonic_seconds() + if self._dbusservice['/Alarms/RemoteStartModeDisabled'] != 0: + self._dbusservice['/Alarms/RemoteStartModeDisabled'] = 0 + else: + timedisabled = self._get_monotonic_seconds() - self._remote_start_mode_last_time + if timedisabled > AUTOSTART_DISABLED_ALARM_TIME and self._dbusservice['/Alarms/RemoteStartModeDisabled'] != 2: + self.log_info("Autostart was left for more than %i seconds, triggering alarm." % int(timedisabled)) + self._dbusservice['/Alarms/RemoteStartModeDisabled'] = 2 + + +#### GuiMods warm-up / cool-down - rewrote so acInIsGenerator is updated even if alarm is disabled + def _detect_generator_at_acinput(self): +#### GuiMods warm-up / cool-down + self._acInIsGenerator = False # covers all conditions that result in a return + + state = self._dbusservice['/State'] + if state in [States.STOPPED, States.COOLDOWN, States.WARMUP]: + self._reset_acpower_inverter_input() + return + + vebus_service = self._vebusservice if self._vebusservice else '' + activein_state = self._dbusmonitor.get_value( + vebus_service, '/Ac/ActiveIn/Connected') + + # Path not supported, skip evaluation + if activein_state == None: + return + + # Sources 0 = Not available, 1 = Grid, 2 = Generator, 3 = Shore + generator_acsource = self._dbusmonitor.get_value( + SYSTEM_SERVICE, '/Ac/ActiveIn/Source') == 2 + # Not connected = 0, connected = 1 + activein_connected = activein_state == 1 + +#### GuiMods warm-up / cool-down + if self._settings['nogeneratoratacinalarm'] == 0: + processAlarm = False + self._reset_acpower_inverter_input() + else: + processAlarm = True + + if generator_acsource and activein_connected: +#### GuiMods warm-up / cool-down + self._acInIsGenerator = True +#### GuiMods warm-up / cool-down + if processAlarm and self._acpower_inverter_input['unabletostart']: + self.log_info('Generator detected at inverter AC input, alarm removed') + self._reset_acpower_inverter_input() +#### GuiMods warm-up / cool-down + elif not processAlarm: + self._reset_acpower_inverter_input() + return + elif self._acpower_inverter_input['timeout'] < self.RETRIES_ON_ERROR: + self._acpower_inverter_input['timeout'] += 1 + elif not self._acpower_inverter_input['unabletostart']: + self._acpower_inverter_input['unabletostart'] = True + self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 2 + self.log_info('Generator not detected at inverter AC input, triggering alarm') + + + def _reset_acpower_inverter_input(self, clear_error=True): + if self._acpower_inverter_input['timeout'] != 0: + self._acpower_inverter_input['timeout'] = 0 + + if self._acpower_inverter_input['unabletostart'] != 0: + self._acpower_inverter_input['unabletostart'] = 0 + + self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 + + def _reset_condition(self, condition): + condition['reached'] = False + if condition['timed']: + condition['start_timer'] = 0 + condition['stop_timer'] = 0 + + def _check_condition(self, condition, value): + name = condition['name'] + + if self._settings[name + 'enabled'] == 0: + if condition['enabled']: + condition['enabled'] = False + self.log_info('Disabling (%s) condition' % name) + condition['retries'] = 0 + condition['valid'] = True + self._reset_condition(condition) + return False + + elif not condition['enabled']: + condition['enabled'] = True + self.log_info('Enabling (%s) condition' % name) + + if (condition['monitoring'] == 'battery') and (self._settings['batterymeasurement'] == 'nobattery'): + # If no battery monitor is selected reset the condition + self._reset_condition(condition) + return False + + if value is None and condition['valid']: + if condition['retries'] >= self.RETRIES_ON_ERROR: + logging.info('Error getting (%s) value, skipping evaluation till get a valid value' % name) + self._reset_condition(condition) + self._comunnication_lost = True + condition['valid'] = False + else: + condition['retries'] += 1 + if condition['retries'] == 1 or (condition['retries'] % 10) == 0: + self.log_info('Error getting (%s) value, retrying(#%i)' % (name, condition['retries'])) + return False + + elif value is not None and not condition['valid']: + self.log_info('Success getting (%s) value, resuming evaluation' % name) + condition['valid'] = True + condition['retries'] = 0 + + # Reset retries if value is valid + if value is not None and condition['retries'] > 0: + self.log_info('Success getting (%s) value, resuming evaluation' % name) + condition['retries'] = 0 + + return condition['valid'] + + def _evaluate_condition(self, condition): + name = condition['name'] + value = condition.get_value() + setting = ('qh_' if self._dbusservice['/QuietHours'] == 1 else '') + name + startvalue = self._settings[setting + 'start'] if not condition['boolean'] else 1 + stopvalue = self._settings[setting + 'stop'] if not condition['boolean'] else 0 + + # Check if the condition has to be evaluated + if not self._check_condition(condition, value): + # If generator is started by this condition and value is invalid + # wait till RETRIES_ON_ERROR to skip the condition + if condition['reached'] and condition['retries'] <= self.RETRIES_ON_ERROR: + if condition['retries'] > 0: + return True + + return False + + # As this is a generic evaluation method, we need to know how to compare the values + # first check if start value should be greater than stop value and then compare + start_is_greater = startvalue > stopvalue + +#### GuiMods + stop = value <= stopvalue if start_is_greater else value >= stopvalue + # when starting manually and stopping based on auto stop values, + # start if stop condition is not satisfied + + if self._ignoreAutoStartCondition: + start = not stop + else: + # When the condition is already reached only the stop value can set it to False + start = condition['reached'] or (value >= startvalue if start_is_greater else value <= startvalue) + + # Timed conditions must start/stop after the condition has been reached for a minimum + # time. + if condition['timed']: + if not condition['reached'] and start: + condition['start_timer'] += time.time() if condition['start_timer'] == 0 else 0 + start = time.time() - condition['start_timer'] >= self._settings[name + 'starttimer'] + condition['stop_timer'] *= int(not start) + self._timer_runnning = True + else: + condition['start_timer'] = 0 + + if condition['reached'] and stop: + condition['stop_timer'] += time.time() if condition['stop_timer'] == 0 else 0 + stop = time.time() - condition['stop_timer'] >= self._settings[name + 'stoptimer'] + condition['stop_timer'] *= int(not stop) + self._timer_runnning = True + else: + condition['stop_timer'] = 0 + + condition['reached'] = start and not stop + return condition['reached'] + + def _evaluate_manual_start(self): + if self._dbusservice['/ManualStart'] == 0: + if self._dbusservice['/RunningByCondition'] == 'manual': + self._dbusservice['/ManualStartTimer'] = 0 + return False + + start = True + # If /ManualStartTimer has a value greater than zero will use it to set a stop timer. + # If no timer is set, the generator will not stop until the user stops it manually. + # Once started by manual start, each evaluation the timer is decreased +#### GuiMods + if self._dbusservice['/ManualStartTimer'] > 0: + self._manualstarttimer += time.time() if self._manualstarttimer == 0 else 0 + self._dbusservice['/ManualStartTimer'] -= int(time.time()) - int(self._manualstarttimer) + self._manualstarttimer = time.time() + start = self._dbusservice['/ManualStartTimer'] > 0 + self._dbusservice['/ManualStart'] = int(start) + # Reset if timer is finished + self._manualstarttimer *= int(start) + self._dbusservice['/ManualStartTimer'] *= int(start) + + return start + + def _evaluate_testrun_condition(self): + if self._settings['testrunenabled'] == 0: + self._dbusservice['/SkipTestRun'] = None + self._dbusservice['/NextTestRun'] = None + return False + + today = datetime.date.today() + yesterday = today - datetime.timedelta(days=1) # Should deal well with DST + now = time.time() + runtillbatteryfull = self._settings['testruntillbatteryfull'] == 1 + soc = self._condition_stack['soc'].get_value() + batteryisfull = runtillbatteryfull and soc == 100 + duration = 60 if runtillbatteryfull else self._settings['testrunruntime'] + + try: + startdate = datetime.date.fromtimestamp(self._settings['testrunstartdate']) + _starttime = time.mktime(yesterday.timetuple()) + self._settings['testrunstarttimer'] + + # today might in fact still be yesterday, if this test run started + # before midnight and finishes after. If `now` still falls in + # yesterday's window, then by the temporal anthropic principle, + # which I just made up but loosely states that time must have + # these properties for observers to exist, it must be yesterday + # because we are here to observe it. + if _starttime <= now <= _starttime + duration: + today = yesterday + starttime = _starttime + else: + starttime = time.mktime(today.timetuple()) + self._settings['testrunstarttimer'] + except ValueError: + logging.debug('Invalid dates, skipping testrun') + return False + + # If start date is in the future set as NextTestRun and stop evaluating + if startdate > today: + self._dbusservice['/NextTestRun'] = time.mktime(startdate.timetuple()) + return False + + start = False + # If the accumulated runtime during the tes trun interval is greater than '/TestRunIntervalRuntime' + # the tes trun must be skipped + needed = (self._settings['testrunskipruntime'] > self._dbusservice['/TestRunIntervalRuntime'] + or self._settings['testrunskipruntime'] == 0) + self._dbusservice['/SkipTestRun'] = int(not needed) + + interval = self._settings['testruninterval'] + stoptime = starttime + duration + elapseddays = (today - startdate).days + mod = elapseddays % interval + + start = not bool(mod) and starttime <= now <= stoptime + + if runtillbatteryfull: + if soc is not None: + self._testrun_soc_retries = 0 + start = (start or self._dbusservice['/RunningByCondition'] == 'testrun') and not batteryisfull + elif self._dbusservice['/RunningByCondition'] == 'testrun': + if self._testrun_soc_retries < self.RETRIES_ON_ERROR: + self._testrun_soc_retries += 1 + start = True + if (self._testrun_soc_retries % 10) == 0: + self.log_info('Test run failed to get SOC value, retrying(#%i)' % self._testrun_soc_retries) + else: + self.log_info('Failed to get SOC after %i retries, terminating test run condition' % self._testrun_soc_retries) + start = False + else: + start = False + + if not bool(mod) and (now <= stoptime): + self._dbusservice['/NextTestRun'] = starttime + else: + self._dbusservice['/NextTestRun'] = (time.mktime((today + datetime.timedelta(days=interval - mod)).timetuple()) + + self._settings['testrunstarttimer']) + return start and needed + + def _check_quiet_hours(self): + active = False + if self._settings['quiethoursenabled'] == 1: + # Seconds after today 00:00 + timeinseconds = time.time() - time.mktime(datetime.date.today().timetuple()) + quiethoursstart = self._settings['quiethoursstarttime'] + quiethoursend = self._settings['quiethoursendtime'] + + # Check if the current time is between the start time and end time + if quiethoursstart < quiethoursend: + active = quiethoursstart <= timeinseconds and timeinseconds < quiethoursend + else: # End time is lower than start time, example Start: 21:00, end: 08:00 + active = not (quiethoursend < timeinseconds and timeinseconds < quiethoursstart) + + if self._dbusservice['/QuietHours'] == 0 and active: + self.log_info('Entering to quiet mode') + + elif self._dbusservice['/QuietHours'] == 1 and not active: + self.log_info('Leaving quiet mode') + + self._dbusservice['/QuietHours'] = int(active) + + return active + + def _update_accumulated_time(self): + seconds = self._dbusservice['/Runtime'] + accumulated = seconds - self._last_runtime_update + + self._settings['accumulatedtotal'] = accumulatedtotal = int(self._settings['accumulatedtotal']) + accumulated + # Using calendar to get timestamp in UTC, not local time + today_date = str(calendar.timegm(datetime.date.today().timetuple())) + + # If something goes wrong getting the json string create a new one + try: + accumulated_days = json.loads(self._settings['accumulateddaily']) + except ValueError: + accumulated_days = {today_date: 0} + + if (today_date in accumulated_days): + accumulated_days[today_date] += accumulated + else: + accumulated_days[today_date] = accumulated + + self._last_runtime_update = seconds + + # Keep the historical with a maximum of HISTORY_DAYS + while len(accumulated_days) > HISTORY_DAYS: + accumulated_days.pop(min(accumulated_days.keys()), None) + + # Upadate settings + self._settings['accumulateddaily'] = json.dumps(accumulated_days, sort_keys=True) + self._dbusservice['/TodayRuntime'] = self._interval_runtime(0) + self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) + self._dbusservice['/AccumulatedRuntime'] = accumulatedtotal + + # Service counter + serviceinterval = self._settings['serviceinterval'] + lastservicereset = self._settings['lastservicereset'] + if serviceinterval > 0: + servicecountdown = (lastservicereset + serviceinterval) - accumulatedtotal + self._dbusservice['/ServiceCounter'] = servicecountdown + if servicecountdown <= 0: + self._dbusservice['/Alarms/ServiceIntervalExceeded'] = 1 + elif self._dbusservice['/Alarms/ServiceIntervalExceeded'] != 0: + self._dbusservice['/Alarms/ServiceIntervalExceeded'] = 0 + + + + def _interval_runtime(self, days): + summ = 0 + try: + daily_record = json.loads(self._settings['accumulateddaily']) + except ValueError: + return 0 + + for i in range(days + 1): + previous_day = calendar.timegm((datetime.date.today() - datetime.timedelta(days=i)).timetuple()) + if str(previous_day) in daily_record.keys(): + summ += daily_record[str(previous_day)] if str(previous_day) in daily_record.keys() else 0 + + return summ + + def _get_battery(self): + if self._settings['batterymeasurement'] == 'default': + return Battery(self._dbusmonitor, SYSTEM_SERVICE, BATTERY_PREFIX) + + return Battery(self._dbusmonitor, + self._battery_service if self._battery_service else '', + self._battery_prefix if self._battery_prefix else '') + + def _set_capabilities(self): + # Update capabilities + # The ability to ignore AC1/AC2 came in at the same time as + # AC availability and is used to detect it here. + readout_supported = self._dbusmonitor.get_value(self._vebusservice, + '/Ac/State/AcIn1Available') is not None + self._dbusservice['/Capabilities'] |= ( + Capabilities.WarmupCooldown if readout_supported else 0) + + def _determineservices(self): + # batterymeasurement is either 'default' or 'com_victronenergy_battery_288/Dc/0'. + # In case it is set to default, we use the AutoSelected battery + # measurement, given by SystemCalc. + batterymeasurement = None + newbatteryservice = None + batteryprefix = '' + selectedbattery = self._settings['batterymeasurement'] + vebusservice = None + + if selectedbattery == 'default': + batterymeasurement = 'default' + elif len(selectedbattery.split('/', 1)) == 2: # Only very basic sanity checking.. + batterymeasurement = self._settings['batterymeasurement'] + elif selectedbattery == 'nobattery': + batterymeasurement = None + else: + # Exception: unexpected value for batterymeasurement + pass + + if batterymeasurement and batterymeasurement != 'default': + batteryprefix = '/' + batterymeasurement.split('/', 1)[1] + + # Get the current battery servicename + if self._battery_service: + oldservice = self._battery_service + else: + oldservice = None + + if batterymeasurement != 'default': + battery_instance = int(batterymeasurement.split('_', 3)[3].split('/')[0]) + service_type = None + + if 'vebus' in batterymeasurement: + service_type = 'vebus' + elif 'battery' in batterymeasurement: + service_type = 'battery' + + newbatteryservice = self._get_servicename_by_instance(battery_instance, service_type) + elif batterymeasurement == 'default': + newbatteryservice = 'default' + + if newbatteryservice and newbatteryservice != oldservice: + if selectedbattery == 'default': + self.log_info('Getting battery values from systemcalc.') + if selectedbattery == 'nobattery': + self.log_info('Battery monitoring disabled! Stop evaluating related conditions') + self._battery_service = None + self._battery_prefix = None + self.log_info('Battery service we need (%s) found! Using it for generator start/stop' % batterymeasurement) + self._battery_service = newbatteryservice + self._battery_prefix = batteryprefix + elif not newbatteryservice and newbatteryservice != oldservice: + self.log_info('Error getting battery service!') + self._battery_service = newbatteryservice + self._battery_prefix = batteryprefix + + # Get the default VE.Bus service + vebusservice = self._dbusmonitor.get_value('com.victronenergy.system', '/VebusService') + if vebusservice: + if self._vebusservice != vebusservice: + self._vebusservice = vebusservice + self._set_capabilities() + self.log_info('Vebus service (%s) found! Using it for generator start/stop' % vebusservice) + else: + if self._vebusservice is not None: + self.log_info('Vebus service (%s) dissapeared! Stop evaluating related conditions' % self._vebusservice) + else: + self.log_info('Error getting Vebus service!') + self._vebusservice = None + + def _get_servicename_by_instance(self, instance, service_type=None): + sv = None + services = self._dbusmonitor.get_service_list() + + for service in services: + if service_type and service_type not in service: + continue + + if services[service] == instance: + sv = service + break + + return sv + + def _get_monotonic_seconds(self): + return monotonic_time.monotonic_time().to_seconds_double() + + def _start_generator(self, condition): + state = self._dbusservice['/State'] + remote_running = self._get_remote_switch_state() + + # This function will start the generator in the case generator not + # already running. When differs, the RunningByCondition is updated + running = state in (States.WARMUP, States.COOLDOWN, States.STOPPING, States.RUNNING) + if not (running and remote_running): # STOPPED, ERROR +#### GuiMods warm-up / cool-down + self.log_info('Starting generator by %s condition' % condition) + # if there is a warmup time specified, always go through warm-up state + # regardless of AC input in use + warmUpPeriod = self._settings['warmuptime'] + if warmUpPeriod > 0: + self._warmUpEndTime = self._currentTime + warmUpPeriod + self.log_info ("starting warm-up") + self._dbusservice['/State'] = States.WARMUP + # no warm-up go directly to running + else: + self._dbusservice['/State'] = States.RUNNING + self._warmUpEndTime = 0 + + self._coolDownEndTime = 0 + self._stoptime = 0 + + self._update_remote_switch() + else: # WARMUP, COOLDOWN, RUNNING, STOPPING + if state in (States.COOLDOWN, States.STOPPING): + # Start request during cool-down run, go back to RUNNING + self.log_info ("aborting cool-down - returning to running") + self._dbusservice['/State'] = States.RUNNING + + elif state == States.WARMUP: + if self._currentTime > self._warmUpEndTime: + self.log_info ("warm-up complete") + self._dbusservice['/State'] = States.RUNNING + + # Update the RunningByCondition + if self._dbusservice['/RunningByCondition'] != condition: + self.log_info('Generator previously running by %s condition is now running by %s condition' + % (self._dbusservice['/RunningByCondition'], condition)) +#### end GuiMods warm-up / cool-down + + + self._dbusservice['/RunningByCondition'] = condition + self._dbusservice['/RunningByConditionCode'] = RunningConditions.lookup(condition) + + + def _stop_generator(self): + state = self._dbusservice['/State'] + remote_running = self._get_remote_switch_state() + running = state in (States.WARMUP, States.COOLDOWN, States.STOPPING, States.RUNNING) + + if running or remote_running: +#### GuiMods warm-up / cool-down + if state == States.RUNNING: + state = States.COOLDOWN + if self._currentTime < self._coolDownEndTime: + self.log_info ("starting cool-down") + elif self._settings['cooldowntime'] != 0: + self.log_info ("skipping cool-down -- no AC load on generator") + + # warm-up should also transition to stopping + # cool-down time will have expired since it's set to 0 when starting + # and there has not yet been a load on the generator + if state in (States.WARMUP, States.COOLDOWN): + # cool down complete + if self._currentTime > self._coolDownEndTime: + state = States.STOPPING + self.log_info('Stopping generator that was running by %s condition' % + str(self._dbusservice['/RunningByCondition'])) + self._update_remote_switch() # Stop engine + self._stoptime = self._currentTime + self._settings['generatorstoptime'] + if self._currentTime < self._stoptime: + self.log_info ("waiting for generator so stop") + + if state == States.STOPPING: + # wait for stop period expired - finish up transition to STOPPED + if self._currentTime > self._stoptime: + if self._settings['generatorstoptime'] != 0: + self.log_info ("generator stop time reached - OK to reconnect AC") + state = States.STOPPED + self._update_remote_switch() + self._dbusservice['/RunningByCondition'] = '' + self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped + self._update_accumulated_time() + self._starttime = 0 + self._dbusservice['/Runtime'] = 0 + self._dbusservice['/ManualStartTimer'] = 0 + self._manualstarttimer = 0 + self._last_runtime_update = 0 + + self._dbusservice['/State'] = state +#### end GuiMods warm-up / cool-down + + + @property + def _ac1_is_generator(self): + return self._dbusmonitor.get_value('com.victronenergy.settings', + '/Settings/SystemSetup/AcInput1') == 2 + + @property + def _ac2_is_generator(self): + return self._dbusmonitor.get_value('com.victronenergy.settings', + '/Settings/SystemSetup/AcInput2') == 2 + + def _set_ignore_ac(self, ignore): + # This is here so the Multi/Quattro can be told to disconnect AC-in, + # so that we can do warm-up and cool-down. +#### GuiMods warm-up / cool-down + # stock code does not handle changes in the input type + # which could happen with an external transfer switch + # doing things this way should handle it + + self._activeAcInIsIgnored = ignore + ignore1 = False + ignore2 = False + if self._ac1_is_generator: + ignore1 = ignore + elif self._ac2_is_generator: + ignore2 = ignore + + if ignore1 != self._ac1isIgnored: + if ignore1: + self.log_info ("shedding load - AC input 1") + else: + self.log_info ("restoring load - AC input 1") + self._dbusmonitor.set_value_async(self._vebusservice, '/Ac/Control/IgnoreAcIn1', dbus.Int32(ignore1, variant_level=1)) + self._ac1isIgnored = ignore1 + + if ignore2 != self._ac2isIgnored: + if ignore2: + self.log_info ("shedding load - AC input 2") + else: + self.log_info ("restoring load - AC input 2") + self._dbusmonitor.set_value_async(self._vebusservice, '/Ac/Control/IgnoreAcIn2', dbus.Int32(ignore2, variant_level=1)) + self._ac2isIgnored = ignore2 +#### end GuiMods warm-up / cool-down + + + def _update_remote_switch(self): + # Engine should be started in these states + v = self._dbusservice['/State'] in (States.RUNNING, States.WARMUP, States.COOLDOWN) + self._set_remote_switch_state(dbus.Int32(v, variant_level=1)) +#### GuiMods + if v == True: + self.log_info ("updating remote switch to running") + else: + self.log_info ("updating remote switch to stopped") + + def _get_remote_switch_state(self): + raise Exception('This function should be overridden') + + def _set_remote_switch_state(self, value): + raise Exception('This function should be overridden') + + # Check the remote status, for example errors + def _check_remote_status(self): + raise Exception('This function should be overridden') + + def _remote_setup(self): + raise Exception('This function should be overridden') + + def _create_dbus_monitor(self, *args, **kwargs): + raise Exception('This function should be overridden') + + def _create_settings(self, *args, **kwargs): + raise Exception('This function should be overridden') + + def _create_dbus_service(self): + return create_dbus_service(self._instance) + + +#### GuiMods + +# this function connects the generator digital input (if any) +# OR the generator AC input detection +# to the generator /ManualStart and updates dbus paths used by the GUI +# +# if the generator digital input changes from stopped to running +# AND no run conditions are active, a manual start is innitiated +# +# if the generator digital input changes from running to stopped +# AND a manual start is active, a manual stop is innitiated +# +# /GeneratorRunningState provides the input running state from the digital input to the GUI +# R = running +# S = stopped +# ? = unknown (no digital input found) +# +# /ExternalOverride is used by the GUI to alert the user when there is a conflict +# between the generator running state and the state Venus +# /ExternalOverride is True if /GeneratorRunningState is S +# AND the /RunningCondition is not stopped (which includes a manual run) +# activation is delayed 5 seconds to allow transitions to settle +# +# we must first find the geneator digital input, if it exists at all +# we serche all dBus services looking for a digital input with type generator (9) +# the search only occurs every 10 seconds +# + + def _processGeneratorRunDetection (self): + TheBus = dbus.SystemBus() + generatorState = self._dbusservice['/State'] + try: + # current input service is no longer valid + # search for a new one only every 10 seconds to avoid unnecessary processing + if (self._digitalInputTypeObject == None or self._digitalInputTypeObject.GetValue() != 9) and self._searchDelay > 10: + newInputService = "" + for service in TheBus.list_names(): + # found a digital input servic, now check the type + if service.startswith ("com.victronenergy.digitalinput"): + self._digitalInputTypeObject = TheBus.get_object (service, '/Type') + # found it! + if self._digitalInputTypeObject.GetValue() == 9: + newInputService = service + break + + # found new service - get objects for use later + if newInputService != "": + self.log_info ("Found generator digital input service at %s" % newInputService) + self._generatorInputStateObject = TheBus.get_object(newInputService, '/State') + else: + if self._generatorInputStateObject != None: + self.log_info ("Generator digital input service NOT found") + self._generatorInputStateObject = None + self._digitalInputTypeObject = None + self._searchDelay = 0 # start delay timer + + # if serch delay timer is active, increment it now + if self._searchDelay <= 10: + self._searchDelay += 1 + + + # collect generator input states + inputState = '?' + # if generator digital input is present, use that + if self._generatorInputStateObject != None: + inputState = self._generatorInputStateObject.GetValue () + if inputState == 10: + inputState = 'R' + elif inputState == 11: + inputState = 'S' + # otherwise use generator AC input to determine running state + # use frequency as the test for generator running + elif self._ac1_is_generator or self._ac2_is_generator: + try: + if self._dbusmonitor.get_value (SYSTEM_SERVICE, '/Ac/Genset/Frequency') > 20: + inputState = 'R' + else: + inputState = 'S' + except: + pass + + # update /GeneratorRunningState + if inputState != self._lastState: + self._dbusservice['/GeneratorRunningState'] = inputState + + # forward input state changes to /ManualStart + if self._linkToExternalState: + if inputState == "R" and generatorState == States.STOPPED: + self.log_info ("generator was started externally - syncing ManualStart state") + self._dbusservice['/ManualStart'] = 1 + elif inputState == "S" and self._dbusservice['/ManualStart'] == 1 \ + and generatorState in (States.RUNNING, States.WARMUP, States.COOLDOWN): + self.log_info ("generator was stopped externally - syncing ManualStart state") + self._dbusservice['/ManualStart'] = 0 + + # update /ExternalOverride + if inputState == "S" and self._linkToExternalState and generatorState == States.RUNNING: + if self._externalOverrideDelay > 5: + self._externalOverride = True + else: + self._externalOverrideDelay += 1 + else: + self._externalOverride = False + self._externalOverrideDelay = 0 + + if self._externalOverride != self._lastExternalOverride: + self._dbusservice['/ExternalOverride'] = self._externalOverride + self._lastExternalOverride = self._externalOverride + + except dbus.DBusException: + self.log_info ("dbus exception - generator digital input no longer valid") + self._generatorInputStateObject = None + self._digitalInputTypeObject = None + inputState = 0 + + self._lastState = inputState + + +# +# control the accumulaiton of run time based on generator input Running state +# if the internal state is RUNNING run time is accumulated in self._accumulatedRunTime +# run time is accumulated if the generator's running state is known to be running or +# if the generator running state can't be determined +# the accumulated time dBus parameter and daily and total time accumulators are updated +# only once everh 60 seconds to minimize processor load +# if the internal state is STOPPED, one last dBus, daily and total time updates are done +# then the current time accumulator is cleared + + def _accumulateRunTime (self): + + # grab running state from dBus once, use it many timed below + + if self._dbusservice['/State'] in (States.RUNNING, States.WARMUP, States.COOLDOWN, States.STOPPING): ########## + internalRun = True + else: + internalRun = False + + # if internal state is running, accumulate time if generator is running + if internalRun: + accumuateTime = True + # start new accumulation if not done prevously + if self._last_accumulate_time == 0: + self._last_accumulate_time = self._currentTime + + # if link to external state is enabled, don't accumulate time if running state is stopped + # (accumulate if R or ?) + if self._linkToExternalState: + try: + if self._dbusservice['/GeneratorRunningState'] == 'S': + accumuateTime = False + + # if no Forwarder service, allow accumulation + except dbus.DBusException: + self.log_info ("dBus exception in startstop.py") + + # internal state STOPPED so don't add new time to the accumulation + # but there may be time already accumulated that needs to be added to daily and total accumulations + else: + accumuateTime = False + + # accumulate run time if we passed all the tests above + if accumuateTime: + self._accumulatedRunTime += self._currentTime - self._last_accumulate_time + self._last_accumulate_time = self._currentTime + + # dbus and settings updates trigger time-intensive processing so only do this once every 60 seconds + doUpdate = False + if internalRun: + if self._currentTime - self._last_update_mtime >= 60: + doUpdate = True + self._last_update_mtime = self._currentTime + # it is also done one last time when state is no longer RUNNING + elif self._last_update_mtime != 0: + doUpdate = True + + if doUpdate: + self._update_accumulated_time() + + # stopped - clear the current time accumulator + if internalRun == False: + self._last_update_mtime = 0 + self._accumulatedRunTime = 0 + self._last_accumulate_time = 0 + + self._dbusservice['/Runtime'] = int(self._accumulatedRunTime) +#### end GuiMods diff --git a/FileSets/v3.40~37/startstop.py.orig b/FileSets/v3.34/startstop.py.orig similarity index 100% rename from FileSets/v3.40~37/startstop.py.orig rename to FileSets/v3.34/startstop.py.orig diff --git a/FileSets/v2.71/COMPLETE b/FileSets/v3.40/COMPLETE similarity index 100% rename from FileSets/v2.71/COMPLETE rename to FileSets/v3.40/COMPLETE diff --git a/FileSets/v3.40~13/DetailAcInput.qml b/FileSets/v3.40/DetailAcInput.qml similarity index 100% rename from FileSets/v3.40~13/DetailAcInput.qml rename to FileSets/v3.40/DetailAcInput.qml diff --git a/FileSets/v3.40~39/DetailAcInput.qml.orig b/FileSets/v3.40/DetailAcInput.qml.orig similarity index 100% rename from FileSets/v3.40~39/DetailAcInput.qml.orig rename to FileSets/v3.40/DetailAcInput.qml.orig diff --git a/FileSets/v3.40~13/DetailInverter.qml b/FileSets/v3.40/DetailInverter.qml similarity index 100% rename from FileSets/v3.40~13/DetailInverter.qml rename to FileSets/v3.40/DetailInverter.qml diff --git a/FileSets/v3.40~39/DetailInverter.qml.orig b/FileSets/v3.40/DetailInverter.qml.orig similarity index 100% rename from FileSets/v3.40~39/DetailInverter.qml.orig rename to FileSets/v3.40/DetailInverter.qml.orig diff --git a/FileSets/v3.40~13/DetailLoadsCombined.qml b/FileSets/v3.40/DetailLoadsCombined.qml similarity index 100% rename from FileSets/v3.40~13/DetailLoadsCombined.qml rename to FileSets/v3.40/DetailLoadsCombined.qml diff --git a/FileSets/v3.40~39/DetailLoadsCombined.qml.orig b/FileSets/v3.40/DetailLoadsCombined.qml.orig similarity index 100% rename from FileSets/v3.40~39/DetailLoadsCombined.qml.orig rename to FileSets/v3.40/DetailLoadsCombined.qml.orig diff --git a/FileSets/v3.40~13/DetailLoadsOnInput.qml b/FileSets/v3.40/DetailLoadsOnInput.qml similarity index 100% rename from FileSets/v3.40~13/DetailLoadsOnInput.qml rename to FileSets/v3.40/DetailLoadsOnInput.qml diff --git a/FileSets/v3.40~39/DetailLoadsOnInput.qml.orig b/FileSets/v3.40/DetailLoadsOnInput.qml.orig similarity index 100% rename from FileSets/v3.40~39/DetailLoadsOnInput.qml.orig rename to FileSets/v3.40/DetailLoadsOnInput.qml.orig diff --git a/FileSets/v3.40~13/DetailLoadsOnOutput.qml b/FileSets/v3.40/DetailLoadsOnOutput.qml similarity index 100% rename from FileSets/v3.40~13/DetailLoadsOnOutput.qml rename to FileSets/v3.40/DetailLoadsOnOutput.qml diff --git a/FileSets/v3.40~39/DetailLoadsOnOutput.qml.orig b/FileSets/v3.40/DetailLoadsOnOutput.qml.orig similarity index 100% rename from FileSets/v3.40~39/DetailLoadsOnOutput.qml.orig rename to FileSets/v3.40/DetailLoadsOnOutput.qml.orig diff --git a/FileSets/v3.40~39/HubData.qml b/FileSets/v3.40/HubData.qml similarity index 100% rename from FileSets/v3.40~39/HubData.qml rename to FileSets/v3.40/HubData.qml diff --git a/FileSets/v3.40~39/HubData.qml.orig b/FileSets/v3.40/HubData.qml.orig similarity index 100% rename from FileSets/v3.40~39/HubData.qml.orig rename to FileSets/v3.40/HubData.qml.orig diff --git a/FileSets/v3.40~39/ObjectAcConnection.qml b/FileSets/v3.40/ObjectAcConnection.qml similarity index 100% rename from FileSets/v3.40~39/ObjectAcConnection.qml rename to FileSets/v3.40/ObjectAcConnection.qml diff --git a/FileSets/v3.40~39/ObjectAcConnection.qml.orig b/FileSets/v3.40/ObjectAcConnection.qml.orig similarity index 100% rename from FileSets/v3.40~39/ObjectAcConnection.qml.orig rename to FileSets/v3.40/ObjectAcConnection.qml.orig diff --git a/FileSets/v3.40~39/OverviewAcValuesEnhanced.qml b/FileSets/v3.40/OverviewAcValuesEnhanced.qml similarity index 100% rename from FileSets/v3.40~39/OverviewAcValuesEnhanced.qml rename to FileSets/v3.40/OverviewAcValuesEnhanced.qml diff --git a/FileSets/v3.40~39/OverviewAcValuesEnhanced.qml.orig b/FileSets/v3.40/OverviewAcValuesEnhanced.qml.orig similarity index 100% rename from FileSets/v3.40~39/OverviewAcValuesEnhanced.qml.orig rename to FileSets/v3.40/OverviewAcValuesEnhanced.qml.orig diff --git a/FileSets/v3.40~39/OverviewFlowComplex.qml b/FileSets/v3.40/OverviewFlowComplex.qml similarity index 100% rename from FileSets/v3.40~39/OverviewFlowComplex.qml rename to FileSets/v3.40/OverviewFlowComplex.qml diff --git a/FileSets/v3.40~39/OverviewFlowComplex.qml.orig b/FileSets/v3.40/OverviewFlowComplex.qml.orig similarity index 100% rename from FileSets/v3.40~39/OverviewFlowComplex.qml.orig rename to FileSets/v3.40/OverviewFlowComplex.qml.orig diff --git a/FileSets/v3.40~21/OverviewGeneratorEnhanced.qml b/FileSets/v3.40/OverviewGeneratorEnhanced.qml similarity index 100% rename from FileSets/v3.40~21/OverviewGeneratorEnhanced.qml rename to FileSets/v3.40/OverviewGeneratorEnhanced.qml diff --git a/FileSets/v3.34/OverviewGeneratorEnhanced.qml.orig b/FileSets/v3.40/OverviewGeneratorEnhanced.qml.orig similarity index 100% rename from FileSets/v3.34/OverviewGeneratorEnhanced.qml.orig rename to FileSets/v3.40/OverviewGeneratorEnhanced.qml.orig diff --git a/FileSets/v3.40~39/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40/OverviewGeneratorRelayEnhanced.qml similarity index 100% rename from FileSets/v3.40~39/OverviewGeneratorRelayEnhanced.qml rename to FileSets/v3.40/OverviewGeneratorRelayEnhanced.qml diff --git a/FileSets/v3.40~39/OverviewGeneratorRelayEnhanced.qml.orig b/FileSets/v3.40/OverviewGeneratorRelayEnhanced.qml.orig similarity index 100% rename from FileSets/v3.40~39/OverviewGeneratorRelayEnhanced.qml.orig rename to FileSets/v3.40/OverviewGeneratorRelayEnhanced.qml.orig diff --git a/FileSets/v3.40~39/OverviewGridParallel.qml b/FileSets/v3.40/OverviewGridParallel.qml similarity index 100% rename from FileSets/v3.40~39/OverviewGridParallel.qml rename to FileSets/v3.40/OverviewGridParallel.qml diff --git a/FileSets/v3.40~39/OverviewGridParallel.qml.orig b/FileSets/v3.40/OverviewGridParallel.qml.orig similarity index 100% rename from FileSets/v3.40~39/OverviewGridParallel.qml.orig rename to FileSets/v3.40/OverviewGridParallel.qml.orig diff --git a/FileSets/v3.40~39/OverviewHub.qml b/FileSets/v3.40/OverviewHub.qml similarity index 100% rename from FileSets/v3.40~39/OverviewHub.qml rename to FileSets/v3.40/OverviewHub.qml diff --git a/FileSets/v3.40~39/OverviewHub.qml.orig b/FileSets/v3.40/OverviewHub.qml.orig similarity index 100% rename from FileSets/v3.40~39/OverviewHub.qml.orig rename to FileSets/v3.40/OverviewHub.qml.orig diff --git a/FileSets/v3.40~39/OverviewHubEnhanced.qml b/FileSets/v3.40/OverviewHubEnhanced.qml similarity index 100% rename from FileSets/v3.40~39/OverviewHubEnhanced.qml rename to FileSets/v3.40/OverviewHubEnhanced.qml diff --git a/FileSets/v3.40~39/OverviewHubEnhanced.qml.orig b/FileSets/v3.40/OverviewHubEnhanced.qml.orig similarity index 100% rename from FileSets/v3.40~39/OverviewHubEnhanced.qml.orig rename to FileSets/v3.40/OverviewHubEnhanced.qml.orig diff --git a/FileSets/v3.40~39/OverviewMobileEnhanced.qml b/FileSets/v3.40/OverviewMobileEnhanced.qml similarity index 100% rename from FileSets/v3.40~39/OverviewMobileEnhanced.qml rename to FileSets/v3.40/OverviewMobileEnhanced.qml diff --git a/FileSets/v3.40~39/OverviewMobileEnhanced.qml.orig b/FileSets/v3.40/OverviewMobileEnhanced.qml.orig similarity index 100% rename from FileSets/v3.40~39/OverviewMobileEnhanced.qml.orig rename to FileSets/v3.40/OverviewMobileEnhanced.qml.orig diff --git a/FileSets/v2.73/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40/OverviewTanksTempsDigInputs.qml similarity index 100% rename from FileSets/v2.73/OverviewTanksTempsDigInputs.qml rename to FileSets/v3.40/OverviewTanksTempsDigInputs.qml diff --git a/FileSets/v3.40~39/OverviewTanksTempsDigInputs.qml.orig b/FileSets/v3.40/OverviewTanksTempsDigInputs.qml.orig similarity index 100% rename from FileSets/v3.40~39/OverviewTanksTempsDigInputs.qml.orig rename to FileSets/v3.40/OverviewTanksTempsDigInputs.qml.orig diff --git a/FileSets/v3.40~26/PageGenerator.qml b/FileSets/v3.40/PageGenerator.qml similarity index 96% rename from FileSets/v3.40~26/PageGenerator.qml rename to FileSets/v3.40/PageGenerator.qml index 6164abc4..edad721c 100644 --- a/FileSets/v3.40~26/PageGenerator.qml +++ b/FileSets/v3.40/PageGenerator.qml @@ -5,7 +5,7 @@ import com.victron.velib 1.0 import "utils.js" as Utils MbPage { - id: root + id: generator title: qsTr("Generator start/stop") property string settingsBindPrefix property string startStopBindPrefix @@ -123,7 +123,7 @@ MbPage { subpage: Component { PageGeneratorManualStart { - startStopBindPrefix: root.startStopBindPrefix + startStopBindPrefix: generator.startStopBindPrefix } } } @@ -150,8 +150,8 @@ MbPage { description: qsTr("Settings") subpage: Component { PageSettingsGenerator { - settingsBindPrefix: root.settingsBindPrefix - startStopBindPrefix: root.startStopBindPrefix + settingsBindPrefix: generator.settingsBindPrefix + startStopBindPrefix: generator.startStopBindPrefix } } } diff --git a/FileSets/v3.34/PageGenerator.qml.orig b/FileSets/v3.40/PageGenerator.qml.orig similarity index 100% rename from FileSets/v3.34/PageGenerator.qml.orig rename to FileSets/v3.40/PageGenerator.qml.orig diff --git a/FileSets/v3.40~39/PageSettingsGenerator.qml b/FileSets/v3.40/PageSettingsGenerator.qml similarity index 100% rename from FileSets/v3.40~39/PageSettingsGenerator.qml rename to FileSets/v3.40/PageSettingsGenerator.qml diff --git a/FileSets/v3.40~39/PageSettingsGenerator.qml.orig b/FileSets/v3.40/PageSettingsGenerator.qml.orig similarity index 100% rename from FileSets/v3.40~39/PageSettingsGenerator.qml.orig rename to FileSets/v3.40/PageSettingsGenerator.qml.orig diff --git a/FileSets/v3.40~39/PageSettingsGuiMods.qml b/FileSets/v3.40/PageSettingsGuiMods.qml similarity index 100% rename from FileSets/v3.40~39/PageSettingsGuiMods.qml rename to FileSets/v3.40/PageSettingsGuiMods.qml diff --git a/FileSets/v3.40~39/PageSettingsGuiMods.qml.orig b/FileSets/v3.40/PageSettingsGuiMods.qml.orig similarity index 100% rename from FileSets/v3.40~39/PageSettingsGuiMods.qml.orig rename to FileSets/v3.40/PageSettingsGuiMods.qml.orig diff --git a/FileSets/v3.40~39/PageSettingsRelay.qml b/FileSets/v3.40/PageSettingsRelay.qml similarity index 100% rename from FileSets/v3.40~39/PageSettingsRelay.qml rename to FileSets/v3.40/PageSettingsRelay.qml diff --git a/FileSets/v3.40~39/PageSettingsRelay.qml.orig b/FileSets/v3.40/PageSettingsRelay.qml.orig similarity index 100% rename from FileSets/v3.40~39/PageSettingsRelay.qml.orig rename to FileSets/v3.40/PageSettingsRelay.qml.orig diff --git a/FileSets/v3.40~39/PowerGauge.qml b/FileSets/v3.40/PowerGauge.qml similarity index 100% rename from FileSets/v3.40~39/PowerGauge.qml rename to FileSets/v3.40/PowerGauge.qml diff --git a/FileSets/v3.40~39/PowerGauge.qml.orig b/FileSets/v3.40/PowerGauge.qml.orig similarity index 100% rename from FileSets/v3.40~39/PowerGauge.qml.orig rename to FileSets/v3.40/PowerGauge.qml.orig diff --git a/FileSets/v3.01/TileDigIn.qml b/FileSets/v3.40/TileDigIn.qml similarity index 100% rename from FileSets/v3.01/TileDigIn.qml rename to FileSets/v3.40/TileDigIn.qml diff --git a/FileSets/v3.40~39/TileDigIn.qml.orig b/FileSets/v3.40/TileDigIn.qml.orig similarity index 100% rename from FileSets/v3.40~39/TileDigIn.qml.orig rename to FileSets/v3.40/TileDigIn.qml.orig diff --git a/FileSets/v3.40~39/TileRelay.qml b/FileSets/v3.40/TileRelay.qml similarity index 100% rename from FileSets/v3.40~39/TileRelay.qml rename to FileSets/v3.40/TileRelay.qml diff --git a/FileSets/v3.40~39/TileRelay.qml.orig b/FileSets/v3.40/TileRelay.qml.orig similarity index 100% rename from FileSets/v3.40~39/TileRelay.qml.orig rename to FileSets/v3.40/TileRelay.qml.orig diff --git a/FileSets/v3.40~39/dbus_digitalinputs.py b/FileSets/v3.40/dbus_digitalinputs.py similarity index 100% rename from FileSets/v3.40~39/dbus_digitalinputs.py rename to FileSets/v3.40/dbus_digitalinputs.py diff --git a/FileSets/v3.40~39/dbus_digitalinputs.py.orig b/FileSets/v3.40/dbus_digitalinputs.py.orig similarity index 100% rename from FileSets/v3.40~39/dbus_digitalinputs.py.orig rename to FileSets/v3.40/dbus_digitalinputs.py.orig diff --git a/FileSets/v3.40~39/dbus_generator.py b/FileSets/v3.40/dbus_generator.py similarity index 100% rename from FileSets/v3.40~39/dbus_generator.py rename to FileSets/v3.40/dbus_generator.py diff --git a/FileSets/v3.40~39/dbus_generator.py.orig b/FileSets/v3.40/dbus_generator.py.orig similarity index 100% rename from FileSets/v3.40~39/dbus_generator.py.orig rename to FileSets/v3.40/dbus_generator.py.orig diff --git a/FileSets/v3.40~39/startstop.py b/FileSets/v3.40/startstop.py similarity index 100% rename from FileSets/v3.40~39/startstop.py rename to FileSets/v3.40/startstop.py diff --git a/FileSets/v3.40~39/startstop.py.orig b/FileSets/v3.40/startstop.py.orig similarity index 100% rename from FileSets/v3.40~39/startstop.py.orig rename to FileSets/v3.40/startstop.py.orig diff --git a/FileSets/v3.40~1/Battery.qml b/FileSets/v3.40~1/Battery.qml deleted file mode 120000 index fafc7b36..00000000 --- a/FileSets/v3.40~1/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/COMPLETE b/FileSets/v3.40~1/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~1/DetailAcInput.qml b/FileSets/v3.40~1/DetailAcInput.qml deleted file mode 120000 index d315e33a..00000000 --- a/FileSets/v3.40~1/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/DetailInverter.qml b/FileSets/v3.40~1/DetailInverter.qml deleted file mode 120000 index 2d924d7f..00000000 --- a/FileSets/v3.40~1/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/DetailLoadsCombined.qml b/FileSets/v3.40~1/DetailLoadsCombined.qml deleted file mode 120000 index 58c63979..00000000 --- a/FileSets/v3.40~1/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/DetailLoadsOnInput.qml b/FileSets/v3.40~1/DetailLoadsOnInput.qml deleted file mode 120000 index 5fb19084..00000000 --- a/FileSets/v3.40~1/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/DetailLoadsOnOutput.qml b/FileSets/v3.40~1/DetailLoadsOnOutput.qml deleted file mode 120000 index 9fdfdf28..00000000 --- a/FileSets/v3.40~1/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/HubData.qml b/FileSets/v3.40~1/HubData.qml deleted file mode 120000 index b88f1965..00000000 --- a/FileSets/v3.40~1/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/LINKS_ONLY b/FileSets/v3.40~1/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~1/MbEditBox.qml b/FileSets/v3.40~1/MbEditBox.qml deleted file mode 120000 index 8381b7d5..00000000 --- a/FileSets/v3.40~1/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/MbEditBoxDateTime.qml b/FileSets/v3.40~1/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v3.40~1/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/MbItem.qml b/FileSets/v3.40~1/MbItem.qml deleted file mode 120000 index 048a313c..00000000 --- a/FileSets/v3.40~1/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/MbItemDigitalInput.qml b/FileSets/v3.40~1/MbItemDigitalInput.qml deleted file mode 120000 index 4404b520..00000000 --- a/FileSets/v3.40~1/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/MbSpinBox.qml b/FileSets/v3.40~1/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v3.40~1/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/MbStyle.qml b/FileSets/v3.40~1/MbStyle.qml deleted file mode 120000 index d1940446..00000000 --- a/FileSets/v3.40~1/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/MbSubMenu.qml b/FileSets/v3.40~1/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v3.40~1/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/Multi.qml b/FileSets/v3.40~1/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v3.40~1/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/ObjectAcConnection.qml b/FileSets/v3.40~1/ObjectAcConnection.qml deleted file mode 120000 index cab7f2d4..00000000 --- a/FileSets/v3.40~1/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~1/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 6d1e56b5..00000000 --- a/FileSets/v3.40~1/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewBox.qml b/FileSets/v3.40~1/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v3.40~1/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewConnection.qml b/FileSets/v3.40~1/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v3.40~1/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewConnectionEnd.qml b/FileSets/v3.40~1/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v3.40~1/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewFlowComplex.qml b/FileSets/v3.40~1/OverviewFlowComplex.qml deleted file mode 120000 index 296ff4b1..00000000 --- a/FileSets/v3.40~1/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~1/OverviewGeneratorEnhanced.qml deleted file mode 120000 index da5507a7..00000000 --- a/FileSets/v3.40~1/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~1/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index 1c9b530f..00000000 --- a/FileSets/v3.40~1/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewGridParallel.qml b/FileSets/v3.40~1/OverviewGridParallel.qml deleted file mode 120000 index 3d1f0720..00000000 --- a/FileSets/v3.40~1/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewHub.qml b/FileSets/v3.40~1/OverviewHub.qml deleted file mode 120000 index 83bae2bd..00000000 --- a/FileSets/v3.40~1/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewHubEnhanced.qml b/FileSets/v3.40~1/OverviewHubEnhanced.qml deleted file mode 120000 index 905200b7..00000000 --- a/FileSets/v3.40~1/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewMobileEnhanced.qml b/FileSets/v3.40~1/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.40~1/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewSolarCharger.qml b/FileSets/v3.40~1/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v3.40~1/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewSolarInverter.qml b/FileSets/v3.40~1/OverviewSolarInverter.qml deleted file mode 120000 index 4048703e..00000000 --- a/FileSets/v3.40~1/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewTankDelegate.qml b/FileSets/v3.40~1/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v3.40~1/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewTanks.qml b/FileSets/v3.40~1/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v3.40~1/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~1/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.40~1/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/PageDigitalInput.qml b/FileSets/v3.40~1/PageDigitalInput.qml deleted file mode 120000 index 5b768f8f..00000000 --- a/FileSets/v3.40~1/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/PageGenerator.qml b/FileSets/v3.40~1/PageGenerator.qml deleted file mode 120000 index efbafddf..00000000 --- a/FileSets/v3.40~1/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/PageMain.qml b/FileSets/v3.40~1/PageMain.qml deleted file mode 120000 index 33fe83b0..00000000 --- a/FileSets/v3.40~1/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~13/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/PageSettingsDisplay.qml b/FileSets/v3.40~1/PageSettingsDisplay.qml deleted file mode 120000 index 4e1ac210..00000000 --- a/FileSets/v3.40~1/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/PageSettingsGenerator.qml b/FileSets/v3.40~1/PageSettingsGenerator.qml deleted file mode 120000 index 15dd8f85..00000000 --- a/FileSets/v3.40~1/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/PageSettingsGuiMods.qml b/FileSets/v3.40~1/PageSettingsGuiMods.qml deleted file mode 120000 index e831a7a4..00000000 --- a/FileSets/v3.40~1/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/PageSettingsRelay.qml b/FileSets/v3.40~1/PageSettingsRelay.qml deleted file mode 120000 index 156aadac..00000000 --- a/FileSets/v3.40~1/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/PowerGauge.qml b/FileSets/v3.40~1/PowerGauge.qml deleted file mode 120000 index cfdf038d..00000000 --- a/FileSets/v3.40~1/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/Tile.qml b/FileSets/v3.40~1/Tile.qml deleted file mode 120000 index 0558cecf..00000000 --- a/FileSets/v3.40~1/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/TileDigIn.qml b/FileSets/v3.40~1/TileDigIn.qml deleted file mode 120000 index 44616f30..00000000 --- a/FileSets/v3.40~1/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/TileRelay.qml b/FileSets/v3.40~1/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.40~1/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/TileText.qml b/FileSets/v3.40~1/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v3.40~1/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/attributes.csv b/FileSets/v3.40~1/attributes.csv deleted file mode 120000 index e226e13c..00000000 --- a/FileSets/v3.40~1/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v3.40~6/attributes.csv \ No newline at end of file diff --git a/FileSets/v3.40~1/dbus_digitalinputs.py b/FileSets/v3.40~1/dbus_digitalinputs.py deleted file mode 120000 index e74da5b6..00000000 --- a/FileSets/v3.40~1/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.40~1/dbus_generator.py b/FileSets/v3.40~1/dbus_generator.py deleted file mode 120000 index 0cd84ca3..00000000 --- a/FileSets/v3.40~1/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.40~1/main.qml b/FileSets/v3.40~1/main.qml deleted file mode 120000 index 916fdfbf..00000000 --- a/FileSets/v3.40~1/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~13/main.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/startstop.py b/FileSets/v3.40~1/startstop.py deleted file mode 120000 index 274861e3..00000000 --- a/FileSets/v3.40~1/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~17/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~1/styles.css b/FileSets/v3.40~1/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v3.40~1/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v3.40~10/Battery.qml b/FileSets/v3.40~10/Battery.qml deleted file mode 120000 index fafc7b36..00000000 --- a/FileSets/v3.40~10/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/COMPLETE b/FileSets/v3.40~10/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~10/DetailAcInput.qml b/FileSets/v3.40~10/DetailAcInput.qml deleted file mode 120000 index 3bd58b38..00000000 --- a/FileSets/v3.40~10/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~13/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/DetailInverter.qml b/FileSets/v3.40~10/DetailInverter.qml deleted file mode 120000 index ad371ebf..00000000 --- a/FileSets/v3.40~10/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~13/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/DetailLoadsCombined.qml b/FileSets/v3.40~10/DetailLoadsCombined.qml deleted file mode 120000 index 7e82b287..00000000 --- a/FileSets/v3.40~10/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~13/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/DetailLoadsOnInput.qml b/FileSets/v3.40~10/DetailLoadsOnInput.qml deleted file mode 120000 index f0c6eac9..00000000 --- a/FileSets/v3.40~10/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~13/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/DetailLoadsOnOutput.qml b/FileSets/v3.40~10/DetailLoadsOnOutput.qml deleted file mode 120000 index a61728ed..00000000 --- a/FileSets/v3.40~10/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~13/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/HubData.qml b/FileSets/v3.40~10/HubData.qml deleted file mode 120000 index 9976a993..00000000 --- a/FileSets/v3.40~10/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~13/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/LINKS_ONLY b/FileSets/v3.40~10/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~10/MbEditBoxDateTime.qml b/FileSets/v3.40~10/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v3.40~10/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/MbItem.qml b/FileSets/v3.40~10/MbItem.qml deleted file mode 120000 index 048a313c..00000000 --- a/FileSets/v3.40~10/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/MbItemDigitalInput.qml b/FileSets/v3.40~10/MbItemDigitalInput.qml deleted file mode 120000 index 4404b520..00000000 --- a/FileSets/v3.40~10/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/MbSpinBox.qml b/FileSets/v3.40~10/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v3.40~10/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/MbStyle.qml b/FileSets/v3.40~10/MbStyle.qml deleted file mode 120000 index d1940446..00000000 --- a/FileSets/v3.40~10/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/MbSubMenu.qml b/FileSets/v3.40~10/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v3.40~10/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/Multi.qml b/FileSets/v3.40~10/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v3.40~10/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/ObjectAcConnection.qml b/FileSets/v3.40~10/ObjectAcConnection.qml deleted file mode 120000 index cab7f2d4..00000000 --- a/FileSets/v3.40~10/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~10/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 6d1e56b5..00000000 --- a/FileSets/v3.40~10/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/OverviewBox.qml b/FileSets/v3.40~10/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v3.40~10/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/OverviewConnection.qml b/FileSets/v3.40~10/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v3.40~10/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/OverviewConnectionEnd.qml b/FileSets/v3.40~10/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v3.40~10/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/OverviewFlowComplex.qml b/FileSets/v3.40~10/OverviewFlowComplex.qml deleted file mode 120000 index a151db4f..00000000 --- a/FileSets/v3.40~10/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~10/OverviewGeneratorEnhanced.qml deleted file mode 120000 index da5507a7..00000000 --- a/FileSets/v3.40~10/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~10/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index 1c9b530f..00000000 --- a/FileSets/v3.40~10/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/OverviewGridParallel.qml b/FileSets/v3.40~10/OverviewGridParallel.qml deleted file mode 120000 index d30a27d7..00000000 --- a/FileSets/v3.40~10/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/OverviewHub.qml b/FileSets/v3.40~10/OverviewHub.qml deleted file mode 120000 index 93c6ee1a..00000000 --- a/FileSets/v3.40~10/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/OverviewHubEnhanced.qml b/FileSets/v3.40~10/OverviewHubEnhanced.qml deleted file mode 120000 index c55515d9..00000000 --- a/FileSets/v3.40~10/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/OverviewMobileEnhanced.qml b/FileSets/v3.40~10/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.40~10/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/OverviewSolarCharger.qml b/FileSets/v3.40~10/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v3.40~10/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/OverviewSolarInverter.qml b/FileSets/v3.40~10/OverviewSolarInverter.qml deleted file mode 120000 index 4048703e..00000000 --- a/FileSets/v3.40~10/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/OverviewTankDelegate.qml b/FileSets/v3.40~10/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v3.40~10/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/OverviewTanks.qml b/FileSets/v3.40~10/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v3.40~10/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~10/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.40~10/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/PageDigitalInput.qml b/FileSets/v3.40~10/PageDigitalInput.qml deleted file mode 120000 index 5b768f8f..00000000 --- a/FileSets/v3.40~10/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/PageGenerator.qml b/FileSets/v3.40~10/PageGenerator.qml deleted file mode 120000 index efbafddf..00000000 --- a/FileSets/v3.40~10/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/PageMain.qml b/FileSets/v3.40~10/PageMain.qml deleted file mode 120000 index 33fe83b0..00000000 --- a/FileSets/v3.40~10/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~13/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/PageSettingsDisplay.qml b/FileSets/v3.40~10/PageSettingsDisplay.qml deleted file mode 120000 index 03766d99..00000000 --- a/FileSets/v3.40~10/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/PageSettingsGenerator.qml b/FileSets/v3.40~10/PageSettingsGenerator.qml deleted file mode 120000 index 15dd8f85..00000000 --- a/FileSets/v3.40~10/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/PageSettingsGuiMods.qml b/FileSets/v3.40~10/PageSettingsGuiMods.qml deleted file mode 120000 index e831a7a4..00000000 --- a/FileSets/v3.40~10/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/PageSettingsRelay.qml b/FileSets/v3.40~10/PageSettingsRelay.qml deleted file mode 120000 index 156aadac..00000000 --- a/FileSets/v3.40~10/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/PowerGauge.qml b/FileSets/v3.40~10/PowerGauge.qml deleted file mode 120000 index b34fd299..00000000 --- a/FileSets/v3.40~10/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~13/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/Tile.qml b/FileSets/v3.40~10/Tile.qml deleted file mode 120000 index 0558cecf..00000000 --- a/FileSets/v3.40~10/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/TileDigIn.qml b/FileSets/v3.40~10/TileDigIn.qml deleted file mode 120000 index 44616f30..00000000 --- a/FileSets/v3.40~10/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/TileRelay.qml b/FileSets/v3.40~10/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.40~10/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/TileText.qml b/FileSets/v3.40~10/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v3.40~10/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/attributes.csv b/FileSets/v3.40~10/attributes.csv deleted file mode 120000 index 4157dcc8..00000000 --- a/FileSets/v3.40~10/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v3.40~16/attributes.csv \ No newline at end of file diff --git a/FileSets/v3.40~10/dbus_digitalinputs.py b/FileSets/v3.40~10/dbus_digitalinputs.py deleted file mode 120000 index e74da5b6..00000000 --- a/FileSets/v3.40~10/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.40~10/dbus_generator.py b/FileSets/v3.40~10/dbus_generator.py deleted file mode 120000 index 0cd84ca3..00000000 --- a/FileSets/v3.40~10/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.40~10/main.qml b/FileSets/v3.40~10/main.qml deleted file mode 120000 index 916fdfbf..00000000 --- a/FileSets/v3.40~10/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~13/main.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/startstop.py b/FileSets/v3.40~10/startstop.py deleted file mode 120000 index 274861e3..00000000 --- a/FileSets/v3.40~10/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~17/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~10/styles.css b/FileSets/v3.40~10/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v3.40~10/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v3.40~13/Battery.qml b/FileSets/v3.40~13/Battery.qml deleted file mode 120000 index fafc7b36..00000000 --- a/FileSets/v3.40~13/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/COMPLETE b/FileSets/v3.40~13/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~13/DetailAcInput.qml.orig b/FileSets/v3.40~13/DetailAcInput.qml.orig deleted file mode 100644 index eaf2066b..00000000 --- a/FileSets/v3.40~13/DetailAcInput.qml.orig +++ /dev/null @@ -1,164 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -Item { - id: root - - property string systemPrefix: "com.victronenergy.system" - property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" - - property variant battery: _battery - property alias dcSystem: _dcSystem - property alias pvCharger: _pvCharger - property alias pvOnAcIn1: _pvOnAcIn1 - property alias pvOnAcIn2: _pvOnAcIn2 - property alias pvOnAcOut: _pvOnAcOut - property alias inverterChargerDc: _inverterChargerDc - property alias acLoad: _acLoad - property alias acInLoad: _acInLoad - property alias acOutLoad: _acOutLoad - property alias grid: _grid - property alias genset: _genset - property alias acInput: _activein - property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } - property variant acSource: _acSource.value - property VBusItem preferRenewableEnergy: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/PreferRenewableEnergy") } - property VBusItem remoteGeneratorSelected: VBusItem { bind: Utils.path(vebusPrefix, "/Ac/State/RemoteGeneratorSelected") } - - property alias pvOnGrid: _pvOnAcIn2 - - property int batteryStateIdle: 0 - property int batteryStateCharging: 1 - property int batteryStateDischarging: 2 - - property int acSourceNotAvailable: 0 - property int acSourceGrid: 1 - property int acSourceGenset: 2 - property int acSourceShore: 3 // same as grid - - property alias pvInvertersProductIds: _pvInvertersProductIds - property alias batteryProductId: _batteryProductId - - VBusItem { - id: _pvInvertersProductIds - bind: Utils.path(systemPrefix, "/PvInvertersProductIds") - } - - VBusItem { - id: _batteryProductId - bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") - } - - VBusItem { - id: _vebusService - bind: Utils.path(systemPrefix, "/VebusService") - } - - QtObject { - id: _pvCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} - } - - ObjectAcConnection { - id: _pvOnAcOut - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") - } - - ObjectAcConnection { - id: _pvOnAcIn1 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") - } - - ObjectAcConnection { - id: _pvOnAcIn2 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") - } - - ObjectAcConnection { - id: _genset - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") - } - - VBusItem { - id: _acSource - bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") - } - - /* - * Single Multis that can be split-phase reports NrOfPhases of 2 - * When L2 is disconnected from the input the output L1 and L2 - * are shorted. This item indicates if L2 is passed through - * from AC-in to AC-out. - * 1: L2 is being passed through from AC-in to AC-out. - * 0: L1 and L2 are shorted together. - * invalid: The unit is configured in such way that its L2 output is not used. - */ - - VBusItem { - id: _splitPhaseL2Passthru - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2Passthru") - } - - VBusItem { - id: _l2L1OutSummed - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2L1OutSummed") - } - - - ObjectAcConnection { - id: _grid - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") - } - - ObjectAcConnection { - id: _activein - bindPrefix: Utils.path(systemPrefix, "/Ac/ActiveIn") - } - - ObjectAcConnection { - id: _acLoad - l2AndL1OutSummed: _l2L1OutSummed.valid && (_l2L1OutSummed.value !== 0) - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") - } - - ObjectAcConnection { - id: _acOutLoad - l2AndL1OutSummed: _l2L1OutSummed.valid && (_l2L1OutSummed.value !== 0) - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") - } - - ObjectAcConnection { - id: _acInLoad - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") - } - - ObjectAcConnection { - id: _acUnknown - } - - QtObject { - id: _inverterChargerDc - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/InverterCharger/Power"); unit: "W"} - } - - QtObject { - id: _battery - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} - property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} - property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} - property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} - - // Get the battery charge state, see batteryState properties - property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} - } - - QtObject { - id: _dcSystem - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} - } -} diff --git a/FileSets/v3.40~13/DetailInverter.qml.orig b/FileSets/v3.40~13/DetailInverter.qml.orig deleted file mode 100644 index eaf2066b..00000000 --- a/FileSets/v3.40~13/DetailInverter.qml.orig +++ /dev/null @@ -1,164 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -Item { - id: root - - property string systemPrefix: "com.victronenergy.system" - property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" - - property variant battery: _battery - property alias dcSystem: _dcSystem - property alias pvCharger: _pvCharger - property alias pvOnAcIn1: _pvOnAcIn1 - property alias pvOnAcIn2: _pvOnAcIn2 - property alias pvOnAcOut: _pvOnAcOut - property alias inverterChargerDc: _inverterChargerDc - property alias acLoad: _acLoad - property alias acInLoad: _acInLoad - property alias acOutLoad: _acOutLoad - property alias grid: _grid - property alias genset: _genset - property alias acInput: _activein - property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } - property variant acSource: _acSource.value - property VBusItem preferRenewableEnergy: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/PreferRenewableEnergy") } - property VBusItem remoteGeneratorSelected: VBusItem { bind: Utils.path(vebusPrefix, "/Ac/State/RemoteGeneratorSelected") } - - property alias pvOnGrid: _pvOnAcIn2 - - property int batteryStateIdle: 0 - property int batteryStateCharging: 1 - property int batteryStateDischarging: 2 - - property int acSourceNotAvailable: 0 - property int acSourceGrid: 1 - property int acSourceGenset: 2 - property int acSourceShore: 3 // same as grid - - property alias pvInvertersProductIds: _pvInvertersProductIds - property alias batteryProductId: _batteryProductId - - VBusItem { - id: _pvInvertersProductIds - bind: Utils.path(systemPrefix, "/PvInvertersProductIds") - } - - VBusItem { - id: _batteryProductId - bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") - } - - VBusItem { - id: _vebusService - bind: Utils.path(systemPrefix, "/VebusService") - } - - QtObject { - id: _pvCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} - } - - ObjectAcConnection { - id: _pvOnAcOut - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") - } - - ObjectAcConnection { - id: _pvOnAcIn1 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") - } - - ObjectAcConnection { - id: _pvOnAcIn2 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") - } - - ObjectAcConnection { - id: _genset - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") - } - - VBusItem { - id: _acSource - bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") - } - - /* - * Single Multis that can be split-phase reports NrOfPhases of 2 - * When L2 is disconnected from the input the output L1 and L2 - * are shorted. This item indicates if L2 is passed through - * from AC-in to AC-out. - * 1: L2 is being passed through from AC-in to AC-out. - * 0: L1 and L2 are shorted together. - * invalid: The unit is configured in such way that its L2 output is not used. - */ - - VBusItem { - id: _splitPhaseL2Passthru - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2Passthru") - } - - VBusItem { - id: _l2L1OutSummed - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2L1OutSummed") - } - - - ObjectAcConnection { - id: _grid - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") - } - - ObjectAcConnection { - id: _activein - bindPrefix: Utils.path(systemPrefix, "/Ac/ActiveIn") - } - - ObjectAcConnection { - id: _acLoad - l2AndL1OutSummed: _l2L1OutSummed.valid && (_l2L1OutSummed.value !== 0) - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") - } - - ObjectAcConnection { - id: _acOutLoad - l2AndL1OutSummed: _l2L1OutSummed.valid && (_l2L1OutSummed.value !== 0) - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") - } - - ObjectAcConnection { - id: _acInLoad - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") - } - - ObjectAcConnection { - id: _acUnknown - } - - QtObject { - id: _inverterChargerDc - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/InverterCharger/Power"); unit: "W"} - } - - QtObject { - id: _battery - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} - property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} - property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} - property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} - - // Get the battery charge state, see batteryState properties - property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} - } - - QtObject { - id: _dcSystem - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} - } -} diff --git a/FileSets/v3.40~13/DetailLoadsCombined.qml.orig b/FileSets/v3.40~13/DetailLoadsCombined.qml.orig deleted file mode 100644 index eaf2066b..00000000 --- a/FileSets/v3.40~13/DetailLoadsCombined.qml.orig +++ /dev/null @@ -1,164 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -Item { - id: root - - property string systemPrefix: "com.victronenergy.system" - property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" - - property variant battery: _battery - property alias dcSystem: _dcSystem - property alias pvCharger: _pvCharger - property alias pvOnAcIn1: _pvOnAcIn1 - property alias pvOnAcIn2: _pvOnAcIn2 - property alias pvOnAcOut: _pvOnAcOut - property alias inverterChargerDc: _inverterChargerDc - property alias acLoad: _acLoad - property alias acInLoad: _acInLoad - property alias acOutLoad: _acOutLoad - property alias grid: _grid - property alias genset: _genset - property alias acInput: _activein - property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } - property variant acSource: _acSource.value - property VBusItem preferRenewableEnergy: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/PreferRenewableEnergy") } - property VBusItem remoteGeneratorSelected: VBusItem { bind: Utils.path(vebusPrefix, "/Ac/State/RemoteGeneratorSelected") } - - property alias pvOnGrid: _pvOnAcIn2 - - property int batteryStateIdle: 0 - property int batteryStateCharging: 1 - property int batteryStateDischarging: 2 - - property int acSourceNotAvailable: 0 - property int acSourceGrid: 1 - property int acSourceGenset: 2 - property int acSourceShore: 3 // same as grid - - property alias pvInvertersProductIds: _pvInvertersProductIds - property alias batteryProductId: _batteryProductId - - VBusItem { - id: _pvInvertersProductIds - bind: Utils.path(systemPrefix, "/PvInvertersProductIds") - } - - VBusItem { - id: _batteryProductId - bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") - } - - VBusItem { - id: _vebusService - bind: Utils.path(systemPrefix, "/VebusService") - } - - QtObject { - id: _pvCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} - } - - ObjectAcConnection { - id: _pvOnAcOut - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") - } - - ObjectAcConnection { - id: _pvOnAcIn1 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") - } - - ObjectAcConnection { - id: _pvOnAcIn2 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") - } - - ObjectAcConnection { - id: _genset - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") - } - - VBusItem { - id: _acSource - bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") - } - - /* - * Single Multis that can be split-phase reports NrOfPhases of 2 - * When L2 is disconnected from the input the output L1 and L2 - * are shorted. This item indicates if L2 is passed through - * from AC-in to AC-out. - * 1: L2 is being passed through from AC-in to AC-out. - * 0: L1 and L2 are shorted together. - * invalid: The unit is configured in such way that its L2 output is not used. - */ - - VBusItem { - id: _splitPhaseL2Passthru - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2Passthru") - } - - VBusItem { - id: _l2L1OutSummed - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2L1OutSummed") - } - - - ObjectAcConnection { - id: _grid - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") - } - - ObjectAcConnection { - id: _activein - bindPrefix: Utils.path(systemPrefix, "/Ac/ActiveIn") - } - - ObjectAcConnection { - id: _acLoad - l2AndL1OutSummed: _l2L1OutSummed.valid && (_l2L1OutSummed.value !== 0) - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") - } - - ObjectAcConnection { - id: _acOutLoad - l2AndL1OutSummed: _l2L1OutSummed.valid && (_l2L1OutSummed.value !== 0) - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") - } - - ObjectAcConnection { - id: _acInLoad - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") - } - - ObjectAcConnection { - id: _acUnknown - } - - QtObject { - id: _inverterChargerDc - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/InverterCharger/Power"); unit: "W"} - } - - QtObject { - id: _battery - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} - property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} - property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} - property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} - - // Get the battery charge state, see batteryState properties - property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} - } - - QtObject { - id: _dcSystem - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} - } -} diff --git a/FileSets/v3.40~13/DetailLoadsOnInput.qml.orig b/FileSets/v3.40~13/DetailLoadsOnInput.qml.orig deleted file mode 100644 index eaf2066b..00000000 --- a/FileSets/v3.40~13/DetailLoadsOnInput.qml.orig +++ /dev/null @@ -1,164 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -Item { - id: root - - property string systemPrefix: "com.victronenergy.system" - property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" - - property variant battery: _battery - property alias dcSystem: _dcSystem - property alias pvCharger: _pvCharger - property alias pvOnAcIn1: _pvOnAcIn1 - property alias pvOnAcIn2: _pvOnAcIn2 - property alias pvOnAcOut: _pvOnAcOut - property alias inverterChargerDc: _inverterChargerDc - property alias acLoad: _acLoad - property alias acInLoad: _acInLoad - property alias acOutLoad: _acOutLoad - property alias grid: _grid - property alias genset: _genset - property alias acInput: _activein - property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } - property variant acSource: _acSource.value - property VBusItem preferRenewableEnergy: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/PreferRenewableEnergy") } - property VBusItem remoteGeneratorSelected: VBusItem { bind: Utils.path(vebusPrefix, "/Ac/State/RemoteGeneratorSelected") } - - property alias pvOnGrid: _pvOnAcIn2 - - property int batteryStateIdle: 0 - property int batteryStateCharging: 1 - property int batteryStateDischarging: 2 - - property int acSourceNotAvailable: 0 - property int acSourceGrid: 1 - property int acSourceGenset: 2 - property int acSourceShore: 3 // same as grid - - property alias pvInvertersProductIds: _pvInvertersProductIds - property alias batteryProductId: _batteryProductId - - VBusItem { - id: _pvInvertersProductIds - bind: Utils.path(systemPrefix, "/PvInvertersProductIds") - } - - VBusItem { - id: _batteryProductId - bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") - } - - VBusItem { - id: _vebusService - bind: Utils.path(systemPrefix, "/VebusService") - } - - QtObject { - id: _pvCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} - } - - ObjectAcConnection { - id: _pvOnAcOut - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") - } - - ObjectAcConnection { - id: _pvOnAcIn1 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") - } - - ObjectAcConnection { - id: _pvOnAcIn2 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") - } - - ObjectAcConnection { - id: _genset - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") - } - - VBusItem { - id: _acSource - bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") - } - - /* - * Single Multis that can be split-phase reports NrOfPhases of 2 - * When L2 is disconnected from the input the output L1 and L2 - * are shorted. This item indicates if L2 is passed through - * from AC-in to AC-out. - * 1: L2 is being passed through from AC-in to AC-out. - * 0: L1 and L2 are shorted together. - * invalid: The unit is configured in such way that its L2 output is not used. - */ - - VBusItem { - id: _splitPhaseL2Passthru - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2Passthru") - } - - VBusItem { - id: _l2L1OutSummed - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2L1OutSummed") - } - - - ObjectAcConnection { - id: _grid - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") - } - - ObjectAcConnection { - id: _activein - bindPrefix: Utils.path(systemPrefix, "/Ac/ActiveIn") - } - - ObjectAcConnection { - id: _acLoad - l2AndL1OutSummed: _l2L1OutSummed.valid && (_l2L1OutSummed.value !== 0) - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") - } - - ObjectAcConnection { - id: _acOutLoad - l2AndL1OutSummed: _l2L1OutSummed.valid && (_l2L1OutSummed.value !== 0) - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") - } - - ObjectAcConnection { - id: _acInLoad - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") - } - - ObjectAcConnection { - id: _acUnknown - } - - QtObject { - id: _inverterChargerDc - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/InverterCharger/Power"); unit: "W"} - } - - QtObject { - id: _battery - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} - property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} - property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} - property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} - - // Get the battery charge state, see batteryState properties - property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} - } - - QtObject { - id: _dcSystem - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} - } -} diff --git a/FileSets/v3.40~13/DetailLoadsOnOutput.qml.orig b/FileSets/v3.40~13/DetailLoadsOnOutput.qml.orig deleted file mode 100644 index eaf2066b..00000000 --- a/FileSets/v3.40~13/DetailLoadsOnOutput.qml.orig +++ /dev/null @@ -1,164 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -Item { - id: root - - property string systemPrefix: "com.victronenergy.system" - property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" - - property variant battery: _battery - property alias dcSystem: _dcSystem - property alias pvCharger: _pvCharger - property alias pvOnAcIn1: _pvOnAcIn1 - property alias pvOnAcIn2: _pvOnAcIn2 - property alias pvOnAcOut: _pvOnAcOut - property alias inverterChargerDc: _inverterChargerDc - property alias acLoad: _acLoad - property alias acInLoad: _acInLoad - property alias acOutLoad: _acOutLoad - property alias grid: _grid - property alias genset: _genset - property alias acInput: _activein - property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } - property variant acSource: _acSource.value - property VBusItem preferRenewableEnergy: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/PreferRenewableEnergy") } - property VBusItem remoteGeneratorSelected: VBusItem { bind: Utils.path(vebusPrefix, "/Ac/State/RemoteGeneratorSelected") } - - property alias pvOnGrid: _pvOnAcIn2 - - property int batteryStateIdle: 0 - property int batteryStateCharging: 1 - property int batteryStateDischarging: 2 - - property int acSourceNotAvailable: 0 - property int acSourceGrid: 1 - property int acSourceGenset: 2 - property int acSourceShore: 3 // same as grid - - property alias pvInvertersProductIds: _pvInvertersProductIds - property alias batteryProductId: _batteryProductId - - VBusItem { - id: _pvInvertersProductIds - bind: Utils.path(systemPrefix, "/PvInvertersProductIds") - } - - VBusItem { - id: _batteryProductId - bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") - } - - VBusItem { - id: _vebusService - bind: Utils.path(systemPrefix, "/VebusService") - } - - QtObject { - id: _pvCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} - } - - ObjectAcConnection { - id: _pvOnAcOut - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") - } - - ObjectAcConnection { - id: _pvOnAcIn1 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") - } - - ObjectAcConnection { - id: _pvOnAcIn2 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") - } - - ObjectAcConnection { - id: _genset - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") - } - - VBusItem { - id: _acSource - bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") - } - - /* - * Single Multis that can be split-phase reports NrOfPhases of 2 - * When L2 is disconnected from the input the output L1 and L2 - * are shorted. This item indicates if L2 is passed through - * from AC-in to AC-out. - * 1: L2 is being passed through from AC-in to AC-out. - * 0: L1 and L2 are shorted together. - * invalid: The unit is configured in such way that its L2 output is not used. - */ - - VBusItem { - id: _splitPhaseL2Passthru - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2Passthru") - } - - VBusItem { - id: _l2L1OutSummed - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2L1OutSummed") - } - - - ObjectAcConnection { - id: _grid - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") - } - - ObjectAcConnection { - id: _activein - bindPrefix: Utils.path(systemPrefix, "/Ac/ActiveIn") - } - - ObjectAcConnection { - id: _acLoad - l2AndL1OutSummed: _l2L1OutSummed.valid && (_l2L1OutSummed.value !== 0) - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") - } - - ObjectAcConnection { - id: _acOutLoad - l2AndL1OutSummed: _l2L1OutSummed.valid && (_l2L1OutSummed.value !== 0) - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") - } - - ObjectAcConnection { - id: _acInLoad - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") - } - - ObjectAcConnection { - id: _acUnknown - } - - QtObject { - id: _inverterChargerDc - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/InverterCharger/Power"); unit: "W"} - } - - QtObject { - id: _battery - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} - property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} - property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} - property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} - - // Get the battery charge state, see batteryState properties - property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} - } - - QtObject { - id: _dcSystem - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} - } -} diff --git a/FileSets/v3.40~13/HubData.qml b/FileSets/v3.40~13/HubData.qml deleted file mode 100644 index abe96728..00000000 --- a/FileSets/v3.40~13/HubData.qml +++ /dev/null @@ -1,262 +0,0 @@ -//////// modified for VE.Direct inverter support -//////// modified for grid/genset meter -//////// added alternator, AC charger, wind generator - -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -Item { - id: root - - property variant sys: theSystem - - property string systemPrefix: "com.victronenergy.system" - property string settingsPrefix: "com.victronenergy.settings" - property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" - -//////// add to support VE.Direct inverters - property string inverterService: "" -//////// add for grid/genset meters - property string gridMeterService: "" - property string gensetService: "" - - property variant battery: _battery - property alias dcSystem: _dcSystem - property alias alternator: _alternator - property alias windGenerator: _windGenerator - property alias fuelCell: _fuelCell - property alias acCharger: _acCharger - property alias pvCharger: _pvCharger - property alias pvOnAcIn1: _pvOnAcIn1 - property alias pvOnAcIn2: _pvOnAcIn2 - property alias pvOnAcOut: _pvOnAcOut - property alias inverterChargerDc: _inverterChargerDc - property alias acLoad: _acLoad - property alias acInLoad: _acInLoad - property alias acOutLoad: _acOutLoad - property alias grid: _grid - property alias acInput: _activein - property alias genset: _genset - property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } - property variant acSource: _acSource.value - property VBusItem preferRenewableEnergy: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/PreferRenewableEnergy") } - property VBusItem remoteGeneratorSelected: VBusItem { bind: Utils.path(vebusPrefix, "/Ac/State/RemoteGeneratorSelected") } - - property alias pvOnGrid: _pvOnAcIn2 - - property int batteryStateIdle: 0 - property int batteryStateCharging: 1 - property int batteryStateDischarging: 2 - - property int acSourceNotAvailable: 0 - property int acSourceGrid: 1 - property int acSourceGenset: 2 - property int acSourceShore: 3 // same as grid - - property alias pvInvertersProductIds: _pvInvertersProductIds - property alias batteryProductId: _batteryProductId - - VBusItem { - id: _pvInvertersProductIds - bind: Utils.path(systemPrefix, "/PvInvertersProductIds") - } - - VBusItem { - id: _batteryProductId - bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") - } - - VBusItem { - id: _vebusService - bind: Utils.path(systemPrefix, "/VebusService") - } - - QtObject { - id: _pvCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} - } - -//////// added alternator - QtObject { - id: _alternator - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Alternator/Power"); unit: "W"} - } - -//////// added AC charger - QtObject { - id: _acCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Charger/Power"); unit: "W"} - } - -//////// added wind generator - QtObject { - id: _windGenerator - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/WindGenerator/Power"); unit: "W"} - } - -//////// added fuel cell - QtObject { - id: _fuelCell - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/FuelCell/Power"); unit: "W"} - } - - ObjectAcConnection { - id: _pvOnAcOut - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") - } - - ObjectAcConnection { - id: _pvOnAcIn1 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") - } - - ObjectAcConnection { - id: _pvOnAcIn2 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") - } - - ObjectAcConnection { - id: _genset - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") -//////// modified for VE.Direct inverter support - inverterSource: "/Ac/ActiveIn" - inverterService: sys.vebusPrefix != "" ? sys.vebusPrefix : root.inverterService - } - - VBusItem { - id: _acSource - bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") - } - - /* - * Single Multis that can be split-phase reports NrOfPhases of 2 - * When L2 is disconnected from the input the output L1 and L2 - * are shorted. This item indicates if L2 is passed through - * from AC-in to AC-out. - * 1: L2 is being passed through from AC-in to AC-out. - * 0: L1 and L2 are shorted together. - * invalid: The unit is configured in such way that its L2 output is not used. - */ - - VBusItem { - id: _splitPhaseL2Passthru - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2Passthru") - } - - VBusItem { - id: _l2L1OutSummed - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2L1OutSummed") - } - - - ObjectAcConnection { - id: _grid - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") -//////// modified for VE.Direct inverter support - inverterSource: "/Ac/ActiveIn" - inverterService: sys.vebusPrefix != "" ? sys.vebusPrefix : root.inverterService - } - - ObjectAcConnection { - id: _activein - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/ActiveIn") -//////// modified for VE.Direct inverter support - inverterSource: "/Ac/ActiveIn" - inverterService: sys.vebusPrefix != "" ? sys.vebusPrefix : root.inverterService - } - - ObjectAcConnection { - id: _acLoad - l2AndL1OutSummed: _l2L1OutSummed.valid && (_l2L1OutSummed.value !== 0) - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") -//////// modified for VE.Direct inverter support - inverterSource: "/Ac/Out" - inverterService: sys.vebusPrefix != "" ? sys.vebusPrefix : root.inverterService - } - - ObjectAcConnection { - id: _acOutLoad - l2AndL1OutSummed: _l2L1OutSummed.valid && (_l2L1OutSummed.value !== 0) - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") - } - - ObjectAcConnection { - id: _acInLoad - splitPhaseL2PassthruDisabled:_splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") - } - - ObjectAcConnection { - id: _acUnknown - } - - QtObject { - id: _inverterChargerDc - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/InverterCharger/Power"); unit: "W"} - } - - QtObject { - id: _battery - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} - property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} - property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} - property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} - - // Get the battery charge state, see batteryState properties - property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} - } - - QtObject { - id: _dcSystem - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} - } - -//////// add to support for adjustable watt / killowatt display switching - VBusItem { id: kwThresholdItem; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/KilowattThreshold") } - property int kilowattThreshold: kwThresholdItem.valid ? kwThresholdItem.value : 1000 - -//////// add to support VE.Direct inverters -//////// and grid/genset meters - Component.onCompleted: discoverServices() - - // When new service is found check if is a tank sensor - Connections - { - target: DBusServices - onDbusServiceFound: addService(service) - } - function addService(service) - { - switch (service.type) - { - case DBusService.DBUS_SERVICE_INVERTER: - if (inverterService === "") - inverterService = service.name; - break;; - case DBusService.DBUS_SERVICE_GRIDMETER: - if (gridMeterService === "") - gridMeterService = service.name; - break;; - case DBusService.DBUS_SERVICE_GENSET: - if (gensetService === "") - gensetService = service.name; - break;; - } - } - - // Check available services inverter services - function discoverServices() - { - inverterService = "" - gridMeterService = "" - gensetService = "" - for (var i = 0; i < DBusServices.count; i++) - addService(DBusServices.at(i)) - } -} diff --git a/FileSets/v3.40~13/HubData.qml.orig b/FileSets/v3.40~13/HubData.qml.orig deleted file mode 100644 index eaf2066b..00000000 --- a/FileSets/v3.40~13/HubData.qml.orig +++ /dev/null @@ -1,164 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -Item { - id: root - - property string systemPrefix: "com.victronenergy.system" - property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" - - property variant battery: _battery - property alias dcSystem: _dcSystem - property alias pvCharger: _pvCharger - property alias pvOnAcIn1: _pvOnAcIn1 - property alias pvOnAcIn2: _pvOnAcIn2 - property alias pvOnAcOut: _pvOnAcOut - property alias inverterChargerDc: _inverterChargerDc - property alias acLoad: _acLoad - property alias acInLoad: _acInLoad - property alias acOutLoad: _acOutLoad - property alias grid: _grid - property alias genset: _genset - property alias acInput: _activein - property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } - property variant acSource: _acSource.value - property VBusItem preferRenewableEnergy: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/PreferRenewableEnergy") } - property VBusItem remoteGeneratorSelected: VBusItem { bind: Utils.path(vebusPrefix, "/Ac/State/RemoteGeneratorSelected") } - - property alias pvOnGrid: _pvOnAcIn2 - - property int batteryStateIdle: 0 - property int batteryStateCharging: 1 - property int batteryStateDischarging: 2 - - property int acSourceNotAvailable: 0 - property int acSourceGrid: 1 - property int acSourceGenset: 2 - property int acSourceShore: 3 // same as grid - - property alias pvInvertersProductIds: _pvInvertersProductIds - property alias batteryProductId: _batteryProductId - - VBusItem { - id: _pvInvertersProductIds - bind: Utils.path(systemPrefix, "/PvInvertersProductIds") - } - - VBusItem { - id: _batteryProductId - bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") - } - - VBusItem { - id: _vebusService - bind: Utils.path(systemPrefix, "/VebusService") - } - - QtObject { - id: _pvCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} - } - - ObjectAcConnection { - id: _pvOnAcOut - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") - } - - ObjectAcConnection { - id: _pvOnAcIn1 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") - } - - ObjectAcConnection { - id: _pvOnAcIn2 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") - } - - ObjectAcConnection { - id: _genset - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") - } - - VBusItem { - id: _acSource - bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") - } - - /* - * Single Multis that can be split-phase reports NrOfPhases of 2 - * When L2 is disconnected from the input the output L1 and L2 - * are shorted. This item indicates if L2 is passed through - * from AC-in to AC-out. - * 1: L2 is being passed through from AC-in to AC-out. - * 0: L1 and L2 are shorted together. - * invalid: The unit is configured in such way that its L2 output is not used. - */ - - VBusItem { - id: _splitPhaseL2Passthru - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2Passthru") - } - - VBusItem { - id: _l2L1OutSummed - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2L1OutSummed") - } - - - ObjectAcConnection { - id: _grid - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") - } - - ObjectAcConnection { - id: _activein - bindPrefix: Utils.path(systemPrefix, "/Ac/ActiveIn") - } - - ObjectAcConnection { - id: _acLoad - l2AndL1OutSummed: _l2L1OutSummed.valid && (_l2L1OutSummed.value !== 0) - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") - } - - ObjectAcConnection { - id: _acOutLoad - l2AndL1OutSummed: _l2L1OutSummed.valid && (_l2L1OutSummed.value !== 0) - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") - } - - ObjectAcConnection { - id: _acInLoad - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") - } - - ObjectAcConnection { - id: _acUnknown - } - - QtObject { - id: _inverterChargerDc - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/InverterCharger/Power"); unit: "W"} - } - - QtObject { - id: _battery - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} - property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} - property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} - property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} - - // Get the battery charge state, see batteryState properties - property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} - } - - QtObject { - id: _dcSystem - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} - } -} diff --git a/FileSets/v3.40~13/MbEditBox.qml b/FileSets/v3.40~13/MbEditBox.qml deleted file mode 120000 index 90a92492..00000000 --- a/FileSets/v3.40~13/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/MbEditBoxDateTime.qml b/FileSets/v3.40~13/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v3.40~13/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/MbItem.qml b/FileSets/v3.40~13/MbItem.qml deleted file mode 120000 index 048a313c..00000000 --- a/FileSets/v3.40~13/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/MbItemDigitalInput.qml b/FileSets/v3.40~13/MbItemDigitalInput.qml deleted file mode 120000 index 4404b520..00000000 --- a/FileSets/v3.40~13/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/MbSpinBox.qml b/FileSets/v3.40~13/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v3.40~13/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/MbStyle.qml b/FileSets/v3.40~13/MbStyle.qml deleted file mode 120000 index d1940446..00000000 --- a/FileSets/v3.40~13/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/MbSubMenu.qml b/FileSets/v3.40~13/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v3.40~13/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/Multi.qml b/FileSets/v3.40~13/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v3.40~13/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/ObjectAcConnection.qml b/FileSets/v3.40~13/ObjectAcConnection.qml deleted file mode 120000 index cab7f2d4..00000000 --- a/FileSets/v3.40~13/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~13/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 6d1e56b5..00000000 --- a/FileSets/v3.40~13/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/OverviewBox.qml b/FileSets/v3.40~13/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v3.40~13/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/OverviewConnection.qml b/FileSets/v3.40~13/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v3.40~13/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/OverviewConnectionEnd.qml b/FileSets/v3.40~13/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v3.40~13/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/OverviewFlowComplex.qml b/FileSets/v3.40~13/OverviewFlowComplex.qml deleted file mode 120000 index a151db4f..00000000 --- a/FileSets/v3.40~13/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~13/OverviewGeneratorEnhanced.qml deleted file mode 120000 index da5507a7..00000000 --- a/FileSets/v3.40~13/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~13/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index 1c9b530f..00000000 --- a/FileSets/v3.40~13/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/OverviewGridParallel.qml b/FileSets/v3.40~13/OverviewGridParallel.qml deleted file mode 120000 index d30a27d7..00000000 --- a/FileSets/v3.40~13/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/OverviewHub.qml b/FileSets/v3.40~13/OverviewHub.qml deleted file mode 120000 index 93c6ee1a..00000000 --- a/FileSets/v3.40~13/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/OverviewHubEnhanced.qml b/FileSets/v3.40~13/OverviewHubEnhanced.qml deleted file mode 120000 index c55515d9..00000000 --- a/FileSets/v3.40~13/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/OverviewMobileEnhanced.qml b/FileSets/v3.40~13/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.40~13/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/OverviewSolarCharger.qml b/FileSets/v3.40~13/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v3.40~13/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/OverviewSolarInverter.qml b/FileSets/v3.40~13/OverviewSolarInverter.qml deleted file mode 120000 index 4048703e..00000000 --- a/FileSets/v3.40~13/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/OverviewTankDelegate.qml b/FileSets/v3.40~13/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v3.40~13/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/OverviewTanks.qml b/FileSets/v3.40~13/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v3.40~13/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~13/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.40~13/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/PageDigitalInput.qml b/FileSets/v3.40~13/PageDigitalInput.qml deleted file mode 120000 index 5b768f8f..00000000 --- a/FileSets/v3.40~13/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/PageGenerator.qml b/FileSets/v3.40~13/PageGenerator.qml deleted file mode 120000 index efbafddf..00000000 --- a/FileSets/v3.40~13/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/PageSettingsDisplay.qml b/FileSets/v3.40~13/PageSettingsDisplay.qml deleted file mode 120000 index 03766d99..00000000 --- a/FileSets/v3.40~13/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/PageSettingsGenerator.qml b/FileSets/v3.40~13/PageSettingsGenerator.qml deleted file mode 120000 index 15dd8f85..00000000 --- a/FileSets/v3.40~13/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/PageSettingsGuiMods.qml b/FileSets/v3.40~13/PageSettingsGuiMods.qml deleted file mode 120000 index e831a7a4..00000000 --- a/FileSets/v3.40~13/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/PageSettingsRelay.qml b/FileSets/v3.40~13/PageSettingsRelay.qml deleted file mode 120000 index 156aadac..00000000 --- a/FileSets/v3.40~13/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/PowerGauge.qml b/FileSets/v3.40~13/PowerGauge.qml deleted file mode 100644 index 23d173c8..00000000 --- a/FileSets/v3.40~13/PowerGauge.qml +++ /dev/null @@ -1,320 +0,0 @@ -// displays value as a bar surrounded by three range regions -// use for I/O, PV inverter & charger - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 - -Item { - id: root - -////// GuiMods — DarkMode - property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } - property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 - - property variant connection - // connection2 accommodates combined PV inverter AC input and AC output - property variant connection2: undefined - property bool includeConnection2: connection2 != undefined - - property bool reversePower: false - property bool useInputCurrentLimit: false - property variant endLabelFontSize: 16 - property color endLabelBackgroundColor: "transparent" - - property int reportedPhaseCount1: connection == undefined ? 0 : connection.phaseCount == undefined || ! connection.phaseCount.valid ? 1 : connection.phaseCount.value - property int phaseCount1: reportedPhaseCount1 < 2 ? reportedPhaseCount1 : (connection.isAcOutput ? connection.l2AndL1OutSummed : connection.splitPhaseL2PassthruDisabled) ? 1 : connection.phaseCount.value - - property int reportedPhaseCount2: connection2 == undefined ? 0 : connection2.phaseCount == undefined || ! connection2.phaseCount.valid ? 1 : connection2.phaseCount.value - property int phaseCount2: reportedPhaseCount2 < 2 ? reportedPhaseCount2 : (connection2.isAcOutput ? connection2.l2AndL1OutSummed : connection2.splitPhaseL2PassthruDisabled) ? 1 : connection2.phaseCount.value - - property int phaseCount: includeConnection2 ? Math.max (phaseCount1, phaseCount2) : phaseCount1 - - property string maxForwardPowerParameter: "" - VBusItem { id: maxForwardLimitItem; bind: root.maxForwardPowerParameter } - property string maxForwardPowerParameter2: "" - VBusItem { id: maxForwardLimitItem2; bind: root.maxForwardPowerParameter2 } - - property string maxReversePowerParameter: "" - VBusItem { id: maxReverseLimitItem; bind: root.maxReversePowerParameter } - - property real inPowerLimit: sys.acInput.inCurrentLimit.valid ? sys.acInput.inCurrentLimit.value * sys.acInput.voltageL1.value : 0 - - property real maxForwardPower1: maxForwardLimitItem.valid ? maxForwardLimitItem.value : 0 - property real maxForwardPower2: maxForwardLimitItem2.valid ? maxForwardLimitItem2.value : 0 - property real maxForwardLimit: useInputCurrentLimit ? inPowerLimit : maxForwardPower1 + maxForwardPower2 - property real maxReverseLimit: maxReverseLimitItem.valid ? maxReverseLimitItem.value : 0 - // overload range is 10% of forward to reverse limits - property real overload: (maxForwardLimit + maxReverseLimit) * 0.1 - property real maxForwardDisplayed: maxForwardLimit > 0 ? maxForwardLimit + overload : 0 - property real maxReverseDisplayed: maxReverseLimit > 0 ? maxReverseLimit + overload : 0 - property real totalPowerDisplayed: maxForwardDisplayed + maxReverseDisplayed - - property bool showLabels: false - property variant endLabelColor: "white" - property real labelOffset: 15 - property real showLeftLabel: showGauge && showLabels && maxReverseLimit != 0 - property bool showRightLabel: showGauge && showLabels && maxForwardLimit != 0 - property int labelCount: (showLeftLabel ? 1 : 0) + (showRightLabel ? 1 : 0) - - property bool showGauge: root.connection != undefined && totalPowerDisplayed > 0 && phaseCount > 0 - property real scaleFactor: showGauge ? (root.width - (labelCount * labelOffset)) / totalPowerDisplayed : 0 - property real zeroOffset: showGauge ? ( maxReverseDisplayed * scaleFactor + (showLeftLabel ? labelOffset : 0 )) : 0 - - property int barSpacing: phaseCount > 0 ? Math.max (height / (phaseCount + 1), 2) : 0 - property int barHeight: barSpacing < 3 ? barSpacing : barSpacing - 1 - property int firstBarVertPos: (height - barSpacing * phaseCount) / 2 - property real bar1offset - property real bar2offset - property real bar3offset - - property color bar1color: "black" - property color bar2color: "black" - property color bar3color: "black" - - // left end label - Rectangle - { - anchors.fill: leftlabelText - color: endLabelBackgroundColor - visible: showLeftLabel - } - TileText - { - id: leftlabelText - text: "S" - color: endLabelColor - font.pixelSize: endLabelFontSize - width: labelOffset - anchors - { - verticalCenter: root.verticalCenter - verticalCenterOffset: 1 - left: root.left - } - visible: showLeftLabel - } - // right end label - Rectangle - { - anchors.fill: rightLabelText - color: endLabelBackgroundColor - visible: showRightLabel - } - TileText - { - id: rightLabelText - text: "C" - color: endLabelColor - font.pixelSize: endLabelFontSize - width: labelOffset - anchors - { - verticalCenter: leftlabelText.verticalCenter - right: root.right - } - visible: showRightLabel - } - // overload range Left - Rectangle - { - id: overloadLeft - width: showGauge ? scaleFactor * (maxReverseDisplayed - maxReverseLimit) : 0 - height: root.height - clip: true -////// GuiMods — DarkMode - color: !darkMode ? "#ffb3b3" : "#bf8686" - visible: showGauge - anchors - { - top: root.top - left: root.left; leftMargin: showLeftLabel ? labelOffset : 0 - } - } - // OK range (both left and right in a single rectangle) - Rectangle - { - id: okRange - width: showGauge ? scaleFactor * (maxForwardLimit + maxReverseLimit) : 0 - height: root.height - clip: true -////// GuiMods — DarkMode - color: !darkMode ? "#99ff99" : "#73bf73" - visible: showGauge - anchors - { - top: root.top - left: overloadLeft.right - } - } - // overload range right - Rectangle - { - id: overloadRight - width: showGauge ? scaleFactor * (maxForwardDisplayed - maxForwardLimit) : 0 - height: root.height - clip: true -////// GuiMods — DarkMode - color: !darkMode ? "#ffb3b3" : "#bf8686" - visible: showGauge - anchors - { - top: root.top - left: okRange.right - } - } - - // actual bars - Rectangle - { - id: bar1 - width: phaseCount >= 1 ? calculateBar1width () : 0 - height: barHeight - clip: true - color: root.bar1color - anchors - { - top: root.top; topMargin: firstBarVertPos - left: root.left; leftMargin: root.bar1offset - - } - visible: showGauge && phaseCount >= 1 - } - Rectangle - { - id: bar2 - width: phaseCount >= 2 ? calculateBar2width () : 0 - height: barHeight - clip: true - color: root.bar2color - anchors - { - top: root.top; topMargin: firstBarVertPos + barSpacing - left: root.left; leftMargin: root.bar2offset - } - visible: showGauge && phaseCount >= 2 - } - Rectangle - { - id: bar3 - width: phaseCount >= 3 ? calculateBar3width () : 0 - height: barHeight - clip: true - color: root.bar3color - anchors - { - top: root.top; topMargin: firstBarVertPos + barSpacing * 2 - left: root.left; leftMargin: root.bar3offset - } - visible: showGauge && phaseCount >= 3 - } - - // zero line - draw last so it's on top - Rectangle - { - id: zeroLine - width: 1 - height: root.height - clip: true - color: "black" - visible: showGauge && maxReverseLimit > 0 - anchors - { - top: root.top - left: root.left - leftMargin: zeroOffset - } - } - - function calculateBar1width () - { - var currentValue = 0.0, barWidth - if (root.connection.powerL1 != undefined) - currentValue += root.connection.powerL1.valid ? root.connection.powerL1.value : 0 - else if (root.connection.power != undefined) - currentValue += root.connection.power.valid ? root.connection.power.value : 0 - if (includeConnection2) - { - if (root.connection2.powerL1 != undefined) - currentValue += root.connection2.powerL1.valid ? root.connection2.powerL1.value : 0 - else if (root.connection2.power != undefined) - currentValue += root.connection2.power.valid ? root.connection2.power.value : 0 - } - - if (reversePower) - currentValue = -currentValue - - root.bar1color = getBarColor (currentValue) - barWidth = Math.min ( Math.max (currentValue, -maxReverseDisplayed), maxForwardDisplayed) * scaleFactor - // left of bar is at 0 point - if (barWidth >= 0) - { - root.bar1offset = zeroOffset - return barWidth - } - // RIGHT of bar is at 0 point - else - { - root.bar1offset = zeroOffset + barWidth - return -barWidth - } - } - function calculateBar2width () - { - var currentValue, barWidth - currentValue = root.connection.powerL2.valid ? root.connection.powerL2.value : 0 - if (includeConnection2) - currentValue += root.connection2.powerL2.valid ? root.connection2.powerL2.value : 0 - - if (reversePower) - currentValue = -currentValue - root.bar2color = getBarColor (currentValue) - barWidth = Math.min ( Math.max (currentValue, -maxReverseDisplayed), maxForwardDisplayed) * scaleFactor - // left of bar is at 0 point - if (barWidth >= 0) - { - root.bar2offset = zeroOffset - return barWidth - } - // RIGHT of bar is at 0 point - else - { - root.bar2offset = zeroOffset + barWidth - return -barWidth - } - } - function calculateBar3width () - { - var currentValue, barWidth - currentValue = root.connection.powerL3.valid ? root.connection.powerL3.value : 0 - if (includeConnection2) - currentValue += root.connection2.powerL3.valid ? root.connection2.powerL3.value : 0 - - if (reversePower) - currentValue = -currentValue - root.bar3color = getBarColor (currentValue) - barWidth = Math.min ( Math.max (currentValue, -maxReverseDisplayed), maxForwardDisplayed) * scaleFactor - // left of bar is at 0 point - if (barWidth >= 0) - { - root.bar3offset = zeroOffset - return barWidth - } - // RIGHT of bar is at 0 point - else - { - root.bar3offset = zeroOffset + barWidth - return -barWidth - } - } - - function getBarColor (currentValue) - { - if (currentValue > maxForwardLimit || currentValue < -maxReverseLimit) -////// GuiMods — DarkMode - return !darkMode ? "#ff0000" : "#bf0000" - else -////// GuiMods — DarkMode - return !darkMode ? "#008000" : "#006000" - } -} diff --git a/FileSets/v3.40~13/PowerGauge.qml.orig b/FileSets/v3.40~13/PowerGauge.qml.orig deleted file mode 100644 index eaf2066b..00000000 --- a/FileSets/v3.40~13/PowerGauge.qml.orig +++ /dev/null @@ -1,164 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -Item { - id: root - - property string systemPrefix: "com.victronenergy.system" - property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" - - property variant battery: _battery - property alias dcSystem: _dcSystem - property alias pvCharger: _pvCharger - property alias pvOnAcIn1: _pvOnAcIn1 - property alias pvOnAcIn2: _pvOnAcIn2 - property alias pvOnAcOut: _pvOnAcOut - property alias inverterChargerDc: _inverterChargerDc - property alias acLoad: _acLoad - property alias acInLoad: _acInLoad - property alias acOutLoad: _acOutLoad - property alias grid: _grid - property alias genset: _genset - property alias acInput: _activein - property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } - property variant acSource: _acSource.value - property VBusItem preferRenewableEnergy: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/PreferRenewableEnergy") } - property VBusItem remoteGeneratorSelected: VBusItem { bind: Utils.path(vebusPrefix, "/Ac/State/RemoteGeneratorSelected") } - - property alias pvOnGrid: _pvOnAcIn2 - - property int batteryStateIdle: 0 - property int batteryStateCharging: 1 - property int batteryStateDischarging: 2 - - property int acSourceNotAvailable: 0 - property int acSourceGrid: 1 - property int acSourceGenset: 2 - property int acSourceShore: 3 // same as grid - - property alias pvInvertersProductIds: _pvInvertersProductIds - property alias batteryProductId: _batteryProductId - - VBusItem { - id: _pvInvertersProductIds - bind: Utils.path(systemPrefix, "/PvInvertersProductIds") - } - - VBusItem { - id: _batteryProductId - bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") - } - - VBusItem { - id: _vebusService - bind: Utils.path(systemPrefix, "/VebusService") - } - - QtObject { - id: _pvCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} - } - - ObjectAcConnection { - id: _pvOnAcOut - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") - } - - ObjectAcConnection { - id: _pvOnAcIn1 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") - } - - ObjectAcConnection { - id: _pvOnAcIn2 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") - } - - ObjectAcConnection { - id: _genset - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") - } - - VBusItem { - id: _acSource - bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") - } - - /* - * Single Multis that can be split-phase reports NrOfPhases of 2 - * When L2 is disconnected from the input the output L1 and L2 - * are shorted. This item indicates if L2 is passed through - * from AC-in to AC-out. - * 1: L2 is being passed through from AC-in to AC-out. - * 0: L1 and L2 are shorted together. - * invalid: The unit is configured in such way that its L2 output is not used. - */ - - VBusItem { - id: _splitPhaseL2Passthru - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2Passthru") - } - - VBusItem { - id: _l2L1OutSummed - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2L1OutSummed") - } - - - ObjectAcConnection { - id: _grid - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") - } - - ObjectAcConnection { - id: _activein - bindPrefix: Utils.path(systemPrefix, "/Ac/ActiveIn") - } - - ObjectAcConnection { - id: _acLoad - l2AndL1OutSummed: _l2L1OutSummed.valid && (_l2L1OutSummed.value !== 0) - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") - } - - ObjectAcConnection { - id: _acOutLoad - l2AndL1OutSummed: _l2L1OutSummed.valid && (_l2L1OutSummed.value !== 0) - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") - } - - ObjectAcConnection { - id: _acInLoad - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") - } - - ObjectAcConnection { - id: _acUnknown - } - - QtObject { - id: _inverterChargerDc - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/InverterCharger/Power"); unit: "W"} - } - - QtObject { - id: _battery - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} - property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} - property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} - property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} - - // Get the battery charge state, see batteryState properties - property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} - } - - QtObject { - id: _dcSystem - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} - } -} diff --git a/FileSets/v3.40~13/Tile.qml b/FileSets/v3.40~13/Tile.qml deleted file mode 120000 index 0558cecf..00000000 --- a/FileSets/v3.40~13/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/TileDigIn.qml b/FileSets/v3.40~13/TileDigIn.qml deleted file mode 120000 index 44616f30..00000000 --- a/FileSets/v3.40~13/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/TileRelay.qml b/FileSets/v3.40~13/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.40~13/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/TileText.qml b/FileSets/v3.40~13/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v3.40~13/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.40~13/attributes.csv b/FileSets/v3.40~13/attributes.csv deleted file mode 120000 index 4157dcc8..00000000 --- a/FileSets/v3.40~13/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v3.40~16/attributes.csv \ No newline at end of file diff --git a/FileSets/v3.40~13/dbus_digitalinputs.py b/FileSets/v3.40~13/dbus_digitalinputs.py deleted file mode 120000 index e74da5b6..00000000 --- a/FileSets/v3.40~13/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.40~13/dbus_generator.py b/FileSets/v3.40~13/dbus_generator.py deleted file mode 120000 index 0cd84ca3..00000000 --- a/FileSets/v3.40~13/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.40~13/startstop.py b/FileSets/v3.40~13/startstop.py deleted file mode 120000 index 274861e3..00000000 --- a/FileSets/v3.40~13/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~17/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~13/styles.css b/FileSets/v3.40~13/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v3.40~13/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v3.40~15/Battery.qml b/FileSets/v3.40~15/Battery.qml deleted file mode 120000 index fafc7b36..00000000 --- a/FileSets/v3.40~15/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/COMPLETE b/FileSets/v3.40~15/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~15/DetailAcInput.qml b/FileSets/v3.40~15/DetailAcInput.qml deleted file mode 120000 index 8e76794d..00000000 --- a/FileSets/v3.40~15/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/DetailInverter.qml b/FileSets/v3.40~15/DetailInverter.qml deleted file mode 120000 index 285b3216..00000000 --- a/FileSets/v3.40~15/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/DetailLoadsCombined.qml b/FileSets/v3.40~15/DetailLoadsCombined.qml deleted file mode 120000 index 81c6de5a..00000000 --- a/FileSets/v3.40~15/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/DetailLoadsOnInput.qml b/FileSets/v3.40~15/DetailLoadsOnInput.qml deleted file mode 120000 index a5f97488..00000000 --- a/FileSets/v3.40~15/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/DetailLoadsOnOutput.qml b/FileSets/v3.40~15/DetailLoadsOnOutput.qml deleted file mode 120000 index 7cfc98c6..00000000 --- a/FileSets/v3.40~15/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/HubData.qml b/FileSets/v3.40~15/HubData.qml deleted file mode 120000 index c80a3bff..00000000 --- a/FileSets/v3.40~15/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/LINKS_ONLY b/FileSets/v3.40~15/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~15/MbEditBox.qml b/FileSets/v3.40~15/MbEditBox.qml deleted file mode 120000 index 90a92492..00000000 --- a/FileSets/v3.40~15/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/MbEditBoxDateTime.qml b/FileSets/v3.40~15/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v3.40~15/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/MbItem.qml b/FileSets/v3.40~15/MbItem.qml deleted file mode 120000 index 048a313c..00000000 --- a/FileSets/v3.40~15/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/MbItemDigitalInput.qml b/FileSets/v3.40~15/MbItemDigitalInput.qml deleted file mode 120000 index 4404b520..00000000 --- a/FileSets/v3.40~15/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/MbSpinBox.qml b/FileSets/v3.40~15/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v3.40~15/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/MbStyle.qml b/FileSets/v3.40~15/MbStyle.qml deleted file mode 120000 index d1940446..00000000 --- a/FileSets/v3.40~15/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/MbSubMenu.qml b/FileSets/v3.40~15/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v3.40~15/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/Multi.qml b/FileSets/v3.40~15/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v3.40~15/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/ObjectAcConnection.qml b/FileSets/v3.40~15/ObjectAcConnection.qml deleted file mode 120000 index cab7f2d4..00000000 --- a/FileSets/v3.40~15/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~15/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 6d1e56b5..00000000 --- a/FileSets/v3.40~15/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/OverviewBox.qml b/FileSets/v3.40~15/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v3.40~15/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/OverviewConnection.qml b/FileSets/v3.40~15/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v3.40~15/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/OverviewConnectionEnd.qml b/FileSets/v3.40~15/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v3.40~15/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/OverviewFlowComplex.qml b/FileSets/v3.40~15/OverviewFlowComplex.qml deleted file mode 120000 index a151db4f..00000000 --- a/FileSets/v3.40~15/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~15/OverviewGeneratorEnhanced.qml deleted file mode 120000 index da5507a7..00000000 --- a/FileSets/v3.40~15/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~15/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index 1c9b530f..00000000 --- a/FileSets/v3.40~15/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/OverviewGridParallel.qml b/FileSets/v3.40~15/OverviewGridParallel.qml deleted file mode 120000 index d30a27d7..00000000 --- a/FileSets/v3.40~15/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/OverviewHub.qml b/FileSets/v3.40~15/OverviewHub.qml deleted file mode 120000 index 93c6ee1a..00000000 --- a/FileSets/v3.40~15/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/OverviewHubEnhanced.qml b/FileSets/v3.40~15/OverviewHubEnhanced.qml deleted file mode 120000 index c55515d9..00000000 --- a/FileSets/v3.40~15/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/OverviewMobileEnhanced.qml b/FileSets/v3.40~15/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.40~15/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/OverviewSolarCharger.qml b/FileSets/v3.40~15/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v3.40~15/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/OverviewSolarInverter.qml b/FileSets/v3.40~15/OverviewSolarInverter.qml deleted file mode 120000 index 4048703e..00000000 --- a/FileSets/v3.40~15/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/OverviewTankDelegate.qml b/FileSets/v3.40~15/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v3.40~15/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/OverviewTanks.qml b/FileSets/v3.40~15/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v3.40~15/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~15/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.40~15/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/PageDigitalInput.qml b/FileSets/v3.40~15/PageDigitalInput.qml deleted file mode 120000 index 5b768f8f..00000000 --- a/FileSets/v3.40~15/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/PageGenerator.qml b/FileSets/v3.40~15/PageGenerator.qml deleted file mode 120000 index efbafddf..00000000 --- a/FileSets/v3.40~15/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/PageMain.qml b/FileSets/v3.40~15/PageMain.qml deleted file mode 120000 index ef4b9c47..00000000 --- a/FileSets/v3.40~15/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/PageSettingsDisplay.qml b/FileSets/v3.40~15/PageSettingsDisplay.qml deleted file mode 120000 index 03766d99..00000000 --- a/FileSets/v3.40~15/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/PageSettingsGenerator.qml b/FileSets/v3.40~15/PageSettingsGenerator.qml deleted file mode 120000 index 15dd8f85..00000000 --- a/FileSets/v3.40~15/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/PageSettingsGuiMods.qml b/FileSets/v3.40~15/PageSettingsGuiMods.qml deleted file mode 120000 index e831a7a4..00000000 --- a/FileSets/v3.40~15/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/PageSettingsRelay.qml b/FileSets/v3.40~15/PageSettingsRelay.qml deleted file mode 120000 index 156aadac..00000000 --- a/FileSets/v3.40~15/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/PowerGauge.qml b/FileSets/v3.40~15/PowerGauge.qml deleted file mode 120000 index 4bcaaa4a..00000000 --- a/FileSets/v3.40~15/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/Tile.qml b/FileSets/v3.40~15/Tile.qml deleted file mode 120000 index 0558cecf..00000000 --- a/FileSets/v3.40~15/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/TileDigIn.qml b/FileSets/v3.40~15/TileDigIn.qml deleted file mode 120000 index 44616f30..00000000 --- a/FileSets/v3.40~15/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/TileRelay.qml b/FileSets/v3.40~15/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.40~15/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/TileText.qml b/FileSets/v3.40~15/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v3.40~15/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/attributes.csv b/FileSets/v3.40~15/attributes.csv deleted file mode 120000 index 4157dcc8..00000000 --- a/FileSets/v3.40~15/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v3.40~16/attributes.csv \ No newline at end of file diff --git a/FileSets/v3.40~15/dbus_digitalinputs.py b/FileSets/v3.40~15/dbus_digitalinputs.py deleted file mode 120000 index e74da5b6..00000000 --- a/FileSets/v3.40~15/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.40~15/dbus_generator.py b/FileSets/v3.40~15/dbus_generator.py deleted file mode 120000 index 0cd84ca3..00000000 --- a/FileSets/v3.40~15/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.40~15/main.qml b/FileSets/v3.40~15/main.qml deleted file mode 120000 index 5dbfdf83..00000000 --- a/FileSets/v3.40~15/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/main.qml \ No newline at end of file diff --git a/FileSets/v3.40~15/startstop.py b/FileSets/v3.40~15/startstop.py deleted file mode 120000 index 274861e3..00000000 --- a/FileSets/v3.40~15/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~17/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~15/styles.css b/FileSets/v3.40~15/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v3.40~15/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v3.40~16/Battery.qml b/FileSets/v3.40~16/Battery.qml deleted file mode 120000 index fafc7b36..00000000 --- a/FileSets/v3.40~16/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/COMPLETE b/FileSets/v3.40~16/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~16/DetailAcInput.qml b/FileSets/v3.40~16/DetailAcInput.qml deleted file mode 120000 index 8e76794d..00000000 --- a/FileSets/v3.40~16/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/DetailInverter.qml b/FileSets/v3.40~16/DetailInverter.qml deleted file mode 120000 index 285b3216..00000000 --- a/FileSets/v3.40~16/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/DetailLoadsCombined.qml b/FileSets/v3.40~16/DetailLoadsCombined.qml deleted file mode 120000 index 81c6de5a..00000000 --- a/FileSets/v3.40~16/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/DetailLoadsOnInput.qml b/FileSets/v3.40~16/DetailLoadsOnInput.qml deleted file mode 120000 index a5f97488..00000000 --- a/FileSets/v3.40~16/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/DetailLoadsOnOutput.qml b/FileSets/v3.40~16/DetailLoadsOnOutput.qml deleted file mode 120000 index 7cfc98c6..00000000 --- a/FileSets/v3.40~16/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/HubData.qml b/FileSets/v3.40~16/HubData.qml deleted file mode 120000 index c80a3bff..00000000 --- a/FileSets/v3.40~16/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/LINKS_ONLY b/FileSets/v3.40~16/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~16/MbEditBox.qml b/FileSets/v3.40~16/MbEditBox.qml deleted file mode 120000 index 90a92492..00000000 --- a/FileSets/v3.40~16/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/MbEditBoxDateTime.qml b/FileSets/v3.40~16/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v3.40~16/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/MbItem.qml b/FileSets/v3.40~16/MbItem.qml deleted file mode 120000 index 048a313c..00000000 --- a/FileSets/v3.40~16/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/MbItemDigitalInput.qml b/FileSets/v3.40~16/MbItemDigitalInput.qml deleted file mode 120000 index 4404b520..00000000 --- a/FileSets/v3.40~16/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/MbSpinBox.qml b/FileSets/v3.40~16/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v3.40~16/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/MbStyle.qml b/FileSets/v3.40~16/MbStyle.qml deleted file mode 120000 index d1940446..00000000 --- a/FileSets/v3.40~16/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/MbSubMenu.qml b/FileSets/v3.40~16/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v3.40~16/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/Multi.qml b/FileSets/v3.40~16/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v3.40~16/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/ObjectAcConnection.qml b/FileSets/v3.40~16/ObjectAcConnection.qml deleted file mode 120000 index cab7f2d4..00000000 --- a/FileSets/v3.40~16/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~16/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 6d1e56b5..00000000 --- a/FileSets/v3.40~16/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/OverviewBox.qml b/FileSets/v3.40~16/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v3.40~16/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/OverviewConnection.qml b/FileSets/v3.40~16/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v3.40~16/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/OverviewConnectionEnd.qml b/FileSets/v3.40~16/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v3.40~16/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/OverviewFlowComplex.qml b/FileSets/v3.40~16/OverviewFlowComplex.qml deleted file mode 120000 index a151db4f..00000000 --- a/FileSets/v3.40~16/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~16/OverviewGeneratorEnhanced.qml deleted file mode 120000 index da5507a7..00000000 --- a/FileSets/v3.40~16/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~16/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index 1c9b530f..00000000 --- a/FileSets/v3.40~16/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/OverviewGridParallel.qml b/FileSets/v3.40~16/OverviewGridParallel.qml deleted file mode 120000 index d30a27d7..00000000 --- a/FileSets/v3.40~16/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/OverviewHub.qml b/FileSets/v3.40~16/OverviewHub.qml deleted file mode 120000 index 93c6ee1a..00000000 --- a/FileSets/v3.40~16/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/OverviewHubEnhanced.qml b/FileSets/v3.40~16/OverviewHubEnhanced.qml deleted file mode 120000 index c55515d9..00000000 --- a/FileSets/v3.40~16/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/OverviewMobileEnhanced.qml b/FileSets/v3.40~16/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.40~16/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/OverviewSolarCharger.qml b/FileSets/v3.40~16/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v3.40~16/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/OverviewSolarInverter.qml b/FileSets/v3.40~16/OverviewSolarInverter.qml deleted file mode 120000 index 4048703e..00000000 --- a/FileSets/v3.40~16/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/OverviewTankDelegate.qml b/FileSets/v3.40~16/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v3.40~16/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/OverviewTanks.qml b/FileSets/v3.40~16/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v3.40~16/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~16/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.40~16/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/PageDigitalInput.qml b/FileSets/v3.40~16/PageDigitalInput.qml deleted file mode 120000 index 5b768f8f..00000000 --- a/FileSets/v3.40~16/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/PageGenerator.qml b/FileSets/v3.40~16/PageGenerator.qml deleted file mode 120000 index efbafddf..00000000 --- a/FileSets/v3.40~16/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/PageMain.qml b/FileSets/v3.40~16/PageMain.qml deleted file mode 120000 index ef4b9c47..00000000 --- a/FileSets/v3.40~16/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/PageSettingsDisplay.qml b/FileSets/v3.40~16/PageSettingsDisplay.qml deleted file mode 120000 index 03766d99..00000000 --- a/FileSets/v3.40~16/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/PageSettingsGenerator.qml b/FileSets/v3.40~16/PageSettingsGenerator.qml deleted file mode 120000 index 15dd8f85..00000000 --- a/FileSets/v3.40~16/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/PageSettingsGuiMods.qml b/FileSets/v3.40~16/PageSettingsGuiMods.qml deleted file mode 120000 index e831a7a4..00000000 --- a/FileSets/v3.40~16/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/PageSettingsRelay.qml b/FileSets/v3.40~16/PageSettingsRelay.qml deleted file mode 120000 index 156aadac..00000000 --- a/FileSets/v3.40~16/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/PowerGauge.qml b/FileSets/v3.40~16/PowerGauge.qml deleted file mode 120000 index 4bcaaa4a..00000000 --- a/FileSets/v3.40~16/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/Tile.qml b/FileSets/v3.40~16/Tile.qml deleted file mode 120000 index 0558cecf..00000000 --- a/FileSets/v3.40~16/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/TileDigIn.qml b/FileSets/v3.40~16/TileDigIn.qml deleted file mode 120000 index 44616f30..00000000 --- a/FileSets/v3.40~16/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/TileRelay.qml b/FileSets/v3.40~16/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.40~16/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/TileText.qml b/FileSets/v3.40~16/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v3.40~16/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/dbus_digitalinputs.py b/FileSets/v3.40~16/dbus_digitalinputs.py deleted file mode 120000 index e74da5b6..00000000 --- a/FileSets/v3.40~16/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.40~16/dbus_generator.py b/FileSets/v3.40~16/dbus_generator.py deleted file mode 120000 index 0cd84ca3..00000000 --- a/FileSets/v3.40~16/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.40~16/main.qml b/FileSets/v3.40~16/main.qml deleted file mode 120000 index 5dbfdf83..00000000 --- a/FileSets/v3.40~16/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/main.qml \ No newline at end of file diff --git a/FileSets/v3.40~16/startstop.py b/FileSets/v3.40~16/startstop.py deleted file mode 120000 index 274861e3..00000000 --- a/FileSets/v3.40~16/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~17/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~16/styles.css b/FileSets/v3.40~16/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v3.40~16/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v3.40~17/Battery.qml b/FileSets/v3.40~17/Battery.qml deleted file mode 120000 index fafc7b36..00000000 --- a/FileSets/v3.40~17/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/COMPLETE b/FileSets/v3.40~17/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~17/DetailAcInput.qml b/FileSets/v3.40~17/DetailAcInput.qml deleted file mode 120000 index 8e76794d..00000000 --- a/FileSets/v3.40~17/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/DetailInverter.qml b/FileSets/v3.40~17/DetailInverter.qml deleted file mode 120000 index 285b3216..00000000 --- a/FileSets/v3.40~17/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/DetailLoadsCombined.qml b/FileSets/v3.40~17/DetailLoadsCombined.qml deleted file mode 120000 index 81c6de5a..00000000 --- a/FileSets/v3.40~17/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/DetailLoadsOnInput.qml b/FileSets/v3.40~17/DetailLoadsOnInput.qml deleted file mode 120000 index a5f97488..00000000 --- a/FileSets/v3.40~17/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/DetailLoadsOnOutput.qml b/FileSets/v3.40~17/DetailLoadsOnOutput.qml deleted file mode 120000 index 7cfc98c6..00000000 --- a/FileSets/v3.40~17/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/HubData.qml b/FileSets/v3.40~17/HubData.qml deleted file mode 120000 index c80a3bff..00000000 --- a/FileSets/v3.40~17/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/MbEditBox.qml b/FileSets/v3.40~17/MbEditBox.qml deleted file mode 120000 index 90a92492..00000000 --- a/FileSets/v3.40~17/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/MbEditBoxDateTime.qml b/FileSets/v3.40~17/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v3.40~17/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/MbItem.qml b/FileSets/v3.40~17/MbItem.qml deleted file mode 120000 index 048a313c..00000000 --- a/FileSets/v3.40~17/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/MbItemDigitalInput.qml b/FileSets/v3.40~17/MbItemDigitalInput.qml deleted file mode 120000 index 4404b520..00000000 --- a/FileSets/v3.40~17/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/MbSpinBox.qml b/FileSets/v3.40~17/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v3.40~17/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/MbStyle.qml b/FileSets/v3.40~17/MbStyle.qml deleted file mode 120000 index d1940446..00000000 --- a/FileSets/v3.40~17/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/MbSubMenu.qml b/FileSets/v3.40~17/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v3.40~17/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/Multi.qml b/FileSets/v3.40~17/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v3.40~17/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/ObjectAcConnection.qml b/FileSets/v3.40~17/ObjectAcConnection.qml deleted file mode 120000 index cab7f2d4..00000000 --- a/FileSets/v3.40~17/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~17/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 6d1e56b5..00000000 --- a/FileSets/v3.40~17/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/OverviewBox.qml b/FileSets/v3.40~17/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v3.40~17/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/OverviewConnection.qml b/FileSets/v3.40~17/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v3.40~17/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/OverviewConnectionEnd.qml b/FileSets/v3.40~17/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v3.40~17/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/OverviewFlowComplex.qml b/FileSets/v3.40~17/OverviewFlowComplex.qml deleted file mode 120000 index a151db4f..00000000 --- a/FileSets/v3.40~17/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~17/OverviewGeneratorEnhanced.qml deleted file mode 120000 index da5507a7..00000000 --- a/FileSets/v3.40~17/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~17/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index 1c9b530f..00000000 --- a/FileSets/v3.40~17/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/OverviewGridParallel.qml b/FileSets/v3.40~17/OverviewGridParallel.qml deleted file mode 120000 index d30a27d7..00000000 --- a/FileSets/v3.40~17/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/OverviewHub.qml b/FileSets/v3.40~17/OverviewHub.qml deleted file mode 120000 index 93c6ee1a..00000000 --- a/FileSets/v3.40~17/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/OverviewHubEnhanced.qml b/FileSets/v3.40~17/OverviewHubEnhanced.qml deleted file mode 120000 index c55515d9..00000000 --- a/FileSets/v3.40~17/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/OverviewMobileEnhanced.qml b/FileSets/v3.40~17/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.40~17/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/OverviewSolarCharger.qml b/FileSets/v3.40~17/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v3.40~17/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/OverviewSolarInverter.qml b/FileSets/v3.40~17/OverviewSolarInverter.qml deleted file mode 120000 index 4048703e..00000000 --- a/FileSets/v3.40~17/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/OverviewTankDelegate.qml b/FileSets/v3.40~17/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v3.40~17/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/OverviewTanks.qml b/FileSets/v3.40~17/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v3.40~17/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~17/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.40~17/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/PageDigitalInput.qml b/FileSets/v3.40~17/PageDigitalInput.qml deleted file mode 120000 index 5b768f8f..00000000 --- a/FileSets/v3.40~17/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/PageGenerator.qml b/FileSets/v3.40~17/PageGenerator.qml deleted file mode 120000 index efbafddf..00000000 --- a/FileSets/v3.40~17/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/PageMain.qml b/FileSets/v3.40~17/PageMain.qml deleted file mode 120000 index ef4b9c47..00000000 --- a/FileSets/v3.40~17/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/PageSettingsDisplay.qml b/FileSets/v3.40~17/PageSettingsDisplay.qml deleted file mode 120000 index 03766d99..00000000 --- a/FileSets/v3.40~17/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/PageSettingsGenerator.qml b/FileSets/v3.40~17/PageSettingsGenerator.qml deleted file mode 120000 index 15dd8f85..00000000 --- a/FileSets/v3.40~17/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/PageSettingsGuiMods.qml b/FileSets/v3.40~17/PageSettingsGuiMods.qml deleted file mode 120000 index e831a7a4..00000000 --- a/FileSets/v3.40~17/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/PageSettingsRelay.qml b/FileSets/v3.40~17/PageSettingsRelay.qml deleted file mode 120000 index 156aadac..00000000 --- a/FileSets/v3.40~17/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/PowerGauge.qml b/FileSets/v3.40~17/PowerGauge.qml deleted file mode 120000 index 4bcaaa4a..00000000 --- a/FileSets/v3.40~17/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/Tile.qml b/FileSets/v3.40~17/Tile.qml deleted file mode 120000 index 0558cecf..00000000 --- a/FileSets/v3.40~17/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/TileDigIn.qml b/FileSets/v3.40~17/TileDigIn.qml deleted file mode 120000 index 44616f30..00000000 --- a/FileSets/v3.40~17/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/TileRelay.qml b/FileSets/v3.40~17/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.40~17/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/TileText.qml b/FileSets/v3.40~17/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v3.40~17/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/attributes.csv b/FileSets/v3.40~17/attributes.csv deleted file mode 120000 index 6508da35..00000000 --- a/FileSets/v3.40~17/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v3.40~26/attributes.csv \ No newline at end of file diff --git a/FileSets/v3.40~17/dbus_digitalinputs.py b/FileSets/v3.40~17/dbus_digitalinputs.py deleted file mode 120000 index e74da5b6..00000000 --- a/FileSets/v3.40~17/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.40~17/dbus_generator.py b/FileSets/v3.40~17/dbus_generator.py deleted file mode 120000 index 0cd84ca3..00000000 --- a/FileSets/v3.40~17/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.40~17/dbus_systemcalc.py b/FileSets/v3.40~17/dbus_systemcalc.py deleted file mode 120000 index c519cce7..00000000 --- a/FileSets/v3.40~17/dbus_systemcalc.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~20/dbus_systemcalc.py \ No newline at end of file diff --git a/FileSets/v3.40~17/main.qml b/FileSets/v3.40~17/main.qml deleted file mode 120000 index 5dbfdf83..00000000 --- a/FileSets/v3.40~17/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/main.qml \ No newline at end of file diff --git a/FileSets/v3.40~17/startstop.py b/FileSets/v3.40~17/startstop.py deleted file mode 100644 index e3a11410..00000000 --- a/FileSets/v3.40~17/startstop.py +++ /dev/null @@ -1,1536 +0,0 @@ -#!/usr/bin/python -u -# -*- coding: utf-8 -*- - -#### GuiMods -#### This file has been modified to allow the generator running state derived from the generator digital input -#### or the genset AC input -#### If the incoming generator state changes, the manual start state is updated -#### time accumulation is suspended when the generator is not running -#### A switch in the generator settings menucontrols whethter the incoming state affects manual start or time accumulaiton -#### It is now possible to start the generator manually and have it stop automatically based on the preset conditions -#### for automaitc start / stop -#### A service interval timer was added so the accumulated run time does not need to be reset, -#### providing total run time for the generator -#### warm-up and cool-down periods have been modified in order to work well with an external transfer switch -#### selecting grid or generator ahead of a MultiPlus input. -#### Search for #### GuiMods to find changes - -# Function -# dbus_generator monitors the dbus for batteries (com.victronenergy.battery.*) and -# vebus com.victronenergy.vebus.* -# Battery and vebus monitors can be configured through the gui. -# It then monitors SOC, AC loads, battery current and battery voltage,to auto start/stop the generator based -# on the configuration settings. Generator can be started manually or periodically setting a tes trun period. -# Time zones function allows to use different values for the conditions along the day depending on time - -import dbus -import datetime -import calendar -import time -import sys -import json -import os -import logging -from collections import OrderedDict -import monotonic_time -from gen_utils import SettingsPrefix, Errors, States, enum -from gen_utils import create_dbus_service -# Victron packages -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) -from ve_utils import exit_on_error -from settingsdevice import SettingsDevice - -RunningConditions = enum( - Stopped = 0, - Manual = 1, - TestRun = 2, - LossOfCommunication = 3, - Soc = 4, - Acload = 5, - BatteryCurrent = 6, - BatteryVoltage = 7, - InverterHighTemp = 8, - InverterOverload = 9, - StopOnAc1 = 10, - StopOnAc2 = 11) - -Capabilities = enum( - WarmupCooldown = 1 -) - -SYSTEM_SERVICE = 'com.victronenergy.system' -BATTERY_PREFIX = '/Dc/Battery' -HISTORY_DAYS = 30 - -def safe_max(args): - try: - return max(x for x in args if x is not None) - except ValueError: - return None - -class Condition(object): - def __init__(self, parent): - self.parent = parent - self.reached = False - self.start_timer = 0 - self.stop_timer = 0 - self.valid = True - self.enabled = False - self.retries = 0 - - def __getitem__(self, key): - try: - return getattr(self, key) - except AttributeError: - raise KeyError(key) - - def __setitem__(self, key, value): - setattr(self, key, value) - - def get_value(self): - raise NotImplementedError("get_value") - - @property - def vebus_service(self): - return self.parent._vebusservice if self.parent._vebusservice else '' - - @property - def monitor(self): - return self.parent._dbusmonitor - -class SocCondition(Condition): - name = 'soc' - monitoring = 'battery' - boolean = False - timed = True - - def get_value(self): - return self.parent._get_battery().soc - -class AcLoadCondition(Condition): - name = 'acload' - monitoring = 'vebus' - boolean = False - timed = True - - def get_value(self): - loadOnAcOut = [] - totalConsumption = [] - - for phase in ['L1', 'L2', 'L3']: - # Get the values directly from the inverter, systemcalc doesn't provide raw inverted power - loadOnAcOut.append(self.monitor.get_value(self.vebus_service, ('/Ac/Out/%s/P' % phase))) - - # Calculate total consumption, '/Ac/Consumption/%s/Power' is deprecated - c_i = self.monitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnInput/%s/Power' % phase)) - c_o = self.monitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnOutput/%s/Power' % phase)) - totalConsumption.append(sum(filter(None, (c_i, c_o)))) - - # Invalidate if vebus is not available - if loadOnAcOut[0] == None: - return None - - # Total consumption - if self.parent._settings['acloadmeasurement'] == 0: - return sum(filter(None, totalConsumption)) - - # Load on inverter AC out - if self.parent._settings['acloadmeasurement'] == 1: - return sum(filter(None, loadOnAcOut)) - - # Highest phase load - if self.parent._settings['acloadmeasurement'] == 2: - return safe_max(loadOnAcOut) - -class BatteryCurrentCondition(Condition): - name = 'batterycurrent' - monitoring = 'battery' - boolean = False - timed = True - - def get_value(self): - c = self.parent._get_battery().current - if c is not None: - c *= -1 - return c - -class BatteryVoltageCondition(Condition): - name = 'batteryvoltage' - monitoring = 'battery' - boolean = False - timed = True - - def get_value(self): - return self.parent._get_battery().voltage - -class InverterTempCondition(Condition): - name = 'inverterhightemp' - monitoring = 'vebus' - boolean = True - timed = True - - def get_value(self): - v = self.monitor.get_value(self.vebus_service, - '/Alarms/HighTemperature') - - # When multi is connected to CAN-bus, alarms are published to - # /Alarms/HighTemperature... but when connected to vebus alarms are - # splitted in three phases and published to /Alarms/LX/HighTemperature... - if v is None: - inverterHighTemp = [] - for phase in ['L1', 'L2', 'L3']: - # Inverter alarms must be fetched directly from the inverter service - inverterHighTemp.append(self.monitor.get_value(self.vebus_service, ('/Alarms/%s/HighTemperature' % phase))) - return safe_max(inverterHighTemp) - return v - -class InverterOverloadCondition(Condition): - name = 'inverteroverload' - monitoring = 'vebus' - boolean = True - timed = True - - def get_value(self): - v = self.monitor.get_value(self.vebus_service, - '/Alarms/Overload') - - # When multi is connected to CAN-bus, alarms are published to - # /Alarms/Overload... but when connected to vebus alarms are - # splitted in three phases and published to /Alarms/LX/Overload... - if v is None: - inverterOverload = [] - for phase in ['L1', 'L2', 'L3']: - # Inverter alarms must be fetched directly from the inverter service - inverterOverload.append(self.monitor.get_value(self.vebus_service, ('/Alarms/%s/Overload' % phase))) - return safe_max(inverterOverload) - return v - -class StopOnAc1Condition(Condition): - name = 'stoponac1' - monitoring = 'vebus' - boolean = True - timed = False - - def get_value(self): - # AC input 1 - available = self.monitor.get_value(self.vebus_service, - '/Ac/State/AcIn1Available') - if available is None: - # Not supported in firmware, fall back to old behaviour - activein = self.monitor.get_value(self.vebus_service, - '/Ac/ActiveIn/ActiveInput') - - # Active input is connected - connected = self.monitor.get_value(self.vebus_service, - '/Ac/ActiveIn/Connected') - if None not in (activein, connected): - return activein == 0 and connected == 1 - return None - - return bool(available) - -class StopOnAc2Condition(Condition): - name = 'stoponac2' - monitoring = 'vebus' - boolean = True - timed = False - - def get_value(self): - # AC input 2 available (used when grid is on AC-in-2) - available = self.monitor.get_value(self.vebus_service, - '/Ac/State/AcIn2Available') - - return None if available is None else bool(available) - -class Battery(object): - def __init__(self, monitor, service, prefix): - self.monitor = monitor - self.service = service - self.prefix = prefix - - @property - def voltage(self): - return self.monitor.get_value(self.service, self.prefix + '/Voltage') - - @property - def current(self): - return self.monitor.get_value(self.service, self.prefix + '/Current') - - @property - def soc(self): - # Soc from the device doesn't have the '/Dc/0' prefix like the current and voltage do, but it does - # have the same prefix on systemcalc - return self.monitor.get_value(self.service, (BATTERY_PREFIX if self.prefix == BATTERY_PREFIX else '') + '/Soc') - -class StartStop(object): - _driver = None - def __init__(self, instance): -#### GuiMods - logging.info ("GuiMods version of startstop.py") - self._currentTime = 0 - self._last_update_mtime = 0 - self._accumulatedRunTime = 0 - self._digitalInputTypeObject = None - self._generatorInputStateObject = 0 - self._lastState = 0 - self._externalOverride = False - self._externalOverrideDelay = 99 - self._lastExternalOverride = False - self._searchDelay = 99 - self._linkToExternalState = False -#### GuiMods warm-up / cool-down - self._warmUpEndTime = 0 - self._coolDownEndTime = 0 - self._ac1isIgnored = False - self._ac2isIgnored = False - self._activeAcInIsIgnored = False - self._acInIsGenerator = False - - self._dbusservice = None - self._settings = None - self._dbusmonitor = None - self._remoteservice = None - self._name = None - self._enabled = False - self._instance = instance - - # One second per retry - self.RETRIES_ON_ERROR = 300 - self._testrun_soc_retries = 0 - self._last_counters_check = 0 - - self._starttime = 0 - self._stoptime = 0 # Used for cooldown - self._manualstarttimer = 0 - self._last_runtime_update = 0 - self._timer_runnning = 0 - - # The installer left autostart disabled - self.AUTOSTART_DISABLED_ALARM_TIME = 600 - self._autostart_last_time = self._get_monotonic_seconds() - - - # Manual battery service selection is deprecated in favour - # of getting the values directly from systemcalc, we keep - # manual selected services handling for compatibility reasons. - self._vebusservice = None - self._errorstate = 0 - self._battery_service = None - self._battery_prefix = None - - self._acpower_inverter_input = { - 'timeout': 0, - 'unabletostart': False - } - - # Order is important. Conditions are evaluated in the order listed. - self._condition_stack = OrderedDict({ - SocCondition.name: SocCondition(self), - AcLoadCondition.name: AcLoadCondition(self), - BatteryCurrentCondition.name: BatteryCurrentCondition(self), - BatteryVoltageCondition.name: BatteryVoltageCondition(self), - InverterTempCondition.name: InverterTempCondition(self), - InverterOverloadCondition.name: InverterOverloadCondition(self), - StopOnAc1Condition.name: StopOnAc1Condition(self), - StopOnAc2Condition.name: StopOnAc2Condition(self) - }) - - def set_sources(self, dbusmonitor, settings, name, remoteservice): - self._settings = SettingsPrefix(settings, name) - self._dbusmonitor = dbusmonitor - self._remoteservice = remoteservice - self._name = name - - self.log_info('Start/stop instance created for %s.' % self._remoteservice) - self._remote_setup() - - def _create_service(self): - self._dbusservice = self._create_dbus_service() - - # The driver used for this start/stop service - self._dbusservice.add_path('/Type', value=self._driver) - # State: None = invalid, 0 = stopped, 1 = running, 2=Warm-up, 3=Cool-down - self._dbusservice.add_path('/State', value=None, gettextcallback=lambda p, v: States.get_description(v)) - # RunningByConditionCode: Numeric Companion to /RunningByCondition below, but - # also encompassing a Stopped state. - self._dbusservice.add_path('/RunningByConditionCode', value=None) - # Error - self._dbusservice.add_path('/Error', value=None, gettextcallback=lambda p, v: Errors.get_description(v)) - # Condition that made the generator start - self._dbusservice.add_path('/RunningByCondition', value=None) - # Runtime - self._dbusservice.add_path('/Runtime', value=None, gettextcallback=self._seconds_to_text) - # Today runtime - self._dbusservice.add_path('/TodayRuntime', value=None, gettextcallback=self._seconds_to_text) - # Test run runtime - self._dbusservice.add_path('/TestRunIntervalRuntime', value=None , gettextcallback=self._seconds_to_text) - # Next test run date, values is 0 for test run disabled - self._dbusservice.add_path('/NextTestRun', value=None, gettextcallback=lambda p, v: datetime.datetime.fromtimestamp(v).strftime('%c')) - # Next test run is needed 1, not needed 0 - self._dbusservice.add_path('/SkipTestRun', value=None) - # Manual start - self._dbusservice.add_path('/ManualStart', value=None, writeable=True) - # Manual start timer - self._dbusservice.add_path('/ManualStartTimer', value=None, writeable=True) - # Silent mode active - self._dbusservice.add_path('/QuietHours', value=None) - # Alarms - self._dbusservice.add_path('/Alarms/NoGeneratorAtAcIn', value=None) - self._dbusservice.add_path('/Alarms/ServiceIntervalExceeded', value=None) - self._dbusservice.add_path('/Alarms/AutoStartDisabled', value=None) - # Autostart - self._dbusservice.add_path('/AutoStartEnabled', value=None, writeable=True, onchangecallback=self._set_autostart) - # Accumulated runtime - self._dbusservice.add_path('/AccumulatedRuntime', value=None) - # Service interval - self._dbusservice.add_path('/ServiceInterval', value=None) - # Capabilities, where we can add bits - self._dbusservice.add_path('/Capabilities', value=0) - # Service countdown, calculated by running time and service interval - self._dbusservice.add_path('/ServiceCounter', value=None) - self._dbusservice.add_path('/ServiceCounterReset', value=None, writeable=True, onchangecallback=self._reset_service_counter) - # Publish what service we're controlling, and the productid - self._dbusservice.add_path('/GensetService', value=self._remoteservice) - self._dbusservice.add_path('/GensetInstance', - value=self._dbusmonitor.get_value(self._remoteservice, '/DeviceInstance')) - self._dbusservice.add_path('/GensetProductId', - value=self._dbusmonitor.get_value(self._remoteservice, '/ProductId')) - - # We need to set the values after creating the paths to trigger the 'onValueChanged' event for the gui - # otherwise the gui will report the paths as invalid if we remove and recreate the paths without - # restarting the dbusservice. - self._dbusservice['/State'] = 0 - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped - self._dbusservice['/Error'] = 0 - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/Runtime'] = 0 - self._dbusservice['/TodayRuntime'] = 0 - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - self._dbusservice['/NextTestRun'] = None - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/ProductName'] = "Generator start/stop" - self._dbusservice['/ManualStart'] = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._dbusservice['/QuietHours'] = 0 - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - self._dbusservice['/Alarms/ServiceIntervalExceeded'] = 0 - self._dbusservice['/Alarms/AutoStartDisabled'] = 0 - self._dbusservice['/AutoStartEnabled'] = self._settings['autostart'] - self._dbusservice['/AccumulatedRuntime'] = int(self._settings['accumulatedtotal']) - self._dbusservice['/ServiceInterval'] = int(self._settings['serviceinterval']) - self._dbusservice['/ServiceCounter'] = None - self._dbusservice['/ServiceCounterReset'] = 0 - -#### GuiMods - # generator input running state - self._dbusservice.add_path('/GeneratorRunningState', value=None) - # external override active - self._dbusservice.add_path('/ExternalOverride', value=None) - self._dbusservice['/GeneratorRunningState'] = "?" - self._dbusservice['/ExternalOverride'] = False - self._ignoresAutoStartCondition = False - - @property - def capabilities(self): - return self._dbusservice['/Capabilities'] - - def _set_autostart(self, path, value): - if 0 <= value <= 1: - self._settings['autostart'] = int(value) - return True - return False - - def enable(self): - if self._enabled: - return - self.log_info('Enabling auto start/stop and taking control of remote switch') - self._create_service() - self._determineservices() - self._update_remote_switch() - # If cooldown or warmup is enabled, the Quattro may be left in a bad - # state if there is an unfortunate crash or a reboot. Set the ignore_ac - # flag to a sane value on startup. - if self._settings['cooldowntime'] > 0 or \ - self._settings['warmuptime'] > 0: - self._set_ignore_ac(False) ########### - self._enabled = True - - def disable(self): - if not self._enabled: - return - self.log_info('Disabling auto start/stop, releasing control of remote switch') - self._remove_service() - self._enabled = False - - def remove(self): - self.disable() - self.log_info('Removed from start/stop instances') - - def _remove_service(self): - self._dbusservice.__del__() - self._dbusservice = None - - def device_added(self, dbusservicename, instance): - self._determineservices() - - def device_removed(self, dbusservicename, instance): - self._determineservices() - - def get_error(self): - return self._dbusservice['/Error'] - - def set_error(self, errorn): - self._dbusservice['/Error'] = errorn - - def clear_error(self): - self._dbusservice['/Error'] = Errors.NONE - - def dbus_value_changed(self, dbusServiceName, dbusPath, options, changes, deviceInstance): - if self._dbusservice is None: - return - - # AcIn1Available is needed to determine capabilities, but may - # only show up later. So we have to wait for it here. - if self._vebusservice is not None and \ - dbusServiceName == self._vebusservice and \ - dbusPath == '/Ac/State/AcIn1Available': - self._set_capabilities() - - if dbusServiceName != 'com.victronenergy.system': - return - if dbusPath == '/AutoSelectedBatteryMeasurement' and self._settings['batterymeasurement'] == 'default': - self._determineservices() - - if dbusPath == '/VebusService': - self._determineservices() - - def handlechangedsetting(self, setting, oldvalue, newvalue): - if self._dbusservice is None: - return - if self._name not in setting: - # Not our setting - return - - s = self._settings.removeprefix(setting) - - if s == 'batterymeasurement': - self._determineservices() - # Reset retries and valid if service changes - for condition in self._condition_stack.values(): - if condition['monitoring'] == 'battery': - condition['valid'] = True - condition['retries'] = 0 - - if s == 'autostart': - self.log_info('Autostart function %s.' % ('enabled' if newvalue == 1 else 'disabled')) - self._dbusservice['/AutoStartEnabled'] = self._settings['autostart'] - - if self._dbusservice is not None and s == 'testruninterval': - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime( - self._settings['testruninterval']) - - if s == 'serviceinterval': - try: - self._dbusservice['/ServiceInterval'] = int(newvalue) - except TypeError: - pass - if newvalue == 0: - self._dbusservice['/ServiceCounter'] = None - else: - self._update_accumulated_time() - if s == 'lastservicereset': - self._update_accumulated_time() - - def _reset_service_counter(self, path, value): - if (path == '/ServiceCounterReset' and value == int(1) and self._dbusservice['/AccumulatedRuntime']): - self._settings['lastservicereset'] = self._dbusservice['/AccumulatedRuntime'] - self._update_accumulated_time() - self.log_info('Service counter reset triggered.') - - return True - - def _seconds_to_text(self, path, value): - m, s = divmod(value, 60) - h, m = divmod(m, 60) - return '%dh, %dm, %ds' % (h, m, s) - - def log_info(self, msg): - logging.info(self._name + ': %s' % msg) - - def tick(self): - if not self._enabled: - return - -#### GuiMods warm-up / cool-down - self._currentTime = self._get_monotonic_seconds () - - self._check_remote_status() -#### GuiMods - self._linkToExternalState = self._settings['linkManualStartToExternal'] == 1 - self._processGeneratorRunDetection () - - self._evaluate_startstop_conditions() - self._evaluate_autostart_disabled_alarm() - self._detect_generator_at_acinput() - if self._dbusservice['/ServiceCounterReset'] == 1: - self._dbusservice['/ServiceCounterReset'] = 0 - -#### GuiMods warm-up / cool-down - state = self._dbusservice['/State'] - - # shed load for active generator input in warm-up and cool-down - # note that external transfer switch might change the state of on generator - # so this needs to be checked and load adjusted every pass - # restore load for sources no longer in use or if state is not in warm-up/cool-down - # restoring load is delayed 1following end of cool-down - # to allow the generator to actually stop producing power - if state in (States.WARMUP, States.COOLDOWN, States.STOPPING): - self._set_ignore_ac (True) - else: - self._set_ignore_ac (False) - - # update cool down end time while running and generator has the load - # this is done because acInIsGenerator may change by an external transfer switch - # and we want an accurate picture of the cool down end time - # based on the last time the generatot was loaded - if state == States.RUNNING and self._acInIsGenerator: - self._coolDownEndTime = self._currentTime + self._settings['cooldowntime'] -#### end GuiMods warm-up / cool-down - - - def _evaluate_startstop_conditions(self): - if self.get_error() != Errors.NONE: - # First evaluation after an error, log it - if self._errorstate == 0: - self._errorstate = 1 - self._dbusservice['/State'] = States.ERROR - self.log_info('Error: #%i - %s, stop controlling remote.' % - (self.get_error(), - Errors.get_description(self.get_error()))) - elif self._errorstate == 1: - # Error cleared - self._errorstate = 0 - self._dbusservice['/State'] = States.STOPPED - self.log_info('Error state cleared, taking control of remote switch.') - - start = False - startbycondition = None - activecondition = self._dbusservice['/RunningByCondition'] - today = calendar.timegm(datetime.date.today().timetuple()) - self._timer_runnning = False - connection_lost = False - running = self._dbusservice['/State'] in (States.RUNNING, States.WARMUP) - - self._check_quiet_hours() - - # New day, register it - if self._last_counters_check < today and self._dbusservice['/State'] == States.STOPPED: - self._last_counters_check = today - self._update_accumulated_time() - - # Update current and accumulated runtime. -#### GuiMods - self._accumulateRunTime () - -#### GuiMods - # A negative /ManualStartTimer is used by the GUI to signal the generator should start now - # but stop when all auto stop conditions have been met - # so we skip manual start evaluation if this is the case - # and set a flag for use below to ignore auto start conditions - # the generator is actually started by the auto start/stop logic below - if self._dbusservice['/ManualStartTimer'] < 0 and self._dbusservice['/ManualStart'] == 1: - self._dbusservice['/ManualStartTimer'] = 0 - self._dbusservice['/ManualStart'] = 0 - self._ignoresAutoStartCondition = True - else: - self._ignoresAutoStartCondition = False - if self._evaluate_manual_start(): - startbycondition = 'manual' - start = True - - # Conditions will only be evaluated if the autostart functionality is enabled - if self._settings['autostart'] == 1: - - if self._evaluate_testrun_condition(): - startbycondition = 'testrun' - start = True - - # Evaluate stop on AC IN conditions first, when this conditions are enabled and reached the generator - # will stop as soon as AC IN in active. Manual and testrun conditions will make the generator start - # or keep it running. - stop_on_ac_reached = (self._evaluate_condition(self._condition_stack[StopOnAc1Condition.name]) or - self._evaluate_condition(self._condition_stack[StopOnAc2Condition.name])) - stop_by_ac1_ac2 = startbycondition not in ['manual', 'testrun'] and stop_on_ac_reached - - if stop_by_ac1_ac2 and running and activecondition not in ['manual', 'testrun']: - self.log_info('AC input available, stopping') - - # Evaluate value conditions - for condition, data in self._condition_stack.items(): - # Do not evaluate rest of conditions if generator is configured to stop - # when AC IN is available - if stop_by_ac1_ac2: - start = False - if running: - self._reset_condition(data) - continue - else: - break - - # Don't short-circuit this, _evaluate_condition sets .reached - start = self._evaluate_condition(data) or start - startbycondition = condition if start and startbycondition is None else startbycondition - # Connection lost is set to true if the number of retries of one or more enabled conditions - # >= RETRIES_ON_ERROR - if data.enabled: - connection_lost = data.retries >= self.RETRIES_ON_ERROR - - # If none condition is reached check if connection is lost and start/keep running the generator - # depending on '/OnLossCommunication' setting - if not start and connection_lost: - # Start always - if self._settings['onlosscommunication'] == 1: - start = True - startbycondition = 'lossofcommunication' - # Keep running if generator already started - if running and self._settings['onlosscommunication'] == 2: - start = True - startbycondition = 'lossofcommunication' - - if not start and self._errorstate: - self._stop_generator() - - if self._errorstate: - return - - if start: - self._start_generator(startbycondition) -#### GuiMods - # bypass the minimum run time check if External Override is active - elif (self._dbusservice['/Runtime'] >= self._settings['minimumruntime'] * 60 - or activecondition == 'manual') or self._dbusservice['/ExternalOverride']: - self._stop_generator() - - def _evaluate_autostart_disabled_alarm(self): - - if self._settings['autostart'] == 0 or \ - self.get_error() != Errors.REMOTEDISABLED or \ - self._settings['autostartdisabledalarm'] == 0: - self._autostart_last_time = self._get_monotonic_seconds() - if self._dbusservice['/Alarms/AutoStartDisabled'] != 0: - self._dbusservice['/Alarms/AutoStartDisabled'] = 0 - return - - timedisabled = self._get_monotonic_seconds() - self._autostart_last_time - if timedisabled > self.AUTOSTART_DISABLED_ALARM_TIME and self._dbusservice['/Alarms/AutoStartDisabled'] != 2: - self.log_info("Autostart was left for more than %i seconds, triggering alarm." % int(timedisabled)) - self._dbusservice['/Alarms/AutoStartDisabled'] = 2 - - -#### GuiMods warm-up / cool-down - rewrote so acInIsGenerator is updated even if alarm is disabled - def _detect_generator_at_acinput(self): -#### GuiMods warm-up / cool-down - self._acInIsGenerator = False # covers all conditions that result in a return - - state = self._dbusservice['/State'] - if state in [States.STOPPED, States.COOLDOWN, States.WARMUP]: - self._reset_acpower_inverter_input() - return - - vebus_service = self._vebusservice if self._vebusservice else '' - activein_state = self._dbusmonitor.get_value( - vebus_service, '/Ac/ActiveIn/Connected') - - # Path not supported, skip evaluation - if activein_state == None: - return - - # Sources 0 = Not available, 1 = Grid, 2 = Generator, 3 = Shore - generator_acsource = self._dbusmonitor.get_value( - SYSTEM_SERVICE, '/Ac/ActiveIn/Source') == 2 - # Not connected = 0, connected = 1 - activein_connected = activein_state == 1 - -#### GuiMods warm-up / cool-down - if self._settings['nogeneratoratacinalarm'] == 0: - processAlarm = False - self._reset_acpower_inverter_input() - else: - processAlarm = True - - if generator_acsource and activein_connected: -#### GuiMods warm-up / cool-down - self._acInIsGenerator = True -#### GuiMods warm-up / cool-down - if processAlarm and self._acpower_inverter_input['unabletostart']: - self.log_info('Generator detected at inverter AC input, alarm removed') - self._reset_acpower_inverter_input() -#### GuiMods warm-up / cool-down - elif not processAlarm: - self._reset_acpower_inverter_input() - return - elif self._acpower_inverter_input['timeout'] < self.RETRIES_ON_ERROR: - self._acpower_inverter_input['timeout'] += 1 - elif not self._acpower_inverter_input['unabletostart']: - self._acpower_inverter_input['unabletostart'] = True - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 2 - self.log_info('Generator not detected at inverter AC input, triggering alarm') - - - def _reset_acpower_inverter_input(self, clear_error=True): - if self._acpower_inverter_input['timeout'] != 0: - self._acpower_inverter_input['timeout'] = 0 - - if self._acpower_inverter_input['unabletostart'] != 0: - self._acpower_inverter_input['unabletostart'] = 0 - - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - - def _reset_condition(self, condition): - condition['reached'] = False - if condition['timed']: - condition['start_timer'] = 0 - condition['stop_timer'] = 0 - - def _check_condition(self, condition, value): - name = condition['name'] - - if self._settings[name + 'enabled'] == 0: - if condition['enabled']: - condition['enabled'] = False - self.log_info('Disabling (%s) condition' % name) - condition['retries'] = 0 - condition['valid'] = True - self._reset_condition(condition) - return False - - elif not condition['enabled']: - condition['enabled'] = True - self.log_info('Enabling (%s) condition' % name) - - if (condition['monitoring'] == 'battery') and (self._settings['batterymeasurement'] == 'nobattery'): - # If no battery monitor is selected reset the condition - self._reset_condition(condition) - return False - - if value is None and condition['valid']: - if condition['retries'] >= self.RETRIES_ON_ERROR: - logging.info('Error getting (%s) value, skipping evaluation till get a valid value' % name) - self._reset_condition(condition) - self._comunnication_lost = True - condition['valid'] = False - else: - condition['retries'] += 1 - if condition['retries'] == 1 or (condition['retries'] % 10) == 0: - self.log_info('Error getting (%s) value, retrying(#%i)' % (name, condition['retries'])) - return False - - elif value is not None and not condition['valid']: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['valid'] = True - condition['retries'] = 0 - - # Reset retries if value is valid - if value is not None and condition['retries'] > 0: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['retries'] = 0 - - return condition['valid'] - - def _evaluate_condition(self, condition): - name = condition['name'] - value = condition.get_value() - setting = ('qh_' if self._dbusservice['/QuietHours'] == 1 else '') + name - startvalue = self._settings[setting + 'start'] if not condition['boolean'] else 1 - stopvalue = self._settings[setting + 'stop'] if not condition['boolean'] else 0 - - # Check if the condition has to be evaluated - if not self._check_condition(condition, value): - # If generator is started by this condition and value is invalid - # wait till RETRIES_ON_ERROR to skip the condition - if condition['reached'] and condition['retries'] <= self.RETRIES_ON_ERROR: - if condition['retries'] > 0: - return True - - return False - - # As this is a generic evaluation method, we need to know how to compare the values - # first check if start value should be greater than stop value and then compare - start_is_greater = startvalue > stopvalue - -#### GuiMods - stop = value <= stopvalue if start_is_greater else value >= stopvalue - # when starting manually and stopping based on auto stop values, - # start if stop condition is not satisfied - if self._ignoresAutoStartCondition: - start = not stop - else: - # When the condition is already reached only the stop value can set it to False - start = condition['reached'] or (value >= startvalue if start_is_greater else value <= startvalue) - - # Timed conditions must start/stop after the condition has been reached for a minimum - # time. - if condition['timed']: - if not condition['reached'] and start: - condition['start_timer'] += time.time() if condition['start_timer'] == 0 else 0 - start = time.time() - condition['start_timer'] >= self._settings[name + 'starttimer'] - condition['stop_timer'] *= int(not start) - self._timer_runnning = True - else: - condition['start_timer'] = 0 - - if condition['reached'] and stop: - condition['stop_timer'] += time.time() if condition['stop_timer'] == 0 else 0 - stop = time.time() - condition['stop_timer'] >= self._settings[name + 'stoptimer'] - condition['stop_timer'] *= int(not stop) - self._timer_runnning = True - else: - condition['stop_timer'] = 0 - - condition['reached'] = start and not stop - return condition['reached'] - - def _evaluate_manual_start(self): - if self._dbusservice['/ManualStart'] == 0: - if self._dbusservice['/RunningByCondition'] == 'manual': - self._dbusservice['/ManualStartTimer'] = 0 - return False - - start = True - # If /ManualStartTimer has a value greater than zero will use it to set a stop timer. - # If no timer is set, the generator will not stop until the user stops it manually. - # Once started by manual start, each evaluation the timer is decreased -#### GuiMods - if self._dbusservice['/ManualStartTimer'] > 0: - self._manualstarttimer += time.time() if self._manualstarttimer == 0 else 0 - self._dbusservice['/ManualStartTimer'] -= int(time.time()) - int(self._manualstarttimer) - self._manualstarttimer = time.time() - start = self._dbusservice['/ManualStartTimer'] > 0 - self._dbusservice['/ManualStart'] = int(start) - # Reset if timer is finished - self._manualstarttimer *= int(start) - self._dbusservice['/ManualStartTimer'] *= int(start) - - return start - - def _evaluate_testrun_condition(self): - if self._settings['testrunenabled'] == 0: - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/NextTestRun'] = None - return False - - today = datetime.date.today() - yesterday = today - datetime.timedelta(days=1) # Should deal well with DST - now = time.time() - runtillbatteryfull = self._settings['testruntillbatteryfull'] == 1 - soc = self._condition_stack['soc'].get_value() - batteryisfull = runtillbatteryfull and soc == 100 - duration = 60 if runtillbatteryfull else self._settings['testrunruntime'] - - try: - startdate = datetime.date.fromtimestamp(self._settings['testrunstartdate']) - _starttime = time.mktime(yesterday.timetuple()) + self._settings['testrunstarttimer'] - - # today might in fact still be yesterday, if this test run started - # before midnight and finishes after. If `now` still falls in - # yesterday's window, then by the temporal anthropic principle, - # which I just made up but loosely states that time must have - # these properties for observers to exist, it must be yesterday - # because we are here to observe it. - if _starttime <= now <= _starttime + duration: - today = yesterday - starttime = _starttime - else: - starttime = time.mktime(today.timetuple()) + self._settings['testrunstarttimer'] - except ValueError: - logging.debug('Invalid dates, skipping testrun') - return False - - # If start date is in the future set as NextTestRun and stop evaluating - if startdate > today: - self._dbusservice['/NextTestRun'] = time.mktime(startdate.timetuple()) - return False - - start = False - # If the accumulated runtime during the tes trun interval is greater than '/TestRunIntervalRuntime' - # the tes trun must be skipped - needed = (self._settings['testrunskipruntime'] > self._dbusservice['/TestRunIntervalRuntime'] - or self._settings['testrunskipruntime'] == 0) - self._dbusservice['/SkipTestRun'] = int(not needed) - - interval = self._settings['testruninterval'] - stoptime = starttime + duration - elapseddays = (today - startdate).days - mod = elapseddays % interval - - start = not bool(mod) and starttime <= now <= stoptime - - if runtillbatteryfull: - if soc is not None: - self._testrun_soc_retries = 0 - start = (start or self._dbusservice['/RunningByCondition'] == 'testrun') and not batteryisfull - elif self._dbusservice['/RunningByCondition'] == 'testrun': - if self._testrun_soc_retries < self.RETRIES_ON_ERROR: - self._testrun_soc_retries += 1 - start = True - if (self._testrun_soc_retries % 10) == 0: - self.log_info('Test run failed to get SOC value, retrying(#%i)' % self._testrun_soc_retries) - else: - self.log_info('Failed to get SOC after %i retries, terminating test run condition' % self._testrun_soc_retries) - start = False - else: - start = False - - if not bool(mod) and (now <= stoptime): - self._dbusservice['/NextTestRun'] = starttime - else: - self._dbusservice['/NextTestRun'] = (time.mktime((today + datetime.timedelta(days=interval - mod)).timetuple()) + - self._settings['testrunstarttimer']) - return start and needed - - def _check_quiet_hours(self): - active = False - if self._settings['quiethoursenabled'] == 1: - # Seconds after today 00:00 - timeinseconds = time.time() - time.mktime(datetime.date.today().timetuple()) - quiethoursstart = self._settings['quiethoursstarttime'] - quiethoursend = self._settings['quiethoursendtime'] - - # Check if the current time is between the start time and end time - if quiethoursstart < quiethoursend: - active = quiethoursstart <= timeinseconds and timeinseconds < quiethoursend - else: # End time is lower than start time, example Start: 21:00, end: 08:00 - active = not (quiethoursend < timeinseconds and timeinseconds < quiethoursstart) - - if self._dbusservice['/QuietHours'] == 0 and active: - self.log_info('Entering to quiet mode') - - elif self._dbusservice['/QuietHours'] == 1 and not active: - self.log_info('Leaving quiet mode') - - self._dbusservice['/QuietHours'] = int(active) - - return active - - def _update_accumulated_time(self): - seconds = self._dbusservice['/Runtime'] - accumulated = seconds - self._last_runtime_update - - self._settings['accumulatedtotal'] = accumulatedtotal = int(self._settings['accumulatedtotal']) + accumulated - # Using calendar to get timestamp in UTC, not local time - today_date = str(calendar.timegm(datetime.date.today().timetuple())) - - # If something goes wrong getting the json string create a new one - try: - accumulated_days = json.loads(self._settings['accumulateddaily']) - except ValueError: - accumulated_days = {today_date: 0} - - if (today_date in accumulated_days): - accumulated_days[today_date] += accumulated - else: - accumulated_days[today_date] = accumulated - - self._last_runtime_update = seconds - - # Keep the historical with a maximum of HISTORY_DAYS - while len(accumulated_days) > HISTORY_DAYS: - accumulated_days.pop(min(accumulated_days.keys()), None) - - # Upadate settings - self._settings['accumulateddaily'] = json.dumps(accumulated_days, sort_keys=True) - self._dbusservice['/TodayRuntime'] = self._interval_runtime(0) - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - self._dbusservice['/AccumulatedRuntime'] = accumulatedtotal - - # Service counter - serviceinterval = self._settings['serviceinterval'] - lastservicereset = self._settings['lastservicereset'] - if serviceinterval > 0: - servicecountdown = (lastservicereset + serviceinterval) - accumulatedtotal - self._dbusservice['/ServiceCounter'] = servicecountdown - if servicecountdown <= 0: - self._dbusservice['/Alarms/ServiceIntervalExceeded'] = 1 - elif self._dbusservice['/Alarms/ServiceIntervalExceeded'] != 0: - self._dbusservice['/Alarms/ServiceIntervalExceeded'] = 0 - - - - def _interval_runtime(self, days): - summ = 0 - try: - daily_record = json.loads(self._settings['accumulateddaily']) - except ValueError: - return 0 - - for i in range(days + 1): - previous_day = calendar.timegm((datetime.date.today() - datetime.timedelta(days=i)).timetuple()) - if str(previous_day) in daily_record.keys(): - summ += daily_record[str(previous_day)] if str(previous_day) in daily_record.keys() else 0 - - return summ - - def _get_battery(self): - if self._settings['batterymeasurement'] == 'default': - return Battery(self._dbusmonitor, SYSTEM_SERVICE, BATTERY_PREFIX) - - return Battery(self._dbusmonitor, - self._battery_service if self._battery_service else '', - self._battery_prefix if self._battery_prefix else '') - - def _set_capabilities(self): - # Update capabilities - # The ability to ignore AC1/AC2 came in at the same time as - # AC availability and is used to detect it here. - readout_supported = self._dbusmonitor.get_value(self._vebusservice, - '/Ac/State/AcIn1Available') is not None - self._dbusservice['/Capabilities'] |= ( - Capabilities.WarmupCooldown if readout_supported else 0) - - def _determineservices(self): - # batterymeasurement is either 'default' or 'com_victronenergy_battery_288/Dc/0'. - # In case it is set to default, we use the AutoSelected battery - # measurement, given by SystemCalc. - batterymeasurement = None - newbatteryservice = None - batteryprefix = '' - selectedbattery = self._settings['batterymeasurement'] - vebusservice = None - - if selectedbattery == 'default': - batterymeasurement = 'default' - elif len(selectedbattery.split('/', 1)) == 2: # Only very basic sanity checking.. - batterymeasurement = self._settings['batterymeasurement'] - elif selectedbattery == 'nobattery': - batterymeasurement = None - else: - # Exception: unexpected value for batterymeasurement - pass - - if batterymeasurement and batterymeasurement != 'default': - batteryprefix = '/' + batterymeasurement.split('/', 1)[1] - - # Get the current battery servicename - if self._battery_service: - oldservice = self._battery_service - else: - oldservice = None - - if batterymeasurement != 'default': - battery_instance = int(batterymeasurement.split('_', 3)[3].split('/')[0]) - service_type = None - - if 'vebus' in batterymeasurement: - service_type = 'vebus' - elif 'battery' in batterymeasurement: - service_type = 'battery' - - newbatteryservice = self._get_servicename_by_instance(battery_instance, service_type) - elif batterymeasurement == 'default': - newbatteryservice = 'default' - - if newbatteryservice and newbatteryservice != oldservice: - if selectedbattery == 'default': - self.log_info('Getting battery values from systemcalc.') - if selectedbattery == 'nobattery': - self.log_info('Battery monitoring disabled! Stop evaluating related conditions') - self._battery_service = None - self._battery_prefix = None - self.log_info('Battery service we need (%s) found! Using it for generator start/stop' % batterymeasurement) - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - elif not newbatteryservice and newbatteryservice != oldservice: - self.log_info('Error getting battery service!') - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - - # Get the default VE.Bus service - vebusservice = self._dbusmonitor.get_value('com.victronenergy.system', '/VebusService') - if vebusservice: - if self._vebusservice != vebusservice: - self._vebusservice = vebusservice - self._set_capabilities() - self.log_info('Vebus service (%s) found! Using it for generator start/stop' % vebusservice) - else: - if self._vebusservice is not None: - self.log_info('Vebus service (%s) dissapeared! Stop evaluating related conditions' % self._vebusservice) - else: - self.log_info('Error getting Vebus service!') - self._vebusservice = None - - def _get_servicename_by_instance(self, instance, service_type=None): - sv = None - services = self._dbusmonitor.get_service_list() - - for service in services: - if service_type and service_type not in service: - continue - - if services[service] == instance: - sv = service - break - - return sv - - def _get_monotonic_seconds(self): - return monotonic_time.monotonic_time().to_seconds_double() - - def _start_generator(self, condition): - state = self._dbusservice['/State'] - remote_running = self._get_remote_switch_state() - - # This function will start the generator in the case generator not - # already running. When differs, the RunningByCondition is updated - running = state in (States.WARMUP, States.COOLDOWN, States.STOPPING, States.RUNNING) - if not (running and remote_running): # STOPPED, ERROR -#### GuiMods warm-up / cool-down - self.log_info('Starting generator by %s condition' % condition) - # if there is a warmup time specified, always go through warm-up state - # regardless of AC input in use - warmUpPeriod = self._settings['warmuptime'] - if warmUpPeriod > 0: - self._warmUpEndTime = self._currentTime + warmUpPeriod - self.log_info ("starting warm-up") - self._dbusservice['/State'] = States.WARMUP - # no warm-up go directly to running - else: - self._dbusservice['/State'] = States.RUNNING - self._warmUpEndTime = 0 - - self._coolDownEndTime = 0 - self._stoptime = 0 - - self._update_remote_switch() - else: # WARMUP, COOLDOWN, RUNNING, STOPPING - if state in (States.COOLDOWN, States.STOPPING): - # Start request during cool-down run, go back to RUNNING - self.log_info ("aborting cool-down - returning to running") - self._dbusservice['/State'] = States.RUNNING - - elif state == States.WARMUP: - if self._currentTime > self._warmUpEndTime: - self.log_info ("warm-up complete") - self._dbusservice['/State'] = States.RUNNING - - # Update the RunningByCondition - if self._dbusservice['/RunningByCondition'] != condition: - self.log_info('Generator previously running by %s condition is now running by %s condition' - % (self._dbusservice['/RunningByCondition'], condition)) -#### end GuiMods warm-up / cool-down - - - self._dbusservice['/RunningByCondition'] = condition - self._dbusservice['/RunningByConditionCode'] = RunningConditions.lookup(condition) - - - def _stop_generator(self): - state = self._dbusservice['/State'] - remote_running = self._get_remote_switch_state() - running = state in (States.WARMUP, States.COOLDOWN, States.STOPPING, States.RUNNING) - - if running or remote_running: -#### GuiMods warm-up / cool-down - if state == States.RUNNING: - state = States.COOLDOWN - if self._currentTime < self._coolDownEndTime: - self.log_info ("starting cool-down") - elif self._settings['cooldowntime'] != 0: - self.log_info ("skipping cool-down -- no AC load on generator") - - # warm-up should also transition to stopping - # cool-down time will have expired since it's set to 0 when starting - # and there has not yet been a load on the generator - if state in (States.WARMUP, States.COOLDOWN): - # cool down complete - if self._currentTime > self._coolDownEndTime: - state = States.STOPPING - self.log_info('Stopping generator that was running by %s condition' % - str(self._dbusservice['/RunningByCondition'])) - self._update_remote_switch() # Stop engine - self._stoptime = self._currentTime + self._settings['generatorstoptime'] - if self._currentTime < self._stoptime: - self.log_info ("waiting for generator so stop") - - if state == States.STOPPING: - # wait for stop period expired - finish up transition to STOPPED - if self._currentTime > self._stoptime: - if self._settings['generatorstoptime'] != 0: - self.log_info ("generator stop time reached - OK to reconnect AC") - state = States.STOPPED - self._update_remote_switch() - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped - self._update_accumulated_time() - self._starttime = 0 - self._dbusservice['/Runtime'] = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._manualstarttimer = 0 - self._last_runtime_update = 0 - - self._dbusservice['/State'] = state -#### end GuiMods warm-up / cool-down - - - @property - def _ac1_is_generator(self): - return self._dbusmonitor.get_value('com.victronenergy.settings', - '/Settings/SystemSetup/AcInput1') == 2 - - @property - def _ac2_is_generator(self): - return self._dbusmonitor.get_value('com.victronenergy.settings', - '/Settings/SystemSetup/AcInput2') == 2 - - def _set_ignore_ac(self, ignore): - # This is here so the Multi/Quattro can be told to disconnect AC-in, - # so that we can do warm-up and cool-down. -#### GuiMods warm-up / cool-down - # stock code does not handle changes in the input type - # which could happen with an external transfer switch - # doing things this way should handle it - - self._activeAcInIsIgnored = ignore - ignore1 = False - ignore2 = False - if self._ac1_is_generator: - ignore1 = ignore - elif self._ac2_is_generator: - ignore2 = ignore - - if ignore1 != self._ac1isIgnored: - if ignore1: - self.log_info ("shedding load - AC input 1") - else: - self.log_info ("restoring load - AC input 1") - self._dbusmonitor.set_value_async(self._vebusservice, '/Ac/Control/IgnoreAcIn1', dbus.Int32(ignore1, variant_level=1)) - self._ac1isIgnored = ignore1 - - if ignore2 != self._ac2isIgnored: - if ignore2: - self.log_info ("shedding load - AC input 2") - else: - self.log_info ("restoring load - AC input 2") - self._dbusmonitor.set_value_async(self._vebusservice, '/Ac/Control/IgnoreAcIn2', dbus.Int32(ignore2, variant_level=1)) - self._ac2isIgnored = ignore2 -#### end GuiMods warm-up / cool-down - - - def _update_remote_switch(self): - # Engine should be started in these states - v = self._dbusservice['/State'] in (States.RUNNING, States.WARMUP, States.COOLDOWN) - self._set_remote_switch_state(dbus.Int32(v, variant_level=1)) -#### GuiMods - if v == True: - self.log_info ("updating remote switch to running") - else: - self.log_info ("updating remote switch to stopped") - - def _get_remote_switch_state(self): - raise Exception('This function should be overridden') - - def _set_remote_switch_state(self, value): - raise Exception('This function should be overridden') - - # Check the remote status, for example errors - def _check_remote_status(self): - raise Exception('This function should be overridden') - - def _remote_setup(self): - raise Exception('This function should be overridden') - - def _create_dbus_monitor(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_settings(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_dbus_service(self): - return create_dbus_service(self._instance) - - -#### GuiMods - -# this function connects the generator digital input (if any) -# OR the generator AC input detection -# to the generator /ManualStart and updates dbus paths used by the GUI -# -# if the generator digital input changes from stopped to running -# AND no run conditions are active, a manual start is innitiated -# -# if the generator digital input changes from running to stopped -# AND a manual start is active, a manual stop is innitiated -# -# /GeneratorRunningState provides the input running state from the digital input to the GUI -# R = running -# S = stopped -# ? = unknown (no digital input found) -# -# /ExternalOverride is used by the GUI to alert the user when there is a conflict -# between the generator running state and the state Venus -# /ExternalOverride is True if /GeneratorRunningState is S -# AND the /RunningCondition is not stopped (which includes a manual run) -# activation is delayed 5 seconds to allow transitions to settle -# -# we must first find the geneator digital input, if it exists at all -# we serche all dBus services looking for a digital input with type generator (9) -# the search only occurs every 10 seconds -# - - def _processGeneratorRunDetection (self): - TheBus = dbus.SystemBus() - generatorState = self._dbusservice['/State'] - try: - # current input service is no longer valid - # search for a new one only every 10 seconds to avoid unnecessary processing - if (self._digitalInputTypeObject == None or self._digitalInputTypeObject.GetValue() != 9) and self._searchDelay > 10: - newInputService = "" - for service in TheBus.list_names(): - # found a digital input servic, now check the type - if service.startswith ("com.victronenergy.digitalinput"): - self._digitalInputTypeObject = TheBus.get_object (service, '/Type') - # found it! - if self._digitalInputTypeObject.GetValue() == 9: - newInputService = service - break - - # found new service - get objects for use later - if newInputService != "": - self.log_info ("Found generator digital input service at %s" % newInputService) - self._generatorInputStateObject = TheBus.get_object(newInputService, '/State') - else: - if self._generatorInputStateObject != None: - self.log_info ("Generator digital input service NOT found") - self._generatorInputStateObject = None - self._digitalInputTypeObject = None - self._searchDelay = 0 # start delay timer - - # if serch delay timer is active, increment it now - if self._searchDelay <= 10: - self._searchDelay += 1 - - - # collect generator input states - inputState = '?' - # if generator digital input is present, use that - if self._generatorInputStateObject != None: - inputState = self._generatorInputStateObject.GetValue () - if inputState == 10: - inputState = 'R' - elif inputState == 11: - inputState = 'S' - # otherwise use generator AC input to determine running state - # use frequency as the test for generator running - elif self._ac1_is_generator or self._ac2_is_generator: - try: - if self._dbusmonitor.get_value (SYSTEM_SERVICE, '/Ac/Genset/Frequency') > 20: - inputState = 'R' - else: - inputState = 'S' - except: - pass - - # update /GeneratorRunningState - if inputState != self._lastState: - self._dbusservice['/GeneratorRunningState'] = inputState - - # forward input state changes to /ManualStart - if self._linkToExternalState: - if inputState == "R" and generatorState == States.STOPPED: - self.log_info ("generator was started externally - syncing ManualStart state") - self._dbusservice['/ManualStart'] = 1 - elif inputState == "S" and self._dbusservice['/ManualStart'] == 1 \ - and generatorState in (States.RUNNING, States.WARMUP, States.COOLDOWN): - self.log_info ("generator was stopped externally - syncing ManualStart state") - self._dbusservice['/ManualStart'] = 0 - - # update /ExternalOverride - if inputState == "S" and self._linkToExternalState and generatorState == States.RUNNING: - if self._externalOverrideDelay > 5: - self._externalOverride = True - else: - self._externalOverrideDelay += 1 - else: - self._externalOverride = False - self._externalOverrideDelay = 0 - - if self._externalOverride != self._lastExternalOverride: - self._dbusservice['/ExternalOverride'] = self._externalOverride - self._lastExternalOverride = self._externalOverride - - except dbus.DBusException: - self.log_info ("dbus exception - generator digital input no longer valid") - self._generatorInputStateObject = None - self._digitalInputTypeObject = None - inputState = 0 - - self._lastState = inputState - - -# -# control the accumulaiton of run time based on generator input Running state -# if the internal state is RUNNING run time is accumulated in self._accumulatedRunTime -# run time is accumulated if the generator's running state is known to be running or -# if the generator running state can't be determined -# the accumulated time dBus parameter and daily and total time accumulators are updated -# only once everh 60 seconds to minimize processor load -# if the internal state is STOPPED, one last dBus, daily and total time updates are done -# then the current time accumulator is cleared - - def _accumulateRunTime (self): - - # grab running state from dBus once, use it many timed below - - if self._dbusservice['/State'] in (States.RUNNING, States.WARMUP, States.COOLDOWN, States.STOPPING): ########## - internalRun = True - else: - internalRun = False - - # if internal state is running, accumulate time if generator is running - if internalRun: - accumuateTime = True - # start new accumulation if not done prevously - if self._last_accumulate_time == 0: - self._last_accumulate_time = self._currentTime - - # if link to external state is enabled, don't accumulate time if running state is stopped - # (accumulate if R or ?) - if self._linkToExternalState: - try: - if self._dbusservice['/GeneratorRunningState'] == 'S': - accumuateTime = False - - # if no Forwarder service, allow accumulation - except dbus.DBusException: - self.log_info ("dBus exception in startstop.py") - - # internal state STOPPED so don't add new time to the accumulation - # but there may be time already accumulated that needs to be added to daily and total accumulations - else: - accumuateTime = False - - # accumulate run time if we passed all the tests above - if accumuateTime: - self._accumulatedRunTime += self._currentTime - self._last_accumulate_time - self._last_accumulate_time = self._currentTime - - # dbus and settings updates trigger time-intensive processing so only do this once every 60 seconds - doUpdate = False - if internalRun: - if self._currentTime - self._last_update_mtime >= 60: - doUpdate = True - self._last_update_mtime = self._currentTime - # it is also done one last time when state is no longer RUNNING - elif self._last_update_mtime != 0: - doUpdate = True - - if doUpdate: - self._update_accumulated_time() - - # stopped - clear the current time accumulator - if internalRun == False: - self._last_update_mtime = 0 - self._accumulatedRunTime = 0 - self._last_accumulate_time = 0 - - self._dbusservice['/Runtime'] = int(self._accumulatedRunTime) -#### end GuiMods diff --git a/FileSets/v3.40~17/startstop.py.orig b/FileSets/v3.40~17/startstop.py.orig deleted file mode 100644 index 99a0a6b5..00000000 --- a/FileSets/v3.40~17/startstop.py.orig +++ /dev/null @@ -1,1205 +0,0 @@ -#!/usr/bin/python -u -# -*- coding: utf-8 -*- - -# Function -# dbus_generator monitors the dbus for batteries (com.victronenergy.battery.*) and -# vebus com.victronenergy.vebus.* -# Battery and vebus monitors can be configured through the gui. -# It then monitors SOC, AC loads, battery current and battery voltage,to auto start/stop the generator based -# on the configuration settings. Generator can be started manually or periodically setting a tes trun period. -# Time zones function allows to use different values for the conditions along the day depending on time - -import dbus -import datetime -import calendar -import time -import sys -import json -import os -import logging -from collections import OrderedDict -import monotonic_time -from gen_utils import SettingsPrefix, Errors, States, enum -from gen_utils import create_dbus_service -# Victron packages -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) -from ve_utils import exit_on_error -from settingsdevice import SettingsDevice - -RunningConditions = enum( - Stopped = 0, - Manual = 1, - TestRun = 2, - LossOfCommunication = 3, - Soc = 4, - Acload = 5, - BatteryCurrent = 6, - BatteryVoltage = 7, - InverterHighTemp = 8, - InverterOverload = 9, - StopOnAc1 = 10, - StopOnAc2 = 11) - -Capabilities = enum( - WarmupCooldown = 1 -) - -SYSTEM_SERVICE = 'com.victronenergy.system' -BATTERY_PREFIX = '/Dc/Battery' -HISTORY_DAYS = 30 - -def safe_max(args): - try: - return max(x for x in args if x is not None) - except ValueError: - return None - -class Condition(object): - def __init__(self, parent): - self.parent = parent - self.reached = False - self.start_timer = 0 - self.stop_timer = 0 - self.valid = True - self.enabled = False - self.retries = 0 - - def __getitem__(self, key): - try: - return getattr(self, key) - except AttributeError: - raise KeyError(key) - - def __setitem__(self, key, value): - setattr(self, key, value) - - def get_value(self): - raise NotImplementedError("get_value") - - @property - def vebus_service(self): - return self.parent._vebusservice if self.parent._vebusservice else '' - - @property - def monitor(self): - return self.parent._dbusmonitor - -class SocCondition(Condition): - name = 'soc' - monitoring = 'battery' - boolean = False - timed = True - - def get_value(self): - return self.parent._get_battery().soc - -class AcLoadCondition(Condition): - name = 'acload' - monitoring = 'vebus' - boolean = False - timed = True - - def get_value(self): - loadOnAcOut = [] - totalConsumption = [] - - for phase in ['L1', 'L2', 'L3']: - # Get the values directly from the inverter, systemcalc doesn't provide raw inverted power - loadOnAcOut.append(self.monitor.get_value(self.vebus_service, ('/Ac/Out/%s/P' % phase))) - - # Calculate total consumption, '/Ac/Consumption/%s/Power' is deprecated - c_i = self.monitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnInput/%s/Power' % phase)) - c_o = self.monitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnOutput/%s/Power' % phase)) - totalConsumption.append(sum(filter(None, (c_i, c_o)))) - - # Invalidate if vebus is not available - if loadOnAcOut[0] == None: - return None - - # Total consumption - if self.parent._settings['acloadmeasurement'] == 0: - return sum(filter(None, totalConsumption)) - - # Load on inverter AC out - if self.parent._settings['acloadmeasurement'] == 1: - return sum(filter(None, loadOnAcOut)) - - # Highest phase load - if self.parent._settings['acloadmeasurement'] == 2: - return safe_max(loadOnAcOut) - -class BatteryCurrentCondition(Condition): - name = 'batterycurrent' - monitoring = 'battery' - boolean = False - timed = True - - def get_value(self): - c = self.parent._get_battery().current - if c is not None: - c *= -1 - return c - -class BatteryVoltageCondition(Condition): - name = 'batteryvoltage' - monitoring = 'battery' - boolean = False - timed = True - - def get_value(self): - return self.parent._get_battery().voltage - -class InverterTempCondition(Condition): - name = 'inverterhightemp' - monitoring = 'vebus' - boolean = True - timed = True - - def get_value(self): - v = self.monitor.get_value(self.vebus_service, - '/Alarms/HighTemperature') - - # When multi is connected to CAN-bus, alarms are published to - # /Alarms/HighTemperature... but when connected to vebus alarms are - # splitted in three phases and published to /Alarms/LX/HighTemperature... - if v is None: - inverterHighTemp = [] - for phase in ['L1', 'L2', 'L3']: - # Inverter alarms must be fetched directly from the inverter service - inverterHighTemp.append(self.monitor.get_value(self.vebus_service, ('/Alarms/%s/HighTemperature' % phase))) - return safe_max(inverterHighTemp) - return v - -class InverterOverloadCondition(Condition): - name = 'inverteroverload' - monitoring = 'vebus' - boolean = True - timed = True - - def get_value(self): - v = self.monitor.get_value(self.vebus_service, - '/Alarms/Overload') - - # When multi is connected to CAN-bus, alarms are published to - # /Alarms/Overload... but when connected to vebus alarms are - # splitted in three phases and published to /Alarms/LX/Overload... - if v is None: - inverterOverload = [] - for phase in ['L1', 'L2', 'L3']: - # Inverter alarms must be fetched directly from the inverter service - inverterOverload.append(self.monitor.get_value(self.vebus_service, ('/Alarms/%s/Overload' % phase))) - return safe_max(inverterOverload) - return v - -class StopOnAc1Condition(Condition): - name = 'stoponac1' - monitoring = 'vebus' - boolean = True - timed = False - - def get_value(self): - # AC input 1 - available = self.monitor.get_value(self.vebus_service, - '/Ac/State/AcIn1Available') - if available is None: - # Not supported in firmware, fall back to old behaviour - activein = self.monitor.get_value(self.vebus_service, - '/Ac/ActiveIn/ActiveInput') - - # Active input is connected - connected = self.monitor.get_value(self.vebus_service, - '/Ac/ActiveIn/Connected') - if None not in (activein, connected): - return activein == 0 and connected == 1 - return None - - return bool(available) - -class StopOnAc2Condition(Condition): - name = 'stoponac2' - monitoring = 'vebus' - boolean = True - timed = False - - def get_value(self): - # AC input 2 available (used when grid is on AC-in-2) - available = self.monitor.get_value(self.vebus_service, - '/Ac/State/AcIn2Available') - - return None if available is None else bool(available) - -class Battery(object): - def __init__(self, monitor, service, prefix): - self.monitor = monitor - self.service = service - self.prefix = prefix - - @property - def voltage(self): - return self.monitor.get_value(self.service, self.prefix + '/Voltage') - - @property - def current(self): - return self.monitor.get_value(self.service, self.prefix + '/Current') - - @property - def soc(self): - # Soc from the device doesn't have the '/Dc/0' prefix like the current and voltage do, but it does - # have the same prefix on systemcalc - return self.monitor.get_value(self.service, (BATTERY_PREFIX if self.prefix == BATTERY_PREFIX else '') + '/Soc') - -class StartStop(object): - _driver = None - def __init__(self, instance): - self._dbusservice = None - self._settings = None - self._dbusmonitor = None - self._remoteservice = None - self._name = None - self._enabled = False - self._instance = instance - - # One second per retry - self.RETRIES_ON_ERROR = 300 - self._testrun_soc_retries = 0 - self._last_counters_check = 0 - - self._starttime = 0 - self._stoptime = 0 # Used for cooldown - self._manualstarttimer = 0 - self._last_runtime_update = 0 - self._timer_runnning = 0 - - # The installer left autostart disabled - self.AUTOSTART_DISABLED_ALARM_TIME = 600 - self._autostart_last_time = self._get_monotonic_seconds() - - - # Manual battery service selection is deprecated in favour - # of getting the values directly from systemcalc, we keep - # manual selected services handling for compatibility reasons. - self._vebusservice = None - self._errorstate = 0 - self._battery_service = None - self._battery_prefix = None - - self._acpower_inverter_input = { - 'timeout': 0, - 'unabletostart': False - } - - # Order is important. Conditions are evaluated in the order listed. - self._condition_stack = OrderedDict({ - SocCondition.name: SocCondition(self), - AcLoadCondition.name: AcLoadCondition(self), - BatteryCurrentCondition.name: BatteryCurrentCondition(self), - BatteryVoltageCondition.name: BatteryVoltageCondition(self), - InverterTempCondition.name: InverterTempCondition(self), - InverterOverloadCondition.name: InverterOverloadCondition(self), - StopOnAc1Condition.name: StopOnAc1Condition(self), - StopOnAc2Condition.name: StopOnAc2Condition(self) - }) - - def set_sources(self, dbusmonitor, settings, name, remoteservice): - self._settings = SettingsPrefix(settings, name) - self._dbusmonitor = dbusmonitor - self._remoteservice = remoteservice - self._name = name - - self.log_info('Start/stop instance created for %s.' % self._remoteservice) - self._remote_setup() - - def _create_service(self): - self._dbusservice = self._create_dbus_service() - - # The driver used for this start/stop service - self._dbusservice.add_path('/Type', value=self._driver) - # State: None = invalid, 0 = stopped, 1 = running, 2=Warm-up, 3=Cool-down - self._dbusservice.add_path('/State', value=None, gettextcallback=lambda p, v: States.get_description(v)) - # RunningByConditionCode: Numeric Companion to /RunningByCondition below, but - # also encompassing a Stopped state. - self._dbusservice.add_path('/RunningByConditionCode', value=None) - # Error - self._dbusservice.add_path('/Error', value=None, gettextcallback=lambda p, v: Errors.get_description(v)) - # Condition that made the generator start - self._dbusservice.add_path('/RunningByCondition', value=None) - # Runtime - self._dbusservice.add_path('/Runtime', value=None, gettextcallback=self._seconds_to_text) - # Today runtime - self._dbusservice.add_path('/TodayRuntime', value=None, gettextcallback=self._seconds_to_text) - # Test run runtime - self._dbusservice.add_path('/TestRunIntervalRuntime', value=None , gettextcallback=self._seconds_to_text) - # Next test run date, values is 0 for test run disabled - self._dbusservice.add_path('/NextTestRun', value=None, gettextcallback=lambda p, v: datetime.datetime.fromtimestamp(v).strftime('%c')) - # Next test run is needed 1, not needed 0 - self._dbusservice.add_path('/SkipTestRun', value=None) - # Manual start - self._dbusservice.add_path('/ManualStart', value=None, writeable=True) - # Manual start timer - self._dbusservice.add_path('/ManualStartTimer', value=None, writeable=True) - # Silent mode active - self._dbusservice.add_path('/QuietHours', value=None) - # Alarms - self._dbusservice.add_path('/Alarms/NoGeneratorAtAcIn', value=None) - self._dbusservice.add_path('/Alarms/ServiceIntervalExceeded', value=None) - self._dbusservice.add_path('/Alarms/AutoStartDisabled', value=None) - # Autostart - self._dbusservice.add_path('/AutoStartEnabled', value=None, writeable=True, onchangecallback=self._set_autostart) - # Accumulated runtime - self._dbusservice.add_path('/AccumulatedRuntime', value=None) - # Service interval - self._dbusservice.add_path('/ServiceInterval', value=None) - # Capabilities, where we can add bits - self._dbusservice.add_path('/Capabilities', value=0) - # Service countdown, calculated by running time and service interval - self._dbusservice.add_path('/ServiceCounter', value=None) - self._dbusservice.add_path('/ServiceCounterReset', value=None, writeable=True, onchangecallback=self._reset_service_counter) - # Publish what service we're controlling, and the productid - self._dbusservice.add_path('/GensetService', value=self._remoteservice) - self._dbusservice.add_path('/GensetInstance', - value=self._dbusmonitor.get_value(self._remoteservice, '/DeviceInstance')) - self._dbusservice.add_path('/GensetProductId', - value=self._dbusmonitor.get_value(self._remoteservice, '/ProductId')) - - # We need to set the values after creating the paths to trigger the 'onValueChanged' event for the gui - # otherwise the gui will report the paths as invalid if we remove and recreate the paths without - # restarting the dbusservice. - self._dbusservice['/State'] = 0 - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped - self._dbusservice['/Error'] = 0 - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/Runtime'] = 0 - self._dbusservice['/TodayRuntime'] = 0 - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - self._dbusservice['/NextTestRun'] = None - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/ProductName'] = "Generator start/stop" - self._dbusservice['/ManualStart'] = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._dbusservice['/QuietHours'] = 0 - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - self._dbusservice['/Alarms/ServiceIntervalExceeded'] = 0 - self._dbusservice['/Alarms/AutoStartDisabled'] = 0 - self._dbusservice['/AutoStartEnabled'] = self._settings['autostart'] - self._dbusservice['/AccumulatedRuntime'] = int(self._settings['accumulatedtotal']) - self._dbusservice['/ServiceInterval'] = int(self._settings['serviceinterval']) - self._dbusservice['/ServiceCounter'] = None - self._dbusservice['/ServiceCounterReset'] = 0 - - @property - def capabilities(self): - return self._dbusservice['/Capabilities'] - - def _set_autostart(self, path, value): - if 0 <= value <= 1: - self._settings['autostart'] = int(value) - return True - return False - - def enable(self): - if self._enabled: - return - self.log_info('Enabling auto start/stop and taking control of remote switch') - self._create_service() - self._determineservices() - self._update_remote_switch() - # If cooldown or warmup is enabled, the Quattro may be left in a bad - # state if there is an unfortunate crash or a reboot. Set the ignore_ac - # flag to a sane value on startup. - if self._settings['cooldowntime'] > 0 or \ - self._settings['warmuptime'] > 0: - self._set_ignore_ac(False) - self._enabled = True - - def disable(self): - if not self._enabled: - return - self.log_info('Disabling auto start/stop, releasing control of remote switch') - self._remove_service() - self._enabled = False - - def remove(self): - self.disable() - self.log_info('Removed from start/stop instances') - - def _remove_service(self): - self._dbusservice.__del__() - self._dbusservice = None - - def device_added(self, dbusservicename, instance): - self._determineservices() - - def device_removed(self, dbusservicename, instance): - self._determineservices() - - def get_error(self): - return self._dbusservice['/Error'] - - def set_error(self, errorn): - self._dbusservice['/Error'] = errorn - - def clear_error(self): - self._dbusservice['/Error'] = Errors.NONE - - def dbus_value_changed(self, dbusServiceName, dbusPath, options, changes, deviceInstance): - if self._dbusservice is None: - return - - # AcIn1Available is needed to determine capabilities, but may - # only show up later. So we have to wait for it here. - if self._vebusservice is not None and \ - dbusServiceName == self._vebusservice and \ - dbusPath == '/Ac/State/AcIn1Available': - self._set_capabilities() - - if dbusServiceName != 'com.victronenergy.system': - return - if dbusPath == '/AutoSelectedBatteryMeasurement' and self._settings['batterymeasurement'] == 'default': - self._determineservices() - - if dbusPath == '/VebusService': - self._determineservices() - - def handlechangedsetting(self, setting, oldvalue, newvalue): - if self._dbusservice is None: - return - if self._name not in setting: - # Not our setting - return - - s = self._settings.removeprefix(setting) - - if s == 'batterymeasurement': - self._determineservices() - # Reset retries and valid if service changes - for condition in self._condition_stack.values(): - if condition['monitoring'] == 'battery': - condition['valid'] = True - condition['retries'] = 0 - - if s == 'autostart': - self.log_info('Autostart function %s.' % ('enabled' if newvalue == 1 else 'disabled')) - self._dbusservice['/AutoStartEnabled'] = self._settings['autostart'] - - if self._dbusservice is not None and s == 'testruninterval': - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime( - self._settings['testruninterval']) - - if s == 'serviceinterval': - try: - self._dbusservice['/ServiceInterval'] = int(newvalue) - except TypeError: - pass - if newvalue == 0: - self._dbusservice['/ServiceCounter'] = None - else: - self._update_accumulated_time() - if s == 'lastservicereset': - self._update_accumulated_time() - - def _reset_service_counter(self, path, value): - if (path == '/ServiceCounterReset' and value == int(1) and self._dbusservice['/AccumulatedRuntime']): - self._settings['lastservicereset'] = self._dbusservice['/AccumulatedRuntime'] - self._update_accumulated_time() - self.log_info('Service counter reset triggered.') - - return True - - def _seconds_to_text(self, path, value): - m, s = divmod(value, 60) - h, m = divmod(m, 60) - return '%dh, %dm, %ds' % (h, m, s) - - def log_info(self, msg): - logging.info(self._name + ': %s' % msg) - - def tick(self): - if not self._enabled: - return - self._check_remote_status() - self._evaluate_startstop_conditions() - self._evaluate_autostart_disabled_alarm() - self._detect_generator_at_acinput() - if self._dbusservice['/ServiceCounterReset'] == 1: - self._dbusservice['/ServiceCounterReset'] = 0 - - def _evaluate_startstop_conditions(self): - if self.get_error() != Errors.NONE: - # First evaluation after an error, log it - if self._errorstate == 0: - self._errorstate = 1 - self._dbusservice['/State'] = States.ERROR - self.log_info('Error: #%i - %s, stop controlling remote.' % - (self.get_error(), - Errors.get_description(self.get_error()))) - elif self._errorstate == 1: - # Error cleared - self._errorstate = 0 - self._dbusservice['/State'] = States.STOPPED - self.log_info('Error state cleared, taking control of remote switch.') - - start = False - startbycondition = None - activecondition = self._dbusservice['/RunningByCondition'] - today = calendar.timegm(datetime.date.today().timetuple()) - self._timer_runnning = False - connection_lost = False - running = self._dbusservice['/State'] in (States.RUNNING, States.WARMUP) - - self._check_quiet_hours() - - # New day, register it - if self._last_counters_check < today and self._dbusservice['/State'] == States.STOPPED: - self._last_counters_check = today - self._update_accumulated_time() - - # Update current and accumulated runtime. - # By performance reasons, accumulated runtime is only updated - # once per 60s. When the generator stops is also updated. - if self._dbusservice['/State'] in (States.RUNNING, States.WARMUP, States.COOLDOWN, States.STOPPING): - mtime = monotonic_time.monotonic_time().to_seconds_double() - if (mtime - self._starttime) - self._last_runtime_update >= 60: - self._dbusservice['/Runtime'] = int(mtime - self._starttime) - self._update_accumulated_time() - elif self._last_runtime_update == 0: - self._dbusservice['/Runtime'] = int(mtime - self._starttime) - - - if self._evaluate_manual_start(): - startbycondition = 'manual' - start = True - - # Conditions will only be evaluated if the autostart functionality is enabled - if self._settings['autostart'] == 1: - - if self._evaluate_testrun_condition(): - startbycondition = 'testrun' - start = True - - # Evaluate stop on AC IN conditions first, when this conditions are enabled and reached the generator - # will stop as soon as AC IN in active. Manual and testrun conditions will make the generator start - # or keep it running. - stop_on_ac_reached = (self._evaluate_condition(self._condition_stack[StopOnAc1Condition.name]) or - self._evaluate_condition(self._condition_stack[StopOnAc2Condition.name])) - stop_by_ac1_ac2 = startbycondition not in ['manual', 'testrun'] and stop_on_ac_reached - - if stop_by_ac1_ac2 and running and activecondition not in ['manual', 'testrun']: - self.log_info('AC input available, stopping') - - # Evaluate value conditions - for condition, data in self._condition_stack.items(): - # Do not evaluate rest of conditions if generator is configured to stop - # when AC IN is available - if stop_by_ac1_ac2: - start = False - if running: - self._reset_condition(data) - continue - else: - break - - # Don't short-circuit this, _evaluate_condition sets .reached - start = self._evaluate_condition(data) or start - startbycondition = condition if start and startbycondition is None else startbycondition - # Connection lost is set to true if the number of retries of one or more enabled conditions - # >= RETRIES_ON_ERROR - if data.enabled: - connection_lost = data.retries >= self.RETRIES_ON_ERROR - - # If none condition is reached check if connection is lost and start/keep running the generator - # depending on '/OnLossCommunication' setting - if not start and connection_lost: - # Start always - if self._settings['onlosscommunication'] == 1: - start = True - startbycondition = 'lossofcommunication' - # Keep running if generator already started - if running and self._settings['onlosscommunication'] == 2: - start = True - startbycondition = 'lossofcommunication' - - if not start and self._errorstate: - self._stop_generator() - - if self._errorstate: - return - - if start: - self._start_generator(startbycondition) - elif (self._dbusservice['/Runtime'] >= self._settings['minimumruntime'] * 60 - or activecondition == 'manual'): - self._stop_generator() - - def _evaluate_autostart_disabled_alarm(self): - - if self._settings['autostart'] == 0 or \ - self.get_error() != Errors.REMOTEDISABLED or \ - self._settings['autostartdisabledalarm'] == 0: - self._autostart_last_time = self._get_monotonic_seconds() - if self._dbusservice['/Alarms/AutoStartDisabled'] != 0: - self._dbusservice['/Alarms/AutoStartDisabled'] = 0 - return - - timedisabled = self._get_monotonic_seconds() - self._autostart_last_time - if timedisabled > self.AUTOSTART_DISABLED_ALARM_TIME and self._dbusservice['/Alarms/AutoStartDisabled'] != 2: - self.log_info("Autostart was left for more than %i seconds, triggering alarm." % int(timedisabled)) - self._dbusservice['/Alarms/AutoStartDisabled'] = 2 - - - def _detect_generator_at_acinput(self): - state = self._dbusservice['/State'] - - if state in [States.STOPPED, States.COOLDOWN, States.WARMUP]: - self._reset_acpower_inverter_input() - return - - if self._settings['nogeneratoratacinalarm'] == 0: - self._reset_acpower_inverter_input() - return - - vebus_service = self._vebusservice if self._vebusservice else '' - activein_state = self._dbusmonitor.get_value( - vebus_service, '/Ac/ActiveIn/Connected') - - # Path not supported, skip evaluation - if activein_state == None: - return - - # Sources 0 = Not available, 1 = Grid, 2 = Generator, 3 = Shore - generator_acsource = self._dbusmonitor.get_value( - SYSTEM_SERVICE, '/Ac/ActiveIn/Source') == 2 - # Not connected = 0, connected = 1 - activein_connected = activein_state == 1 - - if generator_acsource and activein_connected: - if self._acpower_inverter_input['unabletostart']: - self.log_info('Generator detected at inverter AC input, alarm removed') - self._reset_acpower_inverter_input() - elif self._acpower_inverter_input['timeout'] < self.RETRIES_ON_ERROR: - self._acpower_inverter_input['timeout'] += 1 - elif not self._acpower_inverter_input['unabletostart']: - self._acpower_inverter_input['unabletostart'] = True - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 2 - self.log_info('Generator not detected at inverter AC input, triggering alarm') - - def _reset_acpower_inverter_input(self, clear_error=True): - if self._acpower_inverter_input['timeout'] != 0: - self._acpower_inverter_input['timeout'] = 0 - - if self._acpower_inverter_input['unabletostart'] != 0: - self._acpower_inverter_input['unabletostart'] = 0 - - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - - def _reset_condition(self, condition): - condition['reached'] = False - if condition['timed']: - condition['start_timer'] = 0 - condition['stop_timer'] = 0 - - def _check_condition(self, condition, value): - name = condition['name'] - - if self._settings[name + 'enabled'] == 0: - if condition['enabled']: - condition['enabled'] = False - self.log_info('Disabling (%s) condition' % name) - condition['retries'] = 0 - condition['valid'] = True - self._reset_condition(condition) - return False - - elif not condition['enabled']: - condition['enabled'] = True - self.log_info('Enabling (%s) condition' % name) - - if (condition['monitoring'] == 'battery') and (self._settings['batterymeasurement'] == 'nobattery'): - # If no battery monitor is selected reset the condition - self._reset_condition(condition) - return False - - if value is None and condition['valid']: - if condition['retries'] >= self.RETRIES_ON_ERROR: - logging.info('Error getting (%s) value, skipping evaluation till get a valid value' % name) - self._reset_condition(condition) - self._comunnication_lost = True - condition['valid'] = False - else: - condition['retries'] += 1 - if condition['retries'] == 1 or (condition['retries'] % 10) == 0: - self.log_info('Error getting (%s) value, retrying(#%i)' % (name, condition['retries'])) - return False - - elif value is not None and not condition['valid']: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['valid'] = True - condition['retries'] = 0 - - # Reset retries if value is valid - if value is not None and condition['retries'] > 0: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['retries'] = 0 - - return condition['valid'] - - def _evaluate_condition(self, condition): - name = condition['name'] - value = condition.get_value() - setting = ('qh_' if self._dbusservice['/QuietHours'] == 1 else '') + name - startvalue = self._settings[setting + 'start'] if not condition['boolean'] else 1 - stopvalue = self._settings[setting + 'stop'] if not condition['boolean'] else 0 - - # Check if the condition has to be evaluated - if not self._check_condition(condition, value): - # If generator is started by this condition and value is invalid - # wait till RETRIES_ON_ERROR to skip the condition - if condition['reached'] and condition['retries'] <= self.RETRIES_ON_ERROR: - if condition['retries'] > 0: - return True - - return False - - # As this is a generic evaluation method, we need to know how to compare the values - # first check if start value should be greater than stop value and then compare - start_is_greater = startvalue > stopvalue - - # When the condition is already reached only the stop value can set it to False - start = condition['reached'] or (value >= startvalue if start_is_greater else value <= startvalue) - stop = value <= stopvalue if start_is_greater else value >= stopvalue - - # Timed conditions must start/stop after the condition has been reached for a minimum - # time. - if condition['timed']: - if not condition['reached'] and start: - condition['start_timer'] += time.time() if condition['start_timer'] == 0 else 0 - start = time.time() - condition['start_timer'] >= self._settings[name + 'starttimer'] - condition['stop_timer'] *= int(not start) - self._timer_runnning = True - else: - condition['start_timer'] = 0 - - if condition['reached'] and stop: - condition['stop_timer'] += time.time() if condition['stop_timer'] == 0 else 0 - stop = time.time() - condition['stop_timer'] >= self._settings[name + 'stoptimer'] - condition['stop_timer'] *= int(not stop) - self._timer_runnning = True - else: - condition['stop_timer'] = 0 - - condition['reached'] = start and not stop - return condition['reached'] - - def _evaluate_manual_start(self): - if self._dbusservice['/ManualStart'] == 0: - if self._dbusservice['/RunningByCondition'] == 'manual': - self._dbusservice['/ManualStartTimer'] = 0 - return False - - start = True - # If /ManualStartTimer has a value greater than zero will use it to set a stop timer. - # If no timer is set, the generator will not stop until the user stops it manually. - # Once started by manual start, each evaluation the timer is decreased - if self._dbusservice['/ManualStartTimer'] != 0: - self._manualstarttimer += time.time() if self._manualstarttimer == 0 else 0 - self._dbusservice['/ManualStartTimer'] -= int(time.time()) - int(self._manualstarttimer) - self._manualstarttimer = time.time() - start = self._dbusservice['/ManualStartTimer'] > 0 - self._dbusservice['/ManualStart'] = int(start) - # Reset if timer is finished - self._manualstarttimer *= int(start) - self._dbusservice['/ManualStartTimer'] *= int(start) - - return start - - def _evaluate_testrun_condition(self): - if self._settings['testrunenabled'] == 0: - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/NextTestRun'] = None - return False - - today = datetime.date.today() - yesterday = today - datetime.timedelta(days=1) # Should deal well with DST - now = time.time() - runtillbatteryfull = self._settings['testruntillbatteryfull'] == 1 - soc = self._condition_stack['soc'].get_value() - batteryisfull = runtillbatteryfull and soc == 100 - duration = 60 if runtillbatteryfull else self._settings['testrunruntime'] - - try: - startdate = datetime.date.fromtimestamp(self._settings['testrunstartdate']) - _starttime = time.mktime(yesterday.timetuple()) + self._settings['testrunstarttimer'] - - # today might in fact still be yesterday, if this test run started - # before midnight and finishes after. If `now` still falls in - # yesterday's window, then by the temporal anthropic principle, - # which I just made up but loosely states that time must have - # these properties for observers to exist, it must be yesterday - # because we are here to observe it. - if _starttime <= now <= _starttime + duration: - today = yesterday - starttime = _starttime - else: - starttime = time.mktime(today.timetuple()) + self._settings['testrunstarttimer'] - except ValueError: - logging.debug('Invalid dates, skipping testrun') - return False - - # If start date is in the future set as NextTestRun and stop evaluating - if startdate > today: - self._dbusservice['/NextTestRun'] = time.mktime(startdate.timetuple()) - return False - - start = False - # If the accumulated runtime during the tes trun interval is greater than '/TestRunIntervalRuntime' - # the tes trun must be skipped - needed = (self._settings['testrunskipruntime'] > self._dbusservice['/TestRunIntervalRuntime'] - or self._settings['testrunskipruntime'] == 0) - self._dbusservice['/SkipTestRun'] = int(not needed) - - interval = self._settings['testruninterval'] - stoptime = starttime + duration - elapseddays = (today - startdate).days - mod = elapseddays % interval - - start = not bool(mod) and starttime <= now <= stoptime - - if runtillbatteryfull: - if soc is not None: - self._testrun_soc_retries = 0 - start = (start or self._dbusservice['/RunningByCondition'] == 'testrun') and not batteryisfull - elif self._dbusservice['/RunningByCondition'] == 'testrun': - if self._testrun_soc_retries < self.RETRIES_ON_ERROR: - self._testrun_soc_retries += 1 - start = True - if (self._testrun_soc_retries % 10) == 0: - self.log_info('Test run failed to get SOC value, retrying(#%i)' % self._testrun_soc_retries) - else: - self.log_info('Failed to get SOC after %i retries, terminating test run condition' % self._testrun_soc_retries) - start = False - else: - start = False - - if not bool(mod) and (now <= stoptime): - self._dbusservice['/NextTestRun'] = starttime - else: - self._dbusservice['/NextTestRun'] = (time.mktime((today + datetime.timedelta(days=interval - mod)).timetuple()) + - self._settings['testrunstarttimer']) - return start and needed - - def _check_quiet_hours(self): - active = False - if self._settings['quiethoursenabled'] == 1: - # Seconds after today 00:00 - timeinseconds = time.time() - time.mktime(datetime.date.today().timetuple()) - quiethoursstart = self._settings['quiethoursstarttime'] - quiethoursend = self._settings['quiethoursendtime'] - - # Check if the current time is between the start time and end time - if quiethoursstart < quiethoursend: - active = quiethoursstart <= timeinseconds and timeinseconds < quiethoursend - else: # End time is lower than start time, example Start: 21:00, end: 08:00 - active = not (quiethoursend < timeinseconds and timeinseconds < quiethoursstart) - - if self._dbusservice['/QuietHours'] == 0 and active: - self.log_info('Entering to quiet mode') - - elif self._dbusservice['/QuietHours'] == 1 and not active: - self.log_info('Leaving quiet mode') - - self._dbusservice['/QuietHours'] = int(active) - - return active - - def _update_accumulated_time(self): - seconds = self._dbusservice['/Runtime'] - accumulated = seconds - self._last_runtime_update - - self._settings['accumulatedtotal'] = accumulatedtotal = int(self._settings['accumulatedtotal']) + accumulated - # Using calendar to get timestamp in UTC, not local time - today_date = str(calendar.timegm(datetime.date.today().timetuple())) - - # If something goes wrong getting the json string create a new one - try: - accumulated_days = json.loads(self._settings['accumulateddaily']) - except ValueError: - accumulated_days = {today_date: 0} - - if (today_date in accumulated_days): - accumulated_days[today_date] += accumulated - else: - accumulated_days[today_date] = accumulated - - self._last_runtime_update = seconds - - # Keep the historical with a maximum of HISTORY_DAYS - while len(accumulated_days) > HISTORY_DAYS: - accumulated_days.pop(min(accumulated_days.keys()), None) - - # Upadate settings - self._settings['accumulateddaily'] = json.dumps(accumulated_days, sort_keys=True) - self._dbusservice['/TodayRuntime'] = self._interval_runtime(0) - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - self._dbusservice['/AccumulatedRuntime'] = accumulatedtotal - - # Service counter - serviceinterval = self._settings['serviceinterval'] - lastservicereset = self._settings['lastservicereset'] - if serviceinterval > 0: - servicecountdown = (lastservicereset + serviceinterval) - accumulatedtotal - self._dbusservice['/ServiceCounter'] = servicecountdown - if servicecountdown <= 0: - self._dbusservice['/Alarms/ServiceIntervalExceeded'] = 1 - elif self._dbusservice['/Alarms/ServiceIntervalExceeded'] != 0: - self._dbusservice['/Alarms/ServiceIntervalExceeded'] = 0 - - - - def _interval_runtime(self, days): - summ = 0 - try: - daily_record = json.loads(self._settings['accumulateddaily']) - except ValueError: - return 0 - - for i in range(days + 1): - previous_day = calendar.timegm((datetime.date.today() - datetime.timedelta(days=i)).timetuple()) - if str(previous_day) in daily_record.keys(): - summ += daily_record[str(previous_day)] if str(previous_day) in daily_record.keys() else 0 - - return summ - - def _get_battery(self): - if self._settings['batterymeasurement'] == 'default': - return Battery(self._dbusmonitor, SYSTEM_SERVICE, BATTERY_PREFIX) - - return Battery(self._dbusmonitor, - self._battery_service if self._battery_service else '', - self._battery_prefix if self._battery_prefix else '') - - def _set_capabilities(self): - # Update capabilities - # The ability to ignore AC1/AC2 came in at the same time as - # AC availability and is used to detect it here. - readout_supported = self._dbusmonitor.get_value(self._vebusservice, - '/Ac/State/AcIn1Available') is not None - self._dbusservice['/Capabilities'] |= ( - Capabilities.WarmupCooldown if readout_supported else 0) - - def _determineservices(self): - # batterymeasurement is either 'default' or 'com_victronenergy_battery_288/Dc/0'. - # In case it is set to default, we use the AutoSelected battery - # measurement, given by SystemCalc. - batterymeasurement = None - newbatteryservice = None - batteryprefix = '' - selectedbattery = self._settings['batterymeasurement'] - vebusservice = None - - if selectedbattery == 'default': - batterymeasurement = 'default' - elif len(selectedbattery.split('/', 1)) == 2: # Only very basic sanity checking.. - batterymeasurement = self._settings['batterymeasurement'] - elif selectedbattery == 'nobattery': - batterymeasurement = None - else: - # Exception: unexpected value for batterymeasurement - pass - - if batterymeasurement and batterymeasurement != 'default': - batteryprefix = '/' + batterymeasurement.split('/', 1)[1] - - # Get the current battery servicename - if self._battery_service: - oldservice = self._battery_service - else: - oldservice = None - - if batterymeasurement != 'default': - battery_instance = int(batterymeasurement.split('_', 3)[3].split('/')[0]) - service_type = None - - if 'vebus' in batterymeasurement: - service_type = 'vebus' - elif 'battery' in batterymeasurement: - service_type = 'battery' - - newbatteryservice = self._get_servicename_by_instance(battery_instance, service_type) - elif batterymeasurement == 'default': - newbatteryservice = 'default' - - if newbatteryservice and newbatteryservice != oldservice: - if selectedbattery == 'default': - self.log_info('Getting battery values from systemcalc.') - if selectedbattery == 'nobattery': - self.log_info('Battery monitoring disabled! Stop evaluating related conditions') - self._battery_service = None - self._battery_prefix = None - self.log_info('Battery service we need (%s) found! Using it for generator start/stop' % batterymeasurement) - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - elif not newbatteryservice and newbatteryservice != oldservice: - self.log_info('Error getting battery service!') - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - - # Get the default VE.Bus service - vebusservice = self._dbusmonitor.get_value('com.victronenergy.system', '/VebusService') - if vebusservice: - if self._vebusservice != vebusservice: - self._vebusservice = vebusservice - self._set_capabilities() - self.log_info('Vebus service (%s) found! Using it for generator start/stop' % vebusservice) - else: - if self._vebusservice is not None: - self.log_info('Vebus service (%s) dissapeared! Stop evaluating related conditions' % self._vebusservice) - else: - self.log_info('Error getting Vebus service!') - self._vebusservice = None - - def _get_servicename_by_instance(self, instance, service_type=None): - sv = None - services = self._dbusmonitor.get_service_list() - - for service in services: - if service_type and service_type not in service: - continue - - if services[service] == instance: - sv = service - break - - return sv - - def _get_monotonic_seconds(self): - return monotonic_time.monotonic_time().to_seconds_double() - - def _start_generator(self, condition): - state = self._dbusservice['/State'] - remote_running = self._get_remote_switch_state() - - # This function will start the generator in the case generator not - # already running. When differs, the RunningByCondition is updated - running = state in (States.WARMUP, States.COOLDOWN, States.STOPPING, States.RUNNING) - if not (running and remote_running): # STOPPED, ERROR - if self._settings['warmuptime'] > 0: - # Remove load while warming up - self._set_ignore_ac(True) - self._dbusservice['/State'] = States.WARMUP - else: - self._dbusservice['/State'] = States.RUNNING - - self._update_remote_switch() - self._starttime = monotonic_time.monotonic_time().to_seconds_double() - self.log_info('Starting generator by %s condition' % condition) - else: # WARMUP, COOLDOWN, RUNNING, STOPPING - if state == States.WARMUP: - if monotonic_time.monotonic_time().to_seconds_double() - self._starttime > self._settings['warmuptime']: - self._set_ignore_ac(False) # Release load onto Generator - self._dbusservice['/State'] = States.RUNNING - elif state in (States.COOLDOWN, States.STOPPING): - # Start request during cool-down run, go back to RUNNING - self._set_ignore_ac(False) # Put load back onto Generator - self._dbusservice['/State'] = States.RUNNING - - # Update the RunningByCondition - if self._dbusservice['/RunningByCondition'] != condition: - self.log_info('Generator previously running by %s condition is now running by %s condition' - % (self._dbusservice['/RunningByCondition'], condition)) - - self._dbusservice['/RunningByCondition'] = condition - self._dbusservice['/RunningByConditionCode'] = RunningConditions.lookup(condition) - - def _stop_generator(self): - state = self._dbusservice['/State'] - remote_running = self._get_remote_switch_state() - running = state in (States.WARMUP, States.COOLDOWN, States.STOPPING, States.RUNNING) - - if running or remote_running: - if self._settings['cooldowntime'] > 0: - if state == States.RUNNING: - self._dbusservice['/State'] = States.COOLDOWN - self._stoptime = monotonic_time.monotonic_time().to_seconds_double() - - # Remove load from Generator - self._set_ignore_ac(True) - - return - elif state == States.COOLDOWN: - if monotonic_time.monotonic_time().to_seconds_double() - \ - self._stoptime <= self._settings['cooldowntime']: - return # Don't stop engine yet - - # When we arrive here, a stop command was given during warmup, the - # cooldown timer expired, or no cooldown was configured. Stop - # the engine, but if we're coming from cooldown, delay another - # while in the STOPPING state before reactivating AC-in. - if state == States.COOLDOWN: - self._dbusservice['/State'] = States.STOPPING - self._update_remote_switch() # Stop engine - return - elif state == States.STOPPING: - if monotonic_time.monotonic_time().to_seconds_double() - \ - self._stoptime <= self._settings['cooldowntime'] + self._settings['generatorstoptime']: - return # Wait for engine stop - - # All other possibilities are handled now. Cooldown is over or not - # configured and we waited for the generator to shut down. - self._dbusservice['/State'] = States.STOPPED - self._update_remote_switch() - self._set_ignore_ac(False) - self.log_info('Stopping generator that was running by %s condition' % - str(self._dbusservice['/RunningByCondition'])) - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped - self._update_accumulated_time() - self._starttime = 0 - self._dbusservice['/Runtime'] = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._manualstarttimer = 0 - self._last_runtime_update = 0 - - @property - def _ac1_is_generator(self): - return self._dbusmonitor.get_value('com.victronenergy.settings', - '/Settings/SystemSetup/AcInput1') == 2 - - @property - def _ac2_is_generator(self): - return self._dbusmonitor.get_value('com.victronenergy.settings', - '/Settings/SystemSetup/AcInput2') == 2 - - def _set_ignore_ac(self, ignore): - # This is here so the Multi/Quattro can be told to disconnect AC-in, - # so that we can do warm-up and cool-down. - if self._vebusservice is not None: - if self._ac1_is_generator: - self._dbusmonitor.set_value_async(self._vebusservice, '/Ac/Control/IgnoreAcIn1', dbus.Int32(ignore, variant_level=1)) - if self._ac2_is_generator: - self._dbusmonitor.set_value_async(self._vebusservice, '/Ac/Control/IgnoreAcIn2', dbus.Int32(ignore, variant_level=1)) - - def _update_remote_switch(self): - # Engine should be started in these states - v = self._dbusservice['/State'] in (States.RUNNING, States.WARMUP, States.COOLDOWN) - self._set_remote_switch_state(dbus.Int32(v, variant_level=1)) - - def _get_remote_switch_state(self): - raise Exception('This function should be overridden') - - def _set_remote_switch_state(self, value): - raise Exception('This function should be overridden') - - # Check the remote status, for example errors - def _check_remote_status(self): - raise Exception('This function should be overridden') - - def _remote_setup(self): - raise Exception('This function should be overridden') - - def _create_dbus_monitor(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_settings(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_dbus_service(self): - return create_dbus_service(self._instance) diff --git a/FileSets/v3.40~17/styles.css b/FileSets/v3.40~17/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v3.40~17/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v3.40~18/Battery.qml b/FileSets/v3.40~18/Battery.qml deleted file mode 120000 index fafc7b36..00000000 --- a/FileSets/v3.40~18/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/COMPLETE b/FileSets/v3.40~18/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~18/DetailAcInput.qml b/FileSets/v3.40~18/DetailAcInput.qml deleted file mode 120000 index 8e76794d..00000000 --- a/FileSets/v3.40~18/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/DetailInverter.qml b/FileSets/v3.40~18/DetailInverter.qml deleted file mode 120000 index 285b3216..00000000 --- a/FileSets/v3.40~18/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/DetailLoadsCombined.qml b/FileSets/v3.40~18/DetailLoadsCombined.qml deleted file mode 120000 index 81c6de5a..00000000 --- a/FileSets/v3.40~18/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/DetailLoadsOnInput.qml b/FileSets/v3.40~18/DetailLoadsOnInput.qml deleted file mode 120000 index a5f97488..00000000 --- a/FileSets/v3.40~18/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/DetailLoadsOnOutput.qml b/FileSets/v3.40~18/DetailLoadsOnOutput.qml deleted file mode 120000 index 7cfc98c6..00000000 --- a/FileSets/v3.40~18/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/HubData.qml b/FileSets/v3.40~18/HubData.qml deleted file mode 120000 index c80a3bff..00000000 --- a/FileSets/v3.40~18/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/LINKS_ONLY b/FileSets/v3.40~18/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~18/MbEditBox.qml b/FileSets/v3.40~18/MbEditBox.qml deleted file mode 120000 index 90a92492..00000000 --- a/FileSets/v3.40~18/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/MbEditBoxDateTime.qml b/FileSets/v3.40~18/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v3.40~18/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/MbItem.qml b/FileSets/v3.40~18/MbItem.qml deleted file mode 120000 index 048a313c..00000000 --- a/FileSets/v3.40~18/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/MbItemDigitalInput.qml b/FileSets/v3.40~18/MbItemDigitalInput.qml deleted file mode 120000 index 4404b520..00000000 --- a/FileSets/v3.40~18/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/MbSpinBox.qml b/FileSets/v3.40~18/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v3.40~18/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/MbStyle.qml b/FileSets/v3.40~18/MbStyle.qml deleted file mode 120000 index d1940446..00000000 --- a/FileSets/v3.40~18/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/MbSubMenu.qml b/FileSets/v3.40~18/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v3.40~18/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/Multi.qml b/FileSets/v3.40~18/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v3.40~18/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/ObjectAcConnection.qml b/FileSets/v3.40~18/ObjectAcConnection.qml deleted file mode 120000 index cab7f2d4..00000000 --- a/FileSets/v3.40~18/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~18/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 6d1e56b5..00000000 --- a/FileSets/v3.40~18/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/OverviewBox.qml b/FileSets/v3.40~18/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v3.40~18/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/OverviewConnection.qml b/FileSets/v3.40~18/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v3.40~18/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/OverviewConnectionEnd.qml b/FileSets/v3.40~18/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v3.40~18/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/OverviewFlowComplex.qml b/FileSets/v3.40~18/OverviewFlowComplex.qml deleted file mode 120000 index a151db4f..00000000 --- a/FileSets/v3.40~18/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~18/OverviewGeneratorEnhanced.qml deleted file mode 120000 index da5507a7..00000000 --- a/FileSets/v3.40~18/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~18/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index 1c9b530f..00000000 --- a/FileSets/v3.40~18/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/OverviewGridParallel.qml b/FileSets/v3.40~18/OverviewGridParallel.qml deleted file mode 120000 index d30a27d7..00000000 --- a/FileSets/v3.40~18/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/OverviewHub.qml b/FileSets/v3.40~18/OverviewHub.qml deleted file mode 120000 index 93c6ee1a..00000000 --- a/FileSets/v3.40~18/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/OverviewHubEnhanced.qml b/FileSets/v3.40~18/OverviewHubEnhanced.qml deleted file mode 120000 index c55515d9..00000000 --- a/FileSets/v3.40~18/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/OverviewMobileEnhanced.qml b/FileSets/v3.40~18/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.40~18/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/OverviewSolarCharger.qml b/FileSets/v3.40~18/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v3.40~18/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/OverviewSolarInverter.qml b/FileSets/v3.40~18/OverviewSolarInverter.qml deleted file mode 120000 index 4048703e..00000000 --- a/FileSets/v3.40~18/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/OverviewTankDelegate.qml b/FileSets/v3.40~18/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v3.40~18/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/OverviewTanks.qml b/FileSets/v3.40~18/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v3.40~18/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~18/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.40~18/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/PageDigitalInput.qml b/FileSets/v3.40~18/PageDigitalInput.qml deleted file mode 120000 index 5b768f8f..00000000 --- a/FileSets/v3.40~18/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/PageGenerator.qml b/FileSets/v3.40~18/PageGenerator.qml deleted file mode 120000 index efbafddf..00000000 --- a/FileSets/v3.40~18/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/PageMain.qml b/FileSets/v3.40~18/PageMain.qml deleted file mode 120000 index ef4b9c47..00000000 --- a/FileSets/v3.40~18/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/PageSettingsDisplay.qml b/FileSets/v3.40~18/PageSettingsDisplay.qml deleted file mode 120000 index 03766d99..00000000 --- a/FileSets/v3.40~18/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/PageSettingsGenerator.qml b/FileSets/v3.40~18/PageSettingsGenerator.qml deleted file mode 120000 index 15dd8f85..00000000 --- a/FileSets/v3.40~18/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/PageSettingsGuiMods.qml b/FileSets/v3.40~18/PageSettingsGuiMods.qml deleted file mode 120000 index e831a7a4..00000000 --- a/FileSets/v3.40~18/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/PageSettingsRelay.qml b/FileSets/v3.40~18/PageSettingsRelay.qml deleted file mode 120000 index 156aadac..00000000 --- a/FileSets/v3.40~18/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/PowerGauge.qml b/FileSets/v3.40~18/PowerGauge.qml deleted file mode 120000 index 4bcaaa4a..00000000 --- a/FileSets/v3.40~18/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/Tile.qml b/FileSets/v3.40~18/Tile.qml deleted file mode 120000 index 0558cecf..00000000 --- a/FileSets/v3.40~18/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/TileDigIn.qml b/FileSets/v3.40~18/TileDigIn.qml deleted file mode 120000 index 44616f30..00000000 --- a/FileSets/v3.40~18/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/TileRelay.qml b/FileSets/v3.40~18/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.40~18/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/TileText.qml b/FileSets/v3.40~18/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v3.40~18/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/attributes.csv b/FileSets/v3.40~18/attributes.csv deleted file mode 120000 index 6508da35..00000000 --- a/FileSets/v3.40~18/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v3.40~26/attributes.csv \ No newline at end of file diff --git a/FileSets/v3.40~18/dbus_digitalinputs.py b/FileSets/v3.40~18/dbus_digitalinputs.py deleted file mode 120000 index e74da5b6..00000000 --- a/FileSets/v3.40~18/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.40~18/dbus_generator.py b/FileSets/v3.40~18/dbus_generator.py deleted file mode 120000 index 0cd84ca3..00000000 --- a/FileSets/v3.40~18/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.40~18/dbus_systemcalc.py b/FileSets/v3.40~18/dbus_systemcalc.py deleted file mode 120000 index c519cce7..00000000 --- a/FileSets/v3.40~18/dbus_systemcalc.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~20/dbus_systemcalc.py \ No newline at end of file diff --git a/FileSets/v3.40~18/main.qml b/FileSets/v3.40~18/main.qml deleted file mode 120000 index 5dbfdf83..00000000 --- a/FileSets/v3.40~18/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/main.qml \ No newline at end of file diff --git a/FileSets/v3.40~18/startstop.py b/FileSets/v3.40~18/startstop.py deleted file mode 120000 index c18bce2d..00000000 --- a/FileSets/v3.40~18/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~37/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~18/styles.css b/FileSets/v3.40~18/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v3.40~18/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v3.40~2/Battery.qml b/FileSets/v3.40~2/Battery.qml deleted file mode 120000 index fafc7b36..00000000 --- a/FileSets/v3.40~2/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/COMPLETE b/FileSets/v3.40~2/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~2/DetailAcInput.qml b/FileSets/v3.40~2/DetailAcInput.qml deleted file mode 120000 index d315e33a..00000000 --- a/FileSets/v3.40~2/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/DetailInverter.qml b/FileSets/v3.40~2/DetailInverter.qml deleted file mode 120000 index 2d924d7f..00000000 --- a/FileSets/v3.40~2/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/DetailLoadsCombined.qml b/FileSets/v3.40~2/DetailLoadsCombined.qml deleted file mode 120000 index 58c63979..00000000 --- a/FileSets/v3.40~2/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/DetailLoadsOnInput.qml b/FileSets/v3.40~2/DetailLoadsOnInput.qml deleted file mode 120000 index 5fb19084..00000000 --- a/FileSets/v3.40~2/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/DetailLoadsOnOutput.qml b/FileSets/v3.40~2/DetailLoadsOnOutput.qml deleted file mode 120000 index 9fdfdf28..00000000 --- a/FileSets/v3.40~2/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/HubData.qml b/FileSets/v3.40~2/HubData.qml deleted file mode 120000 index b88f1965..00000000 --- a/FileSets/v3.40~2/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/LINKS_ONLY b/FileSets/v3.40~2/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~2/MbEditBox.qml b/FileSets/v3.40~2/MbEditBox.qml deleted file mode 120000 index 8381b7d5..00000000 --- a/FileSets/v3.40~2/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/MbEditBoxDateTime.qml b/FileSets/v3.40~2/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v3.40~2/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/MbItem.qml b/FileSets/v3.40~2/MbItem.qml deleted file mode 120000 index 048a313c..00000000 --- a/FileSets/v3.40~2/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/MbItemDigitalInput.qml b/FileSets/v3.40~2/MbItemDigitalInput.qml deleted file mode 120000 index 4404b520..00000000 --- a/FileSets/v3.40~2/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/MbSpinBox.qml b/FileSets/v3.40~2/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v3.40~2/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/MbStyle.qml b/FileSets/v3.40~2/MbStyle.qml deleted file mode 120000 index d1940446..00000000 --- a/FileSets/v3.40~2/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/MbSubMenu.qml b/FileSets/v3.40~2/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v3.40~2/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/Multi.qml b/FileSets/v3.40~2/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v3.40~2/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/ObjectAcConnection.qml b/FileSets/v3.40~2/ObjectAcConnection.qml deleted file mode 120000 index cab7f2d4..00000000 --- a/FileSets/v3.40~2/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~2/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 6d1e56b5..00000000 --- a/FileSets/v3.40~2/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewBox.qml b/FileSets/v3.40~2/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v3.40~2/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewConnection.qml b/FileSets/v3.40~2/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v3.40~2/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewConnectionEnd.qml b/FileSets/v3.40~2/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v3.40~2/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewFlowComplex.qml b/FileSets/v3.40~2/OverviewFlowComplex.qml deleted file mode 120000 index 296ff4b1..00000000 --- a/FileSets/v3.40~2/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~2/OverviewGeneratorEnhanced.qml deleted file mode 120000 index da5507a7..00000000 --- a/FileSets/v3.40~2/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~2/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index 1c9b530f..00000000 --- a/FileSets/v3.40~2/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewGridParallel.qml b/FileSets/v3.40~2/OverviewGridParallel.qml deleted file mode 120000 index 3d1f0720..00000000 --- a/FileSets/v3.40~2/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewHub.qml b/FileSets/v3.40~2/OverviewHub.qml deleted file mode 120000 index 83bae2bd..00000000 --- a/FileSets/v3.40~2/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewHubEnhanced.qml b/FileSets/v3.40~2/OverviewHubEnhanced.qml deleted file mode 120000 index 905200b7..00000000 --- a/FileSets/v3.40~2/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewMobileEnhanced.qml b/FileSets/v3.40~2/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.40~2/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewSolarCharger.qml b/FileSets/v3.40~2/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v3.40~2/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewSolarInverter.qml b/FileSets/v3.40~2/OverviewSolarInverter.qml deleted file mode 120000 index 4048703e..00000000 --- a/FileSets/v3.40~2/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewTankDelegate.qml b/FileSets/v3.40~2/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v3.40~2/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewTanks.qml b/FileSets/v3.40~2/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v3.40~2/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~2/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.40~2/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/PageDigitalInput.qml b/FileSets/v3.40~2/PageDigitalInput.qml deleted file mode 120000 index 5b768f8f..00000000 --- a/FileSets/v3.40~2/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/PageGenerator.qml b/FileSets/v3.40~2/PageGenerator.qml deleted file mode 120000 index efbafddf..00000000 --- a/FileSets/v3.40~2/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/PageMain.qml b/FileSets/v3.40~2/PageMain.qml deleted file mode 120000 index 33fe83b0..00000000 --- a/FileSets/v3.40~2/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~13/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/PageSettingsDisplay.qml b/FileSets/v3.40~2/PageSettingsDisplay.qml deleted file mode 120000 index 4e1ac210..00000000 --- a/FileSets/v3.40~2/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/PageSettingsGenerator.qml b/FileSets/v3.40~2/PageSettingsGenerator.qml deleted file mode 120000 index 15dd8f85..00000000 --- a/FileSets/v3.40~2/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/PageSettingsGuiMods.qml b/FileSets/v3.40~2/PageSettingsGuiMods.qml deleted file mode 120000 index e831a7a4..00000000 --- a/FileSets/v3.40~2/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/PageSettingsRelay.qml b/FileSets/v3.40~2/PageSettingsRelay.qml deleted file mode 120000 index 156aadac..00000000 --- a/FileSets/v3.40~2/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/PowerGauge.qml b/FileSets/v3.40~2/PowerGauge.qml deleted file mode 120000 index cfdf038d..00000000 --- a/FileSets/v3.40~2/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/Tile.qml b/FileSets/v3.40~2/Tile.qml deleted file mode 120000 index 0558cecf..00000000 --- a/FileSets/v3.40~2/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/TileDigIn.qml b/FileSets/v3.40~2/TileDigIn.qml deleted file mode 120000 index 44616f30..00000000 --- a/FileSets/v3.40~2/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/TileRelay.qml b/FileSets/v3.40~2/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.40~2/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/TileText.qml b/FileSets/v3.40~2/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v3.40~2/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/attributes.csv b/FileSets/v3.40~2/attributes.csv deleted file mode 120000 index e226e13c..00000000 --- a/FileSets/v3.40~2/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v3.40~6/attributes.csv \ No newline at end of file diff --git a/FileSets/v3.40~2/dbus_digitalinputs.py b/FileSets/v3.40~2/dbus_digitalinputs.py deleted file mode 120000 index e74da5b6..00000000 --- a/FileSets/v3.40~2/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.40~2/dbus_generator.py b/FileSets/v3.40~2/dbus_generator.py deleted file mode 120000 index 0cd84ca3..00000000 --- a/FileSets/v3.40~2/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.40~2/main.qml b/FileSets/v3.40~2/main.qml deleted file mode 120000 index 916fdfbf..00000000 --- a/FileSets/v3.40~2/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~13/main.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/startstop.py b/FileSets/v3.40~2/startstop.py deleted file mode 120000 index 274861e3..00000000 --- a/FileSets/v3.40~2/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~17/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~2/styles.css b/FileSets/v3.40~2/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v3.40~2/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v3.40~20/Battery.qml b/FileSets/v3.40~20/Battery.qml deleted file mode 120000 index fafc7b36..00000000 --- a/FileSets/v3.40~20/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/COMPLETE b/FileSets/v3.40~20/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~20/DetailAcInput.qml b/FileSets/v3.40~20/DetailAcInput.qml deleted file mode 120000 index 8e76794d..00000000 --- a/FileSets/v3.40~20/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/DetailInverter.qml b/FileSets/v3.40~20/DetailInverter.qml deleted file mode 120000 index 285b3216..00000000 --- a/FileSets/v3.40~20/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/DetailLoadsCombined.qml b/FileSets/v3.40~20/DetailLoadsCombined.qml deleted file mode 120000 index 81c6de5a..00000000 --- a/FileSets/v3.40~20/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/DetailLoadsOnInput.qml b/FileSets/v3.40~20/DetailLoadsOnInput.qml deleted file mode 120000 index a5f97488..00000000 --- a/FileSets/v3.40~20/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/DetailLoadsOnOutput.qml b/FileSets/v3.40~20/DetailLoadsOnOutput.qml deleted file mode 120000 index 7cfc98c6..00000000 --- a/FileSets/v3.40~20/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/HubData.qml b/FileSets/v3.40~20/HubData.qml deleted file mode 120000 index c80a3bff..00000000 --- a/FileSets/v3.40~20/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/LINKS_ONLY b/FileSets/v3.40~20/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~20/MbEditBox.qml b/FileSets/v3.40~20/MbEditBox.qml deleted file mode 120000 index 90a92492..00000000 --- a/FileSets/v3.40~20/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/MbEditBoxDateTime.qml b/FileSets/v3.40~20/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v3.40~20/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/MbItem.qml b/FileSets/v3.40~20/MbItem.qml deleted file mode 120000 index 048a313c..00000000 --- a/FileSets/v3.40~20/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/MbItemDigitalInput.qml b/FileSets/v3.40~20/MbItemDigitalInput.qml deleted file mode 120000 index 4404b520..00000000 --- a/FileSets/v3.40~20/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/MbSpinBox.qml b/FileSets/v3.40~20/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v3.40~20/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/MbStyle.qml b/FileSets/v3.40~20/MbStyle.qml deleted file mode 120000 index d1940446..00000000 --- a/FileSets/v3.40~20/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/MbSubMenu.qml b/FileSets/v3.40~20/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v3.40~20/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/Multi.qml b/FileSets/v3.40~20/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v3.40~20/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/ObjectAcConnection.qml b/FileSets/v3.40~20/ObjectAcConnection.qml deleted file mode 120000 index cab7f2d4..00000000 --- a/FileSets/v3.40~20/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~20/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 6d1e56b5..00000000 --- a/FileSets/v3.40~20/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/OverviewBox.qml b/FileSets/v3.40~20/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v3.40~20/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/OverviewConnection.qml b/FileSets/v3.40~20/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v3.40~20/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/OverviewConnectionEnd.qml b/FileSets/v3.40~20/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v3.40~20/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/OverviewFlowComplex.qml b/FileSets/v3.40~20/OverviewFlowComplex.qml deleted file mode 120000 index a151db4f..00000000 --- a/FileSets/v3.40~20/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~20/OverviewGeneratorEnhanced.qml deleted file mode 120000 index da5507a7..00000000 --- a/FileSets/v3.40~20/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~20/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index 1c9b530f..00000000 --- a/FileSets/v3.40~20/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/OverviewGridParallel.qml b/FileSets/v3.40~20/OverviewGridParallel.qml deleted file mode 120000 index d30a27d7..00000000 --- a/FileSets/v3.40~20/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/OverviewHub.qml b/FileSets/v3.40~20/OverviewHub.qml deleted file mode 120000 index 93c6ee1a..00000000 --- a/FileSets/v3.40~20/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/OverviewHubEnhanced.qml b/FileSets/v3.40~20/OverviewHubEnhanced.qml deleted file mode 120000 index c55515d9..00000000 --- a/FileSets/v3.40~20/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/OverviewMobileEnhanced.qml b/FileSets/v3.40~20/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.40~20/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/OverviewSolarCharger.qml b/FileSets/v3.40~20/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v3.40~20/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/OverviewSolarInverter.qml b/FileSets/v3.40~20/OverviewSolarInverter.qml deleted file mode 120000 index 4048703e..00000000 --- a/FileSets/v3.40~20/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/OverviewTankDelegate.qml b/FileSets/v3.40~20/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v3.40~20/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/OverviewTanks.qml b/FileSets/v3.40~20/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v3.40~20/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~20/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.40~20/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/PageDigitalInput.qml b/FileSets/v3.40~20/PageDigitalInput.qml deleted file mode 120000 index 5b768f8f..00000000 --- a/FileSets/v3.40~20/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/PageGenerator.qml b/FileSets/v3.40~20/PageGenerator.qml deleted file mode 120000 index efbafddf..00000000 --- a/FileSets/v3.40~20/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/PageMain.qml b/FileSets/v3.40~20/PageMain.qml deleted file mode 120000 index ef4b9c47..00000000 --- a/FileSets/v3.40~20/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/PageSettingsDisplay.qml b/FileSets/v3.40~20/PageSettingsDisplay.qml deleted file mode 120000 index 03766d99..00000000 --- a/FileSets/v3.40~20/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/PageSettingsGenerator.qml b/FileSets/v3.40~20/PageSettingsGenerator.qml deleted file mode 120000 index 15dd8f85..00000000 --- a/FileSets/v3.40~20/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/PageSettingsGuiMods.qml b/FileSets/v3.40~20/PageSettingsGuiMods.qml deleted file mode 120000 index e831a7a4..00000000 --- a/FileSets/v3.40~20/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/PageSettingsRelay.qml b/FileSets/v3.40~20/PageSettingsRelay.qml deleted file mode 120000 index 156aadac..00000000 --- a/FileSets/v3.40~20/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/PowerGauge.qml b/FileSets/v3.40~20/PowerGauge.qml deleted file mode 120000 index 4bcaaa4a..00000000 --- a/FileSets/v3.40~20/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/Tile.qml b/FileSets/v3.40~20/Tile.qml deleted file mode 120000 index 0558cecf..00000000 --- a/FileSets/v3.40~20/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/TileDigIn.qml b/FileSets/v3.40~20/TileDigIn.qml deleted file mode 120000 index 44616f30..00000000 --- a/FileSets/v3.40~20/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/TileRelay.qml b/FileSets/v3.40~20/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.40~20/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/TileText.qml b/FileSets/v3.40~20/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v3.40~20/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/attributes.csv b/FileSets/v3.40~20/attributes.csv deleted file mode 120000 index 6508da35..00000000 --- a/FileSets/v3.40~20/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v3.40~26/attributes.csv \ No newline at end of file diff --git a/FileSets/v3.40~20/dbus_digitalinputs.py b/FileSets/v3.40~20/dbus_digitalinputs.py deleted file mode 120000 index e74da5b6..00000000 --- a/FileSets/v3.40~20/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.40~20/dbus_generator.py b/FileSets/v3.40~20/dbus_generator.py deleted file mode 120000 index 0cd84ca3..00000000 --- a/FileSets/v3.40~20/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.40~20/main.qml b/FileSets/v3.40~20/main.qml deleted file mode 120000 index 5dbfdf83..00000000 --- a/FileSets/v3.40~20/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/main.qml \ No newline at end of file diff --git a/FileSets/v3.40~20/startstop.py b/FileSets/v3.40~20/startstop.py deleted file mode 120000 index c18bce2d..00000000 --- a/FileSets/v3.40~20/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~37/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~20/styles.css b/FileSets/v3.40~20/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v3.40~20/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v3.40~21/Battery.qml b/FileSets/v3.40~21/Battery.qml deleted file mode 120000 index fafc7b36..00000000 --- a/FileSets/v3.40~21/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/COMPLETE b/FileSets/v3.40~21/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~21/DetailAcInput.qml b/FileSets/v3.40~21/DetailAcInput.qml deleted file mode 120000 index 8e76794d..00000000 --- a/FileSets/v3.40~21/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/DetailInverter.qml b/FileSets/v3.40~21/DetailInverter.qml deleted file mode 120000 index 285b3216..00000000 --- a/FileSets/v3.40~21/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/DetailLoadsCombined.qml b/FileSets/v3.40~21/DetailLoadsCombined.qml deleted file mode 120000 index 81c6de5a..00000000 --- a/FileSets/v3.40~21/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/DetailLoadsOnInput.qml b/FileSets/v3.40~21/DetailLoadsOnInput.qml deleted file mode 120000 index a5f97488..00000000 --- a/FileSets/v3.40~21/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/DetailLoadsOnOutput.qml b/FileSets/v3.40~21/DetailLoadsOnOutput.qml deleted file mode 120000 index 7cfc98c6..00000000 --- a/FileSets/v3.40~21/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/HubData.qml b/FileSets/v3.40~21/HubData.qml deleted file mode 120000 index c80a3bff..00000000 --- a/FileSets/v3.40~21/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/MbEditBox.qml b/FileSets/v3.40~21/MbEditBox.qml deleted file mode 120000 index 90a92492..00000000 --- a/FileSets/v3.40~21/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/MbEditBoxDateTime.qml b/FileSets/v3.40~21/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v3.40~21/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/MbItem.qml b/FileSets/v3.40~21/MbItem.qml deleted file mode 120000 index 048a313c..00000000 --- a/FileSets/v3.40~21/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/MbItemDigitalInput.qml b/FileSets/v3.40~21/MbItemDigitalInput.qml deleted file mode 120000 index 4404b520..00000000 --- a/FileSets/v3.40~21/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/MbSpinBox.qml b/FileSets/v3.40~21/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v3.40~21/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/MbStyle.qml b/FileSets/v3.40~21/MbStyle.qml deleted file mode 120000 index d1940446..00000000 --- a/FileSets/v3.40~21/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/MbSubMenu.qml b/FileSets/v3.40~21/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v3.40~21/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/Multi.qml b/FileSets/v3.40~21/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v3.40~21/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/ObjectAcConnection.qml b/FileSets/v3.40~21/ObjectAcConnection.qml deleted file mode 120000 index cab7f2d4..00000000 --- a/FileSets/v3.40~21/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~21/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 6d1e56b5..00000000 --- a/FileSets/v3.40~21/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/OverviewBox.qml b/FileSets/v3.40~21/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v3.40~21/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/OverviewConnection.qml b/FileSets/v3.40~21/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v3.40~21/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/OverviewConnectionEnd.qml b/FileSets/v3.40~21/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v3.40~21/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/OverviewFlowComplex.qml b/FileSets/v3.40~21/OverviewFlowComplex.qml deleted file mode 120000 index a151db4f..00000000 --- a/FileSets/v3.40~21/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~21/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index 1c9b530f..00000000 --- a/FileSets/v3.40~21/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/OverviewGridParallel.qml b/FileSets/v3.40~21/OverviewGridParallel.qml deleted file mode 120000 index d30a27d7..00000000 --- a/FileSets/v3.40~21/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/OverviewHub.qml b/FileSets/v3.40~21/OverviewHub.qml deleted file mode 120000 index 93c6ee1a..00000000 --- a/FileSets/v3.40~21/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/OverviewHubEnhanced.qml b/FileSets/v3.40~21/OverviewHubEnhanced.qml deleted file mode 120000 index c55515d9..00000000 --- a/FileSets/v3.40~21/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/OverviewMobileEnhanced.qml b/FileSets/v3.40~21/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.40~21/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/OverviewSolarCharger.qml b/FileSets/v3.40~21/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v3.40~21/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/OverviewSolarInverter.qml b/FileSets/v3.40~21/OverviewSolarInverter.qml deleted file mode 120000 index 4048703e..00000000 --- a/FileSets/v3.40~21/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/OverviewTankDelegate.qml b/FileSets/v3.40~21/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v3.40~21/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/OverviewTanks.qml b/FileSets/v3.40~21/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v3.40~21/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~21/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.40~21/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/PageDigitalInput.qml b/FileSets/v3.40~21/PageDigitalInput.qml deleted file mode 120000 index 5b768f8f..00000000 --- a/FileSets/v3.40~21/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/PageGenerator.qml b/FileSets/v3.40~21/PageGenerator.qml deleted file mode 100644 index c9670db0..00000000 --- a/FileSets/v3.40~21/PageGenerator.qml +++ /dev/null @@ -1,223 +0,0 @@ -//// changed total time to hours (from varilable format) - -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: root - title: qsTr("Generator start/stop") - property string settingsBindPrefix - property string startStopBindPrefix - property alias startStopModel: _startStopModel - property bool allowDisableAutostart: true - property VBusItem activeCondition: VBusItem { bind: Utils.path(startStopBindPrefix, "/RunningByCondition") } - property VBusItem generatorState: VBusItem { bind: Utils.path(startStopBindPrefix, "/State") } - property VBusItem runningTime: VBusItem { bind: Utils.path(startStopBindPrefix, "/Runtime") } - property VBusItem historicalData: VBusItem { bind: Utils.path(settingsBindPrefix, "/AccumulatedDaily") } - -//// changed total time to hours (from varilable format) - function formatTime (time) - { - if (time >= 3600) - return (time / 3600).toFixed(0) + " h" - else - return (time / 60).toFixed(0) + " m" - } - - - function getState() - { - switch(generatorState.value) { - case 10: - return qsTr("Error") - case 2: - return qsTr("Warm-up") - case 3: - return qsTr("Cool-down") - case 4: - return qsTr("Stopping") - } - - switch(activeCondition.value) { - case 'soc': - return qsTr("Running by SOC condition") - case 'acload': - return qsTr("Running by AC Load condition") - case 'batterycurrent': - return qsTr("Running by battery current condition") - case 'batteryvoltage': - return qsTr("Running by battery voltage condition") - case 'inverterhightemp': - return qsTr("Running by inverter high temperature") - case 'inverteroverload': - return qsTr("Running by inverter overload") - case 'testrun': - return qsTr("Test run") - case 'lossofcommunication': - return qsTr("Running by loss of communication") - case 'manual': - return qsTr("Manually started") - default: - return qsTr("Stopped") - } - } - - model: startStopModel - - function formatError(text, value) - { - return "#" + value.toString() + " " + text - } - - VisibleItemModel { - id: _startStopModel - - MbItemValue { - description: qsTr("State") - item.text: activeCondition.valid ? getState() : '---' - } - - MbItemOptions { - id: _gensetStatus - description: qsTr("Error") - bind: Utils.path(startStopBindPrefix, "/Error") - readonly: true - show: valid - possibleValues: [ - MbOption { description: qsTr("No error"); value: 0 }, - MbOption { description: formatError(qsTr("Remote switch control disabled"), 1); value: 1 }, - MbOption { description: formatError(qsTr("Generator in fault condition"), 2); value: 2 }, - MbOption { description: formatError(qsTr("Generator not detected at AC input"), 3); value: 3 } - ] - } - - MbItemValue { - description: qsTr("Run time") - item.text: runningTime.valid ? Utils.secondsToNoSecsString(runningTime.value) : "0" - show: generatorState.value in [1, 2, 3] // Running, Warm-up, Cool-down - } - - MbItemValue { - description: qsTr("Total run time") - show: item.valid - item { - bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") -//// changed total time to hours (from varilable format) - text: formatTime (item.value - accumulatedTotalOffset.value) - } - VBusItem { - id: accumulatedTotalOffset - bind: Utils.path(settingsBindPrefix, "/AccumulatedTotalOffset") - } - } - - MbItemValue { - description: qsTr("Time to service") - show: item.valid - item { - bind: Utils.path(startStopBindPrefix, "/ServiceCounter") - text: qsTr("%1h").arg((item.value / 60 / 60).toFixed(0)) - } - } - - MbItemValue { - description: qsTr("Accumulated running time since last test run") - show: user.accessLevel >= User.AccessService && nextTestRun.show - backgroundColor: style.backgroundColorService - item { - text: Utils.secondsToNoSecsString(item.value) - bind: Utils.path(startStopBindPrefix, "/TestRunIntervalRuntime") - } - } - - MbItemValue { - id: nextTestRun - description: qsTr("Time to next test run") - show: item.valid && item.value > 0 - item { - text: { - var remainingTime = item.value - new Date().getTime() / 1000 - if (remainingTime > 0) - return Utils.secondsToNoSecsString(remainingTime).toString() - return qsTr("Running now") - } - bind: Utils.path(startStopBindPrefix, "/NextTestRun") - } - } - - MbSwitch { - name: qsTr("Auto start functionality") - bind: Utils.path(startStopBindPrefix, "/AutoStartEnabled") - show: allowDisableAutostart - } - - MbSubMenu { - description: qsTr("Manual start") - subpage: Component { - MbPage { - id: manualStartPage - title: qsTr("Manual start") - model: VisibleItemModel { - MbSwitch { - id: manualSwitch - name: qsTr("Start generator") - bind: Utils.path(startStopBindPrefix, "/ManualStart") - writeAccessLevel: User.AccessUser - onCheckedChanged: { - if (manualStartPage.active) { - if (!checked) - toast.createToast(qsTr("Stopping, generator will continue running if other conditions are reached"), 3000) - if (checked && stopTimer.value == 0) - toast.createToast(qsTr("Starting, generator won't stop till user intervention"), 5000) - if (checked && stopTimer.value > 0) - toast.createToast(qsTr("Starting. The generator will stop in %1, unless other conditions keep it running").arg(Utils.secondsToString(stopTimer.value)), 5000) - } - } - - VBusItem { - id: stopTimer - bind: Utils.path(startStopBindPrefix, "/ManualStartTimer") - } - } - - MbEditBoxTime { - description: qsTr("Run for (hh:mm)") - readonly: manualSwitch.checked - item.bind: Utils.path(startStopBindPrefix, "/ManualStartTimer") - writeAccessLevel: User.AccessUser - } - } - } - } - } - - MbSubMenu { - description: qsTr("Daily run time") - subpage: MbPage { - // Invert the order - property variant keys: historicalData.valid ? - Object.keys(JSON.parse(historicalData.value)).reverse() : 0 - - title: qsTr("Daily run time") - focus: active - model: keys - delegate: MbItemValue { - description: Qt.formatDate(new Date(parseInt(keys[index]) * 1000), "dd-MM-yyyy"); - item.text: Utils.secondsToNoSecsString(JSON.parse(historicalData.value)[keys[index]]) - } - } - } - - MbSubMenu { - id: conditions - description: qsTr("Settings") - subpage: Component { - PageSettingsGenerator { - settingsBindPrefix: root.settingsBindPrefix - startStopBindPrefix: root.startStopBindPrefix - } - } - } - } -} diff --git a/FileSets/v3.40~21/PageMain.qml b/FileSets/v3.40~21/PageMain.qml deleted file mode 120000 index ef4b9c47..00000000 --- a/FileSets/v3.40~21/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/PageSettingsDisplay.qml b/FileSets/v3.40~21/PageSettingsDisplay.qml deleted file mode 120000 index 03766d99..00000000 --- a/FileSets/v3.40~21/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/PageSettingsGenerator.qml b/FileSets/v3.40~21/PageSettingsGenerator.qml deleted file mode 120000 index 15dd8f85..00000000 --- a/FileSets/v3.40~21/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/PageSettingsGuiMods.qml b/FileSets/v3.40~21/PageSettingsGuiMods.qml deleted file mode 120000 index e831a7a4..00000000 --- a/FileSets/v3.40~21/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/PageSettingsRelay.qml b/FileSets/v3.40~21/PageSettingsRelay.qml deleted file mode 120000 index 156aadac..00000000 --- a/FileSets/v3.40~21/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/PowerGauge.qml b/FileSets/v3.40~21/PowerGauge.qml deleted file mode 120000 index 4bcaaa4a..00000000 --- a/FileSets/v3.40~21/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/Tile.qml b/FileSets/v3.40~21/Tile.qml deleted file mode 120000 index 0558cecf..00000000 --- a/FileSets/v3.40~21/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/TileDigIn.qml b/FileSets/v3.40~21/TileDigIn.qml deleted file mode 120000 index 44616f30..00000000 --- a/FileSets/v3.40~21/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/TileRelay.qml b/FileSets/v3.40~21/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.40~21/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/TileText.qml b/FileSets/v3.40~21/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v3.40~21/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/attributes.csv b/FileSets/v3.40~21/attributes.csv deleted file mode 120000 index 6508da35..00000000 --- a/FileSets/v3.40~21/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v3.40~26/attributes.csv \ No newline at end of file diff --git a/FileSets/v3.40~21/dbus_digitalinputs.py b/FileSets/v3.40~21/dbus_digitalinputs.py deleted file mode 120000 index e74da5b6..00000000 --- a/FileSets/v3.40~21/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.40~21/dbus_generator.py b/FileSets/v3.40~21/dbus_generator.py deleted file mode 120000 index 0cd84ca3..00000000 --- a/FileSets/v3.40~21/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.40~21/dbus_systemcalc.py b/FileSets/v3.40~21/dbus_systemcalc.py deleted file mode 120000 index a8714390..00000000 --- a/FileSets/v3.40~21/dbus_systemcalc.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~27/dbus_systemcalc.py \ No newline at end of file diff --git a/FileSets/v3.40~21/main.qml b/FileSets/v3.40~21/main.qml deleted file mode 120000 index 5dbfdf83..00000000 --- a/FileSets/v3.40~21/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/main.qml \ No newline at end of file diff --git a/FileSets/v3.40~21/startstop.py b/FileSets/v3.40~21/startstop.py deleted file mode 120000 index c18bce2d..00000000 --- a/FileSets/v3.40~21/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~37/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~21/styles.css b/FileSets/v3.40~21/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v3.40~21/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v3.40~23/Battery.qml b/FileSets/v3.40~23/Battery.qml deleted file mode 120000 index fafc7b36..00000000 --- a/FileSets/v3.40~23/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/COMPLETE b/FileSets/v3.40~23/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~23/DetailAcInput.qml b/FileSets/v3.40~23/DetailAcInput.qml deleted file mode 120000 index 8e76794d..00000000 --- a/FileSets/v3.40~23/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/DetailInverter.qml b/FileSets/v3.40~23/DetailInverter.qml deleted file mode 120000 index 285b3216..00000000 --- a/FileSets/v3.40~23/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/DetailLoadsCombined.qml b/FileSets/v3.40~23/DetailLoadsCombined.qml deleted file mode 120000 index 81c6de5a..00000000 --- a/FileSets/v3.40~23/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/DetailLoadsOnInput.qml b/FileSets/v3.40~23/DetailLoadsOnInput.qml deleted file mode 120000 index a5f97488..00000000 --- a/FileSets/v3.40~23/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/DetailLoadsOnOutput.qml b/FileSets/v3.40~23/DetailLoadsOnOutput.qml deleted file mode 120000 index 7cfc98c6..00000000 --- a/FileSets/v3.40~23/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/HubData.qml b/FileSets/v3.40~23/HubData.qml deleted file mode 120000 index c80a3bff..00000000 --- a/FileSets/v3.40~23/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/LINKS_ONLY b/FileSets/v3.40~23/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~23/MbEditBox.qml b/FileSets/v3.40~23/MbEditBox.qml deleted file mode 120000 index 90a92492..00000000 --- a/FileSets/v3.40~23/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/MbEditBoxDateTime.qml b/FileSets/v3.40~23/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v3.40~23/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/MbItem.qml b/FileSets/v3.40~23/MbItem.qml deleted file mode 120000 index 048a313c..00000000 --- a/FileSets/v3.40~23/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/MbItemDigitalInput.qml b/FileSets/v3.40~23/MbItemDigitalInput.qml deleted file mode 120000 index 4404b520..00000000 --- a/FileSets/v3.40~23/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/MbSpinBox.qml b/FileSets/v3.40~23/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v3.40~23/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/MbStyle.qml b/FileSets/v3.40~23/MbStyle.qml deleted file mode 120000 index d1940446..00000000 --- a/FileSets/v3.40~23/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/MbSubMenu.qml b/FileSets/v3.40~23/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v3.40~23/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/Multi.qml b/FileSets/v3.40~23/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v3.40~23/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/ObjectAcConnection.qml b/FileSets/v3.40~23/ObjectAcConnection.qml deleted file mode 120000 index cab7f2d4..00000000 --- a/FileSets/v3.40~23/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~23/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 6d1e56b5..00000000 --- a/FileSets/v3.40~23/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/OverviewBox.qml b/FileSets/v3.40~23/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v3.40~23/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/OverviewConnection.qml b/FileSets/v3.40~23/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v3.40~23/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/OverviewConnectionEnd.qml b/FileSets/v3.40~23/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v3.40~23/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/OverviewFlowComplex.qml b/FileSets/v3.40~23/OverviewFlowComplex.qml deleted file mode 120000 index a151db4f..00000000 --- a/FileSets/v3.40~23/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~23/OverviewGeneratorEnhanced.qml deleted file mode 120000 index a8b492cd..00000000 --- a/FileSets/v3.40~23/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~26/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~23/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index 1c9b530f..00000000 --- a/FileSets/v3.40~23/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/OverviewGridParallel.qml b/FileSets/v3.40~23/OverviewGridParallel.qml deleted file mode 120000 index d30a27d7..00000000 --- a/FileSets/v3.40~23/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/OverviewHub.qml b/FileSets/v3.40~23/OverviewHub.qml deleted file mode 120000 index 93c6ee1a..00000000 --- a/FileSets/v3.40~23/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/OverviewHubEnhanced.qml b/FileSets/v3.40~23/OverviewHubEnhanced.qml deleted file mode 120000 index c55515d9..00000000 --- a/FileSets/v3.40~23/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/OverviewMobileEnhanced.qml b/FileSets/v3.40~23/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.40~23/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/OverviewSolarCharger.qml b/FileSets/v3.40~23/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v3.40~23/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/OverviewSolarInverter.qml b/FileSets/v3.40~23/OverviewSolarInverter.qml deleted file mode 120000 index 4048703e..00000000 --- a/FileSets/v3.40~23/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/OverviewTankDelegate.qml b/FileSets/v3.40~23/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v3.40~23/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/OverviewTanks.qml b/FileSets/v3.40~23/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v3.40~23/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~23/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.40~23/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/PageDigitalInput.qml b/FileSets/v3.40~23/PageDigitalInput.qml deleted file mode 120000 index 5b768f8f..00000000 --- a/FileSets/v3.40~23/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/PageGenerator.qml b/FileSets/v3.40~23/PageGenerator.qml deleted file mode 120000 index 228ea843..00000000 --- a/FileSets/v3.40~23/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~26/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/PageMain.qml b/FileSets/v3.40~23/PageMain.qml deleted file mode 120000 index ef4b9c47..00000000 --- a/FileSets/v3.40~23/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/PageSettingsDisplay.qml b/FileSets/v3.40~23/PageSettingsDisplay.qml deleted file mode 120000 index 03766d99..00000000 --- a/FileSets/v3.40~23/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/PageSettingsGenerator.qml b/FileSets/v3.40~23/PageSettingsGenerator.qml deleted file mode 120000 index 15dd8f85..00000000 --- a/FileSets/v3.40~23/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/PageSettingsGuiMods.qml b/FileSets/v3.40~23/PageSettingsGuiMods.qml deleted file mode 120000 index e831a7a4..00000000 --- a/FileSets/v3.40~23/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/PageSettingsRelay.qml b/FileSets/v3.40~23/PageSettingsRelay.qml deleted file mode 120000 index 156aadac..00000000 --- a/FileSets/v3.40~23/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/PowerGauge.qml b/FileSets/v3.40~23/PowerGauge.qml deleted file mode 120000 index 4bcaaa4a..00000000 --- a/FileSets/v3.40~23/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/Tile.qml b/FileSets/v3.40~23/Tile.qml deleted file mode 120000 index 0558cecf..00000000 --- a/FileSets/v3.40~23/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/TileDigIn.qml b/FileSets/v3.40~23/TileDigIn.qml deleted file mode 120000 index 44616f30..00000000 --- a/FileSets/v3.40~23/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/TileRelay.qml b/FileSets/v3.40~23/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.40~23/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/TileText.qml b/FileSets/v3.40~23/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v3.40~23/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/attributes.csv b/FileSets/v3.40~23/attributes.csv deleted file mode 120000 index 6508da35..00000000 --- a/FileSets/v3.40~23/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v3.40~26/attributes.csv \ No newline at end of file diff --git a/FileSets/v3.40~23/dbus_digitalinputs.py b/FileSets/v3.40~23/dbus_digitalinputs.py deleted file mode 120000 index e74da5b6..00000000 --- a/FileSets/v3.40~23/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.40~23/dbus_generator.py b/FileSets/v3.40~23/dbus_generator.py deleted file mode 120000 index 0cd84ca3..00000000 --- a/FileSets/v3.40~23/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.40~23/dbus_systemcalc.py b/FileSets/v3.40~23/dbus_systemcalc.py deleted file mode 120000 index a8714390..00000000 --- a/FileSets/v3.40~23/dbus_systemcalc.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~27/dbus_systemcalc.py \ No newline at end of file diff --git a/FileSets/v3.40~23/main.qml b/FileSets/v3.40~23/main.qml deleted file mode 120000 index 5dbfdf83..00000000 --- a/FileSets/v3.40~23/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/main.qml \ No newline at end of file diff --git a/FileSets/v3.40~23/startstop.py b/FileSets/v3.40~23/startstop.py deleted file mode 120000 index c18bce2d..00000000 --- a/FileSets/v3.40~23/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~37/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~23/styles.css b/FileSets/v3.40~23/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v3.40~23/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v3.40~26/Battery.qml b/FileSets/v3.40~26/Battery.qml deleted file mode 120000 index fafc7b36..00000000 --- a/FileSets/v3.40~26/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/COMPLETE b/FileSets/v3.40~26/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~26/DetailAcInput.qml b/FileSets/v3.40~26/DetailAcInput.qml deleted file mode 120000 index 8e76794d..00000000 --- a/FileSets/v3.40~26/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/DetailInverter.qml b/FileSets/v3.40~26/DetailInverter.qml deleted file mode 120000 index 285b3216..00000000 --- a/FileSets/v3.40~26/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/DetailLoadsCombined.qml b/FileSets/v3.40~26/DetailLoadsCombined.qml deleted file mode 120000 index 81c6de5a..00000000 --- a/FileSets/v3.40~26/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/DetailLoadsOnInput.qml b/FileSets/v3.40~26/DetailLoadsOnInput.qml deleted file mode 120000 index a5f97488..00000000 --- a/FileSets/v3.40~26/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/DetailLoadsOnOutput.qml b/FileSets/v3.40~26/DetailLoadsOnOutput.qml deleted file mode 120000 index 7cfc98c6..00000000 --- a/FileSets/v3.40~26/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/HubData.qml b/FileSets/v3.40~26/HubData.qml deleted file mode 120000 index c80a3bff..00000000 --- a/FileSets/v3.40~26/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/MbEditBox.qml b/FileSets/v3.40~26/MbEditBox.qml deleted file mode 120000 index 90a92492..00000000 --- a/FileSets/v3.40~26/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/MbEditBoxDateTime.qml b/FileSets/v3.40~26/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v3.40~26/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/MbItem.qml b/FileSets/v3.40~26/MbItem.qml deleted file mode 120000 index 048a313c..00000000 --- a/FileSets/v3.40~26/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/MbItemDigitalInput.qml b/FileSets/v3.40~26/MbItemDigitalInput.qml deleted file mode 120000 index 4404b520..00000000 --- a/FileSets/v3.40~26/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/MbSpinBox.qml b/FileSets/v3.40~26/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v3.40~26/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/MbStyle.qml b/FileSets/v3.40~26/MbStyle.qml deleted file mode 120000 index d1940446..00000000 --- a/FileSets/v3.40~26/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/MbSubMenu.qml b/FileSets/v3.40~26/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v3.40~26/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/Multi.qml b/FileSets/v3.40~26/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v3.40~26/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/ObjectAcConnection.qml b/FileSets/v3.40~26/ObjectAcConnection.qml deleted file mode 120000 index cab7f2d4..00000000 --- a/FileSets/v3.40~26/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~26/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 6d1e56b5..00000000 --- a/FileSets/v3.40~26/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/OverviewBox.qml b/FileSets/v3.40~26/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v3.40~26/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/OverviewConnection.qml b/FileSets/v3.40~26/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v3.40~26/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/OverviewConnectionEnd.qml b/FileSets/v3.40~26/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v3.40~26/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/OverviewFlowComplex.qml b/FileSets/v3.40~26/OverviewFlowComplex.qml deleted file mode 120000 index a151db4f..00000000 --- a/FileSets/v3.40~26/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~26/OverviewGeneratorEnhanced.qml deleted file mode 100644 index 0c189315..00000000 --- a/FileSets/v3.40~26/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1,547 +0,0 @@ -// GuiMods enhanced generator overview -// This file has been modified to: -// add Auto Start display and control -// show voltage, current, frequency, and power gauge in AC input tile -// show the generator running state inside the icon top left -// show a warning when the generator digital input and expected generator state disagree -// move current run time to separate tile - -import QtQuick 1.1 -import "utils.js" as Utils -import "enhancedFormat.js" as EnhFmt - -OverviewPage { - id: root - - property string settingsBindPrefix - property string bindPrefix - property variant sys: theSystem -//////// added to show alternator in place of inactive genset - property string guiModsPrefix: "com.victronenergy.settings/Settings/GuiMods" - VBusItem { id: replaceAcInItem; bind: Utils.path(guiModsPrefix, "/ReplaceInactiveAcIn") } - property bool hasAlternator: sys.alternator.power.valid - property bool showAlternator: replaceAcInItem.valid && replaceAcInItem.value == 1 && hasAlternator && ! sys.genset.power.valid - property bool showAcIn: ! showAlternator - - property string icon: "overview-generator" - property VBusItem state: VBusItem { bind: Utils.path(bindPrefix, "/State") } - property VBusItem error: VBusItem { bind: Utils.path(bindPrefix, "/Error") } - property VBusItem runningTime: VBusItem { bind: Utils.path(bindPrefix, "/Runtime") } - property VBusItem runningBy: VBusItem { bind: Utils.path(bindPrefix, "/RunningByConditionCode") } - VBusItem { id: totalAcummulatedTime; bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") } - VBusItem { id: totalAccumulatedTimeOffset; bind: Utils.path(settingsBindPrefix, "/AccumulatedTotalOffset") } - property VBusItem quietHours: VBusItem { bind: Utils.path(bindPrefix, "/QuietHours") } - property VBusItem testRunDuration: VBusItem { bind: Utils.path(settingsBindPrefix, "/TestRun/Duration") } - property VBusItem nextTestRun: VBusItem { bind: Utils.path(bindPrefix, "/NextTestRun") } - property VBusItem skipTestRun: VBusItem { bind: Utils.path(bindPrefix, "/SkipTestRun") } - - property VBusItem todayRuntime: VBusItem { bind: Utils.path(bindPrefix, "/TodayRuntime") } - property VBusItem manualTimer: VBusItem { bind: Utils.path(bindPrefix, "/ManualStartTimer") } - property VBusItem autoStart: VBusItem { bind: Utils.path(settingsBindPrefix, "/AutoStartEnabled") } - - property bool errors: ! state.valid || state.value == 10 - - property VBusItem externalOverrideItem: VBusItem { bind: Utils.path(bindPrefix, "/ExternalOverride") } - property bool externalOverride: externalOverrideItem.valid && externalOverrideItem.value == 1 && ! errors - property VBusItem runningState: VBusItem { bind: Utils.path(bindPrefix, "/GeneratorRunningState") } - - VBusItem { id: showGaugesItem; bind: Utils.path(guiModsPrefix, "/ShowGauges") } - property bool showGauges: showGaugesItem.valid ? showGaugesItem.value === 1 ? true : false : false - property bool editMode: autoRunTile.editMode || manualTile.editMode - - VBusItem { id: serviceInterval; bind: Utils.path(settingsBindPrefix, "/ServiceInterval") } - VBusItem { id: serviceCounterItem; bind: Utils.path(bindPrefix, "/ServiceCounter") } - property bool showServiceInfo: serviceCounterItem.valid && serviceInterval.valid && serviceInterval.value > 0 - property bool serviceOverdue: showServiceInfo && serviceCounterItem.value < 0 - -//////// add to display AC input ignored - VBusItem { id: ignoreAcInput1; bind: Utils.path(sys.vebusPrefix, "/Ac/State/IgnoreAcIn1") } - VBusItem { id: ignoreAcInput2; bind: Utils.path(sys.vebusPrefix, "/Ac/State/IgnoreAcIn2") } - VBusItem { id: acActiveInput; bind: Utils.path(sys.vebusPrefix, "/Ac/ActiveIn/ActiveInput") } - VBusItem { id: ac1source; bind: Utils.path("com.victronenergy.settings", "/Settings/SystemSetup/AcInput1") } - VBusItem { id: ac2source; bind: Utils.path("com.victronenergy.settings", "/Settings/SystemSetup/AcInput2") } - - title: qsTr("Generator") - - property bool autoStartSelected: false - - Component.onCompleted: - { - setFocusManual () - } - - Keys.forwardTo: [keyHandler] - Item - { - id: keyHandler - Keys.onUpPressed: - { - setFocusAuto () - event.accepted = true - } - Keys.onDownPressed: - { - setFocusManual () - event.accepted = true - } - // prevents page changes while timers are running - //// Keys.onReturnPressed: event.accepted = manualTile.startCountdown || autoRunTile.startCountdown - //// Keys.onEscapePressed: event.accepted = manualTile.startCountdown || autoRunTile.startCountdown - } - - function setFocusManual () - { - autoStartSelected = false - } - - function setFocusAuto () - { - autoStartSelected = true - } - - function formatTime (time) - { - if (time >= 3600) - return (time / 3600).toFixed(0) + " h" - else - return (time / 60).toFixed(0) + " m" - } - - function stateDescription() - { - if (!state.valid) - return qsTr ("") - else if (state.value === 10) - { - switch(error.value) - { - case 1: - return qsTr("Error: Remote switch control disabled") - case 2: - return qsTr("Error: Generator in fault condition") - case 3: - return qsTr("Error: Generator not detected at AC input") - default: - return qsTr("Error") - } - } - else - { - var condition = "" - var running = true - var manual = false - switch (runningBy.value) - { - case 0: // stopped - condition = "" - running = false - break;; - case 1: - manual = true - condition = "" - break;; - case 2: - condition = qsTr("Test run") - break;; - case 3: - condition = qsTr("Loss of communication") - break;; - case 4: - condition = qsTr("SOC") - break;; - case 5: - condition = qsTr("AC load") - break;; - case 6: - condition = qsTr("Battery current") - break;; - case 7: - condition = qsTr("Battery voltage") - break;; - case 8: - condition = qsTr("Inverter temperature") - break;; - case 9: - condition = qsTr("Inverter overload") - break;; - default: - condition = qsTr("???") - break;; - } - - if (externalOverride) - { - if (running && ! manual) - return qsTr ("auto pending: ") + condition - else - return " " - } - else if (manual) - { - if (manualTimer.valid && manualTimer.value > 0) - return qsTr("Timed run") - else - return qsTr("Manual run") - } - else if (running) - return qsTr ("auto run: ") + condition - else - return " " - } - } - - function getNextTestRun() - { - if ( ! root.state.valid) - return "" - if (!nextTestRun.value) - return qsTr("No test run programmed") - - var todayDate = new Date() - var nextDate = new Date(nextTestRun.value * 1000) - var nextDateEnd = new Date(nextDate.getTime()) - var message = "" - // blank "next run" if test run is active - if (runningBy.value == 2) - return " " - else if (todayDate.getDate() == nextDate.getDate() && todayDate.getMonth() == nextDate.getMonth()) - { - message = qsTr("Next test run today %1").arg( - Qt.formatDateTime(nextDate, "hh:mm").toString()) - } - else - { - message = qsTr("Next test run on %1").arg( - Qt.formatDateTime(nextDate, "dd/MM/yyyy").toString()) - nextDateEnd.setSeconds(testRunDuration.value) } - - if (skipTestRun.value === 1) - message += qsTr(" \(skipped\)") - - return message - } - - Tile { - id: imageTile - width: 180 - height: 136 - MbIcon { - id: generator - iconId: icon - anchors.centerIn: parent - } - anchors { top: parent.top; left: parent.left } - values: [ - // spacer - TileText { - width: imageTile.width - 5 - text: " " - font.pixelSize: 62 - }, - TileText { - width: imageTile.width - 5 - text: runningState.valid ? runningState.value == "R" ? "Running " : runningState.value == "S" ? "Stopped " : "" : "" - } - ] - } - - Tile { - id: statusTile - height: imageTile.height - color: "#4789d0" - anchors { top: parent.top; left: imageTile.right; right: root.right } - title: qsTr("STATUS") - values: [ - TileText - { - width: statusTile.width - 5 - color: externalOverride ? "yellow" : "white" - text: - { - var runPrefix - var message - if ( ! root.state.valid) - return qsTr ("Generator not connected") - else if (root.state.value === 2) - runPrefix = qsTr("Warming up for ") - else - runPrefix = qsTr ("Running for ") - if (!root.state.valid) - message = "" - else if (externalOverride) - message = qsTr("External Override - stopped") - else if (root.state.value === 3) - message = qsTr("Cool-down") - else if (root.state.value === 4) - message = qsTr("Stopping") - else if (runningBy.value == 0) - message = qsTr ("Stopped") - else if ( ! runningTime.valid) - message = runPrefix + "??" - else - { - message = runPrefix + formatTime (runningTime.value) - if (manualTimer.valid && manualTimer.value > 0) - message += qsTr (" ends in ") + formatTime (manualTimer.value) - } - return message - } - }, - Rectangle - { - width: parent.width - height: 3 - color: "transparent" - }, - TileTextMultiLine - { - text: stateDescription() - width: statusTile.width - 5 - }, - Rectangle - { - width: parent.width - height: 3 - color: "transparent" - }, - TileText - { - text: qsTr("\nQuiet hours"); - width: statusTile.width - 5 - font.bold: runningBy.valid && runningBy.value != 0 - color: font.bold ? "yellow" : "white" - visible: quietHours.value === 1 - }, - Rectangle - { - width: parent.width - height: 3 - color: "transparent" - }, - TileTextMultiLine - { - width: statusTile.width - 5 - text: getNextTestRun() - } - ] - } - - Tile { - id: acInTile - title: qsTr("GENERATOR POWER") - width: 150 - height: 136 - color: "#82acde" - anchors { top: imageTile.bottom; left: parent.left } - visible: showAcIn - values: - [ - OverviewAcValuesEnhanced - { - connection: sys.genset - visible: sys.genset.power.valid - }, - TileText - { - width: acInTile.width - 5 - text: - { - if (ac1source.valid && ac1source.value == 2) - { - if (ignoreAcInput1.valid && ignoreAcInput1.value == 1) - return qsTr ("\nAC In Ignored\nduring\ngenerator\nstart / stop") - else - return "" - } - else if (ac2source.valid && ac2source.value == 2) - { - if (ignoreAcInput2.valid && ignoreAcInput2.value == 1) - return qsTr ("\nAC In Ignored\nduring\ngenerator\nstart / stop") - else - return "" - } - else - return qsTr ("\nAC In\nis not\ngenerator") - } - visible: !sys.genset.power.valid - } - ] -////// add power bar graph - PowerGauge - { - id: acInBar - width: parent.width - height: 12 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.genset - useInputCurrentLimit: true - maxForwardPowerParameter: "" - maxReversePowerParameter: "" - visible: showGauges && sys.genset.power.valid - } - } - -//////// added to show alternator in place of AC generator - Tile { - id: alternatorTile - title: qsTr("ALTERNATOR POWER") - color: "#157894" - anchors.fill: acInTile - visible: showAlternator - values: - [ - TileText - { - text: EnhFmt.formatVBusItem (sys.alternator.power, "W") - font.pixelSize: 22 - } - ] -////// add power bar graph - PowerGauge - { - id: alternatorGauge - width: parent.width - height: 12 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.alternator - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxAlternatorPower" - visible: showGauges && showAlternator - } - } - - Tile { - id: runTimeTile - title: qsTr("RUN TIMES") - width: 140 - anchors { top: acInTile.top; bottom: parent.bottom; left: acInTile.right } - values: [ - TileText - { - width: runTimeTile.width - 5 - text: qsTr ("Today") - }, - TileText { - width: runTimeTile.width - 5 - text: todayRuntime.valid ? formatTime (todayRuntime.value) : "--" - }, - Rectangle - { - width: parent.width - height: 3 - color: "transparent" - }, - TileText - { - width: runTimeTile.width - 5 - text: qsTr ("Accumulated") - }, - TileText - { - width: runTimeTile.width - 5 - text: - { - if ( ! totalAcummulatedTime.valid) - return "--" - else if (totalAccumulatedTimeOffset.valid ) - return formatTime (totalAcummulatedTime.value - totalAccumulatedTimeOffset.value) - else - return formatTime (totalAcummulatedTime.value) - } - }, - Rectangle - { - width: parent.width - height: 3 - color: "transparent" - }, - TileText - { - width: runTimeTile.width - 5 - visible: showServiceInfo - color: serviceOverdue ? "red" : "white" - text: serviceOverdue ? qsTr ("Service OVERDUE") : qsTr ("Service in") - }, - TileText - { - width: runTimeTile.width - 5 - visible: showServiceInfo - color: serviceOverdue ? "red" : "white" - text: formatTime (Math.abs (serviceCounterItem.value)) - } - ] - } - - TileAutoRunEnhanced - { - id: autoRunTile - bindPrefix: root.bindPrefix - focus: root.active && autoStartSelected - connected: state.valid - tileHeight: acInTile.height / 2 - anchors { - bottom: parent.bottom; bottomMargin: tileHeight - left: runTimeTile.right - right: parent.right - } - } - - TileManualStartEnhanced - { - id: manualTile - bindPrefix: root.bindPrefix - focus: root.active && ! autoStartSelected - connected: state.valid - tileHeight: acInTile.height / 2 - anchors { - bottom: parent.bottom - left: runTimeTile.right - right: parent.right - } - } - - // mouse areas must be AFTER their associated objects so those objects can catch mouse events - // rejected by these areas - // mouse targets need to be disabled while changes are pending - MouseArea { - id: autoRunTarget - anchors.fill: autoRunTile - enabled: root.active && ! editMode - onPressed: - { - if ( ! root.autoStartSelected ) - { - setFocusAuto () - mouse.accepted = true - } - else - { - mouse.accepted = false - } - } - } - MouseArea { - id: manualStartTarget - anchors.fill: manualTile - enabled: root.active && ! editMode - onPressed: - { - if ( root.autoStartSelected ) - { - setFocusManual () - mouse.accepted = true - } - else - { - mouse.accepted = false - } - } - } -} diff --git a/FileSets/v3.40~26/OverviewGeneratorEnhanced.qml.orig b/FileSets/v3.40~26/OverviewGeneratorEnhanced.qml.orig deleted file mode 100644 index 54b1cbd3..00000000 --- a/FileSets/v3.40~26/OverviewGeneratorEnhanced.qml.orig +++ /dev/null @@ -1,147 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: root - title: qsTr("Generator start/stop") - property string settingsBindPrefix - property string startStopBindPrefix - property alias startStopModel: _startStopModel - property VBusItem activeCondition: VBusItem { bind: Utils.path(startStopBindPrefix, "/RunningByCondition") } - property VBusItem generatorState: VBusItem { bind: Utils.path(startStopBindPrefix, "/State") } - property VBusItem runningTime: VBusItem { bind: Utils.path(startStopBindPrefix, "/Runtime") } - property VBusItem historicalData: VBusItem { bind: Utils.path(settingsBindPrefix, "/AccumulatedDaily") } - - FnGeneratorStates { - id: genState - } - - model: startStopModel - - function formatError(text, value) - { - return "#" + value.toString() + " " + text - } - - VisibleItemModel { - id: _startStopModel - - MbItemValue { - description: qsTr("State") - show: startStopBindPrefix === "com.victronenergy.generator.startstop0" - item.text: activeCondition.valid ? genState.getState(generatorState.value, activeCondition.value) : '---' - } - - MbItemOptions { - id: _gensetStatus - description: qsTr("Error") - bind: Utils.path(startStopBindPrefix, "/Error") - readonly: true - show: valid && startStopBindPrefix === "com.victronenergy.generator.startstop0" - possibleValues: [ - MbOption { description: qsTr("No error"); value: 0 }, - MbOption { description: formatError(qsTr("Remote switch control disabled"), 1); value: 1 }, - MbOption { description: formatError(qsTr("Generator in fault condition"), 2); value: 2 }, - MbOption { description: formatError(qsTr("Generator not detected at AC input"), 3); value: 3 } - ] - } - - MbItemValue { - description: qsTr("Run time") - item.text: runningTime.valid ? Utils.secondsToNoSecsString(runningTime.value) : "0" - show: generatorState.value in [1, 2, 3] // Running, Warm-up, Cool-down - } - - MbItemValue { - description: qsTr("Total run time") - item { - bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") - text: Utils.secondsToNoSecsString(item.value - accumulatedTotalOffset.value) - } - VBusItem { - id: accumulatedTotalOffset - bind: Utils.path(settingsBindPrefix, "/AccumulatedTotalOffset") - } - } - - MbItemValue { - description: qsTr("Time to service") - show: item.valid - item { - bind: Utils.path(startStopBindPrefix, "/ServiceCounter") - text: qsTr("%1h").arg((item.value / 60 / 60).toFixed(0)) - } - } - - MbItemValue { - description: qsTr("Accumulated running time since last test run") - show: user.accessLevel >= User.AccessService && nextTestRun.show - backgroundColor: style.backgroundColorService - item { - text: Utils.secondsToNoSecsString(item.value) - bind: Utils.path(startStopBindPrefix, "/TestRunIntervalRuntime") - } - } - - MbItemValue { - id: nextTestRun - description: qsTr("Time to next test run") - show: item.valid && item.value > 0 - item { - text: { - var remainingTime = item.value - new Date().getTime() / 1000 - if (remainingTime > 0) - return Utils.secondsToNoSecsString(remainingTime).toString() - return qsTr("Running now") - } - bind: Utils.path(startStopBindPrefix, "/NextTestRun") - } - } - - MbSwitch { - name: qsTr("Auto start functionality") - bind: Utils.path(startStopBindPrefix, "/AutoStartEnabled") - show: startStopBindPrefix === "com.victronenergy.generator.startstop0" - } - - MbSubMenu { - description: qsTr("Manual start") - show: startStopBindPrefix === "com.victronenergy.generator.startstop0" - subpage: - Component { - PageGeneratorManualStart { - startStopBindPrefix: root.startStopBindPrefix - } - } - } - - MbSubMenu { - description: qsTr("Daily run time") - subpage: MbPage { - // Invert the order - property variant keys: historicalData.valid ? - Object.keys(JSON.parse(historicalData.value)).reverse() : 0 - - title: qsTr("Daily run time") - focus: active - model: keys - delegate: MbItemValue { - description: Qt.formatDate(new Date(parseInt(keys[index]) * 1000), "dd-MM-yyyy"); - item.text: Utils.secondsToNoSecsString(JSON.parse(historicalData.value)[keys[index]]) - } - } - } - - MbSubMenu { - id: conditions - description: qsTr("Settings") - subpage: Component { - PageSettingsGenerator { - settingsBindPrefix: root.settingsBindPrefix - startStopBindPrefix: root.startStopBindPrefix - } - } - } - } -} diff --git a/FileSets/v3.40~26/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~26/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index 1c9b530f..00000000 --- a/FileSets/v3.40~26/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/OverviewGridParallel.qml b/FileSets/v3.40~26/OverviewGridParallel.qml deleted file mode 120000 index d30a27d7..00000000 --- a/FileSets/v3.40~26/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/OverviewHub.qml b/FileSets/v3.40~26/OverviewHub.qml deleted file mode 120000 index 93c6ee1a..00000000 --- a/FileSets/v3.40~26/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/OverviewHubEnhanced.qml b/FileSets/v3.40~26/OverviewHubEnhanced.qml deleted file mode 120000 index c55515d9..00000000 --- a/FileSets/v3.40~26/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/OverviewMobileEnhanced.qml b/FileSets/v3.40~26/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.40~26/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/OverviewSolarCharger.qml b/FileSets/v3.40~26/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v3.40~26/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/OverviewSolarInverter.qml b/FileSets/v3.40~26/OverviewSolarInverter.qml deleted file mode 120000 index 4048703e..00000000 --- a/FileSets/v3.40~26/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/OverviewTankDelegate.qml b/FileSets/v3.40~26/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v3.40~26/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/OverviewTanks.qml b/FileSets/v3.40~26/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v3.40~26/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~26/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.40~26/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/PageDigitalInput.qml b/FileSets/v3.40~26/PageDigitalInput.qml deleted file mode 120000 index 5b768f8f..00000000 --- a/FileSets/v3.40~26/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/PageGenerator.qml.orig b/FileSets/v3.40~26/PageGenerator.qml.orig deleted file mode 100644 index 54b1cbd3..00000000 --- a/FileSets/v3.40~26/PageGenerator.qml.orig +++ /dev/null @@ -1,147 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: root - title: qsTr("Generator start/stop") - property string settingsBindPrefix - property string startStopBindPrefix - property alias startStopModel: _startStopModel - property VBusItem activeCondition: VBusItem { bind: Utils.path(startStopBindPrefix, "/RunningByCondition") } - property VBusItem generatorState: VBusItem { bind: Utils.path(startStopBindPrefix, "/State") } - property VBusItem runningTime: VBusItem { bind: Utils.path(startStopBindPrefix, "/Runtime") } - property VBusItem historicalData: VBusItem { bind: Utils.path(settingsBindPrefix, "/AccumulatedDaily") } - - FnGeneratorStates { - id: genState - } - - model: startStopModel - - function formatError(text, value) - { - return "#" + value.toString() + " " + text - } - - VisibleItemModel { - id: _startStopModel - - MbItemValue { - description: qsTr("State") - show: startStopBindPrefix === "com.victronenergy.generator.startstop0" - item.text: activeCondition.valid ? genState.getState(generatorState.value, activeCondition.value) : '---' - } - - MbItemOptions { - id: _gensetStatus - description: qsTr("Error") - bind: Utils.path(startStopBindPrefix, "/Error") - readonly: true - show: valid && startStopBindPrefix === "com.victronenergy.generator.startstop0" - possibleValues: [ - MbOption { description: qsTr("No error"); value: 0 }, - MbOption { description: formatError(qsTr("Remote switch control disabled"), 1); value: 1 }, - MbOption { description: formatError(qsTr("Generator in fault condition"), 2); value: 2 }, - MbOption { description: formatError(qsTr("Generator not detected at AC input"), 3); value: 3 } - ] - } - - MbItemValue { - description: qsTr("Run time") - item.text: runningTime.valid ? Utils.secondsToNoSecsString(runningTime.value) : "0" - show: generatorState.value in [1, 2, 3] // Running, Warm-up, Cool-down - } - - MbItemValue { - description: qsTr("Total run time") - item { - bind: Utils.path(settingsBindPrefix, "/AccumulatedTotal") - text: Utils.secondsToNoSecsString(item.value - accumulatedTotalOffset.value) - } - VBusItem { - id: accumulatedTotalOffset - bind: Utils.path(settingsBindPrefix, "/AccumulatedTotalOffset") - } - } - - MbItemValue { - description: qsTr("Time to service") - show: item.valid - item { - bind: Utils.path(startStopBindPrefix, "/ServiceCounter") - text: qsTr("%1h").arg((item.value / 60 / 60).toFixed(0)) - } - } - - MbItemValue { - description: qsTr("Accumulated running time since last test run") - show: user.accessLevel >= User.AccessService && nextTestRun.show - backgroundColor: style.backgroundColorService - item { - text: Utils.secondsToNoSecsString(item.value) - bind: Utils.path(startStopBindPrefix, "/TestRunIntervalRuntime") - } - } - - MbItemValue { - id: nextTestRun - description: qsTr("Time to next test run") - show: item.valid && item.value > 0 - item { - text: { - var remainingTime = item.value - new Date().getTime() / 1000 - if (remainingTime > 0) - return Utils.secondsToNoSecsString(remainingTime).toString() - return qsTr("Running now") - } - bind: Utils.path(startStopBindPrefix, "/NextTestRun") - } - } - - MbSwitch { - name: qsTr("Auto start functionality") - bind: Utils.path(startStopBindPrefix, "/AutoStartEnabled") - show: startStopBindPrefix === "com.victronenergy.generator.startstop0" - } - - MbSubMenu { - description: qsTr("Manual start") - show: startStopBindPrefix === "com.victronenergy.generator.startstop0" - subpage: - Component { - PageGeneratorManualStart { - startStopBindPrefix: root.startStopBindPrefix - } - } - } - - MbSubMenu { - description: qsTr("Daily run time") - subpage: MbPage { - // Invert the order - property variant keys: historicalData.valid ? - Object.keys(JSON.parse(historicalData.value)).reverse() : 0 - - title: qsTr("Daily run time") - focus: active - model: keys - delegate: MbItemValue { - description: Qt.formatDate(new Date(parseInt(keys[index]) * 1000), "dd-MM-yyyy"); - item.text: Utils.secondsToNoSecsString(JSON.parse(historicalData.value)[keys[index]]) - } - } - } - - MbSubMenu { - id: conditions - description: qsTr("Settings") - subpage: Component { - PageSettingsGenerator { - settingsBindPrefix: root.settingsBindPrefix - startStopBindPrefix: root.startStopBindPrefix - } - } - } - } -} diff --git a/FileSets/v3.40~26/PageMain.qml b/FileSets/v3.40~26/PageMain.qml deleted file mode 120000 index ef4b9c47..00000000 --- a/FileSets/v3.40~26/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/PageSettingsDisplay.qml b/FileSets/v3.40~26/PageSettingsDisplay.qml deleted file mode 120000 index 03766d99..00000000 --- a/FileSets/v3.40~26/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/PageSettingsGenerator.qml b/FileSets/v3.40~26/PageSettingsGenerator.qml deleted file mode 120000 index 15dd8f85..00000000 --- a/FileSets/v3.40~26/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/PageSettingsGuiMods.qml b/FileSets/v3.40~26/PageSettingsGuiMods.qml deleted file mode 120000 index e831a7a4..00000000 --- a/FileSets/v3.40~26/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/PageSettingsRelay.qml b/FileSets/v3.40~26/PageSettingsRelay.qml deleted file mode 120000 index 156aadac..00000000 --- a/FileSets/v3.40~26/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/PowerGauge.qml b/FileSets/v3.40~26/PowerGauge.qml deleted file mode 120000 index 4bcaaa4a..00000000 --- a/FileSets/v3.40~26/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/Tile.qml b/FileSets/v3.40~26/Tile.qml deleted file mode 120000 index 0558cecf..00000000 --- a/FileSets/v3.40~26/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/TileDigIn.qml b/FileSets/v3.40~26/TileDigIn.qml deleted file mode 120000 index 44616f30..00000000 --- a/FileSets/v3.40~26/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/TileRelay.qml b/FileSets/v3.40~26/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.40~26/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/TileText.qml b/FileSets/v3.40~26/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v3.40~26/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/dbus_digitalinputs.py b/FileSets/v3.40~26/dbus_digitalinputs.py deleted file mode 120000 index e74da5b6..00000000 --- a/FileSets/v3.40~26/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.40~26/dbus_generator.py b/FileSets/v3.40~26/dbus_generator.py deleted file mode 120000 index 0cd84ca3..00000000 --- a/FileSets/v3.40~26/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.40~26/dbus_systemcalc.py b/FileSets/v3.40~26/dbus_systemcalc.py deleted file mode 120000 index a8714390..00000000 --- a/FileSets/v3.40~26/dbus_systemcalc.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~27/dbus_systemcalc.py \ No newline at end of file diff --git a/FileSets/v3.40~26/main.qml b/FileSets/v3.40~26/main.qml deleted file mode 120000 index 5dbfdf83..00000000 --- a/FileSets/v3.40~26/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/main.qml \ No newline at end of file diff --git a/FileSets/v3.40~26/startstop.py b/FileSets/v3.40~26/startstop.py deleted file mode 120000 index c18bce2d..00000000 --- a/FileSets/v3.40~26/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~37/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~26/styles.css b/FileSets/v3.40~26/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v3.40~26/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v3.40~27/Battery.qml b/FileSets/v3.40~27/Battery.qml deleted file mode 120000 index fafc7b36..00000000 --- a/FileSets/v3.40~27/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/COMPLETE b/FileSets/v3.40~27/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~27/DetailAcInput.qml b/FileSets/v3.40~27/DetailAcInput.qml deleted file mode 120000 index 8e76794d..00000000 --- a/FileSets/v3.40~27/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/DetailInverter.qml b/FileSets/v3.40~27/DetailInverter.qml deleted file mode 120000 index 285b3216..00000000 --- a/FileSets/v3.40~27/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/DetailLoadsCombined.qml b/FileSets/v3.40~27/DetailLoadsCombined.qml deleted file mode 120000 index 81c6de5a..00000000 --- a/FileSets/v3.40~27/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/DetailLoadsOnInput.qml b/FileSets/v3.40~27/DetailLoadsOnInput.qml deleted file mode 120000 index a5f97488..00000000 --- a/FileSets/v3.40~27/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/DetailLoadsOnOutput.qml b/FileSets/v3.40~27/DetailLoadsOnOutput.qml deleted file mode 120000 index 7cfc98c6..00000000 --- a/FileSets/v3.40~27/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/HubData.qml b/FileSets/v3.40~27/HubData.qml deleted file mode 120000 index c80a3bff..00000000 --- a/FileSets/v3.40~27/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/LINKS_ONLY b/FileSets/v3.40~27/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~27/MbEditBox.qml b/FileSets/v3.40~27/MbEditBox.qml deleted file mode 120000 index 90a92492..00000000 --- a/FileSets/v3.40~27/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/MbEditBoxDateTime.qml b/FileSets/v3.40~27/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v3.40~27/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/MbItem.qml b/FileSets/v3.40~27/MbItem.qml deleted file mode 120000 index 048a313c..00000000 --- a/FileSets/v3.40~27/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/MbItemDigitalInput.qml b/FileSets/v3.40~27/MbItemDigitalInput.qml deleted file mode 120000 index 4404b520..00000000 --- a/FileSets/v3.40~27/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/MbSpinBox.qml b/FileSets/v3.40~27/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v3.40~27/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/MbStyle.qml b/FileSets/v3.40~27/MbStyle.qml deleted file mode 120000 index d1940446..00000000 --- a/FileSets/v3.40~27/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/MbSubMenu.qml b/FileSets/v3.40~27/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v3.40~27/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/Multi.qml b/FileSets/v3.40~27/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v3.40~27/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/ObjectAcConnection.qml b/FileSets/v3.40~27/ObjectAcConnection.qml deleted file mode 120000 index cab7f2d4..00000000 --- a/FileSets/v3.40~27/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~27/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 6d1e56b5..00000000 --- a/FileSets/v3.40~27/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/OverviewBox.qml b/FileSets/v3.40~27/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v3.40~27/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/OverviewConnection.qml b/FileSets/v3.40~27/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v3.40~27/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/OverviewConnectionEnd.qml b/FileSets/v3.40~27/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v3.40~27/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/OverviewFlowComplex.qml b/FileSets/v3.40~27/OverviewFlowComplex.qml deleted file mode 120000 index a151db4f..00000000 --- a/FileSets/v3.40~27/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~27/OverviewGeneratorEnhanced.qml deleted file mode 120000 index 3bf44cf5..00000000 --- a/FileSets/v3.40~27/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~27/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index 1c9b530f..00000000 --- a/FileSets/v3.40~27/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/OverviewGridParallel.qml b/FileSets/v3.40~27/OverviewGridParallel.qml deleted file mode 120000 index d30a27d7..00000000 --- a/FileSets/v3.40~27/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/OverviewHub.qml b/FileSets/v3.40~27/OverviewHub.qml deleted file mode 120000 index 93c6ee1a..00000000 --- a/FileSets/v3.40~27/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/OverviewHubEnhanced.qml b/FileSets/v3.40~27/OverviewHubEnhanced.qml deleted file mode 120000 index c55515d9..00000000 --- a/FileSets/v3.40~27/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/OverviewMobileEnhanced.qml b/FileSets/v3.40~27/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.40~27/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/OverviewSolarCharger.qml b/FileSets/v3.40~27/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v3.40~27/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/OverviewSolarInverter.qml b/FileSets/v3.40~27/OverviewSolarInverter.qml deleted file mode 120000 index 4048703e..00000000 --- a/FileSets/v3.40~27/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/OverviewTankDelegate.qml b/FileSets/v3.40~27/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v3.40~27/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/OverviewTanks.qml b/FileSets/v3.40~27/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v3.40~27/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~27/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.40~27/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/PageDigitalInput.qml b/FileSets/v3.40~27/PageDigitalInput.qml deleted file mode 120000 index 5b768f8f..00000000 --- a/FileSets/v3.40~27/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/PageGenerator.qml b/FileSets/v3.40~27/PageGenerator.qml deleted file mode 120000 index 4ff1c509..00000000 --- a/FileSets/v3.40~27/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/PageMain.qml b/FileSets/v3.40~27/PageMain.qml deleted file mode 120000 index ef4b9c47..00000000 --- a/FileSets/v3.40~27/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/PageSettingsDisplay.qml b/FileSets/v3.40~27/PageSettingsDisplay.qml deleted file mode 120000 index 03766d99..00000000 --- a/FileSets/v3.40~27/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/PageSettingsGenerator.qml b/FileSets/v3.40~27/PageSettingsGenerator.qml deleted file mode 120000 index 15dd8f85..00000000 --- a/FileSets/v3.40~27/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/PageSettingsGuiMods.qml b/FileSets/v3.40~27/PageSettingsGuiMods.qml deleted file mode 120000 index e831a7a4..00000000 --- a/FileSets/v3.40~27/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/PageSettingsRelay.qml b/FileSets/v3.40~27/PageSettingsRelay.qml deleted file mode 120000 index 156aadac..00000000 --- a/FileSets/v3.40~27/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/PowerGauge.qml b/FileSets/v3.40~27/PowerGauge.qml deleted file mode 120000 index 4bcaaa4a..00000000 --- a/FileSets/v3.40~27/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/Tile.qml b/FileSets/v3.40~27/Tile.qml deleted file mode 120000 index 0558cecf..00000000 --- a/FileSets/v3.40~27/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/TileDigIn.qml b/FileSets/v3.40~27/TileDigIn.qml deleted file mode 120000 index 44616f30..00000000 --- a/FileSets/v3.40~27/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/TileRelay.qml b/FileSets/v3.40~27/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.40~27/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/TileText.qml b/FileSets/v3.40~27/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v3.40~27/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/attributes.csv b/FileSets/v3.40~27/attributes.csv deleted file mode 120000 index 6e1ceaae..00000000 --- a/FileSets/v3.40~27/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v3.40~32/attributes.csv \ No newline at end of file diff --git a/FileSets/v3.40~27/dbus_digitalinputs.py b/FileSets/v3.40~27/dbus_digitalinputs.py deleted file mode 120000 index e74da5b6..00000000 --- a/FileSets/v3.40~27/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.40~27/dbus_generator.py b/FileSets/v3.40~27/dbus_generator.py deleted file mode 120000 index 0cd84ca3..00000000 --- a/FileSets/v3.40~27/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.40~27/main.qml b/FileSets/v3.40~27/main.qml deleted file mode 120000 index 5dbfdf83..00000000 --- a/FileSets/v3.40~27/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/main.qml \ No newline at end of file diff --git a/FileSets/v3.40~27/startstop.py b/FileSets/v3.40~27/startstop.py deleted file mode 120000 index c18bce2d..00000000 --- a/FileSets/v3.40~27/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~37/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~27/styles.css b/FileSets/v3.40~27/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v3.40~27/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v3.40~29/Battery.qml b/FileSets/v3.40~29/Battery.qml deleted file mode 120000 index fafc7b36..00000000 --- a/FileSets/v3.40~29/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/COMPLETE b/FileSets/v3.40~29/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~29/DetailAcInput.qml b/FileSets/v3.40~29/DetailAcInput.qml deleted file mode 120000 index 8e76794d..00000000 --- a/FileSets/v3.40~29/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/DetailInverter.qml b/FileSets/v3.40~29/DetailInverter.qml deleted file mode 120000 index 285b3216..00000000 --- a/FileSets/v3.40~29/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/DetailLoadsCombined.qml b/FileSets/v3.40~29/DetailLoadsCombined.qml deleted file mode 120000 index 81c6de5a..00000000 --- a/FileSets/v3.40~29/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/DetailLoadsOnInput.qml b/FileSets/v3.40~29/DetailLoadsOnInput.qml deleted file mode 120000 index a5f97488..00000000 --- a/FileSets/v3.40~29/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/DetailLoadsOnOutput.qml b/FileSets/v3.40~29/DetailLoadsOnOutput.qml deleted file mode 120000 index 7cfc98c6..00000000 --- a/FileSets/v3.40~29/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/HubData.qml b/FileSets/v3.40~29/HubData.qml deleted file mode 120000 index c80a3bff..00000000 --- a/FileSets/v3.40~29/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/LINKS_ONLY b/FileSets/v3.40~29/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~29/MbEditBox.qml b/FileSets/v3.40~29/MbEditBox.qml deleted file mode 120000 index 90a92492..00000000 --- a/FileSets/v3.40~29/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/MbEditBoxDateTime.qml b/FileSets/v3.40~29/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v3.40~29/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/MbItem.qml b/FileSets/v3.40~29/MbItem.qml deleted file mode 120000 index 048a313c..00000000 --- a/FileSets/v3.40~29/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/MbItemDigitalInput.qml b/FileSets/v3.40~29/MbItemDigitalInput.qml deleted file mode 120000 index 4404b520..00000000 --- a/FileSets/v3.40~29/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/MbSpinBox.qml b/FileSets/v3.40~29/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v3.40~29/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/MbStyle.qml b/FileSets/v3.40~29/MbStyle.qml deleted file mode 120000 index d1940446..00000000 --- a/FileSets/v3.40~29/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/MbSubMenu.qml b/FileSets/v3.40~29/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v3.40~29/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/Multi.qml b/FileSets/v3.40~29/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v3.40~29/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/ObjectAcConnection.qml b/FileSets/v3.40~29/ObjectAcConnection.qml deleted file mode 120000 index cab7f2d4..00000000 --- a/FileSets/v3.40~29/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~29/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 6d1e56b5..00000000 --- a/FileSets/v3.40~29/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/OverviewBox.qml b/FileSets/v3.40~29/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v3.40~29/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/OverviewConnection.qml b/FileSets/v3.40~29/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v3.40~29/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/OverviewConnectionEnd.qml b/FileSets/v3.40~29/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v3.40~29/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/OverviewFlowComplex.qml b/FileSets/v3.40~29/OverviewFlowComplex.qml deleted file mode 120000 index a151db4f..00000000 --- a/FileSets/v3.40~29/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~29/OverviewGeneratorEnhanced.qml deleted file mode 120000 index 3bf44cf5..00000000 --- a/FileSets/v3.40~29/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~29/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index 1c9b530f..00000000 --- a/FileSets/v3.40~29/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/OverviewGridParallel.qml b/FileSets/v3.40~29/OverviewGridParallel.qml deleted file mode 120000 index d30a27d7..00000000 --- a/FileSets/v3.40~29/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/OverviewHub.qml b/FileSets/v3.40~29/OverviewHub.qml deleted file mode 120000 index 93c6ee1a..00000000 --- a/FileSets/v3.40~29/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/OverviewHubEnhanced.qml b/FileSets/v3.40~29/OverviewHubEnhanced.qml deleted file mode 120000 index c55515d9..00000000 --- a/FileSets/v3.40~29/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/OverviewMobileEnhanced.qml b/FileSets/v3.40~29/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.40~29/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/OverviewSolarCharger.qml b/FileSets/v3.40~29/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v3.40~29/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/OverviewSolarInverter.qml b/FileSets/v3.40~29/OverviewSolarInverter.qml deleted file mode 120000 index 4048703e..00000000 --- a/FileSets/v3.40~29/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/OverviewTankDelegate.qml b/FileSets/v3.40~29/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v3.40~29/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/OverviewTanks.qml b/FileSets/v3.40~29/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v3.40~29/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~29/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.40~29/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/PageDigitalInput.qml b/FileSets/v3.40~29/PageDigitalInput.qml deleted file mode 120000 index 5b768f8f..00000000 --- a/FileSets/v3.40~29/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/PageGenerator.qml b/FileSets/v3.40~29/PageGenerator.qml deleted file mode 120000 index 4ff1c509..00000000 --- a/FileSets/v3.40~29/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/PageMain.qml b/FileSets/v3.40~29/PageMain.qml deleted file mode 120000 index ef4b9c47..00000000 --- a/FileSets/v3.40~29/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/PageSettingsDisplay.qml b/FileSets/v3.40~29/PageSettingsDisplay.qml deleted file mode 120000 index 03766d99..00000000 --- a/FileSets/v3.40~29/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/PageSettingsGenerator.qml b/FileSets/v3.40~29/PageSettingsGenerator.qml deleted file mode 120000 index 15dd8f85..00000000 --- a/FileSets/v3.40~29/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/PageSettingsGuiMods.qml b/FileSets/v3.40~29/PageSettingsGuiMods.qml deleted file mode 120000 index e831a7a4..00000000 --- a/FileSets/v3.40~29/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/PageSettingsRelay.qml b/FileSets/v3.40~29/PageSettingsRelay.qml deleted file mode 120000 index 156aadac..00000000 --- a/FileSets/v3.40~29/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/PowerGauge.qml b/FileSets/v3.40~29/PowerGauge.qml deleted file mode 120000 index 4bcaaa4a..00000000 --- a/FileSets/v3.40~29/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/Tile.qml b/FileSets/v3.40~29/Tile.qml deleted file mode 120000 index 0558cecf..00000000 --- a/FileSets/v3.40~29/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/TileDigIn.qml b/FileSets/v3.40~29/TileDigIn.qml deleted file mode 120000 index 44616f30..00000000 --- a/FileSets/v3.40~29/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/TileRelay.qml b/FileSets/v3.40~29/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.40~29/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/TileText.qml b/FileSets/v3.40~29/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v3.40~29/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/attributes.csv b/FileSets/v3.40~29/attributes.csv deleted file mode 120000 index 6e1ceaae..00000000 --- a/FileSets/v3.40~29/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v3.40~32/attributes.csv \ No newline at end of file diff --git a/FileSets/v3.40~29/dbus_digitalinputs.py b/FileSets/v3.40~29/dbus_digitalinputs.py deleted file mode 120000 index e74da5b6..00000000 --- a/FileSets/v3.40~29/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.40~29/dbus_generator.py b/FileSets/v3.40~29/dbus_generator.py deleted file mode 120000 index 0cd84ca3..00000000 --- a/FileSets/v3.40~29/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.40~29/main.qml b/FileSets/v3.40~29/main.qml deleted file mode 120000 index 5dbfdf83..00000000 --- a/FileSets/v3.40~29/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/main.qml \ No newline at end of file diff --git a/FileSets/v3.40~29/startstop.py b/FileSets/v3.40~29/startstop.py deleted file mode 120000 index c18bce2d..00000000 --- a/FileSets/v3.40~29/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~37/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~29/styles.css b/FileSets/v3.40~29/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v3.40~29/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v3.40~30/Battery.qml b/FileSets/v3.40~30/Battery.qml deleted file mode 120000 index fafc7b36..00000000 --- a/FileSets/v3.40~30/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/COMPLETE b/FileSets/v3.40~30/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~30/DetailAcInput.qml b/FileSets/v3.40~30/DetailAcInput.qml deleted file mode 120000 index 8e76794d..00000000 --- a/FileSets/v3.40~30/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/DetailInverter.qml b/FileSets/v3.40~30/DetailInverter.qml deleted file mode 120000 index 285b3216..00000000 --- a/FileSets/v3.40~30/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/DetailLoadsCombined.qml b/FileSets/v3.40~30/DetailLoadsCombined.qml deleted file mode 120000 index 81c6de5a..00000000 --- a/FileSets/v3.40~30/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/DetailLoadsOnInput.qml b/FileSets/v3.40~30/DetailLoadsOnInput.qml deleted file mode 120000 index a5f97488..00000000 --- a/FileSets/v3.40~30/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/DetailLoadsOnOutput.qml b/FileSets/v3.40~30/DetailLoadsOnOutput.qml deleted file mode 120000 index 7cfc98c6..00000000 --- a/FileSets/v3.40~30/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/HubData.qml b/FileSets/v3.40~30/HubData.qml deleted file mode 120000 index c80a3bff..00000000 --- a/FileSets/v3.40~30/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/LINKS_ONLY b/FileSets/v3.40~30/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~30/MbEditBox.qml b/FileSets/v3.40~30/MbEditBox.qml deleted file mode 120000 index 90a92492..00000000 --- a/FileSets/v3.40~30/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/MbEditBoxDateTime.qml b/FileSets/v3.40~30/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v3.40~30/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/MbItem.qml b/FileSets/v3.40~30/MbItem.qml deleted file mode 120000 index 048a313c..00000000 --- a/FileSets/v3.40~30/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/MbItemDigitalInput.qml b/FileSets/v3.40~30/MbItemDigitalInput.qml deleted file mode 120000 index 4404b520..00000000 --- a/FileSets/v3.40~30/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/MbSpinBox.qml b/FileSets/v3.40~30/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v3.40~30/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/MbStyle.qml b/FileSets/v3.40~30/MbStyle.qml deleted file mode 120000 index d1940446..00000000 --- a/FileSets/v3.40~30/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/MbSubMenu.qml b/FileSets/v3.40~30/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v3.40~30/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/Multi.qml b/FileSets/v3.40~30/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v3.40~30/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/ObjectAcConnection.qml b/FileSets/v3.40~30/ObjectAcConnection.qml deleted file mode 120000 index cab7f2d4..00000000 --- a/FileSets/v3.40~30/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~30/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 6d1e56b5..00000000 --- a/FileSets/v3.40~30/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/OverviewBox.qml b/FileSets/v3.40~30/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v3.40~30/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/OverviewConnection.qml b/FileSets/v3.40~30/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v3.40~30/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/OverviewConnectionEnd.qml b/FileSets/v3.40~30/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v3.40~30/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/OverviewFlowComplex.qml b/FileSets/v3.40~30/OverviewFlowComplex.qml deleted file mode 120000 index a151db4f..00000000 --- a/FileSets/v3.40~30/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~30/OverviewGeneratorEnhanced.qml deleted file mode 120000 index 3bf44cf5..00000000 --- a/FileSets/v3.40~30/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~30/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index 1c9b530f..00000000 --- a/FileSets/v3.40~30/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/OverviewGridParallel.qml b/FileSets/v3.40~30/OverviewGridParallel.qml deleted file mode 120000 index d30a27d7..00000000 --- a/FileSets/v3.40~30/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/OverviewHub.qml b/FileSets/v3.40~30/OverviewHub.qml deleted file mode 120000 index 93c6ee1a..00000000 --- a/FileSets/v3.40~30/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/OverviewHubEnhanced.qml b/FileSets/v3.40~30/OverviewHubEnhanced.qml deleted file mode 120000 index c55515d9..00000000 --- a/FileSets/v3.40~30/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/OverviewMobileEnhanced.qml b/FileSets/v3.40~30/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.40~30/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/OverviewSolarCharger.qml b/FileSets/v3.40~30/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v3.40~30/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/OverviewSolarInverter.qml b/FileSets/v3.40~30/OverviewSolarInverter.qml deleted file mode 120000 index 4048703e..00000000 --- a/FileSets/v3.40~30/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/OverviewTankDelegate.qml b/FileSets/v3.40~30/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v3.40~30/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/OverviewTanks.qml b/FileSets/v3.40~30/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v3.40~30/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~30/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.40~30/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/PageDigitalInput.qml b/FileSets/v3.40~30/PageDigitalInput.qml deleted file mode 120000 index 5b768f8f..00000000 --- a/FileSets/v3.40~30/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/PageGenerator.qml b/FileSets/v3.40~30/PageGenerator.qml deleted file mode 120000 index 4ff1c509..00000000 --- a/FileSets/v3.40~30/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/PageMain.qml b/FileSets/v3.40~30/PageMain.qml deleted file mode 120000 index ef4b9c47..00000000 --- a/FileSets/v3.40~30/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/PageSettingsDisplay.qml b/FileSets/v3.40~30/PageSettingsDisplay.qml deleted file mode 120000 index 03766d99..00000000 --- a/FileSets/v3.40~30/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/PageSettingsGenerator.qml b/FileSets/v3.40~30/PageSettingsGenerator.qml deleted file mode 120000 index 15dd8f85..00000000 --- a/FileSets/v3.40~30/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/PageSettingsGuiMods.qml b/FileSets/v3.40~30/PageSettingsGuiMods.qml deleted file mode 120000 index e831a7a4..00000000 --- a/FileSets/v3.40~30/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/PageSettingsRelay.qml b/FileSets/v3.40~30/PageSettingsRelay.qml deleted file mode 120000 index 156aadac..00000000 --- a/FileSets/v3.40~30/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/PowerGauge.qml b/FileSets/v3.40~30/PowerGauge.qml deleted file mode 120000 index 4bcaaa4a..00000000 --- a/FileSets/v3.40~30/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/Tile.qml b/FileSets/v3.40~30/Tile.qml deleted file mode 120000 index 0558cecf..00000000 --- a/FileSets/v3.40~30/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/TileDigIn.qml b/FileSets/v3.40~30/TileDigIn.qml deleted file mode 120000 index 44616f30..00000000 --- a/FileSets/v3.40~30/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/TileRelay.qml b/FileSets/v3.40~30/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.40~30/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/TileText.qml b/FileSets/v3.40~30/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v3.40~30/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/attributes.csv b/FileSets/v3.40~30/attributes.csv deleted file mode 120000 index 6e1ceaae..00000000 --- a/FileSets/v3.40~30/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v3.40~32/attributes.csv \ No newline at end of file diff --git a/FileSets/v3.40~30/dbus_digitalinputs.py b/FileSets/v3.40~30/dbus_digitalinputs.py deleted file mode 120000 index e74da5b6..00000000 --- a/FileSets/v3.40~30/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.40~30/dbus_generator.py b/FileSets/v3.40~30/dbus_generator.py deleted file mode 120000 index 0cd84ca3..00000000 --- a/FileSets/v3.40~30/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.40~30/main.qml b/FileSets/v3.40~30/main.qml deleted file mode 120000 index 5dbfdf83..00000000 --- a/FileSets/v3.40~30/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/main.qml \ No newline at end of file diff --git a/FileSets/v3.40~30/startstop.py b/FileSets/v3.40~30/startstop.py deleted file mode 120000 index c18bce2d..00000000 --- a/FileSets/v3.40~30/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~37/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~30/styles.css b/FileSets/v3.40~30/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v3.40~30/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v3.40~32/Battery.qml b/FileSets/v3.40~32/Battery.qml deleted file mode 120000 index fafc7b36..00000000 --- a/FileSets/v3.40~32/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/COMPLETE b/FileSets/v3.40~32/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~32/DetailAcInput.qml b/FileSets/v3.40~32/DetailAcInput.qml deleted file mode 120000 index 8e76794d..00000000 --- a/FileSets/v3.40~32/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/DetailInverter.qml b/FileSets/v3.40~32/DetailInverter.qml deleted file mode 120000 index 285b3216..00000000 --- a/FileSets/v3.40~32/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/DetailLoadsCombined.qml b/FileSets/v3.40~32/DetailLoadsCombined.qml deleted file mode 120000 index 81c6de5a..00000000 --- a/FileSets/v3.40~32/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/DetailLoadsOnInput.qml b/FileSets/v3.40~32/DetailLoadsOnInput.qml deleted file mode 120000 index a5f97488..00000000 --- a/FileSets/v3.40~32/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/DetailLoadsOnOutput.qml b/FileSets/v3.40~32/DetailLoadsOnOutput.qml deleted file mode 120000 index 7cfc98c6..00000000 --- a/FileSets/v3.40~32/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/HubData.qml b/FileSets/v3.40~32/HubData.qml deleted file mode 120000 index c80a3bff..00000000 --- a/FileSets/v3.40~32/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/LINKS_ONLY b/FileSets/v3.40~32/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~32/MbEditBox.qml b/FileSets/v3.40~32/MbEditBox.qml deleted file mode 120000 index 90a92492..00000000 --- a/FileSets/v3.40~32/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/MbEditBoxDateTime.qml b/FileSets/v3.40~32/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v3.40~32/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/MbItem.qml b/FileSets/v3.40~32/MbItem.qml deleted file mode 120000 index 048a313c..00000000 --- a/FileSets/v3.40~32/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/MbItemDigitalInput.qml b/FileSets/v3.40~32/MbItemDigitalInput.qml deleted file mode 120000 index 4404b520..00000000 --- a/FileSets/v3.40~32/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/MbSpinBox.qml b/FileSets/v3.40~32/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v3.40~32/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/MbStyle.qml b/FileSets/v3.40~32/MbStyle.qml deleted file mode 120000 index d1940446..00000000 --- a/FileSets/v3.40~32/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/MbSubMenu.qml b/FileSets/v3.40~32/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v3.40~32/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/Multi.qml b/FileSets/v3.40~32/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v3.40~32/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/ObjectAcConnection.qml b/FileSets/v3.40~32/ObjectAcConnection.qml deleted file mode 120000 index cab7f2d4..00000000 --- a/FileSets/v3.40~32/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~32/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 6d1e56b5..00000000 --- a/FileSets/v3.40~32/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/OverviewBox.qml b/FileSets/v3.40~32/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v3.40~32/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/OverviewConnection.qml b/FileSets/v3.40~32/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v3.40~32/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/OverviewConnectionEnd.qml b/FileSets/v3.40~32/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v3.40~32/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/OverviewFlowComplex.qml b/FileSets/v3.40~32/OverviewFlowComplex.qml deleted file mode 120000 index a151db4f..00000000 --- a/FileSets/v3.40~32/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~32/OverviewGeneratorEnhanced.qml deleted file mode 120000 index 3bf44cf5..00000000 --- a/FileSets/v3.40~32/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~32/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index 1c9b530f..00000000 --- a/FileSets/v3.40~32/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/OverviewGridParallel.qml b/FileSets/v3.40~32/OverviewGridParallel.qml deleted file mode 120000 index d30a27d7..00000000 --- a/FileSets/v3.40~32/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/OverviewHub.qml b/FileSets/v3.40~32/OverviewHub.qml deleted file mode 120000 index 93c6ee1a..00000000 --- a/FileSets/v3.40~32/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/OverviewHubEnhanced.qml b/FileSets/v3.40~32/OverviewHubEnhanced.qml deleted file mode 120000 index c55515d9..00000000 --- a/FileSets/v3.40~32/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/OverviewMobileEnhanced.qml b/FileSets/v3.40~32/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.40~32/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/OverviewSolarCharger.qml b/FileSets/v3.40~32/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v3.40~32/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/OverviewSolarInverter.qml b/FileSets/v3.40~32/OverviewSolarInverter.qml deleted file mode 120000 index 4048703e..00000000 --- a/FileSets/v3.40~32/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/OverviewTankDelegate.qml b/FileSets/v3.40~32/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v3.40~32/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/OverviewTanks.qml b/FileSets/v3.40~32/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v3.40~32/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~32/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.40~32/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/PageDigitalInput.qml b/FileSets/v3.40~32/PageDigitalInput.qml deleted file mode 120000 index 5b768f8f..00000000 --- a/FileSets/v3.40~32/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/PageGenerator.qml b/FileSets/v3.40~32/PageGenerator.qml deleted file mode 120000 index 4ff1c509..00000000 --- a/FileSets/v3.40~32/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/PageMain.qml b/FileSets/v3.40~32/PageMain.qml deleted file mode 120000 index ef4b9c47..00000000 --- a/FileSets/v3.40~32/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/PageSettingsDisplay.qml b/FileSets/v3.40~32/PageSettingsDisplay.qml deleted file mode 120000 index 03766d99..00000000 --- a/FileSets/v3.40~32/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/PageSettingsGenerator.qml b/FileSets/v3.40~32/PageSettingsGenerator.qml deleted file mode 120000 index 15dd8f85..00000000 --- a/FileSets/v3.40~32/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/PageSettingsGuiMods.qml b/FileSets/v3.40~32/PageSettingsGuiMods.qml deleted file mode 120000 index e831a7a4..00000000 --- a/FileSets/v3.40~32/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/PageSettingsRelay.qml b/FileSets/v3.40~32/PageSettingsRelay.qml deleted file mode 120000 index 156aadac..00000000 --- a/FileSets/v3.40~32/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/PowerGauge.qml b/FileSets/v3.40~32/PowerGauge.qml deleted file mode 120000 index 4bcaaa4a..00000000 --- a/FileSets/v3.40~32/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/Tile.qml b/FileSets/v3.40~32/Tile.qml deleted file mode 120000 index 0558cecf..00000000 --- a/FileSets/v3.40~32/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/TileDigIn.qml b/FileSets/v3.40~32/TileDigIn.qml deleted file mode 120000 index 44616f30..00000000 --- a/FileSets/v3.40~32/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/TileRelay.qml b/FileSets/v3.40~32/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.40~32/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/TileText.qml b/FileSets/v3.40~32/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v3.40~32/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/dbus_digitalinputs.py b/FileSets/v3.40~32/dbus_digitalinputs.py deleted file mode 120000 index e74da5b6..00000000 --- a/FileSets/v3.40~32/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.40~32/dbus_generator.py b/FileSets/v3.40~32/dbus_generator.py deleted file mode 120000 index 0cd84ca3..00000000 --- a/FileSets/v3.40~32/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.40~32/dbus_systemcalc.py b/FileSets/v3.40~32/dbus_systemcalc.py deleted file mode 120000 index 1632ef7b..00000000 --- a/FileSets/v3.40~32/dbus_systemcalc.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~33/dbus_systemcalc.py \ No newline at end of file diff --git a/FileSets/v3.40~32/main.qml b/FileSets/v3.40~32/main.qml deleted file mode 120000 index 5dbfdf83..00000000 --- a/FileSets/v3.40~32/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/main.qml \ No newline at end of file diff --git a/FileSets/v3.40~32/startstop.py b/FileSets/v3.40~32/startstop.py deleted file mode 120000 index c18bce2d..00000000 --- a/FileSets/v3.40~32/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~37/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~32/styles.css b/FileSets/v3.40~32/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v3.40~32/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v3.40~33/Battery.qml b/FileSets/v3.40~33/Battery.qml deleted file mode 120000 index fafc7b36..00000000 --- a/FileSets/v3.40~33/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/COMPLETE b/FileSets/v3.40~33/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~33/DetailAcInput.qml b/FileSets/v3.40~33/DetailAcInput.qml deleted file mode 120000 index 8e76794d..00000000 --- a/FileSets/v3.40~33/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/DetailInverter.qml b/FileSets/v3.40~33/DetailInverter.qml deleted file mode 120000 index 285b3216..00000000 --- a/FileSets/v3.40~33/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/DetailLoadsCombined.qml b/FileSets/v3.40~33/DetailLoadsCombined.qml deleted file mode 120000 index 81c6de5a..00000000 --- a/FileSets/v3.40~33/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/DetailLoadsOnInput.qml b/FileSets/v3.40~33/DetailLoadsOnInput.qml deleted file mode 120000 index a5f97488..00000000 --- a/FileSets/v3.40~33/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/DetailLoadsOnOutput.qml b/FileSets/v3.40~33/DetailLoadsOnOutput.qml deleted file mode 120000 index 7cfc98c6..00000000 --- a/FileSets/v3.40~33/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/HubData.qml b/FileSets/v3.40~33/HubData.qml deleted file mode 120000 index c80a3bff..00000000 --- a/FileSets/v3.40~33/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/LINKS_ONLY b/FileSets/v3.40~33/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~33/MbEditBox.qml b/FileSets/v3.40~33/MbEditBox.qml deleted file mode 120000 index 90a92492..00000000 --- a/FileSets/v3.40~33/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/MbEditBoxDateTime.qml b/FileSets/v3.40~33/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v3.40~33/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/MbItem.qml b/FileSets/v3.40~33/MbItem.qml deleted file mode 120000 index 048a313c..00000000 --- a/FileSets/v3.40~33/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/MbItemDigitalInput.qml b/FileSets/v3.40~33/MbItemDigitalInput.qml deleted file mode 120000 index 4404b520..00000000 --- a/FileSets/v3.40~33/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/MbSpinBox.qml b/FileSets/v3.40~33/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v3.40~33/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/MbStyle.qml b/FileSets/v3.40~33/MbStyle.qml deleted file mode 120000 index d1940446..00000000 --- a/FileSets/v3.40~33/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/MbSubMenu.qml b/FileSets/v3.40~33/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v3.40~33/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/Multi.qml b/FileSets/v3.40~33/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v3.40~33/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/ObjectAcConnection.qml b/FileSets/v3.40~33/ObjectAcConnection.qml deleted file mode 120000 index cab7f2d4..00000000 --- a/FileSets/v3.40~33/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~33/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 6d1e56b5..00000000 --- a/FileSets/v3.40~33/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/OverviewBox.qml b/FileSets/v3.40~33/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v3.40~33/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/OverviewConnection.qml b/FileSets/v3.40~33/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v3.40~33/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/OverviewConnectionEnd.qml b/FileSets/v3.40~33/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v3.40~33/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/OverviewFlowComplex.qml b/FileSets/v3.40~33/OverviewFlowComplex.qml deleted file mode 120000 index a151db4f..00000000 --- a/FileSets/v3.40~33/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~33/OverviewGeneratorEnhanced.qml deleted file mode 120000 index 3bf44cf5..00000000 --- a/FileSets/v3.40~33/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~33/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index 1c9b530f..00000000 --- a/FileSets/v3.40~33/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/OverviewGridParallel.qml b/FileSets/v3.40~33/OverviewGridParallel.qml deleted file mode 120000 index d30a27d7..00000000 --- a/FileSets/v3.40~33/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/OverviewHub.qml b/FileSets/v3.40~33/OverviewHub.qml deleted file mode 120000 index 93c6ee1a..00000000 --- a/FileSets/v3.40~33/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/OverviewHubEnhanced.qml b/FileSets/v3.40~33/OverviewHubEnhanced.qml deleted file mode 120000 index c55515d9..00000000 --- a/FileSets/v3.40~33/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/OverviewMobileEnhanced.qml b/FileSets/v3.40~33/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.40~33/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/OverviewSolarCharger.qml b/FileSets/v3.40~33/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v3.40~33/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/OverviewSolarInverter.qml b/FileSets/v3.40~33/OverviewSolarInverter.qml deleted file mode 120000 index 4048703e..00000000 --- a/FileSets/v3.40~33/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/OverviewTankDelegate.qml b/FileSets/v3.40~33/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v3.40~33/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/OverviewTanks.qml b/FileSets/v3.40~33/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v3.40~33/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~33/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.40~33/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/PageDigitalInput.qml b/FileSets/v3.40~33/PageDigitalInput.qml deleted file mode 120000 index 5b768f8f..00000000 --- a/FileSets/v3.40~33/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/PageGenerator.qml b/FileSets/v3.40~33/PageGenerator.qml deleted file mode 120000 index 4ff1c509..00000000 --- a/FileSets/v3.40~33/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/PageMain.qml b/FileSets/v3.40~33/PageMain.qml deleted file mode 120000 index ef4b9c47..00000000 --- a/FileSets/v3.40~33/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/PageSettingsDisplay.qml b/FileSets/v3.40~33/PageSettingsDisplay.qml deleted file mode 120000 index 03766d99..00000000 --- a/FileSets/v3.40~33/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/PageSettingsGenerator.qml b/FileSets/v3.40~33/PageSettingsGenerator.qml deleted file mode 120000 index 15dd8f85..00000000 --- a/FileSets/v3.40~33/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/PageSettingsGuiMods.qml b/FileSets/v3.40~33/PageSettingsGuiMods.qml deleted file mode 120000 index e831a7a4..00000000 --- a/FileSets/v3.40~33/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/PageSettingsRelay.qml b/FileSets/v3.40~33/PageSettingsRelay.qml deleted file mode 120000 index 156aadac..00000000 --- a/FileSets/v3.40~33/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/PowerGauge.qml b/FileSets/v3.40~33/PowerGauge.qml deleted file mode 120000 index 4bcaaa4a..00000000 --- a/FileSets/v3.40~33/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/Tile.qml b/FileSets/v3.40~33/Tile.qml deleted file mode 120000 index 0558cecf..00000000 --- a/FileSets/v3.40~33/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/TileDigIn.qml b/FileSets/v3.40~33/TileDigIn.qml deleted file mode 120000 index 44616f30..00000000 --- a/FileSets/v3.40~33/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/TileRelay.qml b/FileSets/v3.40~33/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.40~33/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/TileText.qml b/FileSets/v3.40~33/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v3.40~33/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/attributes.csv.orig b/FileSets/v3.40~33/attributes.csv.orig deleted file mode 100644 index a68d0532..00000000 --- a/FileSets/v3.40~33/attributes.csv.orig +++ /dev/null @@ -1,740 +0,0 @@ -com.victronenergy.gps,/Position/Latitude,d,Decimal degrees,2800,int32,10000000,R -com.victronenergy.gps,/Position/Longitude,d,Decimal degrees,2802,int32,10000000,R -com.victronenergy.gps,/Course,d,Degrees,2804,uint16,100,R -com.victronenergy.gps,/Speed,d,m/s,2805,uint16,100,R -com.victronenergy.gps,/Fix,y,,2806,uint16,1,R -com.victronenergy.gps,/NrOfSatellites,y,,2807,uint16,1,R -com.victronenergy.gps,/Altitude,d,m,2808,int32,10,R -com.victronenergy.settings,/Settings/CGwacs/BatteryLife/State,i,0=BL disabled;1=Restarting;2=Self-consumption;3=Self-consumption;4=Self-consumption;5=Discharge disabled;6=Force charge;7=Sustain;9=Keep batteries charged;10=BL Disabled;11=BL Disabled (Low SoC),2900,uint16,1,W -com.victronenergy.settings,/Settings/CGwacs/BatteryLife/MinimumSocLimit,d,%,2901,uint16,10,W -com.victronenergy.settings,/Settings/CGwacs/Hub4Mode,i,1=ESS with Phase Compensation;2=ESS without phase compensation;3=Disabled/External Control,2902,uint16,1,W -com.victronenergy.settings,/Settings/CGwacs/BatteryLife/SocLimit,d,%,2903,uint16,10,R -com.victronenergy.vebus,/Ac/ActiveIn/L1/V,d,V AC,3,uint16,10,R -com.victronenergy.vebus,/Ac/ActiveIn/L2/V,d,V AC,4,uint16,10,R -com.victronenergy.vebus,/Ac/ActiveIn/L3/V,d,V AC,5,uint16,10,R -com.victronenergy.vebus,/Ac/ActiveIn/L1/I,d,A AC,6,int16,10,R -com.victronenergy.vebus,/Ac/ActiveIn/L2/I,d,A AC,7,int16,10,R -com.victronenergy.vebus,/Ac/ActiveIn/L3/I,d,A AC,8,int16,10,R -com.victronenergy.vebus,/Ac/ActiveIn/L1/F,d,Hz,9,int16,100,R -com.victronenergy.vebus,/Ac/ActiveIn/L2/F,d,Hz,10,int16,100,R -com.victronenergy.vebus,/Ac/ActiveIn/L3/F,d,Hz,11,int16,100,R -com.victronenergy.vebus,/Ac/ActiveIn/L1/P,i,VA or Watts,12,int16,0.1,R -com.victronenergy.vebus,/Ac/ActiveIn/L2/P,i,VA or Watts,13,int16,0.1,R -com.victronenergy.vebus,/Ac/ActiveIn/L3/P,i,VA or Watts,14,int16,0.1,R -com.victronenergy.vebus,/Ac/Out/L1/V,d,V AC,15,uint16,10,R -com.victronenergy.vebus,/Ac/Out/L2/V,d,V AC,16,uint16,10,R -com.victronenergy.vebus,/Ac/Out/L3/V,d,V AC,17,uint16,10,R -com.victronenergy.vebus,/Ac/Out/L1/I,d,A AC,18,int16,10,R -com.victronenergy.vebus,/Ac/Out/L2/I,d,A AC,19,int16,10,R -com.victronenergy.vebus,/Ac/Out/L3/I,d,A AC,20,int16,10,R -com.victronenergy.vebus,/Ac/Out/L1/F,d,Hz,21,int16,100,R -com.victronenergy.vebus,/Ac/ActiveIn/CurrentLimit,d,A,22,int16,10,W -com.victronenergy.vebus,/Ac/Out/L1/P,i,VA or Watts,23,int16,0.1,R -com.victronenergy.vebus,/Ac/Out/L2/P,i,VA or Watts,24,int16,0.1,R -com.victronenergy.vebus,/Ac/Out/L3/P,i,VA or Watts,25,int16,0.1,R -com.victronenergy.vebus,/Dc/0/Voltage,d,V DC,26,uint16,100,R -com.victronenergy.vebus,/Dc/0/Current,d,A DC,27,int16,10,R -com.victronenergy.vebus,/Ac/NumberOfPhases,u,count,28,uint16,1,R -com.victronenergy.vebus,/Ac/ActiveIn/ActiveInput,u,0=AC Input 1;1=AC Input 2;240=Disconnected,29,uint16,1,R -com.victronenergy.vebus,/Soc,d,%,30,uint16,10,W -com.victronenergy.vebus,/State,u,0=Off;1=Low Power;2=Fault;3=Bulk;4=Absorption;5=Float;6=Storage;7=Equalize;8=Passthru;9=Inverting;10=Power assist;11=Power supply;252=External control,31,uint16,1,R -com.victronenergy.vebus,/VebusError,u,0=No error;1=VE.Bus Error 1: Device is switched off because one of the other phases in the system has switched off;2=VE.Bus Error 2: New and old types MK2 are mixed in the system;3=VE.Bus Error 3: Not all- or more than- the expected devices were found in the system;4=VE.Bus Error 4: No other device whatsoever detected;5=VE.Bus Error 5: Overvoltage on AC-out;6=VE.Bus Error 6: Error in DDC Program;7=VE.Bus BMS connected- which requires an Assistant- but no assistant found;10=VE.Bus Error 10: System time synchronisation problem occurred;14=VE.Bus Error 14: Device cannot transmit data;16=VE.Bus Error 16: Dongle missing;17=VE.Bus Error 17: One of the devices assumed master status because the original master failed;18=VE.Bus Error 18: AC Overvoltage on the output of a slave has occurred while already switched off;22=VE.Bus Error 22: This device cannot function as slave;24=VE.Bus Error 24: Switch-over system protection initiated;25=VE.Bus Error 25: Firmware incompatibility. The firmware of one of the connected device is not sufficiently up to date to operate in conjunction with this device;26=VE.Bus Error 26: Internal error,32,uint16,1,R -com.victronenergy.vebus,/Mode,u,1=Charger Only;2=Inverter Only;3=On;4=Off,33,uint16,1,W -com.victronenergy.vebus,/Alarms/HighTemperature,u,0=Ok;1=Warning;2=Alarm,34,uint16,1,R -com.victronenergy.vebus,/Alarms/LowBattery,u,0=Ok;1=Warning;2=Alarm,35,uint16,1,R -com.victronenergy.vebus,/Alarms/Overload,u,0=Ok;1=Warning;2=Alarm,36,uint16,1,R -com.victronenergy.vebus,/Alarms/TemperatureSensor,u,0=Ok;1=Warning;2=Alarm,42,uint16,1,R -com.victronenergy.vebus,/Alarms/VoltageSensor,u,0=Ok;1=Warning;2=Alarm,43,uint16,1,R -com.victronenergy.vebus,/Alarms/L1/HighTemperature,u,0=Ok;1=Warning;2=Alarm,44,uint16,1,R -com.victronenergy.vebus,/Alarms/L1/LowBattery,u,0=Ok;1=Warning;2=Alarm,45,uint16,1,R -com.victronenergy.vebus,/Alarms/L1/Overload,u,0=Ok;1=Warning;2=Alarm,46,uint16,1,R -com.victronenergy.vebus,/Alarms/L1/Ripple,u,0=Ok;1=Warning;2=Alarm,47,uint16,1,R -com.victronenergy.vebus,/Alarms/L2/HighTemperature,u,0=Ok;1=Warning;2=Alarm,48,uint16,1,R -com.victronenergy.vebus,/Alarms/L2/LowBattery,u,0=Ok;1=Warning;2=Alarm,49,uint16,1,R -com.victronenergy.vebus,/Alarms/L2/Overload,u,0=Ok;1=Warning;2=Alarm,50,uint16,1,R -com.victronenergy.vebus,/Alarms/L2/Ripple,u,0=Ok;1=Warning;2=Alarm,51,uint16,1,R -com.victronenergy.vebus,/Alarms/L3/HighTemperature,u,0=Ok;1=Warning;2=Alarm,52,uint16,1,R -com.victronenergy.vebus,/Alarms/L3/LowBattery,u,0=Ok;1=Warning;2=Alarm,53,uint16,1,R -com.victronenergy.vebus,/Alarms/L3/Overload,u,0=Ok;1=Warning;2=Alarm,54,uint16,1,R -com.victronenergy.vebus,/Alarms/L3/Ripple,u,0=Ok;1=Warning;2=Alarm,55,uint16,1,R -com.victronenergy.vebus,/Hub4/L1/AcPowerSetpoint,d,W,37,int16,1,W -com.victronenergy.vebus,/Hub4/DisableCharge,u,0=Charge allowed;1=Charge disabled,38,uint16,1,W -com.victronenergy.vebus,/Hub4/DisableFeedIn,u,0=Feed in allowed;1=Feed in disabled,39,uint16,1,W -com.victronenergy.vebus,/Hub4/L2/AcPowerSetpoint,d,W,40,int16,1,W -com.victronenergy.vebus,/Hub4/L3/AcPowerSetpoint,d,W,41,int16,1,W -com.victronenergy.vebus,/PvInverter/Disable,u,0=PV enabled;1=PV disabled,56,uint16,1,W -com.victronenergy.vebus,/Bms/AllowToCharge,u,0=No;1=Yes,57,uint16,1,R -com.victronenergy.vebus,/Bms/AllowToDischarge,u,0=No;1=Yes,58,uint16,1,R -com.victronenergy.vebus,/Bms/BmsExpected,u,0=No;1=Yes,59,uint16,1,R -com.victronenergy.vebus,/Bms/Error,u,0=No;1=Yes,60,uint16,1,R -com.victronenergy.vebus,/Dc/0/Temperature,d,Degrees celsius,61,int16,10,R -com.victronenergy.vebus,/SystemReset,y,0=No action;1=VE.Bus Reset,62,uint16,1,W -com.victronenergy.vebus,/Alarms/PhaseRotation,u,0=Ok;1=Warning,63,uint16,1,R -com.victronenergy.vebus,/Alarms/GridLost,i,0=No alarm;2=Alarm,64,uint16,1,R -com.victronenergy.vebus,/Alarms/BmsPreAlarm,u,0=OK;1=Pre-Alarm,94,uint16,1,R -com.victronenergy.vebus,/Hub4/DoNotFeedInOvervoltage,i,0=Feed in overvoltage;1=Don't feed in overvoltage,65,uint16,1,W -com.victronenergy.vebus,/Hub4/L1/MaxFeedInPower,d,W,66,uint16,0.01,W -com.victronenergy.vebus,/Hub4/L2/MaxFeedInPower,d,W,67,uint16,0.01,W -com.victronenergy.vebus,/Hub4/L3/MaxFeedInPower,d,W,68,uint16,0.01,W -com.victronenergy.vebus,/Ac/State/IgnoreAcIn1,i,0=AC input not ignored; 1=AC input ignored,69,uint16,1,R -com.victronenergy.vebus,/Ac/State/IgnoreAcIn2,i,0=AC input not ignored; 1=AC input ignored,70,uint16,1,R -com.victronenergy.vebus,/Hub4/TargetPowerIsMaxFeedIn,i,0=AcPowerSetpoint interpreted normally; 1=AcPowerSetpoint as OvervoltageFeedIn limit,71,uint16,,W -com.victronenergy.vebus,/Hub4/FixSolarOffsetTo100mV,i,0=OvervoltageFeedIn uses 1V offset; 1=OvervoltageFeedIn uses 0.1V offset,72,uint16,,W -com.victronenergy.vebus,/Hub4/Sustain,i,0=Sustain inactive; 1=Sustain active,73,uint16,1,R -com.victronenergy.vebus,/Energy/AcIn1ToAcOut,d,kWh,74,uint32,100,R -com.victronenergy.vebus,/Energy/AcIn1ToInverter,d,kWh,76,uint32,100,R -com.victronenergy.vebus,/Energy/AcIn2ToAcOut,d,kWh,78,uint32,100,R -com.victronenergy.vebus,/Energy/AcIn2ToInverter,d,kWh,80,uint32,100,R -com.victronenergy.vebus,/Energy/AcOutToAcIn1,d,kWh,82,uint32,100,R -com.victronenergy.vebus,/Energy/AcOutToAcIn2,d,kWh,84,uint32,100,R -com.victronenergy.vebus,/Energy/InverterToAcIn1,d,kWh,86,uint32,100,R -com.victronenergy.vebus,/Energy/InverterToAcIn2,d,kWh,88,uint32,100,R -com.victronenergy.vebus,/Energy/InverterToAcOut,d,kWh,90,uint32,100,R -com.victronenergy.vebus,/Energy/OutToInverter,d,kWh,92,uint32,100,R -com.victronenergy.vebus,/VebusChargeState,u,0=Initialising;1=Bulk;2=Absorption;3=Float;4=Storage;5=Absorb repeat;6=Forced absorb;7=Equalise;8=Bulk stopped;9=Unknown,95,uint16,1,R -com.victronenergy.vebus,/Hub4/L1/AcPowerSetpoint,d,W,96,int32,1,W -com.victronenergy.vebus,/Hub4/L2/AcPowerSetpoint,d,W,98,int32,1,W -com.victronenergy.vebus,/Hub4/L3/AcPowerSetpoint,d,W,100,int32,1,W -com.victronenergy.vebus,/Dc/0/PreferRenewableEnergy,i,0=Not preferred;1=Preferred,102,uint16,1,W -com.victronenergy.vebus,/Ac/Control/RemoteGeneratorSelected,i,0=Generator not selected;1=Generator selected,103,uint16,1,W -com.victronenergy.vebus,/Ac/State/RemoteGeneratorSelected,i,0=Generator not selected;1=Generator selected,104,uint16,1,R -com.victronenergy.vebus,/RedetectSystem,u,0=No action;1=Redetect system,105,uint16,1,W -com.victronenergy.vebus,/Settings/AssistCurrentBoostFactor,d,,106,uint16,100,W -com.victronenergy.vebus,/Settings/InverterOutputVoltage,d,,107,uint16,100,W -com.victronenergy.vebus,/Settings/PowerAssistEnabled,d,,108,uint16,1,W -com.victronenergy.vebus,/Settings/UpsFunction,d,,109,uint16,1,W -com.victronenergy.battery,/Dc/0/Power,i,W,258,int16,1,R -com.victronenergy.battery,/Dc/0/Voltage,d,V DC,259,uint16,100,R -com.victronenergy.battery,/Dc/1/Voltage,d,V DC,260,uint16,100,R -com.victronenergy.battery,/Dc/0/Current,d,A DC,261,int16,10,R -com.victronenergy.battery,/Dc/0/Temperature,d,Degrees celsius,262,int16,10,R -com.victronenergy.battery,/Dc/0/MidVoltage,d,V DC,263,uint16,100,R -com.victronenergy.battery,/Dc/0/MidVoltageDeviation,d,%,264,uint16,100,R -com.victronenergy.battery,/ConsumedAmphours,d,Ah,265,uint16,-10,R -com.victronenergy.battery,/Soc,y,%,266,uint16,10,R -com.victronenergy.battery,/Soh,y,%,304,uint16,10,R -com.victronenergy.battery,/TimeToGo,q,seconds,303,uint16,0.01,R -com.victronenergy.battery,/Info/MaxChargeVoltage,u,V DC,305,uint16,10,R -com.victronenergy.battery,/Info/BatteryLowVoltage,u,V DC,306,uint16,10,R -com.victronenergy.battery,/Info/MaxChargeCurrent,u,A DC,307,uint16,10,R -com.victronenergy.battery,/Info/MaxDischargeCurrent,u,A DC,308,uint16,10,R -com.victronenergy.battery,/Alarms/Alarm,y,0=No alarm;2=Alarm,267,uint16,1,R -com.victronenergy.battery,/Alarms/LowVoltage,u,0=No alarm;2=Alarm,268,uint16,1,R -com.victronenergy.battery,/Alarms/HighVoltage,u,0=No alarm;2=Alarm,269,uint16,1,R -com.victronenergy.battery,/Alarms/LowStarterVoltage,u,0=No alarm;2=Alarm,270,uint16,1,R -com.victronenergy.battery,/Alarms/HighStarterVoltage,u,0=No alarm;2=Alarm,271,uint16,1,R -com.victronenergy.battery,/Alarms/LowSoc,u,0=No alarm;2=Alarm,272,uint16,1,R -com.victronenergy.battery,/Alarms/LowTemperature,u,0=No alarm;2=Alarm,273,uint16,1,R -com.victronenergy.battery,/Alarms/HighTemperature,u,0=No alarm;2=Alarm,274,uint16,1,R -com.victronenergy.battery,/Alarms/MidVoltage,u,0=No alarm;2=Alarm,275,uint16,1,R -com.victronenergy.battery,/Alarms/LowFusedVoltage,u,0=No alarm;2=Alarm,276,uint16,1,R -com.victronenergy.battery,/Alarms/HighFusedVoltage,u,0=No alarm;2=Alarm,277,uint16,1,R -com.victronenergy.battery,/Alarms/FuseBlown,u,0=No alarm;2=Alarm,278,uint16,1,R -com.victronenergy.battery,/Alarms/HighInternalTemperature,u,0=No alarm;2=Alarm,279,uint16,1,R -com.victronenergy.battery,/Alarms/HighChargeCurrent,u,0=No alarm;2=Alarm,320,uint16,1,R -com.victronenergy.battery,/Alarms/HighDischargeCurrent,u,0=No alarm;2=Alarm,321,uint16,1,R -com.victronenergy.battery,/Alarms/CellImbalance,u,0=No alarm;2=Alarm,322,uint16,1,R -com.victronenergy.battery,/Alarms/InternalFailure,u,0=No alarm;2=Alarm,323,uint16,1,R -com.victronenergy.battery,/Alarms/HighChargeTemperature,u,0=No alarm;2=Alarm,324,uint16,1,R -com.victronenergy.battery,/Alarms/LowChargeTemperature,u,0=No alarm;2=Alarm,325,uint16,1,R -com.victronenergy.battery,/Alarms/LowCellVoltage,u,0=No alarm;1=Almost discharged;2=Alarm,326,uint16,1,R -com.victronenergy.battery,/Relay/0/State,y,0=Open;1=Closed,280,uint16,1,W -com.victronenergy.battery,/History/DeepestDischarge,d,Ah,281,uint16,-10,R -com.victronenergy.battery,/History/LastDischarge,d,Ah,282,uint16,-10,R -com.victronenergy.battery,/History/AverageDischarge,d,Ah,283,uint16,-10,R -com.victronenergy.battery,/History/ChargeCycles,i,count,284,uint16,1,R -com.victronenergy.battery,/History/FullDischarges,i,count,285,uint16,1,R -com.victronenergy.battery,/History/TotalAhDrawn,d,Ah,286,uint16,-10,R -com.victronenergy.battery,/History/MinimumVoltage,d,V DC,287,uint16,100,R -com.victronenergy.battery,/History/MaximumVoltage,d,V DC,288,uint16,100,R -com.victronenergy.battery,/History/TimeSinceLastFullCharge,i,seconds,289,uint16,0.01,R -com.victronenergy.battery,/History/AutomaticSyncs,i,count,290,uint16,1,R -com.victronenergy.battery,/History/LowVoltageAlarms,i,count,291,uint16,1,R -com.victronenergy.battery,/History/HighVoltageAlarms,i,count,292,uint16,1,R -com.victronenergy.battery,/History/LowStarterVoltageAlarms,i,count,293,uint16,1,R -com.victronenergy.battery,/History/HighStarterVoltageAlarms,i,count,294,uint16,1,R -com.victronenergy.battery,/History/MinimumStarterVoltage,d,V DC,295,uint16,100,R -com.victronenergy.battery,/History/MaximumStarterVoltage,d,V DC,296,uint16,100,R -com.victronenergy.battery,/History/LowFusedVoltageAlarms,i,count,297,uint16,1,R -com.victronenergy.battery,/History/HighFusedVoltageAlarms,i,count,298,uint16,1,R -com.victronenergy.battery,/History/MinimumFusedVoltage,d,V DC,299,uint16,100,R -com.victronenergy.battery,/History/MaximumFusedVoltage,d,V DC,300,uint16,100,R -com.victronenergy.battery,/History/DischargedEnergy,d,kWh,301,uint16,10,R -com.victronenergy.battery,/History/ChargedEnergy,d,kWh,302,uint16,10,R -com.victronenergy.battery,/Capacity,d,Ah,309,uint16,10,R -com.victronenergy.battery,/State,y,0=Initializing (Wait start);1=Initializing (before boot);2=Initializing (Before boot delay);3=Initializing (Wait boot);4=Initializing;5=Initializing (Measure battery voltage);6=Initializing (Calculate battery voltage);7=Initializing (Wait bus voltage);8=Initializing (Wait for lynx shunt);9=Running;10=Error;11=Unused;12=Shutdown;13=Slave updating;14=Standby;15=Going to run;16=Per-charging;17=Contactor check,1282,uint16,1,R -com.victronenergy.battery,/ErrorCode,y,0=No error;1=Battery initialization error;2=No batteries connected;3=Unknown battery connected;4=Different battery type;5=Number of batteries incorrect;6=Lynx Shunt not found;7=Battery measure error;8=Internal calculation error;9=Batteries in series not ok;10=Number of batteries incorrect;11=Hardware error;12=Watchdog error;13=Over voltage;14=Under voltage;15=Over temperature;16=Under temperature;17=Hardware fault;18=Standby shutdown;19=Pre-charge charge error;20=Safety contactor check error;21=Pre-charge discharge error;22=ADC error;23=Slave error;24=Slave warning;25=Pre-charge error;26=Safety contactor error;27=Over current;28=Slave update failed;29=Slave update unavailable,1283,uint16,1,R -com.victronenergy.battery,/SystemSwitch,y,0=Disabled;1=Enabled,1284,uint16,1,R -com.victronenergy.battery,/Balancing,y,0=Inactive;1=Active,1285,uint16,1,R -com.victronenergy.battery,/System/NrOfBatteries,y,count,1286,uint16,1,R -com.victronenergy.battery,/System/BatteriesParallel,y,count,1287,uint16,1,R -com.victronenergy.battery,/System/BatteriesSeries,y,count,1288,uint16,1,R -com.victronenergy.battery,/System/NrOfCellsPerBattery,y,count,1289,uint16,1,R -com.victronenergy.battery,/System/MinCellVoltage,d,V DC,1290,uint16,100,R -com.victronenergy.battery,/System/MaxCellVoltage,d,V DC,1291,uint16,100,R -com.victronenergy.battery,/Diagnostics/ShutDownsDueError,q,count,1292,uint16,1,R -com.victronenergy.battery,/Diagnostics/LastErrors/1/Error,y,0=No error;1=Battery initialization error;2=No batteries connected;3=Unknown battery connected;4=Different battery type;5=Number of batteries incorrect;6=Lynx Shunt not found;7=Battery measure error;8=Internal calculation error;9=Batteries in series not ok;10=Number of batteries incorrect;11=Hardware error;12=Watchdog error;13=Over voltage;14=Under voltage;15=Over temperature;16=Under temperature;17=Hardware fault;18=Standby shutdown;19=Pre-charge charge error;20=Safety contactor check error;21=Pre-charge discharge error;22=ADC error;23=Slave error;24=Slave warning;25=Pre-charge error;26=Safety contactor error;27=Over current;28=Slave update failed;29=Slave update unavailable,1293,uint16,1,R -com.victronenergy.battery,/Diagnostics/LastErrors/2/Error,y,0=No error;1=Battery initialization error;2=No batteries connected;3=Unknown battery connected;4=Different battery type;5=Number of batteries incorrect;6=Lynx Shunt not found;7=Battery measure error;8=Internal calculation error;9=Batteries in series not ok;10=Number of batteries incorrect;11=Hardware error;12=Watchdog error;13=Over voltage;14=Under voltage;15=Over temperature;16=Under temperature;17=Hardware fault;18=Standby shutdown;19=Pre-charge charge error;20=Safety contactor check error;21=Pre-charge discharge error;22=ADC error;23=Slave error;24=Slave warning;25=Pre-charge error;26=Safety contactor error;27=Over current;28=Slave update failed;29=Slave update unavailable,1294,uint16,1,R -com.victronenergy.battery,/Diagnostics/LastErrors/3/Error,y,0=No error;1=Battery initialization error;2=No batteries connected;3=Unknown battery connected;4=Different battery type;5=Number of batteries incorrect;6=Lynx Shunt not found;7=Battery measure error;8=Internal calculation error;9=Batteries in series not ok;10=Number of batteries incorrect;11=Hardware error;12=Watchdog error;13=Over voltage;14=Under voltage;15=Over temperature;16=Under temperature;17=Hardware fault;18=Standby shutdown;19=Pre-charge charge error;20=Safety contactor check error;21=Pre-charge discharge error;22=ADC error;23=Slave error;24=Slave warning;25=Pre-charge error;26=Safety contactor error;27=Over current;28=Slave update failed;29=Slave update unavailable,1295,uint16,1,R -com.victronenergy.battery,/Diagnostics/LastErrors/4/Error,y,0=No error;1=Battery initialization error;2=No batteries connected;3=Unknown battery connected;4=Different battery type;5=Number of batteries incorrect;6=Lynx Shunt not found;7=Battery measure error;8=Internal calculation error;9=Batteries in series not ok;10=Number of batteries incorrect;11=Hardware error;12=Watchdog error;13=Over voltage;14=Under voltage;15=Over temperature;16=Under temperature;17=Hardware fault;18=Standby shutdown;19=Pre-charge charge error;20=Safety contactor check error;21=Pre-charge discharge error;22=ADC error;23=Slave error;24=Slave warning;25=Pre-charge error;26=Safety contactor error;27=Over current;28=Slave update failed;29=Slave update unavailable,1296,uint16,1,R -com.victronenergy.battery,/Diagnostics/LastErrors/1/Time,u,,310,int32,1,R -com.victronenergy.battery,/Diagnostics/LastErrors/2/Time,u,,312,int32,1,R -com.victronenergy.battery,/Diagnostics/LastErrors/3/Time,u,,314,int32,1,R -com.victronenergy.battery,/Diagnostics/LastErrors/4/Time,u,,316,int32,1,R -com.victronenergy.battery,/System/MinCellTemperature,d,Degrees celsius,318,int16,10,R -com.victronenergy.battery,/System/MaxCellTemperature,d,Degrees celsius,319,int16,10,R -com.victronenergy.battery,/Io/AllowToCharge,y,0=No;1=Yes,1297,uint16,1,R -com.victronenergy.battery,/Io/AllowToDischarge,y,0=No;1=Yes,1298,uint16,1,R -com.victronenergy.battery,/Io/ExternalRelay,y,0=Inactive;1=Active,1299,uint16,1,R -com.victronenergy.battery,/History/MinimumCellVoltage,d,V DC,1300,uint16,100,R -com.victronenergy.battery,/History/MaximumCellVoltage,d,V DC,1301,uint16,100,R -com.victronenergy.battery,/System/NrOfModulesOffline,u,,1302,uint16,1,R -com.victronenergy.battery,/System/NrOfModulesOnline,u,,1303,uint16,1,R -com.victronenergy.battery,/System/NrOfModulesBlockingCharge,u,,1304,uint16,1,R -com.victronenergy.battery,/System/NrOfModulesBlockingDischarge,u,,1305,uint16,1,R -com.victronenergy.battery,/System/MinVoltageCellId,s,,1306,string[4],1,R -com.victronenergy.battery,/System/MaxVoltageCellId,s,,1310,string[4],1,R -com.victronenergy.battery,/System/MinTemperatureCellId,s,,1314,string[4],1,R -com.victronenergy.battery,/System/MaxTemperatureCellId,s,,1318,string[4],1,R -com.victronenergy.battery,/Mode,i,3=On;252=Standby,1319,uint16,1,W -com.victronenergy.battery,/Balancer/Status,u,0=Unknown;1=Balanced;2=Balancing;3=Cell imbalance,1320,uint16,1,R -com.victronenergy.battery,/Errors/SmartLithium/Communication,u,0=OK;1=Error,1321,uint16,1,R -com.victronenergy.battery,/Errors/SmartLithium/Voltage,u,0=OK;1=Error,1322,uint16,1,R -com.victronenergy.battery,/Errors/SmartLithium/NrOfBatteries,u,0=OK;1=Error,1323,uint16,1,R -com.victronenergy.battery,/Errors/SmartLithium/InvalidConfiguration,u,0=OK;1=Error,1324,uint16,1,R -com.victronenergy.solarcharger,/Dc/0/Voltage,d,V DC,771,uint16,100,R -com.victronenergy.solarcharger,/Dc/0/Current,d,A DC,772,int16,10,R -com.victronenergy.solarcharger,/Dc/0/Temperature,d,Degrees celsius,773,int16,10,R -com.victronenergy.solarcharger,/Mode,i,1=On;4=Off,774,uint16,1,W -com.victronenergy.solarcharger,/State,i,0=Off;2=Fault;3=Bulk;4=Absorption;5=Float;6=Storage;7=Equalize;11=Other (Hub-1);252=Hub-1,775,uint16,1,R -com.victronenergy.solarcharger,/Pv/V,d,V DC,776,uint16,100,R -com.victronenergy.solarcharger,/Pv/I,d,A DC,777,INTERNAL,10,R -com.victronenergy.solarcharger,/Yield/Power,d,W,789,uint16,10,R -com.victronenergy.solarcharger,/Equalization/Pending,i,0=No;1=Yes;2=Error;3=Unavailable- Unknown,778,uint16,1,R -com.victronenergy.solarcharger,/Equalization/TimeRemaining,d,seconds,779,uint16,10,R -com.victronenergy.solarcharger,/Relay/0/State,i,0=Open;1=Closed,780,uint16,1,R -com.victronenergy.solarcharger,/Alarms/Alarm,i,0=No alarm;2=Alarm,781,uint16,1,R -com.victronenergy.solarcharger,/Alarms/LowVoltage,i,0=No alarm;2=Alarm,782,uint16,1,R -com.victronenergy.solarcharger,/Alarms/HighVoltage,i,0=No alarm;2=Alarm,783,uint16,1,R -com.victronenergy.solarcharger,/History/Daily/0/Yield,d,kWh,784,uint16,10,R -com.victronenergy.solarcharger,/History/Daily/0/MaxPower,d,W,785,uint16,1,R -com.victronenergy.solarcharger,/History/Daily/1/Yield,d,kWh,786,uint16,10,R -com.victronenergy.solarcharger,/History/Daily/1/MaxPower,d,W,787,uint16,1,R -com.victronenergy.solarcharger,/ErrorCode,i,0=No error;1=Battery temperature too high;2=Battery voltage too high;3=Battery temperature sensor miswired (+);4=Battery temperature sensor miswired (-);5=Battery temperature sensor disconnected;6=Battery voltage sense miswired (+);7=Battery voltage sense miswired (-);8=Battery voltage sense disconnected;9=Battery voltage wire losses too high;17=Charger temperature too high;18=Charger over-current;19=Charger current polarity reversed;20=Bulk time limit reached;22=Charger temperature sensor miswired;23=Charger temperature sensor disconnected;34=Input current too high,788,uint16,1,R -com.victronenergy.solarcharger,/Yield/User,d,kWh,790,uint16,10,R -com.victronenergy.solarcharger,/MppOperationMode,i,0=Off;1=Voltage/current limited;2=MPPT active;255=Not available,791,uint16,1,R -com.victronenergy.solarcharger,/Pv/0/V,d,V DC,3700,uint16,100,R -com.victronenergy.solarcharger,/Pv/1/V,d,V DC,3701,uint16,100,R -com.victronenergy.solarcharger,/Pv/2/V,d,V DC,3702,uint16,100,R -com.victronenergy.solarcharger,/Pv/3/V,d,V DC,3703,uint16,100,R -com.victronenergy.solarcharger,RESERVED,d,,3704,reserved[4],1,R -com.victronenergy.solarcharger,/History/Daily/0/Pv/0/Yield,d,kWh,3708,uint16,10,R -com.victronenergy.solarcharger,/History/Daily/0/Pv/1/Yield,d,kWh,3709,uint16,10,R -com.victronenergy.solarcharger,/History/Daily/0/Pv/2/Yield,d,kWh,3710,uint16,10,R -com.victronenergy.solarcharger,/History/Daily/0/Pv/3/Yield,d,kWh,3711,uint16,10,R -com.victronenergy.solarcharger,/History/Daily/1/Pv/0/Yield,d,kWh,3712,uint16,10,R -com.victronenergy.solarcharger,/History/Daily/1/Pv/1/Yield,d,kWh,3713,uint16,10,R -com.victronenergy.solarcharger,/History/Daily/1/Pv/2/Yield,d,kWh,3714,uint16,10,R -com.victronenergy.solarcharger,/History/Daily/1/Pv/3/Yield,d,kWh,3715,uint16,10,R -com.victronenergy.solarcharger,/History/Daily/0/Pv/0/MaxPower,d,W,3716,uint16,1,R -com.victronenergy.solarcharger,/History/Daily/0/Pv/1/MaxPower,d,W,3717,uint16,1,R -com.victronenergy.solarcharger,/History/Daily/0/Pv/2/MaxPower,d,W,3718,uint16,1,R -com.victronenergy.solarcharger,/History/Daily/0/Pv/3/MaxPower,d,W,3719,uint16,1,R -com.victronenergy.solarcharger,/History/Daily/1/Pv/0/MaxPower,d,W,3720,uint16,1,R -com.victronenergy.solarcharger,/History/Daily/1/Pv/1/MaxPower,d,W,3721,uint16,1,R -com.victronenergy.solarcharger,/History/Daily/1/Pv/2/MaxPower,d,W,3722,uint16,1,R -com.victronenergy.solarcharger,/History/Daily/1/Pv/3/MaxPower,d,W,3723,uint16,1,R -com.victronenergy.solarcharger,/Pv/0/P,d,W,3724,uint16,1,R -com.victronenergy.solarcharger,/Pv/1/P,d,W,3725,uint16,1,R -com.victronenergy.solarcharger,/Pv/2/P,d,W,3726,uint16,1,R -com.victronenergy.solarcharger,/Pv/3/P,d,W,3727,uint16,1,R -com.victronenergy.solarcharger,/Yield/User,d,kWh,3728,uint32,1,R -com.victronenergy.solarcharger,/Yield/Power,d,W,3730,uint16,1,R -com.victronenergy.solarcharger,/Pv/0/MppOperationMode,i,0=Off;1=Voltage/current limited;2=MPPT active;255=Not available,3731,uint16,1,R -com.victronenergy.solarcharger,/Pv/1/MppOperationMode,i,0=Off;1=Voltage/current limited;2=MPPT active;255=Not available,3732,uint16,1,R -com.victronenergy.solarcharger,/Pv/2/MppOperationMode,i,0=Off;1=Voltage/current limited;2=MPPT active;255=Not available,3733,uint16,1,R -com.victronenergy.solarcharger,/Pv/3/MppOperationMode,i,0=Off;1=Voltage/current limited;2=MPPT active;255=Not available,3734,uint16,1,R -com.victronenergy.system,/Serial,s,,800,string[6],1,R -com.victronenergy.system,/Relay/0/State,i,0=Open;1=Closed,806,uint16,1,W -com.victronenergy.system,/Relay/1/State,i,0=Open;1=Closed,807,uint16,1,W -com.victronenergy.system,/Ac/PvOnOutput/L1/Power,d,W,808,uint16,1,R -com.victronenergy.system,/Ac/PvOnOutput/L2/Power,d,W,809,uint16,1,R -com.victronenergy.system,/Ac/PvOnOutput/L3/Power,d,W,810,uint16,1,R -com.victronenergy.system,/Ac/PvOnGrid/L1/Power,d,W,811,uint16,1,R -com.victronenergy.system,/Ac/PvOnGrid/L2/Power,d,W,812,uint16,1,R -com.victronenergy.system,/Ac/PvOnGrid/L3/Power,d,W,813,uint16,1,R -com.victronenergy.system,/Ac/PvOnGenset/L1/Power,d,W,814,uint16,1,R -com.victronenergy.system,/Ac/PvOnGenset/L2/Power,d,W,815,uint16,1,R -com.victronenergy.system,/Ac/PvOnGenset/L3/Power,d,W,816,uint16,1,R -com.victronenergy.system,/Dc/Pv/Power,d,W,850,uint16,1,R -com.victronenergy.system,/Dc/Pv/Current,d,A DC,851,int16,10,R -com.victronenergy.system,/Dc/Charger/Power,d,W,855,uint16,1,R -com.victronenergy.system,/Ac/Consumption/L1/Power,d,W,817,uint16,1,R -com.victronenergy.system,/Ac/Consumption/L2/Power,d,W,818,uint16,1,R -com.victronenergy.system,/Ac/Consumption/L3/Power,d,W,819,uint16,1,R -com.victronenergy.system,/Ac/Grid/L1/Power,d,W,820,int16,1,R -com.victronenergy.system,/Ac/Grid/L2/Power,d,W,821,int16,1,R -com.victronenergy.system,/Ac/Grid/L3/Power,d,W,822,int16,1,R -com.victronenergy.system,/Ac/Genset/L1/Power,d,W,823,int16,1,R -com.victronenergy.system,/Ac/Genset/L2/Power,d,W,824,int16,1,R -com.victronenergy.system,/Ac/Genset/L3/Power,d,W,825,int16,1,R -com.victronenergy.system,/Ac/ActiveIn/Source,u,0=Not available;1=Grid;2=Generator;3=Shore power;240=Not connected,826,int16,1,R -com.victronenergy.system,RESERVED,d,,827,reserved[3],1,R -com.victronenergy.system,/DateAndTime,d,A DC,830,INTERNAL,1,R -com.victronenergy.system,RESERVED,d,,834,reserved[6],1,R -com.victronenergy.system,/Dc/System/Power,d,W,860,int16,1,R -com.victronenergy.system,/Dc/Battery/Voltage,d,V DC,840,uint16,10,R -com.victronenergy.system,/Dc/Battery/Current,d,A DC,841,int16,10,R -com.victronenergy.system,/Dc/Battery/Power,d,W,842,int16,1,R -com.victronenergy.system,/Dc/Vebus/Current,d,A DC,865,int16,10,R -com.victronenergy.system,/Dc/Vebus/Power,d,W,866,int16,1,R -com.victronenergy.system,/Dc/Battery/Soc,d,%,843,uint16,1,R -com.victronenergy.system,/Dc/Battery/State,i,0=idle;1=charging;2=discharging,844,uint16,1,R -com.victronenergy.system,/Dc/Battery/ConsumedAmphours,d,Ah,845,uint16,-10,R -com.victronenergy.system,/Dc/Battery/TimeToGo,d,s,846,uint16,0.01,R -com.victronenergy.system,RESERVED,d,,867,reserved[1],1,R -com.victronenergy.system,/Dc/InverterCharger/Current,d,A,868,int32,10,R -com.victronenergy.system,/Dc/InverterCharger/Power,d,W,870,int32,1,R -com.victronenergy.system,RESERVED,d,,871,reserved[1],1,R -com.victronenergy.system,/Ac/ConsumptionOnInput/L1/Power,d,W,872,int32,1,R -com.victronenergy.system,/Ac/ConsumptionOnInput/L2/Power,d,W,874,int32,1,R -com.victronenergy.system,/Ac/ConsumptionOnInput/L3/Power,d,W,876,int32,1,R -com.victronenergy.system,/Ac/ConsumptionOnOutput/L1/Power,d,W,878,int32,1,R -com.victronenergy.system,/Ac/ConsumptionOnOutput/L2/Power,d,W,880,int32,1,R -com.victronenergy.system,/Ac/ConsumptionOnOutput/L3/Power,d,W,882,int32,1,R -com.victronenergy.pvinverter,/Position,i,0=AC input 1;1=AC output;2=AC input 2,1026,uint16,1,R -com.victronenergy.pvinverter,/Serial,s,,1039,string[7],1,R -com.victronenergy.pvinverter,/Ac/L1/Voltage,d,V AC,1027,uint16,10,R -com.victronenergy.pvinverter,/Ac/L1/Current,d,A AC,1028,int16,10,R -com.victronenergy.pvinverter,/Ac/L1/Power,i,W,1029,uint16,1,R -com.victronenergy.pvinverter,/Ac/L1/Energy/Forward,u,kWh,1030,uint16,100,R -com.victronenergy.pvinverter,/Ac/L2/Voltage,d,V AC,1031,uint16,10,R -com.victronenergy.pvinverter,/Ac/L2/Current,d,A AC,1032,int16,10,R -com.victronenergy.pvinverter,/Ac/L2/Power,i,W,1033,uint16,1,R -com.victronenergy.pvinverter,/Ac/L2/Energy/Forward,u,kWh,1034,uint16,100,R -com.victronenergy.pvinverter,/Ac/L3/Voltage,d,V AC,1035,uint16,10,R -com.victronenergy.pvinverter,/Ac/L3/Current,d,A AC,1036,int16,10,R -com.victronenergy.pvinverter,/Ac/L3/Power,i,W,1037,uint16,1,R -com.victronenergy.pvinverter,/Ac/L3/Energy/Forward,u,kWh,1038,uint16,100,R -com.victronenergy.pvinverter,/Ac/L1/Energy/Forward,u,kWh,1046,uint32,100,R -com.victronenergy.pvinverter,/Ac/L2/Energy/Forward,u,kWh,1048,uint32,100,R -com.victronenergy.pvinverter,/Ac/L3/Energy/Forward,u,kWh,1050,uint32,100,R -com.victronenergy.pvinverter,/Ac/Power,i,kW,1052,int32,1,W -com.victronenergy.pvinverter,/Ac/MaxPower,u,kW,1054,uint32,1,W -com.victronenergy.pvinverter,/Ac/PowerLimit,u,kW,1056,uint32,1,W -com.victronenergy.pvinverter,/Ac/L1/Power,i,W,1058,uint32,1,R -com.victronenergy.pvinverter,/Ac/L2/Power,i,W,1060,uint32,1,R -com.victronenergy.pvinverter,/Ac/L3/Power,i,W,1062,uint32,1,R -com.victronenergy.motordrive,/Motor/RPM,d,RPM,2048,int16,1,R -com.victronenergy.motordrive,/Motor/Temperature,d,Degrees celsius,2049,int16,10,R -com.victronenergy.motordrive,/Dc/0/Voltage,d,V DC,2050,uint16,100,R -com.victronenergy.motordrive,/Dc/0/Current,d,A DC,2051,int16,10,R -com.victronenergy.motordrive,/Dc/0/Power,d,W,2052,int16,10,R -com.victronenergy.motordrive,/Controller/Temperature,d,Degrees celsius,2053,int16,10,R -com.victronenergy.charger,/Dc/0/Voltage,d,V DC,2307,uint16,100,R -com.victronenergy.charger,/Dc/0/Current,d,A DC,2308,int16,10,R -com.victronenergy.charger,/Dc/0/Temperature,d,Degrees celsius,2309,int16,10,R -com.victronenergy.charger,/Dc/1/Voltage,d,V DC,2310,uint16,100,R -com.victronenergy.charger,/Dc/1/Current,d,A DC,2311,int16,10,R -com.victronenergy.charger,/Dc/2/Voltage,d,V DC,2312,uint16,100,R -com.victronenergy.charger,/Dc/2/Current,d,A DC,2313,int16,10,R -com.victronenergy.charger,/Ac/In/L1/I,d,A AC,2314,int16,10,R -com.victronenergy.charger,/Ac/In/L1/P,d,W DC,2315,uint16,1,R -com.victronenergy.charger,/Ac/In/CurrentLimit,d,A AC,2316,int16,10,W -com.victronenergy.charger,/Mode,i,0=Off;1=On;2=Error;3=Unavailable- Unknown,2317,uint16,1,W -com.victronenergy.charger,/State,i,0=Off;1=Low Power Mode;2=Fault;3=Bulk;4=Absorption;5=Float;6=Storage;7=Equalize;8=Passthru;9=Inverting;10=Power assist;11=Power supply mode;252=External control,2318,uint16,1,R -com.victronenergy.charger,/ErrorCode,i,0=No error;1=Battery temperature too high;2=Battery voltage too high;3=Battery temperature sensor miswired (+);4=Battery temperature sensor miswired (-);5=Battery temperature sensor disconnected;6=Battery voltage sense miswired (+);7=Battery voltage sense miswired (-);8=Battery voltage sense disconnected;9=Battery voltage wire losses too high;17=Charger temperature too high;18=Charger over-current;19=Charger current polarity reversed;20=Bulk time limit reached;22=Charger temperature sensor miswired;23=Charger temperature sensor disconnected;34=Input current too high,2319,uint16,1,R -com.victronenergy.charger,/Relay/0/State,i,0=Open;1=Closed,2320,uint16,1,R -com.victronenergy.charger,/Alarms/LowVoltage,i,0=No alarm;2=Alarm,2321,uint16,1,R -com.victronenergy.charger,/Alarms/HighVoltage,i,0=No alarm;2=Alarm,2322,uint16,1,R -com.victronenergy.grid,/Ac/L1/Power,d,W,2600,int16,1,R -com.victronenergy.grid,/Ac/L2/Power,d,W,2601,int16,1,R -com.victronenergy.grid,/Ac/L3/Power,d,W,2602,int16,1,R -com.victronenergy.grid,/Ac/L1/Energy/Forward,d,kWh,2603,uint16,100,R -com.victronenergy.grid,/Ac/L2/Energy/Forward,d,kWh,2604,uint16,100,R -com.victronenergy.grid,/Ac/L3/Energy/Forward,d,kWh,2605,uint16,100,R -com.victronenergy.grid,/Ac/L1/Energy/Reverse,d,kWh,2606,uint16,100,R -com.victronenergy.grid,/Ac/L2/Energy/Reverse,d,kWh,2607,uint16,100,R -com.victronenergy.grid,/Ac/L3/Energy/Reverse,d,kWh,2608,uint16,100,R -com.victronenergy.grid,/Serial,s,,2609,string[7],,R -com.victronenergy.grid,/Ac/L1/Voltage,d,V AC,2616,uint16,10,R -com.victronenergy.grid,/Ac/L1/Current,d,A AC,2617,int16,10,R -com.victronenergy.grid,/Ac/L2/Voltage,d,V AC,2618,uint16,10,R -com.victronenergy.grid,/Ac/L2/Current,d,A AC,2619,int16,10,R -com.victronenergy.grid,/Ac/L3/Voltage,d,V AC,2620,uint16,10,R -com.victronenergy.grid,/Ac/L3/Current,d,A AC,2621,int16,10,R -com.victronenergy.grid,/Ac/L1/Energy/Forward,d,kWh,2622,uint32,100,R -com.victronenergy.grid,/Ac/L2/Energy/Forward,d,kWh,2624,uint32,100,R -com.victronenergy.grid,/Ac/L3/Energy/Forward,d,kWh,2626,uint32,100,R -com.victronenergy.grid,/Ac/L1/Energy/Reverse,d,kWh,2628,uint32,100,R -com.victronenergy.grid,/Ac/L2/Energy/Reverse,d,kWh,2630,uint32,100,R -com.victronenergy.grid,/Ac/L3/Energy/Reverse,d,kWh,2632,uint32,100,R -com.victronenergy.grid,/Ac/Energy/Forward,d,kWh,2634,uint32,100,R -com.victronenergy.grid,/Ac/Energy/Reverse,d,kWh,2636,uint32,100,R -com.victronenergy.grid,/Ac/L1/Power,d,W,2638,int32,1,R -com.victronenergy.grid,/Ac/L2/Power,d,W,2640,int32,1,R -com.victronenergy.grid,/Ac/L3/Power,d,W,2642,int32,1,R -com.victronenergy.settings,/Settings/CGwacs/AcPowerSetPoint,d,W,2700,int16,1,W -com.victronenergy.settings,/Settings/CGwacs/AcPowerSetPoint,d,W,2703,int16,0.01,W -com.victronenergy.settings,/Settings/CGwacs/MaxChargePercentage,d,%,2701,uint16,1,W -com.victronenergy.settings,/Settings/CGwacs/MaxDischargePercentage,d,%,2702,uint16,1,W -com.victronenergy.settings,/Settings/CGwacs/MaxDischargePower,d,W,2704,int16,0.1,W -com.victronenergy.settings,/Settings/SystemSetup/MaxChargeCurrent,d,A,2705,int16,1,W -com.victronenergy.settings,/Settings/CGwacs/MaxFeedInPower,d,W,2706,int16,0.01,W -com.victronenergy.settings,/Settings/CGwacs/OvervoltageFeedIn,i,0=Don't feed excess DC-coupled PV into grid;1=Feed excess DC-coupled PV into the grid,2707,uint16,1,W -com.victronenergy.settings,/Settings/CGwacs/PreventFeedback,i,0=Feed excess AC-coupled PV into grid;1=Don't feed excess AC-coupled PV into the grid,2708,uint16,1,W -com.victronenergy.settings,/Settings/SystemSetup/MaxChargeVoltage,d,V,2710,uint16,10,W -com.victronenergy.settings,/Settings/SystemSetup/AcInput1,u,0=Unused;1=Grid;2=Genset;3=Shore,2711,uint16,1,W -com.victronenergy.settings,/Settings/SystemSetup/AcInput2,u,0=Unused;1=Grid;2=Genset;3=Shore,2712,uint16,1,W -com.victronenergy.hub4,/PvPowerLimiterActive,i,0=Feed-in limiting inactive;1=Feed-in limiting active,2709,uint16,1,R -com.victronenergy.tank,/ProductId,u,,3000,uint16,1,R -com.victronenergy.tank,/Capacity,d,m3,3001,uint32,10000,R -com.victronenergy.tank,/FluidType,u,0=Fuel;1=Fresh water;2=Waste water;3=Live well;4=Oil;5=Black water (sewage);6=Gasoline;7=Diesel;8=LPG;9=LNG;10=Hydraulic oil;11=Raw water,3003,uint16,1,R -com.victronenergy.tank,/Level,d,%,3004,uint16,10,R -com.victronenergy.tank,/Remaining,d,m3,3005,uint32,10000,R -com.victronenergy.tank,/Status,u,0=OK;1=Open circuit;2=Short circuited;3=Reverse Polarity;4=Unknown,3007,uint16,1,R -com.victronenergy.inverter,/ProductId,u,,3127,uint16,1,R -com.victronenergy.inverter,/FirmwareVersion,u,,3125,uint16,1,R -com.victronenergy.inverter,/Ac/Out/L1/I,d,A AC,3100,int16,10,R -com.victronenergy.inverter,/Ac/Out/L1/V,d,V AC,3101,uint16,10,R -com.victronenergy.inverter,/Ac/Out/L1/P,d,W AC,3102,int16,0.1,R -com.victronenergy.inverter,/Alarms/HighTemperature,u,0=No alarm;1=Warning;2=Alarm,3110,uint16,1,R -com.victronenergy.inverter,/Alarms/HighVoltage,u,0=No alarm;1=Warning;2=Alarm,3111,uint16,1,R -com.victronenergy.inverter,/Alarms/HighVoltageAcOut,u,0=No alarm;1=Warning;2=Alarm,3112,uint16,1,R -com.victronenergy.inverter,/Alarms/LowTemperature,u,0=No alarm;1=Warning;2=Alarm,3113,uint16,1,R -com.victronenergy.inverter,/Alarms/LowVoltage,u,0=No alarm;1=Warning;2=Alarm,3114,uint16,1,R -com.victronenergy.inverter,/Alarms/LowVoltageAcOut,u,0=No alarm;1=Warning;2=Alarm,3115,uint16,1,R -com.victronenergy.inverter,/Alarms/Overload,u,0=No alarm;1=Warning;2=Alarm,3116,uint16,1,R -com.victronenergy.inverter,/Alarms/Ripple,u,0=No alarm;1=Warning;2=Alarm,3117,uint16,1,R -com.victronenergy.inverter,/Dc/0/Voltage,d,V DC,3105,uint16,100,R -com.victronenergy.inverter,/Dc/0/Current,d,A DC,3106,int16,10,R -com.victronenergy.inverter,/Mode,u,2=On;4=Off;5=Eco,3126,uint16,1,W -com.victronenergy.inverter,/State,u,0=Off;1=Low power mode (search mode);2=Fault;9=Inverting (on),3128,uint16,1,R -com.victronenergy.inverter,/Energy/InverterToAcOut,d,kWh,3130,uint32,100,R -com.victronenergy.inverter,/Energy/OutToInverter,d,kWh,3132,uint32,100,R -com.victronenergy.inverter,/Energy/SolarToAcOut,d,kWh,3134,uint32,100,R -com.victronenergy.inverter,/Energy/SolarToBattery,d,kWh,3136,uint32,100,R -com.victronenergy.inverter,/Pv/V,d,V DC,3138,uint16,10,R -com.victronenergy.inverter,/Pv/0/V,d,V DC,3140,uint16,10,R -com.victronenergy.inverter,/Pv/1/V,d,V DC,3141,uint16,10,R -com.victronenergy.inverter,/Pv/2/V,d,V DC,3142,uint16,10,R -com.victronenergy.inverter,/Pv/3/V,d,V DC,3143,uint16,10,R -com.victronenergy.inverter,/History/Daily/0/Pv/0/Yield,d,kWh,3148,uint16,10,R -com.victronenergy.inverter,/History/Daily/0/Pv/1/Yield,d,kWh,3149,uint16,10,R -com.victronenergy.inverter,/History/Daily/0/Pv/2/Yield,d,kWh,3150,uint16,10,R -com.victronenergy.inverter,/History/Daily/0/Pv/3/Yield,d,kWh,3151,uint16,10,R -com.victronenergy.inverter,/History/Daily/1/Pv/0/Yield,d,kWh,3152,uint16,10,R -com.victronenergy.inverter,/History/Daily/1/Pv/1/Yield,d,kWh,3153,uint16,10,R -com.victronenergy.inverter,/History/Daily/1/Pv/2/Yield,d,kWh,3154,uint16,10,R -com.victronenergy.inverter,/History/Daily/1/Pv/3/Yield,d,kWh,3155,uint16,10,R -com.victronenergy.inverter,/History/Daily/0/Pv/0/MaxPower,d,W,3156,uint16,1,R -com.victronenergy.inverter,/History/Daily/0/Pv/1/MaxPower,d,W,3157,uint16,1,R -com.victronenergy.inverter,/History/Daily/0/Pv/2/MaxPower,d,W,3158,uint16,1,R -com.victronenergy.inverter,/History/Daily/0/Pv/3/MaxPower,d,W,3159,uint16,1,R -com.victronenergy.inverter,/History/Daily/1/Pv/0/MaxPower,d,W,3160,uint16,1,R -com.victronenergy.inverter,/History/Daily/1/Pv/1/MaxPower,d,W,3161,uint16,1,R -com.victronenergy.inverter,/History/Daily/1/Pv/2/MaxPower,d,W,3162,uint16,1,R -com.victronenergy.inverter,/History/Daily/1/Pv/3/MaxPower,d,W,3163,uint16,1,R -com.victronenergy.inverter,/Pv/0/P,d,W,3164,uint16,1,R -com.victronenergy.inverter,/Pv/1/P,d,W,3165,uint16,1,R -com.victronenergy.inverter,/Pv/2/P,d,W,3166,uint16,1,R -com.victronenergy.inverter,/Pv/3/P,d,W,3167,uint16,1,R -com.victronenergy.inverter,/Alarms/LowSoc,u,,3168,uint16,1,R -com.victronenergy.inverter,/Pv/0/MppOperationMode,i,0=Off;1=Voltage/current limited;2=MPPT active;255=Not available,3169,uint16,1,R -com.victronenergy.inverter,/Pv/1/MppOperationMode,i,0=Off;1=Voltage/current limited;2=MPPT active;255=Not available,3170,uint16,1,R -com.victronenergy.inverter,/Pv/2/MppOperationMode,i,0=Off;1=Voltage/current limited;2=MPPT active;255=Not available,3171,uint16,1,R -com.victronenergy.inverter,/Pv/3/MppOperationMode,i,0=Off;1=Voltage/current limited;2=MPPT active;255=Not available,3172,uint16,1,R -com.victronenergy.genset,/ProductId,u,,3212,uint16,1,R -com.victronenergy.genset,/StatusCode,u,0=Standby;1=Startup 1;2=Startup 2;3=Startup 3;4=Startup 4;5=Startup 5;6=Startup 6;7=Startup 7;8=Running;9=Stopping;10=Error,3213,uint16,1,R -com.victronenergy.genset,/ErrorCode,u,0=No error;1=AC voltage L1 too low;2=AC frequency L1 too low;3=AC current too low;4=AC power too low;5=Emergency stop;6=Servo current too low;7=Oil pressure too low;8=Engine temperature too low;9=Winding temperature too low;10=Exhaust temperature too low;13=Starter current too low;14=Glow current too low;15=Glow current too low;16=Fuel holding magnet current too low;17=Stop solenoid hold coil current too low;18=Stop solenoid pull coil current too low;19=Optional DC out current too low;20=5V output voltage too low;21=Boost output current too low;22=Panel supply current too high;25=Starter battery voltage too low;26=Startup aborted (rotation too low);28=Rotation too low;29=Power contactor current too low;30=AC voltage L2 too low;31=AC frequency L2 too low;32=AC current L2 too low;33=AC power L2 too low;34=AC voltage L3 too low;35=AC frequency L3 too low;36=AC current L3 too low;37=AC power L3 too low;62=Fuel temperature too low;63=Fuel level too low;65=AC voltage L1 too high;66=AC frequency too high;67=AC current too high;68=AC power too high;70=Servo current too high;71=Oil pressure too high;72=Engine temperature too high;73=Winding temperature too high;74=Exhaust temperature too low;77=Starter current too low;78=Glow current too high;79=Glow current too high;80=Fuel holding magnet current too high;81=Stop solenoid hold coil current too high;82=Stop solenoid pull coil current too high;83=Optional DC out current too high;84=5V output voltage too high;85=Boost output current too high;89=Starter battery voltage too high;90=Startup aborted (rotation too high);92=Rotation too high;93=Power contactor current too high;94=AC voltage L2 too high;95=AC frequency L2 too high;96=AC current L2 too high;97=AC power L2 too high;98=AC voltage L3 too high;99=AC frequency L3 too high;100=AC current L3 too high;101=AC power L3 too high;126=Fuel temperature too high;127=Fuel level too high;130=Lost control unit;131=Lost panel;132=Service needed;133=Lost 3-phase module;134=Lost AGT module;135=Synchronization failure;137=Intake airfilter;139=Lost sync. module;140=Load-balance failed;141=Sync-mode deactivated;142=Engine controller;148=Rotating field wrong;149=Fuel level sensor lost;150=Init failed;151=Watchdog;152=Out: winding;153=Out: exhaust;154=Out: Cyl. head;155=Inverter over temperature;156=Inverter overload;157=Inverter communication lost;158=Inverter sync failed;159=CAN communication lost;160=L1 overload;161=L2 overload;162=L3 overload;163=DC overload;164=DC overvoltage;165=Emergency stop;166=No connection,3214,uint16,1,R -com.victronenergy.genset,/AutoStart,u,0=Disabled;1=Enabled,3215,uint16,1,R -com.victronenergy.genset,/Start,u,0=Stop;1=Start,3223,uint16,1,W -com.victronenergy.genset,/Engine/Load,d,%,3216,uint16,1,R -com.victronenergy.genset,/Engine/Speed,d,RPM,3217,uint16,1,R -com.victronenergy.genset,/Engine/OperatingHours,d,s,3218,uint16,0.01,R -com.victronenergy.genset,/Engine/CoolantTemperature,d,Degrees celsius,3219,int16,10,R -com.victronenergy.genset,/Engine/WindingTemperature,d,Degrees celsius,3220,int16,10,R -com.victronenergy.genset,/Engine/ExaustTemperature,d,Degrees celsius,3221,int16,10,R -com.victronenergy.genset,/StarterVoltage,d,V DC,3222,uint16,100,R -com.victronenergy.genset,/Engine/OilPressure,d,kPa,3224,int16,1,R -com.victronenergy.genset,/Ac/L1/Voltage,d,V AC,3200,uint16,10,R -com.victronenergy.genset,/Ac/L1/Current,d,A AC,3203,int16,10,R -com.victronenergy.genset,/Ac/L1/Power,d,W,3206,int16,1,R -com.victronenergy.genset,/Ac/L1/Frequency,d,Hz,3209,uint16,100,R -com.victronenergy.genset,/Ac/L2/Voltage,d,V AC,3201,uint16,10,R -com.victronenergy.genset,/Ac/L2/Current,d,A AC,3204,int16,10,R -com.victronenergy.genset,/Ac/L2/Power,d,W,3207,int16,1,R -com.victronenergy.genset,/Ac/L2/Frequency,d,Hz,3210,uint16,100,R -com.victronenergy.genset,/Ac/L3/Voltage,d,V AC,3202,uint16,10,R -com.victronenergy.genset,/Ac/L3/Current,d,A AC,3205,int16,10,R -com.victronenergy.genset,/Ac/L3/Power,d,W,3208,int16,1,R -com.victronenergy.genset,/Ac/L3/Frequency,d,Hz,3211,uint16,100,R -com.victronenergy.genset,/Dc/0/Voltage,d,V DC,3225,uint16,100,R -com.victronenergy.genset,/Dc/0/Current,d,A DC,3226,int16,10,R -com.victronenergy.genset,/HeatsinkTemperature,d,Degrees Celsius,3227,int16,10,R -com.victronenergy.genset,/Engine/OilTemperature,d,Degrees Celsius,3228,int16,1,R -com.victronenergy.temperature,/ProductId,u,,3300,uint16,1,R -com.victronenergy.temperature,/Scale,d,,3301,uint16,100,R -com.victronenergy.temperature,/Offset,d,,3302,int16,100,R -com.victronenergy.temperature,/TemperatureType,u,0=Battery;1=Fridge;2=Generic,3303,uint16,1,R -com.victronenergy.temperature,/Temperature,d,Degrees celsius,3304,int16,100,R -com.victronenergy.temperature,/Status,u,0=OK;1=Open circuit;2=Short circuited;3=Reverse Polarity;4=Unknown,3305,uint16,1,R -com.victronenergy.temperature,/Humidity,u,%,3306,uint16,10,R -com.victronenergy.temperature,/BatteryVoltage,d,V,3307,uint16,100,R -com.victronenergy.temperature,/Pressure,u,hPa,3308,uint16,1,R -com.victronenergy.pulsemeter,/Aggregate,i,,3400,uint32,1,R -com.victronenergy.pulsemeter,/Count,i,,3402,uint32,1,R -com.victronenergy.digitalinput,/Count,i,,3420,uint32,1,R -com.victronenergy.digitalinput,/State,i,,3422,uint16,1,R -com.victronenergy.digitalinput,/Alarm,i,0=No alarm;2=Alarm,3423,uint16,1,R -com.victronenergy.digitalinput,/Type,i,2=Door;3=Bilge pump;4=Bilge alarm;5=Burglar alarm;6=Smoke alarm;7=Fire alarm;8=CO2 alarm;9=Generator,3424,uint16,1,R -com.victronenergy.generator,/ManualStart,i,0=Stop generator;1=Start generator,3500,uint16,1,W -com.victronenergy.generator,/RunningByConditionCode,i,0=Stopped;1=Manual;2=TestRun;3=LossOfComms;4=Soc;5=AcLoad;6=BatteryCurrent;7=BatteryVoltage;8=InverterTemperatur;9=InverterOverload;10=StopOnAc1,3501,uint16,1,R -com.victronenergy.generator,/Runtime,i,seconds,3502,uint16,1,R -com.victronenergy.generator,/QuietHours,i,0=Quiet hours inactive; 1=Quiet hours active,3503,uint16,1,R -com.victronenergy.generator,/Runtime,u,seconds,3504,uint32,1,R -com.victronenergy.generator,/State,i,0=Stopped;1=Running;10=Error,3506,uint16,1,R -com.victronenergy.generator,/Error,i,0=No Error;1=Remote disabled;2=Remote fault,3507,uint16,1,R -com.victronenergy.generator,/Alarms/NoGeneratorAtAcIn,i,0=No Alarm;2=Alarm,3508,uint16,1,R -com.victronenergy.generator,/AutoStartEnabled,i,0=Autostart disabled;1=Autostart enabled,3509,uint16,1,W -com.victronenergy.generator,/ServiceCounter,u,seconds,3510,uint32,1,R -com.victronenergy.generator,/ServiceCounterReset,u,1=Reset,3512,uint16,1,W -com.victronenergy.meteo,/Irradiance,d,W/m^2,3600,uint16,10,R -com.victronenergy.meteo,/WindSpeed,d,m/s,3601,uint16,10,R -com.victronenergy.meteo,/CellTemperature,d,Degrees celsius,3602,int16,10,R -com.victronenergy.meteo,/ExternalTemperature,d,Degrees celsius,3603,int16,10,R -com.victronenergy.meteo,/ExternalTemperature2,d,Degrees celsius,3604,int16,10,R -com.victronenergy.evcharger,/ProductId,u,,3800,uint16,1,R -com.victronenergy.evcharger,/FirmwareVersion,u,,3802,uint32,1,R -com.victronenergy.evcharger,/Serial,s,,3804,string[6],,R -com.victronenergy.evcharger,/Model,s,,3810,string[4],,R -com.victronenergy.evcharger,/MaxCurrent,d,A,3814,uint16,1,W -com.victronenergy.evcharger,/Mode,u,0=Manual;1=Auto,3815,uint16,1,W -com.victronenergy.evcharger,/Ac/Energy/Forward,d,kWh,3816,uint32,100,R -com.victronenergy.evcharger,/Ac/L1/Power,d,W,3818,uint16,1,R -com.victronenergy.evcharger,/Ac/L2/Power,d,W,3819,uint16,1,R -com.victronenergy.evcharger,/Ac/L3/Power,d,W,3820,uint16,1,R -com.victronenergy.evcharger,/Ac/Power,d,W,3821,uint16,1,R -com.victronenergy.evcharger,/ChargingTime,d,s,3822,uint16,0.01,R -com.victronenergy.evcharger,/Current,d,A,3823,uint16,1,W -com.victronenergy.evcharger,/Status,u,0=Disconnected;1=Connected;2=Charging;3=Charged;4=Waiting for sun;5=Waiting for RFID;6=Waiting for start;7=Low SOC;8=Ground test error;9=Welded contacts test error;10=CP input test error (shorted);11=Residual current detected;12=Undervoltage detected;13=Overvoltage detected;14=Overheating detected;15=Reserved;16=Reserved;17=Reserved;18=Reserved;19=Reserved;20=Charging limit;21=Start charging;22=Switching to 3 phase;23=Switching to 1 phase;24=Stop charging,3824,uint16,1,R -com.victronenergy.evcharger,/SetCurrent,d,A,3825,uint16,1,W -com.victronenergy.evcharger,/StartStop,u,0=Stop;1=Start,3826,uint16,1,W -com.victronenergy.evcharger,/Position,i,0=AC input 1;1=AC output;2=AC input 2,3827,uint16,1,W -com.victronenergy.acload,/Ac/L1/Power,d,W,3900,int16,1,R -com.victronenergy.acload,/Ac/L2/Power,d,W,3901,int16,1,R -com.victronenergy.acload,/Ac/L3/Power,d,W,3902,int16,1,R -com.victronenergy.acload,/Serial,s,,3903,string[7],,R -com.victronenergy.acload,/Ac/L1/Voltage,d,V AC,3910,uint16,10,R -com.victronenergy.acload,/Ac/L1/Current,d,A AC,3911,int16,10,R -com.victronenergy.acload,/Ac/L2/Voltage,d,V AC,3912,uint16,10,R -com.victronenergy.acload,/Ac/L2/Current,d,A AC,3913,int16,10,R -com.victronenergy.acload,/Ac/L3/Voltage,d,V AC,3914,uint16,10,R -com.victronenergy.acload,/Ac/L3/Current,d,A AC,3915,int16,10,R -com.victronenergy.acload,/Ac/L1/Energy/Forward,d,kWh,3916,uint32,100,R -com.victronenergy.acload,/Ac/L2/Energy/Forward,d,kWh,3918,uint32,100,R -com.victronenergy.acload,/Ac/L3/Energy/Forward,d,kWh,3920,uint32,100,R -com.victronenergy.fuelcell,/Dc/0/Voltage,d,V DC,4000,uint16,100,R -com.victronenergy.fuelcell,/Dc/0/Current,d,A DC,4001,int16,10,R -com.victronenergy.fuelcell,/Dc/1/Voltage,d,V DC,4002,int16,10,R -com.victronenergy.fuelcell,/Dc/0/Temperature,d,Degrees celsius,4003,int16,10,R -com.victronenergy.fuelcell,/History/EnergyOut,d,kWh,4004,uint32,100,R -com.victronenergy.fuelcell,/Alarms/LowVoltage,u,0=No alarm;2=Alarm,4006,uint16,1,R -com.victronenergy.fuelcell,/Alarms/HighVoltage,u,0=No alarm;2=Alarm,4007,uint16,1,R -com.victronenergy.fuelcell,/Alarms/LowStarterVoltage,u,0=No alarm;2=Alarm,4008,uint16,1,R -com.victronenergy.fuelcell,/Alarms/HighStarterVoltage,u,0=No alarm;2=Alarm,4009,uint16,1,R -com.victronenergy.fuelcell,/Alarms/LowTemperature,u,0=No alarm;2=Alarm,4010,uint16,1,R -com.victronenergy.fuelcell,/Alarms/HighTemperature,u,0=No alarm;2=Alarm,4011,uint16,1,R -com.victronenergy.alternator,/Dc/0/Voltage,d,V DC,4100,uint16,100,R -com.victronenergy.alternator,/Dc/0/Current,d,A DC,4101,int16,10,R -com.victronenergy.alternator,/Dc/1/Voltage,d,V DC,4102,int16,10,R -com.victronenergy.alternator,/Dc/0/Temperature,d,Degrees celsius,4103,int16,10,R -com.victronenergy.alternator,/History/EnergyOut,d,kWh,4104,uint32,100,R -com.victronenergy.alternator,/Alarms/LowVoltage,u,0=No alarm;2=Alarm,4106,uint16,1,R -com.victronenergy.alternator,/Alarms/HighVoltage,u,0=No alarm;2=Alarm,4107,uint16,1,R -com.victronenergy.alternator,/Alarms/LowStarterVoltage,u,0=No alarm;2=Alarm,4108,uint16,1,R -com.victronenergy.alternator,/Alarms/HighStarterVoltage,u,0=No alarm;2=Alarm,4109,uint16,1,R -com.victronenergy.alternator,/Alarms/LowTemperature,u,0=No alarm;2=Alarm,4110,uint16,1,R -com.victronenergy.alternator,/Alarms/HighTemperature,u,0=No alarm;2=Alarm,4111,uint16,1,R -com.victronenergy.alternator,/State,u,0=Off;2=Fault;3=Bulk;4=Absorption;5=Float;6=Storage;7=Equalize;252=External control,4112,uint16,1,R -com.victronenergy.alternator,/ErrorCode,u,12=High battery temperature;13=High battery voltage;14=Low battery voltage;15=VBat exceeds $CPB;21=High alternator temperature;22=Alternator overspeed;24=Internal error;41=High field FET temperature;42=Sensor missing;43=Low VAlt;44=High Voltage offset;45=VAlt exceeds $CPB;51-52=Battery disconnect request;53=Battery instance out of range;54=Too many BMSes;55=AEBus fault;56=Too many Victron devices;58-61=Battery requested disconnection;91=BMS lost;92=Forced idle;201=DCDC converter fail;201-207=DCDC error,4113,uint16,1,R -com.victronenergy.alternator,/Engine/Speed,d,RPM,4114,uint16,1,R -com.victronenergy.alternator,/Speed,d,RPM,4115,uint16,1,R -com.victronenergy.alternator,/FieldDrive,q,%,4116,uint16,1,R -com.victronenergy.alternator,/Dc/In/V,d,V DC,4117,uint16,100,R -com.victronenergy.alternator,/Dc/In/P,d,W,4118,uint16,1,R -com.victronenergy.alternator,/Mode,u,1=On;4=Off,4119,uint16,1,W -com.victronenergy.alternator,/History/Cumulative/User/ChargedAh,d,Ah,4120,uint32,10,R -com.victronenergy.dcsource,/Dc/0/Voltage,d,V DC,4200,uint16,100,R -com.victronenergy.dcsource,/Dc/0/Current,d,A DC,4201,int16,10,R -com.victronenergy.dcsource,/Dc/1/Voltage,d,V DC,4202,int16,10,R -com.victronenergy.dcsource,/Dc/0/Temperature,d,Degrees centigrade,4203,int16,10,R -com.victronenergy.dcsource,/History/EnergyOut,d,kWh,4204,uint32,100,R -com.victronenergy.dcsource,/Alarms/LowVoltage,u,0=No alarm;2=Alarm,4206,uint16,1,R -com.victronenergy.dcsource,/Alarms/HighVoltage,u,0=No alarm;2=Alarm,4207,uint16,1,R -com.victronenergy.dcsource,/Alarms/LowStarterVoltage,u,0=No alarm;2=Alarm,4208,uint16,1,R -com.victronenergy.dcsource,/Alarms/HighStarterVoltage,u,0=No alarm;2=Alarm,4209,uint16,1,R -com.victronenergy.dcsource,/Alarms/LowTemperature,u,0=No alarm;2=Alarm,4210,uint16,1,R -com.victronenergy.dcsource,/Alarms/HighTemperature,u,0=No alarm;2=Alarm,4211,uint16,1,R -com.victronenergy.dcload,/Dc/0/Voltage,d,V DC,4300,uint16,100,R -com.victronenergy.dcload,/Dc/0/Current,d,A DC,4301,int16,10,R -com.victronenergy.dcload,/Dc/1/Voltage,d,V DC,4302,int16,10,R -com.victronenergy.dcload,/Dc/0/Temperature,d,Degrees centigrade,4303,int16,10,R -com.victronenergy.dcload,/History/EnergyIn,d,kWh,4304,uint32,100,R -com.victronenergy.dcload,/Alarms/LowVoltage,u,0=No alarm;2=Alarm,4306,uint16,1,R -com.victronenergy.dcload,/Alarms/HighVoltage,u,0=No alarm;2=Alarm,4307,uint16,1,R -com.victronenergy.dcload,/Alarms/LowStarterVoltage,u,0=No alarm;2=Alarm,4308,uint16,1,R -com.victronenergy.dcload,/Alarms/HighStarterVoltage,u,0=No alarm;2=Alarm,4309,uint16,1,R -com.victronenergy.dcload,/Alarms/LowTemperature,u,0=No alarm;2=Alarm,4310,uint16,1,R -com.victronenergy.dcload,/Alarms/HighTemperature,u,0=No alarm;2=Alarm,4311,uint16,1,R -com.victronenergy.dcsystem,/Dc/0/Voltage,d,V DC,4400,uint16,100,R -com.victronenergy.dcsystem,/Dc/0/Current,d,A DC,4401,int16,10,R -com.victronenergy.dcsystem,/Dc/1/Voltage,d,V DC,4402,int16,10,R -com.victronenergy.dcsystem,/Dc/0/Temperature,d,Degrees centigrade,4403,int16,10,R -com.victronenergy.dcsystem,/History/EnergyOut,d,kWh,4404,uint32,100,R -com.victronenergy.dcsystem,/History/EnergyIn,d,kWh,4406,uint32,100,R -com.victronenergy.dcsystem,/Alarms/LowVoltage,u,0=No alarm;2=Alarm,4408,uint16,1,R -com.victronenergy.dcsystem,/Alarms/HighVoltage,u,0=No alarm;2=Alarm,4409,uint16,1,R -com.victronenergy.dcsystem,/Alarms/LowStarterVoltage,u,0=No alarm;2=Alarm,4410,uint16,1,R -com.victronenergy.dcsystem,/Alarms/HighStarterVoltage,u,0=No alarm;2=Alarm,4411,uint16,1,R -com.victronenergy.dcsystem,/Alarms/LowTemperature,u,0=No alarm;2=Alarm,4412,uint16,1,R -com.victronenergy.dcsystem,/Alarms/HighTemperature,u,0=No alarm;2=Alarm,4413,uint16,1,R -com.victronenergy.multi,/Ac/In/1/L1/V,d,V AC,4500,uint16,10,R -com.victronenergy.multi,/Ac/In/1/L2/V,d,V AC,4501,uint16,10,R -com.victronenergy.multi,/Ac/In/1/L3/V,d,V AC,4502,uint16,10,R -com.victronenergy.multi,/Ac/In/1/L1/I,d,A AC,4503,int16,10,R -com.victronenergy.multi,/Ac/In/1/L2/I,d,A AC,4504,int16,10,R -com.victronenergy.multi,/Ac/In/1/L3/I,d,A AC,4505,int16,10,R -com.victronenergy.multi,/Ac/In/1/L1/P,d,W,4506,int16,0.1,R -com.victronenergy.multi,/Ac/In/1/L2/P,d,W,4507,int16,0.1,R -com.victronenergy.multi,/Ac/In/1/L3/P,d,W,4508,int16,0.1,R -com.victronenergy.multi,/Ac/In/1/L1/F,d,Hz,4509,uint16,100,R -com.victronenergy.multi,/Ac/Out/L1/V,d,V AC,4510,uint16,10,R -com.victronenergy.multi,/Ac/Out/L2/V,d,V AC,4511,uint16,10,R -com.victronenergy.multi,/Ac/Out/L3/V,d,V AC,4512,uint16,10,R -com.victronenergy.multi,/Ac/Out/L1/I,d,A AC,4513,int16,10,R -com.victronenergy.multi,/Ac/Out/L2/I,d,A AC,4514,int16,10,R -com.victronenergy.multi,/Ac/Out/L3/I,d,A AC,4515,int16,10,R -com.victronenergy.multi,/Ac/Out/L1/P,d,W,4516,int16,0.1,R -com.victronenergy.multi,/Ac/Out/L2/P,d,W,4517,int16,0.1,R -com.victronenergy.multi,/Ac/Out/L3/P,d,W,4518,int16,0.1,R -com.victronenergy.multi,/Ac/Out/L1/F,d,Hz,4519,uint16,100,R -com.victronenergy.multi,/Ac/In/1/Type,u,0=Unused;1=Grid;2=Genset;3=Shore,4520,uint16,1,R -com.victronenergy.multi,/Ac/In/2/Type,u,0=Unused;1=Grid;2=Genset;3=Shore,4521,uint16,1,R -com.victronenergy.multi,/Ac/In/1/CurrentLimit,d,A,4522,uint16,10,W -com.victronenergy.multi,/Ac/In/2/CurrentLimit,d,A,4523,uint16,10,W -com.victronenergy.multi,/Ac/NumberOfPhases,u,count,4524,uint16,1,R -com.victronenergy.multi,/Ac/ActiveIn/ActiveInput,u,0=AC Input 1;1=AC Input 2;240=Disconnected,4525,uint16,1,R -com.victronenergy.multi,/Dc/0/Voltage,d,V DC,4526,uint16,100,R -com.victronenergy.multi,/Dc/0/Current,d,A DC,4527,int16,10,R -com.victronenergy.multi,/Dc/0/Temperature,d,Degrees celsius,4528,int16,10,R -com.victronenergy.multi,/Soc,d,%,4529,uint16,10,R -com.victronenergy.multi,/State,u,0=Off;1=Low Power;2=Fault;3=Bulk;4=Absorption;5=Float;6=Storage;7=Equalize;8=Passthru;9=Inverting;10=Power assist;11=Power supply;252=External control,4530,uint16,1,R -com.victronenergy.multi,/Mode,u,1=Charger Only;2=Inverter Only;3=On;4=Off,4531,uint16,1,W -com.victronenergy.multi,/Alarms/HighTemperature,u,0=Ok;1=Warning;2=Alarm,4532,uint16,1,R -com.victronenergy.multi,/Alarms/HighVoltage,u,0=Ok;1=Warning;2=Alarm,4533,uint16,1,R -com.victronenergy.multi,/Alarms/HighVoltageAcOut,u,0=Ok;1=Warning;2=Alarm,4534,uint16,1,R -com.victronenergy.multi,/Alarms/LowTemperature,u,0=Ok;1=Warning;2=Alarm,4535,uint16,1,R -com.victronenergy.multi,/Alarms/LowVoltage,u,0=Ok;1=Warning;2=Alarm,4536,uint16,1,R -com.victronenergy.multi,/Alarms/LowVoltageAcOut,u,0=Ok;1=Warning;2=Alarm,4537,uint16,1,R -com.victronenergy.multi,/Alarms/Overload,u,0=Ok;1=Warning;2=Alarm,4538,uint16,1,R -com.victronenergy.multi,/Alarms/Ripple,u,0=Ok;1=Warning;2=Alarm,4539,uint16,1,R -com.victronenergy.multi,/Yield/Power,d,W,4540,uint16,1,R -com.victronenergy.multi,/Yield/User,d,kWh,4541,uint16,10,R -com.victronenergy.multi,/Relay/0/State,i,0=Open;1=Closed,4542,uint16,1,R -com.victronenergy.multi,/MppOperationMode,i,0=Off;1=Voltage/current limited;2=MPPT active;255=Not available,4543,uint16,1,R -com.victronenergy.multi,/Pv/V,d,V DC,4544,uint16,10,R -com.victronenergy.multi,/ErrorCode,i,0=No error;1=Battery temperature too high;2=Battery voltage too high;3=Battery temperature sensor miswired (+);4=Battery temperature sensor miswired (-);5=Battery temperature sensor disconnected;6=Battery voltage sense miswired (+);7=Battery voltage sense miswired (-);8=Battery voltage sense disconnected;9=Battery voltage wire losses too high;17=Charger temperature too high;18=Charger over-current;19=Charger current polarity reversed;20=Bulk time limit reached;22=Charger temperature sensor miswired;23=Charger temperature sensor disconnected;34=Input current too high,4545,uint16,1,R -com.victronenergy.multi,/Energy/AcIn1ToAcOut,d,kWh,4546,uint32,100,R -com.victronenergy.multi,/Energy/AcIn1ToInverter,d,kWh,4548,uint32,100,R -com.victronenergy.multi,/Energy/AcIn2ToAcOut,d,kWh,4550,uint32,100,R -com.victronenergy.multi,/Energy/AcIn2ToInverter,d,kWh,4552,uint32,100,R -com.victronenergy.multi,/Energy/AcOutToAcIn1,d,kWh,4554,uint32,100,R -com.victronenergy.multi,/Energy/AcOutToAcIn2,d,kWh,4556,uint32,100,R -com.victronenergy.multi,/Energy/InverterToAcIn1,d,kWh,4558,uint32,100,R -com.victronenergy.multi,/Energy/InverterToAcIn2,d,kWh,4560,uint32,100,R -com.victronenergy.multi,/Energy/InverterToAcOut,d,kWh,4562,uint32,100,R -com.victronenergy.multi,/Energy/OutToInverter,d,kWh,4564,uint32,100,R -com.victronenergy.multi,/Energy/SolarToAcIn1,d,kWh,4566,uint32,100,R -com.victronenergy.multi,/Energy/SolarToAcIn2,d,kWh,4568,uint32,100,R -com.victronenergy.multi,/Energy/SolarToAcOut,d,kWh,4570,uint32,100,R -com.victronenergy.multi,/Energy/SolarToBattery,d,kWh,4572,uint32,100,R -com.victronenergy.multi,/History/Daily/0/Yield,d,kWh,4574,uint16,10,R -com.victronenergy.multi,/History/Daily/0/MaxPower,d,W,4575,uint16,1,R -com.victronenergy.multi,/History/Daily/1/Yield,d,kWh,4576,uint16,10,R -com.victronenergy.multi,/History/Daily/1/MaxPower,d,W,4577,uint16,1,R -com.victronenergy.multi,/History/Daily/0/Pv/0/Yield,d,kWh,4578,uint16,10,R -com.victronenergy.multi,/History/Daily/0/Pv/1/Yield,d,kWh,4579,uint16,10,R -com.victronenergy.multi,/History/Daily/0/Pv/2/Yield,d,kWh,4580,uint16,10,R -com.victronenergy.multi,/History/Daily/0/Pv/3/Yield,d,kWh,4581,uint16,10,R -com.victronenergy.multi,/History/Daily/1/Pv/0/Yield,d,kWh,4582,uint16,10,R -com.victronenergy.multi,/History/Daily/1/Pv/1/Yield,d,kWh,4583,uint16,10,R -com.victronenergy.multi,/History/Daily/1/Pv/2/Yield,d,kWh,4584,uint16,10,R -com.victronenergy.multi,/History/Daily/1/Pv/3/Yield,d,kWh,4585,uint16,10,R -com.victronenergy.multi,/History/Daily/0/Pv/0/MaxPower,d,W,4586,uint16,1,R -com.victronenergy.multi,/History/Daily/0/Pv/1/MaxPower,d,W,4587,uint16,1,R -com.victronenergy.multi,/History/Daily/0/Pv/2/MaxPower,d,W,4588,uint16,1,R -com.victronenergy.multi,/History/Daily/0/Pv/3/MaxPower,d,W,4589,uint16,1,R -com.victronenergy.multi,/History/Daily/1/Pv/0/MaxPower,d,W,4590,uint16,1,R -com.victronenergy.multi,/History/Daily/1/Pv/1/MaxPower,d,W,4591,uint16,1,R -com.victronenergy.multi,/History/Daily/1/Pv/2/MaxPower,d,W,4592,uint16,1,R -com.victronenergy.multi,/History/Daily/1/Pv/3/MaxPower,d,W,4593,uint16,1,R -com.victronenergy.multi,/Pv/0/V,d,V DC,4594,uint16,10,R -com.victronenergy.multi,/Pv/1/V,d,V DC,4595,uint16,10,R -com.victronenergy.multi,/Pv/2/V,d,V DC,4596,uint16,10,R -com.victronenergy.multi,/Pv/3/V,d,V DC,4597,uint16,10,R -com.victronenergy.multi,/Pv/0/P,d,W,4598,uint16,1,R -com.victronenergy.multi,/Pv/1/P,d,W,4599,uint16,1,R -com.victronenergy.multi,/Pv/2/P,d,W,4600,uint16,1,R -com.victronenergy.multi,/Pv/3/P,d,W,4601,uint16,1,R -com.victronenergy.multi,/Alarms/LowSoc,u,,4602,uint16,1,R -com.victronenergy.multi,/Yield/User,d,kWh,4603,uint32,1,R -com.victronenergy.multi,/Pv/0/MppOperationMode,i,0=Off;1=Voltage/current limited;2=MPPT active;255=Not available,4605,uint16,1,R -com.victronenergy.multi,/Pv/1/MppOperationMode,i,0=Off;1=Voltage/current limited;2=MPPT active;255=Not available,4606,uint16,1,R -com.victronenergy.multi,/Pv/2/MppOperationMode,i,0=Off;1=Voltage/current limited;2=MPPT active;255=Not available,4607,uint16,1,R -com.victronenergy.multi,/Pv/3/MppOperationMode,i,0=Off;1=Voltage/current limited;2=MPPT active;255=Not available,4608,uint16,1,R -com.victronenergy.multi,/Settings/Ess/Mode,i,0=self-consumption (battery-life);1=self-consumption;2=Keep charged;3=External control,4609,uint16,1,W -com.victronenergy.multi,/Ess/AcPowerSetpoint,d,W,4610,int32,1,W -com.victronenergy.multi,/Ess/DisableFeedIn,d,0=Feed-in enabled;1=Feed-in disabled,4612,uint16,1,W -com.victronenergy.multi,/Ess/DisableCharge,d,0=Charge enabled;1=Charge disabled,4613,uint16,1,W -com.victronenergy.multi,/Settings/Ess/MinimumSocLimit,d,%,4614,uint16,1,W -com.victronenergy.pump,/State,d,0=Stopped;1=Running,4700,uint16,1,R -com.victronenergy.settings,/Settings/Pump0/AutoStartEnabled,d,0=Disabled;1=Enabled,4701,uint16,1,W -com.victronenergy.settings,/Settings/Pump0/Mode,d,0=Auto;1=On;2=Off,4702,uint16,1,W -com.victronenergy.settings,/Settings/Pump0/StartValue,d,%,4703,uint16,1,W -com.victronenergy.settings,/Settings/Pump0/StopValue,d,%,4704,uint16,1,W -com.victronenergy.dcdc,/ProductId,u,,4800,uint16,1,R -com.victronenergy.dcdc,/FirmwareVersion,u,,4801,uint32,1,R -com.victronenergy.dcdc,/ErrorCode,i,0=No error;1=Battery temperature too high;2=Battery voltage too high;3=Battery temperature sensor miswired (+);4=Battery temperature sensor miswired (-);5=Battery temperature sensor disconnected;6=Battery voltage sense miswired (+);7=Battery voltage sense miswired (-);8=Battery voltage sense disconnected;9=Battery voltage wire losses too high;17=Charger temperature too high;18=Charger over-current;19=Charger current polarity reversed;20=Bulk time limit reached;22=Charger temperature sensor miswired;23=Charger temperature sensor disconnected;34=Input current too high,4803,uint16,1,R -com.victronenergy.dcdc,/Dc/0/Voltage,d,V DC,4804,uint16,100,R -com.victronenergy.dcdc,/Dc/0/Current,d,A DC,4805,int16,10,R -com.victronenergy.dcdc,/Dc/0/Temperature,d,Degrees celsius,4806,int16,10,R -com.victronenergy.dcdc,/Mode,u,1=On;4=Off,4807,uint16,1,W -com.victronenergy.dcdc,/State,i,0=Off;2=Fault;3=Bulk;4=Absorption;5=Float;6=Storage;7=Equalize,4808,uint16,1,R -com.victronenergy.dcdc,/Dc/In/V,d,V DC,4809,uint16,100,R -com.victronenergy.dcdc,/Dc/In/P,d,W,4810,uint16,1,R -com.victronenergy.dcdc,/History/Cumulative/User/ChargedAh,d,Ah,4811,uint16,10,R -com.victronenergy.acsystem,/State,u,0=Off;1=Low Power;2=Fault;3=Bulk;4=Absorption;5=Float;6=Storage;7=Equalize;8=Passthru;9=Inverting;10=Power assist;11=Power supply;252=External control,4900,uint16,1,R -com.victronenergy.acsystem,/Ac/In/1/L1/V,d,V AC,4901,uint16,10,R -com.victronenergy.acsystem,/Ac/In/1/L2/V,d,V AC,4902,uint16,10,R -com.victronenergy.acsystem,/Ac/In/1/L3/V,d,V AC,4903,uint16,10,R -com.victronenergy.acsystem,/Ac/In/1/L1/I,d,A AC,4904,uint16,10,R -com.victronenergy.acsystem,/Ac/In/1/L2/I,d,A AC,4905,uint16,10,R -com.victronenergy.acsystem,/Ac/In/1/L3/I,d,A AC,4906,uint16,10,R -com.victronenergy.acsystem,/Ac/In/1/L1/P,d,W,4907,int16,0.1,R -com.victronenergy.acsystem,/Ac/In/1/L2/P,d,W,4908,int16,0.1,R -com.victronenergy.acsystem,/Ac/In/1/L3/P,d,W,4909,int16,0.1,R -com.victronenergy.acsystem,/Ac/In/1/L1/F,d,Hz,4910,uint16,100,R -com.victronenergy.acsystem,/Ac/Out/L1/V,d,V AC,4911,uint16,10,R -com.victronenergy.acsystem,/Ac/Out/L2/V,d,V AC,4912,uint16,10,R -com.victronenergy.acsystem,/Ac/Out/L3/V,d,V AC,4913,uint16,10,R -com.victronenergy.acsystem,/Ac/Out/L1/I,d,A AC,4914,int16,10,R -com.victronenergy.acsystem,/Ac/Out/L2/I,d,A AC,4915,int16,10,R -com.victronenergy.acsystem,/Ac/Out/L3/I,d,A AC,4916,int16,10,R -com.victronenergy.acsystem,/Ac/Out/L1/P,d,W,4917,int16,0.1,R -com.victronenergy.acsystem,/Ac/Out/L2/P,d,W,4918,int16,0.1,R -com.victronenergy.acsystem,/Ac/Out/L3/P,d,W,4919,int16,0.1,R -com.victronenergy.acsystem,/Ac/Out/L1/F,d,Hz,4920,uint16,100,R -com.victronenergy.acsystem,/Settings/Ess/Mode,i,0=self-consumption (battery-life);1=self-consumption;2=Keep charged;3=External control,4921,uint16,1,W -com.victronenergy.acsystem,/Ess/AcPowerSetpoint,d,W,4922,int32,1,W -com.victronenergy.acsystem,/Ess/DisableFeedIn,d,0=Feed-in enabled;1=Feed-in disabled,4924,uint16,1,W diff --git a/FileSets/v3.40~33/dbus_digitalinputs.py b/FileSets/v3.40~33/dbus_digitalinputs.py deleted file mode 120000 index e74da5b6..00000000 --- a/FileSets/v3.40~33/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.40~33/dbus_generator.py b/FileSets/v3.40~33/dbus_generator.py deleted file mode 120000 index 0cd84ca3..00000000 --- a/FileSets/v3.40~33/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.40~33/main.qml b/FileSets/v3.40~33/main.qml deleted file mode 120000 index 5dbfdf83..00000000 --- a/FileSets/v3.40~33/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/main.qml \ No newline at end of file diff --git a/FileSets/v3.40~33/startstop.py b/FileSets/v3.40~33/startstop.py deleted file mode 120000 index c18bce2d..00000000 --- a/FileSets/v3.40~33/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~37/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~33/styles.css b/FileSets/v3.40~33/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v3.40~33/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v3.40~34/Battery.qml b/FileSets/v3.40~34/Battery.qml deleted file mode 120000 index fafc7b36..00000000 --- a/FileSets/v3.40~34/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/COMPLETE b/FileSets/v3.40~34/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~34/DetailAcInput.qml b/FileSets/v3.40~34/DetailAcInput.qml deleted file mode 120000 index 8e76794d..00000000 --- a/FileSets/v3.40~34/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/DetailInverter.qml b/FileSets/v3.40~34/DetailInverter.qml deleted file mode 120000 index 285b3216..00000000 --- a/FileSets/v3.40~34/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/DetailLoadsCombined.qml b/FileSets/v3.40~34/DetailLoadsCombined.qml deleted file mode 120000 index 81c6de5a..00000000 --- a/FileSets/v3.40~34/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/DetailLoadsOnInput.qml b/FileSets/v3.40~34/DetailLoadsOnInput.qml deleted file mode 120000 index a5f97488..00000000 --- a/FileSets/v3.40~34/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/DetailLoadsOnOutput.qml b/FileSets/v3.40~34/DetailLoadsOnOutput.qml deleted file mode 120000 index 7cfc98c6..00000000 --- a/FileSets/v3.40~34/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/HubData.qml b/FileSets/v3.40~34/HubData.qml deleted file mode 120000 index c80a3bff..00000000 --- a/FileSets/v3.40~34/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/LINKS_ONLY b/FileSets/v3.40~34/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~34/MbEditBox.qml b/FileSets/v3.40~34/MbEditBox.qml deleted file mode 120000 index 90a92492..00000000 --- a/FileSets/v3.40~34/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/MbEditBoxDateTime.qml b/FileSets/v3.40~34/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v3.40~34/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/MbItem.qml b/FileSets/v3.40~34/MbItem.qml deleted file mode 120000 index 048a313c..00000000 --- a/FileSets/v3.40~34/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/MbItemDigitalInput.qml b/FileSets/v3.40~34/MbItemDigitalInput.qml deleted file mode 120000 index 4404b520..00000000 --- a/FileSets/v3.40~34/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/MbSpinBox.qml b/FileSets/v3.40~34/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v3.40~34/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/MbStyle.qml b/FileSets/v3.40~34/MbStyle.qml deleted file mode 120000 index d1940446..00000000 --- a/FileSets/v3.40~34/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/MbSubMenu.qml b/FileSets/v3.40~34/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v3.40~34/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/Multi.qml b/FileSets/v3.40~34/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v3.40~34/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/ObjectAcConnection.qml b/FileSets/v3.40~34/ObjectAcConnection.qml deleted file mode 120000 index cab7f2d4..00000000 --- a/FileSets/v3.40~34/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~34/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 6d1e56b5..00000000 --- a/FileSets/v3.40~34/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/OverviewBox.qml b/FileSets/v3.40~34/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v3.40~34/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/OverviewConnection.qml b/FileSets/v3.40~34/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v3.40~34/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/OverviewConnectionEnd.qml b/FileSets/v3.40~34/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v3.40~34/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/OverviewFlowComplex.qml b/FileSets/v3.40~34/OverviewFlowComplex.qml deleted file mode 120000 index a151db4f..00000000 --- a/FileSets/v3.40~34/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~34/OverviewGeneratorEnhanced.qml deleted file mode 120000 index 3bf44cf5..00000000 --- a/FileSets/v3.40~34/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~34/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index 1c9b530f..00000000 --- a/FileSets/v3.40~34/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/OverviewGridParallel.qml b/FileSets/v3.40~34/OverviewGridParallel.qml deleted file mode 120000 index d30a27d7..00000000 --- a/FileSets/v3.40~34/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/OverviewHub.qml b/FileSets/v3.40~34/OverviewHub.qml deleted file mode 120000 index 93c6ee1a..00000000 --- a/FileSets/v3.40~34/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/OverviewHubEnhanced.qml b/FileSets/v3.40~34/OverviewHubEnhanced.qml deleted file mode 120000 index c55515d9..00000000 --- a/FileSets/v3.40~34/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/OverviewMobileEnhanced.qml b/FileSets/v3.40~34/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.40~34/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/OverviewSolarCharger.qml b/FileSets/v3.40~34/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v3.40~34/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/OverviewSolarInverter.qml b/FileSets/v3.40~34/OverviewSolarInverter.qml deleted file mode 120000 index 4048703e..00000000 --- a/FileSets/v3.40~34/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/OverviewTankDelegate.qml b/FileSets/v3.40~34/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v3.40~34/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/OverviewTanks.qml b/FileSets/v3.40~34/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v3.40~34/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~34/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.40~34/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/PageDigitalInput.qml b/FileSets/v3.40~34/PageDigitalInput.qml deleted file mode 120000 index 5b768f8f..00000000 --- a/FileSets/v3.40~34/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/PageGenerator.qml b/FileSets/v3.40~34/PageGenerator.qml deleted file mode 120000 index 4ff1c509..00000000 --- a/FileSets/v3.40~34/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/PageMain.qml b/FileSets/v3.40~34/PageMain.qml deleted file mode 120000 index ef4b9c47..00000000 --- a/FileSets/v3.40~34/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/PageSettingsDisplay.qml b/FileSets/v3.40~34/PageSettingsDisplay.qml deleted file mode 120000 index 03766d99..00000000 --- a/FileSets/v3.40~34/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/PageSettingsGenerator.qml b/FileSets/v3.40~34/PageSettingsGenerator.qml deleted file mode 120000 index 15dd8f85..00000000 --- a/FileSets/v3.40~34/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/PageSettingsGuiMods.qml b/FileSets/v3.40~34/PageSettingsGuiMods.qml deleted file mode 120000 index e831a7a4..00000000 --- a/FileSets/v3.40~34/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/PageSettingsRelay.qml b/FileSets/v3.40~34/PageSettingsRelay.qml deleted file mode 120000 index 156aadac..00000000 --- a/FileSets/v3.40~34/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/PowerGauge.qml b/FileSets/v3.40~34/PowerGauge.qml deleted file mode 120000 index 4bcaaa4a..00000000 --- a/FileSets/v3.40~34/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/Tile.qml b/FileSets/v3.40~34/Tile.qml deleted file mode 120000 index 0558cecf..00000000 --- a/FileSets/v3.40~34/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/TileDigIn.qml b/FileSets/v3.40~34/TileDigIn.qml deleted file mode 120000 index 44616f30..00000000 --- a/FileSets/v3.40~34/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/TileRelay.qml b/FileSets/v3.40~34/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.40~34/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/TileText.qml b/FileSets/v3.40~34/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v3.40~34/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/dbus_digitalinputs.py b/FileSets/v3.40~34/dbus_digitalinputs.py deleted file mode 120000 index e74da5b6..00000000 --- a/FileSets/v3.40~34/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.40~34/dbus_generator.py b/FileSets/v3.40~34/dbus_generator.py deleted file mode 120000 index 0cd84ca3..00000000 --- a/FileSets/v3.40~34/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.40~34/main.qml b/FileSets/v3.40~34/main.qml deleted file mode 120000 index 5dbfdf83..00000000 --- a/FileSets/v3.40~34/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/main.qml \ No newline at end of file diff --git a/FileSets/v3.40~34/startstop.py b/FileSets/v3.40~34/startstop.py deleted file mode 120000 index c18bce2d..00000000 --- a/FileSets/v3.40~34/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~37/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~34/styles.css b/FileSets/v3.40~34/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v3.40~34/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v3.40~35/COMPLETE b/FileSets/v3.40~35/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~35/DetailAcInput.qml b/FileSets/v3.40~35/DetailAcInput.qml deleted file mode 120000 index 8e76794d..00000000 --- a/FileSets/v3.40~35/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~35/DetailInverter.qml b/FileSets/v3.40~35/DetailInverter.qml deleted file mode 120000 index 285b3216..00000000 --- a/FileSets/v3.40~35/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~35/DetailLoadsCombined.qml b/FileSets/v3.40~35/DetailLoadsCombined.qml deleted file mode 120000 index 81c6de5a..00000000 --- a/FileSets/v3.40~35/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.40~35/DetailLoadsOnInput.qml b/FileSets/v3.40~35/DetailLoadsOnInput.qml deleted file mode 120000 index a5f97488..00000000 --- a/FileSets/v3.40~35/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~35/DetailLoadsOnOutput.qml b/FileSets/v3.40~35/DetailLoadsOnOutput.qml deleted file mode 120000 index 7cfc98c6..00000000 --- a/FileSets/v3.40~35/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.40~35/HubData.qml b/FileSets/v3.40~35/HubData.qml deleted file mode 120000 index c80a3bff..00000000 --- a/FileSets/v3.40~35/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.40~35/LINKS_ONLY b/FileSets/v3.40~35/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~35/ObjectAcConnection.qml b/FileSets/v3.40~35/ObjectAcConnection.qml deleted file mode 120000 index cab7f2d4..00000000 --- a/FileSets/v3.40~35/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~35/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~35/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 6d1e56b5..00000000 --- a/FileSets/v3.40~35/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~35/OverviewFlowComplex.qml b/FileSets/v3.40~35/OverviewFlowComplex.qml deleted file mode 120000 index a151db4f..00000000 --- a/FileSets/v3.40~35/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.40~35/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~35/OverviewGeneratorEnhanced.qml deleted file mode 120000 index 3bf44cf5..00000000 --- a/FileSets/v3.40~35/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~35/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~35/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index 1c9b530f..00000000 --- a/FileSets/v3.40~35/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~35/OverviewGridParallel.qml b/FileSets/v3.40~35/OverviewGridParallel.qml deleted file mode 120000 index d30a27d7..00000000 --- a/FileSets/v3.40~35/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.40~35/OverviewHub.qml b/FileSets/v3.40~35/OverviewHub.qml deleted file mode 120000 index 93c6ee1a..00000000 --- a/FileSets/v3.40~35/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.40~35/OverviewHubEnhanced.qml b/FileSets/v3.40~35/OverviewHubEnhanced.qml deleted file mode 120000 index c55515d9..00000000 --- a/FileSets/v3.40~35/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~35/OverviewMobileEnhanced.qml b/FileSets/v3.40~35/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.40~35/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~35/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~35/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.40~35/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~35/PageGenerator.qml b/FileSets/v3.40~35/PageGenerator.qml deleted file mode 120000 index 4ff1c509..00000000 --- a/FileSets/v3.40~35/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~35/PageSettingsGenerator.qml b/FileSets/v3.40~35/PageSettingsGenerator.qml deleted file mode 120000 index 15dd8f85..00000000 --- a/FileSets/v3.40~35/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~35/PageSettingsGuiMods.qml b/FileSets/v3.40~35/PageSettingsGuiMods.qml deleted file mode 120000 index e831a7a4..00000000 --- a/FileSets/v3.40~35/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~35/PageSettingsRelay.qml b/FileSets/v3.40~35/PageSettingsRelay.qml deleted file mode 120000 index 156aadac..00000000 --- a/FileSets/v3.40~35/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~35/PowerGauge.qml b/FileSets/v3.40~35/PowerGauge.qml deleted file mode 120000 index 4bcaaa4a..00000000 --- a/FileSets/v3.40~35/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.40~35/TileDigIn.qml b/FileSets/v3.40~35/TileDigIn.qml deleted file mode 120000 index 44616f30..00000000 --- a/FileSets/v3.40~35/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~35/TileRelay.qml b/FileSets/v3.40~35/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.40~35/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~35/dbus_digitalinputs.py b/FileSets/v3.40~35/dbus_digitalinputs.py deleted file mode 120000 index e74da5b6..00000000 --- a/FileSets/v3.40~35/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.40~35/dbus_generator.py b/FileSets/v3.40~35/dbus_generator.py deleted file mode 120000 index 0cd84ca3..00000000 --- a/FileSets/v3.40~35/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.40~35/startstop.py b/FileSets/v3.40~35/startstop.py deleted file mode 120000 index c18bce2d..00000000 --- a/FileSets/v3.40~35/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~37/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~37/COMPLETE b/FileSets/v3.40~37/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~37/DetailAcInput.qml b/FileSets/v3.40~37/DetailAcInput.qml deleted file mode 120000 index 8e76794d..00000000 --- a/FileSets/v3.40~37/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~37/DetailInverter.qml b/FileSets/v3.40~37/DetailInverter.qml deleted file mode 120000 index 285b3216..00000000 --- a/FileSets/v3.40~37/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~37/DetailLoadsCombined.qml b/FileSets/v3.40~37/DetailLoadsCombined.qml deleted file mode 120000 index 81c6de5a..00000000 --- a/FileSets/v3.40~37/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.40~37/DetailLoadsOnInput.qml b/FileSets/v3.40~37/DetailLoadsOnInput.qml deleted file mode 120000 index a5f97488..00000000 --- a/FileSets/v3.40~37/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~37/DetailLoadsOnOutput.qml b/FileSets/v3.40~37/DetailLoadsOnOutput.qml deleted file mode 120000 index 7cfc98c6..00000000 --- a/FileSets/v3.40~37/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.40~37/HubData.qml b/FileSets/v3.40~37/HubData.qml deleted file mode 120000 index c80a3bff..00000000 --- a/FileSets/v3.40~37/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.40~37/ObjectAcConnection.qml b/FileSets/v3.40~37/ObjectAcConnection.qml deleted file mode 120000 index cab7f2d4..00000000 --- a/FileSets/v3.40~37/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~37/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~37/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 6d1e56b5..00000000 --- a/FileSets/v3.40~37/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~37/OverviewFlowComplex.qml b/FileSets/v3.40~37/OverviewFlowComplex.qml deleted file mode 120000 index a151db4f..00000000 --- a/FileSets/v3.40~37/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.40~37/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~37/OverviewGeneratorEnhanced.qml deleted file mode 120000 index 3bf44cf5..00000000 --- a/FileSets/v3.40~37/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~37/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~37/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index 1c9b530f..00000000 --- a/FileSets/v3.40~37/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~37/OverviewGridParallel.qml b/FileSets/v3.40~37/OverviewGridParallel.qml deleted file mode 120000 index d30a27d7..00000000 --- a/FileSets/v3.40~37/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.40~37/OverviewHub.qml b/FileSets/v3.40~37/OverviewHub.qml deleted file mode 120000 index 93c6ee1a..00000000 --- a/FileSets/v3.40~37/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.40~37/OverviewHubEnhanced.qml b/FileSets/v3.40~37/OverviewHubEnhanced.qml deleted file mode 120000 index c55515d9..00000000 --- a/FileSets/v3.40~37/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~37/OverviewMobileEnhanced.qml b/FileSets/v3.40~37/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.40~37/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~37/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~37/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.40~37/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~37/PageGenerator.qml b/FileSets/v3.40~37/PageGenerator.qml deleted file mode 120000 index 4ff1c509..00000000 --- a/FileSets/v3.40~37/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~37/PageSettingsGenerator.qml b/FileSets/v3.40~37/PageSettingsGenerator.qml deleted file mode 120000 index 15dd8f85..00000000 --- a/FileSets/v3.40~37/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~37/PageSettingsGuiMods.qml b/FileSets/v3.40~37/PageSettingsGuiMods.qml deleted file mode 120000 index e831a7a4..00000000 --- a/FileSets/v3.40~37/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~37/PageSettingsRelay.qml b/FileSets/v3.40~37/PageSettingsRelay.qml deleted file mode 120000 index 156aadac..00000000 --- a/FileSets/v3.40~37/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~37/PowerGauge.qml b/FileSets/v3.40~37/PowerGauge.qml deleted file mode 120000 index 4bcaaa4a..00000000 --- a/FileSets/v3.40~37/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.40~37/TileDigIn.qml b/FileSets/v3.40~37/TileDigIn.qml deleted file mode 120000 index 44616f30..00000000 --- a/FileSets/v3.40~37/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~37/TileRelay.qml b/FileSets/v3.40~37/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.40~37/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~37/dbus_digitalinputs.py b/FileSets/v3.40~37/dbus_digitalinputs.py deleted file mode 120000 index e74da5b6..00000000 --- a/FileSets/v3.40~37/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.40~37/dbus_generator.py b/FileSets/v3.40~37/dbus_generator.py deleted file mode 120000 index 0cd84ca3..00000000 --- a/FileSets/v3.40~37/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.40~37/startstop.py b/FileSets/v3.40~37/startstop.py deleted file mode 100644 index fcb79154..00000000 --- a/FileSets/v3.40~37/startstop.py +++ /dev/null @@ -1,1566 +0,0 @@ -#!/usr/bin/python -u -# -*- coding: utf-8 -*- - -#### GuiMods -#### This file has been modified to allow the generator running state derived from the generator digital input -#### or the genset AC input -#### If the incoming generator state changes, the manual start state is updated -#### time accumulation is suspended when the generator is not running -#### A switch in the generator settings menucontrols whethter the incoming state affects manual start or time accumulaiton -#### It is now possible to start the generator manually and have it stop automatically based on the preset conditions -#### for automaitc start / stop -#### A service interval timer was added so the accumulated run time does not need to be reset, -#### providing total run time for the generator -#### warm-up and cool-down periods have been modified in order to work well with an external transfer switch -#### selecting grid or generator ahead of a MultiPlus input. -#### Search for #### GuiMods to find changes - -# Function -# dbus_generator monitors the dbus for batteries (com.victronenergy.battery.*) and -# vebus com.victronenergy.vebus.* -# Battery and vebus monitors can be configured through the gui. -# It then monitors SOC, AC loads, battery current and battery voltage,to auto start/stop the generator based -# on the configuration settings. Generator can be started manually or periodically setting a tes trun period. -# Time zones function allows to use different values for the conditions along the day depending on time - -import dbus -import datetime -import calendar -import time -import sys -import json -import os -import logging -from collections import OrderedDict -import monotonic_time -from gen_utils import SettingsPrefix, Errors, States, enum -from gen_utils import create_dbus_service -# Victron packages -sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python')) -from ve_utils import exit_on_error -from settingsdevice import SettingsDevice - -RunningConditions = enum( - Stopped = 0, - Manual = 1, - TestRun = 2, - LossOfCommunication = 3, - Soc = 4, - Acload = 5, - BatteryCurrent = 6, - BatteryVoltage = 7, - InverterHighTemp = 8, - InverterOverload = 9, - StopOnAc1 = 10, - StopOnAc2 = 11) - -Capabilities = enum( - WarmupCooldown = 1 -) - -SYSTEM_SERVICE = 'com.victronenergy.system' -BATTERY_PREFIX = '/Dc/Battery' -HISTORY_DAYS = 30 -AUTOSTART_DISABLED_ALARM_TIME = 600 - -def safe_max(args): - try: - return max(x for x in args if x is not None) - except ValueError: - return None - -class Condition(object): - def __init__(self, parent): - self.parent = parent - self.reached = False - self.start_timer = 0 - self.stop_timer = 0 - self.valid = True - self.enabled = False - self.retries = 0 - - def __getitem__(self, key): - try: - return getattr(self, key) - except AttributeError: - raise KeyError(key) - - def __setitem__(self, key, value): - setattr(self, key, value) - - def get_value(self): - raise NotImplementedError("get_value") - - @property - def vebus_service(self): - return self.parent._vebusservice if self.parent._vebusservice else '' - - @property - def monitor(self): - return self.parent._dbusmonitor - -class SocCondition(Condition): - name = 'soc' - monitoring = 'battery' - boolean = False - timed = True - - def get_value(self): - return self.parent._get_battery().soc - -class AcLoadCondition(Condition): - name = 'acload' - monitoring = 'vebus' - boolean = False - timed = True - - def get_value(self): - loadOnAcOut = [] - totalConsumption = [] - - for phase in ['L1', 'L2', 'L3']: - # Get the values directly from the inverter, systemcalc doesn't provide raw inverted power - loadOnAcOut.append(self.monitor.get_value(self.vebus_service, ('/Ac/Out/%s/P' % phase))) - - # Calculate total consumption, '/Ac/Consumption/%s/Power' is deprecated - c_i = self.monitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnInput/%s/Power' % phase)) - c_o = self.monitor.get_value(SYSTEM_SERVICE, ('/Ac/ConsumptionOnOutput/%s/Power' % phase)) - totalConsumption.append(sum(filter(None, (c_i, c_o)))) - - # Invalidate if vebus is not available - if loadOnAcOut[0] == None: - return None - - # Total consumption - if self.parent._settings['acloadmeasurement'] == 0: - return sum(filter(None, totalConsumption)) - - # Load on inverter AC out - if self.parent._settings['acloadmeasurement'] == 1: - return sum(filter(None, loadOnAcOut)) - - # Highest phase load - if self.parent._settings['acloadmeasurement'] == 2: - return safe_max(loadOnAcOut) - -class BatteryCurrentCondition(Condition): - name = 'batterycurrent' - monitoring = 'battery' - boolean = False - timed = True - - def get_value(self): - c = self.parent._get_battery().current - if c is not None: - c *= -1 - return c - -class BatteryVoltageCondition(Condition): - name = 'batteryvoltage' - monitoring = 'battery' - boolean = False - timed = True - - def get_value(self): - return self.parent._get_battery().voltage - -class InverterTempCondition(Condition): - name = 'inverterhightemp' - monitoring = 'vebus' - boolean = True - timed = True - - def get_value(self): - v = self.monitor.get_value(self.vebus_service, - '/Alarms/HighTemperature') - - # When multi is connected to CAN-bus, alarms are published to - # /Alarms/HighTemperature... but when connected to vebus alarms are - # splitted in three phases and published to /Alarms/LX/HighTemperature... - if v is None: - inverterHighTemp = [] - for phase in ['L1', 'L2', 'L3']: - # Inverter alarms must be fetched directly from the inverter service - inverterHighTemp.append(self.monitor.get_value(self.vebus_service, ('/Alarms/%s/HighTemperature' % phase))) - return safe_max(inverterHighTemp) - return v - -class InverterOverloadCondition(Condition): - name = 'inverteroverload' - monitoring = 'vebus' - boolean = True - timed = True - - def get_value(self): - v = self.monitor.get_value(self.vebus_service, - '/Alarms/Overload') - - # When multi is connected to CAN-bus, alarms are published to - # /Alarms/Overload... but when connected to vebus alarms are - # splitted in three phases and published to /Alarms/LX/Overload... - if v is None: - inverterOverload = [] - for phase in ['L1', 'L2', 'L3']: - # Inverter alarms must be fetched directly from the inverter service - inverterOverload.append(self.monitor.get_value(self.vebus_service, ('/Alarms/%s/Overload' % phase))) - return safe_max(inverterOverload) - return v - -class StopOnAc1Condition(Condition): - name = 'stoponac1' - monitoring = 'vebus' - boolean = True - timed = False - - def get_value(self): - # AC input 1 - available = self.monitor.get_value(self.vebus_service, - '/Ac/State/AcIn1Available') - if available is None: - # Not supported in firmware, fall back to old behaviour - activein = self.monitor.get_value(self.vebus_service, - '/Ac/ActiveIn/ActiveInput') - - # Active input is connected - connected = self.monitor.get_value(self.vebus_service, - '/Ac/ActiveIn/Connected') - if None not in (activein, connected): - return activein == 0 and connected == 1 - return None - - return bool(available) - -class StopOnAc2Condition(Condition): - name = 'stoponac2' - monitoring = 'vebus' - boolean = True - timed = False - - def get_value(self): - # AC input 2 available (used when grid is on AC-in-2) - available = self.monitor.get_value(self.vebus_service, - '/Ac/State/AcIn2Available') - - return None if available is None else bool(available) - -class Battery(object): - def __init__(self, monitor, service, prefix): - self.monitor = monitor - self.service = service - self.prefix = prefix - - @property - def voltage(self): - return self.monitor.get_value(self.service, self.prefix + '/Voltage') - - @property - def current(self): - return self.monitor.get_value(self.service, self.prefix + '/Current') - - @property - def soc(self): - # Soc from the device doesn't have the '/Dc/0' prefix like the current and voltage do, but it does - # have the same prefix on systemcalc - return self.monitor.get_value(self.service, (BATTERY_PREFIX if self.prefix == BATTERY_PREFIX else '') + '/Soc') - -class StartStop(object): - _driver = None - def __init__(self, instance): -#### GuiMods - logging.info ("GuiMods version of startstop.py") - self._currentTime = 0 - self._last_update_mtime = 0 - self._accumulatedRunTime = 0 - self._digitalInputTypeObject = None - self._generatorInputStateObject = 0 - self._lastState = 0 - self._externalOverride = False - self._externalOverrideDelay = 99 - self._lastExternalOverride = False - self._searchDelay = 99 - self._linkToExternalState = False -#### GuiMods warm-up / cool-down - self._warmUpEndTime = 0 - self._coolDownEndTime = 0 - self._ac1isIgnored = False - self._ac2isIgnored = False - self._activeAcInIsIgnored = False - self._acInIsGenerator = False - - self._dbusservice = None - self._settings = None - self._dbusmonitor = None - self._remoteservice = None - self._name = None - self._enabled = False - self._instance = instance - - # One second per retry - self.RETRIES_ON_ERROR = 300 - self._testrun_soc_retries = 0 - self._last_counters_check = 0 - - self._starttime = 0 - self._stoptime = 0 # Used for cooldown - self._manualstarttimer = 0 - self._last_runtime_update = 0 - self._timer_runnning = 0 - - # The installer left autostart disabled - self._autostart_last_time = self._get_monotonic_seconds() - self._remote_start_mode_last_time = self._get_monotonic_seconds() - - - # Manual battery service selection is deprecated in favour - # of getting the values directly from systemcalc, we keep - # manual selected services handling for compatibility reasons. - self._vebusservice = None - self._errorstate = 0 - self._battery_service = None - self._battery_prefix = None - - self._acpower_inverter_input = { - 'timeout': 0, - 'unabletostart': False - } - - # Order is important. Conditions are evaluated in the order listed. - self._condition_stack = OrderedDict({ - SocCondition.name: SocCondition(self), - AcLoadCondition.name: AcLoadCondition(self), - BatteryCurrentCondition.name: BatteryCurrentCondition(self), - BatteryVoltageCondition.name: BatteryVoltageCondition(self), - InverterTempCondition.name: InverterTempCondition(self), - InverterOverloadCondition.name: InverterOverloadCondition(self), - StopOnAc1Condition.name: StopOnAc1Condition(self), - StopOnAc2Condition.name: StopOnAc2Condition(self) - }) - - def set_sources(self, dbusmonitor, settings, name, remoteservice): - self._settings = SettingsPrefix(settings, name) - self._dbusmonitor = dbusmonitor - self._remoteservice = remoteservice - self._name = name - - self.log_info('Start/stop instance created for %s.' % self._remoteservice) - self._remote_setup() - - def _create_service(self): - self._dbusservice = self._create_dbus_service() - - # The driver used for this start/stop service - self._dbusservice.add_path('/Type', value=self._driver) - # State: None = invalid, 0 = stopped, 1 = running, 2=Warm-up, 3=Cool-down - self._dbusservice.add_path('/State', value=None, gettextcallback=lambda p, v: States.get_description(v)) - # RunningByConditionCode: Numeric Companion to /RunningByCondition below, but - # also encompassing a Stopped state. - self._dbusservice.add_path('/RunningByConditionCode', value=None) - # Error - self._dbusservice.add_path('/Error', value=None, gettextcallback=lambda p, v: Errors.get_description(v)) - # Condition that made the generator start - self._dbusservice.add_path('/RunningByCondition', value=None) - # Runtime - self._dbusservice.add_path('/Runtime', value=None, gettextcallback=self._seconds_to_text) - # Today runtime - self._dbusservice.add_path('/TodayRuntime', value=None, gettextcallback=self._seconds_to_text) - # Test run runtime - self._dbusservice.add_path('/TestRunIntervalRuntime', value=None , gettextcallback=self._seconds_to_text) - # Next test run date, values is 0 for test run disabled - self._dbusservice.add_path('/NextTestRun', value=None, gettextcallback=lambda p, v: datetime.datetime.fromtimestamp(v).strftime('%c')) - # Next test run is needed 1, not needed 0 - self._dbusservice.add_path('/SkipTestRun', value=None) - # Manual start - self._dbusservice.add_path('/ManualStart', value=None, writeable=True) - # Manual start timer - self._dbusservice.add_path('/ManualStartTimer', value=None, writeable=True) - # Silent mode active - self._dbusservice.add_path('/QuietHours', value=None) - # Alarms - self._dbusservice.add_path('/Alarms/NoGeneratorAtAcIn', value=None) - self._dbusservice.add_path('/Alarms/ServiceIntervalExceeded', value=None) - self._dbusservice.add_path('/Alarms/AutoStartDisabled', value=None) - self._dbusservice.add_path('/Alarms/RemoteStartModeDisabled', value=None) - # Autostart - self._dbusservice.add_path('/AutoStartEnabled', value=None, writeable=True, onchangecallback=self._set_autostart) - # Accumulated runtime - self._dbusservice.add_path('/AccumulatedRuntime', value=None) - # Service interval - self._dbusservice.add_path('/ServiceInterval', value=None) - # Capabilities, where we can add bits - self._dbusservice.add_path('/Capabilities', value=0) - # Service countdown, calculated by running time and service interval - self._dbusservice.add_path('/ServiceCounter', value=None) - self._dbusservice.add_path('/ServiceCounterReset', value=None, writeable=True, onchangecallback=self._reset_service_counter) - # Publish what service we're controlling, and the productid - self._dbusservice.add_path('/GensetService', value=self._remoteservice) - self._dbusservice.add_path('/GensetInstance', - value=self._dbusmonitor.get_value(self._remoteservice, '/DeviceInstance')) - self._dbusservice.add_path('/GensetProductId', - value=self._dbusmonitor.get_value(self._remoteservice, '/ProductId')) - - # We need to set the values after creating the paths to trigger the 'onValueChanged' event for the gui - # otherwise the gui will report the paths as invalid if we remove and recreate the paths without - # restarting the dbusservice. - self._dbusservice['/State'] = 0 - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped - self._dbusservice['/Error'] = 0 - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/Runtime'] = 0 - self._dbusservice['/TodayRuntime'] = 0 - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - self._dbusservice['/NextTestRun'] = None - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/ProductName'] = "Generator start/stop" - self._dbusservice['/ManualStart'] = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._dbusservice['/QuietHours'] = 0 - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - self._dbusservice['/Alarms/ServiceIntervalExceeded'] = 0 - self._dbusservice['/Alarms/AutoStartDisabled'] = 0 # GX auto start/stop - self._dbusservice['/Alarms/RemoteStartModeDisabled'] = 0 # Genset remote start mode - self._dbusservice['/AutoStartEnabled'] = self._settings['autostart'] - self._dbusservice['/AccumulatedRuntime'] = int(self._settings['accumulatedtotal']) - self._dbusservice['/ServiceInterval'] = int(self._settings['serviceinterval']) - self._dbusservice['/ServiceCounter'] = None - self._dbusservice['/ServiceCounterReset'] = 0 - -#### GuiMods - # generator input running state - self._dbusservice.add_path('/GeneratorRunningState', value=None) - # external override active - self._dbusservice.add_path('/ExternalOverride', value=None) - self._dbusservice['/GeneratorRunningState'] = "?" - self._dbusservice['/ExternalOverride'] = False - self._ignoreAutoStartCondition = False - - - @property - def capabilities(self): - return self._dbusservice['/Capabilities'] - - def _set_autostart(self, path, value): - if 0 <= value <= 1: - self._settings['autostart'] = int(value) - return True - return False - - def enable(self): - if self._enabled: - return - self.log_info('Enabling auto start/stop and taking control of remote switch') - self._create_service() - self._determineservices() - self._update_remote_switch() - # If cooldown or warmup is enabled, the Quattro may be left in a bad - # state if there is an unfortunate crash or a reboot. Set the ignore_ac - # flag to a sane value on startup. - if self._settings['cooldowntime'] > 0 or \ - self._settings['warmuptime'] > 0: - self._set_ignore_ac(False) ########### - self._enabled = True - - def disable(self): - if not self._enabled: - return - self.log_info('Disabling auto start/stop, releasing control of remote switch') - self._remove_service() - self._enabled = False - - def remove(self): - self.disable() - self.log_info('Removed from start/stop instances') - - def _remove_service(self): - self._dbusservice.__del__() - self._dbusservice = None - - def device_added(self, dbusservicename, instance): - self._determineservices() - - def device_removed(self, dbusservicename, instance): - self._determineservices() - - def get_error(self): - return self._dbusservice['/Error'] - - def set_error(self, errorn): - self._dbusservice['/Error'] = errorn - - def clear_error(self): - self._dbusservice['/Error'] = Errors.NONE - - def dbus_value_changed(self, dbusServiceName, dbusPath, options, changes, deviceInstance): - if self._dbusservice is None: - return - - # AcIn1Available is needed to determine capabilities, but may - # only show up later. So we have to wait for it here. - if self._vebusservice is not None and \ - dbusServiceName == self._vebusservice and \ - dbusPath == '/Ac/State/AcIn1Available': - self._set_capabilities() - - if dbusServiceName != 'com.victronenergy.system': - return - if dbusPath == '/AutoSelectedBatteryMeasurement' and self._settings['batterymeasurement'] == 'default': - self._determineservices() - - if dbusPath == '/VebusService': - self._determineservices() - - def handlechangedsetting(self, setting, oldvalue, newvalue): - if self._dbusservice is None: - return - if self._name not in setting: - # Not our setting - return - - s = self._settings.removeprefix(setting) - - if s == 'batterymeasurement': - self._determineservices() - # Reset retries and valid if service changes - for condition in self._condition_stack.values(): - if condition['monitoring'] == 'battery': - condition['valid'] = True - condition['retries'] = 0 - - if s == 'autostart': - self.log_info('Autostart function %s.' % ('enabled' if newvalue == 1 else 'disabled')) - self._dbusservice['/AutoStartEnabled'] = self._settings['autostart'] - - if self._dbusservice is not None and s == 'testruninterval': - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime( - self._settings['testruninterval']) - - if s == 'serviceinterval': - try: - self._dbusservice['/ServiceInterval'] = int(newvalue) - except TypeError: - pass - if newvalue == 0: - self._dbusservice['/ServiceCounter'] = None - else: - self._update_accumulated_time() - if s == 'lastservicereset': - self._update_accumulated_time() - - def _reset_service_counter(self, path, value): - if (path == '/ServiceCounterReset' and value == int(1) and self._dbusservice['/AccumulatedRuntime']): - self._settings['lastservicereset'] = self._dbusservice['/AccumulatedRuntime'] - self._update_accumulated_time() - self.log_info('Service counter reset triggered.') - - return True - - def _seconds_to_text(self, path, value): - m, s = divmod(value, 60) - h, m = divmod(m, 60) - return '%dh, %dm, %ds' % (h, m, s) - - def log_info(self, msg): - logging.info(self._name + ': %s' % msg) - - def tick(self): - if not self._enabled: - return - -#### GuiMods warm-up / cool-down - self._currentTime = self._get_monotonic_seconds () - - self._check_remote_status() -#### GuiMods - self._linkToExternalState = self._settings['linkManualStartToExternal'] == 1 - self._processGeneratorRunDetection () - - self._evaluate_startstop_conditions() - self._evaluate_autostart_disabled_alarm() - self._detect_generator_at_acinput() - if self._dbusservice['/ServiceCounterReset'] == 1: - self._dbusservice['/ServiceCounterReset'] = 0 - -#### GuiMods warm-up / cool-down - state = self._dbusservice['/State'] - - # shed load for active generator input in warm-up and cool-down - # note that external transfer switch might change the state of on generator - # so this needs to be checked and load adjusted every pass - # restore load for sources no longer in use or if state is not in warm-up/cool-down - # restoring load is delayed 1following end of cool-down - # to allow the generator to actually stop producing power - if state in (States.WARMUP, States.COOLDOWN, States.STOPPING): - self._set_ignore_ac (True) - else: - self._set_ignore_ac (False) - - # update cool down end time while running and generator has the load - # this is done because acInIsGenerator may change by an external transfer switch - # and we want an accurate picture of the cool down end time - # based on the last time the generatot was loaded - if state == States.RUNNING and self._acInIsGenerator: - self._coolDownEndTime = self._currentTime + self._settings['cooldowntime'] -#### end GuiMods warm-up / cool-down - - - def _evaluate_startstop_conditions(self): - if self.get_error() != Errors.NONE: - # First evaluation after an error, log it - if self._errorstate == 0: - self._errorstate = 1 - self._dbusservice['/State'] = States.ERROR - self.log_info('Error: #%i - %s, stop controlling remote.' % - (self.get_error(), - Errors.get_description(self.get_error()))) - elif self._errorstate == 1: - # Error cleared - self._errorstate = 0 - self._dbusservice['/State'] = States.STOPPED - self.log_info('Error state cleared, taking control of remote switch.') - - start = False - startbycondition = None - activecondition = self._dbusservice['/RunningByCondition'] - today = calendar.timegm(datetime.date.today().timetuple()) - self._timer_runnning = False - connection_lost = False - running = self._dbusservice['/State'] in (States.RUNNING, States.WARMUP) - - self._check_quiet_hours() - - # New day, register it - if self._last_counters_check < today and self._dbusservice['/State'] == States.STOPPED: - self._last_counters_check = today - self._update_accumulated_time() - - # Update current and accumulated runtime. -#### GuiMods - self._accumulateRunTime () - -#### GuiMods - # A negative /ManualStartTimer is used by the GUI to signal the generator should start now - # but stop when all auto stop conditions have been met - # so we skip manual start evaluation if this is the case - # and set a flag for use below to ignore auto start conditions - # the generator is actually started by the auto start/stop logic below - if self._dbusservice['/ManualStartTimer'] < 0 and self._dbusservice['/ManualStart'] == 1: - self._dbusservice['/ManualStartTimer'] = 0 - self._dbusservice['/ManualStart'] = 0 - self._ignoreAutoStartCondition = True - - else: - self._ignoreAutoStartCondition = False - if self._evaluate_manual_start(): - startbycondition = 'manual' - start = True - - # Conditions will only be evaluated if the autostart functionality is enabled - if self._settings['autostart'] == 1: - - if self._evaluate_testrun_condition(): - startbycondition = 'testrun' - start = True - - # Evaluate stop on AC IN conditions first, when this conditions are enabled and reached the generator - # will stop as soon as AC IN in active. Manual and testrun conditions will make the generator start - # or keep it running. - stop_on_ac_reached = (self._evaluate_condition(self._condition_stack[StopOnAc1Condition.name]) or - self._evaluate_condition(self._condition_stack[StopOnAc2Condition.name])) - stop_by_ac1_ac2 = startbycondition not in ['manual', 'testrun'] and stop_on_ac_reached - - if stop_by_ac1_ac2 and running and activecondition not in ['manual', 'testrun']: - self.log_info('AC input available, stopping') - - # Evaluate value conditions - for condition, data in self._condition_stack.items(): - # Do not evaluate rest of conditions if generator is configured to stop - # when AC IN is available - if stop_by_ac1_ac2: - start = False - if running: - self._reset_condition(data) - continue - else: - break - - # Don't short-circuit this, _evaluate_condition sets .reached - start = self._evaluate_condition(data) or start - startbycondition = condition if start and startbycondition is None else startbycondition - # Connection lost is set to true if the number of retries of one or more enabled conditions - # >= RETRIES_ON_ERROR - if data.enabled: - connection_lost = data.retries >= self.RETRIES_ON_ERROR - - # If none condition is reached check if connection is lost and start/keep running the generator - # depending on '/OnLossCommunication' setting - if not start and connection_lost: - # Start always - if self._settings['onlosscommunication'] == 1: - start = True - startbycondition = 'lossofcommunication' - # Keep running if generator already started - if running and self._settings['onlosscommunication'] == 2: - start = True - startbycondition = 'lossofcommunication' - -#### GuiMods - ## auto start disabled and generator is stopped - clear the 'reached' flags - elif self._dbusservice['/State'] == States.STOPPED: - for condition, data in self._condition_stack.items(): - self._reset_condition(data) - - if not start and self._errorstate: - self._stop_generator() - - if self._errorstate: - return - - if start: - self._start_generator(startbycondition) -#### GuiMods - # bypass the minimum run time check if External Override is active - elif (self._dbusservice['/Runtime'] >= self._settings['minimumruntime'] * 60 - or activecondition == 'manual') or self._dbusservice['/ExternalOverride']: - self._stop_generator() - - def _evaluate_autostart_disabled_alarm(self): - - if self._settings['autostartdisabledalarm'] == 0: - self._autostart_last_time = self._get_monotonic_seconds() - self._remote_start_mode_last_time = self._get_monotonic_seconds() - if self._dbusservice['/Alarms/AutoStartDisabled'] != 0: - self._dbusservice['/Alarms/AutoStartDisabled'] = 0 - if self._dbusservice['/Alarms/RemoteStartModeDisabled'] != 0: - self._dbusservice['/Alarms/RemoteStartModeDisabled'] = 0 - return - - # GX auto start/stop alarm - if self._settings['autostart'] == 1: - self._autostart_last_time = self._get_monotonic_seconds() - if self._dbusservice['/Alarms/AutoStartDisabled'] != 0: - self._dbusservice['/Alarms/AutoStartDisabled'] = 0 - else: - timedisabled = self._get_monotonic_seconds() - self._autostart_last_time - if timedisabled > AUTOSTART_DISABLED_ALARM_TIME and self._dbusservice['/Alarms/AutoStartDisabled'] != 2: - self.log_info("Autostart was left for more than %i seconds, triggering alarm." % int(timedisabled)) - self._dbusservice['/Alarms/AutoStartDisabled'] = 2 - - # Genset remote start mode alarm - if self.get_error() != Errors.REMOTEDISABLED: - self._remote_start_mode_last_time = self._get_monotonic_seconds() - if self._dbusservice['/Alarms/RemoteStartModeDisabled'] != 0: - self._dbusservice['/Alarms/RemoteStartModeDisabled'] = 0 - else: - timedisabled = self._get_monotonic_seconds() - self._remote_start_mode_last_time - if timedisabled > AUTOSTART_DISABLED_ALARM_TIME and self._dbusservice['/Alarms/RemoteStartModeDisabled'] != 2: - self.log_info("Autostart was left for more than %i seconds, triggering alarm." % int(timedisabled)) - self._dbusservice['/Alarms/RemoteStartModeDisabled'] = 2 - - -#### GuiMods warm-up / cool-down - rewrote so acInIsGenerator is updated even if alarm is disabled - def _detect_generator_at_acinput(self): -#### GuiMods warm-up / cool-down - self._acInIsGenerator = False # covers all conditions that result in a return - - state = self._dbusservice['/State'] - if state in [States.STOPPED, States.COOLDOWN, States.WARMUP]: - self._reset_acpower_inverter_input() - return - - vebus_service = self._vebusservice if self._vebusservice else '' - activein_state = self._dbusmonitor.get_value( - vebus_service, '/Ac/ActiveIn/Connected') - - # Path not supported, skip evaluation - if activein_state == None: - return - - # Sources 0 = Not available, 1 = Grid, 2 = Generator, 3 = Shore - generator_acsource = self._dbusmonitor.get_value( - SYSTEM_SERVICE, '/Ac/ActiveIn/Source') == 2 - # Not connected = 0, connected = 1 - activein_connected = activein_state == 1 - -#### GuiMods warm-up / cool-down - if self._settings['nogeneratoratacinalarm'] == 0: - processAlarm = False - self._reset_acpower_inverter_input() - else: - processAlarm = True - - if generator_acsource and activein_connected: -#### GuiMods warm-up / cool-down - self._acInIsGenerator = True -#### GuiMods warm-up / cool-down - if processAlarm and self._acpower_inverter_input['unabletostart']: - self.log_info('Generator detected at inverter AC input, alarm removed') - self._reset_acpower_inverter_input() -#### GuiMods warm-up / cool-down - elif not processAlarm: - self._reset_acpower_inverter_input() - return - elif self._acpower_inverter_input['timeout'] < self.RETRIES_ON_ERROR: - self._acpower_inverter_input['timeout'] += 1 - elif not self._acpower_inverter_input['unabletostart']: - self._acpower_inverter_input['unabletostart'] = True - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 2 - self.log_info('Generator not detected at inverter AC input, triggering alarm') - - - def _reset_acpower_inverter_input(self, clear_error=True): - if self._acpower_inverter_input['timeout'] != 0: - self._acpower_inverter_input['timeout'] = 0 - - if self._acpower_inverter_input['unabletostart'] != 0: - self._acpower_inverter_input['unabletostart'] = 0 - - self._dbusservice['/Alarms/NoGeneratorAtAcIn'] = 0 - - def _reset_condition(self, condition): - condition['reached'] = False - if condition['timed']: - condition['start_timer'] = 0 - condition['stop_timer'] = 0 - - def _check_condition(self, condition, value): - name = condition['name'] - - if self._settings[name + 'enabled'] == 0: - if condition['enabled']: - condition['enabled'] = False - self.log_info('Disabling (%s) condition' % name) - condition['retries'] = 0 - condition['valid'] = True - self._reset_condition(condition) - return False - - elif not condition['enabled']: - condition['enabled'] = True - self.log_info('Enabling (%s) condition' % name) - - if (condition['monitoring'] == 'battery') and (self._settings['batterymeasurement'] == 'nobattery'): - # If no battery monitor is selected reset the condition - self._reset_condition(condition) - return False - - if value is None and condition['valid']: - if condition['retries'] >= self.RETRIES_ON_ERROR: - logging.info('Error getting (%s) value, skipping evaluation till get a valid value' % name) - self._reset_condition(condition) - self._comunnication_lost = True - condition['valid'] = False - else: - condition['retries'] += 1 - if condition['retries'] == 1 or (condition['retries'] % 10) == 0: - self.log_info('Error getting (%s) value, retrying(#%i)' % (name, condition['retries'])) - return False - - elif value is not None and not condition['valid']: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['valid'] = True - condition['retries'] = 0 - - # Reset retries if value is valid - if value is not None and condition['retries'] > 0: - self.log_info('Success getting (%s) value, resuming evaluation' % name) - condition['retries'] = 0 - - return condition['valid'] - - def _evaluate_condition(self, condition): - name = condition['name'] - value = condition.get_value() - setting = ('qh_' if self._dbusservice['/QuietHours'] == 1 else '') + name - startvalue = self._settings[setting + 'start'] if not condition['boolean'] else 1 - stopvalue = self._settings[setting + 'stop'] if not condition['boolean'] else 0 - - # Check if the condition has to be evaluated - if not self._check_condition(condition, value): - # If generator is started by this condition and value is invalid - # wait till RETRIES_ON_ERROR to skip the condition - if condition['reached'] and condition['retries'] <= self.RETRIES_ON_ERROR: - if condition['retries'] > 0: - return True - - return False - - # As this is a generic evaluation method, we need to know how to compare the values - # first check if start value should be greater than stop value and then compare - start_is_greater = startvalue > stopvalue - -#### GuiMods - stop = value <= stopvalue if start_is_greater else value >= stopvalue - # when starting manually and stopping based on auto stop values, - # start if stop condition is not satisfied - - if self._ignoreAutoStartCondition: - start = not stop - else: - # When the condition is already reached only the stop value can set it to False - start = condition['reached'] or (value >= startvalue if start_is_greater else value <= startvalue) - - # Timed conditions must start/stop after the condition has been reached for a minimum - # time. - if condition['timed']: - if not condition['reached'] and start: - condition['start_timer'] += time.time() if condition['start_timer'] == 0 else 0 - start = time.time() - condition['start_timer'] >= self._settings[name + 'starttimer'] - condition['stop_timer'] *= int(not start) - self._timer_runnning = True - else: - condition['start_timer'] = 0 - - if condition['reached'] and stop: - condition['stop_timer'] += time.time() if condition['stop_timer'] == 0 else 0 - stop = time.time() - condition['stop_timer'] >= self._settings[name + 'stoptimer'] - condition['stop_timer'] *= int(not stop) - self._timer_runnning = True - else: - condition['stop_timer'] = 0 - - condition['reached'] = start and not stop - return condition['reached'] - - def _evaluate_manual_start(self): - if self._dbusservice['/ManualStart'] == 0: - if self._dbusservice['/RunningByCondition'] == 'manual': - self._dbusservice['/ManualStartTimer'] = 0 - return False - - start = True - # If /ManualStartTimer has a value greater than zero will use it to set a stop timer. - # If no timer is set, the generator will not stop until the user stops it manually. - # Once started by manual start, each evaluation the timer is decreased -#### GuiMods - if self._dbusservice['/ManualStartTimer'] > 0: - self._manualstarttimer += time.time() if self._manualstarttimer == 0 else 0 - self._dbusservice['/ManualStartTimer'] -= int(time.time()) - int(self._manualstarttimer) - self._manualstarttimer = time.time() - start = self._dbusservice['/ManualStartTimer'] > 0 - self._dbusservice['/ManualStart'] = int(start) - # Reset if timer is finished - self._manualstarttimer *= int(start) - self._dbusservice['/ManualStartTimer'] *= int(start) - - return start - - def _evaluate_testrun_condition(self): - if self._settings['testrunenabled'] == 0: - self._dbusservice['/SkipTestRun'] = None - self._dbusservice['/NextTestRun'] = None - return False - - today = datetime.date.today() - yesterday = today - datetime.timedelta(days=1) # Should deal well with DST - now = time.time() - runtillbatteryfull = self._settings['testruntillbatteryfull'] == 1 - soc = self._condition_stack['soc'].get_value() - batteryisfull = runtillbatteryfull and soc == 100 - duration = 60 if runtillbatteryfull else self._settings['testrunruntime'] - - try: - startdate = datetime.date.fromtimestamp(self._settings['testrunstartdate']) - _starttime = time.mktime(yesterday.timetuple()) + self._settings['testrunstarttimer'] - - # today might in fact still be yesterday, if this test run started - # before midnight and finishes after. If `now` still falls in - # yesterday's window, then by the temporal anthropic principle, - # which I just made up but loosely states that time must have - # these properties for observers to exist, it must be yesterday - # because we are here to observe it. - if _starttime <= now <= _starttime + duration: - today = yesterday - starttime = _starttime - else: - starttime = time.mktime(today.timetuple()) + self._settings['testrunstarttimer'] - except ValueError: - logging.debug('Invalid dates, skipping testrun') - return False - - # If start date is in the future set as NextTestRun and stop evaluating - if startdate > today: - self._dbusservice['/NextTestRun'] = time.mktime(startdate.timetuple()) - return False - - start = False - # If the accumulated runtime during the tes trun interval is greater than '/TestRunIntervalRuntime' - # the tes trun must be skipped - needed = (self._settings['testrunskipruntime'] > self._dbusservice['/TestRunIntervalRuntime'] - or self._settings['testrunskipruntime'] == 0) - self._dbusservice['/SkipTestRun'] = int(not needed) - - interval = self._settings['testruninterval'] - stoptime = starttime + duration - elapseddays = (today - startdate).days - mod = elapseddays % interval - - start = not bool(mod) and starttime <= now <= stoptime - - if runtillbatteryfull: - if soc is not None: - self._testrun_soc_retries = 0 - start = (start or self._dbusservice['/RunningByCondition'] == 'testrun') and not batteryisfull - elif self._dbusservice['/RunningByCondition'] == 'testrun': - if self._testrun_soc_retries < self.RETRIES_ON_ERROR: - self._testrun_soc_retries += 1 - start = True - if (self._testrun_soc_retries % 10) == 0: - self.log_info('Test run failed to get SOC value, retrying(#%i)' % self._testrun_soc_retries) - else: - self.log_info('Failed to get SOC after %i retries, terminating test run condition' % self._testrun_soc_retries) - start = False - else: - start = False - - if not bool(mod) and (now <= stoptime): - self._dbusservice['/NextTestRun'] = starttime - else: - self._dbusservice['/NextTestRun'] = (time.mktime((today + datetime.timedelta(days=interval - mod)).timetuple()) + - self._settings['testrunstarttimer']) - return start and needed - - def _check_quiet_hours(self): - active = False - if self._settings['quiethoursenabled'] == 1: - # Seconds after today 00:00 - timeinseconds = time.time() - time.mktime(datetime.date.today().timetuple()) - quiethoursstart = self._settings['quiethoursstarttime'] - quiethoursend = self._settings['quiethoursendtime'] - - # Check if the current time is between the start time and end time - if quiethoursstart < quiethoursend: - active = quiethoursstart <= timeinseconds and timeinseconds < quiethoursend - else: # End time is lower than start time, example Start: 21:00, end: 08:00 - active = not (quiethoursend < timeinseconds and timeinseconds < quiethoursstart) - - if self._dbusservice['/QuietHours'] == 0 and active: - self.log_info('Entering to quiet mode') - - elif self._dbusservice['/QuietHours'] == 1 and not active: - self.log_info('Leaving quiet mode') - - self._dbusservice['/QuietHours'] = int(active) - - return active - - def _update_accumulated_time(self): - seconds = self._dbusservice['/Runtime'] - accumulated = seconds - self._last_runtime_update - - self._settings['accumulatedtotal'] = accumulatedtotal = int(self._settings['accumulatedtotal']) + accumulated - # Using calendar to get timestamp in UTC, not local time - today_date = str(calendar.timegm(datetime.date.today().timetuple())) - - # If something goes wrong getting the json string create a new one - try: - accumulated_days = json.loads(self._settings['accumulateddaily']) - except ValueError: - accumulated_days = {today_date: 0} - - if (today_date in accumulated_days): - accumulated_days[today_date] += accumulated - else: - accumulated_days[today_date] = accumulated - - self._last_runtime_update = seconds - - # Keep the historical with a maximum of HISTORY_DAYS - while len(accumulated_days) > HISTORY_DAYS: - accumulated_days.pop(min(accumulated_days.keys()), None) - - # Upadate settings - self._settings['accumulateddaily'] = json.dumps(accumulated_days, sort_keys=True) - self._dbusservice['/TodayRuntime'] = self._interval_runtime(0) - self._dbusservice['/TestRunIntervalRuntime'] = self._interval_runtime(self._settings['testruninterval']) - self._dbusservice['/AccumulatedRuntime'] = accumulatedtotal - - # Service counter - serviceinterval = self._settings['serviceinterval'] - lastservicereset = self._settings['lastservicereset'] - if serviceinterval > 0: - servicecountdown = (lastservicereset + serviceinterval) - accumulatedtotal - self._dbusservice['/ServiceCounter'] = servicecountdown - if servicecountdown <= 0: - self._dbusservice['/Alarms/ServiceIntervalExceeded'] = 1 - elif self._dbusservice['/Alarms/ServiceIntervalExceeded'] != 0: - self._dbusservice['/Alarms/ServiceIntervalExceeded'] = 0 - - - - def _interval_runtime(self, days): - summ = 0 - try: - daily_record = json.loads(self._settings['accumulateddaily']) - except ValueError: - return 0 - - for i in range(days + 1): - previous_day = calendar.timegm((datetime.date.today() - datetime.timedelta(days=i)).timetuple()) - if str(previous_day) in daily_record.keys(): - summ += daily_record[str(previous_day)] if str(previous_day) in daily_record.keys() else 0 - - return summ - - def _get_battery(self): - if self._settings['batterymeasurement'] == 'default': - return Battery(self._dbusmonitor, SYSTEM_SERVICE, BATTERY_PREFIX) - - return Battery(self._dbusmonitor, - self._battery_service if self._battery_service else '', - self._battery_prefix if self._battery_prefix else '') - - def _set_capabilities(self): - # Update capabilities - # The ability to ignore AC1/AC2 came in at the same time as - # AC availability and is used to detect it here. - readout_supported = self._dbusmonitor.get_value(self._vebusservice, - '/Ac/State/AcIn1Available') is not None - self._dbusservice['/Capabilities'] |= ( - Capabilities.WarmupCooldown if readout_supported else 0) - - def _determineservices(self): - # batterymeasurement is either 'default' or 'com_victronenergy_battery_288/Dc/0'. - # In case it is set to default, we use the AutoSelected battery - # measurement, given by SystemCalc. - batterymeasurement = None - newbatteryservice = None - batteryprefix = '' - selectedbattery = self._settings['batterymeasurement'] - vebusservice = None - - if selectedbattery == 'default': - batterymeasurement = 'default' - elif len(selectedbattery.split('/', 1)) == 2: # Only very basic sanity checking.. - batterymeasurement = self._settings['batterymeasurement'] - elif selectedbattery == 'nobattery': - batterymeasurement = None - else: - # Exception: unexpected value for batterymeasurement - pass - - if batterymeasurement and batterymeasurement != 'default': - batteryprefix = '/' + batterymeasurement.split('/', 1)[1] - - # Get the current battery servicename - if self._battery_service: - oldservice = self._battery_service - else: - oldservice = None - - if batterymeasurement != 'default': - battery_instance = int(batterymeasurement.split('_', 3)[3].split('/')[0]) - service_type = None - - if 'vebus' in batterymeasurement: - service_type = 'vebus' - elif 'battery' in batterymeasurement: - service_type = 'battery' - - newbatteryservice = self._get_servicename_by_instance(battery_instance, service_type) - elif batterymeasurement == 'default': - newbatteryservice = 'default' - - if newbatteryservice and newbatteryservice != oldservice: - if selectedbattery == 'default': - self.log_info('Getting battery values from systemcalc.') - if selectedbattery == 'nobattery': - self.log_info('Battery monitoring disabled! Stop evaluating related conditions') - self._battery_service = None - self._battery_prefix = None - self.log_info('Battery service we need (%s) found! Using it for generator start/stop' % batterymeasurement) - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - elif not newbatteryservice and newbatteryservice != oldservice: - self.log_info('Error getting battery service!') - self._battery_service = newbatteryservice - self._battery_prefix = batteryprefix - - # Get the default VE.Bus service - vebusservice = self._dbusmonitor.get_value('com.victronenergy.system', '/VebusService') - if vebusservice: - if self._vebusservice != vebusservice: - self._vebusservice = vebusservice - self._set_capabilities() - self.log_info('Vebus service (%s) found! Using it for generator start/stop' % vebusservice) - else: - if self._vebusservice is not None: - self.log_info('Vebus service (%s) dissapeared! Stop evaluating related conditions' % self._vebusservice) - else: - self.log_info('Error getting Vebus service!') - self._vebusservice = None - - def _get_servicename_by_instance(self, instance, service_type=None): - sv = None - services = self._dbusmonitor.get_service_list() - - for service in services: - if service_type and service_type not in service: - continue - - if services[service] == instance: - sv = service - break - - return sv - - def _get_monotonic_seconds(self): - return monotonic_time.monotonic_time().to_seconds_double() - - def _start_generator(self, condition): - state = self._dbusservice['/State'] - remote_running = self._get_remote_switch_state() - - # This function will start the generator in the case generator not - # already running. When differs, the RunningByCondition is updated - running = state in (States.WARMUP, States.COOLDOWN, States.STOPPING, States.RUNNING) - if not (running and remote_running): # STOPPED, ERROR -#### GuiMods warm-up / cool-down - self.log_info('Starting generator by %s condition' % condition) - # if there is a warmup time specified, always go through warm-up state - # regardless of AC input in use - warmUpPeriod = self._settings['warmuptime'] - if warmUpPeriod > 0: - self._warmUpEndTime = self._currentTime + warmUpPeriod - self.log_info ("starting warm-up") - self._dbusservice['/State'] = States.WARMUP - # no warm-up go directly to running - else: - self._dbusservice['/State'] = States.RUNNING - self._warmUpEndTime = 0 - - self._coolDownEndTime = 0 - self._stoptime = 0 - - self._update_remote_switch() - else: # WARMUP, COOLDOWN, RUNNING, STOPPING - if state in (States.COOLDOWN, States.STOPPING): - # Start request during cool-down run, go back to RUNNING - self.log_info ("aborting cool-down - returning to running") - self._dbusservice['/State'] = States.RUNNING - - elif state == States.WARMUP: - if self._currentTime > self._warmUpEndTime: - self.log_info ("warm-up complete") - self._dbusservice['/State'] = States.RUNNING - - # Update the RunningByCondition - if self._dbusservice['/RunningByCondition'] != condition: - self.log_info('Generator previously running by %s condition is now running by %s condition' - % (self._dbusservice['/RunningByCondition'], condition)) -#### end GuiMods warm-up / cool-down - - - self._dbusservice['/RunningByCondition'] = condition - self._dbusservice['/RunningByConditionCode'] = RunningConditions.lookup(condition) - - - def _stop_generator(self): - state = self._dbusservice['/State'] - remote_running = self._get_remote_switch_state() - running = state in (States.WARMUP, States.COOLDOWN, States.STOPPING, States.RUNNING) - - if running or remote_running: -#### GuiMods warm-up / cool-down - if state == States.RUNNING: - state = States.COOLDOWN - if self._currentTime < self._coolDownEndTime: - self.log_info ("starting cool-down") - elif self._settings['cooldowntime'] != 0: - self.log_info ("skipping cool-down -- no AC load on generator") - - # warm-up should also transition to stopping - # cool-down time will have expired since it's set to 0 when starting - # and there has not yet been a load on the generator - if state in (States.WARMUP, States.COOLDOWN): - # cool down complete - if self._currentTime > self._coolDownEndTime: - state = States.STOPPING - self.log_info('Stopping generator that was running by %s condition' % - str(self._dbusservice['/RunningByCondition'])) - self._update_remote_switch() # Stop engine - self._stoptime = self._currentTime + self._settings['generatorstoptime'] - if self._currentTime < self._stoptime: - self.log_info ("waiting for generator so stop") - - if state == States.STOPPING: - # wait for stop period expired - finish up transition to STOPPED - if self._currentTime > self._stoptime: - if self._settings['generatorstoptime'] != 0: - self.log_info ("generator stop time reached - OK to reconnect AC") - state = States.STOPPED - self._update_remote_switch() - self._dbusservice['/RunningByCondition'] = '' - self._dbusservice['/RunningByConditionCode'] = RunningConditions.Stopped - self._update_accumulated_time() - self._starttime = 0 - self._dbusservice['/Runtime'] = 0 - self._dbusservice['/ManualStartTimer'] = 0 - self._manualstarttimer = 0 - self._last_runtime_update = 0 - - self._dbusservice['/State'] = state -#### end GuiMods warm-up / cool-down - - - @property - def _ac1_is_generator(self): - return self._dbusmonitor.get_value('com.victronenergy.settings', - '/Settings/SystemSetup/AcInput1') == 2 - - @property - def _ac2_is_generator(self): - return self._dbusmonitor.get_value('com.victronenergy.settings', - '/Settings/SystemSetup/AcInput2') == 2 - - def _set_ignore_ac(self, ignore): - # This is here so the Multi/Quattro can be told to disconnect AC-in, - # so that we can do warm-up and cool-down. -#### GuiMods warm-up / cool-down - # stock code does not handle changes in the input type - # which could happen with an external transfer switch - # doing things this way should handle it - - self._activeAcInIsIgnored = ignore - ignore1 = False - ignore2 = False - if self._ac1_is_generator: - ignore1 = ignore - elif self._ac2_is_generator: - ignore2 = ignore - - if ignore1 != self._ac1isIgnored: - if ignore1: - self.log_info ("shedding load - AC input 1") - else: - self.log_info ("restoring load - AC input 1") - self._dbusmonitor.set_value_async(self._vebusservice, '/Ac/Control/IgnoreAcIn1', dbus.Int32(ignore1, variant_level=1)) - self._ac1isIgnored = ignore1 - - if ignore2 != self._ac2isIgnored: - if ignore2: - self.log_info ("shedding load - AC input 2") - else: - self.log_info ("restoring load - AC input 2") - self._dbusmonitor.set_value_async(self._vebusservice, '/Ac/Control/IgnoreAcIn2', dbus.Int32(ignore2, variant_level=1)) - self._ac2isIgnored = ignore2 -#### end GuiMods warm-up / cool-down - - - def _update_remote_switch(self): - # Engine should be started in these states - v = self._dbusservice['/State'] in (States.RUNNING, States.WARMUP, States.COOLDOWN) - self._set_remote_switch_state(dbus.Int32(v, variant_level=1)) -#### GuiMods - if v == True: - self.log_info ("updating remote switch to running") - else: - self.log_info ("updating remote switch to stopped") - - def _get_remote_switch_state(self): - raise Exception('This function should be overridden') - - def _set_remote_switch_state(self, value): - raise Exception('This function should be overridden') - - # Check the remote status, for example errors - def _check_remote_status(self): - raise Exception('This function should be overridden') - - def _remote_setup(self): - raise Exception('This function should be overridden') - - def _create_dbus_monitor(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_settings(self, *args, **kwargs): - raise Exception('This function should be overridden') - - def _create_dbus_service(self): - return create_dbus_service(self._instance) - - -#### GuiMods - -# this function connects the generator digital input (if any) -# OR the generator AC input detection -# to the generator /ManualStart and updates dbus paths used by the GUI -# -# if the generator digital input changes from stopped to running -# AND no run conditions are active, a manual start is innitiated -# -# if the generator digital input changes from running to stopped -# AND a manual start is active, a manual stop is innitiated -# -# /GeneratorRunningState provides the input running state from the digital input to the GUI -# R = running -# S = stopped -# ? = unknown (no digital input found) -# -# /ExternalOverride is used by the GUI to alert the user when there is a conflict -# between the generator running state and the state Venus -# /ExternalOverride is True if /GeneratorRunningState is S -# AND the /RunningCondition is not stopped (which includes a manual run) -# activation is delayed 5 seconds to allow transitions to settle -# -# we must first find the geneator digital input, if it exists at all -# we serche all dBus services looking for a digital input with type generator (9) -# the search only occurs every 10 seconds -# - - def _processGeneratorRunDetection (self): - TheBus = dbus.SystemBus() - generatorState = self._dbusservice['/State'] - try: - # current input service is no longer valid - # search for a new one only every 10 seconds to avoid unnecessary processing - if (self._digitalInputTypeObject == None or self._digitalInputTypeObject.GetValue() != 9) and self._searchDelay > 10: - newInputService = "" - for service in TheBus.list_names(): - # found a digital input servic, now check the type - if service.startswith ("com.victronenergy.digitalinput"): - self._digitalInputTypeObject = TheBus.get_object (service, '/Type') - # found it! - if self._digitalInputTypeObject.GetValue() == 9: - newInputService = service - break - - # found new service - get objects for use later - if newInputService != "": - self.log_info ("Found generator digital input service at %s" % newInputService) - self._generatorInputStateObject = TheBus.get_object(newInputService, '/State') - else: - if self._generatorInputStateObject != None: - self.log_info ("Generator digital input service NOT found") - self._generatorInputStateObject = None - self._digitalInputTypeObject = None - self._searchDelay = 0 # start delay timer - - # if serch delay timer is active, increment it now - if self._searchDelay <= 10: - self._searchDelay += 1 - - - # collect generator input states - inputState = '?' - # if generator digital input is present, use that - if self._generatorInputStateObject != None: - inputState = self._generatorInputStateObject.GetValue () - if inputState == 10: - inputState = 'R' - elif inputState == 11: - inputState = 'S' - # otherwise use generator AC input to determine running state - # use frequency as the test for generator running - elif self._ac1_is_generator or self._ac2_is_generator: - try: - if self._dbusmonitor.get_value (SYSTEM_SERVICE, '/Ac/Genset/Frequency') > 20: - inputState = 'R' - else: - inputState = 'S' - except: - pass - - # update /GeneratorRunningState - if inputState != self._lastState: - self._dbusservice['/GeneratorRunningState'] = inputState - - # forward input state changes to /ManualStart - if self._linkToExternalState: - if inputState == "R" and generatorState == States.STOPPED: - self.log_info ("generator was started externally - syncing ManualStart state") - self._dbusservice['/ManualStart'] = 1 - elif inputState == "S" and self._dbusservice['/ManualStart'] == 1 \ - and generatorState in (States.RUNNING, States.WARMUP, States.COOLDOWN): - self.log_info ("generator was stopped externally - syncing ManualStart state") - self._dbusservice['/ManualStart'] = 0 - - # update /ExternalOverride - if inputState == "S" and self._linkToExternalState and generatorState == States.RUNNING: - if self._externalOverrideDelay > 5: - self._externalOverride = True - else: - self._externalOverrideDelay += 1 - else: - self._externalOverride = False - self._externalOverrideDelay = 0 - - if self._externalOverride != self._lastExternalOverride: - self._dbusservice['/ExternalOverride'] = self._externalOverride - self._lastExternalOverride = self._externalOverride - - except dbus.DBusException: - self.log_info ("dbus exception - generator digital input no longer valid") - self._generatorInputStateObject = None - self._digitalInputTypeObject = None - inputState = 0 - - self._lastState = inputState - - -# -# control the accumulaiton of run time based on generator input Running state -# if the internal state is RUNNING run time is accumulated in self._accumulatedRunTime -# run time is accumulated if the generator's running state is known to be running or -# if the generator running state can't be determined -# the accumulated time dBus parameter and daily and total time accumulators are updated -# only once everh 60 seconds to minimize processor load -# if the internal state is STOPPED, one last dBus, daily and total time updates are done -# then the current time accumulator is cleared - - def _accumulateRunTime (self): - - # grab running state from dBus once, use it many timed below - - if self._dbusservice['/State'] in (States.RUNNING, States.WARMUP, States.COOLDOWN, States.STOPPING): ########## - internalRun = True - else: - internalRun = False - - # if internal state is running, accumulate time if generator is running - if internalRun: - accumuateTime = True - # start new accumulation if not done prevously - if self._last_accumulate_time == 0: - self._last_accumulate_time = self._currentTime - - # if link to external state is enabled, don't accumulate time if running state is stopped - # (accumulate if R or ?) - if self._linkToExternalState: - try: - if self._dbusservice['/GeneratorRunningState'] == 'S': - accumuateTime = False - - # if no Forwarder service, allow accumulation - except dbus.DBusException: - self.log_info ("dBus exception in startstop.py") - - # internal state STOPPED so don't add new time to the accumulation - # but there may be time already accumulated that needs to be added to daily and total accumulations - else: - accumuateTime = False - - # accumulate run time if we passed all the tests above - if accumuateTime: - self._accumulatedRunTime += self._currentTime - self._last_accumulate_time - self._last_accumulate_time = self._currentTime - - # dbus and settings updates trigger time-intensive processing so only do this once every 60 seconds - doUpdate = False - if internalRun: - if self._currentTime - self._last_update_mtime >= 60: - doUpdate = True - self._last_update_mtime = self._currentTime - # it is also done one last time when state is no longer RUNNING - elif self._last_update_mtime != 0: - doUpdate = True - - if doUpdate: - self._update_accumulated_time() - - # stopped - clear the current time accumulator - if internalRun == False: - self._last_update_mtime = 0 - self._accumulatedRunTime = 0 - self._last_accumulate_time = 0 - - self._dbusservice['/Runtime'] = int(self._accumulatedRunTime) -#### end GuiMods diff --git a/FileSets/v3.40~39/COMPLETE b/FileSets/v3.40~39/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~39/DetailAcInput.qml b/FileSets/v3.40~39/DetailAcInput.qml deleted file mode 100644 index d2865e4a..00000000 --- a/FileSets/v3.40~39/DetailAcInput.qml +++ /dev/null @@ -1,606 +0,0 @@ -////// detail page for setting input current limit -////// and displaying AC input details -////// pushed from Flow overview - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 -import "enhancedFormat.js" as EnhFmt - -MbPage { - id: root - - title: "AC Input detail" - - property variant sys: theSystem - property string systemPrefix: "com.victronenergy.system" - property string settingsPrefix: "com.victronenergy.settings" - - property int fontPixelSize: 18 - property color buttonColor: "#979797" - property color pressedColor: "#d3d3d3" - property color backgroundColor: "#b3b3b3" - - property int buttonHeight: 40 - - property int dataColumns: 4 - property int rowTitleWidth: 100 - property int totalDataWidth: 340 - rowTitleWidth - property int tableColumnWidth: totalDataWidth / dataColumns - - property int legColumnWidth: phaseCount <= 1 ? tableColumnWidth * 3 : tableColumnWidth * 3 / phaseCount - - property int phaseCount: sys.acInput.phaseCount.valid ? sys.acInput.phaseCount.value : 0 - - VBusItem { id: vebusServiceItem; bind: Utils.path(systemPrefix, "/VebusService") } - property string inverterService: vebusServiceItem.valid ? vebusServiceItem.value : "" - property bool splitPhasePassthruDisabled: sys.acInput.splitPhaseL2PassthruDisabled - - property real actualCurrentLimit: 0 - property real newCurrentLimit: 0 - - VBusItem { id: acLimitPreset1Item; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/AcCurrentLimit/Preset1") } - VBusItem { id: acLimitPreset2Item; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/AcCurrentLimit/Preset2") } - VBusItem { id: acLimitPreset3Item; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/AcCurrentLimit/Preset3") } - VBusItem { id: acLimitPreset4Item; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/AcCurrentLimit/Preset4") } - property real acLimitPreset1: acLimitPreset1Item.valid ? acLimitPreset1Item.value : 0 - property real acLimitPreset2: acLimitPreset2Item.valid ? acLimitPreset2Item.value : 0 - property real acLimitPreset3: acLimitPreset3Item.valid ? acLimitPreset3Item.value : 0 - property real acLimitPreset4: acLimitPreset4Item.valid ? acLimitPreset4Item.value : 0 - - property bool currentLimitIsAdjustable: currentLimitIsAdjustableItem.valid && currentLimitIsAdjustableItem.value == 1 && currentLimitItem.valid - - Component.onCompleted: { getActualCurrent () } - - VBusItem - { - id: currentLimitIsAdjustableItem - bind: Utils.path(inverterService, "/Ac/ActiveIn/CurrentLimitIsAdjustable") - onValueChanged: getActualCurrent () - onValidChanged: getActualCurrent () - } - VBusItem - { - id: currentLimitItem - bind: Utils.path(inverterService, "/Ac/ActiveIn/CurrentLimit") - onValueChanged: getActualCurrent () - onValidChanged: getActualCurrent () - } - VBusItem { id: activeInputItem; bind: Utils.path(inverterService, "/Ac/ActiveIn/ActiveInput") } - VBusItem { id: numberOfAcInputs; bind: Utils.path(inverterService, "/Ac/In/NumberOfAcInputs") } - VBusItem { id: activeSourceItem; bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") } - VBusItem { id: acIn1sourceItem; bind: Utils.path(settingsPrefix, "/Settings/SystemSetup/AcInput1") } - VBusItem { id: acIn2sourceItem; bind: Utils.path(settingsPrefix, "/Settings/SystemSetup/AcInput2") } - property int activeSource: activeSourceItem.valid ? activeSourceItem.value : 0 - property int acIn1source: acIn1sourceItem.valid ? acIn1sourceItem.value : 0 - property int acIn2source: acIn2sourceItem.valid ? acIn2sourceItem.value : 0 - property int activeInput: activeInputItem.valid && activeInputItem.value == 1 ? 2 : 1 - property bool hasTwoInputs: numberOfAcInputs.valid && numberOfAcInputs.value == 2 - - property variant acSourceName: [qsTr("---"), qsTr("Grid"), qsTr("Generator"), qsTr("Shore")] - - // background - Rectangle - { - anchors - { - fill: parent - } - color: root.backgroundColor - } - - Row - { - spacing: 5 - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - width: parent.width - 6 - Column - { - spacing: 2 - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Total Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.power, "W") - } - PowerGauge - { - id: gauge - width: totalDataWidth - tableColumnWidth - height: 15 - connection: sys.acInput - useInputCurrentLimit: true - maxForwardPowerParameter: "" // handled internally - uses input current limit and AC input voltage - maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxFeedInPower" - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + tableColumnWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Active Source") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth - tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: - { - if (activeSource == 240) - return quTr ("no input") - else if (hasTwoInputs) - return acSourceName[activeSource] + " (AC in " + activeInput + ")" - else - return acSourceName[activeSource] - } - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L1" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L2"; visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L3"; visible: phaseCount >= 3 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: qsTr ("Freq") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.powerL1, "W") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.acInput.powerL2, "W"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.powerL3, "W"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Voltage / Freq") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.voltageL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.acInput.voltageL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.voltageL3, "V"); visible: phaseCount >= 3 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.frequency, "Hz") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.currentL1, "A") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.acInput.currentL2, "A"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.currentL3, "A"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("CurrentLimit") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: - { - var newText - if (newCurrentLimit != actualCurrentLimit) - newText = qsTr(" New ") + newCurrentLimit.toFixed (1) + " A" - else - newText = "" - return currentLimitItem.valid ? currentLimitItem.value.toFixed (1) + " A" + newText: "--" } - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: "L2 values included in L1" - visible: splitPhasePassthruDisabled } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: qsTr("Avaliable Sources") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L1" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L2"; visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L3"; visible: phaseCount >= 3 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: qsTr ("Freq") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: 20; horizontalAlignment: Text.AlignHCenter - text: activeSource == 1 || activeSource == 3 ? ">" : "" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth - 20; horizontalAlignment: Text.AlignRight - text: - { - if (acIn1source == 3 || acIn2source == 3) - return acSourceName[3] - else - return acSourceName[1] - } - } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.grid.voltageL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.grid.voltageL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.grid.voltageL3, "V"); visible: phaseCount >= 3 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.grid.frequency, "Hz") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: 20; horizontalAlignment: Text.AlignHCenter - text: activeSource == 2 ? ">" : "" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth - 20; horizontalAlignment: Text.AlignRight - text: acSourceName[2] } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.genset.voltageL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.genset.voltageL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.genset.voltageL3, "V"); visible: phaseCount >= 3 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.genset.frequency, "Hz") } - } - } - Column - { - id: currentButtonColumn - width: 128 - spacing: 4 - - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: currentButtonColumn.width; horizontalAlignment: Text.AlignHCenter - text: qsTr("Current Limit") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: currentButtonColumn.width; horizontalAlignment: Text.AlignHCenter - text: qsTr("is not adjustable")} - visible: !currentLimitIsAdjustable - } - Row - { - visible: currentLimitIsAdjustable - width: (parent.width / 2) - 2 - spacing: 4 - DetailButton - { - id: preset1button - baseColor: newCurrentLimit === acLimitPreset1 ? "black" : root.buttonColor - pressedColor: root.pressedColor - opacity: acLimitPreset1 === 0 ? 0.001 : 1 - height: 40 - width: parent.width - onClicked: setNewValue (acLimitPreset1) - enabled: acLimitPreset1 === 0 ? false : true - content: TileText - { - text: qsTr(acLimitPreset1 + " A"); font.bold: true; - color: "white" - } - } - DetailButton - { - id: preset2button - baseColor: newCurrentLimit === acLimitPreset2 ? "black" : root.buttonColor - pressedColor: root.pressedColor - opacity: acLimitPreset2 === 0 ? 0.001 : 1 - height: 40 - width: parent.width - onClicked: setNewValue (acLimitPreset2) - enabled: acLimitPreset2 === 0 ? false : true - content: TileText - { - text: qsTr(acLimitPreset2 + " A"); font.bold: true; - color: "white" - } - } - } - Row - { - visible: currentLimitIsAdjustable - width: (parent.width / 2) - 2 - spacing: 4 - DetailButton - { - id: preset3button - baseColor: newCurrentLimit === acLimitPreset3 ? "black" : root.buttonColor - pressedColor: root.pressedColor - opacity: acLimitPreset3 === 0 ? 0.001 : 1 - height: 40 - width: parent.width - onClicked: setNewValue (acLimitPreset3) - enabled: acLimitPreset3 === 0 ? false : true - content: TileText - { - text: qsTr(acLimitPreset3 + " A"); font.bold: true; - color: "white" - } - } - DetailButton - { - visible: currentLimitIsAdjustable - id: preset4button - baseColor: newCurrentLimit === acLimitPreset4 ? "black" : root.buttonColor - pressedColor: root.pressedColor - opacity: acLimitPreset4 === 0 ? 0.001 : 1 - height: 40 - width: parent.width - onClicked: setNewValue (acLimitPreset4) - enabled: acLimitPreset4 === 0 ? false : true - content: TileText - { - text: qsTr(acLimitPreset4 + " A"); font.bold: true; - color: "white" - } - } - } - Row - { - visible: currentLimitIsAdjustable - width: (parent.width / 2) - 2 - spacing: 4 - DetailButton - { - id: trimMinus - baseColor: root.buttonColor - pressedColor: root.pressedColor - height: 40 - width: parent.width - enablePressAndHold: true - onClicked: trimNewValue (-1) - enabled: newCurrentLimit === acLimitPreset4 ? false : true - content: TileText - { - text: qsTr("-1 A"); font.bold: true; - color: "white" - } - } - DetailButton - { - id: trimPlus - baseColor: root.buttonColor - pressedColor: root.pressedColor - height: 40 - width: parent.width - enablePressAndHold: true - onClicked: trimNewValue (+1) - content: TileText - { - text: qsTr("+1 A"); font.bold: true; - color: "white" - } - } - } - Row - { - visible: currentLimitIsAdjustable - width: parent.width - spacing: 4 - DetailButton - { - id: acceptButton - baseColor: root.buttonColor - pressedColor: root.pressedColor - height: 40 - width: parent.width - onClicked: accept() - content: TileText { text: qsTr ("Accept New"); - font.bold: true; color: newCurrentLimit !== actualCurrentLimit ? "white" : "#d9d9d9" } - } - } - } - } - - function setNewValue (newValue) - { - if (currentLimitIsAdjustable) - newCurrentLimit = newValue - } - - function trimNewValue (trimValue) - { - if (!currentLimitIsAdjustable) - return - - newCurrentLimit += trimValue - if (newCurrentLimit < 0) - newCurrentLimit = 0 - } - - function cancel () - { - newCurrentLimit = actualCurrentLimit - pageStack.pop() - } - - function accept () - { - if (currentLimitIsAdjustable) - { - currentLimitItem.setValue (newCurrentLimit) - pageStack.pop() // return to main screen after changing input current limit - } - } - - function getActualCurrent () - { - actualCurrentLimit = currentLimitItem.valid ? currentLimitItem.value : 0 - newCurrentLimit = actualCurrentLimit - } - - // When new service is found check if is a tank sensor - Connections - { - target: DBusServices - onDbusServiceFound: addService(service) - } - - //// hard key handler - // used to press buttons when touch isn't available - // UP and DOWN buttons cycle through the list of buttons - // "space" button is used to simulate a button press - // button must be highlighted so that other uses of "space" - // will still occur - - // list of buttons to be accessed via hard buttons - property variant buttonList: - [ - preset1button, preset2button, preset3button, preset4button, trimMinus, trimPlus, acceptButton - ] - - property int buttonIndex: 0 - - Timer - { - id: targetTimer - interval: 5000 - repeat: false - running: false - onTriggered: { clearHighlight () } - } - - Keys.forwardTo: [keyHandler] - - Item - { - id: keyHandler - Keys.onDownPressed: - { - nextTarget (+1) - event.accepted = true - } - - Keys.onUpPressed: - { - nextTarget (-1) - event.accepted = true - } - } - - function nextTarget (increment) - { - // make one pass through all possible targets to find an enabled one - // if found, that's the new selectedTarget, - // if not selectedTarget does not change - var newIndex = buttonIndex - for (var i = 0; i < buttonList.length; i++) - { - // just restore highlight if not visible - if ( ! targetTimer.running && buttonList[newIndex].visible) - { - setActiveButton (buttonIndex) - return - } - newIndex += increment - if (newIndex >= buttonList.length) - newIndex = 0 - else if (newIndex < 0) - newIndex = buttonList.length - 1 - if (buttonList[newIndex].visible) - { - setActiveButton (newIndex) - break - } - } - } - - // Keys.onSpacePressed doesn't work - stolen by pageHandler - // so build a custom page handler so "space" can be used to press a button - pageToolbarHandler: detailToolbarHandler - ToolbarHandlerPages - { - id: detailToolbarHandler - isDefault: true - function centerAction() - { - acceptSpaceButton () - } - } - - function acceptSpaceButton () - { - if (targetTimer.running) - { - buttonList[buttonIndex].clicked () - } - } - - function setActiveButton (newIndex) - { - buttonIndex = newIndex - for (var i = 0; i < buttonList.length; i++) - if (i == newIndex) - buttonList[i].highlight = true - else - buttonList[i].highlight = false - targetTimer.restart () - } - - function clearHighlight () - { - for (var i = 0; i < buttonList.length; i++) - buttonList[i].highlight = false - } -} diff --git a/FileSets/v3.40~39/DetailInverter.qml b/FileSets/v3.40~39/DetailInverter.qml deleted file mode 100644 index fd7e9def..00000000 --- a/FileSets/v3.40~39/DetailInverter.qml +++ /dev/null @@ -1,653 +0,0 @@ -////// detail page for setting inverter mode -////// and displaying inverter details -////// pushed from Flow overview - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 -import "enhancedFormat.js" as EnhFmt - -MbPage { - id: root - - title: "Inverter detail" - - property variant sys: theSystem - property string systemPrefix: "com.victronenergy.system" - - property int fontPixelSize: 18 - property color buttonColor: "#979797" - property color pressedColor: "#d3d3d3" - property color backgroundColor: "#b3b3b3" - - property int inverterMode: inverterModeItem.valid ? inverterModeItem.value : 0 - property bool editable: inverterService != "" && inverterModeItem.valid - - property int buttonHeight: 40 - property int buttonWidth: 72 - property int buttonAreaWidth: buttonWidth * 2 + 4 - - property int rowTitleWidth: 132 - property int dataColumns: 3 - property int totalDataWidth: root.width - rowTitleWidth - buttonAreaWidth - 12 - property int tableColumnWidth: totalDataWidth / dataColumns - property int legColumnWidth: phaseCount <= 1 ? totalDataWidth : totalDataWidth / phaseCount - - property int numberOfMultis: 0 - property int numberOfInverters: 0 - property string inverterService: "" - property bool isInverter: numberOfMultis === 0 && numberOfInverters === 1 - - Component.onCompleted: { discoverServices(); highlightMode () } - - property bool showChargePriority: numberOfMultis > 0 && sys.preferRenewableEnergy.valid - property bool preferRenewableEnergy: showChargePriority && sys.preferRenewableEnergy.value == 1 - property bool autoReturnToRenewable: sys.remoteGeneratorSelected.valid - property bool acInIsGenerator: sys.acSource == 2 - - VBusItem - { - id: inverterModeItem - bind: Utils.path(inverterService, "/Mode") - onValidChanged: highlightMode () - onValueChanged: highlightMode () - } - property VBusItem systemState: VBusItem { bind: Utils.path(systemPrefix, "/SystemState/State") } - SystemState - { - id: vebusState - bind: systemState.valid ? Utils.path(systemPrefix, "/SystemState/State") : Utils.path(inverterService, "/State") - } - VBusItem { id: pInL1; bind: Utils.path(inverterService, "/Ac/ActiveIn/L1/P") } - VBusItem { id: pInL2; bind: Utils.path(inverterService, "/Ac/ActiveIn/L2/P") } - VBusItem { id: pInL3; bind: Utils.path(inverterService, "/Ac/ActiveIn/L2/P") } - VBusItem { id: vInL1; bind: Utils.path(inverterService, "/Ac/ActiveIn/L1/V") } - VBusItem { id: vInL2; bind: Utils.path(inverterService, "/Ac/ActiveIn/L2/V") } - VBusItem { id: vInL3; bind: Utils.path(inverterService, "/Ac/ActiveIn/L3/V") } - VBusItem { id: iInL1; bind: Utils.path(inverterService, "/Ac/ActiveIn/L1/I") } - VBusItem { id: iInL2; bind: Utils.path(inverterService, "/Ac/ActiveIn/L2/I") } - VBusItem { id: iInL3; bind: Utils.path(inverterService, "/Ac/ActiveIn/L3/I") } - VBusItem { id: pOutL1; bind: Utils.path(inverterService, "/Ac/Out/L1/P") } - VBusItem { id: pOutL2; bind: Utils.path(inverterService, "/Ac/Out/L2/P") } - VBusItem { id: pOutL3; bind: Utils.path(inverterService, "/Ac/Out/L3/P") } - VBusItem { id: vOutL1; bind: Utils.path(inverterService, "/Ac/Out/L1/V") } - VBusItem { id: vOutL2; bind: Utils.path(inverterService, "/Ac/Out/L2/V") } - VBusItem { id: vOutL3; bind: Utils.path(inverterService, "/Ac/Out/L3/V") } - VBusItem { id: iOutL1; bind: Utils.path(inverterService, "/Ac/Out/L1/I") } - VBusItem { id: iOutL2; bind: Utils.path(inverterService, "/Ac/Out/L2/I") } - VBusItem { id: iOutL3; bind: Utils.path(inverterService, "/Ac/Out/L3/I") } - VBusItem { id: fInL1; bind: Utils.path(inverterService, "/Ac/ActiveIn/L1/F") } - VBusItem { id: fOutL1; bind: Utils.path(inverterService, "/Ac/Out/L1/F") } - VBusItem { id: dcPower; bind: Utils.path(inverterService, "/Dc/0/Power") } - VBusItem { id: dcCurrent; bind: Utils.path(inverterService, "/Dc/0/Current") } - VBusItem { id: _l2L1OutSummed; bind: Utils.path(inverterService, "/Ac/State/SplitPhaseL2L1OutSummed") } - VBusItem { id: phaseCountItem; bind: Utils.path(inverterService, "/Ac/NumberOfPhases") } - - property bool noL2inverter: _l2L1OutSummed.valid - property bool l2AndL1OutSummed: noL2inverter && _l2L1OutSummed.value === 1 - property int phaseCount: phaseCountItem.valid ? phaseCountItem.value : 0 - - // background - Rectangle - { - anchors - { - fill: parent - } - color: root.backgroundColor - } - - Column - { - spacing: 2 - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left; anchors.leftMargin: 3 - Row - { - PowerGaugeMulti - { - id: gauge - width: rowTitleWidth + totalDataWidth - height: 15 - inverterService: root.inverterService - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Total Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: - { - var total = 0 - var totalValid = false - if (pOutL1.valid && pInL1.valid) - { - total += pOutL1.value - pInL1.value - totalValid = true - } - if (pOutL2.valid && pInL2.valid) - { - total += pOutL2.value - pInL2.value - totalValid = true - } - if (pOutL3.valid && pInL3.valid) - { - total += pOutL3.value - pInL3.value - totalValid = true - } - if (totalValid) - return EnhFmt.formatValue (total, "W") - else - return "--" - } - } - visible: phaseCount >= 2 - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("State") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: vebusState.text } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: "" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L1" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L2" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L3"; visible: phaseCount >= 3 } - visible: phaseCount >= 2 - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: formatValueDiff (pOutL1, pInL1, "W") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: - { - if (l2AndL1OutSummed) - return "< < <" - else if (noL2inverter) - return qsTr("none") - else - return formatValueDiff (pOutL2, pInL2, "W") - } - visible: phaseCount >= 2 - } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: formatValueDiff (pOutL3, pInL3, "W"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Input Voltage") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (vInL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (vInL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (vInL3, "V"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Output Voltage") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (vOutL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (vOutL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (vOutL3, "V"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Input Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (iInL1, "A") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (iInL2, "A"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (iInL3, "A"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Output Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (iOutL1, "A") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l2AndL1OutSummed ? "< < <" : EnhFmt.formatVBusItem (iOutL2, "A"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (iOutL3, "A"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Frequency In / Out") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth / 2; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (fInL1, "Hz") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth / 2; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (fOutL1, "Hz") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("DC Power / Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth * 0.4; horizontalAlignment: Text.AlignHCenter - text: - { - if (! dcPower.valid) - return "" - else if (dcPower.value > 0) - return qsTr ("supplying") - else if (dcPower.value < 0) - return qsTr ("consuming") - else - return "" - } - } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth * 0.3; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (dcPower, "W") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth * 0.3; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (dcCurrent, "A") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: l2AndL1OutSummed ? qsTr ("L2 Output values included in L1") : qsTr ("L2 AC out from AC in (no inverter)") - visible: noL2inverter - } - } - } - Column - { - id: inverterModeButtonArea - width: root.buttonAreaWidth - anchors.top: parent.top; anchors.topMargin: 3 - anchors.right: parent.right; anchors.rightMargin: 3 - spacing: 4 - - Row - { - Text - { - font.pixelSize: 12; color: "black" - width: root.buttonAreaWidth; horizontalAlignment: Text.AlignHCenter - text: qsTr("Inverter mode") - visible: showChargePriority - } - } - Row - { - spacing: 4 - DetailButton - { - id: onButton - baseColor: inverterMode === 3 ? "green" : "#e6ffe6" - pressedColor: root.pressedColor - height: root.buttonHeight - width: root.buttonWidth - visible: !isInverter - onClicked: changeMode(3) - content: TileText - { - text: qsTr("On"); font.bold: true; - color: inverterMode === 3 ? "white" : "gray" - } - } - DetailButton - { - id: offButton - baseColor: inverterMode === 4 ? "black" : "#e6e6e6" - pressedColor: root.pressedColor - height: root.buttonHeight - width: root.buttonWidth - onClicked: changeMode(4) - content: TileText - { - text: qsTr("Off"); font.bold: true; - color: inverterMode === 4 ? "white" : "gray" - } - } - } - Row - { - spacing: 4 - DetailButton - { - id: invertOnlyButton - baseColor: inverterMode === 2 ? "blue" : "#ccccff" - pressedColor: root.pressedColor - height: root.buttonHeight - width: root.buttonWidth - onClicked: changeMode(2) - content: TileText - { - text: isInverter ? qsTr("On") : qsTr("Inverter\nOnly"); font.bold: true; - color: inverterMode === 2 ? "white" : "gray" - } - } - DetailButton - { - id: chargeOnlyButton - baseColor: inverterMode === 1 ? "orange" : "#ffedcc" - pressedColor: root.pressedColor - height: root.buttonHeight - width: root.buttonWidth - visible: !isInverter - onClicked: changeMode(1) - content: TileText - { - text: qsTr("Charger\nOnly"); font.bold: true; - color: inverterMode === 1 ? "white" : "gray" - } - } - DetailButton - { - id: ecoButton - baseColor: inverterMode === 5 ? "orange" : "#ffedcc" - pressedColor: root.pressedColor - height: root.buttonHeight - width: root.buttonWidth - visible: isInverter - onClicked: changeMode(5) - content: TileText - { - text: qsTr("Eco"); font.bold: true; - color: inverterMode === 5 ? "white" : "black" - } - } - } - } - Column - { - id: chargePriorityButtonArea - width: root.buttonAreaWidth - anchors.bottom: parent.bottom; anchors.bottomMargin: 3 - anchors.right: parent.right; anchors.rightMargin: 3 - spacing: 4 - - Row - { - Text - { - font.pixelSize: 12; color: "black" - width: root.buttonAreaWidth; horizontalAlignment: Text.AlignHCenter - text: qsTr("Charge priority") - visible: showChargePriority - } - } - Row - { - spacing: 4 - DetailButton - { - id: acPriorityButton - baseColor: ! preferRenewableEnergy && ! acInIsGenerator ? "orange" : "#ffedcc" - pressedColor: root.pressedColor - height: root.buttonHeight - width: root.buttonWidth - onClicked: { if (! acInIsGenerator) sys.preferRenewableEnergy.setValue (0)} - visible: showChargePriority - content: TileText - { - text: "Grid"; font.bold: true - color: ! preferRenewableEnergy && ! acInIsGenerator ? "white" : "gray" - } - } - DetailButton - { - id: renewablePriorityButton - baseColor: preferRenewableEnergy && ! acInIsGenerator ? "green" : "#e6ffe6" - pressedColor: root.pressedColor - height: root.buttonHeight - width: root.buttonWidth - visible: showChargePriority - onClicked: { if (! acInIsGenerator) sys.preferRenewableEnergy.setValue (1)} - content: TileText - { - text: qsTr("Renew\nable"); font.bold: true - color: preferRenewableEnergy && ! acInIsGenerator ? "white" : "gray" - } - } - } - Row - { - Text - { - font.pixelSize: 12; color: "black" - width: root.buttonAreaWidth; horizontalAlignment: Text.AlignHCenter - text: - { - if (acInIsGenerator) - return qsTr ("Generator active\nno priority") - else if (autoReturnToRenewable && ! preferRenewableEnergy) - return qsTr ("returns to Renewable\n at 100% SOC") - else return "\n" - } - visible: showChargePriority - } - } - } - - - function changeMode(newMode) - { - if (editable) - { - inverterModeItem.setValue(newMode) - pageStack.pop() // return to flow screen after changing inverter mode - } - } - - function cancel() - { - pageStack.pop() - } - - function highlightMode () - { - if (editable) - inverterMode = inverterModeItem.value - else - inverterMode = 0 - } - - - // When new service is found check if is a tank sensor - Connections - { - target: DBusServices - onDbusServiceFound: addService(service) - } - - function addService(service) - { - switch (service.type) - { - case DBusService.DBUS_SERVICE_MULTI: - case DBusService.DBUS_SERVICE_MULTI_RS: - numberOfMultis++ - if (numberOfMultis === 1) - inverterService = service.name; - break;; - case DBusService.DBUS_SERVICE_INVERTER: - numberOfInverters++ - if (numberOfInverters === 1 && numberOfMultis === 0) - inverterService = service.name; - break;; - } - } - - // Detect available services of interest - function discoverServices() - { - numberOfMultis = 0 - numberOfInverters = 0 - inverterService = "" - for (var i = 0; i < DBusServices.count; i++) - { - addService(DBusServices.at(i)) - } - } - - function formatValueDiff (item1, item2, unit) - { - if (item1.valid && item2.valid) - return EnhFmt.formatValue (item1.value - item2.value, unit) - else - return "--" - } - - - //// hard key handler - // used to press buttons when touch isn't available - // UP and DOWN buttons cycle through the list of buttons - // "space" button is used to simulate a button press - // button must be highlighted so that other uses of "space" - // will still occur - - // list of buttons to be accessed via hard buttons - property variant buttonList: - [ - onButton, offButton, invertOnlyButton, chargeOnlyButton, ecoButton - ] - - property int buttonIndex: 0 - - Timer - { - id: targetTimer - interval: 5000 - repeat: false - running: false - onTriggered: { clearHighlight () } - } - - Keys.forwardTo: [keyHandler] - - Item - { - id: keyHandler - Keys.onDownPressed: - { - nextTarget (+1) - event.accepted = true - } - - Keys.onUpPressed: - { - nextTarget (-1) - event.accepted = true - } - } - - function nextTarget (increment) - { - // make one pass through all possible targets to find an enabled one - // if found, that's the new selectedTarget, - // if not selectedTarget does not change - var newIndex = buttonIndex - for (var i = 0; i < buttonList.length; i++) - { - // just restore highlight if not visible - if ( ! targetTimer.running && buttonList[newIndex].visible) - { - setActiveButton (buttonIndex) - return - } - newIndex += increment - if (newIndex >= buttonList.length) - newIndex = 0 - else if (newIndex < 0) - newIndex = buttonList.length - 1 - if (buttonList[newIndex].visible) - { - setActiveButton (newIndex) - break - } - } - } - - // Keys.onSpacePressed doesn't work - stolen by pageHandler - // so build a custom page handler so "space" can be used to press a button - pageToolbarHandler: detailToolbarHandler - ToolbarHandlerPages - { - id: detailToolbarHandler - isDefault: true - function centerAction() - { - acceptSpaceButton () - } - } - - function acceptSpaceButton () - { - if (targetTimer.running) - { - buttonList[buttonIndex].clicked () - } - } - - function setActiveButton (newIndex) - { - buttonIndex = newIndex - for (var i = 0; i < buttonList.length; i++) - if (i == newIndex) - buttonList[i].highlight = true - else - buttonList[i].highlight = false - targetTimer.restart () - } - - function clearHighlight () - { - for (var i = 0; i < buttonList.length; i++) - buttonList[i].highlight = false - } -} diff --git a/FileSets/v3.40~39/DetailLoadsCombined.qml b/FileSets/v3.40~39/DetailLoadsCombined.qml deleted file mode 100644 index 5909cb10..00000000 --- a/FileSets/v3.40~39/DetailLoadsCombined.qml +++ /dev/null @@ -1,146 +0,0 @@ -////// detail page for displaying critical AC output details -////// pushed from Flow overview - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 -import "enhancedFormat.js" as EnhFmt - -MbPage { - id: root - - title: qsTr ("AC Loads detail") - - property variant sys: theSystem - property string systemPrefix: "com.victronenergy.system" - - property int fontPixelSize: 18 - property color backgroundColor: "#b3b3b3" - - property int dataColumns: 3 - property int rowTitleWidth: 130 - property int totalDataWidth: root.width - rowTitleWidth - 20 - property int tableColumnWidth: totalDataWidth / dataColumns - property int legColumnWidth: phaseCount <= 1 ? totalDataWidth : totalDataWidth / phaseCount - - property int phaseCount: sys.acLoad.phaseCount.valid ? sys.acLoad.phaseCount.value : 0 - - VBusItem { id: vebusServiceItem; bind: Utils.path(systemPrefix, "/VebusService") } - property string inverterService: vebusServiceItem.valid ? vebusServiceItem.value : "" - property bool l2AndL1OutSummed: sys.acLoad.l2AndL1OutSummed - - // background - Rectangle - { - anchors - { - fill: parent - } - color: root.backgroundColor - } - - Row - { - spacing: 5 - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - Column - { - spacing: 2 - Row - { - Text { id: totalLabel; font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Total Power") } - Text { id: totalPower; font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.power, "W") - } - PowerGauge - { - id: gauge - width: (root.width * 0.9) - totalLabel.width - totalPower.width - height: 15 - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputMaxPower" - connection: sys.acLoad - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: "" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L1" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L2"; visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L3"; visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.powerL1, "W") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l2AndL1OutSummed ? "< < <" : EnhFmt.formatVBusItem (sys.acLoad.powerL2, "W"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.powerL3, "W"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Voltage") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.voltageL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l2AndL1OutSummed ? "< < <" : EnhFmt.formatVBusItem (sys.acLoad.voltageL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.voltageL3, "V"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.currentL1, "A") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l2AndL1OutSummed ? "< < <" : EnhFmt.formatVBusItem (sys.acLoad.currentL2, "A"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.currentL3, "A"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Frequency") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.frequency, "Hz") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: "L2 values included in L1" - visible: l2AndL1OutSummed } - } - } - } -} diff --git a/FileSets/v3.40~39/DetailLoadsOnInput.qml b/FileSets/v3.40~39/DetailLoadsOnInput.qml deleted file mode 100644 index 999a62ac..00000000 --- a/FileSets/v3.40~39/DetailLoadsOnInput.qml +++ /dev/null @@ -1,146 +0,0 @@ -////// detail page for displaying non-critical AC output details -////// pushed from Flow overview - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 -import "enhancedFormat.js" as EnhFmt - -MbPage { - id: root - - title: "Loads on AC Input Detail" - - property variant sys: theSystem - property string systemPrefix: "com.victronenergy.system" - - property int fontPixelSize: 18 - property color backgroundColor: "#b3b3b3" - - property int dataColumns: 3 - property int rowTitleWidth: 130 - property int totalDataWidth: root.width - rowTitleWidth - 20 - property int tableColumnWidth: totalDataWidth / dataColumns - property int legColumnWidth: phaseCount <= 1 ? totalDataWidth : totalDataWidth / phaseCount - - property int phaseCount: sys.acInLoad.phaseCount.valid ? sys.acInLoad.phaseCount.value : 0 - - VBusItem { id: vebusServiceItem; bind: Utils.path(systemPrefix, "/VebusService") } - property string inverterService: vebusServiceItem.valid ? vebusServiceItem.value : "" - property bool splitPhasePassthruDisabled: sys.acInput.splitPhasePassthruDisabled - - // background - Rectangle - { - anchors - { - fill: parent - } - color: root.backgroundColor - } - - Row - { - spacing: 5 - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - Column - { - spacing: 2 - Row - { - Text { id: totalLabel; font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Total Power") } - Text { id: totalPower; font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.power, "W") - } - PowerGauge - { - id: gauge - width: (root.width * 0.9) - totalLabel.width - totalPower.width - height: 15 - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputMaxPower" - connection: sys.acInLoad - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: "" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L1" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L2"; visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L3"; visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.powerL1, "W") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.acInLoad.powerL2, "W"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.powerL3, "W"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Voltage") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.voltageL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.acInLoad.voltageL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.voltageL3, "V"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.currentL1, "A") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.acInLoad.currentL2, "A"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.currentL3, "A"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Frequency") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.frequency, "Hz") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: "L2 values included in L1" - visible: splitPhasePassthruDisabled } - } - } - } -} diff --git a/FileSets/v3.40~39/DetailLoadsOnOutput.qml b/FileSets/v3.40~39/DetailLoadsOnOutput.qml deleted file mode 100644 index 2092989c..00000000 --- a/FileSets/v3.40~39/DetailLoadsOnOutput.qml +++ /dev/null @@ -1,151 +0,0 @@ -////// detail page for displaying critical AC output details -////// pushed from Flow overview - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 -import "enhancedFormat.js" as EnhFmt - -MbPage { - id: root - - title: combineAcLoads ? qsTr ("AC Loads detail") : qsTr ("Loads on AC Output detail") - - property variant sys: theSystem - property string systemPrefix: "com.victronenergy.system" - property string settingsPrefix: "com.victronenergy.settings" - - property int fontPixelSize: 18 - property color backgroundColor: "#b3b3b3" - - property int dataColumns: 3 - property int rowTitleWidth: 130 - property int totalDataWidth: root.width - rowTitleWidth - 20 - property int tableColumnWidth: totalDataWidth / dataColumns - property int legColumnWidth: phaseCount <= 1 ? totalDataWidth : totalDataWidth / phaseCount - - property int phaseCount: outputLoad.phaseCount.valid ? outputLoad.phaseCount.value : 0 - - VBusItem { id: vebusServiceItem; bind: Utils.path(systemPrefix, "/VebusService") } - property string inverterService: vebusServiceItem.valid ? vebusServiceItem.value : "" - property bool l2AndL1OutSummed: sys.acLoad.l2AndL1OutSummed - - VBusItem { id: _combineAcLoads; bind: "com.victronenergy.settings/Settings/GuiMods/EnhancedFlowCombineLoads" } - property bool combineAcLoads: _combineAcLoads.valid && _combineAcLoads.value === 1 - property variant outputLoad: combineAcLoads ? sys.acLoad : sys.acOutLoad - - // background - Rectangle - { - anchors - { - fill: parent - } - color: root.backgroundColor - } - - Row - { - spacing: 5 - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - Column - { - spacing: 2 - Row - { - Text { id: totalLabel; font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Total Power") } - Text { id: totalPower; font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.power, "W") - } - PowerGauge - { - id: gauge - width: (root.width * 0.9) - totalLabel.width - totalPower.width - height: 15 - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputMaxPower" - connection: outputLoad - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: "" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L1" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L2"; visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L3"; visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.powerL1, "W") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l2AndL1OutSummed ? "< < <" : EnhFmt.formatVBusItem (outputLoad.powerL2, "W"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.powerL3, "W"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Voltage") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.voltageL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l2AndL1OutSummed ? "< < <" : EnhFmt.formatVBusItem (outputLoad.voltageL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.voltageL3, "V"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.currentL1, "A") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l2AndL1OutSummed ? "< < <" : EnhFmt.formatVBusItem (outputLoad.currentL2, "A"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.currentL3, "A"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Frequency") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.frequency, "Hz") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: "L2 values included in L1" - visible: l2AndL1OutSummed } - } - } - } -} diff --git a/FileSets/v3.40~39/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~39/OverviewGeneratorEnhanced.qml deleted file mode 120000 index 24bc6f1b..00000000 --- a/FileSets/v3.40~39/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.34/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~39/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~39/OverviewTanksTempsDigInputs.qml deleted file mode 100644 index 781e163c..00000000 --- a/FileSets/v3.40~39/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1,207 +0,0 @@ -//// New overview page for tanks, temps and digital inputs -//// part of GuiMods -//// based on tank/temps column in mobile overview - -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils -import "timeToGo.js" as TTG - -OverviewPage { - title: qsTr("Tanks & Temps & Digital Inputs") - id: root - - property variant sys: theSystem - property string systemPrefix: "com.victronenergy.system" - property string settingsBindPreffix: "com.victronenergy.settings" - property string pumpBindPreffix: "com.victronenergy.pump.startstop0" - - property int numberOfTanks: tankModel.rowCount - property real tanksHeight: root.height - property real minTankHeight: 21 // use for temps also - property real maxTankHeight: 80 // use for temps also - property real tankTileHeight: Math.min (Math.max (tanksHeight / numberOfTanks, minTankHeight), maxTankHeight) - property bool tanksCompact: numberOfTanks > 6 - - property int numberOfTemps: 0 - property real tempsHeight: root.height - property real tempsTileHeight: Math.min (Math.max (tempsHeight / numberOfTemps, minTankHeight), maxTankHeight) - property bool tempsCompact: numberOfTemps > 6 - - property int tankWidth: parent.width / 3 - property int tempsWidth: tankWidth - property int digInWidth: tankWidth - - property int numberOfDigIn: 0 - property real digInHeight: root.height - property real digInTileHeight: Math.min (Math.max (digInHeight / numberOfDigIn, minTankHeight), maxTankHeight) - - Component.onCompleted: { discoverServices() } - - // Synchronise name text scroll start - Timer { - id: scrollTimer - interval: 15000 - repeat: true - running: root.active - } - - ListView { - id: tanksColum - - anchors { - top: root.top - left: root.left - } - height: root.tanksHeight - width: root.tankWidth - interactive: root.tankTileHeight * count > (tanksColum.height + 1) ? true : false - - model: TankModel { id: tankModel } - delegate: TileTankEnhanced { - // Without an intermediate assignment this will trigger a binding loop warning. - property variant theService: DBusServices.get(buddy.id) - service: theService - width: tanksColum.width - height: root.tankTileHeight - pumpBindPrefix: root.pumpBindPreffix - compact: root.tanksCompact - Connections { - target: scrollTimer - onTriggered: doScroll() - } - } - Tile { - title: numberOfTanks == 0 ? qsTr ("no tanks") : qsTr("Tanks") - anchors.fill: parent - color: "#b3b3b3" - values: TileText { - text: qsTr("") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - - ListView { - id: tempsColumn - - anchors { - top: root.top - left: tanksColum.right - } - height: root.tempsHeight - width: root.tempsWidth - // make list flickable if more tiles than will fit completely - interactive: root.tankTileHeight * count > (tempsColumn.height + 1) ? true : false - - model: tempsModel - delegate: TileTemp - { - width: tempsColumn.width - height: root.tempsTileHeight - compact: root.tempsCompact - Connections - { - target: scrollTimer - onTriggered: doScroll() - } - } - Tile - { - title: numberOfTemps == 0 ? qsTr ("no temps") : qsTr("Temps") - anchors.fill: parent - color: "#b3b3b3" - values: TileText - { - text: qsTr("") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - ListModel { id: tempsModel } - - ListView { - id: digInputsColumn - - anchors { - top: root.top - right: root.right - } - height: root.digInHeight - width: root.digInWidth - // make list flickable if more tiles than will fit completely - interactive: root.digInTileHeight * count > (digInputsColumn.height + 1) ? true : false - - model: digInModel - delegate: TileDigIn - { - width: digInputsColumn.width - height: root.digInTileHeight - } - Tile - { - title: numberOfDigIn == 0 ? qsTr ("no digital inputs") : qsTr("Digital Inputs") - anchors.fill: parent - color: "#b3b3b3" - values: TileText - { - text: qsTr("") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - ListModel { id: digInModel } - - - // When new service is found add resources as appropriate - Connections { - target: DBusServices - onDbusServiceFound: addService(service) - } - - // hack to get value(s) from within a loop inside a function when service is changing - property string tempServiceName: "" - property VBusItem temperatureItem: VBusItem { bind: Utils.path(tempServiceName, "/Dc/0/Temperature") } - - function addService(service) - { - switch (service.type) - { - case DBusService.DBUS_SERVICE_TEMPERATURE_SENSOR: - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - break;; - case DBusService.DBUS_SERVICE_DIGITAL_INPUT: - case DBusService.DBUS_SERVICE_PULSE_COUNTER: - numberOfDigIn++ - digInModel.append({serviceName: service.name}) - break;; - case DBusService.DBUS_SERVICE_BATTERY: - case DBusService.DBUS_SERVICE_MULTI: - root.tempServiceName = service.name - if (temperatureItem.valid) - { - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - } - break;; - } - } - - // Check available services to find tank sesnsors - function discoverServices() - { - numberOfTemps = 0 - tempsModel.clear() - numberOfDigIn = 0 - digInModel.clear() - for (var i = 0; i < DBusServices.count; i++) - addService(DBusServices.at(i)) - } -} diff --git a/FileSets/v3.40~39/PageGenerator.qml b/FileSets/v3.40~39/PageGenerator.qml deleted file mode 120000 index bd3a4634..00000000 --- a/FileSets/v3.40~39/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.34/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~39/TileDigIn.qml b/FileSets/v3.40~39/TileDigIn.qml deleted file mode 100644 index 492b8b2d..00000000 --- a/FileSets/v3.40~39/TileDigIn.qml +++ /dev/null @@ -1,133 +0,0 @@ -// New for GuiMods to display digital inputs -// based on TileTank.qml - -import QtQuick 1.1 -import "utils.js" as Utils -import "tanksensor.js" as TankSensor - -Tile { - id: root - - property string bindPrefix: serviceName - property VBusItem nameItem: VBusItem { bind: Utils.path(bindPrefix, "/CustomName") } - property VBusItem deviceItem: VBusItem { bind: Utils.path(bindPrefix, "/DeviceInstance") } - property VBusItem aggregateItem: VBusItem { bind: Utils.path(bindPrefix, "/Aggregate") } - property string digInName: nameItem.valid && nameItem.value != "" ? nameItem.value : getType (type) - property VBusItem typeItem: VBusItem { bind: Utils.path(bindPrefix, "/Type") } - property VBusItem stateItem: VBusItem { bind: Utils.path(bindPrefix, "/State") } - property bool isPulseCounter: aggregateItem.valid - // pulse counter doesn't have /Type so fill it in here - property int type: isPulseCounter ? 1 : typeItem.valid ? typeItem.value : 0 - - property variant bkgdColors: [ "#b3b3b3", "#4aa3df", "#1abc9c", "#F39C12", "#95a5a6", "#95a5a6","#dcc6e0", "#f1a9a0", "#7f8c8d", "#ebbc3a" ] - property color bkgdColor: type > 0 && type < 10 ? bkgdColors [type] : "#b3b3b3" - property variant units: ["m3", "L", "gal", "gal"] - - - function getType(type) - { - switch (type) - { - case 0: - return qsTr("Disabled") - case 1: - return qsTr("Pulse meter") - case 2: - return qsTr("Door alarm") - case 3: - return qsTr("Bilge pump") - case 4: - return qsTr("Bilge alarm") - case 5: - return qsTr("Burglar alarm") - case 6: - return qsTr("Smoke alarm") - case 7: - return qsTr("Fire alarm") - case 8: - return qsTr("CO2 alarm") - case 9: - return qsTr("Generator") - case 10: - return qsTr("Generic I/O") -//// added for ExtTransferSwitch package - case 11: - return qsTr("Touch enable") - case 12: - return qsTr("Transfer switch") - default: - return "Unknown" - } - } - - function getState(st) - { - switch (st) - { - case 0: - return qsTr("Low") - case 1: - return qsTr("High") - case 2: - return qsTr("Off") - case 3: - return qsTr("On") - case 4: - return qsTr("No") - case 5: - return qsTr("Yes") - case 6: - return qsTr("Open") - case 7: - return qsTr("Closed") - case 8: - return qsTr("Ok") - case 9: - return qsTr("Alarm") - case 10: - return qsTr("Running") - case 11: - return qsTr("Stopped") -//// added for ExtTransferSwitch package - case 12: - return qsTr("On Generator") - case 13: - return qsTr("On Grid") - default: - return qsTr("Unknown") - } - - } - - title: digInName + " (In " + (deviceItem.valid ? (deviceItem.value.toString ()) : "?") + ")" - - color: bkgdColor - - VBusItem - { - id: unitItem - bind: Utils.path("com.victronenergy.settings/Settings/System/VolumeUnit") - } - - values: Item - { - width: root.width - 10 - height: 12 - TileText - { - width: root.width - text: - { - if (isPulseCounter) - return aggregateItem.value.toString() + (unitItem.valid ? units[unitItem.value] : "??") - else - return stateItem.valid ? getState (stateItem.value) : "??" - } - horizontalAlignment: Text.AlignHCenter - anchors - { - horizontalCenter: parent.horizontalCenter - } - } - } -} diff --git a/FileSets/v3.40~5/Battery.qml b/FileSets/v3.40~5/Battery.qml deleted file mode 120000 index fafc7b36..00000000 --- a/FileSets/v3.40~5/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/COMPLETE b/FileSets/v3.40~5/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~5/DetailAcInput.qml b/FileSets/v3.40~5/DetailAcInput.qml deleted file mode 120000 index d315e33a..00000000 --- a/FileSets/v3.40~5/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/DetailInverter.qml b/FileSets/v3.40~5/DetailInverter.qml deleted file mode 120000 index 2d924d7f..00000000 --- a/FileSets/v3.40~5/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/DetailLoadsCombined.qml b/FileSets/v3.40~5/DetailLoadsCombined.qml deleted file mode 120000 index 58c63979..00000000 --- a/FileSets/v3.40~5/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/DetailLoadsOnInput.qml b/FileSets/v3.40~5/DetailLoadsOnInput.qml deleted file mode 120000 index 5fb19084..00000000 --- a/FileSets/v3.40~5/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/DetailLoadsOnOutput.qml b/FileSets/v3.40~5/DetailLoadsOnOutput.qml deleted file mode 120000 index 9fdfdf28..00000000 --- a/FileSets/v3.40~5/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/HubData.qml b/FileSets/v3.40~5/HubData.qml deleted file mode 120000 index b88f1965..00000000 --- a/FileSets/v3.40~5/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/LINKS_ONLY b/FileSets/v3.40~5/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~5/MbEditBox.qml b/FileSets/v3.40~5/MbEditBox.qml deleted file mode 120000 index 8381b7d5..00000000 --- a/FileSets/v3.40~5/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/MbEditBoxDateTime.qml b/FileSets/v3.40~5/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v3.40~5/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/MbItem.qml b/FileSets/v3.40~5/MbItem.qml deleted file mode 120000 index 048a313c..00000000 --- a/FileSets/v3.40~5/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/MbItemDigitalInput.qml b/FileSets/v3.40~5/MbItemDigitalInput.qml deleted file mode 120000 index 4404b520..00000000 --- a/FileSets/v3.40~5/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/MbSpinBox.qml b/FileSets/v3.40~5/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v3.40~5/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/MbStyle.qml b/FileSets/v3.40~5/MbStyle.qml deleted file mode 120000 index d1940446..00000000 --- a/FileSets/v3.40~5/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/MbSubMenu.qml b/FileSets/v3.40~5/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v3.40~5/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/Multi.qml b/FileSets/v3.40~5/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v3.40~5/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/ObjectAcConnection.qml b/FileSets/v3.40~5/ObjectAcConnection.qml deleted file mode 120000 index cab7f2d4..00000000 --- a/FileSets/v3.40~5/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~5/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 6d1e56b5..00000000 --- a/FileSets/v3.40~5/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewBox.qml b/FileSets/v3.40~5/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v3.40~5/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewConnection.qml b/FileSets/v3.40~5/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v3.40~5/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewConnectionEnd.qml b/FileSets/v3.40~5/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v3.40~5/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewFlowComplex.qml b/FileSets/v3.40~5/OverviewFlowComplex.qml deleted file mode 120000 index 296ff4b1..00000000 --- a/FileSets/v3.40~5/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~5/OverviewGeneratorEnhanced.qml deleted file mode 120000 index da5507a7..00000000 --- a/FileSets/v3.40~5/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~5/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index 1c9b530f..00000000 --- a/FileSets/v3.40~5/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewGridParallel.qml b/FileSets/v3.40~5/OverviewGridParallel.qml deleted file mode 120000 index 3d1f0720..00000000 --- a/FileSets/v3.40~5/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewHub.qml b/FileSets/v3.40~5/OverviewHub.qml deleted file mode 120000 index 83bae2bd..00000000 --- a/FileSets/v3.40~5/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewHubEnhanced.qml b/FileSets/v3.40~5/OverviewHubEnhanced.qml deleted file mode 120000 index 905200b7..00000000 --- a/FileSets/v3.40~5/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewMobileEnhanced.qml b/FileSets/v3.40~5/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.40~5/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewSolarCharger.qml b/FileSets/v3.40~5/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v3.40~5/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewSolarInverter.qml b/FileSets/v3.40~5/OverviewSolarInverter.qml deleted file mode 120000 index 4048703e..00000000 --- a/FileSets/v3.40~5/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewTankDelegate.qml b/FileSets/v3.40~5/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v3.40~5/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewTanks.qml b/FileSets/v3.40~5/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v3.40~5/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~5/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.40~5/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/PageDigitalInput.qml b/FileSets/v3.40~5/PageDigitalInput.qml deleted file mode 120000 index 5b768f8f..00000000 --- a/FileSets/v3.40~5/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/PageGenerator.qml b/FileSets/v3.40~5/PageGenerator.qml deleted file mode 120000 index efbafddf..00000000 --- a/FileSets/v3.40~5/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/PageMain.qml b/FileSets/v3.40~5/PageMain.qml deleted file mode 120000 index 33fe83b0..00000000 --- a/FileSets/v3.40~5/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~13/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/PageSettingsDisplay.qml b/FileSets/v3.40~5/PageSettingsDisplay.qml deleted file mode 120000 index 4e1ac210..00000000 --- a/FileSets/v3.40~5/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/PageSettingsGenerator.qml b/FileSets/v3.40~5/PageSettingsGenerator.qml deleted file mode 120000 index 15dd8f85..00000000 --- a/FileSets/v3.40~5/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/PageSettingsGuiMods.qml b/FileSets/v3.40~5/PageSettingsGuiMods.qml deleted file mode 120000 index e831a7a4..00000000 --- a/FileSets/v3.40~5/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/PageSettingsRelay.qml b/FileSets/v3.40~5/PageSettingsRelay.qml deleted file mode 120000 index 156aadac..00000000 --- a/FileSets/v3.40~5/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/PowerGauge.qml b/FileSets/v3.40~5/PowerGauge.qml deleted file mode 120000 index cfdf038d..00000000 --- a/FileSets/v3.40~5/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/Tile.qml b/FileSets/v3.40~5/Tile.qml deleted file mode 120000 index 0558cecf..00000000 --- a/FileSets/v3.40~5/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/TileDigIn.qml b/FileSets/v3.40~5/TileDigIn.qml deleted file mode 120000 index 44616f30..00000000 --- a/FileSets/v3.40~5/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/TileRelay.qml b/FileSets/v3.40~5/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.40~5/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/TileText.qml b/FileSets/v3.40~5/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v3.40~5/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/attributes.csv b/FileSets/v3.40~5/attributes.csv deleted file mode 120000 index e226e13c..00000000 --- a/FileSets/v3.40~5/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v3.40~6/attributes.csv \ No newline at end of file diff --git a/FileSets/v3.40~5/dbus_digitalinputs.py b/FileSets/v3.40~5/dbus_digitalinputs.py deleted file mode 120000 index e74da5b6..00000000 --- a/FileSets/v3.40~5/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.40~5/dbus_generator.py b/FileSets/v3.40~5/dbus_generator.py deleted file mode 120000 index 0cd84ca3..00000000 --- a/FileSets/v3.40~5/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.40~5/dbus_systemcalc.py b/FileSets/v3.40~5/dbus_systemcalc.py deleted file mode 120000 index 119d5a8c..00000000 --- a/FileSets/v3.40~5/dbus_systemcalc.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~6/dbus_systemcalc.py \ No newline at end of file diff --git a/FileSets/v3.40~5/main.qml b/FileSets/v3.40~5/main.qml deleted file mode 120000 index 916fdfbf..00000000 --- a/FileSets/v3.40~5/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~13/main.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/startstop.py b/FileSets/v3.40~5/startstop.py deleted file mode 120000 index 274861e3..00000000 --- a/FileSets/v3.40~5/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~17/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~5/styles.css b/FileSets/v3.40~5/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v3.40~5/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v3.40~6/Battery.qml b/FileSets/v3.40~6/Battery.qml deleted file mode 120000 index fafc7b36..00000000 --- a/FileSets/v3.40~6/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/COMPLETE b/FileSets/v3.40~6/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~6/DetailAcInput.qml b/FileSets/v3.40~6/DetailAcInput.qml deleted file mode 120000 index d315e33a..00000000 --- a/FileSets/v3.40~6/DetailAcInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/DetailAcInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/DetailInverter.qml b/FileSets/v3.40~6/DetailInverter.qml deleted file mode 120000 index 2d924d7f..00000000 --- a/FileSets/v3.40~6/DetailInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/DetailInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/DetailLoadsCombined.qml b/FileSets/v3.40~6/DetailLoadsCombined.qml deleted file mode 120000 index 58c63979..00000000 --- a/FileSets/v3.40~6/DetailLoadsCombined.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/DetailLoadsCombined.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/DetailLoadsOnInput.qml b/FileSets/v3.40~6/DetailLoadsOnInput.qml deleted file mode 120000 index 5fb19084..00000000 --- a/FileSets/v3.40~6/DetailLoadsOnInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/DetailLoadsOnInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/DetailLoadsOnOutput.qml b/FileSets/v3.40~6/DetailLoadsOnOutput.qml deleted file mode 120000 index 9fdfdf28..00000000 --- a/FileSets/v3.40~6/DetailLoadsOnOutput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/DetailLoadsOnOutput.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/HubData.qml b/FileSets/v3.40~6/HubData.qml deleted file mode 120000 index b88f1965..00000000 --- a/FileSets/v3.40~6/HubData.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/LINKS_ONLY b/FileSets/v3.40~6/LINKS_ONLY deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~6/MbEditBox.qml b/FileSets/v3.40~6/MbEditBox.qml deleted file mode 120000 index 8381b7d5..00000000 --- a/FileSets/v3.40~6/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/MbEditBoxDateTime.qml b/FileSets/v3.40~6/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v3.40~6/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/MbItem.qml b/FileSets/v3.40~6/MbItem.qml deleted file mode 120000 index 048a313c..00000000 --- a/FileSets/v3.40~6/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/MbItemDigitalInput.qml b/FileSets/v3.40~6/MbItemDigitalInput.qml deleted file mode 120000 index 4404b520..00000000 --- a/FileSets/v3.40~6/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/MbSpinBox.qml b/FileSets/v3.40~6/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v3.40~6/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/MbStyle.qml b/FileSets/v3.40~6/MbStyle.qml deleted file mode 120000 index d1940446..00000000 --- a/FileSets/v3.40~6/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/MbSubMenu.qml b/FileSets/v3.40~6/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v3.40~6/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/Multi.qml b/FileSets/v3.40~6/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v3.40~6/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/ObjectAcConnection.qml b/FileSets/v3.40~6/ObjectAcConnection.qml deleted file mode 120000 index cab7f2d4..00000000 --- a/FileSets/v3.40~6/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~6/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 6d1e56b5..00000000 --- a/FileSets/v3.40~6/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewBox.qml b/FileSets/v3.40~6/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v3.40~6/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewConnection.qml b/FileSets/v3.40~6/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v3.40~6/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewConnectionEnd.qml b/FileSets/v3.40~6/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v3.40~6/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewFlowComplex.qml b/FileSets/v3.40~6/OverviewFlowComplex.qml deleted file mode 120000 index 296ff4b1..00000000 --- a/FileSets/v3.40~6/OverviewFlowComplex.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/OverviewFlowComplex.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~6/OverviewGeneratorEnhanced.qml deleted file mode 120000 index da5507a7..00000000 --- a/FileSets/v3.40~6/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~6/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index 1c9b530f..00000000 --- a/FileSets/v3.40~6/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewGridParallel.qml b/FileSets/v3.40~6/OverviewGridParallel.qml deleted file mode 120000 index 3d1f0720..00000000 --- a/FileSets/v3.40~6/OverviewGridParallel.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/OverviewGridParallel.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewHub.qml b/FileSets/v3.40~6/OverviewHub.qml deleted file mode 120000 index 83bae2bd..00000000 --- a/FileSets/v3.40~6/OverviewHub.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/OverviewHub.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewHubEnhanced.qml b/FileSets/v3.40~6/OverviewHubEnhanced.qml deleted file mode 120000 index 905200b7..00000000 --- a/FileSets/v3.40~6/OverviewHubEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/OverviewHubEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewMobileEnhanced.qml b/FileSets/v3.40~6/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.40~6/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewSolarCharger.qml b/FileSets/v3.40~6/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v3.40~6/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewSolarInverter.qml b/FileSets/v3.40~6/OverviewSolarInverter.qml deleted file mode 120000 index 4048703e..00000000 --- a/FileSets/v3.40~6/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewTankDelegate.qml b/FileSets/v3.40~6/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v3.40~6/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewTanks.qml b/FileSets/v3.40~6/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v3.40~6/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~6/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.40~6/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/PageDigitalInput.qml b/FileSets/v3.40~6/PageDigitalInput.qml deleted file mode 120000 index 5b768f8f..00000000 --- a/FileSets/v3.40~6/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/PageGenerator.qml b/FileSets/v3.40~6/PageGenerator.qml deleted file mode 120000 index efbafddf..00000000 --- a/FileSets/v3.40~6/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/PageMain.qml b/FileSets/v3.40~6/PageMain.qml deleted file mode 120000 index 33fe83b0..00000000 --- a/FileSets/v3.40~6/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~13/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/PageSettingsDisplay.qml b/FileSets/v3.40~6/PageSettingsDisplay.qml deleted file mode 120000 index 4e1ac210..00000000 --- a/FileSets/v3.40~6/PageSettingsDisplay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/PageSettingsDisplay.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/PageSettingsGenerator.qml b/FileSets/v3.40~6/PageSettingsGenerator.qml deleted file mode 120000 index 15dd8f85..00000000 --- a/FileSets/v3.40~6/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/PageSettingsGuiMods.qml b/FileSets/v3.40~6/PageSettingsGuiMods.qml deleted file mode 120000 index e831a7a4..00000000 --- a/FileSets/v3.40~6/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/PageSettingsRelay.qml b/FileSets/v3.40~6/PageSettingsRelay.qml deleted file mode 120000 index 156aadac..00000000 --- a/FileSets/v3.40~6/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/PowerGauge.qml b/FileSets/v3.40~6/PowerGauge.qml deleted file mode 120000 index cfdf038d..00000000 --- a/FileSets/v3.40~6/PowerGauge.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~8/PowerGauge.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/Tile.qml b/FileSets/v3.40~6/Tile.qml deleted file mode 120000 index 0558cecf..00000000 --- a/FileSets/v3.40~6/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/TileDigIn.qml b/FileSets/v3.40~6/TileDigIn.qml deleted file mode 120000 index 44616f30..00000000 --- a/FileSets/v3.40~6/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/TileRelay.qml b/FileSets/v3.40~6/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.40~6/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/TileText.qml b/FileSets/v3.40~6/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v3.40~6/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/dbus_digitalinputs.py b/FileSets/v3.40~6/dbus_digitalinputs.py deleted file mode 120000 index e74da5b6..00000000 --- a/FileSets/v3.40~6/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.40~6/dbus_generator.py b/FileSets/v3.40~6/dbus_generator.py deleted file mode 120000 index 0cd84ca3..00000000 --- a/FileSets/v3.40~6/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.40~6/main.qml b/FileSets/v3.40~6/main.qml deleted file mode 120000 index 916fdfbf..00000000 --- a/FileSets/v3.40~6/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~13/main.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/startstop.py b/FileSets/v3.40~6/startstop.py deleted file mode 120000 index 274861e3..00000000 --- a/FileSets/v3.40~6/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~17/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~6/styles.css b/FileSets/v3.40~6/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v3.40~6/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/FileSets/v3.40~8/Battery.qml b/FileSets/v3.40~8/Battery.qml deleted file mode 120000 index fafc7b36..00000000 --- a/FileSets/v3.40~8/Battery.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/COMPLETE b/FileSets/v3.40~8/COMPLETE deleted file mode 100644 index e69de29b..00000000 diff --git a/FileSets/v3.40~8/DetailAcInput.qml b/FileSets/v3.40~8/DetailAcInput.qml deleted file mode 100644 index d2865e4a..00000000 --- a/FileSets/v3.40~8/DetailAcInput.qml +++ /dev/null @@ -1,606 +0,0 @@ -////// detail page for setting input current limit -////// and displaying AC input details -////// pushed from Flow overview - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 -import "enhancedFormat.js" as EnhFmt - -MbPage { - id: root - - title: "AC Input detail" - - property variant sys: theSystem - property string systemPrefix: "com.victronenergy.system" - property string settingsPrefix: "com.victronenergy.settings" - - property int fontPixelSize: 18 - property color buttonColor: "#979797" - property color pressedColor: "#d3d3d3" - property color backgroundColor: "#b3b3b3" - - property int buttonHeight: 40 - - property int dataColumns: 4 - property int rowTitleWidth: 100 - property int totalDataWidth: 340 - rowTitleWidth - property int tableColumnWidth: totalDataWidth / dataColumns - - property int legColumnWidth: phaseCount <= 1 ? tableColumnWidth * 3 : tableColumnWidth * 3 / phaseCount - - property int phaseCount: sys.acInput.phaseCount.valid ? sys.acInput.phaseCount.value : 0 - - VBusItem { id: vebusServiceItem; bind: Utils.path(systemPrefix, "/VebusService") } - property string inverterService: vebusServiceItem.valid ? vebusServiceItem.value : "" - property bool splitPhasePassthruDisabled: sys.acInput.splitPhaseL2PassthruDisabled - - property real actualCurrentLimit: 0 - property real newCurrentLimit: 0 - - VBusItem { id: acLimitPreset1Item; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/AcCurrentLimit/Preset1") } - VBusItem { id: acLimitPreset2Item; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/AcCurrentLimit/Preset2") } - VBusItem { id: acLimitPreset3Item; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/AcCurrentLimit/Preset3") } - VBusItem { id: acLimitPreset4Item; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/AcCurrentLimit/Preset4") } - property real acLimitPreset1: acLimitPreset1Item.valid ? acLimitPreset1Item.value : 0 - property real acLimitPreset2: acLimitPreset2Item.valid ? acLimitPreset2Item.value : 0 - property real acLimitPreset3: acLimitPreset3Item.valid ? acLimitPreset3Item.value : 0 - property real acLimitPreset4: acLimitPreset4Item.valid ? acLimitPreset4Item.value : 0 - - property bool currentLimitIsAdjustable: currentLimitIsAdjustableItem.valid && currentLimitIsAdjustableItem.value == 1 && currentLimitItem.valid - - Component.onCompleted: { getActualCurrent () } - - VBusItem - { - id: currentLimitIsAdjustableItem - bind: Utils.path(inverterService, "/Ac/ActiveIn/CurrentLimitIsAdjustable") - onValueChanged: getActualCurrent () - onValidChanged: getActualCurrent () - } - VBusItem - { - id: currentLimitItem - bind: Utils.path(inverterService, "/Ac/ActiveIn/CurrentLimit") - onValueChanged: getActualCurrent () - onValidChanged: getActualCurrent () - } - VBusItem { id: activeInputItem; bind: Utils.path(inverterService, "/Ac/ActiveIn/ActiveInput") } - VBusItem { id: numberOfAcInputs; bind: Utils.path(inverterService, "/Ac/In/NumberOfAcInputs") } - VBusItem { id: activeSourceItem; bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") } - VBusItem { id: acIn1sourceItem; bind: Utils.path(settingsPrefix, "/Settings/SystemSetup/AcInput1") } - VBusItem { id: acIn2sourceItem; bind: Utils.path(settingsPrefix, "/Settings/SystemSetup/AcInput2") } - property int activeSource: activeSourceItem.valid ? activeSourceItem.value : 0 - property int acIn1source: acIn1sourceItem.valid ? acIn1sourceItem.value : 0 - property int acIn2source: acIn2sourceItem.valid ? acIn2sourceItem.value : 0 - property int activeInput: activeInputItem.valid && activeInputItem.value == 1 ? 2 : 1 - property bool hasTwoInputs: numberOfAcInputs.valid && numberOfAcInputs.value == 2 - - property variant acSourceName: [qsTr("---"), qsTr("Grid"), qsTr("Generator"), qsTr("Shore")] - - // background - Rectangle - { - anchors - { - fill: parent - } - color: root.backgroundColor - } - - Row - { - spacing: 5 - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - width: parent.width - 6 - Column - { - spacing: 2 - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Total Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.power, "W") - } - PowerGauge - { - id: gauge - width: totalDataWidth - tableColumnWidth - height: 15 - connection: sys.acInput - useInputCurrentLimit: true - maxForwardPowerParameter: "" // handled internally - uses input current limit and AC input voltage - maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxFeedInPower" - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + tableColumnWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Active Source") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth - tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: - { - if (activeSource == 240) - return quTr ("no input") - else if (hasTwoInputs) - return acSourceName[activeSource] + " (AC in " + activeInput + ")" - else - return acSourceName[activeSource] - } - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L1" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L2"; visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L3"; visible: phaseCount >= 3 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: qsTr ("Freq") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.powerL1, "W") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.acInput.powerL2, "W"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.powerL3, "W"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Voltage / Freq") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.voltageL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.acInput.voltageL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.voltageL3, "V"); visible: phaseCount >= 3 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.frequency, "Hz") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.currentL1, "A") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.acInput.currentL2, "A"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInput.currentL3, "A"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("CurrentLimit") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: - { - var newText - if (newCurrentLimit != actualCurrentLimit) - newText = qsTr(" New ") + newCurrentLimit.toFixed (1) + " A" - else - newText = "" - return currentLimitItem.valid ? currentLimitItem.value.toFixed (1) + " A" + newText: "--" } - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: "L2 values included in L1" - visible: splitPhasePassthruDisabled } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: qsTr("Avaliable Sources") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L1" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L2"; visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L3"; visible: phaseCount >= 3 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: qsTr ("Freq") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: 20; horizontalAlignment: Text.AlignHCenter - text: activeSource == 1 || activeSource == 3 ? ">" : "" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth - 20; horizontalAlignment: Text.AlignRight - text: - { - if (acIn1source == 3 || acIn2source == 3) - return acSourceName[3] - else - return acSourceName[1] - } - } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.grid.voltageL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.grid.voltageL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.grid.voltageL3, "V"); visible: phaseCount >= 3 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.grid.frequency, "Hz") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: 20; horizontalAlignment: Text.AlignHCenter - text: activeSource == 2 ? ">" : "" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth - 20; horizontalAlignment: Text.AlignRight - text: acSourceName[2] } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.genset.voltageL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.genset.voltageL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.genset.voltageL3, "V"); visible: phaseCount >= 3 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.genset.frequency, "Hz") } - } - } - Column - { - id: currentButtonColumn - width: 128 - spacing: 4 - - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: currentButtonColumn.width; horizontalAlignment: Text.AlignHCenter - text: qsTr("Current Limit") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: currentButtonColumn.width; horizontalAlignment: Text.AlignHCenter - text: qsTr("is not adjustable")} - visible: !currentLimitIsAdjustable - } - Row - { - visible: currentLimitIsAdjustable - width: (parent.width / 2) - 2 - spacing: 4 - DetailButton - { - id: preset1button - baseColor: newCurrentLimit === acLimitPreset1 ? "black" : root.buttonColor - pressedColor: root.pressedColor - opacity: acLimitPreset1 === 0 ? 0.001 : 1 - height: 40 - width: parent.width - onClicked: setNewValue (acLimitPreset1) - enabled: acLimitPreset1 === 0 ? false : true - content: TileText - { - text: qsTr(acLimitPreset1 + " A"); font.bold: true; - color: "white" - } - } - DetailButton - { - id: preset2button - baseColor: newCurrentLimit === acLimitPreset2 ? "black" : root.buttonColor - pressedColor: root.pressedColor - opacity: acLimitPreset2 === 0 ? 0.001 : 1 - height: 40 - width: parent.width - onClicked: setNewValue (acLimitPreset2) - enabled: acLimitPreset2 === 0 ? false : true - content: TileText - { - text: qsTr(acLimitPreset2 + " A"); font.bold: true; - color: "white" - } - } - } - Row - { - visible: currentLimitIsAdjustable - width: (parent.width / 2) - 2 - spacing: 4 - DetailButton - { - id: preset3button - baseColor: newCurrentLimit === acLimitPreset3 ? "black" : root.buttonColor - pressedColor: root.pressedColor - opacity: acLimitPreset3 === 0 ? 0.001 : 1 - height: 40 - width: parent.width - onClicked: setNewValue (acLimitPreset3) - enabled: acLimitPreset3 === 0 ? false : true - content: TileText - { - text: qsTr(acLimitPreset3 + " A"); font.bold: true; - color: "white" - } - } - DetailButton - { - visible: currentLimitIsAdjustable - id: preset4button - baseColor: newCurrentLimit === acLimitPreset4 ? "black" : root.buttonColor - pressedColor: root.pressedColor - opacity: acLimitPreset4 === 0 ? 0.001 : 1 - height: 40 - width: parent.width - onClicked: setNewValue (acLimitPreset4) - enabled: acLimitPreset4 === 0 ? false : true - content: TileText - { - text: qsTr(acLimitPreset4 + " A"); font.bold: true; - color: "white" - } - } - } - Row - { - visible: currentLimitIsAdjustable - width: (parent.width / 2) - 2 - spacing: 4 - DetailButton - { - id: trimMinus - baseColor: root.buttonColor - pressedColor: root.pressedColor - height: 40 - width: parent.width - enablePressAndHold: true - onClicked: trimNewValue (-1) - enabled: newCurrentLimit === acLimitPreset4 ? false : true - content: TileText - { - text: qsTr("-1 A"); font.bold: true; - color: "white" - } - } - DetailButton - { - id: trimPlus - baseColor: root.buttonColor - pressedColor: root.pressedColor - height: 40 - width: parent.width - enablePressAndHold: true - onClicked: trimNewValue (+1) - content: TileText - { - text: qsTr("+1 A"); font.bold: true; - color: "white" - } - } - } - Row - { - visible: currentLimitIsAdjustable - width: parent.width - spacing: 4 - DetailButton - { - id: acceptButton - baseColor: root.buttonColor - pressedColor: root.pressedColor - height: 40 - width: parent.width - onClicked: accept() - content: TileText { text: qsTr ("Accept New"); - font.bold: true; color: newCurrentLimit !== actualCurrentLimit ? "white" : "#d9d9d9" } - } - } - } - } - - function setNewValue (newValue) - { - if (currentLimitIsAdjustable) - newCurrentLimit = newValue - } - - function trimNewValue (trimValue) - { - if (!currentLimitIsAdjustable) - return - - newCurrentLimit += trimValue - if (newCurrentLimit < 0) - newCurrentLimit = 0 - } - - function cancel () - { - newCurrentLimit = actualCurrentLimit - pageStack.pop() - } - - function accept () - { - if (currentLimitIsAdjustable) - { - currentLimitItem.setValue (newCurrentLimit) - pageStack.pop() // return to main screen after changing input current limit - } - } - - function getActualCurrent () - { - actualCurrentLimit = currentLimitItem.valid ? currentLimitItem.value : 0 - newCurrentLimit = actualCurrentLimit - } - - // When new service is found check if is a tank sensor - Connections - { - target: DBusServices - onDbusServiceFound: addService(service) - } - - //// hard key handler - // used to press buttons when touch isn't available - // UP and DOWN buttons cycle through the list of buttons - // "space" button is used to simulate a button press - // button must be highlighted so that other uses of "space" - // will still occur - - // list of buttons to be accessed via hard buttons - property variant buttonList: - [ - preset1button, preset2button, preset3button, preset4button, trimMinus, trimPlus, acceptButton - ] - - property int buttonIndex: 0 - - Timer - { - id: targetTimer - interval: 5000 - repeat: false - running: false - onTriggered: { clearHighlight () } - } - - Keys.forwardTo: [keyHandler] - - Item - { - id: keyHandler - Keys.onDownPressed: - { - nextTarget (+1) - event.accepted = true - } - - Keys.onUpPressed: - { - nextTarget (-1) - event.accepted = true - } - } - - function nextTarget (increment) - { - // make one pass through all possible targets to find an enabled one - // if found, that's the new selectedTarget, - // if not selectedTarget does not change - var newIndex = buttonIndex - for (var i = 0; i < buttonList.length; i++) - { - // just restore highlight if not visible - if ( ! targetTimer.running && buttonList[newIndex].visible) - { - setActiveButton (buttonIndex) - return - } - newIndex += increment - if (newIndex >= buttonList.length) - newIndex = 0 - else if (newIndex < 0) - newIndex = buttonList.length - 1 - if (buttonList[newIndex].visible) - { - setActiveButton (newIndex) - break - } - } - } - - // Keys.onSpacePressed doesn't work - stolen by pageHandler - // so build a custom page handler so "space" can be used to press a button - pageToolbarHandler: detailToolbarHandler - ToolbarHandlerPages - { - id: detailToolbarHandler - isDefault: true - function centerAction() - { - acceptSpaceButton () - } - } - - function acceptSpaceButton () - { - if (targetTimer.running) - { - buttonList[buttonIndex].clicked () - } - } - - function setActiveButton (newIndex) - { - buttonIndex = newIndex - for (var i = 0; i < buttonList.length; i++) - if (i == newIndex) - buttonList[i].highlight = true - else - buttonList[i].highlight = false - targetTimer.restart () - } - - function clearHighlight () - { - for (var i = 0; i < buttonList.length; i++) - buttonList[i].highlight = false - } -} diff --git a/FileSets/v3.40~8/DetailInverter.qml b/FileSets/v3.40~8/DetailInverter.qml deleted file mode 100644 index fd7e9def..00000000 --- a/FileSets/v3.40~8/DetailInverter.qml +++ /dev/null @@ -1,653 +0,0 @@ -////// detail page for setting inverter mode -////// and displaying inverter details -////// pushed from Flow overview - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 -import "enhancedFormat.js" as EnhFmt - -MbPage { - id: root - - title: "Inverter detail" - - property variant sys: theSystem - property string systemPrefix: "com.victronenergy.system" - - property int fontPixelSize: 18 - property color buttonColor: "#979797" - property color pressedColor: "#d3d3d3" - property color backgroundColor: "#b3b3b3" - - property int inverterMode: inverterModeItem.valid ? inverterModeItem.value : 0 - property bool editable: inverterService != "" && inverterModeItem.valid - - property int buttonHeight: 40 - property int buttonWidth: 72 - property int buttonAreaWidth: buttonWidth * 2 + 4 - - property int rowTitleWidth: 132 - property int dataColumns: 3 - property int totalDataWidth: root.width - rowTitleWidth - buttonAreaWidth - 12 - property int tableColumnWidth: totalDataWidth / dataColumns - property int legColumnWidth: phaseCount <= 1 ? totalDataWidth : totalDataWidth / phaseCount - - property int numberOfMultis: 0 - property int numberOfInverters: 0 - property string inverterService: "" - property bool isInverter: numberOfMultis === 0 && numberOfInverters === 1 - - Component.onCompleted: { discoverServices(); highlightMode () } - - property bool showChargePriority: numberOfMultis > 0 && sys.preferRenewableEnergy.valid - property bool preferRenewableEnergy: showChargePriority && sys.preferRenewableEnergy.value == 1 - property bool autoReturnToRenewable: sys.remoteGeneratorSelected.valid - property bool acInIsGenerator: sys.acSource == 2 - - VBusItem - { - id: inverterModeItem - bind: Utils.path(inverterService, "/Mode") - onValidChanged: highlightMode () - onValueChanged: highlightMode () - } - property VBusItem systemState: VBusItem { bind: Utils.path(systemPrefix, "/SystemState/State") } - SystemState - { - id: vebusState - bind: systemState.valid ? Utils.path(systemPrefix, "/SystemState/State") : Utils.path(inverterService, "/State") - } - VBusItem { id: pInL1; bind: Utils.path(inverterService, "/Ac/ActiveIn/L1/P") } - VBusItem { id: pInL2; bind: Utils.path(inverterService, "/Ac/ActiveIn/L2/P") } - VBusItem { id: pInL3; bind: Utils.path(inverterService, "/Ac/ActiveIn/L2/P") } - VBusItem { id: vInL1; bind: Utils.path(inverterService, "/Ac/ActiveIn/L1/V") } - VBusItem { id: vInL2; bind: Utils.path(inverterService, "/Ac/ActiveIn/L2/V") } - VBusItem { id: vInL3; bind: Utils.path(inverterService, "/Ac/ActiveIn/L3/V") } - VBusItem { id: iInL1; bind: Utils.path(inverterService, "/Ac/ActiveIn/L1/I") } - VBusItem { id: iInL2; bind: Utils.path(inverterService, "/Ac/ActiveIn/L2/I") } - VBusItem { id: iInL3; bind: Utils.path(inverterService, "/Ac/ActiveIn/L3/I") } - VBusItem { id: pOutL1; bind: Utils.path(inverterService, "/Ac/Out/L1/P") } - VBusItem { id: pOutL2; bind: Utils.path(inverterService, "/Ac/Out/L2/P") } - VBusItem { id: pOutL3; bind: Utils.path(inverterService, "/Ac/Out/L3/P") } - VBusItem { id: vOutL1; bind: Utils.path(inverterService, "/Ac/Out/L1/V") } - VBusItem { id: vOutL2; bind: Utils.path(inverterService, "/Ac/Out/L2/V") } - VBusItem { id: vOutL3; bind: Utils.path(inverterService, "/Ac/Out/L3/V") } - VBusItem { id: iOutL1; bind: Utils.path(inverterService, "/Ac/Out/L1/I") } - VBusItem { id: iOutL2; bind: Utils.path(inverterService, "/Ac/Out/L2/I") } - VBusItem { id: iOutL3; bind: Utils.path(inverterService, "/Ac/Out/L3/I") } - VBusItem { id: fInL1; bind: Utils.path(inverterService, "/Ac/ActiveIn/L1/F") } - VBusItem { id: fOutL1; bind: Utils.path(inverterService, "/Ac/Out/L1/F") } - VBusItem { id: dcPower; bind: Utils.path(inverterService, "/Dc/0/Power") } - VBusItem { id: dcCurrent; bind: Utils.path(inverterService, "/Dc/0/Current") } - VBusItem { id: _l2L1OutSummed; bind: Utils.path(inverterService, "/Ac/State/SplitPhaseL2L1OutSummed") } - VBusItem { id: phaseCountItem; bind: Utils.path(inverterService, "/Ac/NumberOfPhases") } - - property bool noL2inverter: _l2L1OutSummed.valid - property bool l2AndL1OutSummed: noL2inverter && _l2L1OutSummed.value === 1 - property int phaseCount: phaseCountItem.valid ? phaseCountItem.value : 0 - - // background - Rectangle - { - anchors - { - fill: parent - } - color: root.backgroundColor - } - - Column - { - spacing: 2 - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left; anchors.leftMargin: 3 - Row - { - PowerGaugeMulti - { - id: gauge - width: rowTitleWidth + totalDataWidth - height: 15 - inverterService: root.inverterService - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Total Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: - { - var total = 0 - var totalValid = false - if (pOutL1.valid && pInL1.valid) - { - total += pOutL1.value - pInL1.value - totalValid = true - } - if (pOutL2.valid && pInL2.valid) - { - total += pOutL2.value - pInL2.value - totalValid = true - } - if (pOutL3.valid && pInL3.valid) - { - total += pOutL3.value - pInL3.value - totalValid = true - } - if (totalValid) - return EnhFmt.formatValue (total, "W") - else - return "--" - } - } - visible: phaseCount >= 2 - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("State") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: vebusState.text } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: "" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L1" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L2" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L3"; visible: phaseCount >= 3 } - visible: phaseCount >= 2 - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: formatValueDiff (pOutL1, pInL1, "W") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: - { - if (l2AndL1OutSummed) - return "< < <" - else if (noL2inverter) - return qsTr("none") - else - return formatValueDiff (pOutL2, pInL2, "W") - } - visible: phaseCount >= 2 - } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: formatValueDiff (pOutL3, pInL3, "W"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Input Voltage") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (vInL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (vInL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (vInL3, "V"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Output Voltage") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (vOutL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (vOutL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (vOutL3, "V"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Input Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (iInL1, "A") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (iInL2, "A"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (iInL3, "A"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Output Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (iOutL1, "A") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l2AndL1OutSummed ? "< < <" : EnhFmt.formatVBusItem (iOutL2, "A"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (iOutL3, "A"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Frequency In / Out") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth / 2; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (fInL1, "Hz") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth / 2; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (fOutL1, "Hz") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("DC Power / Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth * 0.4; horizontalAlignment: Text.AlignHCenter - text: - { - if (! dcPower.valid) - return "" - else if (dcPower.value > 0) - return qsTr ("supplying") - else if (dcPower.value < 0) - return qsTr ("consuming") - else - return "" - } - } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth * 0.3; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (dcPower, "W") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth * 0.3; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (dcCurrent, "A") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: l2AndL1OutSummed ? qsTr ("L2 Output values included in L1") : qsTr ("L2 AC out from AC in (no inverter)") - visible: noL2inverter - } - } - } - Column - { - id: inverterModeButtonArea - width: root.buttonAreaWidth - anchors.top: parent.top; anchors.topMargin: 3 - anchors.right: parent.right; anchors.rightMargin: 3 - spacing: 4 - - Row - { - Text - { - font.pixelSize: 12; color: "black" - width: root.buttonAreaWidth; horizontalAlignment: Text.AlignHCenter - text: qsTr("Inverter mode") - visible: showChargePriority - } - } - Row - { - spacing: 4 - DetailButton - { - id: onButton - baseColor: inverterMode === 3 ? "green" : "#e6ffe6" - pressedColor: root.pressedColor - height: root.buttonHeight - width: root.buttonWidth - visible: !isInverter - onClicked: changeMode(3) - content: TileText - { - text: qsTr("On"); font.bold: true; - color: inverterMode === 3 ? "white" : "gray" - } - } - DetailButton - { - id: offButton - baseColor: inverterMode === 4 ? "black" : "#e6e6e6" - pressedColor: root.pressedColor - height: root.buttonHeight - width: root.buttonWidth - onClicked: changeMode(4) - content: TileText - { - text: qsTr("Off"); font.bold: true; - color: inverterMode === 4 ? "white" : "gray" - } - } - } - Row - { - spacing: 4 - DetailButton - { - id: invertOnlyButton - baseColor: inverterMode === 2 ? "blue" : "#ccccff" - pressedColor: root.pressedColor - height: root.buttonHeight - width: root.buttonWidth - onClicked: changeMode(2) - content: TileText - { - text: isInverter ? qsTr("On") : qsTr("Inverter\nOnly"); font.bold: true; - color: inverterMode === 2 ? "white" : "gray" - } - } - DetailButton - { - id: chargeOnlyButton - baseColor: inverterMode === 1 ? "orange" : "#ffedcc" - pressedColor: root.pressedColor - height: root.buttonHeight - width: root.buttonWidth - visible: !isInverter - onClicked: changeMode(1) - content: TileText - { - text: qsTr("Charger\nOnly"); font.bold: true; - color: inverterMode === 1 ? "white" : "gray" - } - } - DetailButton - { - id: ecoButton - baseColor: inverterMode === 5 ? "orange" : "#ffedcc" - pressedColor: root.pressedColor - height: root.buttonHeight - width: root.buttonWidth - visible: isInverter - onClicked: changeMode(5) - content: TileText - { - text: qsTr("Eco"); font.bold: true; - color: inverterMode === 5 ? "white" : "black" - } - } - } - } - Column - { - id: chargePriorityButtonArea - width: root.buttonAreaWidth - anchors.bottom: parent.bottom; anchors.bottomMargin: 3 - anchors.right: parent.right; anchors.rightMargin: 3 - spacing: 4 - - Row - { - Text - { - font.pixelSize: 12; color: "black" - width: root.buttonAreaWidth; horizontalAlignment: Text.AlignHCenter - text: qsTr("Charge priority") - visible: showChargePriority - } - } - Row - { - spacing: 4 - DetailButton - { - id: acPriorityButton - baseColor: ! preferRenewableEnergy && ! acInIsGenerator ? "orange" : "#ffedcc" - pressedColor: root.pressedColor - height: root.buttonHeight - width: root.buttonWidth - onClicked: { if (! acInIsGenerator) sys.preferRenewableEnergy.setValue (0)} - visible: showChargePriority - content: TileText - { - text: "Grid"; font.bold: true - color: ! preferRenewableEnergy && ! acInIsGenerator ? "white" : "gray" - } - } - DetailButton - { - id: renewablePriorityButton - baseColor: preferRenewableEnergy && ! acInIsGenerator ? "green" : "#e6ffe6" - pressedColor: root.pressedColor - height: root.buttonHeight - width: root.buttonWidth - visible: showChargePriority - onClicked: { if (! acInIsGenerator) sys.preferRenewableEnergy.setValue (1)} - content: TileText - { - text: qsTr("Renew\nable"); font.bold: true - color: preferRenewableEnergy && ! acInIsGenerator ? "white" : "gray" - } - } - } - Row - { - Text - { - font.pixelSize: 12; color: "black" - width: root.buttonAreaWidth; horizontalAlignment: Text.AlignHCenter - text: - { - if (acInIsGenerator) - return qsTr ("Generator active\nno priority") - else if (autoReturnToRenewable && ! preferRenewableEnergy) - return qsTr ("returns to Renewable\n at 100% SOC") - else return "\n" - } - visible: showChargePriority - } - } - } - - - function changeMode(newMode) - { - if (editable) - { - inverterModeItem.setValue(newMode) - pageStack.pop() // return to flow screen after changing inverter mode - } - } - - function cancel() - { - pageStack.pop() - } - - function highlightMode () - { - if (editable) - inverterMode = inverterModeItem.value - else - inverterMode = 0 - } - - - // When new service is found check if is a tank sensor - Connections - { - target: DBusServices - onDbusServiceFound: addService(service) - } - - function addService(service) - { - switch (service.type) - { - case DBusService.DBUS_SERVICE_MULTI: - case DBusService.DBUS_SERVICE_MULTI_RS: - numberOfMultis++ - if (numberOfMultis === 1) - inverterService = service.name; - break;; - case DBusService.DBUS_SERVICE_INVERTER: - numberOfInverters++ - if (numberOfInverters === 1 && numberOfMultis === 0) - inverterService = service.name; - break;; - } - } - - // Detect available services of interest - function discoverServices() - { - numberOfMultis = 0 - numberOfInverters = 0 - inverterService = "" - for (var i = 0; i < DBusServices.count; i++) - { - addService(DBusServices.at(i)) - } - } - - function formatValueDiff (item1, item2, unit) - { - if (item1.valid && item2.valid) - return EnhFmt.formatValue (item1.value - item2.value, unit) - else - return "--" - } - - - //// hard key handler - // used to press buttons when touch isn't available - // UP and DOWN buttons cycle through the list of buttons - // "space" button is used to simulate a button press - // button must be highlighted so that other uses of "space" - // will still occur - - // list of buttons to be accessed via hard buttons - property variant buttonList: - [ - onButton, offButton, invertOnlyButton, chargeOnlyButton, ecoButton - ] - - property int buttonIndex: 0 - - Timer - { - id: targetTimer - interval: 5000 - repeat: false - running: false - onTriggered: { clearHighlight () } - } - - Keys.forwardTo: [keyHandler] - - Item - { - id: keyHandler - Keys.onDownPressed: - { - nextTarget (+1) - event.accepted = true - } - - Keys.onUpPressed: - { - nextTarget (-1) - event.accepted = true - } - } - - function nextTarget (increment) - { - // make one pass through all possible targets to find an enabled one - // if found, that's the new selectedTarget, - // if not selectedTarget does not change - var newIndex = buttonIndex - for (var i = 0; i < buttonList.length; i++) - { - // just restore highlight if not visible - if ( ! targetTimer.running && buttonList[newIndex].visible) - { - setActiveButton (buttonIndex) - return - } - newIndex += increment - if (newIndex >= buttonList.length) - newIndex = 0 - else if (newIndex < 0) - newIndex = buttonList.length - 1 - if (buttonList[newIndex].visible) - { - setActiveButton (newIndex) - break - } - } - } - - // Keys.onSpacePressed doesn't work - stolen by pageHandler - // so build a custom page handler so "space" can be used to press a button - pageToolbarHandler: detailToolbarHandler - ToolbarHandlerPages - { - id: detailToolbarHandler - isDefault: true - function centerAction() - { - acceptSpaceButton () - } - } - - function acceptSpaceButton () - { - if (targetTimer.running) - { - buttonList[buttonIndex].clicked () - } - } - - function setActiveButton (newIndex) - { - buttonIndex = newIndex - for (var i = 0; i < buttonList.length; i++) - if (i == newIndex) - buttonList[i].highlight = true - else - buttonList[i].highlight = false - targetTimer.restart () - } - - function clearHighlight () - { - for (var i = 0; i < buttonList.length; i++) - buttonList[i].highlight = false - } -} diff --git a/FileSets/v3.40~8/DetailLoadsCombined.qml b/FileSets/v3.40~8/DetailLoadsCombined.qml deleted file mode 100644 index 5909cb10..00000000 --- a/FileSets/v3.40~8/DetailLoadsCombined.qml +++ /dev/null @@ -1,146 +0,0 @@ -////// detail page for displaying critical AC output details -////// pushed from Flow overview - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 -import "enhancedFormat.js" as EnhFmt - -MbPage { - id: root - - title: qsTr ("AC Loads detail") - - property variant sys: theSystem - property string systemPrefix: "com.victronenergy.system" - - property int fontPixelSize: 18 - property color backgroundColor: "#b3b3b3" - - property int dataColumns: 3 - property int rowTitleWidth: 130 - property int totalDataWidth: root.width - rowTitleWidth - 20 - property int tableColumnWidth: totalDataWidth / dataColumns - property int legColumnWidth: phaseCount <= 1 ? totalDataWidth : totalDataWidth / phaseCount - - property int phaseCount: sys.acLoad.phaseCount.valid ? sys.acLoad.phaseCount.value : 0 - - VBusItem { id: vebusServiceItem; bind: Utils.path(systemPrefix, "/VebusService") } - property string inverterService: vebusServiceItem.valid ? vebusServiceItem.value : "" - property bool l2AndL1OutSummed: sys.acLoad.l2AndL1OutSummed - - // background - Rectangle - { - anchors - { - fill: parent - } - color: root.backgroundColor - } - - Row - { - spacing: 5 - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - Column - { - spacing: 2 - Row - { - Text { id: totalLabel; font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Total Power") } - Text { id: totalPower; font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.power, "W") - } - PowerGauge - { - id: gauge - width: (root.width * 0.9) - totalLabel.width - totalPower.width - height: 15 - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputMaxPower" - connection: sys.acLoad - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: "" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L1" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L2"; visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L3"; visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.powerL1, "W") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l2AndL1OutSummed ? "< < <" : EnhFmt.formatVBusItem (sys.acLoad.powerL2, "W"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.powerL3, "W"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Voltage") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.voltageL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l2AndL1OutSummed ? "< < <" : EnhFmt.formatVBusItem (sys.acLoad.voltageL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.voltageL3, "V"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.currentL1, "A") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l2AndL1OutSummed ? "< < <" : EnhFmt.formatVBusItem (sys.acLoad.currentL2, "A"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.currentL3, "A"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Frequency") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acLoad.frequency, "Hz") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: "L2 values included in L1" - visible: l2AndL1OutSummed } - } - } - } -} diff --git a/FileSets/v3.40~8/DetailLoadsOnInput.qml b/FileSets/v3.40~8/DetailLoadsOnInput.qml deleted file mode 100644 index 999a62ac..00000000 --- a/FileSets/v3.40~8/DetailLoadsOnInput.qml +++ /dev/null @@ -1,146 +0,0 @@ -////// detail page for displaying non-critical AC output details -////// pushed from Flow overview - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 -import "enhancedFormat.js" as EnhFmt - -MbPage { - id: root - - title: "Loads on AC Input Detail" - - property variant sys: theSystem - property string systemPrefix: "com.victronenergy.system" - - property int fontPixelSize: 18 - property color backgroundColor: "#b3b3b3" - - property int dataColumns: 3 - property int rowTitleWidth: 130 - property int totalDataWidth: root.width - rowTitleWidth - 20 - property int tableColumnWidth: totalDataWidth / dataColumns - property int legColumnWidth: phaseCount <= 1 ? totalDataWidth : totalDataWidth / phaseCount - - property int phaseCount: sys.acInLoad.phaseCount.valid ? sys.acInLoad.phaseCount.value : 0 - - VBusItem { id: vebusServiceItem; bind: Utils.path(systemPrefix, "/VebusService") } - property string inverterService: vebusServiceItem.valid ? vebusServiceItem.value : "" - property bool splitPhasePassthruDisabled: sys.acInput.splitPhasePassthruDisabled - - // background - Rectangle - { - anchors - { - fill: parent - } - color: root.backgroundColor - } - - Row - { - spacing: 5 - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - Column - { - spacing: 2 - Row - { - Text { id: totalLabel; font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Total Power") } - Text { id: totalPower; font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.power, "W") - } - PowerGauge - { - id: gauge - width: (root.width * 0.9) - totalLabel.width - totalPower.width - height: 15 - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputMaxPower" - connection: sys.acInLoad - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: "" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L1" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L2"; visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L3"; visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.powerL1, "W") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.acInLoad.powerL2, "W"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.powerL3, "W"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Voltage") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.voltageL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.acInLoad.voltageL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.voltageL3, "V"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.currentL1, "A") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: splitPhasePassthruDisabled ? "< < <" : EnhFmt.formatVBusItem (sys.acInLoad.currentL2, "A"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.currentL3, "A"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Frequency") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (sys.acInLoad.frequency, "Hz") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: "L2 values included in L1" - visible: splitPhasePassthruDisabled } - } - } - } -} diff --git a/FileSets/v3.40~8/DetailLoadsOnOutput.qml b/FileSets/v3.40~8/DetailLoadsOnOutput.qml deleted file mode 100644 index 2092989c..00000000 --- a/FileSets/v3.40~8/DetailLoadsOnOutput.qml +++ /dev/null @@ -1,151 +0,0 @@ -////// detail page for displaying critical AC output details -////// pushed from Flow overview - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 -import "enhancedFormat.js" as EnhFmt - -MbPage { - id: root - - title: combineAcLoads ? qsTr ("AC Loads detail") : qsTr ("Loads on AC Output detail") - - property variant sys: theSystem - property string systemPrefix: "com.victronenergy.system" - property string settingsPrefix: "com.victronenergy.settings" - - property int fontPixelSize: 18 - property color backgroundColor: "#b3b3b3" - - property int dataColumns: 3 - property int rowTitleWidth: 130 - property int totalDataWidth: root.width - rowTitleWidth - 20 - property int tableColumnWidth: totalDataWidth / dataColumns - property int legColumnWidth: phaseCount <= 1 ? totalDataWidth : totalDataWidth / phaseCount - - property int phaseCount: outputLoad.phaseCount.valid ? outputLoad.phaseCount.value : 0 - - VBusItem { id: vebusServiceItem; bind: Utils.path(systemPrefix, "/VebusService") } - property string inverterService: vebusServiceItem.valid ? vebusServiceItem.value : "" - property bool l2AndL1OutSummed: sys.acLoad.l2AndL1OutSummed - - VBusItem { id: _combineAcLoads; bind: "com.victronenergy.settings/Settings/GuiMods/EnhancedFlowCombineLoads" } - property bool combineAcLoads: _combineAcLoads.valid && _combineAcLoads.value === 1 - property variant outputLoad: combineAcLoads ? sys.acLoad : sys.acOutLoad - - // background - Rectangle - { - anchors - { - fill: parent - } - color: root.backgroundColor - } - - Row - { - spacing: 5 - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - Column - { - spacing: 2 - Row - { - Text { id: totalLabel; font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Total Power") } - Text { id: totalPower; font.pixelSize: 12; font.bold: true; color: "black" - width: tableColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.power, "W") - } - PowerGauge - { - id: gauge - width: (root.width * 0.9) - totalLabel.width - totalPower.width - height: 15 - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputMaxPower" - connection: outputLoad - } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: "" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L1" } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L2"; visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: "L3"; visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Power") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.powerL1, "W") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l2AndL1OutSummed ? "< < <" : EnhFmt.formatVBusItem (outputLoad.powerL2, "W"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.powerL3, "W"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Voltage") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.voltageL1, "V") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l2AndL1OutSummed ? "< < <" : EnhFmt.formatVBusItem (outputLoad.voltageL2, "V"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.voltageL3, "V"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Current") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.currentL1, "A") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: l2AndL1OutSummed ? "< < <" : EnhFmt.formatVBusItem (outputLoad.currentL2, "A"); visible: phaseCount >= 2 } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: legColumnWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.currentL3, "A"); visible: phaseCount >= 3 } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth; horizontalAlignment: Text.AlignRight - text: qsTr("Frequency") } - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: EnhFmt.formatVBusItem (outputLoad.frequency, "Hz") } - } - Row - { - Text { font.pixelSize: 12; font.bold: true; color: "black" - width: rowTitleWidth + totalDataWidth; horizontalAlignment: Text.AlignHCenter - text: "L2 values included in L1" - visible: l2AndL1OutSummed } - } - } - } -} diff --git a/FileSets/v3.40~8/HubData.qml b/FileSets/v3.40~8/HubData.qml deleted file mode 100644 index 5e375f49..00000000 --- a/FileSets/v3.40~8/HubData.qml +++ /dev/null @@ -1,273 +0,0 @@ -//////// modified for VE.Direct inverter support -//////// modified for grid/genset meter -//////// added alternator, AC charger, wind generator - -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -Item { - id: root - - property variant sys: theSystem - - property string systemPrefix: "com.victronenergy.system" - property string settingsPrefix: "com.victronenergy.settings" - property string vebusPrefix: _vebusService.valid ? _vebusService.value : "" - -//////// add to support VE.Direct inverters - property string inverterService: "" -//////// add for grid/genset meters - property string gridMeterService: "" - property string gensetService: "" - - property variant battery: _battery - property alias dcSystem: _dcSystem - property alias alternator: _alternator - property alias windGenerator: _windGenerator - property alias fuelCell: _fuelCell - property alias acCharger: _acCharger - property alias pvCharger: _pvCharger - property alias pvOnAcIn1: _pvOnAcIn1 - property alias pvOnAcIn2: _pvOnAcIn2 - property alias pvOnAcOut: _pvOnAcOut - property alias vebusDc: _vebusDc - property alias acLoad: _acLoad - property alias acInLoad: _acInLoad - property alias acOutLoad: _acOutLoad - property alias grid: _grid - property alias acInput: _activein - property alias genset: _genset - property VBusItem systemType: VBusItem { bind: Utils.path(systemPrefix, "/SystemType") } - property variant acSource: _acSource.value - property VBusItem preferRenewableEnergy: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/PreferRenewableEnergy") } - property VBusItem remoteGeneratorSelected: VBusItem { bind: Utils.path(vebusPrefix, "/Ac/State/RemoteGeneratorSelected") } - - property alias pvOnGrid: _pvOnAcIn2 - - property int batteryStateIdle: 0 - property int batteryStateCharging: 1 - property int batteryStateDischarging: 2 - - property int acSourceNotAvailable: 0 - property int acSourceGrid: 1 - property int acSourceGenset: 2 - property int acSourceShore: 3 // same as grid - - property alias pvInvertersProductIds: _pvInvertersProductIds - property alias batteryProductId: _batteryProductId - - VBusItem { - id: _pvInvertersProductIds - bind: Utils.path(systemPrefix, "/PvInvertersProductIds") - } - - VBusItem { - id: _batteryProductId - bind: Utils.path(systemPrefix, "/Dc/Battery/ProductId") - } - - VBusItem { - id: _vebusService - bind: Utils.path(systemPrefix, "/VebusService") - } - - QtObject { - id: _pvCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Pv/Power"); unit: "W"} - } - -//////// added alternator - QtObject { - id: _alternator - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Alternator/Power"); unit: "W"} - } - -//////// added AC charger - QtObject { - id: _acCharger - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Charger/Power"); unit: "W"} - } - -//////// added wind generator - QtObject { - id: _windGenerator - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/WindGenerator/Power"); unit: "W"} - } - -//////// added fuel cell - QtObject { - id: _fuelCell - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/FuelCell/Power"); unit: "W"} - } - - ObjectAcConnection { - id: _pvOnAcOut - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnOutput") - } - - ObjectAcConnection { - id: _pvOnAcIn1 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGenset") - } - - ObjectAcConnection { - id: _pvOnAcIn2 - bindPrefix: Utils.path(systemPrefix, "/Ac/PvOnGrid") - } - - ObjectAcConnection { - id: _genset - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Genset") -//////// modified for VE.Direct inverter support - inverterSource: "/Ac/ActiveIn" - inverterService: sys.vebusPrefix != "" ? sys.vebusPrefix : root.inverterService - } - - VBusItem { - id: _acSource - bind: Utils.path(systemPrefix, "/Ac/ActiveIn/Source") - } - - /* - * Single Multis that can be split-phase reports NrOfPhases of 2 - * When L2 is disconnected from the input the output L1 and L2 - * are shorted. This item indicates if L2 is passed through - * from AC-in to AC-out. - * 1: L2 is being passed through from AC-in to AC-out. - * 0: L1 and L2 are shorted together. - * invalid: The unit is configured in such way that its L2 output is not used. - */ - - VBusItem { - id: _splitPhaseL2Passthru - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2Passthru") - } - - VBusItem { - id: _l2L1OutSummed - bind: Utils.path(vebusPrefix, "/Ac/State/SplitPhaseL2L1OutSummed") - } - - - ObjectAcConnection { - id: _grid - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/Grid") -//////// modified for VE.Direct inverter support - inverterSource: "/Ac/ActiveIn" - inverterService: sys.vebusPrefix != "" ? sys.vebusPrefix : root.inverterService - } - - ObjectAcConnection { - id: _activein - splitPhaseL2PassthruDisabled: _splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/ActiveIn") -//////// modified for VE.Direct inverter support - inverterSource: "/Ac/ActiveIn" - inverterService: sys.vebusPrefix != "" ? sys.vebusPrefix : root.inverterService - } - - ObjectAcConnection { - id: _acLoad - l2AndL1OutSummed: _l2L1OutSummed.valid && (_l2L1OutSummed.value !== 0) - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/Consumption") -//////// modified for VE.Direct inverter support - inverterSource: "/Ac/Out" - inverterService: sys.vebusPrefix != "" ? sys.vebusPrefix : root.inverterService - } - - ObjectAcConnection { - id: _acOutLoad - l2AndL1OutSummed: _l2L1OutSummed.valid && (_l2L1OutSummed.value !== 0) - isAcOutput: true - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnOutput") - } - - ObjectAcConnection { - id: _acInLoad - splitPhaseL2PassthruDisabled:_splitPhaseL2Passthru.value === 0 - bindPrefix: Utils.path(systemPrefix, "/Ac/ConsumptionOnInput") - } - - ObjectAcConnection { - id: _acUnknown - } - - QtObject { - id: _vebusDc - /* - * property VBusItem power: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Power"); unit: "W"} - * DONE: can interface doesn't support this yet! TODO use it...? - */ - property VBusItem current: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Current"); unit: "A"} - property VBusItem voltage: VBusItem { bind: Utils.path(vebusPrefix, "/Dc/0/Voltage"); unit: "V"} - property VBusItem power: VBusItem { - value: _vebusDc.current.valid && _vebusDc.voltage.valid ? - _vebusDc.current.value * _vebusDc.voltage.value : - undefined - unit: "W" - } - } - - QtObject { - id: _battery - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Power"); unit: "W"} - property VBusItem voltage: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Voltage"); unit: "V"} - property VBusItem current: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Current"); unit: "A"} - property VBusItem soc: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/Soc"); unit: "%"} - - // Get the battery charge state, see batteryState properties - property VBusItem state: VBusItem { bind: Utils.path(systemPrefix, "/Dc/Battery/State")} - } - - QtObject { - id: _dcSystem - property VBusItem power: VBusItem { bind: Utils.path(systemPrefix, "/Dc/System/Power"); unit: "W"} - } - -//////// add to support for adjustable watt / killowatt display switching - VBusItem { id: kwThresholdItem; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/KilowattThreshold") } - property int kilowattThreshold: kwThresholdItem.valid ? kwThresholdItem.value : 1000 - -//////// add to support VE.Direct inverters -//////// and grid/genset meters - Component.onCompleted: discoverServices() - - // When new service is found check if is a tank sensor - Connections - { - target: DBusServices - onDbusServiceFound: addService(service) - } - function addService(service) - { - switch (service.type) - { - case DBusService.DBUS_SERVICE_INVERTER: - if (inverterService === "") - inverterService = service.name; - break;; - case DBusService.DBUS_SERVICE_GRIDMETER: - if (gridMeterService === "") - gridMeterService = service.name; - break;; - case DBusService.DBUS_SERVICE_GENSET: - if (gensetService === "") - gensetService = service.name; - break;; - } - } - - // Check available services inverter services - function discoverServices() - { - inverterService = "" - gridMeterService = "" - gensetService = "" - for (var i = 0; i < DBusServices.count; i++) - addService(DBusServices.at(i)) - } -} diff --git a/FileSets/v3.40~8/MbEditBox.qml b/FileSets/v3.40~8/MbEditBox.qml deleted file mode 120000 index 8381b7d5..00000000 --- a/FileSets/v3.40~8/MbEditBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/MbEditBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/MbEditBoxDateTime.qml b/FileSets/v3.40~8/MbEditBoxDateTime.qml deleted file mode 120000 index 7fb351ea..00000000 --- a/FileSets/v3.40~8/MbEditBoxDateTime.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/MbItem.qml b/FileSets/v3.40~8/MbItem.qml deleted file mode 120000 index 048a313c..00000000 --- a/FileSets/v3.40~8/MbItem.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/MbItemDigitalInput.qml b/FileSets/v3.40~8/MbItemDigitalInput.qml deleted file mode 120000 index 4404b520..00000000 --- a/FileSets/v3.40~8/MbItemDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/MbSpinBox.qml b/FileSets/v3.40~8/MbSpinBox.qml deleted file mode 120000 index bc7530c8..00000000 --- a/FileSets/v3.40~8/MbSpinBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/MbStyle.qml b/FileSets/v3.40~8/MbStyle.qml deleted file mode 120000 index d1940446..00000000 --- a/FileSets/v3.40~8/MbStyle.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/MbSubMenu.qml b/FileSets/v3.40~8/MbSubMenu.qml deleted file mode 120000 index 35516a9a..00000000 --- a/FileSets/v3.40~8/MbSubMenu.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/Multi.qml b/FileSets/v3.40~8/Multi.qml deleted file mode 120000 index aa938460..00000000 --- a/FileSets/v3.40~8/Multi.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/ObjectAcConnection.qml b/FileSets/v3.40~8/ObjectAcConnection.qml deleted file mode 120000 index cab7f2d4..00000000 --- a/FileSets/v3.40~8/ObjectAcConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~8/OverviewAcValuesEnhanced.qml deleted file mode 120000 index 6d1e56b5..00000000 --- a/FileSets/v3.40~8/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/OverviewBox.qml b/FileSets/v3.40~8/OverviewBox.qml deleted file mode 120000 index 96aa4214..00000000 --- a/FileSets/v3.40~8/OverviewBox.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/OverviewConnection.qml b/FileSets/v3.40~8/OverviewConnection.qml deleted file mode 120000 index d833fd05..00000000 --- a/FileSets/v3.40~8/OverviewConnection.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/OverviewConnectionEnd.qml b/FileSets/v3.40~8/OverviewConnectionEnd.qml deleted file mode 120000 index 50c4b471..00000000 --- a/FileSets/v3.40~8/OverviewConnectionEnd.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/OverviewFlowComplex.qml b/FileSets/v3.40~8/OverviewFlowComplex.qml deleted file mode 100644 index c1fa7bb5..00000000 --- a/FileSets/v3.40~8/OverviewFlowComplex.qml +++ /dev/null @@ -1,1549 +0,0 @@ -///// Enhanced DC Coupled / AC Coupled Overview for GuiMods - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 -import "timeToGo.js" as TTG -import "enhancedFormat.js" as EnhFmt - -OverviewPage { - id: root - -////// GuiMods — DarkMode - property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } - property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 - - VBusItem { id: flowOverviewItem; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/FlowOverview") } - property bool dcCoupled: flowOverviewItem.valid && flowOverviewItem.value == 2 - - VBusItem { id: showInactiveTilesItem; bind: Utils.path(guiModsPrefix, "/ShowInactiveFlowTiles") } - property real disabledTileOpacity: (showInactiveTiles && showInactiveTilesItem.value === 1) ? 0.3 : 1 - property bool showInactiveTiles: showInactiveTilesItem.valid && showInactiveTilesItem.value >= 1 - property bool showInactiveFlow: showInactiveTilesItem.valid && showInactiveTilesItem.value == 3 - - property variant sys: theSystem - property string systemPrefix: "com.victronenergy.system" - property string settingsPrefix: "com.victronenergy.settings" - property color detailColor: "#b3b3b3" - property real laneWidth: (root.width - inOutTileWidth * 2 - battery.width) / 3 - - property int inOutTileHeight: (root.height - topOffset - bottomOffset - 3 * 5) / 4 - property int inOutTileWidth: 145 - VBusItem { id: timeToGo; bind: Utils.path(systemPrefix, "/Dc/Battery/TimeToGo") } - - VBusItem { id: vebusService; bind: Utils.path(systemPrefix, "/VebusService") } - property bool isMulti: vebusService.valid - property string veDirectInverterService: "" - property string inverterService: vebusService.valid ? vebusService.value : veDirectInverterService - - property bool combineAcLoads: dcCoupled || _combineAcLoads.valid && _combineAcLoads.value === 1 - property variant outputLoad: combineAcLoads ? sys.acLoad : sys.acOutLoad - - // for debug, ignore validity checks so all tiles and their flow lines will show - property bool showAllTiles: showInactiveTilesItem.valid && showInactiveTilesItem.value == 3 - - property bool hasInverter: false - property bool showInverter: hasInverter || inverterService != "" || showAllTiles - - property bool showLoadsOnOutput: showInverter || outputLoad.power.valid - property bool showAcInput: isMulti || sys.acInput.power.valid || showAllTiles - property bool hasLoadsOnInput: showAcInput && ! combineAcLoads && (! loadsOnInputItem.valid || loadsOnInputItem.value === 1) - property bool showLoadsOnInput: !dcCoupled && hasLoadsOnInput - property bool hasPvOnInput: sys.pvOnGrid.power.valid - property bool showPvOnInput: (!dcCoupled || !hasAcCharger) && hasPvOnInput - property bool hasPvOnOutput: sys.pvOnAcOut.power.valid - property bool showPvOnOutput: (!dcCoupled || !hasFuelCell) && hasPvOnOutput - property bool showPvCharger: sys.pvCharger.power.valid - property bool showDcSystem: (hasDcSystemItem.valid && hasDcSystemItem.value > 0) || showAllTiles - property bool showAlternator: (dcCoupled || !hasLoadsOnInput) && sys.alternator.power.valid - property bool hasFuelCell: sys.fuelCell.power.valid - property bool showFuelCell: (dcCoupled || !hasPvOnOutput) && hasFuelCell - property bool showWindGen: sys.windGenerator.power.valid - property bool hasAcCharger: sys.acCharger != undefined && sys.acCharger.power.valid - property bool showAcCharger: (dcCoupled || !hasPvOnInput) && hasAcCharger - - VBusItem { id: motorDrivePowerItem; bind: Utils.path(systemPrefix, "/Dc/MotorDrive/Power") } - property bool showMotorDrive: (dcCoupled || !hasLoadsOnInput) && ! showAlternator && motorDrivePowerItem.valid - - property int bottomOffset: showTanksTemps ? 45 : 5 - property int topOffset: showTanksTemps ? 1 : 5 - property string settingsBindPreffix: "com.victronenergy.settings" - property string pumpBindPreffix: "com.victronenergy.pump.startstop0" - property int numberOfTemps: 0 - - property int tankCount: showTanksEnable ? tankModel.rowCount : 0 - property int tempCount: showTempsEnable ? numberOfTemps : 0 - property int tankTempCount: tankCount + tempCount - property bool showTanks: showTanksEnable ? showStatusBar ? false : tankCount > 0 ? true : false : false - property bool showTemps: showTempsEnable ? showStatusBar ? false : tempCount > 0 ? true : false : false - property bool showTanksTemps: showTanks || showTemps - property int compactThreshold: 45 // height below this will be compacted vertically - property int batteryHeight: 91 - property bool compact: showTanks && showTemps && tankTempCount > 4 - property int tanksHeight: compact ? 22 : 45 - - VBusItem { id: ignoreAcInput1; bind: Utils.path(inverterService, "/Ac/State/IgnoreAcIn1") } - VBusItem { id: ignoreAcInput2; bind: Utils.path(inverterService, "/Ac/State/IgnoreAcIn2") } - VBusItem { id: acActiveInput; bind: Utils.path(inverterService, "/Ac/ActiveIn/ActiveInput") } - - property string guiModsPrefix: "com.victronenergy.settings/Settings/GuiMods" - VBusItem { id: showGaugesItem; bind: Utils.path(guiModsPrefix, "/ShowGauges") } - property bool showGauges: showGaugesItem.valid ? showGaugesItem.value === 1 ? true : false : false - VBusItem { id: showTanksItem; bind: Utils.path(guiModsPrefix, "/ShowEnhancedFlowOverviewTanks") } - property bool showTanksEnable: showTanksItem.valid ? showTanksItem.value === 1 ? true : false : false - VBusItem { id: showTempsItem; bind: Utils.path(guiModsPrefix, "/ShowEnhancedFlowOverviewTemps") } - property bool showTempsEnable: showTempsItem.valid ? showTempsItem.value === 1 ? true : false : false - - VBusItem { id: hasDcSystemItem; bind: "com.victronenergy.settings/Settings/SystemSetup/HasDcSystem" } - - VBusItem { id: timeFormatItem; bind: Utils.path(guiModsPrefix, "/TimeFormat") } - property string timeFormat: getTimeFormat () - - property double acInputFlow: showAcInput ? noNoise (sys.acInput.power) : 0 - property VBusItem vebusAcPower: VBusItem { bind: [sys.vebusPrefix, "/Ac/ActiveIn/P"] } - property double multiAcInputFlow: isMulti ? -noNoise (vebusAcPower) : 0 - property double pvOnInputFlow: showPvOnInput ? noNoise (sys.pvOnGrid.power) : 0 - property double loadsOnInputFlow: sys.acInLoad.power.valid ? -noNoise (sys.acInLoad.power) : 0 - property double pvInverterOnAcOutFlow: showPvOnOutput && sys.pvOnAcOut.power.valid ? noNoise (sys.pvOnAcOut.power) : 0 - property double acOutLoadFlow: sys.acOutLoad.power.valid ? -noNoise (sys.acOutLoad.power) : 0 - - property double pvChargerFlow: showPvCharger ? noNoise (sys.pvCharger.power) : 0 - property double dcSystemFlow: showDcSystem ? -noNoise (sys.dcSystem.power) : 0 - property double alternatorFlow: showAlternator ? noNoise (sys.alternator.power) : 0 - property double motorDriveFlow: showMotorDrive ? noNoise (motorDrivePowerItem) : 0 - property double inverterDcFlow: showInverter ? noNoise (sys.vebusDc.power) : 0 - property double batteryFlow: noNoise (sys.battery.power) - property double windGenFlow: noNoise (sys.windGenerator.power) - property double acChargerFlow: noNoise (sys.acCharger.power) - property double fuelCellFlow: noNoise (sys.fuelCell.power) - - VBusItem { id: showBatteryTempItem; bind: Utils.path(guiModsPrefix, "/ShowBatteryTempOnFlows") } - property bool showBatteryTemp: showBatteryTempItem.valid && showBatteryTempItem.value == 1 - - - function getTimeFormat () - { - if (!timeFormatItem.valid || timeFormatItem.value === 0) - return "" - else if (timeFormatItem.value === 2) - return "h:mm ap" - else - return "hh:mm" - } - - //Component.onCompleted: { discoverServices(); showHelp () } - onActiveChanged: - { - if (root.active) - { - discoverServices() - showHelp () - } - } - - title: dcCoupled ? qsTr("DC Coupled overview") : qsTr("AC Coupled overview") - - VBusItem { id: loadsOnInputItem; bind: "com.victronenergy.settings/Settings/GuiMods/ShowEnhancedFlowLoadsOnInput" } - VBusItem { id: _combineAcLoads; bind: "com.victronenergy.settings/Settings/GuiMods/EnhancedFlowCombineLoads" } - - OverviewBox { - id: acInBox - opacity: showAcInput ? 1 : disabledTileOpacity - visible: showAcInput || showInactiveTiles - width: inOutTileWidth - height: inOutTileHeight - title: - { - // input 1 is active - if (acActiveInput.value == 0) - { - if (ignoreAcInput1.valid && ignoreAcInput1.value == 1) - return qsTr ("AC In 1 Ignored") - else - return getAcSourceName(sys.acSource) - } - // input 2 is active - else if (acActiveInput.value == 1) - { - if (ignoreAcInput2.valid && ignoreAcInput2.value == 1) - return qsTr ("AC In 2 Ignored") - else - return getAcSourceName(sys.acSource) - } - else - return "no input" - } -////// GuiMods — DarkMode - titleColor: !darkMode ? "#E74c3c" : "#73261E" - color: !darkMode ? "#C0392B" : "#601C15" - anchors { - top: root.top; topMargin: topOffset - left: parent.left; leftMargin: 5 - } - values: TileText { - y: 13 - text: EnhFmt.formatVBusItem (sys.acInput.power) - font.pixelSize: 17 - visible: showAcInput - } - - MbIcon { - iconId: getAcSourceIcon(sys.acSource) - anchors { - bottom: parent.bottom - left: parent.left; leftMargin: 2 - } - opacity: 0.5 - } - PowerGauge - { - id: acInGauge - width: parent.width - height: 15 - anchors - { - top: parent.top; topMargin: 18 - horizontalCenter: parent.horizontalCenter - } - connection: sys.acInput - useInputCurrentLimit: true - maxForwardPowerParameter: "" - maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxFeedInPower" - visible: showGauges && showAcInput - } - DetailTarget { id: acInputTarget; detailsPage: "DetailAcInput.qml" } - } - - OverviewBox - { - id: pvInverterOnInput -////// GuiMods — DarkMode - titleColor: !darkMode ? "#F4B350" : "#7A5928" - color: !darkMode ? "#F39C12" : "#794E09" - title: qsTr("PV on Input") - width: inOutTileWidth - height: inOutTileHeight - visible: showPvOnInput || (showInactiveTiles && !dcCoupled) - opacity: showPvOnInput ? 1 : disabledTileOpacity - MbIcon - { - source: - { - var ids = sys.pvInvertersProductIds.text - if (ids.indexOf(0xA142) > -1) - return "image://theme/overview-fronius-logo" - return "" - } - visible: showPvOnInput - opacity: 0.3 - anchors { - bottom: parent.bottom - left: parent.left - margins: 2 - } - } - values: TileText { - y: 11 - text: EnhFmt.formatVBusItem (sys.pvOnGrid.power) - font.pixelSize: 17 - visible: showPvOnInput - } - anchors { - top: acInBox.bottom - topMargin: 5 - left: acInBox.left - } - PowerGauge - { - id: pvInverterOnInputGauge - width: parent.width - height: 15 - anchors - { - top: parent.top; topMargin: 18 - horizontalCenter: parent.horizontalCenter - } - connection: sys.pvOnGrid - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvOnGridMaxPower" - visible: showGauges && showPvOnInput - } - DetailTarget { id: pvOnInputTarget; detailsPage: "DetailPvInverter.qml" } - } - - OverviewBox { - id: acLoadOnInputBox - title: qsTr("AC In Loads") -////// GuiMods — DarkMode - color: !darkMode ? "#27AE60" : "#135730" - titleColor: !darkMode ? "#2ECC71" : "#176638" - width: inOutTileWidth - height: inOutTileHeight - opacity: showLoadsOnInput ? 1 : disabledTileOpacity - visible: showLoadsOnInput || (showInactiveTiles && !dcCoupled) - anchors { - top: pvInverterOnInput.bottom - topMargin: 5 - left: acInBox.left - } - values: TileText { - y: 13 - text: EnhFmt.formatVBusItem (sys.acInLoad.power) - font.pixelSize: 17 - visible: showLoadsOnInput - } - PowerGauge - { - id: acInLoadGauge - width: parent.width - height: 15 - anchors - { - top: parent.top; topMargin: 18 - horizontalCenter: parent.horizontalCenter - } - connection: sys.acInLoad - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputNonCriticalMaxPower" - visible: showGauges && showLoadsOnInput - } - DetailTarget { id: acLoadsOnInputTarget; detailsPage: "DetailLoadsOnInput.qml" } - } - - // check inverter to see if AC out 2 exists and hide noncritical loads if so - VBusItem { id: inverterOut2Item; bind: Utils.path(root.inverterService, "/Ac/Out/L2/V") } - - OverviewBox { - id: acOutputBox - title: combineAcLoads ? qsTr ("AC Loads") : qsTr ("AC Out Loads") -////// GuiMods — DarkMode - color: !darkMode ? "#27AE60" : "#135730" - titleColor: !darkMode ? "#2ECC71" : "#176638" - height: inOutTileHeight - width: inOutTileWidth - opacity: showLoadsOnOutput ? 1 : disabledTileOpacity - visible: showLoadsOnOutput || showInactiveTiles - anchors { - right: root.right; rightMargin: 5 - top: root.top; topMargin: topOffset - } - - values: TileText { - y: 13 - text: EnhFmt.formatVBusItem (outputLoad.power) - font.pixelSize: 17 - visible: showLoadsOnOutput - } - PowerGauge - { - id: acOutLoadGauge - width: parent.width - height: 15 - anchors - { - top: parent.top; topMargin: 18 - horizontalCenter: parent.horizontalCenter - } - connection: outputLoad - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputMaxPower" - visible: showGauges && showLoadsOnOutput - } - DetailTarget { id: acLoadsOnOutputTarget; detailsPage: "DetailLoadsOnOutput.qml" } - } - Timer { - id: wallClock - running: timeFormat != "" - repeat: true - - interval: 1000 - triggeredOnStart: true - onTriggered: time = Qt.formatDateTime(new Date(), timeFormat) - - property string time - } - - MultiEnhancedGP { - id: multi - iconId: "overview-inverter-short" - opacity: showInverter ? 1 : disabledTileOpacity - visible: showInverter || showInactiveTiles - anchors { - horizontalCenter: parent.horizontalCenter - top: acInBox.top - } - inverterService: root.inverterService - PowerGaugeMulti - { - id: multiGauge - width: multi.width - height: 13 - anchors - { - top: parent.top; topMargin: 21 - horizontalCenter: multi.horizontalCenter - } - inverterService: root.inverterService - visible: showGauges && showInverter - } - DetailTarget { id: multiTarget; detailsPage: "DetailInverter.qml"; width: 60; height: 60 } - } - TileText - { - text: wallClock.time - color: showInverter || darkMode ? "white" : "black" - width: inOutTileWidth - wrapMode: Text.WordWrap - font.pixelSize: 16 - anchors - { - bottom: multi.bottom; bottomMargin: 1 - horizontalCenter: multi.horizontalCenter; - horizontalCenterOffset: multiDcConnector.active ? -10 : 0 - } - visible: wallClock.running - } - - Battery { - id: battery - width: 145 - height: 96 - anchors { - bottom: parent.bottom; bottomMargin: bottomOffset; - right: acOutputBox.left; rightMargin: laneWidth - } - soc: sys.battery.soc.valid ? sys.battery.soc.value : 0 -////// add battery current bar graph - PowerGaugeBattery - { - id: batteryBar - width: parent.width - height: 10 - anchors - { - top: parent.top; topMargin: 52 - horizontalCenter: parent.horizontalCenter - } - visible: showGauges - } - values: Column { - width: parent.width - - TileText { - text: sys.battery.soc.value === undefined ? "--" : sys.battery.soc.format (0) - font.pixelSize: 25 - } - TileText { - text: EnhFmt.formatVBusItem (sys.battery.power, "W") - } - TileText { - text: " " - font.pixelSize: 6 - } - TileText { - text: EnhFmt.formatVBusItem (sys.battery.voltage, "V ", 2) - + EnhFmt.formatVBusItem (sys.battery.current, "A") - } - TileText { - text: timeToGo.valid ? qsTr ("Remain: ") + TTG.formatTimeToGo (timeToGo) : qsTr (" ") - } - } - DetailTarget { id: batteryTarget; detailsPage: "DetailBattery.qml" } - } - - OverviewBox - { - id: pvInverterOnAcOut -////// GuiMods — DarkMode - titleColor: !darkMode ? "#F4B350" : "#7A5928" - color: !darkMode ? "#F39C12" : "#794E09" - title: qsTr("PV on Output") - width: inOutTileWidth - height: inOutTileHeight - opacity: showPvOnOutput ? 1 : disabledTileOpacity - visible: showPvOnOutput || (showInactiveTiles && !dcCoupled) - MbIcon - { - source: - { - var ids = sys.pvInvertersProductIds.text - if (ids.indexOf(0xA142) > -1) - return "image://theme/overview-fronius-logo" - return "" - } - visible: showPvOnOutput - opacity: 0.3 - anchors { - bottom: parent.bottom - right: parent.right - margins: 2 - } - } - - values: TileText { - y: 11 - text: EnhFmt.formatVBusItem (sys.pvOnAcOut.power) - font.pixelSize: 17 - visible: showPvOnOutput - } - anchors { - top: acOutputBox.bottom - topMargin: 5 - right: acOutputBox.right - } - PowerGauge - { - id: pvInverterOnAcOutGauge - width: parent.width - height: 15 - anchors - { - top: parent.top; topMargin: 18 - horizontalCenter: parent.horizontalCenter - } - connection: sys.pvOnAcOut - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvOnOutputMaxPower" - visible: showGauges && showPvOnOutput - } - DetailTarget { id: pvOnOutputTarget; detailsPage: "DetailPvInverter.qml" } - } - - OverviewBox - { - id: acChargerBox - title: qsTr ("AC Charger") -////// GuiMods — DarkMode - color: !darkMode ? "#157894" : "#0a3c4a" - titleColor: !darkMode ? "#419FB9" : "#204f5c" - height: inOutTileHeight - width: inOutTileWidth - opacity: showAcCharger ? 1 : disabledTileOpacity - visible: showAcCharger || (showInactiveTiles && dcCoupled) - anchors - { - left: root.left; leftMargin: 5 - bottom: alternatorBox.top; bottomMargin: 5 - } - values: TileText { - text: EnhFmt.formatVBusItem (sys.acCharger.power) - font.pixelSize: 17 - visible: showAcCharger - anchors - { - bottom: parent.bottom; bottomMargin: 0 - horizontalCenter: parent.horizontalCenter - } - } - PowerGauge - { - id: acChargerGauge - width: parent.width - height: 10 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.acCharger - reversePower: true - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxAcChargerPower" - visible: showGauges && showAcCharger - } - DetailTarget { id: acChargerTarget; detailsPage: "DetailAcCharger.qml" } - } - - OverviewBox - { - id: alternatorBox - title: qsTr ("Alternator") -////// GuiMods — DarkMode - color: !darkMode ? "#157894" : "#0a3c4a" - titleColor: !darkMode ? "#419FB9" : "#204f5c" - height: inOutTileHeight - width: inOutTileWidth - opacity: showAlternator ? 1 : disabledTileOpacity - visible: showAlternator || (showInactiveTiles && dcCoupled) - anchors - { - left: root.left; leftMargin: 5 - bottom: pvChargerBox.top; bottomMargin: 5 - } - values: TileText { - text: EnhFmt.formatVBusItem (sys.alternator.power) - font.pixelSize: 17 - visible: showAlternator - anchors - { - bottom: parent.bottom; bottomMargin: 0 - horizontalCenter: parent.horizontalCenter - } - } - PowerGauge - { - id: alternatorGauge - width: parent.width - height: 10 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.alternator - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxAlternatorPower" - visible: showGauges && showAlternator - } - DetailTarget { id: alternatorTarget; detailsPage: "DetailAlternator.qml" } - } - - OverviewBox - { - id: motorDriveBox - title: qsTr ("Motor Drive") -////// GuiMods — DarkMode - color: !darkMode ? "#157894" : "#0a3c4a" - titleColor: !darkMode ? "#419FB9" : "#204f5c" - height: inOutTileHeight - width: inOutTileWidth - opacity: showMotorDrive ? 1 : disabledTileOpacity - visible: showMotorDrive - anchors - { - left: root.left; leftMargin: 5 - bottom: pvChargerBox.top; bottomMargin: 5 - } - values: TileText { - text: EnhFmt.formatVBusItem (motorDrivePowerItem) - font.pixelSize: 17 - visible: showMotorDrive - anchors - { - bottom: parent.bottom; bottomMargin: 0 - horizontalCenter: parent.horizontalCenter - } - } - PowerGauge - { - id: motorDriveGauge - width: parent.width - height: 10 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: motorDrivePowerItem - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxMotorDriveLoad" - maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxMotorDriveCharge" - visible: showGauges && showMotorDrive - showLabels: true - } - DetailTarget { id: motorDriveTarget; detailsPage: "DetailMotorDrive.qml" } - } - - VBusItem { id: dcSystemNameItem; bind: Utils.path(settingsPrefix, "/Settings/GuiMods/CustomDcSystemName") } - - OverviewBox { - id: dcSystemBox - width: inOutTileWidth - height: inOutTileHeight - opacity: showDcSystem ? 1 : disabledTileOpacity - visible: showDcSystem || showInactiveTiles - title: dcSystemNameItem.valid && dcSystemNameItem.value != "" ? dcSystemNameItem.value : qsTr ("DC System") - anchors - { - right: root.right; rightMargin: 5 - bottom: parent.bottom - bottomMargin: bottomOffset - } - values: TileText { - text: EnhFmt.formatVBusItem (sys.dcSystem.power) - font.pixelSize: 17 - visible: showDcSystem - anchors - { - bottom: parent.bottom; bottomMargin: 0 - horizontalCenter: parent.horizontalCenter - } - } - PowerGauge - { - id: dcSystemGauge - width: parent.width - height: 10 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.dcSystem - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/DcSystemMaxLoad" - maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/DcSystemMaxCharge" - showLabels: true - visible: showGauges && showDcSystem - } - DetailTarget { id: dcSystemTarget; detailsPage: "DetailDcSystem.qml" } - } - - OverviewBox { - id: fuelCellBox -////// GuiMods — DarkMode - color: !darkMode ? "#157894" : "#0a3c4a" - titleColor: !darkMode ? "#419FB9" : "#204f5c" - width: inOutTileWidth - height: inOutTileHeight - opacity: showFuelCell ? 1 : disabledTileOpacity - visible: showFuelCell || (showInactiveTiles && dcCoupled) - title: qsTr ("Fuel Cell") - anchors { - left: windGenBox.left - bottom: windGenBox.top; bottomMargin: 5 - } - values: TileText { - text: EnhFmt.formatVBusItem (sys.fuelCell.power) - font.pixelSize: 17 - visible: fuelCellBox.visible - anchors - { - bottom: parent.bottom; bottomMargin: 0 - horizontalCenter: parent.horizontalCenter - } - } - PowerGauge - { - id: fuelCellGauge - width: parent.width - height: 10 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.fuelCell - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxFuelCellPower" - visible: showGauges && fuelCellBox.visible - } - DetailTarget { id: fuelCellTarget; detailsPage: "DetailFuelCell.qml" } - } - - OverviewBox { - id: windGenBox -////// GuiMods — DarkMode - color: !darkMode ? "#157894" : "#0a3c4a" - titleColor: !darkMode ? "#419FB9" : "#204f5c" - width: inOutTileWidth - height: inOutTileHeight - opacity: showWindGen ? 1 : disabledTileOpacity - visible: showWindGen || showInactiveTiles - title: qsTr ("Wind Generator") - anchors - { - right: dcSystemBox.right - bottom: dcSystemBox.top; bottomMargin: 5 - } - values: TileText { - text: EnhFmt.formatVBusItem (sys.windGenerator.power) - font.pixelSize: 17 - visible: showWindGen - anchors - { - bottom: parent.bottom; bottomMargin: 0 - horizontalCenter: parent.horizontalCenter - } - } - PowerGauge - { - id: windGenGauge - width: parent.width - height: 10 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.windGenerator - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxWindGenPower" - visible: showGauges && showWindGen - } - DetailTarget { id: windGenTarget; detailsPage: "DetailWindGen.qml" } - } - - OverviewBox { - id: pvChargerBox - title: qsTr("PV Charger") -////// GuiMods — DarkMode - titleColor: !darkMode ? "#F4B350" : "#7A5928" - color: !darkMode ? "#F39C12" : "#794E09" - width: inOutTileWidth - height: inOutTileHeight - opacity: showPvCharger ? 1 : disabledTileOpacity - visible: showPvCharger || showInactiveTiles - anchors - { - left: root.left; leftMargin: 5 - bottom: parent.bottom; bottomMargin: bottomOffset - } - values: TileText { - y: 12 - text: EnhFmt.formatVBusItem (sys.pvCharger.power) - font.pixelSize: 17 - } - // moved sun icon here from OverviewSolarChager so it can be put below text, etc - MbIcon { - iconId: "overview-sun" - anchors { - bottom: parent.bottom - right: parent.right; rightMargin: 2 - } - opacity: 0.5 - } - - PowerGauge - { - id: pvChargerGauge - width: parent.width - height: 10 - anchors - { - top: parent.top; topMargin: 20 - horizontalCenter: parent.horizontalCenter - } - connection: sys.pvCharger - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvChargerMaxPower" - visible: showGauges && showPvCharger - } - DetailTarget { id: pvChargerTarget; detailsPage: "DetailPvCharger.qml" } - } - - // move ESS reason to Battery details page - - // invisible item to connection all AC input connections to.. - Item { - id: acInBus - width: laneWidth - anchors { - left: acInBox.right; - top: multi.top; topMargin: multi.height / 2 + 10 - bottom: pvInverterOnInput.bottom; bottomMargin: 8 - } - } - Item { - id: dcLaneLeft - width: laneWidth - anchors { - right: battery.left; - top: multi.top; topMargin: multi.height / 2 + 10 - bottom: dcSystemBox.bottom; bottomMargin: 8 - } - } - Item { - id: dcLaneRight - width: laneWidth * 0.8 - anchors { - left: battery.right; - - top: dcLaneLeft.top - bottom: dcLaneLeft.bottom - } - } - Item { - id: dcLaneTop - anchors { - left: battery.left - right: battery.right - top: multi.bottom; - bottom: battery.top - } - } - - OverviewConnection { - id: multiAcInFlow - ballCount: 1 - path: straight - active: root.active && ( showAcInput || showPvOnInput || showLoadsOnInput ) - value: -Utils.sign (multiAcInputFlow) - startPointVisible: false - endPointVisible: true - - anchors { - left: acInBus.horizontalCenter; leftMargin: -0.5 - right: multi.left; rightMargin: -8 - bottom: acInBus.top - } - } - - // AC source power flow - OverviewConnection { - id: acSource - ballCount: 1 - path: corner - active: root.active && showAcInput - value: Utils.sign (acInputFlow) - startPointVisible: true - endPointVisible: false - - anchors { - left: acInBox.right; leftMargin: -8 - right: acInBus.horizontalCenter - top: acInBox.bottom; topMargin: -8 - bottom: acInBus.top - } - } - - // Coupled AC sources - OverviewConnection { - id: coupledAcConnection - ballCount: 1 - path: straight - active: root.active && ((showLoadsOnInput && showPvOnInput) || (!dcCoupled && showInactiveFlow)) - value: -Utils.sign (pvOnInputFlow + loadsOnInputFlow) - startPointVisible: false - endPointVisible: false - - anchors { - right: acInBus.horizontalCenter - rightMargin: 0.5 // makes this line up with others - top: acInBus.top - bottom: acInBus.bottom - } - } - - // Grid inverter power flow - OverviewConnection { - id: pvInverterOnInputConnection - ballCount: showLoadsOnInput ? 1 : 2 - path: showLoadsOnInput || (!dcCoupled && showInactiveFlow) ? straight : corner - active: root.active && (showPvOnInput || (!dcCoupled && showInactiveFlow)) - value: Utils.sign (pvOnInputFlow) - startPointVisible: true - endPointVisible: false - - anchors { - left: pvInverterOnInput.right; leftMargin: -8 - right: acInBus.horizontalCenter - top: pvInverterOnInput.bottom; topMargin: -8 - bottom: showLoadsOnInput || (!dcCoupled && showInactiveFlow) ? pvInverterOnInput.bottom : multiAcInFlow.verticalCenter - bottomMargin: showLoadsOnInput || (!dcCoupled && showInactiveFlow) ? 8 : 0 - } - } - - // power to loads on input - OverviewConnection { - id: loadsOnInput - ballCount: 1 - path: corner - active: root.active && (showLoadsOnInput || (!dcCoupled && showInactiveFlow)) - value: Utils.sign (loadsOnInputFlow) - startPointVisible: true - endPointVisible: false - - anchors { - left: acLoadOnInputBox.right; leftMargin: -8 - right: acInBus.horizontalCenter - rightMargin: 0.5 // makes this line up with others - top: acLoadOnInputBox.top; topMargin: 8 - bottom: showPvOnInput|| (!dcCoupled && showInactiveFlow) ? acInBus.bottom : acInBus.top - } - } - - // invisible item to connection all AC output connections to.. - Item { - id: acOutNode - height: 6 - anchors { - left: multi.right - right: acOutputBox.left - verticalCenter: acInBus.top - } - } - - // AC out connection - OverviewConnection { - id: multiAcOutConnection - - ballCount: 1 - path: straight - active: root.active && ((showLoadsOnOutput || showPvOnOutput) || (!dcCoupled && showInactiveFlow)) - value: -Utils.sign (acOutLoadFlow + pvInverterOnAcOutFlow) - endPointVisible: false - - anchors { - left: multi.right; leftMargin: -8 - right: acOutNode.horizontalCenter - top: acOutNode.verticalCenter - } - } - - // loads on output conenction - OverviewConnection { - id: acOutBoxConnection - - ballCount: 1 - path: corner - active: root.active && (showLoadsOnOutput || (!dcCoupled && showInactiveFlow)) - value: Utils.sign (acOutLoadFlow) - startPointVisible: true - endPointVisible: false - - anchors { - right: acOutNode.horizontalCenter - rightMargin: -0.5 // makes this line up with others - left: acOutputBox.left; leftMargin: 8 - top: acOutputBox.bottom; topMargin: -8 - bottom: acOutNode.verticalCenter - } - } - - // PV Inverter on AC out connection - OverviewConnection { - id: pvOnAcOutConnection - - ballCount: 2 - path: corner - active: root.active && (showPvOnOutput || (!dcCoupled && showInactiveFlow)) - value: Utils.sign (pvInverterOnAcOutFlow) - startPointVisible: true - endPointVisible: false - - anchors { - left: pvInverterOnAcOut.left; leftMargin: 8 - top: pvInverterOnAcOut.bottom; topMargin: -8 - right: acOutNode.horizontalCenter - bottom: acOutNode.verticalCenter - } - } - - // invisible summing point for all DC connections - Item { - id: dcNode - height: 10 - width: 10 - anchors { - horizontalCenter: batteryDcConnector.horizontalCenter - verticalCenter: dcLaneTop.verticalCenter - } - } - - // DC bus segments - OverviewConnection { - id: dcBus1 - ballCount: 1 - path: straight - active: root.active && ((showAlternator || showMotorDrive || showPvCharger) || (dcCoupled && showInactiveFlow)) - value: -Utils.sign (alternatorFlow + motorDriveFlow + pvChargerFlow) - startPointVisible: false - endPointVisible: false - - anchors { - right: dcLaneLeft.horizontalCenter - rightMargin: 0.5 // makes this line up with others - bottom: alternatorConnection.verticalCenter - top: dcLaneTop.verticalCenter - } - } - OverviewConnection { - id: dcBus2 - ballCount: 1 - path: straight - active: root.active && ((showAlternator || showMotorDrive || showAcCharger || showPvCharger) || (dcCoupled && showInactiveFlow)) - value: Utils.sign (alternatorFlow + motorDriveFlow + pvChargerFlow + acChargerFlow) - startPointVisible: false - endPointVisible: false - - anchors { - left: dcLaneLeft.horizontalCenter - right: dcBus3.left - bottom: dcLaneTop.verticalCenter - } - } - OverviewConnection { - id: dcBus3 - ballCount: 2 - path: straight - active: root.active && ((showInverter || showFuelCell || showWindGen || showDcSystem) || showInactiveFlow) - value: -Utils.sign (inverterDcFlow + fuelCellFlow + windGenFlow + dcSystemFlow) - startPointVisible: false - endPointVisible: false - - anchors { - left: batteryDcConnector.horizontalCenter - right: multiDcConnector.horizontalCenter - bottom: dcLaneTop.verticalCenter - } - } - OverviewConnection { - id: dcBus4 - ballCount: 1 - path: straight - active: root.active && ((showFuelCell || showWindGen || showDcSystem) || showInactiveFlow) - value: -Utils.sign (fuelCellFlow + windGenFlow + dcSystemFlow) - startPointVisible: false - endPointVisible: false - - anchors { - left: multiDcConnector.horizontalCenter - right: dcLaneRight.horizontalCenter - bottom: dcLaneTop.verticalCenter - } - } - OverviewConnection { - id: dcBus5 - ballCount: 1 - path: straight - active: root.active && ((showWindGen || showDcSystem) || showInactiveFlow) - value: -Utils.sign (windGenFlow + dcSystemFlow) - startPointVisible: false - endPointVisible: false - - anchors { - left: dcLaneRight.horizontalCenter - top: dcLaneTop.verticalCenter - bottom: windGenConnection.verticalCenter - } - } - - - // DC connection multi to bus - OverviewConnection { - id: multiDcConnector - ballCount: 1 - path: straight - active: root.active && (showInverter || showInactiveFlow) - value: Utils.sign (inverterDcFlow) - startPointVisible: true - endPointVisible: false - - anchors { - right: multi.right; rightMargin: 25 - top: multi.bottom; topMargin: -8 - bottom: dcLaneTop.verticalCenter - } - } - // DC connection battery to bus - OverviewConnection { - id: batteryDcConnector - ballCount: 1 - path: straight - active: root.active && ((sys.battery.soc.valid || showDcSystem) || (dcCoupled && showInactiveFlow)) - value: -Utils.sign (batteryFlow) - startPointVisible: true - endPointVisible: false - - anchors { - left: battery.left; leftMargin: 30 - top: battery.top; topMargin: 15 - bottom: dcLaneTop.verticalCenter - } - } - - // AC charger to DC bus - OverviewConnection - { - id: acChargerConnection - ballCount: 1 - path: corner - active: root.active && (showAcCharger || (dcCoupled && showInactiveFlow)) - value: Utils.sign (acChargerFlow) - startPointVisible: true - endPointVisible: false - anchors - { - left: acChargerBox.right; leftMargin: -8 - top: acChargerBox.bottom; topMargin: -8 - right: dcLaneLeft.horizontalCenter - bottom: dcLaneTop.verticalCenter - } - } - - // Alternator to bus - OverviewConnection - { - id: alternatorConnection - ballCount: 1 - path: straight - active: root.active && (showAlternator || showMotorDrive || (dcCoupled && showInactiveFlow)) - value: Utils.sign (alternatorFlow + motorDriveFlow) - startPointVisible: true - endPointVisible: false - anchors - { - left: alternatorBox.right; leftMargin: -8 - top: alternatorBox.bottom; topMargin: -8 - right: dcLaneLeft.horizontalCenter - } - } - - // DC system to DC bus - OverviewConnection - { - id: dcSystemConnection - ballCount: 2 - path: corner - active: root.active && (showDcSystem || (dcCoupled && showInactiveFlow)) - value: Utils.sign (dcSystemFlow) - endPointVisible: false - anchors - { - left: dcSystemBox.left; leftMargin: 8 - top: dcSystemBox.bottom; topMargin: -8 - right: dcLaneRight.horizontalCenter - rightMargin: -0.5 // makes this line up with others - bottom: windGenConnection.verticalCenter - } - } - - - // other DC connection to DC right bus - OverviewConnection - { - id: fuelCellConnection - ballCount: 2 - path: corner - active: root.active && (showFuelCell || (dcCoupled && showInactiveFlow)) - value: Utils.sign (fuelCellFlow) - startPointVisible: true - endPointVisible: false - anchors - { - left: fuelCellBox.left; leftMargin: 8 - top: fuelCellBox.bottom; topMargin: -8 - right: dcLaneRight.horizontalCenter - rightMargin: -0.5 // makes this line up with others - bottom: dcLaneTop.verticalCenter - } - } - - // Wind Gen DC right bus - OverviewConnection - { - id: windGenConnection - ballCount: 1 - path: straight - active: root.active && (showWindGen || showInactiveFlow) - value: Utils.sign (windGenFlow) - startPointVisible: true - endPointVisible: false - anchors - { - left: windGenBox.left; leftMargin: 8 - top: windGenBox.bottom; topMargin: -8 - right: dcLaneRight.horizontalCenter - } - } - - // Solar charger to DC right bus - OverviewConnection - { - id: pvChargerConnection - ballCount: 2 - path: corner - active: root.active && (showPvCharger || showInactiveFlow) - value: Utils.sign (pvChargerFlow) - startPointVisible: true - endPointVisible: false - anchors - { - left: pvChargerBox.right; leftMargin: -8 - top: pvChargerBox.bottom; topMargin: -8 - right: dcLaneLeft.horizontalCenter - bottom: alternatorConnection.top - } - } - - // Synchronise tank name text scroll start - Timer - { - id: scrollTimer - interval: 15000 - repeat: true - running: root.active - } - - ListView - { - id: tanksColum - - visible: showTanks - width: compact ? root.width : root.width * tankCount / tankTempCount - property int tileWidth: width / Math.min (count, 5.2) - height: root.tanksHeight - anchors - { - bottom: root.bottom - left: root.left - } - - // flickable list if more than will fit across bottom of screen - interactive: count > 4 ? true : false - orientation: ListView.Horizontal - - model: TankModel { id: tankModel } - delegate: TileTankEnhanced { - // Without an intermediate assignment this will trigger a binding loop warning. - property variant theService: DBusServices.get(buddy.id) - service: theService - width: tanksColum.tileWidth - height: root.tanksHeight - pumpBindPrefix: root.pumpBindPreffix - compact: root.compact - Connections { - target: scrollTimer - onTriggered: doScroll() - } - } - Tile { - title: qsTr("tanks") - anchors.fill: parent - values: TileText { - text: qsTr("") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - - ListView - { - id: tempsColumn - - visible: showTemps - width: compact ? root.width : root.width * tempCount / tankTempCount - property int tileWidth: width / Math.min (count, 5.2) - height: root.tanksHeight - anchors - { - bottom: root.bottom - bottomMargin: compact ? root.tanksHeight : 0 - right: root.right - } - - // make list flickable if more tiles than will fit completely - interactive: count > 4 ? true : false - orientation: ListView.Horizontal - - model: tempsModel - delegate: TileTemp - { - width: tempsColumn.tileWidth - height: tempsColumn.height - compact: root.compact - Connections - { - target: scrollTimer - onTriggered: doScroll() - } - } - Tile - { - title: qsTr("TEMPS") - anchors.fill: parent - values: TileText - { - text: qsTr("") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - ListModel { id: tempsModel } - - // When new service is found check if is a tank sensor - Connections - { - target: DBusServices - onDbusServiceFound: addService(service) - } - - // hack to get value(s) from within a loop inside a function when service is changing - property string tempServiceName: "" - property VBusItem temperatureItem: VBusItem { bind: Utils.path(tempServiceName, "/Dc/0/Temperature") } - - function addService(service) - { - switch (service.type) - { - case DBusService.DBUS_SERVICE_TEMPERATURE_SENSOR: - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - break;; - - case DBusService.DBUS_SERVICE_MULTI: - hasInverter = true - root.tempServiceName = service.name - if (temperatureItem.valid && showBatteryTemp) - { - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - } - break;; - case DBusService.DBUS_SERVICE_MULTI_RS: - hasInverter = true - break;; - case DBusService.DBUS_SERVICE_INVERTER: - hasInverter = true - if (veDirectInverterService == "") - veDirectInverterService = service.name; - break;; - case DBusService.DBUS_SERVICE_BATTERY: - root.tempServiceName = service.name - if (temperatureItem.valid && showBatteryTemp) - { - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - } - break;; - } - } - - // Detect available services of interest - function discoverServices() - { - numberOfTemps = 0 - tempsModel.clear() - veDirectInverterService = "" - hasInverter = false - for (var i = 0; i < DBusServices.count; i++) - { - addService(DBusServices.at(i)) - } - } - VBusItem { id: incomingTankName; - bind: Utils.path(settingsBindPreffix, "/Settings/Devices/TankRepeater/IncomingTankService") } - - // help message shown when menu is first drawn - Rectangle - { - id: helpBox - color: "white" - width: multi.width - height: 32 - opacity: 0.7 - anchors - { - verticalCenter: dcLaneTop.verticalCenter - horizontalCenter: root.horizontalCenter - } - visible: false - } - TileText - { - text: qsTr ( "Tap tile center for detail at any time" ) - color: "black" - anchors.fill: helpBox - wrapMode: Text.WordWrap - font.pixelSize: 12 - visible: helpBox.visible - } - - //// hard key handler - // used to press buttons when touch isn't available - // UP and DOWN buttons cycle through the list of touch areas - // "space" button is used to simulate a touch on the area - // target must be highlighted so that other uses of "space" - // will still occur - - // list of all details touchable areas - property variant targetList: - [ - acInputTarget, pvOnInputTarget, acLoadsOnInputTarget, - acChargerTarget, alternatorTarget, motorDriveTarget, pvChargerTarget, - multiTarget, batteryTarget, - acLoadsOnOutputTarget, pvOnOutputTarget, fuelCellTarget, windGenTarget, dcSystemTarget - ] - - property int selectedTarget: 0 - - Timer - { - id: targetTimer - interval: 5000 - repeat: false - running: false - onTriggered: { hideAllTargets () } - } - - Keys.forwardTo: [keyHandler] - Item - { - id: keyHandler - Keys.onUpPressed: - { - nextTarget (-1) - event.accepted = true - } - - Keys.onDownPressed: - { - nextTarget (+1) - event.accepted = true - } - Keys.onSpacePressed: - { - if (targetTimer.running) - { - var foo // hack to make clicked() work - bar.clicked (foo) - event.accepted = true - } - else - event.accepted = false - } - } - // hack to make clicked() work - property variant bar: targetList[selectedTarget] - - function nextTarget (increment) - { - // make one pass through all possible targets to find an enabled one - // if found, that's the new selectedTarget, - // if not selectedTarget does not change - var newIndex = selectedTarget - for (var i = 0; i < targetList.length; i++) - { - if (( ! targetTimer.running || helpBox.visible) && targetList[newIndex].enabled) - { - highlightSelectedTarget () - return - } - newIndex += increment - if (newIndex >= targetList.length) - newIndex = 0 - else if (newIndex < 0) - newIndex = targetList.length - 1 - if (targetList[newIndex].enabled) - { - selectedTarget = newIndex - highlightSelectedTarget () - break - } - } - } - - function showHelp () - { - for (var i = 0; i < targetList.length; i++) - { - targetList[i].targetVisible = true - } - helpBox.visible = true - targetTimer.restart () - } - function hideAllTargets () - { - for (var i = 0; i < targetList.length; i++) - { - targetList[i].targetVisible = false - } - helpBox.visible = false - } - function highlightSelectedTarget () - { - for (var i = 0; i < targetList.length; i++) - { - if (targetList[i] == targetList[selectedTarget]) - targetList[i].targetVisible = true - else - targetList[i].targetVisible = false - } - helpBox.visible = false - targetTimer.restart () - } -} diff --git a/FileSets/v3.40~8/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~8/OverviewGeneratorEnhanced.qml deleted file mode 120000 index da5507a7..00000000 --- a/FileSets/v3.40~8/OverviewGeneratorEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~8/OverviewGeneratorRelayEnhanced.qml deleted file mode 120000 index 1c9b530f..00000000 --- a/FileSets/v3.40~8/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/OverviewGridParallel.qml b/FileSets/v3.40~8/OverviewGridParallel.qml deleted file mode 100644 index 6e79cb8b..00000000 --- a/FileSets/v3.40~8/OverviewGridParallel.qml +++ /dev/null @@ -1,490 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -OverviewPage { - id: root - -////// GuiMods — DarkMode - property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } - property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 - - property variant sys: theSystem - property bool hasAcOutSystem: _hasAcOutSystem.value === 1 - - title: qsTr("Overview") - - VBusItem { - id: _hasAcOutSystem - bind: "com.victronenergy.settings/Settings/SystemSetup/HasAcOutSystem" - } - - OverviewBox { - id: acInBox - - width: 148 - height: 100 - title: getAcSourceName(sys.acSource) -////// GuiMods — DarkMode - titleColor: !darkMode ? "#E74c3c" : "#73261E" - color: !darkMode ? "#C0392B" : "#601C15" - anchors { - top: root.top; topMargin: 1 - left: parent.left; leftMargin: 5 - } - - values: OverviewAcValues { - connection: sys.acInput - } - - MbIcon { - iconId: getAcSourceIcon(sys.acSource) - anchors { - bottom: parent.bottom - left: parent.left; leftMargin: 2 - } - opacity: 0.5 - } - } - - OverviewBox { - id: acLoadBox - title: qsTr("AC Loads") -////// GuiMods — DarkMode - color: !darkMode ? "#27AE60" : "#135730" - titleColor: !darkMode ? "#2ECC71" : "#176638" - width: 148 - height: 100 - - anchors { - left: acInBox.right - leftMargin: hasAcOutSystem ? 10 : 174 - top: root.top; topMargin: 1 - } - - values: OverviewAcValues { - connection: sys.acInLoad - } - } - - OverviewBox { - id: acOutputBox - title: qsTr("Critical Loads") -////// GuiMods — DarkMode - color: !darkMode ? "#157894" : "#0a3c4a" - titleColor: !darkMode ? "#419FB9" : "#204f5c" - height: 100 - width: 148 - visible: hasAcOutSystem - anchors { - right: root.right; rightMargin: 5 - top: root.top; topMargin: 17 - } - - values: OverviewAcValues { - connection: sys.acOutLoad - } - } - - Multi { - id: multi - iconId: "overview-inverter-short" - anchors { - horizontalCenter: parent.horizontalCenter - bottom: root.bottom; bottomMargin: 39 - } - } - - // invisible item to connection all AC connections to.. - Item { - id: acBus - height: 10 - anchors { - left: acInBox.left; leftMargin: hasAcOutSystem ? 5 : acInBox.width - 5 - right: acLoadBox.right; rightMargin: 2 - bottom: acInBox.bottom; bottomMargin: -15 - } - } - - Battery { - id: battery - - soc: sys.battery.soc.valid ? sys.battery.soc.value : 0 - preferRenewable: sys.preferRenewableEnergy.valid - preferRenewableOverride: sys.preferRenewableEnergy.value === 0 - height: pvInverterOnGrid.visible ? 81 : 101 - width: 145 - - anchors { - bottom: parent.bottom; bottomMargin: 5; - left:parent.left; leftMargin: 5 - } - values: Column { - y: pvInverterOnGrid.visible ? 0 : 8 - width: parent.width - - TileText { - text: sys.battery.soc.valid ? sys.battery.soc.value.toFixed(0) : "--" - font.pixelSize: 30 - - Text { - anchors { - bottom: parent.bottom; bottomMargin: 4 - horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: parent.paintedWidth / 2 + 5 - } - visible: sys.battery.soc.valid - text: "%" - color: "white" - font.bold: true - font.pixelSize: 12 - } - } - TileText { - text: sys.battery.power.format(0) - } - TileText { - text: sys.battery.voltage.format(1) + " " + sys.battery.current.format(1) - } - } - } - - // PV inverter on AC in, AC Output ignored - OverviewSolarInverter { - id: pvInverterOnGridNoAcOut - title: qsTr("PV Inverter") - width: 154 - height: 100 - visible: sys.pvOnGrid.power.valid && !hasAcOutSystem - showInverterIcon: false - values: TileText { - y: 2 - text: sys.pvOnGrid.power.format(0) - font.pixelSize: 25 - } - anchors { - top: root.top; topMargin: 1 - horizontalCenter: root.horizontalCenter - } - } - - OverviewSolarInverter { - id: pvInverterOnGrid - title: qsTr("PV Inverter") - width: 148 - height: 60 - visible: sys.pvOnGrid.power.valid && hasAcOutSystem - showInverterIcon: false - values: TileText { - y: 2 - text: sys.pvOnGrid.power.format(0) - font.pixelSize: 20 - } - anchors { - bottom: battery.top; bottomMargin: 5 - left: root.left; leftMargin: 5 - } - } - - OverviewSolarInverter { - id: pvInverterOnAcOut - title: qsTr("PV Inverter") - width: 148 - height: 60 - visible: sys.pvOnAcOut.power.valid - showInverterIcon: false - - values: TileText { - y: 2 - text: sys.pvOnAcOut.power.format(0) - font.pixelSize: 20 - } - anchors { - bottom: blueSolarCharger.top; bottomMargin: 5 - right: parent.right; rightMargin: 5 - } - } - - OverviewSolarCharger { - id: blueSolarCharger - title: qsTr("PV Charger") - width: 148 - height: 60 - visible: sys.pvCharger.power.valid - showChargerIcon: false - - anchors { - right: root.right; rightMargin: 5 - bottom: root.bottom; bottomMargin: 5; - } - - values: TileText { - y: 2 - text: sys.pvCharger.power.format(0) - font.pixelSize: 20 - } - } - - OverviewEssReason { - anchors { - bottom: parent.bottom; bottomMargin: 5 - horizontalCenter: parent.horizontalCenter - } - } - - // AC source power flow - OverviewConnection { - id: acSource - ballCount: 4 - path: corner - active: root.active && hasAcOutSystem - value: flow(sys.acInput ? sys.acInput.power : undefined) * -1 - startPointVisible: false - - anchors { - right: acInBox.left; rightMargin: -9 - left: pvInverterOnGridConnection.horizontalCenter - bottom: acInBox.bottom; bottomMargin: 8 - top: acBus.verticalCenter - } - } - - // Coupled AC sources - OverviewConnection { - id: coupledAcConnection - - property VBusItem coupled: VBusItem { - property double gridPower: sys.acInput.power.valid ? sys.acInput.power.value : 0 - property double pvPower: sys.pvOnGrid.power.valid ? sys.pvOnGrid.power.value : 0 - value: gridPower + pvPower - } - - ballCount: 1 - path: straight - active: root.active && hasAcOutSystem - value: flow(coupled) - startPointVisible: false - endPointVisible: false - - anchors { - left: pvInverterOnGridConnection.right - right: vebusConnection.left - top: acBus.verticalCenter - bottom: acBus.verticalCenter - } - } - - // AC source power flow, ignored AC output - OverviewConnection { - id: acSourceNoAcOut - ballCount: 5 - path: corner - active: root.active && !hasAcOutSystem - value: acSource.value - startPointVisible: false - - anchors { - right: acInBox.left; rightMargin: -9 - left: pvInverterOnGridConnectionNoAcOut.horizontalCenter - bottom: acInBox.bottom; bottomMargin: 8 - top: acBus.verticalCenter - } - } - - // Coupled AC sources, ignored AC output - OverviewConnection { - id: coupledAcConnectionNoAcOut - - ballCount: 1 - path: straight - active: root.active && !hasAcOutSystem - value: coupledAcConnection.value - startPointVisible: false - endPointVisible: false - - anchors { - left: pvInverterOnGridConnectionNoAcOut.right - right: vebusConnection.left - top: acBus.verticalCenter - bottom: acBus.verticalCenter - } - } - - // Grid inverter power flow, ignored AC output - OverviewConnection { - id: pvInverterOnGridConnectionNoAcOut - ballCount: 1 - path: straight - active: root.active && pvInverterOnGridNoAcOut.visible - value: flow(sys.pvOnGrid ? sys.pvOnGrid.power : undefined) - startPointVisible: true - endPointVisible: false - - anchors { - top: pvInverterOnGridNoAcOut.bottom; topMargin: -8 - bottom: acBus.verticalCenter - left: pvInverterOnGridNoAcOut.left; leftMargin: 8 - right: pvInverterOnGridNoAcOut.left; rightMargin: -8 - } - } - - // Grid inverter power flow - OverviewConnection { - id: pvInverterOnGridConnection - ballCount: 1 - path: straight - active: root.active && pvInverterOnGrid.visible - value: flow(sys.pvOnGrid ? sys.pvOnGrid.power : undefined) * -1 - startPointVisible: false - - anchors { - top: acBus.verticalCenter - bottom: pvInverterOnGrid.top; bottomMargin: -8 - left: pvInverterOnGrid.right; leftMargin: -8 - } - } - - // power to loads - OverviewConnection { - id: loadConnection - ballCount: hasAcOutSystem ? 3 : 5 - path: corner - active: root.active - value: flow(sys.acInLoad.power) - startPointVisible: false - endPointVisible: true - - anchors { - right: acLoadBox.right; rightMargin: hasAcOutSystem ? 10 : acLoadBox.width - 10 - left: vebusConnection.horizontalCenter - top: acBus.verticalCenter - bottom: acLoadBox.bottom; bottomMargin: 8 - } - } - - // Towards vebus system - OverviewConnection { - id: vebusConnection - - property VBusItem vebusAcPower: VBusItem { bind: [sys.vebusPrefix, "/Ac/ActiveIn/P"] } - - ballCount: 1 - path: straight - active: root.active - value: flow(vebusAcPower) - startPointVisible: false - endPointVisible: true - - anchors { - left: multi.left; leftMargin: 8 - top: acBus.verticalCenter - bottom: multi.top; bottomMargin: -7 - } - } - - // AC out connection - OverviewConnection { - id: acOutConnection - - property double pvInverterOnAcOutPower: sys.pvOnAcOut.power.valid ? sys.pvOnAcOut.power.value : 0 - property double acOutLoad: sys.acOutLoad.power.valid ? sys.acOutLoad.power.value : 0 - property VBusItem vebusAcOutPower: VBusItem { value: acOutConnection.acOutLoad - acOutConnection.pvInverterOnAcOutPower } - - ballCount: 1 - path: straight - active: root.active && (hasAcOutSystem || pvInverterOnAcOut.visible) - value: flow(vebusAcOutPower) - endPointVisible: false - - anchors { - left: multi.right; leftMargin: -8 - right: acOutBoxConnection.left - top: multi.top; topMargin: 8 - } - } - - // UPS conenction - OverviewConnection { - id: acOutBoxConnection - - ballCount: 1 - path: straight - active: root.active && hasAcOutSystem - value: flow(sys.acOutLoad.power) - startPointVisible: false - - anchors { - left: acOutputBox.left; leftMargin: 10 - top: acOutConnection.verticalCenter - bottom: acOutputBox.bottom; bottomMargin: 9 - } - } - - // PV Inverter on AC out connection - OverviewConnection { - id: pvOnAcOutConnection - - ballCount: 1 - path: straight - active: root.active && pvInverterOnAcOut.visible - value: flow(sys.pvOnAcOut.power) - endPointVisible: false - - anchors { - left: acOutBoxConnection.left - bottom: acOutConnection.verticalCenter - top: pvInverterOnAcOut.top; topMargin: 8 - } - } - - // DC connection from multi - OverviewConnection { - ballCount: 1 - path: straight - active: root.active - value: flow(sys.vebusDc.power) - endPointVisible: false - - anchors { - right: dcConnection.right; - top: multi.bottom; topMargin: -10 - bottom: dcConnection.top; - } - } - - // Battery to DC connection - OverviewConnection { - ballCount: 3 - path: straight - active: root.active - value: Utils.sign(noNoise(sys.pvCharger.power) + noNoise(sys.vebusDc.power)) - startPointVisible: false - - anchors { - left: dcConnection.left; - top: dcConnection.verticalCenter - right: battery.right; rightMargin: 10 - } - } - - // Solar charger to DC connection - OverviewConnection { - ballCount: 3 - path: straight - active: root.active && blueSolarCharger.visible - value: flow(sys.pvCharger.power) - endPointVisible: false - - anchors { - right: dcConnection.right; - top: dcConnection.top - left: blueSolarCharger.left; leftMargin: 10 - } - } - - Item { - id: dcConnection - anchors { - horizontalCenter: multi.horizontalCenter - top: multi.bottom; topMargin: 10 - } - } -} diff --git a/FileSets/v3.40~8/OverviewHub.qml b/FileSets/v3.40~8/OverviewHub.qml deleted file mode 100644 index 54d81dda..00000000 --- a/FileSets/v3.40~8/OverviewHub.qml +++ /dev/null @@ -1,315 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -OverviewPage { - id: root - -////// GuiMods — DarkMode - property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } - property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 - - property variant sys: theSystem - property bool hasAcSolarOnAcIn1: sys.pvOnAcIn1.power.valid - property bool hasAcSolarOnAcIn2: sys.pvOnAcIn2.power.valid - property bool hasAcSolarOnIn: hasAcSolarOnAcIn1 || hasAcSolarOnAcIn2 - property bool hasAcSolarOnOut: sys.pvOnAcOut.power.valid - property bool hasAcSolar: hasAcSolarOnIn || hasAcSolarOnOut - property bool hasDcSolar: sys.pvCharger.power.valid - property bool hasDcAndAcSolar: hasAcSolar && hasDcSolar - - title: qsTr("Overview") - - OverviewBox { - id: acInBox - - width: 148 - height: showStatusBar ? 100 : 120 - title: getAcSourceName(sys.acSource) -////// GuiMods — DarkMode - titleColor: !darkMode ? "#E74c3c" : "#73261E" - color: !darkMode ? "#C0392B" : "#601C15" - - anchors { - top: multi.top - left: parent.left; leftMargin: 10 - } - - values: OverviewAcValues { - connection: sys.acInput - } - - MbIcon { - iconId: getAcSourceIcon(sys.acSource) - anchors { - bottom: parent.bottom - left: parent.left; leftMargin: 2 - } - opacity: 0.5 - } - } - - Multi { - id: multi - anchors { - horizontalCenter: parent.horizontalCenter - top: parent.top; topMargin: 5 - } - } - - OverviewBox { - id: acLoadBox - title: qsTr("AC Loads") -////// GuiMods — DarkMode - color: !darkMode ? "#27AE60" : "#135730" - titleColor: !darkMode ? "#2ECC71" : "#176638" - width: 148 - height: showStatusBar ? 100 : 120 - - anchors { - right: parent.right; rightMargin: 10 - top: multi.top - } - - values: OverviewAcValues { - connection: sys.acLoad - } - } - - Battery { - id: battery - - soc: sys.battery.soc.valid ? sys.battery.soc.value : 0 - - anchors { - bottom: parent.bottom; bottomMargin: 5; - left: parent.left; leftMargin: 10 - } - values: Column { - width: parent.width - - TileText { - // Use value here instead of format() because format adds the unit to the number and we - // show the percentage symbol in a separated smaller text. - text: sys.battery.soc.value === undefined ? "--" : sys.battery.soc.value.toFixed(0) - font.pixelSize: 40 - - Text { - anchors { - bottom: parent.bottom; bottomMargin: 9 - horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: parent.paintedWidth / 2 + 5 - } - visible: sys.battery.soc.valid - text: "%" - color: "white" - font.bold: true - font.pixelSize: 12 - } - } - TileText { - text: sys.battery.power.format(0) - } - TileText { - text: sys.battery.voltage.format(1) + " " + sys.battery.current.format(1) - } - } - } - - OverviewBox { - id: dcSystemBox - width: 105 - height: 45 - visible: sys.dcSystem.power.valid - title: qsTr("DC Power") - - anchors { - horizontalCenter: multi.horizontalCenter - bottom: parent.bottom; bottomMargin: 5 - } - - values: TileText { - anchors.centerIn: parent - text: sys.dcSystem.power.format(0) - } - } - - OverviewSolarCharger { - id: blueSolarCharger - - height: hasDcAndAcSolar ? 65 : 114 - width: 148 - title: qsTr("PV Charger") - showChargerIcon: !hasDcAndAcSolar - visible: hasDcSolar || hasDcAndAcSolar - - anchors { - right: root.right; rightMargin: 10 - bottom: root.bottom; bottomMargin: 5; - } - - values: TileText { - y: 5 - text: sys.pvCharger.power.format(0) - font.pixelSize: 20 - } - } - - OverviewSolarInverter { - id: pvInverter - height: hasDcAndAcSolar ? 65 : 115 - width: 148 - title: qsTr("PV Inverter") - showInverterIcon: !hasDcAndAcSolar - visible: hasAcSolar - - anchors { - right: root.right; rightMargin: 10; - bottom: root.bottom; bottomMargin: hasDcAndAcSolar ? 75 : 5 - } - - OverviewAcValues { - connection: hasAcSolarOnOut ? sys.pvOnAcOut : hasAcSolarOnAcIn1 ? sys.pvOnAcIn1 : sys.pvOnAcIn2 - visible: !coupledPvAc.visible - } - - TileText { - id: coupledPvAc - - property double pvInverterOnAcOut: sys.pvOnAcOut.power.valid ? sys.pvOnAcOut.power.value : 0 - property double pvInverterOnAcIn1: sys.pvOnAcIn1.power.valid ? sys.pvOnAcIn1.power.value : 0 - property double pvInverterOnAcIn2: sys.pvOnAcIn2.power.valid ? sys.pvOnAcIn2.power.value : 0 - - y: 5 - text: (pvInverterOnAcOut + pvInverterOnAcIn1 + pvInverterOnAcIn2).toFixed(0) + "W" - font.pixelSize: hasDcAndAcSolar ? 20 : 25 - visible: hasDcAndAcSolar || (hasAcSolarOnIn && hasAcSolarOnOut) || (hasAcSolarOnAcIn1 && hasAcSolarOnAcIn2) - } - } - - OverviewEssReason { - anchors { - bottom: parent.bottom; bottomMargin: dcSystemBox.visible ? battery.height + 15 : 5 - horizontalCenter: parent.horizontalCenter; horizontalCenterOffset: dcSystemBox.visible ? -(root.width / 2 - battery.width / 2 - 10) : 0 - } - } - - OverviewConnection { - id: acInToMulti - ballCount: 2 - path: straight - active: root.active - value: flow(sys.acInput ? sys.acInput.power : 0) - - anchors { - left: acInBox.right; leftMargin: -10; top: multi.verticalCenter; - right: multi.left; rightMargin: -10; bottom: multi.verticalCenter - } - } - - OverviewConnection { - id: multiToAcLoads - ballCount: 2 - path: straight - active: root.active - value: flow(sys.acLoad.power) - - anchors { - left: multi.right; leftMargin: -10; - top: multi.verticalCenter - right: acLoadBox.left; rightMargin: -10 - bottom: multi.verticalCenter - } - } - - OverviewConnection { - id: pvInverterToMulti - - property int hasDcAndAcFlow: Utils.sign(noNoise(sys.pvOnAcOut.power) + noNoise(sys.pvOnAcIn1.power) + noNoise(sys.pvOnAcIn2.power)) - - ballCount: 4 - path: corner - active: root.active && hasAcSolar - value: hasDcAndAcSolar ? hasDcAndAcFlow : flow(sys.pvOnAcOut.power) - - anchors { - left: pvInverter.left; leftMargin: 8 - top: pvInverter.verticalCenter; topMargin: hasDcAndAcSolar ? 1 : 0 - right: multi.horizontalCenter; rightMargin: -20 - bottom: multi.bottom; bottomMargin: 10 - } - } - - // invisible anchor point to connect the chargers to the battery - Item { - id: dcConnect - anchors { - left: multi.horizontalCenter; leftMargin: hasAcSolar ? -20 : 0 - bottom: dcSystemBox.top; bottomMargin: 10 - } - } - - OverviewConnection { - id: multiToDcConnect - ballCount: 3 - path: straight - active: root.active - value: -flow(sys.vebusDc.power); - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: dcConnect.left - bottom: multi.bottom; bottomMargin: 10 - } - } - - OverviewConnection { - id: blueSolarChargerDcConnect - ballCount: 3 - path: straight - active: root.active && hasDcSolar - value: -flow(sys.pvCharger.power) - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: blueSolarCharger.left; rightMargin: -8 - bottom: dcConnect.top; - } - } - - OverviewConnection { - id: chargersToBattery - ballCount: 3 - path: straight - active: root.active - value: Utils.sign(noNoise(sys.pvCharger.power) + noNoise(sys.vebusDc.power)) - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: battery.right; rightMargin: 10 - bottom: dcConnect.top - } - } - - OverviewConnection { - id: batteryToDcSystem - ballCount: 2 - path: straight - active: root.active && sys.dcSystem.power.valid - value: flow(sys.dcSystem.power) - - anchors { - left: battery.right; leftMargin: -10 - top: dcSystemBox.verticalCenter; - right: dcSystemBox.left; rightMargin: -10 - bottom: dcSystemBox.verticalCenter - } - } -} diff --git a/FileSets/v3.40~8/OverviewHubEnhanced.qml b/FileSets/v3.40~8/OverviewHubEnhanced.qml deleted file mode 100644 index 23865ec1..00000000 --- a/FileSets/v3.40~8/OverviewHubEnhanced.qml +++ /dev/null @@ -1,1505 +0,0 @@ -////// MODIFIED to show: -////// tanks in a row along bottom -////// PV voltage and current and DC power current (up to 2 MPPTs with tanks and temps or 3 without) -////// PV inverter power (up to 2 with tanks and temps or 3 without) -////// voltage, current, frequency in AC tiles (plus current limit for AC input) -////// time of day -////// current in DC Loads -////// remaining time in Battery tile -////// bar graphs on AC in/out and Multi -////// detail pages for all tiles -////// bar gauge on PV Charger tile -////// add support for VE.Direct inverters - -import QtQuick 1.1 -import "utils.js" as Utils -////// ADDED to show tanks -import com.victron.velib 1.0 -import "timeToGo.js" as TTG -import "enhancedFormat.js" as EnhFmt - -OverviewPage { - id: root - - property variant sys: theSystem - - property string systemPrefix: "com.victronenergy.system" - property string guiModsPrefix: "com.victronenergy.settings/Settings/GuiMods" - -////// GuiMods — DarkMode - property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } - property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 - - VBusItem { id: vebusService; bind: Utils.path(systemPrefix, "/VebusService") } - property bool isMulti: vebusService.valid - property string veDirectInverterService: "" - property string inverterService: vebusService.valid ? vebusService.value : veDirectInverterService - - VBusItem { id: replaceAcInItem; bind: Utils.path(guiModsPrefix, "/ReplaceInactiveAcIn") } - property bool hasAlternator: sys.alternator.power.valid - property bool replaceAcIn: replaceAcInItem.valid && replaceAcInItem.value == 1 && hasAlternator && (sys.acSource == 0 || sys.acSource == 240) - property bool showAcInput: ((isMulti || sys.acInput.power.valid) && ! replaceAcIn) || showAllTiles - property bool showAlternator: !showAcInput && hasAlternator - property double alternatorFlow: showAlternator ? noNoise (sys.alternator.power) : 0 - property bool showAcLoads: isMulti || sys.acLoad.power.valid || veDirectInverterService != "" - property bool showDcSystem: (hasDcSystemItem.valid && hasDcSystemItem.value > 0) || showAllTiles - property bool hasInverter: false - property bool showInverter: hasInverter || inverterService != "" || showAllTiles - - property bool hasAcSolarOnAcIn1: sys.pvOnAcIn1.power.valid - property bool hasAcSolarOnAcIn2: sys.pvOnAcIn2.power.valid - property bool hasAcSolarOnIn: hasAcSolarOnAcIn1 || hasAcSolarOnAcIn2 - property bool hasAcSolarOnOut: sys.pvOnAcOut.power.valid - property bool hasAcSolar: hasAcSolarOnIn || hasAcSolarOnOut - property bool hasDcSolar: sys.pvCharger.power.valid - property bool hasDcAndAcSolar: hasAcSolar && hasDcSolar - property bool showDcAndAcSolar: hasDcAndAcSolar || showAllTiles - property bool showDcSolar: hasDcSolar || showAllTiles - property bool showAcSolar: hasAcSolar || showAllTiles -////// ADDED to show tanks - property int bottomOffset: 45 - property string settingsBindPreffix: "com.victronenergy.settings" - property string pumpBindPreffix: "com.victronenergy.pump.startstop0" - property int numberOfTemps: 0 -//////// added/modified for control show/hide gauges, tanks and temps from menus - property int tankCount: showTanksEnable ? tankModel.rowCount : 0 - property int tempCount: showTempsEnable ? numberOfTemps : 0 - property int tankTempCount: tankCount + tempCount - property bool showTanks: showTanksEnable ? showStatusBar ? false : tankCount > 0 ? true : false : false - property bool showTemps: showTempsEnable ? showStatusBar ? false : tempCount > 0 ? true : false : false - property bool showTanksTemps: showTanks || showTemps - property int compactThreshold: 45 // height below this will be compacted vertically - property bool compact: showTanks && showTemps && tankTempCount > 4 - property int tanksHeight: compact ? 22 : 45 - - property int leftTileCount: (showAcInput ? 1 : 0) + (showAlternator ? 1 : 0) + (showAlternator ? 1 : 0) - -//////// add for PV CHARGER voltage and current - property string pvChargerPrefix1: "" - property string pvChargerPrefix2: "" - property string pvChargerPrefix3: "" - property string pvChargerPrefix4: "" - property string pvChargerPrefix5: "" - property string pvChargerPrefix6: "" - property string pvChargerPrefix7: "" - property int numberOfPvChargers: 0 - property int pvChargerRows: showTanksTemps ? 4 : 7 - property int pvRowsPerCharger: Math.max ( 1, Math.min (pvChargerRows / numberOfPvChargers, 3)) - property bool pvChargerCompact: pvRowsPerCharger < 3 ? true : false - property bool pvShowDetails: pvRowsPerCharger >= 2 ? true : false - -//////// add for PV INVERTER power - property string pvInverterPrefix1: "" - property string pvInverterPrefix2: "" - property string pvInverterPrefix3: "" - property int numberOfPvInverters: 0 - -//////// add for alternator - alternator replaces AC in if AC in is not present - property string alternatorPrefix1: "" - property string alternatorPrefix2: "" - property int numberOfAlternators: 0 - VBusItem { id: alternatorName1; bind: Utils.path(alternatorPrefix1, "/CustomName") } - VBusItem { id: alternatorPower1; bind: Utils.path(alternatorPrefix1, "/Dc/0/Power") } - VBusItem { id: alternatorVoltage1; bind: Utils.path(alternatorPrefix1, "/Dc/0/Voltage") } - VBusItem { id: alternatorCurrent1; bind: Utils.path(alternatorPrefix1, "/Dc/0/Current") } - VBusItem { id: alternatorName2; bind: Utils.path(alternatorPrefix2, "/CustomName") } - VBusItem { id: alternatorPower2; bind: Utils.path(alternatorPrefix2, "/Dc/0/Power") } - -//////// added for control show/hide gauges, tanks and temps from menus - VBusItem { id: showGaugesItem; bind: Utils.path(guiModsPrefix, "/ShowGauges") } - property bool showGauges: showGaugesItem.valid ? showGaugesItem.value === 1 ? true : false : false - VBusItem { id: showTanksItem; bind: Utils.path(guiModsPrefix, "/ShowEnhancedFlowOverviewTanks") } - property bool showTanksEnable: showTanksItem.valid ? showTanksItem.value === 1 ? true : false : false - VBusItem { id: showTempsItem; bind: Utils.path(guiModsPrefix, "/ShowEnhancedFlowOverviewTemps") } - property bool showTempsEnable: showTempsItem.valid ? showTempsItem.value === 1 ? true : false : false - -//////// added to show/dim tiles - VBusItem { id: showInactiveTilesItem; bind: Utils.path(guiModsPrefix, "/ShowInactiveFlowTiles") } - property real disabledTileOpacity: (showInactiveTiles && showInactiveTilesItem.value === 1) ? 0.3 : 1 - property bool showInactiveTiles: showInactiveTilesItem.valid && showInactiveTilesItem.value >= 1 - - VBusItem { id: showBatteryTempItem; bind: Utils.path(guiModsPrefix, "/ShowBatteryTempOnFlows") } - property bool showBatteryTemp: showBatteryTempItem.valid && showBatteryTempItem.value == 1 - - // for debug, ignore validity checks so all tiles and their flow lines will show - property bool showAllTiles: showInactiveTilesItem.valid && showInactiveTilesItem.value == 3 - -//////// added to control time display - VBusItem { id: timeFormatItem; bind: Utils.path(guiModsPrefix, "/TimeFormat") } - property string timeFormat: getTimeFormat () - - function getTimeFormat () - { - if (!timeFormatItem.valid || timeFormatItem.value === 0) - return "" - else if (timeFormatItem.value === 2) - return "h:mm ap" - else - return "hh:mm" - } - -//////// add to display individual PV charger power - VBusItem { id: pvName1; bind: Utils.path(pvChargerPrefix1, "/CustomName") } - VBusItem { id: pvPower1; bind: Utils.path(pvChargerPrefix1, "/Yield/Power") } - VBusItem { id: pvVoltage1; bind: Utils.path(pvChargerPrefix1, "/Pv/V") } - VBusItem { id: pvCurrent1; bind: Utils.path(pvChargerPrefix1, "/Pv/I") } - VBusItem { id: pv1NrTrackers; bind: Utils.path(pvChargerPrefix1, "/NrOfTrackers") } - VBusItem { id: pvName2; bind: Utils.path(pvChargerPrefix2, "/CustomName") } - VBusItem { id: pvPower2; bind: Utils.path(pvChargerPrefix2, "/Yield/Power") } - VBusItem { id: pvVoltage2; bind: Utils.path(pvChargerPrefix2, "/Pv/V") } - VBusItem { id: pvCurrent2; bind: Utils.path(pvChargerPrefix2, "/Pv/I") } - VBusItem { id: pv2NrTrackers; bind: Utils.path(pvChargerPrefix2, "/NrOfTrackers") } - VBusItem { id: pvName3; bind: Utils.path(pvChargerPrefix3, "/CustomName") } - VBusItem { id: pvPower3; bind: Utils.path(pvChargerPrefix3, "/Yield/Power") } - VBusItem { id: pvVoltage3; bind: Utils.path(pvChargerPrefix3, "/Pv/V") } - VBusItem { id: pvCurrent3; bind: Utils.path(pvChargerPrefix3, "/Pv/I") } - VBusItem { id: pv3NrTrackers; bind: Utils.path(pvChargerPrefix3, "/NrOfTrackers") } - VBusItem { id: pvName4; bind: Utils.path(pvChargerPrefix4, "/CustomName") } - VBusItem { id: pvPower4; bind: Utils.path(pvChargerPrefix4, "/Yield/Power") } - VBusItem { id: pvName5; bind: Utils.path(pvChargerPrefix5, "/CustomName") } - VBusItem { id: pvPower5; bind: Utils.path(pvChargerPrefix5, "/Yield/Power") } - VBusItem { id: pvName6; bind: Utils.path(pvChargerPrefix6, "/CustomName") } - VBusItem { id: pvPower6; bind: Utils.path(pvChargerPrefix6, "/Yield/Power") } - VBusItem { id: pvName7; bind: Utils.path(pvChargerPrefix7, "/CustomName") } - VBusItem { id: pvPower7; bind: Utils.path(pvChargerPrefix7, "/Yield/Power") } - - VBusItem { id: timeToGo; bind: Utils.path("com.victronenergy.system","/Dc/Battery/TimeToGo") } - -//////// add to display PV Inverter power - VBusItem { id: pvInverterPower1; bind: Utils.path(pvInverterPrefix1, "/Ac/Power") } - VBusItem { id: pvInverterL1Power1; bind: Utils.path(pvInverterPrefix1, "/Ac/L1/Power") } - VBusItem { id: pvInverterL2Power1; bind: Utils.path(pvInverterPrefix1, "/Ac/L2/Power") } - VBusItem { id: pvInverterL3Power1; bind: Utils.path(pvInverterPrefix1, "/Ac/L3/Power") } - VBusItem { id: pvInverterName1; bind: Utils.path(pvInverterPrefix1, "/CustomName") } - VBusItem { id: pvInverterPower2; bind: Utils.path(pvInverterPrefix2, "/Ac/Power") } - VBusItem { id: pvInverterName2; bind: Utils.path(pvInverterPrefix2, "/CustomName") } - VBusItem { id: pvInverterPower3; bind: Utils.path(pvInverterPrefix3, "/Ac/Power") } - VBusItem { id: pvInverterName3; bind: Utils.path(pvInverterPrefix3, "/CustomName") } - -//////// add to display AC input ignored - VBusItem { id: ignoreAcInput1; bind: Utils.path(inverterService, "/Ac/State/IgnoreAcIn1") } - VBusItem { id: ignoreAcInput2; bind: Utils.path(inverterService, "/Ac/State/IgnoreAcIn2") } - VBusItem { id: acActiveInput; bind: Utils.path(inverterService, "/Ac/ActiveIn/ActiveInput") } - - VBusItem { id: hasDcSystemItem; bind: "com.victronenergy.settings/Settings/SystemSetup/HasDcSystem" } - - //Component.onCompleted: { discoverServices(); showHelp () } - onActiveChanged: - { - if (root.active) - { - discoverServices() - showHelp () - } - } - - title: qsTr("Simple Overview") - - OverviewBox { - id: acInBox -////// GuiMods — DarkMode - titleColor: !darkMode ? "#E74c3c" : "#73261E" - color: !darkMode ? "#C0392B" : "#601C15" - opacity: showAcInput ? 1 : disabledTileOpacity - visible: showAcInput || showInactiveTiles - width: 148 - height: showStatusBar ? 100 : 120 - title: - { - // input 1 is active - if (acActiveInput.value == 0) - { - if (ignoreAcInput1.valid && ignoreAcInput1.value == 1) - return qsTr ("AC In 1 Ignored") - else - return getAcSourceName(sys.acSource) - } - // input 2 is active - else if (acActiveInput.value == 1) - { - if (ignoreAcInput2.valid && ignoreAcInput2.value == 1) - return qsTr ("AC In 2 Ignored") - else - return getAcSourceName(sys.acSource) - } - else - return "no input" - } - anchors { - top: multi.top - left: parent.left; leftMargin: 10 - } - - values: OverviewAcValuesEnhanced { - connection: sys.acInput - } - - MbIcon { - iconId: getAcSourceIcon(sys.acSource) - anchors { - bottom: parent.bottom - left: parent.left; leftMargin: 2 - } - opacity: 0.5 - } -////// add power bar graph - PowerGauge - { - id: acInBar - width: parent.width - height: 12 - anchors - { - top: parent.top; topMargin: 16 - horizontalCenter: parent.horizontalCenter - } - connection: sys.acInput - useInputCurrentLimit: true - maxForwardPowerParameter: "" - maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxFeedInPower" - visible: showGauges && showAcInput - } - DetailTarget { id: acInputTarget; detailsPage: "DetailAcInput.qml" } - } - - - //// add alternator if AC input not present - OverviewBox { - id: alternatorBox - title: qsTr ("Alternator") - color: !darkMode ? "#157894" : "#0a3c4a" - titleColor: !darkMode ? "#419FB9" : "#204f5c" - opacity: showAlternator ? 1 : disabledTileOpacity - visible: showAlternator || showInactiveTiles && ! acInBox.visible - width: 148 - height: showStatusBar ? 100 : 120 - anchors.fill: acInBox - values: Column - { - width: parent.width - TileText - { - text: " " - font.pixelSize: 6 - } - TileText - { - text: EnhFmt.formatVBusItem (sys.alternator.power, "W") - font.pixelSize: 19 - } - TileText - { - text: alternatorName1.valid ? alternatorName1.value : "-" - visible: showAlternator && numberOfAlternators >= 1 - } - TileText - { - text: EnhFmt.formatVBusItem (alternatorPower1, "W") - font.pixelSize: 15 - visible: showAlternator && numberOfAlternators > 1 - } - TileText { - text: EnhFmt.formatVBusItem (alternatorVoltage1, "V") - font.pixelSize: 15 - visible: showAlternator && numberOfAlternators == 1 - } - TileText { - text: EnhFmt.formatVBusItem (alternatorCurrent1, "A") - font.pixelSize: 15 - visible: showAlternator && numberOfAlternators == 1 - } - TileText - { - text: alternatorName2.valid ? alternatorName2.value : "-" - visible: showAlternator && numberOfAlternators >= 2 - } - TileText - { - text: EnhFmt.formatVBusItem (alternatorPower1, "W") - font.pixelSize: 15 - visible: showAlternator && numberOfAlternators >= 2 - } - } - - PowerGauge - { - id: alternatorBar - width: parent.width - height: 12 - anchors - { - top: parent.top; topMargin: 16 - horizontalCenter: parent.horizontalCenter - } - connection: sys.alternator - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/MaxAlternatorPower" - visible: showGauges && showAlternator - } - DetailTarget { id: alternatorTarget; detailsPage: "DetailAlternator.qml" } - } - - MultiEnhanced { - id: multi - anchors { - horizontalCenter: parent.horizontalCenter - top: parent.top; topMargin: 3 - } - inverterService: root.inverterService - opacity: showInverter ? 1 : disabledTileOpacity - visible: showInverter || showInactiveTiles -////// add power bar graph - PowerGaugeMulti - { - id: multiBar - width: multi.width - height: 12 - anchors - { - top: parent.top; topMargin: 23 - horizontalCenter: parent.horizontalCenter - } - inverterService: root.inverterService - visible: showGauges && showInverter - } - DetailTarget { id: multiTarget; detailsPage: "DetailInverter.qml"; width: 60; height: 60 } - } - -////// ADDED to show time inside inverter icon - Timer { - id: wallClock - running: timeFormat != "" - repeat: true - interval: 1000 - triggeredOnStart: true - onTriggered: time = Qt.formatDateTime(new Date(), timeFormat) - property string time - } - TileText - { - text: wallClock.time - font.pixelSize: 18 - color: showInverter || darkMode ? "white" : "black" - anchors - { - top: multi.top; topMargin: 96 - horizontalCenter: multi.horizontalCenter - } - visible: wallClock.running - } - - OverviewBox { - id: acLoadBox - visible: showAcLoads || showInactiveTiles - opacity: showAcLoads ? 1 : disabledTileOpacity - title: qsTr("AC Loads") -////// GuiMods — DarkMode - color: !darkMode ? "#27AE60" : "#135730" - titleColor: !darkMode ? "#2ECC71" : "#176638" - width: 148 - height: showStatusBar ? 80 : 102 - - anchors { - right: parent.right; rightMargin: 10 - top: multi.top - } - - values: OverviewAcValuesEnhanced { - connection: sys.acLoad - } -////// add power bar graph - PowerGauge - { - id: acLoadBar - width: parent.width - height: 12 - anchors - { - top: parent.top; topMargin: 16 - horizontalCenter: parent.horizontalCenter - } - connection: sys.acLoad - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/AcOutputMaxPower" - visible: showGauges && showAcLoads - } - DetailTarget { id: loadsOnOutputTarget; detailsPage: "DetailLoadsCombined.qml" } - } - - Battery { - id: battery - width: acInBox.width - height: 96 - anchors { - bottom: parent.bottom; bottomMargin: showTanksTemps ? bottomOffset + 3 : 5; - left: parent.left; leftMargin: 10 - } - soc: sys.battery.soc.valid ? sys.battery.soc.value : 0 -////// add battery current bar graph - PowerGaugeBattery - { - id: batteryBar - width: parent.width - height: 10 - anchors - { - top: parent.top; topMargin: 52 - horizontalCenter: parent.horizontalCenter - } - visible: showGauges - } - - values: Column { - width: parent.width - - TileText { - text: sys.battery.soc.value === undefined ? "--" : sys.battery.soc.format (0) - font.pixelSize: 25 - } - TileText { - text: EnhFmt.formatVBusItem (sys.battery.power, "W") - } - TileText { - text: " " - font.pixelSize: 6 - } - TileText { - text: EnhFmt.formatVBusItem (sys.battery.voltage, "V ", 2) - + EnhFmt.formatVBusItem (sys.battery.current, "A") - } - TileText { - text: timeToGo.valid ? qsTr ("Remain: ") + TTG.formatTimeToGo (timeToGo) : qsTr (" ") - } - } - DetailTarget { id: batteryTarget; detailsPage: "DetailBattery.qml" } - } - - VBusItem { id: dcSystemNameItem; bind: Utils.path(settingsBindPreffix, "/Settings/GuiMods/CustomDcSystemName") } - - OverviewBox { - id: dcSystemBox -////// wider to make room for current - width: multi.width + 20 - height: 45 - opacity: showDcSystem ? 1 : disabledTileOpacity - visible: showDcSystem || showInactiveTiles - title: dcSystemNameItem.valid && dcSystemNameItem.value != "" ? dcSystemNameItem.value : qsTr ("DC System") - - anchors { - horizontalCenter: multi.horizontalCenter - horizontalCenterOffset: 2 -////// MODIFIED to show tanks - bottom: parent.bottom; bottomMargin: showTanksTemps ? bottomOffset + 3 : 5 - } - - values: - [ - TileText - { - width: parent.width - anchors - { - horizontalCenter: parent.horizontalCenter - bottom: parent.bottom; bottomMargin: 0 - } - ////// modified to show current - text: - { - if (showDcSystem) - { - var current = "" - if (sys.dcSystem.power.valid && sys.battery.voltage.valid) - current = " " + EnhFmt.formatValue (sys.dcSystem.power.value / sys.battery.voltage.value, "A") - return EnhFmt.formatVBusItem (sys.dcSystem.power) + current - } - else - return "--" - } - } - ] - PowerGauge - { - id: dcSystemGauge - width: parent.width - height: 8 - anchors - { - top: parent.top; topMargin: 19 - left: parent.left; leftMargin: 18 - right: parent.right - } - connection: sys.dcSystem - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/DcSystemMaxLoad" - maxReversePowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/DcSystemMaxCharge" - showLabels: true - visible: showGauges && showDcSystem - - } - DetailTarget { id: dcSystemTarget; detailsPage: "DetailDcSystem.qml" } - } - - property int pvOffset1: 27 - property int pvRowSpacing: 16 - property int pvOffset2: pvOffset1 + pvRowSpacing * pvRowsPerCharger - property int pvOffset3: pvOffset2 + pvRowSpacing * pvRowsPerCharger - property int pvOffset4: pvOffset3 + pvRowSpacing * pvRowsPerCharger - property int pvOffset5: pvOffset4 + pvRowSpacing * pvRowsPerCharger - property int pvOffset6: pvOffset5 + pvRowSpacing * pvRowsPerCharger - property int pvOffset7: pvOffset6 + pvRowSpacing * pvRowsPerCharger - -////// replaced OverviewSolarCharger with OverviewBox - OverviewBox { - id: pvChargerBox - title: qsTr("PV Charger") -////// GuiMods — DarkMode - titleColor: !darkMode ? "#F4B350" : "#7A5928" - color: !darkMode ? "#F39C12" : "#794E09" - visible: hasDcSolar || showInactiveTiles - opacity: hasDcSolar ? 1 : disabledTileOpacity - -////// MODIFIED to show tanks & provide extra space if not - height: - { - var availableHeight = root.height - 3 - acLoadBox.height - 5 - (showTanksTemps ? bottomOffset + 3 : 5) - if (showDcAndAcSolar) - return ((availableHeight - 5) / 2) + 4 - else if (showDcSolar) - return availableHeight - else - return 0 - } - width: 148 - - anchors { - right: root.right; rightMargin: 10 - bottom: parent.bottom; bottomMargin: showTanksTemps ? bottomOffset + 3 : 5 - } - -////// moved sun icon here from OverviewSolarChager so it can be put below text, etc - MbIcon { - iconId: "overview-sun" - anchors { - bottom: parent.bottom - right: parent.right; rightMargin: 2 - } - opacity: 0.5 - visible: ! showDcAndAcSolar - } - -//////// modified to add power for individual PV charger info - values: - [ - TileText { - y: 8 - text: EnhFmt.formatVBusItem (sys.pvCharger.power) - font.pixelSize: 19 - }, - MarqueeEnhanced - { - y: pvOffset1 - id: pv1Name - // ofset left margin for this row if showing tanks/temps - width: - { - if (pvChargerCompact) - { - if (showTanksTemps) - return ((parent.width / 2) - 15) - else - return ((parent.width / 2) - 5) - } - else - return (parent.width - 10) - } - anchors.left: parent.left; anchors.leftMargin: (showTanksTemps && pvChargerCompact) ? 15 : 5 - height: 15 - text: pvName1.valid ? pvName1.value : "pv 1" - textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter - fontSize: 15 - Connections { target: scrollTimer; onTriggered: pv1Name.doScroll() } - scroll: false - visible: numberOfPvChargers >= 1 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset1 + (pvChargerCompact ? 0 : pvRowSpacing) - text: EnhFmt.formatVBusItem (pvPower1, "W") - horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter - anchors.right: parent.right; anchors.rightMargin: 5 - font.pixelSize: 15 - visible: numberOfPvChargers >= 1 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset1 + pvRowSpacing * (pvChargerCompact ? 1 : 2) - text: - { - var voltageText, currentText - if (root.numberOfPvChargers < 1) - return " " - else - { - if (pv1NrTrackers.valid && pv1NrTrackers.value > 1) - return qsTr ("multiple trackers") - else if (pvVoltage1.valid) - voltageText = EnhFmt.formatVBusItem (pvVoltage1, "V") - else - voltageText = "??V" - if (pvCurrent1.valid) - currentText = EnhFmt.formatVBusItem (pvCurrent1, "A") - else if (pvPower1.valid) - currentText = EnhFmt.formatValue ((pvPower1.value / pvVoltage1.value), "A") - else - currentText = "??A" - return voltageText + " " + currentText - } - } - font.pixelSize: 15 - visible: pvShowDetails && numberOfPvChargers >= 1 - }, - MarqueeEnhanced - { - y: pvOffset2 - id: pv2Name - width: pvChargerCompact ? ((parent.width / 2) - 5) : parent.width - 10 - anchors.left: parent.left; anchors.leftMargin: 5 - height: 15 - text: pvName2.valid ? pvName2.value : "pv 2" - textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter - fontSize: 15 - Connections { target: scrollTimer; onTriggered: pv2Name.doScroll() } - scroll: false - visible: numberOfPvChargers >= 2 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset2 + (pvChargerCompact ? 0 : pvRowSpacing) - text: EnhFmt.formatVBusItem (pvPower2, "W") - horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter - anchors.right: parent.right; anchors.rightMargin: 5 - font.pixelSize: 15 - visible: numberOfPvChargers >= 2 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset2 + pvRowSpacing * (pvChargerCompact ? 1 : 2) - text: - { - var voltageText, currentText - if (root.numberOfPvChargers < 2) - return " " - else - { - if (pv2NrTrackers.valid && pv2NrTrackers.value > 1) - return qsTr ("multiple trackers") - else if (pvVoltage2.valid) - voltageText = EnhFmt.formatVBusItem (pvVoltage2, "V") - else - voltageText = "??V" - if (pvCurrent2.valid) - currentText = EnhFmt.formatVBusItem (pvCurrent2, "A") - else if (pvPower2.valid) - currentText = EnhFmt.formatValue ((pvPower2.value / pvVoltage2.value), "A") - else - currentText = "??A" - return voltageText + " " + currentText - } - } - font.pixelSize: 15 - visible: pvShowDetails && numberOfPvChargers >= 2 - }, - MarqueeEnhanced - { - y: pvOffset3 - id: pv3Name - width: pvChargerCompact ? ((parent.width / 2) - 5) : parent.width - 10 - anchors.left: parent.left; anchors.leftMargin: 5 - height: 15 - text: pvName3.valid ? pvName3.value : "pv 3" - textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter - fontSize: 15 - Connections { target: scrollTimer; onTriggered: pv3Name.doScroll() } - scroll: false - visible: numberOfPvChargers >= 3 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset3 + (pvChargerCompact ? 0 : pvRowSpacing) - text: EnhFmt.formatVBusItem (pvPower3, "W") - anchors.right: parent.right; anchors.rightMargin: 5 - horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter - font.pixelSize: 15 - visible: numberOfPvChargers >= 3 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset3 + pvRowSpacing * (pvChargerCompact ? 1 : 2) - text: - { - var voltageText, currentText - if (root.numberOfPvChargers < 3) - return " " - else - { - if (pv3NrTrackers.valid && pv3NrTrackers.value > 1) - return qsTr ("multiple trackers") - else if (pvVoltage3.valid) - voltageText = EnhFmt.formatVBusItem (pvVoltage3, "V") - else - voltageText = "??V" - if (pvCurrent3.valid) - currentText = EnhFmt.formatVBusItem (pvCurrent3, "A") - else if (pvPower3.valid) - currentText = EnhFmt.formatValue ((pvPower3.value / pvVoltage3.value), "A") - else - currentText = "??A" - return voltageText + " " + currentText - } - } - font.pixelSize: 15 - visible: pvShowDetails && numberOfPvChargers >= 2 - }, - MarqueeEnhanced - { - y: pvOffset4 - id: pv4Name - // ofset left margin for this row if NOT showing tanks/temps - width: - { - if (pvChargerCompact) - { - if (! showTanksTemps) - return ((parent.width / 2) - 15) - else - return ((parent.width / 2) - 5) - } - else - return (parent.width - 10) - } - anchors.left: parent.left; anchors.leftMargin: ( ! showTanksTemps && pvChargerCompact) ? 15 : 5 - height: 15 - text: pvName4.valid ? pvName4.value : "pv 4" - textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter - fontSize: 15 - Connections { target: scrollTimer; onTriggered: pv4Name.doScroll() } - scroll: false - visible: numberOfPvChargers >= 4 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset4 + (pvChargerCompact ? 0 : pvRowSpacing) - text: EnhFmt.formatVBusItem (pvPower4, "W") - anchors.right: parent.right; anchors.rightMargin: 5 - horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter - font.pixelSize: 15 - visible: numberOfPvChargers >= 4 && ! showDcAndAcSolar - }, - MarqueeEnhanced - { - y: pvOffset5 - id: pv5Name - width: pvChargerCompact ? ((parent.width / 2) - 5) : parent.width - 10 - anchors.left: parent.left; anchors.leftMargin: 5 - height: 15 - text: pvName5.valid ? pvName5.value : "pv 5" - textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter - fontSize: 15 - Connections { target: scrollTimer; onTriggered: pv5Name.doScroll() } - scroll: false - visible: numberOfPvChargers >= 5 && pvChargerRows >= 5 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset5 + (pvChargerCompact ? 0 : pvRowSpacing) - text: EnhFmt.formatVBusItem (pvPower5, "W") - anchors.right: parent.right; anchors.rightMargin: 5 - horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter - font.pixelSize: 15 - visible: numberOfPvChargers >= 5 && pvChargerRows >= 5 && ! showDcAndAcSolar - }, - MarqueeEnhanced - { - y: pvOffset6 - id: pv6Name - width: pvChargerCompact ? ((parent.width / 2) - 5) : parent.width - 10 - anchors.left: parent.left; anchors.leftMargin: 5 - height: 15 - text: pvName6.valid ? pvName6.value : "pv 6" - textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter - fontSize: 15 - Connections { target: scrollTimer; onTriggered: pv6Name.doScroll() } - scroll: false - visible: numberOfPvChargers >= 6 && pvChargerRows >= 6 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset6 + (pvChargerCompact ? 0 : pvRowSpacing) - text: EnhFmt.formatVBusItem (pvPower6, "W") - anchors.right: parent.right; anchors.rightMargin: 5 - horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter - font.pixelSize: 15 - visible: numberOfPvChargers >= 6 && pvChargerRows >= 6 && ! showDcAndAcSolar - }, - MarqueeEnhanced - { - y: pvOffset7 - id: pv7Name - width: pvChargerCompact ? ((parent.width / 2) - 5) : parent.width - 10 - anchors.left: parent.left; anchors.leftMargin: 5 - height: 15 - text: pvName7.valid ? pvName7.value : "pv 7" - textHorizontalAlignment: pvChargerCompact ? Text.AlignLeft : Text.AlignHCenter - fontSize: 15 - Connections { target: scrollTimer; onTriggered: pv6Name.doScroll() } - scroll: false - visible: numberOfPvChargers >= 7 && pvChargerRows >= 7 && ! showDcAndAcSolar - }, - TileText { - y: pvOffset7 + (pvChargerCompact ? 0 : pvRowSpacing) - text: EnhFmt.formatVBusItem (pvPower7, "W") - anchors.right: parent.right; anchors.rightMargin: 5 - horizontalAlignment: pvChargerCompact ? Text.AlignRight : Text.AlignHCenter - font.pixelSize: 15 - visible: numberOfPvChargers >= 7 && pvChargerRows >= 7 && ! showDcAndAcSolar - } - ] -////// add power bar graph - PowerGauge - { - id: pvChargerBar - width: parent.width - (showDcAndAcSolar && ! showTanksTemps ? 20 : 0) - height: 10 - anchors - { - top: parent.top; topMargin: 19 - right: parent.right; rightMargin: 0.5 - } - connection: sys.pvCharger - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvChargerMaxPower" - visible: showGauges && showDcSolar - } - DetailTarget { id: pvChargerTarget; detailsPage: "DetailPvCharger.qml" } - } - -////// replaced OverviewSolarInverter with OverviewBox - OverviewBox { - id: pvInverter - title: qsTr("PV Inverter") -////// GuiMods — DarkMode - titleColor: !darkMode ? "#F4B350" : "#7A5928" - color: !darkMode ? "#F39C12" : "#794E09" - visible: hasAcSolar || showInactiveTiles - opacity: hasAcSolar ? 1 : disabledTileOpacity - -////// MODIFIED to show tanks & provide extra space if not - height: - { - var availableHeight = root.height - 3 - acLoadBox.height -5 - availableHeight -= (showTanksTemps ? bottomOffset + 3 : 5) - if (showDcAndAcSolar) - availableHeight -= pvChargerBox.height + 5 - if (showAcSolar) - return availableHeight - else - return 0 - } - width: 148 - - anchors { - right: root.right; rightMargin: 10; - bottom: showDcAndAcSolar ? pvChargerBox.top : root.bottom - bottomMargin: showDcAndAcSolar ? 5 : showTanksTemps ? bottomOffset + 3 : 5 - } - - values: - [ - TileText { - id: coupledPvAc - - property double pvInverterOnAcOut: sys.pvOnAcOut.power.valid ? sys.pvOnAcOut.power.value : 0 - property double pvInverterOnAcIn1: sys.pvOnAcIn1.power.valid ? sys.pvOnAcIn1.power.value : 0 - property double pvInverterOnAcIn2: sys.pvOnAcIn2.power.valid ? sys.pvOnAcIn2.power.value : 0 - property bool powerValid: sys.pvOnAcOut.power.valid || sys.pvOnAcIn1.power.valid || sys.pvOnAcIn2.power.valid - - y: 10 - text: powerValid ? EnhFmt.formatValue (pvInverterOnAcOut + pvInverterOnAcIn1 + pvInverterOnAcIn2, "W") : "" - font.pixelSize: 19 - visible: showAcSolar - }, -//////// add individual PV inverter powers - TileText { - y: 31 - text: pvInverterName1.valid ? pvInverterName1.value : "-" - visible: !showDcAndAcSolar && numberOfPvInverters >= 2 - }, - TileText { - y: 47 - text: EnhFmt.formatVBusItem (pvInverterPower1, "W") - font.pixelSize: 15 - visible: !showDcAndAcSolar && numberOfPvInverters >= 2 - }, - TileText { - y: 63 - text: pvInverterName2.valid ? pvInverterName2.value : "-" - visible: !showDcAndAcSolar && numberOfPvInverters >= 2 - }, - TileText { - y: 77 - text: EnhFmt.formatVBusItem (pvInverterPower2, "W") - font.pixelSize: 15 - visible: !showDcAndAcSolar && numberOfPvInverters >= 2 - }, - TileText { - y: 93 - text: pvInverterName3.valid ? pvInverterName3.value : "-" - visible: !showDcAndAcSolar && numberOfPvInverters >=3 && ! showTanksTemps - }, - TileText { - y: 107 - text: EnhFmt.formatVBusItem (pvInverterPower3, "W") - font.pixelSize: 15 - visible: !showDcAndAcSolar && numberOfPvInverters >=3 && ! showTanksTemps - }, - TileText { - y: 31 - text: qsTr ("L1: ") + EnhFmt.formatVBusItem (pvInverterL1Power1, "W") - visible: !showDcAndAcSolar && numberOfPvInverters == 1 && pvInverterL1Power1.valid && (pvInverterL2Power1.valid || pvInverterL3Power1.valid) - }, - TileText { - y: 47 - text: qsTr ("L2: ") + EnhFmt.formatVBusItem (pvInverterL2Power1, "W") - visible: !showDcAndAcSolar && numberOfPvInverters == 1 && pvInverterL2Power1.valid - }, - TileText { - y: 63 - text: qsTr ("L3: ") + EnhFmt.formatVBusItem (pvInverterL3Power1, "W") - visible: !showDcAndAcSolar && numberOfPvInverters == 1 && pvInverterL3Power1.valid - } - ] -////// add power bar graph - PowerGauge - { - id: pvInverterBar - width: parent.width - height: 12 - anchors - { - top: parent.top; topMargin: 19 - horizontalCenter: parent.horizontalCenter - } - maxForwardPowerParameter: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvOnOutputMaxPower" - maxForwardPowerParameter2: "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvOnGridMaxPower" - connection: sys.pvOnAcOut - connection2: sys.pvOnGrid - visible: showGauges && showAcSolar - } - DetailTarget { id: pvInverterTarget; detailsPage: "DetailPvInverter.qml" } - } - - OverviewConnection { - id: acInToMulti - visible: showAcInput - ballCount: 2 - path: straight - active: root.active && showAcInput && showInverter - value: flow(sys.acInput ? sys.acInput.power : 0) - - anchors { - left: acInBox.right; leftMargin: -10 - right: multi.left; rightMargin: -10; bottom: acInBox.bottom; bottomMargin: 25 - } - } - - OverviewConnection { - id: multiToAcLoads - ballCount: 2 - path: straight - active: root.active && ( showAcLoads && showInverter ) - value: flow(sys.acLoad.power) - - anchors { - left: multi.right; leftMargin: -10; - right: acLoadBox.left; rightMargin: -10 - bottom: acLoadBox.bottom; bottomMargin: 8 - } - } - - OverviewConnection { - id: pvInverterToMulti - ballCount: 3 - path: corner - active: root.active && showAcSolar && showInverter - value: Utils.sign(noNoise(sys.pvOnAcOut.power) + noNoise(sys.pvOnAcIn1.power) + noNoise(sys.pvOnAcIn2.power)) - - anchors { - left: pvInverter.left; leftMargin: 8 - top: pvInverter.verticalCenter; topMargin: showDcAndAcSolar ? 10 : 0 - right: multi.horizontalCenter; rightMargin: -20 - bottom: multi.bottom; bottomMargin: 10 - } - } - - // invisible anchor point to connect the chargers to the battery - Item { - id: dcConnect - anchors { - left: multi.horizontalCenter; leftMargin: showAcSolar ? -20 : 0 - bottom: dcSystemBox.top; bottomMargin: showDcAndAcSolar ? 7 : 10 - } - } - - OverviewConnection - { - id: dcBus2 - ballCount: 2 - path: straight - active: root.active && ( showInverter || showDcSolar ) - value: -Utils.sign (noNoise (sys.pvCharger.power) + noNoise (sys.vebusDc.power)) - startPointVisible: false - endPointVisible: false - - anchors { - right: dcConnect.left - top: dcConnect.top - - left: multi.left; leftMargin: -10 - bottom: dcConnect.top - } - } - - OverviewConnection - { - id: alternatorToDcBus2 - ballCount: 3 - path: corner - active: root.active && showAlternator - value: Utils.sign (alternatorFlow) - endPointVisible: false - anchors - { - left: alternatorBox.right; leftMargin: -10 - top: alternatorBox.bottom; topMargin: -15 - - right: dcBus2.left - bottom: dcBus2.bottom - } - } - - OverviewConnection { - id: multiToDcConnect - ballCount: showTanksTemps ? 2 : 4 - path: straight - active: root.active && showInverter - value: -flow(sys.vebusDc.power); - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: dcConnect.left - bottom: multi.bottom; bottomMargin: 10 - } - } - - OverviewConnection { - id: pvChargerBoxDcConnect - ballCount: 3 - path: straight - active: root.active && showDcSolar - value: -flow(sys.pvCharger.power) - startPointVisible: false - - anchors { - left: dcConnect.left - top: dcConnect.top - - right: pvChargerBox.left; rightMargin: -8 - bottom: dcConnect.top; - } - } - - OverviewConnection { - id: batteryToDcBus2 - ballCount: 1 - path: straight - active: root.active && ( showInverter || showDcSolar ) - value: Utils.sign(noNoise(sys.pvCharger.power) + noNoise(sys.vebusDc.power) + alternatorFlow) - startPointVisible: false - - anchors { - left: dcBus2.left - top: dcBus2.top - - right: battery.right; rightMargin: 10 - bottom: dcBus2.top - } - } - - OverviewConnection { - id: batteryToDcSystem - ballCount: 2 - path: straight - active: root.active && showDcSystem - value: flow(sys.dcSystem.power) - - anchors { - left: battery.right; leftMargin: -10 - top: dcSystemBox.verticalCenter; - right: dcSystemBox.left; rightMargin: -10 - bottom: dcSystemBox.verticalCenter - } - } -////// moved order so it covers connections -////// moved to under Multi - OverviewEssReason { - anchors { - top: multi.bottom; topMargin: 7 - horizontalCenter: parent.horizontalCenter - } - } - -////// ADDED to show tanks & temps - // Synchronise tank name text scroll start and PV Charger name scroll - Timer - { - id: scrollTimer - interval: 15000 - repeat: true - running: root.active - } - ListView - { - id: tanksColum - - visible: showTanks - width: compact ? root.width : root.width * tankCount / tankTempCount - property int tileWidth: width / Math.min (count, 5.2) - height: root.tanksHeight - anchors - { - bottom: root.bottom - left: root.left - } - - // flickable list if more than will fit across bottom of screen - interactive: count > 4 ? true : false - orientation: ListView.Horizontal - - model: TankModel { id: tankModel } - delegate: TileTankEnhanced { - // Without an intermediate assignment this will trigger a binding loop warning. - property variant theService: DBusServices.get(buddy.id) - service: theService - width: tanksColum.tileWidth - height: root.tanksHeight - pumpBindPrefix: root.pumpBindPreffix - compact: root.compact - Connections { - target: scrollTimer - onTriggered: doScroll() - } - } - Tile { - title: qsTr("TANKS") - anchors.fill: parent - values: TileText { - text: qsTr("") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - - ListView - { - id: tempsColumn - - visible: showTemps - width: compact ? root.width : root.width * tempCount / tankTempCount - property int tileWidth: width / Math.min (count, 5.2) - height: root.tanksHeight - anchors - { - bottom: root.bottom - bottomMargin: compact ? root.tanksHeight : 0 - right: root.right - } - - // make list flickable if more tiles than will fit completely - interactive: count > 4 ? true : false - orientation: ListView.Horizontal - - model: tempsModel - delegate: TileTemp - { - width: tempsColumn.tileWidth - height: tempsColumn.height - compact: root.compact - Connections - { - target: scrollTimer - onTriggered: doScroll() - } - } - Tile - { - title: qsTr("TEMPS") - anchors.fill: parent - values: TileText - { - text: qsTr("") - width: parent.width - wrapMode: Text.WordWrap - } - z: -1 - } - } - ListModel { id: tempsModel } - - // When new service is found add resources as appropriate - Connections - { - target: DBusServices - onDbusServiceFound: addService(service) - } - - // hack to get value(s) from within a loop inside a function when service is changing - property string tempServiceName: "" - property VBusItem temperatureItem: VBusItem { bind: Utils.path(tempServiceName, "/Dc/0/Temperature") } - - function addService(service) - { - switch (service.type) - { -//////// add for temp sensors - case DBusService.DBUS_SERVICE_TEMPERATURE_SENSOR: - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - break;; - case DBusService.DBUS_SERVICE_MULTI: - hasInverter = true - root.tempServiceName = service.name - if (temperatureItem.valid && showBatteryTemp) - { - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - } - break;; -//////// add for VE.Direct inverters - case DBusService.DBUS_SERVICE_INVERTER: - hasInverter = true - if (veDirectInverterService == "") - veDirectInverterService = service.name; - break;; - -//////// add for PV CHARGER voltage and current display - case DBusService.DBUS_SERVICE_SOLAR_CHARGER: - case DBusService.DBUS_SERVICE_MULTI_RS: - if ( service.type == DBusService.DBUS_SERVICE_MULTI_RS ) - hasInverter = true - numberOfPvChargers++ - if (numberOfPvChargers === 1) - pvChargerPrefix1 = service.name; - else if (numberOfPvChargers === 2) - pvChargerPrefix2 = service.name; - else if (numberOfPvChargers === 3) - pvChargerPrefix3 = service.name; - else if (numberOfPvChargers === 4) - pvChargerPrefix4 = service.name; - else if (numberOfPvChargers === 5) - pvChargerPrefix5 = service.name; - else if (numberOfPvChargers === 6) - pvChargerPrefix6 = service.name; - else if (numberOfPvChargers === 7) - pvChargerPrefix7 = service.name; - break;; - -//////// add for PV INVERTER power display - case DBusService.DBUS_SERVICE_PV_INVERTER: - numberOfPvInverters++ - if (numberOfPvInverters === 1) - pvInverterPrefix1 = service.name; - else if (numberOfPvInverters === 2) - pvInverterPrefix2 = service.name; - else if (numberOfPvInverters === 3) - pvInverterPrefix3 = service.name; - break;; - case DBusService.DBUS_SERVICE_BATTERY: - root.tempServiceName = service.name - if (temperatureItem.valid && showBatteryTemp) - { - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - } - break;; -//////// add for alternator - case DBusService.DBUS_SERVICE_ALTERNATOR: - numberOfAlternators++ - if (numberOfAlternators === 1) - alternatorPrefix1 = service.name; - else if (numberOfAlternators === 2) - alternatorPrefix2 = service.name; - break;; - } - } - - // Detect available services of interest - function discoverServices() - { - numberOfTemps = 0 - numberOfPvChargers = 0 - numberOfPvInverters = 0 - numberOfAlternators = 0 - veDirectInverterService = "" - hasInverter = false - pvChargerPrefix1 = "" - pvChargerPrefix2 = "" - pvChargerPrefix3 = "" - pvChargerPrefix4 = "" - pvChargerPrefix5 = "" - pvChargerPrefix6 = "" - pvChargerPrefix7 = "" - pvInverterPrefix1 = "" - pvInverterPrefix2 = "" - pvInverterPrefix3 = "" - alternatorPrefix1 = "" - alternatorPrefix2 = "" - tempsModel.clear() - for (var i = 0; i < DBusServices.count; i++) - { - addService(DBusServices.at(i)) - } - } - -// Details targets - - // help message shown when menu is first drawn - Rectangle - { - id: helpBox - color: "white" - width: multi.width - height: 32 -////// GuiMods — DarkMode - opacity: !darkMode ? 0.7 : 0.85 - anchors - { - top: multi.bottom; topMargin: 1 - horizontalCenter: root.horizontalCenter - } - visible: false - TileText - { - text: qsTr ( "Tap tile center for detail at any time" ) - color: "black" - anchors.fill: helpBox - wrapMode: Text.WordWrap - font.pixelSize: 12 - visible: parent.visible - } - } - - //// hard key handler - // used to press buttons when touch isn't available - // UP and DOWN buttons cycle through the list of touch areas - // "space" button is used to simulate a touch on the area - // target must be highlighted so that other uses of "space" - // will still occur - - // list of all details touchable areas - property variant targetList: - [ - acInputTarget, alternatorTarget, batteryTarget, - multiTarget, dcSystemTarget, - loadsOnOutputTarget, pvInverterTarget, pvChargerTarget - ] - - property int selectedTarget: 0 - - Timer - { - id: targetTimer - interval: 5000 - repeat: false - running: false - onTriggered: { hideAllTargets () } - } - - Keys.forwardTo: [keyHandler] - Item - { - id: keyHandler - Keys.onUpPressed: - { - nextTarget (-1) - event.accepted = true - } - - Keys.onDownPressed: - { - nextTarget (+1) - event.accepted = true - } - Keys.onSpacePressed: - { - if (targetTimer.running) - { - var foo // hack to make clicked() work - bar.clicked (foo) - event.accepted = true - } - else - event.accepted = false - } - } - // hack to make clicked() work - property variant bar: targetList[selectedTarget] - - function nextTarget (increment) - { - // make one pass through all possible targets to find an enabled one - // if found, that's the new selectedTarget, - // if not selectedTarget does not change - var newIndex = selectedTarget - for (var i = 0; i < targetList.length; i++) - { - if (( ! targetTimer.running || helpBox.visible) && targetList[newIndex].enabled) - { - highlightSelectedTarget () - return - } - newIndex += increment - if (newIndex >= targetList.length) - newIndex = 0 - else if (newIndex < 0) - newIndex = targetList.length - 1 - if (targetList[newIndex].enabled) - { - selectedTarget = newIndex - highlightSelectedTarget () - break - } - } - } - - function showHelp () - { - for (var i = 0; i < targetList.length; i++) - { - targetList[i].targetVisible = true - } - helpBox.visible = true - targetTimer.restart () - } - function hideAllTargets () - { - for (var i = 0; i < targetList.length; i++) - { - targetList[i].targetVisible = false - } - helpBox.visible = false - } - function highlightSelectedTarget () - { - for (var i = 0; i < targetList.length; i++) - { - if (targetList[i] == targetList[selectedTarget]) - targetList[i].targetVisible = true - else - targetList[i].targetVisible = false - } - helpBox.visible = false - targetTimer.restart () - } -} diff --git a/FileSets/v3.40~8/OverviewMobileEnhanced.qml b/FileSets/v3.40~8/OverviewMobileEnhanced.qml deleted file mode 120000 index ea719476..00000000 --- a/FileSets/v3.40~8/OverviewMobileEnhanced.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/OverviewSolarCharger.qml b/FileSets/v3.40~8/OverviewSolarCharger.qml deleted file mode 120000 index 7353cec9..00000000 --- a/FileSets/v3.40~8/OverviewSolarCharger.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/OverviewSolarInverter.qml b/FileSets/v3.40~8/OverviewSolarInverter.qml deleted file mode 120000 index 4048703e..00000000 --- a/FileSets/v3.40~8/OverviewSolarInverter.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/OverviewTankDelegate.qml b/FileSets/v3.40~8/OverviewTankDelegate.qml deleted file mode 120000 index faeb9aeb..00000000 --- a/FileSets/v3.40~8/OverviewTankDelegate.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/OverviewTanks.qml b/FileSets/v3.40~8/OverviewTanks.qml deleted file mode 120000 index 645a324b..00000000 --- a/FileSets/v3.40~8/OverviewTanks.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~8/OverviewTanksTempsDigInputs.qml deleted file mode 120000 index 47c4f55e..00000000 --- a/FileSets/v3.40~8/OverviewTanksTempsDigInputs.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/PageDigitalInput.qml b/FileSets/v3.40~8/PageDigitalInput.qml deleted file mode 120000 index 5b768f8f..00000000 --- a/FileSets/v3.40~8/PageDigitalInput.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/PageGenerator.qml b/FileSets/v3.40~8/PageGenerator.qml deleted file mode 120000 index efbafddf..00000000 --- a/FileSets/v3.40~8/PageGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~21/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/PageMain.qml b/FileSets/v3.40~8/PageMain.qml deleted file mode 120000 index 33fe83b0..00000000 --- a/FileSets/v3.40~8/PageMain.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~13/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/PageSettingsGenerator.qml b/FileSets/v3.40~8/PageSettingsGenerator.qml deleted file mode 120000 index 15dd8f85..00000000 --- a/FileSets/v3.40~8/PageSettingsGenerator.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/PageSettingsGuiMods.qml b/FileSets/v3.40~8/PageSettingsGuiMods.qml deleted file mode 120000 index e831a7a4..00000000 --- a/FileSets/v3.40~8/PageSettingsGuiMods.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/PageSettingsRelay.qml b/FileSets/v3.40~8/PageSettingsRelay.qml deleted file mode 120000 index 156aadac..00000000 --- a/FileSets/v3.40~8/PageSettingsRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/PowerGauge.qml b/FileSets/v3.40~8/PowerGauge.qml deleted file mode 100644 index fb5c55f2..00000000 --- a/FileSets/v3.40~8/PowerGauge.qml +++ /dev/null @@ -1,320 +0,0 @@ -// displays value as a bar surrounded by three range regions -// use for I/O, PV inverter & charger - -import QtQuick 1.1 -import "utils.js" as Utils -import com.victron.velib 1.0 - -Item { - id: root - -////// GuiMods — DarkMode - property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } - property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 - - property variant connection - // connection2 accommodates combined PV inverter AC input and AC output - property variant connection2: undefined - property bool includeConnection2: connection2 != undefined - - property bool reversePower: false - property bool useInputCurrentLimit: false - property variant endLabelFontSize: 16 - property color endLabelBackgroundColor: "transparent" - - property int reportedPhaseCount1: connection == undefined ? 0 : connection.phaseCount == undefined || ! connection.phaseCount.valid ? 1 : connection.phaseCount.value - property int phaseCount1: reportedPhaseCount1 < 2 ? reportedPhaseCount1 : (connection.isAcOutput ? connection.l2AndL1OutSummed : connection.splitPhaseL2PassthruDisabled) ? 1 : connection.phaseCount.value - - property int reportedPhaseCount2: connection2 == undefined ? 0 : connection2.phaseCount == undefined || ! connection2.phaseCount.valid ? 1 : connection2.phaseCount.value - property int phaseCount2: reportedPhaseCount2 < 2 ? reportedPhaseCount2 : (connection2.isAcOutput ? connection2.l2AndL1OutSummed : connection2.splitPhaseL2PassthruDisabled) ? 1 : connection2.phaseCount.value - - property int phaseCount: includeConnection2 ? Math.max (phaseCount1, phaseCount2) : phaseCount1 - - property string maxForwardPowerParameter: "" - VBusItem { id: maxForwardLimitItem; bind: root.maxForwardPowerParameter } - property string maxForwardPowerParameter2: "" - VBusItem { id: maxForwardLimitItem2; bind: root.maxForwardPowerParameter2 } - - property string maxReversePowerParameter: "" - VBusItem { id: maxReverseLimitItem; bind: root.maxReversePowerParameter } - - property real inPowerLimit: sys.acInput.inCurrentLimit.valid ? sys.acInput.inCurrentLimit.value * sys.acInput.voltageL1.value : 0 - - property real maxForwardPower1: maxForwardLimitItem.valid ? maxForwardLimitItem.value : 0 - property real maxForwardPower2: maxForwardLimitItem2.valid ? maxForwardLimitItem2.value : 0 - property real maxForwardLimit: useInputCurrentLimit ? inPowerLimit : maxForwardPower1 + maxForwardPower2 - property real maxReverseLimit: maxReverseLimitItem.valid ? maxReverseLimitItem.value : 0 - // overload range is 10% of forward to reverse limits - property real overload: (maxForwardLimit + maxReverseLimit) * 0.1 - property real maxForwardDisplayed: maxForwardLimit > 0 ? maxForwardLimit + overload : 0 - property real maxReverseDisplayed: maxReverseLimit > 0 ? maxReverseLimit + overload : 0 - property real totalPowerDisplayed: maxForwardDisplayed + maxReverseDisplayed - - property bool showLabels: false - property variant endLabelColor: "white" - property real labelOffset: 15 - property real showLeftLabel: showGauge && showLabels && maxReverseLimit != 0 - property bool showRightLabel: showGauge && showLabels && maxForwardLimit != 0 - property int labelCount: (showLeftLabel ? 1 : 0) + (showRightLabel ? 1 : 0) - - property bool showGauge: root.connection != undefined && totalPowerDisplayed > 0 && phaseCount > 0 - property real scaleFactor: showGauge ? (root.width - (labelCount * labelOffset)) / totalPowerDisplayed : 0 - property real zeroOffset: showGauge ? ( maxReverseDisplayed * scaleFactor + (showLeftLabel ? labelOffset : 0 )) : 0 - - property int barSpacing: phaseCount > 0 ? Math.max (height / (phaseCount + 1), 2) : 0 - property int barHeight: barSpacing < 3 ? barSpacing : barSpacing - 1 - property int firstBarVertPos: (height - barSpacing * phaseCount) / 2 - property real bar1offset - property real bar2offset - property real bar3offset - - property color bar1color: "black" - property color bar2color: "black" - property color bar3color: "black" - - // left end label - Rectangle - { - anchors.fill: leftlabelText - color: endLabelBackgroundColor - visible: showLeftLabel - } - TileText - { - id: leftlabelText - text: "S" - color: endLabelColor - font.pixelSize: endLabelFontSize - width: labelOffset - anchors - { - verticalCenter: root.verticalCenter - verticalCenterOffset: 1 - left: root.left - } - visible: showLeftLabel - } - // right end label - Rectangle - { - anchors.fill: rightLabelText - color: endLabelBackgroundColor - visible: showRightLabel - } - TileText - { - id: rightLabelText - text: "C" - color: endLabelColor - font.pixelSize: endLabelFontSize - width: labelOffset - anchors - { - verticalCenter: leftlabelText.verticalCenter - right: root.right - } - visible: showRightLabel - } - // overload range Left - Rectangle - { - id: overloadLeft - width: showGauge ? scaleFactor * (maxReverseDisplayed - maxReverseLimit) : 0 - height: root.height - clip: true -////// GuiMods — DarkMode - color: !darkMode ? "#ffb3b3" : "#bf8686" - visible: showGauge - anchors - { - top: root.top - left: root.left; leftMargin: showLeftLabel ? labelOffset : 0 - } - } - // OK range (both left and right in a single rectangle) - Rectangle - { - id: okRange - width: showGauge ? scaleFactor * (maxForwardLimit + maxReverseLimit) : 0 - height: root.height - clip: true -////// GuiMods — DarkMode - color: !darkMode ? "#99ff99" : "#73bf73" - visible: showGauge - anchors - { - top: root.top - left: overloadLeft.right - } - } - // overload range right - Rectangle - { - id: overloadRight - width: showGauge ? scaleFactor * (maxForwardDisplayed - maxForwardLimit) : 0 - height: root.height - clip: true -////// GuiMods — DarkMode - color: !darkMode ? "#ffb3b3" : "#bf8686" - visible: showGauge - anchors - { - top: root.top - left: okRange.right - } - } - - // actual bars - Rectangle - { - id: bar1 - width: phaseCount >= 1 ? calculateBar1width () : 0 - height: barHeight - clip: true - color: root.bar1color - anchors - { - top: root.top; topMargin: firstBarVertPos - left: root.left; leftMargin: root.bar1offset - - } - visible: showGauge && phaseCount >= 1 - } - Rectangle - { - id: bar2 - width: phaseCount >= 2 ? calculateBar2width () : 0 - height: barHeight - clip: true - color: root.bar2color - anchors - { - top: root.top; topMargin: firstBarVertPos + barSpacing - left: root.left; leftMargin: root.bar2offset - } - visible: showGauge && phaseCount >= 2 - } - Rectangle - { - id: bar3 - width: phaseCount >= 3 ? calculateBar3width () : 0 - height: barHeight - clip: true - color: root.bar3color - anchors - { - top: root.top; topMargin: firstBarVertPos + barSpacing * 2 - left: root.left; leftMargin: root.bar3offset - } - visible: showGauge && phaseCount >= 3 - } - - // zero line - draw last so it's on top - Rectangle - { - id: zeroLine - width: 1 - height: root.height - clip: true - color: "black" - visible: showGauge && maxReverseLimit > 0 - anchors - { - top: root.top - left: root.left - leftMargin: zeroOffset - } - } - - function calculateBar1width () - { - var currentValue = 0.0, barWidth - if (root.connection.powerL1 != undefined) - currentValue += root.connection.powerL1.valid ? root.connection.powerL1.value : 0 - else if (root.connection.power != undefined) - currentValue += root.connection.power.valid ? root.connection.power.value : 0 - if (includeConnection2) - { - if (root.connection2.powerL1 != undefined) - currentValue += root.connection2.powerL1.valid ? root.connection2.powerL1.value : 0 - else if (root.connection2.power != undefined) - currentValue += root.connection2.power.valid ? root.connection2.power.value : 0 - } - - if (reversePower) - currentValue = -currentValue - - root.bar1color = getBarColor (currentValue) - barWidth = Math.min ( Math.max (currentValue, -maxReverseDisplayed), maxForwardDisplayed) * scaleFactor - // left of bar is at 0 point - if (barWidth >= 0) - { - root.bar1offset = zeroOffset - return barWidth - } - // RIGHT of bar is at 0 point - else - { - root.bar1offset = zeroOffset + barWidth - return -barWidth - } - } - function calculateBar2width () - { - var currentValue, barWidth - currentValue = root.connection.powerL2.valid ? root.connection.powerL2.value : 0 - if (includeConnection2) - currentValue += root.connection2.powerL2.valid ? root.connection2.powerL2.value : 0 - - if (reversePower) - currentValue = -currentValue - root.bar2color = getBarColor (currentValue) - barWidth = Math.min ( Math.max (currentValue, -maxReverseDisplayed), maxForwardDisplayed) * scaleFactor - // left of bar is at 0 point - if (barWidth >= 0) - { - root.bar2offset = zeroOffset - return barWidth - } - // RIGHT of bar is at 0 point - else - { - root.bar2offset = zeroOffset + barWidth - return -barWidth - } - } - function calculateBar3width () - { - var currentValue, barWidth - currentValue = root.connection.powerL3.valid ? root.connection.powerL3.value : 0 - if (includeConnection2) - currentValue += root.connection2.powerL3.valid ? root.connection2.powerL3.value : 0 - - if (reversePower) - currentValue = -currentValue - root.bar3color = getBarColor (currentValue) - barWidth = Math.min ( Math.max (currentValue, -maxReverseDisplayed), maxForwardDisplayed) * scaleFactor - // left of bar is at 0 point - if (barWidth >= 0) - { - root.bar3offset = zeroOffset - return barWidth - } - // RIGHT of bar is at 0 point - else - { - root.bar3offset = zeroOffset + barWidth - return -barWidth - } - } - - function getBarColor (currentValue) - { - if (currentValue > maxForwardLimit || currentValue < -maxReverseLimit) -////// GuiMods — DarkMode - return !darkMode ? "#ff0000" : "#bf0000" - else -////// GuiMods — DarkMode - return !darkMode ? "#008000" : "#006000" - } -} diff --git a/FileSets/v3.40~8/Tile.qml b/FileSets/v3.40~8/Tile.qml deleted file mode 120000 index 0558cecf..00000000 --- a/FileSets/v3.40~8/Tile.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/TileDigIn.qml b/FileSets/v3.40~8/TileDigIn.qml deleted file mode 120000 index 44616f30..00000000 --- a/FileSets/v3.40~8/TileDigIn.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/TileRelay.qml b/FileSets/v3.40~8/TileRelay.qml deleted file mode 120000 index 9f83152f..00000000 --- a/FileSets/v3.40~8/TileRelay.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/TileText.qml b/FileSets/v3.40~8/TileText.qml deleted file mode 120000 index 8d7c0778..00000000 --- a/FileSets/v3.40~8/TileText.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/attributes.csv b/FileSets/v3.40~8/attributes.csv deleted file mode 120000 index 4157dcc8..00000000 --- a/FileSets/v3.40~8/attributes.csv +++ /dev/null @@ -1 +0,0 @@ -../v3.40~16/attributes.csv \ No newline at end of file diff --git a/FileSets/v3.40~8/dbus_digitalinputs.py b/FileSets/v3.40~8/dbus_digitalinputs.py deleted file mode 120000 index e74da5b6..00000000 --- a/FileSets/v3.40~8/dbus_digitalinputs.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.40~8/dbus_generator.py b/FileSets/v3.40~8/dbus_generator.py deleted file mode 120000 index 0cd84ca3..00000000 --- a/FileSets/v3.40~8/dbus_generator.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~39/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.40~8/dbus_systemcalc.py b/FileSets/v3.40~8/dbus_systemcalc.py deleted file mode 120000 index 7ef1f49f..00000000 --- a/FileSets/v3.40~8/dbus_systemcalc.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~10/dbus_systemcalc.py \ No newline at end of file diff --git a/FileSets/v3.40~8/main.qml b/FileSets/v3.40~8/main.qml deleted file mode 120000 index 916fdfbf..00000000 --- a/FileSets/v3.40~8/main.qml +++ /dev/null @@ -1 +0,0 @@ -../v3.40~13/main.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/startstop.py b/FileSets/v3.40~8/startstop.py deleted file mode 120000 index 274861e3..00000000 --- a/FileSets/v3.40~8/startstop.py +++ /dev/null @@ -1 +0,0 @@ -../v3.40~17/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~8/styles.css b/FileSets/v3.40~8/styles.css deleted file mode 120000 index ef8557ec..00000000 --- a/FileSets/v3.40~8/styles.css +++ /dev/null @@ -1 +0,0 @@ -../v3.40~35/styles.css \ No newline at end of file diff --git a/ReadMe b/ReadMe index edc17064..fb0ae023 100644 --- a/ReadMe +++ b/ReadMe @@ -1,8 +1,6 @@ -Recent changes: - ExtTransferSwitch functionality has been merged into GuiMods - ExtTransferSwitch is now obsolete and will be uninstalled by GuiMods - -GuiMods has been revived with combined functionality of the original GuiMods and GuiMods2 +NOTE: Support for firmware prior to v3.10 has been dropped starting with GuiMods v10.56 + if you are running older versions, change the branch/tag to preV3.10support + for any packages you wish to run on that firmware This package provides the following modifications to the VenusOS GUI: diff --git a/changes b/changes index 833615f2..7760f138 100644 --- a/changes +++ b/changes @@ -1,3 +1,9 @@ +10.56: + add support for v3.40 + dropping support for firmware earlier than v3.10 + dropping support for v3.40 beta versions + moved velib_python in SetupHelper to a single version + v10.55: add support for v3.40~39 moved more replacements to patched files