From a7eb57e1bb5b4f464747a3e42753edf164abdf1f Mon Sep 17 00:00:00 2001
From: kwindrem <58538395+kwindrem@users.noreply.github.com>
Date: Wed, 17 Jul 2024 14:29:58 -0700
Subject: [PATCH] add v3.40, dropping support for firmware earlier than v3.10
---
ExtTransferSwitch.py | 22 +-
...Battery.qml-v3.40~32 => Battery.qml-v3.34} | 0
...l-v3.40~32.orig => Battery.qml-v3.34.orig} | 0
...v3.40~32.patch => Battery.qml-v3.34.patch} | 4 +-
...Battery.qml-v3.40~35 => Battery.qml-v3.40} | 0
...qmlv3.40~35.orig => Battery.qmlv3.40.orig} | 0
.../MbItemDigitalInput.qml-v2.94.patch | 20 -
...-v3.40~35 => MbItemDigitalInput.qml-v3.40} | 0
...orig => MbItemDigitalInput.qml-v3.40.orig} | 0
...tch => MbItemDigitalInput.qml-v3.40.patch} | 4 +-
.../PatchSource/MbSpinBox.qml-v2.73.patch | 34 -
.../PatchSource/MbSpinBox.qml-v2.89.patch | 34 -
...inBox.qml-v3.40~35 => MbSpinBox.qml-v3.40} | 0
...v3.40~35.orig => MbSpinBox.qml-v3.40.orig} | 0
...ox.qml.patch => MbSpinBox.qml-v3.40.patch} | 4 +-
.../PatchSource/MbSpinBox.qml-v3.40~35.patch | 28 -
FileSets/PatchSource/MbStyle.qml-v2.94.patch | 43 -
...MbStyle.qml-v3.40~35 => MbStyle.qml-v3.40} | 0
...l-v3.40~35.orig => MbStyle.qml-v3.40.orig} | 0
...v3.40~35.patch => MbStyle.qml-v3.40.patch} | 4 +-
FileSets/PatchSource/PageMain.qml-v2.94.patch | 120 --
...geMain.qml-v3.40~13 => PageMain.qml-v3.34} | 0
...-v3.40~13.orig => PageMain.qml-v3.34.orig} | 0
...3.40~13.patch => PageMain.qml-v3.34.patch} | 4 +-
...geMain.qml-v3.40~35 => PageMain.qml-v3.40} | 0
...-v3.40~35.orig => PageMain.qml-v3.40.orig} | 0
...3.40~35.patch => PageMain.qml-v3.40.patch} | 4 +-
.../PageSettingsDisplay.qml-v2.89.patch | 55 -
.../PageSettingsDisplay.qml-v2.94.patch | 40 -
.../PageSettingsDisplay.qml-v3.01.patch | 58 -
...v3.40~35 => PageSettingsDisplay.qml-v3.40} | 0
...rig => PageSettingsDisplay.qml-v3.40.orig} | 0
...ch => PageSettingsDisplay.qml-v3.40.patch} | 4 +-
.../PageSettingsDisplay.qml-v3.40~35.patch | 24 -
.../PatchSource/attributes.csv-v2.94.patch | 5 -
...utes.csv-v3.40~35 => attributes.csv-v3.40} | 0
...3.40~35.orig => attributes.csv-v3.40.orig} | 0
...40~35.patch => attributes.csv-v3.40.patch} | 4 +-
.../dbus_systemcalc.py-v2.73.patch | 300 ----
.../dbus_systemcalc.py-v2.84.patch | 291 ---
.../dbus_systemcalc.py-v2.89.patch | 385 ----
.../dbus_systemcalc.py-v2.94.patch | 384 ----
...lc.py-v3.40~2 => dbus_systemcalc.py-v3.34} | 0
...0~2.orig => dbus_systemcalc.py-v3.34.orig} | 0
...2.patch => dbus_systemcalc.py-v3.34.patch} | 4 +-
...c.py-v3.40~35 => dbus_systemcalc.py-v3.40} | 0
...~35.orig => dbus_systemcalc.py-v3.40.orig} | 0
...5.patch => dbus_systemcalc.py-v3.40.patch} | 4 +-
.../dbus_systemcalc.py-v3.40~10.patch | 392 ----
.../dbus_systemcalc.py-v3.40~15.patch | 569 ------
FileSets/PatchSource/main.qml-v2.94.patch | 470 -----
.../{main.qml-v3.40~13 => main.qml-v3.34} | 0
....qml-v3.40~13.orig => main.qml-v3.34.orig} | 0
...ml-v3.40~13.patch => main.qml-v3.34.patch} | 4 +-
.../{main.qml-v3.40~35 => main.qml-v3.40} | 0
....qml-v3.40~35.orig => main.qml-v3.40.orig} | 0
...ml-v3.40~35.patch => main.qml-v3.40.patch} | 4 +-
.../MbItemDigitalInput.qml-v2.94 | 0
.../MbItemDigitalInput.qml-v2.94.orig | 0
.../{ => obsoletePatches}/MbSpinBox.qml-v2.73 | 0
.../MbSpinBox.qml-v2.73.orig | 0
.../{ => obsoletePatches}/MbSpinBox.qml-v2.89 | 0
.../MbSpinBox.qml-v2.89.orig | 0
.../{ => obsoletePatches}/MbStyle.qml-v2.94 | 0
.../MbStyle.qml-v2.94.orig | 0
.../{ => obsoletePatches}/PageMain.qml-v2.94 | 0
.../PageMain.qml-v2.94.orig | 0
.../PageSettingsDisplay.qml-v2.89 | 0
.../PageSettingsDisplay.qml-v2.89.orig | 0
.../PageSettingsDisplay.qml-v2.94 | 0
.../PageSettingsDisplay.qml-v2.94.orig | 0
.../PageSettingsDisplay.qml-v3.01 | 0
.../PageSettingsDisplay.qml-v3.01.orig | 0
.../PageSettingsDisplay.qml-v3.40~8 | 0
.../PageSettingsDisplay.qml-v3.40~8.orig | 0
.../attributes.csv-v2.94 | 0
.../attributes.csv-v2.94.orig | 0
.../dbus_systemcalc.py-v2.73 | 0
.../dbus_systemcalc.py-v2.73.orig | 0
.../dbus_systemcalc.py-v2.84 | 0
.../dbus_systemcalc.py-v2.84.orig | 0
.../dbus_systemcalc.py-v2.89 | 0
.../dbus_systemcalc.py-v2.89.orig | 0
.../dbus_systemcalc.py-v2.94 | 0
.../dbus_systemcalc.py-v2.94.orig | 0
.../dbus_systemcalc.py-v3.40~10.orig | 0
.../dbus_systemcalc.py-v3.40~15 | 0
.../dbus_systemcalc.py-v3.40~15.orig | 0
.../{ => obsoletePatches}/main.qml-v2.94 | 0
.../{ => obsoletePatches}/main.qml-v2.94.orig | 0
FileSets/v2.71/Battery.qml | 1 -
FileSets/v2.71/DetailAcInput.qml | 1 -
FileSets/v2.71/DetailInverter.qml | 1 -
FileSets/v2.71/DetailLoadsCombined.qml | 1 -
FileSets/v2.71/DetailLoadsOnInput.qml | 1 -
FileSets/v2.71/DetailLoadsOnOutput.qml | 1 -
FileSets/v2.71/HubData.qml | 1 -
FileSets/v2.71/LINKS_ONLY | 0
FileSets/v2.71/MbEditBox.qml | 1 -
FileSets/v2.71/MbEditBoxDateTime.qml | 1 -
FileSets/v2.71/MbItem.qml | 1 -
FileSets/v2.71/MbItemDigitalInput.qml | 1 -
FileSets/v2.71/MbSpinBox.qml | 1 -
FileSets/v2.71/MbStyle.qml | 1 -
FileSets/v2.71/MbSubMenu.qml | 1 -
FileSets/v2.71/Multi.qml | 1 -
FileSets/v2.71/ObjectAcConnection.qml | 1 -
FileSets/v2.71/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v2.71/OverviewBox.qml | 1 -
FileSets/v2.71/OverviewConnection.qml | 1 -
FileSets/v2.71/OverviewConnectionEnd.qml | 1 -
FileSets/v2.71/OverviewFlowComplex.qml | 1 -
FileSets/v2.71/OverviewGeneratorEnhanced.qml | 1 -
.../v2.71/OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v2.71/OverviewGridParallel.qml | 1 -
FileSets/v2.71/OverviewHub.qml | 1 -
FileSets/v2.71/OverviewHubEnhanced.qml | 1 -
FileSets/v2.71/OverviewMobileEnhanced.qml | 1 -
FileSets/v2.71/OverviewSolarCharger.qml | 1 -
FileSets/v2.71/OverviewSolarInverter.qml | 1 -
FileSets/v2.71/OverviewTankDelegate.qml | 1 -
FileSets/v2.71/OverviewTanks.qml | 1 -
.../v2.71/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v2.71/PageDigitalInput.qml | 1 -
FileSets/v2.71/PageGenerator.qml | 1 -
FileSets/v2.71/PageMain.qml | 1 -
FileSets/v2.71/PageSettingsDisplay.qml | 1 -
FileSets/v2.71/PageSettingsGenerator.qml | 1 -
FileSets/v2.71/PageSettingsGuiMods.qml | 1 -
FileSets/v2.71/PageSettingsRelay.qml | 1 -
FileSets/v2.71/PowerGauge.qml | 1 -
FileSets/v2.71/Tile.qml | 1 -
FileSets/v2.71/TileDigIn.qml | 1 -
FileSets/v2.71/TileRelay.qml | 1 -
FileSets/v2.71/TileText.qml | 1 -
FileSets/v2.71/attributes.csv | 1 -
FileSets/v2.71/dbus_digitalinputs.py | 1 -
FileSets/v2.71/dbus_generator.py | 1 -
FileSets/v2.71/dbus_systemcalc.py | 1 -
FileSets/v2.71/main.qml | 1 -
FileSets/v2.71/startstop.py | 1 -
FileSets/v2.71/styles.css | 1 -
FileSets/v2.72/Battery.qml | 1 -
FileSets/v2.72/COMPLETE | 0
FileSets/v2.72/DetailAcInput.qml | 1 -
FileSets/v2.72/DetailInverter.qml | 1 -
FileSets/v2.72/DetailLoadsCombined.qml | 1 -
FileSets/v2.72/DetailLoadsOnInput.qml | 1 -
FileSets/v2.72/DetailLoadsOnOutput.qml | 1 -
FileSets/v2.72/HubData.qml | 1 -
FileSets/v2.72/LINKS_ONLY | 0
FileSets/v2.72/MbEditBox.qml | 1 -
FileSets/v2.72/MbEditBoxDateTime.qml | 1 -
FileSets/v2.72/MbItem.qml | 1 -
FileSets/v2.72/MbItemDigitalInput.qml | 1 -
FileSets/v2.72/MbSpinBox.qml | 1 -
FileSets/v2.72/MbStyle.qml | 1 -
FileSets/v2.72/MbSubMenu.qml | 1 -
FileSets/v2.72/Multi.qml | 1 -
FileSets/v2.72/ObjectAcConnection.qml | 1 -
FileSets/v2.72/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v2.72/OverviewBox.qml | 1 -
FileSets/v2.72/OverviewConnection.qml | 1 -
FileSets/v2.72/OverviewConnectionEnd.qml | 1 -
FileSets/v2.72/OverviewFlowComplex.qml | 1 -
FileSets/v2.72/OverviewGeneratorEnhanced.qml | 1 -
.../v2.72/OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v2.72/OverviewGridParallel.qml | 1 -
FileSets/v2.72/OverviewHub.qml | 1 -
FileSets/v2.72/OverviewHubEnhanced.qml | 1 -
FileSets/v2.72/OverviewMobileEnhanced.qml | 1 -
FileSets/v2.72/OverviewSolarCharger.qml | 1 -
FileSets/v2.72/OverviewSolarInverter.qml | 1 -
FileSets/v2.72/OverviewTankDelegate.qml | 1 -
FileSets/v2.72/OverviewTanks.qml | 1 -
.../v2.72/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v2.72/PageDigitalInput.qml | 1 -
FileSets/v2.72/PageGenerator.qml | 1 -
FileSets/v2.72/PageMain.qml | 1 -
FileSets/v2.72/PageSettingsDisplay.qml | 1 -
FileSets/v2.72/PageSettingsGenerator.qml | 1 -
FileSets/v2.72/PageSettingsGuiMods.qml | 1 -
FileSets/v2.72/PageSettingsRelay.qml | 1 -
FileSets/v2.72/PowerGauge.qml | 1 -
FileSets/v2.72/Tile.qml | 1 -
FileSets/v2.72/TileDigIn.qml | 1 -
FileSets/v2.72/TileRelay.qml | 1 -
FileSets/v2.72/TileText.qml | 1 -
FileSets/v2.72/attributes.csv | 1 -
FileSets/v2.72/dbus_digitalinputs.py | 1 -
FileSets/v2.72/dbus_generator.py | 1 -
FileSets/v2.72/dbus_systemcalc.py | 1 -
FileSets/v2.72/main.qml | 1 -
FileSets/v2.72/startstop.py | 1 -
FileSets/v2.72/styles.css | 1 -
FileSets/v2.73/Battery.qml | 1 -
FileSets/v2.73/COMPLETE | 0
FileSets/v2.73/DetailAcInput.qml | 607 -------
FileSets/v2.73/DetailAcInput.qml.orig | 142 --
FileSets/v2.73/DetailInverter.qml | 556 ------
FileSets/v2.73/DetailInverter.qml.orig | 142 --
FileSets/v2.73/DetailLoadsCombined.qml | 147 --
FileSets/v2.73/DetailLoadsCombined.qml.orig | 142 --
FileSets/v2.73/DetailLoadsOnInput.qml | 147 --
FileSets/v2.73/DetailLoadsOnInput.qml.orig | 142 --
FileSets/v2.73/DetailLoadsOnOutput.qml | 152 --
FileSets/v2.73/DetailLoadsOnOutput.qml.orig | 142 --
FileSets/v2.73/HubData.qml | 224 ---
FileSets/v2.73/HubData.qml.orig | 142 --
FileSets/v2.73/MbEditBox.qml | 1 -
FileSets/v2.73/MbEditBoxDateTime.qml | 1 -
FileSets/v2.73/MbItem.qml | 1 -
FileSets/v2.73/MbItemDigitalInput.qml | 1 -
FileSets/v2.73/MbStyle.qml | 1 -
FileSets/v2.73/MbSubMenu.qml | 1 -
FileSets/v2.73/Multi.qml | 1 -
FileSets/v2.73/ObjectAcConnection.qml | 53 -
FileSets/v2.73/ObjectAcConnection.qml.orig | 26 -
FileSets/v2.73/OverviewAcValuesEnhanced.qml | 101 --
.../v2.73/OverviewAcValuesEnhanced.qml.orig | 37 -
FileSets/v2.73/OverviewBox.qml | 1 -
FileSets/v2.73/OverviewConnection.qml | 1 -
FileSets/v2.73/OverviewConnectionEnd.qml | 1 -
FileSets/v2.73/OverviewFlowComplex.qml | 1 -
FileSets/v2.73/OverviewGeneratorEnhanced.qml | 1 -
.../v2.73/OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v2.73/OverviewGridParallel.qml | 1 -
FileSets/v2.73/OverviewHub.qml | 322 ----
FileSets/v2.73/OverviewHub.qml.orig | 314 ----
FileSets/v2.73/OverviewHubEnhanced.qml | 1449 ---------------
FileSets/v2.73/OverviewHubEnhanced.qml.orig | 314 ----
FileSets/v2.73/OverviewMobileEnhanced.qml | 987 ----------
.../v2.73/OverviewMobileEnhanced.qml.orig | 642 -------
FileSets/v2.73/OverviewSolarCharger.qml | 1 -
FileSets/v2.73/OverviewSolarInverter.qml | 1 -
FileSets/v2.73/OverviewTankDelegate.qml | 1 -
FileSets/v2.73/OverviewTanks.qml | 1 -
.../OverviewTanksTempsDigInputs.qml.orig | 642 -------
FileSets/v2.73/PageDigitalInput.qml | 1 -
FileSets/v2.73/PageGenerator.qml | 1 -
FileSets/v2.73/PageSettingsDisplay.qml | 1 -
FileSets/v2.73/PageSettingsGenerator.qml | 1 -
FileSets/v2.73/PageSettingsGuiMods.qml | 270 ---
FileSets/v2.73/PageSettingsGuiMods.qml.orig | 311 ----
FileSets/v2.73/PageSettingsRelay.qml | 502 ------
FileSets/v2.73/PageSettingsRelay.qml.orig | 67 -
FileSets/v2.73/PowerGauge.qml | 319 ----
FileSets/v2.73/PowerGauge.qml.orig | 142 --
FileSets/v2.73/Tile.qml | 1 -
FileSets/v2.73/TileDigIn.qml | 131 --
FileSets/v2.73/TileDigIn.qml.orig | 537 ------
FileSets/v2.73/TileRelay.qml | 1 -
FileSets/v2.73/TileText.qml | 1 -
FileSets/v2.73/dbus_digitalinputs.py | 556 ------
FileSets/v2.73/dbus_digitalinputs.py.orig | 537 ------
FileSets/v2.73/dbus_generator.py | 350 ----
FileSets/v2.73/dbus_generator.py.orig | 329 ----
FileSets/v2.73/main.qml | 1 -
FileSets/v2.73/startstop.py | 1207 -------------
FileSets/v2.73/startstop.py.orig | 964 ----------
FileSets/v2.73/styles.css | 1 -
FileSets/v2.80/Battery.qml | 1 -
FileSets/v2.80/COMPLETE | 0
FileSets/v2.80/DetailAcInput.qml | 1 -
FileSets/v2.80/DetailInverter.qml | 1 -
FileSets/v2.80/DetailLoadsCombined.qml | 1 -
FileSets/v2.80/DetailLoadsOnInput.qml | 1 -
FileSets/v2.80/DetailLoadsOnOutput.qml | 1 -
FileSets/v2.80/HubData.qml | 1 -
FileSets/v2.80/LINKS_ONLY | 0
FileSets/v2.80/MbEditBox.qml | 1 -
FileSets/v2.80/MbEditBoxDateTime.qml | 1 -
FileSets/v2.80/MbItem.qml | 1 -
FileSets/v2.80/MbItemDigitalInput.qml | 1 -
FileSets/v2.80/MbSpinBox.qml | 1 -
FileSets/v2.80/MbStyle.qml | 1 -
FileSets/v2.80/MbSubMenu.qml | 1 -
FileSets/v2.80/Multi.qml | 1 -
FileSets/v2.80/ObjectAcConnection.qml | 1 -
FileSets/v2.80/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v2.80/OverviewBox.qml | 1 -
FileSets/v2.80/OverviewConnection.qml | 1 -
FileSets/v2.80/OverviewConnectionEnd.qml | 1 -
FileSets/v2.80/OverviewFlowComplex.qml | 1 -
FileSets/v2.80/OverviewGeneratorEnhanced.qml | 1 -
.../v2.80/OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v2.80/OverviewGridParallel.qml | 1 -
FileSets/v2.80/OverviewHub.qml | 1 -
FileSets/v2.80/OverviewHubEnhanced.qml | 1 -
FileSets/v2.80/OverviewMobileEnhanced.qml | 1 -
FileSets/v2.80/OverviewSolarCharger.qml | 1 -
FileSets/v2.80/OverviewSolarInverter.qml | 1 -
FileSets/v2.80/OverviewTankDelegate.qml | 1 -
FileSets/v2.80/OverviewTanks.qml | 1 -
.../v2.80/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v2.80/PageDigitalInput.qml | 1 -
FileSets/v2.80/PageGenerator.qml | 1 -
FileSets/v2.80/PageMain.qml | 1 -
FileSets/v2.80/PageSettingsDisplay.qml | 1 -
FileSets/v2.80/PageSettingsGenerator.qml | 1 -
FileSets/v2.80/PageSettingsGuiMods.qml | 1 -
FileSets/v2.80/PageSettingsRelay.qml | 1 -
FileSets/v2.80/PowerGauge.qml | 1 -
FileSets/v2.80/Tile.qml | 1 -
FileSets/v2.80/TileDigIn.qml | 1 -
FileSets/v2.80/TileRelay.qml | 1 -
FileSets/v2.80/TileText.qml | 1 -
FileSets/v2.80/attributes.csv | 1 -
FileSets/v2.80/dbus_digitalinputs.py | 1 -
FileSets/v2.80/dbus_generator.py | 1 -
FileSets/v2.80/dbus_systemcalc.py | 1 -
FileSets/v2.80/main.qml | 1 -
FileSets/v2.80/startstop.py | 1 -
FileSets/v2.80/styles.css | 1 -
FileSets/v2.81/Battery.qml | 1 -
FileSets/v2.81/COMPLETE | 0
FileSets/v2.81/DetailAcInput.qml | 1 -
FileSets/v2.81/DetailInverter.qml | 1 -
FileSets/v2.81/DetailLoadsCombined.qml | 1 -
FileSets/v2.81/DetailLoadsOnInput.qml | 1 -
FileSets/v2.81/DetailLoadsOnOutput.qml | 1 -
FileSets/v2.81/HubData.qml | 1 -
FileSets/v2.81/LINKS_ONLY | 0
FileSets/v2.81/MbEditBox.qml | 1 -
FileSets/v2.81/MbEditBoxDateTime.qml | 1 -
FileSets/v2.81/MbItem.qml | 1 -
FileSets/v2.81/MbItemDigitalInput.qml | 1 -
FileSets/v2.81/MbSpinBox.qml | 1 -
FileSets/v2.81/MbStyle.qml | 1 -
FileSets/v2.81/MbSubMenu.qml | 1 -
FileSets/v2.81/Multi.qml | 1 -
FileSets/v2.81/ObjectAcConnection.qml | 1 -
FileSets/v2.81/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v2.81/OverviewBox.qml | 1 -
FileSets/v2.81/OverviewConnection.qml | 1 -
FileSets/v2.81/OverviewConnectionEnd.qml | 1 -
FileSets/v2.81/OverviewFlowComplex.qml | 1 -
FileSets/v2.81/OverviewGeneratorEnhanced.qml | 1 -
.../v2.81/OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v2.81/OverviewGridParallel.qml | 1 -
FileSets/v2.81/OverviewHub.qml | 1 -
FileSets/v2.81/OverviewHubEnhanced.qml | 1 -
FileSets/v2.81/OverviewMobileEnhanced.qml | 1 -
FileSets/v2.81/OverviewSolarCharger.qml | 1 -
FileSets/v2.81/OverviewSolarInverter.qml | 1 -
FileSets/v2.81/OverviewTankDelegate.qml | 1 -
FileSets/v2.81/OverviewTanks.qml | 1 -
.../v2.81/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v2.81/PageDigitalInput.qml | 1 -
FileSets/v2.81/PageGenerator.qml | 1 -
FileSets/v2.81/PageMain.qml | 1 -
FileSets/v2.81/PageSettingsDisplay.qml | 1 -
FileSets/v2.81/PageSettingsGenerator.qml | 1 -
FileSets/v2.81/PageSettingsGuiMods.qml | 1 -
FileSets/v2.81/PageSettingsRelay.qml | 1 -
FileSets/v2.81/PowerGauge.qml | 1 -
FileSets/v2.81/Tile.qml | 1 -
FileSets/v2.81/TileDigIn.qml | 1 -
FileSets/v2.81/TileRelay.qml | 1 -
FileSets/v2.81/TileText.qml | 1 -
FileSets/v2.81/attributes.csv | 1 -
FileSets/v2.81/dbus_digitalinputs.py | 1 -
FileSets/v2.81/dbus_generator.py | 1 -
FileSets/v2.81/dbus_systemcalc.py | 1 -
FileSets/v2.81/main.qml | 1 -
FileSets/v2.81/startstop.py | 1 -
FileSets/v2.81/styles.css | 1 -
FileSets/v2.82/Battery.qml | 1 -
FileSets/v2.82/COMPLETE | 0
FileSets/v2.82/DetailAcInput.qml | 1 -
FileSets/v2.82/DetailInverter.qml | 1 -
FileSets/v2.82/DetailLoadsCombined.qml | 1 -
FileSets/v2.82/DetailLoadsOnInput.qml | 1 -
FileSets/v2.82/DetailLoadsOnOutput.qml | 1 -
FileSets/v2.82/HubData.qml | 1 -
FileSets/v2.82/LINKS_ONLY | 0
FileSets/v2.82/MbEditBox.qml | 1 -
FileSets/v2.82/MbEditBoxDateTime.qml | 1 -
FileSets/v2.82/MbItem.qml | 1 -
FileSets/v2.82/MbItemDigitalInput.qml | 1 -
FileSets/v2.82/MbSpinBox.qml | 1 -
FileSets/v2.82/MbStyle.qml | 1 -
FileSets/v2.82/MbSubMenu.qml | 1 -
FileSets/v2.82/Multi.qml | 1 -
FileSets/v2.82/ObjectAcConnection.qml | 1 -
FileSets/v2.82/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v2.82/OverviewBox.qml | 1 -
FileSets/v2.82/OverviewConnection.qml | 1 -
FileSets/v2.82/OverviewConnectionEnd.qml | 1 -
FileSets/v2.82/OverviewFlowComplex.qml | 1 -
FileSets/v2.82/OverviewGeneratorEnhanced.qml | 1 -
.../v2.82/OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v2.82/OverviewGridParallel.qml | 1 -
FileSets/v2.82/OverviewHub.qml | 1 -
FileSets/v2.82/OverviewHubEnhanced.qml | 1 -
FileSets/v2.82/OverviewMobileEnhanced.qml | 1 -
FileSets/v2.82/OverviewSolarCharger.qml | 1 -
FileSets/v2.82/OverviewSolarInverter.qml | 1 -
FileSets/v2.82/OverviewTankDelegate.qml | 1 -
FileSets/v2.82/OverviewTanks.qml | 1 -
.../v2.82/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v2.82/PageDigitalInput.qml | 1 -
FileSets/v2.82/PageGenerator.qml | 1 -
FileSets/v2.82/PageMain.qml | 1 -
FileSets/v2.82/PageSettingsDisplay.qml | 1 -
FileSets/v2.82/PageSettingsGenerator.qml | 1 -
FileSets/v2.82/PageSettingsGuiMods.qml | 1 -
FileSets/v2.82/PageSettingsRelay.qml | 1 -
FileSets/v2.82/PowerGauge.qml | 1 -
FileSets/v2.82/Tile.qml | 1 -
FileSets/v2.82/TileDigIn.qml | 1 -
FileSets/v2.82/TileRelay.qml | 1 -
FileSets/v2.82/TileText.qml | 1 -
FileSets/v2.82/attributes.csv | 1 -
FileSets/v2.82/dbus_digitalinputs.py | 1 -
FileSets/v2.82/dbus_generator.py | 1 -
FileSets/v2.82/dbus_systemcalc.py | 1 -
FileSets/v2.82/main.qml | 1 -
FileSets/v2.82/startstop.py | 1 -
FileSets/v2.82/styles.css | 1 -
FileSets/v2.83/Battery.qml | 1 -
FileSets/v2.83/COMPLETE | 0
FileSets/v2.83/DetailAcInput.qml | 1 -
FileSets/v2.83/DetailInverter.qml | 1 -
FileSets/v2.83/DetailLoadsCombined.qml | 1 -
FileSets/v2.83/DetailLoadsOnInput.qml | 1 -
FileSets/v2.83/DetailLoadsOnOutput.qml | 1 -
FileSets/v2.83/HubData.qml | 1 -
FileSets/v2.83/LINKS_ONLY | 0
FileSets/v2.83/MbEditBox.qml | 1 -
FileSets/v2.83/MbEditBoxDateTime.qml | 1 -
FileSets/v2.83/MbItem.qml | 1 -
FileSets/v2.83/MbItemDigitalInput.qml | 1 -
FileSets/v2.83/MbSpinBox.qml | 1 -
FileSets/v2.83/MbStyle.qml | 1 -
FileSets/v2.83/MbSubMenu.qml | 1 -
FileSets/v2.83/Multi.qml | 1 -
FileSets/v2.83/ObjectAcConnection.qml | 1 -
FileSets/v2.83/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v2.83/OverviewBox.qml | 1 -
FileSets/v2.83/OverviewConnection.qml | 1 -
FileSets/v2.83/OverviewConnectionEnd.qml | 1 -
FileSets/v2.83/OverviewFlowComplex.qml | 1 -
FileSets/v2.83/OverviewGeneratorEnhanced.qml | 1 -
.../v2.83/OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v2.83/OverviewGridParallel.qml | 1 -
FileSets/v2.83/OverviewHub.qml | 1 -
FileSets/v2.83/OverviewHubEnhanced.qml | 1 -
FileSets/v2.83/OverviewMobileEnhanced.qml | 1 -
FileSets/v2.83/OverviewSolarCharger.qml | 1 -
FileSets/v2.83/OverviewSolarInverter.qml | 1 -
FileSets/v2.83/OverviewTankDelegate.qml | 1 -
FileSets/v2.83/OverviewTanks.qml | 1 -
.../v2.83/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v2.83/PageDigitalInput.qml | 1 -
FileSets/v2.83/PageGenerator.qml | 1 -
FileSets/v2.83/PageMain.qml | 1 -
FileSets/v2.83/PageSettingsDisplay.qml | 1 -
FileSets/v2.83/PageSettingsGenerator.qml | 1 -
FileSets/v2.83/PageSettingsGuiMods.qml | 1 -
FileSets/v2.83/PageSettingsRelay.qml | 1 -
FileSets/v2.83/PowerGauge.qml | 1 -
FileSets/v2.83/Tile.qml | 1 -
FileSets/v2.83/TileDigIn.qml | 1 -
FileSets/v2.83/TileRelay.qml | 1 -
FileSets/v2.83/TileText.qml | 1 -
FileSets/v2.83/attributes.csv | 1 -
FileSets/v2.83/dbus_digitalinputs.py | 1 -
FileSets/v2.83/dbus_generator.py | 1 -
FileSets/v2.83/dbus_systemcalc.py | 1 -
FileSets/v2.83/main.qml | 1 -
FileSets/v2.83/startstop.py | 1 -
FileSets/v2.83/styles.css | 1 -
FileSets/v2.84/Battery.qml | 1 -
FileSets/v2.84/COMPLETE | 0
FileSets/v2.84/DetailAcInput.qml | 1 -
FileSets/v2.84/DetailInverter.qml | 1 -
FileSets/v2.84/DetailLoadsCombined.qml | 1 -
FileSets/v2.84/DetailLoadsOnInput.qml | 1 -
FileSets/v2.84/DetailLoadsOnOutput.qml | 1 -
FileSets/v2.84/HubData.qml | 1 -
FileSets/v2.84/LINKS_ONLY | 0
FileSets/v2.84/MbEditBox.qml | 1 -
FileSets/v2.84/MbEditBoxDateTime.qml | 1 -
FileSets/v2.84/MbItem.qml | 1 -
FileSets/v2.84/MbItemDigitalInput.qml | 1 -
FileSets/v2.84/MbSpinBox.qml | 1 -
FileSets/v2.84/MbStyle.qml | 1 -
FileSets/v2.84/MbSubMenu.qml | 1 -
FileSets/v2.84/Multi.qml | 1 -
FileSets/v2.84/ObjectAcConnection.qml | 1 -
FileSets/v2.84/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v2.84/OverviewBox.qml | 1 -
FileSets/v2.84/OverviewConnection.qml | 1 -
FileSets/v2.84/OverviewConnectionEnd.qml | 1 -
FileSets/v2.84/OverviewFlowComplex.qml | 1 -
FileSets/v2.84/OverviewGeneratorEnhanced.qml | 1 -
.../v2.84/OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v2.84/OverviewGridParallel.qml | 1 -
FileSets/v2.84/OverviewHub.qml | 1 -
FileSets/v2.84/OverviewHubEnhanced.qml | 1 -
FileSets/v2.84/OverviewMobileEnhanced.qml | 1 -
FileSets/v2.84/OverviewSolarCharger.qml | 1 -
FileSets/v2.84/OverviewSolarInverter.qml | 1 -
FileSets/v2.84/OverviewTankDelegate.qml | 1 -
FileSets/v2.84/OverviewTanks.qml | 1 -
.../v2.84/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v2.84/PageDigitalInput.qml | 1 -
FileSets/v2.84/PageGenerator.qml | 1 -
FileSets/v2.84/PageMain.qml | 1 -
FileSets/v2.84/PageSettingsDisplay.qml | 1 -
FileSets/v2.84/PageSettingsGenerator.qml | 1 -
FileSets/v2.84/PageSettingsGuiMods.qml | 1 -
FileSets/v2.84/PageSettingsRelay.qml | 1 -
FileSets/v2.84/PowerGauge.qml | 1 -
FileSets/v2.84/Tile.qml | 1 -
FileSets/v2.84/TileDigIn.qml | 1 -
FileSets/v2.84/TileRelay.qml | 1 -
FileSets/v2.84/TileText.qml | 1 -
FileSets/v2.84/attributes.csv | 1 -
FileSets/v2.84/dbus_digitalinputs.py | 1 -
FileSets/v2.84/dbus_generator.py | 1 -
FileSets/v2.84/main.qml | 1 -
FileSets/v2.84/startstop.py | 1 -
FileSets/v2.84/styles.css | 1 -
FileSets/v2.85/Battery.qml | 1 -
FileSets/v2.85/COMPLETE | 0
FileSets/v2.85/DetailAcInput.qml | 1 -
FileSets/v2.85/DetailInverter.qml | 1 -
FileSets/v2.85/DetailLoadsCombined.qml | 1 -
FileSets/v2.85/DetailLoadsOnInput.qml | 1 -
FileSets/v2.85/DetailLoadsOnOutput.qml | 1 -
FileSets/v2.85/HubData.qml | 1 -
FileSets/v2.85/LINKS_ONLY | 0
FileSets/v2.85/MbEditBox.qml | 1 -
FileSets/v2.85/MbEditBoxDateTime.qml | 1 -
FileSets/v2.85/MbItem.qml | 1 -
FileSets/v2.85/MbItemDigitalInput.qml | 1 -
FileSets/v2.85/MbSpinBox.qml | 1 -
FileSets/v2.85/MbStyle.qml | 1 -
FileSets/v2.85/MbSubMenu.qml | 1 -
FileSets/v2.85/Multi.qml | 1 -
FileSets/v2.85/ObjectAcConnection.qml | 1 -
FileSets/v2.85/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v2.85/OverviewBox.qml | 1 -
FileSets/v2.85/OverviewConnection.qml | 1 -
FileSets/v2.85/OverviewConnectionEnd.qml | 1 -
FileSets/v2.85/OverviewFlowComplex.qml | 1 -
FileSets/v2.85/OverviewGeneratorEnhanced.qml | 1 -
.../v2.85/OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v2.85/OverviewGridParallel.qml | 1 -
FileSets/v2.85/OverviewHub.qml | 1 -
FileSets/v2.85/OverviewHubEnhanced.qml | 1 -
FileSets/v2.85/OverviewMobileEnhanced.qml | 1 -
FileSets/v2.85/OverviewSolarCharger.qml | 1 -
FileSets/v2.85/OverviewSolarInverter.qml | 1 -
FileSets/v2.85/OverviewTankDelegate.qml | 1 -
FileSets/v2.85/OverviewTanks.qml | 1 -
.../v2.85/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v2.85/PageDigitalInput.qml | 1 -
FileSets/v2.85/PageGenerator.qml | 1 -
FileSets/v2.85/PageMain.qml | 1 -
FileSets/v2.85/PageSettingsDisplay.qml | 1 -
FileSets/v2.85/PageSettingsGenerator.qml | 1 -
FileSets/v2.85/PageSettingsGuiMods.qml | 1 -
FileSets/v2.85/PageSettingsRelay.qml | 1 -
FileSets/v2.85/PowerGauge.qml | 1 -
FileSets/v2.85/Tile.qml | 1 -
FileSets/v2.85/TileDigIn.qml | 1 -
FileSets/v2.85/TileRelay.qml | 1 -
FileSets/v2.85/TileText.qml | 1 -
FileSets/v2.85/attributes.csv | 1 -
FileSets/v2.85/dbus_digitalinputs.py | 1 -
FileSets/v2.85/dbus_generator.py | 1 -
FileSets/v2.85/dbus_systemcalc.py | 1 -
FileSets/v2.85/main.qml | 1 -
FileSets/v2.85/startstop.py | 1 -
FileSets/v2.85/styles.css | 1 -
FileSets/v2.86/Battery.qml | 1 -
FileSets/v2.86/COMPLETE | 0
FileSets/v2.86/DetailAcInput.qml | 1 -
FileSets/v2.86/DetailInverter.qml | 1 -
FileSets/v2.86/DetailLoadsCombined.qml | 1 -
FileSets/v2.86/DetailLoadsOnInput.qml | 1 -
FileSets/v2.86/DetailLoadsOnOutput.qml | 1 -
FileSets/v2.86/HubData.qml | 1 -
FileSets/v2.86/LINKS_ONLY | 0
FileSets/v2.86/MbEditBox.qml | 1 -
FileSets/v2.86/MbEditBoxDateTime.qml | 1 -
FileSets/v2.86/MbItem.qml | 1 -
FileSets/v2.86/MbItemDigitalInput.qml | 1 -
FileSets/v2.86/MbSpinBox.qml | 1 -
FileSets/v2.86/MbStyle.qml | 1 -
FileSets/v2.86/MbSubMenu.qml | 1 -
FileSets/v2.86/Multi.qml | 1 -
FileSets/v2.86/ObjectAcConnection.qml | 1 -
FileSets/v2.86/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v2.86/OverviewBox.qml | 1 -
FileSets/v2.86/OverviewConnection.qml | 1 -
FileSets/v2.86/OverviewConnectionEnd.qml | 1 -
FileSets/v2.86/OverviewFlowComplex.qml | 1 -
FileSets/v2.86/OverviewGeneratorEnhanced.qml | 1 -
.../v2.86/OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v2.86/OverviewGridParallel.qml | 1 -
FileSets/v2.86/OverviewHub.qml | 1 -
FileSets/v2.86/OverviewHubEnhanced.qml | 1 -
FileSets/v2.86/OverviewMobileEnhanced.qml | 1 -
FileSets/v2.86/OverviewSolarCharger.qml | 1 -
FileSets/v2.86/OverviewSolarInverter.qml | 1 -
FileSets/v2.86/OverviewTankDelegate.qml | 1 -
FileSets/v2.86/OverviewTanks.qml | 1 -
.../v2.86/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v2.86/PageDigitalInput.qml | 1 -
FileSets/v2.86/PageGenerator.qml | 1 -
FileSets/v2.86/PageMain.qml | 1 -
FileSets/v2.86/PageSettingsDisplay.qml | 1 -
FileSets/v2.86/PageSettingsGenerator.qml | 1 -
FileSets/v2.86/PageSettingsGuiMods.qml | 1 -
FileSets/v2.86/PageSettingsRelay.qml | 1 -
FileSets/v2.86/PowerGauge.qml | 1 -
FileSets/v2.86/Tile.qml | 1 -
FileSets/v2.86/TileDigIn.qml | 1 -
FileSets/v2.86/TileRelay.qml | 1 -
FileSets/v2.86/TileText.qml | 1 -
FileSets/v2.86/attributes.csv | 1 -
FileSets/v2.86/dbus_digitalinputs.py | 1 -
FileSets/v2.86/dbus_generator.py | 1 -
FileSets/v2.86/dbus_systemcalc.py | 1 -
FileSets/v2.86/main.qml | 1 -
FileSets/v2.86/startstop.py | 1 -
FileSets/v2.86/styles.css | 1 -
FileSets/v2.87/Battery.qml | 1 -
FileSets/v2.87/COMPLETE | 0
FileSets/v2.87/DetailAcInput.qml | 1 -
FileSets/v2.87/DetailInverter.qml | 1 -
FileSets/v2.87/DetailLoadsCombined.qml | 1 -
FileSets/v2.87/DetailLoadsOnInput.qml | 1 -
FileSets/v2.87/DetailLoadsOnOutput.qml | 1 -
FileSets/v2.87/HubData.qml | 1 -
FileSets/v2.87/LINKS_ONLY | 0
FileSets/v2.87/MbEditBox.qml | 1 -
FileSets/v2.87/MbEditBoxDateTime.qml | 1 -
FileSets/v2.87/MbItem.qml | 1 -
FileSets/v2.87/MbItemDigitalInput.qml | 1 -
FileSets/v2.87/MbSpinBox.qml | 1 -
FileSets/v2.87/MbStyle.qml | 1 -
FileSets/v2.87/MbSubMenu.qml | 1 -
FileSets/v2.87/Multi.qml | 1 -
FileSets/v2.87/ObjectAcConnection.qml | 1 -
FileSets/v2.87/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v2.87/OverviewBox.qml | 1 -
FileSets/v2.87/OverviewConnection.qml | 1 -
FileSets/v2.87/OverviewConnectionEnd.qml | 1 -
FileSets/v2.87/OverviewFlowComplex.qml | 1 -
FileSets/v2.87/OverviewGeneratorEnhanced.qml | 1 -
.../v2.87/OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v2.87/OverviewGridParallel.qml | 1 -
FileSets/v2.87/OverviewHub.qml | 1 -
FileSets/v2.87/OverviewHubEnhanced.qml | 1 -
FileSets/v2.87/OverviewMobileEnhanced.qml | 1 -
FileSets/v2.87/OverviewSolarCharger.qml | 1 -
FileSets/v2.87/OverviewSolarInverter.qml | 1 -
FileSets/v2.87/OverviewTankDelegate.qml | 1 -
FileSets/v2.87/OverviewTanks.qml | 1 -
.../v2.87/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v2.87/PageDigitalInput.qml | 1 -
FileSets/v2.87/PageGenerator.qml | 1 -
FileSets/v2.87/PageMain.qml | 1 -
FileSets/v2.87/PageSettingsDisplay.qml | 1 -
FileSets/v2.87/PageSettingsGenerator.qml | 1 -
FileSets/v2.87/PageSettingsGuiMods.qml | 1 -
FileSets/v2.87/PageSettingsRelay.qml | 1 -
FileSets/v2.87/PowerGauge.qml | 1 -
FileSets/v2.87/Tile.qml | 1 -
FileSets/v2.87/TileDigIn.qml | 1 -
FileSets/v2.87/TileRelay.qml | 1 -
FileSets/v2.87/TileText.qml | 1 -
FileSets/v2.87/attributes.csv | 1 -
FileSets/v2.87/dbus_digitalinputs.py | 1 -
FileSets/v2.87/dbus_generator.py | 1 -
FileSets/v2.87/dbus_systemcalc.py | 1 -
FileSets/v2.87/main.qml | 1 -
FileSets/v2.87/startstop.py | 1 -
FileSets/v2.87/styles.css | 1 -
FileSets/v2.89/Battery.qml | 1 -
FileSets/v2.89/COMPLETE | 0
FileSets/v2.89/DetailAcInput.qml | 1 -
FileSets/v2.89/DetailInverter.qml | 1 -
FileSets/v2.89/DetailLoadsCombined.qml | 1 -
FileSets/v2.89/DetailLoadsOnInput.qml | 1 -
FileSets/v2.89/DetailLoadsOnOutput.qml | 1 -
FileSets/v2.89/HubData.qml | 1 -
FileSets/v2.89/MbEditBox.qml | 1 -
FileSets/v2.89/MbEditBoxDateTime.qml | 1 -
FileSets/v2.89/MbItem.qml | 1 -
FileSets/v2.89/MbItemDigitalInput.qml | 1 -
FileSets/v2.89/MbStyle.qml | 1 -
FileSets/v2.89/MbSubMenu.qml | 1 -
FileSets/v2.89/Multi.qml | 1 -
FileSets/v2.89/ObjectAcConnection.qml | 1 -
FileSets/v2.89/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v2.89/OverviewBox.qml | 1 -
FileSets/v2.89/OverviewConnection.qml | 1 -
FileSets/v2.89/OverviewConnectionEnd.qml | 1 -
FileSets/v2.89/OverviewFlowComplex.qml | 1 -
FileSets/v2.89/OverviewGeneratorEnhanced.qml | 1 -
.../v2.89/OverviewGeneratorRelayEnhanced.qml | 8 -
.../OverviewGeneratorRelayEnhanced.qml.orig | 8 -
FileSets/v2.89/OverviewGridParallel.qml | 1 -
FileSets/v2.89/OverviewHub.qml | 1 -
FileSets/v2.89/OverviewHubEnhanced.qml | 1 -
FileSets/v2.89/OverviewMobileEnhanced.qml | 987 ----------
.../v2.89/OverviewMobileEnhanced.qml.orig | 637 -------
FileSets/v2.89/OverviewSolarCharger.qml | 1 -
FileSets/v2.89/OverviewSolarInverter.qml | 1 -
FileSets/v2.89/OverviewTankDelegate.qml | 1 -
FileSets/v2.89/OverviewTanks.qml | 1 -
.../v2.89/OverviewTanksTempsDigInputs.qml | 208 ---
.../OverviewTanksTempsDigInputs.qml.orig | 637 -------
FileSets/v2.89/PageDigitalInput.qml | 1 -
FileSets/v2.89/PageGenerator.qml | 1 -
FileSets/v2.89/PageSettingsGenerator.qml | 189 --
FileSets/v2.89/PageSettingsGenerator.qml.orig | 133 --
FileSets/v2.89/PageSettingsGuiMods.qml | 274 ---
FileSets/v2.89/PageSettingsGuiMods.qml.orig | 312 ----
FileSets/v2.89/PageSettingsRelay.qml | 1 -
FileSets/v2.89/PowerGauge.qml | 1 -
FileSets/v2.89/Tile.qml | 1 -
FileSets/v2.89/TileDigIn.qml | 131 --
FileSets/v2.89/TileDigIn.qml.orig | 534 ------
FileSets/v2.89/TileRelay.qml | 507 ------
FileSets/v2.89/TileRelay.qml.orig | 23 -
FileSets/v2.89/TileText.qml | 1 -
FileSets/v2.89/dbus_digitalinputs.py | 553 ------
FileSets/v2.89/dbus_digitalinputs.py.orig | 534 ------
FileSets/v2.89/dbus_generator.py | 351 ----
FileSets/v2.89/dbus_generator.py.orig | 330 ----
FileSets/v2.89/startstop.py | 1207 -------------
FileSets/v2.89/startstop.py.orig | 970 ----------
FileSets/v2.89/styles.css | 1 -
FileSets/v2.90/Battery.qml | 1 -
FileSets/v2.90/COMPLETE | 0
FileSets/v2.90/DetailAcInput.qml | 1 -
FileSets/v2.90/DetailInverter.qml | 1 -
FileSets/v2.90/DetailLoadsCombined.qml | 1 -
FileSets/v2.90/DetailLoadsOnInput.qml | 1 -
FileSets/v2.90/DetailLoadsOnOutput.qml | 1 -
FileSets/v2.90/HubData.qml | 1 -
FileSets/v2.90/LINKS_ONLY | 0
FileSets/v2.90/MbEditBox.qml | 1 -
FileSets/v2.90/MbEditBoxDateTime.qml | 1 -
FileSets/v2.90/MbItem.qml | 1 -
FileSets/v2.90/MbItemDigitalInput.qml | 1 -
FileSets/v2.90/MbSpinBox.qml | 1 -
FileSets/v2.90/MbStyle.qml | 1 -
FileSets/v2.90/MbSubMenu.qml | 1 -
FileSets/v2.90/Multi.qml | 1 -
FileSets/v2.90/ObjectAcConnection.qml | 1 -
FileSets/v2.90/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v2.90/OverviewBox.qml | 1 -
FileSets/v2.90/OverviewConnection.qml | 1 -
FileSets/v2.90/OverviewConnectionEnd.qml | 1 -
FileSets/v2.90/OverviewFlowComplex.qml | 1 -
FileSets/v2.90/OverviewGeneratorEnhanced.qml | 1 -
.../v2.90/OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v2.90/OverviewGridParallel.qml | 1 -
FileSets/v2.90/OverviewHub.qml | 1 -
FileSets/v2.90/OverviewHubEnhanced.qml | 1 -
FileSets/v2.90/OverviewMobileEnhanced.qml | 1 -
FileSets/v2.90/OverviewSolarCharger.qml | 1 -
FileSets/v2.90/OverviewSolarInverter.qml | 1 -
FileSets/v2.90/OverviewTankDelegate.qml | 1 -
FileSets/v2.90/OverviewTanks.qml | 1 -
.../v2.90/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v2.90/PageDigitalInput.qml | 1 -
FileSets/v2.90/PageGenerator.qml | 1 -
FileSets/v2.90/PageMain.qml | 1 -
FileSets/v2.90/PageSettingsDisplay.qml | 1 -
FileSets/v2.90/PageSettingsGenerator.qml | 1 -
FileSets/v2.90/PageSettingsGuiMods.qml | 1 -
FileSets/v2.90/PageSettingsRelay.qml | 1 -
FileSets/v2.90/PowerGauge.qml | 1 -
FileSets/v2.90/Tile.qml | 1 -
FileSets/v2.90/TileDigIn.qml | 1 -
FileSets/v2.90/TileRelay.qml | 1 -
FileSets/v2.90/TileText.qml | 1 -
FileSets/v2.90/attributes.csv | 1 -
FileSets/v2.90/dbus_digitalinputs.py | 1 -
FileSets/v2.90/dbus_generator.py | 1 -
FileSets/v2.90/dbus_systemcalc.py | 1 -
FileSets/v2.90/main.qml | 1 -
FileSets/v2.90/startstop.py | 1 -
FileSets/v2.90/styles.css | 1 -
FileSets/v2.91/Battery.qml | 1 -
FileSets/v2.91/COMPLETE | 0
FileSets/v2.91/DetailAcInput.qml | 1 -
FileSets/v2.91/DetailInverter.qml | 1 -
FileSets/v2.91/DetailLoadsCombined.qml | 1 -
FileSets/v2.91/DetailLoadsOnInput.qml | 1 -
FileSets/v2.91/DetailLoadsOnOutput.qml | 1 -
FileSets/v2.91/HubData.qml | 1 -
FileSets/v2.91/LINKS_ONLY | 0
FileSets/v2.91/MbEditBox.qml | 1 -
FileSets/v2.91/MbEditBoxDateTime.qml | 1 -
FileSets/v2.91/MbItem.qml | 1 -
FileSets/v2.91/MbItemDigitalInput.qml | 1 -
FileSets/v2.91/MbSpinBox.qml | 1 -
FileSets/v2.91/MbStyle.qml | 1 -
FileSets/v2.91/MbSubMenu.qml | 1 -
FileSets/v2.91/Multi.qml | 1 -
FileSets/v2.91/ObjectAcConnection.qml | 1 -
FileSets/v2.91/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v2.91/OverviewBox.qml | 1 -
FileSets/v2.91/OverviewConnection.qml | 1 -
FileSets/v2.91/OverviewConnectionEnd.qml | 1 -
FileSets/v2.91/OverviewFlowComplex.qml | 1 -
FileSets/v2.91/OverviewGeneratorEnhanced.qml | 1 -
.../v2.91/OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v2.91/OverviewGridParallel.qml | 1 -
FileSets/v2.91/OverviewHub.qml | 1 -
FileSets/v2.91/OverviewHubEnhanced.qml | 1 -
FileSets/v2.91/OverviewMobileEnhanced.qml | 1 -
FileSets/v2.91/OverviewSolarCharger.qml | 1 -
FileSets/v2.91/OverviewSolarInverter.qml | 1 -
FileSets/v2.91/OverviewTankDelegate.qml | 1 -
FileSets/v2.91/OverviewTanks.qml | 1 -
.../v2.91/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v2.91/PageDigitalInput.qml | 1 -
FileSets/v2.91/PageGenerator.qml | 1 -
FileSets/v2.91/PageMain.qml | 1 -
FileSets/v2.91/PageSettingsDisplay.qml | 1 -
FileSets/v2.91/PageSettingsGenerator.qml | 1 -
FileSets/v2.91/PageSettingsGuiMods.qml | 1 -
FileSets/v2.91/PageSettingsRelay.qml | 1 -
FileSets/v2.91/PowerGauge.qml | 1 -
FileSets/v2.91/Tile.qml | 1 -
FileSets/v2.91/TileDigIn.qml | 1 -
FileSets/v2.91/TileRelay.qml | 1 -
FileSets/v2.91/TileText.qml | 1 -
FileSets/v2.91/attributes.csv | 1 -
FileSets/v2.91/dbus_digitalinputs.py | 1 -
FileSets/v2.91/dbus_generator.py | 1 -
FileSets/v2.91/dbus_systemcalc.py | 1 -
FileSets/v2.91/main.qml | 1 -
FileSets/v2.91/startstop.py | 1 -
FileSets/v2.91/styles.css | 1 -
FileSets/v2.92/Battery.qml | 1 -
FileSets/v2.92/COMPLETE | 0
FileSets/v2.92/DetailAcInput.qml | 1 -
FileSets/v2.92/DetailInverter.qml | 1 -
FileSets/v2.92/DetailLoadsCombined.qml | 1 -
FileSets/v2.92/DetailLoadsOnInput.qml | 1 -
FileSets/v2.92/DetailLoadsOnOutput.qml | 1 -
FileSets/v2.92/HubData.qml | 1 -
FileSets/v2.92/LINKS_ONLY | 0
FileSets/v2.92/MbEditBox.qml | 1 -
FileSets/v2.92/MbEditBoxDateTime.qml | 1 -
FileSets/v2.92/MbItem.qml | 1 -
FileSets/v2.92/MbItemDigitalInput.qml | 1 -
FileSets/v2.92/MbSpinBox.qml | 1 -
FileSets/v2.92/MbStyle.qml | 1 -
FileSets/v2.92/MbSubMenu.qml | 1 -
FileSets/v2.92/Multi.qml | 1 -
FileSets/v2.92/ObjectAcConnection.qml | 1 -
FileSets/v2.92/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v2.92/OverviewBox.qml | 1 -
FileSets/v2.92/OverviewConnection.qml | 1 -
FileSets/v2.92/OverviewConnectionEnd.qml | 1 -
FileSets/v2.92/OverviewFlowComplex.qml | 1 -
FileSets/v2.92/OverviewGeneratorEnhanced.qml | 1 -
.../v2.92/OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v2.92/OverviewGridParallel.qml | 1 -
FileSets/v2.92/OverviewHub.qml | 1 -
FileSets/v2.92/OverviewHubEnhanced.qml | 1 -
FileSets/v2.92/OverviewMobileEnhanced.qml | 1 -
FileSets/v2.92/OverviewSolarCharger.qml | 1 -
FileSets/v2.92/OverviewSolarInverter.qml | 1 -
FileSets/v2.92/OverviewTankDelegate.qml | 1 -
FileSets/v2.92/OverviewTanks.qml | 1 -
.../v2.92/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v2.92/PageDigitalInput.qml | 1 -
FileSets/v2.92/PageGenerator.qml | 1 -
FileSets/v2.92/PageMain.qml | 1 -
FileSets/v2.92/PageSettingsDisplay.qml | 1 -
FileSets/v2.92/PageSettingsGenerator.qml | 1 -
FileSets/v2.92/PageSettingsGuiMods.qml | 1 -
FileSets/v2.92/PageSettingsRelay.qml | 1 -
FileSets/v2.92/PowerGauge.qml | 1 -
FileSets/v2.92/Tile.qml | 1 -
FileSets/v2.92/TileDigIn.qml | 1 -
FileSets/v2.92/TileRelay.qml | 1 -
FileSets/v2.92/TileText.qml | 1 -
FileSets/v2.92/attributes.csv | 1 -
FileSets/v2.92/dbus_digitalinputs.py | 1 -
FileSets/v2.92/dbus_generator.py | 1 -
FileSets/v2.92/main.qml | 1 -
FileSets/v2.92/startstop.py | 1 -
FileSets/v2.92/styles.css | 1 -
FileSets/v2.93/Battery.qml | 1 -
FileSets/v2.93/COMPLETE | 0
FileSets/v2.93/DetailAcInput.qml | 1 -
FileSets/v2.93/DetailInverter.qml | 1 -
FileSets/v2.93/DetailLoadsCombined.qml | 1 -
FileSets/v2.93/DetailLoadsOnInput.qml | 1 -
FileSets/v2.93/DetailLoadsOnOutput.qml | 1 -
FileSets/v2.93/HubData.qml | 1 -
FileSets/v2.93/LINKS_ONLY | 0
FileSets/v2.93/MbEditBox.qml | 1 -
FileSets/v2.93/MbEditBoxDateTime.qml | 1 -
FileSets/v2.93/MbItem.qml | 1 -
FileSets/v2.93/MbItemDigitalInput.qml | 1 -
FileSets/v2.93/MbSpinBox.qml | 1 -
FileSets/v2.93/MbStyle.qml | 1 -
FileSets/v2.93/MbSubMenu.qml | 1 -
FileSets/v2.93/Multi.qml | 1 -
FileSets/v2.93/ObjectAcConnection.qml | 1 -
FileSets/v2.93/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v2.93/OverviewBox.qml | 1 -
FileSets/v2.93/OverviewConnection.qml | 1 -
FileSets/v2.93/OverviewConnectionEnd.qml | 1 -
FileSets/v2.93/OverviewFlowComplex.qml | 1 -
FileSets/v2.93/OverviewGeneratorEnhanced.qml | 1 -
.../v2.93/OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v2.93/OverviewGridParallel.qml | 1 -
FileSets/v2.93/OverviewHub.qml | 1 -
FileSets/v2.93/OverviewHubEnhanced.qml | 1 -
FileSets/v2.93/OverviewMobileEnhanced.qml | 1 -
FileSets/v2.93/OverviewSolarCharger.qml | 1 -
FileSets/v2.93/OverviewSolarInverter.qml | 1 -
FileSets/v2.93/OverviewTankDelegate.qml | 1 -
FileSets/v2.93/OverviewTanks.qml | 1 -
.../v2.93/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v2.93/PageDigitalInput.qml | 1 -
FileSets/v2.93/PageGenerator.qml | 1 -
FileSets/v2.93/PageMain.qml | 1 -
FileSets/v2.93/PageSettingsDisplay.qml | 1 -
FileSets/v2.93/PageSettingsGenerator.qml | 1 -
FileSets/v2.93/PageSettingsGuiMods.qml | 1 -
FileSets/v2.93/PageSettingsRelay.qml | 1 -
FileSets/v2.93/PowerGauge.qml | 1 -
FileSets/v2.93/Tile.qml | 1 -
FileSets/v2.93/TileDigIn.qml | 1 -
FileSets/v2.93/TileRelay.qml | 1 -
FileSets/v2.93/TileText.qml | 1 -
FileSets/v2.93/attributes.csv | 1 -
FileSets/v2.93/dbus_digitalinputs.py | 1 -
FileSets/v2.93/dbus_generator.py | 1 -
FileSets/v2.93/dbus_systemcalc.py | 1 -
FileSets/v2.93/main.qml | 1 -
FileSets/v2.93/startstop.py | 1 -
FileSets/v2.93/styles.css | 1 -
FileSets/v2.94/Battery.qml | 1 -
FileSets/v2.94/COMPLETE | 0
FileSets/v2.94/DetailAcInput.qml | 1 -
FileSets/v2.94/DetailInverter.qml | 1 -
FileSets/v2.94/DetailLoadsCombined.qml | 1 -
FileSets/v2.94/DetailLoadsOnInput.qml | 1 -
FileSets/v2.94/DetailLoadsOnOutput.qml | 1 -
FileSets/v2.94/HubData.qml | 1 -
FileSets/v2.94/MbEditBox.qml | 1 -
FileSets/v2.94/MbEditBoxDateTime.qml | 1 -
FileSets/v2.94/MbSpinBox.qml | 1 -
FileSets/v2.94/MbSubMenu.qml | 1 -
FileSets/v2.94/Multi.qml | 1 -
FileSets/v2.94/ObjectAcConnection.qml | 1 -
FileSets/v2.94/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v2.94/OverviewBox.qml | 1 -
FileSets/v2.94/OverviewConnection.qml | 1 -
FileSets/v2.94/OverviewConnectionEnd.qml | 1 -
FileSets/v2.94/OverviewFlowComplex.qml | 1 -
FileSets/v2.94/OverviewGeneratorEnhanced.qml | 536 ------
.../v2.94/OverviewGeneratorEnhanced.qml.orig | 189 --
.../v2.94/OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v2.94/OverviewGridParallel.qml | 1 -
FileSets/v2.94/OverviewHub.qml | 1 -
FileSets/v2.94/OverviewHubEnhanced.qml | 1 -
FileSets/v2.94/OverviewMobileEnhanced.qml | 989 ----------
.../v2.94/OverviewMobileEnhanced.qml.orig | 640 -------
FileSets/v2.94/OverviewSolarCharger.qml | 1 -
FileSets/v2.94/OverviewSolarInverter.qml | 1 -
FileSets/v2.94/OverviewTankDelegate.qml | 1 -
FileSets/v2.94/OverviewTanks.qml | 1 -
.../v2.94/OverviewTanksTempsDigInputs.qml | 207 ---
.../OverviewTanksTempsDigInputs.qml.orig | 640 -------
FileSets/v2.94/PageGenerator.qml | 221 ---
FileSets/v2.94/PageGenerator.qml.orig | 189 --
FileSets/v2.94/PageSettingsGenerator.qml | 192 --
FileSets/v2.94/PageSettingsGenerator.qml.orig | 135 --
FileSets/v2.94/PageSettingsGuiMods.qml | 290 ---
FileSets/v2.94/PageSettingsGuiMods.qml.orig | 322 ----
FileSets/v2.94/PageSettingsRelay.qml | 533 ------
FileSets/v2.94/PageSettingsRelay.qml.orig | 91 -
FileSets/v2.94/PowerGauge.qml | 1 -
FileSets/v2.94/TileDigIn.qml | 131 --
FileSets/v2.94/TileDigIn.qml.orig | 550 ------
FileSets/v2.94/TileRelay.qml | 488 -----
FileSets/v2.94/TileRelay.qml.orig | 23 -
FileSets/v2.94/TileText.qml | 1 -
FileSets/v2.94/dbus_digitalinputs.py | 562 ------
FileSets/v2.94/dbus_digitalinputs.py.orig | 550 ------
FileSets/v2.94/dbus_generator.py | 1 -
FileSets/v2.94/startstop.py | 1186 ------------
FileSets/v2.94/startstop.py.orig | 956 ----------
FileSets/v2.94/styles.css | 1 -
FileSets/v3.00/Battery.qml | 1 -
FileSets/v3.00/COMPLETE | 0
FileSets/v3.00/DetailAcInput.qml | 1 -
FileSets/v3.00/DetailInverter.qml | 1 -
FileSets/v3.00/DetailLoadsCombined.qml | 1 -
FileSets/v3.00/DetailLoadsOnInput.qml | 1 -
FileSets/v3.00/DetailLoadsOnOutput.qml | 1 -
FileSets/v3.00/HubData.qml | 1 -
FileSets/v3.00/LINKS_ONLY | 0
FileSets/v3.00/MbEditBox.qml | 1 -
FileSets/v3.00/MbEditBoxDateTime.qml | 1 -
FileSets/v3.00/MbItem.qml | 1 -
FileSets/v3.00/MbItemDigitalInput.qml | 1 -
FileSets/v3.00/MbSpinBox.qml | 1 -
FileSets/v3.00/MbStyle.qml | 1 -
FileSets/v3.00/MbSubMenu.qml | 1 -
FileSets/v3.00/Multi.qml | 1 -
FileSets/v3.00/ObjectAcConnection.qml | 1 -
FileSets/v3.00/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v3.00/OverviewBox.qml | 1 -
FileSets/v3.00/OverviewConnection.qml | 1 -
FileSets/v3.00/OverviewConnectionEnd.qml | 1 -
FileSets/v3.00/OverviewFlowComplex.qml | 1 -
FileSets/v3.00/OverviewGeneratorEnhanced.qml | 1 -
.../v3.00/OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v3.00/OverviewGridParallel.qml | 1 -
FileSets/v3.00/OverviewHub.qml | 1 -
FileSets/v3.00/OverviewHubEnhanced.qml | 1 -
FileSets/v3.00/OverviewMobileEnhanced.qml | 1 -
FileSets/v3.00/OverviewSolarCharger.qml | 1 -
FileSets/v3.00/OverviewSolarInverter.qml | 1 -
FileSets/v3.00/OverviewTankDelegate.qml | 1 -
FileSets/v3.00/OverviewTanks.qml | 1 -
.../v3.00/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.00/PageDigitalInput.qml | 1 -
FileSets/v3.00/PageGenerator.qml | 1 -
FileSets/v3.00/PageMain.qml | 1 -
FileSets/v3.00/PageSettingsDisplay.qml | 1 -
FileSets/v3.00/PageSettingsGenerator.qml | 1 -
FileSets/v3.00/PageSettingsGuiMods.qml | 1 -
FileSets/v3.00/PageSettingsRelay.qml | 1 -
FileSets/v3.00/PowerGauge.qml | 1 -
FileSets/v3.00/Tile.qml | 1 -
FileSets/v3.00/TileDigIn.qml | 1 -
FileSets/v3.00/TileRelay.qml | 1 -
FileSets/v3.00/TileText.qml | 1 -
FileSets/v3.00/attributes.csv | 1 -
FileSets/v3.00/dbus_digitalinputs.py | 1 -
FileSets/v3.00/dbus_generator.py | 1 -
FileSets/v3.00/main.qml | 1 -
FileSets/v3.00/startstop.py | 1 -
FileSets/v3.00/styles.css | 1 -
FileSets/v3.00~32/COMPLETE | 0
FileSets/v3.00~32/DetailAcInput.qml | 1 -
FileSets/v3.00~32/DetailInverter.qml | 1 -
FileSets/v3.00~32/DetailLoadsCombined.qml | 1 -
FileSets/v3.00~32/DetailLoadsOnInput.qml | 1 -
FileSets/v3.00~32/DetailLoadsOnOutput.qml | 1 -
FileSets/v3.00~32/HubData.qml | 1 -
FileSets/v3.00~32/MbEditBox.qml | 1 -
FileSets/v3.00~32/MbEditBoxDateTime.qml | 1 -
FileSets/v3.00~32/MbItem.qml | 1 -
FileSets/v3.00~32/MbItemDigitalInput.qml | 1 -
FileSets/v3.00~32/MbSpinBox.qml | 1 -
FileSets/v3.00~32/MbStyle.qml | 1 -
FileSets/v3.00~32/MbSubMenu.qml | 1 -
FileSets/v3.00~32/Multi.qml | 1 -
FileSets/v3.00~32/ObjectAcConnection.qml | 1 -
.../v3.00~32/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v3.00~32/OverviewBox.qml | 1 -
FileSets/v3.00~32/OverviewConnection.qml | 1 -
FileSets/v3.00~32/OverviewConnectionEnd.qml | 1 -
FileSets/v3.00~32/OverviewFlowComplex.qml | 1 -
.../v3.00~32/OverviewGeneratorEnhanced.qml | 546 ------
.../OverviewGeneratorEnhanced.qml.orig | 189 --
.../OverviewGeneratorRelayEnhanced.qml | 8 -
.../OverviewGeneratorRelayEnhanced.qml.orig | 8 -
FileSets/v3.00~32/OverviewGridParallel.qml | 1 -
FileSets/v3.00~32/OverviewHub.qml | 1 -
FileSets/v3.00~32/OverviewHubEnhanced.qml | 1 -
FileSets/v3.00~32/OverviewMobileEnhanced.qml | 1 -
FileSets/v3.00~32/OverviewSolarCharger.qml | 1 -
FileSets/v3.00~32/OverviewTankDelegate.qml | 1 -
FileSets/v3.00~32/OverviewTanks.qml | 1 -
.../v3.00~32/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.00~32/PageGenerator.qml | 220 ---
FileSets/v3.00~32/PageGenerator.qml.orig | 189 --
FileSets/v3.00~32/PageMain.qml | 1 -
FileSets/v3.00~32/PageSettingsDisplay.qml | 1 -
FileSets/v3.00~32/PageSettingsGenerator.qml | 192 --
.../v3.00~32/PageSettingsGenerator.qml.orig | 135 --
FileSets/v3.00~32/PageSettingsGuiMods.qml | 1 -
FileSets/v3.00~32/PageSettingsRelay.qml | 1 -
FileSets/v3.00~32/PowerGauge.qml | 1 -
FileSets/v3.00~32/Tile.qml | 1 -
FileSets/v3.00~32/TileDigIn.qml | 1 -
FileSets/v3.00~32/TileRelay.qml | 1 -
FileSets/v3.00~32/TileText.qml | 1 -
FileSets/v3.00~32/attributes.csv | 1 -
FileSets/v3.00~32/dbus_digitalinputs.py | 1 -
FileSets/v3.00~32/dbus_generator.py | 339 ----
FileSets/v3.00~32/dbus_generator.py.orig | 318 ----
FileSets/v3.00~32/main.qml | 1 -
FileSets/v3.00~32/startstop.py | 1188 ------------
FileSets/v3.00~32/startstop.py.orig | 957 ----------
FileSets/v3.00~32/styles.css | 1 -
FileSets/v3.01/COMPLETE | 0
FileSets/v3.01/DetailAcInput.qml | 607 -------
FileSets/v3.01/DetailAcInput.qml.orig | 167 --
FileSets/v3.01/DetailInverter.qml | 556 ------
FileSets/v3.01/DetailInverter.qml.orig | 167 --
FileSets/v3.01/DetailLoadsCombined.qml | 147 --
FileSets/v3.01/DetailLoadsCombined.qml.orig | 167 --
FileSets/v3.01/DetailLoadsOnInput.qml | 147 --
FileSets/v3.01/DetailLoadsOnInput.qml.orig | 167 --
FileSets/v3.01/DetailLoadsOnOutput.qml | 152 --
FileSets/v3.01/DetailLoadsOnOutput.qml.orig | 167 --
FileSets/v3.01/HubData.qml | 264 ---
FileSets/v3.01/HubData.qml.orig | 167 --
FileSets/v3.01/MbEditBox.qml | 1 -
FileSets/v3.01/MbEditBoxDateTime.qml | 1 -
FileSets/v3.01/MbItem.qml | 1 -
FileSets/v3.01/MbItemDigitalInput.qml | 1 -
FileSets/v3.01/MbSpinBox.qml | 1 -
FileSets/v3.01/MbStyle.qml | 1 -
FileSets/v3.01/MbSubMenu.qml | 1 -
FileSets/v3.01/Multi.qml | 1 -
FileSets/v3.01/ObjectAcConnection.qml | 52 -
FileSets/v3.01/ObjectAcConnection.qml.orig | 30 -
FileSets/v3.01/OverviewAcValuesEnhanced.qml | 109 --
.../v3.01/OverviewAcValuesEnhanced.qml.orig | 42 -
FileSets/v3.01/OverviewBox.qml | 1 -
FileSets/v3.01/OverviewConnection.qml | 1 -
FileSets/v3.01/OverviewConnectionEnd.qml | 1 -
FileSets/v3.01/OverviewFlowComplex.qml | 1590 -----------------
FileSets/v3.01/OverviewFlowComplex.qml.orig | 481 -----
FileSets/v3.01/OverviewGeneratorEnhanced.qml | 536 ------
.../v3.01/OverviewGeneratorEnhanced.qml.orig | 194 --
.../v3.01/OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v3.01/OverviewGridParallel.qml | 488 -----
FileSets/v3.01/OverviewGridParallel.qml.orig | 481 -----
FileSets/v3.01/OverviewHub.qml | 315 ----
FileSets/v3.01/OverviewHub.qml.orig | 309 ----
FileSets/v3.01/OverviewHubEnhanced.qml | 1508 ----------------
FileSets/v3.01/OverviewHubEnhanced.qml.orig | 309 ----
FileSets/v3.01/OverviewMobileEnhanced.qml | 1 -
FileSets/v3.01/OverviewSolarCharger.qml | 1 -
FileSets/v3.01/OverviewSolarInverter.qml | 1 -
FileSets/v3.01/OverviewTankDelegate.qml | 1 -
FileSets/v3.01/OverviewTanks.qml | 1 -
.../v3.01/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.01/PageGenerator.qml | 226 ---
FileSets/v3.01/PageGenerator.qml.orig | 194 --
FileSets/v3.01/PageMain.qml | 1 -
FileSets/v3.01/PageSettingsGenerator.qml | 219 ---
FileSets/v3.01/PageSettingsGenerator.qml.orig | 152 --
FileSets/v3.01/PageSettingsGuiMods.qml | 291 ---
FileSets/v3.01/PageSettingsGuiMods.qml.orig | 346 ----
FileSets/v3.01/PageSettingsRelay.qml | 1 -
FileSets/v3.01/PowerGauge.qml | 317 ----
FileSets/v3.01/PowerGauge.qml.orig | 167 --
FileSets/v3.01/Tile.qml | 1 -
FileSets/v3.01/TileDigIn.qml.orig | 584 ------
FileSets/v3.01/TileRelay.qml | 1 -
FileSets/v3.01/TileText.qml | 1 -
FileSets/v3.01/dbus_digitalinputs.py | 596 ------
FileSets/v3.01/dbus_digitalinputs.py.orig | 584 ------
FileSets/v3.01/dbus_generator.py | 348 ----
FileSets/v3.01/dbus_generator.py.orig | 326 ----
FileSets/v3.01/startstop.py | 1463 ---------------
FileSets/v3.01/startstop.py.orig | 1112 ------------
FileSets/v3.01/styles.css | 1 -
FileSets/v3.10/DetailAcInput.qml | 2 +-
FileSets/v3.10/DetailInverter.qml | 2 +-
FileSets/v3.10/DetailLoadsCombined.qml | 2 +-
FileSets/v3.10/DetailLoadsOnInput.qml | 2 +-
FileSets/v3.10/DetailLoadsOnOutput.qml | 2 +-
FileSets/v3.10/HubData.qml | 2 +-
FileSets/v3.10/ObjectAcConnection.qml | 2 +-
FileSets/v3.10/OverviewAcValuesEnhanced.qml | 2 +-
FileSets/v3.10/OverviewFlowComplex.qml | 2 +-
.../v3.10/OverviewGeneratorRelayEnhanced.qml | 2 +-
FileSets/v3.10/OverviewGridParallel.qml | 2 +-
FileSets/v3.10/OverviewHub.qml | 2 +-
FileSets/v3.10/OverviewHubEnhanced.qml | 2 +-
FileSets/v3.10/OverviewMobileEnhanced.qml | 2 +-
.../v3.10/OverviewTanksTempsDigInputs.qml | 2 +-
FileSets/v3.10/PowerGauge.qml | 2 +-
FileSets/v3.10/TileDigIn.qml | 2 +-
FileSets/v3.10/TileRelay.qml | 2 +-
FileSets/v3.10/dbus_digitalinputs.py | 2 +-
FileSets/v3.11/DetailAcInput.qml | 2 +-
FileSets/v3.11/DetailInverter.qml | 2 +-
FileSets/v3.11/DetailLoadsCombined.qml | 2 +-
FileSets/v3.11/DetailLoadsOnInput.qml | 2 +-
FileSets/v3.11/DetailLoadsOnOutput.qml | 2 +-
FileSets/v3.11/HubData.qml | 2 +-
FileSets/v3.11/ObjectAcConnection.qml | 2 +-
FileSets/v3.11/OverviewAcValuesEnhanced.qml | 2 +-
FileSets/v3.11/OverviewFlowComplex.qml | 2 +-
.../v3.11/OverviewGeneratorRelayEnhanced.qml | 2 +-
FileSets/v3.11/OverviewGridParallel.qml | 2 +-
FileSets/v3.11/OverviewHub.qml | 2 +-
FileSets/v3.11/OverviewHubEnhanced.qml | 2 +-
FileSets/v3.11/OverviewMobileEnhanced.qml | 2 +-
.../v3.11/OverviewTanksTempsDigInputs.qml | 2 +-
FileSets/v3.11/PowerGauge.qml | 2 +-
FileSets/v3.11/TileDigIn.qml | 2 +-
FileSets/v3.11/TileRelay.qml | 2 +-
FileSets/v3.11/dbus_digitalinputs.py | 2 +-
FileSets/v3.12/DetailAcInput.qml | 2 +-
FileSets/v3.12/DetailInverter.qml | 2 +-
FileSets/v3.12/DetailLoadsCombined.qml | 2 +-
FileSets/v3.12/DetailLoadsOnInput.qml | 2 +-
FileSets/v3.12/DetailLoadsOnOutput.qml | 2 +-
FileSets/v3.12/HubData.qml | 2 +-
FileSets/v3.12/ObjectAcConnection.qml | 2 +-
FileSets/v3.12/OverviewAcValuesEnhanced.qml | 2 +-
FileSets/v3.12/OverviewFlowComplex.qml | 2 +-
.../v3.12/OverviewGeneratorRelayEnhanced.qml | 2 +-
FileSets/v3.12/OverviewGridParallel.qml | 2 +-
FileSets/v3.12/OverviewHub.qml | 2 +-
FileSets/v3.12/OverviewHubEnhanced.qml | 2 +-
FileSets/v3.12/OverviewMobileEnhanced.qml | 2 +-
.../v3.12/OverviewTanksTempsDigInputs.qml | 2 +-
FileSets/v3.12/PowerGauge.qml | 2 +-
FileSets/v3.12/TileDigIn.qml | 2 +-
FileSets/v3.12/TileRelay.qml | 2 +-
FileSets/v3.12/dbus_digitalinputs.py | 2 +-
FileSets/v3.13/DetailAcInput.qml | 2 +-
FileSets/v3.13/DetailInverter.qml | 2 +-
FileSets/v3.13/DetailLoadsCombined.qml | 2 +-
FileSets/v3.13/DetailLoadsOnInput.qml | 2 +-
FileSets/v3.13/DetailLoadsOnOutput.qml | 2 +-
FileSets/v3.13/HubData.qml | 2 +-
FileSets/v3.13/ObjectAcConnection.qml | 2 +-
FileSets/v3.13/OverviewAcValuesEnhanced.qml | 2 +-
FileSets/v3.13/OverviewFlowComplex.qml | 2 +-
.../v3.13/OverviewGeneratorRelayEnhanced.qml | 2 +-
FileSets/v3.13/OverviewGridParallel.qml | 2 +-
FileSets/v3.13/OverviewHub.qml | 2 +-
FileSets/v3.13/OverviewHubEnhanced.qml | 2 +-
FileSets/v3.13/OverviewMobileEnhanced.qml | 2 +-
.../v3.13/OverviewTanksTempsDigInputs.qml | 2 +-
FileSets/v3.13/PowerGauge.qml | 2 +-
FileSets/v3.13/TileDigIn.qml | 2 +-
FileSets/v3.13/TileRelay.qml | 2 +-
FileSets/v3.13/dbus_digitalinputs.py | 2 +-
FileSets/v3.14/DetailAcInput.qml | 2 +-
FileSets/v3.14/DetailInverter.qml | 2 +-
FileSets/v3.14/DetailLoadsCombined.qml | 2 +-
FileSets/v3.14/DetailLoadsOnInput.qml | 2 +-
FileSets/v3.14/DetailLoadsOnOutput.qml | 2 +-
FileSets/v3.14/HubData.qml | 2 +-
FileSets/v3.14/ObjectAcConnection.qml | 2 +-
FileSets/v3.14/OverviewAcValuesEnhanced.qml | 2 +-
FileSets/v3.14/OverviewFlowComplex.qml | 2 +-
.../v3.14/OverviewGeneratorRelayEnhanced.qml | 2 +-
FileSets/v3.14/OverviewGridParallel.qml | 2 +-
FileSets/v3.14/OverviewHub.qml | 2 +-
FileSets/v3.14/OverviewHubEnhanced.qml | 2 +-
FileSets/v3.14/OverviewMobileEnhanced.qml | 2 +-
.../v3.14/OverviewTanksTempsDigInputs.qml | 2 +-
FileSets/v3.14/PowerGauge.qml | 2 +-
FileSets/v3.14/TileDigIn.qml | 2 +-
FileSets/v3.14/TileRelay.qml | 2 +-
FileSets/v3.14/dbus_digitalinputs.py | 2 +-
FileSets/v3.20/DetailAcInput.qml | 2 +-
FileSets/v3.20/DetailInverter.qml | 2 +-
FileSets/v3.20/DetailLoadsCombined.qml | 2 +-
FileSets/v3.20/DetailLoadsOnInput.qml | 2 +-
FileSets/v3.20/DetailLoadsOnOutput.qml | 2 +-
FileSets/v3.20/HubData.qml | 2 +-
FileSets/v3.20/ObjectAcConnection.qml | 2 +-
FileSets/v3.20/OverviewAcValuesEnhanced.qml | 2 +-
FileSets/v3.20/OverviewFlowComplex.qml | 2 +-
.../v3.20/OverviewGeneratorRelayEnhanced.qml | 2 +-
FileSets/v3.20/OverviewGridParallel.qml | 2 +-
FileSets/v3.20/OverviewHub.qml | 2 +-
FileSets/v3.20/OverviewHubEnhanced.qml | 2 +-
FileSets/v3.20/OverviewMobileEnhanced.qml | 2 +-
.../v3.20/OverviewTanksTempsDigInputs.qml | 2 +-
FileSets/v3.20/PageSettingsGenerator.qml | 2 +-
FileSets/v3.20/PowerGauge.qml | 2 +-
FileSets/v3.20/TileDigIn.qml | 2 +-
FileSets/v3.20/TileRelay.qml | 2 +-
FileSets/v3.20/dbus_digitalinputs.py | 2 +-
FileSets/v3.20/dbus_generator.py | 2 +-
FileSets/v3.21/DetailAcInput.qml | 2 +-
FileSets/v3.21/DetailInverter.qml | 2 +-
FileSets/v3.21/DetailLoadsCombined.qml | 2 +-
FileSets/v3.21/DetailLoadsOnInput.qml | 2 +-
FileSets/v3.21/DetailLoadsOnOutput.qml | 2 +-
FileSets/v3.21/HubData.qml | 2 +-
FileSets/v3.21/ObjectAcConnection.qml | 2 +-
FileSets/v3.21/OverviewAcValuesEnhanced.qml | 2 +-
FileSets/v3.21/OverviewFlowComplex.qml | 2 +-
.../v3.21/OverviewGeneratorRelayEnhanced.qml | 2 +-
FileSets/v3.21/OverviewGridParallel.qml | 2 +-
FileSets/v3.21/OverviewHub.qml | 2 +-
FileSets/v3.21/OverviewHubEnhanced.qml | 2 +-
FileSets/v3.21/OverviewMobileEnhanced.qml | 2 +-
.../v3.21/OverviewTanksTempsDigInputs.qml | 2 +-
FileSets/v3.21/PageSettingsGenerator.qml | 2 +-
FileSets/v3.21/PowerGauge.qml | 2 +-
FileSets/v3.21/TileDigIn.qml | 2 +-
FileSets/v3.21/TileRelay.qml | 2 +-
FileSets/v3.21/dbus_digitalinputs.py | 2 +-
FileSets/v3.21/dbus_generator.py | 2 +-
FileSets/v3.22/DetailAcInput.qml | 2 +-
FileSets/v3.22/DetailInverter.qml | 2 +-
FileSets/v3.22/DetailLoadsCombined.qml | 2 +-
FileSets/v3.22/DetailLoadsOnInput.qml | 2 +-
FileSets/v3.22/DetailLoadsOnOutput.qml | 2 +-
FileSets/v3.22/HubData.qml | 2 +-
FileSets/v3.22/ObjectAcConnection.qml | 2 +-
FileSets/v3.22/OverviewAcValuesEnhanced.qml | 2 +-
FileSets/v3.22/OverviewFlowComplex.qml | 2 +-
.../v3.22/OverviewGeneratorRelayEnhanced.qml | 2 +-
FileSets/v3.22/OverviewGridParallel.qml | 2 +-
FileSets/v3.22/OverviewHub.qml | 2 +-
FileSets/v3.22/OverviewHubEnhanced.qml | 2 +-
FileSets/v3.22/OverviewMobileEnhanced.qml | 2 +-
.../v3.22/OverviewTanksTempsDigInputs.qml | 2 +-
FileSets/v3.22/PageSettingsGenerator.qml | 2 +-
FileSets/v3.22/PowerGauge.qml | 2 +-
FileSets/v3.22/TileDigIn.qml | 2 +-
FileSets/v3.22/TileRelay.qml | 2 +-
FileSets/v3.22/dbus_digitalinputs.py | 2 +-
FileSets/v3.22/dbus_generator.py | 2 +-
FileSets/v3.30/DetailAcInput.qml | 2 +-
FileSets/v3.30/DetailInverter.qml | 2 +-
FileSets/v3.30/DetailLoadsCombined.qml | 2 +-
FileSets/v3.30/DetailLoadsOnInput.qml | 2 +-
FileSets/v3.30/DetailLoadsOnOutput.qml | 2 +-
FileSets/v3.30/HubData.qml | 2 +-
FileSets/v3.30/ObjectAcConnection.qml | 2 +-
FileSets/v3.30/OverviewAcValuesEnhanced.qml | 2 +-
FileSets/v3.30/OverviewFlowComplex.qml | 2 +-
.../v3.30/OverviewGeneratorRelayEnhanced.qml | 2 +-
FileSets/v3.30/OverviewGridParallel.qml | 2 +-
FileSets/v3.30/OverviewHub.qml | 2 +-
FileSets/v3.30/OverviewHubEnhanced.qml | 2 +-
FileSets/v3.30/OverviewMobileEnhanced.qml | 2 +-
.../v3.30/OverviewTanksTempsDigInputs.qml | 2 +-
FileSets/v3.30/PageSettingsGenerator.qml | 2 +-
FileSets/v3.30/PageSettingsGuiMods.qml | 2 +-
FileSets/v3.30/PageSettingsRelay.qml | 2 +-
FileSets/v3.30/PowerGauge.qml | 2 +-
FileSets/v3.30/TileDigIn.qml | 2 +-
FileSets/v3.30/TileRelay.qml | 2 +-
FileSets/v3.30/dbus_digitalinputs.py | 2 +-
FileSets/v3.30/dbus_generator.py | 2 +-
FileSets/v3.31/DetailAcInput.qml | 2 +-
FileSets/v3.31/DetailInverter.qml | 2 +-
FileSets/v3.31/DetailLoadsCombined.qml | 2 +-
FileSets/v3.31/DetailLoadsOnInput.qml | 2 +-
FileSets/v3.31/DetailLoadsOnOutput.qml | 2 +-
FileSets/v3.31/HubData.qml | 2 +-
FileSets/v3.31/ObjectAcConnection.qml | 2 +-
FileSets/v3.31/OverviewAcValuesEnhanced.qml | 2 +-
FileSets/v3.31/OverviewFlowComplex.qml | 2 +-
FileSets/v3.31/OverviewGeneratorEnhanced.qml | 548 +++++-
.../OverviewGeneratorEnhanced.qml.orig | 0
.../v3.31/OverviewGeneratorRelayEnhanced.qml | 2 +-
FileSets/v3.31/OverviewGridParallel.qml | 2 +-
FileSets/v3.31/OverviewHub.qml | 2 +-
FileSets/v3.31/OverviewHubEnhanced.qml | 2 +-
FileSets/v3.31/OverviewMobileEnhanced.qml | 2 +-
.../v3.31/OverviewTanksTempsDigInputs.qml | 2 +-
FileSets/v3.31/PageGenerator.qml | 224 ++-
.../PageGenerator.qml.orig | 0
FileSets/v3.31/PageSettingsGenerator.qml | 2 +-
FileSets/v3.31/PageSettingsGuiMods.qml | 2 +-
FileSets/v3.31/PageSettingsRelay.qml | 2 +-
FileSets/v3.31/PowerGauge.qml | 2 +-
FileSets/v3.31/TileDigIn.qml | 2 +-
FileSets/v3.31/TileRelay.qml | 2 +-
FileSets/v3.31/dbus_digitalinputs.py | 2 +-
FileSets/v3.31/dbus_generator.py | 2 +-
FileSets/v3.33/DetailAcInput.qml | 2 +-
FileSets/v3.33/DetailInverter.qml | 2 +-
FileSets/v3.33/DetailLoadsCombined.qml | 2 +-
FileSets/v3.33/DetailLoadsOnInput.qml | 2 +-
FileSets/v3.33/DetailLoadsOnOutput.qml | 2 +-
FileSets/v3.33/HubData.qml | 2 +-
FileSets/v3.33/ObjectAcConnection.qml | 2 +-
FileSets/v3.33/OverviewAcValuesEnhanced.qml | 2 +-
FileSets/v3.33/OverviewFlowComplex.qml | 2 +-
FileSets/v3.33/OverviewGeneratorEnhanced.qml | 2 +-
.../v3.33/OverviewGeneratorRelayEnhanced.qml | 2 +-
FileSets/v3.33/OverviewGridParallel.qml | 2 +-
FileSets/v3.33/OverviewHub.qml | 2 +-
FileSets/v3.33/OverviewHubEnhanced.qml | 2 +-
FileSets/v3.33/OverviewMobileEnhanced.qml | 2 +-
.../v3.33/OverviewTanksTempsDigInputs.qml | 2 +-
FileSets/v3.33/PageGenerator.qml | 2 +-
FileSets/v3.33/PageSettingsGenerator.qml | 2 +-
FileSets/v3.33/PageSettingsGuiMods.qml | 2 +-
FileSets/v3.33/PageSettingsRelay.qml | 2 +-
FileSets/v3.33/PowerGauge.qml | 2 +-
FileSets/v3.33/TileDigIn.qml | 2 +-
FileSets/v3.33/TileRelay.qml | 2 +-
FileSets/v3.33/dbus_digitalinputs.py | 2 +-
FileSets/v3.33/dbus_generator.py | 2 +-
FileSets/v3.34/DetailAcInput.qml | 607 ++++++-
.../{v3.40~8 => v3.34}/DetailAcInput.qml.orig | 0
FileSets/v3.34/DetailInverter.qml | 654 ++++++-
.../DetailInverter.qml.orig | 0
FileSets/v3.34/DetailLoadsCombined.qml | 147 +-
.../DetailLoadsCombined.qml.orig | 0
FileSets/v3.34/DetailLoadsOnInput.qml | 147 +-
.../DetailLoadsOnInput.qml.orig | 0
FileSets/v3.34/DetailLoadsOnOutput.qml | 152 +-
.../DetailLoadsOnOutput.qml.orig | 0
FileSets/v3.34/HubData.qml | 274 ++-
FileSets/{v3.40~8 => v3.34}/HubData.qml.orig | 0
FileSets/v3.34/ObjectAcConnection.qml | 2 +-
FileSets/v3.34/OverviewAcValuesEnhanced.qml | 2 +-
FileSets/v3.34/OverviewFlowComplex.qml | 1550 +++++++++++++++-
.../OverviewFlowComplex.qml.orig | 0
FileSets/v3.34/OverviewGeneratorEnhanced.qml | 548 +-----
.../v3.34/OverviewGeneratorRelayEnhanced.qml | 2 +-
FileSets/v3.34/OverviewGridParallel.qml | 491 ++++-
.../OverviewGridParallel.qml.orig | 0
FileSets/v3.34/OverviewHub.qml | 316 +++-
.../{v3.40~8 => v3.34}/OverviewHub.qml.orig | 0
FileSets/v3.34/OverviewHubEnhanced.qml | 1506 +++++++++++++++-
.../OverviewHubEnhanced.qml.orig | 0
FileSets/v3.34/OverviewMobileEnhanced.qml | 2 +-
.../v3.34/OverviewTanksTempsDigInputs.qml | 2 +-
FileSets/v3.34/PageGenerator.qml | 160 +-
FileSets/v3.34/PageSettingsGenerator.qml | 2 +-
FileSets/v3.34/PageSettingsGuiMods.qml | 2 +-
FileSets/v3.34/PageSettingsRelay.qml | 2 +-
FileSets/v3.34/PowerGauge.qml | 321 +++-
.../{v3.40~8 => v3.34}/PowerGauge.qml.orig | 0
FileSets/v3.34/TileDigIn.qml | 2 +-
FileSets/v3.34/TileRelay.qml | 2 +-
FileSets/v3.34/dbus_digitalinputs.py | 2 +-
FileSets/v3.34/dbus_generator.py | 2 +-
FileSets/v3.34/startstop.py | 1567 +++++++++++++++-
.../{v3.40~37 => v3.34}/startstop.py.orig | 0
FileSets/{v2.71 => v3.40}/COMPLETE | 0
.../{v3.40~13 => v3.40}/DetailAcInput.qml | 0
.../DetailAcInput.qml.orig | 0
.../{v3.40~13 => v3.40}/DetailInverter.qml | 0
.../DetailInverter.qml.orig | 0
.../DetailLoadsCombined.qml | 0
.../DetailLoadsCombined.qml.orig | 0
.../DetailLoadsOnInput.qml | 0
.../DetailLoadsOnInput.qml.orig | 0
.../DetailLoadsOnOutput.qml | 0
.../DetailLoadsOnOutput.qml.orig | 0
FileSets/{v3.40~39 => v3.40}/HubData.qml | 0
FileSets/{v3.40~39 => v3.40}/HubData.qml.orig | 0
.../ObjectAcConnection.qml | 0
.../ObjectAcConnection.qml.orig | 0
.../OverviewAcValuesEnhanced.qml | 0
.../OverviewAcValuesEnhanced.qml.orig | 0
.../OverviewFlowComplex.qml | 0
.../OverviewFlowComplex.qml.orig | 0
.../OverviewGeneratorEnhanced.qml | 0
.../OverviewGeneratorEnhanced.qml.orig | 0
.../OverviewGeneratorRelayEnhanced.qml | 0
.../OverviewGeneratorRelayEnhanced.qml.orig | 0
.../OverviewGridParallel.qml | 0
.../OverviewGridParallel.qml.orig | 0
FileSets/{v3.40~39 => v3.40}/OverviewHub.qml | 0
.../{v3.40~39 => v3.40}/OverviewHub.qml.orig | 0
.../OverviewHubEnhanced.qml | 0
.../OverviewHubEnhanced.qml.orig | 0
.../OverviewMobileEnhanced.qml | 0
.../OverviewMobileEnhanced.qml.orig | 0
.../OverviewTanksTempsDigInputs.qml | 0
.../OverviewTanksTempsDigInputs.qml.orig | 0
.../{v3.40~26 => v3.40}/PageGenerator.qml | 8 +-
.../{v3.34 => v3.40}/PageGenerator.qml.orig | 0
.../PageSettingsGenerator.qml | 0
.../PageSettingsGenerator.qml.orig | 0
.../PageSettingsGuiMods.qml | 0
.../PageSettingsGuiMods.qml.orig | 0
.../{v3.40~39 => v3.40}/PageSettingsRelay.qml | 0
.../PageSettingsRelay.qml.orig | 0
FileSets/{v3.40~39 => v3.40}/PowerGauge.qml | 0
.../{v3.40~39 => v3.40}/PowerGauge.qml.orig | 0
FileSets/{v3.01 => v3.40}/TileDigIn.qml | 0
.../{v3.40~39 => v3.40}/TileDigIn.qml.orig | 0
FileSets/{v3.40~39 => v3.40}/TileRelay.qml | 0
.../{v3.40~39 => v3.40}/TileRelay.qml.orig | 0
.../{v3.40~39 => v3.40}/dbus_digitalinputs.py | 0
.../dbus_digitalinputs.py.orig | 0
.../{v3.40~39 => v3.40}/dbus_generator.py | 0
.../dbus_generator.py.orig | 0
FileSets/{v3.40~39 => v3.40}/startstop.py | 0
.../{v3.40~39 => v3.40}/startstop.py.orig | 0
FileSets/v3.40~1/Battery.qml | 1 -
FileSets/v3.40~1/COMPLETE | 0
FileSets/v3.40~1/DetailAcInput.qml | 1 -
FileSets/v3.40~1/DetailInverter.qml | 1 -
FileSets/v3.40~1/DetailLoadsCombined.qml | 1 -
FileSets/v3.40~1/DetailLoadsOnInput.qml | 1 -
FileSets/v3.40~1/DetailLoadsOnOutput.qml | 1 -
FileSets/v3.40~1/HubData.qml | 1 -
FileSets/v3.40~1/LINKS_ONLY | 0
FileSets/v3.40~1/MbEditBox.qml | 1 -
FileSets/v3.40~1/MbEditBoxDateTime.qml | 1 -
FileSets/v3.40~1/MbItem.qml | 1 -
FileSets/v3.40~1/MbItemDigitalInput.qml | 1 -
FileSets/v3.40~1/MbSpinBox.qml | 1 -
FileSets/v3.40~1/MbStyle.qml | 1 -
FileSets/v3.40~1/MbSubMenu.qml | 1 -
FileSets/v3.40~1/Multi.qml | 1 -
FileSets/v3.40~1/ObjectAcConnection.qml | 1 -
FileSets/v3.40~1/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v3.40~1/OverviewBox.qml | 1 -
FileSets/v3.40~1/OverviewConnection.qml | 1 -
FileSets/v3.40~1/OverviewConnectionEnd.qml | 1 -
FileSets/v3.40~1/OverviewFlowComplex.qml | 1 -
.../v3.40~1/OverviewGeneratorEnhanced.qml | 1 -
.../OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v3.40~1/OverviewGridParallel.qml | 1 -
FileSets/v3.40~1/OverviewHub.qml | 1 -
FileSets/v3.40~1/OverviewHubEnhanced.qml | 1 -
FileSets/v3.40~1/OverviewMobileEnhanced.qml | 1 -
FileSets/v3.40~1/OverviewSolarCharger.qml | 1 -
FileSets/v3.40~1/OverviewSolarInverter.qml | 1 -
FileSets/v3.40~1/OverviewTankDelegate.qml | 1 -
FileSets/v3.40~1/OverviewTanks.qml | 1 -
.../v3.40~1/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.40~1/PageDigitalInput.qml | 1 -
FileSets/v3.40~1/PageGenerator.qml | 1 -
FileSets/v3.40~1/PageMain.qml | 1 -
FileSets/v3.40~1/PageSettingsDisplay.qml | 1 -
FileSets/v3.40~1/PageSettingsGenerator.qml | 1 -
FileSets/v3.40~1/PageSettingsGuiMods.qml | 1 -
FileSets/v3.40~1/PageSettingsRelay.qml | 1 -
FileSets/v3.40~1/PowerGauge.qml | 1 -
FileSets/v3.40~1/Tile.qml | 1 -
FileSets/v3.40~1/TileDigIn.qml | 1 -
FileSets/v3.40~1/TileRelay.qml | 1 -
FileSets/v3.40~1/TileText.qml | 1 -
FileSets/v3.40~1/attributes.csv | 1 -
FileSets/v3.40~1/dbus_digitalinputs.py | 1 -
FileSets/v3.40~1/dbus_generator.py | 1 -
FileSets/v3.40~1/main.qml | 1 -
FileSets/v3.40~1/startstop.py | 1 -
FileSets/v3.40~1/styles.css | 1 -
FileSets/v3.40~10/Battery.qml | 1 -
FileSets/v3.40~10/COMPLETE | 0
FileSets/v3.40~10/DetailAcInput.qml | 1 -
FileSets/v3.40~10/DetailInverter.qml | 1 -
FileSets/v3.40~10/DetailLoadsCombined.qml | 1 -
FileSets/v3.40~10/DetailLoadsOnInput.qml | 1 -
FileSets/v3.40~10/DetailLoadsOnOutput.qml | 1 -
FileSets/v3.40~10/HubData.qml | 1 -
FileSets/v3.40~10/LINKS_ONLY | 0
FileSets/v3.40~10/MbEditBoxDateTime.qml | 1 -
FileSets/v3.40~10/MbItem.qml | 1 -
FileSets/v3.40~10/MbItemDigitalInput.qml | 1 -
FileSets/v3.40~10/MbSpinBox.qml | 1 -
FileSets/v3.40~10/MbStyle.qml | 1 -
FileSets/v3.40~10/MbSubMenu.qml | 1 -
FileSets/v3.40~10/Multi.qml | 1 -
FileSets/v3.40~10/ObjectAcConnection.qml | 1 -
.../v3.40~10/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v3.40~10/OverviewBox.qml | 1 -
FileSets/v3.40~10/OverviewConnection.qml | 1 -
FileSets/v3.40~10/OverviewConnectionEnd.qml | 1 -
FileSets/v3.40~10/OverviewFlowComplex.qml | 1 -
.../v3.40~10/OverviewGeneratorEnhanced.qml | 1 -
.../OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v3.40~10/OverviewGridParallel.qml | 1 -
FileSets/v3.40~10/OverviewHub.qml | 1 -
FileSets/v3.40~10/OverviewHubEnhanced.qml | 1 -
FileSets/v3.40~10/OverviewMobileEnhanced.qml | 1 -
FileSets/v3.40~10/OverviewSolarCharger.qml | 1 -
FileSets/v3.40~10/OverviewSolarInverter.qml | 1 -
FileSets/v3.40~10/OverviewTankDelegate.qml | 1 -
FileSets/v3.40~10/OverviewTanks.qml | 1 -
.../v3.40~10/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.40~10/PageDigitalInput.qml | 1 -
FileSets/v3.40~10/PageGenerator.qml | 1 -
FileSets/v3.40~10/PageMain.qml | 1 -
FileSets/v3.40~10/PageSettingsDisplay.qml | 1 -
FileSets/v3.40~10/PageSettingsGenerator.qml | 1 -
FileSets/v3.40~10/PageSettingsGuiMods.qml | 1 -
FileSets/v3.40~10/PageSettingsRelay.qml | 1 -
FileSets/v3.40~10/PowerGauge.qml | 1 -
FileSets/v3.40~10/Tile.qml | 1 -
FileSets/v3.40~10/TileDigIn.qml | 1 -
FileSets/v3.40~10/TileRelay.qml | 1 -
FileSets/v3.40~10/TileText.qml | 1 -
FileSets/v3.40~10/attributes.csv | 1 -
FileSets/v3.40~10/dbus_digitalinputs.py | 1 -
FileSets/v3.40~10/dbus_generator.py | 1 -
FileSets/v3.40~10/main.qml | 1 -
FileSets/v3.40~10/startstop.py | 1 -
FileSets/v3.40~10/styles.css | 1 -
FileSets/v3.40~13/Battery.qml | 1 -
FileSets/v3.40~13/COMPLETE | 0
FileSets/v3.40~13/DetailAcInput.qml.orig | 164 --
FileSets/v3.40~13/DetailInverter.qml.orig | 164 --
.../v3.40~13/DetailLoadsCombined.qml.orig | 164 --
FileSets/v3.40~13/DetailLoadsOnInput.qml.orig | 164 --
.../v3.40~13/DetailLoadsOnOutput.qml.orig | 164 --
FileSets/v3.40~13/HubData.qml | 262 ---
FileSets/v3.40~13/HubData.qml.orig | 164 --
FileSets/v3.40~13/MbEditBox.qml | 1 -
FileSets/v3.40~13/MbEditBoxDateTime.qml | 1 -
FileSets/v3.40~13/MbItem.qml | 1 -
FileSets/v3.40~13/MbItemDigitalInput.qml | 1 -
FileSets/v3.40~13/MbSpinBox.qml | 1 -
FileSets/v3.40~13/MbStyle.qml | 1 -
FileSets/v3.40~13/MbSubMenu.qml | 1 -
FileSets/v3.40~13/Multi.qml | 1 -
FileSets/v3.40~13/ObjectAcConnection.qml | 1 -
.../v3.40~13/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v3.40~13/OverviewBox.qml | 1 -
FileSets/v3.40~13/OverviewConnection.qml | 1 -
FileSets/v3.40~13/OverviewConnectionEnd.qml | 1 -
FileSets/v3.40~13/OverviewFlowComplex.qml | 1 -
.../v3.40~13/OverviewGeneratorEnhanced.qml | 1 -
.../OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v3.40~13/OverviewGridParallel.qml | 1 -
FileSets/v3.40~13/OverviewHub.qml | 1 -
FileSets/v3.40~13/OverviewHubEnhanced.qml | 1 -
FileSets/v3.40~13/OverviewMobileEnhanced.qml | 1 -
FileSets/v3.40~13/OverviewSolarCharger.qml | 1 -
FileSets/v3.40~13/OverviewSolarInverter.qml | 1 -
FileSets/v3.40~13/OverviewTankDelegate.qml | 1 -
FileSets/v3.40~13/OverviewTanks.qml | 1 -
.../v3.40~13/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.40~13/PageDigitalInput.qml | 1 -
FileSets/v3.40~13/PageGenerator.qml | 1 -
FileSets/v3.40~13/PageSettingsDisplay.qml | 1 -
FileSets/v3.40~13/PageSettingsGenerator.qml | 1 -
FileSets/v3.40~13/PageSettingsGuiMods.qml | 1 -
FileSets/v3.40~13/PageSettingsRelay.qml | 1 -
FileSets/v3.40~13/PowerGauge.qml | 320 ----
FileSets/v3.40~13/PowerGauge.qml.orig | 164 --
FileSets/v3.40~13/Tile.qml | 1 -
FileSets/v3.40~13/TileDigIn.qml | 1 -
FileSets/v3.40~13/TileRelay.qml | 1 -
FileSets/v3.40~13/TileText.qml | 1 -
FileSets/v3.40~13/attributes.csv | 1 -
FileSets/v3.40~13/dbus_digitalinputs.py | 1 -
FileSets/v3.40~13/dbus_generator.py | 1 -
FileSets/v3.40~13/startstop.py | 1 -
FileSets/v3.40~13/styles.css | 1 -
FileSets/v3.40~15/Battery.qml | 1 -
FileSets/v3.40~15/COMPLETE | 0
FileSets/v3.40~15/DetailAcInput.qml | 1 -
FileSets/v3.40~15/DetailInverter.qml | 1 -
FileSets/v3.40~15/DetailLoadsCombined.qml | 1 -
FileSets/v3.40~15/DetailLoadsOnInput.qml | 1 -
FileSets/v3.40~15/DetailLoadsOnOutput.qml | 1 -
FileSets/v3.40~15/HubData.qml | 1 -
FileSets/v3.40~15/LINKS_ONLY | 0
FileSets/v3.40~15/MbEditBox.qml | 1 -
FileSets/v3.40~15/MbEditBoxDateTime.qml | 1 -
FileSets/v3.40~15/MbItem.qml | 1 -
FileSets/v3.40~15/MbItemDigitalInput.qml | 1 -
FileSets/v3.40~15/MbSpinBox.qml | 1 -
FileSets/v3.40~15/MbStyle.qml | 1 -
FileSets/v3.40~15/MbSubMenu.qml | 1 -
FileSets/v3.40~15/Multi.qml | 1 -
FileSets/v3.40~15/ObjectAcConnection.qml | 1 -
.../v3.40~15/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v3.40~15/OverviewBox.qml | 1 -
FileSets/v3.40~15/OverviewConnection.qml | 1 -
FileSets/v3.40~15/OverviewConnectionEnd.qml | 1 -
FileSets/v3.40~15/OverviewFlowComplex.qml | 1 -
.../v3.40~15/OverviewGeneratorEnhanced.qml | 1 -
.../OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v3.40~15/OverviewGridParallel.qml | 1 -
FileSets/v3.40~15/OverviewHub.qml | 1 -
FileSets/v3.40~15/OverviewHubEnhanced.qml | 1 -
FileSets/v3.40~15/OverviewMobileEnhanced.qml | 1 -
FileSets/v3.40~15/OverviewSolarCharger.qml | 1 -
FileSets/v3.40~15/OverviewSolarInverter.qml | 1 -
FileSets/v3.40~15/OverviewTankDelegate.qml | 1 -
FileSets/v3.40~15/OverviewTanks.qml | 1 -
.../v3.40~15/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.40~15/PageDigitalInput.qml | 1 -
FileSets/v3.40~15/PageGenerator.qml | 1 -
FileSets/v3.40~15/PageMain.qml | 1 -
FileSets/v3.40~15/PageSettingsDisplay.qml | 1 -
FileSets/v3.40~15/PageSettingsGenerator.qml | 1 -
FileSets/v3.40~15/PageSettingsGuiMods.qml | 1 -
FileSets/v3.40~15/PageSettingsRelay.qml | 1 -
FileSets/v3.40~15/PowerGauge.qml | 1 -
FileSets/v3.40~15/Tile.qml | 1 -
FileSets/v3.40~15/TileDigIn.qml | 1 -
FileSets/v3.40~15/TileRelay.qml | 1 -
FileSets/v3.40~15/TileText.qml | 1 -
FileSets/v3.40~15/attributes.csv | 1 -
FileSets/v3.40~15/dbus_digitalinputs.py | 1 -
FileSets/v3.40~15/dbus_generator.py | 1 -
FileSets/v3.40~15/main.qml | 1 -
FileSets/v3.40~15/startstop.py | 1 -
FileSets/v3.40~15/styles.css | 1 -
FileSets/v3.40~16/Battery.qml | 1 -
FileSets/v3.40~16/COMPLETE | 0
FileSets/v3.40~16/DetailAcInput.qml | 1 -
FileSets/v3.40~16/DetailInverter.qml | 1 -
FileSets/v3.40~16/DetailLoadsCombined.qml | 1 -
FileSets/v3.40~16/DetailLoadsOnInput.qml | 1 -
FileSets/v3.40~16/DetailLoadsOnOutput.qml | 1 -
FileSets/v3.40~16/HubData.qml | 1 -
FileSets/v3.40~16/LINKS_ONLY | 0
FileSets/v3.40~16/MbEditBox.qml | 1 -
FileSets/v3.40~16/MbEditBoxDateTime.qml | 1 -
FileSets/v3.40~16/MbItem.qml | 1 -
FileSets/v3.40~16/MbItemDigitalInput.qml | 1 -
FileSets/v3.40~16/MbSpinBox.qml | 1 -
FileSets/v3.40~16/MbStyle.qml | 1 -
FileSets/v3.40~16/MbSubMenu.qml | 1 -
FileSets/v3.40~16/Multi.qml | 1 -
FileSets/v3.40~16/ObjectAcConnection.qml | 1 -
.../v3.40~16/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v3.40~16/OverviewBox.qml | 1 -
FileSets/v3.40~16/OverviewConnection.qml | 1 -
FileSets/v3.40~16/OverviewConnectionEnd.qml | 1 -
FileSets/v3.40~16/OverviewFlowComplex.qml | 1 -
.../v3.40~16/OverviewGeneratorEnhanced.qml | 1 -
.../OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v3.40~16/OverviewGridParallel.qml | 1 -
FileSets/v3.40~16/OverviewHub.qml | 1 -
FileSets/v3.40~16/OverviewHubEnhanced.qml | 1 -
FileSets/v3.40~16/OverviewMobileEnhanced.qml | 1 -
FileSets/v3.40~16/OverviewSolarCharger.qml | 1 -
FileSets/v3.40~16/OverviewSolarInverter.qml | 1 -
FileSets/v3.40~16/OverviewTankDelegate.qml | 1 -
FileSets/v3.40~16/OverviewTanks.qml | 1 -
.../v3.40~16/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.40~16/PageDigitalInput.qml | 1 -
FileSets/v3.40~16/PageGenerator.qml | 1 -
FileSets/v3.40~16/PageMain.qml | 1 -
FileSets/v3.40~16/PageSettingsDisplay.qml | 1 -
FileSets/v3.40~16/PageSettingsGenerator.qml | 1 -
FileSets/v3.40~16/PageSettingsGuiMods.qml | 1 -
FileSets/v3.40~16/PageSettingsRelay.qml | 1 -
FileSets/v3.40~16/PowerGauge.qml | 1 -
FileSets/v3.40~16/Tile.qml | 1 -
FileSets/v3.40~16/TileDigIn.qml | 1 -
FileSets/v3.40~16/TileRelay.qml | 1 -
FileSets/v3.40~16/TileText.qml | 1 -
FileSets/v3.40~16/dbus_digitalinputs.py | 1 -
FileSets/v3.40~16/dbus_generator.py | 1 -
FileSets/v3.40~16/main.qml | 1 -
FileSets/v3.40~16/startstop.py | 1 -
FileSets/v3.40~16/styles.css | 1 -
FileSets/v3.40~17/Battery.qml | 1 -
FileSets/v3.40~17/COMPLETE | 0
FileSets/v3.40~17/DetailAcInput.qml | 1 -
FileSets/v3.40~17/DetailInverter.qml | 1 -
FileSets/v3.40~17/DetailLoadsCombined.qml | 1 -
FileSets/v3.40~17/DetailLoadsOnInput.qml | 1 -
FileSets/v3.40~17/DetailLoadsOnOutput.qml | 1 -
FileSets/v3.40~17/HubData.qml | 1 -
FileSets/v3.40~17/MbEditBox.qml | 1 -
FileSets/v3.40~17/MbEditBoxDateTime.qml | 1 -
FileSets/v3.40~17/MbItem.qml | 1 -
FileSets/v3.40~17/MbItemDigitalInput.qml | 1 -
FileSets/v3.40~17/MbSpinBox.qml | 1 -
FileSets/v3.40~17/MbStyle.qml | 1 -
FileSets/v3.40~17/MbSubMenu.qml | 1 -
FileSets/v3.40~17/Multi.qml | 1 -
FileSets/v3.40~17/ObjectAcConnection.qml | 1 -
.../v3.40~17/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v3.40~17/OverviewBox.qml | 1 -
FileSets/v3.40~17/OverviewConnection.qml | 1 -
FileSets/v3.40~17/OverviewConnectionEnd.qml | 1 -
FileSets/v3.40~17/OverviewFlowComplex.qml | 1 -
.../v3.40~17/OverviewGeneratorEnhanced.qml | 1 -
.../OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v3.40~17/OverviewGridParallel.qml | 1 -
FileSets/v3.40~17/OverviewHub.qml | 1 -
FileSets/v3.40~17/OverviewHubEnhanced.qml | 1 -
FileSets/v3.40~17/OverviewMobileEnhanced.qml | 1 -
FileSets/v3.40~17/OverviewSolarCharger.qml | 1 -
FileSets/v3.40~17/OverviewSolarInverter.qml | 1 -
FileSets/v3.40~17/OverviewTankDelegate.qml | 1 -
FileSets/v3.40~17/OverviewTanks.qml | 1 -
.../v3.40~17/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.40~17/PageDigitalInput.qml | 1 -
FileSets/v3.40~17/PageGenerator.qml | 1 -
FileSets/v3.40~17/PageMain.qml | 1 -
FileSets/v3.40~17/PageSettingsDisplay.qml | 1 -
FileSets/v3.40~17/PageSettingsGenerator.qml | 1 -
FileSets/v3.40~17/PageSettingsGuiMods.qml | 1 -
FileSets/v3.40~17/PageSettingsRelay.qml | 1 -
FileSets/v3.40~17/PowerGauge.qml | 1 -
FileSets/v3.40~17/Tile.qml | 1 -
FileSets/v3.40~17/TileDigIn.qml | 1 -
FileSets/v3.40~17/TileRelay.qml | 1 -
FileSets/v3.40~17/TileText.qml | 1 -
FileSets/v3.40~17/attributes.csv | 1 -
FileSets/v3.40~17/dbus_digitalinputs.py | 1 -
FileSets/v3.40~17/dbus_generator.py | 1 -
FileSets/v3.40~17/dbus_systemcalc.py | 1 -
FileSets/v3.40~17/main.qml | 1 -
FileSets/v3.40~17/startstop.py | 1536 ----------------
FileSets/v3.40~17/startstop.py.orig | 1205 -------------
FileSets/v3.40~17/styles.css | 1 -
FileSets/v3.40~18/Battery.qml | 1 -
FileSets/v3.40~18/COMPLETE | 0
FileSets/v3.40~18/DetailAcInput.qml | 1 -
FileSets/v3.40~18/DetailInverter.qml | 1 -
FileSets/v3.40~18/DetailLoadsCombined.qml | 1 -
FileSets/v3.40~18/DetailLoadsOnInput.qml | 1 -
FileSets/v3.40~18/DetailLoadsOnOutput.qml | 1 -
FileSets/v3.40~18/HubData.qml | 1 -
FileSets/v3.40~18/LINKS_ONLY | 0
FileSets/v3.40~18/MbEditBox.qml | 1 -
FileSets/v3.40~18/MbEditBoxDateTime.qml | 1 -
FileSets/v3.40~18/MbItem.qml | 1 -
FileSets/v3.40~18/MbItemDigitalInput.qml | 1 -
FileSets/v3.40~18/MbSpinBox.qml | 1 -
FileSets/v3.40~18/MbStyle.qml | 1 -
FileSets/v3.40~18/MbSubMenu.qml | 1 -
FileSets/v3.40~18/Multi.qml | 1 -
FileSets/v3.40~18/ObjectAcConnection.qml | 1 -
.../v3.40~18/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v3.40~18/OverviewBox.qml | 1 -
FileSets/v3.40~18/OverviewConnection.qml | 1 -
FileSets/v3.40~18/OverviewConnectionEnd.qml | 1 -
FileSets/v3.40~18/OverviewFlowComplex.qml | 1 -
.../v3.40~18/OverviewGeneratorEnhanced.qml | 1 -
.../OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v3.40~18/OverviewGridParallel.qml | 1 -
FileSets/v3.40~18/OverviewHub.qml | 1 -
FileSets/v3.40~18/OverviewHubEnhanced.qml | 1 -
FileSets/v3.40~18/OverviewMobileEnhanced.qml | 1 -
FileSets/v3.40~18/OverviewSolarCharger.qml | 1 -
FileSets/v3.40~18/OverviewSolarInverter.qml | 1 -
FileSets/v3.40~18/OverviewTankDelegate.qml | 1 -
FileSets/v3.40~18/OverviewTanks.qml | 1 -
.../v3.40~18/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.40~18/PageDigitalInput.qml | 1 -
FileSets/v3.40~18/PageGenerator.qml | 1 -
FileSets/v3.40~18/PageMain.qml | 1 -
FileSets/v3.40~18/PageSettingsDisplay.qml | 1 -
FileSets/v3.40~18/PageSettingsGenerator.qml | 1 -
FileSets/v3.40~18/PageSettingsGuiMods.qml | 1 -
FileSets/v3.40~18/PageSettingsRelay.qml | 1 -
FileSets/v3.40~18/PowerGauge.qml | 1 -
FileSets/v3.40~18/Tile.qml | 1 -
FileSets/v3.40~18/TileDigIn.qml | 1 -
FileSets/v3.40~18/TileRelay.qml | 1 -
FileSets/v3.40~18/TileText.qml | 1 -
FileSets/v3.40~18/attributes.csv | 1 -
FileSets/v3.40~18/dbus_digitalinputs.py | 1 -
FileSets/v3.40~18/dbus_generator.py | 1 -
FileSets/v3.40~18/dbus_systemcalc.py | 1 -
FileSets/v3.40~18/main.qml | 1 -
FileSets/v3.40~18/startstop.py | 1 -
FileSets/v3.40~18/styles.css | 1 -
FileSets/v3.40~2/Battery.qml | 1 -
FileSets/v3.40~2/COMPLETE | 0
FileSets/v3.40~2/DetailAcInput.qml | 1 -
FileSets/v3.40~2/DetailInverter.qml | 1 -
FileSets/v3.40~2/DetailLoadsCombined.qml | 1 -
FileSets/v3.40~2/DetailLoadsOnInput.qml | 1 -
FileSets/v3.40~2/DetailLoadsOnOutput.qml | 1 -
FileSets/v3.40~2/HubData.qml | 1 -
FileSets/v3.40~2/LINKS_ONLY | 0
FileSets/v3.40~2/MbEditBox.qml | 1 -
FileSets/v3.40~2/MbEditBoxDateTime.qml | 1 -
FileSets/v3.40~2/MbItem.qml | 1 -
FileSets/v3.40~2/MbItemDigitalInput.qml | 1 -
FileSets/v3.40~2/MbSpinBox.qml | 1 -
FileSets/v3.40~2/MbStyle.qml | 1 -
FileSets/v3.40~2/MbSubMenu.qml | 1 -
FileSets/v3.40~2/Multi.qml | 1 -
FileSets/v3.40~2/ObjectAcConnection.qml | 1 -
FileSets/v3.40~2/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v3.40~2/OverviewBox.qml | 1 -
FileSets/v3.40~2/OverviewConnection.qml | 1 -
FileSets/v3.40~2/OverviewConnectionEnd.qml | 1 -
FileSets/v3.40~2/OverviewFlowComplex.qml | 1 -
.../v3.40~2/OverviewGeneratorEnhanced.qml | 1 -
.../OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v3.40~2/OverviewGridParallel.qml | 1 -
FileSets/v3.40~2/OverviewHub.qml | 1 -
FileSets/v3.40~2/OverviewHubEnhanced.qml | 1 -
FileSets/v3.40~2/OverviewMobileEnhanced.qml | 1 -
FileSets/v3.40~2/OverviewSolarCharger.qml | 1 -
FileSets/v3.40~2/OverviewSolarInverter.qml | 1 -
FileSets/v3.40~2/OverviewTankDelegate.qml | 1 -
FileSets/v3.40~2/OverviewTanks.qml | 1 -
.../v3.40~2/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.40~2/PageDigitalInput.qml | 1 -
FileSets/v3.40~2/PageGenerator.qml | 1 -
FileSets/v3.40~2/PageMain.qml | 1 -
FileSets/v3.40~2/PageSettingsDisplay.qml | 1 -
FileSets/v3.40~2/PageSettingsGenerator.qml | 1 -
FileSets/v3.40~2/PageSettingsGuiMods.qml | 1 -
FileSets/v3.40~2/PageSettingsRelay.qml | 1 -
FileSets/v3.40~2/PowerGauge.qml | 1 -
FileSets/v3.40~2/Tile.qml | 1 -
FileSets/v3.40~2/TileDigIn.qml | 1 -
FileSets/v3.40~2/TileRelay.qml | 1 -
FileSets/v3.40~2/TileText.qml | 1 -
FileSets/v3.40~2/attributes.csv | 1 -
FileSets/v3.40~2/dbus_digitalinputs.py | 1 -
FileSets/v3.40~2/dbus_generator.py | 1 -
FileSets/v3.40~2/main.qml | 1 -
FileSets/v3.40~2/startstop.py | 1 -
FileSets/v3.40~2/styles.css | 1 -
FileSets/v3.40~20/Battery.qml | 1 -
FileSets/v3.40~20/COMPLETE | 0
FileSets/v3.40~20/DetailAcInput.qml | 1 -
FileSets/v3.40~20/DetailInverter.qml | 1 -
FileSets/v3.40~20/DetailLoadsCombined.qml | 1 -
FileSets/v3.40~20/DetailLoadsOnInput.qml | 1 -
FileSets/v3.40~20/DetailLoadsOnOutput.qml | 1 -
FileSets/v3.40~20/HubData.qml | 1 -
FileSets/v3.40~20/LINKS_ONLY | 0
FileSets/v3.40~20/MbEditBox.qml | 1 -
FileSets/v3.40~20/MbEditBoxDateTime.qml | 1 -
FileSets/v3.40~20/MbItem.qml | 1 -
FileSets/v3.40~20/MbItemDigitalInput.qml | 1 -
FileSets/v3.40~20/MbSpinBox.qml | 1 -
FileSets/v3.40~20/MbStyle.qml | 1 -
FileSets/v3.40~20/MbSubMenu.qml | 1 -
FileSets/v3.40~20/Multi.qml | 1 -
FileSets/v3.40~20/ObjectAcConnection.qml | 1 -
.../v3.40~20/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v3.40~20/OverviewBox.qml | 1 -
FileSets/v3.40~20/OverviewConnection.qml | 1 -
FileSets/v3.40~20/OverviewConnectionEnd.qml | 1 -
FileSets/v3.40~20/OverviewFlowComplex.qml | 1 -
.../v3.40~20/OverviewGeneratorEnhanced.qml | 1 -
.../OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v3.40~20/OverviewGridParallel.qml | 1 -
FileSets/v3.40~20/OverviewHub.qml | 1 -
FileSets/v3.40~20/OverviewHubEnhanced.qml | 1 -
FileSets/v3.40~20/OverviewMobileEnhanced.qml | 1 -
FileSets/v3.40~20/OverviewSolarCharger.qml | 1 -
FileSets/v3.40~20/OverviewSolarInverter.qml | 1 -
FileSets/v3.40~20/OverviewTankDelegate.qml | 1 -
FileSets/v3.40~20/OverviewTanks.qml | 1 -
.../v3.40~20/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.40~20/PageDigitalInput.qml | 1 -
FileSets/v3.40~20/PageGenerator.qml | 1 -
FileSets/v3.40~20/PageMain.qml | 1 -
FileSets/v3.40~20/PageSettingsDisplay.qml | 1 -
FileSets/v3.40~20/PageSettingsGenerator.qml | 1 -
FileSets/v3.40~20/PageSettingsGuiMods.qml | 1 -
FileSets/v3.40~20/PageSettingsRelay.qml | 1 -
FileSets/v3.40~20/PowerGauge.qml | 1 -
FileSets/v3.40~20/Tile.qml | 1 -
FileSets/v3.40~20/TileDigIn.qml | 1 -
FileSets/v3.40~20/TileRelay.qml | 1 -
FileSets/v3.40~20/TileText.qml | 1 -
FileSets/v3.40~20/attributes.csv | 1 -
FileSets/v3.40~20/dbus_digitalinputs.py | 1 -
FileSets/v3.40~20/dbus_generator.py | 1 -
FileSets/v3.40~20/main.qml | 1 -
FileSets/v3.40~20/startstop.py | 1 -
FileSets/v3.40~20/styles.css | 1 -
FileSets/v3.40~21/Battery.qml | 1 -
FileSets/v3.40~21/COMPLETE | 0
FileSets/v3.40~21/DetailAcInput.qml | 1 -
FileSets/v3.40~21/DetailInverter.qml | 1 -
FileSets/v3.40~21/DetailLoadsCombined.qml | 1 -
FileSets/v3.40~21/DetailLoadsOnInput.qml | 1 -
FileSets/v3.40~21/DetailLoadsOnOutput.qml | 1 -
FileSets/v3.40~21/HubData.qml | 1 -
FileSets/v3.40~21/MbEditBox.qml | 1 -
FileSets/v3.40~21/MbEditBoxDateTime.qml | 1 -
FileSets/v3.40~21/MbItem.qml | 1 -
FileSets/v3.40~21/MbItemDigitalInput.qml | 1 -
FileSets/v3.40~21/MbSpinBox.qml | 1 -
FileSets/v3.40~21/MbStyle.qml | 1 -
FileSets/v3.40~21/MbSubMenu.qml | 1 -
FileSets/v3.40~21/Multi.qml | 1 -
FileSets/v3.40~21/ObjectAcConnection.qml | 1 -
.../v3.40~21/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v3.40~21/OverviewBox.qml | 1 -
FileSets/v3.40~21/OverviewConnection.qml | 1 -
FileSets/v3.40~21/OverviewConnectionEnd.qml | 1 -
FileSets/v3.40~21/OverviewFlowComplex.qml | 1 -
.../OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v3.40~21/OverviewGridParallel.qml | 1 -
FileSets/v3.40~21/OverviewHub.qml | 1 -
FileSets/v3.40~21/OverviewHubEnhanced.qml | 1 -
FileSets/v3.40~21/OverviewMobileEnhanced.qml | 1 -
FileSets/v3.40~21/OverviewSolarCharger.qml | 1 -
FileSets/v3.40~21/OverviewSolarInverter.qml | 1 -
FileSets/v3.40~21/OverviewTankDelegate.qml | 1 -
FileSets/v3.40~21/OverviewTanks.qml | 1 -
.../v3.40~21/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.40~21/PageDigitalInput.qml | 1 -
FileSets/v3.40~21/PageGenerator.qml | 223 ---
FileSets/v3.40~21/PageMain.qml | 1 -
FileSets/v3.40~21/PageSettingsDisplay.qml | 1 -
FileSets/v3.40~21/PageSettingsGenerator.qml | 1 -
FileSets/v3.40~21/PageSettingsGuiMods.qml | 1 -
FileSets/v3.40~21/PageSettingsRelay.qml | 1 -
FileSets/v3.40~21/PowerGauge.qml | 1 -
FileSets/v3.40~21/Tile.qml | 1 -
FileSets/v3.40~21/TileDigIn.qml | 1 -
FileSets/v3.40~21/TileRelay.qml | 1 -
FileSets/v3.40~21/TileText.qml | 1 -
FileSets/v3.40~21/attributes.csv | 1 -
FileSets/v3.40~21/dbus_digitalinputs.py | 1 -
FileSets/v3.40~21/dbus_generator.py | 1 -
FileSets/v3.40~21/dbus_systemcalc.py | 1 -
FileSets/v3.40~21/main.qml | 1 -
FileSets/v3.40~21/startstop.py | 1 -
FileSets/v3.40~21/styles.css | 1 -
FileSets/v3.40~23/Battery.qml | 1 -
FileSets/v3.40~23/COMPLETE | 0
FileSets/v3.40~23/DetailAcInput.qml | 1 -
FileSets/v3.40~23/DetailInverter.qml | 1 -
FileSets/v3.40~23/DetailLoadsCombined.qml | 1 -
FileSets/v3.40~23/DetailLoadsOnInput.qml | 1 -
FileSets/v3.40~23/DetailLoadsOnOutput.qml | 1 -
FileSets/v3.40~23/HubData.qml | 1 -
FileSets/v3.40~23/LINKS_ONLY | 0
FileSets/v3.40~23/MbEditBox.qml | 1 -
FileSets/v3.40~23/MbEditBoxDateTime.qml | 1 -
FileSets/v3.40~23/MbItem.qml | 1 -
FileSets/v3.40~23/MbItemDigitalInput.qml | 1 -
FileSets/v3.40~23/MbSpinBox.qml | 1 -
FileSets/v3.40~23/MbStyle.qml | 1 -
FileSets/v3.40~23/MbSubMenu.qml | 1 -
FileSets/v3.40~23/Multi.qml | 1 -
FileSets/v3.40~23/ObjectAcConnection.qml | 1 -
.../v3.40~23/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v3.40~23/OverviewBox.qml | 1 -
FileSets/v3.40~23/OverviewConnection.qml | 1 -
FileSets/v3.40~23/OverviewConnectionEnd.qml | 1 -
FileSets/v3.40~23/OverviewFlowComplex.qml | 1 -
.../v3.40~23/OverviewGeneratorEnhanced.qml | 1 -
.../OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v3.40~23/OverviewGridParallel.qml | 1 -
FileSets/v3.40~23/OverviewHub.qml | 1 -
FileSets/v3.40~23/OverviewHubEnhanced.qml | 1 -
FileSets/v3.40~23/OverviewMobileEnhanced.qml | 1 -
FileSets/v3.40~23/OverviewSolarCharger.qml | 1 -
FileSets/v3.40~23/OverviewSolarInverter.qml | 1 -
FileSets/v3.40~23/OverviewTankDelegate.qml | 1 -
FileSets/v3.40~23/OverviewTanks.qml | 1 -
.../v3.40~23/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.40~23/PageDigitalInput.qml | 1 -
FileSets/v3.40~23/PageGenerator.qml | 1 -
FileSets/v3.40~23/PageMain.qml | 1 -
FileSets/v3.40~23/PageSettingsDisplay.qml | 1 -
FileSets/v3.40~23/PageSettingsGenerator.qml | 1 -
FileSets/v3.40~23/PageSettingsGuiMods.qml | 1 -
FileSets/v3.40~23/PageSettingsRelay.qml | 1 -
FileSets/v3.40~23/PowerGauge.qml | 1 -
FileSets/v3.40~23/Tile.qml | 1 -
FileSets/v3.40~23/TileDigIn.qml | 1 -
FileSets/v3.40~23/TileRelay.qml | 1 -
FileSets/v3.40~23/TileText.qml | 1 -
FileSets/v3.40~23/attributes.csv | 1 -
FileSets/v3.40~23/dbus_digitalinputs.py | 1 -
FileSets/v3.40~23/dbus_generator.py | 1 -
FileSets/v3.40~23/dbus_systemcalc.py | 1 -
FileSets/v3.40~23/main.qml | 1 -
FileSets/v3.40~23/startstop.py | 1 -
FileSets/v3.40~23/styles.css | 1 -
FileSets/v3.40~26/Battery.qml | 1 -
FileSets/v3.40~26/COMPLETE | 0
FileSets/v3.40~26/DetailAcInput.qml | 1 -
FileSets/v3.40~26/DetailInverter.qml | 1 -
FileSets/v3.40~26/DetailLoadsCombined.qml | 1 -
FileSets/v3.40~26/DetailLoadsOnInput.qml | 1 -
FileSets/v3.40~26/DetailLoadsOnOutput.qml | 1 -
FileSets/v3.40~26/HubData.qml | 1 -
FileSets/v3.40~26/MbEditBox.qml | 1 -
FileSets/v3.40~26/MbEditBoxDateTime.qml | 1 -
FileSets/v3.40~26/MbItem.qml | 1 -
FileSets/v3.40~26/MbItemDigitalInput.qml | 1 -
FileSets/v3.40~26/MbSpinBox.qml | 1 -
FileSets/v3.40~26/MbStyle.qml | 1 -
FileSets/v3.40~26/MbSubMenu.qml | 1 -
FileSets/v3.40~26/Multi.qml | 1 -
FileSets/v3.40~26/ObjectAcConnection.qml | 1 -
.../v3.40~26/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v3.40~26/OverviewBox.qml | 1 -
FileSets/v3.40~26/OverviewConnection.qml | 1 -
FileSets/v3.40~26/OverviewConnectionEnd.qml | 1 -
FileSets/v3.40~26/OverviewFlowComplex.qml | 1 -
.../v3.40~26/OverviewGeneratorEnhanced.qml | 547 ------
.../OverviewGeneratorEnhanced.qml.orig | 147 --
.../OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v3.40~26/OverviewGridParallel.qml | 1 -
FileSets/v3.40~26/OverviewHub.qml | 1 -
FileSets/v3.40~26/OverviewHubEnhanced.qml | 1 -
FileSets/v3.40~26/OverviewMobileEnhanced.qml | 1 -
FileSets/v3.40~26/OverviewSolarCharger.qml | 1 -
FileSets/v3.40~26/OverviewSolarInverter.qml | 1 -
FileSets/v3.40~26/OverviewTankDelegate.qml | 1 -
FileSets/v3.40~26/OverviewTanks.qml | 1 -
.../v3.40~26/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.40~26/PageDigitalInput.qml | 1 -
FileSets/v3.40~26/PageGenerator.qml.orig | 147 --
FileSets/v3.40~26/PageMain.qml | 1 -
FileSets/v3.40~26/PageSettingsDisplay.qml | 1 -
FileSets/v3.40~26/PageSettingsGenerator.qml | 1 -
FileSets/v3.40~26/PageSettingsGuiMods.qml | 1 -
FileSets/v3.40~26/PageSettingsRelay.qml | 1 -
FileSets/v3.40~26/PowerGauge.qml | 1 -
FileSets/v3.40~26/Tile.qml | 1 -
FileSets/v3.40~26/TileDigIn.qml | 1 -
FileSets/v3.40~26/TileRelay.qml | 1 -
FileSets/v3.40~26/TileText.qml | 1 -
FileSets/v3.40~26/dbus_digitalinputs.py | 1 -
FileSets/v3.40~26/dbus_generator.py | 1 -
FileSets/v3.40~26/dbus_systemcalc.py | 1 -
FileSets/v3.40~26/main.qml | 1 -
FileSets/v3.40~26/startstop.py | 1 -
FileSets/v3.40~26/styles.css | 1 -
FileSets/v3.40~27/Battery.qml | 1 -
FileSets/v3.40~27/COMPLETE | 0
FileSets/v3.40~27/DetailAcInput.qml | 1 -
FileSets/v3.40~27/DetailInverter.qml | 1 -
FileSets/v3.40~27/DetailLoadsCombined.qml | 1 -
FileSets/v3.40~27/DetailLoadsOnInput.qml | 1 -
FileSets/v3.40~27/DetailLoadsOnOutput.qml | 1 -
FileSets/v3.40~27/HubData.qml | 1 -
FileSets/v3.40~27/LINKS_ONLY | 0
FileSets/v3.40~27/MbEditBox.qml | 1 -
FileSets/v3.40~27/MbEditBoxDateTime.qml | 1 -
FileSets/v3.40~27/MbItem.qml | 1 -
FileSets/v3.40~27/MbItemDigitalInput.qml | 1 -
FileSets/v3.40~27/MbSpinBox.qml | 1 -
FileSets/v3.40~27/MbStyle.qml | 1 -
FileSets/v3.40~27/MbSubMenu.qml | 1 -
FileSets/v3.40~27/Multi.qml | 1 -
FileSets/v3.40~27/ObjectAcConnection.qml | 1 -
.../v3.40~27/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v3.40~27/OverviewBox.qml | 1 -
FileSets/v3.40~27/OverviewConnection.qml | 1 -
FileSets/v3.40~27/OverviewConnectionEnd.qml | 1 -
FileSets/v3.40~27/OverviewFlowComplex.qml | 1 -
.../v3.40~27/OverviewGeneratorEnhanced.qml | 1 -
.../OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v3.40~27/OverviewGridParallel.qml | 1 -
FileSets/v3.40~27/OverviewHub.qml | 1 -
FileSets/v3.40~27/OverviewHubEnhanced.qml | 1 -
FileSets/v3.40~27/OverviewMobileEnhanced.qml | 1 -
FileSets/v3.40~27/OverviewSolarCharger.qml | 1 -
FileSets/v3.40~27/OverviewSolarInverter.qml | 1 -
FileSets/v3.40~27/OverviewTankDelegate.qml | 1 -
FileSets/v3.40~27/OverviewTanks.qml | 1 -
.../v3.40~27/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.40~27/PageDigitalInput.qml | 1 -
FileSets/v3.40~27/PageGenerator.qml | 1 -
FileSets/v3.40~27/PageMain.qml | 1 -
FileSets/v3.40~27/PageSettingsDisplay.qml | 1 -
FileSets/v3.40~27/PageSettingsGenerator.qml | 1 -
FileSets/v3.40~27/PageSettingsGuiMods.qml | 1 -
FileSets/v3.40~27/PageSettingsRelay.qml | 1 -
FileSets/v3.40~27/PowerGauge.qml | 1 -
FileSets/v3.40~27/Tile.qml | 1 -
FileSets/v3.40~27/TileDigIn.qml | 1 -
FileSets/v3.40~27/TileRelay.qml | 1 -
FileSets/v3.40~27/TileText.qml | 1 -
FileSets/v3.40~27/attributes.csv | 1 -
FileSets/v3.40~27/dbus_digitalinputs.py | 1 -
FileSets/v3.40~27/dbus_generator.py | 1 -
FileSets/v3.40~27/main.qml | 1 -
FileSets/v3.40~27/startstop.py | 1 -
FileSets/v3.40~27/styles.css | 1 -
FileSets/v3.40~29/Battery.qml | 1 -
FileSets/v3.40~29/COMPLETE | 0
FileSets/v3.40~29/DetailAcInput.qml | 1 -
FileSets/v3.40~29/DetailInverter.qml | 1 -
FileSets/v3.40~29/DetailLoadsCombined.qml | 1 -
FileSets/v3.40~29/DetailLoadsOnInput.qml | 1 -
FileSets/v3.40~29/DetailLoadsOnOutput.qml | 1 -
FileSets/v3.40~29/HubData.qml | 1 -
FileSets/v3.40~29/LINKS_ONLY | 0
FileSets/v3.40~29/MbEditBox.qml | 1 -
FileSets/v3.40~29/MbEditBoxDateTime.qml | 1 -
FileSets/v3.40~29/MbItem.qml | 1 -
FileSets/v3.40~29/MbItemDigitalInput.qml | 1 -
FileSets/v3.40~29/MbSpinBox.qml | 1 -
FileSets/v3.40~29/MbStyle.qml | 1 -
FileSets/v3.40~29/MbSubMenu.qml | 1 -
FileSets/v3.40~29/Multi.qml | 1 -
FileSets/v3.40~29/ObjectAcConnection.qml | 1 -
.../v3.40~29/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v3.40~29/OverviewBox.qml | 1 -
FileSets/v3.40~29/OverviewConnection.qml | 1 -
FileSets/v3.40~29/OverviewConnectionEnd.qml | 1 -
FileSets/v3.40~29/OverviewFlowComplex.qml | 1 -
.../v3.40~29/OverviewGeneratorEnhanced.qml | 1 -
.../OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v3.40~29/OverviewGridParallel.qml | 1 -
FileSets/v3.40~29/OverviewHub.qml | 1 -
FileSets/v3.40~29/OverviewHubEnhanced.qml | 1 -
FileSets/v3.40~29/OverviewMobileEnhanced.qml | 1 -
FileSets/v3.40~29/OverviewSolarCharger.qml | 1 -
FileSets/v3.40~29/OverviewSolarInverter.qml | 1 -
FileSets/v3.40~29/OverviewTankDelegate.qml | 1 -
FileSets/v3.40~29/OverviewTanks.qml | 1 -
.../v3.40~29/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.40~29/PageDigitalInput.qml | 1 -
FileSets/v3.40~29/PageGenerator.qml | 1 -
FileSets/v3.40~29/PageMain.qml | 1 -
FileSets/v3.40~29/PageSettingsDisplay.qml | 1 -
FileSets/v3.40~29/PageSettingsGenerator.qml | 1 -
FileSets/v3.40~29/PageSettingsGuiMods.qml | 1 -
FileSets/v3.40~29/PageSettingsRelay.qml | 1 -
FileSets/v3.40~29/PowerGauge.qml | 1 -
FileSets/v3.40~29/Tile.qml | 1 -
FileSets/v3.40~29/TileDigIn.qml | 1 -
FileSets/v3.40~29/TileRelay.qml | 1 -
FileSets/v3.40~29/TileText.qml | 1 -
FileSets/v3.40~29/attributes.csv | 1 -
FileSets/v3.40~29/dbus_digitalinputs.py | 1 -
FileSets/v3.40~29/dbus_generator.py | 1 -
FileSets/v3.40~29/main.qml | 1 -
FileSets/v3.40~29/startstop.py | 1 -
FileSets/v3.40~29/styles.css | 1 -
FileSets/v3.40~30/Battery.qml | 1 -
FileSets/v3.40~30/COMPLETE | 0
FileSets/v3.40~30/DetailAcInput.qml | 1 -
FileSets/v3.40~30/DetailInverter.qml | 1 -
FileSets/v3.40~30/DetailLoadsCombined.qml | 1 -
FileSets/v3.40~30/DetailLoadsOnInput.qml | 1 -
FileSets/v3.40~30/DetailLoadsOnOutput.qml | 1 -
FileSets/v3.40~30/HubData.qml | 1 -
FileSets/v3.40~30/LINKS_ONLY | 0
FileSets/v3.40~30/MbEditBox.qml | 1 -
FileSets/v3.40~30/MbEditBoxDateTime.qml | 1 -
FileSets/v3.40~30/MbItem.qml | 1 -
FileSets/v3.40~30/MbItemDigitalInput.qml | 1 -
FileSets/v3.40~30/MbSpinBox.qml | 1 -
FileSets/v3.40~30/MbStyle.qml | 1 -
FileSets/v3.40~30/MbSubMenu.qml | 1 -
FileSets/v3.40~30/Multi.qml | 1 -
FileSets/v3.40~30/ObjectAcConnection.qml | 1 -
.../v3.40~30/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v3.40~30/OverviewBox.qml | 1 -
FileSets/v3.40~30/OverviewConnection.qml | 1 -
FileSets/v3.40~30/OverviewConnectionEnd.qml | 1 -
FileSets/v3.40~30/OverviewFlowComplex.qml | 1 -
.../v3.40~30/OverviewGeneratorEnhanced.qml | 1 -
.../OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v3.40~30/OverviewGridParallel.qml | 1 -
FileSets/v3.40~30/OverviewHub.qml | 1 -
FileSets/v3.40~30/OverviewHubEnhanced.qml | 1 -
FileSets/v3.40~30/OverviewMobileEnhanced.qml | 1 -
FileSets/v3.40~30/OverviewSolarCharger.qml | 1 -
FileSets/v3.40~30/OverviewSolarInverter.qml | 1 -
FileSets/v3.40~30/OverviewTankDelegate.qml | 1 -
FileSets/v3.40~30/OverviewTanks.qml | 1 -
.../v3.40~30/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.40~30/PageDigitalInput.qml | 1 -
FileSets/v3.40~30/PageGenerator.qml | 1 -
FileSets/v3.40~30/PageMain.qml | 1 -
FileSets/v3.40~30/PageSettingsDisplay.qml | 1 -
FileSets/v3.40~30/PageSettingsGenerator.qml | 1 -
FileSets/v3.40~30/PageSettingsGuiMods.qml | 1 -
FileSets/v3.40~30/PageSettingsRelay.qml | 1 -
FileSets/v3.40~30/PowerGauge.qml | 1 -
FileSets/v3.40~30/Tile.qml | 1 -
FileSets/v3.40~30/TileDigIn.qml | 1 -
FileSets/v3.40~30/TileRelay.qml | 1 -
FileSets/v3.40~30/TileText.qml | 1 -
FileSets/v3.40~30/attributes.csv | 1 -
FileSets/v3.40~30/dbus_digitalinputs.py | 1 -
FileSets/v3.40~30/dbus_generator.py | 1 -
FileSets/v3.40~30/main.qml | 1 -
FileSets/v3.40~30/startstop.py | 1 -
FileSets/v3.40~30/styles.css | 1 -
FileSets/v3.40~32/Battery.qml | 1 -
FileSets/v3.40~32/COMPLETE | 0
FileSets/v3.40~32/DetailAcInput.qml | 1 -
FileSets/v3.40~32/DetailInverter.qml | 1 -
FileSets/v3.40~32/DetailLoadsCombined.qml | 1 -
FileSets/v3.40~32/DetailLoadsOnInput.qml | 1 -
FileSets/v3.40~32/DetailLoadsOnOutput.qml | 1 -
FileSets/v3.40~32/HubData.qml | 1 -
FileSets/v3.40~32/LINKS_ONLY | 0
FileSets/v3.40~32/MbEditBox.qml | 1 -
FileSets/v3.40~32/MbEditBoxDateTime.qml | 1 -
FileSets/v3.40~32/MbItem.qml | 1 -
FileSets/v3.40~32/MbItemDigitalInput.qml | 1 -
FileSets/v3.40~32/MbSpinBox.qml | 1 -
FileSets/v3.40~32/MbStyle.qml | 1 -
FileSets/v3.40~32/MbSubMenu.qml | 1 -
FileSets/v3.40~32/Multi.qml | 1 -
FileSets/v3.40~32/ObjectAcConnection.qml | 1 -
.../v3.40~32/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v3.40~32/OverviewBox.qml | 1 -
FileSets/v3.40~32/OverviewConnection.qml | 1 -
FileSets/v3.40~32/OverviewConnectionEnd.qml | 1 -
FileSets/v3.40~32/OverviewFlowComplex.qml | 1 -
.../v3.40~32/OverviewGeneratorEnhanced.qml | 1 -
.../OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v3.40~32/OverviewGridParallel.qml | 1 -
FileSets/v3.40~32/OverviewHub.qml | 1 -
FileSets/v3.40~32/OverviewHubEnhanced.qml | 1 -
FileSets/v3.40~32/OverviewMobileEnhanced.qml | 1 -
FileSets/v3.40~32/OverviewSolarCharger.qml | 1 -
FileSets/v3.40~32/OverviewSolarInverter.qml | 1 -
FileSets/v3.40~32/OverviewTankDelegate.qml | 1 -
FileSets/v3.40~32/OverviewTanks.qml | 1 -
.../v3.40~32/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.40~32/PageDigitalInput.qml | 1 -
FileSets/v3.40~32/PageGenerator.qml | 1 -
FileSets/v3.40~32/PageMain.qml | 1 -
FileSets/v3.40~32/PageSettingsDisplay.qml | 1 -
FileSets/v3.40~32/PageSettingsGenerator.qml | 1 -
FileSets/v3.40~32/PageSettingsGuiMods.qml | 1 -
FileSets/v3.40~32/PageSettingsRelay.qml | 1 -
FileSets/v3.40~32/PowerGauge.qml | 1 -
FileSets/v3.40~32/Tile.qml | 1 -
FileSets/v3.40~32/TileDigIn.qml | 1 -
FileSets/v3.40~32/TileRelay.qml | 1 -
FileSets/v3.40~32/TileText.qml | 1 -
FileSets/v3.40~32/dbus_digitalinputs.py | 1 -
FileSets/v3.40~32/dbus_generator.py | 1 -
FileSets/v3.40~32/dbus_systemcalc.py | 1 -
FileSets/v3.40~32/main.qml | 1 -
FileSets/v3.40~32/startstop.py | 1 -
FileSets/v3.40~32/styles.css | 1 -
FileSets/v3.40~33/Battery.qml | 1 -
FileSets/v3.40~33/COMPLETE | 0
FileSets/v3.40~33/DetailAcInput.qml | 1 -
FileSets/v3.40~33/DetailInverter.qml | 1 -
FileSets/v3.40~33/DetailLoadsCombined.qml | 1 -
FileSets/v3.40~33/DetailLoadsOnInput.qml | 1 -
FileSets/v3.40~33/DetailLoadsOnOutput.qml | 1 -
FileSets/v3.40~33/HubData.qml | 1 -
FileSets/v3.40~33/LINKS_ONLY | 0
FileSets/v3.40~33/MbEditBox.qml | 1 -
FileSets/v3.40~33/MbEditBoxDateTime.qml | 1 -
FileSets/v3.40~33/MbItem.qml | 1 -
FileSets/v3.40~33/MbItemDigitalInput.qml | 1 -
FileSets/v3.40~33/MbSpinBox.qml | 1 -
FileSets/v3.40~33/MbStyle.qml | 1 -
FileSets/v3.40~33/MbSubMenu.qml | 1 -
FileSets/v3.40~33/Multi.qml | 1 -
FileSets/v3.40~33/ObjectAcConnection.qml | 1 -
.../v3.40~33/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v3.40~33/OverviewBox.qml | 1 -
FileSets/v3.40~33/OverviewConnection.qml | 1 -
FileSets/v3.40~33/OverviewConnectionEnd.qml | 1 -
FileSets/v3.40~33/OverviewFlowComplex.qml | 1 -
.../v3.40~33/OverviewGeneratorEnhanced.qml | 1 -
.../OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v3.40~33/OverviewGridParallel.qml | 1 -
FileSets/v3.40~33/OverviewHub.qml | 1 -
FileSets/v3.40~33/OverviewHubEnhanced.qml | 1 -
FileSets/v3.40~33/OverviewMobileEnhanced.qml | 1 -
FileSets/v3.40~33/OverviewSolarCharger.qml | 1 -
FileSets/v3.40~33/OverviewSolarInverter.qml | 1 -
FileSets/v3.40~33/OverviewTankDelegate.qml | 1 -
FileSets/v3.40~33/OverviewTanks.qml | 1 -
.../v3.40~33/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.40~33/PageDigitalInput.qml | 1 -
FileSets/v3.40~33/PageGenerator.qml | 1 -
FileSets/v3.40~33/PageMain.qml | 1 -
FileSets/v3.40~33/PageSettingsDisplay.qml | 1 -
FileSets/v3.40~33/PageSettingsGenerator.qml | 1 -
FileSets/v3.40~33/PageSettingsGuiMods.qml | 1 -
FileSets/v3.40~33/PageSettingsRelay.qml | 1 -
FileSets/v3.40~33/PowerGauge.qml | 1 -
FileSets/v3.40~33/Tile.qml | 1 -
FileSets/v3.40~33/TileDigIn.qml | 1 -
FileSets/v3.40~33/TileRelay.qml | 1 -
FileSets/v3.40~33/TileText.qml | 1 -
FileSets/v3.40~33/attributes.csv.orig | 740 --------
FileSets/v3.40~33/dbus_digitalinputs.py | 1 -
FileSets/v3.40~33/dbus_generator.py | 1 -
FileSets/v3.40~33/main.qml | 1 -
FileSets/v3.40~33/startstop.py | 1 -
FileSets/v3.40~33/styles.css | 1 -
FileSets/v3.40~34/Battery.qml | 1 -
FileSets/v3.40~34/COMPLETE | 0
FileSets/v3.40~34/DetailAcInput.qml | 1 -
FileSets/v3.40~34/DetailInverter.qml | 1 -
FileSets/v3.40~34/DetailLoadsCombined.qml | 1 -
FileSets/v3.40~34/DetailLoadsOnInput.qml | 1 -
FileSets/v3.40~34/DetailLoadsOnOutput.qml | 1 -
FileSets/v3.40~34/HubData.qml | 1 -
FileSets/v3.40~34/LINKS_ONLY | 0
FileSets/v3.40~34/MbEditBox.qml | 1 -
FileSets/v3.40~34/MbEditBoxDateTime.qml | 1 -
FileSets/v3.40~34/MbItem.qml | 1 -
FileSets/v3.40~34/MbItemDigitalInput.qml | 1 -
FileSets/v3.40~34/MbSpinBox.qml | 1 -
FileSets/v3.40~34/MbStyle.qml | 1 -
FileSets/v3.40~34/MbSubMenu.qml | 1 -
FileSets/v3.40~34/Multi.qml | 1 -
FileSets/v3.40~34/ObjectAcConnection.qml | 1 -
.../v3.40~34/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v3.40~34/OverviewBox.qml | 1 -
FileSets/v3.40~34/OverviewConnection.qml | 1 -
FileSets/v3.40~34/OverviewConnectionEnd.qml | 1 -
FileSets/v3.40~34/OverviewFlowComplex.qml | 1 -
.../v3.40~34/OverviewGeneratorEnhanced.qml | 1 -
.../OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v3.40~34/OverviewGridParallel.qml | 1 -
FileSets/v3.40~34/OverviewHub.qml | 1 -
FileSets/v3.40~34/OverviewHubEnhanced.qml | 1 -
FileSets/v3.40~34/OverviewMobileEnhanced.qml | 1 -
FileSets/v3.40~34/OverviewSolarCharger.qml | 1 -
FileSets/v3.40~34/OverviewSolarInverter.qml | 1 -
FileSets/v3.40~34/OverviewTankDelegate.qml | 1 -
FileSets/v3.40~34/OverviewTanks.qml | 1 -
.../v3.40~34/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.40~34/PageDigitalInput.qml | 1 -
FileSets/v3.40~34/PageGenerator.qml | 1 -
FileSets/v3.40~34/PageMain.qml | 1 -
FileSets/v3.40~34/PageSettingsDisplay.qml | 1 -
FileSets/v3.40~34/PageSettingsGenerator.qml | 1 -
FileSets/v3.40~34/PageSettingsGuiMods.qml | 1 -
FileSets/v3.40~34/PageSettingsRelay.qml | 1 -
FileSets/v3.40~34/PowerGauge.qml | 1 -
FileSets/v3.40~34/Tile.qml | 1 -
FileSets/v3.40~34/TileDigIn.qml | 1 -
FileSets/v3.40~34/TileRelay.qml | 1 -
FileSets/v3.40~34/TileText.qml | 1 -
FileSets/v3.40~34/dbus_digitalinputs.py | 1 -
FileSets/v3.40~34/dbus_generator.py | 1 -
FileSets/v3.40~34/main.qml | 1 -
FileSets/v3.40~34/startstop.py | 1 -
FileSets/v3.40~34/styles.css | 1 -
FileSets/v3.40~35/COMPLETE | 0
FileSets/v3.40~35/DetailAcInput.qml | 1 -
FileSets/v3.40~35/DetailInverter.qml | 1 -
FileSets/v3.40~35/DetailLoadsCombined.qml | 1 -
FileSets/v3.40~35/DetailLoadsOnInput.qml | 1 -
FileSets/v3.40~35/DetailLoadsOnOutput.qml | 1 -
FileSets/v3.40~35/HubData.qml | 1 -
FileSets/v3.40~35/LINKS_ONLY | 0
FileSets/v3.40~35/ObjectAcConnection.qml | 1 -
.../v3.40~35/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v3.40~35/OverviewFlowComplex.qml | 1 -
.../v3.40~35/OverviewGeneratorEnhanced.qml | 1 -
.../OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v3.40~35/OverviewGridParallel.qml | 1 -
FileSets/v3.40~35/OverviewHub.qml | 1 -
FileSets/v3.40~35/OverviewHubEnhanced.qml | 1 -
FileSets/v3.40~35/OverviewMobileEnhanced.qml | 1 -
.../v3.40~35/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.40~35/PageGenerator.qml | 1 -
FileSets/v3.40~35/PageSettingsGenerator.qml | 1 -
FileSets/v3.40~35/PageSettingsGuiMods.qml | 1 -
FileSets/v3.40~35/PageSettingsRelay.qml | 1 -
FileSets/v3.40~35/PowerGauge.qml | 1 -
FileSets/v3.40~35/TileDigIn.qml | 1 -
FileSets/v3.40~35/TileRelay.qml | 1 -
FileSets/v3.40~35/dbus_digitalinputs.py | 1 -
FileSets/v3.40~35/dbus_generator.py | 1 -
FileSets/v3.40~35/startstop.py | 1 -
FileSets/v3.40~37/COMPLETE | 0
FileSets/v3.40~37/DetailAcInput.qml | 1 -
FileSets/v3.40~37/DetailInverter.qml | 1 -
FileSets/v3.40~37/DetailLoadsCombined.qml | 1 -
FileSets/v3.40~37/DetailLoadsOnInput.qml | 1 -
FileSets/v3.40~37/DetailLoadsOnOutput.qml | 1 -
FileSets/v3.40~37/HubData.qml | 1 -
FileSets/v3.40~37/ObjectAcConnection.qml | 1 -
.../v3.40~37/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v3.40~37/OverviewFlowComplex.qml | 1 -
.../v3.40~37/OverviewGeneratorEnhanced.qml | 1 -
.../OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v3.40~37/OverviewGridParallel.qml | 1 -
FileSets/v3.40~37/OverviewHub.qml | 1 -
FileSets/v3.40~37/OverviewHubEnhanced.qml | 1 -
FileSets/v3.40~37/OverviewMobileEnhanced.qml | 1 -
.../v3.40~37/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.40~37/PageGenerator.qml | 1 -
FileSets/v3.40~37/PageSettingsGenerator.qml | 1 -
FileSets/v3.40~37/PageSettingsGuiMods.qml | 1 -
FileSets/v3.40~37/PageSettingsRelay.qml | 1 -
FileSets/v3.40~37/PowerGauge.qml | 1 -
FileSets/v3.40~37/TileDigIn.qml | 1 -
FileSets/v3.40~37/TileRelay.qml | 1 -
FileSets/v3.40~37/dbus_digitalinputs.py | 1 -
FileSets/v3.40~37/dbus_generator.py | 1 -
FileSets/v3.40~37/startstop.py | 1566 ----------------
FileSets/v3.40~39/COMPLETE | 0
FileSets/v3.40~39/DetailAcInput.qml | 606 -------
FileSets/v3.40~39/DetailInverter.qml | 653 -------
FileSets/v3.40~39/DetailLoadsCombined.qml | 146 --
FileSets/v3.40~39/DetailLoadsOnInput.qml | 146 --
FileSets/v3.40~39/DetailLoadsOnOutput.qml | 151 --
.../v3.40~39/OverviewGeneratorEnhanced.qml | 1 -
.../v3.40~39/OverviewTanksTempsDigInputs.qml | 207 ---
FileSets/v3.40~39/PageGenerator.qml | 1 -
FileSets/v3.40~39/TileDigIn.qml | 133 --
FileSets/v3.40~5/Battery.qml | 1 -
FileSets/v3.40~5/COMPLETE | 0
FileSets/v3.40~5/DetailAcInput.qml | 1 -
FileSets/v3.40~5/DetailInverter.qml | 1 -
FileSets/v3.40~5/DetailLoadsCombined.qml | 1 -
FileSets/v3.40~5/DetailLoadsOnInput.qml | 1 -
FileSets/v3.40~5/DetailLoadsOnOutput.qml | 1 -
FileSets/v3.40~5/HubData.qml | 1 -
FileSets/v3.40~5/LINKS_ONLY | 0
FileSets/v3.40~5/MbEditBox.qml | 1 -
FileSets/v3.40~5/MbEditBoxDateTime.qml | 1 -
FileSets/v3.40~5/MbItem.qml | 1 -
FileSets/v3.40~5/MbItemDigitalInput.qml | 1 -
FileSets/v3.40~5/MbSpinBox.qml | 1 -
FileSets/v3.40~5/MbStyle.qml | 1 -
FileSets/v3.40~5/MbSubMenu.qml | 1 -
FileSets/v3.40~5/Multi.qml | 1 -
FileSets/v3.40~5/ObjectAcConnection.qml | 1 -
FileSets/v3.40~5/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v3.40~5/OverviewBox.qml | 1 -
FileSets/v3.40~5/OverviewConnection.qml | 1 -
FileSets/v3.40~5/OverviewConnectionEnd.qml | 1 -
FileSets/v3.40~5/OverviewFlowComplex.qml | 1 -
.../v3.40~5/OverviewGeneratorEnhanced.qml | 1 -
.../OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v3.40~5/OverviewGridParallel.qml | 1 -
FileSets/v3.40~5/OverviewHub.qml | 1 -
FileSets/v3.40~5/OverviewHubEnhanced.qml | 1 -
FileSets/v3.40~5/OverviewMobileEnhanced.qml | 1 -
FileSets/v3.40~5/OverviewSolarCharger.qml | 1 -
FileSets/v3.40~5/OverviewSolarInverter.qml | 1 -
FileSets/v3.40~5/OverviewTankDelegate.qml | 1 -
FileSets/v3.40~5/OverviewTanks.qml | 1 -
.../v3.40~5/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.40~5/PageDigitalInput.qml | 1 -
FileSets/v3.40~5/PageGenerator.qml | 1 -
FileSets/v3.40~5/PageMain.qml | 1 -
FileSets/v3.40~5/PageSettingsDisplay.qml | 1 -
FileSets/v3.40~5/PageSettingsGenerator.qml | 1 -
FileSets/v3.40~5/PageSettingsGuiMods.qml | 1 -
FileSets/v3.40~5/PageSettingsRelay.qml | 1 -
FileSets/v3.40~5/PowerGauge.qml | 1 -
FileSets/v3.40~5/Tile.qml | 1 -
FileSets/v3.40~5/TileDigIn.qml | 1 -
FileSets/v3.40~5/TileRelay.qml | 1 -
FileSets/v3.40~5/TileText.qml | 1 -
FileSets/v3.40~5/attributes.csv | 1 -
FileSets/v3.40~5/dbus_digitalinputs.py | 1 -
FileSets/v3.40~5/dbus_generator.py | 1 -
FileSets/v3.40~5/dbus_systemcalc.py | 1 -
FileSets/v3.40~5/main.qml | 1 -
FileSets/v3.40~5/startstop.py | 1 -
FileSets/v3.40~5/styles.css | 1 -
FileSets/v3.40~6/Battery.qml | 1 -
FileSets/v3.40~6/COMPLETE | 0
FileSets/v3.40~6/DetailAcInput.qml | 1 -
FileSets/v3.40~6/DetailInverter.qml | 1 -
FileSets/v3.40~6/DetailLoadsCombined.qml | 1 -
FileSets/v3.40~6/DetailLoadsOnInput.qml | 1 -
FileSets/v3.40~6/DetailLoadsOnOutput.qml | 1 -
FileSets/v3.40~6/HubData.qml | 1 -
FileSets/v3.40~6/LINKS_ONLY | 0
FileSets/v3.40~6/MbEditBox.qml | 1 -
FileSets/v3.40~6/MbEditBoxDateTime.qml | 1 -
FileSets/v3.40~6/MbItem.qml | 1 -
FileSets/v3.40~6/MbItemDigitalInput.qml | 1 -
FileSets/v3.40~6/MbSpinBox.qml | 1 -
FileSets/v3.40~6/MbStyle.qml | 1 -
FileSets/v3.40~6/MbSubMenu.qml | 1 -
FileSets/v3.40~6/Multi.qml | 1 -
FileSets/v3.40~6/ObjectAcConnection.qml | 1 -
FileSets/v3.40~6/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v3.40~6/OverviewBox.qml | 1 -
FileSets/v3.40~6/OverviewConnection.qml | 1 -
FileSets/v3.40~6/OverviewConnectionEnd.qml | 1 -
FileSets/v3.40~6/OverviewFlowComplex.qml | 1 -
.../v3.40~6/OverviewGeneratorEnhanced.qml | 1 -
.../OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v3.40~6/OverviewGridParallel.qml | 1 -
FileSets/v3.40~6/OverviewHub.qml | 1 -
FileSets/v3.40~6/OverviewHubEnhanced.qml | 1 -
FileSets/v3.40~6/OverviewMobileEnhanced.qml | 1 -
FileSets/v3.40~6/OverviewSolarCharger.qml | 1 -
FileSets/v3.40~6/OverviewSolarInverter.qml | 1 -
FileSets/v3.40~6/OverviewTankDelegate.qml | 1 -
FileSets/v3.40~6/OverviewTanks.qml | 1 -
.../v3.40~6/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.40~6/PageDigitalInput.qml | 1 -
FileSets/v3.40~6/PageGenerator.qml | 1 -
FileSets/v3.40~6/PageMain.qml | 1 -
FileSets/v3.40~6/PageSettingsDisplay.qml | 1 -
FileSets/v3.40~6/PageSettingsGenerator.qml | 1 -
FileSets/v3.40~6/PageSettingsGuiMods.qml | 1 -
FileSets/v3.40~6/PageSettingsRelay.qml | 1 -
FileSets/v3.40~6/PowerGauge.qml | 1 -
FileSets/v3.40~6/Tile.qml | 1 -
FileSets/v3.40~6/TileDigIn.qml | 1 -
FileSets/v3.40~6/TileRelay.qml | 1 -
FileSets/v3.40~6/TileText.qml | 1 -
FileSets/v3.40~6/dbus_digitalinputs.py | 1 -
FileSets/v3.40~6/dbus_generator.py | 1 -
FileSets/v3.40~6/main.qml | 1 -
FileSets/v3.40~6/startstop.py | 1 -
FileSets/v3.40~6/styles.css | 1 -
FileSets/v3.40~8/Battery.qml | 1 -
FileSets/v3.40~8/COMPLETE | 0
FileSets/v3.40~8/DetailAcInput.qml | 606 -------
FileSets/v3.40~8/DetailInverter.qml | 653 -------
FileSets/v3.40~8/DetailLoadsCombined.qml | 146 --
FileSets/v3.40~8/DetailLoadsOnInput.qml | 146 --
FileSets/v3.40~8/DetailLoadsOnOutput.qml | 151 --
FileSets/v3.40~8/HubData.qml | 273 ---
FileSets/v3.40~8/MbEditBox.qml | 1 -
FileSets/v3.40~8/MbEditBoxDateTime.qml | 1 -
FileSets/v3.40~8/MbItem.qml | 1 -
FileSets/v3.40~8/MbItemDigitalInput.qml | 1 -
FileSets/v3.40~8/MbSpinBox.qml | 1 -
FileSets/v3.40~8/MbStyle.qml | 1 -
FileSets/v3.40~8/MbSubMenu.qml | 1 -
FileSets/v3.40~8/Multi.qml | 1 -
FileSets/v3.40~8/ObjectAcConnection.qml | 1 -
FileSets/v3.40~8/OverviewAcValuesEnhanced.qml | 1 -
FileSets/v3.40~8/OverviewBox.qml | 1 -
FileSets/v3.40~8/OverviewConnection.qml | 1 -
FileSets/v3.40~8/OverviewConnectionEnd.qml | 1 -
FileSets/v3.40~8/OverviewFlowComplex.qml | 1549 ----------------
.../v3.40~8/OverviewGeneratorEnhanced.qml | 1 -
.../OverviewGeneratorRelayEnhanced.qml | 1 -
FileSets/v3.40~8/OverviewGridParallel.qml | 490 -----
FileSets/v3.40~8/OverviewHub.qml | 315 ----
FileSets/v3.40~8/OverviewHubEnhanced.qml | 1505 ----------------
FileSets/v3.40~8/OverviewMobileEnhanced.qml | 1 -
FileSets/v3.40~8/OverviewSolarCharger.qml | 1 -
FileSets/v3.40~8/OverviewSolarInverter.qml | 1 -
FileSets/v3.40~8/OverviewTankDelegate.qml | 1 -
FileSets/v3.40~8/OverviewTanks.qml | 1 -
.../v3.40~8/OverviewTanksTempsDigInputs.qml | 1 -
FileSets/v3.40~8/PageDigitalInput.qml | 1 -
FileSets/v3.40~8/PageGenerator.qml | 1 -
FileSets/v3.40~8/PageMain.qml | 1 -
FileSets/v3.40~8/PageSettingsGenerator.qml | 1 -
FileSets/v3.40~8/PageSettingsGuiMods.qml | 1 -
FileSets/v3.40~8/PageSettingsRelay.qml | 1 -
FileSets/v3.40~8/PowerGauge.qml | 320 ----
FileSets/v3.40~8/Tile.qml | 1 -
FileSets/v3.40~8/TileDigIn.qml | 1 -
FileSets/v3.40~8/TileRelay.qml | 1 -
FileSets/v3.40~8/TileText.qml | 1 -
FileSets/v3.40~8/attributes.csv | 1 -
FileSets/v3.40~8/dbus_digitalinputs.py | 1 -
FileSets/v3.40~8/dbus_generator.py | 1 -
FileSets/v3.40~8/dbus_systemcalc.py | 1 -
FileSets/v3.40~8/main.qml | 1 -
FileSets/v3.40~8/startstop.py | 1 -
FileSets/v3.40~8/styles.css | 1 -
ReadMe | 8 +-
changes | 6 +
2656 files changed, 8777 insertions(+), 74776 deletions(-)
rename FileSets/PatchSource/{Battery.qml-v3.40~32 => Battery.qml-v3.34} (100%)
rename FileSets/PatchSource/{Battery.qml-v3.40~32.orig => Battery.qml-v3.34.orig} (100%)
rename FileSets/PatchSource/{Battery.qml-v3.40~32.patch => Battery.qml-v3.34.patch} (95%)
rename FileSets/PatchSource/{Battery.qml-v3.40~35 => Battery.qml-v3.40} (100%)
rename FileSets/PatchSource/{Battery.qmlv3.40~35.orig => Battery.qmlv3.40.orig} (100%)
delete mode 100644 FileSets/PatchSource/MbItemDigitalInput.qml-v2.94.patch
rename FileSets/PatchSource/{MbItemDigitalInput.qml-v3.40~35 => MbItemDigitalInput.qml-v3.40} (100%)
rename FileSets/PatchSource/{MbItemDigitalInput.qml-v3.40~35.orig => MbItemDigitalInput.qml-v3.40.orig} (100%)
rename FileSets/PatchSource/{MbItemDigitalInput.qml-v3.40~35.patch => MbItemDigitalInput.qml-v3.40.patch} (89%)
delete mode 100644 FileSets/PatchSource/MbSpinBox.qml-v2.73.patch
delete mode 100644 FileSets/PatchSource/MbSpinBox.qml-v2.89.patch
rename FileSets/PatchSource/{MbSpinBox.qml-v3.40~35 => MbSpinBox.qml-v3.40} (100%)
rename FileSets/PatchSource/{MbSpinBox.qml-v3.40~35.orig => MbSpinBox.qml-v3.40.orig} (100%)
rename FileSets/PatchSource/{MbSpinBox.qml.patch => MbSpinBox.qml-v3.40.patch} (93%)
delete mode 100644 FileSets/PatchSource/MbSpinBox.qml-v3.40~35.patch
delete mode 100644 FileSets/PatchSource/MbStyle.qml-v2.94.patch
rename FileSets/PatchSource/{MbStyle.qml-v3.40~35 => MbStyle.qml-v3.40} (100%)
rename FileSets/PatchSource/{MbStyle.qml-v3.40~35.orig => MbStyle.qml-v3.40.orig} (100%)
rename FileSets/PatchSource/{MbStyle.qml-v3.40~35.patch => MbStyle.qml-v3.40.patch} (96%)
delete mode 100644 FileSets/PatchSource/PageMain.qml-v2.94.patch
rename FileSets/PatchSource/{PageMain.qml-v3.40~13 => PageMain.qml-v3.34} (100%)
rename FileSets/PatchSource/{PageMain.qml-v3.40~13.orig => PageMain.qml-v3.34.orig} (100%)
rename FileSets/PatchSource/{PageMain.qml-v3.40~13.patch => PageMain.qml-v3.34.patch} (97%)
rename FileSets/PatchSource/{PageMain.qml-v3.40~35 => PageMain.qml-v3.40} (100%)
rename FileSets/PatchSource/{PageMain.qml-v3.40~35.orig => PageMain.qml-v3.40.orig} (100%)
rename FileSets/PatchSource/{PageMain.qml-v3.40~35.patch => PageMain.qml-v3.40.patch} (97%)
delete mode 100644 FileSets/PatchSource/PageSettingsDisplay.qml-v2.89.patch
delete mode 100644 FileSets/PatchSource/PageSettingsDisplay.qml-v2.94.patch
delete mode 100644 FileSets/PatchSource/PageSettingsDisplay.qml-v3.01.patch
rename FileSets/PatchSource/{PageSettingsDisplay.qml-v3.40~35 => PageSettingsDisplay.qml-v3.40} (100%)
rename FileSets/PatchSource/{PageSettingsDisplay.qml-v3.40~35.orig => PageSettingsDisplay.qml-v3.40.orig} (100%)
rename FileSets/PatchSource/{PageSettingsDisplay.qml-v3.40~8.patch => PageSettingsDisplay.qml-v3.40.patch} (85%)
delete mode 100644 FileSets/PatchSource/PageSettingsDisplay.qml-v3.40~35.patch
delete mode 100644 FileSets/PatchSource/attributes.csv-v2.94.patch
rename FileSets/PatchSource/{attributes.csv-v3.40~35 => attributes.csv-v3.40} (100%)
rename FileSets/PatchSource/{attributes.csv-v3.40~35.orig => attributes.csv-v3.40.orig} (100%)
rename FileSets/PatchSource/{attributes.csv-v3.40~35.patch => attributes.csv-v3.40.patch} (85%)
delete mode 100644 FileSets/PatchSource/dbus_systemcalc.py-v2.73.patch
delete mode 100644 FileSets/PatchSource/dbus_systemcalc.py-v2.84.patch
delete mode 100644 FileSets/PatchSource/dbus_systemcalc.py-v2.89.patch
delete mode 100644 FileSets/PatchSource/dbus_systemcalc.py-v2.94.patch
rename FileSets/PatchSource/{dbus_systemcalc.py-v3.40~2 => dbus_systemcalc.py-v3.34} (100%)
rename FileSets/PatchSource/{dbus_systemcalc.py-v3.40~2.orig => dbus_systemcalc.py-v3.34.orig} (100%)
rename FileSets/PatchSource/{dbus_systemcalc.py-v3.40~2.patch => dbus_systemcalc.py-v3.34.patch} (99%)
rename FileSets/PatchSource/{dbus_systemcalc.py-v3.40~35 => dbus_systemcalc.py-v3.40} (100%)
rename FileSets/PatchSource/{dbus_systemcalc.py-v3.40~35.orig => dbus_systemcalc.py-v3.40.orig} (100%)
rename FileSets/PatchSource/{dbus_systemcalc.py-v3.40~35.patch => dbus_systemcalc.py-v3.40.patch} (99%)
delete mode 100644 FileSets/PatchSource/dbus_systemcalc.py-v3.40~10.patch
delete mode 100644 FileSets/PatchSource/dbus_systemcalc.py-v3.40~15.patch
delete mode 100644 FileSets/PatchSource/main.qml-v2.94.patch
rename FileSets/PatchSource/{main.qml-v3.40~13 => main.qml-v3.34} (100%)
rename FileSets/PatchSource/{main.qml-v3.40~13.orig => main.qml-v3.34.orig} (100%)
rename FileSets/PatchSource/{main.qml-v3.40~13.patch => main.qml-v3.34.patch} (99%)
rename FileSets/PatchSource/{main.qml-v3.40~35 => main.qml-v3.40} (100%)
rename FileSets/PatchSource/{main.qml-v3.40~35.orig => main.qml-v3.40.orig} (100%)
rename FileSets/PatchSource/{main.qml-v3.40~35.patch => main.qml-v3.40.patch} (99%)
rename FileSets/PatchSource/{ => obsoletePatches}/MbItemDigitalInput.qml-v2.94 (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/MbItemDigitalInput.qml-v2.94.orig (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/MbSpinBox.qml-v2.73 (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/MbSpinBox.qml-v2.73.orig (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/MbSpinBox.qml-v2.89 (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/MbSpinBox.qml-v2.89.orig (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/MbStyle.qml-v2.94 (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/MbStyle.qml-v2.94.orig (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/PageMain.qml-v2.94 (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/PageMain.qml-v2.94.orig (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/PageSettingsDisplay.qml-v2.89 (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/PageSettingsDisplay.qml-v2.89.orig (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/PageSettingsDisplay.qml-v2.94 (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/PageSettingsDisplay.qml-v2.94.orig (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/PageSettingsDisplay.qml-v3.01 (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/PageSettingsDisplay.qml-v3.01.orig (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/PageSettingsDisplay.qml-v3.40~8 (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/PageSettingsDisplay.qml-v3.40~8.orig (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/attributes.csv-v2.94 (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/attributes.csv-v2.94.orig (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/dbus_systemcalc.py-v2.73 (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/dbus_systemcalc.py-v2.73.orig (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/dbus_systemcalc.py-v2.84 (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/dbus_systemcalc.py-v2.84.orig (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/dbus_systemcalc.py-v2.89 (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/dbus_systemcalc.py-v2.89.orig (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/dbus_systemcalc.py-v2.94 (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/dbus_systemcalc.py-v2.94.orig (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/dbus_systemcalc.py-v3.40~10.orig (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/dbus_systemcalc.py-v3.40~15 (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/dbus_systemcalc.py-v3.40~15.orig (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/main.qml-v2.94 (100%)
rename FileSets/PatchSource/{ => obsoletePatches}/main.qml-v2.94.orig (100%)
delete mode 120000 FileSets/v2.71/Battery.qml
delete mode 120000 FileSets/v2.71/DetailAcInput.qml
delete mode 120000 FileSets/v2.71/DetailInverter.qml
delete mode 120000 FileSets/v2.71/DetailLoadsCombined.qml
delete mode 120000 FileSets/v2.71/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v2.71/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v2.71/HubData.qml
delete mode 100644 FileSets/v2.71/LINKS_ONLY
delete mode 120000 FileSets/v2.71/MbEditBox.qml
delete mode 120000 FileSets/v2.71/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v2.71/MbItem.qml
delete mode 120000 FileSets/v2.71/MbItemDigitalInput.qml
delete mode 120000 FileSets/v2.71/MbSpinBox.qml
delete mode 120000 FileSets/v2.71/MbStyle.qml
delete mode 120000 FileSets/v2.71/MbSubMenu.qml
delete mode 120000 FileSets/v2.71/Multi.qml
delete mode 120000 FileSets/v2.71/ObjectAcConnection.qml
delete mode 120000 FileSets/v2.71/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v2.71/OverviewBox.qml
delete mode 120000 FileSets/v2.71/OverviewConnection.qml
delete mode 120000 FileSets/v2.71/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v2.71/OverviewFlowComplex.qml
delete mode 120000 FileSets/v2.71/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v2.71/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v2.71/OverviewGridParallel.qml
delete mode 120000 FileSets/v2.71/OverviewHub.qml
delete mode 120000 FileSets/v2.71/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v2.71/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v2.71/OverviewSolarCharger.qml
delete mode 120000 FileSets/v2.71/OverviewSolarInverter.qml
delete mode 120000 FileSets/v2.71/OverviewTankDelegate.qml
delete mode 120000 FileSets/v2.71/OverviewTanks.qml
delete mode 120000 FileSets/v2.71/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v2.71/PageDigitalInput.qml
delete mode 120000 FileSets/v2.71/PageGenerator.qml
delete mode 120000 FileSets/v2.71/PageMain.qml
delete mode 120000 FileSets/v2.71/PageSettingsDisplay.qml
delete mode 120000 FileSets/v2.71/PageSettingsGenerator.qml
delete mode 120000 FileSets/v2.71/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v2.71/PageSettingsRelay.qml
delete mode 120000 FileSets/v2.71/PowerGauge.qml
delete mode 120000 FileSets/v2.71/Tile.qml
delete mode 120000 FileSets/v2.71/TileDigIn.qml
delete mode 120000 FileSets/v2.71/TileRelay.qml
delete mode 120000 FileSets/v2.71/TileText.qml
delete mode 120000 FileSets/v2.71/attributes.csv
delete mode 120000 FileSets/v2.71/dbus_digitalinputs.py
delete mode 120000 FileSets/v2.71/dbus_generator.py
delete mode 120000 FileSets/v2.71/dbus_systemcalc.py
delete mode 120000 FileSets/v2.71/main.qml
delete mode 120000 FileSets/v2.71/startstop.py
delete mode 120000 FileSets/v2.71/styles.css
delete mode 120000 FileSets/v2.72/Battery.qml
delete mode 100644 FileSets/v2.72/COMPLETE
delete mode 120000 FileSets/v2.72/DetailAcInput.qml
delete mode 120000 FileSets/v2.72/DetailInverter.qml
delete mode 120000 FileSets/v2.72/DetailLoadsCombined.qml
delete mode 120000 FileSets/v2.72/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v2.72/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v2.72/HubData.qml
delete mode 100644 FileSets/v2.72/LINKS_ONLY
delete mode 120000 FileSets/v2.72/MbEditBox.qml
delete mode 120000 FileSets/v2.72/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v2.72/MbItem.qml
delete mode 120000 FileSets/v2.72/MbItemDigitalInput.qml
delete mode 120000 FileSets/v2.72/MbSpinBox.qml
delete mode 120000 FileSets/v2.72/MbStyle.qml
delete mode 120000 FileSets/v2.72/MbSubMenu.qml
delete mode 120000 FileSets/v2.72/Multi.qml
delete mode 120000 FileSets/v2.72/ObjectAcConnection.qml
delete mode 120000 FileSets/v2.72/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v2.72/OverviewBox.qml
delete mode 120000 FileSets/v2.72/OverviewConnection.qml
delete mode 120000 FileSets/v2.72/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v2.72/OverviewFlowComplex.qml
delete mode 120000 FileSets/v2.72/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v2.72/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v2.72/OverviewGridParallel.qml
delete mode 120000 FileSets/v2.72/OverviewHub.qml
delete mode 120000 FileSets/v2.72/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v2.72/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v2.72/OverviewSolarCharger.qml
delete mode 120000 FileSets/v2.72/OverviewSolarInverter.qml
delete mode 120000 FileSets/v2.72/OverviewTankDelegate.qml
delete mode 120000 FileSets/v2.72/OverviewTanks.qml
delete mode 120000 FileSets/v2.72/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v2.72/PageDigitalInput.qml
delete mode 120000 FileSets/v2.72/PageGenerator.qml
delete mode 120000 FileSets/v2.72/PageMain.qml
delete mode 120000 FileSets/v2.72/PageSettingsDisplay.qml
delete mode 120000 FileSets/v2.72/PageSettingsGenerator.qml
delete mode 120000 FileSets/v2.72/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v2.72/PageSettingsRelay.qml
delete mode 120000 FileSets/v2.72/PowerGauge.qml
delete mode 120000 FileSets/v2.72/Tile.qml
delete mode 120000 FileSets/v2.72/TileDigIn.qml
delete mode 120000 FileSets/v2.72/TileRelay.qml
delete mode 120000 FileSets/v2.72/TileText.qml
delete mode 120000 FileSets/v2.72/attributes.csv
delete mode 120000 FileSets/v2.72/dbus_digitalinputs.py
delete mode 120000 FileSets/v2.72/dbus_generator.py
delete mode 120000 FileSets/v2.72/dbus_systemcalc.py
delete mode 120000 FileSets/v2.72/main.qml
delete mode 120000 FileSets/v2.72/startstop.py
delete mode 120000 FileSets/v2.72/styles.css
delete mode 120000 FileSets/v2.73/Battery.qml
delete mode 100644 FileSets/v2.73/COMPLETE
delete mode 100644 FileSets/v2.73/DetailAcInput.qml
delete mode 100644 FileSets/v2.73/DetailAcInput.qml.orig
delete mode 100644 FileSets/v2.73/DetailInverter.qml
delete mode 100644 FileSets/v2.73/DetailInverter.qml.orig
delete mode 100644 FileSets/v2.73/DetailLoadsCombined.qml
delete mode 100644 FileSets/v2.73/DetailLoadsCombined.qml.orig
delete mode 100644 FileSets/v2.73/DetailLoadsOnInput.qml
delete mode 100644 FileSets/v2.73/DetailLoadsOnInput.qml.orig
delete mode 100644 FileSets/v2.73/DetailLoadsOnOutput.qml
delete mode 100644 FileSets/v2.73/DetailLoadsOnOutput.qml.orig
delete mode 100644 FileSets/v2.73/HubData.qml
delete mode 100644 FileSets/v2.73/HubData.qml.orig
delete mode 120000 FileSets/v2.73/MbEditBox.qml
delete mode 120000 FileSets/v2.73/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v2.73/MbItem.qml
delete mode 120000 FileSets/v2.73/MbItemDigitalInput.qml
delete mode 120000 FileSets/v2.73/MbStyle.qml
delete mode 120000 FileSets/v2.73/MbSubMenu.qml
delete mode 120000 FileSets/v2.73/Multi.qml
delete mode 100644 FileSets/v2.73/ObjectAcConnection.qml
delete mode 100644 FileSets/v2.73/ObjectAcConnection.qml.orig
delete mode 100644 FileSets/v2.73/OverviewAcValuesEnhanced.qml
delete mode 100644 FileSets/v2.73/OverviewAcValuesEnhanced.qml.orig
delete mode 120000 FileSets/v2.73/OverviewBox.qml
delete mode 120000 FileSets/v2.73/OverviewConnection.qml
delete mode 120000 FileSets/v2.73/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v2.73/OverviewFlowComplex.qml
delete mode 120000 FileSets/v2.73/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v2.73/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v2.73/OverviewGridParallel.qml
delete mode 100644 FileSets/v2.73/OverviewHub.qml
delete mode 100644 FileSets/v2.73/OverviewHub.qml.orig
delete mode 100644 FileSets/v2.73/OverviewHubEnhanced.qml
delete mode 100644 FileSets/v2.73/OverviewHubEnhanced.qml.orig
delete mode 100644 FileSets/v2.73/OverviewMobileEnhanced.qml
delete mode 100644 FileSets/v2.73/OverviewMobileEnhanced.qml.orig
delete mode 120000 FileSets/v2.73/OverviewSolarCharger.qml
delete mode 120000 FileSets/v2.73/OverviewSolarInverter.qml
delete mode 120000 FileSets/v2.73/OverviewTankDelegate.qml
delete mode 120000 FileSets/v2.73/OverviewTanks.qml
delete mode 100644 FileSets/v2.73/OverviewTanksTempsDigInputs.qml.orig
delete mode 120000 FileSets/v2.73/PageDigitalInput.qml
delete mode 120000 FileSets/v2.73/PageGenerator.qml
delete mode 120000 FileSets/v2.73/PageSettingsDisplay.qml
delete mode 120000 FileSets/v2.73/PageSettingsGenerator.qml
delete mode 100644 FileSets/v2.73/PageSettingsGuiMods.qml
delete mode 100644 FileSets/v2.73/PageSettingsGuiMods.qml.orig
delete mode 100644 FileSets/v2.73/PageSettingsRelay.qml
delete mode 100644 FileSets/v2.73/PageSettingsRelay.qml.orig
delete mode 100644 FileSets/v2.73/PowerGauge.qml
delete mode 100644 FileSets/v2.73/PowerGauge.qml.orig
delete mode 120000 FileSets/v2.73/Tile.qml
delete mode 100644 FileSets/v2.73/TileDigIn.qml
delete mode 100755 FileSets/v2.73/TileDigIn.qml.orig
delete mode 120000 FileSets/v2.73/TileRelay.qml
delete mode 120000 FileSets/v2.73/TileText.qml
delete mode 100755 FileSets/v2.73/dbus_digitalinputs.py
delete mode 100755 FileSets/v2.73/dbus_digitalinputs.py.orig
delete mode 100755 FileSets/v2.73/dbus_generator.py
delete mode 100755 FileSets/v2.73/dbus_generator.py.orig
delete mode 120000 FileSets/v2.73/main.qml
delete mode 100755 FileSets/v2.73/startstop.py
delete mode 100644 FileSets/v2.73/startstop.py.orig
delete mode 120000 FileSets/v2.73/styles.css
delete mode 120000 FileSets/v2.80/Battery.qml
delete mode 100644 FileSets/v2.80/COMPLETE
delete mode 120000 FileSets/v2.80/DetailAcInput.qml
delete mode 120000 FileSets/v2.80/DetailInverter.qml
delete mode 120000 FileSets/v2.80/DetailLoadsCombined.qml
delete mode 120000 FileSets/v2.80/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v2.80/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v2.80/HubData.qml
delete mode 100644 FileSets/v2.80/LINKS_ONLY
delete mode 120000 FileSets/v2.80/MbEditBox.qml
delete mode 120000 FileSets/v2.80/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v2.80/MbItem.qml
delete mode 120000 FileSets/v2.80/MbItemDigitalInput.qml
delete mode 120000 FileSets/v2.80/MbSpinBox.qml
delete mode 120000 FileSets/v2.80/MbStyle.qml
delete mode 120000 FileSets/v2.80/MbSubMenu.qml
delete mode 120000 FileSets/v2.80/Multi.qml
delete mode 120000 FileSets/v2.80/ObjectAcConnection.qml
delete mode 120000 FileSets/v2.80/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v2.80/OverviewBox.qml
delete mode 120000 FileSets/v2.80/OverviewConnection.qml
delete mode 120000 FileSets/v2.80/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v2.80/OverviewFlowComplex.qml
delete mode 120000 FileSets/v2.80/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v2.80/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v2.80/OverviewGridParallel.qml
delete mode 120000 FileSets/v2.80/OverviewHub.qml
delete mode 120000 FileSets/v2.80/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v2.80/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v2.80/OverviewSolarCharger.qml
delete mode 120000 FileSets/v2.80/OverviewSolarInverter.qml
delete mode 120000 FileSets/v2.80/OverviewTankDelegate.qml
delete mode 120000 FileSets/v2.80/OverviewTanks.qml
delete mode 120000 FileSets/v2.80/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v2.80/PageDigitalInput.qml
delete mode 120000 FileSets/v2.80/PageGenerator.qml
delete mode 120000 FileSets/v2.80/PageMain.qml
delete mode 120000 FileSets/v2.80/PageSettingsDisplay.qml
delete mode 120000 FileSets/v2.80/PageSettingsGenerator.qml
delete mode 120000 FileSets/v2.80/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v2.80/PageSettingsRelay.qml
delete mode 120000 FileSets/v2.80/PowerGauge.qml
delete mode 120000 FileSets/v2.80/Tile.qml
delete mode 120000 FileSets/v2.80/TileDigIn.qml
delete mode 120000 FileSets/v2.80/TileRelay.qml
delete mode 120000 FileSets/v2.80/TileText.qml
delete mode 120000 FileSets/v2.80/attributes.csv
delete mode 120000 FileSets/v2.80/dbus_digitalinputs.py
delete mode 120000 FileSets/v2.80/dbus_generator.py
delete mode 120000 FileSets/v2.80/dbus_systemcalc.py
delete mode 120000 FileSets/v2.80/main.qml
delete mode 120000 FileSets/v2.80/startstop.py
delete mode 120000 FileSets/v2.80/styles.css
delete mode 120000 FileSets/v2.81/Battery.qml
delete mode 100644 FileSets/v2.81/COMPLETE
delete mode 120000 FileSets/v2.81/DetailAcInput.qml
delete mode 120000 FileSets/v2.81/DetailInverter.qml
delete mode 120000 FileSets/v2.81/DetailLoadsCombined.qml
delete mode 120000 FileSets/v2.81/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v2.81/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v2.81/HubData.qml
delete mode 100644 FileSets/v2.81/LINKS_ONLY
delete mode 120000 FileSets/v2.81/MbEditBox.qml
delete mode 120000 FileSets/v2.81/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v2.81/MbItem.qml
delete mode 120000 FileSets/v2.81/MbItemDigitalInput.qml
delete mode 120000 FileSets/v2.81/MbSpinBox.qml
delete mode 120000 FileSets/v2.81/MbStyle.qml
delete mode 120000 FileSets/v2.81/MbSubMenu.qml
delete mode 120000 FileSets/v2.81/Multi.qml
delete mode 120000 FileSets/v2.81/ObjectAcConnection.qml
delete mode 120000 FileSets/v2.81/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v2.81/OverviewBox.qml
delete mode 120000 FileSets/v2.81/OverviewConnection.qml
delete mode 120000 FileSets/v2.81/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v2.81/OverviewFlowComplex.qml
delete mode 120000 FileSets/v2.81/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v2.81/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v2.81/OverviewGridParallel.qml
delete mode 120000 FileSets/v2.81/OverviewHub.qml
delete mode 120000 FileSets/v2.81/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v2.81/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v2.81/OverviewSolarCharger.qml
delete mode 120000 FileSets/v2.81/OverviewSolarInverter.qml
delete mode 120000 FileSets/v2.81/OverviewTankDelegate.qml
delete mode 120000 FileSets/v2.81/OverviewTanks.qml
delete mode 120000 FileSets/v2.81/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v2.81/PageDigitalInput.qml
delete mode 120000 FileSets/v2.81/PageGenerator.qml
delete mode 120000 FileSets/v2.81/PageMain.qml
delete mode 120000 FileSets/v2.81/PageSettingsDisplay.qml
delete mode 120000 FileSets/v2.81/PageSettingsGenerator.qml
delete mode 120000 FileSets/v2.81/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v2.81/PageSettingsRelay.qml
delete mode 120000 FileSets/v2.81/PowerGauge.qml
delete mode 120000 FileSets/v2.81/Tile.qml
delete mode 120000 FileSets/v2.81/TileDigIn.qml
delete mode 120000 FileSets/v2.81/TileRelay.qml
delete mode 120000 FileSets/v2.81/TileText.qml
delete mode 120000 FileSets/v2.81/attributes.csv
delete mode 120000 FileSets/v2.81/dbus_digitalinputs.py
delete mode 120000 FileSets/v2.81/dbus_generator.py
delete mode 120000 FileSets/v2.81/dbus_systemcalc.py
delete mode 120000 FileSets/v2.81/main.qml
delete mode 120000 FileSets/v2.81/startstop.py
delete mode 120000 FileSets/v2.81/styles.css
delete mode 120000 FileSets/v2.82/Battery.qml
delete mode 100644 FileSets/v2.82/COMPLETE
delete mode 120000 FileSets/v2.82/DetailAcInput.qml
delete mode 120000 FileSets/v2.82/DetailInverter.qml
delete mode 120000 FileSets/v2.82/DetailLoadsCombined.qml
delete mode 120000 FileSets/v2.82/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v2.82/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v2.82/HubData.qml
delete mode 100644 FileSets/v2.82/LINKS_ONLY
delete mode 120000 FileSets/v2.82/MbEditBox.qml
delete mode 120000 FileSets/v2.82/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v2.82/MbItem.qml
delete mode 120000 FileSets/v2.82/MbItemDigitalInput.qml
delete mode 120000 FileSets/v2.82/MbSpinBox.qml
delete mode 120000 FileSets/v2.82/MbStyle.qml
delete mode 120000 FileSets/v2.82/MbSubMenu.qml
delete mode 120000 FileSets/v2.82/Multi.qml
delete mode 120000 FileSets/v2.82/ObjectAcConnection.qml
delete mode 120000 FileSets/v2.82/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v2.82/OverviewBox.qml
delete mode 120000 FileSets/v2.82/OverviewConnection.qml
delete mode 120000 FileSets/v2.82/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v2.82/OverviewFlowComplex.qml
delete mode 120000 FileSets/v2.82/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v2.82/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v2.82/OverviewGridParallel.qml
delete mode 120000 FileSets/v2.82/OverviewHub.qml
delete mode 120000 FileSets/v2.82/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v2.82/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v2.82/OverviewSolarCharger.qml
delete mode 120000 FileSets/v2.82/OverviewSolarInverter.qml
delete mode 120000 FileSets/v2.82/OverviewTankDelegate.qml
delete mode 120000 FileSets/v2.82/OverviewTanks.qml
delete mode 120000 FileSets/v2.82/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v2.82/PageDigitalInput.qml
delete mode 120000 FileSets/v2.82/PageGenerator.qml
delete mode 120000 FileSets/v2.82/PageMain.qml
delete mode 120000 FileSets/v2.82/PageSettingsDisplay.qml
delete mode 120000 FileSets/v2.82/PageSettingsGenerator.qml
delete mode 120000 FileSets/v2.82/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v2.82/PageSettingsRelay.qml
delete mode 120000 FileSets/v2.82/PowerGauge.qml
delete mode 120000 FileSets/v2.82/Tile.qml
delete mode 120000 FileSets/v2.82/TileDigIn.qml
delete mode 120000 FileSets/v2.82/TileRelay.qml
delete mode 120000 FileSets/v2.82/TileText.qml
delete mode 120000 FileSets/v2.82/attributes.csv
delete mode 120000 FileSets/v2.82/dbus_digitalinputs.py
delete mode 120000 FileSets/v2.82/dbus_generator.py
delete mode 120000 FileSets/v2.82/dbus_systemcalc.py
delete mode 120000 FileSets/v2.82/main.qml
delete mode 120000 FileSets/v2.82/startstop.py
delete mode 120000 FileSets/v2.82/styles.css
delete mode 120000 FileSets/v2.83/Battery.qml
delete mode 100644 FileSets/v2.83/COMPLETE
delete mode 120000 FileSets/v2.83/DetailAcInput.qml
delete mode 120000 FileSets/v2.83/DetailInverter.qml
delete mode 120000 FileSets/v2.83/DetailLoadsCombined.qml
delete mode 120000 FileSets/v2.83/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v2.83/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v2.83/HubData.qml
delete mode 100644 FileSets/v2.83/LINKS_ONLY
delete mode 120000 FileSets/v2.83/MbEditBox.qml
delete mode 120000 FileSets/v2.83/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v2.83/MbItem.qml
delete mode 120000 FileSets/v2.83/MbItemDigitalInput.qml
delete mode 120000 FileSets/v2.83/MbSpinBox.qml
delete mode 120000 FileSets/v2.83/MbStyle.qml
delete mode 120000 FileSets/v2.83/MbSubMenu.qml
delete mode 120000 FileSets/v2.83/Multi.qml
delete mode 120000 FileSets/v2.83/ObjectAcConnection.qml
delete mode 120000 FileSets/v2.83/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v2.83/OverviewBox.qml
delete mode 120000 FileSets/v2.83/OverviewConnection.qml
delete mode 120000 FileSets/v2.83/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v2.83/OverviewFlowComplex.qml
delete mode 120000 FileSets/v2.83/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v2.83/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v2.83/OverviewGridParallel.qml
delete mode 120000 FileSets/v2.83/OverviewHub.qml
delete mode 120000 FileSets/v2.83/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v2.83/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v2.83/OverviewSolarCharger.qml
delete mode 120000 FileSets/v2.83/OverviewSolarInverter.qml
delete mode 120000 FileSets/v2.83/OverviewTankDelegate.qml
delete mode 120000 FileSets/v2.83/OverviewTanks.qml
delete mode 120000 FileSets/v2.83/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v2.83/PageDigitalInput.qml
delete mode 120000 FileSets/v2.83/PageGenerator.qml
delete mode 120000 FileSets/v2.83/PageMain.qml
delete mode 120000 FileSets/v2.83/PageSettingsDisplay.qml
delete mode 120000 FileSets/v2.83/PageSettingsGenerator.qml
delete mode 120000 FileSets/v2.83/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v2.83/PageSettingsRelay.qml
delete mode 120000 FileSets/v2.83/PowerGauge.qml
delete mode 120000 FileSets/v2.83/Tile.qml
delete mode 120000 FileSets/v2.83/TileDigIn.qml
delete mode 120000 FileSets/v2.83/TileRelay.qml
delete mode 120000 FileSets/v2.83/TileText.qml
delete mode 120000 FileSets/v2.83/attributes.csv
delete mode 120000 FileSets/v2.83/dbus_digitalinputs.py
delete mode 120000 FileSets/v2.83/dbus_generator.py
delete mode 120000 FileSets/v2.83/dbus_systemcalc.py
delete mode 120000 FileSets/v2.83/main.qml
delete mode 120000 FileSets/v2.83/startstop.py
delete mode 120000 FileSets/v2.83/styles.css
delete mode 120000 FileSets/v2.84/Battery.qml
delete mode 100644 FileSets/v2.84/COMPLETE
delete mode 120000 FileSets/v2.84/DetailAcInput.qml
delete mode 120000 FileSets/v2.84/DetailInverter.qml
delete mode 120000 FileSets/v2.84/DetailLoadsCombined.qml
delete mode 120000 FileSets/v2.84/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v2.84/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v2.84/HubData.qml
delete mode 100644 FileSets/v2.84/LINKS_ONLY
delete mode 120000 FileSets/v2.84/MbEditBox.qml
delete mode 120000 FileSets/v2.84/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v2.84/MbItem.qml
delete mode 120000 FileSets/v2.84/MbItemDigitalInput.qml
delete mode 120000 FileSets/v2.84/MbSpinBox.qml
delete mode 120000 FileSets/v2.84/MbStyle.qml
delete mode 120000 FileSets/v2.84/MbSubMenu.qml
delete mode 120000 FileSets/v2.84/Multi.qml
delete mode 120000 FileSets/v2.84/ObjectAcConnection.qml
delete mode 120000 FileSets/v2.84/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v2.84/OverviewBox.qml
delete mode 120000 FileSets/v2.84/OverviewConnection.qml
delete mode 120000 FileSets/v2.84/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v2.84/OverviewFlowComplex.qml
delete mode 120000 FileSets/v2.84/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v2.84/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v2.84/OverviewGridParallel.qml
delete mode 120000 FileSets/v2.84/OverviewHub.qml
delete mode 120000 FileSets/v2.84/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v2.84/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v2.84/OverviewSolarCharger.qml
delete mode 120000 FileSets/v2.84/OverviewSolarInverter.qml
delete mode 120000 FileSets/v2.84/OverviewTankDelegate.qml
delete mode 120000 FileSets/v2.84/OverviewTanks.qml
delete mode 120000 FileSets/v2.84/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v2.84/PageDigitalInput.qml
delete mode 120000 FileSets/v2.84/PageGenerator.qml
delete mode 120000 FileSets/v2.84/PageMain.qml
delete mode 120000 FileSets/v2.84/PageSettingsDisplay.qml
delete mode 120000 FileSets/v2.84/PageSettingsGenerator.qml
delete mode 120000 FileSets/v2.84/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v2.84/PageSettingsRelay.qml
delete mode 120000 FileSets/v2.84/PowerGauge.qml
delete mode 120000 FileSets/v2.84/Tile.qml
delete mode 120000 FileSets/v2.84/TileDigIn.qml
delete mode 120000 FileSets/v2.84/TileRelay.qml
delete mode 120000 FileSets/v2.84/TileText.qml
delete mode 120000 FileSets/v2.84/attributes.csv
delete mode 120000 FileSets/v2.84/dbus_digitalinputs.py
delete mode 120000 FileSets/v2.84/dbus_generator.py
delete mode 120000 FileSets/v2.84/main.qml
delete mode 120000 FileSets/v2.84/startstop.py
delete mode 120000 FileSets/v2.84/styles.css
delete mode 120000 FileSets/v2.85/Battery.qml
delete mode 100644 FileSets/v2.85/COMPLETE
delete mode 120000 FileSets/v2.85/DetailAcInput.qml
delete mode 120000 FileSets/v2.85/DetailInverter.qml
delete mode 120000 FileSets/v2.85/DetailLoadsCombined.qml
delete mode 120000 FileSets/v2.85/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v2.85/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v2.85/HubData.qml
delete mode 100644 FileSets/v2.85/LINKS_ONLY
delete mode 120000 FileSets/v2.85/MbEditBox.qml
delete mode 120000 FileSets/v2.85/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v2.85/MbItem.qml
delete mode 120000 FileSets/v2.85/MbItemDigitalInput.qml
delete mode 120000 FileSets/v2.85/MbSpinBox.qml
delete mode 120000 FileSets/v2.85/MbStyle.qml
delete mode 120000 FileSets/v2.85/MbSubMenu.qml
delete mode 120000 FileSets/v2.85/Multi.qml
delete mode 120000 FileSets/v2.85/ObjectAcConnection.qml
delete mode 120000 FileSets/v2.85/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v2.85/OverviewBox.qml
delete mode 120000 FileSets/v2.85/OverviewConnection.qml
delete mode 120000 FileSets/v2.85/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v2.85/OverviewFlowComplex.qml
delete mode 120000 FileSets/v2.85/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v2.85/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v2.85/OverviewGridParallel.qml
delete mode 120000 FileSets/v2.85/OverviewHub.qml
delete mode 120000 FileSets/v2.85/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v2.85/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v2.85/OverviewSolarCharger.qml
delete mode 120000 FileSets/v2.85/OverviewSolarInverter.qml
delete mode 120000 FileSets/v2.85/OverviewTankDelegate.qml
delete mode 120000 FileSets/v2.85/OverviewTanks.qml
delete mode 120000 FileSets/v2.85/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v2.85/PageDigitalInput.qml
delete mode 120000 FileSets/v2.85/PageGenerator.qml
delete mode 120000 FileSets/v2.85/PageMain.qml
delete mode 120000 FileSets/v2.85/PageSettingsDisplay.qml
delete mode 120000 FileSets/v2.85/PageSettingsGenerator.qml
delete mode 120000 FileSets/v2.85/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v2.85/PageSettingsRelay.qml
delete mode 120000 FileSets/v2.85/PowerGauge.qml
delete mode 120000 FileSets/v2.85/Tile.qml
delete mode 120000 FileSets/v2.85/TileDigIn.qml
delete mode 120000 FileSets/v2.85/TileRelay.qml
delete mode 120000 FileSets/v2.85/TileText.qml
delete mode 120000 FileSets/v2.85/attributes.csv
delete mode 120000 FileSets/v2.85/dbus_digitalinputs.py
delete mode 120000 FileSets/v2.85/dbus_generator.py
delete mode 120000 FileSets/v2.85/dbus_systemcalc.py
delete mode 120000 FileSets/v2.85/main.qml
delete mode 120000 FileSets/v2.85/startstop.py
delete mode 120000 FileSets/v2.85/styles.css
delete mode 120000 FileSets/v2.86/Battery.qml
delete mode 100644 FileSets/v2.86/COMPLETE
delete mode 120000 FileSets/v2.86/DetailAcInput.qml
delete mode 120000 FileSets/v2.86/DetailInverter.qml
delete mode 120000 FileSets/v2.86/DetailLoadsCombined.qml
delete mode 120000 FileSets/v2.86/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v2.86/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v2.86/HubData.qml
delete mode 100644 FileSets/v2.86/LINKS_ONLY
delete mode 120000 FileSets/v2.86/MbEditBox.qml
delete mode 120000 FileSets/v2.86/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v2.86/MbItem.qml
delete mode 120000 FileSets/v2.86/MbItemDigitalInput.qml
delete mode 120000 FileSets/v2.86/MbSpinBox.qml
delete mode 120000 FileSets/v2.86/MbStyle.qml
delete mode 120000 FileSets/v2.86/MbSubMenu.qml
delete mode 120000 FileSets/v2.86/Multi.qml
delete mode 120000 FileSets/v2.86/ObjectAcConnection.qml
delete mode 120000 FileSets/v2.86/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v2.86/OverviewBox.qml
delete mode 120000 FileSets/v2.86/OverviewConnection.qml
delete mode 120000 FileSets/v2.86/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v2.86/OverviewFlowComplex.qml
delete mode 120000 FileSets/v2.86/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v2.86/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v2.86/OverviewGridParallel.qml
delete mode 120000 FileSets/v2.86/OverviewHub.qml
delete mode 120000 FileSets/v2.86/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v2.86/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v2.86/OverviewSolarCharger.qml
delete mode 120000 FileSets/v2.86/OverviewSolarInverter.qml
delete mode 120000 FileSets/v2.86/OverviewTankDelegate.qml
delete mode 120000 FileSets/v2.86/OverviewTanks.qml
delete mode 120000 FileSets/v2.86/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v2.86/PageDigitalInput.qml
delete mode 120000 FileSets/v2.86/PageGenerator.qml
delete mode 120000 FileSets/v2.86/PageMain.qml
delete mode 120000 FileSets/v2.86/PageSettingsDisplay.qml
delete mode 120000 FileSets/v2.86/PageSettingsGenerator.qml
delete mode 120000 FileSets/v2.86/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v2.86/PageSettingsRelay.qml
delete mode 120000 FileSets/v2.86/PowerGauge.qml
delete mode 120000 FileSets/v2.86/Tile.qml
delete mode 120000 FileSets/v2.86/TileDigIn.qml
delete mode 120000 FileSets/v2.86/TileRelay.qml
delete mode 120000 FileSets/v2.86/TileText.qml
delete mode 120000 FileSets/v2.86/attributes.csv
delete mode 120000 FileSets/v2.86/dbus_digitalinputs.py
delete mode 120000 FileSets/v2.86/dbus_generator.py
delete mode 120000 FileSets/v2.86/dbus_systemcalc.py
delete mode 120000 FileSets/v2.86/main.qml
delete mode 120000 FileSets/v2.86/startstop.py
delete mode 120000 FileSets/v2.86/styles.css
delete mode 120000 FileSets/v2.87/Battery.qml
delete mode 100644 FileSets/v2.87/COMPLETE
delete mode 120000 FileSets/v2.87/DetailAcInput.qml
delete mode 120000 FileSets/v2.87/DetailInverter.qml
delete mode 120000 FileSets/v2.87/DetailLoadsCombined.qml
delete mode 120000 FileSets/v2.87/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v2.87/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v2.87/HubData.qml
delete mode 100644 FileSets/v2.87/LINKS_ONLY
delete mode 120000 FileSets/v2.87/MbEditBox.qml
delete mode 120000 FileSets/v2.87/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v2.87/MbItem.qml
delete mode 120000 FileSets/v2.87/MbItemDigitalInput.qml
delete mode 120000 FileSets/v2.87/MbSpinBox.qml
delete mode 120000 FileSets/v2.87/MbStyle.qml
delete mode 120000 FileSets/v2.87/MbSubMenu.qml
delete mode 120000 FileSets/v2.87/Multi.qml
delete mode 120000 FileSets/v2.87/ObjectAcConnection.qml
delete mode 120000 FileSets/v2.87/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v2.87/OverviewBox.qml
delete mode 120000 FileSets/v2.87/OverviewConnection.qml
delete mode 120000 FileSets/v2.87/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v2.87/OverviewFlowComplex.qml
delete mode 120000 FileSets/v2.87/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v2.87/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v2.87/OverviewGridParallel.qml
delete mode 120000 FileSets/v2.87/OverviewHub.qml
delete mode 120000 FileSets/v2.87/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v2.87/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v2.87/OverviewSolarCharger.qml
delete mode 120000 FileSets/v2.87/OverviewSolarInverter.qml
delete mode 120000 FileSets/v2.87/OverviewTankDelegate.qml
delete mode 120000 FileSets/v2.87/OverviewTanks.qml
delete mode 120000 FileSets/v2.87/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v2.87/PageDigitalInput.qml
delete mode 120000 FileSets/v2.87/PageGenerator.qml
delete mode 120000 FileSets/v2.87/PageMain.qml
delete mode 120000 FileSets/v2.87/PageSettingsDisplay.qml
delete mode 120000 FileSets/v2.87/PageSettingsGenerator.qml
delete mode 120000 FileSets/v2.87/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v2.87/PageSettingsRelay.qml
delete mode 120000 FileSets/v2.87/PowerGauge.qml
delete mode 120000 FileSets/v2.87/Tile.qml
delete mode 120000 FileSets/v2.87/TileDigIn.qml
delete mode 120000 FileSets/v2.87/TileRelay.qml
delete mode 120000 FileSets/v2.87/TileText.qml
delete mode 120000 FileSets/v2.87/attributes.csv
delete mode 120000 FileSets/v2.87/dbus_digitalinputs.py
delete mode 120000 FileSets/v2.87/dbus_generator.py
delete mode 120000 FileSets/v2.87/dbus_systemcalc.py
delete mode 120000 FileSets/v2.87/main.qml
delete mode 120000 FileSets/v2.87/startstop.py
delete mode 120000 FileSets/v2.87/styles.css
delete mode 120000 FileSets/v2.89/Battery.qml
delete mode 100644 FileSets/v2.89/COMPLETE
delete mode 120000 FileSets/v2.89/DetailAcInput.qml
delete mode 120000 FileSets/v2.89/DetailInverter.qml
delete mode 120000 FileSets/v2.89/DetailLoadsCombined.qml
delete mode 120000 FileSets/v2.89/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v2.89/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v2.89/HubData.qml
delete mode 120000 FileSets/v2.89/MbEditBox.qml
delete mode 120000 FileSets/v2.89/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v2.89/MbItem.qml
delete mode 120000 FileSets/v2.89/MbItemDigitalInput.qml
delete mode 120000 FileSets/v2.89/MbStyle.qml
delete mode 120000 FileSets/v2.89/MbSubMenu.qml
delete mode 120000 FileSets/v2.89/Multi.qml
delete mode 120000 FileSets/v2.89/ObjectAcConnection.qml
delete mode 120000 FileSets/v2.89/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v2.89/OverviewBox.qml
delete mode 120000 FileSets/v2.89/OverviewConnection.qml
delete mode 120000 FileSets/v2.89/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v2.89/OverviewFlowComplex.qml
delete mode 120000 FileSets/v2.89/OverviewGeneratorEnhanced.qml
delete mode 100644 FileSets/v2.89/OverviewGeneratorRelayEnhanced.qml
delete mode 100644 FileSets/v2.89/OverviewGeneratorRelayEnhanced.qml.orig
delete mode 120000 FileSets/v2.89/OverviewGridParallel.qml
delete mode 120000 FileSets/v2.89/OverviewHub.qml
delete mode 120000 FileSets/v2.89/OverviewHubEnhanced.qml
delete mode 100644 FileSets/v2.89/OverviewMobileEnhanced.qml
delete mode 100644 FileSets/v2.89/OverviewMobileEnhanced.qml.orig
delete mode 120000 FileSets/v2.89/OverviewSolarCharger.qml
delete mode 120000 FileSets/v2.89/OverviewSolarInverter.qml
delete mode 120000 FileSets/v2.89/OverviewTankDelegate.qml
delete mode 120000 FileSets/v2.89/OverviewTanks.qml
delete mode 100644 FileSets/v2.89/OverviewTanksTempsDigInputs.qml
delete mode 100644 FileSets/v2.89/OverviewTanksTempsDigInputs.qml.orig
delete mode 120000 FileSets/v2.89/PageDigitalInput.qml
delete mode 120000 FileSets/v2.89/PageGenerator.qml
delete mode 100644 FileSets/v2.89/PageSettingsGenerator.qml
delete mode 100644 FileSets/v2.89/PageSettingsGenerator.qml.orig
delete mode 100644 FileSets/v2.89/PageSettingsGuiMods.qml
delete mode 100644 FileSets/v2.89/PageSettingsGuiMods.qml.orig
delete mode 120000 FileSets/v2.89/PageSettingsRelay.qml
delete mode 120000 FileSets/v2.89/PowerGauge.qml
delete mode 120000 FileSets/v2.89/Tile.qml
delete mode 100644 FileSets/v2.89/TileDigIn.qml
delete mode 100755 FileSets/v2.89/TileDigIn.qml.orig
delete mode 100644 FileSets/v2.89/TileRelay.qml
delete mode 100644 FileSets/v2.89/TileRelay.qml.orig
delete mode 120000 FileSets/v2.89/TileText.qml
delete mode 100755 FileSets/v2.89/dbus_digitalinputs.py
delete mode 100755 FileSets/v2.89/dbus_digitalinputs.py.orig
delete mode 100755 FileSets/v2.89/dbus_generator.py
delete mode 100755 FileSets/v2.89/dbus_generator.py.orig
delete mode 100644 FileSets/v2.89/startstop.py
delete mode 100644 FileSets/v2.89/startstop.py.orig
delete mode 120000 FileSets/v2.89/styles.css
delete mode 120000 FileSets/v2.90/Battery.qml
delete mode 100644 FileSets/v2.90/COMPLETE
delete mode 120000 FileSets/v2.90/DetailAcInput.qml
delete mode 120000 FileSets/v2.90/DetailInverter.qml
delete mode 120000 FileSets/v2.90/DetailLoadsCombined.qml
delete mode 120000 FileSets/v2.90/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v2.90/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v2.90/HubData.qml
delete mode 100644 FileSets/v2.90/LINKS_ONLY
delete mode 120000 FileSets/v2.90/MbEditBox.qml
delete mode 120000 FileSets/v2.90/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v2.90/MbItem.qml
delete mode 120000 FileSets/v2.90/MbItemDigitalInput.qml
delete mode 120000 FileSets/v2.90/MbSpinBox.qml
delete mode 120000 FileSets/v2.90/MbStyle.qml
delete mode 120000 FileSets/v2.90/MbSubMenu.qml
delete mode 120000 FileSets/v2.90/Multi.qml
delete mode 120000 FileSets/v2.90/ObjectAcConnection.qml
delete mode 120000 FileSets/v2.90/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v2.90/OverviewBox.qml
delete mode 120000 FileSets/v2.90/OverviewConnection.qml
delete mode 120000 FileSets/v2.90/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v2.90/OverviewFlowComplex.qml
delete mode 120000 FileSets/v2.90/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v2.90/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v2.90/OverviewGridParallel.qml
delete mode 120000 FileSets/v2.90/OverviewHub.qml
delete mode 120000 FileSets/v2.90/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v2.90/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v2.90/OverviewSolarCharger.qml
delete mode 120000 FileSets/v2.90/OverviewSolarInverter.qml
delete mode 120000 FileSets/v2.90/OverviewTankDelegate.qml
delete mode 120000 FileSets/v2.90/OverviewTanks.qml
delete mode 120000 FileSets/v2.90/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v2.90/PageDigitalInput.qml
delete mode 120000 FileSets/v2.90/PageGenerator.qml
delete mode 120000 FileSets/v2.90/PageMain.qml
delete mode 120000 FileSets/v2.90/PageSettingsDisplay.qml
delete mode 120000 FileSets/v2.90/PageSettingsGenerator.qml
delete mode 120000 FileSets/v2.90/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v2.90/PageSettingsRelay.qml
delete mode 120000 FileSets/v2.90/PowerGauge.qml
delete mode 120000 FileSets/v2.90/Tile.qml
delete mode 120000 FileSets/v2.90/TileDigIn.qml
delete mode 120000 FileSets/v2.90/TileRelay.qml
delete mode 120000 FileSets/v2.90/TileText.qml
delete mode 120000 FileSets/v2.90/attributes.csv
delete mode 120000 FileSets/v2.90/dbus_digitalinputs.py
delete mode 120000 FileSets/v2.90/dbus_generator.py
delete mode 120000 FileSets/v2.90/dbus_systemcalc.py
delete mode 120000 FileSets/v2.90/main.qml
delete mode 120000 FileSets/v2.90/startstop.py
delete mode 120000 FileSets/v2.90/styles.css
delete mode 120000 FileSets/v2.91/Battery.qml
delete mode 100644 FileSets/v2.91/COMPLETE
delete mode 120000 FileSets/v2.91/DetailAcInput.qml
delete mode 120000 FileSets/v2.91/DetailInverter.qml
delete mode 120000 FileSets/v2.91/DetailLoadsCombined.qml
delete mode 120000 FileSets/v2.91/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v2.91/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v2.91/HubData.qml
delete mode 100644 FileSets/v2.91/LINKS_ONLY
delete mode 120000 FileSets/v2.91/MbEditBox.qml
delete mode 120000 FileSets/v2.91/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v2.91/MbItem.qml
delete mode 120000 FileSets/v2.91/MbItemDigitalInput.qml
delete mode 120000 FileSets/v2.91/MbSpinBox.qml
delete mode 120000 FileSets/v2.91/MbStyle.qml
delete mode 120000 FileSets/v2.91/MbSubMenu.qml
delete mode 120000 FileSets/v2.91/Multi.qml
delete mode 120000 FileSets/v2.91/ObjectAcConnection.qml
delete mode 120000 FileSets/v2.91/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v2.91/OverviewBox.qml
delete mode 120000 FileSets/v2.91/OverviewConnection.qml
delete mode 120000 FileSets/v2.91/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v2.91/OverviewFlowComplex.qml
delete mode 120000 FileSets/v2.91/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v2.91/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v2.91/OverviewGridParallel.qml
delete mode 120000 FileSets/v2.91/OverviewHub.qml
delete mode 120000 FileSets/v2.91/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v2.91/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v2.91/OverviewSolarCharger.qml
delete mode 120000 FileSets/v2.91/OverviewSolarInverter.qml
delete mode 120000 FileSets/v2.91/OverviewTankDelegate.qml
delete mode 120000 FileSets/v2.91/OverviewTanks.qml
delete mode 120000 FileSets/v2.91/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v2.91/PageDigitalInput.qml
delete mode 120000 FileSets/v2.91/PageGenerator.qml
delete mode 120000 FileSets/v2.91/PageMain.qml
delete mode 120000 FileSets/v2.91/PageSettingsDisplay.qml
delete mode 120000 FileSets/v2.91/PageSettingsGenerator.qml
delete mode 120000 FileSets/v2.91/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v2.91/PageSettingsRelay.qml
delete mode 120000 FileSets/v2.91/PowerGauge.qml
delete mode 120000 FileSets/v2.91/Tile.qml
delete mode 120000 FileSets/v2.91/TileDigIn.qml
delete mode 120000 FileSets/v2.91/TileRelay.qml
delete mode 120000 FileSets/v2.91/TileText.qml
delete mode 120000 FileSets/v2.91/attributes.csv
delete mode 120000 FileSets/v2.91/dbus_digitalinputs.py
delete mode 120000 FileSets/v2.91/dbus_generator.py
delete mode 120000 FileSets/v2.91/dbus_systemcalc.py
delete mode 120000 FileSets/v2.91/main.qml
delete mode 120000 FileSets/v2.91/startstop.py
delete mode 120000 FileSets/v2.91/styles.css
delete mode 120000 FileSets/v2.92/Battery.qml
delete mode 100644 FileSets/v2.92/COMPLETE
delete mode 120000 FileSets/v2.92/DetailAcInput.qml
delete mode 120000 FileSets/v2.92/DetailInverter.qml
delete mode 120000 FileSets/v2.92/DetailLoadsCombined.qml
delete mode 120000 FileSets/v2.92/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v2.92/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v2.92/HubData.qml
delete mode 100644 FileSets/v2.92/LINKS_ONLY
delete mode 120000 FileSets/v2.92/MbEditBox.qml
delete mode 120000 FileSets/v2.92/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v2.92/MbItem.qml
delete mode 120000 FileSets/v2.92/MbItemDigitalInput.qml
delete mode 120000 FileSets/v2.92/MbSpinBox.qml
delete mode 120000 FileSets/v2.92/MbStyle.qml
delete mode 120000 FileSets/v2.92/MbSubMenu.qml
delete mode 120000 FileSets/v2.92/Multi.qml
delete mode 120000 FileSets/v2.92/ObjectAcConnection.qml
delete mode 120000 FileSets/v2.92/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v2.92/OverviewBox.qml
delete mode 120000 FileSets/v2.92/OverviewConnection.qml
delete mode 120000 FileSets/v2.92/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v2.92/OverviewFlowComplex.qml
delete mode 120000 FileSets/v2.92/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v2.92/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v2.92/OverviewGridParallel.qml
delete mode 120000 FileSets/v2.92/OverviewHub.qml
delete mode 120000 FileSets/v2.92/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v2.92/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v2.92/OverviewSolarCharger.qml
delete mode 120000 FileSets/v2.92/OverviewSolarInverter.qml
delete mode 120000 FileSets/v2.92/OverviewTankDelegate.qml
delete mode 120000 FileSets/v2.92/OverviewTanks.qml
delete mode 120000 FileSets/v2.92/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v2.92/PageDigitalInput.qml
delete mode 120000 FileSets/v2.92/PageGenerator.qml
delete mode 120000 FileSets/v2.92/PageMain.qml
delete mode 120000 FileSets/v2.92/PageSettingsDisplay.qml
delete mode 120000 FileSets/v2.92/PageSettingsGenerator.qml
delete mode 120000 FileSets/v2.92/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v2.92/PageSettingsRelay.qml
delete mode 120000 FileSets/v2.92/PowerGauge.qml
delete mode 120000 FileSets/v2.92/Tile.qml
delete mode 120000 FileSets/v2.92/TileDigIn.qml
delete mode 120000 FileSets/v2.92/TileRelay.qml
delete mode 120000 FileSets/v2.92/TileText.qml
delete mode 120000 FileSets/v2.92/attributes.csv
delete mode 120000 FileSets/v2.92/dbus_digitalinputs.py
delete mode 120000 FileSets/v2.92/dbus_generator.py
delete mode 120000 FileSets/v2.92/main.qml
delete mode 120000 FileSets/v2.92/startstop.py
delete mode 120000 FileSets/v2.92/styles.css
delete mode 120000 FileSets/v2.93/Battery.qml
delete mode 100644 FileSets/v2.93/COMPLETE
delete mode 120000 FileSets/v2.93/DetailAcInput.qml
delete mode 120000 FileSets/v2.93/DetailInverter.qml
delete mode 120000 FileSets/v2.93/DetailLoadsCombined.qml
delete mode 120000 FileSets/v2.93/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v2.93/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v2.93/HubData.qml
delete mode 100644 FileSets/v2.93/LINKS_ONLY
delete mode 120000 FileSets/v2.93/MbEditBox.qml
delete mode 120000 FileSets/v2.93/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v2.93/MbItem.qml
delete mode 120000 FileSets/v2.93/MbItemDigitalInput.qml
delete mode 120000 FileSets/v2.93/MbSpinBox.qml
delete mode 120000 FileSets/v2.93/MbStyle.qml
delete mode 120000 FileSets/v2.93/MbSubMenu.qml
delete mode 120000 FileSets/v2.93/Multi.qml
delete mode 120000 FileSets/v2.93/ObjectAcConnection.qml
delete mode 120000 FileSets/v2.93/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v2.93/OverviewBox.qml
delete mode 120000 FileSets/v2.93/OverviewConnection.qml
delete mode 120000 FileSets/v2.93/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v2.93/OverviewFlowComplex.qml
delete mode 120000 FileSets/v2.93/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v2.93/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v2.93/OverviewGridParallel.qml
delete mode 120000 FileSets/v2.93/OverviewHub.qml
delete mode 120000 FileSets/v2.93/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v2.93/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v2.93/OverviewSolarCharger.qml
delete mode 120000 FileSets/v2.93/OverviewSolarInverter.qml
delete mode 120000 FileSets/v2.93/OverviewTankDelegate.qml
delete mode 120000 FileSets/v2.93/OverviewTanks.qml
delete mode 120000 FileSets/v2.93/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v2.93/PageDigitalInput.qml
delete mode 120000 FileSets/v2.93/PageGenerator.qml
delete mode 120000 FileSets/v2.93/PageMain.qml
delete mode 120000 FileSets/v2.93/PageSettingsDisplay.qml
delete mode 120000 FileSets/v2.93/PageSettingsGenerator.qml
delete mode 120000 FileSets/v2.93/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v2.93/PageSettingsRelay.qml
delete mode 120000 FileSets/v2.93/PowerGauge.qml
delete mode 120000 FileSets/v2.93/Tile.qml
delete mode 120000 FileSets/v2.93/TileDigIn.qml
delete mode 120000 FileSets/v2.93/TileRelay.qml
delete mode 120000 FileSets/v2.93/TileText.qml
delete mode 120000 FileSets/v2.93/attributes.csv
delete mode 120000 FileSets/v2.93/dbus_digitalinputs.py
delete mode 120000 FileSets/v2.93/dbus_generator.py
delete mode 120000 FileSets/v2.93/dbus_systemcalc.py
delete mode 120000 FileSets/v2.93/main.qml
delete mode 120000 FileSets/v2.93/startstop.py
delete mode 120000 FileSets/v2.93/styles.css
delete mode 120000 FileSets/v2.94/Battery.qml
delete mode 100644 FileSets/v2.94/COMPLETE
delete mode 120000 FileSets/v2.94/DetailAcInput.qml
delete mode 120000 FileSets/v2.94/DetailInverter.qml
delete mode 120000 FileSets/v2.94/DetailLoadsCombined.qml
delete mode 120000 FileSets/v2.94/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v2.94/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v2.94/HubData.qml
delete mode 120000 FileSets/v2.94/MbEditBox.qml
delete mode 120000 FileSets/v2.94/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v2.94/MbSpinBox.qml
delete mode 120000 FileSets/v2.94/MbSubMenu.qml
delete mode 120000 FileSets/v2.94/Multi.qml
delete mode 120000 FileSets/v2.94/ObjectAcConnection.qml
delete mode 120000 FileSets/v2.94/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v2.94/OverviewBox.qml
delete mode 120000 FileSets/v2.94/OverviewConnection.qml
delete mode 120000 FileSets/v2.94/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v2.94/OverviewFlowComplex.qml
delete mode 100644 FileSets/v2.94/OverviewGeneratorEnhanced.qml
delete mode 100644 FileSets/v2.94/OverviewGeneratorEnhanced.qml.orig
delete mode 120000 FileSets/v2.94/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v2.94/OverviewGridParallel.qml
delete mode 120000 FileSets/v2.94/OverviewHub.qml
delete mode 120000 FileSets/v2.94/OverviewHubEnhanced.qml
delete mode 100644 FileSets/v2.94/OverviewMobileEnhanced.qml
delete mode 100644 FileSets/v2.94/OverviewMobileEnhanced.qml.orig
delete mode 120000 FileSets/v2.94/OverviewSolarCharger.qml
delete mode 120000 FileSets/v2.94/OverviewSolarInverter.qml
delete mode 120000 FileSets/v2.94/OverviewTankDelegate.qml
delete mode 120000 FileSets/v2.94/OverviewTanks.qml
delete mode 100644 FileSets/v2.94/OverviewTanksTempsDigInputs.qml
delete mode 100644 FileSets/v2.94/OverviewTanksTempsDigInputs.qml.orig
delete mode 100644 FileSets/v2.94/PageGenerator.qml
delete mode 100644 FileSets/v2.94/PageGenerator.qml.orig
delete mode 100644 FileSets/v2.94/PageSettingsGenerator.qml
delete mode 100644 FileSets/v2.94/PageSettingsGenerator.qml.orig
delete mode 100644 FileSets/v2.94/PageSettingsGuiMods.qml
delete mode 100644 FileSets/v2.94/PageSettingsGuiMods.qml.orig
delete mode 100644 FileSets/v2.94/PageSettingsRelay.qml
delete mode 100644 FileSets/v2.94/PageSettingsRelay.qml.orig
delete mode 120000 FileSets/v2.94/PowerGauge.qml
delete mode 100644 FileSets/v2.94/TileDigIn.qml
delete mode 100755 FileSets/v2.94/TileDigIn.qml.orig
delete mode 100644 FileSets/v2.94/TileRelay.qml
delete mode 100644 FileSets/v2.94/TileRelay.qml.orig
delete mode 120000 FileSets/v2.94/TileText.qml
delete mode 100755 FileSets/v2.94/dbus_digitalinputs.py
delete mode 100755 FileSets/v2.94/dbus_digitalinputs.py.orig
delete mode 120000 FileSets/v2.94/dbus_generator.py
delete mode 100644 FileSets/v2.94/startstop.py
delete mode 100644 FileSets/v2.94/startstop.py.orig
delete mode 120000 FileSets/v2.94/styles.css
delete mode 120000 FileSets/v3.00/Battery.qml
delete mode 100644 FileSets/v3.00/COMPLETE
delete mode 120000 FileSets/v3.00/DetailAcInput.qml
delete mode 120000 FileSets/v3.00/DetailInverter.qml
delete mode 120000 FileSets/v3.00/DetailLoadsCombined.qml
delete mode 120000 FileSets/v3.00/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v3.00/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v3.00/HubData.qml
delete mode 100644 FileSets/v3.00/LINKS_ONLY
delete mode 120000 FileSets/v3.00/MbEditBox.qml
delete mode 120000 FileSets/v3.00/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v3.00/MbItem.qml
delete mode 120000 FileSets/v3.00/MbItemDigitalInput.qml
delete mode 120000 FileSets/v3.00/MbSpinBox.qml
delete mode 120000 FileSets/v3.00/MbStyle.qml
delete mode 120000 FileSets/v3.00/MbSubMenu.qml
delete mode 120000 FileSets/v3.00/Multi.qml
delete mode 120000 FileSets/v3.00/ObjectAcConnection.qml
delete mode 120000 FileSets/v3.00/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v3.00/OverviewBox.qml
delete mode 120000 FileSets/v3.00/OverviewConnection.qml
delete mode 120000 FileSets/v3.00/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v3.00/OverviewFlowComplex.qml
delete mode 120000 FileSets/v3.00/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v3.00/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v3.00/OverviewGridParallel.qml
delete mode 120000 FileSets/v3.00/OverviewHub.qml
delete mode 120000 FileSets/v3.00/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v3.00/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.00/OverviewSolarCharger.qml
delete mode 120000 FileSets/v3.00/OverviewSolarInverter.qml
delete mode 120000 FileSets/v3.00/OverviewTankDelegate.qml
delete mode 120000 FileSets/v3.00/OverviewTanks.qml
delete mode 120000 FileSets/v3.00/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v3.00/PageDigitalInput.qml
delete mode 120000 FileSets/v3.00/PageGenerator.qml
delete mode 120000 FileSets/v3.00/PageMain.qml
delete mode 120000 FileSets/v3.00/PageSettingsDisplay.qml
delete mode 120000 FileSets/v3.00/PageSettingsGenerator.qml
delete mode 120000 FileSets/v3.00/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v3.00/PageSettingsRelay.qml
delete mode 120000 FileSets/v3.00/PowerGauge.qml
delete mode 120000 FileSets/v3.00/Tile.qml
delete mode 120000 FileSets/v3.00/TileDigIn.qml
delete mode 120000 FileSets/v3.00/TileRelay.qml
delete mode 120000 FileSets/v3.00/TileText.qml
delete mode 120000 FileSets/v3.00/attributes.csv
delete mode 120000 FileSets/v3.00/dbus_digitalinputs.py
delete mode 120000 FileSets/v3.00/dbus_generator.py
delete mode 120000 FileSets/v3.00/main.qml
delete mode 120000 FileSets/v3.00/startstop.py
delete mode 120000 FileSets/v3.00/styles.css
delete mode 100644 FileSets/v3.00~32/COMPLETE
delete mode 120000 FileSets/v3.00~32/DetailAcInput.qml
delete mode 120000 FileSets/v3.00~32/DetailInverter.qml
delete mode 120000 FileSets/v3.00~32/DetailLoadsCombined.qml
delete mode 120000 FileSets/v3.00~32/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v3.00~32/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v3.00~32/HubData.qml
delete mode 120000 FileSets/v3.00~32/MbEditBox.qml
delete mode 120000 FileSets/v3.00~32/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v3.00~32/MbItem.qml
delete mode 120000 FileSets/v3.00~32/MbItemDigitalInput.qml
delete mode 120000 FileSets/v3.00~32/MbSpinBox.qml
delete mode 120000 FileSets/v3.00~32/MbStyle.qml
delete mode 120000 FileSets/v3.00~32/MbSubMenu.qml
delete mode 120000 FileSets/v3.00~32/Multi.qml
delete mode 120000 FileSets/v3.00~32/ObjectAcConnection.qml
delete mode 120000 FileSets/v3.00~32/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v3.00~32/OverviewBox.qml
delete mode 120000 FileSets/v3.00~32/OverviewConnection.qml
delete mode 120000 FileSets/v3.00~32/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v3.00~32/OverviewFlowComplex.qml
delete mode 100644 FileSets/v3.00~32/OverviewGeneratorEnhanced.qml
delete mode 100644 FileSets/v3.00~32/OverviewGeneratorEnhanced.qml.orig
delete mode 100644 FileSets/v3.00~32/OverviewGeneratorRelayEnhanced.qml
delete mode 100644 FileSets/v3.00~32/OverviewGeneratorRelayEnhanced.qml.orig
delete mode 120000 FileSets/v3.00~32/OverviewGridParallel.qml
delete mode 120000 FileSets/v3.00~32/OverviewHub.qml
delete mode 120000 FileSets/v3.00~32/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v3.00~32/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.00~32/OverviewSolarCharger.qml
delete mode 120000 FileSets/v3.00~32/OverviewTankDelegate.qml
delete mode 120000 FileSets/v3.00~32/OverviewTanks.qml
delete mode 120000 FileSets/v3.00~32/OverviewTanksTempsDigInputs.qml
delete mode 100644 FileSets/v3.00~32/PageGenerator.qml
delete mode 100644 FileSets/v3.00~32/PageGenerator.qml.orig
delete mode 120000 FileSets/v3.00~32/PageMain.qml
delete mode 120000 FileSets/v3.00~32/PageSettingsDisplay.qml
delete mode 100644 FileSets/v3.00~32/PageSettingsGenerator.qml
delete mode 100644 FileSets/v3.00~32/PageSettingsGenerator.qml.orig
delete mode 120000 FileSets/v3.00~32/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v3.00~32/PageSettingsRelay.qml
delete mode 120000 FileSets/v3.00~32/PowerGauge.qml
delete mode 120000 FileSets/v3.00~32/Tile.qml
delete mode 120000 FileSets/v3.00~32/TileDigIn.qml
delete mode 120000 FileSets/v3.00~32/TileRelay.qml
delete mode 120000 FileSets/v3.00~32/TileText.qml
delete mode 120000 FileSets/v3.00~32/attributes.csv
delete mode 120000 FileSets/v3.00~32/dbus_digitalinputs.py
delete mode 100755 FileSets/v3.00~32/dbus_generator.py
delete mode 100755 FileSets/v3.00~32/dbus_generator.py.orig
delete mode 120000 FileSets/v3.00~32/main.qml
delete mode 100644 FileSets/v3.00~32/startstop.py
delete mode 100644 FileSets/v3.00~32/startstop.py.orig
delete mode 120000 FileSets/v3.00~32/styles.css
delete mode 100644 FileSets/v3.01/COMPLETE
delete mode 100644 FileSets/v3.01/DetailAcInput.qml
delete mode 100644 FileSets/v3.01/DetailAcInput.qml.orig
delete mode 100644 FileSets/v3.01/DetailInverter.qml
delete mode 100644 FileSets/v3.01/DetailInverter.qml.orig
delete mode 100644 FileSets/v3.01/DetailLoadsCombined.qml
delete mode 100644 FileSets/v3.01/DetailLoadsCombined.qml.orig
delete mode 100644 FileSets/v3.01/DetailLoadsOnInput.qml
delete mode 100644 FileSets/v3.01/DetailLoadsOnInput.qml.orig
delete mode 100644 FileSets/v3.01/DetailLoadsOnOutput.qml
delete mode 100644 FileSets/v3.01/DetailLoadsOnOutput.qml.orig
delete mode 100644 FileSets/v3.01/HubData.qml
delete mode 100644 FileSets/v3.01/HubData.qml.orig
delete mode 120000 FileSets/v3.01/MbEditBox.qml
delete mode 120000 FileSets/v3.01/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v3.01/MbItem.qml
delete mode 120000 FileSets/v3.01/MbItemDigitalInput.qml
delete mode 120000 FileSets/v3.01/MbSpinBox.qml
delete mode 120000 FileSets/v3.01/MbStyle.qml
delete mode 120000 FileSets/v3.01/MbSubMenu.qml
delete mode 120000 FileSets/v3.01/Multi.qml
delete mode 100644 FileSets/v3.01/ObjectAcConnection.qml
delete mode 100644 FileSets/v3.01/ObjectAcConnection.qml.orig
delete mode 100644 FileSets/v3.01/OverviewAcValuesEnhanced.qml
delete mode 100644 FileSets/v3.01/OverviewAcValuesEnhanced.qml.orig
delete mode 120000 FileSets/v3.01/OverviewBox.qml
delete mode 120000 FileSets/v3.01/OverviewConnection.qml
delete mode 120000 FileSets/v3.01/OverviewConnectionEnd.qml
delete mode 100644 FileSets/v3.01/OverviewFlowComplex.qml
delete mode 100644 FileSets/v3.01/OverviewFlowComplex.qml.orig
delete mode 100644 FileSets/v3.01/OverviewGeneratorEnhanced.qml
delete mode 100644 FileSets/v3.01/OverviewGeneratorEnhanced.qml.orig
delete mode 120000 FileSets/v3.01/OverviewGeneratorRelayEnhanced.qml
delete mode 100644 FileSets/v3.01/OverviewGridParallel.qml
delete mode 100644 FileSets/v3.01/OverviewGridParallel.qml.orig
delete mode 100644 FileSets/v3.01/OverviewHub.qml
delete mode 100644 FileSets/v3.01/OverviewHub.qml.orig
delete mode 100644 FileSets/v3.01/OverviewHubEnhanced.qml
delete mode 100644 FileSets/v3.01/OverviewHubEnhanced.qml.orig
delete mode 120000 FileSets/v3.01/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.01/OverviewSolarCharger.qml
delete mode 120000 FileSets/v3.01/OverviewSolarInverter.qml
delete mode 120000 FileSets/v3.01/OverviewTankDelegate.qml
delete mode 120000 FileSets/v3.01/OverviewTanks.qml
delete mode 120000 FileSets/v3.01/OverviewTanksTempsDigInputs.qml
delete mode 100644 FileSets/v3.01/PageGenerator.qml
delete mode 100644 FileSets/v3.01/PageGenerator.qml.orig
delete mode 120000 FileSets/v3.01/PageMain.qml
delete mode 100644 FileSets/v3.01/PageSettingsGenerator.qml
delete mode 100644 FileSets/v3.01/PageSettingsGenerator.qml.orig
delete mode 100644 FileSets/v3.01/PageSettingsGuiMods.qml
delete mode 100644 FileSets/v3.01/PageSettingsGuiMods.qml.orig
delete mode 120000 FileSets/v3.01/PageSettingsRelay.qml
delete mode 100644 FileSets/v3.01/PowerGauge.qml
delete mode 100644 FileSets/v3.01/PowerGauge.qml.orig
delete mode 120000 FileSets/v3.01/Tile.qml
delete mode 100755 FileSets/v3.01/TileDigIn.qml.orig
delete mode 120000 FileSets/v3.01/TileRelay.qml
delete mode 120000 FileSets/v3.01/TileText.qml
delete mode 100755 FileSets/v3.01/dbus_digitalinputs.py
delete mode 100755 FileSets/v3.01/dbus_digitalinputs.py.orig
delete mode 100755 FileSets/v3.01/dbus_generator.py
delete mode 100755 FileSets/v3.01/dbus_generator.py.orig
delete mode 100644 FileSets/v3.01/startstop.py
delete mode 100644 FileSets/v3.01/startstop.py.orig
delete mode 120000 FileSets/v3.01/styles.css
mode change 120000 => 100644 FileSets/v3.31/OverviewGeneratorEnhanced.qml
rename FileSets/{v3.40~21 => v3.31}/OverviewGeneratorEnhanced.qml.orig (100%)
mode change 120000 => 100644 FileSets/v3.31/PageGenerator.qml
rename FileSets/{v3.40~21 => v3.31}/PageGenerator.qml.orig (100%)
mode change 120000 => 100644 FileSets/v3.34/DetailAcInput.qml
rename FileSets/{v3.40~8 => v3.34}/DetailAcInput.qml.orig (100%)
mode change 120000 => 100644 FileSets/v3.34/DetailInverter.qml
rename FileSets/{v3.40~8 => v3.34}/DetailInverter.qml.orig (100%)
mode change 120000 => 100644 FileSets/v3.34/DetailLoadsCombined.qml
rename FileSets/{v3.40~8 => v3.34}/DetailLoadsCombined.qml.orig (100%)
mode change 120000 => 100644 FileSets/v3.34/DetailLoadsOnInput.qml
rename FileSets/{v3.40~8 => v3.34}/DetailLoadsOnInput.qml.orig (100%)
mode change 120000 => 100644 FileSets/v3.34/DetailLoadsOnOutput.qml
rename FileSets/{v3.40~8 => v3.34}/DetailLoadsOnOutput.qml.orig (100%)
mode change 120000 => 100644 FileSets/v3.34/HubData.qml
rename FileSets/{v3.40~8 => v3.34}/HubData.qml.orig (100%)
mode change 120000 => 100644 FileSets/v3.34/OverviewFlowComplex.qml
rename FileSets/{v3.40~8 => v3.34}/OverviewFlowComplex.qml.orig (100%)
mode change 100644 => 120000 FileSets/v3.34/OverviewGeneratorEnhanced.qml
mode change 120000 => 100644 FileSets/v3.34/OverviewGridParallel.qml
rename FileSets/{v3.40~8 => v3.34}/OverviewGridParallel.qml.orig (100%)
mode change 120000 => 100644 FileSets/v3.34/OverviewHub.qml
rename FileSets/{v3.40~8 => v3.34}/OverviewHub.qml.orig (100%)
mode change 120000 => 100644 FileSets/v3.34/OverviewHubEnhanced.qml
rename FileSets/{v3.40~8 => v3.34}/OverviewHubEnhanced.qml.orig (100%)
mode change 100644 => 120000 FileSets/v3.34/PageGenerator.qml
mode change 120000 => 100644 FileSets/v3.34/PowerGauge.qml
rename FileSets/{v3.40~8 => v3.34}/PowerGauge.qml.orig (100%)
mode change 120000 => 100644 FileSets/v3.34/startstop.py
rename FileSets/{v3.40~37 => v3.34}/startstop.py.orig (100%)
rename FileSets/{v2.71 => v3.40}/COMPLETE (100%)
rename FileSets/{v3.40~13 => v3.40}/DetailAcInput.qml (100%)
rename FileSets/{v3.40~39 => v3.40}/DetailAcInput.qml.orig (100%)
rename FileSets/{v3.40~13 => v3.40}/DetailInverter.qml (100%)
rename FileSets/{v3.40~39 => v3.40}/DetailInverter.qml.orig (100%)
rename FileSets/{v3.40~13 => v3.40}/DetailLoadsCombined.qml (100%)
rename FileSets/{v3.40~39 => v3.40}/DetailLoadsCombined.qml.orig (100%)
rename FileSets/{v3.40~13 => v3.40}/DetailLoadsOnInput.qml (100%)
rename FileSets/{v3.40~39 => v3.40}/DetailLoadsOnInput.qml.orig (100%)
rename FileSets/{v3.40~13 => v3.40}/DetailLoadsOnOutput.qml (100%)
rename FileSets/{v3.40~39 => v3.40}/DetailLoadsOnOutput.qml.orig (100%)
rename FileSets/{v3.40~39 => v3.40}/HubData.qml (100%)
rename FileSets/{v3.40~39 => v3.40}/HubData.qml.orig (100%)
rename FileSets/{v3.40~39 => v3.40}/ObjectAcConnection.qml (100%)
rename FileSets/{v3.40~39 => v3.40}/ObjectAcConnection.qml.orig (100%)
rename FileSets/{v3.40~39 => v3.40}/OverviewAcValuesEnhanced.qml (100%)
rename FileSets/{v3.40~39 => v3.40}/OverviewAcValuesEnhanced.qml.orig (100%)
rename FileSets/{v3.40~39 => v3.40}/OverviewFlowComplex.qml (100%)
rename FileSets/{v3.40~39 => v3.40}/OverviewFlowComplex.qml.orig (100%)
rename FileSets/{v3.40~21 => v3.40}/OverviewGeneratorEnhanced.qml (100%)
rename FileSets/{v3.34 => v3.40}/OverviewGeneratorEnhanced.qml.orig (100%)
rename FileSets/{v3.40~39 => v3.40}/OverviewGeneratorRelayEnhanced.qml (100%)
rename FileSets/{v3.40~39 => v3.40}/OverviewGeneratorRelayEnhanced.qml.orig (100%)
rename FileSets/{v3.40~39 => v3.40}/OverviewGridParallel.qml (100%)
rename FileSets/{v3.40~39 => v3.40}/OverviewGridParallel.qml.orig (100%)
rename FileSets/{v3.40~39 => v3.40}/OverviewHub.qml (100%)
rename FileSets/{v3.40~39 => v3.40}/OverviewHub.qml.orig (100%)
rename FileSets/{v3.40~39 => v3.40}/OverviewHubEnhanced.qml (100%)
rename FileSets/{v3.40~39 => v3.40}/OverviewHubEnhanced.qml.orig (100%)
rename FileSets/{v3.40~39 => v3.40}/OverviewMobileEnhanced.qml (100%)
rename FileSets/{v3.40~39 => v3.40}/OverviewMobileEnhanced.qml.orig (100%)
rename FileSets/{v2.73 => v3.40}/OverviewTanksTempsDigInputs.qml (100%)
rename FileSets/{v3.40~39 => v3.40}/OverviewTanksTempsDigInputs.qml.orig (100%)
rename FileSets/{v3.40~26 => v3.40}/PageGenerator.qml (96%)
rename FileSets/{v3.34 => v3.40}/PageGenerator.qml.orig (100%)
rename FileSets/{v3.40~39 => v3.40}/PageSettingsGenerator.qml (100%)
rename FileSets/{v3.40~39 => v3.40}/PageSettingsGenerator.qml.orig (100%)
rename FileSets/{v3.40~39 => v3.40}/PageSettingsGuiMods.qml (100%)
rename FileSets/{v3.40~39 => v3.40}/PageSettingsGuiMods.qml.orig (100%)
rename FileSets/{v3.40~39 => v3.40}/PageSettingsRelay.qml (100%)
rename FileSets/{v3.40~39 => v3.40}/PageSettingsRelay.qml.orig (100%)
rename FileSets/{v3.40~39 => v3.40}/PowerGauge.qml (100%)
rename FileSets/{v3.40~39 => v3.40}/PowerGauge.qml.orig (100%)
rename FileSets/{v3.01 => v3.40}/TileDigIn.qml (100%)
rename FileSets/{v3.40~39 => v3.40}/TileDigIn.qml.orig (100%)
rename FileSets/{v3.40~39 => v3.40}/TileRelay.qml (100%)
rename FileSets/{v3.40~39 => v3.40}/TileRelay.qml.orig (100%)
rename FileSets/{v3.40~39 => v3.40}/dbus_digitalinputs.py (100%)
rename FileSets/{v3.40~39 => v3.40}/dbus_digitalinputs.py.orig (100%)
rename FileSets/{v3.40~39 => v3.40}/dbus_generator.py (100%)
rename FileSets/{v3.40~39 => v3.40}/dbus_generator.py.orig (100%)
rename FileSets/{v3.40~39 => v3.40}/startstop.py (100%)
rename FileSets/{v3.40~39 => v3.40}/startstop.py.orig (100%)
delete mode 120000 FileSets/v3.40~1/Battery.qml
delete mode 100644 FileSets/v3.40~1/COMPLETE
delete mode 120000 FileSets/v3.40~1/DetailAcInput.qml
delete mode 120000 FileSets/v3.40~1/DetailInverter.qml
delete mode 120000 FileSets/v3.40~1/DetailLoadsCombined.qml
delete mode 120000 FileSets/v3.40~1/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v3.40~1/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v3.40~1/HubData.qml
delete mode 100644 FileSets/v3.40~1/LINKS_ONLY
delete mode 120000 FileSets/v3.40~1/MbEditBox.qml
delete mode 120000 FileSets/v3.40~1/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v3.40~1/MbItem.qml
delete mode 120000 FileSets/v3.40~1/MbItemDigitalInput.qml
delete mode 120000 FileSets/v3.40~1/MbSpinBox.qml
delete mode 120000 FileSets/v3.40~1/MbStyle.qml
delete mode 120000 FileSets/v3.40~1/MbSubMenu.qml
delete mode 120000 FileSets/v3.40~1/Multi.qml
delete mode 120000 FileSets/v3.40~1/ObjectAcConnection.qml
delete mode 120000 FileSets/v3.40~1/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v3.40~1/OverviewBox.qml
delete mode 120000 FileSets/v3.40~1/OverviewConnection.qml
delete mode 120000 FileSets/v3.40~1/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v3.40~1/OverviewFlowComplex.qml
delete mode 120000 FileSets/v3.40~1/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v3.40~1/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v3.40~1/OverviewGridParallel.qml
delete mode 120000 FileSets/v3.40~1/OverviewHub.qml
delete mode 120000 FileSets/v3.40~1/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v3.40~1/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.40~1/OverviewSolarCharger.qml
delete mode 120000 FileSets/v3.40~1/OverviewSolarInverter.qml
delete mode 120000 FileSets/v3.40~1/OverviewTankDelegate.qml
delete mode 120000 FileSets/v3.40~1/OverviewTanks.qml
delete mode 120000 FileSets/v3.40~1/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v3.40~1/PageDigitalInput.qml
delete mode 120000 FileSets/v3.40~1/PageGenerator.qml
delete mode 120000 FileSets/v3.40~1/PageMain.qml
delete mode 120000 FileSets/v3.40~1/PageSettingsDisplay.qml
delete mode 120000 FileSets/v3.40~1/PageSettingsGenerator.qml
delete mode 120000 FileSets/v3.40~1/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v3.40~1/PageSettingsRelay.qml
delete mode 120000 FileSets/v3.40~1/PowerGauge.qml
delete mode 120000 FileSets/v3.40~1/Tile.qml
delete mode 120000 FileSets/v3.40~1/TileDigIn.qml
delete mode 120000 FileSets/v3.40~1/TileRelay.qml
delete mode 120000 FileSets/v3.40~1/TileText.qml
delete mode 120000 FileSets/v3.40~1/attributes.csv
delete mode 120000 FileSets/v3.40~1/dbus_digitalinputs.py
delete mode 120000 FileSets/v3.40~1/dbus_generator.py
delete mode 120000 FileSets/v3.40~1/main.qml
delete mode 120000 FileSets/v3.40~1/startstop.py
delete mode 120000 FileSets/v3.40~1/styles.css
delete mode 120000 FileSets/v3.40~10/Battery.qml
delete mode 100644 FileSets/v3.40~10/COMPLETE
delete mode 120000 FileSets/v3.40~10/DetailAcInput.qml
delete mode 120000 FileSets/v3.40~10/DetailInverter.qml
delete mode 120000 FileSets/v3.40~10/DetailLoadsCombined.qml
delete mode 120000 FileSets/v3.40~10/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v3.40~10/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v3.40~10/HubData.qml
delete mode 100644 FileSets/v3.40~10/LINKS_ONLY
delete mode 120000 FileSets/v3.40~10/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v3.40~10/MbItem.qml
delete mode 120000 FileSets/v3.40~10/MbItemDigitalInput.qml
delete mode 120000 FileSets/v3.40~10/MbSpinBox.qml
delete mode 120000 FileSets/v3.40~10/MbStyle.qml
delete mode 120000 FileSets/v3.40~10/MbSubMenu.qml
delete mode 120000 FileSets/v3.40~10/Multi.qml
delete mode 120000 FileSets/v3.40~10/ObjectAcConnection.qml
delete mode 120000 FileSets/v3.40~10/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v3.40~10/OverviewBox.qml
delete mode 120000 FileSets/v3.40~10/OverviewConnection.qml
delete mode 120000 FileSets/v3.40~10/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v3.40~10/OverviewFlowComplex.qml
delete mode 120000 FileSets/v3.40~10/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v3.40~10/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v3.40~10/OverviewGridParallel.qml
delete mode 120000 FileSets/v3.40~10/OverviewHub.qml
delete mode 120000 FileSets/v3.40~10/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v3.40~10/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.40~10/OverviewSolarCharger.qml
delete mode 120000 FileSets/v3.40~10/OverviewSolarInverter.qml
delete mode 120000 FileSets/v3.40~10/OverviewTankDelegate.qml
delete mode 120000 FileSets/v3.40~10/OverviewTanks.qml
delete mode 120000 FileSets/v3.40~10/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v3.40~10/PageDigitalInput.qml
delete mode 120000 FileSets/v3.40~10/PageGenerator.qml
delete mode 120000 FileSets/v3.40~10/PageMain.qml
delete mode 120000 FileSets/v3.40~10/PageSettingsDisplay.qml
delete mode 120000 FileSets/v3.40~10/PageSettingsGenerator.qml
delete mode 120000 FileSets/v3.40~10/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v3.40~10/PageSettingsRelay.qml
delete mode 120000 FileSets/v3.40~10/PowerGauge.qml
delete mode 120000 FileSets/v3.40~10/Tile.qml
delete mode 120000 FileSets/v3.40~10/TileDigIn.qml
delete mode 120000 FileSets/v3.40~10/TileRelay.qml
delete mode 120000 FileSets/v3.40~10/TileText.qml
delete mode 120000 FileSets/v3.40~10/attributes.csv
delete mode 120000 FileSets/v3.40~10/dbus_digitalinputs.py
delete mode 120000 FileSets/v3.40~10/dbus_generator.py
delete mode 120000 FileSets/v3.40~10/main.qml
delete mode 120000 FileSets/v3.40~10/startstop.py
delete mode 120000 FileSets/v3.40~10/styles.css
delete mode 120000 FileSets/v3.40~13/Battery.qml
delete mode 100644 FileSets/v3.40~13/COMPLETE
delete mode 100644 FileSets/v3.40~13/DetailAcInput.qml.orig
delete mode 100644 FileSets/v3.40~13/DetailInverter.qml.orig
delete mode 100644 FileSets/v3.40~13/DetailLoadsCombined.qml.orig
delete mode 100644 FileSets/v3.40~13/DetailLoadsOnInput.qml.orig
delete mode 100644 FileSets/v3.40~13/DetailLoadsOnOutput.qml.orig
delete mode 100644 FileSets/v3.40~13/HubData.qml
delete mode 100644 FileSets/v3.40~13/HubData.qml.orig
delete mode 120000 FileSets/v3.40~13/MbEditBox.qml
delete mode 120000 FileSets/v3.40~13/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v3.40~13/MbItem.qml
delete mode 120000 FileSets/v3.40~13/MbItemDigitalInput.qml
delete mode 120000 FileSets/v3.40~13/MbSpinBox.qml
delete mode 120000 FileSets/v3.40~13/MbStyle.qml
delete mode 120000 FileSets/v3.40~13/MbSubMenu.qml
delete mode 120000 FileSets/v3.40~13/Multi.qml
delete mode 120000 FileSets/v3.40~13/ObjectAcConnection.qml
delete mode 120000 FileSets/v3.40~13/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v3.40~13/OverviewBox.qml
delete mode 120000 FileSets/v3.40~13/OverviewConnection.qml
delete mode 120000 FileSets/v3.40~13/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v3.40~13/OverviewFlowComplex.qml
delete mode 120000 FileSets/v3.40~13/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v3.40~13/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v3.40~13/OverviewGridParallel.qml
delete mode 120000 FileSets/v3.40~13/OverviewHub.qml
delete mode 120000 FileSets/v3.40~13/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v3.40~13/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.40~13/OverviewSolarCharger.qml
delete mode 120000 FileSets/v3.40~13/OverviewSolarInverter.qml
delete mode 120000 FileSets/v3.40~13/OverviewTankDelegate.qml
delete mode 120000 FileSets/v3.40~13/OverviewTanks.qml
delete mode 120000 FileSets/v3.40~13/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v3.40~13/PageDigitalInput.qml
delete mode 120000 FileSets/v3.40~13/PageGenerator.qml
delete mode 120000 FileSets/v3.40~13/PageSettingsDisplay.qml
delete mode 120000 FileSets/v3.40~13/PageSettingsGenerator.qml
delete mode 120000 FileSets/v3.40~13/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v3.40~13/PageSettingsRelay.qml
delete mode 100644 FileSets/v3.40~13/PowerGauge.qml
delete mode 100644 FileSets/v3.40~13/PowerGauge.qml.orig
delete mode 120000 FileSets/v3.40~13/Tile.qml
delete mode 120000 FileSets/v3.40~13/TileDigIn.qml
delete mode 120000 FileSets/v3.40~13/TileRelay.qml
delete mode 120000 FileSets/v3.40~13/TileText.qml
delete mode 120000 FileSets/v3.40~13/attributes.csv
delete mode 120000 FileSets/v3.40~13/dbus_digitalinputs.py
delete mode 120000 FileSets/v3.40~13/dbus_generator.py
delete mode 120000 FileSets/v3.40~13/startstop.py
delete mode 120000 FileSets/v3.40~13/styles.css
delete mode 120000 FileSets/v3.40~15/Battery.qml
delete mode 100644 FileSets/v3.40~15/COMPLETE
delete mode 120000 FileSets/v3.40~15/DetailAcInput.qml
delete mode 120000 FileSets/v3.40~15/DetailInverter.qml
delete mode 120000 FileSets/v3.40~15/DetailLoadsCombined.qml
delete mode 120000 FileSets/v3.40~15/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v3.40~15/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v3.40~15/HubData.qml
delete mode 100644 FileSets/v3.40~15/LINKS_ONLY
delete mode 120000 FileSets/v3.40~15/MbEditBox.qml
delete mode 120000 FileSets/v3.40~15/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v3.40~15/MbItem.qml
delete mode 120000 FileSets/v3.40~15/MbItemDigitalInput.qml
delete mode 120000 FileSets/v3.40~15/MbSpinBox.qml
delete mode 120000 FileSets/v3.40~15/MbStyle.qml
delete mode 120000 FileSets/v3.40~15/MbSubMenu.qml
delete mode 120000 FileSets/v3.40~15/Multi.qml
delete mode 120000 FileSets/v3.40~15/ObjectAcConnection.qml
delete mode 120000 FileSets/v3.40~15/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v3.40~15/OverviewBox.qml
delete mode 120000 FileSets/v3.40~15/OverviewConnection.qml
delete mode 120000 FileSets/v3.40~15/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v3.40~15/OverviewFlowComplex.qml
delete mode 120000 FileSets/v3.40~15/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v3.40~15/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v3.40~15/OverviewGridParallel.qml
delete mode 120000 FileSets/v3.40~15/OverviewHub.qml
delete mode 120000 FileSets/v3.40~15/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v3.40~15/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.40~15/OverviewSolarCharger.qml
delete mode 120000 FileSets/v3.40~15/OverviewSolarInverter.qml
delete mode 120000 FileSets/v3.40~15/OverviewTankDelegate.qml
delete mode 120000 FileSets/v3.40~15/OverviewTanks.qml
delete mode 120000 FileSets/v3.40~15/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v3.40~15/PageDigitalInput.qml
delete mode 120000 FileSets/v3.40~15/PageGenerator.qml
delete mode 120000 FileSets/v3.40~15/PageMain.qml
delete mode 120000 FileSets/v3.40~15/PageSettingsDisplay.qml
delete mode 120000 FileSets/v3.40~15/PageSettingsGenerator.qml
delete mode 120000 FileSets/v3.40~15/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v3.40~15/PageSettingsRelay.qml
delete mode 120000 FileSets/v3.40~15/PowerGauge.qml
delete mode 120000 FileSets/v3.40~15/Tile.qml
delete mode 120000 FileSets/v3.40~15/TileDigIn.qml
delete mode 120000 FileSets/v3.40~15/TileRelay.qml
delete mode 120000 FileSets/v3.40~15/TileText.qml
delete mode 120000 FileSets/v3.40~15/attributes.csv
delete mode 120000 FileSets/v3.40~15/dbus_digitalinputs.py
delete mode 120000 FileSets/v3.40~15/dbus_generator.py
delete mode 120000 FileSets/v3.40~15/main.qml
delete mode 120000 FileSets/v3.40~15/startstop.py
delete mode 120000 FileSets/v3.40~15/styles.css
delete mode 120000 FileSets/v3.40~16/Battery.qml
delete mode 100644 FileSets/v3.40~16/COMPLETE
delete mode 120000 FileSets/v3.40~16/DetailAcInput.qml
delete mode 120000 FileSets/v3.40~16/DetailInverter.qml
delete mode 120000 FileSets/v3.40~16/DetailLoadsCombined.qml
delete mode 120000 FileSets/v3.40~16/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v3.40~16/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v3.40~16/HubData.qml
delete mode 100644 FileSets/v3.40~16/LINKS_ONLY
delete mode 120000 FileSets/v3.40~16/MbEditBox.qml
delete mode 120000 FileSets/v3.40~16/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v3.40~16/MbItem.qml
delete mode 120000 FileSets/v3.40~16/MbItemDigitalInput.qml
delete mode 120000 FileSets/v3.40~16/MbSpinBox.qml
delete mode 120000 FileSets/v3.40~16/MbStyle.qml
delete mode 120000 FileSets/v3.40~16/MbSubMenu.qml
delete mode 120000 FileSets/v3.40~16/Multi.qml
delete mode 120000 FileSets/v3.40~16/ObjectAcConnection.qml
delete mode 120000 FileSets/v3.40~16/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v3.40~16/OverviewBox.qml
delete mode 120000 FileSets/v3.40~16/OverviewConnection.qml
delete mode 120000 FileSets/v3.40~16/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v3.40~16/OverviewFlowComplex.qml
delete mode 120000 FileSets/v3.40~16/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v3.40~16/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v3.40~16/OverviewGridParallel.qml
delete mode 120000 FileSets/v3.40~16/OverviewHub.qml
delete mode 120000 FileSets/v3.40~16/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v3.40~16/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.40~16/OverviewSolarCharger.qml
delete mode 120000 FileSets/v3.40~16/OverviewSolarInverter.qml
delete mode 120000 FileSets/v3.40~16/OverviewTankDelegate.qml
delete mode 120000 FileSets/v3.40~16/OverviewTanks.qml
delete mode 120000 FileSets/v3.40~16/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v3.40~16/PageDigitalInput.qml
delete mode 120000 FileSets/v3.40~16/PageGenerator.qml
delete mode 120000 FileSets/v3.40~16/PageMain.qml
delete mode 120000 FileSets/v3.40~16/PageSettingsDisplay.qml
delete mode 120000 FileSets/v3.40~16/PageSettingsGenerator.qml
delete mode 120000 FileSets/v3.40~16/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v3.40~16/PageSettingsRelay.qml
delete mode 120000 FileSets/v3.40~16/PowerGauge.qml
delete mode 120000 FileSets/v3.40~16/Tile.qml
delete mode 120000 FileSets/v3.40~16/TileDigIn.qml
delete mode 120000 FileSets/v3.40~16/TileRelay.qml
delete mode 120000 FileSets/v3.40~16/TileText.qml
delete mode 120000 FileSets/v3.40~16/dbus_digitalinputs.py
delete mode 120000 FileSets/v3.40~16/dbus_generator.py
delete mode 120000 FileSets/v3.40~16/main.qml
delete mode 120000 FileSets/v3.40~16/startstop.py
delete mode 120000 FileSets/v3.40~16/styles.css
delete mode 120000 FileSets/v3.40~17/Battery.qml
delete mode 100644 FileSets/v3.40~17/COMPLETE
delete mode 120000 FileSets/v3.40~17/DetailAcInput.qml
delete mode 120000 FileSets/v3.40~17/DetailInverter.qml
delete mode 120000 FileSets/v3.40~17/DetailLoadsCombined.qml
delete mode 120000 FileSets/v3.40~17/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v3.40~17/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v3.40~17/HubData.qml
delete mode 120000 FileSets/v3.40~17/MbEditBox.qml
delete mode 120000 FileSets/v3.40~17/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v3.40~17/MbItem.qml
delete mode 120000 FileSets/v3.40~17/MbItemDigitalInput.qml
delete mode 120000 FileSets/v3.40~17/MbSpinBox.qml
delete mode 120000 FileSets/v3.40~17/MbStyle.qml
delete mode 120000 FileSets/v3.40~17/MbSubMenu.qml
delete mode 120000 FileSets/v3.40~17/Multi.qml
delete mode 120000 FileSets/v3.40~17/ObjectAcConnection.qml
delete mode 120000 FileSets/v3.40~17/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v3.40~17/OverviewBox.qml
delete mode 120000 FileSets/v3.40~17/OverviewConnection.qml
delete mode 120000 FileSets/v3.40~17/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v3.40~17/OverviewFlowComplex.qml
delete mode 120000 FileSets/v3.40~17/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v3.40~17/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v3.40~17/OverviewGridParallel.qml
delete mode 120000 FileSets/v3.40~17/OverviewHub.qml
delete mode 120000 FileSets/v3.40~17/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v3.40~17/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.40~17/OverviewSolarCharger.qml
delete mode 120000 FileSets/v3.40~17/OverviewSolarInverter.qml
delete mode 120000 FileSets/v3.40~17/OverviewTankDelegate.qml
delete mode 120000 FileSets/v3.40~17/OverviewTanks.qml
delete mode 120000 FileSets/v3.40~17/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v3.40~17/PageDigitalInput.qml
delete mode 120000 FileSets/v3.40~17/PageGenerator.qml
delete mode 120000 FileSets/v3.40~17/PageMain.qml
delete mode 120000 FileSets/v3.40~17/PageSettingsDisplay.qml
delete mode 120000 FileSets/v3.40~17/PageSettingsGenerator.qml
delete mode 120000 FileSets/v3.40~17/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v3.40~17/PageSettingsRelay.qml
delete mode 120000 FileSets/v3.40~17/PowerGauge.qml
delete mode 120000 FileSets/v3.40~17/Tile.qml
delete mode 120000 FileSets/v3.40~17/TileDigIn.qml
delete mode 120000 FileSets/v3.40~17/TileRelay.qml
delete mode 120000 FileSets/v3.40~17/TileText.qml
delete mode 120000 FileSets/v3.40~17/attributes.csv
delete mode 120000 FileSets/v3.40~17/dbus_digitalinputs.py
delete mode 120000 FileSets/v3.40~17/dbus_generator.py
delete mode 120000 FileSets/v3.40~17/dbus_systemcalc.py
delete mode 120000 FileSets/v3.40~17/main.qml
delete mode 100644 FileSets/v3.40~17/startstop.py
delete mode 100644 FileSets/v3.40~17/startstop.py.orig
delete mode 120000 FileSets/v3.40~17/styles.css
delete mode 120000 FileSets/v3.40~18/Battery.qml
delete mode 100644 FileSets/v3.40~18/COMPLETE
delete mode 120000 FileSets/v3.40~18/DetailAcInput.qml
delete mode 120000 FileSets/v3.40~18/DetailInverter.qml
delete mode 120000 FileSets/v3.40~18/DetailLoadsCombined.qml
delete mode 120000 FileSets/v3.40~18/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v3.40~18/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v3.40~18/HubData.qml
delete mode 100644 FileSets/v3.40~18/LINKS_ONLY
delete mode 120000 FileSets/v3.40~18/MbEditBox.qml
delete mode 120000 FileSets/v3.40~18/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v3.40~18/MbItem.qml
delete mode 120000 FileSets/v3.40~18/MbItemDigitalInput.qml
delete mode 120000 FileSets/v3.40~18/MbSpinBox.qml
delete mode 120000 FileSets/v3.40~18/MbStyle.qml
delete mode 120000 FileSets/v3.40~18/MbSubMenu.qml
delete mode 120000 FileSets/v3.40~18/Multi.qml
delete mode 120000 FileSets/v3.40~18/ObjectAcConnection.qml
delete mode 120000 FileSets/v3.40~18/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v3.40~18/OverviewBox.qml
delete mode 120000 FileSets/v3.40~18/OverviewConnection.qml
delete mode 120000 FileSets/v3.40~18/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v3.40~18/OverviewFlowComplex.qml
delete mode 120000 FileSets/v3.40~18/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v3.40~18/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v3.40~18/OverviewGridParallel.qml
delete mode 120000 FileSets/v3.40~18/OverviewHub.qml
delete mode 120000 FileSets/v3.40~18/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v3.40~18/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.40~18/OverviewSolarCharger.qml
delete mode 120000 FileSets/v3.40~18/OverviewSolarInverter.qml
delete mode 120000 FileSets/v3.40~18/OverviewTankDelegate.qml
delete mode 120000 FileSets/v3.40~18/OverviewTanks.qml
delete mode 120000 FileSets/v3.40~18/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v3.40~18/PageDigitalInput.qml
delete mode 120000 FileSets/v3.40~18/PageGenerator.qml
delete mode 120000 FileSets/v3.40~18/PageMain.qml
delete mode 120000 FileSets/v3.40~18/PageSettingsDisplay.qml
delete mode 120000 FileSets/v3.40~18/PageSettingsGenerator.qml
delete mode 120000 FileSets/v3.40~18/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v3.40~18/PageSettingsRelay.qml
delete mode 120000 FileSets/v3.40~18/PowerGauge.qml
delete mode 120000 FileSets/v3.40~18/Tile.qml
delete mode 120000 FileSets/v3.40~18/TileDigIn.qml
delete mode 120000 FileSets/v3.40~18/TileRelay.qml
delete mode 120000 FileSets/v3.40~18/TileText.qml
delete mode 120000 FileSets/v3.40~18/attributes.csv
delete mode 120000 FileSets/v3.40~18/dbus_digitalinputs.py
delete mode 120000 FileSets/v3.40~18/dbus_generator.py
delete mode 120000 FileSets/v3.40~18/dbus_systemcalc.py
delete mode 120000 FileSets/v3.40~18/main.qml
delete mode 120000 FileSets/v3.40~18/startstop.py
delete mode 120000 FileSets/v3.40~18/styles.css
delete mode 120000 FileSets/v3.40~2/Battery.qml
delete mode 100644 FileSets/v3.40~2/COMPLETE
delete mode 120000 FileSets/v3.40~2/DetailAcInput.qml
delete mode 120000 FileSets/v3.40~2/DetailInverter.qml
delete mode 120000 FileSets/v3.40~2/DetailLoadsCombined.qml
delete mode 120000 FileSets/v3.40~2/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v3.40~2/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v3.40~2/HubData.qml
delete mode 100644 FileSets/v3.40~2/LINKS_ONLY
delete mode 120000 FileSets/v3.40~2/MbEditBox.qml
delete mode 120000 FileSets/v3.40~2/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v3.40~2/MbItem.qml
delete mode 120000 FileSets/v3.40~2/MbItemDigitalInput.qml
delete mode 120000 FileSets/v3.40~2/MbSpinBox.qml
delete mode 120000 FileSets/v3.40~2/MbStyle.qml
delete mode 120000 FileSets/v3.40~2/MbSubMenu.qml
delete mode 120000 FileSets/v3.40~2/Multi.qml
delete mode 120000 FileSets/v3.40~2/ObjectAcConnection.qml
delete mode 120000 FileSets/v3.40~2/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v3.40~2/OverviewBox.qml
delete mode 120000 FileSets/v3.40~2/OverviewConnection.qml
delete mode 120000 FileSets/v3.40~2/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v3.40~2/OverviewFlowComplex.qml
delete mode 120000 FileSets/v3.40~2/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v3.40~2/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v3.40~2/OverviewGridParallel.qml
delete mode 120000 FileSets/v3.40~2/OverviewHub.qml
delete mode 120000 FileSets/v3.40~2/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v3.40~2/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.40~2/OverviewSolarCharger.qml
delete mode 120000 FileSets/v3.40~2/OverviewSolarInverter.qml
delete mode 120000 FileSets/v3.40~2/OverviewTankDelegate.qml
delete mode 120000 FileSets/v3.40~2/OverviewTanks.qml
delete mode 120000 FileSets/v3.40~2/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v3.40~2/PageDigitalInput.qml
delete mode 120000 FileSets/v3.40~2/PageGenerator.qml
delete mode 120000 FileSets/v3.40~2/PageMain.qml
delete mode 120000 FileSets/v3.40~2/PageSettingsDisplay.qml
delete mode 120000 FileSets/v3.40~2/PageSettingsGenerator.qml
delete mode 120000 FileSets/v3.40~2/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v3.40~2/PageSettingsRelay.qml
delete mode 120000 FileSets/v3.40~2/PowerGauge.qml
delete mode 120000 FileSets/v3.40~2/Tile.qml
delete mode 120000 FileSets/v3.40~2/TileDigIn.qml
delete mode 120000 FileSets/v3.40~2/TileRelay.qml
delete mode 120000 FileSets/v3.40~2/TileText.qml
delete mode 120000 FileSets/v3.40~2/attributes.csv
delete mode 120000 FileSets/v3.40~2/dbus_digitalinputs.py
delete mode 120000 FileSets/v3.40~2/dbus_generator.py
delete mode 120000 FileSets/v3.40~2/main.qml
delete mode 120000 FileSets/v3.40~2/startstop.py
delete mode 120000 FileSets/v3.40~2/styles.css
delete mode 120000 FileSets/v3.40~20/Battery.qml
delete mode 100644 FileSets/v3.40~20/COMPLETE
delete mode 120000 FileSets/v3.40~20/DetailAcInput.qml
delete mode 120000 FileSets/v3.40~20/DetailInverter.qml
delete mode 120000 FileSets/v3.40~20/DetailLoadsCombined.qml
delete mode 120000 FileSets/v3.40~20/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v3.40~20/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v3.40~20/HubData.qml
delete mode 100644 FileSets/v3.40~20/LINKS_ONLY
delete mode 120000 FileSets/v3.40~20/MbEditBox.qml
delete mode 120000 FileSets/v3.40~20/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v3.40~20/MbItem.qml
delete mode 120000 FileSets/v3.40~20/MbItemDigitalInput.qml
delete mode 120000 FileSets/v3.40~20/MbSpinBox.qml
delete mode 120000 FileSets/v3.40~20/MbStyle.qml
delete mode 120000 FileSets/v3.40~20/MbSubMenu.qml
delete mode 120000 FileSets/v3.40~20/Multi.qml
delete mode 120000 FileSets/v3.40~20/ObjectAcConnection.qml
delete mode 120000 FileSets/v3.40~20/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v3.40~20/OverviewBox.qml
delete mode 120000 FileSets/v3.40~20/OverviewConnection.qml
delete mode 120000 FileSets/v3.40~20/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v3.40~20/OverviewFlowComplex.qml
delete mode 120000 FileSets/v3.40~20/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v3.40~20/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v3.40~20/OverviewGridParallel.qml
delete mode 120000 FileSets/v3.40~20/OverviewHub.qml
delete mode 120000 FileSets/v3.40~20/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v3.40~20/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.40~20/OverviewSolarCharger.qml
delete mode 120000 FileSets/v3.40~20/OverviewSolarInverter.qml
delete mode 120000 FileSets/v3.40~20/OverviewTankDelegate.qml
delete mode 120000 FileSets/v3.40~20/OverviewTanks.qml
delete mode 120000 FileSets/v3.40~20/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v3.40~20/PageDigitalInput.qml
delete mode 120000 FileSets/v3.40~20/PageGenerator.qml
delete mode 120000 FileSets/v3.40~20/PageMain.qml
delete mode 120000 FileSets/v3.40~20/PageSettingsDisplay.qml
delete mode 120000 FileSets/v3.40~20/PageSettingsGenerator.qml
delete mode 120000 FileSets/v3.40~20/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v3.40~20/PageSettingsRelay.qml
delete mode 120000 FileSets/v3.40~20/PowerGauge.qml
delete mode 120000 FileSets/v3.40~20/Tile.qml
delete mode 120000 FileSets/v3.40~20/TileDigIn.qml
delete mode 120000 FileSets/v3.40~20/TileRelay.qml
delete mode 120000 FileSets/v3.40~20/TileText.qml
delete mode 120000 FileSets/v3.40~20/attributes.csv
delete mode 120000 FileSets/v3.40~20/dbus_digitalinputs.py
delete mode 120000 FileSets/v3.40~20/dbus_generator.py
delete mode 120000 FileSets/v3.40~20/main.qml
delete mode 120000 FileSets/v3.40~20/startstop.py
delete mode 120000 FileSets/v3.40~20/styles.css
delete mode 120000 FileSets/v3.40~21/Battery.qml
delete mode 100644 FileSets/v3.40~21/COMPLETE
delete mode 120000 FileSets/v3.40~21/DetailAcInput.qml
delete mode 120000 FileSets/v3.40~21/DetailInverter.qml
delete mode 120000 FileSets/v3.40~21/DetailLoadsCombined.qml
delete mode 120000 FileSets/v3.40~21/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v3.40~21/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v3.40~21/HubData.qml
delete mode 120000 FileSets/v3.40~21/MbEditBox.qml
delete mode 120000 FileSets/v3.40~21/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v3.40~21/MbItem.qml
delete mode 120000 FileSets/v3.40~21/MbItemDigitalInput.qml
delete mode 120000 FileSets/v3.40~21/MbSpinBox.qml
delete mode 120000 FileSets/v3.40~21/MbStyle.qml
delete mode 120000 FileSets/v3.40~21/MbSubMenu.qml
delete mode 120000 FileSets/v3.40~21/Multi.qml
delete mode 120000 FileSets/v3.40~21/ObjectAcConnection.qml
delete mode 120000 FileSets/v3.40~21/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v3.40~21/OverviewBox.qml
delete mode 120000 FileSets/v3.40~21/OverviewConnection.qml
delete mode 120000 FileSets/v3.40~21/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v3.40~21/OverviewFlowComplex.qml
delete mode 120000 FileSets/v3.40~21/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v3.40~21/OverviewGridParallel.qml
delete mode 120000 FileSets/v3.40~21/OverviewHub.qml
delete mode 120000 FileSets/v3.40~21/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v3.40~21/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.40~21/OverviewSolarCharger.qml
delete mode 120000 FileSets/v3.40~21/OverviewSolarInverter.qml
delete mode 120000 FileSets/v3.40~21/OverviewTankDelegate.qml
delete mode 120000 FileSets/v3.40~21/OverviewTanks.qml
delete mode 120000 FileSets/v3.40~21/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v3.40~21/PageDigitalInput.qml
delete mode 100644 FileSets/v3.40~21/PageGenerator.qml
delete mode 120000 FileSets/v3.40~21/PageMain.qml
delete mode 120000 FileSets/v3.40~21/PageSettingsDisplay.qml
delete mode 120000 FileSets/v3.40~21/PageSettingsGenerator.qml
delete mode 120000 FileSets/v3.40~21/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v3.40~21/PageSettingsRelay.qml
delete mode 120000 FileSets/v3.40~21/PowerGauge.qml
delete mode 120000 FileSets/v3.40~21/Tile.qml
delete mode 120000 FileSets/v3.40~21/TileDigIn.qml
delete mode 120000 FileSets/v3.40~21/TileRelay.qml
delete mode 120000 FileSets/v3.40~21/TileText.qml
delete mode 120000 FileSets/v3.40~21/attributes.csv
delete mode 120000 FileSets/v3.40~21/dbus_digitalinputs.py
delete mode 120000 FileSets/v3.40~21/dbus_generator.py
delete mode 120000 FileSets/v3.40~21/dbus_systemcalc.py
delete mode 120000 FileSets/v3.40~21/main.qml
delete mode 120000 FileSets/v3.40~21/startstop.py
delete mode 120000 FileSets/v3.40~21/styles.css
delete mode 120000 FileSets/v3.40~23/Battery.qml
delete mode 100644 FileSets/v3.40~23/COMPLETE
delete mode 120000 FileSets/v3.40~23/DetailAcInput.qml
delete mode 120000 FileSets/v3.40~23/DetailInverter.qml
delete mode 120000 FileSets/v3.40~23/DetailLoadsCombined.qml
delete mode 120000 FileSets/v3.40~23/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v3.40~23/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v3.40~23/HubData.qml
delete mode 100644 FileSets/v3.40~23/LINKS_ONLY
delete mode 120000 FileSets/v3.40~23/MbEditBox.qml
delete mode 120000 FileSets/v3.40~23/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v3.40~23/MbItem.qml
delete mode 120000 FileSets/v3.40~23/MbItemDigitalInput.qml
delete mode 120000 FileSets/v3.40~23/MbSpinBox.qml
delete mode 120000 FileSets/v3.40~23/MbStyle.qml
delete mode 120000 FileSets/v3.40~23/MbSubMenu.qml
delete mode 120000 FileSets/v3.40~23/Multi.qml
delete mode 120000 FileSets/v3.40~23/ObjectAcConnection.qml
delete mode 120000 FileSets/v3.40~23/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v3.40~23/OverviewBox.qml
delete mode 120000 FileSets/v3.40~23/OverviewConnection.qml
delete mode 120000 FileSets/v3.40~23/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v3.40~23/OverviewFlowComplex.qml
delete mode 120000 FileSets/v3.40~23/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v3.40~23/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v3.40~23/OverviewGridParallel.qml
delete mode 120000 FileSets/v3.40~23/OverviewHub.qml
delete mode 120000 FileSets/v3.40~23/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v3.40~23/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.40~23/OverviewSolarCharger.qml
delete mode 120000 FileSets/v3.40~23/OverviewSolarInverter.qml
delete mode 120000 FileSets/v3.40~23/OverviewTankDelegate.qml
delete mode 120000 FileSets/v3.40~23/OverviewTanks.qml
delete mode 120000 FileSets/v3.40~23/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v3.40~23/PageDigitalInput.qml
delete mode 120000 FileSets/v3.40~23/PageGenerator.qml
delete mode 120000 FileSets/v3.40~23/PageMain.qml
delete mode 120000 FileSets/v3.40~23/PageSettingsDisplay.qml
delete mode 120000 FileSets/v3.40~23/PageSettingsGenerator.qml
delete mode 120000 FileSets/v3.40~23/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v3.40~23/PageSettingsRelay.qml
delete mode 120000 FileSets/v3.40~23/PowerGauge.qml
delete mode 120000 FileSets/v3.40~23/Tile.qml
delete mode 120000 FileSets/v3.40~23/TileDigIn.qml
delete mode 120000 FileSets/v3.40~23/TileRelay.qml
delete mode 120000 FileSets/v3.40~23/TileText.qml
delete mode 120000 FileSets/v3.40~23/attributes.csv
delete mode 120000 FileSets/v3.40~23/dbus_digitalinputs.py
delete mode 120000 FileSets/v3.40~23/dbus_generator.py
delete mode 120000 FileSets/v3.40~23/dbus_systemcalc.py
delete mode 120000 FileSets/v3.40~23/main.qml
delete mode 120000 FileSets/v3.40~23/startstop.py
delete mode 120000 FileSets/v3.40~23/styles.css
delete mode 120000 FileSets/v3.40~26/Battery.qml
delete mode 100644 FileSets/v3.40~26/COMPLETE
delete mode 120000 FileSets/v3.40~26/DetailAcInput.qml
delete mode 120000 FileSets/v3.40~26/DetailInverter.qml
delete mode 120000 FileSets/v3.40~26/DetailLoadsCombined.qml
delete mode 120000 FileSets/v3.40~26/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v3.40~26/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v3.40~26/HubData.qml
delete mode 120000 FileSets/v3.40~26/MbEditBox.qml
delete mode 120000 FileSets/v3.40~26/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v3.40~26/MbItem.qml
delete mode 120000 FileSets/v3.40~26/MbItemDigitalInput.qml
delete mode 120000 FileSets/v3.40~26/MbSpinBox.qml
delete mode 120000 FileSets/v3.40~26/MbStyle.qml
delete mode 120000 FileSets/v3.40~26/MbSubMenu.qml
delete mode 120000 FileSets/v3.40~26/Multi.qml
delete mode 120000 FileSets/v3.40~26/ObjectAcConnection.qml
delete mode 120000 FileSets/v3.40~26/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v3.40~26/OverviewBox.qml
delete mode 120000 FileSets/v3.40~26/OverviewConnection.qml
delete mode 120000 FileSets/v3.40~26/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v3.40~26/OverviewFlowComplex.qml
delete mode 100644 FileSets/v3.40~26/OverviewGeneratorEnhanced.qml
delete mode 100644 FileSets/v3.40~26/OverviewGeneratorEnhanced.qml.orig
delete mode 120000 FileSets/v3.40~26/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v3.40~26/OverviewGridParallel.qml
delete mode 120000 FileSets/v3.40~26/OverviewHub.qml
delete mode 120000 FileSets/v3.40~26/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v3.40~26/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.40~26/OverviewSolarCharger.qml
delete mode 120000 FileSets/v3.40~26/OverviewSolarInverter.qml
delete mode 120000 FileSets/v3.40~26/OverviewTankDelegate.qml
delete mode 120000 FileSets/v3.40~26/OverviewTanks.qml
delete mode 120000 FileSets/v3.40~26/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v3.40~26/PageDigitalInput.qml
delete mode 100644 FileSets/v3.40~26/PageGenerator.qml.orig
delete mode 120000 FileSets/v3.40~26/PageMain.qml
delete mode 120000 FileSets/v3.40~26/PageSettingsDisplay.qml
delete mode 120000 FileSets/v3.40~26/PageSettingsGenerator.qml
delete mode 120000 FileSets/v3.40~26/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v3.40~26/PageSettingsRelay.qml
delete mode 120000 FileSets/v3.40~26/PowerGauge.qml
delete mode 120000 FileSets/v3.40~26/Tile.qml
delete mode 120000 FileSets/v3.40~26/TileDigIn.qml
delete mode 120000 FileSets/v3.40~26/TileRelay.qml
delete mode 120000 FileSets/v3.40~26/TileText.qml
delete mode 120000 FileSets/v3.40~26/dbus_digitalinputs.py
delete mode 120000 FileSets/v3.40~26/dbus_generator.py
delete mode 120000 FileSets/v3.40~26/dbus_systemcalc.py
delete mode 120000 FileSets/v3.40~26/main.qml
delete mode 120000 FileSets/v3.40~26/startstop.py
delete mode 120000 FileSets/v3.40~26/styles.css
delete mode 120000 FileSets/v3.40~27/Battery.qml
delete mode 100644 FileSets/v3.40~27/COMPLETE
delete mode 120000 FileSets/v3.40~27/DetailAcInput.qml
delete mode 120000 FileSets/v3.40~27/DetailInverter.qml
delete mode 120000 FileSets/v3.40~27/DetailLoadsCombined.qml
delete mode 120000 FileSets/v3.40~27/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v3.40~27/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v3.40~27/HubData.qml
delete mode 100644 FileSets/v3.40~27/LINKS_ONLY
delete mode 120000 FileSets/v3.40~27/MbEditBox.qml
delete mode 120000 FileSets/v3.40~27/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v3.40~27/MbItem.qml
delete mode 120000 FileSets/v3.40~27/MbItemDigitalInput.qml
delete mode 120000 FileSets/v3.40~27/MbSpinBox.qml
delete mode 120000 FileSets/v3.40~27/MbStyle.qml
delete mode 120000 FileSets/v3.40~27/MbSubMenu.qml
delete mode 120000 FileSets/v3.40~27/Multi.qml
delete mode 120000 FileSets/v3.40~27/ObjectAcConnection.qml
delete mode 120000 FileSets/v3.40~27/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v3.40~27/OverviewBox.qml
delete mode 120000 FileSets/v3.40~27/OverviewConnection.qml
delete mode 120000 FileSets/v3.40~27/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v3.40~27/OverviewFlowComplex.qml
delete mode 120000 FileSets/v3.40~27/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v3.40~27/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v3.40~27/OverviewGridParallel.qml
delete mode 120000 FileSets/v3.40~27/OverviewHub.qml
delete mode 120000 FileSets/v3.40~27/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v3.40~27/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.40~27/OverviewSolarCharger.qml
delete mode 120000 FileSets/v3.40~27/OverviewSolarInverter.qml
delete mode 120000 FileSets/v3.40~27/OverviewTankDelegate.qml
delete mode 120000 FileSets/v3.40~27/OverviewTanks.qml
delete mode 120000 FileSets/v3.40~27/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v3.40~27/PageDigitalInput.qml
delete mode 120000 FileSets/v3.40~27/PageGenerator.qml
delete mode 120000 FileSets/v3.40~27/PageMain.qml
delete mode 120000 FileSets/v3.40~27/PageSettingsDisplay.qml
delete mode 120000 FileSets/v3.40~27/PageSettingsGenerator.qml
delete mode 120000 FileSets/v3.40~27/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v3.40~27/PageSettingsRelay.qml
delete mode 120000 FileSets/v3.40~27/PowerGauge.qml
delete mode 120000 FileSets/v3.40~27/Tile.qml
delete mode 120000 FileSets/v3.40~27/TileDigIn.qml
delete mode 120000 FileSets/v3.40~27/TileRelay.qml
delete mode 120000 FileSets/v3.40~27/TileText.qml
delete mode 120000 FileSets/v3.40~27/attributes.csv
delete mode 120000 FileSets/v3.40~27/dbus_digitalinputs.py
delete mode 120000 FileSets/v3.40~27/dbus_generator.py
delete mode 120000 FileSets/v3.40~27/main.qml
delete mode 120000 FileSets/v3.40~27/startstop.py
delete mode 120000 FileSets/v3.40~27/styles.css
delete mode 120000 FileSets/v3.40~29/Battery.qml
delete mode 100644 FileSets/v3.40~29/COMPLETE
delete mode 120000 FileSets/v3.40~29/DetailAcInput.qml
delete mode 120000 FileSets/v3.40~29/DetailInverter.qml
delete mode 120000 FileSets/v3.40~29/DetailLoadsCombined.qml
delete mode 120000 FileSets/v3.40~29/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v3.40~29/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v3.40~29/HubData.qml
delete mode 100644 FileSets/v3.40~29/LINKS_ONLY
delete mode 120000 FileSets/v3.40~29/MbEditBox.qml
delete mode 120000 FileSets/v3.40~29/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v3.40~29/MbItem.qml
delete mode 120000 FileSets/v3.40~29/MbItemDigitalInput.qml
delete mode 120000 FileSets/v3.40~29/MbSpinBox.qml
delete mode 120000 FileSets/v3.40~29/MbStyle.qml
delete mode 120000 FileSets/v3.40~29/MbSubMenu.qml
delete mode 120000 FileSets/v3.40~29/Multi.qml
delete mode 120000 FileSets/v3.40~29/ObjectAcConnection.qml
delete mode 120000 FileSets/v3.40~29/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v3.40~29/OverviewBox.qml
delete mode 120000 FileSets/v3.40~29/OverviewConnection.qml
delete mode 120000 FileSets/v3.40~29/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v3.40~29/OverviewFlowComplex.qml
delete mode 120000 FileSets/v3.40~29/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v3.40~29/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v3.40~29/OverviewGridParallel.qml
delete mode 120000 FileSets/v3.40~29/OverviewHub.qml
delete mode 120000 FileSets/v3.40~29/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v3.40~29/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.40~29/OverviewSolarCharger.qml
delete mode 120000 FileSets/v3.40~29/OverviewSolarInverter.qml
delete mode 120000 FileSets/v3.40~29/OverviewTankDelegate.qml
delete mode 120000 FileSets/v3.40~29/OverviewTanks.qml
delete mode 120000 FileSets/v3.40~29/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v3.40~29/PageDigitalInput.qml
delete mode 120000 FileSets/v3.40~29/PageGenerator.qml
delete mode 120000 FileSets/v3.40~29/PageMain.qml
delete mode 120000 FileSets/v3.40~29/PageSettingsDisplay.qml
delete mode 120000 FileSets/v3.40~29/PageSettingsGenerator.qml
delete mode 120000 FileSets/v3.40~29/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v3.40~29/PageSettingsRelay.qml
delete mode 120000 FileSets/v3.40~29/PowerGauge.qml
delete mode 120000 FileSets/v3.40~29/Tile.qml
delete mode 120000 FileSets/v3.40~29/TileDigIn.qml
delete mode 120000 FileSets/v3.40~29/TileRelay.qml
delete mode 120000 FileSets/v3.40~29/TileText.qml
delete mode 120000 FileSets/v3.40~29/attributes.csv
delete mode 120000 FileSets/v3.40~29/dbus_digitalinputs.py
delete mode 120000 FileSets/v3.40~29/dbus_generator.py
delete mode 120000 FileSets/v3.40~29/main.qml
delete mode 120000 FileSets/v3.40~29/startstop.py
delete mode 120000 FileSets/v3.40~29/styles.css
delete mode 120000 FileSets/v3.40~30/Battery.qml
delete mode 100644 FileSets/v3.40~30/COMPLETE
delete mode 120000 FileSets/v3.40~30/DetailAcInput.qml
delete mode 120000 FileSets/v3.40~30/DetailInverter.qml
delete mode 120000 FileSets/v3.40~30/DetailLoadsCombined.qml
delete mode 120000 FileSets/v3.40~30/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v3.40~30/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v3.40~30/HubData.qml
delete mode 100644 FileSets/v3.40~30/LINKS_ONLY
delete mode 120000 FileSets/v3.40~30/MbEditBox.qml
delete mode 120000 FileSets/v3.40~30/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v3.40~30/MbItem.qml
delete mode 120000 FileSets/v3.40~30/MbItemDigitalInput.qml
delete mode 120000 FileSets/v3.40~30/MbSpinBox.qml
delete mode 120000 FileSets/v3.40~30/MbStyle.qml
delete mode 120000 FileSets/v3.40~30/MbSubMenu.qml
delete mode 120000 FileSets/v3.40~30/Multi.qml
delete mode 120000 FileSets/v3.40~30/ObjectAcConnection.qml
delete mode 120000 FileSets/v3.40~30/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v3.40~30/OverviewBox.qml
delete mode 120000 FileSets/v3.40~30/OverviewConnection.qml
delete mode 120000 FileSets/v3.40~30/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v3.40~30/OverviewFlowComplex.qml
delete mode 120000 FileSets/v3.40~30/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v3.40~30/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v3.40~30/OverviewGridParallel.qml
delete mode 120000 FileSets/v3.40~30/OverviewHub.qml
delete mode 120000 FileSets/v3.40~30/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v3.40~30/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.40~30/OverviewSolarCharger.qml
delete mode 120000 FileSets/v3.40~30/OverviewSolarInverter.qml
delete mode 120000 FileSets/v3.40~30/OverviewTankDelegate.qml
delete mode 120000 FileSets/v3.40~30/OverviewTanks.qml
delete mode 120000 FileSets/v3.40~30/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v3.40~30/PageDigitalInput.qml
delete mode 120000 FileSets/v3.40~30/PageGenerator.qml
delete mode 120000 FileSets/v3.40~30/PageMain.qml
delete mode 120000 FileSets/v3.40~30/PageSettingsDisplay.qml
delete mode 120000 FileSets/v3.40~30/PageSettingsGenerator.qml
delete mode 120000 FileSets/v3.40~30/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v3.40~30/PageSettingsRelay.qml
delete mode 120000 FileSets/v3.40~30/PowerGauge.qml
delete mode 120000 FileSets/v3.40~30/Tile.qml
delete mode 120000 FileSets/v3.40~30/TileDigIn.qml
delete mode 120000 FileSets/v3.40~30/TileRelay.qml
delete mode 120000 FileSets/v3.40~30/TileText.qml
delete mode 120000 FileSets/v3.40~30/attributes.csv
delete mode 120000 FileSets/v3.40~30/dbus_digitalinputs.py
delete mode 120000 FileSets/v3.40~30/dbus_generator.py
delete mode 120000 FileSets/v3.40~30/main.qml
delete mode 120000 FileSets/v3.40~30/startstop.py
delete mode 120000 FileSets/v3.40~30/styles.css
delete mode 120000 FileSets/v3.40~32/Battery.qml
delete mode 100644 FileSets/v3.40~32/COMPLETE
delete mode 120000 FileSets/v3.40~32/DetailAcInput.qml
delete mode 120000 FileSets/v3.40~32/DetailInverter.qml
delete mode 120000 FileSets/v3.40~32/DetailLoadsCombined.qml
delete mode 120000 FileSets/v3.40~32/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v3.40~32/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v3.40~32/HubData.qml
delete mode 100644 FileSets/v3.40~32/LINKS_ONLY
delete mode 120000 FileSets/v3.40~32/MbEditBox.qml
delete mode 120000 FileSets/v3.40~32/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v3.40~32/MbItem.qml
delete mode 120000 FileSets/v3.40~32/MbItemDigitalInput.qml
delete mode 120000 FileSets/v3.40~32/MbSpinBox.qml
delete mode 120000 FileSets/v3.40~32/MbStyle.qml
delete mode 120000 FileSets/v3.40~32/MbSubMenu.qml
delete mode 120000 FileSets/v3.40~32/Multi.qml
delete mode 120000 FileSets/v3.40~32/ObjectAcConnection.qml
delete mode 120000 FileSets/v3.40~32/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v3.40~32/OverviewBox.qml
delete mode 120000 FileSets/v3.40~32/OverviewConnection.qml
delete mode 120000 FileSets/v3.40~32/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v3.40~32/OverviewFlowComplex.qml
delete mode 120000 FileSets/v3.40~32/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v3.40~32/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v3.40~32/OverviewGridParallel.qml
delete mode 120000 FileSets/v3.40~32/OverviewHub.qml
delete mode 120000 FileSets/v3.40~32/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v3.40~32/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.40~32/OverviewSolarCharger.qml
delete mode 120000 FileSets/v3.40~32/OverviewSolarInverter.qml
delete mode 120000 FileSets/v3.40~32/OverviewTankDelegate.qml
delete mode 120000 FileSets/v3.40~32/OverviewTanks.qml
delete mode 120000 FileSets/v3.40~32/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v3.40~32/PageDigitalInput.qml
delete mode 120000 FileSets/v3.40~32/PageGenerator.qml
delete mode 120000 FileSets/v3.40~32/PageMain.qml
delete mode 120000 FileSets/v3.40~32/PageSettingsDisplay.qml
delete mode 120000 FileSets/v3.40~32/PageSettingsGenerator.qml
delete mode 120000 FileSets/v3.40~32/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v3.40~32/PageSettingsRelay.qml
delete mode 120000 FileSets/v3.40~32/PowerGauge.qml
delete mode 120000 FileSets/v3.40~32/Tile.qml
delete mode 120000 FileSets/v3.40~32/TileDigIn.qml
delete mode 120000 FileSets/v3.40~32/TileRelay.qml
delete mode 120000 FileSets/v3.40~32/TileText.qml
delete mode 120000 FileSets/v3.40~32/dbus_digitalinputs.py
delete mode 120000 FileSets/v3.40~32/dbus_generator.py
delete mode 120000 FileSets/v3.40~32/dbus_systemcalc.py
delete mode 120000 FileSets/v3.40~32/main.qml
delete mode 120000 FileSets/v3.40~32/startstop.py
delete mode 120000 FileSets/v3.40~32/styles.css
delete mode 120000 FileSets/v3.40~33/Battery.qml
delete mode 100644 FileSets/v3.40~33/COMPLETE
delete mode 120000 FileSets/v3.40~33/DetailAcInput.qml
delete mode 120000 FileSets/v3.40~33/DetailInverter.qml
delete mode 120000 FileSets/v3.40~33/DetailLoadsCombined.qml
delete mode 120000 FileSets/v3.40~33/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v3.40~33/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v3.40~33/HubData.qml
delete mode 100644 FileSets/v3.40~33/LINKS_ONLY
delete mode 120000 FileSets/v3.40~33/MbEditBox.qml
delete mode 120000 FileSets/v3.40~33/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v3.40~33/MbItem.qml
delete mode 120000 FileSets/v3.40~33/MbItemDigitalInput.qml
delete mode 120000 FileSets/v3.40~33/MbSpinBox.qml
delete mode 120000 FileSets/v3.40~33/MbStyle.qml
delete mode 120000 FileSets/v3.40~33/MbSubMenu.qml
delete mode 120000 FileSets/v3.40~33/Multi.qml
delete mode 120000 FileSets/v3.40~33/ObjectAcConnection.qml
delete mode 120000 FileSets/v3.40~33/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v3.40~33/OverviewBox.qml
delete mode 120000 FileSets/v3.40~33/OverviewConnection.qml
delete mode 120000 FileSets/v3.40~33/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v3.40~33/OverviewFlowComplex.qml
delete mode 120000 FileSets/v3.40~33/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v3.40~33/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v3.40~33/OverviewGridParallel.qml
delete mode 120000 FileSets/v3.40~33/OverviewHub.qml
delete mode 120000 FileSets/v3.40~33/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v3.40~33/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.40~33/OverviewSolarCharger.qml
delete mode 120000 FileSets/v3.40~33/OverviewSolarInverter.qml
delete mode 120000 FileSets/v3.40~33/OverviewTankDelegate.qml
delete mode 120000 FileSets/v3.40~33/OverviewTanks.qml
delete mode 120000 FileSets/v3.40~33/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v3.40~33/PageDigitalInput.qml
delete mode 120000 FileSets/v3.40~33/PageGenerator.qml
delete mode 120000 FileSets/v3.40~33/PageMain.qml
delete mode 120000 FileSets/v3.40~33/PageSettingsDisplay.qml
delete mode 120000 FileSets/v3.40~33/PageSettingsGenerator.qml
delete mode 120000 FileSets/v3.40~33/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v3.40~33/PageSettingsRelay.qml
delete mode 120000 FileSets/v3.40~33/PowerGauge.qml
delete mode 120000 FileSets/v3.40~33/Tile.qml
delete mode 120000 FileSets/v3.40~33/TileDigIn.qml
delete mode 120000 FileSets/v3.40~33/TileRelay.qml
delete mode 120000 FileSets/v3.40~33/TileText.qml
delete mode 100644 FileSets/v3.40~33/attributes.csv.orig
delete mode 120000 FileSets/v3.40~33/dbus_digitalinputs.py
delete mode 120000 FileSets/v3.40~33/dbus_generator.py
delete mode 120000 FileSets/v3.40~33/main.qml
delete mode 120000 FileSets/v3.40~33/startstop.py
delete mode 120000 FileSets/v3.40~33/styles.css
delete mode 120000 FileSets/v3.40~34/Battery.qml
delete mode 100644 FileSets/v3.40~34/COMPLETE
delete mode 120000 FileSets/v3.40~34/DetailAcInput.qml
delete mode 120000 FileSets/v3.40~34/DetailInverter.qml
delete mode 120000 FileSets/v3.40~34/DetailLoadsCombined.qml
delete mode 120000 FileSets/v3.40~34/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v3.40~34/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v3.40~34/HubData.qml
delete mode 100644 FileSets/v3.40~34/LINKS_ONLY
delete mode 120000 FileSets/v3.40~34/MbEditBox.qml
delete mode 120000 FileSets/v3.40~34/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v3.40~34/MbItem.qml
delete mode 120000 FileSets/v3.40~34/MbItemDigitalInput.qml
delete mode 120000 FileSets/v3.40~34/MbSpinBox.qml
delete mode 120000 FileSets/v3.40~34/MbStyle.qml
delete mode 120000 FileSets/v3.40~34/MbSubMenu.qml
delete mode 120000 FileSets/v3.40~34/Multi.qml
delete mode 120000 FileSets/v3.40~34/ObjectAcConnection.qml
delete mode 120000 FileSets/v3.40~34/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v3.40~34/OverviewBox.qml
delete mode 120000 FileSets/v3.40~34/OverviewConnection.qml
delete mode 120000 FileSets/v3.40~34/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v3.40~34/OverviewFlowComplex.qml
delete mode 120000 FileSets/v3.40~34/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v3.40~34/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v3.40~34/OverviewGridParallel.qml
delete mode 120000 FileSets/v3.40~34/OverviewHub.qml
delete mode 120000 FileSets/v3.40~34/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v3.40~34/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.40~34/OverviewSolarCharger.qml
delete mode 120000 FileSets/v3.40~34/OverviewSolarInverter.qml
delete mode 120000 FileSets/v3.40~34/OverviewTankDelegate.qml
delete mode 120000 FileSets/v3.40~34/OverviewTanks.qml
delete mode 120000 FileSets/v3.40~34/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v3.40~34/PageDigitalInput.qml
delete mode 120000 FileSets/v3.40~34/PageGenerator.qml
delete mode 120000 FileSets/v3.40~34/PageMain.qml
delete mode 120000 FileSets/v3.40~34/PageSettingsDisplay.qml
delete mode 120000 FileSets/v3.40~34/PageSettingsGenerator.qml
delete mode 120000 FileSets/v3.40~34/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v3.40~34/PageSettingsRelay.qml
delete mode 120000 FileSets/v3.40~34/PowerGauge.qml
delete mode 120000 FileSets/v3.40~34/Tile.qml
delete mode 120000 FileSets/v3.40~34/TileDigIn.qml
delete mode 120000 FileSets/v3.40~34/TileRelay.qml
delete mode 120000 FileSets/v3.40~34/TileText.qml
delete mode 120000 FileSets/v3.40~34/dbus_digitalinputs.py
delete mode 120000 FileSets/v3.40~34/dbus_generator.py
delete mode 120000 FileSets/v3.40~34/main.qml
delete mode 120000 FileSets/v3.40~34/startstop.py
delete mode 120000 FileSets/v3.40~34/styles.css
delete mode 100644 FileSets/v3.40~35/COMPLETE
delete mode 120000 FileSets/v3.40~35/DetailAcInput.qml
delete mode 120000 FileSets/v3.40~35/DetailInverter.qml
delete mode 120000 FileSets/v3.40~35/DetailLoadsCombined.qml
delete mode 120000 FileSets/v3.40~35/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v3.40~35/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v3.40~35/HubData.qml
delete mode 100644 FileSets/v3.40~35/LINKS_ONLY
delete mode 120000 FileSets/v3.40~35/ObjectAcConnection.qml
delete mode 120000 FileSets/v3.40~35/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v3.40~35/OverviewFlowComplex.qml
delete mode 120000 FileSets/v3.40~35/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v3.40~35/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v3.40~35/OverviewGridParallel.qml
delete mode 120000 FileSets/v3.40~35/OverviewHub.qml
delete mode 120000 FileSets/v3.40~35/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v3.40~35/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.40~35/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v3.40~35/PageGenerator.qml
delete mode 120000 FileSets/v3.40~35/PageSettingsGenerator.qml
delete mode 120000 FileSets/v3.40~35/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v3.40~35/PageSettingsRelay.qml
delete mode 120000 FileSets/v3.40~35/PowerGauge.qml
delete mode 120000 FileSets/v3.40~35/TileDigIn.qml
delete mode 120000 FileSets/v3.40~35/TileRelay.qml
delete mode 120000 FileSets/v3.40~35/dbus_digitalinputs.py
delete mode 120000 FileSets/v3.40~35/dbus_generator.py
delete mode 120000 FileSets/v3.40~35/startstop.py
delete mode 100644 FileSets/v3.40~37/COMPLETE
delete mode 120000 FileSets/v3.40~37/DetailAcInput.qml
delete mode 120000 FileSets/v3.40~37/DetailInverter.qml
delete mode 120000 FileSets/v3.40~37/DetailLoadsCombined.qml
delete mode 120000 FileSets/v3.40~37/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v3.40~37/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v3.40~37/HubData.qml
delete mode 120000 FileSets/v3.40~37/ObjectAcConnection.qml
delete mode 120000 FileSets/v3.40~37/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v3.40~37/OverviewFlowComplex.qml
delete mode 120000 FileSets/v3.40~37/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v3.40~37/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v3.40~37/OverviewGridParallel.qml
delete mode 120000 FileSets/v3.40~37/OverviewHub.qml
delete mode 120000 FileSets/v3.40~37/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v3.40~37/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.40~37/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v3.40~37/PageGenerator.qml
delete mode 120000 FileSets/v3.40~37/PageSettingsGenerator.qml
delete mode 120000 FileSets/v3.40~37/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v3.40~37/PageSettingsRelay.qml
delete mode 120000 FileSets/v3.40~37/PowerGauge.qml
delete mode 120000 FileSets/v3.40~37/TileDigIn.qml
delete mode 120000 FileSets/v3.40~37/TileRelay.qml
delete mode 120000 FileSets/v3.40~37/dbus_digitalinputs.py
delete mode 120000 FileSets/v3.40~37/dbus_generator.py
delete mode 100644 FileSets/v3.40~37/startstop.py
delete mode 100644 FileSets/v3.40~39/COMPLETE
delete mode 100644 FileSets/v3.40~39/DetailAcInput.qml
delete mode 100644 FileSets/v3.40~39/DetailInverter.qml
delete mode 100644 FileSets/v3.40~39/DetailLoadsCombined.qml
delete mode 100644 FileSets/v3.40~39/DetailLoadsOnInput.qml
delete mode 100644 FileSets/v3.40~39/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v3.40~39/OverviewGeneratorEnhanced.qml
delete mode 100644 FileSets/v3.40~39/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v3.40~39/PageGenerator.qml
delete mode 100644 FileSets/v3.40~39/TileDigIn.qml
delete mode 120000 FileSets/v3.40~5/Battery.qml
delete mode 100644 FileSets/v3.40~5/COMPLETE
delete mode 120000 FileSets/v3.40~5/DetailAcInput.qml
delete mode 120000 FileSets/v3.40~5/DetailInverter.qml
delete mode 120000 FileSets/v3.40~5/DetailLoadsCombined.qml
delete mode 120000 FileSets/v3.40~5/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v3.40~5/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v3.40~5/HubData.qml
delete mode 100644 FileSets/v3.40~5/LINKS_ONLY
delete mode 120000 FileSets/v3.40~5/MbEditBox.qml
delete mode 120000 FileSets/v3.40~5/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v3.40~5/MbItem.qml
delete mode 120000 FileSets/v3.40~5/MbItemDigitalInput.qml
delete mode 120000 FileSets/v3.40~5/MbSpinBox.qml
delete mode 120000 FileSets/v3.40~5/MbStyle.qml
delete mode 120000 FileSets/v3.40~5/MbSubMenu.qml
delete mode 120000 FileSets/v3.40~5/Multi.qml
delete mode 120000 FileSets/v3.40~5/ObjectAcConnection.qml
delete mode 120000 FileSets/v3.40~5/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v3.40~5/OverviewBox.qml
delete mode 120000 FileSets/v3.40~5/OverviewConnection.qml
delete mode 120000 FileSets/v3.40~5/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v3.40~5/OverviewFlowComplex.qml
delete mode 120000 FileSets/v3.40~5/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v3.40~5/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v3.40~5/OverviewGridParallel.qml
delete mode 120000 FileSets/v3.40~5/OverviewHub.qml
delete mode 120000 FileSets/v3.40~5/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v3.40~5/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.40~5/OverviewSolarCharger.qml
delete mode 120000 FileSets/v3.40~5/OverviewSolarInverter.qml
delete mode 120000 FileSets/v3.40~5/OverviewTankDelegate.qml
delete mode 120000 FileSets/v3.40~5/OverviewTanks.qml
delete mode 120000 FileSets/v3.40~5/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v3.40~5/PageDigitalInput.qml
delete mode 120000 FileSets/v3.40~5/PageGenerator.qml
delete mode 120000 FileSets/v3.40~5/PageMain.qml
delete mode 120000 FileSets/v3.40~5/PageSettingsDisplay.qml
delete mode 120000 FileSets/v3.40~5/PageSettingsGenerator.qml
delete mode 120000 FileSets/v3.40~5/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v3.40~5/PageSettingsRelay.qml
delete mode 120000 FileSets/v3.40~5/PowerGauge.qml
delete mode 120000 FileSets/v3.40~5/Tile.qml
delete mode 120000 FileSets/v3.40~5/TileDigIn.qml
delete mode 120000 FileSets/v3.40~5/TileRelay.qml
delete mode 120000 FileSets/v3.40~5/TileText.qml
delete mode 120000 FileSets/v3.40~5/attributes.csv
delete mode 120000 FileSets/v3.40~5/dbus_digitalinputs.py
delete mode 120000 FileSets/v3.40~5/dbus_generator.py
delete mode 120000 FileSets/v3.40~5/dbus_systemcalc.py
delete mode 120000 FileSets/v3.40~5/main.qml
delete mode 120000 FileSets/v3.40~5/startstop.py
delete mode 120000 FileSets/v3.40~5/styles.css
delete mode 120000 FileSets/v3.40~6/Battery.qml
delete mode 100644 FileSets/v3.40~6/COMPLETE
delete mode 120000 FileSets/v3.40~6/DetailAcInput.qml
delete mode 120000 FileSets/v3.40~6/DetailInverter.qml
delete mode 120000 FileSets/v3.40~6/DetailLoadsCombined.qml
delete mode 120000 FileSets/v3.40~6/DetailLoadsOnInput.qml
delete mode 120000 FileSets/v3.40~6/DetailLoadsOnOutput.qml
delete mode 120000 FileSets/v3.40~6/HubData.qml
delete mode 100644 FileSets/v3.40~6/LINKS_ONLY
delete mode 120000 FileSets/v3.40~6/MbEditBox.qml
delete mode 120000 FileSets/v3.40~6/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v3.40~6/MbItem.qml
delete mode 120000 FileSets/v3.40~6/MbItemDigitalInput.qml
delete mode 120000 FileSets/v3.40~6/MbSpinBox.qml
delete mode 120000 FileSets/v3.40~6/MbStyle.qml
delete mode 120000 FileSets/v3.40~6/MbSubMenu.qml
delete mode 120000 FileSets/v3.40~6/Multi.qml
delete mode 120000 FileSets/v3.40~6/ObjectAcConnection.qml
delete mode 120000 FileSets/v3.40~6/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v3.40~6/OverviewBox.qml
delete mode 120000 FileSets/v3.40~6/OverviewConnection.qml
delete mode 120000 FileSets/v3.40~6/OverviewConnectionEnd.qml
delete mode 120000 FileSets/v3.40~6/OverviewFlowComplex.qml
delete mode 120000 FileSets/v3.40~6/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v3.40~6/OverviewGeneratorRelayEnhanced.qml
delete mode 120000 FileSets/v3.40~6/OverviewGridParallel.qml
delete mode 120000 FileSets/v3.40~6/OverviewHub.qml
delete mode 120000 FileSets/v3.40~6/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v3.40~6/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.40~6/OverviewSolarCharger.qml
delete mode 120000 FileSets/v3.40~6/OverviewSolarInverter.qml
delete mode 120000 FileSets/v3.40~6/OverviewTankDelegate.qml
delete mode 120000 FileSets/v3.40~6/OverviewTanks.qml
delete mode 120000 FileSets/v3.40~6/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v3.40~6/PageDigitalInput.qml
delete mode 120000 FileSets/v3.40~6/PageGenerator.qml
delete mode 120000 FileSets/v3.40~6/PageMain.qml
delete mode 120000 FileSets/v3.40~6/PageSettingsDisplay.qml
delete mode 120000 FileSets/v3.40~6/PageSettingsGenerator.qml
delete mode 120000 FileSets/v3.40~6/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v3.40~6/PageSettingsRelay.qml
delete mode 120000 FileSets/v3.40~6/PowerGauge.qml
delete mode 120000 FileSets/v3.40~6/Tile.qml
delete mode 120000 FileSets/v3.40~6/TileDigIn.qml
delete mode 120000 FileSets/v3.40~6/TileRelay.qml
delete mode 120000 FileSets/v3.40~6/TileText.qml
delete mode 120000 FileSets/v3.40~6/dbus_digitalinputs.py
delete mode 120000 FileSets/v3.40~6/dbus_generator.py
delete mode 120000 FileSets/v3.40~6/main.qml
delete mode 120000 FileSets/v3.40~6/startstop.py
delete mode 120000 FileSets/v3.40~6/styles.css
delete mode 120000 FileSets/v3.40~8/Battery.qml
delete mode 100644 FileSets/v3.40~8/COMPLETE
delete mode 100644 FileSets/v3.40~8/DetailAcInput.qml
delete mode 100644 FileSets/v3.40~8/DetailInverter.qml
delete mode 100644 FileSets/v3.40~8/DetailLoadsCombined.qml
delete mode 100644 FileSets/v3.40~8/DetailLoadsOnInput.qml
delete mode 100644 FileSets/v3.40~8/DetailLoadsOnOutput.qml
delete mode 100644 FileSets/v3.40~8/HubData.qml
delete mode 120000 FileSets/v3.40~8/MbEditBox.qml
delete mode 120000 FileSets/v3.40~8/MbEditBoxDateTime.qml
delete mode 120000 FileSets/v3.40~8/MbItem.qml
delete mode 120000 FileSets/v3.40~8/MbItemDigitalInput.qml
delete mode 120000 FileSets/v3.40~8/MbSpinBox.qml
delete mode 120000 FileSets/v3.40~8/MbStyle.qml
delete mode 120000 FileSets/v3.40~8/MbSubMenu.qml
delete mode 120000 FileSets/v3.40~8/Multi.qml
delete mode 120000 FileSets/v3.40~8/ObjectAcConnection.qml
delete mode 120000 FileSets/v3.40~8/OverviewAcValuesEnhanced.qml
delete mode 120000 FileSets/v3.40~8/OverviewBox.qml
delete mode 120000 FileSets/v3.40~8/OverviewConnection.qml
delete mode 120000 FileSets/v3.40~8/OverviewConnectionEnd.qml
delete mode 100644 FileSets/v3.40~8/OverviewFlowComplex.qml
delete mode 120000 FileSets/v3.40~8/OverviewGeneratorEnhanced.qml
delete mode 120000 FileSets/v3.40~8/OverviewGeneratorRelayEnhanced.qml
delete mode 100644 FileSets/v3.40~8/OverviewGridParallel.qml
delete mode 100644 FileSets/v3.40~8/OverviewHub.qml
delete mode 100644 FileSets/v3.40~8/OverviewHubEnhanced.qml
delete mode 120000 FileSets/v3.40~8/OverviewMobileEnhanced.qml
delete mode 120000 FileSets/v3.40~8/OverviewSolarCharger.qml
delete mode 120000 FileSets/v3.40~8/OverviewSolarInverter.qml
delete mode 120000 FileSets/v3.40~8/OverviewTankDelegate.qml
delete mode 120000 FileSets/v3.40~8/OverviewTanks.qml
delete mode 120000 FileSets/v3.40~8/OverviewTanksTempsDigInputs.qml
delete mode 120000 FileSets/v3.40~8/PageDigitalInput.qml
delete mode 120000 FileSets/v3.40~8/PageGenerator.qml
delete mode 120000 FileSets/v3.40~8/PageMain.qml
delete mode 120000 FileSets/v3.40~8/PageSettingsGenerator.qml
delete mode 120000 FileSets/v3.40~8/PageSettingsGuiMods.qml
delete mode 120000 FileSets/v3.40~8/PageSettingsRelay.qml
delete mode 100644 FileSets/v3.40~8/PowerGauge.qml
delete mode 120000 FileSets/v3.40~8/Tile.qml
delete mode 120000 FileSets/v3.40~8/TileDigIn.qml
delete mode 120000 FileSets/v3.40~8/TileRelay.qml
delete mode 120000 FileSets/v3.40~8/TileText.qml
delete mode 120000 FileSets/v3.40~8/attributes.csv
delete mode 120000 FileSets/v3.40~8/dbus_digitalinputs.py
delete mode 120000 FileSets/v3.40~8/dbus_generator.py
delete mode 120000 FileSets/v3.40~8/dbus_systemcalc.py
delete mode 120000 FileSets/v3.40~8/main.qml
delete mode 120000 FileSets/v3.40~8/startstop.py
delete mode 120000 FileSets/v3.40~8/styles.css
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