From 17f63e22b0bee8f955427cc3c8f598855548c0b1 Mon Sep 17 00:00:00 2001 From: kwindrem <58538395+kwindrem@users.noreply.github.com> Date: Wed, 1 May 2024 08:30:29 -0700 Subject: [PATCH] add support for v3.40~11 --- FileSets/v2.71/MbEditBoxDateTime.qml | 2 +- FileSets/v2.71/MbSubMenu.qml | 2 +- FileSets/v2.71/Multi.qml | 2 +- FileSets/v2.71/OverviewBox.qml | 2 +- FileSets/v2.71/OverviewConnection.qml | 2 +- FileSets/v2.71/OverviewConnectionEnd.qml | 2 +- FileSets/v2.71/OverviewSolarCharger.qml | 2 +- FileSets/v2.71/OverviewTankDelegate.qml | 2 +- FileSets/v2.71/OverviewTanks.qml | 2 +- FileSets/v2.71/TileText.qml | 2 +- FileSets/v2.71/styles.css | 2 +- FileSets/v2.72/MbEditBoxDateTime.qml | 2 +- FileSets/v2.72/MbSubMenu.qml | 2 +- FileSets/v2.72/Multi.qml | 2 +- FileSets/v2.72/OverviewBox.qml | 2 +- FileSets/v2.72/OverviewConnection.qml | 2 +- FileSets/v2.72/OverviewConnectionEnd.qml | 2 +- FileSets/v2.72/OverviewSolarCharger.qml | 2 +- FileSets/v2.72/OverviewTankDelegate.qml | 2 +- FileSets/v2.72/OverviewTanks.qml | 2 +- FileSets/v2.72/TileText.qml | 2 +- FileSets/v2.72/styles.css | 2 +- FileSets/v2.73/MbEditBoxDateTime.qml | 2 +- FileSets/v2.73/MbSubMenu.qml | 2 +- FileSets/v2.73/Multi.qml | 2 +- FileSets/v2.73/OverviewBox.qml | 2 +- FileSets/v2.73/OverviewConnection.qml | 2 +- FileSets/v2.73/OverviewConnectionEnd.qml | 2 +- FileSets/v2.73/OverviewSolarCharger.qml | 2 +- FileSets/v2.73/OverviewTankDelegate.qml | 2 +- FileSets/v2.73/OverviewTanks.qml | 2 +- FileSets/v2.73/TileText.qml | 2 +- FileSets/v2.73/styles.css | 2 +- FileSets/v2.80/MbEditBoxDateTime.qml | 2 +- FileSets/v2.80/MbSubMenu.qml | 2 +- FileSets/v2.80/Multi.qml | 2 +- FileSets/v2.80/OverviewBox.qml | 2 +- FileSets/v2.80/OverviewConnection.qml | 2 +- FileSets/v2.80/OverviewConnectionEnd.qml | 2 +- FileSets/v2.80/OverviewSolarCharger.qml | 2 +- FileSets/v2.80/OverviewTankDelegate.qml | 2 +- FileSets/v2.80/OverviewTanks.qml | 2 +- FileSets/v2.80/TileText.qml | 2 +- FileSets/v2.80/styles.css | 2 +- FileSets/v2.81/MbEditBoxDateTime.qml | 2 +- FileSets/v2.81/MbSubMenu.qml | 2 +- FileSets/v2.81/Multi.qml | 2 +- FileSets/v2.81/OverviewBox.qml | 2 +- FileSets/v2.81/OverviewConnection.qml | 2 +- FileSets/v2.81/OverviewConnectionEnd.qml | 2 +- FileSets/v2.81/OverviewSolarCharger.qml | 2 +- FileSets/v2.81/OverviewTankDelegate.qml | 2 +- FileSets/v2.81/OverviewTanks.qml | 2 +- FileSets/v2.81/TileText.qml | 2 +- FileSets/v2.81/styles.css | 2 +- FileSets/v2.82/MbEditBoxDateTime.qml | 2 +- FileSets/v2.82/MbSubMenu.qml | 2 +- FileSets/v2.82/Multi.qml | 2 +- FileSets/v2.82/OverviewBox.qml | 2 +- FileSets/v2.82/OverviewConnection.qml | 2 +- FileSets/v2.82/OverviewConnectionEnd.qml | 2 +- FileSets/v2.82/OverviewSolarCharger.qml | 2 +- FileSets/v2.82/OverviewTankDelegate.qml | 2 +- FileSets/v2.82/OverviewTanks.qml | 2 +- FileSets/v2.82/TileText.qml | 2 +- FileSets/v2.82/styles.css | 2 +- FileSets/v2.83/MbEditBoxDateTime.qml | 2 +- FileSets/v2.83/MbSubMenu.qml | 2 +- FileSets/v2.83/Multi.qml | 2 +- FileSets/v2.83/OverviewBox.qml | 2 +- FileSets/v2.83/OverviewConnection.qml | 2 +- FileSets/v2.83/OverviewConnectionEnd.qml | 2 +- FileSets/v2.83/OverviewSolarCharger.qml | 2 +- FileSets/v2.83/OverviewTankDelegate.qml | 2 +- FileSets/v2.83/OverviewTanks.qml | 2 +- FileSets/v2.83/TileText.qml | 2 +- FileSets/v2.83/styles.css | 2 +- FileSets/v2.84/MbEditBoxDateTime.qml | 2 +- FileSets/v2.84/MbSubMenu.qml | 2 +- FileSets/v2.84/Multi.qml | 2 +- FileSets/v2.84/OverviewBox.qml | 2 +- FileSets/v2.84/OverviewConnection.qml | 2 +- FileSets/v2.84/OverviewConnectionEnd.qml | 2 +- FileSets/v2.84/OverviewSolarCharger.qml | 2 +- FileSets/v2.84/OverviewTankDelegate.qml | 2 +- FileSets/v2.84/OverviewTanks.qml | 2 +- FileSets/v2.84/TileText.qml | 2 +- FileSets/v2.84/styles.css | 2 +- FileSets/v2.85/MbEditBoxDateTime.qml | 2 +- FileSets/v2.85/MbSubMenu.qml | 2 +- FileSets/v2.85/Multi.qml | 2 +- FileSets/v2.85/OverviewBox.qml | 2 +- FileSets/v2.85/OverviewConnection.qml | 2 +- FileSets/v2.85/OverviewConnectionEnd.qml | 2 +- FileSets/v2.85/OverviewSolarCharger.qml | 2 +- FileSets/v2.85/OverviewTankDelegate.qml | 2 +- FileSets/v2.85/OverviewTanks.qml | 2 +- FileSets/v2.85/TileText.qml | 2 +- FileSets/v2.85/styles.css | 2 +- FileSets/v2.86/MbEditBoxDateTime.qml | 2 +- FileSets/v2.86/MbSubMenu.qml | 2 +- FileSets/v2.86/Multi.qml | 2 +- FileSets/v2.86/OverviewBox.qml | 2 +- FileSets/v2.86/OverviewConnection.qml | 2 +- FileSets/v2.86/OverviewConnectionEnd.qml | 2 +- FileSets/v2.86/OverviewSolarCharger.qml | 2 +- FileSets/v2.86/OverviewTankDelegate.qml | 2 +- FileSets/v2.86/OverviewTanks.qml | 2 +- FileSets/v2.86/TileText.qml | 2 +- FileSets/v2.86/styles.css | 2 +- FileSets/v2.87/MbEditBoxDateTime.qml | 2 +- FileSets/v2.87/MbSubMenu.qml | 2 +- FileSets/v2.87/Multi.qml | 2 +- FileSets/v2.87/OverviewBox.qml | 2 +- FileSets/v2.87/OverviewConnection.qml | 2 +- FileSets/v2.87/OverviewConnectionEnd.qml | 2 +- FileSets/v2.87/OverviewSolarCharger.qml | 2 +- FileSets/v2.87/OverviewTankDelegate.qml | 2 +- FileSets/v2.87/OverviewTanks.qml | 2 +- FileSets/v2.87/TileText.qml | 2 +- FileSets/v2.87/styles.css | 2 +- FileSets/v2.89/MbEditBoxDateTime.qml | 2 +- FileSets/v2.89/MbSubMenu.qml | 2 +- FileSets/v2.89/Multi.qml | 2 +- FileSets/v2.89/OverviewBox.qml | 2 +- FileSets/v2.89/OverviewConnection.qml | 2 +- FileSets/v2.89/OverviewConnectionEnd.qml | 2 +- FileSets/v2.89/OverviewSolarCharger.qml | 2 +- FileSets/v2.89/OverviewTankDelegate.qml | 2 +- FileSets/v2.89/OverviewTanks.qml | 2 +- FileSets/v2.89/TileText.qml | 2 +- FileSets/v2.89/styles.css | 2 +- FileSets/v2.90/MbEditBoxDateTime.qml | 2 +- FileSets/v2.90/MbSpinBox.qml | 2 +- FileSets/v2.90/MbSubMenu.qml | 2 +- FileSets/v2.90/Multi.qml | 2 +- FileSets/v2.90/OverviewBox.qml | 2 +- FileSets/v2.90/OverviewConnection.qml | 2 +- FileSets/v2.90/OverviewConnectionEnd.qml | 2 +- FileSets/v2.90/OverviewSolarCharger.qml | 2 +- FileSets/v2.90/OverviewTankDelegate.qml | 2 +- FileSets/v2.90/OverviewTanks.qml | 2 +- FileSets/v2.90/TileText.qml | 2 +- FileSets/v2.90/styles.css | 2 +- FileSets/v2.91/MbEditBoxDateTime.qml | 2 +- FileSets/v2.91/MbSpinBox.qml | 2 +- FileSets/v2.91/MbSubMenu.qml | 2 +- FileSets/v2.91/Multi.qml | 2 +- FileSets/v2.91/OverviewBox.qml | 2 +- FileSets/v2.91/OverviewConnection.qml | 2 +- FileSets/v2.91/OverviewConnectionEnd.qml | 2 +- FileSets/v2.91/OverviewSolarCharger.qml | 2 +- FileSets/v2.91/OverviewTankDelegate.qml | 2 +- FileSets/v2.91/OverviewTanks.qml | 2 +- FileSets/v2.91/TileText.qml | 2 +- FileSets/v2.91/styles.css | 2 +- FileSets/v2.92/MbEditBoxDateTime.qml | 2 +- FileSets/v2.92/MbSpinBox.qml | 2 +- FileSets/v2.92/MbSubMenu.qml | 2 +- FileSets/v2.92/Multi.qml | 2 +- FileSets/v2.92/OverviewBox.qml | 2 +- FileSets/v2.92/OverviewConnection.qml | 2 +- FileSets/v2.92/OverviewConnectionEnd.qml | 2 +- FileSets/v2.92/OverviewSolarCharger.qml | 2 +- FileSets/v2.92/OverviewTankDelegate.qml | 2 +- FileSets/v2.92/OverviewTanks.qml | 2 +- FileSets/v2.92/TileText.qml | 2 +- FileSets/v2.92/styles.css | 2 +- FileSets/v2.93/MbEditBoxDateTime.qml | 2 +- FileSets/v2.93/MbSpinBox.qml | 2 +- FileSets/v2.93/MbSubMenu.qml | 2 +- FileSets/v2.93/Multi.qml | 2 +- FileSets/v2.93/OverviewBox.qml | 2 +- FileSets/v2.93/OverviewConnection.qml | 2 +- FileSets/v2.93/OverviewConnectionEnd.qml | 2 +- FileSets/v2.93/OverviewSolarCharger.qml | 2 +- FileSets/v2.93/OverviewTankDelegate.qml | 2 +- FileSets/v2.93/OverviewTanks.qml | 2 +- FileSets/v2.93/TileText.qml | 2 +- FileSets/v2.93/styles.css | 2 +- FileSets/v2.94/MbEditBoxDateTime.qml | 2 +- FileSets/v2.94/MbSpinBox.qml | 2 +- FileSets/v2.94/MbSubMenu.qml | 2 +- FileSets/v2.94/Multi.qml | 2 +- FileSets/v2.94/OverviewBox.qml | 2 +- FileSets/v2.94/OverviewConnection.qml | 2 +- FileSets/v2.94/OverviewConnectionEnd.qml | 2 +- FileSets/v2.94/OverviewSolarCharger.qml | 2 +- FileSets/v2.94/OverviewTankDelegate.qml | 2 +- FileSets/v2.94/OverviewTanks.qml | 2 +- FileSets/v2.94/TileText.qml | 2 +- FileSets/v2.94/styles.css | 2 +- FileSets/v3.00/MbEditBoxDateTime.qml | 2 +- FileSets/v3.00/MbItem.qml | 2 +- FileSets/v3.00/MbItemDigitalInput.qml | 2 +- FileSets/v3.00/MbSpinBox.qml | 2 +- FileSets/v3.00/MbStyle.qml | 2 +- FileSets/v3.00/MbSubMenu.qml | 2 +- FileSets/v3.00/Multi.qml | 2 +- FileSets/v3.00/OverviewBox.qml | 2 +- FileSets/v3.00/OverviewConnection.qml | 2 +- FileSets/v3.00/OverviewConnectionEnd.qml | 2 +- .../v3.00/OverviewGeneratorRelayEnhanced.qml | 2 +- FileSets/v3.00/OverviewMobileEnhanced.qml | 2 +- FileSets/v3.00/OverviewSolarCharger.qml | 2 +- FileSets/v3.00/OverviewSolarInverter.qml | 2 +- FileSets/v3.00/OverviewTankDelegate.qml | 2 +- FileSets/v3.00/OverviewTanks.qml | 2 +- .../v3.00/OverviewTanksTempsDigInputs.qml | 2 +- FileSets/v3.00/Tile.qml | 2 +- FileSets/v3.00/TileRelay.qml | 2 +- FileSets/v3.00/TileText.qml | 2 +- FileSets/v3.00/styles.css | 2 +- FileSets/v3.00~32/MbEditBoxDateTime.qml | 2 +- FileSets/v3.00~32/MbItem.qml | 2 +- FileSets/v3.00~32/MbItemDigitalInput.qml | 2 +- FileSets/v3.00~32/MbSpinBox.qml | 2 +- FileSets/v3.00~32/MbStyle.qml | 2 +- FileSets/v3.00~32/MbSubMenu.qml | 2 +- FileSets/v3.00~32/Multi.qml | 2 +- FileSets/v3.00~32/OverviewBox.qml | 2 +- FileSets/v3.00~32/OverviewConnection.qml | 2 +- FileSets/v3.00~32/OverviewConnectionEnd.qml | 2 +- FileSets/v3.00~32/OverviewMobileEnhanced.qml | 2 +- FileSets/v3.00~32/OverviewSolarCharger.qml | 2 +- FileSets/v3.00~32/OverviewTankDelegate.qml | 2 +- FileSets/v3.00~32/OverviewTanks.qml | 2 +- .../v3.00~32/OverviewTanksTempsDigInputs.qml | 2 +- FileSets/v3.00~32/Tile.qml | 2 +- FileSets/v3.00~32/TileRelay.qml | 2 +- FileSets/v3.00~32/TileText.qml | 2 +- FileSets/v3.00~32/styles.css | 2 +- FileSets/v3.01/MbEditBoxDateTime.qml | 2 +- FileSets/v3.01/MbItem.qml | 2 +- FileSets/v3.01/MbItemDigitalInput.qml | 2 +- FileSets/v3.01/MbSpinBox.qml | 2 +- FileSets/v3.01/MbStyle.qml | 2 +- FileSets/v3.01/MbSubMenu.qml | 2 +- FileSets/v3.01/Multi.qml | 2 +- FileSets/v3.01/OverviewBox.qml | 2 +- FileSets/v3.01/OverviewConnection.qml | 2 +- FileSets/v3.01/OverviewConnectionEnd.qml | 2 +- .../v3.01/OverviewGeneratorRelayEnhanced.qml | 2 +- FileSets/v3.01/OverviewMobileEnhanced.qml | 2 +- FileSets/v3.01/OverviewSolarCharger.qml | 2 +- FileSets/v3.01/OverviewSolarInverter.qml | 2 +- FileSets/v3.01/OverviewTankDelegate.qml | 2 +- FileSets/v3.01/OverviewTanks.qml | 2 +- .../v3.01/OverviewTanksTempsDigInputs.qml | 2 +- FileSets/v3.01/Tile.qml | 2 +- FileSets/v3.01/TileRelay.qml | 2 +- FileSets/v3.01/TileText.qml | 2 +- FileSets/v3.01/styles.css | 2 +- FileSets/v3.10/Battery.qml | 2 +- FileSets/v3.10/MbEditBoxDateTime.qml | 2 +- FileSets/v3.10/MbItem.qml | 2 +- FileSets/v3.10/MbItemDigitalInput.qml | 2 +- FileSets/v3.10/MbSpinBox.qml | 2 +- FileSets/v3.10/MbStyle.qml | 2 +- FileSets/v3.10/MbSubMenu.qml | 2 +- FileSets/v3.10/Multi.qml | 2 +- FileSets/v3.10/ObjectAcConnection.qml | 2 +- FileSets/v3.10/OverviewAcValuesEnhanced.qml | 2 +- FileSets/v3.10/OverviewBox.qml | 2 +- FileSets/v3.10/OverviewConnection.qml | 2 +- FileSets/v3.10/OverviewConnectionEnd.qml | 2 +- .../v3.10/OverviewGeneratorRelayEnhanced.qml | 2 +- FileSets/v3.10/OverviewMobileEnhanced.qml | 2 +- FileSets/v3.10/OverviewSolarCharger.qml | 2 +- FileSets/v3.10/OverviewSolarInverter.qml | 2 +- FileSets/v3.10/OverviewTankDelegate.qml | 2 +- FileSets/v3.10/OverviewTanks.qml | 2 +- .../v3.10/OverviewTanksTempsDigInputs.qml | 2 +- FileSets/v3.10/PageDigitalInput.qml | 2 +- FileSets/v3.10/Tile.qml | 2 +- FileSets/v3.10/TileDigIn.qml | 2 +- FileSets/v3.10/TileRelay.qml | 2 +- FileSets/v3.10/TileText.qml | 2 +- FileSets/v3.10/dbus_digitalinputs.py | 2 +- FileSets/v3.10/styles.css | 2 +- FileSets/v3.11/Battery.qml | 2 +- FileSets/v3.11/MbEditBoxDateTime.qml | 2 +- FileSets/v3.11/MbItem.qml | 2 +- FileSets/v3.11/MbItemDigitalInput.qml | 2 +- FileSets/v3.11/MbSpinBox.qml | 2 +- FileSets/v3.11/MbStyle.qml | 2 +- FileSets/v3.11/MbSubMenu.qml | 2 +- FileSets/v3.11/Multi.qml | 2 +- FileSets/v3.11/ObjectAcConnection.qml | 2 +- FileSets/v3.11/OverviewAcValuesEnhanced.qml | 2 +- FileSets/v3.11/OverviewBox.qml | 2 +- FileSets/v3.11/OverviewConnection.qml | 2 +- FileSets/v3.11/OverviewConnectionEnd.qml | 2 +- FileSets/v3.11/OverviewGeneratorEnhanced.qml | 2 +- .../v3.11/OverviewGeneratorRelayEnhanced.qml | 2 +- FileSets/v3.11/OverviewMobileEnhanced.qml | 2 +- FileSets/v3.11/OverviewSolarCharger.qml | 2 +- FileSets/v3.11/OverviewSolarInverter.qml | 2 +- FileSets/v3.11/OverviewTankDelegate.qml | 2 +- FileSets/v3.11/OverviewTanks.qml | 2 +- .../v3.11/OverviewTanksTempsDigInputs.qml | 2 +- FileSets/v3.11/PageDigitalInput.qml | 2 +- FileSets/v3.11/PageGenerator.qml | 2 +- FileSets/v3.11/Tile.qml | 2 +- FileSets/v3.11/TileDigIn.qml | 2 +- FileSets/v3.11/TileRelay.qml | 2 +- FileSets/v3.11/TileText.qml | 2 +- FileSets/v3.11/dbus_digitalinputs.py | 2 +- FileSets/v3.11/styles.css | 2 +- FileSets/v3.12/Battery.qml | 2 +- FileSets/v3.12/MbEditBoxDateTime.qml | 2 +- FileSets/v3.12/MbItem.qml | 2 +- FileSets/v3.12/MbItemDigitalInput.qml | 2 +- FileSets/v3.12/MbSpinBox.qml | 2 +- FileSets/v3.12/MbStyle.qml | 2 +- FileSets/v3.12/MbSubMenu.qml | 2 +- FileSets/v3.12/Multi.qml | 2 +- FileSets/v3.12/ObjectAcConnection.qml | 2 +- FileSets/v3.12/OverviewAcValuesEnhanced.qml | 2 +- FileSets/v3.12/OverviewBox.qml | 2 +- FileSets/v3.12/OverviewConnection.qml | 2 +- FileSets/v3.12/OverviewConnectionEnd.qml | 2 +- FileSets/v3.12/OverviewGeneratorEnhanced.qml | 2 +- .../v3.12/OverviewGeneratorRelayEnhanced.qml | 2 +- FileSets/v3.12/OverviewMobileEnhanced.qml | 2 +- FileSets/v3.12/OverviewSolarCharger.qml | 2 +- FileSets/v3.12/OverviewSolarInverter.qml | 2 +- FileSets/v3.12/OverviewTankDelegate.qml | 2 +- FileSets/v3.12/OverviewTanks.qml | 2 +- .../v3.12/OverviewTanksTempsDigInputs.qml | 2 +- FileSets/v3.12/PageDigitalInput.qml | 2 +- FileSets/v3.12/PageGenerator.qml | 2 +- FileSets/v3.12/Tile.qml | 2 +- FileSets/v3.12/TileDigIn.qml | 2 +- FileSets/v3.12/TileRelay.qml | 2 +- FileSets/v3.12/TileText.qml | 2 +- FileSets/v3.12/dbus_digitalinputs.py | 2 +- FileSets/v3.12/styles.css | 2 +- FileSets/v3.13/Battery.qml | 2 +- FileSets/v3.13/MbEditBoxDateTime.qml | 2 +- FileSets/v3.13/MbItem.qml | 2 +- FileSets/v3.13/MbItemDigitalInput.qml | 2 +- FileSets/v3.13/MbSpinBox.qml | 2 +- FileSets/v3.13/MbStyle.qml | 2 +- FileSets/v3.13/MbSubMenu.qml | 2 +- FileSets/v3.13/Multi.qml | 2 +- FileSets/v3.13/ObjectAcConnection.qml | 2 +- FileSets/v3.13/OverviewAcValuesEnhanced.qml | 2 +- FileSets/v3.13/OverviewBox.qml | 2 +- FileSets/v3.13/OverviewConnection.qml | 2 +- FileSets/v3.13/OverviewConnectionEnd.qml | 2 +- FileSets/v3.13/OverviewGeneratorEnhanced.qml | 2 +- .../v3.13/OverviewGeneratorRelayEnhanced.qml | 2 +- FileSets/v3.13/OverviewMobileEnhanced.qml | 2 +- FileSets/v3.13/OverviewSolarCharger.qml | 2 +- FileSets/v3.13/OverviewSolarInverter.qml | 2 +- FileSets/v3.13/OverviewTankDelegate.qml | 2 +- FileSets/v3.13/OverviewTanks.qml | 2 +- .../v3.13/OverviewTanksTempsDigInputs.qml | 2 +- FileSets/v3.13/PageDigitalInput.qml | 2 +- FileSets/v3.13/PageGenerator.qml | 2 +- FileSets/v3.13/Tile.qml | 2 +- FileSets/v3.13/TileDigIn.qml | 2 +- FileSets/v3.13/TileRelay.qml | 2 +- FileSets/v3.13/TileText.qml | 2 +- FileSets/v3.13/dbus_digitalinputs.py | 2 +- FileSets/v3.13/styles.css | 2 +- FileSets/v3.14/Battery.qml | 2 +- FileSets/v3.14/MbEditBoxDateTime.qml | 2 +- FileSets/v3.14/MbItem.qml | 2 +- FileSets/v3.14/MbItemDigitalInput.qml | 2 +- FileSets/v3.14/MbSpinBox.qml | 2 +- FileSets/v3.14/MbStyle.qml | 2 +- FileSets/v3.14/MbSubMenu.qml | 2 +- FileSets/v3.14/Multi.qml | 2 +- FileSets/v3.14/ObjectAcConnection.qml | 2 +- FileSets/v3.14/OverviewAcValuesEnhanced.qml | 2 +- FileSets/v3.14/OverviewBox.qml | 2 +- FileSets/v3.14/OverviewConnection.qml | 2 +- FileSets/v3.14/OverviewConnectionEnd.qml | 2 +- FileSets/v3.14/OverviewGeneratorEnhanced.qml | 2 +- .../v3.14/OverviewGeneratorRelayEnhanced.qml | 2 +- FileSets/v3.14/OverviewMobileEnhanced.qml | 2 +- FileSets/v3.14/OverviewSolarCharger.qml | 2 +- FileSets/v3.14/OverviewSolarInverter.qml | 2 +- FileSets/v3.14/OverviewTankDelegate.qml | 2 +- FileSets/v3.14/OverviewTanks.qml | 2 +- .../v3.14/OverviewTanksTempsDigInputs.qml | 2 +- FileSets/v3.14/PageDigitalInput.qml | 2 +- FileSets/v3.14/PageGenerator.qml | 2 +- FileSets/v3.14/Tile.qml | 2 +- FileSets/v3.14/TileDigIn.qml | 2 +- FileSets/v3.14/TileRelay.qml | 2 +- FileSets/v3.14/TileText.qml | 2 +- FileSets/v3.14/dbus_digitalinputs.py | 2 +- FileSets/v3.14/styles.css | 2 +- FileSets/v3.20/Battery.qml | 2 +- FileSets/v3.20/MbEditBoxDateTime.qml | 2 +- FileSets/v3.20/MbItem.qml | 2 +- FileSets/v3.20/MbItemDigitalInput.qml | 2 +- FileSets/v3.20/MbSpinBox.qml | 2 +- FileSets/v3.20/MbStyle.qml | 2 +- FileSets/v3.20/MbSubMenu.qml | 2 +- FileSets/v3.20/Multi.qml | 2 +- FileSets/v3.20/ObjectAcConnection.qml | 2 +- FileSets/v3.20/OverviewAcValuesEnhanced.qml | 2 +- FileSets/v3.20/OverviewBox.qml | 2 +- FileSets/v3.20/OverviewConnection.qml | 2 +- FileSets/v3.20/OverviewConnectionEnd.qml | 2 +- FileSets/v3.20/OverviewGeneratorEnhanced.qml | 2 +- .../v3.20/OverviewGeneratorRelayEnhanced.qml | 2 +- FileSets/v3.20/OverviewMobileEnhanced.qml | 2 +- FileSets/v3.20/OverviewSolarCharger.qml | 2 +- FileSets/v3.20/OverviewSolarInverter.qml | 2 +- FileSets/v3.20/OverviewTankDelegate.qml | 2 +- FileSets/v3.20/OverviewTanks.qml | 2 +- .../v3.20/OverviewTanksTempsDigInputs.qml | 2 +- FileSets/v3.20/PageDigitalInput.qml | 2 +- FileSets/v3.20/PageGenerator.qml | 2 +- FileSets/v3.20/PageSettingsGenerator.qml | 2 +- FileSets/v3.20/Tile.qml | 2 +- FileSets/v3.20/TileDigIn.qml | 2 +- FileSets/v3.20/TileRelay.qml | 2 +- FileSets/v3.20/TileText.qml | 2 +- FileSets/v3.20/dbus_digitalinputs.py | 2 +- FileSets/v3.20/dbus_generator.py | 2 +- FileSets/v3.20/styles.css | 2 +- FileSets/v3.21/Battery.qml | 2 +- FileSets/v3.21/MbEditBoxDateTime.qml | 2 +- FileSets/v3.21/MbItem.qml | 2 +- FileSets/v3.21/MbItemDigitalInput.qml | 2 +- FileSets/v3.21/MbSpinBox.qml | 2 +- FileSets/v3.21/MbStyle.qml | 2 +- FileSets/v3.21/MbSubMenu.qml | 2 +- FileSets/v3.21/Multi.qml | 2 +- FileSets/v3.21/ObjectAcConnection.qml | 2 +- FileSets/v3.21/OverviewAcValuesEnhanced.qml | 2 +- FileSets/v3.21/OverviewBox.qml | 2 +- FileSets/v3.21/OverviewConnection.qml | 2 +- FileSets/v3.21/OverviewConnectionEnd.qml | 2 +- FileSets/v3.21/OverviewGeneratorEnhanced.qml | 2 +- .../v3.21/OverviewGeneratorRelayEnhanced.qml | 2 +- FileSets/v3.21/OverviewMobileEnhanced.qml | 2 +- FileSets/v3.21/OverviewSolarCharger.qml | 2 +- FileSets/v3.21/OverviewSolarInverter.qml | 2 +- FileSets/v3.21/OverviewTankDelegate.qml | 2 +- FileSets/v3.21/OverviewTanks.qml | 2 +- .../v3.21/OverviewTanksTempsDigInputs.qml | 2 +- FileSets/v3.21/PageDigitalInput.qml | 2 +- FileSets/v3.21/PageGenerator.qml | 2 +- FileSets/v3.21/PageSettingsGenerator.qml | 2 +- FileSets/v3.21/Tile.qml | 2 +- FileSets/v3.21/TileDigIn.qml | 2 +- FileSets/v3.21/TileRelay.qml | 2 +- FileSets/v3.21/TileText.qml | 2 +- FileSets/v3.21/dbus_digitalinputs.py | 2 +- FileSets/v3.21/dbus_generator.py | 2 +- FileSets/v3.21/styles.css | 2 +- FileSets/v3.22/Battery.qml | 2 +- FileSets/v3.22/MbEditBoxDateTime.qml | 2 +- FileSets/v3.22/MbItem.qml | 2 +- FileSets/v3.22/MbItemDigitalInput.qml | 2 +- FileSets/v3.22/MbSpinBox.qml | 2 +- FileSets/v3.22/MbStyle.qml | 2 +- FileSets/v3.22/MbSubMenu.qml | 2 +- FileSets/v3.22/Multi.qml | 2 +- FileSets/v3.22/ObjectAcConnection.qml | 2 +- FileSets/v3.22/OverviewAcValuesEnhanced.qml | 2 +- FileSets/v3.22/OverviewBox.qml | 2 +- FileSets/v3.22/OverviewConnection.qml | 2 +- FileSets/v3.22/OverviewConnectionEnd.qml | 2 +- FileSets/v3.22/OverviewGeneratorEnhanced.qml | 2 +- .../v3.22/OverviewGeneratorRelayEnhanced.qml | 2 +- FileSets/v3.22/OverviewMobileEnhanced.qml | 2 +- FileSets/v3.22/OverviewSolarCharger.qml | 2 +- FileSets/v3.22/OverviewSolarInverter.qml | 2 +- FileSets/v3.22/OverviewTankDelegate.qml | 2 +- FileSets/v3.22/OverviewTanks.qml | 2 +- .../v3.22/OverviewTanksTempsDigInputs.qml | 2 +- FileSets/v3.22/PageDigitalInput.qml | 2 +- FileSets/v3.22/PageGenerator.qml | 2 +- FileSets/v3.22/PageSettingsGenerator.qml | 2 +- FileSets/v3.22/Tile.qml | 2 +- FileSets/v3.22/TileDigIn.qml | 2 +- FileSets/v3.22/TileRelay.qml | 2 +- FileSets/v3.22/TileText.qml | 2 +- FileSets/v3.22/dbus_digitalinputs.py | 2 +- FileSets/v3.22/dbus_generator.py | 2 +- FileSets/v3.22/styles.css | 2 +- FileSets/v3.30/Battery.qml | 2 +- FileSets/v3.30/MbEditBoxDateTime.qml | 2 +- FileSets/v3.30/MbItem.qml | 2 +- FileSets/v3.30/MbItemDigitalInput.qml | 2 +- FileSets/v3.30/MbSpinBox.qml | 2 +- FileSets/v3.30/MbStyle.qml | 2 +- FileSets/v3.30/MbSubMenu.qml | 2 +- FileSets/v3.30/Multi.qml | 2 +- FileSets/v3.30/ObjectAcConnection.qml | 2 +- FileSets/v3.30/OverviewAcValuesEnhanced.qml | 2 +- FileSets/v3.30/OverviewBox.qml | 2 +- FileSets/v3.30/OverviewConnection.qml | 2 +- FileSets/v3.30/OverviewConnectionEnd.qml | 2 +- FileSets/v3.30/OverviewGeneratorEnhanced.qml | 2 +- .../v3.30/OverviewGeneratorRelayEnhanced.qml | 2 +- FileSets/v3.30/OverviewMobileEnhanced.qml | 2 +- FileSets/v3.30/OverviewSolarCharger.qml | 2 +- FileSets/v3.30/OverviewSolarInverter.qml | 2 +- FileSets/v3.30/OverviewTankDelegate.qml | 2 +- FileSets/v3.30/OverviewTanks.qml | 2 +- .../v3.30/OverviewTanksTempsDigInputs.qml | 2 +- FileSets/v3.30/PageDigitalInput.qml | 2 +- FileSets/v3.30/PageGenerator.qml | 2 +- FileSets/v3.30/PageMain.qml | 2 +- FileSets/v3.30/PageSettingsGenerator.qml | 2 +- FileSets/v3.30/PageSettingsGuiMods.qml | 2 +- FileSets/v3.30/PageSettingsRelay.qml | 2 +- FileSets/v3.30/Tile.qml | 2 +- FileSets/v3.30/TileDigIn.qml | 2 +- FileSets/v3.30/TileRelay.qml | 2 +- FileSets/v3.30/TileText.qml | 2 +- FileSets/v3.30/dbus_digitalinputs.py | 2 +- FileSets/v3.30/dbus_generator.py | 2 +- FileSets/v3.30/main.qml | 2 +- FileSets/v3.30/styles.css | 2 +- FileSets/v3.31/Battery.qml | 2 +- FileSets/v3.31/MbEditBoxDateTime.qml | 2 +- FileSets/v3.31/MbItem.qml | 2 +- FileSets/v3.31/MbItemDigitalInput.qml | 2 +- FileSets/v3.31/MbSpinBox.qml | 2 +- FileSets/v3.31/MbStyle.qml | 2 +- FileSets/v3.31/MbSubMenu.qml | 2 +- FileSets/v3.31/Multi.qml | 2 +- FileSets/v3.31/ObjectAcConnection.qml | 2 +- FileSets/v3.31/OverviewAcValuesEnhanced.qml | 2 +- FileSets/v3.31/OverviewBox.qml | 2 +- FileSets/v3.31/OverviewConnection.qml | 2 +- FileSets/v3.31/OverviewConnectionEnd.qml | 2 +- FileSets/v3.31/OverviewGeneratorEnhanced.qml | 2 +- .../v3.31/OverviewGeneratorRelayEnhanced.qml | 2 +- FileSets/v3.31/OverviewMobileEnhanced.qml | 2 +- FileSets/v3.31/OverviewSolarCharger.qml | 2 +- FileSets/v3.31/OverviewSolarInverter.qml | 2 +- FileSets/v3.31/OverviewTankDelegate.qml | 2 +- FileSets/v3.31/OverviewTanks.qml | 2 +- .../v3.31/OverviewTanksTempsDigInputs.qml | 2 +- FileSets/v3.31/PageDigitalInput.qml | 2 +- FileSets/v3.31/PageGenerator.qml | 2 +- FileSets/v3.31/PageMain.qml | 2 +- FileSets/v3.31/PageSettingsGenerator.qml | 2 +- FileSets/v3.31/PageSettingsGuiMods.qml | 2 +- FileSets/v3.31/PageSettingsRelay.qml | 2 +- FileSets/v3.31/Tile.qml | 2 +- FileSets/v3.31/TileDigIn.qml | 2 +- FileSets/v3.31/TileRelay.qml | 2 +- FileSets/v3.31/TileText.qml | 2 +- FileSets/v3.31/dbus_digitalinputs.py | 2 +- FileSets/v3.31/dbus_generator.py | 2 +- FileSets/v3.31/main.qml | 2 +- FileSets/v3.31/styles.css | 2 +- FileSets/v3.40~1/Battery.qml | 2 +- FileSets/v3.40~1/MbEditBoxDateTime.qml | 2 +- FileSets/v3.40~1/MbItem.qml | 2 +- FileSets/v3.40~1/MbItemDigitalInput.qml | 2 +- FileSets/v3.40~1/MbSpinBox.qml | 2 +- FileSets/v3.40~1/MbStyle.qml | 2 +- FileSets/v3.40~1/MbSubMenu.qml | 2 +- FileSets/v3.40~1/Multi.qml | 2 +- FileSets/v3.40~1/ObjectAcConnection.qml | 2 +- FileSets/v3.40~1/OverviewAcValuesEnhanced.qml | 2 +- FileSets/v3.40~1/OverviewBox.qml | 2 +- FileSets/v3.40~1/OverviewConnection.qml | 2 +- FileSets/v3.40~1/OverviewConnectionEnd.qml | 2 +- .../v3.40~1/OverviewGeneratorEnhanced.qml | 2 +- .../OverviewGeneratorRelayEnhanced.qml | 2 +- FileSets/v3.40~1/OverviewMobileEnhanced.qml | 2 +- FileSets/v3.40~1/OverviewSolarCharger.qml | 2 +- FileSets/v3.40~1/OverviewSolarInverter.qml | 2 +- FileSets/v3.40~1/OverviewTankDelegate.qml | 2 +- FileSets/v3.40~1/OverviewTanks.qml | 2 +- .../v3.40~1/OverviewTanksTempsDigInputs.qml | 2 +- FileSets/v3.40~1/PageDigitalInput.qml | 2 +- FileSets/v3.40~1/PageGenerator.qml | 2 +- FileSets/v3.40~1/PageMain.qml | 2 +- FileSets/v3.40~1/PageSettingsGenerator.qml | 2 +- FileSets/v3.40~1/PageSettingsGuiMods.qml | 2 +- FileSets/v3.40~1/PageSettingsRelay.qml | 2 +- FileSets/v3.40~1/Tile.qml | 2 +- FileSets/v3.40~1/TileDigIn.qml | 2 +- FileSets/v3.40~1/TileRelay.qml | 2 +- FileSets/v3.40~1/TileText.qml | 2 +- FileSets/v3.40~1/dbus_digitalinputs.py | 2 +- FileSets/v3.40~1/dbus_generator.py | 2 +- FileSets/v3.40~1/main.qml | 2 +- FileSets/v3.40~1/startstop.py | 2 +- FileSets/v3.40~1/styles.css | 2 +- FileSets/v3.40~10/Battery.qml | 177 +- FileSets/v3.40~10/DetailAcInput.qml | 607 +- FileSets/v3.40~10/DetailInverter.qml | 654 +- FileSets/v3.40~10/DetailLoadsCombined.qml | 147 +- FileSets/v3.40~10/DetailLoadsOnInput.qml | 147 +- FileSets/v3.40~10/DetailLoadsOnOutput.qml | 152 +- FileSets/v3.40~10/HubData.qml | 263 +- FileSets/v3.40~10/MbEditBoxDateTime.qml | 97 +- FileSets/v3.40~10/MbItem.qml | 194 +- FileSets/v3.40~10/MbItemDigitalInput.qml | 32 +- FileSets/v3.40~10/MbSpinBox.qml | 184 +- FileSets/v3.40~10/MbStyle.qml | 48 +- FileSets/v3.40~10/MbSubMenu.qml | 70 +- FileSets/v3.40~10/Multi.qml | 120 +- FileSets/v3.40~10/ObjectAcConnection.qml | 53 +- .../v3.40~10/OverviewAcValuesEnhanced.qml | 95 +- FileSets/v3.40~10/OverviewBox.qml | 56 +- FileSets/v3.40~10/OverviewConnection.qml | 138 +- FileSets/v3.40~10/OverviewConnectionEnd.qml | 47 +- FileSets/v3.40~10/OverviewFlowComplex.qml | 1536 +-- .../v3.40~10/OverviewGeneratorEnhanced.qml | 548 +- .../OverviewGeneratorRelayEnhanced.qml | 9 +- FileSets/v3.40~10/OverviewGridParallel.qml | 491 +- FileSets/v3.40~10/OverviewHub.qml | 316 +- FileSets/v3.40~10/OverviewHubEnhanced.qml | 1493 +-- FileSets/v3.40~10/OverviewMobileEnhanced.qml | 990 +- FileSets/v3.40~10/OverviewSolarCharger.qml | 59 +- FileSets/v3.40~10/OverviewSolarInverter.qml | 68 +- FileSets/v3.40~10/OverviewTankDelegate.qml | 116 +- FileSets/v3.40~10/OverviewTanks.qml | 270 +- .../v3.40~10/OverviewTanksTempsDigInputs.qml | 208 +- FileSets/v3.40~10/PageDigitalInput.qml | 148 +- FileSets/v3.40~10/PageGenerator.qml | 224 +- FileSets/v3.40~10/PageMain.qml | 286 +- FileSets/v3.40~10/PageSettingsDisplay.qml | 136 +- FileSets/v3.40~10/PageSettingsGenerator.qml | 130 +- FileSets/v3.40~10/PageSettingsGuiMods.qml | 291 +- FileSets/v3.40~10/PageSettingsRelay.qml | 516 +- FileSets/v3.40~10/PowerGauge.qml | 298 +- FileSets/v3.40~10/Tile.qml | 66 +- FileSets/v3.40~10/TileDigIn.qml | 134 +- FileSets/v3.40~10/TileRelay.qml | 502 +- FileSets/v3.40~10/TileText.qml | 14 +- FileSets/v3.40~10/attributes.csv | 736 +- FileSets/v3.40~10/dbus_digitalinputs.py | 652 +- FileSets/v3.40~10/dbus_generator.py | 349 +- FileSets/v3.40~10/main.qml | 599 +- FileSets/v3.40~10/startstop.py | 1537 +-- FileSets/v3.40~10/styles.css | 11044 +--------------- FileSets/v3.40~11/Battery.qml | 176 + .../{v3.40~10 => v3.40~11}/Battery.qml.orig | 0 FileSets/v3.40~11/COMPLETE | 0 FileSets/v3.40~11/DetailAcInput.qml | 606 + .../DetailAcInput.qml.orig | 0 FileSets/v3.40~11/DetailInverter.qml | 653 + .../DetailInverter.qml.orig | 0 FileSets/v3.40~11/DetailLoadsCombined.qml | 146 + .../DetailLoadsCombined.qml.orig | 0 FileSets/v3.40~11/DetailLoadsOnInput.qml | 146 + .../DetailLoadsOnInput.qml.orig | 0 FileSets/v3.40~11/DetailLoadsOnOutput.qml | 151 + .../DetailLoadsOnOutput.qml.orig | 0 FileSets/v3.40~11/HubData.qml | 262 + .../{v3.40~10 => v3.40~11}/HubData.qml.orig | 0 FileSets/v3.40~11/MbEditBox.qml | 414 + FileSets/v3.40~11/MbEditBox.qml.orig | 405 + FileSets/v3.40~11/MbEditBoxDateTime.qml | 96 + .../MbEditBoxDateTime.qml.orig | 0 FileSets/v3.40~11/MbItem.qml | 193 + .../{v3.40~10 => v3.40~11}/MbItem.qml.orig | 0 FileSets/v3.40~11/MbItemDigitalInput.qml | 31 + .../MbItemDigitalInput.qml.orig | 0 FileSets/v3.40~11/MbSpinBox.qml | 183 + .../{v3.40~10 => v3.40~11}/MbSpinBox.qml.orig | 0 FileSets/v3.40~11/MbStyle.qml | 47 + .../{v3.40~10 => v3.40~11}/MbStyle.qml.orig | 0 FileSets/v3.40~11/MbSubMenu.qml | 69 + .../{v3.40~10 => v3.40~11}/MbSubMenu.qml.orig | 0 FileSets/v3.40~11/Multi.qml | 119 + .../{v3.40~10 => v3.40~11}/Multi.qml.orig | 0 FileSets/v3.40~11/ObjectAcConnection.qml | 52 + .../ObjectAcConnection.qml.orig | 0 .../v3.40~11/OverviewAcValuesEnhanced.qml | 94 + .../OverviewAcValuesEnhanced.qml.orig | 0 FileSets/v3.40~11/OverviewBox.qml | 55 + .../OverviewBox.qml.orig | 0 FileSets/v3.40~11/OverviewConnection.qml | 137 + .../OverviewConnection.qml.orig | 0 FileSets/v3.40~11/OverviewConnectionEnd.qml | 46 + .../OverviewConnectionEnd.qml.orig | 0 FileSets/v3.40~11/OverviewFlowComplex.qml | 1535 +++ .../OverviewFlowComplex.qml.orig | 0 .../v3.40~11/OverviewGeneratorEnhanced.qml | 547 + .../OverviewGeneratorEnhanced.qml.orig | 0 .../OverviewGeneratorRelayEnhanced.qml | 8 + .../OverviewGeneratorRelayEnhanced.qml.orig | 0 FileSets/v3.40~11/OverviewGridParallel.qml | 490 + .../OverviewGridParallel.qml.orig | 0 FileSets/v3.40~11/OverviewHub.qml | 315 + .../OverviewHub.qml.orig | 0 FileSets/v3.40~11/OverviewHubEnhanced.qml | 1492 +++ .../OverviewHubEnhanced.qml.orig | 0 FileSets/v3.40~11/OverviewMobileEnhanced.qml | 989 ++ .../OverviewMobileEnhanced.qml.orig | 0 FileSets/v3.40~11/OverviewSolarCharger.qml | 58 + .../OverviewSolarCharger.qml.orig | 0 FileSets/v3.40~11/OverviewSolarInverter.qml | 67 + .../OverviewSolarInverter.qml.orig | 0 FileSets/v3.40~11/OverviewTankDelegate.qml | 115 + .../OverviewTankDelegate.qml.orig | 0 FileSets/v3.40~11/OverviewTanks.qml | 269 + .../OverviewTanks.qml.orig | 0 .../v3.40~11/OverviewTanksTempsDigInputs.qml | 207 + .../OverviewTanksTempsDigInputs.qml.orig | 0 FileSets/v3.40~11/PageDigitalInput.qml | 147 + .../PageDigitalInput.qml.orig | 0 FileSets/v3.40~11/PageGenerator.qml | 223 + .../PageGenerator.qml.orig | 0 FileSets/v3.40~11/PageMain.qml | 285 + .../{v3.40~10 => v3.40~11}/PageMain.qml.orig | 0 FileSets/v3.40~11/PageSettingsDisplay.qml | 135 + .../PageSettingsDisplay.qml.orig | 0 FileSets/v3.40~11/PageSettingsGenerator.qml | 129 + .../PageSettingsGenerator.qml.orig | 0 FileSets/v3.40~11/PageSettingsGuiMods.qml | 290 + .../PageSettingsGuiMods.qml.orig | 0 FileSets/v3.40~11/PageSettingsRelay.qml | 515 + .../PageSettingsRelay.qml.orig | 0 FileSets/v3.40~11/PowerGauge.qml | 297 + .../PowerGauge.qml.orig | 0 FileSets/v3.40~11/Tile.qml | 65 + FileSets/{v3.40~10 => v3.40~11}/Tile.qml.orig | 0 FileSets/v3.40~11/TileDigIn.qml | 133 + .../{v3.40~10 => v3.40~11}/TileDigIn.qml.orig | 0 FileSets/v3.40~11/TileRelay.qml | 501 + .../{v3.40~10 => v3.40~11}/TileRelay.qml.orig | 0 FileSets/v3.40~11/TileText.qml | 13 + .../{v3.40~10 => v3.40~11}/TileText.qml.orig | 0 FileSets/v3.40~11/attributes.csv | 735 + .../attributes.csv.orig | 0 FileSets/v3.40~11/dbus_digitalinputs.py | 651 + .../dbus_digitalinputs.py.orig | 0 FileSets/v3.40~11/dbus_generator.py | 348 + .../dbus_generator.py.orig | 0 FileSets/v3.40~11/dbus_systemcalc.py | 1488 +++ FileSets/v3.40~11/dbus_systemcalc.py.orig | 1245 ++ FileSets/v3.40~11/main.qml | 598 + FileSets/{v3.40~10 => v3.40~11}/main.qml.orig | 0 FileSets/v3.40~11/startstop.py | 1536 +++ .../{v3.40~10 => v3.40~11}/startstop.py.orig | 0 FileSets/v3.40~11/styles.css | 11043 +++++++++++++++ .../{v3.40~10 => v3.40~11}/styles.css.orig | 0 FileSets/v3.40~2/Battery.qml | 2 +- FileSets/v3.40~2/MbEditBoxDateTime.qml | 2 +- FileSets/v3.40~2/MbItem.qml | 2 +- FileSets/v3.40~2/MbItemDigitalInput.qml | 2 +- FileSets/v3.40~2/MbSpinBox.qml | 2 +- FileSets/v3.40~2/MbStyle.qml | 2 +- FileSets/v3.40~2/MbSubMenu.qml | 2 +- FileSets/v3.40~2/Multi.qml | 2 +- FileSets/v3.40~2/ObjectAcConnection.qml | 2 +- FileSets/v3.40~2/OverviewAcValuesEnhanced.qml | 2 +- FileSets/v3.40~2/OverviewBox.qml | 2 +- FileSets/v3.40~2/OverviewConnection.qml | 2 +- FileSets/v3.40~2/OverviewConnectionEnd.qml | 2 +- .../v3.40~2/OverviewGeneratorEnhanced.qml | 2 +- .../OverviewGeneratorRelayEnhanced.qml | 2 +- FileSets/v3.40~2/OverviewMobileEnhanced.qml | 2 +- FileSets/v3.40~2/OverviewSolarCharger.qml | 2 +- FileSets/v3.40~2/OverviewSolarInverter.qml | 2 +- FileSets/v3.40~2/OverviewTankDelegate.qml | 2 +- FileSets/v3.40~2/OverviewTanks.qml | 2 +- .../v3.40~2/OverviewTanksTempsDigInputs.qml | 2 +- FileSets/v3.40~2/PageDigitalInput.qml | 2 +- FileSets/v3.40~2/PageGenerator.qml | 2 +- FileSets/v3.40~2/PageMain.qml | 2 +- FileSets/v3.40~2/PageSettingsGenerator.qml | 2 +- FileSets/v3.40~2/PageSettingsGuiMods.qml | 2 +- FileSets/v3.40~2/PageSettingsRelay.qml | 2 +- FileSets/v3.40~2/Tile.qml | 2 +- FileSets/v3.40~2/TileDigIn.qml | 2 +- FileSets/v3.40~2/TileRelay.qml | 2 +- FileSets/v3.40~2/TileText.qml | 2 +- FileSets/v3.40~2/dbus_digitalinputs.py | 2 +- FileSets/v3.40~2/dbus_generator.py | 2 +- FileSets/v3.40~2/main.qml | 2 +- FileSets/v3.40~2/startstop.py | 2 +- FileSets/v3.40~2/styles.css | 2 +- FileSets/v3.40~5/Battery.qml | 2 +- FileSets/v3.40~5/MbEditBoxDateTime.qml | 2 +- FileSets/v3.40~5/MbItem.qml | 2 +- FileSets/v3.40~5/MbItemDigitalInput.qml | 2 +- FileSets/v3.40~5/MbSpinBox.qml | 2 +- FileSets/v3.40~5/MbStyle.qml | 2 +- FileSets/v3.40~5/MbSubMenu.qml | 2 +- FileSets/v3.40~5/Multi.qml | 2 +- FileSets/v3.40~5/ObjectAcConnection.qml | 2 +- FileSets/v3.40~5/OverviewAcValuesEnhanced.qml | 2 +- FileSets/v3.40~5/OverviewBox.qml | 2 +- FileSets/v3.40~5/OverviewConnection.qml | 2 +- FileSets/v3.40~5/OverviewConnectionEnd.qml | 2 +- .../v3.40~5/OverviewGeneratorEnhanced.qml | 2 +- .../OverviewGeneratorRelayEnhanced.qml | 2 +- FileSets/v3.40~5/OverviewMobileEnhanced.qml | 2 +- FileSets/v3.40~5/OverviewSolarCharger.qml | 2 +- FileSets/v3.40~5/OverviewSolarInverter.qml | 2 +- FileSets/v3.40~5/OverviewTankDelegate.qml | 2 +- FileSets/v3.40~5/OverviewTanks.qml | 2 +- .../v3.40~5/OverviewTanksTempsDigInputs.qml | 2 +- FileSets/v3.40~5/PageDigitalInput.qml | 2 +- FileSets/v3.40~5/PageGenerator.qml | 2 +- FileSets/v3.40~5/PageMain.qml | 2 +- FileSets/v3.40~5/PageSettingsGenerator.qml | 2 +- FileSets/v3.40~5/PageSettingsGuiMods.qml | 2 +- FileSets/v3.40~5/PageSettingsRelay.qml | 2 +- FileSets/v3.40~5/Tile.qml | 2 +- FileSets/v3.40~5/TileDigIn.qml | 2 +- FileSets/v3.40~5/TileRelay.qml | 2 +- FileSets/v3.40~5/TileText.qml | 2 +- FileSets/v3.40~5/dbus_digitalinputs.py | 2 +- FileSets/v3.40~5/dbus_generator.py | 2 +- FileSets/v3.40~5/main.qml | 2 +- FileSets/v3.40~5/startstop.py | 2 +- FileSets/v3.40~5/styles.css | 2 +- FileSets/v3.40~6/Battery.qml | 2 +- FileSets/v3.40~6/MbEditBoxDateTime.qml | 2 +- FileSets/v3.40~6/MbItem.qml | 2 +- FileSets/v3.40~6/MbItemDigitalInput.qml | 2 +- FileSets/v3.40~6/MbSpinBox.qml | 2 +- FileSets/v3.40~6/MbStyle.qml | 2 +- FileSets/v3.40~6/MbSubMenu.qml | 2 +- FileSets/v3.40~6/Multi.qml | 2 +- FileSets/v3.40~6/ObjectAcConnection.qml | 2 +- FileSets/v3.40~6/OverviewAcValuesEnhanced.qml | 2 +- FileSets/v3.40~6/OverviewBox.qml | 2 +- FileSets/v3.40~6/OverviewConnection.qml | 2 +- FileSets/v3.40~6/OverviewConnectionEnd.qml | 2 +- .../v3.40~6/OverviewGeneratorEnhanced.qml | 2 +- .../OverviewGeneratorRelayEnhanced.qml | 2 +- FileSets/v3.40~6/OverviewMobileEnhanced.qml | 2 +- FileSets/v3.40~6/OverviewSolarCharger.qml | 2 +- FileSets/v3.40~6/OverviewSolarInverter.qml | 2 +- FileSets/v3.40~6/OverviewTankDelegate.qml | 2 +- FileSets/v3.40~6/OverviewTanks.qml | 2 +- .../v3.40~6/OverviewTanksTempsDigInputs.qml | 2 +- FileSets/v3.40~6/PageDigitalInput.qml | 2 +- FileSets/v3.40~6/PageGenerator.qml | 2 +- FileSets/v3.40~6/PageMain.qml | 2 +- FileSets/v3.40~6/PageSettingsGenerator.qml | 2 +- FileSets/v3.40~6/PageSettingsGuiMods.qml | 2 +- FileSets/v3.40~6/PageSettingsRelay.qml | 2 +- FileSets/v3.40~6/Tile.qml | 2 +- FileSets/v3.40~6/TileDigIn.qml | 2 +- FileSets/v3.40~6/TileRelay.qml | 2 +- FileSets/v3.40~6/TileText.qml | 2 +- FileSets/v3.40~6/dbus_digitalinputs.py | 2 +- FileSets/v3.40~6/dbus_generator.py | 2 +- FileSets/v3.40~6/main.qml | 2 +- FileSets/v3.40~6/startstop.py | 2 +- FileSets/v3.40~6/styles.css | 2 +- FileSets/v3.40~8/Battery.qml | 2 +- FileSets/v3.40~8/MbEditBoxDateTime.qml | 2 +- FileSets/v3.40~8/MbItem.qml | 2 +- FileSets/v3.40~8/MbItemDigitalInput.qml | 2 +- FileSets/v3.40~8/MbSpinBox.qml | 2 +- FileSets/v3.40~8/MbStyle.qml | 2 +- FileSets/v3.40~8/MbSubMenu.qml | 2 +- FileSets/v3.40~8/Multi.qml | 2 +- FileSets/v3.40~8/ObjectAcConnection.qml | 2 +- FileSets/v3.40~8/OverviewAcValuesEnhanced.qml | 2 +- FileSets/v3.40~8/OverviewBox.qml | 2 +- FileSets/v3.40~8/OverviewConnection.qml | 2 +- FileSets/v3.40~8/OverviewConnectionEnd.qml | 2 +- .../v3.40~8/OverviewGeneratorEnhanced.qml | 2 +- .../OverviewGeneratorRelayEnhanced.qml | 2 +- FileSets/v3.40~8/OverviewMobileEnhanced.qml | 2 +- FileSets/v3.40~8/OverviewSolarCharger.qml | 2 +- FileSets/v3.40~8/OverviewSolarInverter.qml | 2 +- FileSets/v3.40~8/OverviewTankDelegate.qml | 2 +- FileSets/v3.40~8/OverviewTanks.qml | 2 +- .../v3.40~8/OverviewTanksTempsDigInputs.qml | 2 +- FileSets/v3.40~8/PageDigitalInput.qml | 2 +- FileSets/v3.40~8/PageGenerator.qml | 2 +- FileSets/v3.40~8/PageMain.qml | 2 +- FileSets/v3.40~8/PageSettingsGenerator.qml | 2 +- FileSets/v3.40~8/PageSettingsGuiMods.qml | 2 +- FileSets/v3.40~8/PageSettingsRelay.qml | 2 +- FileSets/v3.40~8/Tile.qml | 2 +- FileSets/v3.40~8/TileDigIn.qml | 2 +- FileSets/v3.40~8/TileRelay.qml | 2 +- FileSets/v3.40~8/TileText.qml | 2 +- FileSets/v3.40~8/attributes.csv | 2 +- FileSets/v3.40~8/dbus_digitalinputs.py | 2 +- FileSets/v3.40~8/dbus_generator.py | 2 +- FileSets/v3.40~8/main.qml | 2 +- FileSets/v3.40~8/startstop.py | 2 +- FileSets/v3.40~8/styles.css | 2 +- changes | 3 + version | 2 +- 894 files changed, 31343 insertions(+), 27739 deletions(-) mode change 100644 => 120000 FileSets/v3.40~10/Battery.qml mode change 100644 => 120000 FileSets/v3.40~10/DetailAcInput.qml mode change 100644 => 120000 FileSets/v3.40~10/DetailInverter.qml mode change 100644 => 120000 FileSets/v3.40~10/DetailLoadsCombined.qml mode change 100644 => 120000 FileSets/v3.40~10/DetailLoadsOnInput.qml mode change 100644 => 120000 FileSets/v3.40~10/DetailLoadsOnOutput.qml mode change 100644 => 120000 FileSets/v3.40~10/HubData.qml mode change 100644 => 120000 FileSets/v3.40~10/MbEditBoxDateTime.qml mode change 100644 => 120000 FileSets/v3.40~10/MbItem.qml mode change 100644 => 120000 FileSets/v3.40~10/MbItemDigitalInput.qml mode change 100644 => 120000 FileSets/v3.40~10/MbSpinBox.qml mode change 100644 => 120000 FileSets/v3.40~10/MbStyle.qml mode change 100644 => 120000 FileSets/v3.40~10/MbSubMenu.qml mode change 100644 => 120000 FileSets/v3.40~10/Multi.qml mode change 100644 => 120000 FileSets/v3.40~10/ObjectAcConnection.qml mode change 100644 => 120000 FileSets/v3.40~10/OverviewAcValuesEnhanced.qml mode change 100644 => 120000 FileSets/v3.40~10/OverviewBox.qml mode change 100644 => 120000 FileSets/v3.40~10/OverviewConnection.qml mode change 100644 => 120000 FileSets/v3.40~10/OverviewConnectionEnd.qml mode change 100644 => 120000 FileSets/v3.40~10/OverviewFlowComplex.qml mode change 100644 => 120000 FileSets/v3.40~10/OverviewGeneratorEnhanced.qml mode change 100644 => 120000 FileSets/v3.40~10/OverviewGeneratorRelayEnhanced.qml mode change 100644 => 120000 FileSets/v3.40~10/OverviewGridParallel.qml mode change 100644 => 120000 FileSets/v3.40~10/OverviewHub.qml mode change 100644 => 120000 FileSets/v3.40~10/OverviewHubEnhanced.qml mode change 100644 => 120000 FileSets/v3.40~10/OverviewMobileEnhanced.qml mode change 100644 => 120000 FileSets/v3.40~10/OverviewSolarCharger.qml mode change 100644 => 120000 FileSets/v3.40~10/OverviewSolarInverter.qml mode change 100644 => 120000 FileSets/v3.40~10/OverviewTankDelegate.qml mode change 100644 => 120000 FileSets/v3.40~10/OverviewTanks.qml mode change 100644 => 120000 FileSets/v3.40~10/OverviewTanksTempsDigInputs.qml mode change 100644 => 120000 FileSets/v3.40~10/PageDigitalInput.qml mode change 100644 => 120000 FileSets/v3.40~10/PageGenerator.qml mode change 100644 => 120000 FileSets/v3.40~10/PageMain.qml mode change 100644 => 120000 FileSets/v3.40~10/PageSettingsDisplay.qml mode change 100644 => 120000 FileSets/v3.40~10/PageSettingsGenerator.qml mode change 100644 => 120000 FileSets/v3.40~10/PageSettingsGuiMods.qml mode change 100644 => 120000 FileSets/v3.40~10/PageSettingsRelay.qml mode change 100644 => 120000 FileSets/v3.40~10/PowerGauge.qml mode change 100644 => 120000 FileSets/v3.40~10/Tile.qml mode change 100644 => 120000 FileSets/v3.40~10/TileDigIn.qml mode change 100644 => 120000 FileSets/v3.40~10/TileRelay.qml mode change 100644 => 120000 FileSets/v3.40~10/TileText.qml mode change 100644 => 120000 FileSets/v3.40~10/attributes.csv mode change 100755 => 120000 FileSets/v3.40~10/dbus_digitalinputs.py mode change 100755 => 120000 FileSets/v3.40~10/dbus_generator.py mode change 100644 => 120000 FileSets/v3.40~10/main.qml mode change 100644 => 120000 FileSets/v3.40~10/startstop.py mode change 100644 => 120000 FileSets/v3.40~10/styles.css create mode 100644 FileSets/v3.40~11/Battery.qml rename FileSets/{v3.40~10 => v3.40~11}/Battery.qml.orig (100%) create mode 100644 FileSets/v3.40~11/COMPLETE create mode 100644 FileSets/v3.40~11/DetailAcInput.qml rename FileSets/{v3.40~10 => v3.40~11}/DetailAcInput.qml.orig (100%) create mode 100644 FileSets/v3.40~11/DetailInverter.qml rename FileSets/{v3.40~10 => v3.40~11}/DetailInverter.qml.orig (100%) create mode 100644 FileSets/v3.40~11/DetailLoadsCombined.qml rename FileSets/{v3.40~10 => v3.40~11}/DetailLoadsCombined.qml.orig (100%) create mode 100644 FileSets/v3.40~11/DetailLoadsOnInput.qml rename FileSets/{v3.40~10 => v3.40~11}/DetailLoadsOnInput.qml.orig (100%) create mode 100644 FileSets/v3.40~11/DetailLoadsOnOutput.qml rename FileSets/{v3.40~10 => v3.40~11}/DetailLoadsOnOutput.qml.orig (100%) create mode 100644 FileSets/v3.40~11/HubData.qml rename FileSets/{v3.40~10 => v3.40~11}/HubData.qml.orig (100%) create mode 100644 FileSets/v3.40~11/MbEditBox.qml create mode 100644 FileSets/v3.40~11/MbEditBox.qml.orig create mode 100644 FileSets/v3.40~11/MbEditBoxDateTime.qml rename FileSets/{v3.40~10 => v3.40~11}/MbEditBoxDateTime.qml.orig (100%) create mode 100644 FileSets/v3.40~11/MbItem.qml rename FileSets/{v3.40~10 => v3.40~11}/MbItem.qml.orig (100%) create mode 100644 FileSets/v3.40~11/MbItemDigitalInput.qml rename FileSets/{v3.40~10 => v3.40~11}/MbItemDigitalInput.qml.orig (100%) create mode 100644 FileSets/v3.40~11/MbSpinBox.qml rename FileSets/{v3.40~10 => v3.40~11}/MbSpinBox.qml.orig (100%) create mode 100644 FileSets/v3.40~11/MbStyle.qml rename FileSets/{v3.40~10 => v3.40~11}/MbStyle.qml.orig (100%) create mode 100644 FileSets/v3.40~11/MbSubMenu.qml rename FileSets/{v3.40~10 => v3.40~11}/MbSubMenu.qml.orig (100%) create mode 100644 FileSets/v3.40~11/Multi.qml rename FileSets/{v3.40~10 => v3.40~11}/Multi.qml.orig (100%) create mode 100644 FileSets/v3.40~11/ObjectAcConnection.qml rename FileSets/{v3.40~10 => v3.40~11}/ObjectAcConnection.qml.orig (100%) create mode 100644 FileSets/v3.40~11/OverviewAcValuesEnhanced.qml rename FileSets/{v3.40~10 => v3.40~11}/OverviewAcValuesEnhanced.qml.orig (100%) create mode 100644 FileSets/v3.40~11/OverviewBox.qml rename FileSets/{v3.40~10 => v3.40~11}/OverviewBox.qml.orig (100%) create mode 100644 FileSets/v3.40~11/OverviewConnection.qml rename FileSets/{v3.40~10 => v3.40~11}/OverviewConnection.qml.orig (100%) create mode 100644 FileSets/v3.40~11/OverviewConnectionEnd.qml rename FileSets/{v3.40~10 => v3.40~11}/OverviewConnectionEnd.qml.orig (100%) create mode 100644 FileSets/v3.40~11/OverviewFlowComplex.qml rename FileSets/{v3.40~10 => v3.40~11}/OverviewFlowComplex.qml.orig (100%) create mode 100644 FileSets/v3.40~11/OverviewGeneratorEnhanced.qml rename FileSets/{v3.40~10 => v3.40~11}/OverviewGeneratorEnhanced.qml.orig (100%) create mode 100644 FileSets/v3.40~11/OverviewGeneratorRelayEnhanced.qml rename FileSets/{v3.40~10 => v3.40~11}/OverviewGeneratorRelayEnhanced.qml.orig (100%) create mode 100644 FileSets/v3.40~11/OverviewGridParallel.qml rename FileSets/{v3.40~10 => v3.40~11}/OverviewGridParallel.qml.orig (100%) create mode 100644 FileSets/v3.40~11/OverviewHub.qml rename FileSets/{v3.40~10 => v3.40~11}/OverviewHub.qml.orig (100%) create mode 100644 FileSets/v3.40~11/OverviewHubEnhanced.qml rename FileSets/{v3.40~10 => v3.40~11}/OverviewHubEnhanced.qml.orig (100%) create mode 100644 FileSets/v3.40~11/OverviewMobileEnhanced.qml rename FileSets/{v3.40~10 => v3.40~11}/OverviewMobileEnhanced.qml.orig (100%) create mode 100644 FileSets/v3.40~11/OverviewSolarCharger.qml rename FileSets/{v3.40~10 => v3.40~11}/OverviewSolarCharger.qml.orig (100%) create mode 100644 FileSets/v3.40~11/OverviewSolarInverter.qml rename FileSets/{v3.40~10 => v3.40~11}/OverviewSolarInverter.qml.orig (100%) create mode 100644 FileSets/v3.40~11/OverviewTankDelegate.qml rename FileSets/{v3.40~10 => v3.40~11}/OverviewTankDelegate.qml.orig (100%) create mode 100644 FileSets/v3.40~11/OverviewTanks.qml rename FileSets/{v3.40~10 => v3.40~11}/OverviewTanks.qml.orig (100%) create mode 100644 FileSets/v3.40~11/OverviewTanksTempsDigInputs.qml rename FileSets/{v3.40~10 => v3.40~11}/OverviewTanksTempsDigInputs.qml.orig (100%) create mode 100644 FileSets/v3.40~11/PageDigitalInput.qml rename FileSets/{v3.40~10 => v3.40~11}/PageDigitalInput.qml.orig (100%) create mode 100644 FileSets/v3.40~11/PageGenerator.qml rename FileSets/{v3.40~10 => v3.40~11}/PageGenerator.qml.orig (100%) create mode 100644 FileSets/v3.40~11/PageMain.qml rename FileSets/{v3.40~10 => v3.40~11}/PageMain.qml.orig (100%) create mode 100644 FileSets/v3.40~11/PageSettingsDisplay.qml rename FileSets/{v3.40~10 => v3.40~11}/PageSettingsDisplay.qml.orig (100%) create mode 100644 FileSets/v3.40~11/PageSettingsGenerator.qml rename FileSets/{v3.40~10 => v3.40~11}/PageSettingsGenerator.qml.orig (100%) create mode 100644 FileSets/v3.40~11/PageSettingsGuiMods.qml rename FileSets/{v3.40~10 => v3.40~11}/PageSettingsGuiMods.qml.orig (100%) create mode 100644 FileSets/v3.40~11/PageSettingsRelay.qml rename FileSets/{v3.40~10 => v3.40~11}/PageSettingsRelay.qml.orig (100%) create mode 100644 FileSets/v3.40~11/PowerGauge.qml rename FileSets/{v3.40~10 => v3.40~11}/PowerGauge.qml.orig (100%) create mode 100644 FileSets/v3.40~11/Tile.qml rename FileSets/{v3.40~10 => v3.40~11}/Tile.qml.orig (100%) create mode 100644 FileSets/v3.40~11/TileDigIn.qml rename FileSets/{v3.40~10 => v3.40~11}/TileDigIn.qml.orig (100%) create mode 100644 FileSets/v3.40~11/TileRelay.qml rename FileSets/{v3.40~10 => v3.40~11}/TileRelay.qml.orig (100%) create mode 100644 FileSets/v3.40~11/TileText.qml rename FileSets/{v3.40~10 => v3.40~11}/TileText.qml.orig (100%) create mode 100644 FileSets/v3.40~11/attributes.csv rename FileSets/{v3.40~10 => v3.40~11}/attributes.csv.orig (100%) create mode 100755 FileSets/v3.40~11/dbus_digitalinputs.py rename FileSets/{v3.40~10 => v3.40~11}/dbus_digitalinputs.py.orig (100%) create mode 100755 FileSets/v3.40~11/dbus_generator.py rename FileSets/{v3.40~10 => v3.40~11}/dbus_generator.py.orig (100%) create mode 100755 FileSets/v3.40~11/dbus_systemcalc.py create mode 100755 FileSets/v3.40~11/dbus_systemcalc.py.orig create mode 100644 FileSets/v3.40~11/main.qml rename FileSets/{v3.40~10 => v3.40~11}/main.qml.orig (100%) create mode 100644 FileSets/v3.40~11/startstop.py rename FileSets/{v3.40~10 => v3.40~11}/startstop.py.orig (100%) create mode 100644 FileSets/v3.40~11/styles.css rename FileSets/{v3.40~10 => v3.40~11}/styles.css.orig (100%) diff --git a/FileSets/v2.71/MbEditBoxDateTime.qml b/FileSets/v2.71/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v2.71/MbEditBoxDateTime.qml +++ b/FileSets/v2.71/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.71/MbSubMenu.qml b/FileSets/v2.71/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v2.71/MbSubMenu.qml +++ b/FileSets/v2.71/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.71/Multi.qml b/FileSets/v2.71/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v2.71/Multi.qml +++ b/FileSets/v2.71/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.71/OverviewBox.qml b/FileSets/v2.71/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v2.71/OverviewBox.qml +++ b/FileSets/v2.71/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.71/OverviewConnection.qml b/FileSets/v2.71/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v2.71/OverviewConnection.qml +++ b/FileSets/v2.71/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.71/OverviewConnectionEnd.qml b/FileSets/v2.71/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v2.71/OverviewConnectionEnd.qml +++ b/FileSets/v2.71/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.71/OverviewSolarCharger.qml b/FileSets/v2.71/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v2.71/OverviewSolarCharger.qml +++ b/FileSets/v2.71/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.71/OverviewTankDelegate.qml b/FileSets/v2.71/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v2.71/OverviewTankDelegate.qml +++ b/FileSets/v2.71/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.71/OverviewTanks.qml b/FileSets/v2.71/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v2.71/OverviewTanks.qml +++ b/FileSets/v2.71/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.71/TileText.qml b/FileSets/v2.71/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v2.71/TileText.qml +++ b/FileSets/v2.71/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.71/styles.css b/FileSets/v2.71/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v2.71/styles.css +++ b/FileSets/v2.71/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v2.72/MbEditBoxDateTime.qml b/FileSets/v2.72/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v2.72/MbEditBoxDateTime.qml +++ b/FileSets/v2.72/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.72/MbSubMenu.qml b/FileSets/v2.72/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v2.72/MbSubMenu.qml +++ b/FileSets/v2.72/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.72/Multi.qml b/FileSets/v2.72/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v2.72/Multi.qml +++ b/FileSets/v2.72/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.72/OverviewBox.qml b/FileSets/v2.72/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v2.72/OverviewBox.qml +++ b/FileSets/v2.72/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.72/OverviewConnection.qml b/FileSets/v2.72/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v2.72/OverviewConnection.qml +++ b/FileSets/v2.72/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.72/OverviewConnectionEnd.qml b/FileSets/v2.72/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v2.72/OverviewConnectionEnd.qml +++ b/FileSets/v2.72/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.72/OverviewSolarCharger.qml b/FileSets/v2.72/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v2.72/OverviewSolarCharger.qml +++ b/FileSets/v2.72/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.72/OverviewTankDelegate.qml b/FileSets/v2.72/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v2.72/OverviewTankDelegate.qml +++ b/FileSets/v2.72/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.72/OverviewTanks.qml b/FileSets/v2.72/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v2.72/OverviewTanks.qml +++ b/FileSets/v2.72/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.72/TileText.qml b/FileSets/v2.72/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v2.72/TileText.qml +++ b/FileSets/v2.72/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.72/styles.css b/FileSets/v2.72/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v2.72/styles.css +++ b/FileSets/v2.72/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v2.73/MbEditBoxDateTime.qml b/FileSets/v2.73/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v2.73/MbEditBoxDateTime.qml +++ b/FileSets/v2.73/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.73/MbSubMenu.qml b/FileSets/v2.73/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v2.73/MbSubMenu.qml +++ b/FileSets/v2.73/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.73/Multi.qml b/FileSets/v2.73/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v2.73/Multi.qml +++ b/FileSets/v2.73/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.73/OverviewBox.qml b/FileSets/v2.73/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v2.73/OverviewBox.qml +++ b/FileSets/v2.73/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.73/OverviewConnection.qml b/FileSets/v2.73/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v2.73/OverviewConnection.qml +++ b/FileSets/v2.73/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.73/OverviewConnectionEnd.qml b/FileSets/v2.73/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v2.73/OverviewConnectionEnd.qml +++ b/FileSets/v2.73/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.73/OverviewSolarCharger.qml b/FileSets/v2.73/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v2.73/OverviewSolarCharger.qml +++ b/FileSets/v2.73/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.73/OverviewTankDelegate.qml b/FileSets/v2.73/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v2.73/OverviewTankDelegate.qml +++ b/FileSets/v2.73/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.73/OverviewTanks.qml b/FileSets/v2.73/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v2.73/OverviewTanks.qml +++ b/FileSets/v2.73/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.73/TileText.qml b/FileSets/v2.73/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v2.73/TileText.qml +++ b/FileSets/v2.73/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.73/styles.css b/FileSets/v2.73/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v2.73/styles.css +++ b/FileSets/v2.73/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v2.80/MbEditBoxDateTime.qml b/FileSets/v2.80/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v2.80/MbEditBoxDateTime.qml +++ b/FileSets/v2.80/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.80/MbSubMenu.qml b/FileSets/v2.80/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v2.80/MbSubMenu.qml +++ b/FileSets/v2.80/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.80/Multi.qml b/FileSets/v2.80/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v2.80/Multi.qml +++ b/FileSets/v2.80/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.80/OverviewBox.qml b/FileSets/v2.80/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v2.80/OverviewBox.qml +++ b/FileSets/v2.80/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.80/OverviewConnection.qml b/FileSets/v2.80/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v2.80/OverviewConnection.qml +++ b/FileSets/v2.80/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.80/OverviewConnectionEnd.qml b/FileSets/v2.80/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v2.80/OverviewConnectionEnd.qml +++ b/FileSets/v2.80/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.80/OverviewSolarCharger.qml b/FileSets/v2.80/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v2.80/OverviewSolarCharger.qml +++ b/FileSets/v2.80/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.80/OverviewTankDelegate.qml b/FileSets/v2.80/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v2.80/OverviewTankDelegate.qml +++ b/FileSets/v2.80/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.80/OverviewTanks.qml b/FileSets/v2.80/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v2.80/OverviewTanks.qml +++ b/FileSets/v2.80/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.80/TileText.qml b/FileSets/v2.80/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v2.80/TileText.qml +++ b/FileSets/v2.80/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.80/styles.css b/FileSets/v2.80/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v2.80/styles.css +++ b/FileSets/v2.80/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v2.81/MbEditBoxDateTime.qml b/FileSets/v2.81/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v2.81/MbEditBoxDateTime.qml +++ b/FileSets/v2.81/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.81/MbSubMenu.qml b/FileSets/v2.81/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v2.81/MbSubMenu.qml +++ b/FileSets/v2.81/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.81/Multi.qml b/FileSets/v2.81/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v2.81/Multi.qml +++ b/FileSets/v2.81/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.81/OverviewBox.qml b/FileSets/v2.81/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v2.81/OverviewBox.qml +++ b/FileSets/v2.81/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.81/OverviewConnection.qml b/FileSets/v2.81/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v2.81/OverviewConnection.qml +++ b/FileSets/v2.81/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.81/OverviewConnectionEnd.qml b/FileSets/v2.81/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v2.81/OverviewConnectionEnd.qml +++ b/FileSets/v2.81/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.81/OverviewSolarCharger.qml b/FileSets/v2.81/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v2.81/OverviewSolarCharger.qml +++ b/FileSets/v2.81/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.81/OverviewTankDelegate.qml b/FileSets/v2.81/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v2.81/OverviewTankDelegate.qml +++ b/FileSets/v2.81/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.81/OverviewTanks.qml b/FileSets/v2.81/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v2.81/OverviewTanks.qml +++ b/FileSets/v2.81/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.81/TileText.qml b/FileSets/v2.81/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v2.81/TileText.qml +++ b/FileSets/v2.81/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.81/styles.css b/FileSets/v2.81/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v2.81/styles.css +++ b/FileSets/v2.81/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v2.82/MbEditBoxDateTime.qml b/FileSets/v2.82/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v2.82/MbEditBoxDateTime.qml +++ b/FileSets/v2.82/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.82/MbSubMenu.qml b/FileSets/v2.82/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v2.82/MbSubMenu.qml +++ b/FileSets/v2.82/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.82/Multi.qml b/FileSets/v2.82/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v2.82/Multi.qml +++ b/FileSets/v2.82/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.82/OverviewBox.qml b/FileSets/v2.82/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v2.82/OverviewBox.qml +++ b/FileSets/v2.82/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.82/OverviewConnection.qml b/FileSets/v2.82/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v2.82/OverviewConnection.qml +++ b/FileSets/v2.82/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.82/OverviewConnectionEnd.qml b/FileSets/v2.82/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v2.82/OverviewConnectionEnd.qml +++ b/FileSets/v2.82/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.82/OverviewSolarCharger.qml b/FileSets/v2.82/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v2.82/OverviewSolarCharger.qml +++ b/FileSets/v2.82/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.82/OverviewTankDelegate.qml b/FileSets/v2.82/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v2.82/OverviewTankDelegate.qml +++ b/FileSets/v2.82/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.82/OverviewTanks.qml b/FileSets/v2.82/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v2.82/OverviewTanks.qml +++ b/FileSets/v2.82/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.82/TileText.qml b/FileSets/v2.82/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v2.82/TileText.qml +++ b/FileSets/v2.82/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.82/styles.css b/FileSets/v2.82/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v2.82/styles.css +++ b/FileSets/v2.82/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v2.83/MbEditBoxDateTime.qml b/FileSets/v2.83/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v2.83/MbEditBoxDateTime.qml +++ b/FileSets/v2.83/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.83/MbSubMenu.qml b/FileSets/v2.83/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v2.83/MbSubMenu.qml +++ b/FileSets/v2.83/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.83/Multi.qml b/FileSets/v2.83/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v2.83/Multi.qml +++ b/FileSets/v2.83/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.83/OverviewBox.qml b/FileSets/v2.83/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v2.83/OverviewBox.qml +++ b/FileSets/v2.83/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.83/OverviewConnection.qml b/FileSets/v2.83/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v2.83/OverviewConnection.qml +++ b/FileSets/v2.83/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.83/OverviewConnectionEnd.qml b/FileSets/v2.83/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v2.83/OverviewConnectionEnd.qml +++ b/FileSets/v2.83/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.83/OverviewSolarCharger.qml b/FileSets/v2.83/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v2.83/OverviewSolarCharger.qml +++ b/FileSets/v2.83/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.83/OverviewTankDelegate.qml b/FileSets/v2.83/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v2.83/OverviewTankDelegate.qml +++ b/FileSets/v2.83/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.83/OverviewTanks.qml b/FileSets/v2.83/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v2.83/OverviewTanks.qml +++ b/FileSets/v2.83/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.83/TileText.qml b/FileSets/v2.83/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v2.83/TileText.qml +++ b/FileSets/v2.83/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.83/styles.css b/FileSets/v2.83/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v2.83/styles.css +++ b/FileSets/v2.83/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v2.84/MbEditBoxDateTime.qml b/FileSets/v2.84/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v2.84/MbEditBoxDateTime.qml +++ b/FileSets/v2.84/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.84/MbSubMenu.qml b/FileSets/v2.84/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v2.84/MbSubMenu.qml +++ b/FileSets/v2.84/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.84/Multi.qml b/FileSets/v2.84/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v2.84/Multi.qml +++ b/FileSets/v2.84/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.84/OverviewBox.qml b/FileSets/v2.84/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v2.84/OverviewBox.qml +++ b/FileSets/v2.84/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.84/OverviewConnection.qml b/FileSets/v2.84/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v2.84/OverviewConnection.qml +++ b/FileSets/v2.84/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.84/OverviewConnectionEnd.qml b/FileSets/v2.84/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v2.84/OverviewConnectionEnd.qml +++ b/FileSets/v2.84/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.84/OverviewSolarCharger.qml b/FileSets/v2.84/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v2.84/OverviewSolarCharger.qml +++ b/FileSets/v2.84/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.84/OverviewTankDelegate.qml b/FileSets/v2.84/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v2.84/OverviewTankDelegate.qml +++ b/FileSets/v2.84/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.84/OverviewTanks.qml b/FileSets/v2.84/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v2.84/OverviewTanks.qml +++ b/FileSets/v2.84/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.84/TileText.qml b/FileSets/v2.84/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v2.84/TileText.qml +++ b/FileSets/v2.84/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.84/styles.css b/FileSets/v2.84/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v2.84/styles.css +++ b/FileSets/v2.84/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v2.85/MbEditBoxDateTime.qml b/FileSets/v2.85/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v2.85/MbEditBoxDateTime.qml +++ b/FileSets/v2.85/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.85/MbSubMenu.qml b/FileSets/v2.85/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v2.85/MbSubMenu.qml +++ b/FileSets/v2.85/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.85/Multi.qml b/FileSets/v2.85/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v2.85/Multi.qml +++ b/FileSets/v2.85/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.85/OverviewBox.qml b/FileSets/v2.85/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v2.85/OverviewBox.qml +++ b/FileSets/v2.85/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.85/OverviewConnection.qml b/FileSets/v2.85/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v2.85/OverviewConnection.qml +++ b/FileSets/v2.85/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.85/OverviewConnectionEnd.qml b/FileSets/v2.85/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v2.85/OverviewConnectionEnd.qml +++ b/FileSets/v2.85/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.85/OverviewSolarCharger.qml b/FileSets/v2.85/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v2.85/OverviewSolarCharger.qml +++ b/FileSets/v2.85/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.85/OverviewTankDelegate.qml b/FileSets/v2.85/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v2.85/OverviewTankDelegate.qml +++ b/FileSets/v2.85/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.85/OverviewTanks.qml b/FileSets/v2.85/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v2.85/OverviewTanks.qml +++ b/FileSets/v2.85/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.85/TileText.qml b/FileSets/v2.85/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v2.85/TileText.qml +++ b/FileSets/v2.85/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.85/styles.css b/FileSets/v2.85/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v2.85/styles.css +++ b/FileSets/v2.85/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v2.86/MbEditBoxDateTime.qml b/FileSets/v2.86/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v2.86/MbEditBoxDateTime.qml +++ b/FileSets/v2.86/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.86/MbSubMenu.qml b/FileSets/v2.86/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v2.86/MbSubMenu.qml +++ b/FileSets/v2.86/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.86/Multi.qml b/FileSets/v2.86/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v2.86/Multi.qml +++ b/FileSets/v2.86/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.86/OverviewBox.qml b/FileSets/v2.86/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v2.86/OverviewBox.qml +++ b/FileSets/v2.86/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.86/OverviewConnection.qml b/FileSets/v2.86/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v2.86/OverviewConnection.qml +++ b/FileSets/v2.86/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.86/OverviewConnectionEnd.qml b/FileSets/v2.86/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v2.86/OverviewConnectionEnd.qml +++ b/FileSets/v2.86/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.86/OverviewSolarCharger.qml b/FileSets/v2.86/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v2.86/OverviewSolarCharger.qml +++ b/FileSets/v2.86/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.86/OverviewTankDelegate.qml b/FileSets/v2.86/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v2.86/OverviewTankDelegate.qml +++ b/FileSets/v2.86/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.86/OverviewTanks.qml b/FileSets/v2.86/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v2.86/OverviewTanks.qml +++ b/FileSets/v2.86/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.86/TileText.qml b/FileSets/v2.86/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v2.86/TileText.qml +++ b/FileSets/v2.86/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.86/styles.css b/FileSets/v2.86/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v2.86/styles.css +++ b/FileSets/v2.86/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v2.87/MbEditBoxDateTime.qml b/FileSets/v2.87/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v2.87/MbEditBoxDateTime.qml +++ b/FileSets/v2.87/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.87/MbSubMenu.qml b/FileSets/v2.87/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v2.87/MbSubMenu.qml +++ b/FileSets/v2.87/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.87/Multi.qml b/FileSets/v2.87/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v2.87/Multi.qml +++ b/FileSets/v2.87/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.87/OverviewBox.qml b/FileSets/v2.87/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v2.87/OverviewBox.qml +++ b/FileSets/v2.87/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.87/OverviewConnection.qml b/FileSets/v2.87/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v2.87/OverviewConnection.qml +++ b/FileSets/v2.87/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.87/OverviewConnectionEnd.qml b/FileSets/v2.87/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v2.87/OverviewConnectionEnd.qml +++ b/FileSets/v2.87/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.87/OverviewSolarCharger.qml b/FileSets/v2.87/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v2.87/OverviewSolarCharger.qml +++ b/FileSets/v2.87/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.87/OverviewTankDelegate.qml b/FileSets/v2.87/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v2.87/OverviewTankDelegate.qml +++ b/FileSets/v2.87/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.87/OverviewTanks.qml b/FileSets/v2.87/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v2.87/OverviewTanks.qml +++ b/FileSets/v2.87/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.87/TileText.qml b/FileSets/v2.87/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v2.87/TileText.qml +++ b/FileSets/v2.87/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.87/styles.css b/FileSets/v2.87/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v2.87/styles.css +++ b/FileSets/v2.87/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v2.89/MbEditBoxDateTime.qml b/FileSets/v2.89/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v2.89/MbEditBoxDateTime.qml +++ b/FileSets/v2.89/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.89/MbSubMenu.qml b/FileSets/v2.89/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v2.89/MbSubMenu.qml +++ b/FileSets/v2.89/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.89/Multi.qml b/FileSets/v2.89/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v2.89/Multi.qml +++ b/FileSets/v2.89/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.89/OverviewBox.qml b/FileSets/v2.89/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v2.89/OverviewBox.qml +++ b/FileSets/v2.89/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.89/OverviewConnection.qml b/FileSets/v2.89/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v2.89/OverviewConnection.qml +++ b/FileSets/v2.89/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.89/OverviewConnectionEnd.qml b/FileSets/v2.89/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v2.89/OverviewConnectionEnd.qml +++ b/FileSets/v2.89/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.89/OverviewSolarCharger.qml b/FileSets/v2.89/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v2.89/OverviewSolarCharger.qml +++ b/FileSets/v2.89/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.89/OverviewTankDelegate.qml b/FileSets/v2.89/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v2.89/OverviewTankDelegate.qml +++ b/FileSets/v2.89/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.89/OverviewTanks.qml b/FileSets/v2.89/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v2.89/OverviewTanks.qml +++ b/FileSets/v2.89/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.89/TileText.qml b/FileSets/v2.89/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v2.89/TileText.qml +++ b/FileSets/v2.89/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.89/styles.css b/FileSets/v2.89/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v2.89/styles.css +++ b/FileSets/v2.89/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v2.90/MbEditBoxDateTime.qml b/FileSets/v2.90/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v2.90/MbEditBoxDateTime.qml +++ b/FileSets/v2.90/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.90/MbSpinBox.qml b/FileSets/v2.90/MbSpinBox.qml index 8390ce03..fca806a7 120000 --- a/FileSets/v2.90/MbSpinBox.qml +++ b/FileSets/v2.90/MbSpinBox.qml @@ -1 +1 @@ -../v3.40~10/MbSpinBox.qml \ No newline at end of file +../v3.40~11/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v2.90/MbSubMenu.qml b/FileSets/v2.90/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v2.90/MbSubMenu.qml +++ b/FileSets/v2.90/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.90/Multi.qml b/FileSets/v2.90/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v2.90/Multi.qml +++ b/FileSets/v2.90/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.90/OverviewBox.qml b/FileSets/v2.90/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v2.90/OverviewBox.qml +++ b/FileSets/v2.90/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.90/OverviewConnection.qml b/FileSets/v2.90/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v2.90/OverviewConnection.qml +++ b/FileSets/v2.90/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.90/OverviewConnectionEnd.qml b/FileSets/v2.90/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v2.90/OverviewConnectionEnd.qml +++ b/FileSets/v2.90/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.90/OverviewSolarCharger.qml b/FileSets/v2.90/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v2.90/OverviewSolarCharger.qml +++ b/FileSets/v2.90/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.90/OverviewTankDelegate.qml b/FileSets/v2.90/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v2.90/OverviewTankDelegate.qml +++ b/FileSets/v2.90/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.90/OverviewTanks.qml b/FileSets/v2.90/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v2.90/OverviewTanks.qml +++ b/FileSets/v2.90/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.90/TileText.qml b/FileSets/v2.90/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v2.90/TileText.qml +++ b/FileSets/v2.90/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.90/styles.css b/FileSets/v2.90/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v2.90/styles.css +++ b/FileSets/v2.90/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v2.91/MbEditBoxDateTime.qml b/FileSets/v2.91/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v2.91/MbEditBoxDateTime.qml +++ b/FileSets/v2.91/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.91/MbSpinBox.qml b/FileSets/v2.91/MbSpinBox.qml index 8390ce03..fca806a7 120000 --- a/FileSets/v2.91/MbSpinBox.qml +++ b/FileSets/v2.91/MbSpinBox.qml @@ -1 +1 @@ -../v3.40~10/MbSpinBox.qml \ No newline at end of file +../v3.40~11/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v2.91/MbSubMenu.qml b/FileSets/v2.91/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v2.91/MbSubMenu.qml +++ b/FileSets/v2.91/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.91/Multi.qml b/FileSets/v2.91/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v2.91/Multi.qml +++ b/FileSets/v2.91/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.91/OverviewBox.qml b/FileSets/v2.91/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v2.91/OverviewBox.qml +++ b/FileSets/v2.91/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.91/OverviewConnection.qml b/FileSets/v2.91/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v2.91/OverviewConnection.qml +++ b/FileSets/v2.91/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.91/OverviewConnectionEnd.qml b/FileSets/v2.91/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v2.91/OverviewConnectionEnd.qml +++ b/FileSets/v2.91/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.91/OverviewSolarCharger.qml b/FileSets/v2.91/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v2.91/OverviewSolarCharger.qml +++ b/FileSets/v2.91/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.91/OverviewTankDelegate.qml b/FileSets/v2.91/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v2.91/OverviewTankDelegate.qml +++ b/FileSets/v2.91/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.91/OverviewTanks.qml b/FileSets/v2.91/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v2.91/OverviewTanks.qml +++ b/FileSets/v2.91/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.91/TileText.qml b/FileSets/v2.91/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v2.91/TileText.qml +++ b/FileSets/v2.91/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.91/styles.css b/FileSets/v2.91/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v2.91/styles.css +++ b/FileSets/v2.91/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v2.92/MbEditBoxDateTime.qml b/FileSets/v2.92/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v2.92/MbEditBoxDateTime.qml +++ b/FileSets/v2.92/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.92/MbSpinBox.qml b/FileSets/v2.92/MbSpinBox.qml index 8390ce03..fca806a7 120000 --- a/FileSets/v2.92/MbSpinBox.qml +++ b/FileSets/v2.92/MbSpinBox.qml @@ -1 +1 @@ -../v3.40~10/MbSpinBox.qml \ No newline at end of file +../v3.40~11/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v2.92/MbSubMenu.qml b/FileSets/v2.92/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v2.92/MbSubMenu.qml +++ b/FileSets/v2.92/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.92/Multi.qml b/FileSets/v2.92/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v2.92/Multi.qml +++ b/FileSets/v2.92/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.92/OverviewBox.qml b/FileSets/v2.92/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v2.92/OverviewBox.qml +++ b/FileSets/v2.92/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.92/OverviewConnection.qml b/FileSets/v2.92/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v2.92/OverviewConnection.qml +++ b/FileSets/v2.92/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.92/OverviewConnectionEnd.qml b/FileSets/v2.92/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v2.92/OverviewConnectionEnd.qml +++ b/FileSets/v2.92/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.92/OverviewSolarCharger.qml b/FileSets/v2.92/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v2.92/OverviewSolarCharger.qml +++ b/FileSets/v2.92/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.92/OverviewTankDelegate.qml b/FileSets/v2.92/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v2.92/OverviewTankDelegate.qml +++ b/FileSets/v2.92/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.92/OverviewTanks.qml b/FileSets/v2.92/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v2.92/OverviewTanks.qml +++ b/FileSets/v2.92/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.92/TileText.qml b/FileSets/v2.92/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v2.92/TileText.qml +++ b/FileSets/v2.92/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.92/styles.css b/FileSets/v2.92/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v2.92/styles.css +++ b/FileSets/v2.92/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v2.93/MbEditBoxDateTime.qml b/FileSets/v2.93/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v2.93/MbEditBoxDateTime.qml +++ b/FileSets/v2.93/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.93/MbSpinBox.qml b/FileSets/v2.93/MbSpinBox.qml index 8390ce03..fca806a7 120000 --- a/FileSets/v2.93/MbSpinBox.qml +++ b/FileSets/v2.93/MbSpinBox.qml @@ -1 +1 @@ -../v3.40~10/MbSpinBox.qml \ No newline at end of file +../v3.40~11/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v2.93/MbSubMenu.qml b/FileSets/v2.93/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v2.93/MbSubMenu.qml +++ b/FileSets/v2.93/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.93/Multi.qml b/FileSets/v2.93/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v2.93/Multi.qml +++ b/FileSets/v2.93/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.93/OverviewBox.qml b/FileSets/v2.93/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v2.93/OverviewBox.qml +++ b/FileSets/v2.93/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.93/OverviewConnection.qml b/FileSets/v2.93/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v2.93/OverviewConnection.qml +++ b/FileSets/v2.93/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.93/OverviewConnectionEnd.qml b/FileSets/v2.93/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v2.93/OverviewConnectionEnd.qml +++ b/FileSets/v2.93/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.93/OverviewSolarCharger.qml b/FileSets/v2.93/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v2.93/OverviewSolarCharger.qml +++ b/FileSets/v2.93/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.93/OverviewTankDelegate.qml b/FileSets/v2.93/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v2.93/OverviewTankDelegate.qml +++ b/FileSets/v2.93/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.93/OverviewTanks.qml b/FileSets/v2.93/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v2.93/OverviewTanks.qml +++ b/FileSets/v2.93/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.93/TileText.qml b/FileSets/v2.93/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v2.93/TileText.qml +++ b/FileSets/v2.93/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.93/styles.css b/FileSets/v2.93/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v2.93/styles.css +++ b/FileSets/v2.93/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v2.94/MbEditBoxDateTime.qml b/FileSets/v2.94/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v2.94/MbEditBoxDateTime.qml +++ b/FileSets/v2.94/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v2.94/MbSpinBox.qml b/FileSets/v2.94/MbSpinBox.qml index 8390ce03..fca806a7 120000 --- a/FileSets/v2.94/MbSpinBox.qml +++ b/FileSets/v2.94/MbSpinBox.qml @@ -1 +1 @@ -../v3.40~10/MbSpinBox.qml \ No newline at end of file +../v3.40~11/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v2.94/MbSubMenu.qml b/FileSets/v2.94/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v2.94/MbSubMenu.qml +++ b/FileSets/v2.94/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v2.94/Multi.qml b/FileSets/v2.94/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v2.94/Multi.qml +++ b/FileSets/v2.94/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v2.94/OverviewBox.qml b/FileSets/v2.94/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v2.94/OverviewBox.qml +++ b/FileSets/v2.94/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v2.94/OverviewConnection.qml b/FileSets/v2.94/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v2.94/OverviewConnection.qml +++ b/FileSets/v2.94/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v2.94/OverviewConnectionEnd.qml b/FileSets/v2.94/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v2.94/OverviewConnectionEnd.qml +++ b/FileSets/v2.94/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v2.94/OverviewSolarCharger.qml b/FileSets/v2.94/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v2.94/OverviewSolarCharger.qml +++ b/FileSets/v2.94/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v2.94/OverviewTankDelegate.qml b/FileSets/v2.94/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v2.94/OverviewTankDelegate.qml +++ b/FileSets/v2.94/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v2.94/OverviewTanks.qml b/FileSets/v2.94/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v2.94/OverviewTanks.qml +++ b/FileSets/v2.94/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v2.94/TileText.qml b/FileSets/v2.94/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v2.94/TileText.qml +++ b/FileSets/v2.94/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v2.94/styles.css b/FileSets/v2.94/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v2.94/styles.css +++ b/FileSets/v2.94/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v3.00/MbEditBoxDateTime.qml b/FileSets/v3.00/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v3.00/MbEditBoxDateTime.qml +++ b/FileSets/v3.00/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.00/MbItem.qml b/FileSets/v3.00/MbItem.qml index 5e1bcc78..d1f5c0bb 120000 --- a/FileSets/v3.00/MbItem.qml +++ b/FileSets/v3.00/MbItem.qml @@ -1 +1 @@ -../v3.40~10/MbItem.qml \ No newline at end of file +../v3.40~11/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.00/MbItemDigitalInput.qml b/FileSets/v3.00/MbItemDigitalInput.qml index 68ec5c25..6be026f8 120000 --- a/FileSets/v3.00/MbItemDigitalInput.qml +++ b/FileSets/v3.00/MbItemDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/MbItemDigitalInput.qml \ No newline at end of file +../v3.40~11/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.00/MbSpinBox.qml b/FileSets/v3.00/MbSpinBox.qml index 8390ce03..fca806a7 120000 --- a/FileSets/v3.00/MbSpinBox.qml +++ b/FileSets/v3.00/MbSpinBox.qml @@ -1 +1 @@ -../v3.40~10/MbSpinBox.qml \ No newline at end of file +../v3.40~11/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.00/MbStyle.qml b/FileSets/v3.00/MbStyle.qml index 5d7cf621..17573562 120000 --- a/FileSets/v3.00/MbStyle.qml +++ b/FileSets/v3.00/MbStyle.qml @@ -1 +1 @@ -../v3.40~10/MbStyle.qml \ No newline at end of file +../v3.40~11/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.00/MbSubMenu.qml b/FileSets/v3.00/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v3.00/MbSubMenu.qml +++ b/FileSets/v3.00/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.00/Multi.qml b/FileSets/v3.00/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v3.00/Multi.qml +++ b/FileSets/v3.00/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewBox.qml b/FileSets/v3.00/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v3.00/OverviewBox.qml +++ b/FileSets/v3.00/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewConnection.qml b/FileSets/v3.00/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v3.00/OverviewConnection.qml +++ b/FileSets/v3.00/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewConnectionEnd.qml b/FileSets/v3.00/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v3.00/OverviewConnectionEnd.qml +++ b/FileSets/v3.00/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.00/OverviewGeneratorRelayEnhanced.qml index a65e18d8..e0bbd3df 120000 --- a/FileSets/v3.00/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.00/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewMobileEnhanced.qml b/FileSets/v3.00/OverviewMobileEnhanced.qml index d6107e91..46ae0c55 120000 --- a/FileSets/v3.00/OverviewMobileEnhanced.qml +++ b/FileSets/v3.00/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewSolarCharger.qml b/FileSets/v3.00/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v3.00/OverviewSolarCharger.qml +++ b/FileSets/v3.00/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewSolarInverter.qml b/FileSets/v3.00/OverviewSolarInverter.qml index c31a9074..61f0bff7 120000 --- a/FileSets/v3.00/OverviewSolarInverter.qml +++ b/FileSets/v3.00/OverviewSolarInverter.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarInverter.qml \ No newline at end of file +../v3.40~11/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewTankDelegate.qml b/FileSets/v3.00/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v3.00/OverviewTankDelegate.qml +++ b/FileSets/v3.00/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewTanks.qml b/FileSets/v3.00/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v3.00/OverviewTanks.qml +++ b/FileSets/v3.00/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.00/OverviewTanksTempsDigInputs.qml b/FileSets/v3.00/OverviewTanksTempsDigInputs.qml index 302fd03e..26dd2c44 120000 --- a/FileSets/v3.00/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.00/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40~11/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.00/Tile.qml b/FileSets/v3.00/Tile.qml index ac462f2e..5c566101 120000 --- a/FileSets/v3.00/Tile.qml +++ b/FileSets/v3.00/Tile.qml @@ -1 +1 @@ -../v3.40~10/Tile.qml \ No newline at end of file +../v3.40~11/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.00/TileRelay.qml b/FileSets/v3.00/TileRelay.qml index 7e3866d3..2ebdf179 120000 --- a/FileSets/v3.00/TileRelay.qml +++ b/FileSets/v3.00/TileRelay.qml @@ -1 +1 @@ -../v3.40~10/TileRelay.qml \ No newline at end of file +../v3.40~11/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.00/TileText.qml b/FileSets/v3.00/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v3.00/TileText.qml +++ b/FileSets/v3.00/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.00/styles.css b/FileSets/v3.00/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v3.00/styles.css +++ b/FileSets/v3.00/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v3.00~32/MbEditBoxDateTime.qml b/FileSets/v3.00~32/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v3.00~32/MbEditBoxDateTime.qml +++ b/FileSets/v3.00~32/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/MbItem.qml b/FileSets/v3.00~32/MbItem.qml index 5e1bcc78..d1f5c0bb 120000 --- a/FileSets/v3.00~32/MbItem.qml +++ b/FileSets/v3.00~32/MbItem.qml @@ -1 +1 @@ -../v3.40~10/MbItem.qml \ No newline at end of file +../v3.40~11/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/MbItemDigitalInput.qml b/FileSets/v3.00~32/MbItemDigitalInput.qml index 68ec5c25..6be026f8 120000 --- a/FileSets/v3.00~32/MbItemDigitalInput.qml +++ b/FileSets/v3.00~32/MbItemDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/MbItemDigitalInput.qml \ No newline at end of file +../v3.40~11/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/MbSpinBox.qml b/FileSets/v3.00~32/MbSpinBox.qml index 8390ce03..fca806a7 120000 --- a/FileSets/v3.00~32/MbSpinBox.qml +++ b/FileSets/v3.00~32/MbSpinBox.qml @@ -1 +1 @@ -../v3.40~10/MbSpinBox.qml \ No newline at end of file +../v3.40~11/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/MbStyle.qml b/FileSets/v3.00~32/MbStyle.qml index 5d7cf621..17573562 120000 --- a/FileSets/v3.00~32/MbStyle.qml +++ b/FileSets/v3.00~32/MbStyle.qml @@ -1 +1 @@ -../v3.40~10/MbStyle.qml \ No newline at end of file +../v3.40~11/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/MbSubMenu.qml b/FileSets/v3.00~32/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v3.00~32/MbSubMenu.qml +++ b/FileSets/v3.00~32/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/Multi.qml b/FileSets/v3.00~32/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v3.00~32/Multi.qml +++ b/FileSets/v3.00~32/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/OverviewBox.qml b/FileSets/v3.00~32/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v3.00~32/OverviewBox.qml +++ b/FileSets/v3.00~32/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/OverviewConnection.qml b/FileSets/v3.00~32/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v3.00~32/OverviewConnection.qml +++ b/FileSets/v3.00~32/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/OverviewConnectionEnd.qml b/FileSets/v3.00~32/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v3.00~32/OverviewConnectionEnd.qml +++ b/FileSets/v3.00~32/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/OverviewMobileEnhanced.qml b/FileSets/v3.00~32/OverviewMobileEnhanced.qml index d6107e91..46ae0c55 120000 --- a/FileSets/v3.00~32/OverviewMobileEnhanced.qml +++ b/FileSets/v3.00~32/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/OverviewSolarCharger.qml b/FileSets/v3.00~32/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v3.00~32/OverviewSolarCharger.qml +++ b/FileSets/v3.00~32/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/OverviewTankDelegate.qml b/FileSets/v3.00~32/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v3.00~32/OverviewTankDelegate.qml +++ b/FileSets/v3.00~32/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/OverviewTanks.qml b/FileSets/v3.00~32/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v3.00~32/OverviewTanks.qml +++ b/FileSets/v3.00~32/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/OverviewTanksTempsDigInputs.qml b/FileSets/v3.00~32/OverviewTanksTempsDigInputs.qml index 302fd03e..26dd2c44 120000 --- a/FileSets/v3.00~32/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.00~32/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40~11/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/Tile.qml b/FileSets/v3.00~32/Tile.qml index ac462f2e..5c566101 120000 --- a/FileSets/v3.00~32/Tile.qml +++ b/FileSets/v3.00~32/Tile.qml @@ -1 +1 @@ -../v3.40~10/Tile.qml \ No newline at end of file +../v3.40~11/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/TileRelay.qml b/FileSets/v3.00~32/TileRelay.qml index 7e3866d3..2ebdf179 120000 --- a/FileSets/v3.00~32/TileRelay.qml +++ b/FileSets/v3.00~32/TileRelay.qml @@ -1 +1 @@ -../v3.40~10/TileRelay.qml \ No newline at end of file +../v3.40~11/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/TileText.qml b/FileSets/v3.00~32/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v3.00~32/TileText.qml +++ b/FileSets/v3.00~32/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.00~32/styles.css b/FileSets/v3.00~32/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v3.00~32/styles.css +++ b/FileSets/v3.00~32/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v3.01/MbEditBoxDateTime.qml b/FileSets/v3.01/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v3.01/MbEditBoxDateTime.qml +++ b/FileSets/v3.01/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.01/MbItem.qml b/FileSets/v3.01/MbItem.qml index 5e1bcc78..d1f5c0bb 120000 --- a/FileSets/v3.01/MbItem.qml +++ b/FileSets/v3.01/MbItem.qml @@ -1 +1 @@ -../v3.40~10/MbItem.qml \ No newline at end of file +../v3.40~11/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.01/MbItemDigitalInput.qml b/FileSets/v3.01/MbItemDigitalInput.qml index 68ec5c25..6be026f8 120000 --- a/FileSets/v3.01/MbItemDigitalInput.qml +++ b/FileSets/v3.01/MbItemDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/MbItemDigitalInput.qml \ No newline at end of file +../v3.40~11/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.01/MbSpinBox.qml b/FileSets/v3.01/MbSpinBox.qml index 8390ce03..fca806a7 120000 --- a/FileSets/v3.01/MbSpinBox.qml +++ b/FileSets/v3.01/MbSpinBox.qml @@ -1 +1 @@ -../v3.40~10/MbSpinBox.qml \ No newline at end of file +../v3.40~11/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.01/MbStyle.qml b/FileSets/v3.01/MbStyle.qml index 5d7cf621..17573562 120000 --- a/FileSets/v3.01/MbStyle.qml +++ b/FileSets/v3.01/MbStyle.qml @@ -1 +1 @@ -../v3.40~10/MbStyle.qml \ No newline at end of file +../v3.40~11/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.01/MbSubMenu.qml b/FileSets/v3.01/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v3.01/MbSubMenu.qml +++ b/FileSets/v3.01/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.01/Multi.qml b/FileSets/v3.01/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v3.01/Multi.qml +++ b/FileSets/v3.01/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.01/OverviewBox.qml b/FileSets/v3.01/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v3.01/OverviewBox.qml +++ b/FileSets/v3.01/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.01/OverviewConnection.qml b/FileSets/v3.01/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v3.01/OverviewConnection.qml +++ b/FileSets/v3.01/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.01/OverviewConnectionEnd.qml b/FileSets/v3.01/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v3.01/OverviewConnectionEnd.qml +++ b/FileSets/v3.01/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.01/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.01/OverviewGeneratorRelayEnhanced.qml index a65e18d8..e0bbd3df 120000 --- a/FileSets/v3.01/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.01/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.01/OverviewMobileEnhanced.qml b/FileSets/v3.01/OverviewMobileEnhanced.qml index d6107e91..46ae0c55 120000 --- a/FileSets/v3.01/OverviewMobileEnhanced.qml +++ b/FileSets/v3.01/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.01/OverviewSolarCharger.qml b/FileSets/v3.01/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v3.01/OverviewSolarCharger.qml +++ b/FileSets/v3.01/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.01/OverviewSolarInverter.qml b/FileSets/v3.01/OverviewSolarInverter.qml index c31a9074..61f0bff7 120000 --- a/FileSets/v3.01/OverviewSolarInverter.qml +++ b/FileSets/v3.01/OverviewSolarInverter.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarInverter.qml \ No newline at end of file +../v3.40~11/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.01/OverviewTankDelegate.qml b/FileSets/v3.01/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v3.01/OverviewTankDelegate.qml +++ b/FileSets/v3.01/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.01/OverviewTanks.qml b/FileSets/v3.01/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v3.01/OverviewTanks.qml +++ b/FileSets/v3.01/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.01/OverviewTanksTempsDigInputs.qml b/FileSets/v3.01/OverviewTanksTempsDigInputs.qml index 302fd03e..26dd2c44 120000 --- a/FileSets/v3.01/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.01/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40~11/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.01/Tile.qml b/FileSets/v3.01/Tile.qml index ac462f2e..5c566101 120000 --- a/FileSets/v3.01/Tile.qml +++ b/FileSets/v3.01/Tile.qml @@ -1 +1 @@ -../v3.40~10/Tile.qml \ No newline at end of file +../v3.40~11/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.01/TileRelay.qml b/FileSets/v3.01/TileRelay.qml index 7e3866d3..2ebdf179 120000 --- a/FileSets/v3.01/TileRelay.qml +++ b/FileSets/v3.01/TileRelay.qml @@ -1 +1 @@ -../v3.40~10/TileRelay.qml \ No newline at end of file +../v3.40~11/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.01/TileText.qml b/FileSets/v3.01/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v3.01/TileText.qml +++ b/FileSets/v3.01/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.01/styles.css b/FileSets/v3.01/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v3.01/styles.css +++ b/FileSets/v3.01/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v3.10/Battery.qml b/FileSets/v3.10/Battery.qml index 1f99218e..8e76916a 120000 --- a/FileSets/v3.10/Battery.qml +++ b/FileSets/v3.10/Battery.qml @@ -1 +1 @@ -../v3.40~10/Battery.qml \ No newline at end of file +../v3.40~11/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.10/MbEditBoxDateTime.qml b/FileSets/v3.10/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v3.10/MbEditBoxDateTime.qml +++ b/FileSets/v3.10/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.10/MbItem.qml b/FileSets/v3.10/MbItem.qml index 5e1bcc78..d1f5c0bb 120000 --- a/FileSets/v3.10/MbItem.qml +++ b/FileSets/v3.10/MbItem.qml @@ -1 +1 @@ -../v3.40~10/MbItem.qml \ No newline at end of file +../v3.40~11/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.10/MbItemDigitalInput.qml b/FileSets/v3.10/MbItemDigitalInput.qml index 68ec5c25..6be026f8 120000 --- a/FileSets/v3.10/MbItemDigitalInput.qml +++ b/FileSets/v3.10/MbItemDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/MbItemDigitalInput.qml \ No newline at end of file +../v3.40~11/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.10/MbSpinBox.qml b/FileSets/v3.10/MbSpinBox.qml index 8390ce03..fca806a7 120000 --- a/FileSets/v3.10/MbSpinBox.qml +++ b/FileSets/v3.10/MbSpinBox.qml @@ -1 +1 @@ -../v3.40~10/MbSpinBox.qml \ No newline at end of file +../v3.40~11/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.10/MbStyle.qml b/FileSets/v3.10/MbStyle.qml index 5d7cf621..17573562 120000 --- a/FileSets/v3.10/MbStyle.qml +++ b/FileSets/v3.10/MbStyle.qml @@ -1 +1 @@ -../v3.40~10/MbStyle.qml \ No newline at end of file +../v3.40~11/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.10/MbSubMenu.qml b/FileSets/v3.10/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v3.10/MbSubMenu.qml +++ b/FileSets/v3.10/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.10/Multi.qml b/FileSets/v3.10/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v3.10/Multi.qml +++ b/FileSets/v3.10/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.10/ObjectAcConnection.qml b/FileSets/v3.10/ObjectAcConnection.qml index 7edd9db8..8d459a07 120000 --- a/FileSets/v3.10/ObjectAcConnection.qml +++ b/FileSets/v3.10/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~10/ObjectAcConnection.qml \ No newline at end of file +../v3.40~11/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.10/OverviewAcValuesEnhanced.qml b/FileSets/v3.10/OverviewAcValuesEnhanced.qml index fe5152b2..8e55e8dc 120000 --- a/FileSets/v3.10/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.10/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.10/OverviewBox.qml b/FileSets/v3.10/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v3.10/OverviewBox.qml +++ b/FileSets/v3.10/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.10/OverviewConnection.qml b/FileSets/v3.10/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v3.10/OverviewConnection.qml +++ b/FileSets/v3.10/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.10/OverviewConnectionEnd.qml b/FileSets/v3.10/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v3.10/OverviewConnectionEnd.qml +++ b/FileSets/v3.10/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.10/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.10/OverviewGeneratorRelayEnhanced.qml index a65e18d8..e0bbd3df 120000 --- a/FileSets/v3.10/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.10/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.10/OverviewMobileEnhanced.qml b/FileSets/v3.10/OverviewMobileEnhanced.qml index d6107e91..46ae0c55 120000 --- a/FileSets/v3.10/OverviewMobileEnhanced.qml +++ b/FileSets/v3.10/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.10/OverviewSolarCharger.qml b/FileSets/v3.10/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v3.10/OverviewSolarCharger.qml +++ b/FileSets/v3.10/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.10/OverviewSolarInverter.qml b/FileSets/v3.10/OverviewSolarInverter.qml index c31a9074..61f0bff7 120000 --- a/FileSets/v3.10/OverviewSolarInverter.qml +++ b/FileSets/v3.10/OverviewSolarInverter.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarInverter.qml \ No newline at end of file +../v3.40~11/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.10/OverviewTankDelegate.qml b/FileSets/v3.10/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v3.10/OverviewTankDelegate.qml +++ b/FileSets/v3.10/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.10/OverviewTanks.qml b/FileSets/v3.10/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v3.10/OverviewTanks.qml +++ b/FileSets/v3.10/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.10/OverviewTanksTempsDigInputs.qml b/FileSets/v3.10/OverviewTanksTempsDigInputs.qml index 302fd03e..26dd2c44 120000 --- a/FileSets/v3.10/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.10/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40~11/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.10/PageDigitalInput.qml b/FileSets/v3.10/PageDigitalInput.qml index f279fa05..a9b9e513 120000 --- a/FileSets/v3.10/PageDigitalInput.qml +++ b/FileSets/v3.10/PageDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/PageDigitalInput.qml \ No newline at end of file +../v3.40~11/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.10/Tile.qml b/FileSets/v3.10/Tile.qml index ac462f2e..5c566101 120000 --- a/FileSets/v3.10/Tile.qml +++ b/FileSets/v3.10/Tile.qml @@ -1 +1 @@ -../v3.40~10/Tile.qml \ No newline at end of file +../v3.40~11/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.10/TileDigIn.qml b/FileSets/v3.10/TileDigIn.qml index ff43ea83..fc269e05 120000 --- a/FileSets/v3.10/TileDigIn.qml +++ b/FileSets/v3.10/TileDigIn.qml @@ -1 +1 @@ -../v3.40~10/TileDigIn.qml \ No newline at end of file +../v3.40~11/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.10/TileRelay.qml b/FileSets/v3.10/TileRelay.qml index 7e3866d3..2ebdf179 120000 --- a/FileSets/v3.10/TileRelay.qml +++ b/FileSets/v3.10/TileRelay.qml @@ -1 +1 @@ -../v3.40~10/TileRelay.qml \ No newline at end of file +../v3.40~11/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.10/TileText.qml b/FileSets/v3.10/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v3.10/TileText.qml +++ b/FileSets/v3.10/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.10/dbus_digitalinputs.py b/FileSets/v3.10/dbus_digitalinputs.py index bdaa4e12..085682ce 120000 --- a/FileSets/v3.10/dbus_digitalinputs.py +++ b/FileSets/v3.10/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~10/dbus_digitalinputs.py \ No newline at end of file +../v3.40~11/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.10/styles.css b/FileSets/v3.10/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v3.10/styles.css +++ b/FileSets/v3.10/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v3.11/Battery.qml b/FileSets/v3.11/Battery.qml index 1f99218e..8e76916a 120000 --- a/FileSets/v3.11/Battery.qml +++ b/FileSets/v3.11/Battery.qml @@ -1 +1 @@ -../v3.40~10/Battery.qml \ No newline at end of file +../v3.40~11/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.11/MbEditBoxDateTime.qml b/FileSets/v3.11/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v3.11/MbEditBoxDateTime.qml +++ b/FileSets/v3.11/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.11/MbItem.qml b/FileSets/v3.11/MbItem.qml index 5e1bcc78..d1f5c0bb 120000 --- a/FileSets/v3.11/MbItem.qml +++ b/FileSets/v3.11/MbItem.qml @@ -1 +1 @@ -../v3.40~10/MbItem.qml \ No newline at end of file +../v3.40~11/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.11/MbItemDigitalInput.qml b/FileSets/v3.11/MbItemDigitalInput.qml index 68ec5c25..6be026f8 120000 --- a/FileSets/v3.11/MbItemDigitalInput.qml +++ b/FileSets/v3.11/MbItemDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/MbItemDigitalInput.qml \ No newline at end of file +../v3.40~11/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.11/MbSpinBox.qml b/FileSets/v3.11/MbSpinBox.qml index 8390ce03..fca806a7 120000 --- a/FileSets/v3.11/MbSpinBox.qml +++ b/FileSets/v3.11/MbSpinBox.qml @@ -1 +1 @@ -../v3.40~10/MbSpinBox.qml \ No newline at end of file +../v3.40~11/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.11/MbStyle.qml b/FileSets/v3.11/MbStyle.qml index 5d7cf621..17573562 120000 --- a/FileSets/v3.11/MbStyle.qml +++ b/FileSets/v3.11/MbStyle.qml @@ -1 +1 @@ -../v3.40~10/MbStyle.qml \ No newline at end of file +../v3.40~11/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.11/MbSubMenu.qml b/FileSets/v3.11/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v3.11/MbSubMenu.qml +++ b/FileSets/v3.11/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.11/Multi.qml b/FileSets/v3.11/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v3.11/Multi.qml +++ b/FileSets/v3.11/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.11/ObjectAcConnection.qml b/FileSets/v3.11/ObjectAcConnection.qml index 7edd9db8..8d459a07 120000 --- a/FileSets/v3.11/ObjectAcConnection.qml +++ b/FileSets/v3.11/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~10/ObjectAcConnection.qml \ No newline at end of file +../v3.40~11/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.11/OverviewAcValuesEnhanced.qml b/FileSets/v3.11/OverviewAcValuesEnhanced.qml index fe5152b2..8e55e8dc 120000 --- a/FileSets/v3.11/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.11/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.11/OverviewBox.qml b/FileSets/v3.11/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v3.11/OverviewBox.qml +++ b/FileSets/v3.11/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.11/OverviewConnection.qml b/FileSets/v3.11/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v3.11/OverviewConnection.qml +++ b/FileSets/v3.11/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.11/OverviewConnectionEnd.qml b/FileSets/v3.11/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v3.11/OverviewConnectionEnd.qml +++ b/FileSets/v3.11/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.11/OverviewGeneratorEnhanced.qml b/FileSets/v3.11/OverviewGeneratorEnhanced.qml index f0f8b29d..f118934b 120000 --- a/FileSets/v3.11/OverviewGeneratorEnhanced.qml +++ b/FileSets/v3.11/OverviewGeneratorEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.11/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.11/OverviewGeneratorRelayEnhanced.qml index a65e18d8..e0bbd3df 120000 --- a/FileSets/v3.11/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.11/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.11/OverviewMobileEnhanced.qml b/FileSets/v3.11/OverviewMobileEnhanced.qml index d6107e91..46ae0c55 120000 --- a/FileSets/v3.11/OverviewMobileEnhanced.qml +++ b/FileSets/v3.11/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.11/OverviewSolarCharger.qml b/FileSets/v3.11/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v3.11/OverviewSolarCharger.qml +++ b/FileSets/v3.11/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.11/OverviewSolarInverter.qml b/FileSets/v3.11/OverviewSolarInverter.qml index c31a9074..61f0bff7 120000 --- a/FileSets/v3.11/OverviewSolarInverter.qml +++ b/FileSets/v3.11/OverviewSolarInverter.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarInverter.qml \ No newline at end of file +../v3.40~11/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.11/OverviewTankDelegate.qml b/FileSets/v3.11/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v3.11/OverviewTankDelegate.qml +++ b/FileSets/v3.11/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.11/OverviewTanks.qml b/FileSets/v3.11/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v3.11/OverviewTanks.qml +++ b/FileSets/v3.11/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.11/OverviewTanksTempsDigInputs.qml b/FileSets/v3.11/OverviewTanksTempsDigInputs.qml index 302fd03e..26dd2c44 120000 --- a/FileSets/v3.11/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.11/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40~11/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.11/PageDigitalInput.qml b/FileSets/v3.11/PageDigitalInput.qml index f279fa05..a9b9e513 120000 --- a/FileSets/v3.11/PageDigitalInput.qml +++ b/FileSets/v3.11/PageDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/PageDigitalInput.qml \ No newline at end of file +../v3.40~11/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.11/PageGenerator.qml b/FileSets/v3.11/PageGenerator.qml index f99cb9de..7ecabc54 120000 --- a/FileSets/v3.11/PageGenerator.qml +++ b/FileSets/v3.11/PageGenerator.qml @@ -1 +1 @@ -../v3.40~10/PageGenerator.qml \ No newline at end of file +../v3.40~11/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.11/Tile.qml b/FileSets/v3.11/Tile.qml index ac462f2e..5c566101 120000 --- a/FileSets/v3.11/Tile.qml +++ b/FileSets/v3.11/Tile.qml @@ -1 +1 @@ -../v3.40~10/Tile.qml \ No newline at end of file +../v3.40~11/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.11/TileDigIn.qml b/FileSets/v3.11/TileDigIn.qml index ff43ea83..fc269e05 120000 --- a/FileSets/v3.11/TileDigIn.qml +++ b/FileSets/v3.11/TileDigIn.qml @@ -1 +1 @@ -../v3.40~10/TileDigIn.qml \ No newline at end of file +../v3.40~11/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.11/TileRelay.qml b/FileSets/v3.11/TileRelay.qml index 7e3866d3..2ebdf179 120000 --- a/FileSets/v3.11/TileRelay.qml +++ b/FileSets/v3.11/TileRelay.qml @@ -1 +1 @@ -../v3.40~10/TileRelay.qml \ No newline at end of file +../v3.40~11/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.11/TileText.qml b/FileSets/v3.11/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v3.11/TileText.qml +++ b/FileSets/v3.11/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.11/dbus_digitalinputs.py b/FileSets/v3.11/dbus_digitalinputs.py index bdaa4e12..085682ce 120000 --- a/FileSets/v3.11/dbus_digitalinputs.py +++ b/FileSets/v3.11/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~10/dbus_digitalinputs.py \ No newline at end of file +../v3.40~11/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.11/styles.css b/FileSets/v3.11/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v3.11/styles.css +++ b/FileSets/v3.11/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v3.12/Battery.qml b/FileSets/v3.12/Battery.qml index 1f99218e..8e76916a 120000 --- a/FileSets/v3.12/Battery.qml +++ b/FileSets/v3.12/Battery.qml @@ -1 +1 @@ -../v3.40~10/Battery.qml \ No newline at end of file +../v3.40~11/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.12/MbEditBoxDateTime.qml b/FileSets/v3.12/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v3.12/MbEditBoxDateTime.qml +++ b/FileSets/v3.12/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.12/MbItem.qml b/FileSets/v3.12/MbItem.qml index 5e1bcc78..d1f5c0bb 120000 --- a/FileSets/v3.12/MbItem.qml +++ b/FileSets/v3.12/MbItem.qml @@ -1 +1 @@ -../v3.40~10/MbItem.qml \ No newline at end of file +../v3.40~11/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.12/MbItemDigitalInput.qml b/FileSets/v3.12/MbItemDigitalInput.qml index 68ec5c25..6be026f8 120000 --- a/FileSets/v3.12/MbItemDigitalInput.qml +++ b/FileSets/v3.12/MbItemDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/MbItemDigitalInput.qml \ No newline at end of file +../v3.40~11/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.12/MbSpinBox.qml b/FileSets/v3.12/MbSpinBox.qml index 8390ce03..fca806a7 120000 --- a/FileSets/v3.12/MbSpinBox.qml +++ b/FileSets/v3.12/MbSpinBox.qml @@ -1 +1 @@ -../v3.40~10/MbSpinBox.qml \ No newline at end of file +../v3.40~11/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.12/MbStyle.qml b/FileSets/v3.12/MbStyle.qml index 5d7cf621..17573562 120000 --- a/FileSets/v3.12/MbStyle.qml +++ b/FileSets/v3.12/MbStyle.qml @@ -1 +1 @@ -../v3.40~10/MbStyle.qml \ No newline at end of file +../v3.40~11/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.12/MbSubMenu.qml b/FileSets/v3.12/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v3.12/MbSubMenu.qml +++ b/FileSets/v3.12/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.12/Multi.qml b/FileSets/v3.12/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v3.12/Multi.qml +++ b/FileSets/v3.12/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.12/ObjectAcConnection.qml b/FileSets/v3.12/ObjectAcConnection.qml index 7edd9db8..8d459a07 120000 --- a/FileSets/v3.12/ObjectAcConnection.qml +++ b/FileSets/v3.12/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~10/ObjectAcConnection.qml \ No newline at end of file +../v3.40~11/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.12/OverviewAcValuesEnhanced.qml b/FileSets/v3.12/OverviewAcValuesEnhanced.qml index fe5152b2..8e55e8dc 120000 --- a/FileSets/v3.12/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.12/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.12/OverviewBox.qml b/FileSets/v3.12/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v3.12/OverviewBox.qml +++ b/FileSets/v3.12/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.12/OverviewConnection.qml b/FileSets/v3.12/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v3.12/OverviewConnection.qml +++ b/FileSets/v3.12/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.12/OverviewConnectionEnd.qml b/FileSets/v3.12/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v3.12/OverviewConnectionEnd.qml +++ b/FileSets/v3.12/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.12/OverviewGeneratorEnhanced.qml b/FileSets/v3.12/OverviewGeneratorEnhanced.qml index f0f8b29d..f118934b 120000 --- a/FileSets/v3.12/OverviewGeneratorEnhanced.qml +++ b/FileSets/v3.12/OverviewGeneratorEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.12/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.12/OverviewGeneratorRelayEnhanced.qml index a65e18d8..e0bbd3df 120000 --- a/FileSets/v3.12/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.12/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.12/OverviewMobileEnhanced.qml b/FileSets/v3.12/OverviewMobileEnhanced.qml index d6107e91..46ae0c55 120000 --- a/FileSets/v3.12/OverviewMobileEnhanced.qml +++ b/FileSets/v3.12/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.12/OverviewSolarCharger.qml b/FileSets/v3.12/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v3.12/OverviewSolarCharger.qml +++ b/FileSets/v3.12/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.12/OverviewSolarInverter.qml b/FileSets/v3.12/OverviewSolarInverter.qml index c31a9074..61f0bff7 120000 --- a/FileSets/v3.12/OverviewSolarInverter.qml +++ b/FileSets/v3.12/OverviewSolarInverter.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarInverter.qml \ No newline at end of file +../v3.40~11/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.12/OverviewTankDelegate.qml b/FileSets/v3.12/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v3.12/OverviewTankDelegate.qml +++ b/FileSets/v3.12/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.12/OverviewTanks.qml b/FileSets/v3.12/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v3.12/OverviewTanks.qml +++ b/FileSets/v3.12/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.12/OverviewTanksTempsDigInputs.qml b/FileSets/v3.12/OverviewTanksTempsDigInputs.qml index 302fd03e..26dd2c44 120000 --- a/FileSets/v3.12/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.12/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40~11/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.12/PageDigitalInput.qml b/FileSets/v3.12/PageDigitalInput.qml index f279fa05..a9b9e513 120000 --- a/FileSets/v3.12/PageDigitalInput.qml +++ b/FileSets/v3.12/PageDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/PageDigitalInput.qml \ No newline at end of file +../v3.40~11/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.12/PageGenerator.qml b/FileSets/v3.12/PageGenerator.qml index f99cb9de..7ecabc54 120000 --- a/FileSets/v3.12/PageGenerator.qml +++ b/FileSets/v3.12/PageGenerator.qml @@ -1 +1 @@ -../v3.40~10/PageGenerator.qml \ No newline at end of file +../v3.40~11/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.12/Tile.qml b/FileSets/v3.12/Tile.qml index ac462f2e..5c566101 120000 --- a/FileSets/v3.12/Tile.qml +++ b/FileSets/v3.12/Tile.qml @@ -1 +1 @@ -../v3.40~10/Tile.qml \ No newline at end of file +../v3.40~11/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.12/TileDigIn.qml b/FileSets/v3.12/TileDigIn.qml index ff43ea83..fc269e05 120000 --- a/FileSets/v3.12/TileDigIn.qml +++ b/FileSets/v3.12/TileDigIn.qml @@ -1 +1 @@ -../v3.40~10/TileDigIn.qml \ No newline at end of file +../v3.40~11/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.12/TileRelay.qml b/FileSets/v3.12/TileRelay.qml index 7e3866d3..2ebdf179 120000 --- a/FileSets/v3.12/TileRelay.qml +++ b/FileSets/v3.12/TileRelay.qml @@ -1 +1 @@ -../v3.40~10/TileRelay.qml \ No newline at end of file +../v3.40~11/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.12/TileText.qml b/FileSets/v3.12/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v3.12/TileText.qml +++ b/FileSets/v3.12/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.12/dbus_digitalinputs.py b/FileSets/v3.12/dbus_digitalinputs.py index bdaa4e12..085682ce 120000 --- a/FileSets/v3.12/dbus_digitalinputs.py +++ b/FileSets/v3.12/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~10/dbus_digitalinputs.py \ No newline at end of file +../v3.40~11/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.12/styles.css b/FileSets/v3.12/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v3.12/styles.css +++ b/FileSets/v3.12/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v3.13/Battery.qml b/FileSets/v3.13/Battery.qml index 1f99218e..8e76916a 120000 --- a/FileSets/v3.13/Battery.qml +++ b/FileSets/v3.13/Battery.qml @@ -1 +1 @@ -../v3.40~10/Battery.qml \ No newline at end of file +../v3.40~11/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.13/MbEditBoxDateTime.qml b/FileSets/v3.13/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v3.13/MbEditBoxDateTime.qml +++ b/FileSets/v3.13/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.13/MbItem.qml b/FileSets/v3.13/MbItem.qml index 5e1bcc78..d1f5c0bb 120000 --- a/FileSets/v3.13/MbItem.qml +++ b/FileSets/v3.13/MbItem.qml @@ -1 +1 @@ -../v3.40~10/MbItem.qml \ No newline at end of file +../v3.40~11/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.13/MbItemDigitalInput.qml b/FileSets/v3.13/MbItemDigitalInput.qml index 68ec5c25..6be026f8 120000 --- a/FileSets/v3.13/MbItemDigitalInput.qml +++ b/FileSets/v3.13/MbItemDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/MbItemDigitalInput.qml \ No newline at end of file +../v3.40~11/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.13/MbSpinBox.qml b/FileSets/v3.13/MbSpinBox.qml index 8390ce03..fca806a7 120000 --- a/FileSets/v3.13/MbSpinBox.qml +++ b/FileSets/v3.13/MbSpinBox.qml @@ -1 +1 @@ -../v3.40~10/MbSpinBox.qml \ No newline at end of file +../v3.40~11/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.13/MbStyle.qml b/FileSets/v3.13/MbStyle.qml index 5d7cf621..17573562 120000 --- a/FileSets/v3.13/MbStyle.qml +++ b/FileSets/v3.13/MbStyle.qml @@ -1 +1 @@ -../v3.40~10/MbStyle.qml \ No newline at end of file +../v3.40~11/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.13/MbSubMenu.qml b/FileSets/v3.13/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v3.13/MbSubMenu.qml +++ b/FileSets/v3.13/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.13/Multi.qml b/FileSets/v3.13/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v3.13/Multi.qml +++ b/FileSets/v3.13/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.13/ObjectAcConnection.qml b/FileSets/v3.13/ObjectAcConnection.qml index 7edd9db8..8d459a07 120000 --- a/FileSets/v3.13/ObjectAcConnection.qml +++ b/FileSets/v3.13/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~10/ObjectAcConnection.qml \ No newline at end of file +../v3.40~11/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.13/OverviewAcValuesEnhanced.qml b/FileSets/v3.13/OverviewAcValuesEnhanced.qml index fe5152b2..8e55e8dc 120000 --- a/FileSets/v3.13/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.13/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.13/OverviewBox.qml b/FileSets/v3.13/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v3.13/OverviewBox.qml +++ b/FileSets/v3.13/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.13/OverviewConnection.qml b/FileSets/v3.13/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v3.13/OverviewConnection.qml +++ b/FileSets/v3.13/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.13/OverviewConnectionEnd.qml b/FileSets/v3.13/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v3.13/OverviewConnectionEnd.qml +++ b/FileSets/v3.13/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.13/OverviewGeneratorEnhanced.qml b/FileSets/v3.13/OverviewGeneratorEnhanced.qml index f0f8b29d..f118934b 120000 --- a/FileSets/v3.13/OverviewGeneratorEnhanced.qml +++ b/FileSets/v3.13/OverviewGeneratorEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.13/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.13/OverviewGeneratorRelayEnhanced.qml index a65e18d8..e0bbd3df 120000 --- a/FileSets/v3.13/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.13/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.13/OverviewMobileEnhanced.qml b/FileSets/v3.13/OverviewMobileEnhanced.qml index d6107e91..46ae0c55 120000 --- a/FileSets/v3.13/OverviewMobileEnhanced.qml +++ b/FileSets/v3.13/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.13/OverviewSolarCharger.qml b/FileSets/v3.13/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v3.13/OverviewSolarCharger.qml +++ b/FileSets/v3.13/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.13/OverviewSolarInverter.qml b/FileSets/v3.13/OverviewSolarInverter.qml index c31a9074..61f0bff7 120000 --- a/FileSets/v3.13/OverviewSolarInverter.qml +++ b/FileSets/v3.13/OverviewSolarInverter.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarInverter.qml \ No newline at end of file +../v3.40~11/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.13/OverviewTankDelegate.qml b/FileSets/v3.13/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v3.13/OverviewTankDelegate.qml +++ b/FileSets/v3.13/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.13/OverviewTanks.qml b/FileSets/v3.13/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v3.13/OverviewTanks.qml +++ b/FileSets/v3.13/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.13/OverviewTanksTempsDigInputs.qml b/FileSets/v3.13/OverviewTanksTempsDigInputs.qml index 302fd03e..26dd2c44 120000 --- a/FileSets/v3.13/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.13/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40~11/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.13/PageDigitalInput.qml b/FileSets/v3.13/PageDigitalInput.qml index f279fa05..a9b9e513 120000 --- a/FileSets/v3.13/PageDigitalInput.qml +++ b/FileSets/v3.13/PageDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/PageDigitalInput.qml \ No newline at end of file +../v3.40~11/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.13/PageGenerator.qml b/FileSets/v3.13/PageGenerator.qml index f99cb9de..7ecabc54 120000 --- a/FileSets/v3.13/PageGenerator.qml +++ b/FileSets/v3.13/PageGenerator.qml @@ -1 +1 @@ -../v3.40~10/PageGenerator.qml \ No newline at end of file +../v3.40~11/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.13/Tile.qml b/FileSets/v3.13/Tile.qml index ac462f2e..5c566101 120000 --- a/FileSets/v3.13/Tile.qml +++ b/FileSets/v3.13/Tile.qml @@ -1 +1 @@ -../v3.40~10/Tile.qml \ No newline at end of file +../v3.40~11/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.13/TileDigIn.qml b/FileSets/v3.13/TileDigIn.qml index ff43ea83..fc269e05 120000 --- a/FileSets/v3.13/TileDigIn.qml +++ b/FileSets/v3.13/TileDigIn.qml @@ -1 +1 @@ -../v3.40~10/TileDigIn.qml \ No newline at end of file +../v3.40~11/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.13/TileRelay.qml b/FileSets/v3.13/TileRelay.qml index 7e3866d3..2ebdf179 120000 --- a/FileSets/v3.13/TileRelay.qml +++ b/FileSets/v3.13/TileRelay.qml @@ -1 +1 @@ -../v3.40~10/TileRelay.qml \ No newline at end of file +../v3.40~11/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.13/TileText.qml b/FileSets/v3.13/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v3.13/TileText.qml +++ b/FileSets/v3.13/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.13/dbus_digitalinputs.py b/FileSets/v3.13/dbus_digitalinputs.py index bdaa4e12..085682ce 120000 --- a/FileSets/v3.13/dbus_digitalinputs.py +++ b/FileSets/v3.13/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~10/dbus_digitalinputs.py \ No newline at end of file +../v3.40~11/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.13/styles.css b/FileSets/v3.13/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v3.13/styles.css +++ b/FileSets/v3.13/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v3.14/Battery.qml b/FileSets/v3.14/Battery.qml index 1f99218e..8e76916a 120000 --- a/FileSets/v3.14/Battery.qml +++ b/FileSets/v3.14/Battery.qml @@ -1 +1 @@ -../v3.40~10/Battery.qml \ No newline at end of file +../v3.40~11/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.14/MbEditBoxDateTime.qml b/FileSets/v3.14/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v3.14/MbEditBoxDateTime.qml +++ b/FileSets/v3.14/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.14/MbItem.qml b/FileSets/v3.14/MbItem.qml index 5e1bcc78..d1f5c0bb 120000 --- a/FileSets/v3.14/MbItem.qml +++ b/FileSets/v3.14/MbItem.qml @@ -1 +1 @@ -../v3.40~10/MbItem.qml \ No newline at end of file +../v3.40~11/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.14/MbItemDigitalInput.qml b/FileSets/v3.14/MbItemDigitalInput.qml index 68ec5c25..6be026f8 120000 --- a/FileSets/v3.14/MbItemDigitalInput.qml +++ b/FileSets/v3.14/MbItemDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/MbItemDigitalInput.qml \ No newline at end of file +../v3.40~11/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.14/MbSpinBox.qml b/FileSets/v3.14/MbSpinBox.qml index 8390ce03..fca806a7 120000 --- a/FileSets/v3.14/MbSpinBox.qml +++ b/FileSets/v3.14/MbSpinBox.qml @@ -1 +1 @@ -../v3.40~10/MbSpinBox.qml \ No newline at end of file +../v3.40~11/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.14/MbStyle.qml b/FileSets/v3.14/MbStyle.qml index 5d7cf621..17573562 120000 --- a/FileSets/v3.14/MbStyle.qml +++ b/FileSets/v3.14/MbStyle.qml @@ -1 +1 @@ -../v3.40~10/MbStyle.qml \ No newline at end of file +../v3.40~11/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.14/MbSubMenu.qml b/FileSets/v3.14/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v3.14/MbSubMenu.qml +++ b/FileSets/v3.14/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.14/Multi.qml b/FileSets/v3.14/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v3.14/Multi.qml +++ b/FileSets/v3.14/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.14/ObjectAcConnection.qml b/FileSets/v3.14/ObjectAcConnection.qml index 7edd9db8..8d459a07 120000 --- a/FileSets/v3.14/ObjectAcConnection.qml +++ b/FileSets/v3.14/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~10/ObjectAcConnection.qml \ No newline at end of file +../v3.40~11/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.14/OverviewAcValuesEnhanced.qml b/FileSets/v3.14/OverviewAcValuesEnhanced.qml index fe5152b2..8e55e8dc 120000 --- a/FileSets/v3.14/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.14/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.14/OverviewBox.qml b/FileSets/v3.14/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v3.14/OverviewBox.qml +++ b/FileSets/v3.14/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.14/OverviewConnection.qml b/FileSets/v3.14/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v3.14/OverviewConnection.qml +++ b/FileSets/v3.14/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.14/OverviewConnectionEnd.qml b/FileSets/v3.14/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v3.14/OverviewConnectionEnd.qml +++ b/FileSets/v3.14/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.14/OverviewGeneratorEnhanced.qml b/FileSets/v3.14/OverviewGeneratorEnhanced.qml index f0f8b29d..f118934b 120000 --- a/FileSets/v3.14/OverviewGeneratorEnhanced.qml +++ b/FileSets/v3.14/OverviewGeneratorEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.14/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.14/OverviewGeneratorRelayEnhanced.qml index a65e18d8..e0bbd3df 120000 --- a/FileSets/v3.14/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.14/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.14/OverviewMobileEnhanced.qml b/FileSets/v3.14/OverviewMobileEnhanced.qml index d6107e91..46ae0c55 120000 --- a/FileSets/v3.14/OverviewMobileEnhanced.qml +++ b/FileSets/v3.14/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.14/OverviewSolarCharger.qml b/FileSets/v3.14/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v3.14/OverviewSolarCharger.qml +++ b/FileSets/v3.14/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.14/OverviewSolarInverter.qml b/FileSets/v3.14/OverviewSolarInverter.qml index c31a9074..61f0bff7 120000 --- a/FileSets/v3.14/OverviewSolarInverter.qml +++ b/FileSets/v3.14/OverviewSolarInverter.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarInverter.qml \ No newline at end of file +../v3.40~11/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.14/OverviewTankDelegate.qml b/FileSets/v3.14/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v3.14/OverviewTankDelegate.qml +++ b/FileSets/v3.14/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.14/OverviewTanks.qml b/FileSets/v3.14/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v3.14/OverviewTanks.qml +++ b/FileSets/v3.14/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.14/OverviewTanksTempsDigInputs.qml b/FileSets/v3.14/OverviewTanksTempsDigInputs.qml index 302fd03e..26dd2c44 120000 --- a/FileSets/v3.14/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.14/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40~11/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.14/PageDigitalInput.qml b/FileSets/v3.14/PageDigitalInput.qml index f279fa05..a9b9e513 120000 --- a/FileSets/v3.14/PageDigitalInput.qml +++ b/FileSets/v3.14/PageDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/PageDigitalInput.qml \ No newline at end of file +../v3.40~11/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.14/PageGenerator.qml b/FileSets/v3.14/PageGenerator.qml index f99cb9de..7ecabc54 120000 --- a/FileSets/v3.14/PageGenerator.qml +++ b/FileSets/v3.14/PageGenerator.qml @@ -1 +1 @@ -../v3.40~10/PageGenerator.qml \ No newline at end of file +../v3.40~11/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.14/Tile.qml b/FileSets/v3.14/Tile.qml index ac462f2e..5c566101 120000 --- a/FileSets/v3.14/Tile.qml +++ b/FileSets/v3.14/Tile.qml @@ -1 +1 @@ -../v3.40~10/Tile.qml \ No newline at end of file +../v3.40~11/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.14/TileDigIn.qml b/FileSets/v3.14/TileDigIn.qml index ff43ea83..fc269e05 120000 --- a/FileSets/v3.14/TileDigIn.qml +++ b/FileSets/v3.14/TileDigIn.qml @@ -1 +1 @@ -../v3.40~10/TileDigIn.qml \ No newline at end of file +../v3.40~11/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.14/TileRelay.qml b/FileSets/v3.14/TileRelay.qml index 7e3866d3..2ebdf179 120000 --- a/FileSets/v3.14/TileRelay.qml +++ b/FileSets/v3.14/TileRelay.qml @@ -1 +1 @@ -../v3.40~10/TileRelay.qml \ No newline at end of file +../v3.40~11/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.14/TileText.qml b/FileSets/v3.14/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v3.14/TileText.qml +++ b/FileSets/v3.14/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.14/dbus_digitalinputs.py b/FileSets/v3.14/dbus_digitalinputs.py index bdaa4e12..085682ce 120000 --- a/FileSets/v3.14/dbus_digitalinputs.py +++ b/FileSets/v3.14/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~10/dbus_digitalinputs.py \ No newline at end of file +../v3.40~11/dbus_digitalinputs.py \ No newline at end of file diff --git a/FileSets/v3.14/styles.css b/FileSets/v3.14/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v3.14/styles.css +++ b/FileSets/v3.14/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v3.20/Battery.qml b/FileSets/v3.20/Battery.qml index 1f99218e..8e76916a 120000 --- a/FileSets/v3.20/Battery.qml +++ b/FileSets/v3.20/Battery.qml @@ -1 +1 @@ -../v3.40~10/Battery.qml \ No newline at end of file +../v3.40~11/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.20/MbEditBoxDateTime.qml b/FileSets/v3.20/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v3.20/MbEditBoxDateTime.qml +++ b/FileSets/v3.20/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.20/MbItem.qml b/FileSets/v3.20/MbItem.qml index 5e1bcc78..d1f5c0bb 120000 --- a/FileSets/v3.20/MbItem.qml +++ b/FileSets/v3.20/MbItem.qml @@ -1 +1 @@ -../v3.40~10/MbItem.qml \ No newline at end of file +../v3.40~11/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.20/MbItemDigitalInput.qml b/FileSets/v3.20/MbItemDigitalInput.qml index 68ec5c25..6be026f8 120000 --- a/FileSets/v3.20/MbItemDigitalInput.qml +++ b/FileSets/v3.20/MbItemDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/MbItemDigitalInput.qml \ No newline at end of file +../v3.40~11/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.20/MbSpinBox.qml b/FileSets/v3.20/MbSpinBox.qml index 8390ce03..fca806a7 120000 --- a/FileSets/v3.20/MbSpinBox.qml +++ b/FileSets/v3.20/MbSpinBox.qml @@ -1 +1 @@ -../v3.40~10/MbSpinBox.qml \ No newline at end of file +../v3.40~11/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.20/MbStyle.qml b/FileSets/v3.20/MbStyle.qml index 5d7cf621..17573562 120000 --- a/FileSets/v3.20/MbStyle.qml +++ b/FileSets/v3.20/MbStyle.qml @@ -1 +1 @@ -../v3.40~10/MbStyle.qml \ No newline at end of file +../v3.40~11/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.20/MbSubMenu.qml b/FileSets/v3.20/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v3.20/MbSubMenu.qml +++ b/FileSets/v3.20/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.20/Multi.qml b/FileSets/v3.20/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v3.20/Multi.qml +++ b/FileSets/v3.20/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.20/ObjectAcConnection.qml b/FileSets/v3.20/ObjectAcConnection.qml index 7edd9db8..8d459a07 120000 --- a/FileSets/v3.20/ObjectAcConnection.qml +++ b/FileSets/v3.20/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~10/ObjectAcConnection.qml \ No newline at end of file +../v3.40~11/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.20/OverviewAcValuesEnhanced.qml b/FileSets/v3.20/OverviewAcValuesEnhanced.qml index fe5152b2..8e55e8dc 120000 --- a/FileSets/v3.20/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.20/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.20/OverviewBox.qml b/FileSets/v3.20/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v3.20/OverviewBox.qml +++ b/FileSets/v3.20/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.20/OverviewConnection.qml b/FileSets/v3.20/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v3.20/OverviewConnection.qml +++ b/FileSets/v3.20/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.20/OverviewConnectionEnd.qml b/FileSets/v3.20/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v3.20/OverviewConnectionEnd.qml +++ b/FileSets/v3.20/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.20/OverviewGeneratorEnhanced.qml b/FileSets/v3.20/OverviewGeneratorEnhanced.qml index f0f8b29d..f118934b 120000 --- a/FileSets/v3.20/OverviewGeneratorEnhanced.qml +++ b/FileSets/v3.20/OverviewGeneratorEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.20/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.20/OverviewGeneratorRelayEnhanced.qml index a65e18d8..e0bbd3df 120000 --- a/FileSets/v3.20/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.20/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.20/OverviewMobileEnhanced.qml b/FileSets/v3.20/OverviewMobileEnhanced.qml index d6107e91..46ae0c55 120000 --- a/FileSets/v3.20/OverviewMobileEnhanced.qml +++ b/FileSets/v3.20/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.20/OverviewSolarCharger.qml b/FileSets/v3.20/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v3.20/OverviewSolarCharger.qml +++ b/FileSets/v3.20/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.20/OverviewSolarInverter.qml b/FileSets/v3.20/OverviewSolarInverter.qml index c31a9074..61f0bff7 120000 --- a/FileSets/v3.20/OverviewSolarInverter.qml +++ b/FileSets/v3.20/OverviewSolarInverter.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarInverter.qml \ No newline at end of file +../v3.40~11/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.20/OverviewTankDelegate.qml b/FileSets/v3.20/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v3.20/OverviewTankDelegate.qml +++ b/FileSets/v3.20/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.20/OverviewTanks.qml b/FileSets/v3.20/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v3.20/OverviewTanks.qml +++ b/FileSets/v3.20/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.20/OverviewTanksTempsDigInputs.qml b/FileSets/v3.20/OverviewTanksTempsDigInputs.qml index 302fd03e..26dd2c44 120000 --- a/FileSets/v3.20/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.20/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40~11/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.20/PageDigitalInput.qml b/FileSets/v3.20/PageDigitalInput.qml index f279fa05..a9b9e513 120000 --- a/FileSets/v3.20/PageDigitalInput.qml +++ b/FileSets/v3.20/PageDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/PageDigitalInput.qml \ No newline at end of file +../v3.40~11/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.20/PageGenerator.qml b/FileSets/v3.20/PageGenerator.qml index f99cb9de..7ecabc54 120000 --- a/FileSets/v3.20/PageGenerator.qml +++ b/FileSets/v3.20/PageGenerator.qml @@ -1 +1 @@ -../v3.40~10/PageGenerator.qml \ No newline at end of file +../v3.40~11/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.20/PageSettingsGenerator.qml b/FileSets/v3.20/PageSettingsGenerator.qml index 23140671..efd8d051 120000 --- a/FileSets/v3.20/PageSettingsGenerator.qml +++ b/FileSets/v3.20/PageSettingsGenerator.qml @@ -1 +1 @@ -../v3.40~10/PageSettingsGenerator.qml \ No newline at end of file +../v3.40~11/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.20/Tile.qml b/FileSets/v3.20/Tile.qml index ac462f2e..5c566101 120000 --- a/FileSets/v3.20/Tile.qml +++ b/FileSets/v3.20/Tile.qml @@ -1 +1 @@ -../v3.40~10/Tile.qml \ No newline at end of file +../v3.40~11/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.20/TileDigIn.qml b/FileSets/v3.20/TileDigIn.qml index ff43ea83..fc269e05 120000 --- a/FileSets/v3.20/TileDigIn.qml +++ b/FileSets/v3.20/TileDigIn.qml @@ -1 +1 @@ -../v3.40~10/TileDigIn.qml \ No newline at end of file +../v3.40~11/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.20/TileRelay.qml b/FileSets/v3.20/TileRelay.qml index 7e3866d3..2ebdf179 120000 --- a/FileSets/v3.20/TileRelay.qml +++ b/FileSets/v3.20/TileRelay.qml @@ -1 +1 @@ -../v3.40~10/TileRelay.qml \ No newline at end of file +../v3.40~11/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.20/TileText.qml b/FileSets/v3.20/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v3.20/TileText.qml +++ b/FileSets/v3.20/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.20/dbus_digitalinputs.py b/FileSets/v3.20/dbus_digitalinputs.py index bdaa4e12..085682ce 120000 --- a/FileSets/v3.20/dbus_digitalinputs.py +++ b/FileSets/v3.20/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~10/dbus_digitalinputs.py \ No newline at end of file +../v3.40~11/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 12899ddc..699b4b49 120000 --- a/FileSets/v3.20/dbus_generator.py +++ b/FileSets/v3.20/dbus_generator.py @@ -1 +1 @@ -../v3.40~10/dbus_generator.py \ No newline at end of file +../v3.40~11/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.20/styles.css b/FileSets/v3.20/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v3.20/styles.css +++ b/FileSets/v3.20/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v3.21/Battery.qml b/FileSets/v3.21/Battery.qml index 1f99218e..8e76916a 120000 --- a/FileSets/v3.21/Battery.qml +++ b/FileSets/v3.21/Battery.qml @@ -1 +1 @@ -../v3.40~10/Battery.qml \ No newline at end of file +../v3.40~11/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.21/MbEditBoxDateTime.qml b/FileSets/v3.21/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v3.21/MbEditBoxDateTime.qml +++ b/FileSets/v3.21/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.21/MbItem.qml b/FileSets/v3.21/MbItem.qml index 5e1bcc78..d1f5c0bb 120000 --- a/FileSets/v3.21/MbItem.qml +++ b/FileSets/v3.21/MbItem.qml @@ -1 +1 @@ -../v3.40~10/MbItem.qml \ No newline at end of file +../v3.40~11/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.21/MbItemDigitalInput.qml b/FileSets/v3.21/MbItemDigitalInput.qml index 68ec5c25..6be026f8 120000 --- a/FileSets/v3.21/MbItemDigitalInput.qml +++ b/FileSets/v3.21/MbItemDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/MbItemDigitalInput.qml \ No newline at end of file +../v3.40~11/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.21/MbSpinBox.qml b/FileSets/v3.21/MbSpinBox.qml index 8390ce03..fca806a7 120000 --- a/FileSets/v3.21/MbSpinBox.qml +++ b/FileSets/v3.21/MbSpinBox.qml @@ -1 +1 @@ -../v3.40~10/MbSpinBox.qml \ No newline at end of file +../v3.40~11/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.21/MbStyle.qml b/FileSets/v3.21/MbStyle.qml index 5d7cf621..17573562 120000 --- a/FileSets/v3.21/MbStyle.qml +++ b/FileSets/v3.21/MbStyle.qml @@ -1 +1 @@ -../v3.40~10/MbStyle.qml \ No newline at end of file +../v3.40~11/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.21/MbSubMenu.qml b/FileSets/v3.21/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v3.21/MbSubMenu.qml +++ b/FileSets/v3.21/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.21/Multi.qml b/FileSets/v3.21/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v3.21/Multi.qml +++ b/FileSets/v3.21/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.21/ObjectAcConnection.qml b/FileSets/v3.21/ObjectAcConnection.qml index 7edd9db8..8d459a07 120000 --- a/FileSets/v3.21/ObjectAcConnection.qml +++ b/FileSets/v3.21/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~10/ObjectAcConnection.qml \ No newline at end of file +../v3.40~11/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.21/OverviewAcValuesEnhanced.qml b/FileSets/v3.21/OverviewAcValuesEnhanced.qml index fe5152b2..8e55e8dc 120000 --- a/FileSets/v3.21/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.21/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.21/OverviewBox.qml b/FileSets/v3.21/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v3.21/OverviewBox.qml +++ b/FileSets/v3.21/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.21/OverviewConnection.qml b/FileSets/v3.21/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v3.21/OverviewConnection.qml +++ b/FileSets/v3.21/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.21/OverviewConnectionEnd.qml b/FileSets/v3.21/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v3.21/OverviewConnectionEnd.qml +++ b/FileSets/v3.21/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.21/OverviewGeneratorEnhanced.qml b/FileSets/v3.21/OverviewGeneratorEnhanced.qml index f0f8b29d..f118934b 120000 --- a/FileSets/v3.21/OverviewGeneratorEnhanced.qml +++ b/FileSets/v3.21/OverviewGeneratorEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.21/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.21/OverviewGeneratorRelayEnhanced.qml index a65e18d8..e0bbd3df 120000 --- a/FileSets/v3.21/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.21/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.21/OverviewMobileEnhanced.qml b/FileSets/v3.21/OverviewMobileEnhanced.qml index d6107e91..46ae0c55 120000 --- a/FileSets/v3.21/OverviewMobileEnhanced.qml +++ b/FileSets/v3.21/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.21/OverviewSolarCharger.qml b/FileSets/v3.21/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v3.21/OverviewSolarCharger.qml +++ b/FileSets/v3.21/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.21/OverviewSolarInverter.qml b/FileSets/v3.21/OverviewSolarInverter.qml index c31a9074..61f0bff7 120000 --- a/FileSets/v3.21/OverviewSolarInverter.qml +++ b/FileSets/v3.21/OverviewSolarInverter.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarInverter.qml \ No newline at end of file +../v3.40~11/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.21/OverviewTankDelegate.qml b/FileSets/v3.21/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v3.21/OverviewTankDelegate.qml +++ b/FileSets/v3.21/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.21/OverviewTanks.qml b/FileSets/v3.21/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v3.21/OverviewTanks.qml +++ b/FileSets/v3.21/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.21/OverviewTanksTempsDigInputs.qml b/FileSets/v3.21/OverviewTanksTempsDigInputs.qml index 302fd03e..26dd2c44 120000 --- a/FileSets/v3.21/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.21/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40~11/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.21/PageDigitalInput.qml b/FileSets/v3.21/PageDigitalInput.qml index f279fa05..a9b9e513 120000 --- a/FileSets/v3.21/PageDigitalInput.qml +++ b/FileSets/v3.21/PageDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/PageDigitalInput.qml \ No newline at end of file +../v3.40~11/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.21/PageGenerator.qml b/FileSets/v3.21/PageGenerator.qml index f99cb9de..7ecabc54 120000 --- a/FileSets/v3.21/PageGenerator.qml +++ b/FileSets/v3.21/PageGenerator.qml @@ -1 +1 @@ -../v3.40~10/PageGenerator.qml \ No newline at end of file +../v3.40~11/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.21/PageSettingsGenerator.qml b/FileSets/v3.21/PageSettingsGenerator.qml index 23140671..efd8d051 120000 --- a/FileSets/v3.21/PageSettingsGenerator.qml +++ b/FileSets/v3.21/PageSettingsGenerator.qml @@ -1 +1 @@ -../v3.40~10/PageSettingsGenerator.qml \ No newline at end of file +../v3.40~11/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.21/Tile.qml b/FileSets/v3.21/Tile.qml index ac462f2e..5c566101 120000 --- a/FileSets/v3.21/Tile.qml +++ b/FileSets/v3.21/Tile.qml @@ -1 +1 @@ -../v3.40~10/Tile.qml \ No newline at end of file +../v3.40~11/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.21/TileDigIn.qml b/FileSets/v3.21/TileDigIn.qml index ff43ea83..fc269e05 120000 --- a/FileSets/v3.21/TileDigIn.qml +++ b/FileSets/v3.21/TileDigIn.qml @@ -1 +1 @@ -../v3.40~10/TileDigIn.qml \ No newline at end of file +../v3.40~11/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.21/TileRelay.qml b/FileSets/v3.21/TileRelay.qml index 7e3866d3..2ebdf179 120000 --- a/FileSets/v3.21/TileRelay.qml +++ b/FileSets/v3.21/TileRelay.qml @@ -1 +1 @@ -../v3.40~10/TileRelay.qml \ No newline at end of file +../v3.40~11/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.21/TileText.qml b/FileSets/v3.21/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v3.21/TileText.qml +++ b/FileSets/v3.21/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.21/dbus_digitalinputs.py b/FileSets/v3.21/dbus_digitalinputs.py index bdaa4e12..085682ce 120000 --- a/FileSets/v3.21/dbus_digitalinputs.py +++ b/FileSets/v3.21/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~10/dbus_digitalinputs.py \ No newline at end of file +../v3.40~11/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 12899ddc..699b4b49 120000 --- a/FileSets/v3.21/dbus_generator.py +++ b/FileSets/v3.21/dbus_generator.py @@ -1 +1 @@ -../v3.40~10/dbus_generator.py \ No newline at end of file +../v3.40~11/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.21/styles.css b/FileSets/v3.21/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v3.21/styles.css +++ b/FileSets/v3.21/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v3.22/Battery.qml b/FileSets/v3.22/Battery.qml index 1f99218e..8e76916a 120000 --- a/FileSets/v3.22/Battery.qml +++ b/FileSets/v3.22/Battery.qml @@ -1 +1 @@ -../v3.40~10/Battery.qml \ No newline at end of file +../v3.40~11/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.22/MbEditBoxDateTime.qml b/FileSets/v3.22/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v3.22/MbEditBoxDateTime.qml +++ b/FileSets/v3.22/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.22/MbItem.qml b/FileSets/v3.22/MbItem.qml index 5e1bcc78..d1f5c0bb 120000 --- a/FileSets/v3.22/MbItem.qml +++ b/FileSets/v3.22/MbItem.qml @@ -1 +1 @@ -../v3.40~10/MbItem.qml \ No newline at end of file +../v3.40~11/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.22/MbItemDigitalInput.qml b/FileSets/v3.22/MbItemDigitalInput.qml index 68ec5c25..6be026f8 120000 --- a/FileSets/v3.22/MbItemDigitalInput.qml +++ b/FileSets/v3.22/MbItemDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/MbItemDigitalInput.qml \ No newline at end of file +../v3.40~11/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.22/MbSpinBox.qml b/FileSets/v3.22/MbSpinBox.qml index 8390ce03..fca806a7 120000 --- a/FileSets/v3.22/MbSpinBox.qml +++ b/FileSets/v3.22/MbSpinBox.qml @@ -1 +1 @@ -../v3.40~10/MbSpinBox.qml \ No newline at end of file +../v3.40~11/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.22/MbStyle.qml b/FileSets/v3.22/MbStyle.qml index 5d7cf621..17573562 120000 --- a/FileSets/v3.22/MbStyle.qml +++ b/FileSets/v3.22/MbStyle.qml @@ -1 +1 @@ -../v3.40~10/MbStyle.qml \ No newline at end of file +../v3.40~11/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.22/MbSubMenu.qml b/FileSets/v3.22/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v3.22/MbSubMenu.qml +++ b/FileSets/v3.22/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.22/Multi.qml b/FileSets/v3.22/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v3.22/Multi.qml +++ b/FileSets/v3.22/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.22/ObjectAcConnection.qml b/FileSets/v3.22/ObjectAcConnection.qml index 7edd9db8..8d459a07 120000 --- a/FileSets/v3.22/ObjectAcConnection.qml +++ b/FileSets/v3.22/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~10/ObjectAcConnection.qml \ No newline at end of file +../v3.40~11/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.22/OverviewAcValuesEnhanced.qml b/FileSets/v3.22/OverviewAcValuesEnhanced.qml index fe5152b2..8e55e8dc 120000 --- a/FileSets/v3.22/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.22/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.22/OverviewBox.qml b/FileSets/v3.22/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v3.22/OverviewBox.qml +++ b/FileSets/v3.22/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.22/OverviewConnection.qml b/FileSets/v3.22/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v3.22/OverviewConnection.qml +++ b/FileSets/v3.22/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.22/OverviewConnectionEnd.qml b/FileSets/v3.22/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v3.22/OverviewConnectionEnd.qml +++ b/FileSets/v3.22/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.22/OverviewGeneratorEnhanced.qml b/FileSets/v3.22/OverviewGeneratorEnhanced.qml index f0f8b29d..f118934b 120000 --- a/FileSets/v3.22/OverviewGeneratorEnhanced.qml +++ b/FileSets/v3.22/OverviewGeneratorEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.22/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.22/OverviewGeneratorRelayEnhanced.qml index a65e18d8..e0bbd3df 120000 --- a/FileSets/v3.22/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.22/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.22/OverviewMobileEnhanced.qml b/FileSets/v3.22/OverviewMobileEnhanced.qml index d6107e91..46ae0c55 120000 --- a/FileSets/v3.22/OverviewMobileEnhanced.qml +++ b/FileSets/v3.22/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.22/OverviewSolarCharger.qml b/FileSets/v3.22/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v3.22/OverviewSolarCharger.qml +++ b/FileSets/v3.22/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.22/OverviewSolarInverter.qml b/FileSets/v3.22/OverviewSolarInverter.qml index c31a9074..61f0bff7 120000 --- a/FileSets/v3.22/OverviewSolarInverter.qml +++ b/FileSets/v3.22/OverviewSolarInverter.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarInverter.qml \ No newline at end of file +../v3.40~11/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.22/OverviewTankDelegate.qml b/FileSets/v3.22/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v3.22/OverviewTankDelegate.qml +++ b/FileSets/v3.22/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.22/OverviewTanks.qml b/FileSets/v3.22/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v3.22/OverviewTanks.qml +++ b/FileSets/v3.22/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.22/OverviewTanksTempsDigInputs.qml b/FileSets/v3.22/OverviewTanksTempsDigInputs.qml index 302fd03e..26dd2c44 120000 --- a/FileSets/v3.22/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.22/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40~11/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.22/PageDigitalInput.qml b/FileSets/v3.22/PageDigitalInput.qml index f279fa05..a9b9e513 120000 --- a/FileSets/v3.22/PageDigitalInput.qml +++ b/FileSets/v3.22/PageDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/PageDigitalInput.qml \ No newline at end of file +../v3.40~11/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.22/PageGenerator.qml b/FileSets/v3.22/PageGenerator.qml index f99cb9de..7ecabc54 120000 --- a/FileSets/v3.22/PageGenerator.qml +++ b/FileSets/v3.22/PageGenerator.qml @@ -1 +1 @@ -../v3.40~10/PageGenerator.qml \ No newline at end of file +../v3.40~11/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.22/PageSettingsGenerator.qml b/FileSets/v3.22/PageSettingsGenerator.qml index 23140671..efd8d051 120000 --- a/FileSets/v3.22/PageSettingsGenerator.qml +++ b/FileSets/v3.22/PageSettingsGenerator.qml @@ -1 +1 @@ -../v3.40~10/PageSettingsGenerator.qml \ No newline at end of file +../v3.40~11/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.22/Tile.qml b/FileSets/v3.22/Tile.qml index ac462f2e..5c566101 120000 --- a/FileSets/v3.22/Tile.qml +++ b/FileSets/v3.22/Tile.qml @@ -1 +1 @@ -../v3.40~10/Tile.qml \ No newline at end of file +../v3.40~11/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.22/TileDigIn.qml b/FileSets/v3.22/TileDigIn.qml index ff43ea83..fc269e05 120000 --- a/FileSets/v3.22/TileDigIn.qml +++ b/FileSets/v3.22/TileDigIn.qml @@ -1 +1 @@ -../v3.40~10/TileDigIn.qml \ No newline at end of file +../v3.40~11/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.22/TileRelay.qml b/FileSets/v3.22/TileRelay.qml index 7e3866d3..2ebdf179 120000 --- a/FileSets/v3.22/TileRelay.qml +++ b/FileSets/v3.22/TileRelay.qml @@ -1 +1 @@ -../v3.40~10/TileRelay.qml \ No newline at end of file +../v3.40~11/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.22/TileText.qml b/FileSets/v3.22/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v3.22/TileText.qml +++ b/FileSets/v3.22/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.22/dbus_digitalinputs.py b/FileSets/v3.22/dbus_digitalinputs.py index bdaa4e12..085682ce 120000 --- a/FileSets/v3.22/dbus_digitalinputs.py +++ b/FileSets/v3.22/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~10/dbus_digitalinputs.py \ No newline at end of file +../v3.40~11/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 12899ddc..699b4b49 120000 --- a/FileSets/v3.22/dbus_generator.py +++ b/FileSets/v3.22/dbus_generator.py @@ -1 +1 @@ -../v3.40~10/dbus_generator.py \ No newline at end of file +../v3.40~11/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.22/styles.css b/FileSets/v3.22/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v3.22/styles.css +++ b/FileSets/v3.22/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v3.30/Battery.qml b/FileSets/v3.30/Battery.qml index 1f99218e..8e76916a 120000 --- a/FileSets/v3.30/Battery.qml +++ b/FileSets/v3.30/Battery.qml @@ -1 +1 @@ -../v3.40~10/Battery.qml \ No newline at end of file +../v3.40~11/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.30/MbEditBoxDateTime.qml b/FileSets/v3.30/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v3.30/MbEditBoxDateTime.qml +++ b/FileSets/v3.30/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.30/MbItem.qml b/FileSets/v3.30/MbItem.qml index 5e1bcc78..d1f5c0bb 120000 --- a/FileSets/v3.30/MbItem.qml +++ b/FileSets/v3.30/MbItem.qml @@ -1 +1 @@ -../v3.40~10/MbItem.qml \ No newline at end of file +../v3.40~11/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.30/MbItemDigitalInput.qml b/FileSets/v3.30/MbItemDigitalInput.qml index 68ec5c25..6be026f8 120000 --- a/FileSets/v3.30/MbItemDigitalInput.qml +++ b/FileSets/v3.30/MbItemDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/MbItemDigitalInput.qml \ No newline at end of file +../v3.40~11/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.30/MbSpinBox.qml b/FileSets/v3.30/MbSpinBox.qml index 8390ce03..fca806a7 120000 --- a/FileSets/v3.30/MbSpinBox.qml +++ b/FileSets/v3.30/MbSpinBox.qml @@ -1 +1 @@ -../v3.40~10/MbSpinBox.qml \ No newline at end of file +../v3.40~11/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.30/MbStyle.qml b/FileSets/v3.30/MbStyle.qml index 5d7cf621..17573562 120000 --- a/FileSets/v3.30/MbStyle.qml +++ b/FileSets/v3.30/MbStyle.qml @@ -1 +1 @@ -../v3.40~10/MbStyle.qml \ No newline at end of file +../v3.40~11/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.30/MbSubMenu.qml b/FileSets/v3.30/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v3.30/MbSubMenu.qml +++ b/FileSets/v3.30/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.30/Multi.qml b/FileSets/v3.30/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v3.30/Multi.qml +++ b/FileSets/v3.30/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.30/ObjectAcConnection.qml b/FileSets/v3.30/ObjectAcConnection.qml index 7edd9db8..8d459a07 120000 --- a/FileSets/v3.30/ObjectAcConnection.qml +++ b/FileSets/v3.30/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~10/ObjectAcConnection.qml \ No newline at end of file +../v3.40~11/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.30/OverviewAcValuesEnhanced.qml b/FileSets/v3.30/OverviewAcValuesEnhanced.qml index fe5152b2..8e55e8dc 120000 --- a/FileSets/v3.30/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.30/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.30/OverviewBox.qml b/FileSets/v3.30/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v3.30/OverviewBox.qml +++ b/FileSets/v3.30/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.30/OverviewConnection.qml b/FileSets/v3.30/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v3.30/OverviewConnection.qml +++ b/FileSets/v3.30/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.30/OverviewConnectionEnd.qml b/FileSets/v3.30/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v3.30/OverviewConnectionEnd.qml +++ b/FileSets/v3.30/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.30/OverviewGeneratorEnhanced.qml b/FileSets/v3.30/OverviewGeneratorEnhanced.qml index f0f8b29d..f118934b 120000 --- a/FileSets/v3.30/OverviewGeneratorEnhanced.qml +++ b/FileSets/v3.30/OverviewGeneratorEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.30/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.30/OverviewGeneratorRelayEnhanced.qml index a65e18d8..e0bbd3df 120000 --- a/FileSets/v3.30/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.30/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.30/OverviewMobileEnhanced.qml b/FileSets/v3.30/OverviewMobileEnhanced.qml index d6107e91..46ae0c55 120000 --- a/FileSets/v3.30/OverviewMobileEnhanced.qml +++ b/FileSets/v3.30/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.30/OverviewSolarCharger.qml b/FileSets/v3.30/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v3.30/OverviewSolarCharger.qml +++ b/FileSets/v3.30/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.30/OverviewSolarInverter.qml b/FileSets/v3.30/OverviewSolarInverter.qml index c31a9074..61f0bff7 120000 --- a/FileSets/v3.30/OverviewSolarInverter.qml +++ b/FileSets/v3.30/OverviewSolarInverter.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarInverter.qml \ No newline at end of file +../v3.40~11/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.30/OverviewTankDelegate.qml b/FileSets/v3.30/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v3.30/OverviewTankDelegate.qml +++ b/FileSets/v3.30/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.30/OverviewTanks.qml b/FileSets/v3.30/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v3.30/OverviewTanks.qml +++ b/FileSets/v3.30/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.30/OverviewTanksTempsDigInputs.qml b/FileSets/v3.30/OverviewTanksTempsDigInputs.qml index 302fd03e..26dd2c44 120000 --- a/FileSets/v3.30/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.30/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40~11/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.30/PageDigitalInput.qml b/FileSets/v3.30/PageDigitalInput.qml index f279fa05..a9b9e513 120000 --- a/FileSets/v3.30/PageDigitalInput.qml +++ b/FileSets/v3.30/PageDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/PageDigitalInput.qml \ No newline at end of file +../v3.40~11/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.30/PageGenerator.qml b/FileSets/v3.30/PageGenerator.qml index f99cb9de..7ecabc54 120000 --- a/FileSets/v3.30/PageGenerator.qml +++ b/FileSets/v3.30/PageGenerator.qml @@ -1 +1 @@ -../v3.40~10/PageGenerator.qml \ No newline at end of file +../v3.40~11/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.30/PageMain.qml b/FileSets/v3.30/PageMain.qml index a7aac8b7..0e32fc35 120000 --- a/FileSets/v3.30/PageMain.qml +++ b/FileSets/v3.30/PageMain.qml @@ -1 +1 @@ -../v3.40~10/PageMain.qml \ No newline at end of file +../v3.40~11/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.30/PageSettingsGenerator.qml b/FileSets/v3.30/PageSettingsGenerator.qml index 23140671..efd8d051 120000 --- a/FileSets/v3.30/PageSettingsGenerator.qml +++ b/FileSets/v3.30/PageSettingsGenerator.qml @@ -1 +1 @@ -../v3.40~10/PageSettingsGenerator.qml \ No newline at end of file +../v3.40~11/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.30/PageSettingsGuiMods.qml b/FileSets/v3.30/PageSettingsGuiMods.qml index 0e85c757..50a2393d 120000 --- a/FileSets/v3.30/PageSettingsGuiMods.qml +++ b/FileSets/v3.30/PageSettingsGuiMods.qml @@ -1 +1 @@ -../v3.40~10/PageSettingsGuiMods.qml \ No newline at end of file +../v3.40~11/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.30/PageSettingsRelay.qml b/FileSets/v3.30/PageSettingsRelay.qml index 72de1197..337482f3 120000 --- a/FileSets/v3.30/PageSettingsRelay.qml +++ b/FileSets/v3.30/PageSettingsRelay.qml @@ -1 +1 @@ -../v3.40~10/PageSettingsRelay.qml \ No newline at end of file +../v3.40~11/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.30/Tile.qml b/FileSets/v3.30/Tile.qml index ac462f2e..5c566101 120000 --- a/FileSets/v3.30/Tile.qml +++ b/FileSets/v3.30/Tile.qml @@ -1 +1 @@ -../v3.40~10/Tile.qml \ No newline at end of file +../v3.40~11/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.30/TileDigIn.qml b/FileSets/v3.30/TileDigIn.qml index ff43ea83..fc269e05 120000 --- a/FileSets/v3.30/TileDigIn.qml +++ b/FileSets/v3.30/TileDigIn.qml @@ -1 +1 @@ -../v3.40~10/TileDigIn.qml \ No newline at end of file +../v3.40~11/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.30/TileRelay.qml b/FileSets/v3.30/TileRelay.qml index 7e3866d3..2ebdf179 120000 --- a/FileSets/v3.30/TileRelay.qml +++ b/FileSets/v3.30/TileRelay.qml @@ -1 +1 @@ -../v3.40~10/TileRelay.qml \ No newline at end of file +../v3.40~11/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.30/TileText.qml b/FileSets/v3.30/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v3.30/TileText.qml +++ b/FileSets/v3.30/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.30/dbus_digitalinputs.py b/FileSets/v3.30/dbus_digitalinputs.py index bdaa4e12..085682ce 120000 --- a/FileSets/v3.30/dbus_digitalinputs.py +++ b/FileSets/v3.30/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~10/dbus_digitalinputs.py \ No newline at end of file +../v3.40~11/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 12899ddc..699b4b49 120000 --- a/FileSets/v3.30/dbus_generator.py +++ b/FileSets/v3.30/dbus_generator.py @@ -1 +1 @@ -../v3.40~10/dbus_generator.py \ No newline at end of file +../v3.40~11/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.30/main.qml b/FileSets/v3.30/main.qml index 749f83e6..223531e7 120000 --- a/FileSets/v3.30/main.qml +++ b/FileSets/v3.30/main.qml @@ -1 +1 @@ -../v3.40~10/main.qml \ No newline at end of file +../v3.40~11/main.qml \ No newline at end of file diff --git a/FileSets/v3.30/styles.css b/FileSets/v3.30/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v3.30/styles.css +++ b/FileSets/v3.30/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v3.31/Battery.qml b/FileSets/v3.31/Battery.qml index 1f99218e..8e76916a 120000 --- a/FileSets/v3.31/Battery.qml +++ b/FileSets/v3.31/Battery.qml @@ -1 +1 @@ -../v3.40~10/Battery.qml \ No newline at end of file +../v3.40~11/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.31/MbEditBoxDateTime.qml b/FileSets/v3.31/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v3.31/MbEditBoxDateTime.qml +++ b/FileSets/v3.31/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.31/MbItem.qml b/FileSets/v3.31/MbItem.qml index 5e1bcc78..d1f5c0bb 120000 --- a/FileSets/v3.31/MbItem.qml +++ b/FileSets/v3.31/MbItem.qml @@ -1 +1 @@ -../v3.40~10/MbItem.qml \ No newline at end of file +../v3.40~11/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.31/MbItemDigitalInput.qml b/FileSets/v3.31/MbItemDigitalInput.qml index 68ec5c25..6be026f8 120000 --- a/FileSets/v3.31/MbItemDigitalInput.qml +++ b/FileSets/v3.31/MbItemDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/MbItemDigitalInput.qml \ No newline at end of file +../v3.40~11/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.31/MbSpinBox.qml b/FileSets/v3.31/MbSpinBox.qml index 8390ce03..fca806a7 120000 --- a/FileSets/v3.31/MbSpinBox.qml +++ b/FileSets/v3.31/MbSpinBox.qml @@ -1 +1 @@ -../v3.40~10/MbSpinBox.qml \ No newline at end of file +../v3.40~11/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.31/MbStyle.qml b/FileSets/v3.31/MbStyle.qml index 5d7cf621..17573562 120000 --- a/FileSets/v3.31/MbStyle.qml +++ b/FileSets/v3.31/MbStyle.qml @@ -1 +1 @@ -../v3.40~10/MbStyle.qml \ No newline at end of file +../v3.40~11/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.31/MbSubMenu.qml b/FileSets/v3.31/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v3.31/MbSubMenu.qml +++ b/FileSets/v3.31/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.31/Multi.qml b/FileSets/v3.31/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v3.31/Multi.qml +++ b/FileSets/v3.31/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.31/ObjectAcConnection.qml b/FileSets/v3.31/ObjectAcConnection.qml index 7edd9db8..8d459a07 120000 --- a/FileSets/v3.31/ObjectAcConnection.qml +++ b/FileSets/v3.31/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~10/ObjectAcConnection.qml \ No newline at end of file +../v3.40~11/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.31/OverviewAcValuesEnhanced.qml b/FileSets/v3.31/OverviewAcValuesEnhanced.qml index fe5152b2..8e55e8dc 120000 --- a/FileSets/v3.31/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.31/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.31/OverviewBox.qml b/FileSets/v3.31/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v3.31/OverviewBox.qml +++ b/FileSets/v3.31/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.31/OverviewConnection.qml b/FileSets/v3.31/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v3.31/OverviewConnection.qml +++ b/FileSets/v3.31/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.31/OverviewConnectionEnd.qml b/FileSets/v3.31/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v3.31/OverviewConnectionEnd.qml +++ b/FileSets/v3.31/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.31/OverviewGeneratorEnhanced.qml b/FileSets/v3.31/OverviewGeneratorEnhanced.qml index f0f8b29d..f118934b 120000 --- a/FileSets/v3.31/OverviewGeneratorEnhanced.qml +++ b/FileSets/v3.31/OverviewGeneratorEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.31/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.31/OverviewGeneratorRelayEnhanced.qml index a65e18d8..e0bbd3df 120000 --- a/FileSets/v3.31/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.31/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.31/OverviewMobileEnhanced.qml b/FileSets/v3.31/OverviewMobileEnhanced.qml index d6107e91..46ae0c55 120000 --- a/FileSets/v3.31/OverviewMobileEnhanced.qml +++ b/FileSets/v3.31/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.31/OverviewSolarCharger.qml b/FileSets/v3.31/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v3.31/OverviewSolarCharger.qml +++ b/FileSets/v3.31/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.31/OverviewSolarInverter.qml b/FileSets/v3.31/OverviewSolarInverter.qml index c31a9074..61f0bff7 120000 --- a/FileSets/v3.31/OverviewSolarInverter.qml +++ b/FileSets/v3.31/OverviewSolarInverter.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarInverter.qml \ No newline at end of file +../v3.40~11/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.31/OverviewTankDelegate.qml b/FileSets/v3.31/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v3.31/OverviewTankDelegate.qml +++ b/FileSets/v3.31/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.31/OverviewTanks.qml b/FileSets/v3.31/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v3.31/OverviewTanks.qml +++ b/FileSets/v3.31/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.31/OverviewTanksTempsDigInputs.qml b/FileSets/v3.31/OverviewTanksTempsDigInputs.qml index 302fd03e..26dd2c44 120000 --- a/FileSets/v3.31/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.31/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40~11/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.31/PageDigitalInput.qml b/FileSets/v3.31/PageDigitalInput.qml index f279fa05..a9b9e513 120000 --- a/FileSets/v3.31/PageDigitalInput.qml +++ b/FileSets/v3.31/PageDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/PageDigitalInput.qml \ No newline at end of file +../v3.40~11/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.31/PageGenerator.qml b/FileSets/v3.31/PageGenerator.qml index f99cb9de..7ecabc54 120000 --- a/FileSets/v3.31/PageGenerator.qml +++ b/FileSets/v3.31/PageGenerator.qml @@ -1 +1 @@ -../v3.40~10/PageGenerator.qml \ No newline at end of file +../v3.40~11/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.31/PageMain.qml b/FileSets/v3.31/PageMain.qml index a7aac8b7..0e32fc35 120000 --- a/FileSets/v3.31/PageMain.qml +++ b/FileSets/v3.31/PageMain.qml @@ -1 +1 @@ -../v3.40~10/PageMain.qml \ No newline at end of file +../v3.40~11/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.31/PageSettingsGenerator.qml b/FileSets/v3.31/PageSettingsGenerator.qml index 23140671..efd8d051 120000 --- a/FileSets/v3.31/PageSettingsGenerator.qml +++ b/FileSets/v3.31/PageSettingsGenerator.qml @@ -1 +1 @@ -../v3.40~10/PageSettingsGenerator.qml \ No newline at end of file +../v3.40~11/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.31/PageSettingsGuiMods.qml b/FileSets/v3.31/PageSettingsGuiMods.qml index 0e85c757..50a2393d 120000 --- a/FileSets/v3.31/PageSettingsGuiMods.qml +++ b/FileSets/v3.31/PageSettingsGuiMods.qml @@ -1 +1 @@ -../v3.40~10/PageSettingsGuiMods.qml \ No newline at end of file +../v3.40~11/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.31/PageSettingsRelay.qml b/FileSets/v3.31/PageSettingsRelay.qml index 72de1197..337482f3 120000 --- a/FileSets/v3.31/PageSettingsRelay.qml +++ b/FileSets/v3.31/PageSettingsRelay.qml @@ -1 +1 @@ -../v3.40~10/PageSettingsRelay.qml \ No newline at end of file +../v3.40~11/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.31/Tile.qml b/FileSets/v3.31/Tile.qml index ac462f2e..5c566101 120000 --- a/FileSets/v3.31/Tile.qml +++ b/FileSets/v3.31/Tile.qml @@ -1 +1 @@ -../v3.40~10/Tile.qml \ No newline at end of file +../v3.40~11/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.31/TileDigIn.qml b/FileSets/v3.31/TileDigIn.qml index ff43ea83..fc269e05 120000 --- a/FileSets/v3.31/TileDigIn.qml +++ b/FileSets/v3.31/TileDigIn.qml @@ -1 +1 @@ -../v3.40~10/TileDigIn.qml \ No newline at end of file +../v3.40~11/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.31/TileRelay.qml b/FileSets/v3.31/TileRelay.qml index 7e3866d3..2ebdf179 120000 --- a/FileSets/v3.31/TileRelay.qml +++ b/FileSets/v3.31/TileRelay.qml @@ -1 +1 @@ -../v3.40~10/TileRelay.qml \ No newline at end of file +../v3.40~11/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.31/TileText.qml b/FileSets/v3.31/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v3.31/TileText.qml +++ b/FileSets/v3.31/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.31/dbus_digitalinputs.py b/FileSets/v3.31/dbus_digitalinputs.py index bdaa4e12..085682ce 120000 --- a/FileSets/v3.31/dbus_digitalinputs.py +++ b/FileSets/v3.31/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~10/dbus_digitalinputs.py \ No newline at end of file +../v3.40~11/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 12899ddc..699b4b49 120000 --- a/FileSets/v3.31/dbus_generator.py +++ b/FileSets/v3.31/dbus_generator.py @@ -1 +1 @@ -../v3.40~10/dbus_generator.py \ No newline at end of file +../v3.40~11/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.31/main.qml b/FileSets/v3.31/main.qml index 749f83e6..223531e7 120000 --- a/FileSets/v3.31/main.qml +++ b/FileSets/v3.31/main.qml @@ -1 +1 @@ -../v3.40~10/main.qml \ No newline at end of file +../v3.40~11/main.qml \ No newline at end of file diff --git a/FileSets/v3.31/styles.css b/FileSets/v3.31/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v3.31/styles.css +++ b/FileSets/v3.31/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v3.40~1/Battery.qml b/FileSets/v3.40~1/Battery.qml index 1f99218e..8e76916a 120000 --- a/FileSets/v3.40~1/Battery.qml +++ b/FileSets/v3.40~1/Battery.qml @@ -1 +1 @@ -../v3.40~10/Battery.qml \ No newline at end of file +../v3.40~11/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/MbEditBoxDateTime.qml b/FileSets/v3.40~1/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v3.40~1/MbEditBoxDateTime.qml +++ b/FileSets/v3.40~1/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/MbItem.qml b/FileSets/v3.40~1/MbItem.qml index 5e1bcc78..d1f5c0bb 120000 --- a/FileSets/v3.40~1/MbItem.qml +++ b/FileSets/v3.40~1/MbItem.qml @@ -1 +1 @@ -../v3.40~10/MbItem.qml \ No newline at end of file +../v3.40~11/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/MbItemDigitalInput.qml b/FileSets/v3.40~1/MbItemDigitalInput.qml index 68ec5c25..6be026f8 120000 --- a/FileSets/v3.40~1/MbItemDigitalInput.qml +++ b/FileSets/v3.40~1/MbItemDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/MbItemDigitalInput.qml \ No newline at end of file +../v3.40~11/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/MbSpinBox.qml b/FileSets/v3.40~1/MbSpinBox.qml index 8390ce03..fca806a7 120000 --- a/FileSets/v3.40~1/MbSpinBox.qml +++ b/FileSets/v3.40~1/MbSpinBox.qml @@ -1 +1 @@ -../v3.40~10/MbSpinBox.qml \ No newline at end of file +../v3.40~11/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/MbStyle.qml b/FileSets/v3.40~1/MbStyle.qml index 5d7cf621..17573562 120000 --- a/FileSets/v3.40~1/MbStyle.qml +++ b/FileSets/v3.40~1/MbStyle.qml @@ -1 +1 @@ -../v3.40~10/MbStyle.qml \ No newline at end of file +../v3.40~11/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/MbSubMenu.qml b/FileSets/v3.40~1/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v3.40~1/MbSubMenu.qml +++ b/FileSets/v3.40~1/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/Multi.qml b/FileSets/v3.40~1/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v3.40~1/Multi.qml +++ b/FileSets/v3.40~1/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/ObjectAcConnection.qml b/FileSets/v3.40~1/ObjectAcConnection.qml index 7edd9db8..8d459a07 120000 --- a/FileSets/v3.40~1/ObjectAcConnection.qml +++ b/FileSets/v3.40~1/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~10/ObjectAcConnection.qml \ No newline at end of file +../v3.40~11/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~1/OverviewAcValuesEnhanced.qml index fe5152b2..8e55e8dc 120000 --- a/FileSets/v3.40~1/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.40~1/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewBox.qml b/FileSets/v3.40~1/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v3.40~1/OverviewBox.qml +++ b/FileSets/v3.40~1/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewConnection.qml b/FileSets/v3.40~1/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v3.40~1/OverviewConnection.qml +++ b/FileSets/v3.40~1/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewConnectionEnd.qml b/FileSets/v3.40~1/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v3.40~1/OverviewConnectionEnd.qml +++ b/FileSets/v3.40~1/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~1/OverviewGeneratorEnhanced.qml index f0f8b29d..f118934b 120000 --- a/FileSets/v3.40~1/OverviewGeneratorEnhanced.qml +++ b/FileSets/v3.40~1/OverviewGeneratorEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~1/OverviewGeneratorRelayEnhanced.qml index a65e18d8..e0bbd3df 120000 --- a/FileSets/v3.40~1/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.40~1/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewMobileEnhanced.qml b/FileSets/v3.40~1/OverviewMobileEnhanced.qml index d6107e91..46ae0c55 120000 --- a/FileSets/v3.40~1/OverviewMobileEnhanced.qml +++ b/FileSets/v3.40~1/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewSolarCharger.qml b/FileSets/v3.40~1/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v3.40~1/OverviewSolarCharger.qml +++ b/FileSets/v3.40~1/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewSolarInverter.qml b/FileSets/v3.40~1/OverviewSolarInverter.qml index c31a9074..61f0bff7 120000 --- a/FileSets/v3.40~1/OverviewSolarInverter.qml +++ b/FileSets/v3.40~1/OverviewSolarInverter.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarInverter.qml \ No newline at end of file +../v3.40~11/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewTankDelegate.qml b/FileSets/v3.40~1/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v3.40~1/OverviewTankDelegate.qml +++ b/FileSets/v3.40~1/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewTanks.qml b/FileSets/v3.40~1/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v3.40~1/OverviewTanks.qml +++ b/FileSets/v3.40~1/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~1/OverviewTanksTempsDigInputs.qml index 302fd03e..26dd2c44 120000 --- a/FileSets/v3.40~1/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.40~1/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40~11/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/PageDigitalInput.qml b/FileSets/v3.40~1/PageDigitalInput.qml index f279fa05..a9b9e513 120000 --- a/FileSets/v3.40~1/PageDigitalInput.qml +++ b/FileSets/v3.40~1/PageDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/PageDigitalInput.qml \ No newline at end of file +../v3.40~11/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/PageGenerator.qml b/FileSets/v3.40~1/PageGenerator.qml index f99cb9de..7ecabc54 120000 --- a/FileSets/v3.40~1/PageGenerator.qml +++ b/FileSets/v3.40~1/PageGenerator.qml @@ -1 +1 @@ -../v3.40~10/PageGenerator.qml \ No newline at end of file +../v3.40~11/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/PageMain.qml b/FileSets/v3.40~1/PageMain.qml index a7aac8b7..0e32fc35 120000 --- a/FileSets/v3.40~1/PageMain.qml +++ b/FileSets/v3.40~1/PageMain.qml @@ -1 +1 @@ -../v3.40~10/PageMain.qml \ No newline at end of file +../v3.40~11/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/PageSettingsGenerator.qml b/FileSets/v3.40~1/PageSettingsGenerator.qml index 23140671..efd8d051 120000 --- a/FileSets/v3.40~1/PageSettingsGenerator.qml +++ b/FileSets/v3.40~1/PageSettingsGenerator.qml @@ -1 +1 @@ -../v3.40~10/PageSettingsGenerator.qml \ No newline at end of file +../v3.40~11/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/PageSettingsGuiMods.qml b/FileSets/v3.40~1/PageSettingsGuiMods.qml index 0e85c757..50a2393d 120000 --- a/FileSets/v3.40~1/PageSettingsGuiMods.qml +++ b/FileSets/v3.40~1/PageSettingsGuiMods.qml @@ -1 +1 @@ -../v3.40~10/PageSettingsGuiMods.qml \ No newline at end of file +../v3.40~11/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/PageSettingsRelay.qml b/FileSets/v3.40~1/PageSettingsRelay.qml index 72de1197..337482f3 120000 --- a/FileSets/v3.40~1/PageSettingsRelay.qml +++ b/FileSets/v3.40~1/PageSettingsRelay.qml @@ -1 +1 @@ -../v3.40~10/PageSettingsRelay.qml \ No newline at end of file +../v3.40~11/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/Tile.qml b/FileSets/v3.40~1/Tile.qml index ac462f2e..5c566101 120000 --- a/FileSets/v3.40~1/Tile.qml +++ b/FileSets/v3.40~1/Tile.qml @@ -1 +1 @@ -../v3.40~10/Tile.qml \ No newline at end of file +../v3.40~11/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/TileDigIn.qml b/FileSets/v3.40~1/TileDigIn.qml index ff43ea83..fc269e05 120000 --- a/FileSets/v3.40~1/TileDigIn.qml +++ b/FileSets/v3.40~1/TileDigIn.qml @@ -1 +1 @@ -../v3.40~10/TileDigIn.qml \ No newline at end of file +../v3.40~11/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/TileRelay.qml b/FileSets/v3.40~1/TileRelay.qml index 7e3866d3..2ebdf179 120000 --- a/FileSets/v3.40~1/TileRelay.qml +++ b/FileSets/v3.40~1/TileRelay.qml @@ -1 +1 @@ -../v3.40~10/TileRelay.qml \ No newline at end of file +../v3.40~11/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/TileText.qml b/FileSets/v3.40~1/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v3.40~1/TileText.qml +++ b/FileSets/v3.40~1/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/dbus_digitalinputs.py b/FileSets/v3.40~1/dbus_digitalinputs.py index bdaa4e12..085682ce 120000 --- a/FileSets/v3.40~1/dbus_digitalinputs.py +++ b/FileSets/v3.40~1/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~10/dbus_digitalinputs.py \ No newline at end of file +../v3.40~11/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 index 12899ddc..699b4b49 120000 --- a/FileSets/v3.40~1/dbus_generator.py +++ b/FileSets/v3.40~1/dbus_generator.py @@ -1 +1 @@ -../v3.40~10/dbus_generator.py \ No newline at end of file +../v3.40~11/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 index 749f83e6..223531e7 120000 --- a/FileSets/v3.40~1/main.qml +++ b/FileSets/v3.40~1/main.qml @@ -1 +1 @@ -../v3.40~10/main.qml \ No newline at end of file +../v3.40~11/main.qml \ No newline at end of file diff --git a/FileSets/v3.40~1/startstop.py b/FileSets/v3.40~1/startstop.py index d2ea898a..c84f296d 120000 --- a/FileSets/v3.40~1/startstop.py +++ b/FileSets/v3.40~1/startstop.py @@ -1 +1 @@ -../v3.40~10/startstop.py \ No newline at end of file +../v3.40~11/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~1/styles.css b/FileSets/v3.40~1/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v3.40~1/styles.css +++ b/FileSets/v3.40~1/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/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 100644 index 9e4fd95c..00000000 --- a/FileSets/v3.40~10/Battery.qml +++ /dev/null @@ -1,176 +0,0 @@ -import QtQuick 1.1 - -Item { - id: root - - width: 145 - height: 101 - - property real soc: 80 -////// GuiMods — DarkMode - property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } - property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 - property string color: !darkMode ? "#4789d0" : "#234468" - property string emptyColor: !darkMode ? "#1abc9c" : "#0d5e4e" - - property alias values: _values.children - property bool renewablePreferred: sys.preferRenewableEnergy.valid - property bool renewableOverride: renewablePreferred - && (sys.preferRenewableEnergy.value === 0 || sys.preferRenewableEnergy.value === 2 || sys.acSource == 2) - - //// dummies for backward compatiblity - not actually used - values grabbed from sys. directly - property bool preferRenewable: false - property bool preferRenewableOverride: false - property bool preferRenewableOverrideGenset: false - - - SvgRectangle { - id: leftTerminal - width: 12 - height: 8 - radius: 3 - color: soc < 100 ? emptyColor : root.color - anchors { - left: root.left; leftMargin: 12 - } - x: 12 - } - - SvgRectangle { - id: rightTerminal - width: 12 - height: 8 - radius: 3 - color: soc < 100 ? emptyColor : root.color - anchors { - right: root.right; rightMargin: 12 - } - } - - Rectangle { - id: background - - // NOTE: to remove the bottom of the terminals -////// GuiMods — DarkMode - border {width: 2; color: !darkMode ? "white" : "#202020"} - height: root.height - leftTerminal.height - width: root.width - y: leftTerminal.height - 1 - - SvgRectangle { - height: parent.height - width: parent.width - color: root.emptyColor - radius: 3 - } - - SvgRectangle { - id: filledPart - width: root.width - height: soc * background.height / 100 - color: root.color - anchors.bottom: parent.bottom - radius: 3 - } - - SvgRectangle { - height: parent.height - width: parent.width * 0.7 - anchors.centerIn: parent -////// GuiMods — DarkMode - color: !darkMode ? "#ffffff" : "#202020" - opacity: 0.06 - } - } - - MbIcon { - iconId: getBatteryLogo() - anchors { - right: parent.right; rightMargin: 4 - bottom: parent.bottom; bottomMargin: 4 - } - - function getBatteryLogo() - { - var pid = sys.batteryProductId.value - var logo = "" - - if (pid === 0xB014) - logo = "overview-battery-freedomwon" - - return logo - } - } - - Rectangle { - height: 30 - width: 25 - visible: renewablePreferred - color: renewableOverride ? "#b84b00" : "transparent" - clip: true - anchors { - top: background.top - topMargin: 13 - } - - MbIcon { - iconId: "double-arrow-up" - visible: renewableOverride - anchors { - verticalCenter: parent.verticalCenter - horizontalCenter: parent.horizontalCenter - } - } - MbIcon { - iconId: - { - if (renewableOverride) - { - if (sys.acSource == 2) - return "overview-generator-background" - else - return "overview-tower-background" - } - else if (darkMode) - return "overview-renewable-light" - else - return "overview-renewable" - } - height: parent.height * 0.9 - width: parent.width * 0.8 - fillMode: Image.PreserveAspectFit - anchors { - horizontalCenter: parent.horizontalCenter - verticalCenter: parent.verticalCenter - } - } - } - - Text { - text: "-" - font.pixelSize: 13; font.bold: true - anchors.centerIn: leftTerminal - anchors.verticalCenterOffset: 12 -////// GuiMods — DarkMode - color: !darkMode ? "#fff" : "#e1e1e1" - } - - Text { - text: "+" - font.pixelSize: 13; font.bold: true - anchors.centerIn: rightTerminal - anchors.verticalCenterOffset: 12 -////// GuiMods — DarkMode - color: !darkMode ? "#fff" : "#e1e1e1" - } - - Item { - id: _values - anchors { - top: background.top; - bottom: root.bottom - left: root.left - right: root.right - } - } -} diff --git a/FileSets/v3.40~10/Battery.qml b/FileSets/v3.40~10/Battery.qml new file mode 120000 index 00000000..8e76916a --- /dev/null +++ b/FileSets/v3.40~10/Battery.qml @@ -0,0 +1 @@ +../v3.40~11/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/DetailAcInput.qml b/FileSets/v3.40~10/DetailAcInput.qml deleted file mode 100644 index d2865e4a..00000000 --- a/FileSets/v3.40~10/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~10/DetailAcInput.qml b/FileSets/v3.40~10/DetailAcInput.qml new file mode 120000 index 00000000..2f42278c --- /dev/null +++ b/FileSets/v3.40~10/DetailAcInput.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index fd7e9def..00000000 --- a/FileSets/v3.40~10/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~10/DetailInverter.qml b/FileSets/v3.40~10/DetailInverter.qml new file mode 120000 index 00000000..27951154 --- /dev/null +++ b/FileSets/v3.40~10/DetailInverter.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 5909cb10..00000000 --- a/FileSets/v3.40~10/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~10/DetailLoadsCombined.qml b/FileSets/v3.40~10/DetailLoadsCombined.qml new file mode 120000 index 00000000..000e08da --- /dev/null +++ b/FileSets/v3.40~10/DetailLoadsCombined.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 999a62ac..00000000 --- a/FileSets/v3.40~10/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~10/DetailLoadsOnInput.qml b/FileSets/v3.40~10/DetailLoadsOnInput.qml new file mode 120000 index 00000000..747e7201 --- /dev/null +++ b/FileSets/v3.40~10/DetailLoadsOnInput.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 2092989c..00000000 --- a/FileSets/v3.40~10/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~10/DetailLoadsOnOutput.qml b/FileSets/v3.40~10/DetailLoadsOnOutput.qml new file mode 120000 index 00000000..66560e4e --- /dev/null +++ b/FileSets/v3.40~10/DetailLoadsOnOutput.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index abe96728..00000000 --- a/FileSets/v3.40~10/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~10/HubData.qml b/FileSets/v3.40~10/HubData.qml new file mode 120000 index 00000000..4a063f2d --- /dev/null +++ b/FileSets/v3.40~10/HubData.qml @@ -0,0 +1 @@ +../v3.40~11/HubData.qml \ No newline at end of file diff --git a/FileSets/v3.40~10/MbEditBoxDateTime.qml b/FileSets/v3.40~10/MbEditBoxDateTime.qml deleted file mode 100644 index 12b9ed3a..00000000 --- a/FileSets/v3.40~10/MbEditBoxDateTime.qml +++ /dev/null @@ -1,96 +0,0 @@ -import QtQuick 1.1 - -MbEditBox { - id: root - -////// GuiMods — DarkMode - property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } - property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 - - property string format: "yyyy-MM-dd hh:mm" - property bool utc: false - - ignoreChars: "-: " - matchString: "0123456789" - maximumLength: format.length - overwriteMode: true - numericOnlyLayout: true - upDownText: qsTr("Select number") -////// GuiMods — DarkMode - textInput.color: editMode ? (vePlatform.secondsFromString(_editText, format) !== -1 ? (!darkMode ? "#000000" : "#fdfdfd") : "red") : (!darkMode ? "#000000" : "#fdfdfd") - - // note: overwritten by MbEditBoxTime! - function getTimeSeconds(str) { - return vePlatform.secondsFromString(str, format) - } - - function editTextToValue() { - var value = getTimeSeconds(_editText) - return (value === -1 ? null : value) - } - - function valueToText(value) { - if (utc) - return vePlatform.formatDateTimeUtc(value, format) - return Qt.formatDateTime(new Date(value * 1000), format) - } - - // make sure the time of days keeps below 24:00 - function validateHours(str, pos) { - if (format[pos] === 'h' && format[pos + 1] === 'h' && str[pos] === '2' && str[pos + 1] > 3) - str = setValueAt(str, pos + 1, '3', false); - return str; - } - - function validate(newText, pos) { - var wrap = wrapAround(pos) - - if ((newText[pos] - '0') >= wrap) { - var text = qsTr("Only numbers up to %1 are valid on this location").arg(wrap - 1) - toast.createToast(text, 3000) - return null - } - - // respect the minimum value. Note: instead of declining the change the minimum value - // is forced. The reason for that is that if e.g. 00:10 is decremented with a minimum - // of one minute it becomes 00:01 instead of silently refusing the change. - var ret = validateHours(newText, pos) - if (item.min && getTimeSeconds(ret) < item.min) - return valueToText(item.min) - - return ret - } - - // some digit in e.g. time/data loop earlier than 0..9 - function wrapAround(pos) { - switch (format[pos]) { - // mm goes till 59 - case 'm': - if (format[pos + 1] === 'm') - return 6; - break - // hours till 23 - case 'h': - if (format[pos + 1] === 'h') - return 3; - if (format[pos - 1] === 'h') - return _editText[pos - 1] === '2' ? 4 : matchString.length - break - // days up to 31 - case 'd': - if (format[pos + 1] === 'd') - return 4; - if (format[pos - 1] === 'd') - return _editText[pos - 1] === '3' ? 2 : matchString.length; - break; - // months till 12 - case 'M': - if (format[pos + 1] === 'M') - return 2; - if (format[pos - 1] === 'M') - return _editText[pos - 1] === '1' ? 3 : matchString.length - break - } - return matchString.length - } -} diff --git a/FileSets/v3.40~10/MbEditBoxDateTime.qml b/FileSets/v3.40~10/MbEditBoxDateTime.qml new file mode 120000 index 00000000..f2e26436 --- /dev/null +++ b/FileSets/v3.40~10/MbEditBoxDateTime.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index fb849144..00000000 --- a/FileSets/v3.40~10/MbItem.qml +++ /dev/null @@ -1,193 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -/* - * The MbItem serves as a base object for Items which can be placed in - * the menubrowser (Mb), see MbPage. It adds default functions for key - * behavior, icons, subpage navigtation and only shows a default - * background. Any derived mb Item can fill it to its desire. - */ -Item { - id: root - width: (parent ? parent.width : 0) - height: defaultHeight - property bool show: user.accessLevel >= showAccessLevel - -////// GuiMods — DarkMode - property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } - property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 - - property int defaultHeight: style.itemHeight - - property bool editMode - property variant toolbarHandler: editMode ? editToolbarHandler : navToolBar - property alias navigationHandler: navToolBar - - property bool isCurrentItem: root.ListView.isCurrentItem - property MbStyle style: MbStyle { isCurrentItem: root.ListView.isCurrentItem } - - // Navigation for subpages - property bool hasSubpage: subpage !== undefined - property variant subpage - property variant _subpageInstance - - property bool cornerMark: false - - property int showAccessLevel: User.AccessUser - property int writeAccessLevel: User.AccessInstaller - property bool userHasWriteAccess: user.accessLevel >= writeAccessLevel - property bool editable: true - property alias backgroundColor: background.color - - // NOTE: this is added to our 4.8 qt version. Uncomment this line to run on a - // vanilla QT. But optional rows are then always visible. - //property bool show - - signal selected - signal clicked - - ToolbarHandler { - id: editToolbarHandler - - leftIcon: "icon-toolbar-cancel" - rightIcon: "icon-toolbar-ok" - - function leftAction() - { - cancel() - } - - function rightAction() - { - save() - } - } - - ToolbarHandlerMbItems { - id: navToolBar - isDefault: true - } - - function open() { - if (pageStack.currentPage.active && hasSubpage) - _subpageInstance = pageStack.push(subpage); - } - - function edit(isMouse) { - } - - function cancel() { - } - - function save() { - } - - function select() { - if (!pageStack) - return - - // Note: Getting the index from the model depends on the model type. - // So lets asked the listview for our index instead. - var n = pageStack.currentPage.listview.indexAt(root.x, root.y) - if (n < 0) - return - pageStack.currentPage.currentIndex = n - - if (!userHasWriteAccess && !hasSubpage && editable) - toast.createToast(qsTr("Setting locked for \"user\" access level."), 3000, "icon-lock-active"); - root.selected() - } - - Rectangle { - id: background - anchors.fill: parent - color: showAccessLevel >= User.AccessSuperUser ? style.backgroundColorService : style.backgroundColor - } - - MbIcon { - id: cornerMarkIcon - -////// GuiMods — DarkMode - iconId: "icon-items-corner" + (root.ListView.isCurrentItem || darkMode ? "-active" : "") - visible: cornerMark - anchors { - right: parent.right; rightMargin: 1 - bottom: bottomBorder.top; bottomMargin: 1 - } - } - - Rectangle { - id: bottomBorder - width: root.width - height: 1 - color: style.borderColor - anchors.bottom: root.bottom - } - - onIsCurrentItemChanged: { - if (editMode) - cancel() - } - - Keys.onRightPressed: { - if (userHasWriteAccess) - root.clicked() - if (!userHasWriteAccess && !hasSubpage) - toast.createToast(qsTr("Setting locked due to access level."), 3000, "icon-lock-active"); - else - open() - } - - function defaultCenterAction() - { - if (userHasWriteAccess) - root.clicked() - if (!userHasWriteAccess && !hasSubpage && editable) { - toast.createToast(qsTr("Setting locked due to access level."), 3000, "icon-lock-active"); - } else { - if (pageStack.currentPage.active && hasSubpage) - open() - else - edit() - } - } - - function handleMouseClick(onItem) { - if (hasSubpage && !onItem && editable) { - // When clicking again an on item with a value and a submenu which is in edit mode, - // since the value was pressed, then leave edit mode first instead of opening the - // page while leaving the item in an edit state. - if (editMode) { - cancel() - } else { - select() - open() - } - } else { - if (!root.ListView.isCurrentItem) { - select() - } else { - root.clicked() - edit(true) - } - } - } - - // If a submenu is opened with a dynamic model, the items can be destructed - // while a subpage is in the pagestack. Since navigation will then get stuck, - // do navigate out of the submenu in such a case. - Component.onDestruction: { - if (pageStack && _subpageInstance) { - if (pageStack.find(function(page) { return page === _subpageInstance; } ) !== null) { - pageStack.pop(_subpageInstance) - } - } - } - - MouseArea { - id: mouseArea - anchors.fill: parent - onClicked: handleMouseClick() - } -} diff --git a/FileSets/v3.40~10/MbItem.qml b/FileSets/v3.40~10/MbItem.qml new file mode 120000 index 00000000..d1f5c0bb --- /dev/null +++ b/FileSets/v3.40~10/MbItem.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 599ed90a..00000000 --- a/FileSets/v3.40~10/MbItemDigitalInput.qml +++ /dev/null @@ -1,31 +0,0 @@ -//// modified for ExtTransferSwitch package - -import QtQuick 1.1 - -MbItemOptions { - show: valid - signal disabled - property variant previousValue: undefined - possibleValues: [ - MbOption { description: qsTr("Disabled"); value: 0 }, - MbOption { description: qsTr("Pulse meter"); value: 1 }, - MbOption { description: qsTr("Door alarm"); value: 2 }, - MbOption { description: qsTr("Bilge pump"); value: 3 }, - MbOption { description: qsTr("Bilge alarm"); value: 4 }, - MbOption { description: qsTr("Burglar alarm"); value: 5 }, - MbOption { description: qsTr("Smoke alarm"); value: 6 }, - MbOption { description: qsTr("Fire alarm"); value: 7 }, - MbOption { description: qsTr("CO2 alarm"); value: 8 }, - MbOption { description: qsTr("Generic I/O"); value: 10 }, - MbOption { description: qsTr("Generator"); value: 9 }, - MbOption { description: qsTr("Touch input control"); value: 11 }, -//// added for ExtTransferSwitch package - MbOption { description: qsTr("External transfer switch"); value: 12 } - ] - onValueChanged: { - if (valid) { - if (previousValue != undefined && value == 0) disabled() - previousValue = value - } - } -} diff --git a/FileSets/v3.40~10/MbItemDigitalInput.qml b/FileSets/v3.40~10/MbItemDigitalInput.qml new file mode 120000 index 00000000..6be026f8 --- /dev/null +++ b/FileSets/v3.40~10/MbItemDigitalInput.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 031b6ba2..00000000 --- a/FileSets/v3.40~10/MbSpinBox.qml +++ /dev/null @@ -1,183 +0,0 @@ -import QtQuick 1.1 -import Qt.labs.components.native 1.0 -import com.victron.velib 1.0 - -MbItem { - 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 { - isSetting: true - decimals: 1 - step: 0.5 - } - property bool useVirtualKeyboard - property variant spinboxToolbarHandler: editMode ? _spinboxToolbarHandler : navigationHandler - default property alias values: container.data - - editMode: spinbox.enabled - height: keyboard.y + keyboard.height + 1 - toolbarHandler: spinboxToolbarHandler - - ToolbarHandler { - id: _spinboxToolbarHandler - property string leftIcon: "icon-toolbar-cancel" - property string rightIcon: "icon-toolbar-ok" - property string rightText: "" - - function leftAction() - { - cancel() - } - - function rightAction() - { - save() - } - } - - signal exitEditMode(bool changed, variant newValue) - signal maxValueReached() - signal minValueReached() - - Item { - id: verticalCentered - height: root.defaultHeight - width: root.width - - MbTextDescription { - id: name - anchors { - left: parent.left; leftMargin: style.marginDefault - verticalCenter: parent.verticalCenter - } - - isCurrentItem: root.ListView.isCurrentItem - text: root.description - opacity: item.valid ? style.opacityEnabled : style.opacityDisabled - } - - Item { - id: container - width: childrenRect.width - height: childrenRect.height - anchors { - right: graytag.left; rightMargin: style.marginDefault - verticalCenter: parent.verticalCenter - } - } - - MbBackgroundRect { - id: graytag -////// GuiMods — DarkMode - color: !darkMode ? (!spinbox.enabled ? "#ddd": "#fff") : (!spinbox.enabled ? "#4b4b4b": "#747474") - height: spinbox.height + 6 - width: spinbox.width + unit.width + 10 -////// GuiMods — DarkMode - border.color: !darkMode ? "#ddd" : "#4b4b4b" - border.width: spinbox.enabled ? 1 : 0 - anchors { - right: parent.right; rightMargin: style.marginDefault - verticalCenter: parent.verticalCenter - } - } - - MbTextValue { - id: unit - - text: root.item.unit - anchors { - right: parent.right; rightMargin: style.marginDefault + 5 - verticalCenter: spinbox.verticalCenter - } - } - - SpinBox { - id: spinbox - - color: style.color2 - font.pixelSize: name.font.pixelSize - font.family: name.font.family - font.bold: false - minimumValue: item.min - maximumValue: item.max - stepSize: item.step - enabled: false - greyed: item.valid - numOfDecimals: item.decimals - anchors { - right: unit.left - verticalCenter: parent.verticalCenter - } - - /* note: these functions break binding hence the Binding item below */ - Keys.onRightPressed: { if (value === maximumValue) maxValueReached(); spinbox.up(event.isAutoRepeat); } - Keys.onLeftPressed: { if (value === minimumValue) minValueReached(); spinbox.down(event.isAutoRepeat); } - Keys.onUpPressed: { if (value === maximumValue) maxValueReached(); spinbox.up(event.isAutoRepeat); } - Keys.onDownPressed: { if (value === minimumValue) minValueReached(); spinbox.down(event.isAutoRepeat); } - - /* Focus is removed to ignore keypresses */ - Keys.onSpacePressed: save(false) - Keys.onReturnPressed: save(false) - Keys.onEscapePressed: cancel() - } - - MouseArea { - anchors { - fill: spinbox - leftMargin: -20 - rightMargin: -20 - } - - onPressed: handleMouseClick(true) - } - } - - Keyboard { - id: keyboard - anchors.top: verticalCentered.bottom - anchors.topMargin: -1 - width: root.width - active: spinbox.enabled && useVirtualKeyboard - layout: "KeyboardLoaderPlusMin.qml" - onAnimatingChanged: listview.positionViewAtIndex(currentIndex, ListView.Contain) - } - - /* binding is done explicitly to reenable binding after edit */ - Binding { - target: spinbox - property: "value" - value: item.value - when: item.valid && !spinbox.enabled - } - - function edit(isMouse) - { - if (item.valid && !readOnly) - { - useVirtualKeyboard = isMouse === true - spinbox.enabled = true - spinbox.focus = true - } - } - - function save() { - var newValue = spinbox.value - item.setValue(spinbox.value) - focus = true; - spinbox.enabled = false - exitEditMode(true, newValue) - } - - function cancel() { - focus = true - spinbox.enabled = false - exitEditMode(false, undefined) - } -} diff --git a/FileSets/v3.40~10/MbSpinBox.qml b/FileSets/v3.40~10/MbSpinBox.qml new file mode 120000 index 00000000..fca806a7 --- /dev/null +++ b/FileSets/v3.40~10/MbSpinBox.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 9bba6057..00000000 --- a/FileSets/v3.40~10/MbStyle.qml +++ /dev/null @@ -1,47 +0,0 @@ -import QtQuick 1.1 - -/* - * 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 - property int itemHeight: 35 - - // Default font and size for e.g. the menus - property string fontFamily: "default" - property int fontPixelSize: 16 - -////// GuiMods — DarkMode - property string borderColor: !darkMode ? "#ddd" : "#4b4b4b" - property string backgroundColor: !darkMode ? (isCurrentItem ? '#4790d0' : 'transparent') : (isCurrentItem ? '#234468' : '#303030') - property string backgroundColorService: !darkMode ? (isCurrentItem ? "#2969a1" : '#ffe9b7') : (isCurrentItem ? "#234468" : '#7f745b') - property string backgroundColorComponent: borderColor - - // Text mainly used for description etc. -////// GuiMods — DarkMode - property string textColor: !darkMode ? "#000000" : "#fdfdfd" - property string textColorSelected: !darkMode ? "#FFFFFF" : "#fdfdfd" - - // Color typically used for values -////// GuiMods — DarkMode - property string valueColor: !darkMode ? "#333333" : "#fdfdfd" - property int valueHorizontalAlignment: Text.AlignRight - property string color2: !darkMode ? "#333333" : "#fdfdfd" - - property int marginDefault: 8 - // margin between MbItem border and components for bottom / top - property int marginItemVertical: 3 - // margin from the "sides", typically left / right - property int marginItemHorizontal: 8 - // prefered left / right text margin within text components - property int marginTextHorizontal: 5 - - property real opacityEnabled: 1.0 - property real opacityDisabled: 0.5 -} diff --git a/FileSets/v3.40~10/MbStyle.qml b/FileSets/v3.40~10/MbStyle.qml new file mode 120000 index 00000000..17573562 --- /dev/null +++ b/FileSets/v3.40~10/MbStyle.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 094cda24..00000000 --- a/FileSets/v3.40~10/MbSubMenu.qml +++ /dev/null @@ -1,69 +0,0 @@ -import QtQuick 1.1 -import Qt.labs.components.native 1.0 -import com.victron.velib 1.0 - -MbItem { - id: root - width: pageStack ? pageStack.currentPage.width : 0 - -////// 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 VBusItem item: VBusItem {} - property string iconId: "icon-toolbar-enter" - property bool check: false - property bool indent: false - default property alias values: _values.data - - MbTextDescription { - id: checkText - anchors { - left: parent.left; leftMargin: style.marginDefault - verticalCenter: parent.verticalCenter - } - width: root.indent ? 9 : 0 - text: root.check ? "√" : " " - } - - MbTextDescription { - id: name - anchors { - left: checkText.right; leftMargin: root.indent ? checkText.width : 0 - verticalCenter: parent.verticalCenter - } - text: root.description - } - - MbRow { - id: _values - - anchors { - right: icon.left; rightMargin: style.marginDefault / 2 - verticalCenter: parent.verticalCenter - } - - Repeater { - id: repeater - model: root.item.value && root.item.value.constructor === Array ? root.item.value.length : 1 - - MbTextBlock { - item.text: repeater.model === 1 ? root.item.text : root.item.value[index] - opacity: item.text !== item.invalidText - } - } - } - - MbIcon { - id: icon - - display: hasSubpage - anchors { - right: root.right; rightMargin: style.marginDefault - verticalCenter: parent.verticalCenter - } -////// GuiMods — DarkMode - iconId: root.iconId ? root.iconId + (root.ListView.isCurrentItem || darkMode ? "-active" : "") : "" - } -} diff --git a/FileSets/v3.40~10/MbSubMenu.qml b/FileSets/v3.40~10/MbSubMenu.qml new file mode 120000 index 00000000..11b22a13 --- /dev/null +++ b/FileSets/v3.40~10/MbSubMenu.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 9ce49240..00000000 --- a/FileSets/v3.40~10/Multi.qml +++ /dev/null @@ -1,119 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbIcon { - id: multi - iconId: "overview-inverter" - -////// GuiMods — DarkMode - property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } - property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 - - SvgRectangle - { - id:inverterForeground - width: multi.width - height: multi.height - radius: 3 - color: "#000000" -////// GuiMods — DarkMode - opacity: !darkMode ? 0 : 0.35 - } - - property string vebusPrefix: "" - property string systemPrefix: "com.victronenergy.system" - property VBusItem systemState: VBusItem { bind: Utils.path(systemPrefix, "/SystemState/State") } - - Component.onCompleted: discoverMultis() - - Column { - spacing: 3 - x: 26 - y: 62 - - Led { - bind: Utils.path(sys.vebusPrefix, "/Leds/Mains") - onColor: "#68FF00" - } - - Led { - bind: Utils.path(sys.vebusPrefix, "/Leds/Bulk") - } - - Led { - bind: Utils.path(sys.vebusPrefix, "/Leds/Absorption") - } - - Led { - bind: Utils.path(sys.vebusPrefix, "/Leds/Float") - } - } - - Column { - spacing: 3 - x: multi.width - 28 - y: 62 - - Led { - bind: Utils.path(sys.vebusPrefix, "/Leds/Inverter") - onColor: "#68FF00" - } - - Led { - bind: Utils.path(sys.vebusPrefix, "/Leds/Overload") - onColor: "#F75E25" - } - - Led { - bind: Utils.path(sys.vebusPrefix, "/Leds/LowBattery") - onColor: "#F75E25" - } - - Led { - bind: Utils.path(sys.vebusPrefix, "/Leds/Temperature") - onColor: "#F75E25" - } - } - - Text { - anchors { - horizontalCenter: multi.horizontalCenter - top: multi.top; topMargin: 8 - } - horizontalAlignment: Text.AlignHCenter -////// GuiMods — DarkMode - color: !darkMode ? "white" : "#e1e1e1" - font {pixelSize: 16; bold: true} - text: vebusState.text - - SystemState { - id: vebusState - bind: systemState.valid?Utils.path(systemPrefix, "/SystemState/State"):Utils.path(sys.vebusPrefix, "/State") - } - } - - // When a new service is found check if is a multi - Connections { - target: DBusServices - onDbusServiceFound: addService(service) - } - - function addService(service) - { - if (service.type === DBusService.DBUS_SERVICE_MULTI) { - if (vebusPrefix === "") - vebusPrefix = service.name; - } - } - - // Check available services to find multis - function discoverMultis() - { - for (var i = 0; i < DBusServices.count; i++) { - if (DBusServices.at(i).type === DBusService.DBUS_SERVICE_MULTI) { - addService(DBusServices.at(i)) - } - } - } -} diff --git a/FileSets/v3.40~10/Multi.qml b/FileSets/v3.40~10/Multi.qml new file mode 120000 index 00000000..879c4d3e --- /dev/null +++ b/FileSets/v3.40~10/Multi.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 9e87e2db..00000000 --- a/FileSets/v3.40~10/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 l2AndL1OutSummed: false -////// 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.40~10/ObjectAcConnection.qml b/FileSets/v3.40~10/ObjectAcConnection.qml new file mode 120000 index 00000000..8d459a07 --- /dev/null +++ b/FileSets/v3.40~10/ObjectAcConnection.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index dc36d2ea..00000000 --- a/FileSets/v3.40~10/OverviewAcValuesEnhanced.qml +++ /dev/null @@ -1,94 +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 - } - - // 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 - } - TileText { - text: - { - if (root.connection.l2AndL1OutSummed) - 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: - { - if (phaseCount >= 3) - return "L3: " + EnhFmt.formatVBusItem (root.connection.powerL3, "W") - + " " + EnhFmt.formatVBusItem (root.connection.voltageL3, "V") - + " " + EnhFmt.formatVBusItem (root.connection.currentL3, "A") - else - return " " - } - visible: phaseCount >= 2 - font.pixelSize: 11 - } - TileText { - text: EnhFmt.formatVBusItem (root.connection.frequency, "Hz") - font.pixelSize: phaseCount >= 2 ? 11 : 15 - } - TileText { - text: qsTr("Limit: ") + EnhFmt.formatVBusItem (root.connection.inCurrentLimit) - font.pixelSize: phaseCount >= 2 ? 11 : 15 - visible: root.connection == sys.acInput - } - } -} diff --git a/FileSets/v3.40~10/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~10/OverviewAcValuesEnhanced.qml new file mode 120000 index 00000000..8e55e8dc --- /dev/null +++ b/FileSets/v3.40~10/OverviewAcValuesEnhanced.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 5bda96da..00000000 --- a/FileSets/v3.40~10/OverviewBox.qml +++ /dev/null @@ -1,55 +0,0 @@ -import QtQuick 1.1 - -SvgRectangle { - id: root - -////// GuiMods — DarkMode - property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } - property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 - - radius: 6 - width: 110 - height: 110 -////// GuiMods — DarkMode - color: !darkMode ? "#16a185" : "#0B5042" - clip: true // hides an off by one pixel offset - - property string title -////// GuiMods — DarkMode - property string titleColor: !darkMode ? "#1abc9c" : "#136050" - property alias values: _values.children - - SvgRectangle { - id: header - width: parent.width - height: 20 - radius: root.radius - color: titleColor - - // prevent rounded corners at the bottom - SvgRectangle { - height: parent.height / 2 - width: parent.width - color: parent.color - anchors.top: parent.verticalCenter - } - - Text { - text: title - font {pixelSize: 14; bold: true} -////// GuiMods — DarkMode - color: !darkMode ? "white" : "#e1e1e1" - anchors.centerIn: parent - } - } - - Item { - id: _values - anchors { - top: header.bottom; - bottom: root.bottom - left: root.left - right: root.right - } - } -} diff --git a/FileSets/v3.40~10/OverviewBox.qml b/FileSets/v3.40~10/OverviewBox.qml new file mode 120000 index 00000000..033b4017 --- /dev/null +++ b/FileSets/v3.40~10/OverviewBox.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 608a101d..00000000 --- a/FileSets/v3.40~10/OverviewConnection.qml +++ /dev/null @@ -1,137 +0,0 @@ -import QtQuick 1.1 - -/* - * This qml Item creates a line with moving balls on it representing a - * power flow in the overview. The line can be made up of an arbitary - * amount of straight line segments. The paths is drawn from (0,0) to - * (width, height) so it can simply be anchored to the points you want - * to connect. Since this item can have negative height and width the - * wording (top, left) and (right, bottom) is a bit weird, since they - * can be two arbitrary points, but so be it. - * - * This item is a bit weird anyway, first of all, since Path is an array, - * and qml arrays are weird in qt quick 1.1, it is not possible to bind - * to its contents. Hence the onCompleted events are used to assign them - * by value. - * - * Secondly, this item is slow! To deal with that a bit, the contents is - * only drawn when active is true. So the item can first be layout and - * its contents only layouted once. - */ - -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 Path path: emptyPath - - property Path straight: Path { - PathLine {x: 0; y: 0} - PathLine {x: width; y: height} - } - property Path corner: Path { - PathLine {x: 0; y: 0} - PathLine {x: width; y: 0} - PathLine {x: width; y: height} - } - property Path emptyPath: Path {} - - property bool active - property int ballCount: 4 -////// GuiMods — DarkMode - property color ballColor: !darkMode ? "#4789d0" : "#386ca5" - property real ballDiameter: lineWidth * 2 + 1 -////// GuiMods — DarkMode - property color lineColor: !darkMode ? "#4789d0" : "#386ca5" - property int lineWidth: 3 - property int value - property bool startPointVisible: true - property bool endPointVisible: true - - // internal - property int lineSegments - property Path activePath: active ? path : emptyPath - - visible: active - - function update() { - if (activePath === emptyPath) { - lineSegments = 0 - return - } - - var newValue = activePath.pathElements.length - 1 - - if (lineSegments == newValue) - lineSegments = newValue - 1; - lineSegments = newValue - - startPoint.update() - endPoint.update() - } - - onActivePathChanged: update() - onHeightChanged: update() - onWidthChanged: update() - - // end points of the path - OverviewConnectionEnd { - id: startPoint - visible: active && startPointVisible - connectionSize: ballDiameter - - // assign this otherwise qml will warn it is unbindable - function update() { - rotation = Math.atan2(activePath.pathElements[1].y, activePath.pathElements[1].x) * (180 / Math.PI) - } - } - - OverviewConnectionEnd { - id: endPoint - visible: active && endPointVisible - x: root.width - y: root.height - connectionSize: ballDiameter - - function update() { - var dx = activePath.pathElements[lineSegments].x - activePath.pathElements[lineSegments - 1].x - var dy = activePath.pathElements[lineSegments].y - activePath.pathElements[lineSegments - 1].y - rotation = 180 + Math.atan2(dy, dx) * (180 / Math.PI) - } - } - - // Draw foreground lines on top of that - Repeater { - id: lines - model: lineSegments - - Line { - lineWidth: root.lineWidth - color: lineColor - - // assign this otherwise qml will warn it is unbindable - Component.onCompleted: { - from = activePath.pathElements[index] - to = activePath.pathElements[index + 1] - } - } - } - - // moving balls over the lines - PathView { - id: ballsPath - model: active ? ballCount : 0 - interactive: false - path: activePath - visible: value != 0 - offset: active && value < 0 ? 1 - mover.pos : mover.pos - - delegate: Circle { - color: ballColor - radius: root.ballDiameter / 2 - } - } -} diff --git a/FileSets/v3.40~10/OverviewConnection.qml b/FileSets/v3.40~10/OverviewConnection.qml new file mode 120000 index 00000000..cb3709b9 --- /dev/null +++ b/FileSets/v3.40~10/OverviewConnection.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 60384d20..00000000 --- a/FileSets/v3.40~10/OverviewConnectionEnd.qml +++ /dev/null @@ -1,46 +0,0 @@ -import QtQuick 1.1 - -// NOTE: centers around the circle it midpoint -// width and height are bogus! -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 real radius: 5.5 - property alias color: ball.color - property int connectionSize: 7 - property int connectionLength: 9 - property alias rotation: connection.rotation - - Rectangle { - id: connection - - transformOrigin: Item.Left -////// GuiMods — DarkMode - color: !darkMode ? "white" : "#202020" - width: root.radius + connectionLength - height: connectionSize - anchors { - verticalCenter: ball.verticalCenter - left: ball.horizontalCenter - } - } - - Circle { - id: ball - radius: root.radius -////// GuiMods — DarkMode - color: !darkMode ? "#4789d0" : "#386ca5" - x: -radius - y: -radius - - border { - width: 2 -////// GuiMods — DarkMode - color: !darkMode ? "white" : "#202020" - } - } -} diff --git a/FileSets/v3.40~10/OverviewConnectionEnd.qml b/FileSets/v3.40~10/OverviewConnectionEnd.qml new file mode 120000 index 00000000..a2eab5c2 --- /dev/null +++ b/FileSets/v3.40~10/OverviewConnectionEnd.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 55a375b1..00000000 --- a/FileSets/v3.40~10/OverviewFlowComplex.qml +++ /dev/null @@ -1,1535 +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 showInverter: 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.inverterChargerDc.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 () - } - - 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" - 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 - } - DetailTarget { id: multiTarget; detailsPage: "DetailInverter.qml"; width: 60; height: 60 } - } - TileText - { - text: wallClock.time - color: "white" - 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: - root.tempServiceName = service.name - if (temperatureItem.valid && showBatteryTemp) - { - numberOfTemps++ - tempsModel.append({serviceName: service.name}) - } - break;; - case DBusService.DBUS_SERVICE_INVERTER: - 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 = "" - 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~10/OverviewFlowComplex.qml b/FileSets/v3.40~10/OverviewFlowComplex.qml new file mode 120000 index 00000000..601ebb86 --- /dev/null +++ b/FileSets/v3.40~10/OverviewFlowComplex.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 0c189315..00000000 --- a/FileSets/v3.40~10/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~10/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~10/OverviewGeneratorEnhanced.qml new file mode 120000 index 00000000..f118934b --- /dev/null +++ b/FileSets/v3.40~10/OverviewGeneratorEnhanced.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 83326226..00000000 --- a/FileSets/v3.40~10/OverviewGeneratorRelayEnhanced.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 1.1 -import "utils.js" as Utils - -OverviewGeneratorEnhanced { - icon: "overview-generator" - settingsBindPrefix: "com.victronenergy.settings/Settings/Generator0" - bindPrefix: "com.victronenergy.generator.startstop0" -} diff --git a/FileSets/v3.40~10/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~10/OverviewGeneratorRelayEnhanced.qml new file mode 120000 index 00000000..e0bbd3df --- /dev/null +++ b/FileSets/v3.40~10/OverviewGeneratorRelayEnhanced.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 8e11752d..00000000 --- a/FileSets/v3.40~10/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.inverterChargerDc.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.inverterChargerDc.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~10/OverviewGridParallel.qml b/FileSets/v3.40~10/OverviewGridParallel.qml new file mode 120000 index 00000000..68aeb5e3 --- /dev/null +++ b/FileSets/v3.40~10/OverviewGridParallel.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 7c04b763..00000000 --- a/FileSets/v3.40~10/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.inverterChargerDc.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.inverterChargerDc.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~10/OverviewHub.qml b/FileSets/v3.40~10/OverviewHub.qml new file mode 120000 index 00000000..156fd130 --- /dev/null +++ b/FileSets/v3.40~10/OverviewHub.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index fd22b360..00000000 --- a/FileSets/v3.40~10/OverviewHubEnhanced.qml +++ /dev/null @@ -1,1492 +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 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 () } - - 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 -////// 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 - } - 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 - 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 -////// 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: - { - if (hasAcSolarOnOut) - return "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvOnOutputMaxPower" - else - return "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvOnGridMaxPower" - } - connection: hasAcSolarOnOut ? sys.pvOnAcOut : hasAcSolarOnAcIn1 ? sys.pvOnAcIn1 : sys.pvOnAcIn2 - visible: showGauges && showAcSolar && !showDcAndAcSolar - } - DetailTarget { id: pvInverterTarget; detailsPage: "DetailPvInverter.qml" } - } - - OverviewConnection { - id: acInToMulti - visible: showAcInput - ballCount: 2 - path: straight - active: root.active - 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 || showAllTiles ) - 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 - value: -Utils.sign (noNoise (sys.pvCharger.power) + noNoise (sys.inverterChargerDc.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 - value: -flow(sys.inverterChargerDc.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 - value: Utils.sign(noNoise(sys.pvCharger.power) + noNoise(sys.inverterChargerDc.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: - 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: - 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: - 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 = "" - 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~10/OverviewHubEnhanced.qml b/FileSets/v3.40~10/OverviewHubEnhanced.qml new file mode 120000 index 00000000..f3015ab9 --- /dev/null +++ b/FileSets/v3.40~10/OverviewHubEnhanced.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 175a4bac..00000000 --- a/FileSets/v3.40~10/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 - 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 { // 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 - 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 - } - connection: sys.acInput - useInputCurrentLimit: true - maxForwardPowerParameter: "" - 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 - 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/v3.40~10/OverviewMobileEnhanced.qml b/FileSets/v3.40~10/OverviewMobileEnhanced.qml new file mode 120000 index 00000000..46ae0c55 --- /dev/null +++ b/FileSets/v3.40~10/OverviewMobileEnhanced.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 020c26f5..00000000 --- a/FileSets/v3.40~10/OverviewSolarCharger.qml +++ /dev/null @@ -1,58 +0,0 @@ -import QtQuick 1.1 - -Item { - id: root - -////// GuiMods — DarkMode - property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } - property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 - - default property alias values: blueSolarChargerBox.values - property alias title: blueSolarChargerBox.title - property bool showChargerIcon: true - - width: 155 - height: 115 - - MbIcon { - id: blueSolarChargerIcon - - iconId: "overview-bluesolar-charger" - anchors.bottom: root.bottom - visible: showChargerIcon - } - - OverviewBox { - id: blueSolarChargerBox - - height: root.height - title: qsTr("PV Power") -////// GuiMods — DarkMode - titleColor: !darkMode ? "#F4B350" : "#7A5928" - color: !darkMode ? "#F39C12" : "#794E09" - - anchors { - bottom: root.bottom - left: blueSolarChargerIcon.left; leftMargin: showChargerIcon ? 43 : 0 - right: parent.right - } - } - - MbIcon { - anchors { - bottom: blueSolarChargerBox.bottom; bottomMargin: 3 - right: blueSolarChargerBox.right; rightMargin: 3 - } - iconId: "overview-sun" - display: showChargerIcon - } - - MbIcon { - anchors { - bottom: blueSolarChargerBox.bottom; bottomMargin: 3 - left: parent.left; leftMargin: 2 - } - iconId: "overview-victron-logo-small" - display: !showChargerIcon - } -} diff --git a/FileSets/v3.40~10/OverviewSolarCharger.qml b/FileSets/v3.40~10/OverviewSolarCharger.qml new file mode 120000 index 00000000..597ead23 --- /dev/null +++ b/FileSets/v3.40~10/OverviewSolarCharger.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 98f931d2..00000000 --- a/FileSets/v3.40~10/OverviewSolarInverter.qml +++ /dev/null @@ -1,67 +0,0 @@ -import QtQuick 1.1 - -Rectangle { - id: root - -////// GuiMods — DarkMode - property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } - property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 - - default property alias values: pvInverterBox.values - property alias title: pvInverterBox.title - property bool showInverterIcon: true - - width: 155 - height: 115 - color: "transparent" - clip: true - - MbIcon { - id: pvInverterIcon - iconId: getDeviceIcon() - visible: showInverterIcon && getDeviceIcon() !== "" - anchors.bottom: parent.bottom - } - - OverviewBox { - id: pvInverterBox - - height: root.height - title: qsTr("PV Power") -////// GuiMods — DarkMode - titleColor: !darkMode ? "#F4B350" : "#7A5928" - color: !darkMode ? "#F39C12" : "#794E09" - - anchors { - bottom: parent.bottom - left: pvInverterIcon.left; leftMargin: pvInverterIcon.visible ? 32 : 0 - right: parent.right - } - - MbIcon { - iconId: getDeviceLogo() - visible: !showInverterIcon - anchors { - bottom: parent.bottom - left: parent.left - margins: 2 - } - } - } - - function getDeviceIcon() - { - var ids = sys.pvInvertersProductIds.text - if (ids.indexOf(0xA142) > -1) - return "overview-pvinverter-fronius" - return "" - } - - function getDeviceLogo() - { - var ids = sys.pvInvertersProductIds.text - if (ids.indexOf(0xA142) > -1) - return "overview-fronius-logo" - return "" - } -} diff --git a/FileSets/v3.40~10/OverviewSolarInverter.qml b/FileSets/v3.40~10/OverviewSolarInverter.qml new file mode 120000 index 00000000..61f0bff7 --- /dev/null +++ b/FileSets/v3.40~10/OverviewSolarInverter.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index e884d92c..00000000 --- a/FileSets/v3.40~10/OverviewTankDelegate.qml +++ /dev/null @@ -1,115 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils -import "tanksensor.js" as TankSensor - -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 string bindPrefix - property variant service: DBusServices.get(bindPrefix) - property variant info: TankSensor.info(fluidTypeItem.value) - - property VBusItem fluidTypeItem: VBusItem { bind: Utils.path(bindPrefix, "/FluidType") } - property VBusItem volumeUnit: VBusItem { bind: "com.victronenergy.settings/Settings/System/VolumeUnit" } - property VBusItem tankLevelItem: VBusItem { - bind: Utils.path(bindPrefix, "/Level") - decimals: 0 - unit: "%" - } - property VBusItem tankCapacityItem: VBusItem { - bind: Utils.path(bindPrefix, "/Capacity") - text: TankSensor.formatVolume(volumeUnit.value, value) - } - property VBusItem tankRemainingItem: VBusItem { - bind: Utils.path(bindPrefix, "/Remaining") - text: TankSensor.formatVolume(volumeUnit.value, value) - } - - width: 65 - height: 150 - - SvgRectangle { - id: mainRect - border { color: info.color; width: 2 } - width: root.width - height: root.height * 0.72 -////// GuiMods — DarkMode - color: !darkMode ? "white" : "#c0c0c0" - - SvgRectangle { - color: info.color - height: (parent.height - 4) * (tankLevelItem.value / 100) - width: parent.width - 5 - anchors { - left: parent.left; leftMargin: 2 - right: parent.right; rightMargin: 2 - bottom: parent.bottom; bottomMargin: 2 - } - } - - Text { - text: tankLevelItem.text - width: parent.width - font.pixelSize: width < 50 ? 12 : 18 - horizontalAlignment: Text.AlignHCenter - clip: true - anchors { - horizontalCenter: parent.horizontalCenter - top: parent.top; topMargin: 6 - } - } - - MbIcon { - iconId: info.icon - anchors.centerIn: parent - } - - Text { - text: tankRemainingItem.text - font.pixelSize: width < 50 ? 11 : 12 - width: parent.width - horizontalAlignment: Text.AlignHCenter - clip: true - anchors { - horizontalCenter: parent.horizontalCenter - bottom: _capacityText.top - } - } - - Text { - id: _capacityText - text: "(%1)".arg(tankCapacityItem.text) - font.pixelSize: width < 50 ? 11 : 12 - width: parent.width - horizontalAlignment: Text.AlignHCenter - clip: true - anchors { - horizontalCenter: parent.horizontalCenter - bottom: parent.bottom; bottomMargin: 6 - } - } - } - - Text { - id: _tankName - text: service.description -////// GuiMods — DarkMode - color: !darkMode ? "black" : "#e1e1e1" - width: parent.width + (parent.width < 50 ? 4 : 13) - horizontalAlignment: Text.AlignHCenter - wrapMode: Text.WrapAtWordBoundaryOrAnywhere - font.pixelSize: 12 - maximumLineCount: 2 - clip: true - anchors { - top: mainRect.bottom; topMargin: 6 - bottom: root.bottom - horizontalCenter: root.horizontalCenter - } - } -} diff --git a/FileSets/v3.40~10/OverviewTankDelegate.qml b/FileSets/v3.40~10/OverviewTankDelegate.qml new file mode 120000 index 00000000..51481985 --- /dev/null +++ b/FileSets/v3.40~10/OverviewTankDelegate.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 690918ec..00000000 --- a/FileSets/v3.40~10/OverviewTanks.qml +++ /dev/null @@ -1,269 +0,0 @@ -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils -import "tanksensor.js" as TankSensor - -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 int numberOfTanks: tanks.all.rowCount - property int visibleTanks: tanks.rowCount - property int maxTanksPerPage: 10 - property bool showAllTanksPage: numberOfTanks > 0 && numberOfTanks <= maxTanksPerPage - property int currentIndex - property int availableFluidTypes - - title: qsTr("Tanks") - clip: true - - ListModel { id: fluidModel } - - property TankModel tanks: TankModel { - all.onRowCountChanged: fluidTypesChanged() - all.onDataChanged: fluidTypesChanged() - } - - Component.onCompleted: fluidTypesChanged() - - // Background image when searching for tanks - Image { - id: loadingBackground - source: "image://theme/overview-tanks-loading" - anchors.fill: parent - visible: numberOfTanks === 0 - } - - Text { - text: qsTr("No tanks found") -////// GuiMods — DarkMode - color: !darkMode ? "#ffffff" : "#e1e1e1" - font.pixelSize: 25 - anchors.centerIn: parent - visible: numberOfTanks === 0 - } - - ListView { - id: titleList - width: root.width - height: 25 - orientation: ListView.Horizontal - spacing: 20 - - // Keep the currentItem in the middle of the listview - highlightRangeMode: ListView.StrictlyEnforceRange - preferredHighlightBegin: currentItem ? width / 2 - currentItem.width / 2 : 0 - preferredHighlightEnd: currentItem ? width / 2 + currentItem.width / 2 : 0 - - model: fluidModel - interactive: false - anchors { top: parent.top; topMargin: 16 } - currentIndex: root.currentIndex - visible: numberOfTanks > 0 - - delegate: Text { - text: fluidName - height: 25 - font.pixelSize: 16 -////// GuiMods — DarkMode - opacity: ListView.isCurrentItem ? 1 : (!darkMode ? 0.3 : 0.5) - verticalAlignment: Text.AlignVCenter - scale: ListView.isCurrentItem ? 1.25 : 1 -////// GuiMods — DarkMode - color: !darkMode ? "black" : "#e1e1e1" - - Behavior on scale { - NumberAnimation { duration: 150 } - } - - MouseArea { - anchors.fill: parent - onClicked: setCurrentIndex(model.index) - } - } - - // Fade the sides of the title list - Rectangle { - height: parent.width / 3 - width: parent.height - y: 25 - transform: Rotation { origin.x: 0; origin.y: 0; angle: -90} - gradient: Gradient { -////// GuiMods — DarkMode - GradientStop { position: 0.7; color: !darkMode ? "white" : "#202020" } - GradientStop { position: 1; color: "transparent" } - } - } - - Rectangle { - height: parent.width / 3 - width: parent.height - x: parent.width - transform: Rotation { origin.x: 0; origin.y: 0; angle: 90} - gradient: Gradient { -////// GuiMods — DarkMode - GradientStop { position: 0.7; color: !darkMode ? "white" : "#202020" } - GradientStop { position: 1; color: "transparent" } - } - } - - // touch buttons for selecting a tank type - MbIcon { -////// GuiMods — DarkMode - iconId: darkMode ? "icon-toolbar-enter" : "icon-toolbar-enter-active" - rotation: 180 - anchors { - left: parent.left; leftMargin: 40 - verticalCenter: parent.verticalCenter - } - - MouseArea { - onClicked: decreaseIndex() - anchors { - fill: parent; margins: -16 - } - } - } - - MbIcon { -////// GuiMods — DarkMode - iconId: darkMode ? "icon-toolbar-enter" : "icon-toolbar-enter-active" - anchors { - right: parent.right; rightMargin: 40 - verticalCenter: parent.verticalCenter - } - - MouseArea { - onClicked: increaseIndex() - anchors { - fill: parent; margins: -16 - } - } - } - } - - Flow { - id: tanksFlow - spacing: visibleTanks > 8 ? 10 : 15 - - anchors { - horizontalCenter: parent.horizontalCenter - bottom: navigation.top; bottomMargin: 4 - top: titleList.bottom; topMargin: 16 - } - - Repeater { - id: tanksRepeater - model: tanks - delegate: OverviewTankDelegate { - bindPrefix: buddy.id - width: Math.min(65, Math.max((470 / visibleTanks - tanksFlow.spacing) + tanksFlow.spacing / visibleTanks, 35)) - height: tanksFlow.height - } - } - } - - Flow { - id: navigation - height: 41 - spacing: 15 - visible: numberOfTanks > 0 - - anchors { - bottom: parent.bottom; bottomMargin: 16 - horizontalCenter: parent.horizontalCenter - } - - Repeater { - model: fluidModel - delegate: OverviewRoundButton { - iconId: fluidIcon - separatorLine.visible: model.index === 0 && showAllTanksPage - onClicked: setCurrentIndex(index) - } - } - } - - // This is a seperate item, to disable the default left / right action, showing the toolbar - Item { - Keys.onLeftPressed: decreaseIndex() - Keys.onRightPressed: increaseIndex() - focus: root.active - } - - // Handle index change and set fluid type filter - function setCurrentIndex(index) - { - currentIndex = (index + fluidModel.count) % fluidModel.count - - // Note: the keys can always be pressed even if fluidModel is empty, prevent - // getting unexisting elements. - if (fluidModel.count === 0) { - tanks.filterRegExp = "" - } else { - var fluidType = fluidModel.get(currentIndex).fluidType - tanks.filterRegExp = fluidType >= 0 ? "^" + fluidType + "$" : "" - } - } - - function increaseIndex() - { - setCurrentIndex(currentIndex + 1) - } - - function decreaseIndex() - { - setCurrentIndex(currentIndex - 1) - } - - function fluidTypesChanged() - { - var fluids = 0 - for (var i = 0; i < numberOfTanks; i++) { - var val = tanks.all.getValue(i, VeQItemTableModel.ValueColumn) - if (val !== undefined) - fluids |= (1 << val) - } - - if (availableFluidTypes !== fluids) { - availableFluidTypes = fluids - updateFluidsModel() - } - } - - function updateFluidsModel() - { - var selectedType = fluidModel.count ? fluidModel.get(currentIndex).fluidType : -1 - var index = 0 - - fluidModel.clear() - if (showAllTanksPage) { - fluidModel.append({ fluidType: -1, fluidName: qsTr("All"), fluidIcon: "overview-tanks-all" }) - index = 1 - } - - var fluids = availableFluidTypes - var fluidType = 0 - var typeFound = false - while (fluids != 0) { - if (fluids & 1) { - var info = TankSensor.info(fluidType) - fluidModel.append({ fluidType: fluidType, fluidName: info.name, fluidIcon: info.icon }) - if (selectedType === fluidType) { - setCurrentIndex(index) - typeFound = true - } - index++ - } - fluids = fluids >> 1 - fluidType++ - } - - // If the selected tanks all disappeared, select all again / the first type - if (!typeFound) - setCurrentIndex(0) - } -} diff --git a/FileSets/v3.40~10/OverviewTanks.qml b/FileSets/v3.40~10/OverviewTanks.qml new file mode 120000 index 00000000..8d5563ca --- /dev/null +++ b/FileSets/v3.40~10/OverviewTanks.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 781e163c..00000000 --- a/FileSets/v3.40~10/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~10/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~10/OverviewTanksTempsDigInputs.qml new file mode 120000 index 00000000..26dd2c44 --- /dev/null +++ b/FileSets/v3.40~10/OverviewTanksTempsDigInputs.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 3a9483ca..00000000 --- a/FileSets/v3.40~10/PageDigitalInput.qml +++ /dev/null @@ -1,147 +0,0 @@ -//// modified for ExtTransferSwitch package - -import QtQuick 1.1 -import com.victron.velib 1.0 -import "utils.js" as Utils - -MbPage { - id: root - - property variant service - property string bindPrefix - property string settingsBindPreffix: "com.victronenergy.settings/Settings/DigitalInput/" + inputNumber - property int inputNumber: instance.valid ? instance.value : 0 - - title: getType(service.description) - summary: getState(state.item.value) - - VBusItem { - id: instance - bind: service.path("/DeviceInstance") - } - -//// added for ExtTransferSwitch package - VBusItem - { - id: ac2connectedItem - bind: Utils.path ("com.victronenergy.system", "/Ac/In/1/Connected") - } - property bool showTransferSwitchConnection: ac2connectedItem.valid - VBusItem - { - id: typeItem - bind: service.path("/Type") - } - property bool isTransferSwitch: typeItem.valid && typeItem.value == 12 - - // Handle translations - function getType(type){ - switch (type) { - case "Disabled": - return qsTr("Disabled") - case "Pulse meter": - return qsTr("Pulse meter") - case "Door alarm": - return qsTr("Door alarm") - case "Bilge pump": - return qsTr("Bilge pump") - case "Bilge alarm": - return qsTr("Bilge alarm") - case "Burglar alarm": - return qsTr("Burglar alarm") - case "Smoke alarm": - return qsTr("Smoke alarm") - case "Fire alarm": - return qsTr("Fire alarm") - case "CO2 alarm": - return qsTr("CO2 alarm") - case "Generator": - return qsTr("Generator") -//// added for ExtTransferSwitch package - case "TransferSwitch": - return qsTr("External transfer switch") - } - return type; - } - - 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") - } - - return qsTr("Unknown") - } - - model: VisibleItemModel { - MbItemValue { - id: state - description: qsTr("State") - item.bind: service.path("/State") - item.text: getState(item.value) - } - - MbSubMenu { - id: setupMenu - description: qsTr("Setup") - subpage: Component { - PageDigitalInputSetup { - bindPrefix: root.settingsBindPreffix - } - } - } - - MbSubMenu { - id: deviceMenu - description: qsTr("Device") - subpage: Component { - PageDeviceInfo { - title: deviceMenu.description - bindPrefix: root.bindPrefix - } - } - } - -//// added for ExtTransferSwitch package - MbItemOptions - { - id: extTransferSwitch - description: qsTr("External transfer switch connection") - bind: Utils.path ("com.victronenergy.settings/Settings", "/TransferSwitch/TransferSwitchOnAc2") - possibleValues: - [ - MbOption {description: qsTr("AC 1 in"); value: 0}, - MbOption {description: qsTr("AC 2 in"); value: 1} - ] - visible: root.isTransferSwitch && root.showTransferSwitchConnection - } - } -} diff --git a/FileSets/v3.40~10/PageDigitalInput.qml b/FileSets/v3.40~10/PageDigitalInput.qml new file mode 120000 index 00000000..a9b9e513 --- /dev/null +++ b/FileSets/v3.40~10/PageDigitalInput.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index c9670db0..00000000 --- a/FileSets/v3.40~10/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~10/PageGenerator.qml b/FileSets/v3.40~10/PageGenerator.qml new file mode 120000 index 00000000..7ecabc54 --- /dev/null +++ b/FileSets/v3.40~10/PageGenerator.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 31ec72ff..00000000 --- a/FileSets/v3.40~10/PageMain.qml +++ /dev/null @@ -1,285 +0,0 @@ -//////// GuiMods 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") - -//////// GuiMods put Settings, Notifications, Remove disconnected... at top of 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 { -//////// GuiMods put Settings, Notifications, Remove disconnected... at top of list - VisibleItemModel { - MbSubMenu { - description: qsTr("Settings") - subpage: Component { PageSettings {} } - show: settingsAtTop - } - - MbSubMenu { - id: menuNotificationsTop - description: qsTr("Notifications") - item: VBusItem { value: menuNotifications.subpage.summary } - subpage: 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() - } - } - } -//////// end GuiMods put Settings, Notifications, Remove disconnected... at top of list - - VisualDataModel { - model: VeSortFilterProxyModel { - model: DeviceList { - id: deviceList - onRowsAboutToBeRemoved: { - for (var i = first; i <= last; i++) - deviceList.page(i).destroy() - } - } - sortRole: DeviceList.DescriptionRole - dynamicSortFilter: true - naturalSort: true - sortCaseSensitivity: Qt.CaseInsensitive - } - - delegate: MbDevice { - iconId: "icon-toolbar-enter" - service: model.page.service - subpage: model.page - } - } - VisibleItemModel { - MbSubMenu { - id: menuNotifications - description: qsTr("Notifications") - item: VBusItem { value: menuNotifications.subpage.summary } - subpage: PageNotifications { } -//////// GuiMods hide this if added at top - show: !settingsAtTop - } - - MbSubMenu { - description: qsTr("Settings") - subpage: Component { PageSettings {} } -//////// GuiMods hide this if added at top - show: !settingsAtTop - } - - MbOK { - description: qsTr("Remove disconnected devices") - value: qsTr("Press to remove") -//////// GuiMods hide this if added at top - show: !settingsAtTop && deviceList.disconnectedDevices != 0 - editable: true - - function clicked() { - listview.decrementCurrentIndex() - deviceList.removeDisconnected() - } - } - } - } - - Component { - id: vebusPage - PageVebus {} - } - - Component { - id: multiRsPage - PageMultiRs {} - } - - Component { - id: batteryPage - PageBattery {} - } - - Component { - id: solarChargerPage - PageSolarCharger {} - } - - Component { - id: acInPage - PageAcIn {} - } - - Component { - id: acChargerPage - PageAcCharger {} - } - - Component { - id: tankPage - PageTankSensor {} - } - - Component { - id: motorDrivePage - PageMotorDrive {} - } - - Component { - id: inverterPage - PageInverter {} - } - - Component { - id: pulseCounterPage - PagePulseCounter {} - } - - Component { - id: digitalInputPage - PageDigitalInput {} - } - - Component { - id: temperatureSensorPage - PageTemperatureSensor {} - } - - Component { - id: unsupportedDevicePage - PageUnsupportedDevice {} - } - - Component { - id: meteoDevicePage - PageMeteo {} - } - - Component { - id: evChargerPage - PageEvCharger {} - } - - Component { - id: dcMeterPage - PageDcMeter {} - } - - Component { - id: alternatorPage - PageAlternator {} - } - - Component { - id: dcDcConverterPage - PageDcDcConverter {} - } - - function addService(service) - { - var name = service.name - - var page - switch(service.type) - { - case DBusService.DBUS_SERVICE_MULTI: - page = vebusPage - break; - case DBusService.DBUS_SERVICE_MULTI_RS: - page = multiRsPage - break; - case DBusService.DBUS_SERVICE_BATTERY: - page = batteryPage - break; - case DBusService.DBUS_SERVICE_SOLAR_CHARGER: - page = solarChargerPage - break; - case DBusService.DBUS_SERVICE_PV_INVERTER: - page = acInPage - break; - case DBusService.DBUS_SERVICE_AC_CHARGER: - page = acChargerPage - break; - case DBusService.DBUS_SERVICE_TANK: - page = tankPage - break; - case DBusService.DBUS_SERVICE_GRIDMETER: - page = acInPage - break - case DBusService.DBUS_SERVICE_GENSET: - page = acInPage - break - case DBusService.DBUS_SERVICE_MOTOR_DRIVE: - page = motorDrivePage - break - case DBusService.DBUS_SERVICE_INVERTER: - page = inverterPage - break; - case DBusService.DBUS_SERVICE_TEMPERATURE_SENSOR: - page = temperatureSensorPage - break; - case DBusService.DBUS_SERVICE_SYSTEM_CALC: - return; - case DBusService.DBUS_SERVICE_DIGITAL_INPUT: - page = digitalInputPage - break; - case DBusService.DBUS_SERVICE_PULSE_COUNTER: - page = pulseCounterPage - break; - case DBusService.DBUS_SERVICE_UNSUPPORTED: - page = unsupportedDevicePage - break; - case DBusService.DBUS_SERVICE_METEO: - page = meteoDevicePage - break; - case DBusService.DBUS_SERVICE_VECAN: - return; - case DBusService.DBUS_SERVICE_EVCHARGER: - page = evChargerPage - break - case DBusService.DBUS_SERVICE_ACLOAD: - page = acInPage - break - case DBusService.DBUS_SERVICE_HUB4: - return; - case DBusService.DBUS_SERVICE_FUELCELL: - case DBusService.DBUS_SERVICE_DCSOURCE: - case DBusService.DBUS_SERVICE_DCLOAD: - case DBusService.DBUS_SERVICE_DCSYSTEM: - page = dcMeterPage - break - case DBusService.DBUS_SERVICE_ALTERNATOR: - page = alternatorPage - break - case DBusService.DBUS_SERVICE_DCDC: - page = dcDcConverterPage - break - default: - console.log("unknown service " + name) - return; - } - - deviceList.append(service, page.createObject(root, {service: service, bindPrefix: service.name})) - } - - Component.onCompleted: { - for (var i = 0; i < DBusServices.count; i++) - addService(DBusServices.at(i)) - } - - Connections { - target: DBusServices - onDbusServiceFound: addService(service) - } -} diff --git a/FileSets/v3.40~10/PageMain.qml b/FileSets/v3.40~10/PageMain.qml new file mode 120000 index 00000000..0e32fc35 --- /dev/null +++ b/FileSets/v3.40~10/PageMain.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index ad1b1187..00000000 --- a/FileSets/v3.40~10/PageSettingsDisplay.qml +++ /dev/null @@ -1,135 +0,0 @@ -//////// 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" - - VBusItem { - id: autoBrightnessSetting - bind: Utils.path(bindPrefix, "/AutoBrightness") - isSetting: true - - // max is set to 0 if AutoBrightness is not supported. - // The setting used to be added unconditionally. - property bool hasAutoBrightness: valid && max === 1 - } - - model: VisibleItemModel { - MbSwitch { - id: autoBrightness - name: qsTr("Adaptive brightness") - bind: Utils.path(bindPrefix, "/AutoBrightness") - show: autoBrightnessSetting.hasAutoBrightness - } - - MbItemSlider { - id: backlight - show: item.valid && (!autoBrightnessSetting.hasAutoBrightness || autoBrightnessSetting.value !== 1) - icondId: "icon-items-brightness" - directUpdates: true - item { - bind: Utils.path(bindPrefix, "/Brightness") - isSetting: true - step: 1 - } - writeAccessLevel: User.AccessUser - } - - MbItemOptions { - show: vePlatform.hasScreenSaver - description: qsTr("Display off time") - bind: Utils.path(bindPrefix, "/DisplayOff") - writeAccessLevel: User.AccessUser - possibleValues: [ - MbOption { description: qsTr("10 sec"); value: 10 }, - MbOption { description: qsTr("30 sec"); value: 30 }, - MbOption { description: qsTr("1 min"); value: 60 }, - MbOption { description: qsTr("10 min"); value: 600 }, - MbOption { description: qsTr("30 min"); value: 1800 }, - MbOption { description: qsTr("Never"); value: 0 } - ] - } - - 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" } - } - - 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") - 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. - possibleValues: [ - MbOptionLang { description: "English"; value: "en" }, - MbOptionLang { description: "Čeština"; value: "cs" }, - MbOptionLang { description: "Dansk"; value: "da" }, - MbOptionLang { description: "Deutsch"; value: "de" }, - MbOptionLang { description: "Español"; value: "es" }, - 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: "uk" }, - MbOptionLang { description: "中文"; value: "zh" }, - MbOptionLang { description: "العربية"; value: "ar" } - ] - } - - MbSubMenu { - description: qsTr("Units") - subpage: Component { - PageSettingsDisplayUnits { - title: qsTr("Units") - } - } - } - - MbItemOptions { - property VBusItem updateFeed: VBusItem { bind: "com.victronenergy.settings/Settings/System/ReleaseType" } - show: vePlatform.isGuiv2Installed() && vePlatform.displayPresent() && updateFeed.value >= Updater.FirmwareCandidate - bind: "com.victronenergy.settings/Settings/Gui/RunningVersion" - description: "Onscreen UI (GX Touch & Ekrano)" - writeAccessLevel: User.AccessUser - possibleValues: [ - MbOption { description: "Standard version"; value: 1 }, - MbOption { description: "Gui-v2 version (beta, check the announcement first)"; value: 2 } - ] - onOptionSelected: { - if (newValue === 2) { - vePlatform.splash("Starting the beta UI") - } - } - } - } -} diff --git a/FileSets/v3.40~10/PageSettingsDisplay.qml b/FileSets/v3.40~10/PageSettingsDisplay.qml new file mode 120000 index 00000000..cf8c2070 --- /dev/null +++ b/FileSets/v3.40~10/PageSettingsDisplay.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 79afbd25..00000000 --- a/FileSets/v3.40~10/PageSettingsGenerator.qml +++ /dev/null @@ -1,129 +0,0 @@ -//// GuiMods -//// 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 - } - } - - MbSubMenu { - show: capabilities.value & warmupCapability - description: qsTr("Warm-up & cool-down") - subpage: - Component { - PageSettingsGeneratorWarmup { - title: qsTr("Warm-up & cool-down") - } - } - } - - MbSwitch { - 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 { - name: qsTr("Alarm when generator is not in auto start mode") - bind: Utils.path(settingsBindPrefix, "/Alarms/AutoStartDisabled") - onClicked: { - if (!checked) { - toast.createToast(qsTr("An alarm will be triggered when auto start function is left disabled for more than 10 minutes."), 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 - } - - MbSubMenu { - id: runtimePage - description: qsTr("Run time and service") - subpage: - Component { - PageGeneratorRuntimeService { - title: qsTr("Run time and service") - startStopBindPrefix: root.startStopBindPrefix - settingsBindPrefix: root.settingsBindPrefix - } - } - } - } -} diff --git a/FileSets/v3.40~10/PageSettingsGenerator.qml b/FileSets/v3.40~10/PageSettingsGenerator.qml new file mode 120000 index 00000000..efd8d051 --- /dev/null +++ b/FileSets/v3.40~10/PageSettingsGenerator.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 420a42ac..00000000 --- a/FileSets/v3.40~10/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: 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.40~10/PageSettingsGuiMods.qml b/FileSets/v3.40~10/PageSettingsGuiMods.qml new file mode 120000 index 00000000..50a2393d --- /dev/null +++ b/FileSets/v3.40~10/PageSettingsGuiMods.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 60d9d900..00000000 --- a/FileSets/v3.40~10/PageSettingsRelay.qml +++ /dev/null @@ -1,515 +0,0 @@ -//////// modified to -//////// add up to 18 relays -//////// 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 + (hasRelay2 ? qsTr("Relay 1") : qsTr("Relay")) + suffix + " " + qsTr("On") - else - return prefix + qsTr("Relay") + " " + relayNumber + suffix + " " + qsTr("On") - } - - model: VisibleItemModel { - 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: 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/v3.40~10/PageSettingsRelay.qml b/FileSets/v3.40~10/PageSettingsRelay.qml new file mode 120000 index 00000000..337482f3 --- /dev/null +++ b/FileSets/v3.40~10/PageSettingsRelay.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 91166066..00000000 --- a/FileSets/v3.40~10/PowerGauge.qml +++ /dev/null @@ -1,297 +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 - - property bool reversePower: false - property bool useInputCurrentLimit: false - property variant endLabelFontSize: 16 - property color endLabelBackgroundColor: "transparent" - - property int reportedPhaseCount: connection == undefined ? 0 : connection.phaseCount == undefined || ! connection.phaseCount.valid ? 1 : connection.phaseCount.value - property int phaseCount: reportedPhaseCount < 2 ? reportedPhaseCount : (connection.isAcOutput ? connection.l2AndL1OutSummed : connection.splitPhaseL2PassthruDisabled) ? 1 : connection.phaseCount.value - - property string maxForwardPowerParameter: "" - VBusItem { id: maxForwardLimitItem; bind: root.maxForwardPowerParameter } - - 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 maxForwardLimit: useInputCurrentLimit ? inPowerLimit : maxForwardLimitItem.valid ? maxForwardLimitItem.value : 0 - 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 - else - currentValue = 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 (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 (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~10/PowerGauge.qml b/FileSets/v3.40~10/PowerGauge.qml new file mode 120000 index 00000000..daebe48d --- /dev/null +++ b/FileSets/v3.40~10/PowerGauge.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index a28bc1a8..00000000 --- a/FileSets/v3.40~10/Tile.qml +++ /dev/null @@ -1,65 +0,0 @@ -import QtQuick 1.1 - -Rectangle { - id: root - -////// GuiMods — DarkMode - property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } - property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 - - color: "#009ec6" - border.width: 2 -////// GuiMods — DarkMode - border.color: !darkMode ? "#fff" : "#202020" - clip: true - - property string title - property alias values: column.children - property bool readOnly: true - property bool editable: false - property bool editMode: false - property bool isCurrentItem: ListView.isCurrentItem - property int contentHeight: column.y + column.height - property bool show: true - - Text { - id: titleField - font.pixelSize: 13 - text: title -////// GuiMods — DarkMode - color: !darkMode ? "white" : "#ddd" - height: text === "" ? 0 : paintedHeight - anchors { - top: parent.top; topMargin: 5 - left: parent.left; leftMargin: 5 - } - } - - Rectangle { - id: titleLine - width: parent.width - 10 - height: 1 - visible: title !== "" -////// GuiMods — DarkMode - color: !darkMode ? "white" : "#ddd" - anchors { - top: titleField.bottom - left: titleField.left - } - } - - Column { - id: column - anchors { - top: titleLine.bottom; topMargin: 3 - horizontalCenter: parent.horizontalCenter - } - } - - MbIcon { - id: editIcon - iconId: root.isCurrentItem ? "icon-tile-edit-active" : "icon-tile-edit" - visible: (root.isCurrentItem || root.focus) && root.editable && !editMode - anchors { right: parent.right; bottom: column.bottom; margins: 3} - } -} diff --git a/FileSets/v3.40~10/Tile.qml b/FileSets/v3.40~10/Tile.qml new file mode 120000 index 00000000..5c566101 --- /dev/null +++ b/FileSets/v3.40~10/Tile.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 492b8b2d..00000000 --- a/FileSets/v3.40~10/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~10/TileDigIn.qml b/FileSets/v3.40~10/TileDigIn.qml new file mode 120000 index 00000000..fc269e05 --- /dev/null +++ b/FileSets/v3.40~10/TileDigIn.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 3c6bb0ca..00000000 --- a/FileSets/v3.40~10/TileRelay.qml +++ /dev/null @@ -1,501 +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: 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") - 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 (!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/v3.40~10/TileRelay.qml b/FileSets/v3.40~10/TileRelay.qml new file mode 120000 index 00000000..2ebdf179 --- /dev/null +++ b/FileSets/v3.40~10/TileRelay.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index bce0789c..00000000 --- a/FileSets/v3.40~10/TileText.qml +++ /dev/null @@ -1,13 +0,0 @@ -import QtQuick 1.1 - -Text { -////// GuiMods — DarkMode - property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } - property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 - - font.pixelSize: 14 -////// GuiMods — DarkMode - color: !darkMode ? "white" : "#e1e1e1" - width: parent.width - horizontalAlignment: Text.AlignHCenter -} diff --git a/FileSets/v3.40~10/TileText.qml b/FileSets/v3.40~10/TileText.qml new file mode 120000 index 00000000..e5901c0b --- /dev/null +++ b/FileSets/v3.40~10/TileText.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 21fb2a18..00000000 --- a/FileSets/v3.40~10/attributes.csv +++ /dev/null @@ -1,735 +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,/Devices/0/Settings/AssistCurrentBoostFactor,d,,106,uint16,100,W -com.victronenergy.vebus,/Devices/1/Settings/AssistCurrentBoostFactor,d,,107,uint16,100,W -com.victronenergy.vebus,/Devices/2/Settings/AssistCurrentBoostFactor,d,,108,uint16,100,W -com.victronenergy.vebus,/Devices/3/Settings/AssistCurrentBoostFactor,d,,109,uint16,100,W -com.victronenergy.vebus,/Devices/4/Settings/AssistCurrentBoostFactor,d,,110,uint16,100,W -com.victronenergy.vebus,/Devices/5/Settings/AssistCurrentBoostFactor,d,,111,uint16,100,W -com.victronenergy.vebus,/Devices/6/Settings/AssistCurrentBoostFactor,d,,112,uint16,100,W -com.victronenergy.vebus,/Devices/7/Settings/AssistCurrentBoostFactor,d,,113,uint16,100,W -com.victronenergy.vebus,/Devices/8/Settings/AssistCurrentBoostFactor,d,,114,uint16,100,W -com.victronenergy.vebus,/Devices/9/Settings/AssistCurrentBoostFactor,d,,115,uint16,100,W -com.victronenergy.vebus,/Devices/10/Settings/AssistCurrentBoostFactor,d,,116,uint16,100,W -com.victronenergy.vebus,/Devices/11/Settings/AssistCurrentBoostFactor,d,,117,uint16,100,W -com.victronenergy.vebus,/Devices/0/Settings/InverterOutputVoltage,d,V AC,118,uint16,100,W -com.victronenergy.vebus,/Devices/1/Settings/InverterOutputVoltage,d,V AC,119,uint16,100,W -com.victronenergy.vebus,/Devices/2/Settings/InverterOutputVoltage,d,V AC,120,uint16,100,W -com.victronenergy.vebus,/Devices/3/Settings/InverterOutputVoltage,d,V AC,121,uint16,100,W -com.victronenergy.vebus,/Devices/4/Settings/InverterOutputVoltage,d,V AC,122,uint16,100,W -com.victronenergy.vebus,/Devices/5/Settings/InverterOutputVoltage,d,V AC,123,uint16,100,W -com.victronenergy.vebus,/Devices/6/Settings/InverterOutputVoltage,d,V AC,124,uint16,100,W -com.victronenergy.vebus,/Devices/7/Settings/InverterOutputVoltage,d,V AC,125,uint16,100,W -com.victronenergy.vebus,/Devices/8/Settings/InverterOutputVoltage,d,V AC,126,uint16,100,W -com.victronenergy.vebus,/Devices/9/Settings/InverterOutputVoltage,d,V AC,127,uint16,100,W -com.victronenergy.vebus,/Devices/10/Settings/InverterOutputVoltage,d,V AC,128,uint16,100,W -com.victronenergy.vebus,/Devices/11/Settings/InverterOutputVoltage,d,V AC,129,uint16,100,W -com.victronenergy.vebus,/Devices/0/Settings/PowerAssistEnabled,d,,130,uint16,1,R -com.victronenergy.vebus,/Devices/1/Settings/PowerAssistEnabled,d,,131,uint16,1,R -com.victronenergy.vebus,/Devices/2/Settings/PowerAssistEnabled,d,,132,uint16,1,R -com.victronenergy.vebus,/Devices/3/Settings/PowerAssistEnabled,d,,133,uint16,1,R -com.victronenergy.vebus,/Devices/4/Settings/PowerAssistEnabled,d,,134,uint16,1,R -com.victronenergy.vebus,/Devices/5/Settings/PowerAssistEnabled,d,,135,uint16,1,R -com.victronenergy.vebus,/Devices/6/Settings/PowerAssistEnabled,d,,136,uint16,1,R -com.victronenergy.vebus,/Devices/7/Settings/PowerAssistEnabled,d,,137,uint16,1,R -com.victronenergy.vebus,/Devices/8/Settings/PowerAssistEnabled,d,,138,uint16,1,R -com.victronenergy.vebus,/Devices/9/Settings/PowerAssistEnabled,d,,139,uint16,1,R -com.victronenergy.vebus,/Devices/10/Settings/PowerAssistEnabled,d,,140,uint16,1,R -com.victronenergy.vebus,/Devices/11/Settings/PowerAssistEnabled,d,,141,uint16,1,R -com.victronenergy.vebus,/Devices/0/Settings/UpsFunction,u,,142,uint16,1,R -com.victronenergy.vebus,/Devices/1/Settings/UpsFunction,u,,143,uint16,1,R -com.victronenergy.vebus,/Devices/2/Settings/UpsFunction,u,,144,uint16,1,R -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.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.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=Disconnected;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.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=Disconnected;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;11=ExtTransferSwitch,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 fault;9=Welded contacts;10=CP Input shorted;11=Residual current detected;12=Under voltage detected;13=Overvoltage detected;14=Overheating detected,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,uint16,10,R -com.victronenergy.multi,/Ac/In/1/L2/I,d,A AC,4504,uint16,10,R -com.victronenergy.multi,/Ac/In/1/L3/I,d,A AC,4505,uint16,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,uint16,10,R -com.victronenergy.multi,/Ac/Out/L2/I,d,A AC,4514,uint16,10,R -com.victronenergy.multi,/Ac/Out/L3/I,d,A AC,4515,uint16,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 diff --git a/FileSets/v3.40~10/attributes.csv b/FileSets/v3.40~10/attributes.csv new file mode 120000 index 00000000..e4d1dc3a --- /dev/null +++ b/FileSets/v3.40~10/attributes.csv @@ -0,0 +1 @@ +../v3.40~11/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 100755 index a49e9c6e..00000000 --- a/FileSets/v3.40~10/dbus_digitalinputs.py +++ /dev/null @@ -1,651 +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.23' -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']) - - -class Generator(PinAlarm): - _product_name = "Generator" - type_id = 9 - translation = 5 # running, stopped - - def __init__(self, *args, **kwargs): - super(Generator, self).__init__(*args, **kwargs) - # Periodically rewrite the generator selection. The Multi may reset - # causing this to be lost, or a race condition on startup may cause - # it to not be set properly. - self._timer = GLib.timeout_add(30000, - lambda: self.select_generator(self.level ^ self.settings['invert'] ^ 1) or True) - -#### added for ExtTransferSwitch package - self.mainVeBusServiceItem = None -#### end added for ExtTransferSwitch package - - - def select_generator(self, v): - - # Find all vebus services, and let them know - try: - services = [n for n in self.bus.list_names() if n.startswith( - 'com.victronenergy.vebus.')] - for n in services: -#### added for ExtTransferSwitch package - # skip this service if it is the main VE.Bus device - # processing for that is handled in ExtTransferSwitch - try: - if self.mainVeBusServiceItem == None: - self.mainVeBusServiceItem = VeDbusItemImport(self.bus, - "com.victronenergy.service", "/VebusService") - if n == self.mainVeBusService.get_value (): - continue - except: - pass -#### end added for ExtTransferSwitch package - - self.bus.call_async(n, '/Ac/Control/RemoteGeneratorSelected', None, - 'SetValue', 'v', [v], None, None) - except dbus.exceptions.DBusException: - print ("DBus exception setting RemoteGeneratorSelected") - traceback.print_exc() - - def toggle(self, level): - super(Generator, self).toggle(level) - - # Follow the same inversion sense as for display - self.select_generator(level ^ self.settings['invert'] ^ 1) - - def deactivate(self): - super(Generator, self).deactivate() - # When deactivating, reset the generator selection state - self.select_generator(0) - - # And kill the periodic job - if self._timer is not None: - GLib.source_remove(self._timer) - self._timer = None - -# 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 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.40~10/dbus_digitalinputs.py b/FileSets/v3.40~10/dbus_digitalinputs.py new file mode 120000 index 00000000..085682ce --- /dev/null +++ b/FileSets/v3.40~10/dbus_digitalinputs.py @@ -0,0 +1 @@ +../v3.40~11/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 100755 index d6f8f00d..00000000 --- a/FileSets/v3.40~10/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 -#### 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 genset -from version import softwareversion - -class Generator(object): - def __init__(self): - self._exit = False - self._instances = {} - self._modules = [relay, genset] - - # 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], - 'serviceinterval': ['/Settings/{0}/ServiceInterval', 0, 0, 0], - 'lastservicereset': ['/Settings/{0}/LastServiceReset', 0, 0, 0], - 'accumulateddaily': ['/Settings/{0}/AccumulatedDaily', '', 0, 0, True], - 'accumulatedtotal': ['/Settings/{0}/AccumulatedTotal', 0, 0, 0, True], # Internal, can't be reset by the user - 'accumulatedtotalOffset': ['/Settings/{0}/AccumulatedTotalOffset', 0, 0, 0], # For calculating user runtime -#### GuiMods - '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], - 'socstarttimer': ['/Settings/{0}/Soc/StartTimer', 0, 0, 10000], - 'socstoptimer': ['/Settings/{0}/Soc/StopTimer', 0, 0, 10000], - '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], - 'autostartdisabledalarm': ['/Settings/{0}/Alarms/AutoStartDisabled', 0, 0, 1], - # Warm-up and Cool-down - 'warmuptime': ['/Settings/{0}/WarmUpTime', 0, 0, 600], - 'cooldowntime': ['/Settings/{0}/CoolDownTime', 0, 0, 600], - 'generatorstoptime': ['/Settings/{0}/GeneratorStopTime', 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) - - 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) - 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.40~10/dbus_generator.py b/FileSets/v3.40~10/dbus_generator.py new file mode 120000 index 00000000..699b4b49 --- /dev/null +++ b/FileSets/v3.40~10/dbus_generator.py @@ -0,0 +1 @@ +../v3.40~11/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 100644 index d300de63..00000000 --- a/FileSets/v3.40~10/main.qml +++ /dev/null @@ -1,598 +0,0 @@ -//////// Modified to hide the OverviewTiles page -//////// Modified to substitute flow overview pages - -import QtQuick 1.1 - -import Qt.labs.components.native 1.0 -import com.victron.velib 1.0 -import "utils.js" as Utils - -PageStackWindow { - id: rootWindow - - gpsConnected: gpsFix.value === 1 - onCompletedChanged: checkAlarm() - initialPage: PageMain {} - - property VeQuickItem gpsService: VeQuickItem { uid: "dbus/com.victronenergy.system/GpsService" } - property VeQuickItem gpsFix: VeQuickItem { uid: Utils.path("dbus/", gpsService.value, "/Fix") } - property bool completed: false - property bool alarm: alarmNotification.valid ? alarmNotification.value : 0 - property bool showAlert: alertNotification.valid ? alertNotification.value : 0 -//////// 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 : "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 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 - } - 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: selectGeneratorOverview () - } - - VBusItem - { - id: generatorOverviewEnhanced - bind: "com.victronenergy.settings/Settings/GuiMods/UseEnhancedGeneratorOverview" - onValueChanged: selectGeneratorOverview () - } - - VBusItem { - bind: "com.victronenergy.generator.startstop1/GensetProductId" - onValueChanged: { - // Show specific overview for FischerPanda - extraOverview("OverviewGeneratorFp.qml", value === 0xB040) - - // Show generic overview for ComAp and DSE - extraOverview("OverviewGeneratorOther.qml", - [0xB044, 0xB046].indexOf(value) > -1) - - // Switch to FP overview in case it is the default one - if (isOverviewPage) { - pageStack.currentPage.currentIndex = getDefaultOverviewIndex() - } - } - } - - 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 = "" - } - } - } - -//////// 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" - } - - VBusItem { - id: withoutGridMeter - bind: "com.victronenergy.settings/Settings/CGwacs/RunWithoutGridMeter" - } - - - VBusItem { - id: defaultOverview - bind: "com.victronenergy.settings/Settings/Gui/DefaultOverview" - } - - VBusItem { - id: touchEnabled - bind: "com.victronenergy.settings/Settings/Gui/TouchEnabled" - onValueChanged: { - if (completed && value !== undefined) - toast.createToast(value ? qsTr("Touch input on") : qsTr("Touch input off"), 3000) - } - } - - VBusItem { - id: alertNotification - bind: "com.victronenergy.platform/Notifications/Alert" - } - - VBusItem { - id: alarmNotification - bind: "com.victronenergy.platform/Notifications/Alarm" - } - - // Note: finding a firmware image on the storage device is error 4 for vrm storage - // since it should not be used for logging. That fact is used here to determine if - // there is a firmware image. - Connections { - target: storageEvents - onVrmStorageError: { - if (error === 4) { - setTopPage(offlineFwUpdates) - } - } - } - - Connections { - target: vePlatform - onMouseRejected: toast.createToast(qsTr("Touch input disabled"), 1000) - } - - onAlarmChanged: { - if (completed) - checkAlarm() - } - - // always keep track of system information - HubData { - id: theSystem - } - - // note: used for leaving the overviews as well - function backToMainMenu() - { - pageStack.pop(initialPage); - } - - Toast { - id: toast - transform: Scale { - xScale: screen.scaleX - yScale: screen.scaleY - origin.x: toast.width / 2 - origin.y: toast.height / 2 - } - } - - SignalToaster {} - - ToolbarHandlerPages { - id: mainToolbarHandler - isDefault: true - } - - ToolBarLayout { - id: mbTools - height: parent.height - -//// 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) - } - } - - 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 - } - } - } - - Item { - anchors.verticalCenter: parent.verticalCenter - height: mbTools.height - width: mbTools.width - pagesItem.width - menusItem.width - centerScrollIndicator.width - - MouseArea - { - anchors.fill: parent - onClicked: - { - if (darkModeItem.valid) - darkModeItem.setValue (! darkMode) - } - } - - 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: 12 - visible: darkModeItem.valid - } - } - Item - { - id: centerScrollIndicator - anchors.verticalCenter: parent.verticalCenter - height: mbTools.height - width: 20 - MbIcon { - anchors.verticalCenter: parent.verticalCenter - iconId: pageStack.currentPage ? pageStack.currentPage.scrollIndicator : "" - } - } - - 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) - } - } - - Row { - anchors.centerIn: parent - - 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 - } - } - } - } - } - - Component.onCompleted: { - completed = true - } - - ListModel { - id: overviewModel - ListElement { - pageSource: "OverviewHub.qml" - } -//////// (commented out) -- added dynamically above -// ListElement { -// pageSource: "OverviewTiles.qml" -// } - } - - Component { - id: overviewComponent - PageFlow { - // Display default overview when loaded - defaultIndex: getDefaultOverviewIndex() - // Store the current overview page as default - onCurrentIndexChanged: if (active) defaultOverview.setValue(overviewModel.get(currentIndex).pageSource.replace(".qml", "")) - model: overviewModel - } - } - - // When all the related settings items are valid, show the overview page if was the last oppened page - // before restarting - Timer { - interval: 2000 - running: completed && overviewsLoaded && startWithMenu.valid - onTriggered: - { -//////// modified for OverviewGridParallelEnhanced page - selectHubOverview () - if (startWithMenu.value === 0) showOverview() - } - } - - function getDefaultOverviewIndex() - { - if(!defaultOverview.valid) - return 0 - for (var i = 0; i < overviewModel.count; i++){ - if (overviewModel.get(i).pageSource.replace(".qml", "") === defaultOverview.value) { - return i - } - } - return 0 - } - - Component { - id: noticationsComponent - PageNotifications {} - } - - Component { - id: offlineFwUpdates - PageSettingsFirmwareOffline { checkOnCompleted: true} - - } - - // Add or remove extra overviews. for example, generator overview - // shouldn't be shown if the start/stop functionality is not enabled. - // Index parameter is optional, usefull to keep an order. - function extraOverview(name, show, index) - { - var i = 0 - if (show) { - if (index !== undefined) { - if (overviewModel.get(index).pageSource === name) - return - // First append the page - overviewModel.append({"pageSource": name}) - // Then move all the pages behind index - overviewModel.move(index, overviewModel.count - 2, overviewModel.count - 2) - } else { - for (i = 0; i < overviewModel.count; i++) - if (overviewModel.get(i).pageSource === name) - // Don't append if already exists - return - overviewModel.append({"pageSource": name}) - } - } else { - for (i = 0; i < overviewModel.count; i++) - if (overviewModel.get(i).pageSource === name) - overviewModel.remove(i) - } - } - -//////// 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 - // Instead of using a timer per line, using a central one - // reduces the CPU usage a little bit and makes the animations - // smoother. - Timer { - id: mover - property double pos: _counter / _loops - property int _counter - property int _loops: 13 - - interval: 100 - running: true - repeat: true - onTriggered: if (_counter >= (_loops - 1)) _counter = 0; else _counter++ - } - - // If an overview or notifications is active, the new page will replace it - // instead to be pushed. This way we prevent an unwanted stackpage depth - // increment everytime another page wants to be on top. - function setTopPage(page) - { - if (touchEnabled.valid && !touchEnabled.value) - return - - if (isNotificationPage || isOverviewPage || isOfflineFwUpdatePage) - rootWindow.pageStack.replace(page); - else - rootWindow.pageStack.push(page); - } - - function spuriousKeyPress() - { - return !pageStack.currentPage || !pageStack.currentPage.active - } - - function showOverview() - { - if (spuriousKeyPress() || isOverviewPage) - return - setTopPage(overviewComponent) - } - - function showPageNotifications() - { - if (spuriousKeyPress() || isNotificationPage) - return - setTopPage(noticationsComponent) - } - - function checkAlarm() - { - if (alarm) - showPageNotifications() - } - - FirmwareUpdate { id: firmwareUpdate } -} diff --git a/FileSets/v3.40~10/main.qml b/FileSets/v3.40~10/main.qml new file mode 120000 index 00000000..223531e7 --- /dev/null +++ b/FileSets/v3.40~10/main.qml @@ -0,0 +1 @@ +../v3.40~11/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 100644 index e3a11410..00000000 --- a/FileSets/v3.40~10/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~10/startstop.py b/FileSets/v3.40~10/startstop.py new file mode 120000 index 00000000..c84f296d --- /dev/null +++ b/FileSets/v3.40~10/startstop.py @@ -0,0 +1 @@ +../v3.40~11/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 100644 index 67c5230f..00000000 --- a/FileSets/v3.40~10/styles.css +++ /dev/null @@ -1,11043 +0,0 @@ -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -nav, -section { - display: block; -} -audio, -canvas, -video { - display: inline-block; - *display: inline; - *zoom: 1; -} -audio:not([controls]) { - display: none; -} -html { - font-size: 100%; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; -} -a:focus { - outline: thin dotted #333; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} -a:hover, -a:active { - outline: 0; -} -sub, -sup { - position: relative; - font-size: 75%; - line-height: 0; - vertical-align: baseline; -} -sup { - top: -0.5em; -} -sub { - bottom: -0.25em; -} -img { - /* Responsive images (ensure images don't scale beyond their parents) */ - max-width: 100%; - /* Part 1: Set a maxium relative to the parent */ - width: auto\9; - /* IE7-8 need help adjusting responsive images */ - height: auto; - /* Part 2: Scale the height according to the width, otherwise you get stretching */ - vertical-align: middle; - border: 0; - -ms-interpolation-mode: bicubic; -} -#map_canvas img, -.google-maps img { - max-width: none; -} -button, -input, -select, -textarea { - margin: 0; - font-size: 100%; - vertical-align: middle; - background-image: none; -} -button, -input { - *overflow: visible; - line-height: normal; -} -button::-moz-focus-inner, -input::-moz-focus-inner { - padding: 0; - border: 0; -} -button, -html input[type="button"], -input[type="reset"], -input[type="submit"] { - -webkit-appearance: button; - cursor: pointer; -} -label, -select, -button, -input[type="button"], -input[type="reset"], -input[type="submit"], -input[type="radio"], -input[type="checkbox"] { - cursor: pointer; -} -input[type="search"] { - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; - -webkit-appearance: textfield; -} -input[type="search"]::-webkit-search-decoration, -input[type="search"]::-webkit-search-cancel-button { - -webkit-appearance: none; -} -textarea { - overflow: auto; - vertical-align: top; -} -@media print { - * { - text-shadow: none !important; - color: #000 !important; - background: transparent !important; - box-shadow: none !important; - } - a, - a:visited { - text-decoration: underline; - } - a[href]:after { - content: " (" attr(href) ")"; - } - abbr[title]:after { - content: " (" attr(title) ")"; - } - .ir a:after, - a[href^="javascript:"]:after, - a[href^="#"]:after { - content: ""; - } - pre, - blockquote { - border: 1px solid #999; - page-break-inside: avoid; - } - thead { - display: table-header-group; - } - tr, - img { - page-break-inside: avoid; - } - img { - max-width: 100% !important; - } - @page { - margin: 0.5cm; - } - p, - h2, - h3 { - orphans: 3; - widows: 3; - } - h2, - h3 { - page-break-after: avoid; - } -} -/* @group Base */ -.chzn-container { - position: relative; - display: inline-block; - zoom: 1; -} -.chzn-container .chzn-drop { - border-top: 0; - position: absolute; - left: 0; - z-index: 1010; -} -/* @end */ -/* @group Single Chosen */ -.chzn-container-single .chzn-single { - display: block; - outline: none; - overflow: hidden; - white-space: nowrap; - position: relative; - text-decoration: none; -} -.chzn-container-single .chzn-single span { - display: block; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} -.chzn-container-single .chzn-single .handle { - position: absolute; - right: 0; - top: 0; - display: block; -} -.chzn-container-single .chzn-search { - position: relative; - white-space: nowrap; - z-index: 1010; -} -.no-search + .chzn-container-single .chzn-search { - display: none !important; -} -.chzn-container-single .chzn-search input { - outline: 0; -} -/* @group Results */ -.chzn-container .chzn-results { - position: relative; - overflow-x: hidden; - overflow-y: auto; - -webkit-overflow-scrolling: touch; -} -.chzn-container-multi .chzn-results { - padding: 0; -} -.chzn-container .chzn-results li { - display: none; - margin: 0; - list-style: none; -} -.chzn-container .chzn-results .active-result { - cursor: pointer; - display: list-item; - width: 100%; -} -.chzn-container .chzn-results .no-results { - display: list-item; -} -.chzn-container .chzn-results .group-result { - cursor: default; -} -.chzn-container .chzn-results .group-option { - padding-left: 15px; -} -.chzn-container-multi .chzn-drop .result-selected { - display: none; -} -/* @end */ -div.datepicker { - position: relative; - font-family: Arial, Helvetica, sans-serif; - font-size: 12px; - width: 196px; - height: 147px; - position: absolute; - cursor: default; - top: 0; - left: 0; - display: none; -} -.datepickerContainer { - position: absolute; -} -/* Hide border divs by default */ -.datepickerBorderT, -.datepickerBorderB, -.datepickerBorderL, -.datepickerBorderR, -.datepickerBorderTL, -.datepickerBorderTR, -.datepickerBorderBL, -.datepickerBorderBR { - display: none; -} -.datepickerHidden { - display: none; -} -div.datepicker table { - border-collapse: collapse; -} -div.datepicker a { - color: black; - text-decoration: none; - cursor: default; - outline: none; -} -div.datepicker table td { - text-align: center; - padding: 0; - margin: 0; -} -div.datepicker th { - text-align: center; - color: #666666; - font-weight: normal; - padding: 0; -} -div.datepicker tbody a { - display: block; -} -.datepickerDays a { - width: 20px; - line-height: 16px; - height: 16px; - padding-right: 2px; -} -.datepickerYears a, -.datepickerMonths a { - width: 39px; - line-height: 36px; - height: 36px; - text-align: center; -} -.datepickerMonths td:first-child a, -.datepickerMonths td:last-child a, -.datepickerYears td:first-child a, -.datepickerYears td:last-child a { - width: 38px; -} -td.datepickerNotInMonth a { - color: #666666; -} -tbody.datepickerDays td.datepickerSelected { - background: #136A9F; -} -tbody.datepickerDays td.datepickerNotInMonth.datepickerSelected { - background: #17384d; -} -tbody.datepickerYears td.datepickerSelected, -tbody.datepickerMonths td.datepickerSelected { - background: #17384d; -} -div.datepicker td.datepickerSelected a { - color: white; -} -div.datepicker a:hover, -div.datepicker a:hover { - color: #88c5eb; -} -div.datepicker td.datepickerNotInMonth a:hover { - color: #999999; -} -.datepickerSpace div { - width: 20px; -} -.datepickerBlock { - vertical-align: top; -} -a.datepickerGoNext, -a.datepickerGoPrev, -a.datepickerMonth { - text-align: center; - height: 20px; - line-height: 20px; - float: left; -} -div.datepicker th a.datepickerGoNext, -div.datepicker th a.datepickerGoPrev { - width: 20px; - color: #666666; - display: none; -} -div.datepicker th a.datepickerMonth { - width: 114px; - display: block; -} -/* Only display the previous/next arrows on the first/last calendars */ -div.datepicker .datepickerFirstView th a.datepickerGoPrev, -div.datepicker .datepickerLastView th a.datepickerGoNext { - display: block; -} -/* Compensate for the space lost by not having a previous arrow */ -div.datepicker th a.datepickerMonth { - margin-left: 20px; -} -div.datepicker .datepickerFirstView th a.datepickerMonth { - margin-left: 0; -} -/* Day mode calendar body */ -table.datepickerViewDays tbody.datepickerMonths, -table.datepickerViewDays tbody.datepickerYears { - display: none; -} -/* Month mode calendar body */ -table.datepickerViewMonths tbody.datepickerDays, -table.datepickerViewMonths tbody.datepickerYears, -table.datepickerViewMonths tr.datepickerDoW { - display: none; -} -/* Year mode calendar body */ -table.datepickerViewYears tbody.datepickerDays, -table.datepickerViewYears tbody.datepickerMonths, -table.datepickerViewYears tr.datepickerDoW { - display: none; -} -td.datepickerDisabled a, -td.datepickerDisabled.datepickerNotInMonth a { - color: #555555; -} -td.datepickerDisabled a:hover { - color: #333333; -} -/* Not used by default, calendar cells can be marked as special if desired (doesn't seem to be totally working) */ -div.datepicker tbody.datepickerDays td.datepickerSpecial a { - background: #770000; - color: white; -} -div.datepicker tbody.datepickerDays td.datepickerSpecial.datepickerSelected a { - background: #aa0000; -} -/* style the 'not in month' day cell away */ -tbody.datepickerDays td.datepickerNotInMonth.datepickerSelected { - background-color: transparent; -} -div.datepicker td.datepickerNotInMonth a span { - display: none; -} -div.datepicker td.datepickerNotInMonth a:hover span { - display: none; -} -div.datepicker tbody.datepickerDays td.datepickerNotInMonth:hover { - background-color: transparent; -} -.picker { - font-size: 16px; - text-align: left; - line-height: 1.2; - color: #000; - position: absolute; - z-index: 10000; -} -.picker__input { - cursor: default; -} -.picker__input.picker__input--active { - border-color: #0089ec; -} -.picker__holder { - width: 100%; - overflow-y: auto; - -webkit-overflow-scrolling: touch; -} -.picker { - width: 100%; -} -.picker__holder { - position: absolute; - background: #fff; - border: 1px solid #aaa; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - min-width: 176px; - max-width: 466px; - -webkit-border-radius: 0 0 5px 5px; - -moz-border-radius: 0 0 5px 5px; - border-radius: 0 0 5px 5px; - max-height: 0; - -ms-filter: "alpha(Opacity=0)"; - filter: alpha(opacity=0); - -moz-opacity: 0; - opacity: 0; - -webkit-transform: translateY(-1em) perspective(600px) rotateX(10deg); - -moz-transform: translateY(-1em) perspective(600px) rotateX(10deg); - transform: translateY(-1em) perspective(600px) rotateX(10deg); - -webkit-transition: all 0.15s ease-out, max-height 0 0.15s; - -moz-transition: all 0.15s ease-out, max-height 0 0.15s; - transition: all 0.15s ease-out, max-height 0 0.15s; -} -.picker--opened .picker__holder { - max-height: 25em; - -ms-filter: "alpha(Opacity=100)"; - filter: alpha(opacity=100); - -moz-opacity: 1; - opacity: 1; - -webkit-transform: translateY(0) perspective(600px) rotateX(0); - -moz-transform: translateY(0) perspective(600px) rotateX(0); - transform: translateY(0) perspective(600px) rotateX(0); - -webkit-transition: all 0.15s ease-out, max-height 0; - -moz-transition: all 0.15s ease-out, max-height 0; - transition: all 0.15s ease-out, max-height 0; - -webkit-box-shadow: 0 6px 18px 1px rgba(0, 0, 0, 0.12); - -moz-box-shadow: 0 6px 18px 1px rgba(0, 0, 0, 0.12); - box-shadow: 0 6px 18px 1px rgba(0, 0, 0, 0.12); -} -.picker__box { - padding: 0 1em; -} -.picker__header { - text-align: center; - position: relative; - margin-top: 0.75em; -} -.picker__month, -.picker__year { - font-weight: 500; - display: inline-block; - margin-left: .25em; - margin-right: 0.25em; -} -.picker__year { - color: #999; - font-size: .8em; - font-style: italic; -} -.picker__select--month, -.picker__select--year { - font-size: .8em; - border: 1px solid #b7b7b7; - height: 2.5em; - padding: .5em .25em; - margin-left: .25em; - margin-right: .25em; - margin-top: -0.5em; -} -.picker__select--month { - width: 35%; -} -.picker__select--year { - width: 22.5%; -} -.picker__select--month:focus, -.picker__select--year:focus { - border-color: #0089ec; -} -.picker__nav--prev, -.picker__nav--next { - position: absolute; - top: -0.33em; - padding: .5em 1.33em; - width: 1em; - height: 1em; -} -.picker__nav--prev { - left: -1em; - padding-right: 1.5em; -} -.picker__nav--next { - right: -1em; - padding-left: 1.5em; -} -.picker__nav--prev:before, -.picker__nav--next:before { - content: " "; - border-top: .5em solid transparent; - border-bottom: .5em solid transparent; - border-right: .75em solid #000; - width: 0; - height: 0; - display: block; - margin: 0 auto; -} -.picker__nav--next:before { - border-right: 0; - border-left: 0.75em solid #000000; -} -.picker__nav--prev:hover, -.picker__nav--next:hover { - cursor: pointer; - color: #000; - background: #b1dcfb; -} -.picker__nav--disabled, -.picker__nav--disabled:hover, -.picker__nav--disabled:before, -.picker__nav--disabled:before:hover { - cursor: default; - background: 0; - border-right-color: #f5f5f5; - border-left-color: #f5f5f5; -} -.picker__table { - text-align: center; - border-collapse: collapse; - border-spacing: 0; - table-layout: fixed; - font-size: inherit; - width: 100%; - margin-top: .75em; - margin-bottom: 0.5em; -} -@media (min-height: 33.875em) { - .picker__table { - margin-bottom: 0.75em; - } -} -.picker__table td { - margin: 0; - padding: 0; -} -.picker__weekday { - width: 14.285714286%; - font-size: .75em; - padding-bottom: .25em; - color: #999; - font-weight: 500; -} -@media (min-height: 33.875em) { - .picker__weekday { - padding-bottom: 0.5em; - } -} -.picker__day { - padding: .3125em 0; - font-weight: 200; - border: 1px solid transparent; -} -.picker__day--today { - color: #0089ec; - position: relative; -} -.picker__day--today:before { - content: " "; - position: absolute; - top: 2px; - right: 2px; - width: 0; - height: 0; - border-top: .5em solid #0059bc; - border-left: 0.5em solid transparent; -} -.picker__day--selected, -.picker__day--selected:hover { - border-color: #0089ec; -} -.picker__day--highlighted { - background: #b1dcfb; -} -.picker__day--disabled:before { - border-top-color: #aaaaaa; -} -.picker__day--outfocus { - color: #dddddd; -} -.picker__day--infocus:hover, -.picker__day--outfocus:hover { - cursor: pointer; - color: #000; - background: #b1dcfb; -} -.picker__day--highlighted:hover, -.picker--focused .picker__day--highlighted { - background: #0089ec; - color: #ffffff; -} -.picker__day--disabled, -.picker__day--disabled:hover { - background: #f5f5f5; - border-color: #f5f5f5; - color: #ddd; - cursor: default; -} -.picker__day--highlighted.picker__day--disabled, -.picker__day--highlighted.picker__day--disabled:hover { - background: #bbbbbb; -} -.picker__footer { - text-align: center; -} -.picker__button--today, -.picker__button--clear { - border: 1px solid #fff; - background: #fff; - font-size: .8em; - padding: .66em 0; - font-weight: 700; - width: 50%; - display: inline-block; - vertical-align: bottom; -} -.picker__button--today:hover, -.picker__button--clear:hover { - cursor: pointer; - color: #000; - background: #b1dcfb; - border-bottom-color: #b1dcfb; -} -.picker__button--today:focus, -.picker__button--clear:focus { - background: #b1dcfb; - border-color: #0089ec; - outline: 0; -} -.picker__button--today:before, -.picker__button--clear:before { - position: relative; - display: inline-block; - height: 0; -} -.picker__button--today:before { - content: " "; - margin-right: .45em; - top: -0.05em; - width: 0; - border-top: .66em solid #0059bc; - border-left: 0.66em solid transparent; -} -.picker__button--clear:before { - content: "\D7"; - margin-right: .35em; - top: -0.1em; - color: #e20; - vertical-align: top; - font-size: 1.1em; -} -.picker__list { - list-style: none; - padding: .75em 0 4.2em; - margin: 0; -} -.picker__list-item { - border-bottom: 1px solid #ddd; - border-top: 1px solid #ddd; - margin-bottom: -1px; - position: relative; - background: #fff; - padding: 0.75em 1.25em; -} -@media (min-height: 46.75em) { - .picker__list-item { - padding: 0.5em 1em; - } -} -.picker__list-item:hover { - cursor: pointer; - color: #000; - background: #b1dcfb; - border-color: #0089ec; - z-index: 10; -} -.picker__list-item--selected, -.picker__list-item--selected:hover { - border-color: #0089ec; - z-index: 10; -} -.picker__list-item--highlighted { - background: #b1dcfb; -} -.picker__list-item--highlighted:hover, -.picker--focused .picker__list-item--highlighted { - background: #0089ec; - color: #ffffff; -} -.picker__list-item--disabled, -.picker__list-item--disabled:hover, -.picker--focused .picker__list-item--disabled { - background: #f5f5f5; - border-color: #f5f5f5; - color: #ddd; - cursor: default; - border-color: #ddd; - z-index: auto; -} -.picker--time .picker__button--clear { - display: block; - width: 80%; - margin: 1em auto 0; - padding: 1em 1.25em; - background: 0; - border: 0; - font-weight: 500; - font-size: .67em; - text-align: center; - text-transform: uppercase; - color: #666666; -} -.picker--time .picker__button--clear:hover, -.picker--time .picker__button--clear:focus { - color: #000; - background: #b1dcfb; - background: #e20; - border-color: #e20; - cursor: pointer; - color: #fff; - outline: 0; -} -.picker--time .picker__button--clear:before { - top: -0.25em; - color: #666; - font-size: 1.25em; - font-weight: 700; -} -.picker--time .picker__button--clear:hover:before, -.picker--time .picker__button--clear:focus:before { - color: #ffffff; -} -.picker--time { - min-width: 256px; - max-width: 320px; -} -.picker--time .picker__holder { - background: #f2f2f2; -} -@media (min-height: 40.125em) { - .picker--time .picker__holder { - font-size: 0.875em; - } -} -.picker--time .picker__box { - padding: 0; -} -/*rules for the plot target div. These will be cascaded down to all plot elements according to css rules*/ -.jqplot-target { - position: relative; - color: #666666; - font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; - font-size: 1em; - /* height: 300px; - width: 400px;*/ -} -/*rules applied to all axes*/ -.jqplot-axis { - font-size: 0.75em; -} -.jqplot-xaxis { - margin-top: 10px; -} -.jqplot-x2axis { - margin-bottom: 10px; -} -.jqplot-yaxis { - margin-right: 10px; -} -.jqplot-y2axis, -.jqplot-y3axis, -.jqplot-y4axis, -.jqplot-y5axis, -.jqplot-y6axis, -.jqplot-y7axis, -.jqplot-y8axis, -.jqplot-y9axis, -.jqplot-yMidAxis { - margin-left: 10px; - margin-right: 0px; -} -/*rules applied to all axis tick divs*/ -.jqplot-axis-tick, -.jqplot-xaxis-tick, -.jqplot-yaxis-tick, -.jqplot-x2axis-tick, -.jqplot-y2axis-tick, -.jqplot-y3axis-tick, -.jqplot-y4axis-tick, -.jqplot-y5axis-tick, -.jqplot-y6axis-tick, -.jqplot-y7axis-tick, -.jqplot-y8axis-tick, -.jqplot-y9axis-tick, -.jqplot-yMidAxis-tick { - position: absolute; - white-space: pre; -} -.jqplot-xaxis-tick { - top: 0px; - /* initial position untill tick is drawn in proper place */ - left: 15px; - /* padding-top: 10px;*/ - text-align: center; - vertical-align: top; -} -.jqplot-x2axis-tick { - bottom: 0px; - /* initial position untill tick is drawn in proper place */ - left: 15px; - /* padding-bottom: 10px;*/ - vertical-align: bottom; -} -.jqplot-yaxis-tick { - right: 0px; - /* initial position untill tick is drawn in proper place */ - top: 15px; - /* padding-right: 10px;*/ - text-align: right; -} -.jqplot-yaxis-tick.jqplot-breakTick { - right: -20px; - margin-right: 0px; - padding: 1px 5px 1px 5px; - /* background-color: white;*/ - z-index: 2; - font-size: 1.5em; -} -.jqplot-y2axis-tick, -.jqplot-y3axis-tick, -.jqplot-y4axis-tick, -.jqplot-y5axis-tick, -.jqplot-y6axis-tick, -.jqplot-y7axis-tick, -.jqplot-y8axis-tick, -.jqplot-y9axis-tick { - left: 0px; - /* initial position untill tick is drawn in proper place */ - top: 15px; - /* padding-left: 10px;*/ - /* padding-right: 15px;*/ - text-align: left; -} -.jqplot-yMidAxis-tick { - text-align: center; - white-space: nowrap; -} -.jqplot-xaxis-label { - margin-top: 10px; - font-size: 11pt; - position: absolute; -} -.jqplot-x2axis-label { - margin-bottom: 10px; - font-size: 11pt; - position: absolute; -} -.jqplot-yaxis-label { - margin-right: 10px; - /* text-align: center;*/ - font-size: 11pt; - position: absolute; -} -.jqplot-yMidAxis-label { - font-size: 11pt; - position: absolute; -} -.jqplot-y2axis-label, -.jqplot-y3axis-label, -.jqplot-y4axis-label, -.jqplot-y5axis-label, -.jqplot-y6axis-label, -.jqplot-y7axis-label, -.jqplot-y8axis-label, -.jqplot-y9axis-label { - /* text-align: center;*/ - font-size: 11pt; - margin-left: 10px; - position: absolute; -} -.jqplot-meterGauge-tick { - font-size: 0.75em; - color: #999999; -} -.jqplot-meterGauge-label { - font-size: 1em; - color: #999999; -} -table.jqplot-table-legend { - margin-top: 12px; - margin-bottom: 12px; - margin-left: 12px; - margin-right: 12px; -} -table.jqplot-table-legend, -table.jqplot-cursor-legend { - background-color: rgba(255, 255, 255, 0.6); - border: 1px solid #cccccc; - position: absolute; - font-size: 0.75em; -} -td.jqplot-table-legend { - vertical-align: middle; -} -/* -These rules could be used instead of assigning -element styles and relying on js object properties. -*/ -/* -td.jqplot-table-legend-swatch { - padding-top: 0.5em; - text-align: center; -} - -tr.jqplot-table-legend:first td.jqplot-table-legend-swatch { - padding-top: 0px; -} -*/ -td.jqplot-seriesToggle:hover, -td.jqplot-seriesToggle:active { - cursor: pointer; -} -.jqplot-table-legend .jqplot-series-hidden { - text-decoration: line-through; -} -div.jqplot-table-legend-swatch-outline { - border: 1px solid #cccccc; - padding: 1px; -} -div.jqplot-table-legend-swatch { - width: 0px; - height: 0px; - border-top-width: 5px; - border-bottom-width: 5px; - border-left-width: 6px; - border-right-width: 6px; - border-top-style: solid; - border-bottom-style: solid; - border-left-style: solid; - border-right-style: solid; -} -.jqplot-title { - top: 0px; - left: 0px; - padding-bottom: 0.5em; - font-size: 1.7em; -} -table.jqplot-cursor-tooltip { - border: 1px solid #cccccc; - font-size: 0.75em; -} -.jqplot-cursor-tooltip { - border: 1px solid #cccccc; - font-size: 0.75em; - white-space: nowrap; - background: rgba(208, 208, 208, 0.5); - padding: 1px; -} -.jqplot-highlighter-tooltip, -.jqplot-canvasOverlay-tooltip { - border: 1px solid #cccccc; - font-size: 0.75em; - white-space: nowrap; - background: rgba(208, 208, 208, 0.5); - padding: 1px; -} -.jqplot-point-label { - font-size: 0.75em; - z-index: 2; -} -td.jqplot-cursor-legend-swatch { - vertical-align: middle; - text-align: center; -} -div.jqplot-cursor-legend-swatch { - width: 1.2em; - height: 0.7em; -} -.jqplot-error { - /* Styles added to the plot target container when there is an error go here.*/ - text-align: center; -} -.jqplot-error-message { - /* Styling of the custom error message div goes here.*/ - position: relative; - top: 46%; - display: inline-block; -} -div.jqplot-bubble-label { - font-size: 0.8em; - /* background: rgba(90%, 90%, 90%, 0.15);*/ - padding-left: 2px; - padding-right: 2px; - color: #333333; -} -div.jqplot-bubble-label.jqplot-bubble-label-highlight { - background: rgba(230, 230, 230, 0.7); -} -div.jqplot-noData-container { - text-align: center; - background-color: rgba(245, 245, 245, 0.3); -} -.jqplot-table-legend { - width: initial; - left: 27px !important; - border: 0; - background-color: transparent; -} -.jqplot-table-legend tr { - display: block; - float: left; - border: 0; -} -.jqplot-table-legend tr td { - padding: 4px !important; - border: 0; - background: transparent; - line-height: 24px; -} -.jqplot-table-legend tr td .jqplot-table-legend-swatch-outline { - border: 0; - padding: 0; -} -.jqplot-table-legend tr td .jqplot-table-legend-swatch { - border-width: 1px; - border-style: solid; - width: 19px; - height: 19px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; -} -.ps-container .ps-scrollbar-x-rail { - position: absolute; - /* please don't change 'position' */ - bottom: 3px; - /* there must be 'bottom' for ps-scrollbar-x-rail */ - height: 8px; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - opacity: 0; - filter: alpha(opacity=0); - -o-transition: background-color 0.2s linear, opacity 0.2s linear; - -webkit-transition: background-color 0.2s linear, opacity 0.2s linear; - -moz-transition: background-color 0.2s linear, opacity 0.2s linear; - transition: background-color 0.2s linear, opacity 0.2s linear; -} -.ps-container:hover .ps-scrollbar-x-rail, -.ps-container.hover .ps-scrollbar-x-rail { - opacity: 0.6; - filter: alpha(opacity=60); -} -.ps-container .ps-scrollbar-x-rail:hover, -.ps-container .ps-scrollbar-x-rail.hover { - background-color: #eee; - opacity: 0.9; - filter: alpha(opacity=90); -} -.ps-container .ps-scrollbar-x-rail.in-scrolling { - background-color: #eee; - opacity: 0.9; - filter: alpha(opacity=90); -} -.ps-container .ps-scrollbar-y-rail { - position: absolute; - /* please don't change 'position' */ - right: 3px; - /* there must be 'right' for ps-scrollbar-y-rail */ - width: 8px; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - opacity: 0; - filter: alpha(opacity = 0); - -o-transition: background-color 0.2s linear, opacity 0.2s linear; - -webkit-transition: background-color 0.2s linear, opacity 0.2s linear; - -moz-transition: background-color 0.2s linear, opacity 0.2s linear; - transition: background-color 0.2s linear, opacity 0.2s linear; -} -.ps-container:hover .ps-scrollbar-y-rail, -.ps-container.hover .ps-scrollbar-y-rail { - opacity: 0.6; - filter: alpha(opacity=60); -} -.ps-container .ps-scrollbar-y-rail:hover, -.ps-container .ps-scrollbar-y-rail.hover { - background-color: #eee; - opacity: 0.9; - filter: alpha(opacity=90); -} -.ps-container .ps-scrollbar-y-rail.in-scrolling { - background-color: #eee; - opacity: 0.9; - filter: alpha(opacity=90); -} -.ps-container .ps-scrollbar-x { - position: absolute; - /* please don't change 'position' */ - bottom: 0; - /* there must be 'bottom' for ps-scrollbar-x */ - height: 8px; - background-color: #aaa; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - -o-transition: background-color 0.2s linear; - -webkit-transition: background-color 0.2s linear; - -moz-transition: background-color 0.2s linear; - transition: background-color 0.2s linear; -} -.ps-container.ie6 .ps-scrollbar-x { - font-size: 0; - /* fixed scrollbar height in xp sp3 ie6 */ -} -.ps-container .ps-scrollbar-x-rail:hover .ps-scrollbar-x, -.ps-container .ps-scrollbar-x-rail.hover .ps-scrollbar-x { - background-color: #999; -} -.ps-container .ps-scrollbar-y { - position: absolute; - /* please don't change 'position' */ - right: 0; - /* there must be 'right' for ps-scrollbar-y */ - width: 8px; - background-color: #aaa; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - -o-transition: background-color 0.2s linear; - -webkit-transition: background-color 0.2s linear; - -moz-transition: background-color 0.2s linear; - transition: background-color 0.2s linear; -} -.ps-container.ie6 .ps-scrollbar-y { - font-size: 0; - /* fixed scrollbar height in xp sp3 ie6 */ -} -.ps-container .ps-scrollbar-y-rail:hover .ps-scrollbar-y, -.ps-container .ps-scrollbar-y-rail.hover .ps-scrollbar-y { - background-color: #999; -} -.ps-container.ie .ps-scrollbar-x, -.ps-container.ie .ps-scrollbar-y { - visibility: hidden; -} -.ps-container.ie:hover .ps-scrollbar-x, -.ps-container.ie:hover .ps-scrollbar-y, -.ps-container.ie.hover .ps-scrollbar-x, -.ps-container.ie.hover .ps-scrollbar-y { - visibility: visible; -} -.chardinjs-overlay { - display: none; - position: absolute; - z-index: 999999; - background-color: black; - opacity: 0.8; - filter: alpha(opacity=80); -} -.chardinjs-helper-layer { - position: absolute; - z-index: 9999998; - color: white; -} -.chardinjs-helper-layer.chardinjs-left { - border-left: solid white 1px; - margin-left: -10px; -} -.chardinjs-helper-layer.chardinjs-right { - border-right: solid white 1px; - padding-right: 10px; -} -.chardinjs-helper-layer.chardinjs-bottom { - border-bottom: solid white 1px; - padding-bottom: 10px; -} -.chardinjs-helper-layer.chardinjs-top { - border-top: solid white 1px; - padding-top: 10px; -} -.chardinjs-tooltip { - position: absolute; - -webkit-transition: opacity 0.1s ease-out; - -moz-transition: opacity 0.1s ease-out; - -o-transition: opacity 0.1s ease-out; - transition: opacity 0.1s ease-out; - max-width: 200px; -} -.chardinjs-tooltip.chardinjs-left { - margin-left: -135px; - padding-right: 10px; -} -.chardinjs-tooltip.chardinjs-right { - margin-right: -135px; - padding-left: 10px; -} -.chardinjs-tooltip.chardinjs-bottom { - margin-bottom: -50px; - padding-top: 10px; -} -.chardinjs-tooltip.chardinjs-top { - margin-top: -50px; - padding-bottom: 10px; -} -.chardinjs-tooltip.chardinjs-right:before, -.chardinjs-tooltip.chardinjs-left:after, -.chardinjs-tooltip.chardinjs-bottom:before, -.chardinjs-tooltip.chardinjs-top:after { - content: "."; - display: inline-block; - background-color: white; - height: 1px; - overflow: hidden; - position: absolute; -} -.chardinjs-tooltip.chardinjs-right:before, -.chardinjs-tooltip.chardinjs-left:after { - width: 100px; - top: 50%; -} -.chardinjs-tooltip.chardinjs-bottom:before, -.chardinjs-tooltip.chardinjs-top:after { - width: 1px; - height: 50px; - left: 50%; -} -.chardinjs-tooltip.chardinjs-bottom:before { - top: -50px; -} -.chardinjs-tooltip.chardinjs-top:after { - bottom: -50px; -} -.chardinjs-tooltip.chardinjs-right:before { - left: -100px; -} -.chardinjs-tooltip.chardinjs-left:after { - right: -100px; -} -.chardinjs-show-element { - z-index: 9999999 !important; - opacity: 0.8; - filter: alpha(opacity=80); -} -.chardinjs-relative-position { - position: relative; -} -/* required styles */ -.leaflet-map-pane, -.leaflet-tile, -.leaflet-marker-icon, -.leaflet-marker-shadow, -.leaflet-tile-pane, -.leaflet-tile-container, -.leaflet-overlay-pane, -.leaflet-shadow-pane, -.leaflet-marker-pane, -.leaflet-popup-pane, -.leaflet-overlay-pane svg, -.leaflet-zoom-box, -.leaflet-image-layer, -.leaflet-layer { - position: absolute; - left: 0; - top: 0; -} -.leaflet-container { - overflow: hidden; - -ms-touch-action: none; -} -.leaflet-tile, -.leaflet-marker-icon, -.leaflet-marker-shadow { - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; - -webkit-user-drag: none; -} -.leaflet-marker-icon, -.leaflet-marker-shadow { - display: block; -} -.leaflet-container img { - max-width: none ! important; -} -.leaflet-container img.leaflet-image-layer { - max-width: 15000px ! important; -} -.leaflet-tile { - filter: inherit; - visibility: hidden; -} -.leaflet-tile-loaded { - visibility: inherit; -} -.leaflet-zoom-box { - width: 0; - height: 0; -} -.leaflet-overlay-pane svg { - -moz-user-select: none; -} -.leaflet-tile-pane { - z-index: 2; -} -.leaflet-objects-pane { - z-index: 3; -} -.leaflet-overlay-pane { - z-index: 4; -} -.leaflet-shadow-pane { - z-index: 5; -} -.leaflet-marker-pane { - z-index: 6; -} -.leaflet-popup-pane { - z-index: 7; -} -.leaflet-vml-shape { - width: 1px; - height: 1px; -} -.lvml { - behavior: url(#default#VML); - display: inline-block; - position: absolute; -} -.leaflet-control { - position: relative; - z-index: 7; - pointer-events: auto; -} -.leaflet-top, -.leaflet-bottom { - position: absolute; - z-index: 1000; - pointer-events: none; -} -.leaflet-top { - top: 0; -} -.leaflet-right { - right: 0; -} -.leaflet-bottom { - bottom: 0; -} -.leaflet-left { - left: 0; -} -.leaflet-control { - float: left; - clear: both; -} -.leaflet-right .leaflet-control { - float: right; -} -.leaflet-top .leaflet-control { - margin-top: 10px; -} -.leaflet-bottom .leaflet-control { - margin-bottom: 10px; -} -.leaflet-left .leaflet-control { - margin-left: 10px; -} -.leaflet-right .leaflet-control { - margin-right: 10px; -} -.leaflet-fade-anim .leaflet-tile, -.leaflet-fade-anim .leaflet-popup { - opacity: 0; - -webkit-transition: opacity 0.2s linear; - -moz-transition: opacity 0.2s linear; - -o-transition: opacity 0.2s linear; - transition: opacity 0.2s linear; -} -.leaflet-fade-anim .leaflet-tile-loaded, -.leaflet-fade-anim .leaflet-map-pane .leaflet-popup { - opacity: 1; -} -.leaflet-zoom-anim .leaflet-zoom-animated { - -webkit-transition: -webkit-transform 0.25s cubic-bezier(0, 0, 0.25, 1); - -moz-transition: -moz-transform 0.25s cubic-bezier(0, 0, 0.25, 1); - -o-transition: -o-transform 0.25s cubic-bezier(0, 0, 0.25, 1); - transition: transform 0.25s cubic-bezier(0, 0, 0.25, 1); -} -.leaflet-zoom-anim .leaflet-tile, -.leaflet-pan-anim .leaflet-tile, -.leaflet-touching .leaflet-zoom-animated { - -webkit-transition: none; - -moz-transition: none; - -o-transition: none; - transition: none; -} -.leaflet-zoom-anim .leaflet-zoom-hide { - visibility: hidden; -} -.leaflet-clickable { - cursor: pointer; -} -.leaflet-container { - cursor: -webkit-grab; - cursor: -moz-grab; -} -.leaflet-popup-pane, -.leaflet-control { - cursor: auto; -} -.leaflet-dragging .leaflet-container, -.leaflet-dragging .leaflet-clickable { - cursor: move; - cursor: -webkit-grabbing; - cursor: -moz-grabbing; -} -.leaflet-container { - background: #ddd; - outline: 0; -} -.leaflet-container a { - color: #0078A8; -} -.leaflet-container a.leaflet-active { - outline: 2px solid orange; -} -.leaflet-zoom-box { - border: 2px dotted #38f; - background: rgba(255, 255, 255, 0.5); -} -.leaflet-container { - font: 12px / 1.5 "Helvetica Neue", Arial, Helvetica, sans-serif; -} -.leaflet-bar { - box-shadow: 0 1px 5px rgba(0, 0, 0, 0.65); - border-radius: 4px; -} -.leaflet-bar a, -.leaflet-bar a:hover { - background-color: #fff; - border-bottom: 1px solid #ccc; - width: 26px; - height: 26px; - line-height: 26px; - display: block; - text-align: center; - text-decoration: none; - color: black; -} -.leaflet-bar a, -.leaflet-control-layers-toggle { - background-position: 50% 50%; - background-repeat: no-repeat; - display: block; -} -.leaflet-bar a:hover { - background-color: #f4f4f4; -} -.leaflet-bar a:first-child { - border-top-left-radius: 4px; - border-top-right-radius: 4px; -} -.leaflet-bar a:last-child { - border-bottom-left-radius: 4px; - border-bottom-right-radius: 4px; - border-bottom: none; -} -.leaflet-bar a.leaflet-disabled { - cursor: default; - background-color: #f4f4f4; - color: #bbb; -} -.leaflet-touch .leaflet-bar a { - width: 30px; - height: 30px; - line-height: 30px; -} -.leaflet-control-zoom-in, -.leaflet-control-zoom-out { - font: bold 18px 'Lucida Console', Monaco, monospace; - text-indent: 1px; -} -.leaflet-control-zoom-out { - font-size: 20px; -} -.leaflet-touch .leaflet-control-zoom-in { - font-size: 22px; -} -.leaflet-touch .leaflet-control-zoom-out { - font-size: 24px; -} -.leaflet-control-layers { - box-shadow: 0 1px 5px rgba(0, 0, 0, 0.4); - background: #fff; - border-radius: 5px; -} -.leaflet-control-layers-toggle { - background-image: url(images/layers.png); - width: 36px; - height: 36px; -} -.leaflet-retina .leaflet-control-layers-toggle { - background-image: url(images/layers-2x.png); - background-size: 26px 26px; -} -.leaflet-touch .leaflet-control-layers-toggle { - width: 44px; - height: 44px; -} -.leaflet-control-layers .leaflet-control-layers-list, -.leaflet-control-layers-expanded .leaflet-control-layers-toggle { - display: none; -} -.leaflet-control-layers-expanded .leaflet-control-layers-list { - display: block; - position: relative; -} -.leaflet-control-layers-expanded { - padding: 6px 10px 6px 6px; - color: #333; - background: #fff; -} -.leaflet-control-layers-selector { - margin-top: 2px; - position: relative; - top: 1px; -} -.leaflet-control-layers label { - display: block; -} -.leaflet-control-layers-separator { - height: 0; - border-top: 1px solid #ddd; - margin: 5px -10px 5px -6px; -} -.leaflet-container .leaflet-control-attribution { - background: #fff; - background: rgba(255, 255, 255, 0.7); - margin: 0; -} -.leaflet-control-attribution, -.leaflet-control-scale-line { - padding: 0 5px; - color: #333; -} -.leaflet-control-attribution a { - text-decoration: none; -} -.leaflet-control-attribution a:hover { - text-decoration: underline; -} -.leaflet-container .leaflet-control-attribution, -.leaflet-container .leaflet-control-scale { - font-size: 11px; -} -.leaflet-left .leaflet-control-scale { - margin-left: 5px; -} -.leaflet-bottom .leaflet-control-scale { - margin-bottom: 5px; -} -.leaflet-control-scale-line { - border: 2px solid #777; - border-top: none; - line-height: 1.1; - padding: 2px 5px 1px; - font-size: 11px; - white-space: nowrap; - overflow: hidden; - -moz-box-sizing: content-box; - box-sizing: content-box; - background: #fff; - background: rgba(255, 255, 255, 0.5); -} -.leaflet-control-scale-line:not(:first-child) { - border-top: 2px solid #777; - border-bottom: none; - margin-top: -2px; -} -.leaflet-control-scale-line:not(:first-child):not(:last-child) { - border-bottom: 2px solid #777; -} -.leaflet-touch .leaflet-control-attribution, -.leaflet-touch .leaflet-control-layers, -.leaflet-touch .leaflet-bar { - box-shadow: none; -} -.leaflet-touch .leaflet-control-layers, -.leaflet-touch .leaflet-bar { - border: 2px solid rgba(0, 0, 0, 0.2); - background-clip: padding-box; -} -.leaflet-popup { - position: absolute; - text-align: center; -} -.leaflet-popup-content-wrapper { - padding: 1px; - text-align: left; - border-radius: 12px; -} -.leaflet-popup-content { - margin: 13px 19px; - line-height: 1.4; -} -.leaflet-popup-content p { - margin: 18px 0; -} -.leaflet-popup-tip-container { - margin: 0 auto; - width: 40px; - height: 20px; - position: relative; - overflow: hidden; -} -.leaflet-popup-tip { - width: 17px; - height: 17px; - padding: 1px; - margin: -10px auto 0; - -webkit-transform: rotate(45deg); - -moz-transform: rotate(45deg); - -ms-transform: rotate(45deg); - -o-transform: rotate(45deg); - transform: rotate(45deg); -} -.leaflet-popup-content-wrapper, -.leaflet-popup-tip { - background: white; - box-shadow: 0 3px 14px rgba(0, 0, 0, 0.4); -} -.leaflet-container a.leaflet-popup-close-button { - position: absolute; - top: 0; - right: 0; - padding: 4px 4px 0 0; - text-align: center; - width: 18px; - height: 14px; - font: 16px / 14px Tahoma, Verdana, sans-serif; - color: #c3c3c3; - text-decoration: none; - font-weight: bold; - background: transparent; -} -.leaflet-container a.leaflet-popup-close-button:hover { - color: #999; -} -.leaflet-popup-scrolled { - overflow: auto; - border-bottom: 1px solid #ddd; - border-top: 1px solid #ddd; -} -.leaflet-oldie .leaflet-popup-content-wrapper { - zoom: 1; -} -.leaflet-oldie .leaflet-popup-tip { - width: 24px; - margin: 0 auto; - -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)"; - filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678); -} -.leaflet-oldie .leaflet-popup-tip-container { - margin-top: -1px; -} -.leaflet-oldie .leaflet-control-zoom, -.leaflet-oldie .leaflet-control-layers, -.leaflet-oldie .leaflet-popup-content-wrapper, -.leaflet-oldie .leaflet-popup-tip { - border: 1px solid #999; -} -.leaflet-div-icon { - background: #fff; - border: 1px solid #666; -} -.leaflet-cluster-anim .leaflet-marker-icon, -.leaflet-cluster-anim .leaflet-marker-shadow { - -webkit-transition: -webkit-transform 0.3s ease-out, opacity 0.3s ease-in; - -moz-transition: -moz-transform 0.3s ease-out, opacity 0.3s ease-in; - -o-transition: -o-transform 0.3s ease-out, opacity 0.3s ease-in; - transition: transform 0.3s ease-out, opacity 0.3s ease-in; -} -.marker-cluster-small { - background-color: rgba(181, 226, 140, 0.6); -} -.marker-cluster-small div { - background-color: rgba(110, 204, 57, 0.6); -} -.marker-cluster-medium { - background-color: rgba(241, 211, 87, 0.6); -} -.marker-cluster-medium div { - background-color: rgba(240, 194, 12, 0.6); -} -.marker-cluster-large { - background-color: rgba(253, 156, 115, 0.6); -} -.marker-cluster-large div { - background-color: rgba(241, 128, 23, 0.6); -} -.leaflet-oldie .marker-cluster-small { - background-color: #b5e28c; -} -.leaflet-oldie .marker-cluster-small div { - background-color: #6ecc39; -} -.leaflet-oldie .marker-cluster-medium { - background-color: #f1d357; -} -.leaflet-oldie .marker-cluster-medium div { - background-color: #f0c20c; -} -.leaflet-oldie .marker-cluster-large { - background-color: #fd9c73; -} -.leaflet-oldie .marker-cluster-large div { - background-color: #f18017; -} -.marker-cluster { - background-clip: padding-box; - border-radius: 20px; -} -.marker-cluster div { - width: 30px; - height: 30px; - margin-left: 5px; - margin-top: 5px; - text-align: center; - border-radius: 15px; - font: 12px "Helvetica Neue", Arial, Helvetica, sans-serif; -} -.marker-cluster span { - line-height: 30px; -} -/* Magnific Popup CSS */ -.mfp-bg { - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 1042; - overflow: hidden; - position: fixed; - background: #0b0b0b; - opacity: 0.8; - filter: alpha(opacity=80); -} -.mfp-wrap { - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 1102; - position: fixed; - outline: none !important; - -webkit-backface-visibility: hidden; -} -.mfp-container { - text-align: center; - position: absolute; - width: 100%; - height: 100%; - left: 0; - top: 0; - padding: 0 8px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.mfp-container:before { - content: ''; - display: inline-block; - height: 100%; - vertical-align: middle; -} -.mfp-align-top .mfp-container:before { - display: none; -} -.mfp-content { - position: relative; - display: inline-block; - vertical-align: middle; - margin: 0 auto; - text-align: left; - z-index: 1045; -} -.mfp-inline-holder .mfp-content, -.mfp-ajax-holder .mfp-content { - width: 100%; - cursor: auto; -} -.mfp-ajax-cur { - cursor: progress; -} -.mfp-zoom-out-cur, -.mfp-zoom-out-cur .mfp-image-holder .mfp-close { - cursor: -moz-zoom-out; - cursor: -webkit-zoom-out; - cursor: zoom-out; -} -.mfp-zoom { - cursor: pointer; - cursor: -webkit-zoom-in; - cursor: -moz-zoom-in; - cursor: zoom-in; -} -.mfp-auto-cursor .mfp-content { - cursor: auto; -} -.mfp-close, -.mfp-arrow, -.mfp-preloader, -.mfp-counter { - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; -} -.mfp-loading.mfp-figure { - display: none; -} -.mfp-hide { - display: none !important; -} -.mfp-preloader { - color: #cccccc; - position: absolute; - top: 50%; - width: auto; - text-align: center; - margin-top: -0.8em; - left: 8px; - right: 8px; - z-index: 1044; -} -.mfp-preloader a { - color: #cccccc; -} -.mfp-preloader a:hover { - color: white; -} -.mfp-s-ready .mfp-preloader { - display: none; -} -.mfp-s-error .mfp-content { - display: none; -} -button.mfp-close, -button.mfp-arrow { - overflow: visible; - cursor: pointer; - background: transparent; - border: 0; - -webkit-appearance: none; - display: block; - outline: none; - padding: 0; - z-index: 1046; - -webkit-box-shadow: none; - box-shadow: none; -} -button::-moz-focus-inner { - padding: 0; - border: 0; -} -.mfp-close { - width: 44px; - height: 44px; - line-height: 44px; - position: absolute; - right: 0; - top: 0; - text-decoration: none; - text-align: center; - opacity: 0.65; - filter: alpha(opacity=65); - padding: 0 0 18px 10px; - color: white; - font-style: normal; - font-size: 28px; - font-family: Arial, Baskerville, monospace; -} -.mfp-close:hover, -.mfp-close:focus { - opacity: 1; - filter: alpha(opacity=100); -} -.mfp-close:active { - top: 1px; -} -.mfp-close-btn-in .mfp-close { - color: #333333; -} -.mfp-image-holder .mfp-close, -.mfp-iframe-holder .mfp-close { - color: white; - right: -6px; - text-align: right; - padding-right: 6px; - width: 100%; -} -.mfp-counter { - position: absolute; - top: 0; - right: 0; - color: #cccccc; - font-size: 12px; - line-height: 18px; -} -.mfp-arrow { - position: absolute; - opacity: 0.65; - filter: alpha(opacity=65); - margin: 0; - top: 50%; - margin-top: -55px; - padding: 0; - width: 90px; - height: 110px; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); -} -.mfp-arrow:active { - margin-top: -54px; -} -.mfp-arrow:hover, -.mfp-arrow:focus { - opacity: 1; - filter: alpha(opacity=100); -} -.mfp-arrow:before, -.mfp-arrow:after, -.mfp-arrow .mfp-b, -.mfp-arrow .mfp-a { - content: ''; - display: block; - width: 0; - height: 0; - position: absolute; - left: 0; - top: 0; - margin-top: 35px; - margin-left: 35px; - border: medium inset transparent; -} -.mfp-arrow:after, -.mfp-arrow .mfp-a { - border-top-width: 13px; - border-bottom-width: 13px; - top: 8px; -} -.mfp-arrow:before, -.mfp-arrow .mfp-b { - border-top-width: 21px; - border-bottom-width: 21px; - opacity: 0.7; -} -.mfp-arrow-left { - left: 0; -} -.mfp-arrow-left:after, -.mfp-arrow-left .mfp-a { - border-right: 17px solid white; - margin-left: 31px; -} -.mfp-arrow-left:before, -.mfp-arrow-left .mfp-b { - margin-left: 25px; - border-right: 27px solid #3f3f3f; -} -.mfp-arrow-right { - right: 0; -} -.mfp-arrow-right:after, -.mfp-arrow-right .mfp-a { - border-left: 17px solid white; - margin-left: 39px; -} -.mfp-arrow-right:before, -.mfp-arrow-right .mfp-b { - border-left: 27px solid #3f3f3f; -} -.mfp-iframe-holder { - padding-top: 40px; - padding-bottom: 40px; -} -.mfp-iframe-holder .mfp-content { - line-height: 0; - width: 100%; - max-width: 900px; -} -.mfp-iframe-holder .mfp-close { - top: -40px; -} -.mfp-iframe-scaler { - width: 100%; - height: 0; - overflow: hidden; - padding-top: 56.25%; -} -.mfp-iframe-scaler iframe { - position: absolute; - display: block; - top: 0; - left: 0; - width: 100%; - height: 100%; - box-shadow: 0 0 8px rgba(0, 0, 0, 0.6); - background: black; -} -/* Main image in popup */ -img.mfp-img { - width: auto; - max-width: 100%; - height: auto; - display: block; - line-height: 0; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - padding: 40px 0 40px; - margin: 0 auto; -} -/* The shadow behind the image */ -.mfp-figure { - line-height: 0; -} -.mfp-figure:after { - content: ''; - position: absolute; - left: 0; - top: 40px; - bottom: 40px; - display: block; - right: 0; - width: auto; - height: auto; - z-index: -1; - box-shadow: 0 0 8px rgba(0, 0, 0, 0.6); - background: #444444; -} -.mfp-figure small { - color: #bdbdbd; - display: block; - font-size: 12px; - line-height: 14px; -} -.mfp-figure figure { - margin: 0; -} -.mfp-bottom-bar { - margin-top: -36px; - position: absolute; - top: 100%; - left: 0; - width: 100%; - cursor: auto; -} -.mfp-title { - text-align: left; - line-height: 18px; - color: #f3f3f3; - word-wrap: break-word; - padding-right: 36px; -} -.mfp-image-holder .mfp-content { - max-width: 100%; -} -.mfp-gallery .mfp-image-holder .mfp-figure { - cursor: pointer; -} -@media screen and (max-width: 800px) and (orientation: landscape), screen and (max-height: 300px) { - /** - * Remove all paddings around the image on small screen - */ - .mfp-img-mobile .mfp-image-holder { - padding-left: 0; - padding-right: 0; - } - .mfp-img-mobile img.mfp-img { - padding: 0; - } - .mfp-img-mobile .mfp-figure:after { - top: 0; - bottom: 0; - } - .mfp-img-mobile .mfp-figure small { - display: inline; - margin-left: 5px; - } - .mfp-img-mobile .mfp-bottom-bar { - background: rgba(0, 0, 0, 0.6); - bottom: 0; - margin: 0; - top: auto; - padding: 3px 5px; - position: fixed; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - } - .mfp-img-mobile .mfp-bottom-bar:empty { - padding: 0; - } - .mfp-img-mobile .mfp-counter { - right: 5px; - top: 3px; - } - .mfp-img-mobile .mfp-close { - top: 0; - right: 0; - width: 35px; - height: 35px; - line-height: 35px; - background: rgba(0, 0, 0, 0.6); - position: fixed; - text-align: center; - padding: 0; - } -} -@media all and (max-width: 900px) { - .mfp-arrow { - -webkit-transform: scale(0.75); - transform: scale(0.75); - } - .mfp-arrow-left { - -webkit-transform-origin: 0; - transform-origin: 0; - } - .mfp-arrow-right { - -webkit-transform-origin: 100%; - transform-origin: 100%; - } - .mfp-container { - padding-left: 6px; - padding-right: 6px; - } -} -.mfp-ie7 .mfp-img { - padding: 0; -} -.mfp-ie7 .mfp-bottom-bar { - width: 600px; - left: 50%; - margin-left: -300px; - margin-top: 5px; - padding-bottom: 5px; -} -.mfp-ie7 .mfp-container { - padding: 0; -} -.mfp-ie7 .mfp-content { - padding-top: 44px; -} -.mfp-ie7 .mfp-close { - top: 0; - right: 0; - padding-top: 0; -} -/* - -====== Zoom effect ====== - -*/ -.mfp-zoom-in { - /* start state */ - /* animate in */ - /* animate out */ -} -.mfp-zoom-in .mfp-with-anim { - opacity: 0; - filter: alpha(opacity=0); - -webkit-transition: all 0.2s ease-in-out; - -moz-transition: all 0.2s ease-in-out; - -o-transition: all 0.2s ease-in-out; - transition: all 0.2s ease-in-out; - -webkit-transform: scale(0.1); - -moz-transform: scale(0.1); - -ms-transform: scale(0.1); - -o-transform: scale(0.1); - transform: scale(0.1); -} -.mfp-zoom-in.mfp-bg { - opacity: 0; - filter: alpha(opacity=0); - -webkit-transition: all 0.3s ease-out; - -moz-transition: all 0.3s ease-out; - -o-transition: all 0.3s ease-out; - transition: all 0.3s ease-out; -} -.mfp-zoom-in.mfp-ready .mfp-with-anim { - opacity: 1; - filter: alpha(opacity=100); - -webkit-transform: scale(1); - -moz-transform: scale(1); - -ms-transform: scale(1); - -o-transform: scale(1); - transform: scale(1); -} -.mfp-zoom-in.mfp-ready.mfp-bg { - opacity: 0.8; - filter: alpha(opacity=80); -} -.mfp-zoom-in.mfp-removing .mfp-with-anim { - transform: scale(0.1); - opacity: 0; - filter: alpha(opacity=0); -} -.mfp-zoom-in.mfp-removing.mfp-bg { - opacity: 0; - filter: alpha(opacity=0); -} -.clearfix { - *zoom: 1; -} -.clearfix:before, -.clearfix:after { - display: table; - content: ""; - line-height: 0; -} -.clearfix:after { - clear: both; -} -.sprite-site-icons.none { - background-image: none; -} -.sprite-site-icons.soc-0-percent { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -96px -120px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.soc-0-percent { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.soc-25-percent { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -144px -120px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.soc-25-percent { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.soc-50-percent { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -192px -120px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.soc-50-percent { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.soc-75-percent { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -240px -120px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.soc-75-percent { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.soc-100-percent { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -288px -120px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.soc-100-percent { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.consumption { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -336px -120px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.consumption { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.charging { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -384px -120px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.charging { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.weather-sunny { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -96px -168px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.weather-sunny { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.weather-cloudy { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -144px -168px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.weather-cloudy { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.weather-cloudy-with-rain { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -192px -168px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.weather-cloudy-with-rain { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.weather-partially-cloudy-with-rain { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -240px -168px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.weather-partially-cloudy-with-rain { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.weather-partially-cloudy { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -288px -168px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.weather-partially-cloudy { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.weather-thunderstorm { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -336px -168px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.weather-thunderstorm { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.clock { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -384px -168px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.clock { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.weather-thunderstorm-with-rain { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -96px -216px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.weather-thunderstorm-with-rain { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.weather-clear-night { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -144px -216px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.weather-clear-night { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.weather-partially-cloudy-night { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -192px -216px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.weather-partially-cloudy-night { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.weather-snow { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -240px -216px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.weather-snow { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.weather-snow-and-rain { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -288px -216px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.weather-snow-and-rain { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.weather-fog { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -336px -216px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.weather-fog { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.light-bulb { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -384px -216px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.light-bulb { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.mains-on { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -336px -264px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.mains-on { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.mains-off { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -384px -264px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.mains-off { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.device-solar-charger { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -96px -312px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.device-solar-charger { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.device-battery-monitor { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -144px -312px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.device-battery-monitor { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.device-gateway { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -192px -312px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.device-gateway { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.device-ve-bus { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -240px -312px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.device-ve-bus { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.device-pv-inverter { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -288px -312px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.device-pv-inverter { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.device-io-extender { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -336px -312px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.device-io-extender { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-site-icons.device-fluid-monitor { - display: inline-block; - width: 48px; - height: 48px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -384px -312px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-site-icons.device-fluid-monitor { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons { - /**************************************************************************************************************************************** - 'Deprecated triangles' (start) - - The triangles on lines 11, 12 and 13 should normally not be used. Instead use the triangles from lines 15, 16 and 17 and give the - background a color. That way we can use transitions for these triangles by changing the background color. For an example see the - dropdowns in the styleguide. - ****************************************************************************************************************************************/ - /**************************************************************************************************************************************** - 'Deprecated triangles' (end) - ****************************************************************************************************************************************/ -} -.sprite-icons.pie-chart-light { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px 0px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.pie-chart-light { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.pie-chart-dark { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px 0px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.pie-chart-dark { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.graph-bars-light { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -24px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.graph-bars-light { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.graph-bars-dark { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -24px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.graph-bars-dark { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.lightning-light { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -48px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.lightning-light { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.lightning-dark { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -48px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.lightning-dark { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.sun-light { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -72px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.sun-light { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.sun-dark { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -72px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.sun-dark { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.sun-orange { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -48px -72px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.sun-orange { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.graph-line-light { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -96px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.graph-line-light { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.graph-line-dark { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -96px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.graph-line-dark { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.graph-line-blue { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -48px -96px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.graph-line-blue { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.graph-line-orange { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -72px -96px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.graph-line-orange { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.wrench-light { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -120px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.wrench-light { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.wrench-dark { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -120px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.wrench-dark { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.cross-light { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -144px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.cross-light { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.cross-dark { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -144px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.cross-dark { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.clock-light { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -168px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.clock-light { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.clock-dark { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -168px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.clock-dark { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.clock-red { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -48px -168px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.clock-red { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.clock-white { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -72px -168px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.clock-white { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.alert-light { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -192px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.alert-light { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.alert-dark { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -192px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.alert-dark { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.alert-red { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -48px -192px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.alert-red { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.checkmark-light { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -216px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.checkmark-light { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.checkmark-dark { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -216px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.checkmark-dark { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.triangle-up-light { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -240px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.triangle-up-light { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.triangle-up-dark { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -240px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.triangle-up-dark { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.triangle-up-middle { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -48px -240px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.triangle-up-middle { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.triangle-down-light { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -264px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.triangle-down-light { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.triangle-down-dark { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -264px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.triangle-down-dark { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.triangle-down-middle { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -48px -264px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.triangle-down-middle { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.triangle-right-light { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -288px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.triangle-right-light { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.triangle-right-dark { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -288px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.triangle-right-dark { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.triangle-right-middle { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -48px -288px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.triangle-right-middle { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.triangle-right-white { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -72px -288px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.triangle-right-white { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.vertical-lines-light { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -312px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.vertical-lines-light { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.vertical-lines-dark { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -312px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.vertical-lines-dark { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.triangle-up-transparent-white { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -336px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.triangle-up-transparent-white { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.triangle-down-transparent-white { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -336px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.triangle-down-transparent-white { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.triangle-right-transparent-white { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -48px -336px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.triangle-right-transparent-white { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.triangle-up-transparent-blue { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -360px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.triangle-up-transparent-blue { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.triangle-down-transparent-blue { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -360px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.triangle-down-transparent-blue { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.triangle-right-transparent-blue { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -48px -360px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.triangle-right-transparent-blue { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.triangle-up-transparent-red { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -384px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.triangle-up-transparent-red { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.triangle-down-transparent-red { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -384px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.triangle-down-transparent-red { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.triangle-right-transparent-red { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -48px -384px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.triangle-right-transparent-red { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.magnifier-light { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -408px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.magnifier-light { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.magnifier-dark { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -408px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.magnifier-dark { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.cross-in-circle-light { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -432px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.cross-in-circle-light { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.cross-in-circle-dark { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -432px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.cross-in-circle-dark { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.cross-in-circle-white { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -48px -432px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.cross-in-circle-white { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.download-light { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -456px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.download-light { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.download-dark { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -456px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.download-dark { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.download-middle { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -48px -456px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.download-middle { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.download-white { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -72px -456px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.download-white { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.download-blue { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -72px -480px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.download-blue { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.generator-blue { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -480px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.generator-blue { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.grid-green { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -504px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.grid-green { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.grid-red { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -504px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.grid-red { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.vertical-lines-thick-light { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -528px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.vertical-lines-thick-light { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.vertical-lines-thick-dark { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -528px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.vertical-lines-thick-dark { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.horizontal-lines-thick-light { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -552px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.horizontal-lines-thick-light { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.horizontal-lines-thick-dark { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -552px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.horizontal-lines-thick-dark { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.horizontal-lines-thick-blue { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -48px -552px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.horizontal-lines-thick-blue { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.clock-advanced-white { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -600px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.clock-advanced-white { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.clock-advanced-dark { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -600px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.clock-advanced-dark { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.circle-plus-light { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -624px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.circle-plus-light { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.circle-plus-dark { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -624px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.circle-plus-dark { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.circle-plus-middle { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -48px -624px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.circle-plus-middle { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.circle-minus-light { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -648px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.circle-minus-light { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.circle-minus-dark { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -648px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.circle-minus-dark { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.circle-minus-middle { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -48px -648px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.circle-minus-middle { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.map-marker-blue { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -100px 0px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.map-marker-blue { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.map-marker-red { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -250px 0px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.map-marker-red { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.dotted-arrow-left-blue { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -48px -696px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.dotted-arrow-left-blue { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.dotted-arrow-right-blue { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -48px -720px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.dotted-arrow-right-blue { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.arrow-up-blue { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -48px -744px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.arrow-up-blue { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sprite-icons.arrow-down-blue { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -48px -768px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .sprite-icons.arrow-down-blue { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -/**************************************************************************************************************************************** -Colors (start) -****************************************************************************************************************************************/ -/**************************************************************************************************************************************** -Colors (end) -****************************************************************************************************************************************/ -/**************************************************************************************************************************************** -Fonts and sizes (start) -****************************************************************************************************************************************/ -@font-face { - font-family: 'MuseoSans-300'; - font-style: normal; - font-weight: normal; - src: url('/styling/webfonts/MuseoSans-300.eot'); - src: url('/styling/webfonts/MuseoSans-300.eot?#iefix') format('embedded-opentype'), url('/styling/webfonts/MuseoSans-300.woff') format('woff'), local('MuseoSans-300'), url('/styling/webfonts/MuseoSans-300.otf') format('opentype'), url('/styling/webfonts/MuseoSans-300.ttf') format('truetype'), url('/styling/webfonts/MuseoSans-300.svg#MuseoSans-300') format('svg'); -} -@font-face { - font-family: 'MuseoSans-700'; - font-style: normal; - font-weight: normal; - src: url('/styling/webfonts/MuseoSans-700.eot'); - src: url('/styling/webfonts/MuseoSans-700.eot?#iefix') format('embedded-opentype'), url('/styling/webfonts/MuseoSans-700.woff') format('woff'), local('MuseoSans-700'), url('/styling/webfonts/MuseoSans-700.otf') format('opentype'), url('/styling/webfonts/MuseoSans-700.ttf') format('truetype'), url('/styling/webfonts/MuseoSans-700.svg#MuseoSans-700') format('svg'); -} -@font-face { - font-family: 'screensaver-icons'; - font-style: normal; - font-weight: normal; - src: url('/styling/webfonts/icons/VRM-screensaver-icons.eot'); - src: url('/styling/webfonts/icons/VRM-screensaver-icons.eot?#iefix') format('embedded-opentype'), url('/styling/webfonts/icons/VRM-screensaver-icons.woff') format('woff'), url('/styling/webfonts/icons/VRM-screensaver-icons.otf') format('opentype'), url('/styling/webfonts/icons/VRM-screensaver-icons.ttf') format('truetype'), url('/styling/webfonts/icons/VRM-screensaver-icons.svg#VRM-screensaver-icon') format('svg'); -} -/**************************************************************************************************************************************** -Fonts and sizes (end) -****************************************************************************************************************************************/ -/**************************************************************************************************************************************** -Other defaults (start) -****************************************************************************************************************************************/ -/**************************************************************************************************************************************** -Other defaults (end) -****************************************************************************************************************************************/ -/**************************************************************************************************************************************** -HTML elements (start) -****************************************************************************************************************************************/ -body { - background-color: #e6e5e1; - color: #272622; - font-family: 'MuseoSans-300', sans-serif; - font-size: 15px; - line-height: 21px; - margin: 0; -} -h1 { - font-size: 26px; - font-weight: normal; - line-height: 26px; - margin-bottom: 30px; - margin-top: 75px; -} -h1.large { - font-size: 40px; -} -h2 { - font-size: 21px; - font-weight: normal; - line-height: 21px; - margin-bottom: 20px; - margin-top: 45px; -} -h3 { - font-size: 18px; - font-weight: normal; - line-height: 21px; - margin: 0; -} -h4 { - font-size: 15px; - font-weight: normal; - line-height: 15px; - margin: 0; - color: #387dc5; -} -a { - color: #387dc5; - text-decoration: underline; -} -a:hover { - color: #387dc5; -} -a:focus { - outline-style: none; -} -.legend { - font-family: 'Arial'; - font-size: 11px; - line-height: 21px; -} -ul { - margin: 0; - padding: 0; - list-style-type: none; -} -select { - height: 50px; -} -fieldset { - margin: 0; - border: 0; - padding: 0; -} -/**************************************************************************************************************************************** -HTML elements (end) -****************************************************************************************************************************************/ -/**************************************************************************************************************************************** -Inputs and buttons (start) -****************************************************************************************************************************************/ -.btn, -input, -textarea { - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - display: inline-block; - font-size: 18px; - line-height: 18px; - min-height: 40px; - padding: 10px 10px; - text-decoration: none; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; -} -.btn:hover, -input:hover, -textarea:hover { - text-decoration: none; -} -.btn.blue, -input.blue, -textarea.blue { - background-color: #4790d0; - border: 1px solid #387dc5; - color: #ffffff; -} -.btn.blue:hover, -input.blue:hover, -textarea.blue:hover { - background-color: #387dc5; - border: 1px solid #387dc5; -} -.btn.orange, -input.orange, -textarea.orange { - background-color: #f7ab3e; - border: 1px solid #f0962e; - color: #ffffff; -} -.btn.orange:hover, -input.orange:hover, -textarea.orange:hover { - background-color: #f0962e; - border: 1px solid #f0962e; -} -.btn.green, -input.green, -textarea.green { - background-color: #8bc964; - border: 1px solid #72b84c; - color: #ffffff; -} -.btn.green:hover, -input.green:hover, -textarea.green:hover { - background-color: #72b84c; - border: 1px solid #72b84c; -} -.btn.red, -input.red, -textarea.red { - background-color: #fa716f; - border: 1px solid #f35c58; - color: #ffffff; -} -.btn.red:hover, -input.red:hover, -textarea.red:hover { - background-color: #f35c58; - border: 1px solid #f35c58; -} -.btn.gray, -input.gray, -textarea.gray { - background-color: #e6e5e1; - border: 1px solid #dcdbd7; - color: #63625e; -} -.btn.gray:hover, -input.gray:hover, -textarea.gray:hover { - background-color: #f0efeb; - border: 1px solid #dcdbd7; -} -.btn.light, -input.light, -textarea.light { - background-color: #faf9f5; - border: 1px solid #dcdbd7; - color: #63625e; -} -.btn.light:hover, -input.light:hover, -textarea.light:hover { - background-color: #ffffff; - border: 1px solid #dcdbd7; -} -.btn.disabled, -input.disabled, -textarea.disabled, -.btn:disabled, -input:disabled, -textarea:disabled { - background-color: #e6e5e1; - border: #dcdbd7 1px solid; - border-color: #dcdbd7; - color: #63625e; - cursor: default; -} -.btn.disabled:hover, -input.disabled:hover, -textarea.disabled:hover, -.btn:disabled:hover, -input:disabled:hover, -textarea:disabled:hover { - background-color: #e6e5e1; - border: #dcdbd7 1px solid; -} -input, -button, -textarea { - outline: none; - font-family: 'MuseoSans-300', sans-serif; - padding-left: 18px; -} -input[type="text"], -input[type="email"], -input[type="password"], -input[type="tel"], -input[type="url"], -textarea { - font-size: 15px; - background-color: #f0efeb; - border: 1px solid #dcdbd7; - color: #387dc5; - height: inherit; - line-height: inherit; - padding: 10px 13px 7px; -} -input[type="text"]:hover, -input[type="email"]:hover, -input[type="password"]:hover, -input[type="tel"]:hover, -input[type="url"]:hover, -textarea:hover { - background-color: #e6e5e1; - border: 1px solid #dcdbd7; -} -input[type="text"]:-moz-placeholder, -input[type="email"]:-moz-placeholder, -input[type="password"]:-moz-placeholder, -input[type="tel"]:-moz-placeholder, -input[type="url"]:-moz-placeholder, -textarea:-moz-placeholder { - color: #63625e; - opacity: 1; -} -input[type="text"]::-moz-placeholder, -input[type="email"]::-moz-placeholder, -input[type="password"]::-moz-placeholder, -input[type="tel"]::-moz-placeholder, -input[type="url"]::-moz-placeholder, -textarea::-moz-placeholder { - color: #63625e; - opacity: 1; -} -input[type="text"]:-webkit-input-placeholder, -input[type="email"]:-webkit-input-placeholder, -input[type="password"]:-webkit-input-placeholder, -input[type="tel"]:-webkit-input-placeholder, -input[type="url"]:-webkit-input-placeholder, -textarea:-webkit-input-placeholder { - color: #63625e; - opacity: 1; -} -input[type="text"]::-webkit-input-placeholder, -input[type="email"]::-webkit-input-placeholder, -input[type="password"]::-webkit-input-placeholder, -input[type="tel"]::-webkit-input-placeholder, -input[type="url"]::-webkit-input-placeholder, -textarea::-webkit-input-placeholder { - color: #63625e; - opacity: 1; -} -input[type="text"]:-ms-input-placeholder, -input[type="email"]:-ms-input-placeholder, -input[type="password"]:-ms-input-placeholder, -input[type="tel"]:-ms-input-placeholder, -input[type="url"]:-ms-input-placeholder, -textarea:-ms-input-placeholder { - color: #63625e; - opacity: 1; -} -input[type="text"]::-ms-input-placeholder, -input[type="email"]::-ms-input-placeholder, -input[type="password"]::-ms-input-placeholder, -input[type="tel"]::-ms-input-placeholder, -input[type="url"]::-ms-input-placeholder, -textarea::-ms-input-placeholder { - color: #63625e; - opacity: 1; -} -input[type="text"]:hover, -input[type="email"]:hover, -input[type="password"]:hover, -input[type="tel"]:hover, -input[type="url"]:hover, -textarea:hover { - background-color: #ffffff; -} -input[type="text"]:focus, -input[type="email"]:focus, -input[type="password"]:focus, -input[type="tel"]:focus, -input[type="url"]:focus, -textarea:focus { - background-color: #ffffff; - border-color: #4790d0; -} -input[type="text"].completed, -input[type="email"].completed, -input[type="password"].completed, -input[type="tel"].completed, -input[type="url"].completed, -textarea.completed { - background-color: #ffffff; -} -input[type="text"].completed:hover, -input[type="email"].completed:hover, -input[type="password"].completed:hover, -input[type="tel"].completed:hover, -input[type="url"].completed:hover, -textarea.completed:hover { - border-color: #4790d0; -} -input[type="text"]:invalid, -input[type="email"]:invalid, -input[type="password"]:invalid, -input[type="tel"]:invalid, -input[type="url"]:invalid, -textarea:invalid { - box-shadow: none; -} -input[type="text"].error, -input[type="email"].error, -input[type="password"].error, -input[type="tel"].error, -input[type="url"].error, -textarea.error, -input[type="text"]:not(.needstouch):invalid:not(:focus), -input[type="email"]:not(.needstouch):invalid:not(:focus), -input[type="password"]:not(.needstouch):invalid:not(:focus), -input[type="tel"]:not(.needstouch):invalid:not(:focus), -input[type="url"]:not(.needstouch):invalid:not(:focus), -textarea:not(.needstouch):invalid:not(:focus) { - border-color: #fa716f; - color: #f35c58; -} -input[type="text"].error:hover, -input[type="email"].error:hover, -input[type="password"].error:hover, -input[type="tel"].error:hover, -input[type="url"].error:hover, -textarea.error:hover, -input[type="text"]:not(.needstouch):invalid:not(:focus):hover, -input[type="email"]:not(.needstouch):invalid:not(:focus):hover, -input[type="password"]:not(.needstouch):invalid:not(:focus):hover, -input[type="tel"]:not(.needstouch):invalid:not(:focus):hover, -input[type="url"]:not(.needstouch):invalid:not(:focus):hover, -textarea:not(.needstouch):invalid:not(:focus):hover { - border-color: #fa716f; -} -input[type="text"].disabled, -input[type="email"].disabled, -input[type="password"].disabled, -input[type="tel"].disabled, -input[type="url"].disabled, -textarea.disabled { - background-color: #e6e5e1; - border-color: #dcdbd7; - color: #63625e; -} -input[type="text"].disabled:hover, -input[type="email"].disabled:hover, -input[type="password"].disabled:hover, -input[type="tel"].disabled:hover, -input[type="url"].disabled:hover, -textarea.disabled:hover { - background-color: #f0efeb; - border-color: #dcdbd7; -} -input[type="button"], -input[type="submit"] { - border: none; - /*padding: 0;*/ - vertical-align: baseline; -} -.btn { - text-align: center; -} -/**************************************************************************************************************************************** -Inputs and buttons (end) -****************************************************************************************************************************************/ -/**************************************************************************************************************************************** -Custom select (start) -****************************************************************************************************************************************/ -.chzn-select { - visibility: hidden; -} -.chzn-select.no-search + .chzn-container .chzn-drop .chzn-results { - max-height: 259px; -} -.chzn-select.no-search + .chzn-container .chzn-drop .chzn-results .active-result:first-child { - padding-top: 20px; -} -.chzn-container { - display: block; -} -.chzn-container .chzn-single { - background-color: #ffffff; - border: 1px solid #dcdbd7; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - color: #63625e; - height: 40px; - line-height: 40px; - padding: 0 70px 0 15px; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; - z-index: 1011; -} -.chzn-container .chzn-single:hover { - border-color: #959490; - color: #272622; -} -.chzn-container .chzn-single:hover .handle { - border-left-color: #959490; -} -.chzn-container .chzn-single:hover .handle .sprite-icons { - background-color: #959490; -} -.chzn-container .chzn-single .handle { - border-left: 1px solid #dcdbd7; - height: 18px; - margin-top: 11px; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; - width: 37px; -} -.chzn-container .chzn-single .handle .sprite-icons { - background-color: #dcdbd7; - -webkit-transition-property: background-position; - -webkit-transition-duration: 0s; - -moz-transition-property: background-position; - -moz-transition-duration: 0s; - -o-transition-property: background-position; - -o-transition-duration: 0s; - -ms-transition-property: background-position; - -ms-transition-duration: 0s; - transition-property: background-position; - transition-duration: 0s; - -webkit-transition-property: background-color; - -webkit-transition-duration: 0.2s; - -moz-transition-property: background-color; - -moz-transition-duration: 0.2s; - -o-transition-property: background-color; - -o-transition-duration: 0.2s; - -ms-transition-property: background-color; - -ms-transition-duration: 0.2s; - transition-property: background-color; - transition-duration: 0.2s; - right: 8px; - position: absolute; - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -336px; - top: -2px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .chzn-container .chzn-single .handle .sprite-icons { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.chzn-container .chzn-drop { - background: #ffffff; - border: 1px solid #dcdbd7; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; - margin-top: 5px; - z-index: 1012; -} -.chzn-container .chzn-drop .chzn-search { - background-color: #959490; - position: relative; - -webkit-border-top-left-radius: 5px; - -moz-border-radius-topleft: 5px; - border-top-left-radius: 5px; - -webkit-border-top-right-radius: 5px; - -moz-border-radius-topright: 5px; - border-top-right-radius: 5px; -} -.chzn-container .chzn-drop .chzn-search .sprite-icons { - left: 15px; - position: absolute; - top: 8px; -} -.chzn-container .chzn-drop .chzn-search input[type="text"] { - background-color: #959490; - border: none; - color: #ffffff; - padding-left: 55px; - width: 100% !important; -} -.chzn-container .chzn-drop .chzn-search input[type="text"]:-moz-placeholder { - color: #e6e5e1; - opacity: 1; -} -.chzn-container .chzn-drop .chzn-search input[type="text"]::-moz-placeholder { - color: #e6e5e1; - opacity: 1; -} -.chzn-container .chzn-drop .chzn-search input[type="text"]:-webkit-input-placeholder { - color: #e6e5e1; - opacity: 1; -} -.chzn-container .chzn-drop .chzn-search input[type="text"]::-webkit-input-placeholder { - color: #e6e5e1; - opacity: 1; -} -.chzn-container .chzn-drop .chzn-search input[type="text"]:-ms-input-placeholder { - color: #e6e5e1; - opacity: 1; -} -.chzn-container .chzn-drop .chzn-search input[type="text"]::-ms-input-placeholder { - color: #e6e5e1; - opacity: 1; -} -.chzn-container .chzn-drop .chzn-results { - margin: 0px; - max-height: 254px; - padding: 0px; -} -.chzn-container .chzn-drop .chzn-results .active-result { - border-top: 1px solid #dcdbd7; - color: #63625e; - min-height: 20px; - padding: 9px 15px; -} -.chzn-container .chzn-drop .chzn-results .active-result:first-child { - border-top: none; -} -.chzn-container .chzn-drop .chzn-results .active-result.highlighted { - background-color: #e6e5e1; - color: #272622; -} -.chzn-container .chzn-drop .chzn-results .active-result.result-selected { - color: #387dc5; -} -.chzn-container .chzn-drop .chzn-results .no-results { - color: #f35c58; - height: 40px; - line-height: 44px; - padding: 0 20px; -} -.chzn-container.chzn-container-active .chzn-single { - border-color: #959490; - color: #272622; -} -.chzn-container.chzn-container-active .chzn-single .handle { - border-left-color: #959490; -} -.chzn-container.chzn-container-active .chzn-single .handle .sprite-icons { - background-color: #959490; -} -.chzn-container.chzn-container-active .chzn-single.chzn-single-with-drop .handle .sprite-icons { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -336px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .chzn-container.chzn-container-active .chzn-single.chzn-single-with-drop .handle .sprite-icons { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -/**************************************************************************************************************************************** -Custom select (end) -****************************************************************************************************************************************/ -/* The functionality */ -.custom-check-and-radio:not(#OLD-IE), -.custom-toggle:not(#OLD-IE) { - position: relative; -} -.custom-check-and-radio:not(#OLD-IE) input, -.custom-toggle:not(#OLD-IE) input { - cursor: pointer; - float: left; - height: 0px; - min-height: 0px; - opacity: 0; - filter: alpha(opacity=0); - width: 0px; - padding: 0; - position: absolute; - margin: 0; -} -.custom-check-and-radio:not(#OLD-IE) .alternative-display, -.custom-toggle:not(#OLD-IE) .alternative-display { - display: block; - cursor: pointer; - left: 0px; - position: absolute; - top: 0px; -} -.custom-check-and-radio:not(#OLD-IE) input + label, -.custom-toggle:not(#OLD-IE) input + label { - cursor: pointer; - display: block; -} -/* The common styling for checkboxes and radio buttons */ -.custom-check-and-radio:not(#OLD-IE) .alternative-display { - display: block; - background-color: #f0efeb; - border: 1px solid #dcdbd7; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - height: 24px; - min-height: 0; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; - width: 24px; -} -.custom-check-and-radio:not(#OLD-IE) input + label { - /* line-height: 28px;*/ - padding: 4px 0 0 40px; -} -.custom-check-and-radio:not(#OLD-IE) input:checked + label .alternative-display { - background-color: #4790d0; -} -.custom-check-and-radio:not(#OLD-IE) input:disabled + label .alternative-display { - background-color: #959490; -} -.custom-check-and-radio:not(#OLD-IE):hover .alternative-display { - background-color: #e6e5e1; -} -.custom-check-and-radio:not(#OLD-IE):hover input:checked + label .alternative-display { - background-color: #387dc5; -} -/* The specific styling of the checkbox */ -.custom-check:not(#OLD-IE) .alternative-display { - display: block; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; -} -.custom-check:not(#OLD-IE) .alternative-display .sprite-icons { - margin-left: -1px; - margin-top: -1px; - opacity: 0; - filter: alpha(opacity=0); - display: inline-block; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -216px; - width: 24px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .custom-check:not(#OLD-IE) .alternative-display .sprite-icons { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.custom-check:not(#OLD-IE) input:checked + label .alternative-display .sprite-icons { - opacity: 1; - filter: alpha(opacity=100); -} -.custom-check:not(#OLD-IE):hover .alternative-display .sprite-icons { - opacity: 1; - filter: alpha(opacity=100); -} -/* The specific styling of the radio button */ -.custom-radio:not(#OLD-IE) .alternative-display { - display: block; - -webkit-border-radius: 12px; - -moz-border-radius: 12px; - border-radius: 12px; -} -.custom-radio:not(#OLD-IE) .alternative-display .dot { - background-color: #f0efeb; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - height: 8px; - left: 7px; - position: absolute; - top: 7px; - width: 8px; -} -.custom-radio:not(#OLD-IE) input:checked + label .alternative-display .dot { - background-color: #ffffff; -} -.custom-radio:not(#OLD-IE):hover input:checked + label .alternative-display .dot { - background-color: #ffffff; -} -/* The specific styling of the toggle */ -.custom-toggle:not(#OLD-IE).slide-over-text .alternative-display { - border: 1px solid #dcdbd7; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; - height: 40px; - width: 120px; - clear: both; -} -.custom-toggle:not(#OLD-IE).slide-over-text .alternative-display .on, -.custom-toggle:not(#OLD-IE).slide-over-text .alternative-display.toggle-blue .on { - background-color: #4790d0; - -webkit-border-top-left-radius: 4px; - -moz-border-radius-topleft: 4px; - border-top-left-radius: 4px; - -webkit-border-bottom-left-radius: 4px; - -moz-border-radius-bottomleft: 4px; - border-bottom-left-radius: 4px; - -webkit-box-shadow: 0px 2px 0px #387dc5 inset; - -moz-box-shadow: 0px 2px 0px #387dc5 inset; - box-shadow: 0px 2px 0px #387dc5 inset; -} -.custom-toggle:not(#OLD-IE).slide-over-text .alternative-display.toggle-green .on { - background-color: #8bc964; - -webkit-box-shadow: 0px 2px 0px #72b84c inset; - -moz-box-shadow: 0px 2px 0px #72b84c inset; - box-shadow: 0px 2px 0px #72b84c inset; -} -.custom-toggle:not(#OLD-IE).slide-over-text .alternative-display.toggle-red .on { - background-color: #fa716f; - -webkit-box-shadow: 0px 2px 0px #f35c58 inset; - -moz-box-shadow: 0px 2px 0px #f35c58 inset; - box-shadow: 0px 2px 0px #f35c58 inset; -} -.custom-toggle:not(#OLD-IE).slide-over-text .alternative-display .off { - background-color: #959490; - -webkit-border-top-right-radius: 4px; - -moz-border-radius-topright: 4px; - border-top-right-radius: 4px; - -webkit-border-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; - border-bottom-right-radius: 4px; - -webkit-box-shadow: 0px 2px 0px #8e8d89 inset; - -moz-box-shadow: 0px 2px 0px #8e8d89 inset; - box-shadow: 0px 2px 0px #8e8d89 inset; -} -.custom-toggle:not(#OLD-IE).slide-over-text .alternative-display .on, -.custom-toggle:not(#OLD-IE).slide-over-text .alternative-display .off { - display: block; - color: #ffffff; - float: left; - height: 100%; - line-height: 41px; - text-align: center; - position: relative; - width: 50%; -} -.custom-toggle:not(#OLD-IE).slide-over-text .alternative-display .knob { - display: block; - background-color: #e6e5e1; - border: 1px solid #dcdbd7; - border-bottom: 0px; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; - border-top: none; - -webkit-box-shadow: 5px 0px 0px #8e8d89; - -moz-box-shadow: 5px 0px 0px #8e8d89; - box-shadow: 5px 0px 0px #8e8d89; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; - height: 38px; - left: -1px; - position: absolute; - top: 0px; - width: 62px; -} -.custom-toggle:not(#OLD-IE).slide-over-text .alternative-display .knob .sprite-icons { - left: 17px; - position: absolute; - top: 8px; -} -.custom-toggle:not(#OLD-IE).slide-over-text input + label { - line-height: 44px; - padding: 0 0 0 140px; -} -.custom-toggle:not(#OLD-IE).slide-over-text.under-label label { - padding: 0px; -} -.custom-toggle:not(#OLD-IE).slide-over-text.under-label label .alternative-display { - position: relative; -} -.custom-toggle:not(#OLD-IE).slide-over-text.right-aligned input + label { - padding: 0; -} -.custom-toggle:not(#OLD-IE).slide-over-text.right-aligned .alternative-display { - left: auto; - right: 0px; -} -.custom-toggle:not(#OLD-IE).slide-over-text input:checked + label .alternative-display .knob, -.custom-toggle:not(#OLD-IE).slide-over-text input:checked + label .alternative-display.toggle-blue .knob { - -webkit-box-shadow: -5px 0px 0px #5b9bcd; - -moz-box-shadow: -5px 0px 0px #5b9bcd; - box-shadow: -5px 0px 0px #5b9bcd; - left: 57px; -} -.custom-toggle:not(#OLD-IE).slide-over-text input:checked + label .alternative-display.toggle-green .knob { - -webkit-box-shadow: -5px 0px 0px #98c478; - -moz-box-shadow: -5px 0px 0px #98c478; - box-shadow: -5px 0px 0px #98c478; -} -.custom-toggle:not(#OLD-IE).slide-over-text input:checked + label .alternative-display.toggle-red .knob { - -webkit-box-shadow: -5px 0px 0px #e66e6e; - -moz-box-shadow: -5px 0px 0px #e66e6e; - box-shadow: -5px 0px 0px #e66e6e; -} -.custom-toggle:not(#OLD-IE).slide-over-text:hover .alternative-display .knob { - background-color: #ffffff; -} -.custom-toggle:not(#OLD-IE).slide-over-text.button-variant .alternative-display { - display: block; - width: 140px; -} -.custom-toggle:not(#OLD-IE).slide-over-text.button-variant .toggle-caption { - display: block; - font-size: 15px; - margin-top: 11px; - text-align: center; -} -.custom-toggle:not(#OLD-IE).slide-over-text.button-variant .caption-on { - color: #8bc964; - display: none; -} -.custom-toggle:not(#OLD-IE).slide-over-text.button-variant .caption-off { - color: #959490; -} -.custom-toggle:not(#OLD-IE).slide-over-text.button-variant input:checked + label .alternative-display { - border-color: #8bc964; -} -.custom-toggle:not(#OLD-IE).slide-over-text.button-variant input:checked + label .caption-on { - display: block; -} -.custom-toggle:not(#OLD-IE).slide-over-text.button-variant input:checked + label .caption-off { - display: none; -} -.custom-toggle:not(#OLD-IE).slide-colors .alternative-display { - display: block; - background-color: #e6e5e1; - border: 1px solid #dcdbd7; - display: inline-block; - /*font-size: @sgFontSizeText * 10px;*/ - height: 30px; - position: relative; - width: 80px; - -webkit-border-radius: 100px; - -moz-border-radius: 100px; - border-radius: 100px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; -} -.custom-toggle:not(#OLD-IE).slide-colors .alternative-display .on { - background-color: #8bc964; - left: 10px; - width: 0; -} -.custom-toggle:not(#OLD-IE).slide-colors .alternative-display .off { - background-color: #fa716f; - right: 10px; - width: 58px; -} -.custom-toggle:not(#OLD-IE).slide-colors .alternative-display .on, -.custom-toggle:not(#OLD-IE).slide-colors .alternative-display .off { - display: block; - height: 4px; - position: absolute; - top: 12px; - -webkit-border-radius: 100px; - -moz-border-radius: 100px; - border-radius: 100px; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; -} -.custom-toggle:not(#OLD-IE).slide-colors .alternative-display .knob { - display: block; - background-color: #ffffff; - height: 24px; - left: 2px; - position: absolute; - top: 2px; - width: 24px; - -webkit-border-radius: 100px; - -moz-border-radius: 100px; - border-radius: 100px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - -webkit-box-shadow: 0 2px 6px rgba(150, 149, 145, 0.5); - -moz-box-shadow: 0 2px 6px rgba(150, 149, 145, 0.5); - box-shadow: 0 2px 6px rgba(150, 149, 145, 0.5); - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; -} -.custom-toggle:not(#OLD-IE).slide-colors .alternative-display .knob .dot { - background-color: #fa716f; - height: 8px; - left: 8px; - position: absolute; - top: 8px; - width: 8px; - -webkit-border-radius: 100px; - -moz-border-radius: 100px; - border-radius: 100px; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; -} -.custom-toggle:not(#OLD-IE).slide-colors .caption-container { - display: inline-block; - vertical-align: top; -} -.custom-toggle:not(#OLD-IE).slide-colors .caption { - color: #fa716f; - line-height: 30px; - padding-left: 17px; - text-transform: uppercase; -} -.custom-toggle:not(#OLD-IE).slide-colors .caption:after { - content: "Off"; -} -.custom-toggle:not(#OLD-IE).slide-colors input + label { - line-height: 34px; -} -.custom-toggle:not(#OLD-IE).slide-colors input:checked + label .alternative-display .on { - width: 58px; -} -.custom-toggle:not(#OLD-IE).slide-colors input:checked + label .alternative-display .off { - width: 0; -} -.custom-toggle:not(#OLD-IE).slide-colors input:checked + label .alternative-display .knob { - left: 52px; -} -.custom-toggle:not(#OLD-IE).slide-colors input:checked + label .alternative-display .knob .dot { - background-color: #8bc964; -} -.custom-toggle:not(#OLD-IE).slide-colors input:checked + label .caption { - color: #8bc964; -} -.custom-toggle:not(#OLD-IE).slide-colors input:checked + label .caption:after { - content: "On"; -} -.custom-toggle:not(#OLD-IE).slide-colors:hover .alternative-display .knob { - background-color: #ffffff; -} -/**************************************************************************************************************************************** -Tabs (start) -****************************************************************************************************************************************/ -#vrm-tabs { - height: 65px; - margin: 0px; - padding: 0px; -} -#vrm-tabs li { - background-color: #63625e; - border-bottom: 4px solid #595854; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; - float: left; - height: 60px; - list-style-position: inside; - list-style-type: none; - margin-top: 5px; - width: 100px; -} -#vrm-tabs li a { - display: inline-block; - float: left; - height: 100%; - position: relative; - text-decoration: none; - width: 99px; -} -#vrm-tabs li a .sprite-icons { - left: 38px; - position: absolute; - top: 12px; -} -#vrm-tabs li a .sprite-icons.default { - z-index: 1; -} -#vrm-tabs li a .text { - color: #e6e5e1; - font-size: 11px; - margin-top: 36px; - text-align: center; -} -#vrm-tabs li.darker { - background-color: #4f4e4a; -} -#vrm-tabs li.active { - background-color: #faf9f5; - border: none; - border-color: #ffffff; - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; - height: 65px; - margin-top: 0px; -} -#vrm-tabs li.active#tab-live-feed, -#vrm-tabs li.active#tab-settings { - background-color: #f0efeb; -} -#vrm-tabs li.active a .sprite-icons.default { - display: none; -} -#vrm-tabs li.active a .text { - color: #63625e; -} -#vrm-tabs li.active .divider .border { - -webkit-transition: 0s; - -moz-transition: 0s; - -o-transition: 0s; - transition: 0s; - background-color: transparent; -} -#vrm-tabs li.active + li .divider .border { - background-color: transparent; -} -#vrm-tabs li:hover { - border-color: #959490; -} -#vrm-tabs li:hover:not(.active) { - background-color: #959490; -} -#vrm-tabs li:hover:not(.active) .divider .border { - background-color: #959490; -} -#vrm-tabs li:hover.active { - border-color: #ffffff; -} -#vrm-tabs li:hover + li .divider .border { - background-color: transparent; -} -#vrm-tabs li .divider { - display: inline-block; - float: left; - width: 0.5px; -} -#vrm-tabs li .divider .border { - background-color: #4f4e4a; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; - height: 40px; - margin-top: 10px; -} -#vrm-tabs-content { - background-color: #f0efeb; -} -#vrm-tabs-content .tab-pane { - display: none; -} -#vrm-tabs-content .tab-pane .content { - padding: 10px 20px; -} -#vrm-tabs-content .active { - display: block; -} -/**************************************************************************************************************************************** -Tabs (end) -****************************************************************************************************************************************/ -/**************************************************************************************************************************************** -Form Tabs (start) -****************************************************************************************************************************************/ -.form-tabs { - list-style: none; - margin: 0; - padding: 0; -} -.form-tabs li { - border-left: 1px solid #dcdbd7; - border-bottom: 1px solid #dcdbd7; - border-right: 1px solid #dcdbd7; - background-color: #e6e5e1; -} -.form-tabs li:first-child { - border-top: 1px solid #dcdbd7; -} -.form-tabs li a { - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; - display: block; - height: 50px; - line-height: 50px; - color: #63625e; - text-decoration: none; - text-align: right; - padding-right: 25px; - position: relative; - cursor: pointer; -} -.form-tabs li a.active, -.form-tabs li a:hover { - background: white; - color: #387dc5; -} -.form-tabs li a .required { - color: #4790d0; - position: absolute; - right: 20px; -} -/**************************************************************************************************************************************** -Form Tabs (end) -****************************************************************************************************************************************/ -/**************************************************************************************************************************************** -12-column grid (start) -****************************************************************************************************************************************/ -/* This mixin sets the width of an element based on the number of columns. */ -/* This mixin sets the width of a grid item based on the number of columns. */ -.container .container-inner { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - *zoom: 1; - margin: 0 auto; - width: 960px; -} -.container .container-inner:before, -.container .container-inner:after { - display: table; - content: ""; - line-height: 0; -} -.container .container-inner:after { - clear: both; -} -.container .container-inner .grid-item { - float: left; - /* Classes for setting the width of a grid item based on the number of columns it is wide. */ -} -.container .container-inner .grid-item.one-columns-width { - margin-left: 10px; - margin-right: 10px; - width: 60px; -} -.container .container-inner .grid-item.two-columns-width { - margin-left: 10px; - margin-right: 10px; - width: 140px; -} -.container .container-inner .grid-item.three-columns-width { - margin-left: 10px; - margin-right: 10px; - width: 220px; -} -.container .container-inner .grid-item.four-columns-width { - margin-left: 10px; - margin-right: 10px; - width: 300px; -} -.container .container-inner .grid-item.five-columns-width { - margin-left: 10px; - margin-right: 10px; - width: 380px; -} -.container .container-inner .grid-item.six-columns-width { - margin-left: 10px; - margin-right: 10px; - width: 460px; -} -.container .container-inner .grid-item.seven-columns-width { - margin-left: 10px; - margin-right: 10px; - width: 540px; -} -.container .container-inner .grid-item.eight-columns-width { - margin-left: 10px; - margin-right: 10px; - width: 620px; -} -.container .container-inner .grid-item.nine-columns-width { - margin-left: 10px; - margin-right: 10px; - width: 700px; -} -.container .container-inner .grid-item.ten-columns-width { - margin-left: 10px; - margin-right: 10px; - width: 780px; -} -.container .container-inner .grid-item.eleven-columns-width { - margin-left: 10px; - margin-right: 10px; - width: 860px; -} -.container .container-inner .grid-item.twelve-columns-width { - margin-left: 10px; - margin-right: 10px; - width: 940px; -} -.container .container-inner .grid-item.offset-one { - margin-left: 90px; -} -.container .container-inner .grid-item.offset-two { - margin-left: 170px; -} -.container .container-inner .grid-item.offset-three { - margin-left: 250px; -} -.container .container-inner .grid-item.offset-four { - margin-left: 330px; -} -.container .container-inner .grid-item.offset-five { - margin-left: 410px; -} -.container .container-inner .grid-item.offset-six { - margin-left: 490px; -} -.offset-gutter { - margin-left: 20px; -} -/* Classes for setting the width of an element based on the number of columns it is wide. */ -.two-columns-width { - width: 140px; -} -.two-columns-width.force-width { - width: 140px !important; -} -.three-columns-width { - width: 220px; -} -.three-columns-width.force-width { - width: 220px !important; -} -.four-columns-width { - width: 300px; -} -.four-columns-width.force-width { - width: 300px !important; -} -/**************************************************************************************************************************************** -12-column grid (end) -****************************************************************************************************************************************/ -/* -----------[Global styling]--------------*/ -.no-display { - display: none; -} -/* -----------[Homepage]--------------*/ -.vrm.index.index .container-inner .main-image-container { - background: url(/img/homepage/main-image.png) no-repeat transparent center; - height: 539px; - left: 0px; - position: absolute; - width: 100%; - min-width: 960px; - z-index: 1; -} -.vrm.index.index .container-inner .main-image-container.christmas { - background-color: #272622; - background-image: url(/img/homepage/main-image-christmas.jpg); - height: 528px; -} -.vrm.index.index .container-inner .main-image-laptop-slideshow-container { - position: relative; -} -.vrm.index.index .container-inner .main-image-laptop-slideshow-container { - position: relative; -} -.vrm.index.index .container-inner .main-image-laptop-slideshow { - height: 303px; - overflow: hidden; - position: absolute; - right: 0; - top: 154px; - width: 443px; - z-index: 1; - -webkit-transform: matrix3d(0.75766177, -0.11351643, 0, -0.00032209, -0.19498093, 0.94274818, 0, -0.00009209, 0, 0, 1, 0, 27, 40, 0, 1); - -moz-transform: matrix3d(0.75766177, -0.11351643, 0, -0.00032209, -0.19498093, 0.94274818, 0, -0.00009209, 0, 0, 1, 0, 27, 40, 0, 1); - -ms-transform: matrix3d(0.75766177, -0.11351643, 0, -0.00032209, -0.19498093, 0.94274818, 0, -0.00009209, 0, 0, 1, 0, 27, 40, 0, 1); - -o-transform: matrix3d(0.75766177, -0.11351643, 0, -0.00032209, -0.19498093, 0.94274818, 0, -0.00009209, 0, 0, 1, 0, 27, 40, 0, 1); - transform: matrix3d(0.75766177, -0.11351643, 0, -0.00032209, -0.19498093, 0.94274818, 0, -0.00009209, 0, 0, 1, 0, 27, 40, 0, 1); - outline: 1px solid transparent; - -webkit-transform-origin: 0px 0px 0px; - transform-origin: 0px 0px 0px; -} -.vrm.index.index .container-inner .main-image-laptop-slideshow-slide-list { - height: 100%; - list-style-type: none; - margin: 0; - padding: 0; - width: 100%; -} -.vrm.index.index .container-inner .main-image-laptop-slideshow-slide { - background-color: transparent; - background-size: cover; - height: 100%; - overflow: hidden; - pointer-events: none; - position: absolute; - width: 100%; - z-index: 1; -} -.vrm.index.index .container-inner .main-image-laptop-slideshow-slide.slide-1 { - background-image: url('/img/homepage/slideshow/slide-1.jpg'); -} -.vrm.index.index .container-inner .main-image-laptop-slideshow-slide.slide-2 { - background-image: url('/img/homepage/slideshow/slide-2.jpg'); -} -.vrm.index.index .container-inner .main-image-laptop-slideshow-slide.slide-3 { - background-image: url('/img/homepage/slideshow/slide-3.jpg'); -} -.vrm.index.index .container-inner .main-image-laptop-slideshow-slide.current { - pointer-events: auto; - z-index: 100; - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); -} -.vrm.index.index .container-inner .main-image-laptop-slideshow-slide.in--next { - z-index: 50; - -webkit-animation: inNext 0.5s forwards ease-in-out; - animation: inNext 0.5s forwards ease-in-out; -} -.vrm.index.index .container-inner .main-image-laptop-slideshow-slide.out--next { - -webkit-animation: outNext 0.5s forwards ease-in-out; - animation: outNext 0.5s forwards ease-in-out; -} -@-webkit-keyframes inNext { - 0% { - -webkit-transform: translate3d(30%, 0, 0); - transform: translate3d(30%, 0, 0); - } - 100% { - -webkit-transform: none; - transform: none; - } -} -@keyframes inNext { - 0% { - -webkit-transform: translate3d(30%, 0, 0); - transform: translate3d(30%, 0, 0); - } - 100% { - -webkit-transform: none; - transform: none; - } -} -@-webkit-keyframes outNext { - 100% { - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - } -} -@keyframes outNext { - 100% { - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - } -} -.vrm.index.index .container-inner .main-image-overlay { - color: #f0efeb; - height: 494px; - padding-left: 7px; - padding-top: 45px; - position: relative; - min-width: 960px; - z-index: 2; -} -.vrm.index.index .container-inner .main-image-overlay .title { - font-size: 40px; - line-height: 40px; - width: 550px; -} -.vrm.index.index .container-inner .main-image-overlay .subtitle { - padding-top: 21px; - width: 325px; -} -.vrm.index.index .container-inner .main-image-overlay .sign-up { - background-color: rgba(0, 0, 0, 0.2); - -webkit-border-radius: 7px; - -moz-border-radius: 7px; - border-radius: 7px; - margin-top: 45px; - padding: 5px; - text-transform: uppercase; - width: 220px; -} -.vrm.index.index .container-inner .main-image-overlay.christmas .title, -.vrm.index.index .container-inner .main-image-overlay.christmas .subtitle { - visibility: hidden; -} -.vrm.index.index .container-inner .main-image-overlay.christmas .sign-up { - margin-top: 18px; -} -.vrm.index.index .container-inner .middle-section-container { - background-color: #ffffff; - border-bottom: 1px solid #dcdbd7; - left: 0px; - height: 759px; - margin-top: -11px; - padding-top: 13px; - position: absolute; - width: 100%; - min-width: 960px; -} -.vrm.index.index .container-inner .middle-section-container .middle-section-inner { - margin: 0 auto; - width: 960px; -} -.vrm.index.index .container-inner .middle-section-container .middle-section-inner .story-container { - margin-top: 17px; -} -.vrm.index.index .container-inner .middle-section-container .middle-section-inner .video-container { - margin-top: 42px; -} -.vrm.index.index .container-inner .middle-section-container .middle-section-inner .video-player { - width: 640px; - margin: 0 auto; -} -.vrm.index.index .container-inner .middle-section-container .middle-section-inner .main-image { - margin-top: 75px; - text-align: center; -} -.vrm.index.index .container-inner .middle-bottom-section-container { - background-color: #faf9f5; - border-bottom: 1px solid #dcdbd7; - left: 0px; - top: 1393px; - margin-top: -11px; - padding-top: 50px; - position: absolute; - width: 100%; - min-width: 960px; -} -.vrm.index.index .container-inner .middle-bottom-section-container .middle-section-inner { - margin: 0 auto; - width: 960px; -} -.vrm.index.index .container-inner .middle-bottom-section-container .middle-section-inner .main-image img { - float: right; - margin-right: -55px; -} -.vrm.index.index .container-inner .middle-bottom-section-container .middle-section-inner .app-icon { - padding-top: 108px; -} -.vrm.index.index .container-inner .middle-bottom-section-container .middle-section-inner .app-icon img { - float: right; -} -.vrm.index.index .container-inner .middle-bottom-section-container .middle-section-inner .text { - padding-top: 49px; -} -.vrm.index.index .container-inner .middle-bottom-section-container .middle-section-inner .text .btn { - margin-top: 35px; - padding: 8px 10px; -} -.vrm.index.index .container-inner .middle-bottom-section-container .middle-section-inner .text .btn.google-play { - margin-left: 15px; -} -.vrm.index.index .container-inner .middle-bottom-section-container .middle-section-inner .text .btn.google-play img { - padding-top: 4px; -} -.vrm.index.index .container-inner .bottom-section-container { - margin-top: 1228px; -} -.vrm.index.index .container-inner .bottom-section-container .bottom-section-inner .text h1 { - margin-top: 61px; -} -.vrm.index.index .container-inner .bottom-section-container .bottom-section-inner .text h3 { - color: #4790d0; - margin-top: 20px; -} -.vrm.index.index .container-inner .bottom-section-container .bottom-section-inner .text .btn { - margin-top: 55px; - padding: 16px 10px; -} -.vrm.index.index .container-inner .bottom-section-container .bottom-section-inner .main-image { - padding-top: 43px; - text-align: center; -} -.vrm.index.index .container-inner .bottom-section-container .bottom-section-inner .subscribe-to-newsletter { - background-color: #4790d0; - border: #dcdbd7 1px solid; - -webkit-border-radius: 7px; - -moz-border-radius: 7px; - border-radius: 7px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - color: #f0efeb; - font-size: 26px; - max-height: 80px; - margin-top: 50px; - padding: 16px 19px 14px 30px; - position: relative; -} -.vrm.index.index .container-inner .bottom-section-container .bottom-section-inner .subscribe-to-newsletter .caption { - display: inline-block; - margin-top: 16px; -} -.vrm.index.index .container-inner .bottom-section-container .bottom-section-inner .subscribe-to-newsletter input[type="text"], -.vrm.index.index .container-inner .bottom-section-container .bottom-section-inner .subscribe-to-newsletter input[type="email"] { - border: #8cc3f0 1px solid; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - height: 50px; - padding-right: 62px; - width: 440px; -} -.vrm.index.index .container-inner .bottom-section-container .bottom-section-inner .subscribe-to-newsletter input[type="submit"] { - /* no retina needed, homepage not visible on mobile */ - background-image: url("/img/VRM-sprite.png"); - background-position: -64px -281px; - height: 40px; - min-height: 40px; - position: absolute; - right: 24px; - top: 21px; - width: 40px; -} -#loginForm { - display: none; -} -.msie9 .main-image-laptop-slideshow-container { - display: none !important; -} -/* -----------[ Rejected browser ]--------------*/ -.browserReject .browsers { - margin-top: 15px; -} -.browserReject .browsers a { - display: inline-block; - vertical-align: top; - width: 100px; - overflow: hidden; - margin: 0 30px; - padding-top: 110px; - /* no retina needed, homepage not visible on mobile */ - background-image: url('/img/browserSprite100.png'); - background-repeat: no-repeat; - border: none; - text-decoration: none; - cursor: pointer; - color: black; -} -.browserReject .browsers a.ie { - background-position: 0px 0px; -} -.browserReject .browsers a.firefox { - background-position: -100px 0px; -} -.browserReject .browsers a.chrome { - background-position: -200px 0px; -} -.browserReject .browsers a.opera { - background-position: -300px 0px; -} -.browserReject .browsers a.safari { - background-position: -400px 0px; -} -/* -----------[Messages, could go to styleguide]--------------*/ -.global-message, -.flash-message, -.form-message { - min-height: 40px; - color: #ffffff; -} -.global-message.error, -.flash-message.error, -.form-message.error { - background-color: #fa716f; - color: #ffffff; -} -.global-message.error ul li, -.flash-message.error ul li, -.form-message.error ul li { - padding-left: 45px; -} -.global-message.error ul li .sprite-icons, -.flash-message.error ul li .sprite-icons, -.form-message.error ul li .sprite-icons { - display: inline-block; - margin-right: 20px; -} -.global-message.success, -.flash-message.success, -.form-message.success { - background-color: #8bc964; -} -.global-message.notice, -.flash-message.notice, -.form-message.notice { - background-color: #4790d0; -} -.global-message.client-side, -.flash-message.client-side, -.form-message.client-side { - display: none; -} -.global-message ul, -.flash-message ul, -.form-message ul { - padding: 15px 0; - margin: 0; - list-style-type: none; -} -.global-message ul li, -.flash-message ul li, -.form-message ul li { - position: relative; -} -.global-message ul li .sprite-icons, -.flash-message ul li .sprite-icons, -.form-message ul li .sprite-icons { - display: none; - left: 0px; - position: absolute; - top: -3px; - top: calc(50% - 12px); -} -.global-message ul li a, -.flash-message ul li a, -.form-message ul li a { - color: #ffffff; -} -.global-message .message-text, -.flash-message .message-text, -.form-message .message-text { - display: inline-block; - padding: 15px 0; -} -.global-message .message-text a, -.flash-message .message-text a, -.form-message .message-text a { - color: #ffffff; -} -.global-message .container-inner, -.flash-message .container-inner, -.form-message .container-inner { - padding-bottom: 0; -} -.flash-message ul li { - margin-top: 10px; -} -.flash-message ul li:first-child { - margin-top: 0px; -} -/* -----------[Form related styling, could go to styleguide]--------------*/ -.form-container h3 { - padding: 18px 18px 0 18px; -} -.form-container h4 { - padding: 6px 18px 6px 18px; -} -.form-container select { - width: 260px; -} -form fieldset { - border: 1px solid #dcdbd7; - background-color: #ffffff; - padding: 19px; - min-width: inherit; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -form input[type="text"], -form input[type="email"], -form input[type="password"], -form input[type="tel"], -form input[type="url"], -form input[type="submit"], -form select { - width: 100%; -} -#sitesettings > fieldset { - width: 300px; -} -#sitesettings > fieldset#fieldset-tags { - width: 100%; -} -#fieldset-summarywidget { - width: 300px; - border: 0; - background-color: transparent; - padding: 0; -} -#fieldset-summarywidget.desktop { - width: 100%; -} -#fieldset-summarywidget.desktop .sortable-summary-widgets { - width: 300px; -} -#fieldset-summarywidget.desktop .sortable-summary-widgets .placeholder { - background-color: #dcdbd7; -} -#fieldset-summarywidget.desktop .sortable-summary-widgets .site-info { - cursor: move; -} -#fieldset-summarywidget.desktop .sortable-summary-widgets .site-info label { - cursor: move; -} -#fieldset-summarywidget.desktop .summary-widget-list-disabled-container { - float: right; - position: relative; -} -#fieldset-summarywidget.desktop .summary-widget-list-disabled .placeholder { - background-color: #f0efeb; - height: 92px; - margin-bottom: 20px; -} -#fieldset-summarywidget.desktop .summary-widget-list-disabled .site-info .custom-data-toggle { - background-color: #f0efeb; -} -#fieldset-summarywidget.desktop .summary-widget-list-disabled .site-info .custom-data-toggle label { - padding: 23px 10px 24px; -} -#fieldset-summarywidget.desktop .summary-widget-list-disabled .form-element { - margin-bottom: 10px; -} -#fieldset-summarywidget.desktop .summary-widget-list-enabled-container { - float: left; - position: relative; -} -#fieldset-summarywidget.desktop .summary-widget-list-enabled-container .horizontal-line { - background-color: #dcdbd7; - height: 1px; -} -#fieldset-summarywidget.desktop .summary-widget-list-enabled-container.full .placeholder-list-item { - display: none !important; -} -#fieldset-summarywidget.desktop .summary-widget-list-header .sub-title { - color: #4790d0; -} -#fieldset-summarywidget.desktop .summary-widget-list-enabled { - -webkit-box-shadow: 0 0 10px #dcdbd7; - -moz-box-shadow: 0 0 10px #dcdbd7; - box-shadow: 0 0 10px #dcdbd7; - /* This dummy is to be able to put styling on only the list items that are actually selected items, so without the header */ -} -#fieldset-summarywidget.desktop .summary-widget-list-enabled .invisible-dummy { - display: none; -} -#fieldset-summarywidget.desktop .summary-widget-list-enabled .form-element { - margin: 0; -} -#fieldset-summarywidget.desktop .summary-widget-list-enabled .custom-data-toggle { - border: none; - padding: 0; -} -#fieldset-summarywidget.desktop .summary-widget-list-enabled .custom-data-toggle label { - padding: 0; -} -#fieldset-summarywidget.desktop .summary-widget-list-enabled .placeholder { - background: url('/img/drag-drop-placeholder-pattern.png') repeat; - background-color: #f0efeb !important; - height: 99px; - position: relative; -} -#fieldset-summarywidget.desktop .summary-widget-list-enabled .placeholder:before { - background-color: #f0efeb; - content: ' '; - left: 50%; - margin-left: -12px; - margin-top: -12px; - position: absolute; - top: 50%; - -webkit-border-radius: 100px; - -moz-border-radius: 100px; - border-radius: 100px; - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -48px -672px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - #fieldset-summarywidget.desktop .summary-widget-list-enabled .placeholder:before { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -#fieldset-summarywidget.desktop .summary-widget-list-enabled .placeholder-list-item { - background: url('/img/drag-drop-placeholder-pattern.png') repeat; - background-color: #f0efeb !important; - height: 99px; - position: relative; -} -#fieldset-summarywidget.desktop .summary-widget-list-enabled .placeholder-list-item:before { - background-color: #f0efeb; - content: ' '; - left: 50%; - margin-left: -12px; - margin-top: -12px; - position: absolute; - top: 50%; - -webkit-border-radius: 100px; - -moz-border-radius: 100px; - border-radius: 100px; - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -48px -672px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - #fieldset-summarywidget.desktop .summary-widget-list-enabled .placeholder-list-item:before { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -#fieldset-summarywidget.desktop .summary-widget-list-enabled.no-placeholder .placeholder { - display: none; -} -#fieldset-summarywidget.desktop .summary-widget-list-enabled-placeholder .invisible-dummy { - display: none; -} -.sortable-widget-list-enabled-caption { - color: #4790d0; - margin-top: 15px; - padding-right: 30px; - position: relative; - text-align: right; -} -.sortable-widget-list-enabled-caption .sprite-icons { - bottom: -1px; - right: 0; - position: absolute; -} -.sortable-widget-list-disabled-caption { - color: #4790d0; - margin-bottom: 12px; - margin-top: 46px; - padding-left: 33px; - position: relative; -} -.sortable-widget-list-disabled-caption .sprite-icons { - bottom: -1px; - left: 0; - position: absolute; -} -.ui-sortable-helper { - background-color: #ffffff !important; - border: 1px solid #dcdbd7; - -webkit-box-shadow: 0 0 10px #dcdbd7; - -moz-box-shadow: 0 0 10px #dcdbd7; - box-shadow: 0 0 10px #dcdbd7; -} -.ui-sortable-helper label { - color: #4790d0 !important; -} -.ui-sortable-helper .custom-data-toggle { - background-color: #ffffff !important; -} -.form-box input[type=file] { - font-size: 100%; -} -.form-element, -.below-fieldset-element { - margin-top: 15px; -} -.form-element:first-child, -.below-fieldset-element:first-child { - margin-top: 0px; -} -.form-element:last-child, -.below-fieldset-element:last-child { - margin-bottom: 20px; -} -.form-element ul, -.below-fieldset-element ul { - padding: 5px 0; - margin: 0; - list-style-type: none; -} -.form-element ul li, -.below-fieldset-element ul li { - color: #fa716f; -} -.form-element > label, -.below-fieldset-element > label { - display: inline-block; - margin-bottom: 5px; -} -.below-fieldset-element { - padding: 20px; - width: 260px; -} -.below-fieldset-element #submit { - width: 100%; -} -.forgot-password-link { - padding: 14px 0; - display: block; - text-align: center; -} -/* -----------[Specific form stlying for a particular parent class]--------------*/ -.button-list { - margin-top: 20px; -} -.button-list li { - padding: 0 20px; - min-height: 50px; - vertical-align: middle; -} -.button-list li .btn { - width: 100%; -} -.add-site-description, -.add-alarm-description { - color: #4790d0; - margin: 80px 0 0 0; -} -.error { - color: #fa716f; -} -.form-tabs { - margin-top: 97px; -} -.mandatory-settings { - display: inline-block; - color: #4790d0; -} -.location-help, -.summary-help { - position: absolute; - display: none; -} -body.vrm.site { - background-color: #f0efeb; -} -body.vrm.site.add .container .container-inner, -body.vrm.site.update .container .container-inner, -#form-container-sitesettings .container .container-inner { - width: 982px; -} -body.vrm.site.add .form-container, -body.vrm.site.update .form-container, -#form-container-sitesettings .form-container { - padding-bottom: 60px; -} -body.vrm.site.add #location_timezone, -body.vrm.site.update #location_timezone, -#form-container-sitesettings #location_timezone { - width: 262px; -} -body.vrm.site.add #fieldset-location.fieldset-location-map, -body.vrm.site.update #fieldset-location.fieldset-location-map, -#form-container-sitesettings #fieldset-location.fieldset-location-map { - border: none; - position: relative; - margin-right: 20px; - padding: 0; -} -body.vrm.site.add #fieldset-location.fieldset-location-map .location-map-container, -body.vrm.site.update #fieldset-location.fieldset-location-map .location-map-container, -#form-container-sitesettings #fieldset-location.fieldset-location-map .location-map-container { - border: 1px solid #dcdbd7; -} -body.vrm.site.add #fieldset-location.fieldset-location-map .location-map-container #location-map, -body.vrm.site.update #fieldset-location.fieldset-location-map .location-map-container #location-map, -#form-container-sitesettings #fieldset-location.fieldset-location-map .location-map-container #location-map { - border: 1px solid #ffffff; - height: 395px; - width: 618px; -} -body.vrm.site.add #fieldset-location.fieldset-location-map #location-info, -body.vrm.site.update #fieldset-location.fieldset-location-map #location-info, -#form-container-sitesettings #fieldset-location.fieldset-location-map #location-info { - background-color: #f0efeb; - height: 50px; - padding-top: 30px; - width: 100%; -} -body.vrm.site.add #fieldset-location.fieldset-location-map #location-info h3, -body.vrm.site.update #fieldset-location.fieldset-location-map #location-info h3, -#form-container-sitesettings #fieldset-location.fieldset-location-map #location-info h3 { - padding-top: 0; -} -body.vrm.site.add #fieldset-geofence.fieldset-geofence-map, -body.vrm.site.update #fieldset-geofence.fieldset-geofence-map, -#form-container-sitesettings #fieldset-geofence.fieldset-geofence-map { - border: none; - position: relative; - margin-right: 20px; - padding: 0; - width: 618px; - background-color: inherit; -} -body.vrm.site.add #fieldset-geofence.fieldset-geofence-map .geofence-map-container, -body.vrm.site.update #fieldset-geofence.fieldset-geofence-map .geofence-map-container, -#form-container-sitesettings #fieldset-geofence.fieldset-geofence-map .geofence-map-container { - margin-top: 20px; - border: 1px solid #dcdbd7; -} -body.vrm.site.add #fieldset-geofence.fieldset-geofence-map .geofence-map-container #geofence-map, -body.vrm.site.update #fieldset-geofence.fieldset-geofence-map .geofence-map-container #geofence-map, -#form-container-sitesettings #fieldset-geofence.fieldset-geofence-map .geofence-map-container #geofence-map { - border: 1px solid #ffffff; - height: 395px; - width: 618px; -} -body.vrm.site.add #fieldset-geofence.fieldset-geofence-map .form-element, -body.vrm.site.update #fieldset-geofence.fieldset-geofence-map .form-element, -#form-container-sitesettings #fieldset-geofence.fieldset-geofence-map .form-element { - width: 50% !important; -} -body.vrm.site.add #fieldset-geofence.fieldset-geofence-map .hint, -body.vrm.site.update #fieldset-geofence.fieldset-geofence-map .hint, -#form-container-sitesettings #fieldset-geofence.fieldset-geofence-map .hint { - color: #4790d0; -} -body.vrm.site.add #fieldset-geofence.fieldset-geofence-map .mobile-hint, -body.vrm.site.update #fieldset-geofence.fieldset-geofence-map .mobile-hint, -#form-container-sitesettings #fieldset-geofence.fieldset-geofence-map .mobile-hint { - color: #4790d0; -} -body.vrm.site.add #fieldset-geofence.fieldset-geofence-map .mobile-hint, -body.vrm.site.update #fieldset-geofence.fieldset-geofence-map .mobile-hint, -#form-container-sitesettings #fieldset-geofence.fieldset-geofence-map .mobile-hint { - display: none; -} -body.vrm.site.add #submit, -body.vrm.site.update #submit, -#form-container-sitesettings #submit { - max-width: 260px; - float: right; -} -#form-container-user-settings #toggleInviteForm { - position: absolute; - top: 4px; - right: 10px; -} -#form-container-user-settings #form-container-inviteuser { - width: 320px; -} -#form-container-user-settings #form-container-inviteuser textarea#personalMessage { - max-width: 280px; - min-width: 280px; - min-height: 100px; - height: 100px; -} -#form-container-user-settings #inviteFormExplanation { - position: absolute; - top: 100px; - right: 0; - width: 270px; - color: #4790d0; -} -#form-container-user-settings #form-user-settings-container .form-input-list .only-text { - font-size: 15px !important; -} -#form-container-user-settings #form-user-settings-container .form-input-list h4 { - color: #63625e; -} -.globalbtn { - margin-top: 20px; -} -/* -----------[User pages]--------------*/ -.vrm.user h2 { - padding-left: 20px; -} -/* ---------[Page with title and table]--------------------*/ -.vrm { - padding-bottom: 30px; -} -.vrm h2.title-with-icon { - position: relative; - padding-left: 60px; - margin-top: 48px; - margin-bottom: 38px; - line-height: 27px; -} -.vrm h2.title-with-icon .sprite-icons { - position: absolute; - left: 0px; - margin: 0px 17px; -} -/* ---------[Admin tables, could go to styleguide]------------*/ -.table-overview.registrations-per-month thead th { - text-align: center; -} -.table-overview, -.table-diagnostics { - background-color: #ffffff; - border: 1px solid #dcdbd7; - border-collapse: collapse; - margin-top: 5px; - margin-bottom: 30px; - width: 100%; - font-size: 13.5px; -} -.table-overview thead th, -.table-diagnostics thead th, -.table-overview tfoot th, -.table-diagnostics tfoot th { - text-align: left; - color: #63625e; - background-color: #f0efeb; -} -.table-overview th, -.table-diagnostics th, -.table-overview td, -.table-diagnostics td { - padding: 4px 5px 3px 5px; - border-bottom: 1px solid #dcdbd7; -} -.table-overview.table-striped thead tr, -.table-diagnostics.table-striped thead tr, -.table-overview.table-striped tfoot tr, -.table-diagnostics.table-striped tfoot tr { - background-color: #e6e5e1; -} -.table-overview.table-striped thead tr th, -.table-diagnostics.table-striped thead tr th, -.table-overview.table-striped tfoot tr th, -.table-diagnostics.table-striped tfoot tr th { - border-bottom-width: 2px; -} -.table-overview.table-striped tbody tr:nth-child(2n), -.table-diagnostics.table-striped tbody tr:nth-child(2n) { - background-color: #e6e5e1; -} -.table-overview img.gravatar, -.table-diagnostics img.gravatar { - height: 40px; - width: 40px; - -webkit-border-radius: 50%; - -moz-border-radius: 50%; - border-radius: 50%; -} -.table-overview div.gravatar-wrapper, -.table-diagnostics div.gravatar-wrapper { - height: 40px; - width: 40px; - position: relative; - text-align: center; - vertical-align: middle; - color: #4790d0; - text-transform: uppercase; - font-size: 14px; - line-height: 40px; - border: none !important; - -webkit-border-radius: 50%; - -moz-border-radius: 50%; - border-radius: 50%; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; -} -.table-overview div.gravatar-wrapper img.gravatar, -.table-diagnostics div.gravatar-wrapper img.gravatar { - position: absolute !important; - top: 0 !important; - left: 0 !important; - height: 38px !important; - width: 38px !important; - float: none !important; - margin: 0 !important; - border-width: 1px !important; - border-style: solid !important; - border-color: #dcdbd7; - background: none !important; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; -} -.table-overview img.gravatar, -.table-diagnostics img.gravatar, -.table-overview div.gravatar-wrapper img.gravatar, -.table-diagnostics div.gravatar-wrapper img.gravatar, -.table-overview div.gravatar-wrapper, -.table-diagnostics div.gravatar-wrapper { - background-color: white; -} -.chrome .table-overview img.gravatar, -.chrome .table-diagnostics img.gravatar, -.chrome .table-overview div.gravatar-wrapper img.gravatar, -.chrome .table-diagnostics div.gravatar-wrapper img.gravatar, -.chrome .table-overview div.gravatar-wrapper, -.chrome .table-diagnostics div.gravatar-wrapper, -.webkit .table-overview img.gravatar, -.webkit .table-diagnostics img.gravatar, -.webkit .table-overview div.gravatar-wrapper img.gravatar, -.webkit .table-diagnostics div.gravatar-wrapper img.gravatar, -.webkit .table-overview div.gravatar-wrapper, -.webkit .table-diagnostics div.gravatar-wrapper { - line-height: 44px; -} -/* --------[Specific tables]----------*/ -.table-system-overview { - background-color: #ffffff; - border: 1px solid #dcdbd7; - border-collapse: collapse; - margin-top: 5px; - margin-bottom: 30px; - width: 100%; -} -.table-system-overview thead th, -.table-system-overview tfoot th { - text-align: left; - color: #63625e; - background-color: #f0efeb; -} -.table-system-overview th, -.table-system-overview td { - padding: 15px 20px 13px 20px; - border-bottom: 1px solid #dcdbd7; -} -.table-system-overview th:first-child, -.table-system-overview td:first-child { - width: 200px; -} -#mobile-alarms { - display: none; -} -.table-alarms .alarmStarted { - color: #fa716f; -} -.table-alarms .alarmCleared { - color: #4790d0; -} -.table-alarms .alarmActive { - color: #fa716f; -} -.table-alarms .alarmInactive { - color: #4790d0; -} -.pagination ul { - display: inline-block; - background-color: #ffffff; - border: 1px solid #dcdbd7; - margin: 15px 0; - padding: 0 10px; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; -} -.pagination ul li { - display: inline-block; - padding: 5px; -} -.pagination ul li a { - text-decoration: none; -} -.pagination ul li.active { - font-weight: bold; - font-size: calc(16px); -} -.pagination ul li.disabled a { - color: #272622; - cursor: default; -} -.pagination.pagination-centered { - margin-left: auto; - margin-right: auto; - text-align: center; -} -/* -----------[Menu]--------------*/ -.top-menu { - background-color: #272622; - height: 35px; - position: relative; -} -.top-menu .container-inner { - height: 100%; - text-align: right; -} -.top-menu ul { - height: 100%; - margin: 0; -} -.top-menu ul li { - display: inline-block; - height: 100%; - margin-top: -13px; - padding: 0 12.5px; -} -.top-menu ul li.pull-left { - -webkit-transform: translateY(13px); - -moz-transform: translateY(13px); - -ms-transform: translateY(13px); - -o-transform: translateY(13px); - transform: translateY(13px); -} -.top-menu ul li > ul.sub-menu { - display: none; - position: absolute; - top: 100%; - z-index: 999999; - height: auto; - margin-top: -8px; - margin-left: -32.5px; - padding: 8px 20px 20px 20px; -} -.top-menu ul li > ul.sub-menu li { - display: block; - background-color: #272622; - height: 35px; - padding: 0; - margin-top: 0; - text-align: left; - border-left: 1px solid #dcdbd7; - border-right: 1px solid #dcdbd7; -} -.top-menu ul li > ul.sub-menu li a { - padding: 7px 12.5px; - box-sizing: border-box; - min-width: 100%; -} -.top-menu ul li > ul.sub-menu li:last-child { - border-bottom-right-radius: 5px; - border-bottom-left-radius: 5px; - barder-bottom: 1px solid #dcdbd7; -} -.top-menu ul li:hover > ul.sub-menu, -.top-menu ul li > ul.sub-menu.expanded { - display: block; -} -.top-menu a, -.top-menu span { - color: #ffffff; - display: inline-block; - padding-top: 7px; - text-decoration: none; -} -.top-menu a:hover { - color: #ffffff; - text-decoration: underline; -} -.top-menu .plus-sign { - color: #afe18d; -} -.top-menu .container-inner { - padding-bottom: 0; -} -.top-menu-language-selector-container { - border-left: 1px solid #63625e; - cursor: pointer; - -webkit-transform: translateY(13px); - -moz-transform: translateY(13px); - -ms-transform: translateY(13px); - -o-transform: translateY(13px); - transform: translateY(13px); -} -.top-menu-language-selector-container:hover .top-menu-language-abbreviation { - text-decoration: underline; -} -.top-menu-language-abbreviation { - color: #ffffff; - float: left; - padding-top: 7px; -} -.top-menu-language-handle { - float: left; - margin-left: 4px; - margin-top: 5px; -} -.top-menu-language-fly-out { - background-color: #ffffff; - left: 0; - overflow: hidden; - position: absolute; - top: 35px; - width: 100%; - z-index: 1100; - -webkit-box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1); - box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1); -} -.top-menu-language-fly-out-content { - text-align: left; -} -.top-menu-language-fly-out-content.transitional { - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; -} -.top-menu-language-fly-out-content.visible { - margin-top: 0 !important; -} -.top-menu-language-fly-out-title { - margin-top: 24px; -} -.top-menu-language-fly-out-language-container { - margin-bottom: 20px; - margin-top: 20px; -} -.top-menu .top-menu-language-fly-out-language-link { - color: #4790d0; -} -.top-menu .top-menu-language-fly-out-language-link:hover { - color: #4790d0; -} -.top-menu .top-menu-language-fly-out-language-current { - display: inline-block; - padding-top: 7px; - color: #272622; -} -.mobile-menu { - display: none; -} -.site-overlay-on-menu-open { - background-color: rgba(0, 0, 0, 0.6); - left: -10000px; - position: fixed; - top: 0; - height: 100%; - width: 100%; - z-index: 1099; - opacity: 0; - filter: alpha(opacity=0); -} -.mobile-menu-open-handle { - display: none; -} -.mobile-menu-close-handle { - position: fixed; - top: 20px; - right: -50px; - z-index: 1100; -} -/* -----------[Header]--------------*/ -.header { - background-color: #f0efeb; - border-bottom: 1px solid #dcdbd7; - height: 80px; -} -.header .secondary-controls { - margin: 15px 10px; -} -.header .secondary-controls .btn { - padding: 14px 10px 13px 10px; -} -.header .secondary-controls ul li { - display: inline-block; - margin-left: 15px; -} -.header .secondary-controls ul li .login { - background-color: #4790d0; - color: #ffffff; -} -.header .secondary-controls ul li .login:hover { - background-color: #387dc5; -} -.breadcrumb { - background-color: #f0efeb; - border-bottom: 1px solid #dcdbd7; - border-top: 1px solid #dcdbd7; - height: 80px; -} -.breadcrumb .breadcrumb-buttons-container { - padding-top: 20px; - text-align: right; -} -.breadcrumb .breadcrumb-buttons-container .btn { - float: right; - font-size: 15px; - margin-left: 16px; -} -.breadcrumb .breadcrumb-buttons-container .remote-console-control-icon { - fill: #ffffff; -} -.breadcrumb .breadcrumb-buttons-container .remote-console-control-icon path { - fill: #ffffff; -} -.breadcrumb .site-select { - display: inline-block; - text-align: left; -} -.breadcrumb .secondary-controls { - margin: 15px 10px; -} -.breadcrumb .secondary-controls ul li { - display: inline-block; - margin-left: 15px; -} -.breadcrumb-site-title { - display: none; - font-size: 21px; - margin: 30px 0; - text-align: left; -} -.branding-logo { - display: inline-block; - width: 240px; - height: 80px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -97px -577px; - float: left; - margin: 0; - text-decoration: none; - border: none; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .branding-logo { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.sites-statistics { - display: none; -} -.map-view .map { - height: 230px; -} -.map-overview .map { - height: 480px; -} -.siteinfo img { - position: absolute !important; - width: 372.59999999999997px; - height: 532.8px; - clip: rect(86.39999999999999px 28.799999999999997px 100.79999999999998px 14.399999999999999px); - top: -81.39999999999999px; - right: -338.8px; -} -.siteinfo .infowindow { - background-color: white; - padding: 10px; - border: 1px solid #dcdbd7; - font-family: 'MuseoSans-300', sans-serif; - font-size: 12px; - line-height: 13px; -} -.siteinfo .infowindow > *:first-child { - padding-right: 14.399999999999999px; -} -.siteinfo .infowindow > * { - margin-top: 6px; -} -.map-overview, -.map-view { - border-bottom: 1px solid #dcdbd7; - position: relative; -} -.map-overview .top-shadow, -.map-view .top-shadow, -.map-overview .bottom-shadow, -.map-view .bottom-shadow { - background-color: rgba(99, 98, 94, 0.1); - position: absolute; - width: 100%; - z-index: 3; -} -.map-overview .top-shadow, -.map-view .top-shadow { - height: 5px; -} -.map-overview .bottom-shadow, -.map-view .bottom-shadow { - bottom: 0px; - height: 10px; -} -.map .cluster { - margin-top: -31px; - margin-left: -10px; -} -#vrm-tabs { - margin-top: -65px; - padding-left: 10px; - position: absolute; - z-index: 4; -} -body.vrm.site.index .main-content { - position: relative; -} -body .site-overview { - padding-top: 50px; -} -body .site-overview h2 { - margin-top: 0; - margin-bottom: 15px; -} -body .site-overview .container-inner { - position: relative; -} -body .site-overview .container-inner .over-google-map { - position: absolute; - top: -116px; - z-index: 2; -} -body .site-overview .container-inner .over-google-map .grid-item { - margin-bottom: 20px; -} -body .site-overview .container-inner table.site-list { - background: #ffffff; - width: 100%; - border: 1px solid #dcdbd7; -} -body .site-overview .container-inner table.site-list th { - text-align: left; - height: 45px; - border-bottom: 1px solid #dcdbd7; - background: #faf9f5; - padding: 0 0 0 20px; - font-weight: normal; - color: #63625e; - width: 110px; -} -body .site-overview .container-inner table.site-list th.name { - width: 200px; -} -body .site-overview .container-inner table.site-list th.soc { - width: 125px; -} -body .site-overview .container-inner table.site-list th.alarm { - width: 55px; - padding-right: 20px; - text-align: center; -} -body .site-overview .container-inner table.site-list th.sort-column-asc::after { - content: "▴"; - margin-left: 6px; -} -body .site-overview .container-inner table.site-list th.sort-column-desc::after { - content: "▾"; - margin-left: 6px; -} -body .site-overview .container-inner table.site-list tr.has-alarm td:first-child { - border-left: 3px solid #fa716f; - padding-left: 17px; -} -body .site-overview .container-inner table.site-list td { - height: 50px; - border-bottom: 1px solid #dcdbd7; - padding: 0 0 0 20px; -} -body .site-overview .container-inner table.site-list td.has-alarm { - border-left: 3px solid #fa716f; - padding-left: 17px; -} -body .site-overview .container-inner table.site-list td .caption { - line-height: 24px; -} -body .site-overview .container-inner table.site-list td:last-child { - text-align: center; - padding-right: 20px; -} -body .site-overview .container-inner table.site-list .voltage { - color: #387dc5; -} -body .site-overview .container-inner table.site-list .current { - color: #f0962e; -} -.site-overview-controls { - background: #faf9f5; - border-bottom: 1px solid #dcdbd7; - color: #63625e; - padding: 30px 0; -} -.site-overview-controls .container-inner { - padding: 0; -} -.site-overview-controls .container-inner .grid-item .caption { - margin-bottom: 5px; -} -.site-overview-controls .container-inner .grid-item.view-toggle .view-toggle-container { - margin-left: 20px; -} -.site-overview-controls .container-inner .grid-item.view-toggle .view-toggle-container .custom-toggle { - margin: 10px 0; - text-align: right; -} -.site-overview-controls .container-inner .grid-item.view-toggle .view-toggle-container .custom-toggle .alternative-display .on .sprite-icons, -.site-overview-controls .container-inner .grid-item.view-toggle .view-toggle-container .custom-toggle .alternative-display .off .sprite-icons { - margin-top: 8px; -} -.site-overview-controls .container-inner .grid-item.view-toggle .view-toggle-container .custom-toggle .alternative-display .off { - background-color: #4790d0 !important; - -webkit-box-shadow: 0px 2px 0px #387dc5 inset !important; - -moz-box-shadow: 0px 2px 0px #387dc5 inset !important; - box-shadow: 0px 2px 0px #387dc5 inset !important; -} -.site-overview-controls .container-inner .grid-item.view-toggle .view-toggle-container .custom-toggle .alternative-display .knob { - -webkit-box-shadow: 5px 0px 0px #5b9bcd !important; - -moz-box-shadow: 5px 0px 0px #5b9bcd !important; - box-shadow: 5px 0px 0px #5b9bcd !important; -} -.site-overview-controls .container-inner .grid-item.view-toggle .view-toggle-container .custom-toggle input:checked + label .alternative-display .knob { - -webkit-box-shadow: -5px 0px 0px #5b9bcd !important; - -moz-box-shadow: -5px 0px 0px #5b9bcd !important; - box-shadow: -5px 0px 0px #5b9bcd !important; - left: 57px; -} -.site-overview-controls .container-inner .grid-item.tags { - clear: none; - padding-top: 21px; -} -.tags, -.tagsinput { - clear: both; -} -.tags span.tag, -.tagsinput span.tag { - background-color: #4790d0; - border: 1px solid #dcdbd7; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; - -webkit-box-shadow: 0px 2px 0px #387dc5 inset; - -moz-box-shadow: 0px 2px 0px #387dc5 inset; - box-shadow: 0px 2px 0px #387dc5 inset; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - color: #ffffff; - display: inline-block; - min-height: 40px; - padding: 8px 45px 8px 10px; - text-decoration: none; - margin: 10px 10px 0 0; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; - position: relative; -} -.tags span.tag:hover, -.tagsinput span.tag:hover { - background-color: #387dc5; - text-decoration: none; -} -.tags span.tag a, -.tagsinput span.tag a { - color: #4790d0; - position: absolute; - right: 7px; - top: 7px; - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -48px -432px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .tags span.tag a, - .tagsinput span.tag a { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.site-view { - background-color: #f0efeb; -} -.site-view .container-inner { - position: relative; -} -.site-view .container-inner .tab-select { - display: none; -} -.site-view .container-inner.no-bottom-padding { - padding-bottom: 0px; -} -.VRM_Widget_SiteSummary { - margin-bottom: 20px; -} -.VRM_Widget_SiteSummary a { - display: block; - text-decoration: none; - color: #63625e; -} -.VRM_Widget_SiteSummary .title { - line-height: 22px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} -.VRM_Widget_SiteSummary .sub-title { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} -.VRM_Widget_SiteSummary.has-alarm .site-name { - color: #f35c58; - position: relative; -} -.VRM_Widget_SiteSummary.has-alarm .site-name .title { - padding-right: 30px; -} -.VRM_Widget_SiteSummary.has-alarm .site-name .alert-red { - position: absolute; - right: 20px; - top: 21px; -} -.VRM_Widget_SiteSummary.has-alarm a { - color: #f35c58; -} -.VRM_Widget_SolarChargerPVYield .jqplot-target .jqplot-yaxis { - color: #666666 !important; -} -.site-info-list li { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - max-height: 99px; - min-height: 99px; - border-top: 1px solid #dcdbd7; - border-left: 1px solid #dcdbd7; - border-right: 1px solid #dcdbd7; - background-color: #ffffff; - padding: 22px 20px 24px 20px; -} -.site-info-list li:first-child { - background-color: #faf9f5; - max-height: 79px; - min-height: 79px; -} -.site-info-list li:first-child .data-container .voltage { - color: #387dc5; -} -.site-info-list li:first-child .data-container .current { - color: #f0962e; -} -.site-info-list li.site-name { - padding: 0px; -} -.site-info-list li.site-name a { - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; - height: 78px; - width: 298px; -} -.site-info-list li.site-name a:hover { - background-color: #ffffff; -} -.site-info-list li.site-name .title { - font-size: 21px; - padding-left: 20px; - padding-right: 20px; - padding-top: 22px; -} -.site-info-list li.site-name .sub-title { - padding-left: 20px; -} -.site-info-list li.site-name .sub-title .caption { - vertical-align: super; -} -.site-info-list li.site-info { - *zoom: 1; -} -.site-info-list li.site-info:before, -.site-info-list li.site-info:after { - display: table; - content: ""; - line-height: 0; -} -.site-info-list li.site-info:after { - clear: both; -} -.site-info-list li.site-info .img-container { - width: 45px; - height: 45px; - float: left; -} -.site-info-list li.site-info .data-container { - float: right; - width: 170px; - padding: 5px 5px 5px 15px; -} -.site-info-list li.site-info .data-container .caption { - display: block; - font-size: 18px; -} -.site-info-list li.site-info .data-container .data-value { - display: block; -} -.site-info-list li.site-info .data-container .data-value .olddata { - color: #f35c58; -} -.site-info-list li.site-info .data-container .data-value .current { - color: #f0962e; -} -.site-info-list li.site-info .data-container .data-value .voltage { - color: #387dc5; -} -.site-info-list li.site-info .data-container .data-value .standard { - color: #387dc5; -} -.site-info-list li:last-child { - border-bottom: 1px solid #dcdbd7; -} -/* -----------[Custom data toggle]--------------*/ -.custom-data-toggle { - *zoom: 1; - background-color: #e6e5e1; - border: 1px solid #dcdbd7; - padding: 0px 10px; -} -.custom-data-toggle:before, -.custom-data-toggle:after { - display: table; - content: ""; - line-height: 0; -} -.custom-data-toggle:after { - clear: both; -} -.custom-data-toggle.checked { - background-color: #ffffff; -} -.custom-data-toggle input { - display: none; -} -.custom-data-toggle label { - display: block; - height: 50px; - padding: 20px 10px; -} -.custom-data-toggle .img-container { - width: 45px; - height: 45px; - float: left; -} -.custom-data-toggle .data-container { - float: right; - width: 180px; - padding: 5px; -} -.custom-data-toggle .data-container .caption { - display: block; -} -.custom-data-toggle .data-container .data-value { - display: block; -} -/* -------------[ Google Maps ]-------------- */ -.gm-style img { - /** Fixes that obnoxious Bootstrap responsive image hack */ - max-width: none; -} -.gmnoprint img { - max-width: inherit; -} -/* --------------[ Tabs ]--------------------*/ -#vrm-tabs-content { - color: #63625e; -} -#vrm-tabs-content .tab-pane .content { - position: relative; - padding: 0; -} -#vrm-tabs-content .tab-pane#settings #main-settings-form { - display: none; -} -#vrm-tabs-content .tab-pane#settings .content .form-tabs-container .mobile-title { - display: none; -} -#vrm-tabs-content .tab-pane#settings .content .form-tabs-container .form-tabs { - margin-top: 0px; -} -#vrm-tabs-content .tab-pane#settings .content .form-tabs-container .form-tabs li { - overflow: hidden; -} -#vrm-tabs-content .tab-pane#settings .content .form-tabs-container .form-tabs li:first-child { - -webkit-border-top-left-radius: 5px; - -moz-border-radius-topleft: 5px; - border-top-left-radius: 5px; - -webkit-border-top-right-radius: 5px; - -moz-border-radius-topright: 5px; - border-top-right-radius: 5px; -} -#vrm-tabs-content .tab-pane#settings .content .form-tabs-container .form-tabs li:first-child a { - -webkit-border-top-left-radius: 5px; - -moz-border-radius-topleft: 5px; - border-top-left-radius: 5px; - -webkit-border-top-right-radius: 5px; - -moz-border-radius-topright: 5px; - border-top-right-radius: 5px; -} -#vrm-tabs-content .tab-pane#settings .content .form-tabs-container .form-tabs li:last-child { - -webkit-border-bottom-left-radius: 5px; - -moz-border-radius-bottomleft: 5px; - border-bottom-left-radius: 5px; - -webkit-border-bottom-right-radius: 5px; - -moz-border-radius-bottomright: 5px; - border-bottom-right-radius: 5px; -} -#vrm-tabs-content .tab-pane#settings .content .form-tabs-container .form-tabs li:last-child a { - -webkit-border-bottom-left-radius: 5px; - -moz-border-radius-bottomleft: 5px; - border-bottom-left-radius: 5px; - -webkit-border-bottom-right-radius: 5px; - -moz-border-radius-bottomright: 5px; - border-bottom-right-radius: 5px; -} -#vrm-tabs-content .tab-pane#settings .content .form-tabs-container .form-tabs .error, -#vrm-tabs-content .tab-pane#settings .content .form-tabs-container .form-tabs .error .required { - color: #fa716f; -} -#vrm-tabs-content .tab-pane#settings .content #settingsButtonErrorText { - display: block; - margin-top: 20px; - text-align: center; - color: #fa716f; -} -#vrm-tabs-content .tab-pane#settings .content .remove-site-question { - margin-bottom: 20px; -} -#vrm-tabs-content .tab-pane#settings .content .remove-site-question h3 { - margin-bottom: 10px; -} -#vrm-tabs-content .tab-pane#settings .content .header { - background-color: #f0efeb; - border: 1px solid #dcdbd7; - border-bottom: none; - height: 10px; - padding: 17px 20px 22px; -} -#vrm-tabs-content .tab-pane#settings .content .header .caption-right { - float: right; - padding-right: 18px; -} -#vrm-tabs-content .tab-pane#settings .content .sortable-widgets-header { - background-color: #faf9f5; - border: 1px solid #dcdbd7; - border-bottom: none; - height: 30px; - padding: 18px 20px 2px 18px; -} -#vrm-tabs-content .tab-pane#settings .content .sortable-widgets-header .caption { - font-size: 21px; -} -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .header { - background-color: #faf9f5; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list, -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list, -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list { - background-color: #ffffff; - border: 1px solid #dcdbd7; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list .row, -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row, -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row { - border-bottom: 1px solid #f0efeb; - height: 60px; - overflow: hidden; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list .row:last-child, -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row:last-child, -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row:last-child { - border-color: #dcdbd7; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list .row .inner-container, -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container, -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container { - padding: 10px 20px 10px 20px; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list .row .inner-container .custom-toggle > input, -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container .custom-toggle > input, -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle > input { - display: none; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list .row .inner-container .custom-toggle label, -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label, -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle label { - font-size: 18px; - padding: 0px; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list .row .inner-container .custom-toggle label .alternative-display, -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label .alternative-display, -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle label .alternative-display { - left: auto; - right: 0px; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list .row .inner-container .custom-toggle label a, -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label a, -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle label a { - display: block; - position: absolute; - top: 8px; - right: 0px; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list .row .inner-container .custom-toggle label a:hover > div, -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label a:hover > div, -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle label a:hover > div { - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -432px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - #vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list .row .inner-container .custom-toggle label a:hover > div, - #vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label a:hover > div, - #vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle label a:hover > div { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list .row .inner-container .only-text, -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container .only-text, -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container .only-text { - font-size: 18px; - line-height: 44px; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list .row .inner-container .only-text .on-off, -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container .only-text .on-off, -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container .only-text .on-off { - float: right; - margin-top: -10px; - width: 170px; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list .row .inner-container .email-caption, -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container .email-caption, -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container .email-caption { - color: #387dc5; - font-size: 15px; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list:last-child, -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list:last-child, -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list:last-child { - border-bottom: none; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list.sortable-widgets, -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list.sortable-widgets, -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list.sortable-widgets { - position: relative; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list.sortable-widgets li, -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list.sortable-widgets li, -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list.sortable-widgets li { - height: 49px; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list.sortable-widgets .row, -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list.sortable-widgets .row, -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list.sortable-widgets .row { - color: #4790d0; - cursor: move; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list.sortable-widgets .row .inner-container, -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list.sortable-widgets .row .inner-container, -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list.sortable-widgets .row .inner-container { - color: #63625e; - display: block; - padding: 17px 0 12px 46px; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list.sortable-widgets .row .inner-container .custom-toggle label, -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list.sortable-widgets .row .inner-container .custom-toggle label, -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list.sortable-widgets .row .inner-container .custom-toggle label { - cursor: move; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list.sortable-widgets .row input[type="checkbox"], -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list.sortable-widgets .row input[type="checkbox"], -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list.sortable-widgets .row input[type="checkbox"] { - position: absolute; - visibility: hidden; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list.sortable-widgets .row.ui-sortable-placeholder, -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list.sortable-widgets .row.ui-sortable-placeholder, -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list.sortable-widgets .row.ui-sortable-placeholder { - visibility: visible !important; -} -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row { - border-bottom: 1px solid #f0efeb; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .disabled-widgets-container { - float: right; - margin-right: 0px; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .disabled-widgets { - background-color: #f0efeb; - border: none; - min-height: 50px; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .disabled-widgets li { - border: 1px solid #dcdbd7; - margin-bottom: -1px; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .disabled-widgets li .inner-container { - padding-left: 37px !important; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .disabled-widgets .ui-sortable-placeholder { - border: none; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .sortable-widget-list-disabled-caption { - margin-bottom: 3px; - margin-top: 27px; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .active-widgets-container { - float: left; - margin-left: 0px; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .active-widgets-container .horizontal-line { - background-color: #dcdbd7; - height: 1px; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .active-widgets { - list-style-type: none; - margin: 0; - padding: 0; - -webkit-box-shadow: 0 0 10px #dcdbd7; - -moz-box-shadow: 0 0 10px #dcdbd7; - box-shadow: 0 0 10px #dcdbd7; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .active-widgets li { - counter-increment: customlistcounter; - list-style-position: inside; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .active-widgets li:before { - content: counter(customlistcounter) " "; - float: left; - margin-left: 20px; - margin-top: 17px; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .active-widgets li:first-child { - counter-reset: customlistcounter; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .active-widgets .placeholder-list-item { - background: url('/img/drag-drop-placeholder-pattern.png') repeat; - background-color: #f0efeb !important; - height: 99px; - position: relative; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .active-widgets .placeholder-list-item:before { - background-color: #f0efeb; - content: ' '; - left: 50%; - margin-left: -12px; - margin-top: -12px; - position: absolute; - top: 50%; - -webkit-border-radius: 100px; - -moz-border-radius: 100px; - border-radius: 100px; - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -48px -672px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - #vrm-tabs-content .tab-pane#settings .content #form-widget-settings .active-widgets .placeholder-list-item:before { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .active-widgets .ui-sortable-placeholder { - background: url('/img/drag-drop-placeholder-pattern.png') repeat; - background-color: #f0efeb !important; - height: 99px; - position: relative; -} -#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .active-widgets .ui-sortable-placeholder:before { - background-color: #f0efeb; - content: ' '; - left: 50%; - margin-left: -12px; - margin-top: -12px; - position: absolute; - top: 50%; - -webkit-border-radius: 100px; - -moz-border-radius: 100px; - border-radius: 100px; - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -48px -672px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - #vrm-tabs-content .tab-pane#settings .content #form-widget-settings .active-widgets .ui-sortable-placeholder:before { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label, -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle label { - line-height: 21px; -} -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container .only-text, -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container .only-text { - line-height: 21px; -} -#vrm-tabs-content .tab-pane#settings .content #form-container-sitesettings { - margin-bottom: 20px; -} -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .header { - background-color: #faf9f5; -} -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .header .caption-right { - padding-right: 0; - width: 170px; -} -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container img.gravatar { - height: 40px; - width: 40px; - -webkit-border-radius: 50%; - -moz-border-radius: 50%; - border-radius: 50%; -} -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container div.gravatar-wrapper { - height: 40px; - width: 40px; - position: relative; - text-align: center; - vertical-align: middle; - color: #4790d0; - text-transform: uppercase; - font-size: 14px; - line-height: 40px; - border: none !important; - -webkit-border-radius: 50%; - -moz-border-radius: 50%; - border-radius: 50%; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; -} -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container div.gravatar-wrapper img.gravatar { - position: absolute !important; - top: 0 !important; - left: 0 !important; - height: 38px !important; - width: 38px !important; - float: none !important; - margin: 0 !important; - border-width: 1px !important; - border-style: solid !important; - border-color: #dcdbd7; - background: none !important; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; -} -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container img.gravatar, -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container div.gravatar-wrapper img.gravatar, -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container div.gravatar-wrapper { - float: left; - margin-right: 20px; -} -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container img.gravatar.admin, -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container div.gravatar-wrapper img.gravatar.admin, -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container div.gravatar-wrapper.admin { - color: #8bc964; - border-color: #8bc964; -} -.chrome #vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container img.gravatar, -.chrome #vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container div.gravatar-wrapper img.gravatar, -.chrome #vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container div.gravatar-wrapper, -.webkit #vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container img.gravatar, -.webkit #vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container div.gravatar-wrapper img.gravatar, -.webkit #vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container div.gravatar-wrapper { - line-height: 41px !important; -} -#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label .alternative-display { - display: block; - right: 40px; -} -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings { - margin-bottom: 10px; -} -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row { - border-bottom: 1px solid #f0efeb; -} -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container img.gravatar { - height: 40px; - width: 40px; - -webkit-border-radius: 50%; - -moz-border-radius: 50%; - border-radius: 50%; -} -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container div.gravatar-wrapper { - height: 40px; - width: 40px; - position: relative; - text-align: center; - vertical-align: middle; - color: #4790d0; - text-transform: uppercase; - font-size: 14px; - line-height: 40px; - border: none !important; - -webkit-border-radius: 50%; - -moz-border-radius: 50%; - border-radius: 50%; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; -} -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container div.gravatar-wrapper img.gravatar { - position: absolute !important; - top: 0 !important; - left: 0 !important; - height: 38px !important; - width: 38px !important; - float: none !important; - margin: 0 !important; - border-width: 1px !important; - border-style: solid !important; - border-color: #dcdbd7; - background: none !important; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; -} -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container img.gravatar, -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container div.gravatar-wrapper img.gravatar, -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container div.gravatar-wrapper { - float: left; - margin-right: 20px; -} -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container img.gravatar.receives-notifications, -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container div.gravatar-wrapper img.gravatar.receives-notifications, -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container div.gravatar-wrapper.receives-notifications { - color: #4790d0; - border-color: #4790d0; -} -.chrome #vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container img.gravatar, -.chrome #vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container div.gravatar-wrapper img.gravatar, -.chrome #vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container div.gravatar-wrapper, -.webkit #vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container img.gravatar, -.webkit #vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container div.gravatar-wrapper img.gravatar, -.webkit #vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container div.gravatar-wrapper { - line-height: 41px !important; -} -#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row:last-child { - border-bottom: 1px solid #dcdbd7; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings { - position: relative; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container { - /*width: 300px;*/ -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #alarm_notifications-label, -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #no_data-label, -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #float_limits-label, -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #enum_limits-label { - height: 0px; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #alarm_notifications-element .custom-toggle.main label .caption, -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #no_data-element .custom-toggle.main label .caption { - color: #387dc5; - font-size: 18px; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #alarm_notifications-element dt { - height: 0px; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #alarm_notifications-element .form-input-list { - margin: 0px; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #no_data-element, -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits { - position: relative; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #no_data-element fieldset dl, -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits fieldset dl { - margin: 0px; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #no_data-element fieldset dl #no_data-enabled-label, -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits fieldset dl #no_data-enabled-label { - height: 0px; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #no_data-element fieldset dl #no_data-enabled-element, -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits fieldset dl #no_data-enabled-element { - margin-bottom: 15px; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #no_data-element fieldset dl .hint, -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits fieldset dl .hint { - color: #4790d0; - position: absolute; - right: -300px; - top: 0px; - width: 270px; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-no_data { - margin-bottom: 15px; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-float_limits, -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits { - border: none; - padding: 15px; - margin-bottom: 15px; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-float_limits > dl, -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits > dl { - background-color: #f0efeb; - margin: 0px; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-float_limits > dl > dt, -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits > dl > dt { - height: 0px; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-float_limits > dl > dd, -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits > dl > dd { - position: relative; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-float_limits > dl > dd > fieldset > dl, -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits > dl > dd > fieldset > dl { - margin-top: 0px; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-float_limits > dl > dd > fieldset > dl > dt:nth-child(2), -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits > dl > dd > fieldset > dl > dt:nth-child(2) { - height: 0px; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-float_limits > dl > dd > fieldset > dl > dt:not(:first-child), -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits > dl > dd > fieldset > dl > dt:not(:first-child) { - margin-top: 15px; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-float_limits .custom-toggle.main label .caption, -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits .custom-toggle.main label .caption { - color: #387dc5; - font-size: 18px; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-float_limits .remove-alarm-button, -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits .remove-alarm-button { - position: absolute; - top: 20px; - right: 20px; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form dd { - margin-left: 0px; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .above-fieldset-element { - position: absolute; - right: 0px; - top: -69px; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .above-fieldset-element .btn { - margin-left: 12px; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .admin-users-box .title { - font-size: 18px; - margin: 20px 0 20px 20px; -} -#vrm-tabs-content .tab-pane#settings .content #form-user-settings .sprite-icons.cross-in-circle-dark { - vertical-align: top; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-system-overview .device-icon { - float: left; - margin-right: 5px; -} -#vrm-tabs-content .tab-pane#settings .content #forms-container-system-overview .device-icon + h3 { - line-height: 48px; -} -#vrm-tabs-content h2 { - margin: 12px 0 2px 0; -} -#vrm-tabs-content .section-heading { - *zoom: 1; - margin: 35px 0 7px 0; -} -#vrm-tabs-content .section-heading:before, -#vrm-tabs-content .section-heading:after { - display: table; - content: ""; - line-height: 0; -} -#vrm-tabs-content .section-heading:after { - clear: both; -} -#vrm-tabs-content .section-heading .sprite-icons { - float: left; - margin: 9px 21px 25px 25px; -} -#vrm-tabs-content .section-heading .information { - float: left; -} -#vrm-tabs-content .section-heading .btn { - margin-right: 10px; - margin-top: 29px; -} -#vrm-tabs-content .widget-filter-container { - margin-bottom: 20px; -} -#vrm-tabs-content .widget-filter-container #widget-filter { - width: 100%; -} -#vrm-tabs-content #advanced .section-heading { - margin: 35px 0; -} -#vrm-tabs-content .last-update-info { - color: #63625e; - padding-right: 15px; - text-align: right; - float: left; -} -#vrm-tabs-content .mobile-graph-refresh { - display: none; -} -#vrm-tabs-content .progress-meters-container { - border-top: 1px solid #dcdbd7; - height: 396px; -} -#vrm-tabs-content .progress-meters-container .progress-meter-container { - background-color: #ffffff; - border: 1px solid #dcdbd7; - border-top: none; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - padding: 20px 60px 48px 60px; - position: relative; - width: 100%; -} -#vrm-tabs-content .progress-meters-container .progress-meter-container .progress-meter, -#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter { - position: relative; - width: 100%; -} -#vrm-tabs-content .progress-meters-container .progress-meter-container .progress-meter .inner-meter-container, -#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container { - position: relative; -} -#vrm-tabs-content .progress-meters-container .progress-meter-container .progress-meter .inner-meter-container .meter, -#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .meter { - background: #e6e5e1; - float: left; - height: 10px; - margin-top: 37px; -} -#vrm-tabs-content .progress-meters-container .progress-meter-container .progress-meter .inner-meter-container .meter .progress, -#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .meter .progress { - display: block; - height: 100%; - overflow: hidden; - width: 0%; -} -#vrm-tabs-content .progress-meters-container .progress-meter-container .progress-meter .inner-meter-container .indicator, -#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .indicator { - display: inline-block; - position: absolute; - top: 0px; - visibility: hidden; - white-space: nowrap; - z-index: 1; -} -#vrm-tabs-content .progress-meters-container .progress-meter-container .progress-meter .inner-meter-container .indicator .indicator-body, -#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .indicator .indicator-body { - color: #ffffff; - background: #63625e; - line-height: 30px; - padding: 0px 6px; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} -#vrm-tabs-content .progress-meters-container .progress-meter-container .progress-meter .inner-meter-container .indicator .indicator-footer, -#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .indicator .indicator-footer { - height: 5px; - width: 0px; - margin: 0 auto; - border-top: 5px outset #63625e; - border-left: 5px inset rgba(0, 0, 0, 0); - border-right: 5px inset rgba(0, 0, 0, 0); -} -#vrm-tabs-content .progress-meters-container .progress-meter-container .progress-meter .inner-meter-container .icon, -#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .icon { - left: -42px; - position: absolute; - top: 30px; -} -#vrm-tabs-content .progress-meters-container .progress-meter-container .progress-meter .inner-meter-container p, -#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container p { - font-size: 11px; - position: absolute; - top: 41px; -} -#vrm-tabs-content .progress-meters-container .progress-meter-container .progress-meter .inner-meter-container p.pull-right, -#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container p.pull-right { - right: 0px; -} -#vrm-tabs-content .progress-meters-container .progress-meter-container .progress-meter .meter { - width: 100%; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} -#vrm-tabs-content .progress-meters-container .progress-meter-container .progress-meter .meter .progress { - background: #f7ab3e; - -webkit-border-top-left-radius: 2px; - -moz-border-radius-topleft: 2px; - border-top-left-radius: 2px; - -webkit-border-bottom-left-radius: 2px; - -moz-border-radius-bottomleft: 2px; - border-bottom-left-radius: 2px; -} -#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .meter.positive { - -webkit-border-top-left-radius: 2px; - -moz-border-radius-topleft: 2px; - border-top-left-radius: 2px; - -webkit-border-bottom-left-radius: 2px; - -moz-border-radius-bottomleft: 2px; - border-bottom-left-radius: 2px; - width: 50%; -} -#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .meter.positive .progress { - background-color: #8bc964; - float: right; -} -#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .meter.negative { - -webkit-border-top-right-radius: 2px; - -moz-border-radius-topright: 2px; - border-top-right-radius: 2px; - -webkit-border-bottom-right-radius: 2px; - -moz-border-radius-bottomright: 2px; - border-bottom-right-radius: 2px; - width: 50%; -} -#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .meter.negative .progress { - background-color: #fa716f; -} -#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .center-point { - left: 50%; - position: absolute; - top: 36px; -} -#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .center-point .divider { - background-color: #959490; - height: 18px; - width: 1px; -} -#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .center-point .caption { - color: #959490; - font-size: 11px; - margin-left: -3px; -} -#vrm-tabs-content .progress-meters-container .progress-meter-container.power-distribution .meter { - background: #e6e5e1; -} -#vrm-tabs-content .progress-meters-container .progress-meter-container.genset-actual .progress-meter .inner-meter-container .meter .progress { - background: #4790d0; -} -#vrm-tabs-content .progress-meters-container.rows-1 { - height: 198px; -} -#vrm-tabs-content .progress-meters-container.rows-1 .progress-meter-container { - height: 199px; - padding-top: 30px; -} -#vrm-tabs-content .progress-meters-container.rows-1 .progress-meter-container .inner-meter-container { - margin-top: 5px; -} -#vrm-tabs-content .progress-meters-container.rows-2 .progress-meter-container { - height: 198px; - padding-top: 30px; -} -#vrm-tabs-content .progress-meters-container.rows-2 .progress-meter-container .inner-meter-container { - margin-top: 5px; -} -#vrm-tabs-content .progress-meters-container.rows-2 .progress-meter-container:last-child { - height: 197px; -} -#vrm-tabs-content .progress-meters-container.rows-3 .progress-meter-container { - height: 132px; -} -#vrm-tabs-content .progress-meters-container.rows-3 .progress-meter-container:last-child { - height: 131px; -} -#vrm-tabs-content .totalProduced li:first-child { - border: none; - min-height: 99px; - padding: 0; -} -#vrm-tabs-content .totalProduced li:first-child .main-section { - background: #f7ab3e; - border: 0; - color: #ffffff; - height: 74px; - float: left; - padding-left: 40px; - padding-top: 25px; - width: 260px; -} -#vrm-tabs-content .totalProduced li:first-child .main-section h1 { - margin: 4px 0 0 0; -} -#vrm-tabs-content .totalProduced li:first-child .main-section.status-ok { - background: #8bc964; -} -#vrm-tabs-content .totalProduced li:first-child .main-section.status-alarm { - background: #fa716f; -} -#vrm-tabs-content .totalProduced li:first-child .corner { - position: absolute; - right: 10px; -} -#vrm-tabs-content .totalProduced li:first-child .corner.blue { - display: inline-block; - width: 30px; - height: 60px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -432px -120px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - #vrm-tabs-content .totalProduced li:first-child .corner.blue { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -#vrm-tabs-content .totalProduced li:first-child .corner.orange { - display: inline-block; - width: 30px; - height: 60px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -462px -120px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - #vrm-tabs-content .totalProduced li:first-child .corner.orange { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -#vrm-tabs-content .totalProduced li:first-child .corner.red { - display: inline-block; - width: 30px; - height: 60px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -492px -120px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - #vrm-tabs-content .totalProduced li:first-child .corner.red { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -#vrm-tabs-content .totalProduced li:first-child .corner.green { - display: inline-block; - width: 30px; - height: 60px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -522px -120px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - #vrm-tabs-content .totalProduced li:first-child .corner.green { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -#vrm-tabs-content .totalProduced li:nth-child(2) { - border-top: none; -} -#vrm-tabs-content .tab-pane#advanced .download-data-container { - position: absolute; - top: 14px; - right: 17px; - line-height: 26px; - padding-left: 28px; - max-height: 52px; - text-align: left; -} -#vrm-tabs-content .tab-pane#advanced .download-data-container .link-text { - padding: 0 5px; -} -#vrm-tabs-content .tab-pane#batteries .section-graph, -#vrm-tabs-content .tab-pane#solar-yield .section-graph, -#vrm-tabs-content .tab-pane#consumption .section-graph { - background-color: #ffffff; - border: 1px solid #dcdbd7; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -#vrm-tabs-content .tab-pane#batteries .section-graph .dashboard-graph, -#vrm-tabs-content .tab-pane#solar-yield .section-graph .dashboard-graph, -#vrm-tabs-content .tab-pane#consumption .section-graph .dashboard-graph { - height: 324px; - margin: 40px 60px 30px 10px; -} -#vrm-tabs-content .tab-pane#batteries .section-graph .dashboard-graph.move-last-tick-to-front .jqplot-xaxis canvas:last-child, -#vrm-tabs-content .tab-pane#solar-yield .section-graph .dashboard-graph.move-last-tick-to-front .jqplot-xaxis canvas:last-child, -#vrm-tabs-content .tab-pane#consumption .section-graph .dashboard-graph.move-last-tick-to-front .jqplot-xaxis canvas:last-child { - left: 0px !important; -} -#vrm-tabs-content .tab-pane#batteries .section-graph .dashboard-legend, -#vrm-tabs-content .tab-pane#solar-yield .section-graph .dashboard-legend, -#vrm-tabs-content .tab-pane#consumption .section-graph .dashboard-legend { - background-color: #e6e5e1; - border-top: 1px solid #dcdbd7; - height: 60px; -} -#vrm-tabs-content .tab-pane#batteries .section-graph .dashboard-legend ul, -#vrm-tabs-content .tab-pane#solar-yield .section-graph .dashboard-legend ul, -#vrm-tabs-content .tab-pane#consumption .section-graph .dashboard-legend ul { - margin-left: 20px; - margin-top: 20px; -} -#vrm-tabs-content .tab-pane#batteries .section-graph .dashboard-legend ul li, -#vrm-tabs-content .tab-pane#solar-yield .section-graph .dashboard-legend ul li, -#vrm-tabs-content .tab-pane#consumption .section-graph .dashboard-legend ul li { - float: left; - margin-right: 50px; -} -#vrm-tabs-content .tab-pane#batteries .section-graph .dashboard-legend ul li .color-square, -#vrm-tabs-content .tab-pane#solar-yield .section-graph .dashboard-legend ul li .color-square, -#vrm-tabs-content .tab-pane#consumption .section-graph .dashboard-legend ul li .color-square { - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - float: left; - height: 20px; - margin-right: 9px; - width: 20px; -} -#vrm-tabs-content .tab-pane#batteries .section-graph .dashboard-legend ul li .color-square.blue, -#vrm-tabs-content .tab-pane#solar-yield .section-graph .dashboard-legend ul li .color-square.blue, -#vrm-tabs-content .tab-pane#consumption .section-graph .dashboard-legend ul li .color-square.blue { - background-color: #4790d0; -} -#vrm-tabs-content .tab-pane#batteries .section-graph .dashboard-legend ul li .color-square.green, -#vrm-tabs-content .tab-pane#solar-yield .section-graph .dashboard-legend ul li .color-square.green, -#vrm-tabs-content .tab-pane#consumption .section-graph .dashboard-legend ul li .color-square.green { - background-color: #8bc964; -} -#vrm-tabs-content .tab-pane#batteries .section-graph .dashboard-legend ul li .color-square.orange, -#vrm-tabs-content .tab-pane#solar-yield .section-graph .dashboard-legend ul li .color-square.orange, -#vrm-tabs-content .tab-pane#consumption .section-graph .dashboard-legend ul li .color-square.orange { - background-color: #f7ab3e; -} -#vrm-tabs-content .tab-pane#batteries .section-graph .dashboard-legend ul li .color-square.red, -#vrm-tabs-content .tab-pane#solar-yield .section-graph .dashboard-legend ul li .color-square.red, -#vrm-tabs-content .tab-pane#consumption .section-graph .dashboard-legend ul li .color-square.red { - background-color: #fa716f; -} -#vrm-tabs-content .tab-pane#batteries .section-graph .dashboard-legend ul li .caption, -#vrm-tabs-content .tab-pane#solar-yield .section-graph .dashboard-legend ul li .caption, -#vrm-tabs-content .tab-pane#consumption .section-graph .dashboard-legend ul li .caption { - color: #63625e; - float: left; - font-size: 11px; -} -#vrm-tabs-content .tab-pane#batteries .site-info-list li:first-child { - background-color: #ffffff; - max-height: 99px; -} -#vrm-tabs-content .tab-pane#solar-yield .site-info-list li, -#vrm-tabs-content .tab-pane#consumption .site-info-list li { - padding: 0px; -} -#vrm-tabs-content .tab-pane#solar-yield .site-info-list li:first-child, -#vrm-tabs-content .tab-pane#consumption .site-info-list li:first-child { - background-color: #ffffff; - max-height: 99px; -} -#vrm-tabs-content .tab-pane#solar-yield .site-info-list li .plot, -#vrm-tabs-content .tab-pane#consumption .site-info-list li .plot { - float: left; - height: 93px; - margin-bottom: -4px; - margin-top: 10px; - width: 99px; -} -#vrm-tabs-content .tab-pane#solar-yield .site-info-list li .plot-info, -#vrm-tabs-content .tab-pane#consumption .site-info-list li .plot-info { - float: left; - height: 99px; -} -#vrm-tabs-content .tab-pane#solar-yield .site-info-list li .plot-info .caption, -#vrm-tabs-content .tab-pane#consumption .site-info-list li .plot-info .caption { - font-size: 18px; - margin-top: 31px; -} -#vrm-tabs-content .tab-pane#solar-yield .site-info-list li .plot-info .subcaption, -#vrm-tabs-content .tab-pane#consumption .site-info-list li .plot-info .subcaption { - color: #f7ab3e; -} -#vrm-tabs-content .tab-pane#solar-yield .site-info-list li .plot-info ul li, -#vrm-tabs-content .tab-pane#consumption .site-info-list li .plot-info ul li { - border: none; - float: left; - min-height: 0px; - padding-right: 10px; -} -#vrm-tabs-content .tab-pane#solar-yield .site-info-list li .plot-info ul li.toGrid, -#vrm-tabs-content .tab-pane#consumption .site-info-list li .plot-info ul li.toGrid, -#vrm-tabs-content .tab-pane#solar-yield .site-info-list li .plot-info ul li.gridUse, -#vrm-tabs-content .tab-pane#consumption .site-info-list li .plot-info ul li.gridUse { - color: #fa716f; -} -#vrm-tabs-content .tab-pane#solar-yield .site-info-list li .plot-info ul li.toBattery, -#vrm-tabs-content .tab-pane#consumption .site-info-list li .plot-info ul li.toBattery, -#vrm-tabs-content .tab-pane#solar-yield .site-info-list li .plot-info ul li.batteryUse, -#vrm-tabs-content .tab-pane#consumption .site-info-list li .plot-info ul li.batteryUse { - color: #4790d0; -} -#vrm-tabs-content .tab-pane#solar-yield .site-info-list li .plot-info ul li.directUse, -#vrm-tabs-content .tab-pane#consumption .site-info-list li .plot-info ul li.directUse, -#vrm-tabs-content .tab-pane#solar-yield .site-info-list li .plot-info ul li.solarUse, -#vrm-tabs-content .tab-pane#consumption .site-info-list li .plot-info ul li.solarUse { - color: #f7ab3e; -} -#vrm-tabs-content .tab-pane#solar-yield .site-info-list li .plot-info ul li.gensetUse, -#vrm-tabs-content .tab-pane#consumption .site-info-list li .plot-info ul li.gensetUse { - color: #8bc964; -} -/* --------------[ Date range selectors ]--------------------*/ -.advanced-view-time-toggle .icon-24-center { - left: 17px; - position: absolute; - top: 8px; -} -.date-range-selectors, -.date-range-selectors-advanced { - display: none; - background-color: #faf9f5; - padding: 21px 0 30px 0; - border-bottom: 1px solid #e5e4e0; -} -.date-range-selectors .custom_date_selector_container, -.date-range-selectors-advanced .custom_date_selector_container { - padding-left: 20px; -} -.date-range-selectors .selector-list > li, -.date-range-selectors-advanced .selector-list > li { - float: left; - margin-left: 17px; -} -.date-range-selectors .selector-list > li.pickerOnly, -.date-range-selectors-advanced .selector-list > li.pickerOnly { - visibility: hidden; - width: 0; - height: 0; - overflow: hidden; -} -.date-range-selectors .selector-list > li:first-child, -.date-range-selectors-advanced .selector-list > li:first-child { - margin-left: 0px; -} -.date-range-selectors .js__datepicker, -.date-range-selectors-advanced .js__datepicker { - color: #63625e; -} -.date-range-selectors .set-time-label, -.date-range-selectors-advanced .set-time-label, -.date-range-selectors .set-view-label, -.date-range-selectors-advanced .set-view-label { - color: #63625e; - line-height: 30px; -} -.date-range-selectors .time-selector-simple, -.date-range-selectors-advanced .time-selector-simple { - height: 51px; -} -.date-range-selectors .time-selector-custom, -.date-range-selectors-advanced .time-selector-custom { - height: 51px; - display: none; -} -.date-range-selectors .advanced-view-time-toggle, -.date-range-selectors-advanced .advanced-view-time-toggle { - margin: 5px 0 0 0; -} -.currenttime { - display: none; -} -/* --------------[ Date picker: pickadate ]--------------------*/ -.picker__input { - cursor: pointer; - text-align: center; -} -.picker { - margin-left: 10px; - margin-right: 10px; - width: 300px; - margin: 10px 0; -} -.picker .picker__holder { - border: 1px solid #dcdbd7; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; - color: #272622; -} -.picker .picker__holder .picker__header .picker__nav--prev:hover, -.picker .picker__holder .picker__header .picker__nav--next:hover { - background-color: #e6e5e1; -} -.picker .picker__holder .picker__day--highlighted { - background-color: #4790d0; -} -.picker .picker__holder .picker__day--highlighted:hover { - background-color: #4790d0 !important; -} -.picker .picker__holder .picker__day--selected { - border: none; -} -.picker .picker__holder .picker__day--infocus:hover, -.picker .picker__holder .picker__day--outfocus:hover { - background-color: #e6e5e1; -} -.picker .picker__holder .picker__footer .picker__button--today:hover { - background-color: #e6e5e1; -} -.date-range-selectors-advanced .section { - float: left; - margin-left: 20px; -} -.date-range-selectors-advanced .section:first-child { - margin-left: 0px; -} -.date-range-selectors-advanced .mobile-caption { - display: none; -} -.date-range-selectors-advanced .vrm-date-time-picker { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - height: 50px; - padding: 0; - position: relative; - display: inherit; -} -.date-range-selectors-advanced .vrm-date-time-picker .picker__input, -.date-range-selectors-advanced .vrm-date-time-picker .date-range-picker-divider { - background-color: #e6e5e1; - float: left; - min-height: 48px; - max-height: 48px; -} -.date-range-selectors-advanced .vrm-date-time-picker .picker__input.changed, -.date-range-selectors-advanced .vrm-date-time-picker .date-range-picker-divider.changed { - background-color: #ffffff; - color: #63625e; -} -.date-range-selectors-advanced .vrm-date-time-picker .js__datepicker { - border: none; - color: #63625e; - -webkit-border-top-right-radius: 0px; - -moz-border-radius-topright: 0px; - border-top-right-radius: 0px; - -webkit-border-bottom-right-radius: 0px; - -moz-border-radius-bottomright: 0px; - border-bottom-right-radius: 0px; - padding: 16px 0px 12px; - width: 121px; -} -.date-range-selectors-advanced .vrm-date-time-picker .js__timepicker { - border: none; - color: #63625e; - -webkit-border-top-left-radius: 0px; - -moz-border-radius-topleft: 0px; - border-top-left-radius: 0px; - -webkit-border-bottom-left-radius: 0px; - -moz-border-radius-bottomleft: 0px; - border-bottom-left-radius: 0px; - padding: 16px 0px 12px; - width: 95px; -} -.date-range-selectors-advanced .vrm-date-time-picker .date-range-picker-divider { - height: 100%; - width: 1px; -} -.date-range-selectors-advanced .vrm-date-time-picker .date-range-picker-divider .divider { - background-color: #dcdbd7; - height: 30px; - margin-top: 9px; -} -.date-range-selectors-advanced .vrm-date-time-picker:hover .date-range-picker-divider .divider { - background-color: #e6e5e1; -} -.date-range-selectors-advanced .vrm-date-time-picker .picker { - top: 49px; - left: -1px; -} -.date-range-selectors-advanced .set-time .btn { - cursor: pointer; - padding-bottom: 9px; - padding-top: 13px; - position: relative; -} -.date-range-selectors-advanced .set-time .btn .sprite-icons { - left: 18px; - position: absolute; - top: 13px; -} -.date-range-selectors-advanced .set-time .btn .caption { - font-size: 18px; - line-height: 25px; - padding-left: 26px; -} -.date-range-selectors-advanced .set-time .btn.disabled { - cursor: default; -} -.VRM_Widget_DateRange .header.date-range-header { - height: auto; - min-height: 64px; -} -.VRM_Widget_DateRange .header.date-range-header > h3 { - float: left; - margin: 13px 11px; -} -.VRM_Widget_DateRange .date-range-list { - margin: 0; - padding: 0; - list-style-type: none; -} -.VRM_Widget_DateRange .date-range-list > li { - float: left; - color: white; - font-weight: bold; - margin: 8px 4px; -} -.VRM_Widget_DateRange .date-range-list > li.range-button-refresh { - float: right; -} -.VRM_Widget_DateRange .date-range-list > li.range-button-download { - float: right; - margin-right: 12px; - margin-left: 6px; -} -.VRM_Widget_DateRange .date-range-list > li > input, -.VRM_Widget_DateRange .date-range-list > li > span > input { - font-size: 22px; - line-height: 28px; - width: 220px; -} -.VRM_Widget_DateRange .date-range-list > li > button.small { - margin: 2px 0px; -} -.VRM_Widget_DateRange .date-range-list > li > input:hover, -.VRM_Widget_DateRange .date-range-list > li > span > input:hover { - font-style: normal; - cursor: pointer; -} -#timeRange-desktop { - position: relative; - float: left; - overflow: hidden; - width: 100%; - height: 160px; - padding: 0 0 8px 0; - margin: 0; -} -#timeRange-desktop #timePickers-desktop { - position: absolute; - top: 10px; - left: 45px; - width: 100px; - font-family: Arial; - font-size: 11px; - font-weight: normal; -} -#timeRange-desktop #timePickers-desktop input { - width: 100%; -} -#timeRange-desktop #timeRangeSet-desktop { - position: absolute; - top: 65px; - right: 45px; -} -#timeRange-desktop .datepicker { - position: relative; - font-family: Arial, Helvetica, sans-serif; - font-size: 12px; - width: 196px; - height: 147px; - cursor: default; - display: none; - margin: 0 auto; - /* Hide border divs by default */ - /* Only display the previous/next arrows on the first/last calendars */ - /* Compensate for the space lost by not having a previous arrow */ - /* Day mode calendar body */ - /* Month mode calendar body */ - /* Year mode calendar body */ - /* Not used by default, calendar cells can be marked as special if desired (doesn't seem to be totally working) */ - /* style the 'not in month' day cell away */ - /* Datepicker border styling */ - background-color: #F7F7F7; - border: 1px solid #CCCCCC; - border-radius: 5px 5px 5px 5px; - padding: 10px; - /* Tighten up the spacing between multiple calendars */ - /* Grey background behind Month Name row, and blue text */ - /* style the day of week header cells */ - /* grey underline beneath day of week row */ - /* Black text, white background, and grey borders around day cells */ - /* blue cell color for selected days */ - /* Grey out dates in the future */ - /* yellow cell background on hover */ - /* Bold today's date */ - /* cells are wider in the clean style */ -} -#timeRange-desktop .datepicker .datepickerContainer { - position: absolute; -} -#timeRange-desktop .datepicker .datepickerBorderT, -#timeRange-desktop .datepicker .datepickerBorderB, -#timeRange-desktop .datepicker .datepickerBorderL, -#timeRange-desktop .datepicker .datepickerBorderR, -#timeRange-desktop .datepicker .datepickerBorderTL, -#timeRange-desktop .datepicker .datepickerBorderTR, -#timeRange-desktop .datepicker .datepickerBorderBL, -#timeRange-desktop .datepicker .datepickerBorderBR { - display: none; -} -#timeRange-desktop .datepicker .datepickerHidden { - display: none; -} -#timeRange-desktop .datepicker table { - border-collapse: collapse; -} -#timeRange-desktop .datepicker a { - color: black; - text-decoration: none; - cursor: default; - outline: none; -} -#timeRange-desktop .datepicker table td { - text-align: center; - padding: 0; - margin: 0; -} -#timeRange-desktop .datepicker th { - text-align: center; - color: #666666; - font-weight: normal; - padding: 0; -} -#timeRange-desktop .datepicker tbody a { - display: block; -} -#timeRange-desktop .datepicker .datepickerDays a { - width: 20px; - line-height: 16px; - height: 16px; - padding-right: 2px; -} -#timeRange-desktop .datepicker .datepickerYears a, -#timeRange-desktop .datepicker .datepickerMonths a { - width: 39px; - line-height: 36px; - height: 36px; - text-align: center; -} -#timeRange-desktop .datepicker .datepickerMonths td:first-child a, -#timeRange-desktop .datepicker .datepickerMonths td:last-child a, -#timeRange-desktop .datepicker .datepickerYears td:first-child a, -#timeRange-desktop .datepicker .datepickerYears td:last-child a { - width: 38px; -} -#timeRange-desktop .datepicker td.datepickerNotInMonth a { - color: #666666; -} -#timeRange-desktop .datepicker tbody.datepickerDays td.datepickerSelected { - background: #136A9F; -} -#timeRange-desktop .datepicker tbody.datepickerDays td.datepickerNotInMonth.datepickerSelected { - background: #17384d; -} -#timeRange-desktop .datepicker tbody.datepickerYears td.datepickerSelected, -#timeRange-desktop .datepicker tbody.datepickerMonths td.datepickerSelected { - background: #17384d; -} -#timeRange-desktop .datepicker td.datepickerSelected a { - color: white; -} -#timeRange-desktop .datepicker a:hover { - color: #88c5eb; -} -#timeRange-desktop .datepicker td.datepickerNotInMonth a:hover { - color: #999999; -} -#timeRange-desktop .datepicker .datepickerSpace div { - width: 20px; -} -#timeRange-desktop .datepicker .datepickerBlock { - vertical-align: top; -} -#timeRange-desktop .datepicker a.datepickerGoNext, -#timeRange-desktop .datepicker a.datepickerGoPrev, -#timeRange-desktop .datepicker a.datepickerMonth { - text-align: center; - height: 20px; - line-height: 20px; - float: left; -} -#timeRange-desktop .datepicker th a.datepickerGoNext, -#timeRange-desktop .datepicker th a.datepickerGoPrev { - width: 20px; - color: #666666; - display: none; -} -#timeRange-desktop .datepicker th a.datepickerMonth { - width: 114px; - display: block; -} -#timeRange-desktop .datepicker .datepickerFirstView th a.datepickerGoPrev, -#timeRange-desktop .datepicker .datepickerLastView th a.datepickerGoNext { - display: block; -} -#timeRange-desktop .datepicker th a.datepickerMonth { - margin-left: 20px; -} -#timeRange-desktop .datepicker .datepickerFirstView th a.datepickerMonth { - margin-left: 0; -} -#timeRange-desktop .datepicker table.datepickerViewDays tbody.datepickerMonths, -#timeRange-desktop .datepicker table.datepickerViewDays tbody.datepickerYears { - display: none; -} -#timeRange-desktop .datepicker table.datepickerViewMonths tbody.datepickerDays, -#timeRange-desktop .datepicker table.datepickerViewMonths tbody.datepickerYears, -#timeRange-desktop .datepicker table.datepickerViewMonths tr.datepickerDoW { - display: none; -} -#timeRange-desktop .datepicker table.datepickerViewYears tbody.datepickerDays, -#timeRange-desktop .datepicker table.datepickerViewYears tbody.datepickerMonths, -#timeRange-desktop .datepicker table.datepickerViewYears tr.datepickerDoW { - display: none; -} -#timeRange-desktop .datepicker td.datepickerDisabled a, -#timeRange-desktop .datepicker td.datepickerDisabled.datepickerNotInMonth a { - color: #555555; -} -#timeRange-desktop .datepicker td.datepickerDisabled a:hover { - color: #333333; -} -#timeRange-desktop .datepicker tbody.datepickerDays td.datepickerSpecial a { - background: #770000; - color: white; -} -#timeRange-desktop .datepicker tbody.datepickerDays td.datepickerSpecial.datepickerSelected a { - background: #aa0000; -} -#timeRange-desktop .datepicker tbody.datepickerDays td.datepickerNotInMonth.datepickerSelected { - background-color: transparent; -} -#timeRange-desktop .datepicker td.datepickerNotInMonth a span { - display: none; -} -#timeRange-desktop .datepicker td.datepickerNotInMonth a:hover span { - display: none; -} -#timeRange-desktop .datepicker tbody.datepickerDays td.datepickerNotInMonth:hover { - background-color: transparent; -} -#timeRange-desktop .datepicker .datepickerSpace div { - width: 2px; -} -#timeRange-desktop .datepicker th { - background-color: #DDDDDD; -} -#timeRange-desktop .datepicker th a.datepickerMonth { - color: #008ED6; - font-weight: normal; -} -#timeRange-desktop .datepicker th { - color: black; - font-weight: bold; -} -#timeRange-desktop .datepicker table thead tr.datepickerDoW th { - border-bottom: 1px solid #CCCCCC; -} -#timeRange-desktop .datepicker a, -#timeRange-desktop .datepicker a:hover { - color: black; -} -#timeRange-desktop .datepicker table.datepickerViewDays, -#timeRange-desktop .datepicker table.datepickerViewMonths, -#timeRange-desktop .datepicker table.datepickerViewYears { - background-color: white; -} -#timeRange-desktop .datepicker table tbody.datepickerDays td { - border: 1px solid #F7F7F7; -} -#timeRange-desktop .datepicker tbody.datepickerDays td.datepickerSelected { - background-color: #0077CC; -} -#timeRange-desktop .datepicker td.datepickerFuture a { - color: #DDDDDD; -} -#timeRange-desktop .datepicker tbody.datepickerDays td:hover { - background-color: #FFCC33; -} -#timeRange-desktop .datepicker td.datepickerToday a { - font-weight: bold; -} -#timeRange-desktop .datepicker .datepickerYears a, -#timeRange-desktop .datepicker .datepickerMonths a { - width: 42px; -} -#timeRange-desktop .datepicker .datepickerMonths td:first-child a, -#timeRange-desktop .datepicker .datepickerYears td:first-child a { - width: 39px; -} -#timeRange-desktop .datepicker th a.datepickerMonth { - width: 121px; -} -.ui-timepicker-list { - overflow-y: auto; - height: 150px; - width: 6.5em; - background: #fff; - border: 1px solid #ddd; - margin: 0; - padding: 0; - list-style: none; - -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - outline: none; - z-index: 10001; -} -.ui-timepicker-list.ui-timepicker-with-duration { - width: 11em; -} -.ui-timepicker-duration { - margin-left: 5px; - color: #888; -} -.ui-timepicker-list:hover .ui-timepicker-duration { - color: #888; -} -.ui-timepicker-list li { - padding: 3px 0 3px 5px; - cursor: pointer; - white-space: nowrap; - color: #000; - list-style: none; - margin: 0; -} -.ui-timepicker-list:hover .ui-timepicker-selected { - background: #fff; - color: #000; -} -li.ui-timepicker-selected, -.ui-timepicker-list li:hover, -.ui-timepicker-list:hover .ui-timepicker-selected:hover { - background: #1980EC; - color: #fff; -} -li.ui-timepicker-selected .ui-timepicker-duration, -.ui-timepicker-list li:hover .ui-timepicker-duration { - color: #ccc; -} -/* Mobile only hidden unless overriden by media.css */ -.mobile-only { - display: none; -} -#dashboard-simple-datepicker.completed { - background-color: #f0efeb; -} -/* -----------[Widgets]--------------*/ -.widget { - background-color: #ffffff; - margin-bottom: 53px; -} -.widget .btn-download { - background-color: #63625e; - border: 1px solid #dcdbd7; - border-top: none; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - color: white; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; - display: block; - font-size: 18px; - height: 79px; - line-height: 80px; - text-align: center; - text-decoration: none; - width: 100%; -} -.widget .btn-download:hover { - background-color: #4f4e4a; -} -.widget .btn-download .caption { - display: inline-block; - vertical-align: super; -} -.widget .btn-download.no-border { - border: 0; -} -.widget .header { - background-color: #faf9f5; - border: 1px solid #dcdbd7; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - min-height: 80px; - height: auto; - width: 100%; -} -.widget .header a { - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; - display: block; - height: 100%; -} -.widget .header a:hover { - background-color: #ffffff; -} -.widget .header a { - color: #63625e; - text-decoration: none; -} -.widget .header .alert-red { - display: none; -} -.widget .header .title { - font-size: 21px; - padding-left: 20px; - padding-top: 20px; -} -.widget .header .sub-title { - padding-left: 20px; -} -.widget .header .sub-title ul li { - float: left; - margin-right: 35px; -} -.widget .header .sub-title ul li .caption { - margin-left: 10px; - vertical-align: super; -} -.widget .header .sub-title ul li .caption.blue { - color: #4790d0; -} -.widget .header .sub-title ul li .caption.orange { - color: #f7ab3e; -} -.widget .header .sub-title ul li .caption.gray { - color: #63625e; -} -.widget .header .sub-title ul li.toggled { - opacity: 0.4; - filter: alpha(opacity=40); -} -.widget .header .sub-title .caption { - vertical-align: super; -} -.widget .header.no-subtitle .title { - padding-top: 30px; -} -.widget .header.has-alarm { - position: relative; -} -.widget .header.has-alarm a { - color: #f35c58; - text-decoration: none; -} -.widget .header.has-alarm .alert-red { - position: absolute; - right: 20px; - top: 28px; -} -.widget .content { - border: 1px solid #dcdbd7; - border-top: none; -} -.widget .content .graph-container { - height: 255px; - padding: 50px 28px 25px 22px; -} -.widget .content .graph-container .date-range-triggered { - height: 235px !important; -} -.widget .content .jqplot-target .jqplot-yaxis { - color: #4790d0; -} -.widget .content .jqplot-target .jqplot-y2axis { - color: #f7ab3e; -} -.widget .content .blockMsg { - top: 156px !important; -} -.widget .bottom-graph { - background-color: #f0efeb; - height: 60px; - position: relative; - text-align: right; -} -.widget .bottom-graph .graph-links { - border-top: 1px solid #dcdbd7; - height: 100%; - position: absolute; - right: 0px; - top: -1px; -} -.widget .bottom-graph .graph-links li { - background-color: #63625e; - border: none; - border-bottom: 1px solid #dcdbd7; - border-top: 1px solid #dcdbd7; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - color: #e6e5e1; - cursor: pointer; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; - float: left; - height: 100%; - line-height: 62px; - margin-top: -1px; - outline: none; - text-align: center; -} -.widget .bottom-graph .graph-links li:last-child { - border-right: 1px solid #dcdbd7; -} -.widget .bottom-graph .graph-links li:first-child { - border-left: 1px solid #dcdbd7; -} -.widget .bottom-graph .graph-links li.selected { - background-color: #ffffff; - border-left: 1px solid #dcdbd7; - border-right: 1px solid #dcdbd7; - border-top-color: #ffffff; - color: #63625e; -} -.widget .bottom-graph .graph-links li.selected .divider .border { - -webkit-transition: 0s; - -moz-transition: 0s; - -o-transition: 0s; - transition: 0s; - background-color: transparent; -} -.widget .bottom-graph .graph-links li.selected + li .divider:first-child .border { - background-color: transparent; -} -.widget .bottom-graph .graph-links li:hover:not(.selected) { - background-color: #959490; -} -.widget .bottom-graph .graph-links li:hover:not(.selected) .divider .border { - background-color: #959490; -} -.widget .bottom-graph .graph-links li:hover + li .divider:first-child .border { - background-color: transparent; -} -.widget .bottom-graph .graph-links li .caption { - display: inline-block; - float: left; - height: 100%; - width: 98px; -} -.widget .bottom-graph .graph-links li .divider { - display: inline-block; - float: left; - height: 100%; - width: 0.5px; -} -.widget .bottom-graph .graph-links li .divider .border { - background-color: #4f4e4a; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; - height: 40px; - margin-top: 10px; -} -.widget.VRM_Widget_Alarm .inner-container { - padding: 0 20px !important; -} -.widget.VRM_Widget_Alarm .inner-container .column { - display: inline-block; - float: left; -} -.widget.VRM_Widget_Alarm .inner-container .column.left { - width: 65%; -} -.widget.VRM_Widget_Alarm .inner-container .column.right { - width: 35%; -} -.widget.VRM_Widget_Alarm .inner-container .column .duration { - color: #4790d0; -} -.widget.VRM_Widget_Status .content .widget-content-list .row:first-child, -.widget.VRM_Widget_Status .content .widget-content-list .row:nth-child(2) { - height: 117px; -} -.widget.VRM_Widget_Status .content .widget-content-list .row:last-child { - border-bottom: none; -} -.widget.VRM_Widget_Status .content .widget-content-list .row .inner-container .label { - padding-bottom: 5px; -} -.widget.VRM_Widget_Status .content .widget-content-list .row .inner-container .value .column { - text-align: right; -} -.widget.VRM_Widget_HistoricData .content .widget-content-list .row:last-child { - border-bottom: none; -} -.widget.VRM_Widget_GPSWidget .widget-map { - height: 236px; - width: 100%; -} -.widget.VRM_Widget_VeConfigure .content { - height: 316px !important; -} -.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expand-trigger:hover:not(.expanded) { - background-color: #e6e5e1; - cursor: pointer; -} -.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expandable-section { - background-color: #e6e5e1; - border-bottom: none; - display: none; - height: 236px; - position: relative; -} -.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expandable-section .inner-container .close-container { - margin-bottom: 12px; - margin-top: -3px; - text-align: right; -} -.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expandable-section .inner-container .close-container ul { - cursor: pointer; - display: inline-block; -} -.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expandable-section .inner-container .close-container ul li { - display: inline-block; -} -.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expandable-section .inner-container .close-container ul:hover .caption { - text-decoration: underline; -} -.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expandable-section .inner-container .close-container .caption { - padding-top: 2px; - vertical-align: top; -} -.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expandable-section .inner-container .button-container { - bottom: 10px; - left: 10px; - position: absolute; - width: 100%; -} -.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expandable-section .inner-container .button-container .filename { - display: none; -} -.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expandable-section .inner-container .button-container input[type="button"] { - width: 134px; -} -.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expandable-section .inner-container .button-container input[type="button"]:first-child { - margin-right: 6px; -} -.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expandable-section .inner-container .button-container .file-wrapper input[type="file"] { - opacity: 0; - filter: alpha(opacity=0); - left: -10000px; - position: absolute; -} -.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expandable-section .inner-container .button-container #upload { - display: none; -} -.widget.VRM_Widget_State .content .graph-container, -.widget.VRM_Widget_VeBusWarningsAndAlarms .content .graph-container { - height: 310px; - padding: 40px 48px 0px 35px; -} -.widget.VRM_Widget_State .content .graph-container .jqplot-target, -.widget.VRM_Widget_VeBusWarningsAndAlarms .content .graph-container .jqplot-target { - height: 260px !important; -} -.widget.VRM_Widget_State .state-legend, -.widget.VRM_Widget_VeBusWarningsAndAlarms .state-legend { - background-color: #e6e5e1; - border: 1px solid #dcdbd7; - border-top: none; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - *zoom: 1; - color: #959490; - display: none; - font-size: 11px; - min-height: 60px; - padding: 20px 34px; -} -.widget.VRM_Widget_State .state-legend:before, -.widget.VRM_Widget_VeBusWarningsAndAlarms .state-legend:before, -.widget.VRM_Widget_State .state-legend:after, -.widget.VRM_Widget_VeBusWarningsAndAlarms .state-legend:after { - display: table; - content: ""; - line-height: 0; -} -.widget.VRM_Widget_State .state-legend:after, -.widget.VRM_Widget_VeBusWarningsAndAlarms .state-legend:after { - clear: both; -} -.widget.VRM_Widget_State .state-legend ul li, -.widget.VRM_Widget_VeBusWarningsAndAlarms .state-legend ul li { - float: left; - margin-right: 15px; -} -.widget.VRM_Widget_State .state-legend ul li .abbreviation, -.widget.VRM_Widget_VeBusWarningsAndAlarms .state-legend ul li .abbreviation { - color: #387dc5; - margin-right: 7px; -} -.widget.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section { - border-bottom: none; - height: 395px; - position: relative; -} -.widget.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section .inner-container .close-container { - margin-bottom: 12px; - margin-top: -3px; - text-align: right; -} -.widget.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section .inner-container .close-container ul { - cursor: pointer; - display: inline-block; -} -.widget.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section .inner-container .close-container ul li { - display: inline-block; -} -.widget.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section .inner-container .close-container ul:hover .caption { - text-decoration: underline; -} -.widget.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section .inner-container .close-container .caption { - padding-top: 2px; - vertical-align: top; -} -.widget.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section .inner-container .button-container { - bottom: 10px; - left: 10px; - position: absolute; - width: 100%; -} -.widget.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section .inner-container .button-container .filename { - display: none; -} -.widget.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section .inner-container .button-container input[type="button"] { - width: 134px; -} -.widget.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section .inner-container .button-container input[type="button"]:first-child { - margin-right: 6px; -} -.widget.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section .inner-container .button-container .file-wrapper input[type="file"] { - opacity: 0; - filter: alpha(opacity=0); - left: -10000px; - position: absolute; -} -.widget.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section .inner-container .button-container #upload { - display: none; -} -.widget.VRM_Widget_PVInverterStatus .content .widget-content-list .row { - height: 98px !important; -} -.widget.VRM_Widget_PVInverterStatus .content .widget-content-list .row:last-child { - border-bottom: none; -} -.widget.list .content { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - height: 395px; - overflow: hidden; - padding-right: 0px !important; - width: 100%; -} -.widget.list .content .widget-content-list .row { - border-bottom: 1px solid #dcdbd7; - height: 78px; - overflow: hidden; -} -.widget.list .content .widget-content-list .row .floater { - height: 50%; -} -.widget.list .content .widget-content-list .row .inner-container { - padding: 20px 20px; -} -.widget.list .content .widget-content-list .row .inner-container .label { - font-size: 18px; -} -.widget.list .content .widget-content-list .row .inner-container .label .duration { - color: #387dc5; -} -.widget.list .content .widget-content-list .row .inner-container .value { - color: #387dc5; -} -.widget.list .content .widget-content-list .row .inner-container .value .column { - float: left; - width: 33%; -} -.widget.list .content .widget-content-list .row .inner-container .value .right { - color: #f0962e; -} -.widget.list .content .widget-content-list .row .inner-container .value .voltage { - color: #387dc5; -} -.widget.list .content .widget-content-list .row .inner-container .value .current { - color: #f0962e; -} -.widget.list .content .widget-content-list .row .inner-container .value .olddata { - color: #f35c58; -} -.widget.list .content .widget-content-list .row .inner-container .datetime.alarm { - color: #f35c58; -} -.widget.list .content .widget-content-list .row.no-border-bottom { - border-bottom: none; -} -.widget.list .content.ps-active-y .ps-scrollbar-y-rail, -.widget.list .content.ps-active-y .ps-scrollbar-y-rail:hover, -.widget.list .content.ps-active-y.ps-container:hover .ps-scrollbar-y-rail { - opacity: 1; - filter: alpha(opacity=100); -} -.widget.list .content.ps-active-y.ps-container:hover .ps-scrollbar-y .row.handle { - background-color: #64635f; -} -.widget.list .content.ps-active-y.ps-container:hover .ps-scrollbar-y-rail { - background-color: #f0efeb; - border: 1px solid #dcdbd7; -} -.widget.list .content.ps-active-y .ps-scrollbar-y-rail { - background-color: rgba(240, 239, 235, 0.5); - border: 1px solid rgba(220, 219, 215, 0.5); - right: 10px !important; - margin-top: 10px; - margin-bottom: 10px; -} -.widget.list .content.ps-active-y .ps-scrollbar-y-rail .ps-scrollbar-y { - background-color: transparent; - display: table; - margin-top: -10px; -} -.widget.list .content.ps-active-y .ps-scrollbar-y-rail .ps-scrollbar-y .row { - display: table-row; -} -.widget.list .content.ps-active-y .ps-scrollbar-y-rail .ps-scrollbar-y .row .transparent-edge { - background-color: transparent; - display: table-cell; - height: 10px; - width: 100%; -} -.widget.list .content.ps-active-y .ps-scrollbar-y-rail .ps-scrollbar-y .row.handle { - background-color: #969591; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - cursor: pointer; - display: table-cell; - opacity: 1 !important; - filter: alpha(opacity=100) !important; - -webkit-transition: background-color 0.2s linear; - -moz-transition: background-color 0.2s linear; - -o-transition: background-color 0.2s linear; - transition: background-color 0.2s linear; -} -.widget.list .content.ps-active-y .ps-scrollbar-y-rail .ps-scrollbar-y .row .handle { - width: 8px; -} -/* -----------[jQuery Tags Plugin]--------------*/ -div.tagsinput { - border: 1px solid #e5e4e0; - background: #ffffff; - padding: 5px; - overflow-y: auto; -} -div.tagsinput span.tag { - display: block; - float: left; - text-decoration: none; - margin-right: 5px; - margin-bottom: 5px; - margin-top: 0px; -} -div.tagsinput span.tag a { - font-size: 0; -} -div.tagsinput input { - width: 80px !important; - margin: 0px; - border: 1px solid transparent; - padding: 5px; - background: transparent; - font-size: 15px; - color: #272622; - outline: 0px; - margin-right: 5px; - margin-bottom: 5px; - min-height: 40px; - margin-top: 0px; -} -div.tagsinput div { - display: block; - float: left; -} -div.tagsinput .tags_clear { - clear: both; - width: 100%; - height: 0px; -} -div.tagsinput .not_valid { - background: #fa716f !important; - color: #ffffff !important; -} -.VRM_Widget_CCGXDataUpload { - line-height: 19px; -} -.VRM_Widget_CCGXDataUpload .text { - border-bottom: 1px solid #dcdbd7; -} -.VRM_Widget_CCGXDataUpload .text:last-child { - border: none; -} -.VRM_Widget_CCGXDataUpload #ccgx-upload, -.VRM_Widget_CCGXDataUpload #inserted-file, -.VRM_Widget_CCGXDataUpload #ccgx-fileinput { - display: none; -} -.VRM_Widget_CCGXDataUpload .filename { - cursor: pointer; -} -.VRM_Widget_CCGXDataUpload .filename li { - float: left; - margin: 0 5px; -} -.VRM_Widget_CCGXDataUpload .filename .caption { - max-width: 210px; - overflow: hidden; - text-overflow: ellipsis; - padding: 3px 0 0 0; -} -.VRM_Widget_CCGXDataUpload .content { - overflow: visible !important; -} -.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section { - height: 316px !important; -} -.VRM_Widget_CCGXDataUpload #inserted-file { - margin: 10px 0 0 0; -} -.VRM_Widget_CCGXDataUpload .insert-ccgx-file { - background-color: #63625e; - border: 1px solid #63625e; - border-top: none; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - color: white; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; - display: block; - font-size: 18px; - height: 79px; - line-height: 80px; - text-align: center; - text-decoration: none; - width: 100%; -} -.VRM_Widget_CCGXDataUpload .insert-ccgx-file:hover { - background-color: #4f4e4a; -} -.VRM_Widget_CCGXDataUpload .insert-ccgx-file .caption { - display: inline-block; - vertical-align: super; -} -.VRM_Widget_CCGXDataUpload .insert-ccgx-file .inverted { - -webkit-transform: rotate(180deg); - /* Opera, Chrome, and Safari */ - -ms-transform: rotate(180deg); - /* IE 9 */ - transform: rotate(180deg); -} -.leaflet-control-container .leaflet-bottom.leaflet-right { - z-index: 3; -} -.leaflet-marker-text { - margin-top: -5px; - color: #4790d0; - font-size: 21px; - font-family: Arial, sans-serif; - font-weight: bold; - font-style: normal; - text-decoration: none; - text-align: center; - line-height: 64px; -} -.leaflet-marker-text-red { - color: #fa716f; -} -.icon-pointer-blue-empty { - display: inline-block; - width: 75px; - height: 64px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -472px 0px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .icon-pointer-blue-empty { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.icon-pointer-red-empty { - display: inline-block; - width: 75px; - height: 64px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -547px 0px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .icon-pointer-red-empty { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -body.map-none .map-view { - height: 65px; - background-color: rgba(99, 98, 94, 0.1); -} -body.map-none .map-view .top-shadow, -body.map-none .map-view .bottom-shadow { - display: none; -} -body.map-none.embedded .breadcrumb { - background-color: #E6E5E1; -} -body.map-none.embedded #vrm-tabs { - right: 0; -} -body.map-none.embedded #vrm-tabs li.active { - border-top: 1px solid #dcdbd7; - border-left: 1px solid #dcdbd7; - border-right: 1px solid #dcdbd7; -} -#updateForm img.gravatar, -#updateGravatarForm img.gravatar { - height: 80px; - width: 80px; - -webkit-border-radius: 50%; - -moz-border-radius: 50%; - border-radius: 50%; -} -#updateForm div.gravatar-wrapper, -#updateGravatarForm div.gravatar-wrapper { - height: 80px; - width: 80px; - position: relative; - text-align: center; - vertical-align: middle; - color: #4790d0; - text-transform: uppercase; - font-size: 14px; - line-height: 80px; - border: none !important; - -webkit-border-radius: 50%; - -moz-border-radius: 50%; - border-radius: 50%; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; -} -#updateForm div.gravatar-wrapper img.gravatar, -#updateGravatarForm div.gravatar-wrapper img.gravatar { - position: absolute !important; - top: 0 !important; - left: 0 !important; - height: 78px !important; - width: 78px !important; - float: none !important; - margin: 0 !important; - border-width: 1px !important; - border-style: solid !important; - border-color: #dcdbd7; - background: none !important; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; -} -#updateForm img.gravatar, -#updateGravatarForm img.gravatar, -#updateForm div.gravatar-wrapper img.gravatar, -#updateGravatarForm div.gravatar-wrapper img.gravatar, -#updateForm div.gravatar-wrapper, -#updateGravatarForm div.gravatar-wrapper { - margin-bottom: 20px; - display: inline-block; -} -#updateForm .change-gravatar, -#updateGravatarForm .change-gravatar { - float: right; - margin-top: 23px; -} -#updateGravatarForm { - display: none; -} -#updateGravatarForm .gravatar-file-upload { - cursor: pointer; -} -#updateGravatarForm .gravatar-file-upload .sprite-icons { - position: absolute; -} -#updateGravatarForm .gravatar-upload-label { - margin: 2px 0 2px 40px; - display: inline-block; -} -.user.update .form-tabs.profile, -.user.two-step-update .form-tabs.profile, -.user.two-step-new .form-tabs.profile, -.user.two-step-verify .form-tabs.profile, -.user.two-step-done .form-tabs.profile, -.user.update-dealer .form-tabs.profile { - margin-top: 0px; -} -/* need new section for styling settings alarms form */ -#forms-container-alarms-settings label { - line-height: 44px; -} -#forms-container-alarms-settings label[class="required"]:after { - content: "*"; - color: #4790d0; -} -#forms-container-alarms-settings .custom-radio label { - line-height: 21px; -} -#forms-container-alarms-settings .settings-alarm-header { - background-color: #faf9f5; - border: 1px solid #dcdbd7; - padding: 19px; -} -#forms-container-alarms-settings .settings-alarm-toggle { - border-top: 1px solid #f0efeb; - cursor: pointer; - position: relative; -} -#forms-container-alarms-settings .settings-alarm-toggle.one-line { - padding: 19px 45px 19px 80px; -} -#forms-container-alarms-settings .settings-alarm-toggle.two-lines { - padding: 8px 45px 8px 80px; -} -#forms-container-alarms-settings .settings-alarm-toggle.has-error:first-child::before { - position: absolute; - top: 18px; - left: -35px; - content: ' '; - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -48px -192px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - #forms-container-alarms-settings .settings-alarm-toggle.has-error:first-child::before { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -#forms-container-alarms-settings .settings-alarm-toggle .device-name { - font-size: 18px; -} -#forms-container-alarms-settings .settings-alarm-toggle .alarm-name { - display: block; - color: #4790d0; - font-size: 15px; -} -#forms-container-alarms-settings .settings-alarm-toggle .alarm-name.gray, -#forms-container-alarms-settings .settings-alarm-toggle .alarm-name .gray { - color: #63625e; -} -#forms-container-alarms-settings .settings-alarm-toggle .toggle-icon { - position: absolute; - right: 20px; - top: 18px; -} -#forms-container-alarms-settings .settings-alarm-toggle .device-icon { - position: absolute; - left: 18px; - top: 7px; -} -#forms-container-alarms-settings .settings-alarm-group { - border: 1px solid #dcdbd7; - background-color: #faf9f5; - border-top: 0; - border-bottom: 0; -} -#forms-container-alarms-settings .settings-alarm-group li.has-alarm-error { - border-left: 3px solid #fa716f; -} -#forms-container-alarms-settings .settings-alarm-group:first-child { - border-top: 1px solid #dcdbd7; -} -#forms-container-alarms-settings .settings-alarm-group:first-child .settings-alarm-toggle:first-child { - border-top: 0; -} -#forms-container-alarms-settings .settings-alarm-group .settings-alarm-toggle .icon-toggle { - background: url('/img/icon/icon-open.png') center center no-repeat; -} -#forms-container-alarms-settings .settings-alarm-group.active { - background-color: #ffffff; -} -#forms-container-alarms-settings .settings-alarm-group.active .settings-alarm-toggle { - border-bottom: 1px solid #f0efeb; -} -#forms-container-alarms-settings .settings-alarm-group.active .settings-alarm-toggle .icon-toggle { - background: url('/img/icon/icon-close.png') center center no-repeat; -} -#forms-container-alarms-settings .settings-alarm-group.below-alarms-fieldset-element { - border-top: 1px solid #f0efeb; - border-bottom: 1px solid #dcdbd7; - min-height: 60px; -} -#forms-container-alarms-settings .settings-alarm-group.below-alarms-fieldset-element a { - line-height: 60px; - margin-left: 80px; -} -#forms-container-alarms-settings .settings-alarm-group li:last-child { - margin-bottom: 19px; -} -#forms-container-alarms-settings .settings-alarm-description { - padding: 19px 19px 19px 80px; - display: none; -} -#forms-container-alarms-settings .settings-alarm-element { - padding: 19px 19px 0px 80px; - width: 240px; - float: left; - display: none; -} -#forms-container-alarms-settings .settings-alarm-element.has-error input[type="text"], -#forms-container-alarms-settings .settings-alarm-element.has-error input[type="email"], -#forms-container-alarms-settings .settings-alarm-element.has-error input[type="password"], -#forms-container-alarms-settings .settings-alarm-element.has-error input[type="tel"], -#forms-container-alarms-settings .settings-alarm-element.has-error input[type="url"], -#forms-container-alarms-settings .settings-alarm-element.has-error textarea { - border-color: #fa716f; - color: #fa716f; -} -#forms-container-alarms-settings .settings-alarm-element ul.errors li { - color: #fa716f; -} -#forms-container-alarms-settings .settings-alarm-delete { - width: 100%; -} -#forms-container-alarms-settings .settings-alarm-element:nth-child(even) { - padding: 19px 19px 0 19px; -} -#forms-container-alarms-settings .settings-alarm-toggle .settings-alarm-element:nth-child(even) { - padding: 19px 19px 0 19px; -} -#forms-container-alarms-settings .settings-alarm-toggle.no-description ~ .settings-alarm-element:nth-child(even) { - padding: 19px 19px 0 80px; -} -#forms-container-alarms-settings .settings-alarm-toggle.no-description ~ .settings-alarm-element:nth-child(odd) { - padding: 19px 19px 0 19px; -} -#forms-container-alarms-settings .settings-alarm-element:nth-child(2) { - padding-top: 5px; -} -.VRM_Widget_SiteSummary { - color: #63625e; -} -/* -----------[Screensave]--------------*/ -.screensaver { - background-color: #272622; - height: 100%; - left: 0; - position: fixed; - top: 0; - visibility: hidden; - width: 100%; - z-index: 10000; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; - opacity: 0; - filter: alpha(opacity=0); -} -.screensaver.visible { - visibility: visible; - opacity: 1; - filter: alpha(opacity=100); -} -.screensaver.on-solar .screensaver-text { - color: #f7ab3e; -} -.screensaver.on-solar .screensaver-icon:before { - color: #f7ab3e; - content: '\e603'; -} -.screensaver.on-generator .screensaver-text { - color: #4790d0; -} -.screensaver.on-generator .screensaver-icon:before { - margin-left: -50%; - color: #4790d0; - content: '\e600'; -} -.screensaver.on-battery .screensaver-text { - color: #4790d0; -} -.screensaver.on-battery .screensaver-icon:before { - color: #4790d0; - content: '\e601'; -} -.screensaver.on-grid .screensaver-text { - color: #8bc964; -} -.screensaver.on-grid .screensaver-icon:before { - color: #8bc964; - content: '\e602'; -} -.screensaver-icon { - left: 50%; - position: absolute; - top: 50%; -} -.screensaver-icon:before { - font-family: 'screensaver-icons'; - margin-top: 60%; - position: absolute; -} -.screensaver-text { - left: 50%; - position: absolute; - text-transform: uppercase; - top: 50%; -} -.screensaver-text-grid-type { - color: #ffffff; - font-family: 'MuseoSans-700'; -} -.screensaver-company-logo { - bottom: 0; - position: absolute; - right: 0; -} -.screensaver-company-logo img { - height: 100%; - width: 100%; -} -.whitelabel-active .screensaver-company-logo { - display: none; -} -.beta-badge { - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - display: inline-block; - font-size: 13px; - line-height: 11px; - min-width: 50px; - min-height: 20px; - padding-top: 5px; - text-decoration: none; - text-align: center; - background-color: #f7ab3e; - color: #ffffff; - top: -2px; - position: relative; - margin-left: 10px; -} -/* -----------[Modal popups]--------------*/ -.modal-popup-container { - background-color: #ffffff; - border: 1px solid #e5e4e0; - margin: 20px auto; - max-width: 560px; - padding: 20px 0; - position: relative; - width: auto; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -#modal-popup-container-share #guest-account-content { - margin-bottom: 25px; - margin-top: 25px; -} -#modal-popup-container-share #guest-account-content .modal-popup-content-row, -#modal-popup-container-share #guest-account-content .modal-popup-content-row-divider { - overflow: hidden; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; -} -#modal-popup-container-share #guest-account-content .modal-popup-content-row:not(.visible), -#modal-popup-container-share #guest-account-content .modal-popup-content-row-divider:not(.visible) { - height: 0; - min-height: 0; - margin: 0; - padding: 0; -} -#modal-popup-container-share #guest-account-content .modal-popup-content-left-right-container { - min-height: 50px; -} -#modal-popup-container-share #guest-account-content .modal-popup-content-left-right-container .modal-popup-content-left-max { - line-height: 40px; -} -#modal-popup-container-share #guest-account-content .modal-popup-content-left-right-container .modal-popup-content-left-max input { - line-height: 10px; -} -#modal-popup-container-share #guest-account-content .modal-popup-content-left-right-container .modal-popup-content-left-max input::-webkit-input-placeholder { - line-height: normal; -} -#modal-popup-container-share #invite-user-content { - margin-top: 30px; -} -#modal-popup-container-share #invite-user-content .modal-popup-content-left-max input, -#modal-popup-container-share #invite-user-content .modal-popup-content-left-max textarea { - margin-bottom: 10px; -} -#modal-popup-container-share .invite-user-message { - margin-top: 5px; -} -.modal-popup-content { - padding: 0 49px; -} -.modal-popup-content h1 { - margin-bottom: 21px; - margin-top: 28px; -} -.modal-popup-tab-content.hidden { - display: none; -} -.modal-popup-tabs-list { - margin-bottom: -1px; -} -.modal-popup-tabs-item { - cursor: pointer; - float: left; - font-size: 18px; - margin-right: 20px; - padding-bottom: 3px; - padding-right: 10px; -} -.modal-popup-tabs-item:hover { - border-bottom: 1px solid #4790d0; -} -.modal-popup-tabs-item.selected { - border-bottom: 2px solid #4790d0; - color: #4790d0; - cursor: default; -} -.modal-popup-tabs-container { - border-bottom: 1px solid #e5e4e0; -} -.modal-popup-content-full-width { - margin-bottom: 10px; -} -.modal-popup-content-left-right-container { - position: relative; -} -.modal-popup-content-left-right-container.password-container { - height: 0; - min-height: 0 !important; - overflow: hidden; - -webkit-transition: 0.2s; - -moz-transition: 0.2s; - -o-transition: 0.2s; - transition: 0.2s; -} -.modal-popup-content-left-right-container.password-container.visible { - height: 62px; -} -.modal-popup-content-left-right-container.renew-container .modal-popup-content-left-max { - height: 40px; - line-height: 40px; -} -.modal-popup-content-left-max { - padding-right: 90px; -} -.modal-popup-content-left-max input, -.modal-popup-content-left-max textarea { - margin-bottom: 5px; - width: 100%; -} -.modal-popup-content-right-control { - position: absolute; - right: 0; - top: 0; - width: 80px; -} -.modal-popup-content-right-control .custom-toggle.slide-colors { - margin-top: 5px; -} -.modal-popup-content-right-control input { - width: 100%; -} -.modal-popup-content-right-control.completed:before { - content: ''; - left: 28px; - position: absolute; - top: 9px; - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: 0px -216px; -} -@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { - .modal-popup-content-right-control.completed:before { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -.modal-popup-content-row-divider { - background-color: #dcdbd7; - height: 1px; - margin-bottom: 15px; - margin-top: 15px; -} -.modal-popup-bottom-button-row { - padding-bottom: 29px; -} -.modal-popup-bottom-button-row .btn { - margin-top: 5px; -} -.modal-popup-bottom-button-row a { - margin-top: 16px; -} -.loading-spinner { - background-image: url('/img/loader-circle.gif'); - background-repeat: no-repeat; - background-position: center center; -} -#forms-container-system-overview .btn.site-diagnostics { - margin-right: 20px; -} -/* -----------[Remote Console]--------------*/ -.remote-console-trigger { - float: right; -} -#vrm-tabs-content #remoteConsoleButton { - margin-top: 10px; -} -.remote-console-popup-container { - background-color: #faf9f5; - border: none; - max-width: 783px; - overflow: hidden; - padding: 0; - position: relative; - width: 620px; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; -} -.remote-console-popup-container.password-needed .remote-console-login { - display: block; -} -.remote-console-popup-container.password-needed .remote-console-status { - display: none; -} -.remote-console-popup-container.password-needed .remote-console-logged-in { - display: none; -} -.remote-console-popup-container.password-needed .mfp-close { - color: #faf9f5; -} -.remote-console-popup-container.logged-in { - width: 783px; - /* This is needed to prevent the canvas becoming tiny on some occasions.. */ -} -.remote-console-popup-container.logged-in .remote-console-login { - display: none; -} -.remote-console-popup-container.logged-in .remote-console-status { - display: none; -} -.remote-console-popup-container.logged-in .remote-console-logged-in { - display: block; -} -.remote-console-popup-container.logged-in #remote-console-canvas { - height: 100% !important; - width: 100% !important; -} -.remote-console-popup-container.logged-in .mfp-close { - color: #faf9f5; -} -.remote-console-popup-container .mfp-close { - color: #4790d0; -} -.remote-console-login { - display: none; - height: 312px; - padding-right: 240px; -} -.remote-console-login .remote-console-display-container { - height: 100%; - text-align: center; - width: 100%; -} -.remote-console-login .remote-console-controls-container { - width: 240px; -} -.remote-console-login .remote-console-controls-title { - margin-top: 92px; - text-align: left; -} -.remote-console-status { - text-align: center; - height: 312px; -} -.remote-console-status.notification .remote-console-login-icon.notification { - display: inline-block; -} -.remote-console-status.alarm .remote-console-login-icon.alarm { - display: inline-block; -} -.remote-console-status .remote-console-login-icon { - display: none; -} -.remote-console-status .remote-console-login-icon.alarm { - fill: #fa716f; -} -.remote-console-status .remote-console-login-icon.alarm path { - fill: #fa716f !important; -} -.remote-console-status .remote-console-login-title { - margin-bottom: 10px; -} -.remote-console-status-content { - margin-top: -50px; - position: absolute; - top: 50%; - width: 100%; -} -.remote-console-logged-in { - display: none; -} -.remote-console-login-contents { - display: inline-block; - margin: 0 auto; - padding-top: 41px; - text-align: center; -} -.remote-console-login-icon { - display: inline-block; - height: 32px; - width: 32px; -} -.remote-console-login-icon path { - fill: #4790d0 !important; -} -.remote-console-login-title { - font-family: 'MuseoSans-700'; - margin-bottom: 37px; - margin-top: 11px; -} -.remote-console-login-fields-container { - text-align: left; -} -.remote-console-login-fields { - margin-top: 4px; -} -#remote-console-password { - margin-right: 5px; - width: 174px; -} -#remote-console-login { - line-height: 16px; -} -#remote-console-login .svg { - fill: #faf9f5; - height: 16px; - width: 16px; -} -.custom-check-and-radio { - margin-top: 20px; -} -.remote-console-title { - color: #4790d0; - display: none; - font-family: 'MuseoSans-700'; - margin-bottom: 0; - margin-top: 20px; - padding-left: 20px; -} -.remote-console-display-container { - display: table; -} -.remote-console-display { - background-color: #faf9f5; - padding: 20px; -} -.remote-console-display-inner { - position: relative; - border: 1px solid #e5e4e0; - height: 272px; - width: 480px; -} -.remote-console-display-inner .remote-console-status-text { - position: absolute; - top: 40%; - left: 0; - width: 100%; - text-align: center; - z-index: 9999; - color: #959490; -} -.remote-console-controls-container { - background-color: #4790d0; - height: 100%; - position: absolute; - right: 0; - top: 0; - width: 262px; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-user-select: none -} -.remote-console-controls-text { - padding-left: 20px; - padding-right: 20px; -} -.remote-console-controls-title { - margin-bottom: 0; - margin-top: 33px; -} -.remote-console-controls-subtitle { - line-height: 21px; - margin-top: 4px; -} -.remote-console-controls-explanation { - color: #f3f2ee; - line-height: 21px; - margin-top: 23px; -} -.remote-console-controls-title, -.remote-console-controls-subtitle { - color: #f3f2ee; - text-align: center; -} -.remote-console-controls { - bottom: 0; - height: 187px; - left: 0; - padding-bottom: 25px; - padding-top: 25px; - position: absolute; - width: 100%; -} -.remote-console-controls-row { - padding-bottom: 5px; - padding-top: 5px; - text-align: center; -} -.remote-console-controls-row:first-child { - /*margin-bottom: 20px;*/ -} -.remote-console-control-button { - cursor: pointer; - height: 40px; - margin-left: 3px; - margin-right: 3px; - padding: 0; - position: relative; - width: 40px; -} -.remote-console-control-button.wide { - width: 65px; -} -.remote-console-control-button.extra-wide { - width: 140px; -} -.remote-console-control-button .remote-console-control-icon { - color: #4790d0; - display: inline-block; - fill: #4790d0; - font-size: 17px; - height: 16px; - line-height: 20px; - margin-top: 11px; - width: 16px; -} -.remote-console-control-button .remote-console-control-icon.text { - left: 19px; - position: absolute; - top: -3px; - width: auto; -} -.remote-console-control-button .remote-console-control-icon path { - fill: #4790d0; -} -.remote-console-rotate-message-container { - background-color: #e5e4e0; - display: none; - height: 100%; - position: fixed; - top: 0; - width: 100%; - z-index: 100000; -} -.rotate-message-contents { - margin-top: -66px; - position: absolute; - text-align: center; - top: 50%; - width: 100%; -} -.rotate-message-icon { - display: inline-block; - height: 72px; - margin-bottom: 20px; - width: 72px; -} -.rotate-message-icon path { - fill: #4790d0; -} -.rotate-message-title { - font-family: 'MuseoSans-700'; - margin: 0; -} -#privateShareButtonMobile, -#remoteConsoleButtonMobile { - background-color: #8bc964; -} -#privateShareButtonMobile:hover, -#remoteConsoleButtonMobile:hover { - background-color: #72b84c; -} -/* -----------[Media queries for desktop]--------------*/ -@media screen and (min-width: 960px) { - .hide-desktop { - display: none; - } -} -/* -----------[Media queries for mobile/responsive]--------------*/ -@media screen and (max-width: 959px) { - .hide-responsive { - display: none; - } - .site-overview-controls .container-inner .grid-item.five-columns-width, - .site-overview-controls .container-inner .grid-item.six-columns-width, - .site-overview-controls .container-inner .grid-item.seven-columns-width, - .site-overview-controls .container-inner .grid-item.eight-columns-width, - .site-overview-controls .container-inner .grid-item.nine-columns-width, - .site-overview-controls .container-inner .grid-item.ten-columns-width, - .site-overview-controls .container-inner .grid-item.eleven-columns-width, - .site-overview-controls .container-inner .grid-item.twelve-columns-width { - margin-left: 10px; - margin-right: 10px; - width: 300px; - } - .site-overview-controls .container-inner .grid-item.view-toggle .view-toggle-container { - display: none; - } - .this-is-the-homepage { - display: none; - } - .vrm-date-range-selection { - margin-top: 40px; - } - .date-range-selectors { - height: 65px; - } - .date-range-selectors .current, - .date-range-selectors .previous { - display: none; - } - .date-range-selectors-advanced { - margin-bottom: 4px; - } - .date-range-selectors-advanced .section { - margin-bottom: 7px; - margin-left: 0px; - width: 100%; - } - .date-range-selectors-advanced .section .mobile-caption { - display: inline-block; - float: left; - line-height: 54px; - } - .date-range-selectors-advanced .section .vrm-date-time-picker { - float: right; - } - .date-range-selectors-advanced .section .vrm-date-time-picker .picker { - left: -80px; - } - .date-range-selectors-advanced .section.set-time { - display: none; - height: 0px; - margin-bottom: 11px; - } - .date-range-selectors-advanced .section.set-time .btn { - float: left; - } - .date-range-selectors .selector-list > li:first-child { - float: left; - } - .date-range-selectors .selector-list > li:last-child { - float: right; - } - .date-range-selectors .selector-list > li, - .date-range-selectors-advanced .selector-list > li { - margin-left: 0px; - } - .date-range-selectors .custom_date_selector_container, - .date-range-selectors-advanced .custom_date_selector_container { - float: left; - padding-left: 0px; - } - .picker { - width: 300px; - } - #alarms { - display: none; - } - #mobile-alarms { - display: block; - } - #mobile-alarms .alarmCleared, - #mobile-alarms .alarmState { - text-align: right; - } - #mobile-alarms tbody tr td { - border-bottom: 0px; - padding-bottom: 0px; - } - #mobile-alarms tbody tr:nth-child(3n) td { - border-bottom: 1px solid #dcdbd7; - padding-top: 0px; - padding-bottom: 18px; - width: 320px; - } - #mobile-alarms tbody tr:nth-child(3n) td .alarmCleared { - float: right; - } - .pagination .previous, - .pagination .next { - display: none; - } - .pagination ul li { - padding: 7px; - } - .container.site-overview-content { - margin-bottom: 40px; - } - .container .container-inner { - width: 320px; - } - .container .container-inner .secondary-controls { - display: none; - } - .container .container-inner .grid-item.eight-columns-width, - .container .container-inner .grid-item.twelve-columns-width { - margin-left: 10px; - margin-right: 10px; - width: 300px; - } - .container .container-inner .grid-item.offset-four { - margin-left: 10px; - } - .container .container-inner .over-google-map { - position: relative; - top: 0px; - } - .container .container-inner .tab-select { - display: block; - margin-top: 14px; - } - .container.top-menu { - display: none; - } - .container.breadcrumb { - background-color: #e6e5e1; - } - .container.breadcrumb .buttons-container { - display: none; - } - .container.breadcrumb .btn { - display: none; - } - .container.breadcrumb .site-select { - display: none; - } - .container.breadcrumb .breadcrumb-site-title { - display: block; - } - .container .breadcrumb-buttons-container { - padding-bottom: 12px; - } - .vrm.site.index .container.breadcrumb + .clearfix { - display: none; - } - .container.sites-statistics { - background-color: #f0efeb; - border-bottom: 1px solid #dcdbd7; - color: #959490; - display: block; - height: 80px; - } - .container.sites-statistics .grid-item { - float: none; - } - .container.sites-statistics .results .total { - padding-left: 20px; - } - .container.sites-statistics .results .alarms { - color: #f35c58; - } - .container.map-view { - display: none; - } - .container.map-overview .map { - height: 230px; - width: 100%; - } - .container.site-overview { - padding-top: 15px; - } - .container.site-view .container-inner #vrm-tabs { - display: none; - } - .container #vrm-tabs-content .tab-pane#advanced .section-heading { - margin: 35px 0 7px 0; - } - .container #vrm-tabs-content .tab-pane#advanced .download-data-container { - position: static; - top: 0; - left: 0; - float: left; - margin-bottom: 14px; - padding-left: 24px; - max-height: none; - } - .container #vrm-tabs-content .tab-pane#advanced .download-data-container .download-blue { - float: left; - } - .container #vrm-tabs-content .tab-pane#advanced .download-data-container .link-text { - float: right; - clear: right; - width: 145px; - padding: 0; - } - .container #vrm-tabs-content .tab-pane .content .last-update-info { - margin-bottom: 8px; - padding-right: 0px; - position: relative; - top: 0px; - } - .container #vrm-tabs-content .tab-pane .content .last-update-info > span:first-child { - padding-left: 27px; - } - .container #vrm-tabs-content .tab-pane .content .last-update-info .pull-right { - float: left; - } - .container #vrm-tabs-content .tab-pane .content .last-update-info .sprite-icons { - left: 0px; - position: absolute; - } - .container #vrm-tabs-content .tab-pane .content .section-heading > span, - .container #vrm-tabs-content .tab-pane .content .section-heading h2 { - display: none; - } - .container #vrm-tabs-content .tab-pane .content .mobile-graph-refresh { - display: inline-block; - width: 300px; - margin: 10px; - } - .container #vrm-tabs-content .tab-pane .content .progress-meters-container { - height: auto; - margin-bottom: 40px; - } - .container #vrm-tabs-content .tab-pane .content .progress-meters-container .progress-meter-container { - height: 150px !important; - padding: 20px 20px 48px 20px; - } - .container #vrm-tabs-content .tab-pane .content .progress-meters-container .progress-meter-container .progress-meter .inner-meter-container .icon, - .container #vrm-tabs-content .tab-pane .content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .icon { - left: auto !important; - right: 0px !important; - top: -30px !important; - } - .container #vrm-tabs-content .tab-pane .content .section-graph { - margin-bottom: 40px; - } - .container #vrm-tabs-content .tab-pane .content .section-graph .dashboard-graph { - height: 224px !important; - margin: 40px 20px 30px 10px !important; - } - .container #vrm-tabs-content .tab-pane .content .section-graph .dashboard-legend { - height: 90px !important; - } - .container #vrm-tabs-content .tab-pane .content .section-graph .dashboard-legend ul li { - margin-bottom: 9px; - margin-right: 0px !important; - width: 130px; - } - .container #vrm-tabs-content #solar-yield .content .section-graph .dashboard-graph.move-last-tick-to-front .jqplot-xaxis canvas:last-child, - .container #vrm-tabs-content #consumption .content .section-graph .dashboard-graph.move-last-tick-to-front .jqplot-xaxis canvas:last-child, - .container #vrm-tabs-content #batteries .content .section-graph .dashboard-graph.move-last-tick-to-front .jqplot-xaxis canvas:last-child { - left: 10px !important; - } - .container #vrm-tabs-content #settings .content .form-tabs-container { - margin-bottom: 40px; - margin-left: 10px; - margin-right: 10px; - width: 300px; - } - .container #vrm-tabs-content #settings .content .form-tabs-container .form-tabs { - margin-top: 14px; - } - .container #vrm-tabs-content #settings .content .form-tabs-container .form-tabs li a { - padding-left: 20px; - text-align: left; - } - .container #vrm-tabs-content #settings .content .form-tabs-container .btn { - width: 300px; - } - .container #vrm-tabs-content #settings .content .form-tabs-container .btn.force-width { - width: 300px !important; - } - .container #vrm-tabs-content #settings .content .form-tabs-container .mobile-title { - display: block; - margin-bottom: 0px; - margin-top: 50px; - } - .container #vrm-tabs-content #settings .content .remove-site-question .btn { - width: 300px; - } - .container #vrm-tabs-content #settings .content .remove-site-question .btn.force-width { - width: 300px !important; - } - .container #vrm-tabs-content #settings .content #form-container-sitesettings #sitesettings #fieldset-location .location-map-container #location-map { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - height: 300px; - width: 300px; - } - .container #vrm-tabs-content #settings .content #form-container-sitesettings #sitesettings #fieldset-summarywidget .summary-widget-list-enabled-caption { - margin-bottom: 13px; - padding-right: 0; - text-align: left; - } - .container #vrm-tabs-content #settings .content #form-container-sitesettings #sitesettings #fieldset-summarywidget .summary-widget-list-enabled-caption, - .container #vrm-tabs-content #settings .content #form-container-sitesettings #sitesettings #fieldset-summarywidget .summary-widget-list-disabled-caption { - margin-top: 17px; - padding-left: 37px; - } - .container #vrm-tabs-content #settings .content #form-container-sitesettings #sitesettings #fieldset-summarywidget .summary-widget-list-enabled-caption .sprite-icons, - .container #vrm-tabs-content #settings .content #form-container-sitesettings #sitesettings #fieldset-summarywidget .summary-widget-list-disabled-caption .sprite-icons { - left: 15px; - } - .container #vrm-tabs-content #settings .content #form-container-sitesettings #sitesettings #fieldset-geofence.fieldset-geofence-map { - width: auto; - } - .container #vrm-tabs-content #settings .content #form-container-sitesettings #sitesettings #fieldset-geofence.fieldset-geofence-map .form-element { - width: auto !important; - } - .container #vrm-tabs-content #settings .content #form-container-sitesettings #sitesettings #fieldset-geofence.fieldset-geofence-map .geofence-map-container { - width: auto; - } - .container #vrm-tabs-content #settings .content #form-container-sitesettings #sitesettings #fieldset-geofence.fieldset-geofence-map .geofence-map-container #geofence-map { - width: auto; - } - .container #vrm-tabs-content #settings .content .sortable-widget-list-enabled-caption { - margin-bottom: 13px; - padding-right: 0; - text-align: left; - } - .container #vrm-tabs-content #settings .content .sortable-widget-list-disabled-caption { - margin-bottom: 13px !important; - margin-top: 16px !important; - } - .container #vrm-tabs-content #settings .content .sortable-widget-list-enabled-caption, - .container #vrm-tabs-content #settings .content .sortable-widget-list-disabled-caption { - padding-left: 37px; - } - .container #vrm-tabs-content #settings .content .sortable-widget-list-enabled-caption .sprite-icons, - .container #vrm-tabs-content #settings .content .sortable-widget-list-disabled-caption .sprite-icons { - left: 15px; - } - .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-alarms-admin-settings .form-input-list .row, - .container #vrm-tabs-content #settings .content #form-container-user-settings #form-alarms-admin-settings .form-input-list .row, - .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-alarms-admin-settings .form-input-list .row, - .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-user-settings-container .form-input-list .row, - .container #vrm-tabs-content #settings .content #form-container-user-settings #form-user-settings-container .form-input-list .row, - .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-user-settings-container .form-input-list .row, - .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-widget-settings .form-input-list .row, - .container #vrm-tabs-content #settings .content #form-container-user-settings #form-widget-settings .form-input-list .row, - .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-widget-settings .form-input-list .row { - height: auto; - } - .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle label .alternative-display, - .container #vrm-tabs-content #settings .content #form-container-user-settings #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle label .alternative-display, - .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle label .alternative-display, - .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label .alternative-display, - .container #vrm-tabs-content #settings .content #form-container-user-settings #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label .alternative-display, - .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label .alternative-display, - .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-widget-settings .form-input-list .row .inner-container .custom-toggle label .alternative-display, - .container #vrm-tabs-content #settings .content #form-container-user-settings #form-widget-settings .form-input-list .row .inner-container .custom-toggle label .alternative-display, - .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-widget-settings .form-input-list .row .inner-container .custom-toggle label .alternative-display { - position: relative; - left: 0; - margin-top: 10px; - } - .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle label > a, - .container #vrm-tabs-content #settings .content #form-container-user-settings #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle label > a, - .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle label > a, - .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label > a, - .container #vrm-tabs-content #settings .content #form-container-user-settings #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label > a, - .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label > a, - .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-widget-settings .form-input-list .row .inner-container .custom-toggle label > a, - .container #vrm-tabs-content #settings .content #form-container-user-settings #form-widget-settings .form-input-list .row .inner-container .custom-toggle label > a, - .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-widget-settings .form-input-list .row .inner-container .custom-toggle label > a { - top: 0; - } - .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle.adjust-margin label .caption, - .container #vrm-tabs-content #settings .content #form-container-user-settings #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle.adjust-margin label .caption, - .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle.adjust-margin label .caption, - .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-user-settings-container .form-input-list .row .inner-container .custom-toggle.adjust-margin label .caption, - .container #vrm-tabs-content #settings .content #form-container-user-settings #form-user-settings-container .form-input-list .row .inner-container .custom-toggle.adjust-margin label .caption, - .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-user-settings-container .form-input-list .row .inner-container .custom-toggle.adjust-margin label .caption, - .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-widget-settings .form-input-list .row .inner-container .custom-toggle.adjust-margin label .caption, - .container #vrm-tabs-content #settings .content #form-container-user-settings #form-widget-settings .form-input-list .row .inner-container .custom-toggle.adjust-margin label .caption, - .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-widget-settings .form-input-list .row .inner-container .custom-toggle.adjust-margin label .caption { - display: inline-block; - margin-top: 10px; - } - .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle.adjust-margin label .email-caption, - .container #vrm-tabs-content #settings .content #form-container-user-settings #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle.adjust-margin label .email-caption, - .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle.adjust-margin label .email-caption, - .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-user-settings-container .form-input-list .row .inner-container .custom-toggle.adjust-margin label .email-caption, - .container #vrm-tabs-content #settings .content #form-container-user-settings #form-user-settings-container .form-input-list .row .inner-container .custom-toggle.adjust-margin label .email-caption, - .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-user-settings-container .form-input-list .row .inner-container .custom-toggle.adjust-margin label .email-caption, - .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-widget-settings .form-input-list .row .inner-container .custom-toggle.adjust-margin label .email-caption, - .container #vrm-tabs-content #settings .content #form-container-user-settings #form-widget-settings .form-input-list .row .inner-container .custom-toggle.adjust-margin label .email-caption, - .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-widget-settings .form-input-list .row .inner-container .custom-toggle.adjust-margin label .email-caption { - display: inline-block; - min-width: 200px; - margin-top: 6px; - } - .container #vrm-tabs-content #settings .content #form-container-user-settings #toggleInviteForm, - .container #vrm-tabs-content #settings .content #form-alarms-admin-settings #toggleInviteForm { - margin-bottom: 20px; - position: static; - width: 300px; - } - .container #vrm-tabs-content #settings .content #form-container-user-settings #toggleInviteForm.force-width, - .container #vrm-tabs-content #settings .content #form-alarms-admin-settings #toggleInviteForm.force-width { - width: 300px !important; - } - .container #vrm-tabs-content #settings .content #form-container-user-settings #inviteFormExplanation, - .container #vrm-tabs-content #settings .content #form-alarms-admin-settings #inviteFormExplanation { - position: static; - } - .container #vrm-tabs-content #settings .content #form-container-user-settings .header .caption-right, - .container #vrm-tabs-content #settings .content #form-alarms-admin-settings .header .caption-right { - float: none; - text-transform: lowercase; - } - .container #vrm-tabs-content #settings .content #form-alarms-admin-settings .header { - height: auto; - padding-top: 7px; - padding-bottom: 6px; - } - .container #vrm-tabs-content #settings .content #forms-container-alarms-settings .above-fieldset-element { - margin-bottom: 20px; - position: static; - } - .container #vrm-tabs-content #settings .content #forms-container-alarms-settings .above-fieldset-element .btn { - margin-left: 0; - margin-bottom: 12px; - width: 300px; - } - .container #vrm-tabs-content #settings .content #forms-container-alarms-settings .above-fieldset-element .btn.force-width { - width: 300px !important; - } - .container #vrm-tabs-content #settings .content #forms-container-alarms-settings .below-alarms-fieldset-element { - text-align: center; - } - .container #vrm-tabs-content #settings .content #forms-container-alarms-settings .below-alarms-fieldset-element a { - margin-left: 0; - width: 300px; - } - .container #vrm-tabs-content #settings .content #forms-container-alarms-settings .below-alarms-fieldset-element a.force-width { - width: 300px !important; - } - .container #vrm-tabs-content #settings .content #forms-container-alarms-settings .hint { - display: none; - } - /* -----------[Widgets]--------------*/ - .widget .header .sub-title ul li:nth-child(2) { - margin-top: -8px; - } - .widget .bottom-graph .graph-links li.selected:nth-child(2) .caption { - width: 97px; - } - .widget.VRM_Widget_State .content .graph-container, - .widget.VRM_Widget_VeBusWarningsAndAlarms .content .graph-container { - height: 255px; - padding: 50px 28px 25px 22px; - } - .widget.VRM_Widget_State .state-legend, - .widget.VRM_Widget_VeBusWarningsAndAlarms .state-legend { - padding: 20px 22px; - } - .widget .content.ps-container { - height: auto; - } - #forms-container-alarms-settings .settings-alarm-element { - width: 188px; - float: none; - padding: 0px 19px 19px 80px !important; - } - #forms-container-alarms-settings .settings-alarm-element:nth-child(2) { - padding-top: 5px !important; - } - /* -----------[Mobile menu]--------------*/ - .mobile-menu-open-handle { - border: 1px solid #dcdbd7; - cursor: pointer; - display: block; - height: 40px; - margin-right: 0; - position: absolute; - right: 10px; - top: 20px; - width: 40px; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; - } - .mobile-menu-open-handle .sprite-icons { - margin-left: 8px; - margin-top: 8px; - } - body.mobile-menu-open { - overflow: auto; - } - body.mobile-menu-open .mobile-menu-open-handle { - display: none; - } - body.mobile-menu-open .mobile-menu-close-handle { - right: 20px; - } - body.mobile-menu-open .mobile-menu { - left: 0; - } - body.mobile-menu-open .site-overlay-on-menu-open { - left: 0; - opacity: 1; - filter: alpha(opacity=100); - -webkit-transition: opacity 0.25s; - -moz-transition: opacity 0.25s; - -o-transition: opacity 0.25s; - transition: opacity 0.25s; - } - .mobile-menu { - background-color: #faf9f5; - bottom: 0; - display: block; - overflow: hidden; - position: fixed; - left: -258px; - top: 0; - z-index: 1101; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - -webkit-transition: left 0.25s; - -moz-transition: left 0.25s; - -o-transition: left 0.25s; - transition: left 0.25s; - -webkit-transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); - transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); - -webkit-transform: translateZ(0); - -moz-transform: translateZ(0); - -ms-transform: translateZ(0); - -o-transform: translateZ(0); - transform: translateZ(0); - -webkit-perspective: 1000; - -moz-perspective: 1000; - -ms-perspective: 1000; - perspective: 1000; - } - .mobile-menu.has-user-search-input .hide-on-user-search-input { - display: none !important; - } - .mobile-menu .container-inner { - padding-bottom: 0; - width: 258px !important; - height: 100%; - } - .mobile-menu .container-inner ul { - position: absolute; - top: 0; - bottom: 0; - width: 100%; - margin-top: 40px; - overflow-y: scroll; - } - .mobile-menu .container-inner ul li { - padding-left: 18px; - padding-right: 18px; - } - .mobile-menu .container-inner ul li.collapsable-parent .mobile-menu-link-main { - padding-right: 20px; - } - .mobile-menu .container-inner ul li.collapsable-parent .collapsable-parent-handle { - position: absolute; - right: 13px; - top: -2px; - display: inline-block; - width: 24px; - height: 24px; - background-image: url("/img/VRM-sprite.png?v=3"); - background-size: 621px 888px; - background-repeat: no-repeat; - background-position: -24px -240px; - } - .mobile-menu .container-inner ul li.collapsable-child.collapsed { - display: none; - } - .mobile-menu .container-inner ul li a { - display: block; - text-decoration: none; - } - .mobile-menu .container-inner ul li a .plus-sign { - color: #afe18d; - } - .mobile-menu .container-inner ul li .mobile-menu-link-main { - color: #272622; - font-size: 18px; - margin-bottom: 17px; - margin-top: 35px; - } - .mobile-menu .container-inner ul li .mobile-menu-link-sub { - margin-top: 14px; - } - .mobile-menu .top-menu-language-fly-out, - .mobile-menu .top-menu-language-selector-container { - display: none; - } - .mobile-menu-search { - display: block; - height: 40px; - } - .mobile-menu-search .sprite-icons { - left: 8px; - position: absolute; - top: 8px; - } - .mobile-menu-search input { - background-color: #959490 !important; - border-color: #959490 !important; - color: #ffffff !important; - height: 100%; - padding-left: 40px; - width: 100%; - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; - } - .mobile-menu-search input:-moz-placeholder { - color: #e6e5e1; - opacity: 1; - } - .mobile-menu-search input::-moz-placeholder { - color: #e6e5e1; - opacity: 1; - } - .mobile-menu-search input:-webkit-input-placeholder { - color: #e6e5e1; - opacity: 1; - } - .mobile-menu-search input::-webkit-input-placeholder { - color: #e6e5e1; - opacity: 1; - } - .mobile-menu-search input:-ms-input-placeholder { - color: #e6e5e1; - opacity: 1; - } - .mobile-menu-search input::-ms-input-placeholder { - color: #e6e5e1; - opacity: 1; - } - .mobile-menu-site-title { - font-size: 21px !important; - } - .mobile-menu-buttons-container .btn { - display: inline-block !important; - font-size: 15px; - } - .mobile-menu-buttons-container .remote-console-trigger { - display: inline-block; - } - /* -----------[Admin sites overview]--------------*/ - body.diagnostics .breadcrumb .site-select, - body.site-overview .breadcrumb .site-select, - body.user-overview .breadcrumb .site-select { - display: inline-block; - } - /* -----------[Two factor login]--------------*/ - .two-step-login .mobile-menu { - display: none; - } - .user.update .container .form-tabs-container, - .user.two-step-update .container .form-tabs-container, - .user.update-dealer .container .form-tabs-container { - margin-bottom: 40px; - margin-left: 10px; - margin-right: 10px; - width: 300px; - } - .user.update .container .form-tabs-container .form-tabs, - .user.two-step-update .container .form-tabs-container .form-tabs, - .user.update-dealer .container .form-tabs-container .form-tabs { - margin-top: 14px; - } - .user.update .container .form-tabs-container .form-tabs li a, - .user.two-step-update .container .form-tabs-container .form-tabs li a, - .user.update-dealer .container .form-tabs-container .form-tabs li a { - padding-left: 20px; - text-align: left; - } - .user.update .container .form-tabs-container .btn, - .user.two-step-update .container .form-tabs-container .btn, - .user.update-dealer .container .form-tabs-container .btn { - width: 300px; - } - .user.update .container .form-tabs-container .btn.force-width, - .user.two-step-update .container .form-tabs-container .btn.force-width, - .user.update-dealer .container .form-tabs-container .btn.force-width { - width: 300px !important; - } - .user.update .container .form-tabs-container .mobile-title, - .user.two-step-update .container .form-tabs-container .mobile-title, - .user.update-dealer .container .form-tabs-container .mobile-title { - display: block; - margin-bottom: 0px; - margin-top: 50px; - } - .user.update .container .container-inner .four-columns-width, - .user.two-step-update .container .container-inner .four-columns-width, - .user.update-dealer .container .container-inner .four-columns-width { - width: 300px; - margin-left: 10px; - margin-right: 10px; - } - .remote-console-trigger { - float: none; - margin-left: 10px; - } -} -@media screen and (max-width: 959px) and print, screen and (max-width: 959px) and (-webkit-min-device-pixel-ratio: 1.25), screen and (max-width: 959px) and (-o-min-device-pixel-ratio: 3/2), screen and (max-width: 959px) and (min--moz-device-pixel-ratio: 1.25), screen and (max-width: 959px) and (-moz-min-device-pixel-ratio: 1.25), screen and (max-width: 959px) and (-ms-min-device-pixel-ratio: 1.25), screen and (max-width: 959px) and (min-device-pixel-ratio: 1.25), screen and (max-width: 959px) and (min-resolution: 120dpi), screen and (max-width: 959px) and (min-resolution: 1.25dppx) { - .mobile-menu .container-inner ul li.collapsable-parent .collapsable-parent-handle { - background-image: url("/img/VRM-sprite@2X.png?v=3"); - background-size: 621px 888px; - } -} -@media screen and (max-width: 795px) { - .remote-console-popup-container.logged-in { - width: 682px; - } - .remote-console-logged-in .remote-console-controls-title { - display: none; - } - .remote-console-title { - display: block; - } - .remote-console-display-container { - width: 100%; - } - .remote-console-display { - padding-right: 184px; - } - .remote-console-controls { - bottom: auto; - height: 230px; - top: 70px; - } - .remote-console-logged-in .remote-console-controls-container { - background-color: #faf9f5; - width: 181px; - } - .remote-console-logged-in .remote-console-controls-title, - .remote-console-logged-in .remote-console-controls-subtitle { - color: #4790d0; - } - .remote-console-logged-in .remote-console-controls-subtitle { - margin-top: 59px; - text-align: left; - } - .btn.remote-console-control-button { - background-color: #4790d0; - } - .btn.remote-console-control-button:hover { - background-color: #387dc5; - } - .btn.remote-console-control-button .remote-console-control-icon { - color: #faf9f5; - fill: #faf9f5; - } - .btn.remote-console-control-button .remote-console-control-icon path { - fill: #faf9f5; - } -} -@media screen and (max-width: 767px) { - .remote-console-popup-container { - border-radius: 0; - height: 100%; - left: 0; - margin: 0; - position: fixed; - top: 0; - width: 100%; - } - .remote-console-popup-container .mfp-close { - color: #4790d0; - } - .remote-console-popup-container.logged-in { - width: 100%; - } - .remote-console-popup-container.logged-in .mfp-close { - color: #4790d0; - } - .remote-console-display-inner { - width: 100%; - } - .remote-console-status { - height: 100%; - } -} -@media screen and (max-width: 570px) { - .remote-console-display-inner { - height: 200px !important; - } -} -.pull-right { - float: right; -} -.pull-left { - float: left; -} -.hide { - display: none; -} -.show { - display: block; -} -.invisible { - visibility: hidden; -} -.affix { - position: fixed; -} -#cssValues.colors.blue { - color: #4790d0; -} -#cssValues.colors.blueHover { - color: #387dc5; -} -#cssValues.colors.blueShadow { - color: #5b9bcd; -} -#cssValues.colors.orange { - color: #f7ab3e; -} -#cssValues.colors.orangeHover { - color: #f0962e; -} -#cssValues.colors.green { - color: #8bc964; -} -#cssValues.colors.greenHover { - color: #72b84c; -} -#cssValues.colors.greenShadow { - color: #98c478; -} -#cssValues.colors.lightGreen { - color: #afe18d; -} -#cssValues.colors.red { - color: #fa716f; -} -#cssValues.colors.redHover { - color: #f35c58; -} -#cssValues.colors.redShadow { - color: #e66e6e; -} -#cssValues.colors.black { - color: #272622; -} -#cssValues.colors.white { - color: #ffffff; -} -#cssValues.colors.darkGray { - color: #63625e; -} -#cssValues.colors.darkGrayShadow { - color: rgba(99, 98, 94, 0.1); -} -#cssValues.colors.darkGrayLines { - color: #4f4f4b; -} -#cssValues.colors.gray { - color: #959490; -} -#cssValues.colors.grayShadow { - color: #8e8d89; -} -#cssValues.colors.lightGrayLines { - color: #dcdbd7; -} -#cssValues.colors.lightGraySurfaces { - color: #e6e5e1; -} -#cssValues.colors.lightGrayBackground { - color: #f0efeb; -} -#cssValues.colors.lightGrayWidgetHeader { - color: #faf9f5; -} -#cssValues.colors.grayLines { - color: #e5e4e0; -} -#cssValues.sprites.url { - background-image: url("/img/VRM-sprite.png?v=3"); -} -#cssValues.sprites.url2X { - background-image: url("/img/VRM-sprite@2X.png?v=3"); -} -#cssValues.sprites.width { - width: 621px; -} -#cssValues.sprites.height { - height: 888px; -} -#cssValues.fonts.fontFamily { - font-family: 'MuseoSans-300', sans-serif; -} -/*# sourceMappingURL=1a83de5aa35b26837c2042d512c73c5a_md5_7b8754c004401cfe0be061108bf9f813.css.map * - -/**************************************************************************************************************************************** -Dark mode (start) -****************************************************************************************************************************************/ -@media (prefers-color-scheme: dark) { - body, - .remote-console-rotate-message-container { - /*background-color: #1b1b1b;*/ - background-color: #101010; - color: #e6e5e1; - } - .remote-console-display { - /*background-color: #303030;*/ - background-color: #202020; - } - .remote-console-popup-container { - /*background-color: #303030;*/ - background-color: #202020; - } - .remote-console-controls-container { - background-color: #234868; - } - - .remote-console-controls-title, - .remote-console-controls-subtitle, - .remote-console-logged-in .remote-console-controls-title, - .remote-console-logged-in .remote-console-controls-subtitle { - color: #f3f2ee; - } - - .btn.light, input.light, textarea.light { - /*background-color: #7d7c7a;*/ - background-color: #303030; - /*background-color: #202020;*/ - border: 1px solid #4b4b4b; - } - .btn.light:hover, input.light:hover, textarea.light:hover { - /*background-color: #9d9d9d;*/ - background-color: #565656; - border: 1px solid #727272; - } - .remote-console-control-button .remote-console-control-icon { - color: #cfe9ff; - fill: #cfe9ff; - } - .remote-console-control-button .remote-console-control-icon path { - fill: #cfe9ff; - } - .remote-console-display-inner { - border: 1px solid #4b4b4b; - } - - @media screen and (max-width: 795px) { - .remote-console-logged-in .remote-console-controls-container { - background-color: #234868; - } - - .remote-console-controls-title, - .remote-console-controls-subtitle, - .remote-console-logged-in .remote-console-controls-title, - .remote-console-logged-in .remote-console-controls-subtitle { - color: #f3f2ee; - } - } - -} -/**************************************************************************************************************************************** -Dark mode (end) -****************************************************************************************************************************************/ diff --git a/FileSets/v3.40~10/styles.css b/FileSets/v3.40~10/styles.css new file mode 120000 index 00000000..2a980b7d --- /dev/null +++ b/FileSets/v3.40~10/styles.css @@ -0,0 +1 @@ +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v3.40~11/Battery.qml b/FileSets/v3.40~11/Battery.qml new file mode 100644 index 00000000..9e4fd95c --- /dev/null +++ b/FileSets/v3.40~11/Battery.qml @@ -0,0 +1,176 @@ +import QtQuick 1.1 + +Item { + id: root + + width: 145 + height: 101 + + property real soc: 80 +////// GuiMods — DarkMode + property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } + property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 + property string color: !darkMode ? "#4789d0" : "#234468" + property string emptyColor: !darkMode ? "#1abc9c" : "#0d5e4e" + + property alias values: _values.children + property bool renewablePreferred: sys.preferRenewableEnergy.valid + property bool renewableOverride: renewablePreferred + && (sys.preferRenewableEnergy.value === 0 || sys.preferRenewableEnergy.value === 2 || sys.acSource == 2) + + //// dummies for backward compatiblity - not actually used - values grabbed from sys. directly + property bool preferRenewable: false + property bool preferRenewableOverride: false + property bool preferRenewableOverrideGenset: false + + + SvgRectangle { + id: leftTerminal + width: 12 + height: 8 + radius: 3 + color: soc < 100 ? emptyColor : root.color + anchors { + left: root.left; leftMargin: 12 + } + x: 12 + } + + SvgRectangle { + id: rightTerminal + width: 12 + height: 8 + radius: 3 + color: soc < 100 ? emptyColor : root.color + anchors { + right: root.right; rightMargin: 12 + } + } + + Rectangle { + id: background + + // NOTE: to remove the bottom of the terminals +////// GuiMods — DarkMode + border {width: 2; color: !darkMode ? "white" : "#202020"} + height: root.height - leftTerminal.height + width: root.width + y: leftTerminal.height - 1 + + SvgRectangle { + height: parent.height + width: parent.width + color: root.emptyColor + radius: 3 + } + + SvgRectangle { + id: filledPart + width: root.width + height: soc * background.height / 100 + color: root.color + anchors.bottom: parent.bottom + radius: 3 + } + + SvgRectangle { + height: parent.height + width: parent.width * 0.7 + anchors.centerIn: parent +////// GuiMods — DarkMode + color: !darkMode ? "#ffffff" : "#202020" + opacity: 0.06 + } + } + + MbIcon { + iconId: getBatteryLogo() + anchors { + right: parent.right; rightMargin: 4 + bottom: parent.bottom; bottomMargin: 4 + } + + function getBatteryLogo() + { + var pid = sys.batteryProductId.value + var logo = "" + + if (pid === 0xB014) + logo = "overview-battery-freedomwon" + + return logo + } + } + + Rectangle { + height: 30 + width: 25 + visible: renewablePreferred + color: renewableOverride ? "#b84b00" : "transparent" + clip: true + anchors { + top: background.top + topMargin: 13 + } + + MbIcon { + iconId: "double-arrow-up" + visible: renewableOverride + anchors { + verticalCenter: parent.verticalCenter + horizontalCenter: parent.horizontalCenter + } + } + MbIcon { + iconId: + { + if (renewableOverride) + { + if (sys.acSource == 2) + return "overview-generator-background" + else + return "overview-tower-background" + } + else if (darkMode) + return "overview-renewable-light" + else + return "overview-renewable" + } + height: parent.height * 0.9 + width: parent.width * 0.8 + fillMode: Image.PreserveAspectFit + anchors { + horizontalCenter: parent.horizontalCenter + verticalCenter: parent.verticalCenter + } + } + } + + Text { + text: "-" + font.pixelSize: 13; font.bold: true + anchors.centerIn: leftTerminal + anchors.verticalCenterOffset: 12 +////// GuiMods — DarkMode + color: !darkMode ? "#fff" : "#e1e1e1" + } + + Text { + text: "+" + font.pixelSize: 13; font.bold: true + anchors.centerIn: rightTerminal + anchors.verticalCenterOffset: 12 +////// GuiMods — DarkMode + color: !darkMode ? "#fff" : "#e1e1e1" + } + + Item { + id: _values + anchors { + top: background.top; + bottom: root.bottom + left: root.left + right: root.right + } + } +} diff --git a/FileSets/v3.40~10/Battery.qml.orig b/FileSets/v3.40~11/Battery.qml.orig similarity index 100% rename from FileSets/v3.40~10/Battery.qml.orig rename to FileSets/v3.40~11/Battery.qml.orig diff --git a/FileSets/v3.40~11/COMPLETE b/FileSets/v3.40~11/COMPLETE new file mode 100644 index 00000000..e69de29b diff --git a/FileSets/v3.40~11/DetailAcInput.qml b/FileSets/v3.40~11/DetailAcInput.qml new file mode 100644 index 00000000..d2865e4a --- /dev/null +++ b/FileSets/v3.40~11/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~10/DetailAcInput.qml.orig b/FileSets/v3.40~11/DetailAcInput.qml.orig similarity index 100% rename from FileSets/v3.40~10/DetailAcInput.qml.orig rename to FileSets/v3.40~11/DetailAcInput.qml.orig diff --git a/FileSets/v3.40~11/DetailInverter.qml b/FileSets/v3.40~11/DetailInverter.qml new file mode 100644 index 00000000..fd7e9def --- /dev/null +++ b/FileSets/v3.40~11/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~10/DetailInverter.qml.orig b/FileSets/v3.40~11/DetailInverter.qml.orig similarity index 100% rename from FileSets/v3.40~10/DetailInverter.qml.orig rename to FileSets/v3.40~11/DetailInverter.qml.orig diff --git a/FileSets/v3.40~11/DetailLoadsCombined.qml b/FileSets/v3.40~11/DetailLoadsCombined.qml new file mode 100644 index 00000000..5909cb10 --- /dev/null +++ b/FileSets/v3.40~11/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~10/DetailLoadsCombined.qml.orig b/FileSets/v3.40~11/DetailLoadsCombined.qml.orig similarity index 100% rename from FileSets/v3.40~10/DetailLoadsCombined.qml.orig rename to FileSets/v3.40~11/DetailLoadsCombined.qml.orig diff --git a/FileSets/v3.40~11/DetailLoadsOnInput.qml b/FileSets/v3.40~11/DetailLoadsOnInput.qml new file mode 100644 index 00000000..999a62ac --- /dev/null +++ b/FileSets/v3.40~11/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~10/DetailLoadsOnInput.qml.orig b/FileSets/v3.40~11/DetailLoadsOnInput.qml.orig similarity index 100% rename from FileSets/v3.40~10/DetailLoadsOnInput.qml.orig rename to FileSets/v3.40~11/DetailLoadsOnInput.qml.orig diff --git a/FileSets/v3.40~11/DetailLoadsOnOutput.qml b/FileSets/v3.40~11/DetailLoadsOnOutput.qml new file mode 100644 index 00000000..2092989c --- /dev/null +++ b/FileSets/v3.40~11/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~10/DetailLoadsOnOutput.qml.orig b/FileSets/v3.40~11/DetailLoadsOnOutput.qml.orig similarity index 100% rename from FileSets/v3.40~10/DetailLoadsOnOutput.qml.orig rename to FileSets/v3.40~11/DetailLoadsOnOutput.qml.orig diff --git a/FileSets/v3.40~11/HubData.qml b/FileSets/v3.40~11/HubData.qml new file mode 100644 index 00000000..abe96728 --- /dev/null +++ b/FileSets/v3.40~11/HubData.qml @@ -0,0 +1,262 @@ +//////// 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~10/HubData.qml.orig b/FileSets/v3.40~11/HubData.qml.orig similarity index 100% rename from FileSets/v3.40~10/HubData.qml.orig rename to FileSets/v3.40~11/HubData.qml.orig diff --git a/FileSets/v3.40~11/MbEditBox.qml b/FileSets/v3.40~11/MbEditBox.qml new file mode 100644 index 00000000..50c85742 --- /dev/null +++ b/FileSets/v3.40~11/MbEditBox.qml @@ -0,0 +1,414 @@ +import QtQuick 1.1 +import Qt.labs.components.native 1.0 +import com.victron.velib 1.0 + +MbItem { + id: root + cornerMark: !readonly && !editMode + height: expanded.y + expanded.height + 1 + +////// GuiMods — DarkMode + property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } + property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 + + property alias maximumLength: ti.maximumLength + property variant tmpValue + property string matchString: "0123456789 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~!@#$%^&*()-_=+[]{}\\;:|/.,<>?" + property string ignoreChars + property bool readonly: !userHasWriteAccess + property bool overwriteMode: false + property VBusItem item: VBusItem { text: valueToText(value) } + property string invalidText: "" + property string description + property bool enableSpaceBar: false + property bool useVirtualKeyboard + property alias numericOnlyLayout: virtualKeyboard.numericOnlyLayout + property alias textInput: ti + property alias leftRightText: buttonExplanation.leftRightText + property alias upDownText: buttonExplanation.upDownText + property alias centerText: buttonExplanation.centerText + property alias unit: _unitText.text + + // internal + property string _editText + + signal editDone(string newValue) + + NumberAnimation { + id: blink + target: textInput + property: "opacity" + from: textInput.opacity + to: !textInput.opacity + loops: 5 + duration: 350 + onCompleted: textInput.opacity = 1 + } + + function restoreOriginalText() { + item.setValue(tmpValue) + } + + function valueToText(value) { + return (value === undefined ? invalidText : value) + } + + function editTextToValue() { + return _editText.trim() + } + + function getEditText(value) { + return item.text + } + + function validate(newText, pos) { + return newText + } + + function save() { + var newValue = editTextToValue() + if (newValue === null) { + blink.running = true + } else { + editMode = false + root.focus = true + item.setValue(newValue) + root.editDone(newValue) + } + } + + function cancel() { + if (editMode) { + editMode = false + root.focus = true + item.setValue(tmpValue) + } + } + + function edit(isMouse) { + if (!readonly && !editMode) { + useVirtualKeyboard = isMouse === true + ti.focus = true + _editText = getEditText() + tmpValue = item.value + editMode = true + ti.cursorPosition = 0; + } + } + + function isEditablePosition(pos) + { + if (pos === undefined) + pos = textInput.cursorPosition + + return pos >= 0 && pos < textInput.text.length && ignoreChars.indexOf(textInput.text[pos]) < 0 + } + + function setValueAtPosition(position, value, insert, moveCursor) { + if (insert) { + if (_editText.length >= maximumLength) + return + } else { + if (!isEditablePosition(position)) + return + } + + // check for supported characters + if (matchString.indexOf(value) < 0) + return + + var newText = setValueAt(_editText, position, value, insert); + newText = validate(newText, position) + if (newText === null) + return + + // assign new text, and place the cursor at the right position + _editText = newText; + setCursorPosition(position, moveCursor) + } + + function setCursorPosition(position, direction) { + if (direction) + position += direction + + while (position >= 0 && position < textInput.text.length) { + if (!direction || ignoreChars.indexOf(textInput.text[position]) < 0) { + textInput.cursorPosition = position + return + } + position += direction + } + if (!overwriteMode && position === textInput.text.length) + textInput.cursorPosition = position + } + + function wrapAround(pos) { + return matchString.length + } + + function cursorUpOrDown(direction) { + if (!overwriteMode && textInput.cursorPosition === _editText.length && _editText.length < maximumLength) + _editText += " " + + if (!isEditablePosition()) + return + + var chr = _editText.charAt(textInput.cursorPosition) + var wrap = wrapAround(textInput.cursorPosition) + var index = (matchString.indexOf(chr) + wrap + direction) % wrap; + setValueAtPosition(textInput.cursorPosition, matchString[index]) + } + + function cursorLeftOrRight(direction) { + // add and eat spaces at the beginning and end when not in overwriteMode + if (!overwriteMode) { + if (textInput.cursorPosition === 0) { + if (direction === -1 && _editText.length < maximumLength) { + setValueAtPosition(0, " ", true) + return + } + if (direction === 1 && _editText.charAt(0) === " ") { + setValueAtPosition(textInput.cursorPosition, "") + return + } + } + + if (textInput.cursorPosition === _editText.length) { + if (direction === -1 && _editText.charAt(textInput.cursorPosition - 1) === " ") { + setValueAtPosition(textInput.cursorPosition - 1, "") + return + } + if (direction === 1 && _editText.length < maximumLength) { + setValueAtPosition(textInput.cursorPosition, " ", true, 1) + return + } + } + } + + setCursorPosition(textInput.cursorPosition, direction) + } + + function keyPressed(event) { + event.accepted = true + + switch (event.key) { + case Qt.Key_Backspace: + if (overwriteMode || overwriteMode) + cursorLeftOrRight(-1) + else + setValueAtPosition(textInput.cursorPosition - 1, '') + return + + case Qt.Key_Delete: + if (overwriteMode || overwriteMode) + return + setValueAtPosition(textInput.cursorPosition, '') + return + + default: + if (event.text === "") + return + } + + setValueAtPosition(textInput.cursorPosition, event.text, !overwriteMode, 1) + } + + // javascript lacks a char replace for strings, spell it out + function setValueAt(str, index, character, insert) { + return str.substr(0, index) + character + str.substr(index + (insert === true ? 0 : 1)); + } + + MbTextDescription { + id: name + height: defaultHeight + + anchors { + left: parent.left; + leftMargin: style.marginDefault + top: parent.top + } + verticalAlignment: Text.AlignVCenter + text: root.description + isCurrentItem: root.ListView.isCurrentItem || editMode + } + + Item { + id: inputItem + + property real cursorWidth: 8.0 + height: defaultHeight + anchors { + right: parent.right + top: parent.top + } + + MbBackgroundRect { + id: greytag +////// GuiMods — DarkMode + color: !darkMode ? (editMode ? "#fff": "#ddd") : (editMode ? "#747474": "#4b4b4b") + width: ti.width + 2 * style.marginDefault + height: ti.height + 6 +////// GuiMods — DarkMode + border.color: !darkMode ? "#ddd" : "#4b4b4b" + border.width: editMode ? 1 : 0 + anchors.centerIn: ti + } + + // Optional unit at the right. It will remain gray, also in edit mode + MbBackgroundRect { + id: rightSide + anchors.right: parent.right; anchors.rightMargin: style.marginDefault + anchors.verticalCenter: ti.verticalCenter + width: (_unitText.width ? _unitText.width + style.marginDefault : 0) + height: greytag.height + + Text { + id: _unitText + font.pixelSize: root.style.fontPixelSize + anchors.verticalCenter: parent.verticalCenter + } + } + + Text { + id: ti + anchors{ + right: rightSide.left + // If there is a unit, make the two round boxes overlap.. + rightMargin: _unitText.width ? 0 : root.style.marginDefault + top: parent.top + topMargin: (defaultHeight - height) / 2 + } + +////// GuiMods — DarkMode + color: !darkMode ? "#000000" : "#fdfdfd" + + text: editMode ? _editText : item.text + // When editing the it is nice to have a fix with font, so when changing + // digits the text does change in length all the time. However this fonts + // has an zero with a dot in it, with looks inconsitent with the regular + // font. So only use the fixed with font when editing. + font.family: editMode ? "DejaVu Sans Mono" : root.style.fontFamily + font.pixelSize: root.style.fontPixelSize + + property int maximumLength: 20 + property int cursorPosition + + Item { + id: cursorItem + + anchors { + left: ti.left + // The vePlatform.measureText can be off by one, which normally doesn't matter but causes + // a wobbling cursor when at the end. So ti.paintedWidth when at the end instead. + leftMargin: ( + ti.cursorPosition === _editText.length ? + ti.paintedWidth : + vePlatform.measureText(ti.font.family, ti.font.pixelSize, ti.text, 0, ti.cursorPosition) + ) + top: ti.top + bottom: ti.bottom + } + width: (ti.cursorPosition < ti.text.length ? + vePlatform.measureText(ti.font.family, ti.font.pixelSize, ti.text, ti.cursorPosition, 1) : + 6) + + Rectangle { + anchors.top: cursorItem.top + anchors.topMargin: -1 + width: cursorItem.width + height: parent.parent.focus ? 2 : 0 + border.color: "black" + border.width: 2 + } + + Rectangle { + anchors.bottom: cursorItem.bottom + anchors.bottomMargin: -2 + width: cursorItem.width + height: parent.parent.focus ? 2 : 0 + border.color: "black" + border.width: 2 + } + } + + Keys.onPressed: keyPressed(event) + + Keys.onSpacePressed: { + if (root.enableSpaceBar || root.useVirtualKeyboard) { + event.accepted = false; + return + } + + save() + } + + Keys.onReturnPressed: save() + Keys.onEscapePressed: cancel() + Keys.onUpPressed: cursorUpOrDown(1) + Keys.onDownPressed: cursorUpOrDown(-1) + Keys.onRightPressed: cursorLeftOrRight(1) + Keys.onLeftPressed: cursorLeftOrRight(-1) + } + + MouseArea { + anchors { + left: ti.left + right: inputItem.right + top: ti.top + bottom: ti.bottom + } + + onPressed: { + if (editMode) { + var n = vePlatform.hitTestText(ti.font.family, ti.font.pixelSize, ti.text, mouseX) + // The position after the last one can be selected so backspace works. + // Since it is not a editable position, check this first. + if (!overwriteMode && n === textInput.text.length) { + ti.cursorPosition = n + return + } + // Don't select the other uneditable positions + if (!isEditablePosition(n)) + return + ti.cursorPosition = n + } else { + handleMouseClick(); + } + } + } + } + + Item { + id: expanded + height: childrenRect.height + anchors.top: inputItem.bottom + anchors.topMargin: -1 + + Keyboard { + id: virtualKeyboard + + overwriteMode: root.overwriteMode + width: root.width + active: editMode && root.useVirtualKeyboard + onAnimatingChanged: { + if (!animating) + listview.positionViewAtIndex(currentIndex, ListView.Contain) + } + } + + MbButtonExplanation { + id: buttonExplanation + + width: root.width + shown: editMode && !root.useVirtualKeyboard + leftRightText: qsTr("Select position") + upDownText: qsTr("Select character") + centerText: enableSpaceBar ? qsTr("Add space") : qsTr("Apply changes") + + onAnimatingChanged: { + if (!animating) + listview.positionViewAtIndex(currentIndex, ListView.Contain) + } + } + } +} diff --git a/FileSets/v3.40~11/MbEditBox.qml.orig b/FileSets/v3.40~11/MbEditBox.qml.orig new file mode 100644 index 00000000..5c2f6d14 --- /dev/null +++ b/FileSets/v3.40~11/MbEditBox.qml.orig @@ -0,0 +1,405 @@ +import QtQuick 1.1 +import Qt.labs.components.native 1.0 +import com.victron.velib 1.0 + +MbItem { + id: root + cornerMark: !readonly && !editMode + height: expanded.y + expanded.height + 1 + + property alias maximumLength: ti.maximumLength + property variant tmpValue + property string matchString: "0123456789 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~!@#$%^&*()-_=+[]{}\\;:|/.,<>?" + property string ignoreChars + property bool readonly: !userHasWriteAccess + property bool overwriteMode: false + property VBusItem item: VBusItem { text: valueToText(value) } + property string invalidText: "" + property string description + property bool enableSpaceBar: false + property bool useVirtualKeyboard + property alias numericOnlyLayout: virtualKeyboard.numericOnlyLayout + property alias textInput: ti + property alias leftRightText: buttonExplanation.leftRightText + property alias upDownText: buttonExplanation.upDownText + property alias centerText: buttonExplanation.centerText + property alias unit: _unitText.text + + // internal + property string _editText + + signal editDone(string newValue) + + NumberAnimation { + id: blink + target: textInput + property: "opacity" + from: textInput.opacity + to: !textInput.opacity + loops: 5 + duration: 350 + onCompleted: textInput.opacity = 1 + } + + function restoreOriginalText() { + item.setValue(tmpValue) + } + + function valueToText(value) { + return (value === undefined ? invalidText : value) + } + + function editTextToValue() { + return _editText.trim() + } + + function getEditText(value) { + return item.text + } + + function validate(newText, pos) { + return newText + } + + function save() { + var newValue = editTextToValue() + if (newValue === null) { + blink.running = true + } else { + editMode = false + root.focus = true + item.setValue(newValue) + root.editDone(newValue) + } + } + + function cancel() { + if (editMode) { + editMode = false + root.focus = true + item.setValue(tmpValue) + } + } + + function edit(isMouse) { + if (!readonly && !editMode) { + useVirtualKeyboard = isMouse === true + ti.focus = true + _editText = getEditText() + tmpValue = item.value + editMode = true + ti.cursorPosition = 0; + } + } + + function isEditablePosition(pos) + { + if (pos === undefined) + pos = textInput.cursorPosition + + return pos >= 0 && pos < textInput.text.length && ignoreChars.indexOf(textInput.text[pos]) < 0 + } + + function setValueAtPosition(position, value, insert, moveCursor) { + if (insert) { + if (_editText.length >= maximumLength) + return + } else { + if (!isEditablePosition(position)) + return + } + + // check for supported characters + if (matchString.indexOf(value) < 0) + return + + var newText = setValueAt(_editText, position, value, insert); + newText = validate(newText, position) + if (newText === null) + return + + // assign new text, and place the cursor at the right position + _editText = newText; + setCursorPosition(position, moveCursor) + } + + function setCursorPosition(position, direction) { + if (direction) + position += direction + + while (position >= 0 && position < textInput.text.length) { + if (!direction || ignoreChars.indexOf(textInput.text[position]) < 0) { + textInput.cursorPosition = position + return + } + position += direction + } + if (!overwriteMode && position === textInput.text.length) + textInput.cursorPosition = position + } + + function wrapAround(pos) { + return matchString.length + } + + function cursorUpOrDown(direction) { + if (!overwriteMode && textInput.cursorPosition === _editText.length && _editText.length < maximumLength) + _editText += " " + + if (!isEditablePosition()) + return + + var chr = _editText.charAt(textInput.cursorPosition) + var wrap = wrapAround(textInput.cursorPosition) + var index = (matchString.indexOf(chr) + wrap + direction) % wrap; + setValueAtPosition(textInput.cursorPosition, matchString[index]) + } + + function cursorLeftOrRight(direction) { + // add and eat spaces at the beginning and end when not in overwriteMode + if (!overwriteMode) { + if (textInput.cursorPosition === 0) { + if (direction === -1 && _editText.length < maximumLength) { + setValueAtPosition(0, " ", true) + return + } + if (direction === 1 && _editText.charAt(0) === " ") { + setValueAtPosition(textInput.cursorPosition, "") + return + } + } + + if (textInput.cursorPosition === _editText.length) { + if (direction === -1 && _editText.charAt(textInput.cursorPosition - 1) === " ") { + setValueAtPosition(textInput.cursorPosition - 1, "") + return + } + if (direction === 1 && _editText.length < maximumLength) { + setValueAtPosition(textInput.cursorPosition, " ", true, 1) + return + } + } + } + + setCursorPosition(textInput.cursorPosition, direction) + } + + function keyPressed(event) { + event.accepted = true + + switch (event.key) { + case Qt.Key_Backspace: + if (overwriteMode || overwriteMode) + cursorLeftOrRight(-1) + else + setValueAtPosition(textInput.cursorPosition - 1, '') + return + + case Qt.Key_Delete: + if (overwriteMode || overwriteMode) + return + setValueAtPosition(textInput.cursorPosition, '') + return + + default: + if (event.text === "") + return + } + + setValueAtPosition(textInput.cursorPosition, event.text, !overwriteMode, 1) + } + + // javascript lacks a char replace for strings, spell it out + function setValueAt(str, index, character, insert) { + return str.substr(0, index) + character + str.substr(index + (insert === true ? 0 : 1)); + } + + MbTextDescription { + id: name + height: defaultHeight + + anchors { + left: parent.left; + leftMargin: style.marginDefault + top: parent.top + } + verticalAlignment: Text.AlignVCenter + text: root.description + isCurrentItem: root.ListView.isCurrentItem || editMode + } + + Item { + id: inputItem + + property real cursorWidth: 8.0 + height: defaultHeight + anchors { + right: parent.right + top: parent.top + } + + MbBackgroundRect { + id: greytag + color: editMode ? "#fff": "#ddd" + width: ti.width + 2 * style.marginDefault + height: ti.height + 6 + border.color: "#ddd" + border.width: editMode ? 1 : 0 + anchors.centerIn: ti + } + + // Optional unit at the right. It will remain gray, also in edit mode + MbBackgroundRect { + id: rightSide + anchors.right: parent.right; anchors.rightMargin: style.marginDefault + anchors.verticalCenter: ti.verticalCenter + width: (_unitText.width ? _unitText.width + style.marginDefault : 0) + height: greytag.height + + Text { + id: _unitText + font.pixelSize: root.style.fontPixelSize + anchors.verticalCenter: parent.verticalCenter + } + } + + Text { + id: ti + anchors{ + right: rightSide.left + // If there is a unit, make the two round boxes overlap.. + rightMargin: _unitText.width ? 0 : root.style.marginDefault + top: parent.top + topMargin: (defaultHeight - height) / 2 + } + + text: editMode ? _editText : item.text + // When editing the it is nice to have a fix with font, so when changing + // digits the text does change in length all the time. However this fonts + // has an zero with a dot in it, with looks inconsitent with the regular + // font. So only use the fixed with font when editing. + font.family: editMode ? "DejaVu Sans Mono" : root.style.fontFamily + font.pixelSize: root.style.fontPixelSize + + property int maximumLength: 20 + property int cursorPosition + + Item { + id: cursorItem + + anchors { + left: ti.left + // The vePlatform.measureText can be off by one, which normally doesn't matter but causes + // a wobbling cursor when at the end. So ti.paintedWidth when at the end instead. + leftMargin: ( + ti.cursorPosition === _editText.length ? + ti.paintedWidth : + vePlatform.measureText(ti.font.family, ti.font.pixelSize, ti.text, 0, ti.cursorPosition) + ) + top: ti.top + bottom: ti.bottom + } + width: (ti.cursorPosition < ti.text.length ? + vePlatform.measureText(ti.font.family, ti.font.pixelSize, ti.text, ti.cursorPosition, 1) : + 6) + + Rectangle { + anchors.top: cursorItem.top + anchors.topMargin: -1 + width: cursorItem.width + height: parent.parent.focus ? 2 : 0 + border.color: "black" + border.width: 2 + } + + Rectangle { + anchors.bottom: cursorItem.bottom + anchors.bottomMargin: -2 + width: cursorItem.width + height: parent.parent.focus ? 2 : 0 + border.color: "black" + border.width: 2 + } + } + + Keys.onPressed: keyPressed(event) + + Keys.onSpacePressed: { + if (root.enableSpaceBar || root.useVirtualKeyboard) { + event.accepted = false; + return + } + + save() + } + + Keys.onReturnPressed: save() + Keys.onEscapePressed: cancel() + Keys.onUpPressed: cursorUpOrDown(1) + Keys.onDownPressed: cursorUpOrDown(-1) + Keys.onRightPressed: cursorLeftOrRight(1) + Keys.onLeftPressed: cursorLeftOrRight(-1) + } + + MouseArea { + anchors { + left: ti.left + right: inputItem.right + top: ti.top + bottom: ti.bottom + } + + onPressed: { + if (editMode) { + var n = vePlatform.hitTestText(ti.font.family, ti.font.pixelSize, ti.text, mouseX) + // The position after the last one can be selected so backspace works. + // Since it is not a editable position, check this first. + if (!overwriteMode && n === textInput.text.length) { + ti.cursorPosition = n + return + } + // Don't select the other uneditable positions + if (!isEditablePosition(n)) + return + ti.cursorPosition = n + } else { + handleMouseClick(); + } + } + } + } + + Item { + id: expanded + height: childrenRect.height + anchors.top: inputItem.bottom + anchors.topMargin: -1 + + Keyboard { + id: virtualKeyboard + + overwriteMode: root.overwriteMode + width: root.width + active: editMode && root.useVirtualKeyboard + onAnimatingChanged: { + if (!animating) + listview.positionViewAtIndex(currentIndex, ListView.Contain) + } + } + + MbButtonExplanation { + id: buttonExplanation + + width: root.width + shown: editMode && !root.useVirtualKeyboard + leftRightText: qsTr("Select position") + upDownText: qsTr("Select character") + centerText: enableSpaceBar ? qsTr("Add space") : qsTr("Apply changes") + + onAnimatingChanged: { + if (!animating) + listview.positionViewAtIndex(currentIndex, ListView.Contain) + } + } + } +} diff --git a/FileSets/v3.40~11/MbEditBoxDateTime.qml b/FileSets/v3.40~11/MbEditBoxDateTime.qml new file mode 100644 index 00000000..12b9ed3a --- /dev/null +++ b/FileSets/v3.40~11/MbEditBoxDateTime.qml @@ -0,0 +1,96 @@ +import QtQuick 1.1 + +MbEditBox { + id: root + +////// GuiMods — DarkMode + property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } + property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 + + property string format: "yyyy-MM-dd hh:mm" + property bool utc: false + + ignoreChars: "-: " + matchString: "0123456789" + maximumLength: format.length + overwriteMode: true + numericOnlyLayout: true + upDownText: qsTr("Select number") +////// GuiMods — DarkMode + textInput.color: editMode ? (vePlatform.secondsFromString(_editText, format) !== -1 ? (!darkMode ? "#000000" : "#fdfdfd") : "red") : (!darkMode ? "#000000" : "#fdfdfd") + + // note: overwritten by MbEditBoxTime! + function getTimeSeconds(str) { + return vePlatform.secondsFromString(str, format) + } + + function editTextToValue() { + var value = getTimeSeconds(_editText) + return (value === -1 ? null : value) + } + + function valueToText(value) { + if (utc) + return vePlatform.formatDateTimeUtc(value, format) + return Qt.formatDateTime(new Date(value * 1000), format) + } + + // make sure the time of days keeps below 24:00 + function validateHours(str, pos) { + if (format[pos] === 'h' && format[pos + 1] === 'h' && str[pos] === '2' && str[pos + 1] > 3) + str = setValueAt(str, pos + 1, '3', false); + return str; + } + + function validate(newText, pos) { + var wrap = wrapAround(pos) + + if ((newText[pos] - '0') >= wrap) { + var text = qsTr("Only numbers up to %1 are valid on this location").arg(wrap - 1) + toast.createToast(text, 3000) + return null + } + + // respect the minimum value. Note: instead of declining the change the minimum value + // is forced. The reason for that is that if e.g. 00:10 is decremented with a minimum + // of one minute it becomes 00:01 instead of silently refusing the change. + var ret = validateHours(newText, pos) + if (item.min && getTimeSeconds(ret) < item.min) + return valueToText(item.min) + + return ret + } + + // some digit in e.g. time/data loop earlier than 0..9 + function wrapAround(pos) { + switch (format[pos]) { + // mm goes till 59 + case 'm': + if (format[pos + 1] === 'm') + return 6; + break + // hours till 23 + case 'h': + if (format[pos + 1] === 'h') + return 3; + if (format[pos - 1] === 'h') + return _editText[pos - 1] === '2' ? 4 : matchString.length + break + // days up to 31 + case 'd': + if (format[pos + 1] === 'd') + return 4; + if (format[pos - 1] === 'd') + return _editText[pos - 1] === '3' ? 2 : matchString.length; + break; + // months till 12 + case 'M': + if (format[pos + 1] === 'M') + return 2; + if (format[pos - 1] === 'M') + return _editText[pos - 1] === '1' ? 3 : matchString.length + break + } + return matchString.length + } +} diff --git a/FileSets/v3.40~10/MbEditBoxDateTime.qml.orig b/FileSets/v3.40~11/MbEditBoxDateTime.qml.orig similarity index 100% rename from FileSets/v3.40~10/MbEditBoxDateTime.qml.orig rename to FileSets/v3.40~11/MbEditBoxDateTime.qml.orig diff --git a/FileSets/v3.40~11/MbItem.qml b/FileSets/v3.40~11/MbItem.qml new file mode 100644 index 00000000..fb849144 --- /dev/null +++ b/FileSets/v3.40~11/MbItem.qml @@ -0,0 +1,193 @@ +import QtQuick 1.1 +import com.victron.velib 1.0 +import "utils.js" as Utils + +/* + * The MbItem serves as a base object for Items which can be placed in + * the menubrowser (Mb), see MbPage. It adds default functions for key + * behavior, icons, subpage navigtation and only shows a default + * background. Any derived mb Item can fill it to its desire. + */ +Item { + id: root + width: (parent ? parent.width : 0) + height: defaultHeight + property bool show: user.accessLevel >= showAccessLevel + +////// GuiMods — DarkMode + property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } + property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 + + property int defaultHeight: style.itemHeight + + property bool editMode + property variant toolbarHandler: editMode ? editToolbarHandler : navToolBar + property alias navigationHandler: navToolBar + + property bool isCurrentItem: root.ListView.isCurrentItem + property MbStyle style: MbStyle { isCurrentItem: root.ListView.isCurrentItem } + + // Navigation for subpages + property bool hasSubpage: subpage !== undefined + property variant subpage + property variant _subpageInstance + + property bool cornerMark: false + + property int showAccessLevel: User.AccessUser + property int writeAccessLevel: User.AccessInstaller + property bool userHasWriteAccess: user.accessLevel >= writeAccessLevel + property bool editable: true + property alias backgroundColor: background.color + + // NOTE: this is added to our 4.8 qt version. Uncomment this line to run on a + // vanilla QT. But optional rows are then always visible. + //property bool show + + signal selected + signal clicked + + ToolbarHandler { + id: editToolbarHandler + + leftIcon: "icon-toolbar-cancel" + rightIcon: "icon-toolbar-ok" + + function leftAction() + { + cancel() + } + + function rightAction() + { + save() + } + } + + ToolbarHandlerMbItems { + id: navToolBar + isDefault: true + } + + function open() { + if (pageStack.currentPage.active && hasSubpage) + _subpageInstance = pageStack.push(subpage); + } + + function edit(isMouse) { + } + + function cancel() { + } + + function save() { + } + + function select() { + if (!pageStack) + return + + // Note: Getting the index from the model depends on the model type. + // So lets asked the listview for our index instead. + var n = pageStack.currentPage.listview.indexAt(root.x, root.y) + if (n < 0) + return + pageStack.currentPage.currentIndex = n + + if (!userHasWriteAccess && !hasSubpage && editable) + toast.createToast(qsTr("Setting locked for \"user\" access level."), 3000, "icon-lock-active"); + root.selected() + } + + Rectangle { + id: background + anchors.fill: parent + color: showAccessLevel >= User.AccessSuperUser ? style.backgroundColorService : style.backgroundColor + } + + MbIcon { + id: cornerMarkIcon + +////// GuiMods — DarkMode + iconId: "icon-items-corner" + (root.ListView.isCurrentItem || darkMode ? "-active" : "") + visible: cornerMark + anchors { + right: parent.right; rightMargin: 1 + bottom: bottomBorder.top; bottomMargin: 1 + } + } + + Rectangle { + id: bottomBorder + width: root.width + height: 1 + color: style.borderColor + anchors.bottom: root.bottom + } + + onIsCurrentItemChanged: { + if (editMode) + cancel() + } + + Keys.onRightPressed: { + if (userHasWriteAccess) + root.clicked() + if (!userHasWriteAccess && !hasSubpage) + toast.createToast(qsTr("Setting locked due to access level."), 3000, "icon-lock-active"); + else + open() + } + + function defaultCenterAction() + { + if (userHasWriteAccess) + root.clicked() + if (!userHasWriteAccess && !hasSubpage && editable) { + toast.createToast(qsTr("Setting locked due to access level."), 3000, "icon-lock-active"); + } else { + if (pageStack.currentPage.active && hasSubpage) + open() + else + edit() + } + } + + function handleMouseClick(onItem) { + if (hasSubpage && !onItem && editable) { + // When clicking again an on item with a value and a submenu which is in edit mode, + // since the value was pressed, then leave edit mode first instead of opening the + // page while leaving the item in an edit state. + if (editMode) { + cancel() + } else { + select() + open() + } + } else { + if (!root.ListView.isCurrentItem) { + select() + } else { + root.clicked() + edit(true) + } + } + } + + // If a submenu is opened with a dynamic model, the items can be destructed + // while a subpage is in the pagestack. Since navigation will then get stuck, + // do navigate out of the submenu in such a case. + Component.onDestruction: { + if (pageStack && _subpageInstance) { + if (pageStack.find(function(page) { return page === _subpageInstance; } ) !== null) { + pageStack.pop(_subpageInstance) + } + } + } + + MouseArea { + id: mouseArea + anchors.fill: parent + onClicked: handleMouseClick() + } +} diff --git a/FileSets/v3.40~10/MbItem.qml.orig b/FileSets/v3.40~11/MbItem.qml.orig similarity index 100% rename from FileSets/v3.40~10/MbItem.qml.orig rename to FileSets/v3.40~11/MbItem.qml.orig diff --git a/FileSets/v3.40~11/MbItemDigitalInput.qml b/FileSets/v3.40~11/MbItemDigitalInput.qml new file mode 100644 index 00000000..599ed90a --- /dev/null +++ b/FileSets/v3.40~11/MbItemDigitalInput.qml @@ -0,0 +1,31 @@ +//// modified for ExtTransferSwitch package + +import QtQuick 1.1 + +MbItemOptions { + show: valid + signal disabled + property variant previousValue: undefined + possibleValues: [ + MbOption { description: qsTr("Disabled"); value: 0 }, + MbOption { description: qsTr("Pulse meter"); value: 1 }, + MbOption { description: qsTr("Door alarm"); value: 2 }, + MbOption { description: qsTr("Bilge pump"); value: 3 }, + MbOption { description: qsTr("Bilge alarm"); value: 4 }, + MbOption { description: qsTr("Burglar alarm"); value: 5 }, + MbOption { description: qsTr("Smoke alarm"); value: 6 }, + MbOption { description: qsTr("Fire alarm"); value: 7 }, + MbOption { description: qsTr("CO2 alarm"); value: 8 }, + MbOption { description: qsTr("Generic I/O"); value: 10 }, + MbOption { description: qsTr("Generator"); value: 9 }, + MbOption { description: qsTr("Touch input control"); value: 11 }, +//// added for ExtTransferSwitch package + MbOption { description: qsTr("External transfer switch"); value: 12 } + ] + onValueChanged: { + if (valid) { + if (previousValue != undefined && value == 0) disabled() + previousValue = value + } + } +} diff --git a/FileSets/v3.40~10/MbItemDigitalInput.qml.orig b/FileSets/v3.40~11/MbItemDigitalInput.qml.orig similarity index 100% rename from FileSets/v3.40~10/MbItemDigitalInput.qml.orig rename to FileSets/v3.40~11/MbItemDigitalInput.qml.orig diff --git a/FileSets/v3.40~11/MbSpinBox.qml b/FileSets/v3.40~11/MbSpinBox.qml new file mode 100644 index 00000000..031b6ba2 --- /dev/null +++ b/FileSets/v3.40~11/MbSpinBox.qml @@ -0,0 +1,183 @@ +import QtQuick 1.1 +import Qt.labs.components.native 1.0 +import com.victron.velib 1.0 + +MbItem { + 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 { + isSetting: true + decimals: 1 + step: 0.5 + } + property bool useVirtualKeyboard + property variant spinboxToolbarHandler: editMode ? _spinboxToolbarHandler : navigationHandler + default property alias values: container.data + + editMode: spinbox.enabled + height: keyboard.y + keyboard.height + 1 + toolbarHandler: spinboxToolbarHandler + + ToolbarHandler { + id: _spinboxToolbarHandler + property string leftIcon: "icon-toolbar-cancel" + property string rightIcon: "icon-toolbar-ok" + property string rightText: "" + + function leftAction() + { + cancel() + } + + function rightAction() + { + save() + } + } + + signal exitEditMode(bool changed, variant newValue) + signal maxValueReached() + signal minValueReached() + + Item { + id: verticalCentered + height: root.defaultHeight + width: root.width + + MbTextDescription { + id: name + anchors { + left: parent.left; leftMargin: style.marginDefault + verticalCenter: parent.verticalCenter + } + + isCurrentItem: root.ListView.isCurrentItem + text: root.description + opacity: item.valid ? style.opacityEnabled : style.opacityDisabled + } + + Item { + id: container + width: childrenRect.width + height: childrenRect.height + anchors { + right: graytag.left; rightMargin: style.marginDefault + verticalCenter: parent.verticalCenter + } + } + + MbBackgroundRect { + id: graytag +////// GuiMods — DarkMode + color: !darkMode ? (!spinbox.enabled ? "#ddd": "#fff") : (!spinbox.enabled ? "#4b4b4b": "#747474") + height: spinbox.height + 6 + width: spinbox.width + unit.width + 10 +////// GuiMods — DarkMode + border.color: !darkMode ? "#ddd" : "#4b4b4b" + border.width: spinbox.enabled ? 1 : 0 + anchors { + right: parent.right; rightMargin: style.marginDefault + verticalCenter: parent.verticalCenter + } + } + + MbTextValue { + id: unit + + text: root.item.unit + anchors { + right: parent.right; rightMargin: style.marginDefault + 5 + verticalCenter: spinbox.verticalCenter + } + } + + SpinBox { + id: spinbox + + color: style.color2 + font.pixelSize: name.font.pixelSize + font.family: name.font.family + font.bold: false + minimumValue: item.min + maximumValue: item.max + stepSize: item.step + enabled: false + greyed: item.valid + numOfDecimals: item.decimals + anchors { + right: unit.left + verticalCenter: parent.verticalCenter + } + + /* note: these functions break binding hence the Binding item below */ + Keys.onRightPressed: { if (value === maximumValue) maxValueReached(); spinbox.up(event.isAutoRepeat); } + Keys.onLeftPressed: { if (value === minimumValue) minValueReached(); spinbox.down(event.isAutoRepeat); } + Keys.onUpPressed: { if (value === maximumValue) maxValueReached(); spinbox.up(event.isAutoRepeat); } + Keys.onDownPressed: { if (value === minimumValue) minValueReached(); spinbox.down(event.isAutoRepeat); } + + /* Focus is removed to ignore keypresses */ + Keys.onSpacePressed: save(false) + Keys.onReturnPressed: save(false) + Keys.onEscapePressed: cancel() + } + + MouseArea { + anchors { + fill: spinbox + leftMargin: -20 + rightMargin: -20 + } + + onPressed: handleMouseClick(true) + } + } + + Keyboard { + id: keyboard + anchors.top: verticalCentered.bottom + anchors.topMargin: -1 + width: root.width + active: spinbox.enabled && useVirtualKeyboard + layout: "KeyboardLoaderPlusMin.qml" + onAnimatingChanged: listview.positionViewAtIndex(currentIndex, ListView.Contain) + } + + /* binding is done explicitly to reenable binding after edit */ + Binding { + target: spinbox + property: "value" + value: item.value + when: item.valid && !spinbox.enabled + } + + function edit(isMouse) + { + if (item.valid && !readOnly) + { + useVirtualKeyboard = isMouse === true + spinbox.enabled = true + spinbox.focus = true + } + } + + function save() { + var newValue = spinbox.value + item.setValue(spinbox.value) + focus = true; + spinbox.enabled = false + exitEditMode(true, newValue) + } + + function cancel() { + focus = true + spinbox.enabled = false + exitEditMode(false, undefined) + } +} diff --git a/FileSets/v3.40~10/MbSpinBox.qml.orig b/FileSets/v3.40~11/MbSpinBox.qml.orig similarity index 100% rename from FileSets/v3.40~10/MbSpinBox.qml.orig rename to FileSets/v3.40~11/MbSpinBox.qml.orig diff --git a/FileSets/v3.40~11/MbStyle.qml b/FileSets/v3.40~11/MbStyle.qml new file mode 100644 index 00000000..9bba6057 --- /dev/null +++ b/FileSets/v3.40~11/MbStyle.qml @@ -0,0 +1,47 @@ +import QtQuick 1.1 + +/* + * 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 + property int itemHeight: 35 + + // Default font and size for e.g. the menus + property string fontFamily: "default" + property int fontPixelSize: 16 + +////// GuiMods — DarkMode + property string borderColor: !darkMode ? "#ddd" : "#4b4b4b" + property string backgroundColor: !darkMode ? (isCurrentItem ? '#4790d0' : 'transparent') : (isCurrentItem ? '#234468' : '#303030') + property string backgroundColorService: !darkMode ? (isCurrentItem ? "#2969a1" : '#ffe9b7') : (isCurrentItem ? "#234468" : '#7f745b') + property string backgroundColorComponent: borderColor + + // Text mainly used for description etc. +////// GuiMods — DarkMode + property string textColor: !darkMode ? "#000000" : "#fdfdfd" + property string textColorSelected: !darkMode ? "#FFFFFF" : "#fdfdfd" + + // Color typically used for values +////// GuiMods — DarkMode + property string valueColor: !darkMode ? "#333333" : "#fdfdfd" + property int valueHorizontalAlignment: Text.AlignRight + property string color2: !darkMode ? "#333333" : "#fdfdfd" + + property int marginDefault: 8 + // margin between MbItem border and components for bottom / top + property int marginItemVertical: 3 + // margin from the "sides", typically left / right + property int marginItemHorizontal: 8 + // prefered left / right text margin within text components + property int marginTextHorizontal: 5 + + property real opacityEnabled: 1.0 + property real opacityDisabled: 0.5 +} diff --git a/FileSets/v3.40~10/MbStyle.qml.orig b/FileSets/v3.40~11/MbStyle.qml.orig similarity index 100% rename from FileSets/v3.40~10/MbStyle.qml.orig rename to FileSets/v3.40~11/MbStyle.qml.orig diff --git a/FileSets/v3.40~11/MbSubMenu.qml b/FileSets/v3.40~11/MbSubMenu.qml new file mode 100644 index 00000000..094cda24 --- /dev/null +++ b/FileSets/v3.40~11/MbSubMenu.qml @@ -0,0 +1,69 @@ +import QtQuick 1.1 +import Qt.labs.components.native 1.0 +import com.victron.velib 1.0 + +MbItem { + id: root + width: pageStack ? pageStack.currentPage.width : 0 + +////// 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 VBusItem item: VBusItem {} + property string iconId: "icon-toolbar-enter" + property bool check: false + property bool indent: false + default property alias values: _values.data + + MbTextDescription { + id: checkText + anchors { + left: parent.left; leftMargin: style.marginDefault + verticalCenter: parent.verticalCenter + } + width: root.indent ? 9 : 0 + text: root.check ? "√" : " " + } + + MbTextDescription { + id: name + anchors { + left: checkText.right; leftMargin: root.indent ? checkText.width : 0 + verticalCenter: parent.verticalCenter + } + text: root.description + } + + MbRow { + id: _values + + anchors { + right: icon.left; rightMargin: style.marginDefault / 2 + verticalCenter: parent.verticalCenter + } + + Repeater { + id: repeater + model: root.item.value && root.item.value.constructor === Array ? root.item.value.length : 1 + + MbTextBlock { + item.text: repeater.model === 1 ? root.item.text : root.item.value[index] + opacity: item.text !== item.invalidText + } + } + } + + MbIcon { + id: icon + + display: hasSubpage + anchors { + right: root.right; rightMargin: style.marginDefault + verticalCenter: parent.verticalCenter + } +////// GuiMods — DarkMode + iconId: root.iconId ? root.iconId + (root.ListView.isCurrentItem || darkMode ? "-active" : "") : "" + } +} diff --git a/FileSets/v3.40~10/MbSubMenu.qml.orig b/FileSets/v3.40~11/MbSubMenu.qml.orig similarity index 100% rename from FileSets/v3.40~10/MbSubMenu.qml.orig rename to FileSets/v3.40~11/MbSubMenu.qml.orig diff --git a/FileSets/v3.40~11/Multi.qml b/FileSets/v3.40~11/Multi.qml new file mode 100644 index 00000000..9ce49240 --- /dev/null +++ b/FileSets/v3.40~11/Multi.qml @@ -0,0 +1,119 @@ +import QtQuick 1.1 +import com.victron.velib 1.0 +import "utils.js" as Utils + +MbIcon { + id: multi + iconId: "overview-inverter" + +////// GuiMods — DarkMode + property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } + property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 + + SvgRectangle + { + id:inverterForeground + width: multi.width + height: multi.height + radius: 3 + color: "#000000" +////// GuiMods — DarkMode + opacity: !darkMode ? 0 : 0.35 + } + + property string vebusPrefix: "" + property string systemPrefix: "com.victronenergy.system" + property VBusItem systemState: VBusItem { bind: Utils.path(systemPrefix, "/SystemState/State") } + + Component.onCompleted: discoverMultis() + + Column { + spacing: 3 + x: 26 + y: 62 + + Led { + bind: Utils.path(sys.vebusPrefix, "/Leds/Mains") + onColor: "#68FF00" + } + + Led { + bind: Utils.path(sys.vebusPrefix, "/Leds/Bulk") + } + + Led { + bind: Utils.path(sys.vebusPrefix, "/Leds/Absorption") + } + + Led { + bind: Utils.path(sys.vebusPrefix, "/Leds/Float") + } + } + + Column { + spacing: 3 + x: multi.width - 28 + y: 62 + + Led { + bind: Utils.path(sys.vebusPrefix, "/Leds/Inverter") + onColor: "#68FF00" + } + + Led { + bind: Utils.path(sys.vebusPrefix, "/Leds/Overload") + onColor: "#F75E25" + } + + Led { + bind: Utils.path(sys.vebusPrefix, "/Leds/LowBattery") + onColor: "#F75E25" + } + + Led { + bind: Utils.path(sys.vebusPrefix, "/Leds/Temperature") + onColor: "#F75E25" + } + } + + Text { + anchors { + horizontalCenter: multi.horizontalCenter + top: multi.top; topMargin: 8 + } + horizontalAlignment: Text.AlignHCenter +////// GuiMods — DarkMode + color: !darkMode ? "white" : "#e1e1e1" + font {pixelSize: 16; bold: true} + text: vebusState.text + + SystemState { + id: vebusState + bind: systemState.valid?Utils.path(systemPrefix, "/SystemState/State"):Utils.path(sys.vebusPrefix, "/State") + } + } + + // When a new service is found check if is a multi + Connections { + target: DBusServices + onDbusServiceFound: addService(service) + } + + function addService(service) + { + if (service.type === DBusService.DBUS_SERVICE_MULTI) { + if (vebusPrefix === "") + vebusPrefix = service.name; + } + } + + // Check available services to find multis + function discoverMultis() + { + for (var i = 0; i < DBusServices.count; i++) { + if (DBusServices.at(i).type === DBusService.DBUS_SERVICE_MULTI) { + addService(DBusServices.at(i)) + } + } + } +} diff --git a/FileSets/v3.40~10/Multi.qml.orig b/FileSets/v3.40~11/Multi.qml.orig similarity index 100% rename from FileSets/v3.40~10/Multi.qml.orig rename to FileSets/v3.40~11/Multi.qml.orig diff --git a/FileSets/v3.40~11/ObjectAcConnection.qml b/FileSets/v3.40~11/ObjectAcConnection.qml new file mode 100644 index 00000000..9e87e2db --- /dev/null +++ b/FileSets/v3.40~11/ObjectAcConnection.qml @@ -0,0 +1,52 @@ +////// 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 l2AndL1OutSummed: false +////// 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.40~10/ObjectAcConnection.qml.orig b/FileSets/v3.40~11/ObjectAcConnection.qml.orig similarity index 100% rename from FileSets/v3.40~10/ObjectAcConnection.qml.orig rename to FileSets/v3.40~11/ObjectAcConnection.qml.orig diff --git a/FileSets/v3.40~11/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~11/OverviewAcValuesEnhanced.qml new file mode 100644 index 00000000..dc36d2ea --- /dev/null +++ b/FileSets/v3.40~11/OverviewAcValuesEnhanced.qml @@ -0,0 +1,94 @@ +////// 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 + } + + // 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 + } + TileText { + text: + { + if (root.connection.l2AndL1OutSummed) + 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: + { + if (phaseCount >= 3) + return "L3: " + EnhFmt.formatVBusItem (root.connection.powerL3, "W") + + " " + EnhFmt.formatVBusItem (root.connection.voltageL3, "V") + + " " + EnhFmt.formatVBusItem (root.connection.currentL3, "A") + else + return " " + } + visible: phaseCount >= 2 + font.pixelSize: 11 + } + TileText { + text: EnhFmt.formatVBusItem (root.connection.frequency, "Hz") + font.pixelSize: phaseCount >= 2 ? 11 : 15 + } + TileText { + text: qsTr("Limit: ") + EnhFmt.formatVBusItem (root.connection.inCurrentLimit) + font.pixelSize: phaseCount >= 2 ? 11 : 15 + visible: root.connection == sys.acInput + } + } +} diff --git a/FileSets/v3.40~10/OverviewAcValuesEnhanced.qml.orig b/FileSets/v3.40~11/OverviewAcValuesEnhanced.qml.orig similarity index 100% rename from FileSets/v3.40~10/OverviewAcValuesEnhanced.qml.orig rename to FileSets/v3.40~11/OverviewAcValuesEnhanced.qml.orig diff --git a/FileSets/v3.40~11/OverviewBox.qml b/FileSets/v3.40~11/OverviewBox.qml new file mode 100644 index 00000000..5bda96da --- /dev/null +++ b/FileSets/v3.40~11/OverviewBox.qml @@ -0,0 +1,55 @@ +import QtQuick 1.1 + +SvgRectangle { + id: root + +////// GuiMods — DarkMode + property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } + property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 + + radius: 6 + width: 110 + height: 110 +////// GuiMods — DarkMode + color: !darkMode ? "#16a185" : "#0B5042" + clip: true // hides an off by one pixel offset + + property string title +////// GuiMods — DarkMode + property string titleColor: !darkMode ? "#1abc9c" : "#136050" + property alias values: _values.children + + SvgRectangle { + id: header + width: parent.width + height: 20 + radius: root.radius + color: titleColor + + // prevent rounded corners at the bottom + SvgRectangle { + height: parent.height / 2 + width: parent.width + color: parent.color + anchors.top: parent.verticalCenter + } + + Text { + text: title + font {pixelSize: 14; bold: true} +////// GuiMods — DarkMode + color: !darkMode ? "white" : "#e1e1e1" + anchors.centerIn: parent + } + } + + Item { + id: _values + anchors { + top: header.bottom; + bottom: root.bottom + left: root.left + right: root.right + } + } +} diff --git a/FileSets/v3.40~10/OverviewBox.qml.orig b/FileSets/v3.40~11/OverviewBox.qml.orig similarity index 100% rename from FileSets/v3.40~10/OverviewBox.qml.orig rename to FileSets/v3.40~11/OverviewBox.qml.orig diff --git a/FileSets/v3.40~11/OverviewConnection.qml b/FileSets/v3.40~11/OverviewConnection.qml new file mode 100644 index 00000000..608a101d --- /dev/null +++ b/FileSets/v3.40~11/OverviewConnection.qml @@ -0,0 +1,137 @@ +import QtQuick 1.1 + +/* + * This qml Item creates a line with moving balls on it representing a + * power flow in the overview. The line can be made up of an arbitary + * amount of straight line segments. The paths is drawn from (0,0) to + * (width, height) so it can simply be anchored to the points you want + * to connect. Since this item can have negative height and width the + * wording (top, left) and (right, bottom) is a bit weird, since they + * can be two arbitrary points, but so be it. + * + * This item is a bit weird anyway, first of all, since Path is an array, + * and qml arrays are weird in qt quick 1.1, it is not possible to bind + * to its contents. Hence the onCompleted events are used to assign them + * by value. + * + * Secondly, this item is slow! To deal with that a bit, the contents is + * only drawn when active is true. So the item can first be layout and + * its contents only layouted once. + */ + +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 Path path: emptyPath + + property Path straight: Path { + PathLine {x: 0; y: 0} + PathLine {x: width; y: height} + } + property Path corner: Path { + PathLine {x: 0; y: 0} + PathLine {x: width; y: 0} + PathLine {x: width; y: height} + } + property Path emptyPath: Path {} + + property bool active + property int ballCount: 4 +////// GuiMods — DarkMode + property color ballColor: !darkMode ? "#4789d0" : "#386ca5" + property real ballDiameter: lineWidth * 2 + 1 +////// GuiMods — DarkMode + property color lineColor: !darkMode ? "#4789d0" : "#386ca5" + property int lineWidth: 3 + property int value + property bool startPointVisible: true + property bool endPointVisible: true + + // internal + property int lineSegments + property Path activePath: active ? path : emptyPath + + visible: active + + function update() { + if (activePath === emptyPath) { + lineSegments = 0 + return + } + + var newValue = activePath.pathElements.length - 1 + + if (lineSegments == newValue) + lineSegments = newValue - 1; + lineSegments = newValue + + startPoint.update() + endPoint.update() + } + + onActivePathChanged: update() + onHeightChanged: update() + onWidthChanged: update() + + // end points of the path + OverviewConnectionEnd { + id: startPoint + visible: active && startPointVisible + connectionSize: ballDiameter + + // assign this otherwise qml will warn it is unbindable + function update() { + rotation = Math.atan2(activePath.pathElements[1].y, activePath.pathElements[1].x) * (180 / Math.PI) + } + } + + OverviewConnectionEnd { + id: endPoint + visible: active && endPointVisible + x: root.width + y: root.height + connectionSize: ballDiameter + + function update() { + var dx = activePath.pathElements[lineSegments].x - activePath.pathElements[lineSegments - 1].x + var dy = activePath.pathElements[lineSegments].y - activePath.pathElements[lineSegments - 1].y + rotation = 180 + Math.atan2(dy, dx) * (180 / Math.PI) + } + } + + // Draw foreground lines on top of that + Repeater { + id: lines + model: lineSegments + + Line { + lineWidth: root.lineWidth + color: lineColor + + // assign this otherwise qml will warn it is unbindable + Component.onCompleted: { + from = activePath.pathElements[index] + to = activePath.pathElements[index + 1] + } + } + } + + // moving balls over the lines + PathView { + id: ballsPath + model: active ? ballCount : 0 + interactive: false + path: activePath + visible: value != 0 + offset: active && value < 0 ? 1 - mover.pos : mover.pos + + delegate: Circle { + color: ballColor + radius: root.ballDiameter / 2 + } + } +} diff --git a/FileSets/v3.40~10/OverviewConnection.qml.orig b/FileSets/v3.40~11/OverviewConnection.qml.orig similarity index 100% rename from FileSets/v3.40~10/OverviewConnection.qml.orig rename to FileSets/v3.40~11/OverviewConnection.qml.orig diff --git a/FileSets/v3.40~11/OverviewConnectionEnd.qml b/FileSets/v3.40~11/OverviewConnectionEnd.qml new file mode 100644 index 00000000..60384d20 --- /dev/null +++ b/FileSets/v3.40~11/OverviewConnectionEnd.qml @@ -0,0 +1,46 @@ +import QtQuick 1.1 + +// NOTE: centers around the circle it midpoint +// width and height are bogus! +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 real radius: 5.5 + property alias color: ball.color + property int connectionSize: 7 + property int connectionLength: 9 + property alias rotation: connection.rotation + + Rectangle { + id: connection + + transformOrigin: Item.Left +////// GuiMods — DarkMode + color: !darkMode ? "white" : "#202020" + width: root.radius + connectionLength + height: connectionSize + anchors { + verticalCenter: ball.verticalCenter + left: ball.horizontalCenter + } + } + + Circle { + id: ball + radius: root.radius +////// GuiMods — DarkMode + color: !darkMode ? "#4789d0" : "#386ca5" + x: -radius + y: -radius + + border { + width: 2 +////// GuiMods — DarkMode + color: !darkMode ? "white" : "#202020" + } + } +} diff --git a/FileSets/v3.40~10/OverviewConnectionEnd.qml.orig b/FileSets/v3.40~11/OverviewConnectionEnd.qml.orig similarity index 100% rename from FileSets/v3.40~10/OverviewConnectionEnd.qml.orig rename to FileSets/v3.40~11/OverviewConnectionEnd.qml.orig diff --git a/FileSets/v3.40~11/OverviewFlowComplex.qml b/FileSets/v3.40~11/OverviewFlowComplex.qml new file mode 100644 index 00000000..55a375b1 --- /dev/null +++ b/FileSets/v3.40~11/OverviewFlowComplex.qml @@ -0,0 +1,1535 @@ +///// 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 showInverter: 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.inverterChargerDc.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 () + } + + 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" + 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 + } + DetailTarget { id: multiTarget; detailsPage: "DetailInverter.qml"; width: 60; height: 60 } + } + TileText + { + text: wallClock.time + color: "white" + 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: + root.tempServiceName = service.name + if (temperatureItem.valid && showBatteryTemp) + { + numberOfTemps++ + tempsModel.append({serviceName: service.name}) + } + break;; + case DBusService.DBUS_SERVICE_INVERTER: + 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 = "" + 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~10/OverviewFlowComplex.qml.orig b/FileSets/v3.40~11/OverviewFlowComplex.qml.orig similarity index 100% rename from FileSets/v3.40~10/OverviewFlowComplex.qml.orig rename to FileSets/v3.40~11/OverviewFlowComplex.qml.orig diff --git a/FileSets/v3.40~11/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~11/OverviewGeneratorEnhanced.qml new file mode 100644 index 00000000..0c189315 --- /dev/null +++ b/FileSets/v3.40~11/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~10/OverviewGeneratorEnhanced.qml.orig b/FileSets/v3.40~11/OverviewGeneratorEnhanced.qml.orig similarity index 100% rename from FileSets/v3.40~10/OverviewGeneratorEnhanced.qml.orig rename to FileSets/v3.40~11/OverviewGeneratorEnhanced.qml.orig diff --git a/FileSets/v3.40~11/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~11/OverviewGeneratorRelayEnhanced.qml new file mode 100644 index 00000000..83326226 --- /dev/null +++ b/FileSets/v3.40~11/OverviewGeneratorRelayEnhanced.qml @@ -0,0 +1,8 @@ +import QtQuick 1.1 +import "utils.js" as Utils + +OverviewGeneratorEnhanced { + icon: "overview-generator" + settingsBindPrefix: "com.victronenergy.settings/Settings/Generator0" + bindPrefix: "com.victronenergy.generator.startstop0" +} diff --git a/FileSets/v3.40~10/OverviewGeneratorRelayEnhanced.qml.orig b/FileSets/v3.40~11/OverviewGeneratorRelayEnhanced.qml.orig similarity index 100% rename from FileSets/v3.40~10/OverviewGeneratorRelayEnhanced.qml.orig rename to FileSets/v3.40~11/OverviewGeneratorRelayEnhanced.qml.orig diff --git a/FileSets/v3.40~11/OverviewGridParallel.qml b/FileSets/v3.40~11/OverviewGridParallel.qml new file mode 100644 index 00000000..8e11752d --- /dev/null +++ b/FileSets/v3.40~11/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.inverterChargerDc.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.inverterChargerDc.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~10/OverviewGridParallel.qml.orig b/FileSets/v3.40~11/OverviewGridParallel.qml.orig similarity index 100% rename from FileSets/v3.40~10/OverviewGridParallel.qml.orig rename to FileSets/v3.40~11/OverviewGridParallel.qml.orig diff --git a/FileSets/v3.40~11/OverviewHub.qml b/FileSets/v3.40~11/OverviewHub.qml new file mode 100644 index 00000000..7c04b763 --- /dev/null +++ b/FileSets/v3.40~11/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.inverterChargerDc.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.inverterChargerDc.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~10/OverviewHub.qml.orig b/FileSets/v3.40~11/OverviewHub.qml.orig similarity index 100% rename from FileSets/v3.40~10/OverviewHub.qml.orig rename to FileSets/v3.40~11/OverviewHub.qml.orig diff --git a/FileSets/v3.40~11/OverviewHubEnhanced.qml b/FileSets/v3.40~11/OverviewHubEnhanced.qml new file mode 100644 index 00000000..fd22b360 --- /dev/null +++ b/FileSets/v3.40~11/OverviewHubEnhanced.qml @@ -0,0 +1,1492 @@ +////// 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 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 () } + + 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 +////// 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 + } + 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 + 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 +////// 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: + { + if (hasAcSolarOnOut) + return "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvOnOutputMaxPower" + else + return "com.victronenergy.settings/Settings/GuiMods/GaugeLimits/PvOnGridMaxPower" + } + connection: hasAcSolarOnOut ? sys.pvOnAcOut : hasAcSolarOnAcIn1 ? sys.pvOnAcIn1 : sys.pvOnAcIn2 + visible: showGauges && showAcSolar && !showDcAndAcSolar + } + DetailTarget { id: pvInverterTarget; detailsPage: "DetailPvInverter.qml" } + } + + OverviewConnection { + id: acInToMulti + visible: showAcInput + ballCount: 2 + path: straight + active: root.active + 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 || showAllTiles ) + 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 + value: -Utils.sign (noNoise (sys.pvCharger.power) + noNoise (sys.inverterChargerDc.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 + value: -flow(sys.inverterChargerDc.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 + value: Utils.sign(noNoise(sys.pvCharger.power) + noNoise(sys.inverterChargerDc.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: + 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: + 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: + 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 = "" + 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~10/OverviewHubEnhanced.qml.orig b/FileSets/v3.40~11/OverviewHubEnhanced.qml.orig similarity index 100% rename from FileSets/v3.40~10/OverviewHubEnhanced.qml.orig rename to FileSets/v3.40~11/OverviewHubEnhanced.qml.orig diff --git a/FileSets/v3.40~11/OverviewMobileEnhanced.qml b/FileSets/v3.40~11/OverviewMobileEnhanced.qml new file mode 100644 index 00000000..175a4bac --- /dev/null +++ b/FileSets/v3.40~11/OverviewMobileEnhanced.qml @@ -0,0 +1,989 @@ +// 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 + 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 { // 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 + 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 + } + connection: sys.acInput + useInputCurrentLimit: true + maxForwardPowerParameter: "" + 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 + 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/v3.40~10/OverviewMobileEnhanced.qml.orig b/FileSets/v3.40~11/OverviewMobileEnhanced.qml.orig similarity index 100% rename from FileSets/v3.40~10/OverviewMobileEnhanced.qml.orig rename to FileSets/v3.40~11/OverviewMobileEnhanced.qml.orig diff --git a/FileSets/v3.40~11/OverviewSolarCharger.qml b/FileSets/v3.40~11/OverviewSolarCharger.qml new file mode 100644 index 00000000..020c26f5 --- /dev/null +++ b/FileSets/v3.40~11/OverviewSolarCharger.qml @@ -0,0 +1,58 @@ +import QtQuick 1.1 + +Item { + id: root + +////// GuiMods — DarkMode + property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } + property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 + + default property alias values: blueSolarChargerBox.values + property alias title: blueSolarChargerBox.title + property bool showChargerIcon: true + + width: 155 + height: 115 + + MbIcon { + id: blueSolarChargerIcon + + iconId: "overview-bluesolar-charger" + anchors.bottom: root.bottom + visible: showChargerIcon + } + + OverviewBox { + id: blueSolarChargerBox + + height: root.height + title: qsTr("PV Power") +////// GuiMods — DarkMode + titleColor: !darkMode ? "#F4B350" : "#7A5928" + color: !darkMode ? "#F39C12" : "#794E09" + + anchors { + bottom: root.bottom + left: blueSolarChargerIcon.left; leftMargin: showChargerIcon ? 43 : 0 + right: parent.right + } + } + + MbIcon { + anchors { + bottom: blueSolarChargerBox.bottom; bottomMargin: 3 + right: blueSolarChargerBox.right; rightMargin: 3 + } + iconId: "overview-sun" + display: showChargerIcon + } + + MbIcon { + anchors { + bottom: blueSolarChargerBox.bottom; bottomMargin: 3 + left: parent.left; leftMargin: 2 + } + iconId: "overview-victron-logo-small" + display: !showChargerIcon + } +} diff --git a/FileSets/v3.40~10/OverviewSolarCharger.qml.orig b/FileSets/v3.40~11/OverviewSolarCharger.qml.orig similarity index 100% rename from FileSets/v3.40~10/OverviewSolarCharger.qml.orig rename to FileSets/v3.40~11/OverviewSolarCharger.qml.orig diff --git a/FileSets/v3.40~11/OverviewSolarInverter.qml b/FileSets/v3.40~11/OverviewSolarInverter.qml new file mode 100644 index 00000000..98f931d2 --- /dev/null +++ b/FileSets/v3.40~11/OverviewSolarInverter.qml @@ -0,0 +1,67 @@ +import QtQuick 1.1 + +Rectangle { + id: root + +////// GuiMods — DarkMode + property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } + property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 + + default property alias values: pvInverterBox.values + property alias title: pvInverterBox.title + property bool showInverterIcon: true + + width: 155 + height: 115 + color: "transparent" + clip: true + + MbIcon { + id: pvInverterIcon + iconId: getDeviceIcon() + visible: showInverterIcon && getDeviceIcon() !== "" + anchors.bottom: parent.bottom + } + + OverviewBox { + id: pvInverterBox + + height: root.height + title: qsTr("PV Power") +////// GuiMods — DarkMode + titleColor: !darkMode ? "#F4B350" : "#7A5928" + color: !darkMode ? "#F39C12" : "#794E09" + + anchors { + bottom: parent.bottom + left: pvInverterIcon.left; leftMargin: pvInverterIcon.visible ? 32 : 0 + right: parent.right + } + + MbIcon { + iconId: getDeviceLogo() + visible: !showInverterIcon + anchors { + bottom: parent.bottom + left: parent.left + margins: 2 + } + } + } + + function getDeviceIcon() + { + var ids = sys.pvInvertersProductIds.text + if (ids.indexOf(0xA142) > -1) + return "overview-pvinverter-fronius" + return "" + } + + function getDeviceLogo() + { + var ids = sys.pvInvertersProductIds.text + if (ids.indexOf(0xA142) > -1) + return "overview-fronius-logo" + return "" + } +} diff --git a/FileSets/v3.40~10/OverviewSolarInverter.qml.orig b/FileSets/v3.40~11/OverviewSolarInverter.qml.orig similarity index 100% rename from FileSets/v3.40~10/OverviewSolarInverter.qml.orig rename to FileSets/v3.40~11/OverviewSolarInverter.qml.orig diff --git a/FileSets/v3.40~11/OverviewTankDelegate.qml b/FileSets/v3.40~11/OverviewTankDelegate.qml new file mode 100644 index 00000000..e884d92c --- /dev/null +++ b/FileSets/v3.40~11/OverviewTankDelegate.qml @@ -0,0 +1,115 @@ +import QtQuick 1.1 +import com.victron.velib 1.0 +import "utils.js" as Utils +import "tanksensor.js" as TankSensor + +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 string bindPrefix + property variant service: DBusServices.get(bindPrefix) + property variant info: TankSensor.info(fluidTypeItem.value) + + property VBusItem fluidTypeItem: VBusItem { bind: Utils.path(bindPrefix, "/FluidType") } + property VBusItem volumeUnit: VBusItem { bind: "com.victronenergy.settings/Settings/System/VolumeUnit" } + property VBusItem tankLevelItem: VBusItem { + bind: Utils.path(bindPrefix, "/Level") + decimals: 0 + unit: "%" + } + property VBusItem tankCapacityItem: VBusItem { + bind: Utils.path(bindPrefix, "/Capacity") + text: TankSensor.formatVolume(volumeUnit.value, value) + } + property VBusItem tankRemainingItem: VBusItem { + bind: Utils.path(bindPrefix, "/Remaining") + text: TankSensor.formatVolume(volumeUnit.value, value) + } + + width: 65 + height: 150 + + SvgRectangle { + id: mainRect + border { color: info.color; width: 2 } + width: root.width + height: root.height * 0.72 +////// GuiMods — DarkMode + color: !darkMode ? "white" : "#c0c0c0" + + SvgRectangle { + color: info.color + height: (parent.height - 4) * (tankLevelItem.value / 100) + width: parent.width - 5 + anchors { + left: parent.left; leftMargin: 2 + right: parent.right; rightMargin: 2 + bottom: parent.bottom; bottomMargin: 2 + } + } + + Text { + text: tankLevelItem.text + width: parent.width + font.pixelSize: width < 50 ? 12 : 18 + horizontalAlignment: Text.AlignHCenter + clip: true + anchors { + horizontalCenter: parent.horizontalCenter + top: parent.top; topMargin: 6 + } + } + + MbIcon { + iconId: info.icon + anchors.centerIn: parent + } + + Text { + text: tankRemainingItem.text + font.pixelSize: width < 50 ? 11 : 12 + width: parent.width + horizontalAlignment: Text.AlignHCenter + clip: true + anchors { + horizontalCenter: parent.horizontalCenter + bottom: _capacityText.top + } + } + + Text { + id: _capacityText + text: "(%1)".arg(tankCapacityItem.text) + font.pixelSize: width < 50 ? 11 : 12 + width: parent.width + horizontalAlignment: Text.AlignHCenter + clip: true + anchors { + horizontalCenter: parent.horizontalCenter + bottom: parent.bottom; bottomMargin: 6 + } + } + } + + Text { + id: _tankName + text: service.description +////// GuiMods — DarkMode + color: !darkMode ? "black" : "#e1e1e1" + width: parent.width + (parent.width < 50 ? 4 : 13) + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.WrapAtWordBoundaryOrAnywhere + font.pixelSize: 12 + maximumLineCount: 2 + clip: true + anchors { + top: mainRect.bottom; topMargin: 6 + bottom: root.bottom + horizontalCenter: root.horizontalCenter + } + } +} diff --git a/FileSets/v3.40~10/OverviewTankDelegate.qml.orig b/FileSets/v3.40~11/OverviewTankDelegate.qml.orig similarity index 100% rename from FileSets/v3.40~10/OverviewTankDelegate.qml.orig rename to FileSets/v3.40~11/OverviewTankDelegate.qml.orig diff --git a/FileSets/v3.40~11/OverviewTanks.qml b/FileSets/v3.40~11/OverviewTanks.qml new file mode 100644 index 00000000..690918ec --- /dev/null +++ b/FileSets/v3.40~11/OverviewTanks.qml @@ -0,0 +1,269 @@ +import QtQuick 1.1 +import com.victron.velib 1.0 +import "utils.js" as Utils +import "tanksensor.js" as TankSensor + +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 int numberOfTanks: tanks.all.rowCount + property int visibleTanks: tanks.rowCount + property int maxTanksPerPage: 10 + property bool showAllTanksPage: numberOfTanks > 0 && numberOfTanks <= maxTanksPerPage + property int currentIndex + property int availableFluidTypes + + title: qsTr("Tanks") + clip: true + + ListModel { id: fluidModel } + + property TankModel tanks: TankModel { + all.onRowCountChanged: fluidTypesChanged() + all.onDataChanged: fluidTypesChanged() + } + + Component.onCompleted: fluidTypesChanged() + + // Background image when searching for tanks + Image { + id: loadingBackground + source: "image://theme/overview-tanks-loading" + anchors.fill: parent + visible: numberOfTanks === 0 + } + + Text { + text: qsTr("No tanks found") +////// GuiMods — DarkMode + color: !darkMode ? "#ffffff" : "#e1e1e1" + font.pixelSize: 25 + anchors.centerIn: parent + visible: numberOfTanks === 0 + } + + ListView { + id: titleList + width: root.width + height: 25 + orientation: ListView.Horizontal + spacing: 20 + + // Keep the currentItem in the middle of the listview + highlightRangeMode: ListView.StrictlyEnforceRange + preferredHighlightBegin: currentItem ? width / 2 - currentItem.width / 2 : 0 + preferredHighlightEnd: currentItem ? width / 2 + currentItem.width / 2 : 0 + + model: fluidModel + interactive: false + anchors { top: parent.top; topMargin: 16 } + currentIndex: root.currentIndex + visible: numberOfTanks > 0 + + delegate: Text { + text: fluidName + height: 25 + font.pixelSize: 16 +////// GuiMods — DarkMode + opacity: ListView.isCurrentItem ? 1 : (!darkMode ? 0.3 : 0.5) + verticalAlignment: Text.AlignVCenter + scale: ListView.isCurrentItem ? 1.25 : 1 +////// GuiMods — DarkMode + color: !darkMode ? "black" : "#e1e1e1" + + Behavior on scale { + NumberAnimation { duration: 150 } + } + + MouseArea { + anchors.fill: parent + onClicked: setCurrentIndex(model.index) + } + } + + // Fade the sides of the title list + Rectangle { + height: parent.width / 3 + width: parent.height + y: 25 + transform: Rotation { origin.x: 0; origin.y: 0; angle: -90} + gradient: Gradient { +////// GuiMods — DarkMode + GradientStop { position: 0.7; color: !darkMode ? "white" : "#202020" } + GradientStop { position: 1; color: "transparent" } + } + } + + Rectangle { + height: parent.width / 3 + width: parent.height + x: parent.width + transform: Rotation { origin.x: 0; origin.y: 0; angle: 90} + gradient: Gradient { +////// GuiMods — DarkMode + GradientStop { position: 0.7; color: !darkMode ? "white" : "#202020" } + GradientStop { position: 1; color: "transparent" } + } + } + + // touch buttons for selecting a tank type + MbIcon { +////// GuiMods — DarkMode + iconId: darkMode ? "icon-toolbar-enter" : "icon-toolbar-enter-active" + rotation: 180 + anchors { + left: parent.left; leftMargin: 40 + verticalCenter: parent.verticalCenter + } + + MouseArea { + onClicked: decreaseIndex() + anchors { + fill: parent; margins: -16 + } + } + } + + MbIcon { +////// GuiMods — DarkMode + iconId: darkMode ? "icon-toolbar-enter" : "icon-toolbar-enter-active" + anchors { + right: parent.right; rightMargin: 40 + verticalCenter: parent.verticalCenter + } + + MouseArea { + onClicked: increaseIndex() + anchors { + fill: parent; margins: -16 + } + } + } + } + + Flow { + id: tanksFlow + spacing: visibleTanks > 8 ? 10 : 15 + + anchors { + horizontalCenter: parent.horizontalCenter + bottom: navigation.top; bottomMargin: 4 + top: titleList.bottom; topMargin: 16 + } + + Repeater { + id: tanksRepeater + model: tanks + delegate: OverviewTankDelegate { + bindPrefix: buddy.id + width: Math.min(65, Math.max((470 / visibleTanks - tanksFlow.spacing) + tanksFlow.spacing / visibleTanks, 35)) + height: tanksFlow.height + } + } + } + + Flow { + id: navigation + height: 41 + spacing: 15 + visible: numberOfTanks > 0 + + anchors { + bottom: parent.bottom; bottomMargin: 16 + horizontalCenter: parent.horizontalCenter + } + + Repeater { + model: fluidModel + delegate: OverviewRoundButton { + iconId: fluidIcon + separatorLine.visible: model.index === 0 && showAllTanksPage + onClicked: setCurrentIndex(index) + } + } + } + + // This is a seperate item, to disable the default left / right action, showing the toolbar + Item { + Keys.onLeftPressed: decreaseIndex() + Keys.onRightPressed: increaseIndex() + focus: root.active + } + + // Handle index change and set fluid type filter + function setCurrentIndex(index) + { + currentIndex = (index + fluidModel.count) % fluidModel.count + + // Note: the keys can always be pressed even if fluidModel is empty, prevent + // getting unexisting elements. + if (fluidModel.count === 0) { + tanks.filterRegExp = "" + } else { + var fluidType = fluidModel.get(currentIndex).fluidType + tanks.filterRegExp = fluidType >= 0 ? "^" + fluidType + "$" : "" + } + } + + function increaseIndex() + { + setCurrentIndex(currentIndex + 1) + } + + function decreaseIndex() + { + setCurrentIndex(currentIndex - 1) + } + + function fluidTypesChanged() + { + var fluids = 0 + for (var i = 0; i < numberOfTanks; i++) { + var val = tanks.all.getValue(i, VeQItemTableModel.ValueColumn) + if (val !== undefined) + fluids |= (1 << val) + } + + if (availableFluidTypes !== fluids) { + availableFluidTypes = fluids + updateFluidsModel() + } + } + + function updateFluidsModel() + { + var selectedType = fluidModel.count ? fluidModel.get(currentIndex).fluidType : -1 + var index = 0 + + fluidModel.clear() + if (showAllTanksPage) { + fluidModel.append({ fluidType: -1, fluidName: qsTr("All"), fluidIcon: "overview-tanks-all" }) + index = 1 + } + + var fluids = availableFluidTypes + var fluidType = 0 + var typeFound = false + while (fluids != 0) { + if (fluids & 1) { + var info = TankSensor.info(fluidType) + fluidModel.append({ fluidType: fluidType, fluidName: info.name, fluidIcon: info.icon }) + if (selectedType === fluidType) { + setCurrentIndex(index) + typeFound = true + } + index++ + } + fluids = fluids >> 1 + fluidType++ + } + + // If the selected tanks all disappeared, select all again / the first type + if (!typeFound) + setCurrentIndex(0) + } +} diff --git a/FileSets/v3.40~10/OverviewTanks.qml.orig b/FileSets/v3.40~11/OverviewTanks.qml.orig similarity index 100% rename from FileSets/v3.40~10/OverviewTanks.qml.orig rename to FileSets/v3.40~11/OverviewTanks.qml.orig diff --git a/FileSets/v3.40~11/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~11/OverviewTanksTempsDigInputs.qml new file mode 100644 index 00000000..781e163c --- /dev/null +++ b/FileSets/v3.40~11/OverviewTanksTempsDigInputs.qml @@ -0,0 +1,207 @@ +//// 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~10/OverviewTanksTempsDigInputs.qml.orig b/FileSets/v3.40~11/OverviewTanksTempsDigInputs.qml.orig similarity index 100% rename from FileSets/v3.40~10/OverviewTanksTempsDigInputs.qml.orig rename to FileSets/v3.40~11/OverviewTanksTempsDigInputs.qml.orig diff --git a/FileSets/v3.40~11/PageDigitalInput.qml b/FileSets/v3.40~11/PageDigitalInput.qml new file mode 100644 index 00000000..3a9483ca --- /dev/null +++ b/FileSets/v3.40~11/PageDigitalInput.qml @@ -0,0 +1,147 @@ +//// modified for ExtTransferSwitch package + +import QtQuick 1.1 +import com.victron.velib 1.0 +import "utils.js" as Utils + +MbPage { + id: root + + property variant service + property string bindPrefix + property string settingsBindPreffix: "com.victronenergy.settings/Settings/DigitalInput/" + inputNumber + property int inputNumber: instance.valid ? instance.value : 0 + + title: getType(service.description) + summary: getState(state.item.value) + + VBusItem { + id: instance + bind: service.path("/DeviceInstance") + } + +//// added for ExtTransferSwitch package + VBusItem + { + id: ac2connectedItem + bind: Utils.path ("com.victronenergy.system", "/Ac/In/1/Connected") + } + property bool showTransferSwitchConnection: ac2connectedItem.valid + VBusItem + { + id: typeItem + bind: service.path("/Type") + } + property bool isTransferSwitch: typeItem.valid && typeItem.value == 12 + + // Handle translations + function getType(type){ + switch (type) { + case "Disabled": + return qsTr("Disabled") + case "Pulse meter": + return qsTr("Pulse meter") + case "Door alarm": + return qsTr("Door alarm") + case "Bilge pump": + return qsTr("Bilge pump") + case "Bilge alarm": + return qsTr("Bilge alarm") + case "Burglar alarm": + return qsTr("Burglar alarm") + case "Smoke alarm": + return qsTr("Smoke alarm") + case "Fire alarm": + return qsTr("Fire alarm") + case "CO2 alarm": + return qsTr("CO2 alarm") + case "Generator": + return qsTr("Generator") +//// added for ExtTransferSwitch package + case "TransferSwitch": + return qsTr("External transfer switch") + } + return type; + } + + 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") + } + + return qsTr("Unknown") + } + + model: VisibleItemModel { + MbItemValue { + id: state + description: qsTr("State") + item.bind: service.path("/State") + item.text: getState(item.value) + } + + MbSubMenu { + id: setupMenu + description: qsTr("Setup") + subpage: Component { + PageDigitalInputSetup { + bindPrefix: root.settingsBindPreffix + } + } + } + + MbSubMenu { + id: deviceMenu + description: qsTr("Device") + subpage: Component { + PageDeviceInfo { + title: deviceMenu.description + bindPrefix: root.bindPrefix + } + } + } + +//// added for ExtTransferSwitch package + MbItemOptions + { + id: extTransferSwitch + description: qsTr("External transfer switch connection") + bind: Utils.path ("com.victronenergy.settings/Settings", "/TransferSwitch/TransferSwitchOnAc2") + possibleValues: + [ + MbOption {description: qsTr("AC 1 in"); value: 0}, + MbOption {description: qsTr("AC 2 in"); value: 1} + ] + visible: root.isTransferSwitch && root.showTransferSwitchConnection + } + } +} diff --git a/FileSets/v3.40~10/PageDigitalInput.qml.orig b/FileSets/v3.40~11/PageDigitalInput.qml.orig similarity index 100% rename from FileSets/v3.40~10/PageDigitalInput.qml.orig rename to FileSets/v3.40~11/PageDigitalInput.qml.orig diff --git a/FileSets/v3.40~11/PageGenerator.qml b/FileSets/v3.40~11/PageGenerator.qml new file mode 100644 index 00000000..c9670db0 --- /dev/null +++ b/FileSets/v3.40~11/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~10/PageGenerator.qml.orig b/FileSets/v3.40~11/PageGenerator.qml.orig similarity index 100% rename from FileSets/v3.40~10/PageGenerator.qml.orig rename to FileSets/v3.40~11/PageGenerator.qml.orig diff --git a/FileSets/v3.40~11/PageMain.qml b/FileSets/v3.40~11/PageMain.qml new file mode 100644 index 00000000..31ec72ff --- /dev/null +++ b/FileSets/v3.40~11/PageMain.qml @@ -0,0 +1,285 @@ +//////// GuiMods 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") + +//////// GuiMods put Settings, Notifications, Remove disconnected... at top of 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 { +//////// GuiMods put Settings, Notifications, Remove disconnected... at top of list + VisibleItemModel { + MbSubMenu { + description: qsTr("Settings") + subpage: Component { PageSettings {} } + show: settingsAtTop + } + + MbSubMenu { + id: menuNotificationsTop + description: qsTr("Notifications") + item: VBusItem { value: menuNotifications.subpage.summary } + subpage: 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() + } + } + } +//////// end GuiMods put Settings, Notifications, Remove disconnected... at top of list + + VisualDataModel { + model: VeSortFilterProxyModel { + model: DeviceList { + id: deviceList + onRowsAboutToBeRemoved: { + for (var i = first; i <= last; i++) + deviceList.page(i).destroy() + } + } + sortRole: DeviceList.DescriptionRole + dynamicSortFilter: true + naturalSort: true + sortCaseSensitivity: Qt.CaseInsensitive + } + + delegate: MbDevice { + iconId: "icon-toolbar-enter" + service: model.page.service + subpage: model.page + } + } + VisibleItemModel { + MbSubMenu { + id: menuNotifications + description: qsTr("Notifications") + item: VBusItem { value: menuNotifications.subpage.summary } + subpage: PageNotifications { } +//////// GuiMods hide this if added at top + show: !settingsAtTop + } + + MbSubMenu { + description: qsTr("Settings") + subpage: Component { PageSettings {} } +//////// GuiMods hide this if added at top + show: !settingsAtTop + } + + MbOK { + description: qsTr("Remove disconnected devices") + value: qsTr("Press to remove") +//////// GuiMods hide this if added at top + show: !settingsAtTop && deviceList.disconnectedDevices != 0 + editable: true + + function clicked() { + listview.decrementCurrentIndex() + deviceList.removeDisconnected() + } + } + } + } + + Component { + id: vebusPage + PageVebus {} + } + + Component { + id: multiRsPage + PageMultiRs {} + } + + Component { + id: batteryPage + PageBattery {} + } + + Component { + id: solarChargerPage + PageSolarCharger {} + } + + Component { + id: acInPage + PageAcIn {} + } + + Component { + id: acChargerPage + PageAcCharger {} + } + + Component { + id: tankPage + PageTankSensor {} + } + + Component { + id: motorDrivePage + PageMotorDrive {} + } + + Component { + id: inverterPage + PageInverter {} + } + + Component { + id: pulseCounterPage + PagePulseCounter {} + } + + Component { + id: digitalInputPage + PageDigitalInput {} + } + + Component { + id: temperatureSensorPage + PageTemperatureSensor {} + } + + Component { + id: unsupportedDevicePage + PageUnsupportedDevice {} + } + + Component { + id: meteoDevicePage + PageMeteo {} + } + + Component { + id: evChargerPage + PageEvCharger {} + } + + Component { + id: dcMeterPage + PageDcMeter {} + } + + Component { + id: alternatorPage + PageAlternator {} + } + + Component { + id: dcDcConverterPage + PageDcDcConverter {} + } + + function addService(service) + { + var name = service.name + + var page + switch(service.type) + { + case DBusService.DBUS_SERVICE_MULTI: + page = vebusPage + break; + case DBusService.DBUS_SERVICE_MULTI_RS: + page = multiRsPage + break; + case DBusService.DBUS_SERVICE_BATTERY: + page = batteryPage + break; + case DBusService.DBUS_SERVICE_SOLAR_CHARGER: + page = solarChargerPage + break; + case DBusService.DBUS_SERVICE_PV_INVERTER: + page = acInPage + break; + case DBusService.DBUS_SERVICE_AC_CHARGER: + page = acChargerPage + break; + case DBusService.DBUS_SERVICE_TANK: + page = tankPage + break; + case DBusService.DBUS_SERVICE_GRIDMETER: + page = acInPage + break + case DBusService.DBUS_SERVICE_GENSET: + page = acInPage + break + case DBusService.DBUS_SERVICE_MOTOR_DRIVE: + page = motorDrivePage + break + case DBusService.DBUS_SERVICE_INVERTER: + page = inverterPage + break; + case DBusService.DBUS_SERVICE_TEMPERATURE_SENSOR: + page = temperatureSensorPage + break; + case DBusService.DBUS_SERVICE_SYSTEM_CALC: + return; + case DBusService.DBUS_SERVICE_DIGITAL_INPUT: + page = digitalInputPage + break; + case DBusService.DBUS_SERVICE_PULSE_COUNTER: + page = pulseCounterPage + break; + case DBusService.DBUS_SERVICE_UNSUPPORTED: + page = unsupportedDevicePage + break; + case DBusService.DBUS_SERVICE_METEO: + page = meteoDevicePage + break; + case DBusService.DBUS_SERVICE_VECAN: + return; + case DBusService.DBUS_SERVICE_EVCHARGER: + page = evChargerPage + break + case DBusService.DBUS_SERVICE_ACLOAD: + page = acInPage + break + case DBusService.DBUS_SERVICE_HUB4: + return; + case DBusService.DBUS_SERVICE_FUELCELL: + case DBusService.DBUS_SERVICE_DCSOURCE: + case DBusService.DBUS_SERVICE_DCLOAD: + case DBusService.DBUS_SERVICE_DCSYSTEM: + page = dcMeterPage + break + case DBusService.DBUS_SERVICE_ALTERNATOR: + page = alternatorPage + break + case DBusService.DBUS_SERVICE_DCDC: + page = dcDcConverterPage + break + default: + console.log("unknown service " + name) + return; + } + + deviceList.append(service, page.createObject(root, {service: service, bindPrefix: service.name})) + } + + Component.onCompleted: { + for (var i = 0; i < DBusServices.count; i++) + addService(DBusServices.at(i)) + } + + Connections { + target: DBusServices + onDbusServiceFound: addService(service) + } +} diff --git a/FileSets/v3.40~10/PageMain.qml.orig b/FileSets/v3.40~11/PageMain.qml.orig similarity index 100% rename from FileSets/v3.40~10/PageMain.qml.orig rename to FileSets/v3.40~11/PageMain.qml.orig diff --git a/FileSets/v3.40~11/PageSettingsDisplay.qml b/FileSets/v3.40~11/PageSettingsDisplay.qml new file mode 100644 index 00000000..ad1b1187 --- /dev/null +++ b/FileSets/v3.40~11/PageSettingsDisplay.qml @@ -0,0 +1,135 @@ +//////// 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" + + VBusItem { + id: autoBrightnessSetting + bind: Utils.path(bindPrefix, "/AutoBrightness") + isSetting: true + + // max is set to 0 if AutoBrightness is not supported. + // The setting used to be added unconditionally. + property bool hasAutoBrightness: valid && max === 1 + } + + model: VisibleItemModel { + MbSwitch { + id: autoBrightness + name: qsTr("Adaptive brightness") + bind: Utils.path(bindPrefix, "/AutoBrightness") + show: autoBrightnessSetting.hasAutoBrightness + } + + MbItemSlider { + id: backlight + show: item.valid && (!autoBrightnessSetting.hasAutoBrightness || autoBrightnessSetting.value !== 1) + icondId: "icon-items-brightness" + directUpdates: true + item { + bind: Utils.path(bindPrefix, "/Brightness") + isSetting: true + step: 1 + } + writeAccessLevel: User.AccessUser + } + + MbItemOptions { + show: vePlatform.hasScreenSaver + description: qsTr("Display off time") + bind: Utils.path(bindPrefix, "/DisplayOff") + writeAccessLevel: User.AccessUser + possibleValues: [ + MbOption { description: qsTr("10 sec"); value: 10 }, + MbOption { description: qsTr("30 sec"); value: 30 }, + MbOption { description: qsTr("1 min"); value: 60 }, + MbOption { description: qsTr("10 min"); value: 600 }, + MbOption { description: qsTr("30 min"); value: 1800 }, + MbOption { description: qsTr("Never"); value: 0 } + ] + } + + 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" } + } + + 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") + 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. + possibleValues: [ + MbOptionLang { description: "English"; value: "en" }, + MbOptionLang { description: "Čeština"; value: "cs" }, + MbOptionLang { description: "Dansk"; value: "da" }, + MbOptionLang { description: "Deutsch"; value: "de" }, + MbOptionLang { description: "Español"; value: "es" }, + 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: "uk" }, + MbOptionLang { description: "中文"; value: "zh" }, + MbOptionLang { description: "العربية"; value: "ar" } + ] + } + + MbSubMenu { + description: qsTr("Units") + subpage: Component { + PageSettingsDisplayUnits { + title: qsTr("Units") + } + } + } + + MbItemOptions { + property VBusItem updateFeed: VBusItem { bind: "com.victronenergy.settings/Settings/System/ReleaseType" } + show: vePlatform.isGuiv2Installed() && vePlatform.displayPresent() && updateFeed.value >= Updater.FirmwareCandidate + bind: "com.victronenergy.settings/Settings/Gui/RunningVersion" + description: "Onscreen UI (GX Touch & Ekrano)" + writeAccessLevel: User.AccessUser + possibleValues: [ + MbOption { description: "Standard version"; value: 1 }, + MbOption { description: "Gui-v2 version (beta, check the announcement first)"; value: 2 } + ] + onOptionSelected: { + if (newValue === 2) { + vePlatform.splash("Starting the beta UI") + } + } + } + } +} diff --git a/FileSets/v3.40~10/PageSettingsDisplay.qml.orig b/FileSets/v3.40~11/PageSettingsDisplay.qml.orig similarity index 100% rename from FileSets/v3.40~10/PageSettingsDisplay.qml.orig rename to FileSets/v3.40~11/PageSettingsDisplay.qml.orig diff --git a/FileSets/v3.40~11/PageSettingsGenerator.qml b/FileSets/v3.40~11/PageSettingsGenerator.qml new file mode 100644 index 00000000..79afbd25 --- /dev/null +++ b/FileSets/v3.40~11/PageSettingsGenerator.qml @@ -0,0 +1,129 @@ +//// GuiMods +//// 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 + } + } + + MbSubMenu { + show: capabilities.value & warmupCapability + description: qsTr("Warm-up & cool-down") + subpage: + Component { + PageSettingsGeneratorWarmup { + title: qsTr("Warm-up & cool-down") + } + } + } + + MbSwitch { + 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 { + name: qsTr("Alarm when generator is not in auto start mode") + bind: Utils.path(settingsBindPrefix, "/Alarms/AutoStartDisabled") + onClicked: { + if (!checked) { + toast.createToast(qsTr("An alarm will be triggered when auto start function is left disabled for more than 10 minutes."), 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 + } + + MbSubMenu { + id: runtimePage + description: qsTr("Run time and service") + subpage: + Component { + PageGeneratorRuntimeService { + title: qsTr("Run time and service") + startStopBindPrefix: root.startStopBindPrefix + settingsBindPrefix: root.settingsBindPrefix + } + } + } + } +} diff --git a/FileSets/v3.40~10/PageSettingsGenerator.qml.orig b/FileSets/v3.40~11/PageSettingsGenerator.qml.orig similarity index 100% rename from FileSets/v3.40~10/PageSettingsGenerator.qml.orig rename to FileSets/v3.40~11/PageSettingsGenerator.qml.orig diff --git a/FileSets/v3.40~11/PageSettingsGuiMods.qml b/FileSets/v3.40~11/PageSettingsGuiMods.qml new file mode 100644 index 00000000..420a42ac --- /dev/null +++ b/FileSets/v3.40~11/PageSettingsGuiMods.qml @@ -0,0 +1,290 @@ +/////// 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.40~10/PageSettingsGuiMods.qml.orig b/FileSets/v3.40~11/PageSettingsGuiMods.qml.orig similarity index 100% rename from FileSets/v3.40~10/PageSettingsGuiMods.qml.orig rename to FileSets/v3.40~11/PageSettingsGuiMods.qml.orig diff --git a/FileSets/v3.40~11/PageSettingsRelay.qml b/FileSets/v3.40~11/PageSettingsRelay.qml new file mode 100644 index 00000000..60d9d900 --- /dev/null +++ b/FileSets/v3.40~11/PageSettingsRelay.qml @@ -0,0 +1,515 @@ +//////// modified to +//////// add up to 18 relays +//////// 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 + (hasRelay2 ? qsTr("Relay 1") : qsTr("Relay")) + suffix + " " + qsTr("On") + else + return prefix + qsTr("Relay") + " " + relayNumber + suffix + " " + qsTr("On") + } + + model: VisibleItemModel { + 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: 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/v3.40~10/PageSettingsRelay.qml.orig b/FileSets/v3.40~11/PageSettingsRelay.qml.orig similarity index 100% rename from FileSets/v3.40~10/PageSettingsRelay.qml.orig rename to FileSets/v3.40~11/PageSettingsRelay.qml.orig diff --git a/FileSets/v3.40~11/PowerGauge.qml b/FileSets/v3.40~11/PowerGauge.qml new file mode 100644 index 00000000..91166066 --- /dev/null +++ b/FileSets/v3.40~11/PowerGauge.qml @@ -0,0 +1,297 @@ +// 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 + + property bool reversePower: false + property bool useInputCurrentLimit: false + property variant endLabelFontSize: 16 + property color endLabelBackgroundColor: "transparent" + + property int reportedPhaseCount: connection == undefined ? 0 : connection.phaseCount == undefined || ! connection.phaseCount.valid ? 1 : connection.phaseCount.value + property int phaseCount: reportedPhaseCount < 2 ? reportedPhaseCount : (connection.isAcOutput ? connection.l2AndL1OutSummed : connection.splitPhaseL2PassthruDisabled) ? 1 : connection.phaseCount.value + + property string maxForwardPowerParameter: "" + VBusItem { id: maxForwardLimitItem; bind: root.maxForwardPowerParameter } + + 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 maxForwardLimit: useInputCurrentLimit ? inPowerLimit : maxForwardLimitItem.valid ? maxForwardLimitItem.value : 0 + 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 + else + currentValue = 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 (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 (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~10/PowerGauge.qml.orig b/FileSets/v3.40~11/PowerGauge.qml.orig similarity index 100% rename from FileSets/v3.40~10/PowerGauge.qml.orig rename to FileSets/v3.40~11/PowerGauge.qml.orig diff --git a/FileSets/v3.40~11/Tile.qml b/FileSets/v3.40~11/Tile.qml new file mode 100644 index 00000000..a28bc1a8 --- /dev/null +++ b/FileSets/v3.40~11/Tile.qml @@ -0,0 +1,65 @@ +import QtQuick 1.1 + +Rectangle { + id: root + +////// GuiMods — DarkMode + property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } + property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 + + color: "#009ec6" + border.width: 2 +////// GuiMods — DarkMode + border.color: !darkMode ? "#fff" : "#202020" + clip: true + + property string title + property alias values: column.children + property bool readOnly: true + property bool editable: false + property bool editMode: false + property bool isCurrentItem: ListView.isCurrentItem + property int contentHeight: column.y + column.height + property bool show: true + + Text { + id: titleField + font.pixelSize: 13 + text: title +////// GuiMods — DarkMode + color: !darkMode ? "white" : "#ddd" + height: text === "" ? 0 : paintedHeight + anchors { + top: parent.top; topMargin: 5 + left: parent.left; leftMargin: 5 + } + } + + Rectangle { + id: titleLine + width: parent.width - 10 + height: 1 + visible: title !== "" +////// GuiMods — DarkMode + color: !darkMode ? "white" : "#ddd" + anchors { + top: titleField.bottom + left: titleField.left + } + } + + Column { + id: column + anchors { + top: titleLine.bottom; topMargin: 3 + horizontalCenter: parent.horizontalCenter + } + } + + MbIcon { + id: editIcon + iconId: root.isCurrentItem ? "icon-tile-edit-active" : "icon-tile-edit" + visible: (root.isCurrentItem || root.focus) && root.editable && !editMode + anchors { right: parent.right; bottom: column.bottom; margins: 3} + } +} diff --git a/FileSets/v3.40~10/Tile.qml.orig b/FileSets/v3.40~11/Tile.qml.orig similarity index 100% rename from FileSets/v3.40~10/Tile.qml.orig rename to FileSets/v3.40~11/Tile.qml.orig diff --git a/FileSets/v3.40~11/TileDigIn.qml b/FileSets/v3.40~11/TileDigIn.qml new file mode 100644 index 00000000..492b8b2d --- /dev/null +++ b/FileSets/v3.40~11/TileDigIn.qml @@ -0,0 +1,133 @@ +// 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~10/TileDigIn.qml.orig b/FileSets/v3.40~11/TileDigIn.qml.orig similarity index 100% rename from FileSets/v3.40~10/TileDigIn.qml.orig rename to FileSets/v3.40~11/TileDigIn.qml.orig diff --git a/FileSets/v3.40~11/TileRelay.qml b/FileSets/v3.40~11/TileRelay.qml new file mode 100644 index 00000000..3c6bb0ca --- /dev/null +++ b/FileSets/v3.40~11/TileRelay.qml @@ -0,0 +1,501 @@ +// 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: 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") + 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 (!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/v3.40~10/TileRelay.qml.orig b/FileSets/v3.40~11/TileRelay.qml.orig similarity index 100% rename from FileSets/v3.40~10/TileRelay.qml.orig rename to FileSets/v3.40~11/TileRelay.qml.orig diff --git a/FileSets/v3.40~11/TileText.qml b/FileSets/v3.40~11/TileText.qml new file mode 100644 index 00000000..bce0789c --- /dev/null +++ b/FileSets/v3.40~11/TileText.qml @@ -0,0 +1,13 @@ +import QtQuick 1.1 + +Text { +////// GuiMods — DarkMode + property VBusItem darkModeItem: VBusItem { bind: "com.victronenergy.settings/Settings/GuiMods/DarkMode" } + property bool darkMode: darkModeItem.valid && darkModeItem.value == 1 + + font.pixelSize: 14 +////// GuiMods — DarkMode + color: !darkMode ? "white" : "#e1e1e1" + width: parent.width + horizontalAlignment: Text.AlignHCenter +} diff --git a/FileSets/v3.40~10/TileText.qml.orig b/FileSets/v3.40~11/TileText.qml.orig similarity index 100% rename from FileSets/v3.40~10/TileText.qml.orig rename to FileSets/v3.40~11/TileText.qml.orig diff --git a/FileSets/v3.40~11/attributes.csv b/FileSets/v3.40~11/attributes.csv new file mode 100644 index 00000000..21fb2a18 --- /dev/null +++ b/FileSets/v3.40~11/attributes.csv @@ -0,0 +1,735 @@ +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,/Devices/0/Settings/AssistCurrentBoostFactor,d,,106,uint16,100,W +com.victronenergy.vebus,/Devices/1/Settings/AssistCurrentBoostFactor,d,,107,uint16,100,W +com.victronenergy.vebus,/Devices/2/Settings/AssistCurrentBoostFactor,d,,108,uint16,100,W +com.victronenergy.vebus,/Devices/3/Settings/AssistCurrentBoostFactor,d,,109,uint16,100,W +com.victronenergy.vebus,/Devices/4/Settings/AssistCurrentBoostFactor,d,,110,uint16,100,W +com.victronenergy.vebus,/Devices/5/Settings/AssistCurrentBoostFactor,d,,111,uint16,100,W +com.victronenergy.vebus,/Devices/6/Settings/AssistCurrentBoostFactor,d,,112,uint16,100,W +com.victronenergy.vebus,/Devices/7/Settings/AssistCurrentBoostFactor,d,,113,uint16,100,W +com.victronenergy.vebus,/Devices/8/Settings/AssistCurrentBoostFactor,d,,114,uint16,100,W +com.victronenergy.vebus,/Devices/9/Settings/AssistCurrentBoostFactor,d,,115,uint16,100,W +com.victronenergy.vebus,/Devices/10/Settings/AssistCurrentBoostFactor,d,,116,uint16,100,W +com.victronenergy.vebus,/Devices/11/Settings/AssistCurrentBoostFactor,d,,117,uint16,100,W +com.victronenergy.vebus,/Devices/0/Settings/InverterOutputVoltage,d,V AC,118,uint16,100,W +com.victronenergy.vebus,/Devices/1/Settings/InverterOutputVoltage,d,V AC,119,uint16,100,W +com.victronenergy.vebus,/Devices/2/Settings/InverterOutputVoltage,d,V AC,120,uint16,100,W +com.victronenergy.vebus,/Devices/3/Settings/InverterOutputVoltage,d,V AC,121,uint16,100,W +com.victronenergy.vebus,/Devices/4/Settings/InverterOutputVoltage,d,V AC,122,uint16,100,W +com.victronenergy.vebus,/Devices/5/Settings/InverterOutputVoltage,d,V AC,123,uint16,100,W +com.victronenergy.vebus,/Devices/6/Settings/InverterOutputVoltage,d,V AC,124,uint16,100,W +com.victronenergy.vebus,/Devices/7/Settings/InverterOutputVoltage,d,V AC,125,uint16,100,W +com.victronenergy.vebus,/Devices/8/Settings/InverterOutputVoltage,d,V AC,126,uint16,100,W +com.victronenergy.vebus,/Devices/9/Settings/InverterOutputVoltage,d,V AC,127,uint16,100,W +com.victronenergy.vebus,/Devices/10/Settings/InverterOutputVoltage,d,V AC,128,uint16,100,W +com.victronenergy.vebus,/Devices/11/Settings/InverterOutputVoltage,d,V AC,129,uint16,100,W +com.victronenergy.vebus,/Devices/0/Settings/PowerAssistEnabled,d,,130,uint16,1,R +com.victronenergy.vebus,/Devices/1/Settings/PowerAssistEnabled,d,,131,uint16,1,R +com.victronenergy.vebus,/Devices/2/Settings/PowerAssistEnabled,d,,132,uint16,1,R +com.victronenergy.vebus,/Devices/3/Settings/PowerAssistEnabled,d,,133,uint16,1,R +com.victronenergy.vebus,/Devices/4/Settings/PowerAssistEnabled,d,,134,uint16,1,R +com.victronenergy.vebus,/Devices/5/Settings/PowerAssistEnabled,d,,135,uint16,1,R +com.victronenergy.vebus,/Devices/6/Settings/PowerAssistEnabled,d,,136,uint16,1,R +com.victronenergy.vebus,/Devices/7/Settings/PowerAssistEnabled,d,,137,uint16,1,R +com.victronenergy.vebus,/Devices/8/Settings/PowerAssistEnabled,d,,138,uint16,1,R +com.victronenergy.vebus,/Devices/9/Settings/PowerAssistEnabled,d,,139,uint16,1,R +com.victronenergy.vebus,/Devices/10/Settings/PowerAssistEnabled,d,,140,uint16,1,R +com.victronenergy.vebus,/Devices/11/Settings/PowerAssistEnabled,d,,141,uint16,1,R +com.victronenergy.vebus,/Devices/0/Settings/UpsFunction,u,,142,uint16,1,R +com.victronenergy.vebus,/Devices/1/Settings/UpsFunction,u,,143,uint16,1,R +com.victronenergy.vebus,/Devices/2/Settings/UpsFunction,u,,144,uint16,1,R +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.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.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=Disconnected;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.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=Disconnected;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;11=ExtTransferSwitch,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 fault;9=Welded contacts;10=CP Input shorted;11=Residual current detected;12=Under voltage detected;13=Overvoltage detected;14=Overheating detected,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,uint16,10,R +com.victronenergy.multi,/Ac/In/1/L2/I,d,A AC,4504,uint16,10,R +com.victronenergy.multi,/Ac/In/1/L3/I,d,A AC,4505,uint16,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,uint16,10,R +com.victronenergy.multi,/Ac/Out/L2/I,d,A AC,4514,uint16,10,R +com.victronenergy.multi,/Ac/Out/L3/I,d,A AC,4515,uint16,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 diff --git a/FileSets/v3.40~10/attributes.csv.orig b/FileSets/v3.40~11/attributes.csv.orig similarity index 100% rename from FileSets/v3.40~10/attributes.csv.orig rename to FileSets/v3.40~11/attributes.csv.orig diff --git a/FileSets/v3.40~11/dbus_digitalinputs.py b/FileSets/v3.40~11/dbus_digitalinputs.py new file mode 100755 index 00000000..a49e9c6e --- /dev/null +++ b/FileSets/v3.40~11/dbus_digitalinputs.py @@ -0,0 +1,651 @@ +#!/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.23' +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']) + + +class Generator(PinAlarm): + _product_name = "Generator" + type_id = 9 + translation = 5 # running, stopped + + def __init__(self, *args, **kwargs): + super(Generator, self).__init__(*args, **kwargs) + # Periodically rewrite the generator selection. The Multi may reset + # causing this to be lost, or a race condition on startup may cause + # it to not be set properly. + self._timer = GLib.timeout_add(30000, + lambda: self.select_generator(self.level ^ self.settings['invert'] ^ 1) or True) + +#### added for ExtTransferSwitch package + self.mainVeBusServiceItem = None +#### end added for ExtTransferSwitch package + + + def select_generator(self, v): + + # Find all vebus services, and let them know + try: + services = [n for n in self.bus.list_names() if n.startswith( + 'com.victronenergy.vebus.')] + for n in services: +#### added for ExtTransferSwitch package + # skip this service if it is the main VE.Bus device + # processing for that is handled in ExtTransferSwitch + try: + if self.mainVeBusServiceItem == None: + self.mainVeBusServiceItem = VeDbusItemImport(self.bus, + "com.victronenergy.service", "/VebusService") + if n == self.mainVeBusService.get_value (): + continue + except: + pass +#### end added for ExtTransferSwitch package + + self.bus.call_async(n, '/Ac/Control/RemoteGeneratorSelected', None, + 'SetValue', 'v', [v], None, None) + except dbus.exceptions.DBusException: + print ("DBus exception setting RemoteGeneratorSelected") + traceback.print_exc() + + def toggle(self, level): + super(Generator, self).toggle(level) + + # Follow the same inversion sense as for display + self.select_generator(level ^ self.settings['invert'] ^ 1) + + def deactivate(self): + super(Generator, self).deactivate() + # When deactivating, reset the generator selection state + self.select_generator(0) + + # And kill the periodic job + if self._timer is not None: + GLib.source_remove(self._timer) + self._timer = None + +# 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 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.40~10/dbus_digitalinputs.py.orig b/FileSets/v3.40~11/dbus_digitalinputs.py.orig similarity index 100% rename from FileSets/v3.40~10/dbus_digitalinputs.py.orig rename to FileSets/v3.40~11/dbus_digitalinputs.py.orig diff --git a/FileSets/v3.40~11/dbus_generator.py b/FileSets/v3.40~11/dbus_generator.py new file mode 100755 index 00000000..d6f8f00d --- /dev/null +++ b/FileSets/v3.40~11/dbus_generator.py @@ -0,0 +1,348 @@ +#!/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 +#### 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 genset +from version import softwareversion + +class Generator(object): + def __init__(self): + self._exit = False + self._instances = {} + self._modules = [relay, genset] + + # 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], + 'serviceinterval': ['/Settings/{0}/ServiceInterval', 0, 0, 0], + 'lastservicereset': ['/Settings/{0}/LastServiceReset', 0, 0, 0], + 'accumulateddaily': ['/Settings/{0}/AccumulatedDaily', '', 0, 0, True], + 'accumulatedtotal': ['/Settings/{0}/AccumulatedTotal', 0, 0, 0, True], # Internal, can't be reset by the user + 'accumulatedtotalOffset': ['/Settings/{0}/AccumulatedTotalOffset', 0, 0, 0], # For calculating user runtime +#### GuiMods + '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], + 'socstarttimer': ['/Settings/{0}/Soc/StartTimer', 0, 0, 10000], + 'socstoptimer': ['/Settings/{0}/Soc/StopTimer', 0, 0, 10000], + '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], + 'autostartdisabledalarm': ['/Settings/{0}/Alarms/AutoStartDisabled', 0, 0, 1], + # Warm-up and Cool-down + 'warmuptime': ['/Settings/{0}/WarmUpTime', 0, 0, 600], + 'cooldowntime': ['/Settings/{0}/CoolDownTime', 0, 0, 600], + 'generatorstoptime': ['/Settings/{0}/GeneratorStopTime', 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) + + 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) + 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.40~10/dbus_generator.py.orig b/FileSets/v3.40~11/dbus_generator.py.orig similarity index 100% rename from FileSets/v3.40~10/dbus_generator.py.orig rename to FileSets/v3.40~11/dbus_generator.py.orig diff --git a/FileSets/v3.40~11/dbus_systemcalc.py b/FileSets/v3.40~11/dbus_systemcalc.py new file mode 100755 index 00000000..80bf657f --- /dev/null +++ b/FileSets/v3.40~11/dbus_systemcalc.py @@ -0,0 +1,1488 @@ +#!/usr/bin/python3 -u +# -*- coding: utf-8 -*- + +#### modified for GuiMods + +from dbus.mainloop.glib import DBusGMainLoop +import dbus +import argparse +import sys +import os +import json +import time +import re +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 get_vrm_portal_id, exit_on_error +from dbusmonitor import DbusMonitor +from settingsdevice import SettingsDevice +from logger import setup_logging +import delegates +from sc_utils import safeadd as _safeadd, safemax as _safemax + +softwareVersion = '2.162' + +class SystemCalc: + STATE_IDLE = 0 + STATE_CHARGING = 1 + STATE_DISCHARGING = 2 + BATSERVICE_DEFAULT = 'default' + BATSERVICE_NOBATTERY = 'nobattery' + def __init__(self): + # Why this dummy? Because DbusMonitor expects these values to be there, even though we don't + # need them. So just add some dummy data. This can go away when DbusMonitor is more generic. + dummy = {'code': None, 'whenToLog': 'configChange', 'accessLevel': None} + dbus_tree = { + 'com.victronenergy.solarcharger': { + '/Connected': dummy, + '/ProductName': dummy, + '/Mgmt/Connection': dummy, + '/Dc/0/Voltage': dummy, + '/Dc/0/Current': dummy, + '/Load/I': dummy, + '/FirmwareVersion': dummy}, + 'com.victronenergy.battery': { + '/Connected': dummy, + '/ProductName': dummy, + '/Mgmt/Connection': dummy, + '/DeviceInstance': dummy, + '/Dc/0/Voltage': dummy, + '/Dc/1/Voltage': dummy, + '/Dc/0/Current': dummy, + '/Dc/0/Power': dummy, + '/Soc': dummy, + '/Sense/Current': dummy, + '/TimeToGo': dummy, + '/ConsumedAmphours': dummy, + '/ProductId': dummy, + '/CustomName': dummy, + '/Info/MaxChargeVoltage': dummy}, + 'com.victronenergy.vebus' : { + '/Ac/ActiveIn/ActiveInput': dummy, + '/Ac/ActiveIn/L1/P': dummy, + '/Ac/ActiveIn/L2/P': dummy, + '/Ac/ActiveIn/L3/P': dummy, + '/Ac/ActiveIn/L1/I': dummy, + '/Ac/ActiveIn/L2/I': dummy, + '/Ac/ActiveIn/L3/I': dummy, + '/Ac/Out/L1/P': dummy, + '/Ac/Out/L2/P': dummy, + '/Ac/Out/L3/P': dummy, + '/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, + '/Mgmt/Connection': dummy, + '/Mode': dummy, + '/State': dummy, + '/Dc/0/Voltage': dummy, + '/Dc/0/Current': dummy, + '/Dc/0/Power': dummy, + '/Soc': dummy}, + 'com.victronenergy.fuelcell': { + '/Connected': dummy, + '/ProductName': dummy, + '/Mgmt/Connection': dummy, + '/Dc/0/Voltage': dummy, + '/Dc/0/Current': dummy}, + 'com.victronenergy.charger': { + '/Connected': dummy, + '/ProductName': dummy, + '/Mgmt/Connection': dummy, + '/Dc/0/Voltage': dummy, + '/Dc/0/Current': dummy, + '/Dc/1/Voltage': dummy, + '/Dc/1/Current': dummy, + '/Dc/2/Voltage': dummy, + '/Dc/2/Current': dummy}, + 'com.victronenergy.grid' : { + '/Connected': dummy, + '/ProductName': dummy, + '/Mgmt/Connection': dummy, + '/ProductId' : dummy, + '/DeviceType' : dummy, + '/Ac/L1/Power': dummy, + '/Ac/L2/Power': dummy, + '/Ac/L3/Power': dummy, + '/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}, + 'com.victronenergy.genset' : { + '/Connected': dummy, + '/ProductName': dummy, + '/Mgmt/Connection': dummy, + '/ProductId' : dummy, + '/DeviceType' : dummy, + '/Ac/L1/Power': dummy, + '/Ac/L2/Power': dummy, + '/Ac/L3/Power': dummy, + '/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, + '/Settings/SystemSetup/AcInput2' : dummy, + '/Settings/CGwacs/RunWithoutGridMeter' : dummy, + '/Settings/System/TimeZone' : dummy}, + 'com.victronenergy.temperature': { + '/Connected': dummy, + '/ProductName': dummy, + '/Mgmt/Connection': dummy}, + 'com.victronenergy.inverter': { + '/Connected': dummy, + '/ProductName': dummy, + '/Mgmt/Connection': dummy, + '/Dc/0/Voltage': dummy, + '/Dc/0/Current': dummy, + '/Dc/0/Power': dummy, + '/Ac/Out/L1/P': dummy, + '/Ac/Out/L1/S': dummy, + '/Ac/Out/L1/V': dummy, + '/Ac/Out/L1/I': dummy, + '/Ac/Out/L2/P': dummy, + '/Ac/Out/L2/S': dummy, + '/Ac/Out/L2/V': dummy, + '/Ac/Out/L2/I': dummy, + '/Ac/Out/L3/P': dummy, + '/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': { + '/Connected': dummy, + '/ProductName': dummy, + '/Mgmt/Connection': dummy, + '/Dc/0/Voltage': dummy, + '/Dc/0/Current': dummy, + '/Dc/0/Power': dummy, + '/Ac/ActiveIn/ActiveInput': dummy, + '/Ac/In/1/Type': dummy, + '/Ac/In/2/Type': dummy, + '/Ac/In/1/L1/P': dummy, + '/Ac/In/1/L1/I': dummy, + '/Ac/In/2/L1/P': dummy, + '/Ac/In/2/L1/I': dummy, + '/Ac/Out/L1/P': dummy, + '/Ac/Out/L1/V': dummy, + '/Ac/Out/L1/I': dummy, + '/Ac/In/1/L2/P': dummy, + '/Ac/In/1/L2/I': dummy, + '/Ac/In/2/L2/P': dummy, + '/Ac/In/2/L2/I': dummy, + '/Ac/Out/L2/P': dummy, + '/Ac/Out/L2/V': dummy, + '/Ac/Out/L2/I': dummy, + '/Ac/In/1/L3/P': dummy, + '/Ac/In/1/L3/I': dummy, + '/Ac/In/2/L3/P': dummy, + '/Ac/In/2/L3/I': dummy, + '/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': { + '/Dc/0/Voltage': dummy, + '/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 + } + } + + self._modules = [ + delegates.Multi(), + delegates.HubTypeSelect(), + delegates.VebusSocWriter(), + delegates.ServiceMapper(), + delegates.RelayState(), + delegates.BuzzerControl(), + delegates.LgCircuitBreakerDetect(), + delegates.BatterySoc(self), + delegates.Dvcc(self), + delegates.BatterySense(self), + delegates.BatterySettings(self), + delegates.SystemState(self), + delegates.BatteryLife(), + delegates.ScheduledCharging(), + delegates.SourceTimers(), + delegates.BatteryData(), + delegates.Gps(), + delegates.AcInputs(), + delegates.GensetStartStop(), + delegates.SocSync(self), + delegates.PvInverters(), + delegates.BatteryService(self), + delegates.CanBatterySense(), + delegates.InverterCharger(), + delegates.DynamicEss(), + delegates.LoadShedding()] + + for m in self._modules: + for service, paths in m.get_input(): + s = dbus_tree.setdefault(service, {}) + for path in paths: + s[path] = dummy + + 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]} + + 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:]) + + self._settings = self._create_settings(supported_settings, self._handlechangedsetting) + + self._dbusservice = self._create_dbus_service() + + for m in self._modules: + m.set_sources(self._dbusmonitor, self._settings, self._dbusservice) + + # At this moment, VRM portal ID is the MAC address of the CCGX. Anyhow, it should be string uniquely + # identifying the CCGX. + self._dbusservice.add_path('/Serial', value=get_vrm_portal_id()) + self._dbusservice.add_path( + '/AvailableBatteryServices', value=None, gettextcallback=self._gettext) + self._dbusservice.add_path( + '/AvailableBatteryMeasurements', value=None) + self._dbusservice.add_path( + '/AutoSelectedBatteryService', value=None, gettextcallback=self._gettext) + self._dbusservice.add_path( + '/AutoSelectedBatteryMeasurement', value=None, gettextcallback=self._gettext) + self._dbusservice.add_path( + '/ActiveBatteryService', value=None, gettextcallback=self._gettext) + self._dbusservice.add_path( + '/Dc/Battery/BatteryService', value=None) + self._summeditems = { + '/Ac/Grid/L1/Power': {'gettext': '%.0F W'}, + '/Ac/Grid/L2/Power': {'gettext': '%.0F W'}, + '/Ac/Grid/L3/Power': {'gettext': '%.0F W'}, + '/Ac/Grid/L1/Current': {'gettext': '%.1F A'}, + '/Ac/Grid/L2/Current': {'gettext': '%.1F A'}, + '/Ac/Grid/L3/Current': {'gettext': '%.1F A'}, + '/Ac/Grid/NumberOfPhases': {'gettext': '%.0F W'}, + '/Ac/Grid/ProductId': {'gettext': '%s'}, + '/Ac/Grid/DeviceType': {'gettext': '%s'}, + '/Ac/Genset/L1/Power': {'gettext': '%.0F W'}, + '/Ac/Genset/L2/Power': {'gettext': '%.0F W'}, + '/Ac/Genset/L3/Power': {'gettext': '%.0F W'}, + '/Ac/Genset/L1/Current': {'gettext': '%.1F A'}, + '/Ac/Genset/L2/Current': {'gettext': '%.1F A'}, + '/Ac/Genset/L3/Current': {'gettext': '%.1F A'}, + '/Ac/Genset/NumberOfPhases': {'gettext': '%.0F W'}, + '/Ac/Genset/ProductId': {'gettext': '%s'}, + '/Ac/Genset/DeviceType': {'gettext': '%s'}, + '/Ac/ConsumptionOnOutput/NumberOfPhases': {'gettext': '%.0F W'}, + '/Ac/ConsumptionOnOutput/L1/Power': {'gettext': '%.0F W'}, + '/Ac/ConsumptionOnOutput/L2/Power': {'gettext': '%.0F W'}, + '/Ac/ConsumptionOnOutput/L3/Power': {'gettext': '%.0F W'}, + '/Ac/ConsumptionOnOutput/L1/Current': {'gettext': '%.1F A'}, + '/Ac/ConsumptionOnOutput/L2/Current': {'gettext': '%.1F A'}, + '/Ac/ConsumptionOnOutput/L3/Current': {'gettext': '%.1F A'}, + '/Ac/ConsumptionOnInput/NumberOfPhases': {'gettext': '%.0F W'}, + '/Ac/ConsumptionOnInput/L1/Power': {'gettext': '%.0F W'}, + '/Ac/ConsumptionOnInput/L2/Power': {'gettext': '%.0F W'}, + '/Ac/ConsumptionOnInput/L3/Power': {'gettext': '%.0F W'}, + '/Ac/ConsumptionOnInput/L1/Current': {'gettext': '%.1F A'}, + '/Ac/ConsumptionOnInput/L2/Current': {'gettext': '%.1F A'}, + '/Ac/ConsumptionOnInput/L3/Current': {'gettext': '%.1F A'}, + '/Ac/Consumption/NumberOfPhases': {'gettext': '%.0F W'}, + '/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'}, + '/Dc/Pv/Power': {'gettext': '%.0F W'}, + '/Dc/Pv/Current': {'gettext': '%.1F A'}, + '/Dc/Battery/Voltage': {'gettext': '%.2F V'}, + '/Dc/Battery/VoltageService': {'gettext': '%s'}, + '/Dc/Battery/Current': {'gettext': '%.1F A'}, + '/Dc/Battery/Power': {'gettext': '%.0F W'}, + '/Dc/Battery/State': {'gettext': lambda v: ({ + self.STATE_IDLE: 'Idle', + self.STATE_CHARGING: 'Charging', + self.STATE_DISCHARGING: 'Discharging'}.get(v, 'Unknown'))}, + '/Dc/Battery/TimeToGo': {'gettext': '%.0F s'}, + '/Dc/Battery/ConsumedAmphours': {'gettext': '%.1F Ah'}, + '/Dc/Battery/ProductId': {'gettext': '0x%x'}, + '/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'}, + '/Ac/ActiveIn/L1/Power': {'gettext': '%.0F W'}, + '/Ac/ActiveIn/L2/Power': {'gettext': '%.0F W'}, + '/Ac/ActiveIn/L3/Power': {'gettext': '%.0F W'}, + '/Ac/ActiveIn/L1/Current': {'gettext': '%.1F A'}, + '/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: + self._summeditems.update(m.get_output()) + + for path in self._summeditems.keys(): + self._dbusservice.add_path(path, value=None, gettextcallback=self._gettext) + + self._batteryservice = None + self._determinebatteryservice() + + if self._batteryservice is None: + logger.info("Battery service initialized to None (setting == %s)" % + self._settings['batteryservice']) + + 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() + + GLib.timeout_add(1000, exit_on_error, self._handletimertick) + + 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") + + def _handlechangedsetting(self, setting, oldvalue, newvalue): + self._determinebatteryservice() + self._changed = True + + # Give our delegates a chance to react on a settings change + for m in self._modules: + m.settings_changed(setting, oldvalue, newvalue) + + def _find_device_instance(self, serviceclass, instance): + """ Gets a mapping of services vs DeviceInstance using + get_service_list. Then searches for the specified DeviceInstance + and returns the service name. """ + services = self._dbusmonitor.get_service_list(classfilter=serviceclass) + + for k, v in services.items(): + if v == instance: + return k + return None + + def _determinebatteryservice(self): + auto_battery_service = self._autoselect_battery_service() + auto_battery_measurement = None + auto_selected = False + if auto_battery_service is not None: + services = self._dbusmonitor.get_service_list() + if auto_battery_service in services: + auto_battery_measurement = \ + self._get_instance_service_name(auto_battery_service, services[auto_battery_service]) + auto_battery_measurement = auto_battery_measurement.replace('.', '_').replace('/', '_') + '/Dc/0' + self._dbusservice['/AutoSelectedBatteryMeasurement'] = auto_battery_measurement + + if self._settings['batteryservice'] == self.BATSERVICE_DEFAULT: + auto_selected = True + newbatteryservice = auto_battery_service + self._dbusservice['/AutoSelectedBatteryService'] = ( + 'No battery monitor found' if newbatteryservice is None else + self._get_readable_service_name(newbatteryservice)) + + elif self._settings['batteryservice'] == self.BATSERVICE_NOBATTERY: + self._dbusservice['/AutoSelectedBatteryService'] = None + newbatteryservice = None + + else: + self._dbusservice['/AutoSelectedBatteryService'] = None + + s = self._settings['batteryservice'].split('/') + if len(s) != 2: + logger.error("The battery setting (%s) is invalid!" % self._settings['batteryservice']) + serviceclass = s[0] + instance = int(s[1]) if len(s) == 2 else None + + # newbatteryservice might turn into None if a chosen battery + # monitor no longer exists. Don't auto change the setting (it might + # come back) and don't autoselect another. + newbatteryservice = self._find_device_instance(serviceclass, instance) + + if newbatteryservice != self._batteryservice: + services = self._dbusmonitor.get_service_list() + instance = services.get(newbatteryservice, None) + if instance is None: + battery_service = None + else: + battery_service = self._get_instance_service_name(newbatteryservice, instance) + self._dbusservice['/ActiveBatteryService'] = battery_service + logger.info("Battery service, setting == %s, changed from %s to %s (%s)" % + (self._settings['batteryservice'], self._batteryservice, newbatteryservice, instance)) + + # Battery service has changed. Notify delegates. + self._dbusservice['/Dc/Battery/BatteryService'] = self._batteryservice = newbatteryservice + for m in self._modules: + m.battery_service_changed(auto_selected, self._batteryservice, newbatteryservice) + + def _autoselect_battery_service(self): + # Default setting business logic: + # first try to use a battery service (BMV or Lynx Shunt VE.Can). If there + # is more than one battery service, just use a random one. If no battery service is + # available, check if there are not Solar chargers and no normal chargers. If they are not + # there, assume this is a hub-2, hub-3 or hub-4 system and use VE.Bus SOC. + batteries = self._get_connected_service_list('com.victronenergy.battery') + + # Pick the battery service that has the lowest DeviceInstance, giving + # preference to those with a BMS. + if len(batteries) > 0: + batteries = [ + (not self._dbusmonitor.seen(s, '/Info/MaxChargeVoltage'), i, s) + for s, i in batteries.items()] + return sorted(batteries, key=lambda x: x[:2])[0][2] + + # No battery services, and there is a charger in the system. Abandon + # hope. + if self._get_first_connected_service('com.victronenergy.charger') is not None: + return None + + # Also no Multi, then give up. + vebus_service = self._get_service_having_lowest_instance('com.victronenergy.vebus') + if vebus_service is None: + # No VE.Bus, but maybe there is an inverter with built-in SOC + # tracking, eg RS Smart or Multi RS. + inverter = self._get_service_having_lowest_instance('com.victronenergy.multi') + if inverter and self._dbusmonitor.get_value(inverter[0], '/Soc') is not None: + return inverter[0] + + inverter = self._get_service_having_lowest_instance('com.victronenergy.inverter') + if inverter and self._dbusmonitor.get_value(inverter[0], '/Soc') is not None: + return inverter[0] + + return None + + # There is a Multi, it supports tracking external charge current from + # solarchargers, and there are no DC loads. Then use it. + if self._dbusmonitor.get_value( + vebus_service[0], '/ExtraBatteryCurrent') is not None \ + and self._get_first_connected_service('com.victronenergy.dcsystem') is None \ + and self._settings['hasdcsystem'] == 0: + return vebus_service[0] + + # Multi does not support tracking solarcharger current, and we have + # solar chargers. Then we cannot use it. + if self._get_first_connected_service('com.victronenergy.solarcharger') is not None: + return None + + # Only a Multi, no other chargers. Then we can use it. + return vebus_service[0] + + @property + def batteryservice(self): + return self._batteryservice + + # Called on a one second timer + def _handletimertick(self): + if self._changed: + self._updatevalues() + self._changed = False + + return True # keep timer running + + def _updatevalues(self): + # ==== PREPARATIONS ==== + newvalues = {} + + # Set the user timezone + if 'TZ' not in os.environ: + tz = self._dbusmonitor.get_value('com.victronenergy.settings', '/Settings/System/TimeZone') + if tz is not None: + os.environ['TZ'] = tz + time.tzset() + + # Determine values used in logic below + vebusses = self._dbusmonitor.get_service_list('com.victronenergy.vebus') + vebuspower = 0 + for vebus in vebusses: + v = self._dbusmonitor.get_value(vebus, '/Dc/0/Voltage') + i = self._dbusmonitor.get_value(vebus, '/Dc/0/Current') + if v is not None and i is not None: + vebuspower += v * i + + # ==== PVINVERTERS ==== + # Work is done in pv-inverter delegate. Ideally all of this should + # happen in update_values in the delegate, but these values are + # used below in calculating consumption, so until this is less + # unwieldy this has to stay here. + # TODO this can go away once consumption below no longer relies + # on these values, or has moved to its own delegate. + newvalues.update(delegates.PvInverters.instance.get_totals()) + self._compute_number_of_phases('/Ac/PvOnGrid', newvalues) + self._compute_number_of_phases('/Ac/PvOnOutput', newvalues) + self._compute_number_of_phases('/Ac/PvOnGenset', newvalues) + + # ==== SOLARCHARGERS ==== + solarchargers = self._dbusmonitor.get_service_list('com.victronenergy.solarcharger') + solarcharger_batteryvoltage = None + solarcharger_batteryvoltage_service = None + solarchargers_charge_power = 0 + solarchargers_loadoutput_power = None + + for solarcharger in solarchargers: + v = self._dbusmonitor.get_value(solarcharger, '/Dc/0/Voltage') + if v is None: + continue + i = self._dbusmonitor.get_value(solarcharger, '/Dc/0/Current') + if i is None: + continue + l = self._dbusmonitor.get_value(solarcharger, '/Load/I', 0) + + if l is not None: + if solarchargers_loadoutput_power is None: + solarchargers_loadoutput_power = l * v + else: + solarchargers_loadoutput_power += l * v + + solarchargers_charge_power += v * i + + # Note that this path is not in the _summeditems{}, making for it to not be + # published on D-Bus. Which fine. The only one needing it is the vebussocwriter- + # delegate. + if '/Dc/Pv/ChargeCurrent' not in newvalues: + newvalues['/Dc/Pv/ChargeCurrent'] = i + else: + newvalues['/Dc/Pv/ChargeCurrent'] += i + + if '/Dc/Pv/Power' not in newvalues: + newvalues['/Dc/Pv/Power'] = v * _safeadd(i, l) + newvalues['/Dc/Pv/Current'] = _safeadd(i, l) + solarcharger_batteryvoltage = v + solarcharger_batteryvoltage_service = solarcharger + else: + newvalues['/Dc/Pv/Power'] += v * _safeadd(i, l) + newvalues['/Dc/Pv/Current'] += _safeadd(i, l) + + # ==== FUELCELLS ==== + fuelcells = self._dbusmonitor.get_service_list('com.victronenergy.fuelcell') + fuelcell_batteryvoltage = None + fuelcell_batteryvoltage_service = None + for fuelcell in fuelcells: + # Assume the battery connected to output 0 is the main battery + v = self._dbusmonitor.get_value(fuelcell, '/Dc/0/Voltage') + if v is None: + continue + + fuelcell_batteryvoltage = v + fuelcell_batteryvoltage_service = fuelcell + + i = self._dbusmonitor.get_value(fuelcell, '/Dc/0/Current') + if i is None: + continue + + if '/Dc/FuelCell/Power' not in newvalues: + newvalues['/Dc/FuelCell/Power'] = v * i + else: + newvalues['/Dc/FuelCell/Power'] += v * i + + # ==== 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 + charger_batteryvoltage_service = None + for charger in chargers: + # Assume the battery connected to output 0 is the main battery + v = self._dbusmonitor.get_value(charger, '/Dc/0/Voltage') + if v is None: + continue + + charger_batteryvoltage = v + charger_batteryvoltage_service = charger + + i = self._dbusmonitor.get_value(charger, '/Dc/0/Current') + if i is None: + continue + + if '/Dc/Charger/Power' not in newvalues: + newvalues['/Dc/Charger/Power'] = v * i + else: + newvalues['/Dc/Charger/Power'] += v * i + + # ==== Other Inverters and Inverter/Chargers ==== + _other_inverters = sorted((di, s) for s, di in self._dbusmonitor.get_service_list('com.victronenergy.multi').items()) + \ + sorted((di, s) for s, di in self._dbusmonitor.get_service_list('com.victronenergy.inverter').items()) + non_vebus_inverters = [x[1] for x in _other_inverters] + non_vebus_inverter = None + if non_vebus_inverters: + non_vebus_inverter = non_vebus_inverters[0] + + # For RS Smart and Multi RS, add PV to the yield + for i in non_vebus_inverters: + if (pv_yield := self._dbusmonitor.get_value(i, "/Yield/Power")) is not None: + newvalues['/Dc/Pv/Power'] = newvalues.get('/Dc/Pv/Power', 0) + pv_yield + + # Used lower down, possibly needed for battery values as well + dcsystems = self._dbusmonitor.get_service_list('com.victronenergy.dcsystem') + + # ==== BATTERY ==== + if self._batteryservice is not None: + batteryservicetype = self._batteryservice.split('.')[2] + assert batteryservicetype in ('battery', 'vebus', 'inverter', 'multi') + + newvalues['/Dc/Battery/TimeToGo'] = self._dbusmonitor.get_value(self._batteryservice,'/TimeToGo') + newvalues['/Dc/Battery/ConsumedAmphours'] = self._dbusmonitor.get_value(self._batteryservice,'/ConsumedAmphours') + newvalues['/Dc/Battery/ProductId'] = self._dbusmonitor.get_value(self._batteryservice, '/ProductId') + + if batteryservicetype in ('battery', 'inverter', 'multi'): + newvalues['/Dc/Battery/Voltage'] = self._dbusmonitor.get_value(self._batteryservice, '/Dc/0/Voltage') + newvalues['/Dc/Battery/VoltageService'] = self._batteryservice + newvalues['/Dc/Battery/Current'] = self._dbusmonitor.get_value(self._batteryservice, '/Dc/0/Current') + newvalues['/Dc/Battery/Power'] = self._dbusmonitor.get_value(self._batteryservice, '/Dc/0/Power') + + elif batteryservicetype == 'vebus': + vebus_voltage = self._dbusmonitor.get_value(self._batteryservice, '/Dc/0/Voltage') + vebus_current = self._dbusmonitor.get_value(self._batteryservice, '/Dc/0/Current') + vebus_power = None if vebus_voltage is None or vebus_current is None else vebus_current * vebus_voltage + newvalues['/Dc/Battery/Voltage'] = vebus_voltage + newvalues['/Dc/Battery/VoltageService'] = self._batteryservice + if self._settings['hasdcsystem'] == 1 or dcsystems: + # hasdcsystem will normally disqualify the multi from being + # auto-selected as battery monitor, so the only way we're + # here is if the user explicitly selected the multi as the + # battery service + newvalues['/Dc/Battery/Current'] = vebus_current + if vebus_power is not None: + newvalues['/Dc/Battery/Power'] = vebus_power + else: + battery_power = _safeadd(solarchargers_charge_power, vebus_power) + newvalues['/Dc/Battery/Current'] = battery_power / vebus_voltage if vebus_voltage is not None and vebus_voltage > 0 else None + newvalues['/Dc/Battery/Power'] = battery_power + + + p = newvalues.get('/Dc/Battery/Power', None) + if p is not None: + if p > 30: + newvalues['/Dc/Battery/State'] = self.STATE_CHARGING + elif p < -30: + newvalues['/Dc/Battery/State'] = self.STATE_DISCHARGING + else: + newvalues['/Dc/Battery/State'] = self.STATE_IDLE + + else: + # The battery service is not a BMS/BMV or a suitable vebus. A + # suitable vebus is defined as one explicitly selected by the user, + # or one that was automatically selected for SOC tracking. We may + # however still have a VE.Bus, just not one that can accurately + # track SOC. If we have one, use it as voltage source. Otherwise + # try a solar charger, a charger, a vedirect inverter or a dcsource + # as fallbacks. + batteryservicetype = None + vebusses = self._dbusmonitor.get_service_list('com.victronenergy.vebus') + for vebus in vebusses: + v = self._dbusmonitor.get_value(vebus, '/Dc/0/Voltage') + s = self._dbusmonitor.get_value(vebus, '/State') + if v is not None and s not in (0, None): + newvalues['/Dc/Battery/Voltage'] = v + newvalues['/Dc/Battery/VoltageService'] = vebus + break # Skip the else below + else: + # No suitable vebus voltage, try other devices + if non_vebus_inverter is not None and (v := self._dbusmonitor.get_value(non_vebus_inverter, '/Dc/0/Voltage')) is not None: + newvalues['/Dc/Battery/Voltage'] = v + newvalues['/Dc/Battery/VoltageService'] = non_vebus_inverter + elif solarcharger_batteryvoltage is not None: + newvalues['/Dc/Battery/Voltage'] = solarcharger_batteryvoltage + newvalues['/Dc/Battery/VoltageService'] = solarcharger_batteryvoltage_service + elif charger_batteryvoltage is not None: + newvalues['/Dc/Battery/Voltage'] = charger_batteryvoltage + newvalues['/Dc/Battery/VoltageService'] = charger_batteryvoltage_service + elif fuelcell_batteryvoltage is not None: + newvalues['/Dc/Battery/Voltage'] = fuelcell_batteryvoltage + newvalues['/Dc/Battery/VoltageService'] = fuelcell_batteryvoltage_service + elif dcsystems: + # Get voltage from first dcsystem + s = next(iter(dcsystems.keys())) + v = self._dbusmonitor.get_value(s, '/Dc/0/Voltage') + if v is not None: + newvalues['/Dc/Battery/Voltage'] = v + newvalues['/Dc/Battery/VoltageService'] = s + + # We have no suitable battery monitor, so power and current data + # is not available. We can however calculate it from other values, + # if we have at least a battery voltage. + if '/Dc/Battery/Voltage' in newvalues: + dcsystempower = _safeadd(0, *(self._dbusmonitor.get_value(s, + '/Dc/0/Power', 0) for s in dcsystems)) + if dcsystems or self._settings['hasdcsystem'] == 0: + # Either DC loads are monitored, or there are no + # unmonitored DC loads or chargers: derive battery watts + # and amps from vebus, solarchargers, chargers and measured + # loads. + p = solarchargers_charge_power + newvalues.get('/Dc/Charger/Power', 0) + vebuspower - dcsystempower + voltage = newvalues['/Dc/Battery/Voltage'] + newvalues['/Dc/Battery/Current'] = p / voltage if voltage > 0 else None + newvalues['/Dc/Battery/Power'] = p + + # ==== SYSTEM POWER ==== + # Look for dcsytem devices, add them together. Otherwise, if enabled, + # calculate it + if dcsystems: + newvalues['/Dc/System/MeasurementType'] = 1 # measured + newvalues['/Dc/System/Power'] = 0 + for meter in dcsystems: + newvalues['/Dc/System/Power'] = _safeadd(newvalues['/Dc/System/Power'], + self._dbusmonitor.get_value(meter, '/Dc/0/Power')) + elif self._settings['hasdcsystem'] == 1 and batteryservicetype == 'battery': + # Calculate power being generated/consumed by not measured devices in the network. + # For MPPTs, take all the power, including power going out of the load output. + # /Dc/System: positive: consuming power + # VE.Bus: Positive: current flowing from the Multi to the dc system or battery + # Solarcharger & other chargers: positive: charging + # battery: Positive: charging battery. + # battery = solarcharger + charger + ve.bus - system + + battery_power = newvalues.get('/Dc/Battery/Power') + if battery_power is not None: + dc_pv_power = newvalues.get('/Dc/Pv/Power', 0) + 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 + # power values are not available. + inverter_power = 0 + for i in non_vebus_inverters: + inverter_current = self._dbusmonitor.get_value(i, '/Dc/0/Current') + if inverter_current is not None: + inverter_power += self._dbusmonitor.get_value( + i, '/Dc/0/Voltage', 0) * inverter_current + else: + inverter_power -= self._dbusmonitor.get_value( + i, '/Ac/Out/L1/V', 0) * self._dbusmonitor.get_value( + i, '/Ac/Out/L1/I', 0) + newvalues['/Dc/System/MeasurementType'] = 0 # estimated + # FIXME In future we will subtract alternator power from the + # calculated DC power, because it will be individually + # 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 +#### 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 + newvalues['/Dc/System/Power'] = solarchargers_loadoutput_power + + # ===== AC IN SOURCE ===== + multi_path = getattr(delegates.Multi.instance.multi, 'service', None) + ac_in_source = None + active_input = None + if multi_path is None: + # Check if we have an non-VE.Bus inverter. + if non_vebus_inverter is not None: + if (active_input := self._dbusmonitor.get_value(non_vebus_inverter, '/Ac/ActiveIn/ActiveInput')) is not None and \ + active_input in (0, 1) and \ + (active_type := self._dbusmonitor.get_value(non_vebus_inverter, '/Ac/In/{}/Type'.format(active_input + 1))) is not None: + ac_in_source = active_type + else: + ac_in_source = 240 + else: + active_input = self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/ActiveInput') + if active_input == 0xF0: + # Not connected + ac_in_source = 240 + elif active_input is not None: + settings_path = '/Settings/SystemSetup/AcInput%s' % (active_input + 1) + ac_in_source = self._dbusmonitor.get_value('com.victronenergy.settings', settings_path) + newvalues['/Ac/ActiveIn/Source'] = ac_in_source + + # ===== GRID METERS & CONSUMPTION ==== + grid_meter = delegates.AcInputs.instance.gridmeter + genset_meter = delegates.AcInputs.instance.gensetmeter + + # Make an educated guess as to what is being consumed from an AC source. If ac_in_source + # indicates grid, genset or shore, we use that. If the Multi is off, or disconnected through + # a relay assistant or otherwise, then assume the presence of a .grid or .genset service indicates + # presence of that AC source. If both are available, then give up. This decision making is here + # so the GUI has something to present even if the Multi is off. + ac_in_guess = ac_in_source + if ac_in_guess in (None, 0xF0): + if genset_meter is None and grid_meter is not None: + ac_in_guess = 1 + elif grid_meter is None and genset_meter is not None: + ac_in_guess = 2 + + 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. + # com.victronenergy.grid.??? indicates presence of an energy meter used as grid meter. + # com.victronenergy.vebus.???/Ac/ActiveIn/ActiveInput: decides which whether we look at AcIn1 + # or AcIn2 as possible grid connection. + uses_active_input = ac_in_source in _types + for phase in consumption: + p = None + mc = None + pvpower = newvalues.get('/Ac/PvOn%s/%s/Power' % (device_type, phase)) + 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) + 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 + cc = None + if uses_active_input: + if multi_path is not None: + 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): + for i in non_vebus_inverters: + 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 + + # 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) + cc = _safeadd(cc, mc, pvcurrent) + consumption[phase] = _safeadd(consumption[phase], _safemax(0, c)) + 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]) + 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]) + + # 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). + try: + p = _safeadd(p, -pvpower) + mc = _safeadd(mc, -pvcurrent) + except TypeError: + pass + + 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) + + product_id = None + device_type_id = None + if em is not None: + product_id = em.product_id + device_type_id = em.device_type + if product_id is None and uses_active_input: + if multi_path is not None: + product_id = self._dbusmonitor.get_value(multi_path, '/ProductId') + elif non_vebus_inverter is not None: + product_id = self._dbusmonitor.get_value(non_vebus_inverter, '/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. + use_ac_out = \ + self._settings['useacout'] == 1 or \ + (multi_path is not None and self._dbusmonitor.get_value(multi_path, '/Hub4/AssistantId') not in (4, 5)) or \ + self._dbusmonitor.get_value('com.victronenergy.settings', '/Settings/CGwacs/RunWithoutGridMeter') == 1 + for phase in consumption: + c = None + a = None + 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 + c = _safeadd(c, ac_out) + a = _safeadd(a, i) + else: + ac_out = self._dbusmonitor.get_value(multi_path, '/Ac/Out/%s/P' % phase) + 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 + 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) + 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) + + for m in self._modules: + m.update_values(newvalues) + + # ==== UPDATE MINIMUM AND MAXIMUM LEVELS ==== + # 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' + + # 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. + # For the minimum value, make sure it is 0 at its maximum. + # 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): + 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")) + + 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._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 + 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 + newvalues['/Dc/System/Power/Max'] = _safemax(self._dbusservice['/Dc/System/Power/Max'] or 0, + newvalues.get('/Dc/System/Power') or 0) + + # PV power + 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'], + self._dbusservice['/Ac/PvOnGrid/L3/Power'], + self._dbusservice['/Ac/PvOnGenset/L1/Power'], + self._dbusservice['/Ac/PvOnGenset/L2/Power'], + self._dbusservice['/Ac/PvOnGenset/L3/Power'], + self._dbusservice['/Ac/PvOnOutput/L1/Power'], + 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(): + # Why the None? Because we want to invalidate things we don't have anymore. + sss[path] = newvalues.get(path, None) + + def _handleservicechange(self): + # Update the available battery monitor services, used to populate the dropdown in the settings. + # Below code makes a dictionary. The key is [dbuserviceclass]/[deviceinstance]. For example + # "battery/245". The value is the name to show to the user in the dropdown. The full dbus- + # servicename, ie 'com.victronenergy.vebus.ttyO1' is not used, since the last part of that is not + # fixed. dbus-serviceclass name and the device instance are already fixed, so best to use those. + + services = self._get_connected_service_list('com.victronenergy.vebus') + services.update(self._get_connected_service_list('com.victronenergy.battery')) + services.update({k: v for k, v in self._get_connected_service_list( + 'com.victronenergy.multi').items() if self._dbusmonitor.get_value(k, '/Soc') is not None}) + services.update({k: v for k, v in self._get_connected_service_list( + 'com.victronenergy.inverter').items() if self._dbusmonitor.get_value(k, '/Soc') is not None}) + + ul = {self.BATSERVICE_DEFAULT: 'Automatic', self.BATSERVICE_NOBATTERY: 'No battery monitor'} + for servicename, instance in services.items(): + key = self._get_instance_service_name(servicename, instance) + ul[key] = self._get_readable_service_name(servicename) + self._dbusservice['/AvailableBatteryServices'] = json.dumps(ul) + + ul = {self.BATSERVICE_DEFAULT: 'Automatic', self.BATSERVICE_NOBATTERY: 'No battery monitor'} + # For later: for device supporting multiple Dc measurement we should add entries for /Dc/1 etc as + # well. + for servicename, instance in services.items(): + key = self._get_instance_service_name(servicename, instance).replace('.', '_').replace('/', '_') + '/Dc/0' + ul[key] = self._get_readable_service_name(servicename) + self._dbusservice['/AvailableBatteryMeasurements'] = ul + + self._determinebatteryservice() + + self._changed = True + + def _get_readable_service_name(self, servicename): + return '%s on %s' % ( + self._dbusmonitor.get_value(servicename, '/ProductName'), + self._dbusmonitor.get_value(servicename, '/Mgmt/Connection')) + + def _get_instance_service_name(self, service, instance): + return '%s/%s' % ('.'.join(service.split('.')[0:3]), instance) + + def _remove_unconnected_services(self, services): + # Workaround: because com.victronenergy.vebus is available even when there is no vebus product + # connected, remove any service that is not connected. Previously we used + # /State since mandatory path /Connected is not implemented in mk2dbus, + # but this has since been resolved. + for servicename in list(services.keys()): + if (self._dbusmonitor.get_value(servicename, '/Connected') != 1 + or self._dbusmonitor.get_value(servicename, '/ProductName') is None + or self._dbusmonitor.get_value(servicename, '/Mgmt/Connection') is None): + del services[servicename] + + def _dbus_value_changed(self, dbusServiceName, dbusPath, dict, changes, deviceInstance): + self._changed = True + + # Workaround because com.victronenergy.vebus is available even when there is no vebus product + # connected. + if (dbusPath in ['/Connected', '/ProductName', '/Mgmt/Connection'] or + (dbusPath == '/State' and dbusServiceName.split('.')[0:3] == ['com', 'victronenergy', 'vebus'])): + self._handleservicechange() + + # Track the timezone changes + if dbusPath == '/Settings/System/TimeZone': + tz = changes.get('Value') + if tz is not None: + os.environ['TZ'] = tz + time.tzset() + + def _device_added(self, service, instance, do_service_change=True): + if do_service_change: + self._handleservicechange() + + for m in self._modules: + m.device_added(service, instance, do_service_change) + + def _device_removed(self, service, instance): + self._handleservicechange() + + for m in self._modules: + m.device_removed(service, instance) + + def _gettext(self, path, value): + item = self._summeditems.get(path) + if item is not None: + try: + gettext = item['gettext'] + except KeyError: + pass + else: + if callable(gettext): + return gettext(value) + return gettext % value + return str(value) + + def _compute_number_of_phases(self, path, newvalues): + number_of_phases = None + for phase in range(1, 4): + p = newvalues.get('%s/L%s/Power' % (path, phase)) + if p is not None: + number_of_phases = phase + newvalues[path + '/NumberOfPhases'] = number_of_phases + + def _get_connected_service_list(self, classfilter=None): + services = self._dbusmonitor.get_service_list(classfilter=classfilter) + self._remove_unconnected_services(services) + return services + + # returns a servicename string + def _get_first_connected_service(self, classfilter): + services = self._get_connected_service_list(classfilter=classfilter) + if len(services) == 0: + return None + return next(iter(services.items()), (None,))[0] + + # returns a tuple (servicename, instance) + def _get_service_having_lowest_instance(self, classfilter=None): + services = self._get_connected_service_list(classfilter=classfilter) + if len(services) == 0: + return None + + # sort the dict by value; returns list of tuples: (value, key) + s = sorted((value, key) for (key, value) in services.items()) + return (s[0][1], s[0][0]) + + +class DbusSystemCalc(SystemCalc): + 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 _create_dbus_service(self): + venusversion, venusbuildtime = self._get_venus_versioninfo() + + dbusservice = VeDbusService('com.victronenergy.system') + dbusservice.add_mandatory_paths( + processname=__file__, + processversion=softwareVersion, + connection='data from other dbus processes', + deviceinstance=0, + productid=None, + productname=None, + firmwareversion=venusversion, + hardwareversion=None, + connected=1) + dbusservice.add_path('/FirmwareBuild', value=venusbuildtime) + return dbusservice + + def _get_venus_versioninfo(self): + try: + with open("/opt/victronenergy/version", "r") as fp: + version, software, buildtime = fp.read().split('\n')[:3] + major, minor, _, rev = re.compile('v([0-9]*)\.([0-9]*)(~([0-9]*))?').match(version).groups() + return (int(major, 16)<<16)+(int(minor, 16)<<8)+(0 if rev is None else int(rev, 16)), buildtime + except Exception: + pass + return 0, '0' + +if __name__ == "__main__": + # Argument parsing + parser = argparse.ArgumentParser( + description='Converts readings from AC-Sensors connected to a VE.Bus device in a pvinverter ' + + 'D-Bus service.' + ) + + parser.add_argument("-d", "--debug", help="set logging level to debug", + action="store_true") + + args = parser.parse_args() + + print("-------- dbus_systemcalc, 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) + + systemcalc = DbusSystemCalc() + + # Start and run the mainloop + logger.info("Starting mainloop, responding only on events") + mainloop = GLib.MainLoop() + mainloop.run() diff --git a/FileSets/v3.40~11/dbus_systemcalc.py.orig b/FileSets/v3.40~11/dbus_systemcalc.py.orig new file mode 100755 index 00000000..4d2aa0ae --- /dev/null +++ b/FileSets/v3.40~11/dbus_systemcalc.py.orig @@ -0,0 +1,1245 @@ +#!/usr/bin/python3 -u +# -*- coding: utf-8 -*- + +from dbus.mainloop.glib import DBusGMainLoop +import dbus +import argparse +import sys +import os +import json +import time +import re +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 get_vrm_portal_id, exit_on_error +from dbusmonitor import DbusMonitor +from settingsdevice import SettingsDevice +from logger import setup_logging +import delegates +from sc_utils import safeadd as _safeadd, safemax as _safemax + +softwareVersion = '2.164' + +class SystemCalc: + STATE_IDLE = 0 + STATE_CHARGING = 1 + STATE_DISCHARGING = 2 + BATSERVICE_DEFAULT = 'default' + BATSERVICE_NOBATTERY = 'nobattery' + def __init__(self): + # Why this dummy? Because DbusMonitor expects these values to be there, even though we don't + # need them. So just add some dummy data. This can go away when DbusMonitor is more generic. + dummy = {'code': None, 'whenToLog': 'configChange', 'accessLevel': None} + dbus_tree = { + 'com.victronenergy.solarcharger': { + '/Connected': dummy, + '/ProductName': dummy, + '/Mgmt/Connection': dummy, + '/Dc/0/Voltage': dummy, + '/Dc/0/Current': dummy, + '/Load/I': dummy, + '/FirmwareVersion': dummy}, + 'com.victronenergy.battery': { + '/Connected': dummy, + '/ProductName': dummy, + '/Mgmt/Connection': dummy, + '/DeviceInstance': dummy, + '/Dc/0/Voltage': dummy, + '/Dc/1/Voltage': dummy, + '/Dc/0/Current': dummy, + '/Dc/0/Power': dummy, + '/Soc': dummy, + '/Sense/Current': dummy, + '/TimeToGo': dummy, + '/ConsumedAmphours': dummy, + '/ProductId': dummy, + '/CustomName': dummy, + '/Info/MaxChargeVoltage': dummy}, + 'com.victronenergy.vebus' : { + '/Ac/ActiveIn/ActiveInput': dummy, + '/Ac/ActiveIn/L1/P': dummy, + '/Ac/ActiveIn/L2/P': dummy, + '/Ac/ActiveIn/L3/P': dummy, + '/Ac/ActiveIn/L1/I': dummy, + '/Ac/ActiveIn/L2/I': dummy, + '/Ac/ActiveIn/L3/I': dummy, + '/Ac/Out/L1/P': dummy, + '/Ac/Out/L2/P': dummy, + '/Ac/Out/L3/P': dummy, + '/Ac/Out/L1/I': dummy, + '/Ac/Out/L2/I': dummy, + '/Ac/Out/L3/I': dummy, + '/Connected': dummy, + '/ProductId': dummy, + '/ProductName': dummy, + '/Mgmt/Connection': dummy, + '/Mode': dummy, + '/State': dummy, + '/Dc/0/Voltage': dummy, + '/Dc/0/Current': dummy, + '/Dc/0/Power': dummy, + '/Soc': dummy}, + 'com.victronenergy.fuelcell': { + '/Connected': dummy, + '/ProductName': dummy, + '/Mgmt/Connection': dummy, + '/Dc/0/Voltage': dummy, + '/Dc/0/Current': dummy}, + 'com.victronenergy.charger': { + '/Connected': dummy, + '/ProductName': dummy, + '/Mgmt/Connection': dummy, + '/Dc/0/Voltage': dummy, + '/Dc/0/Current': dummy, + '/Dc/1/Voltage': dummy, + '/Dc/1/Current': dummy, + '/Dc/2/Voltage': dummy, + '/Dc/2/Current': dummy}, + 'com.victronenergy.grid' : { + '/Connected': dummy, + '/ProductName': dummy, + '/Mgmt/Connection': dummy, + '/ProductId' : dummy, + '/DeviceType' : dummy, + '/Ac/L1/Power': dummy, + '/Ac/L2/Power': dummy, + '/Ac/L3/Power': dummy, + '/Ac/L1/Current': dummy, + '/Ac/L2/Current': dummy, + '/Ac/L3/Current': dummy}, + 'com.victronenergy.genset' : { + '/Connected': dummy, + '/ProductName': dummy, + '/Mgmt/Connection': dummy, + '/ProductId' : dummy, + '/DeviceType' : dummy, + '/Ac/L1/Power': dummy, + '/Ac/L2/Power': dummy, + '/Ac/L3/Power': dummy, + '/Ac/L1/Current': dummy, + '/Ac/L2/Current': dummy, + '/Ac/L3/Current': dummy, + '/StarterVoltage': dummy}, + 'com.victronenergy.settings' : { + '/Settings/SystemSetup/AcInput1' : dummy, + '/Settings/SystemSetup/AcInput2' : dummy, + '/Settings/CGwacs/RunWithoutGridMeter' : dummy, + '/Settings/System/TimeZone' : dummy}, + 'com.victronenergy.temperature': { + '/Connected': dummy, + '/ProductName': dummy, + '/Mgmt/Connection': dummy}, + 'com.victronenergy.inverter': { + '/Connected': dummy, + '/ProductName': dummy, + '/Mgmt/Connection': dummy, + '/Dc/0/Voltage': dummy, + '/Dc/0/Current': dummy, + '/Dc/0/Power': dummy, + '/Ac/Out/L1/P': dummy, + '/Ac/Out/L1/S': dummy, + '/Ac/Out/L1/V': dummy, + '/Ac/Out/L1/I': dummy, + '/Ac/Out/L2/P': dummy, + '/Ac/Out/L2/S': dummy, + '/Ac/Out/L2/V': dummy, + '/Ac/Out/L2/I': dummy, + '/Ac/Out/L3/P': dummy, + '/Ac/Out/L3/S': dummy, + '/Ac/Out/L3/V': dummy, + '/Ac/Out/L3/I': dummy, + '/Yield/Power': dummy, + '/Soc': dummy}, + 'com.victronenergy.multi': { + '/Connected': dummy, + '/ProductName': dummy, + '/Mgmt/Connection': dummy, + '/Dc/0/Voltage': dummy, + '/Dc/0/Current': dummy, + '/Dc/0/Power': dummy, + '/Ac/ActiveIn/ActiveInput': dummy, + '/Ac/In/1/Type': dummy, + '/Ac/In/2/Type': dummy, + '/Ac/In/1/L1/P': dummy, + '/Ac/In/1/L1/I': dummy, + '/Ac/In/2/L1/P': dummy, + '/Ac/In/2/L1/I': dummy, + '/Ac/Out/L1/P': dummy, + '/Ac/Out/L1/V': dummy, + '/Ac/Out/L1/I': dummy, + '/Ac/In/1/L2/P': dummy, + '/Ac/In/1/L2/I': dummy, + '/Ac/In/2/L2/P': dummy, + '/Ac/In/2/L2/I': dummy, + '/Ac/Out/L2/P': dummy, + '/Ac/Out/L2/V': dummy, + '/Ac/Out/L2/I': dummy, + '/Ac/In/1/L3/P': dummy, + '/Ac/In/1/L3/I': dummy, + '/Ac/In/2/L3/P': dummy, + '/Ac/In/2/L3/I': dummy, + '/Ac/Out/L3/P': dummy, + '/Ac/Out/L3/V': dummy, + '/Ac/Out/L3/I': dummy, + '/Yield/Power': dummy, + '/Soc': dummy}, + 'com.victronenergy.dcsystem': { + '/Dc/0/Voltage': dummy, + '/Dc/0/Power': dummy + }, + 'com.victronenergy.alternator': { + '/Dc/0/Power': dummy + } + } + + self._modules = [ + delegates.Multi(), + delegates.HubTypeSelect(), + delegates.VebusSocWriter(), + delegates.ServiceMapper(), + delegates.RelayState(), + delegates.BuzzerControl(), + delegates.LgCircuitBreakerDetect(), + delegates.BatterySoc(self), + delegates.Dvcc(self), + delegates.BatterySense(self), + delegates.BatterySettings(self), + delegates.SystemState(self), + delegates.BatteryLife(), + delegates.ScheduledCharging(), + delegates.SourceTimers(), + delegates.BatteryData(), + delegates.Gps(), + delegates.AcInputs(), + delegates.GensetStartStop(), + delegates.SocSync(self), + delegates.PvInverters(), + delegates.BatteryService(self), + delegates.CanBatterySense(), + delegates.InverterCharger(), + delegates.DynamicEss(), + delegates.LoadShedding()] + + for m in self._modules: + for service, paths in m.get_input(): + s = dbus_tree.setdefault(service, {}) + for path in paths: + s[path] = dummy + + self._dbusmonitor = self._create_dbus_monitor(dbus_tree, valueChangedCallback=self._dbus_value_changed, + deviceAddedCallback=self._device_added, deviceRemovedCallback=self._device_removed) + + # 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")], + } + + for m in self._modules: + for setting in m.get_settings(): + supported_settings[setting[0]] = list(setting[1:]) + + self._settings = self._create_settings(supported_settings, self._handlechangedsetting) + + self._dbusservice = self._create_dbus_service() + + for m in self._modules: + m.set_sources(self._dbusmonitor, self._settings, self._dbusservice) + + # At this moment, VRM portal ID is the MAC address of the CCGX. Anyhow, it should be string uniquely + # identifying the CCGX. + self._dbusservice.add_path('/Serial', value=get_vrm_portal_id()) + self._dbusservice.add_path( + '/AvailableBatteryServices', value=None, gettextcallback=self._gettext) + self._dbusservice.add_path( + '/AvailableBatteryMeasurements', value=None) + self._dbusservice.add_path( + '/AutoSelectedBatteryService', value=None, gettextcallback=self._gettext) + self._dbusservice.add_path( + '/AutoSelectedBatteryMeasurement', value=None, gettextcallback=self._gettext) + self._dbusservice.add_path( + '/ActiveBatteryService', value=None, gettextcallback=self._gettext) + self._dbusservice.add_path( + '/Dc/Battery/BatteryService', value=None) + self._summeditems = { + '/Ac/Grid/L1/Power': {'gettext': '%.0F W'}, + '/Ac/Grid/L2/Power': {'gettext': '%.0F W'}, + '/Ac/Grid/L3/Power': {'gettext': '%.0F W'}, + '/Ac/Grid/L1/Current': {'gettext': '%.1F A'}, + '/Ac/Grid/L2/Current': {'gettext': '%.1F A'}, + '/Ac/Grid/L3/Current': {'gettext': '%.1F A'}, + '/Ac/Grid/NumberOfPhases': {'gettext': '%.0F W'}, + '/Ac/Grid/ProductId': {'gettext': '%s'}, + '/Ac/Grid/DeviceType': {'gettext': '%s'}, + '/Ac/Genset/L1/Power': {'gettext': '%.0F W'}, + '/Ac/Genset/L2/Power': {'gettext': '%.0F W'}, + '/Ac/Genset/L3/Power': {'gettext': '%.0F W'}, + '/Ac/Genset/L1/Current': {'gettext': '%.1F A'}, + '/Ac/Genset/L2/Current': {'gettext': '%.1F A'}, + '/Ac/Genset/L3/Current': {'gettext': '%.1F A'}, + '/Ac/Genset/NumberOfPhases': {'gettext': '%.0F W'}, + '/Ac/Genset/ProductId': {'gettext': '%s'}, + '/Ac/Genset/DeviceType': {'gettext': '%s'}, + '/Ac/ConsumptionOnOutput/NumberOfPhases': {'gettext': '%.0F W'}, + '/Ac/ConsumptionOnOutput/L1/Power': {'gettext': '%.0F W'}, + '/Ac/ConsumptionOnOutput/L2/Power': {'gettext': '%.0F W'}, + '/Ac/ConsumptionOnOutput/L3/Power': {'gettext': '%.0F W'}, + '/Ac/ConsumptionOnOutput/L1/Current': {'gettext': '%.1F A'}, + '/Ac/ConsumptionOnOutput/L2/Current': {'gettext': '%.1F A'}, + '/Ac/ConsumptionOnOutput/L3/Current': {'gettext': '%.1F A'}, + '/Ac/ConsumptionOnInput/NumberOfPhases': {'gettext': '%.0F W'}, + '/Ac/ConsumptionOnInput/L1/Power': {'gettext': '%.0F W'}, + '/Ac/ConsumptionOnInput/L2/Power': {'gettext': '%.0F W'}, + '/Ac/ConsumptionOnInput/L3/Power': {'gettext': '%.0F W'}, + '/Ac/ConsumptionOnInput/L1/Current': {'gettext': '%.1F A'}, + '/Ac/ConsumptionOnInput/L2/Current': {'gettext': '%.1F A'}, + '/Ac/ConsumptionOnInput/L3/Current': {'gettext': '%.1F A'}, + '/Ac/Consumption/NumberOfPhases': {'gettext': '%.0F W'}, + '/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'}, + '/Dc/Pv/Power': {'gettext': '%.0F W'}, + '/Dc/Pv/Current': {'gettext': '%.1F A'}, + '/Dc/Battery/Voltage': {'gettext': '%.2F V'}, + '/Dc/Battery/VoltageService': {'gettext': '%s'}, + '/Dc/Battery/Current': {'gettext': '%.1F A'}, + '/Dc/Battery/Power': {'gettext': '%.0F W'}, + '/Dc/Battery/State': {'gettext': lambda v: ({ + self.STATE_IDLE: 'Idle', + self.STATE_CHARGING: 'Charging', + self.STATE_DISCHARGING: 'Discharging'}.get(v, 'Unknown'))}, + '/Dc/Battery/TimeToGo': {'gettext': '%.0F s'}, + '/Dc/Battery/ConsumedAmphours': {'gettext': '%.1F Ah'}, + '/Dc/Battery/ProductId': {'gettext': '0x%x'}, + '/Dc/Charger/Power': {'gettext': '%.0F %%'}, + '/Dc/FuelCell/Power': {'gettext': '%.0F %%'}, + '/Dc/Alternator/Power': {'gettext': '%.0F W'}, + '/Dc/System/Power': {'gettext': '%.0F W'}, + '/Dc/System/MeasurementType': {'gettext': '%d'}, + '/Ac/ActiveIn/Source': {'gettext': '%s'}, + '/Ac/ActiveIn/L1/Power': {'gettext': '%.0F W'}, + '/Ac/ActiveIn/L2/Power': {'gettext': '%.0F W'}, + '/Ac/ActiveIn/L3/Power': {'gettext': '%.0F W'}, + '/Ac/ActiveIn/L1/Current': {'gettext': '%.1F A'}, + '/Ac/ActiveIn/L2/Current': {'gettext': '%.1F A'}, + '/Ac/ActiveIn/L3/Current': {'gettext': '%.1F A'}, + '/Ac/ActiveIn/NumberOfPhases': {'gettext': '%d'}, + } + + for m in self._modules: + self._summeditems.update(m.get_output()) + + for path in self._summeditems.keys(): + self._dbusservice.add_path(path, value=None, gettextcallback=self._gettext) + + self._batteryservice = None + self._determinebatteryservice() + + if self._batteryservice is None: + logger.info("Battery service initialized to None (setting == %s)" % + self._settings['batteryservice']) + + self._changed = True + for service, instance in self._dbusmonitor.get_service_list().items(): + self._device_added(service, instance, do_service_change=False) + + self._handleservicechange() + self._updatevalues() + + GLib.timeout_add(1000, exit_on_error, self._handletimertick) + + 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") + + def _handlechangedsetting(self, setting, oldvalue, newvalue): + self._determinebatteryservice() + self._changed = True + + # Give our delegates a chance to react on a settings change + for m in self._modules: + m.settings_changed(setting, oldvalue, newvalue) + + def _find_device_instance(self, serviceclass, instance): + """ Gets a mapping of services vs DeviceInstance using + get_service_list. Then searches for the specified DeviceInstance + and returns the service name. """ + services = self._dbusmonitor.get_service_list(classfilter=serviceclass) + + for k, v in services.items(): + if v == instance: + return k + return None + + def _determinebatteryservice(self): + auto_battery_service = self._autoselect_battery_service() + auto_battery_measurement = None + auto_selected = False + if auto_battery_service is not None: + services = self._dbusmonitor.get_service_list() + if auto_battery_service in services: + auto_battery_measurement = \ + self._get_instance_service_name(auto_battery_service, services[auto_battery_service]) + auto_battery_measurement = auto_battery_measurement.replace('.', '_').replace('/', '_') + '/Dc/0' + self._dbusservice['/AutoSelectedBatteryMeasurement'] = auto_battery_measurement + + if self._settings['batteryservice'] == self.BATSERVICE_DEFAULT: + auto_selected = True + newbatteryservice = auto_battery_service + self._dbusservice['/AutoSelectedBatteryService'] = ( + 'No battery monitor found' if newbatteryservice is None else + self._get_readable_service_name(newbatteryservice)) + + elif self._settings['batteryservice'] == self.BATSERVICE_NOBATTERY: + self._dbusservice['/AutoSelectedBatteryService'] = None + newbatteryservice = None + + else: + self._dbusservice['/AutoSelectedBatteryService'] = None + + s = self._settings['batteryservice'].split('/') + if len(s) != 2: + logger.error("The battery setting (%s) is invalid!" % self._settings['batteryservice']) + serviceclass = s[0] + instance = int(s[1]) if len(s) == 2 else None + + # newbatteryservice might turn into None if a chosen battery + # monitor no longer exists. Don't auto change the setting (it might + # come back) and don't autoselect another. + newbatteryservice = self._find_device_instance(serviceclass, instance) + + if newbatteryservice != self._batteryservice: + services = self._dbusmonitor.get_service_list() + instance = services.get(newbatteryservice, None) + if instance is None: + battery_service = None + else: + battery_service = self._get_instance_service_name(newbatteryservice, instance) + self._dbusservice['/ActiveBatteryService'] = battery_service + logger.info("Battery service, setting == %s, changed from %s to %s (%s)" % + (self._settings['batteryservice'], self._batteryservice, newbatteryservice, instance)) + + # Battery service has changed. Notify delegates. + self._dbusservice['/Dc/Battery/BatteryService'] = self._batteryservice = newbatteryservice + for m in self._modules: + m.battery_service_changed(auto_selected, self._batteryservice, newbatteryservice) + + def _autoselect_battery_service(self): + # Default setting business logic: + # first try to use a battery service (BMV or Lynx Shunt VE.Can). If there + # is more than one battery service, just use a random one. If no battery service is + # available, check if there are not Solar chargers and no normal chargers. If they are not + # there, assume this is a hub-2, hub-3 or hub-4 system and use VE.Bus SOC. + batteries = self._get_connected_service_list('com.victronenergy.battery') + + # Pick the battery service that has the lowest DeviceInstance, giving + # preference to those with a BMS. + if len(batteries) > 0: + batteries = [ + (not self._dbusmonitor.seen(s, '/Info/MaxChargeVoltage'), i, s) + for s, i in batteries.items()] + return sorted(batteries, key=lambda x: x[:2])[0][2] + + # No battery services, and there is a charger in the system. Abandon + # hope. + if self._get_first_connected_service('com.victronenergy.charger') is not None: + return None + + # Also no Multi, then give up. + vebus_service = self._get_service_having_lowest_instance('com.victronenergy.vebus') + if vebus_service is None: + # No VE.Bus, but maybe there is an inverter with built-in SOC + # tracking, eg RS Smart or Multi RS. + inverter = self._get_service_having_lowest_instance('com.victronenergy.multi') + if inverter and self._dbusmonitor.get_value(inverter[0], '/Soc') is not None: + return inverter[0] + + inverter = self._get_service_having_lowest_instance('com.victronenergy.inverter') + if inverter and self._dbusmonitor.get_value(inverter[0], '/Soc') is not None: + return inverter[0] + + return None + + # There is a Multi, it supports tracking external charge current from + # solarchargers, and there are no DC loads. Then use it. + if self._dbusmonitor.get_value( + vebus_service[0], '/ExtraBatteryCurrent') is not None \ + and self._get_first_connected_service('com.victronenergy.dcsystem') is None \ + and self._settings['hasdcsystem'] == 0: + return vebus_service[0] + + # Multi does not support tracking solarcharger current, and we have + # solar chargers. Then we cannot use it. + if self._get_first_connected_service('com.victronenergy.solarcharger') is not None: + return None + + # Only a Multi, no other chargers. Then we can use it. + return vebus_service[0] + + @property + def batteryservice(self): + return self._batteryservice + + # Called on a one second timer + def _handletimertick(self): + if self._changed: + self._updatevalues() + self._changed = False + + return True # keep timer running + + def _updatevalues(self): + # ==== PREPARATIONS ==== + newvalues = {} + + # Set the user timezone + if 'TZ' not in os.environ: + tz = self._dbusmonitor.get_value('com.victronenergy.settings', '/Settings/System/TimeZone') + if tz is not None: + os.environ['TZ'] = tz + time.tzset() + + # Determine values used in logic below + vebusses = self._dbusmonitor.get_service_list('com.victronenergy.vebus') + vebuspower = 0 + for vebus in vebusses: + v = self._dbusmonitor.get_value(vebus, '/Dc/0/Voltage') + i = self._dbusmonitor.get_value(vebus, '/Dc/0/Current') + if v is not None and i is not None: + vebuspower += v * i + + # ==== PVINVERTERS ==== + # Work is done in pv-inverter delegate. Ideally all of this should + # happen in update_values in the delegate, but these values are + # used below in calculating consumption, so until this is less + # unwieldy this has to stay here. + # TODO this can go away once consumption below no longer relies + # on these values, or has moved to its own delegate. + newvalues.update(delegates.PvInverters.instance.get_totals()) + self._compute_number_of_phases('/Ac/PvOnGrid', newvalues) + self._compute_number_of_phases('/Ac/PvOnOutput', newvalues) + self._compute_number_of_phases('/Ac/PvOnGenset', newvalues) + + # ==== SOLARCHARGERS ==== + solarchargers = self._dbusmonitor.get_service_list('com.victronenergy.solarcharger') + solarcharger_batteryvoltage = None + solarcharger_batteryvoltage_service = None + solarchargers_charge_power = 0 + solarchargers_loadoutput_power = None + + for solarcharger in solarchargers: + v = self._dbusmonitor.get_value(solarcharger, '/Dc/0/Voltage') + if v is None: + continue + i = self._dbusmonitor.get_value(solarcharger, '/Dc/0/Current') + if i is None: + continue + l = self._dbusmonitor.get_value(solarcharger, '/Load/I', 0) + + if l is not None: + if solarchargers_loadoutput_power is None: + solarchargers_loadoutput_power = l * v + else: + solarchargers_loadoutput_power += l * v + + solarchargers_charge_power += v * i + + # Note that this path is not in the _summeditems{}, making for it to not be + # published on D-Bus. Which fine. The only one needing it is the vebussocwriter- + # delegate. + if '/Dc/Pv/ChargeCurrent' not in newvalues: + newvalues['/Dc/Pv/ChargeCurrent'] = i + else: + newvalues['/Dc/Pv/ChargeCurrent'] += i + + if '/Dc/Pv/Power' not in newvalues: + newvalues['/Dc/Pv/Power'] = v * _safeadd(i, l) + newvalues['/Dc/Pv/Current'] = _safeadd(i, l) + solarcharger_batteryvoltage = v + solarcharger_batteryvoltage_service = solarcharger + else: + newvalues['/Dc/Pv/Power'] += v * _safeadd(i, l) + newvalues['/Dc/Pv/Current'] += _safeadd(i, l) + + # ==== FUELCELLS ==== + fuelcells = self._dbusmonitor.get_service_list('com.victronenergy.fuelcell') + fuelcell_batteryvoltage = None + fuelcell_batteryvoltage_service = None + for fuelcell in fuelcells: + # Assume the battery connected to output 0 is the main battery + v = self._dbusmonitor.get_value(fuelcell, '/Dc/0/Voltage') + if v is None: + continue + + fuelcell_batteryvoltage = v + fuelcell_batteryvoltage_service = fuelcell + + i = self._dbusmonitor.get_value(fuelcell, '/Dc/0/Current') + if i is None: + continue + + if '/Dc/FuelCell/Power' not in newvalues: + newvalues['/Dc/FuelCell/Power'] = v * i + else: + newvalues['/Dc/FuelCell/Power'] += v * i + + # ==== ALTERNATOR ==== + alternators = self._dbusmonitor.get_service_list('com.victronenergy.alternator') + for alternator in alternators: + # 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 + + if '/Dc/Alternator/Power' not in newvalues: + newvalues['/Dc/Alternator/Power'] = p + else: + newvalues['/Dc/Alternator/Power'] += p + + # ==== CHARGERS ==== + chargers = self._dbusmonitor.get_service_list('com.victronenergy.charger') + charger_batteryvoltage = None + charger_batteryvoltage_service = None + for charger in chargers: + # Assume the battery connected to output 0 is the main battery + v = self._dbusmonitor.get_value(charger, '/Dc/0/Voltage') + if v is None: + continue + + charger_batteryvoltage = v + charger_batteryvoltage_service = charger + + i = self._dbusmonitor.get_value(charger, '/Dc/0/Current') + if i is None: + continue + + if '/Dc/Charger/Power' not in newvalues: + newvalues['/Dc/Charger/Power'] = v * i + else: + newvalues['/Dc/Charger/Power'] += v * i + + # ==== Other Inverters and Inverter/Chargers ==== + _other_inverters = sorted((di, s) for s, di in self._dbusmonitor.get_service_list('com.victronenergy.multi').items()) + \ + sorted((di, s) for s, di in self._dbusmonitor.get_service_list('com.victronenergy.inverter').items()) + non_vebus_inverters = [x[1] for x in _other_inverters] + non_vebus_inverter = None + if non_vebus_inverters: + non_vebus_inverter = non_vebus_inverters[0] + + # For RS Smart and Multi RS, add PV to the yield + for i in non_vebus_inverters: + if (pv_yield := self._dbusmonitor.get_value(i, "/Yield/Power")) is not None: + newvalues['/Dc/Pv/Power'] = newvalues.get('/Dc/Pv/Power', 0) + pv_yield + + # Used lower down, possibly needed for battery values as well + dcsystems = self._dbusmonitor.get_service_list('com.victronenergy.dcsystem') + + # ==== BATTERY ==== + if self._batteryservice is not None: + batteryservicetype = self._batteryservice.split('.')[2] + assert batteryservicetype in ('battery', 'vebus', 'inverter', 'multi') + + newvalues['/Dc/Battery/TimeToGo'] = self._dbusmonitor.get_value(self._batteryservice,'/TimeToGo') + newvalues['/Dc/Battery/ConsumedAmphours'] = self._dbusmonitor.get_value(self._batteryservice,'/ConsumedAmphours') + newvalues['/Dc/Battery/ProductId'] = self._dbusmonitor.get_value(self._batteryservice, '/ProductId') + + if batteryservicetype in ('battery', 'inverter', 'multi'): + newvalues['/Dc/Battery/Voltage'] = self._dbusmonitor.get_value(self._batteryservice, '/Dc/0/Voltage') + newvalues['/Dc/Battery/VoltageService'] = self._batteryservice + newvalues['/Dc/Battery/Current'] = self._dbusmonitor.get_value(self._batteryservice, '/Dc/0/Current') + newvalues['/Dc/Battery/Power'] = self._dbusmonitor.get_value(self._batteryservice, '/Dc/0/Power') + + elif batteryservicetype == 'vebus': + vebus_voltage = self._dbusmonitor.get_value(self._batteryservice, '/Dc/0/Voltage') + vebus_current = self._dbusmonitor.get_value(self._batteryservice, '/Dc/0/Current') + vebus_power = None if vebus_voltage is None or vebus_current is None else vebus_current * vebus_voltage + newvalues['/Dc/Battery/Voltage'] = vebus_voltage + newvalues['/Dc/Battery/VoltageService'] = self._batteryservice + if self._settings['hasdcsystem'] == 1 or dcsystems: + # hasdcsystem will normally disqualify the multi from being + # auto-selected as battery monitor, so the only way we're + # here is if the user explicitly selected the multi as the + # battery service + newvalues['/Dc/Battery/Current'] = vebus_current + if vebus_power is not None: + newvalues['/Dc/Battery/Power'] = vebus_power + else: + battery_power = _safeadd(solarchargers_charge_power, vebus_power) + newvalues['/Dc/Battery/Current'] = battery_power / vebus_voltage if vebus_voltage is not None and vebus_voltage > 0 else None + newvalues['/Dc/Battery/Power'] = battery_power + + + p = newvalues.get('/Dc/Battery/Power', None) + if p is not None: + if p > 30: + newvalues['/Dc/Battery/State'] = self.STATE_CHARGING + elif p < -30: + newvalues['/Dc/Battery/State'] = self.STATE_DISCHARGING + else: + newvalues['/Dc/Battery/State'] = self.STATE_IDLE + + else: + # The battery service is not a BMS/BMV or a suitable vebus. A + # suitable vebus is defined as one explicitly selected by the user, + # or one that was automatically selected for SOC tracking. We may + # however still have a VE.Bus, just not one that can accurately + # track SOC. If we have one, use it as voltage source. Otherwise + # try a solar charger, a charger, a vedirect inverter or a dcsource + # as fallbacks. + batteryservicetype = None + vebusses = self._dbusmonitor.get_service_list('com.victronenergy.vebus') + for vebus in vebusses: + v = self._dbusmonitor.get_value(vebus, '/Dc/0/Voltage') + s = self._dbusmonitor.get_value(vebus, '/State') + if v is not None and s not in (0, None): + newvalues['/Dc/Battery/Voltage'] = v + newvalues['/Dc/Battery/VoltageService'] = vebus + break # Skip the else below + else: + # No suitable vebus voltage, try other devices + if non_vebus_inverter is not None and (v := self._dbusmonitor.get_value(non_vebus_inverter, '/Dc/0/Voltage')) is not None: + newvalues['/Dc/Battery/Voltage'] = v + newvalues['/Dc/Battery/VoltageService'] = non_vebus_inverter + elif solarcharger_batteryvoltage is not None: + newvalues['/Dc/Battery/Voltage'] = solarcharger_batteryvoltage + newvalues['/Dc/Battery/VoltageService'] = solarcharger_batteryvoltage_service + elif charger_batteryvoltage is not None: + newvalues['/Dc/Battery/Voltage'] = charger_batteryvoltage + newvalues['/Dc/Battery/VoltageService'] = charger_batteryvoltage_service + elif fuelcell_batteryvoltage is not None: + newvalues['/Dc/Battery/Voltage'] = fuelcell_batteryvoltage + newvalues['/Dc/Battery/VoltageService'] = fuelcell_batteryvoltage_service + elif dcsystems: + # Get voltage from first dcsystem + s = next(iter(dcsystems.keys())) + v = self._dbusmonitor.get_value(s, '/Dc/0/Voltage') + if v is not None: + newvalues['/Dc/Battery/Voltage'] = v + newvalues['/Dc/Battery/VoltageService'] = s + + # We have no suitable battery monitor, so power and current data + # is not available. We can however calculate it from other values, + # if we have at least a battery voltage. + if '/Dc/Battery/Voltage' in newvalues: + dcsystempower = _safeadd(0, *(self._dbusmonitor.get_value(s, + '/Dc/0/Power', 0) for s in dcsystems)) + if dcsystems or self._settings['hasdcsystem'] == 0: + # Either DC loads are monitored, or there are no + # unmonitored DC loads or chargers: derive battery watts + # and amps from vebus, solarchargers, chargers and measured + # loads. + p = solarchargers_charge_power + newvalues.get('/Dc/Charger/Power', 0) + vebuspower - dcsystempower + voltage = newvalues['/Dc/Battery/Voltage'] + newvalues['/Dc/Battery/Current'] = p / voltage if voltage > 0 else None + newvalues['/Dc/Battery/Power'] = p + + # ==== SYSTEM POWER ==== + # Look for dcsytem devices, add them together. Otherwise, if enabled, + # calculate it + if dcsystems: + newvalues['/Dc/System/MeasurementType'] = 1 # measured + newvalues['/Dc/System/Power'] = 0 + for meter in dcsystems: + newvalues['/Dc/System/Power'] = _safeadd(newvalues['/Dc/System/Power'], + self._dbusmonitor.get_value(meter, '/Dc/0/Power')) + elif self._settings['hasdcsystem'] == 1 and batteryservicetype == 'battery': + # Calculate power being generated/consumed by not measured devices in the network. + # For MPPTs, take all the power, including power going out of the load output. + # /Dc/System: positive: consuming power + # VE.Bus: Positive: current flowing from the Multi to the dc system or battery + # Solarcharger & other chargers: positive: charging + # battery: Positive: charging battery. + # battery = solarcharger + charger + ve.bus - system + + battery_power = newvalues.get('/Dc/Battery/Power') + if battery_power is not None: + dc_pv_power = newvalues.get('/Dc/Pv/Power', 0) + charger_power = newvalues.get('/Dc/Charger/Power', 0) + fuelcell_power = newvalues.get('/Dc/FuelCell/Power', 0) + alternator_power = newvalues.get('/Dc/Alternator/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 + # power values are not available. + inverter_power = 0 + for i in non_vebus_inverters: + inverter_current = self._dbusmonitor.get_value(i, '/Dc/0/Current') + if inverter_current is not None: + inverter_power += self._dbusmonitor.get_value( + i, '/Dc/0/Voltage', 0) * inverter_current + else: + inverter_power -= self._dbusmonitor.get_value( + i, '/Ac/Out/L1/V', 0) * self._dbusmonitor.get_value( + i, '/Ac/Out/L1/I', 0) + newvalues['/Dc/System/MeasurementType'] = 0 # estimated + # FIXME In future we will subtract alternator power from the + # calculated DC power, because it will be individually + # 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 + + elif self._settings['hasdcsystem'] == 1 and solarchargers_loadoutput_power is not None: + newvalues['/Dc/System/MeasurementType'] = 0 # estimated + newvalues['/Dc/System/Power'] = solarchargers_loadoutput_power + + # ===== AC IN SOURCE ===== + multi_path = getattr(delegates.Multi.instance.multi, 'service', None) + ac_in_source = None + active_input = None + if multi_path is None: + # Check if we have an non-VE.Bus inverter. + if non_vebus_inverter is not None: + if (active_input := self._dbusmonitor.get_value(non_vebus_inverter, '/Ac/ActiveIn/ActiveInput')) is not None and \ + active_input in (0, 1) and \ + (active_type := self._dbusmonitor.get_value(non_vebus_inverter, '/Ac/In/{}/Type'.format(active_input + 1))) is not None: + ac_in_source = active_type + else: + ac_in_source = 240 + else: + active_input = self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/ActiveInput') + if active_input == 0xF0: + # Not connected + ac_in_source = 240 + elif active_input is not None: + settings_path = '/Settings/SystemSetup/AcInput%s' % (active_input + 1) + ac_in_source = self._dbusmonitor.get_value('com.victronenergy.settings', settings_path) + newvalues['/Ac/ActiveIn/Source'] = ac_in_source + + # ===== GRID METERS & CONSUMPTION ==== + grid_meter = delegates.AcInputs.instance.gridmeter + genset_meter = delegates.AcInputs.instance.gensetmeter + + # Make an educated guess as to what is being consumed from an AC source. If ac_in_source + # indicates grid, genset or shore, we use that. If the Multi is off, or disconnected through + # a relay assistant or otherwise, then assume the presence of a .grid or .genset service indicates + # presence of that AC source. If both are available, then give up. This decision making is here + # so the GUI has something to present even if the Multi is off. + ac_in_guess = ac_in_source + if ac_in_guess in (None, 0xF0): + if genset_meter is None and grid_meter is not None: + ac_in_guess = 1 + elif grid_meter is None and genset_meter is not None: + ac_in_guess = 2 + + consumption = { "L1" : None, "L2" : None, "L3" : None } + currentconsumption = { "L1" : None, "L2" : None, "L3" : 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. + # com.victronenergy.grid.??? indicates presence of an energy meter used as grid meter. + # com.victronenergy.vebus.???/Ac/ActiveIn/ActiveInput: decides which whether we look at AcIn1 + # or AcIn2 as possible grid connection. + uses_active_input = ac_in_source in _types + for phase in consumption: + p = None + mc = None + pvpower = newvalues.get('/Ac/PvOn%s/%s/Power' % (device_type, phase)) + 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) + mc = self._dbusmonitor.get_value(em.service, '/Ac/%s/Current' % 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 + cc = None + if uses_active_input: + if multi_path is not None: + 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)) + except TypeError: + pass + elif non_vebus_inverter is not None and active_input in (0, 1): + for i in non_vebus_inverters: + 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))) + 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) + cc = _safeadd(cc, mc, pvcurrent) + consumption[phase] = _safeadd(consumption[phase], _safemax(0, c)) + 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]) + currentconsumption[phase] = _safeadd(0, currentconsumption[phase]) + mc = self._dbusmonitor.get_value(multi_path, '/Ac/ActiveIn/%s/I' % phase) + 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))) + if p is not None: + consumption[phase] = _safeadd(0, consumption[phase]) + 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). + try: + p = _safeadd(p, -pvpower) + mc = _safeadd(mc, -pvcurrent) + except TypeError: + pass + + newvalues['/Ac/%s/%s/Power' % (device_type, phase)] = p + newvalues['/Ac/%s/%s/Current' % (device_type, phase)] = mc + if ac_in_guess in _types: + newvalues['/Ac/ActiveIn/%s/Power' % (phase,)] = p + newvalues['/Ac/ActiveIn/%s/Current' % (phase,)] = mc + + self._compute_number_of_phases('/Ac/%s' % device_type, newvalues) + self._compute_number_of_phases('/Ac/ActiveIn', newvalues) + + product_id = None + device_type_id = None + if em is not None: + product_id = em.product_id + device_type_id = em.device_type + if product_id is None and uses_active_input: + if multi_path is not None: + product_id = self._dbusmonitor.get_value(multi_path, '/ProductId') + elif non_vebus_inverter is not None: + product_id = self._dbusmonitor.get_value(non_vebus_inverter, '/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. + use_ac_out = \ + self._settings['useacout'] == 1 or \ + (multi_path is not None and self._dbusmonitor.get_value(multi_path, '/Hub4/AssistantId') not in (4, 5)) or \ + self._dbusmonitor.get_value('com.victronenergy.settings', '/Settings/CGwacs/RunWithoutGridMeter') == 1 + for phase in consumption: + c = None + a = None + if use_ac_out: + c = newvalues.get('/Ac/PvOnOutput/%s/Power' % phase) + a = newvalues.get('/Ac/PvOnOutput/%s/Current' % 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) + + # 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 + c = _safeadd(c, ac_out) + a = _safeadd(a, i) + else: + ac_out = self._dbusmonitor.get_value(multi_path, '/Ac/Out/%s/P' % phase) + c = _safeadd(c, ac_out) + i_out = self._dbusmonitor.get_value(multi_path, '/Ac/Out/%s/I' % phase) + a = _safeadd(a, i_out) + c = _safemax(0, c) + 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) + newvalues['/Ac/Consumption/%s/Current' % phase] = _safeadd(currentconsumption[phase], a) + self._compute_number_of_phases('/Ac/Consumption', newvalues) + self._compute_number_of_phases('/Ac/ConsumptionOnOutput', newvalues) + self._compute_number_of_phases('/Ac/ConsumptionOnInput', newvalues) + + for m in self._modules: + 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. + + # 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 + + # AC input + # Minimum values occur when feeding back to the grid. + # For the minimum value, make sure it is 0 at its maximum. + # 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.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.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], + newvalues.get('/Ac/Consumption/L1/Current') or 0, + newvalues.get('/Ac/Consumption/L2/Current') or 0, + newvalues.get('/Ac/Consumption/L3/Current') or 0) + + # DC input + self._settings['dcinmax'] = max(self._settings['dcinmax'] 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.get('/Dc/System/Power') or 0) + + # PV power + self._settings['pvmax'] = _safemax(self._settings['pvmax'] or 0, + _safeadd(newvalues.get('/Dc/Pv/Power') or 0, + self._dbusservice['/Ac/PvOnGrid/L1/Power'], + self._dbusservice['/Ac/PvOnGrid/L2/Power'], + self._dbusservice['/Ac/PvOnGrid/L3/Power'], + self._dbusservice['/Ac/PvOnGenset/L1/Power'], + self._dbusservice['/Ac/PvOnGenset/L2/Power'], + self._dbusservice['/Ac/PvOnGenset/L3/Power'], + self._dbusservice['/Ac/PvOnOutput/L1/Power'], + self._dbusservice['/Ac/PvOnOutput/L2/Power'], + self._dbusservice['/Ac/PvOnOutput/L3/Power'])) + + # ==== UPDATE DBUS ITEMS ==== + with self._dbusservice as sss: + for path in self._summeditems.keys(): + # Why the None? Because we want to invalidate things we don't have anymore. + sss[path] = newvalues.get(path, None) + + def _handleservicechange(self): + # Update the available battery monitor services, used to populate the dropdown in the settings. + # Below code makes a dictionary. The key is [dbuserviceclass]/[deviceinstance]. For example + # "battery/245". The value is the name to show to the user in the dropdown. The full dbus- + # servicename, ie 'com.victronenergy.vebus.ttyO1' is not used, since the last part of that is not + # fixed. dbus-serviceclass name and the device instance are already fixed, so best to use those. + + services = self._get_connected_service_list('com.victronenergy.vebus') + services.update(self._get_connected_service_list('com.victronenergy.battery')) + services.update({k: v for k, v in self._get_connected_service_list( + 'com.victronenergy.multi').items() if self._dbusmonitor.get_value(k, '/Soc') is not None}) + services.update({k: v for k, v in self._get_connected_service_list( + 'com.victronenergy.inverter').items() if self._dbusmonitor.get_value(k, '/Soc') is not None}) + + ul = {self.BATSERVICE_DEFAULT: 'Automatic', self.BATSERVICE_NOBATTERY: 'No battery monitor'} + for servicename, instance in services.items(): + key = self._get_instance_service_name(servicename, instance) + ul[key] = self._get_readable_service_name(servicename) + self._dbusservice['/AvailableBatteryServices'] = json.dumps(ul) + + ul = {self.BATSERVICE_DEFAULT: 'Automatic', self.BATSERVICE_NOBATTERY: 'No battery monitor'} + # For later: for device supporting multiple Dc measurement we should add entries for /Dc/1 etc as + # well. + for servicename, instance in services.items(): + key = self._get_instance_service_name(servicename, instance).replace('.', '_').replace('/', '_') + '/Dc/0' + ul[key] = self._get_readable_service_name(servicename) + self._dbusservice['/AvailableBatteryMeasurements'] = ul + + self._determinebatteryservice() + + self._changed = True + + def _get_readable_service_name(self, servicename): + return '%s on %s' % ( + self._dbusmonitor.get_value(servicename, '/ProductName'), + self._dbusmonitor.get_value(servicename, '/Mgmt/Connection')) + + def _get_instance_service_name(self, service, instance): + return '%s/%s' % ('.'.join(service.split('.')[0:3]), instance) + + def _remove_unconnected_services(self, services): + # Workaround: because com.victronenergy.vebus is available even when there is no vebus product + # connected, remove any service that is not connected. Previously we used + # /State since mandatory path /Connected is not implemented in mk2dbus, + # but this has since been resolved. + for servicename in list(services.keys()): + if (self._dbusmonitor.get_value(servicename, '/Connected') != 1 + or self._dbusmonitor.get_value(servicename, '/ProductName') is None + or self._dbusmonitor.get_value(servicename, '/Mgmt/Connection') is None): + del services[servicename] + + def _dbus_value_changed(self, dbusServiceName, dbusPath, dict, changes, deviceInstance): + self._changed = True + + # Workaround because com.victronenergy.vebus is available even when there is no vebus product + # connected. + if (dbusPath in ['/Connected', '/ProductName', '/Mgmt/Connection'] or + (dbusPath == '/State' and dbusServiceName.split('.')[0:3] == ['com', 'victronenergy', 'vebus'])): + self._handleservicechange() + + # Track the timezone changes + if dbusPath == '/Settings/System/TimeZone': + tz = changes.get('Value') + if tz is not None: + os.environ['TZ'] = tz + time.tzset() + + def _device_added(self, service, instance, do_service_change=True): + if do_service_change: + self._handleservicechange() + + for m in self._modules: + m.device_added(service, instance, do_service_change) + + def _device_removed(self, service, instance): + self._handleservicechange() + + for m in self._modules: + m.device_removed(service, instance) + + def _gettext(self, path, value): + item = self._summeditems.get(path) + if item is not None: + try: + gettext = item['gettext'] + except KeyError: + pass + else: + if callable(gettext): + return gettext(value) + return gettext % value + return str(value) + + def _compute_number_of_phases(self, path, newvalues): + number_of_phases = None + for phase in range(1, 4): + p = newvalues.get('%s/L%s/Power' % (path, phase)) + if p is not None: + number_of_phases = phase + newvalues[path + '/NumberOfPhases'] = number_of_phases + + def _get_connected_service_list(self, classfilter=None): + services = self._dbusmonitor.get_service_list(classfilter=classfilter) + self._remove_unconnected_services(services) + return services + + # returns a servicename string + def _get_first_connected_service(self, classfilter): + services = self._get_connected_service_list(classfilter=classfilter) + if len(services) == 0: + return None + return next(iter(services.items()), (None,))[0] + + # returns a tuple (servicename, instance) + def _get_service_having_lowest_instance(self, classfilter=None): + services = self._get_connected_service_list(classfilter=classfilter) + if len(services) == 0: + return None + + # sort the dict by value; returns list of tuples: (value, key) + s = sorted((value, key) for (key, value) in services.items()) + return (s[0][1], s[0][0]) + + +class DbusSystemCalc(SystemCalc): + 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 _create_dbus_service(self): + venusversion, venusbuildtime = self._get_venus_versioninfo() + + dbusservice = VeDbusService('com.victronenergy.system') + dbusservice.add_mandatory_paths( + processname=__file__, + processversion=softwareVersion, + connection='data from other dbus processes', + deviceinstance=0, + productid=None, + productname=None, + firmwareversion=venusversion, + hardwareversion=None, + connected=1) + dbusservice.add_path('/FirmwareBuild', value=venusbuildtime) + return dbusservice + + def _get_venus_versioninfo(self): + try: + with open("/opt/victronenergy/version", "r") as fp: + version, software, buildtime = fp.read().split('\n')[:3] + major, minor, _, rev = re.compile('v([0-9]*)\.([0-9]*)(~([0-9]*))?').match(version).groups() + return (int(major, 16)<<16)+(int(minor, 16)<<8)+(0 if rev is None else int(rev, 16)), buildtime + except Exception: + pass + return 0, '0' + +if __name__ == "__main__": + # Argument parsing + parser = argparse.ArgumentParser( + description='Converts readings from AC-Sensors connected to a VE.Bus device in a pvinverter ' + + 'D-Bus service.' + ) + + parser.add_argument("-d", "--debug", help="set logging level to debug", + action="store_true") + + args = parser.parse_args() + + print("-------- dbus_systemcalc, 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) + + systemcalc = DbusSystemCalc() + + # Start and run the mainloop + logger.info("Starting mainloop, responding only on events") + mainloop = GLib.MainLoop() + mainloop.run() diff --git a/FileSets/v3.40~11/main.qml b/FileSets/v3.40~11/main.qml new file mode 100644 index 00000000..d300de63 --- /dev/null +++ b/FileSets/v3.40~11/main.qml @@ -0,0 +1,598 @@ +//////// Modified to hide the OverviewTiles page +//////// Modified to substitute flow overview pages + +import QtQuick 1.1 + +import Qt.labs.components.native 1.0 +import com.victron.velib 1.0 +import "utils.js" as Utils + +PageStackWindow { + id: rootWindow + + gpsConnected: gpsFix.value === 1 + onCompletedChanged: checkAlarm() + initialPage: PageMain {} + + property VeQuickItem gpsService: VeQuickItem { uid: "dbus/com.victronenergy.system/GpsService" } + property VeQuickItem gpsFix: VeQuickItem { uid: Utils.path("dbus/", gpsService.value, "/Fix") } + property bool completed: false + property bool alarm: alarmNotification.valid ? alarmNotification.value : 0 + property bool showAlert: alertNotification.valid ? alertNotification.value : 0 +//////// 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 : "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 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 + } + 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: selectGeneratorOverview () + } + + VBusItem + { + id: generatorOverviewEnhanced + bind: "com.victronenergy.settings/Settings/GuiMods/UseEnhancedGeneratorOverview" + onValueChanged: selectGeneratorOverview () + } + + VBusItem { + bind: "com.victronenergy.generator.startstop1/GensetProductId" + onValueChanged: { + // Show specific overview for FischerPanda + extraOverview("OverviewGeneratorFp.qml", value === 0xB040) + + // Show generic overview for ComAp and DSE + extraOverview("OverviewGeneratorOther.qml", + [0xB044, 0xB046].indexOf(value) > -1) + + // Switch to FP overview in case it is the default one + if (isOverviewPage) { + pageStack.currentPage.currentIndex = getDefaultOverviewIndex() + } + } + } + + 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 = "" + } + } + } + +//////// 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" + } + + VBusItem { + id: withoutGridMeter + bind: "com.victronenergy.settings/Settings/CGwacs/RunWithoutGridMeter" + } + + + VBusItem { + id: defaultOverview + bind: "com.victronenergy.settings/Settings/Gui/DefaultOverview" + } + + VBusItem { + id: touchEnabled + bind: "com.victronenergy.settings/Settings/Gui/TouchEnabled" + onValueChanged: { + if (completed && value !== undefined) + toast.createToast(value ? qsTr("Touch input on") : qsTr("Touch input off"), 3000) + } + } + + VBusItem { + id: alertNotification + bind: "com.victronenergy.platform/Notifications/Alert" + } + + VBusItem { + id: alarmNotification + bind: "com.victronenergy.platform/Notifications/Alarm" + } + + // Note: finding a firmware image on the storage device is error 4 for vrm storage + // since it should not be used for logging. That fact is used here to determine if + // there is a firmware image. + Connections { + target: storageEvents + onVrmStorageError: { + if (error === 4) { + setTopPage(offlineFwUpdates) + } + } + } + + Connections { + target: vePlatform + onMouseRejected: toast.createToast(qsTr("Touch input disabled"), 1000) + } + + onAlarmChanged: { + if (completed) + checkAlarm() + } + + // always keep track of system information + HubData { + id: theSystem + } + + // note: used for leaving the overviews as well + function backToMainMenu() + { + pageStack.pop(initialPage); + } + + Toast { + id: toast + transform: Scale { + xScale: screen.scaleX + yScale: screen.scaleY + origin.x: toast.width / 2 + origin.y: toast.height / 2 + } + } + + SignalToaster {} + + ToolbarHandlerPages { + id: mainToolbarHandler + isDefault: true + } + + ToolBarLayout { + id: mbTools + height: parent.height + +//// 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) + } + } + + 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 + } + } + } + + Item { + anchors.verticalCenter: parent.verticalCenter + height: mbTools.height + width: mbTools.width - pagesItem.width - menusItem.width - centerScrollIndicator.width + + MouseArea + { + anchors.fill: parent + onClicked: + { + if (darkModeItem.valid) + darkModeItem.setValue (! darkMode) + } + } + + 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: 12 + visible: darkModeItem.valid + } + } + Item + { + id: centerScrollIndicator + anchors.verticalCenter: parent.verticalCenter + height: mbTools.height + width: 20 + MbIcon { + anchors.verticalCenter: parent.verticalCenter + iconId: pageStack.currentPage ? pageStack.currentPage.scrollIndicator : "" + } + } + + 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) + } + } + + Row { + anchors.centerIn: parent + + 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 + } + } + } + } + } + + Component.onCompleted: { + completed = true + } + + ListModel { + id: overviewModel + ListElement { + pageSource: "OverviewHub.qml" + } +//////// (commented out) -- added dynamically above +// ListElement { +// pageSource: "OverviewTiles.qml" +// } + } + + Component { + id: overviewComponent + PageFlow { + // Display default overview when loaded + defaultIndex: getDefaultOverviewIndex() + // Store the current overview page as default + onCurrentIndexChanged: if (active) defaultOverview.setValue(overviewModel.get(currentIndex).pageSource.replace(".qml", "")) + model: overviewModel + } + } + + // When all the related settings items are valid, show the overview page if was the last oppened page + // before restarting + Timer { + interval: 2000 + running: completed && overviewsLoaded && startWithMenu.valid + onTriggered: + { +//////// modified for OverviewGridParallelEnhanced page + selectHubOverview () + if (startWithMenu.value === 0) showOverview() + } + } + + function getDefaultOverviewIndex() + { + if(!defaultOverview.valid) + return 0 + for (var i = 0; i < overviewModel.count; i++){ + if (overviewModel.get(i).pageSource.replace(".qml", "") === defaultOverview.value) { + return i + } + } + return 0 + } + + Component { + id: noticationsComponent + PageNotifications {} + } + + Component { + id: offlineFwUpdates + PageSettingsFirmwareOffline { checkOnCompleted: true} + + } + + // Add or remove extra overviews. for example, generator overview + // shouldn't be shown if the start/stop functionality is not enabled. + // Index parameter is optional, usefull to keep an order. + function extraOverview(name, show, index) + { + var i = 0 + if (show) { + if (index !== undefined) { + if (overviewModel.get(index).pageSource === name) + return + // First append the page + overviewModel.append({"pageSource": name}) + // Then move all the pages behind index + overviewModel.move(index, overviewModel.count - 2, overviewModel.count - 2) + } else { + for (i = 0; i < overviewModel.count; i++) + if (overviewModel.get(i).pageSource === name) + // Don't append if already exists + return + overviewModel.append({"pageSource": name}) + } + } else { + for (i = 0; i < overviewModel.count; i++) + if (overviewModel.get(i).pageSource === name) + overviewModel.remove(i) + } + } + +//////// 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 + // Instead of using a timer per line, using a central one + // reduces the CPU usage a little bit and makes the animations + // smoother. + Timer { + id: mover + property double pos: _counter / _loops + property int _counter + property int _loops: 13 + + interval: 100 + running: true + repeat: true + onTriggered: if (_counter >= (_loops - 1)) _counter = 0; else _counter++ + } + + // If an overview or notifications is active, the new page will replace it + // instead to be pushed. This way we prevent an unwanted stackpage depth + // increment everytime another page wants to be on top. + function setTopPage(page) + { + if (touchEnabled.valid && !touchEnabled.value) + return + + if (isNotificationPage || isOverviewPage || isOfflineFwUpdatePage) + rootWindow.pageStack.replace(page); + else + rootWindow.pageStack.push(page); + } + + function spuriousKeyPress() + { + return !pageStack.currentPage || !pageStack.currentPage.active + } + + function showOverview() + { + if (spuriousKeyPress() || isOverviewPage) + return + setTopPage(overviewComponent) + } + + function showPageNotifications() + { + if (spuriousKeyPress() || isNotificationPage) + return + setTopPage(noticationsComponent) + } + + function checkAlarm() + { + if (alarm) + showPageNotifications() + } + + FirmwareUpdate { id: firmwareUpdate } +} diff --git a/FileSets/v3.40~10/main.qml.orig b/FileSets/v3.40~11/main.qml.orig similarity index 100% rename from FileSets/v3.40~10/main.qml.orig rename to FileSets/v3.40~11/main.qml.orig diff --git a/FileSets/v3.40~11/startstop.py b/FileSets/v3.40~11/startstop.py new file mode 100644 index 00000000..e3a11410 --- /dev/null +++ b/FileSets/v3.40~11/startstop.py @@ -0,0 +1,1536 @@ +#!/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~10/startstop.py.orig b/FileSets/v3.40~11/startstop.py.orig similarity index 100% rename from FileSets/v3.40~10/startstop.py.orig rename to FileSets/v3.40~11/startstop.py.orig diff --git a/FileSets/v3.40~11/styles.css b/FileSets/v3.40~11/styles.css new file mode 100644 index 00000000..67c5230f --- /dev/null +++ b/FileSets/v3.40~11/styles.css @@ -0,0 +1,11043 @@ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section { + display: block; +} +audio, +canvas, +video { + display: inline-block; + *display: inline; + *zoom: 1; +} +audio:not([controls]) { + display: none; +} +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} +a:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +a:hover, +a:active { + outline: 0; +} +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} +sup { + top: -0.5em; +} +sub { + bottom: -0.25em; +} +img { + /* Responsive images (ensure images don't scale beyond their parents) */ + max-width: 100%; + /* Part 1: Set a maxium relative to the parent */ + width: auto\9; + /* IE7-8 need help adjusting responsive images */ + height: auto; + /* Part 2: Scale the height according to the width, otherwise you get stretching */ + vertical-align: middle; + border: 0; + -ms-interpolation-mode: bicubic; +} +#map_canvas img, +.google-maps img { + max-width: none; +} +button, +input, +select, +textarea { + margin: 0; + font-size: 100%; + vertical-align: middle; + background-image: none; +} +button, +input { + *overflow: visible; + line-height: normal; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; +} +label, +select, +button, +input[type="button"], +input[type="reset"], +input[type="submit"], +input[type="radio"], +input[type="checkbox"] { + cursor: pointer; +} +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} +textarea { + overflow: auto; + vertical-align: top; +} +@media print { + * { + text-shadow: none !important; + color: #000 !important; + background: transparent !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + .ir a:after, + a[href^="javascript:"]:after, + a[href^="#"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + @page { + margin: 0.5cm; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } +} +/* @group Base */ +.chzn-container { + position: relative; + display: inline-block; + zoom: 1; +} +.chzn-container .chzn-drop { + border-top: 0; + position: absolute; + left: 0; + z-index: 1010; +} +/* @end */ +/* @group Single Chosen */ +.chzn-container-single .chzn-single { + display: block; + outline: none; + overflow: hidden; + white-space: nowrap; + position: relative; + text-decoration: none; +} +.chzn-container-single .chzn-single span { + display: block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.chzn-container-single .chzn-single .handle { + position: absolute; + right: 0; + top: 0; + display: block; +} +.chzn-container-single .chzn-search { + position: relative; + white-space: nowrap; + z-index: 1010; +} +.no-search + .chzn-container-single .chzn-search { + display: none !important; +} +.chzn-container-single .chzn-search input { + outline: 0; +} +/* @group Results */ +.chzn-container .chzn-results { + position: relative; + overflow-x: hidden; + overflow-y: auto; + -webkit-overflow-scrolling: touch; +} +.chzn-container-multi .chzn-results { + padding: 0; +} +.chzn-container .chzn-results li { + display: none; + margin: 0; + list-style: none; +} +.chzn-container .chzn-results .active-result { + cursor: pointer; + display: list-item; + width: 100%; +} +.chzn-container .chzn-results .no-results { + display: list-item; +} +.chzn-container .chzn-results .group-result { + cursor: default; +} +.chzn-container .chzn-results .group-option { + padding-left: 15px; +} +.chzn-container-multi .chzn-drop .result-selected { + display: none; +} +/* @end */ +div.datepicker { + position: relative; + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + width: 196px; + height: 147px; + position: absolute; + cursor: default; + top: 0; + left: 0; + display: none; +} +.datepickerContainer { + position: absolute; +} +/* Hide border divs by default */ +.datepickerBorderT, +.datepickerBorderB, +.datepickerBorderL, +.datepickerBorderR, +.datepickerBorderTL, +.datepickerBorderTR, +.datepickerBorderBL, +.datepickerBorderBR { + display: none; +} +.datepickerHidden { + display: none; +} +div.datepicker table { + border-collapse: collapse; +} +div.datepicker a { + color: black; + text-decoration: none; + cursor: default; + outline: none; +} +div.datepicker table td { + text-align: center; + padding: 0; + margin: 0; +} +div.datepicker th { + text-align: center; + color: #666666; + font-weight: normal; + padding: 0; +} +div.datepicker tbody a { + display: block; +} +.datepickerDays a { + width: 20px; + line-height: 16px; + height: 16px; + padding-right: 2px; +} +.datepickerYears a, +.datepickerMonths a { + width: 39px; + line-height: 36px; + height: 36px; + text-align: center; +} +.datepickerMonths td:first-child a, +.datepickerMonths td:last-child a, +.datepickerYears td:first-child a, +.datepickerYears td:last-child a { + width: 38px; +} +td.datepickerNotInMonth a { + color: #666666; +} +tbody.datepickerDays td.datepickerSelected { + background: #136A9F; +} +tbody.datepickerDays td.datepickerNotInMonth.datepickerSelected { + background: #17384d; +} +tbody.datepickerYears td.datepickerSelected, +tbody.datepickerMonths td.datepickerSelected { + background: #17384d; +} +div.datepicker td.datepickerSelected a { + color: white; +} +div.datepicker a:hover, +div.datepicker a:hover { + color: #88c5eb; +} +div.datepicker td.datepickerNotInMonth a:hover { + color: #999999; +} +.datepickerSpace div { + width: 20px; +} +.datepickerBlock { + vertical-align: top; +} +a.datepickerGoNext, +a.datepickerGoPrev, +a.datepickerMonth { + text-align: center; + height: 20px; + line-height: 20px; + float: left; +} +div.datepicker th a.datepickerGoNext, +div.datepicker th a.datepickerGoPrev { + width: 20px; + color: #666666; + display: none; +} +div.datepicker th a.datepickerMonth { + width: 114px; + display: block; +} +/* Only display the previous/next arrows on the first/last calendars */ +div.datepicker .datepickerFirstView th a.datepickerGoPrev, +div.datepicker .datepickerLastView th a.datepickerGoNext { + display: block; +} +/* Compensate for the space lost by not having a previous arrow */ +div.datepicker th a.datepickerMonth { + margin-left: 20px; +} +div.datepicker .datepickerFirstView th a.datepickerMonth { + margin-left: 0; +} +/* Day mode calendar body */ +table.datepickerViewDays tbody.datepickerMonths, +table.datepickerViewDays tbody.datepickerYears { + display: none; +} +/* Month mode calendar body */ +table.datepickerViewMonths tbody.datepickerDays, +table.datepickerViewMonths tbody.datepickerYears, +table.datepickerViewMonths tr.datepickerDoW { + display: none; +} +/* Year mode calendar body */ +table.datepickerViewYears tbody.datepickerDays, +table.datepickerViewYears tbody.datepickerMonths, +table.datepickerViewYears tr.datepickerDoW { + display: none; +} +td.datepickerDisabled a, +td.datepickerDisabled.datepickerNotInMonth a { + color: #555555; +} +td.datepickerDisabled a:hover { + color: #333333; +} +/* Not used by default, calendar cells can be marked as special if desired (doesn't seem to be totally working) */ +div.datepicker tbody.datepickerDays td.datepickerSpecial a { + background: #770000; + color: white; +} +div.datepicker tbody.datepickerDays td.datepickerSpecial.datepickerSelected a { + background: #aa0000; +} +/* style the 'not in month' day cell away */ +tbody.datepickerDays td.datepickerNotInMonth.datepickerSelected { + background-color: transparent; +} +div.datepicker td.datepickerNotInMonth a span { + display: none; +} +div.datepicker td.datepickerNotInMonth a:hover span { + display: none; +} +div.datepicker tbody.datepickerDays td.datepickerNotInMonth:hover { + background-color: transparent; +} +.picker { + font-size: 16px; + text-align: left; + line-height: 1.2; + color: #000; + position: absolute; + z-index: 10000; +} +.picker__input { + cursor: default; +} +.picker__input.picker__input--active { + border-color: #0089ec; +} +.picker__holder { + width: 100%; + overflow-y: auto; + -webkit-overflow-scrolling: touch; +} +.picker { + width: 100%; +} +.picker__holder { + position: absolute; + background: #fff; + border: 1px solid #aaa; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + min-width: 176px; + max-width: 466px; + -webkit-border-radius: 0 0 5px 5px; + -moz-border-radius: 0 0 5px 5px; + border-radius: 0 0 5px 5px; + max-height: 0; + -ms-filter: "alpha(Opacity=0)"; + filter: alpha(opacity=0); + -moz-opacity: 0; + opacity: 0; + -webkit-transform: translateY(-1em) perspective(600px) rotateX(10deg); + -moz-transform: translateY(-1em) perspective(600px) rotateX(10deg); + transform: translateY(-1em) perspective(600px) rotateX(10deg); + -webkit-transition: all 0.15s ease-out, max-height 0 0.15s; + -moz-transition: all 0.15s ease-out, max-height 0 0.15s; + transition: all 0.15s ease-out, max-height 0 0.15s; +} +.picker--opened .picker__holder { + max-height: 25em; + -ms-filter: "alpha(Opacity=100)"; + filter: alpha(opacity=100); + -moz-opacity: 1; + opacity: 1; + -webkit-transform: translateY(0) perspective(600px) rotateX(0); + -moz-transform: translateY(0) perspective(600px) rotateX(0); + transform: translateY(0) perspective(600px) rotateX(0); + -webkit-transition: all 0.15s ease-out, max-height 0; + -moz-transition: all 0.15s ease-out, max-height 0; + transition: all 0.15s ease-out, max-height 0; + -webkit-box-shadow: 0 6px 18px 1px rgba(0, 0, 0, 0.12); + -moz-box-shadow: 0 6px 18px 1px rgba(0, 0, 0, 0.12); + box-shadow: 0 6px 18px 1px rgba(0, 0, 0, 0.12); +} +.picker__box { + padding: 0 1em; +} +.picker__header { + text-align: center; + position: relative; + margin-top: 0.75em; +} +.picker__month, +.picker__year { + font-weight: 500; + display: inline-block; + margin-left: .25em; + margin-right: 0.25em; +} +.picker__year { + color: #999; + font-size: .8em; + font-style: italic; +} +.picker__select--month, +.picker__select--year { + font-size: .8em; + border: 1px solid #b7b7b7; + height: 2.5em; + padding: .5em .25em; + margin-left: .25em; + margin-right: .25em; + margin-top: -0.5em; +} +.picker__select--month { + width: 35%; +} +.picker__select--year { + width: 22.5%; +} +.picker__select--month:focus, +.picker__select--year:focus { + border-color: #0089ec; +} +.picker__nav--prev, +.picker__nav--next { + position: absolute; + top: -0.33em; + padding: .5em 1.33em; + width: 1em; + height: 1em; +} +.picker__nav--prev { + left: -1em; + padding-right: 1.5em; +} +.picker__nav--next { + right: -1em; + padding-left: 1.5em; +} +.picker__nav--prev:before, +.picker__nav--next:before { + content: " "; + border-top: .5em solid transparent; + border-bottom: .5em solid transparent; + border-right: .75em solid #000; + width: 0; + height: 0; + display: block; + margin: 0 auto; +} +.picker__nav--next:before { + border-right: 0; + border-left: 0.75em solid #000000; +} +.picker__nav--prev:hover, +.picker__nav--next:hover { + cursor: pointer; + color: #000; + background: #b1dcfb; +} +.picker__nav--disabled, +.picker__nav--disabled:hover, +.picker__nav--disabled:before, +.picker__nav--disabled:before:hover { + cursor: default; + background: 0; + border-right-color: #f5f5f5; + border-left-color: #f5f5f5; +} +.picker__table { + text-align: center; + border-collapse: collapse; + border-spacing: 0; + table-layout: fixed; + font-size: inherit; + width: 100%; + margin-top: .75em; + margin-bottom: 0.5em; +} +@media (min-height: 33.875em) { + .picker__table { + margin-bottom: 0.75em; + } +} +.picker__table td { + margin: 0; + padding: 0; +} +.picker__weekday { + width: 14.285714286%; + font-size: .75em; + padding-bottom: .25em; + color: #999; + font-weight: 500; +} +@media (min-height: 33.875em) { + .picker__weekday { + padding-bottom: 0.5em; + } +} +.picker__day { + padding: .3125em 0; + font-weight: 200; + border: 1px solid transparent; +} +.picker__day--today { + color: #0089ec; + position: relative; +} +.picker__day--today:before { + content: " "; + position: absolute; + top: 2px; + right: 2px; + width: 0; + height: 0; + border-top: .5em solid #0059bc; + border-left: 0.5em solid transparent; +} +.picker__day--selected, +.picker__day--selected:hover { + border-color: #0089ec; +} +.picker__day--highlighted { + background: #b1dcfb; +} +.picker__day--disabled:before { + border-top-color: #aaaaaa; +} +.picker__day--outfocus { + color: #dddddd; +} +.picker__day--infocus:hover, +.picker__day--outfocus:hover { + cursor: pointer; + color: #000; + background: #b1dcfb; +} +.picker__day--highlighted:hover, +.picker--focused .picker__day--highlighted { + background: #0089ec; + color: #ffffff; +} +.picker__day--disabled, +.picker__day--disabled:hover { + background: #f5f5f5; + border-color: #f5f5f5; + color: #ddd; + cursor: default; +} +.picker__day--highlighted.picker__day--disabled, +.picker__day--highlighted.picker__day--disabled:hover { + background: #bbbbbb; +} +.picker__footer { + text-align: center; +} +.picker__button--today, +.picker__button--clear { + border: 1px solid #fff; + background: #fff; + font-size: .8em; + padding: .66em 0; + font-weight: 700; + width: 50%; + display: inline-block; + vertical-align: bottom; +} +.picker__button--today:hover, +.picker__button--clear:hover { + cursor: pointer; + color: #000; + background: #b1dcfb; + border-bottom-color: #b1dcfb; +} +.picker__button--today:focus, +.picker__button--clear:focus { + background: #b1dcfb; + border-color: #0089ec; + outline: 0; +} +.picker__button--today:before, +.picker__button--clear:before { + position: relative; + display: inline-block; + height: 0; +} +.picker__button--today:before { + content: " "; + margin-right: .45em; + top: -0.05em; + width: 0; + border-top: .66em solid #0059bc; + border-left: 0.66em solid transparent; +} +.picker__button--clear:before { + content: "\D7"; + margin-right: .35em; + top: -0.1em; + color: #e20; + vertical-align: top; + font-size: 1.1em; +} +.picker__list { + list-style: none; + padding: .75em 0 4.2em; + margin: 0; +} +.picker__list-item { + border-bottom: 1px solid #ddd; + border-top: 1px solid #ddd; + margin-bottom: -1px; + position: relative; + background: #fff; + padding: 0.75em 1.25em; +} +@media (min-height: 46.75em) { + .picker__list-item { + padding: 0.5em 1em; + } +} +.picker__list-item:hover { + cursor: pointer; + color: #000; + background: #b1dcfb; + border-color: #0089ec; + z-index: 10; +} +.picker__list-item--selected, +.picker__list-item--selected:hover { + border-color: #0089ec; + z-index: 10; +} +.picker__list-item--highlighted { + background: #b1dcfb; +} +.picker__list-item--highlighted:hover, +.picker--focused .picker__list-item--highlighted { + background: #0089ec; + color: #ffffff; +} +.picker__list-item--disabled, +.picker__list-item--disabled:hover, +.picker--focused .picker__list-item--disabled { + background: #f5f5f5; + border-color: #f5f5f5; + color: #ddd; + cursor: default; + border-color: #ddd; + z-index: auto; +} +.picker--time .picker__button--clear { + display: block; + width: 80%; + margin: 1em auto 0; + padding: 1em 1.25em; + background: 0; + border: 0; + font-weight: 500; + font-size: .67em; + text-align: center; + text-transform: uppercase; + color: #666666; +} +.picker--time .picker__button--clear:hover, +.picker--time .picker__button--clear:focus { + color: #000; + background: #b1dcfb; + background: #e20; + border-color: #e20; + cursor: pointer; + color: #fff; + outline: 0; +} +.picker--time .picker__button--clear:before { + top: -0.25em; + color: #666; + font-size: 1.25em; + font-weight: 700; +} +.picker--time .picker__button--clear:hover:before, +.picker--time .picker__button--clear:focus:before { + color: #ffffff; +} +.picker--time { + min-width: 256px; + max-width: 320px; +} +.picker--time .picker__holder { + background: #f2f2f2; +} +@media (min-height: 40.125em) { + .picker--time .picker__holder { + font-size: 0.875em; + } +} +.picker--time .picker__box { + padding: 0; +} +/*rules for the plot target div. These will be cascaded down to all plot elements according to css rules*/ +.jqplot-target { + position: relative; + color: #666666; + font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; + font-size: 1em; + /* height: 300px; + width: 400px;*/ +} +/*rules applied to all axes*/ +.jqplot-axis { + font-size: 0.75em; +} +.jqplot-xaxis { + margin-top: 10px; +} +.jqplot-x2axis { + margin-bottom: 10px; +} +.jqplot-yaxis { + margin-right: 10px; +} +.jqplot-y2axis, +.jqplot-y3axis, +.jqplot-y4axis, +.jqplot-y5axis, +.jqplot-y6axis, +.jqplot-y7axis, +.jqplot-y8axis, +.jqplot-y9axis, +.jqplot-yMidAxis { + margin-left: 10px; + margin-right: 0px; +} +/*rules applied to all axis tick divs*/ +.jqplot-axis-tick, +.jqplot-xaxis-tick, +.jqplot-yaxis-tick, +.jqplot-x2axis-tick, +.jqplot-y2axis-tick, +.jqplot-y3axis-tick, +.jqplot-y4axis-tick, +.jqplot-y5axis-tick, +.jqplot-y6axis-tick, +.jqplot-y7axis-tick, +.jqplot-y8axis-tick, +.jqplot-y9axis-tick, +.jqplot-yMidAxis-tick { + position: absolute; + white-space: pre; +} +.jqplot-xaxis-tick { + top: 0px; + /* initial position untill tick is drawn in proper place */ + left: 15px; + /* padding-top: 10px;*/ + text-align: center; + vertical-align: top; +} +.jqplot-x2axis-tick { + bottom: 0px; + /* initial position untill tick is drawn in proper place */ + left: 15px; + /* padding-bottom: 10px;*/ + vertical-align: bottom; +} +.jqplot-yaxis-tick { + right: 0px; + /* initial position untill tick is drawn in proper place */ + top: 15px; + /* padding-right: 10px;*/ + text-align: right; +} +.jqplot-yaxis-tick.jqplot-breakTick { + right: -20px; + margin-right: 0px; + padding: 1px 5px 1px 5px; + /* background-color: white;*/ + z-index: 2; + font-size: 1.5em; +} +.jqplot-y2axis-tick, +.jqplot-y3axis-tick, +.jqplot-y4axis-tick, +.jqplot-y5axis-tick, +.jqplot-y6axis-tick, +.jqplot-y7axis-tick, +.jqplot-y8axis-tick, +.jqplot-y9axis-tick { + left: 0px; + /* initial position untill tick is drawn in proper place */ + top: 15px; + /* padding-left: 10px;*/ + /* padding-right: 15px;*/ + text-align: left; +} +.jqplot-yMidAxis-tick { + text-align: center; + white-space: nowrap; +} +.jqplot-xaxis-label { + margin-top: 10px; + font-size: 11pt; + position: absolute; +} +.jqplot-x2axis-label { + margin-bottom: 10px; + font-size: 11pt; + position: absolute; +} +.jqplot-yaxis-label { + margin-right: 10px; + /* text-align: center;*/ + font-size: 11pt; + position: absolute; +} +.jqplot-yMidAxis-label { + font-size: 11pt; + position: absolute; +} +.jqplot-y2axis-label, +.jqplot-y3axis-label, +.jqplot-y4axis-label, +.jqplot-y5axis-label, +.jqplot-y6axis-label, +.jqplot-y7axis-label, +.jqplot-y8axis-label, +.jqplot-y9axis-label { + /* text-align: center;*/ + font-size: 11pt; + margin-left: 10px; + position: absolute; +} +.jqplot-meterGauge-tick { + font-size: 0.75em; + color: #999999; +} +.jqplot-meterGauge-label { + font-size: 1em; + color: #999999; +} +table.jqplot-table-legend { + margin-top: 12px; + margin-bottom: 12px; + margin-left: 12px; + margin-right: 12px; +} +table.jqplot-table-legend, +table.jqplot-cursor-legend { + background-color: rgba(255, 255, 255, 0.6); + border: 1px solid #cccccc; + position: absolute; + font-size: 0.75em; +} +td.jqplot-table-legend { + vertical-align: middle; +} +/* +These rules could be used instead of assigning +element styles and relying on js object properties. +*/ +/* +td.jqplot-table-legend-swatch { + padding-top: 0.5em; + text-align: center; +} + +tr.jqplot-table-legend:first td.jqplot-table-legend-swatch { + padding-top: 0px; +} +*/ +td.jqplot-seriesToggle:hover, +td.jqplot-seriesToggle:active { + cursor: pointer; +} +.jqplot-table-legend .jqplot-series-hidden { + text-decoration: line-through; +} +div.jqplot-table-legend-swatch-outline { + border: 1px solid #cccccc; + padding: 1px; +} +div.jqplot-table-legend-swatch { + width: 0px; + height: 0px; + border-top-width: 5px; + border-bottom-width: 5px; + border-left-width: 6px; + border-right-width: 6px; + border-top-style: solid; + border-bottom-style: solid; + border-left-style: solid; + border-right-style: solid; +} +.jqplot-title { + top: 0px; + left: 0px; + padding-bottom: 0.5em; + font-size: 1.7em; +} +table.jqplot-cursor-tooltip { + border: 1px solid #cccccc; + font-size: 0.75em; +} +.jqplot-cursor-tooltip { + border: 1px solid #cccccc; + font-size: 0.75em; + white-space: nowrap; + background: rgba(208, 208, 208, 0.5); + padding: 1px; +} +.jqplot-highlighter-tooltip, +.jqplot-canvasOverlay-tooltip { + border: 1px solid #cccccc; + font-size: 0.75em; + white-space: nowrap; + background: rgba(208, 208, 208, 0.5); + padding: 1px; +} +.jqplot-point-label { + font-size: 0.75em; + z-index: 2; +} +td.jqplot-cursor-legend-swatch { + vertical-align: middle; + text-align: center; +} +div.jqplot-cursor-legend-swatch { + width: 1.2em; + height: 0.7em; +} +.jqplot-error { + /* Styles added to the plot target container when there is an error go here.*/ + text-align: center; +} +.jqplot-error-message { + /* Styling of the custom error message div goes here.*/ + position: relative; + top: 46%; + display: inline-block; +} +div.jqplot-bubble-label { + font-size: 0.8em; + /* background: rgba(90%, 90%, 90%, 0.15);*/ + padding-left: 2px; + padding-right: 2px; + color: #333333; +} +div.jqplot-bubble-label.jqplot-bubble-label-highlight { + background: rgba(230, 230, 230, 0.7); +} +div.jqplot-noData-container { + text-align: center; + background-color: rgba(245, 245, 245, 0.3); +} +.jqplot-table-legend { + width: initial; + left: 27px !important; + border: 0; + background-color: transparent; +} +.jqplot-table-legend tr { + display: block; + float: left; + border: 0; +} +.jqplot-table-legend tr td { + padding: 4px !important; + border: 0; + background: transparent; + line-height: 24px; +} +.jqplot-table-legend tr td .jqplot-table-legend-swatch-outline { + border: 0; + padding: 0; +} +.jqplot-table-legend tr td .jqplot-table-legend-swatch { + border-width: 1px; + border-style: solid; + width: 19px; + height: 19px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.ps-container .ps-scrollbar-x-rail { + position: absolute; + /* please don't change 'position' */ + bottom: 3px; + /* there must be 'bottom' for ps-scrollbar-x-rail */ + height: 8px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + opacity: 0; + filter: alpha(opacity=0); + -o-transition: background-color 0.2s linear, opacity 0.2s linear; + -webkit-transition: background-color 0.2s linear, opacity 0.2s linear; + -moz-transition: background-color 0.2s linear, opacity 0.2s linear; + transition: background-color 0.2s linear, opacity 0.2s linear; +} +.ps-container:hover .ps-scrollbar-x-rail, +.ps-container.hover .ps-scrollbar-x-rail { + opacity: 0.6; + filter: alpha(opacity=60); +} +.ps-container .ps-scrollbar-x-rail:hover, +.ps-container .ps-scrollbar-x-rail.hover { + background-color: #eee; + opacity: 0.9; + filter: alpha(opacity=90); +} +.ps-container .ps-scrollbar-x-rail.in-scrolling { + background-color: #eee; + opacity: 0.9; + filter: alpha(opacity=90); +} +.ps-container .ps-scrollbar-y-rail { + position: absolute; + /* please don't change 'position' */ + right: 3px; + /* there must be 'right' for ps-scrollbar-y-rail */ + width: 8px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + opacity: 0; + filter: alpha(opacity = 0); + -o-transition: background-color 0.2s linear, opacity 0.2s linear; + -webkit-transition: background-color 0.2s linear, opacity 0.2s linear; + -moz-transition: background-color 0.2s linear, opacity 0.2s linear; + transition: background-color 0.2s linear, opacity 0.2s linear; +} +.ps-container:hover .ps-scrollbar-y-rail, +.ps-container.hover .ps-scrollbar-y-rail { + opacity: 0.6; + filter: alpha(opacity=60); +} +.ps-container .ps-scrollbar-y-rail:hover, +.ps-container .ps-scrollbar-y-rail.hover { + background-color: #eee; + opacity: 0.9; + filter: alpha(opacity=90); +} +.ps-container .ps-scrollbar-y-rail.in-scrolling { + background-color: #eee; + opacity: 0.9; + filter: alpha(opacity=90); +} +.ps-container .ps-scrollbar-x { + position: absolute; + /* please don't change 'position' */ + bottom: 0; + /* there must be 'bottom' for ps-scrollbar-x */ + height: 8px; + background-color: #aaa; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -o-transition: background-color 0.2s linear; + -webkit-transition: background-color 0.2s linear; + -moz-transition: background-color 0.2s linear; + transition: background-color 0.2s linear; +} +.ps-container.ie6 .ps-scrollbar-x { + font-size: 0; + /* fixed scrollbar height in xp sp3 ie6 */ +} +.ps-container .ps-scrollbar-x-rail:hover .ps-scrollbar-x, +.ps-container .ps-scrollbar-x-rail.hover .ps-scrollbar-x { + background-color: #999; +} +.ps-container .ps-scrollbar-y { + position: absolute; + /* please don't change 'position' */ + right: 0; + /* there must be 'right' for ps-scrollbar-y */ + width: 8px; + background-color: #aaa; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -o-transition: background-color 0.2s linear; + -webkit-transition: background-color 0.2s linear; + -moz-transition: background-color 0.2s linear; + transition: background-color 0.2s linear; +} +.ps-container.ie6 .ps-scrollbar-y { + font-size: 0; + /* fixed scrollbar height in xp sp3 ie6 */ +} +.ps-container .ps-scrollbar-y-rail:hover .ps-scrollbar-y, +.ps-container .ps-scrollbar-y-rail.hover .ps-scrollbar-y { + background-color: #999; +} +.ps-container.ie .ps-scrollbar-x, +.ps-container.ie .ps-scrollbar-y { + visibility: hidden; +} +.ps-container.ie:hover .ps-scrollbar-x, +.ps-container.ie:hover .ps-scrollbar-y, +.ps-container.ie.hover .ps-scrollbar-x, +.ps-container.ie.hover .ps-scrollbar-y { + visibility: visible; +} +.chardinjs-overlay { + display: none; + position: absolute; + z-index: 999999; + background-color: black; + opacity: 0.8; + filter: alpha(opacity=80); +} +.chardinjs-helper-layer { + position: absolute; + z-index: 9999998; + color: white; +} +.chardinjs-helper-layer.chardinjs-left { + border-left: solid white 1px; + margin-left: -10px; +} +.chardinjs-helper-layer.chardinjs-right { + border-right: solid white 1px; + padding-right: 10px; +} +.chardinjs-helper-layer.chardinjs-bottom { + border-bottom: solid white 1px; + padding-bottom: 10px; +} +.chardinjs-helper-layer.chardinjs-top { + border-top: solid white 1px; + padding-top: 10px; +} +.chardinjs-tooltip { + position: absolute; + -webkit-transition: opacity 0.1s ease-out; + -moz-transition: opacity 0.1s ease-out; + -o-transition: opacity 0.1s ease-out; + transition: opacity 0.1s ease-out; + max-width: 200px; +} +.chardinjs-tooltip.chardinjs-left { + margin-left: -135px; + padding-right: 10px; +} +.chardinjs-tooltip.chardinjs-right { + margin-right: -135px; + padding-left: 10px; +} +.chardinjs-tooltip.chardinjs-bottom { + margin-bottom: -50px; + padding-top: 10px; +} +.chardinjs-tooltip.chardinjs-top { + margin-top: -50px; + padding-bottom: 10px; +} +.chardinjs-tooltip.chardinjs-right:before, +.chardinjs-tooltip.chardinjs-left:after, +.chardinjs-tooltip.chardinjs-bottom:before, +.chardinjs-tooltip.chardinjs-top:after { + content: "."; + display: inline-block; + background-color: white; + height: 1px; + overflow: hidden; + position: absolute; +} +.chardinjs-tooltip.chardinjs-right:before, +.chardinjs-tooltip.chardinjs-left:after { + width: 100px; + top: 50%; +} +.chardinjs-tooltip.chardinjs-bottom:before, +.chardinjs-tooltip.chardinjs-top:after { + width: 1px; + height: 50px; + left: 50%; +} +.chardinjs-tooltip.chardinjs-bottom:before { + top: -50px; +} +.chardinjs-tooltip.chardinjs-top:after { + bottom: -50px; +} +.chardinjs-tooltip.chardinjs-right:before { + left: -100px; +} +.chardinjs-tooltip.chardinjs-left:after { + right: -100px; +} +.chardinjs-show-element { + z-index: 9999999 !important; + opacity: 0.8; + filter: alpha(opacity=80); +} +.chardinjs-relative-position { + position: relative; +} +/* required styles */ +.leaflet-map-pane, +.leaflet-tile, +.leaflet-marker-icon, +.leaflet-marker-shadow, +.leaflet-tile-pane, +.leaflet-tile-container, +.leaflet-overlay-pane, +.leaflet-shadow-pane, +.leaflet-marker-pane, +.leaflet-popup-pane, +.leaflet-overlay-pane svg, +.leaflet-zoom-box, +.leaflet-image-layer, +.leaflet-layer { + position: absolute; + left: 0; + top: 0; +} +.leaflet-container { + overflow: hidden; + -ms-touch-action: none; +} +.leaflet-tile, +.leaflet-marker-icon, +.leaflet-marker-shadow { + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + -webkit-user-drag: none; +} +.leaflet-marker-icon, +.leaflet-marker-shadow { + display: block; +} +.leaflet-container img { + max-width: none ! important; +} +.leaflet-container img.leaflet-image-layer { + max-width: 15000px ! important; +} +.leaflet-tile { + filter: inherit; + visibility: hidden; +} +.leaflet-tile-loaded { + visibility: inherit; +} +.leaflet-zoom-box { + width: 0; + height: 0; +} +.leaflet-overlay-pane svg { + -moz-user-select: none; +} +.leaflet-tile-pane { + z-index: 2; +} +.leaflet-objects-pane { + z-index: 3; +} +.leaflet-overlay-pane { + z-index: 4; +} +.leaflet-shadow-pane { + z-index: 5; +} +.leaflet-marker-pane { + z-index: 6; +} +.leaflet-popup-pane { + z-index: 7; +} +.leaflet-vml-shape { + width: 1px; + height: 1px; +} +.lvml { + behavior: url(#default#VML); + display: inline-block; + position: absolute; +} +.leaflet-control { + position: relative; + z-index: 7; + pointer-events: auto; +} +.leaflet-top, +.leaflet-bottom { + position: absolute; + z-index: 1000; + pointer-events: none; +} +.leaflet-top { + top: 0; +} +.leaflet-right { + right: 0; +} +.leaflet-bottom { + bottom: 0; +} +.leaflet-left { + left: 0; +} +.leaflet-control { + float: left; + clear: both; +} +.leaflet-right .leaflet-control { + float: right; +} +.leaflet-top .leaflet-control { + margin-top: 10px; +} +.leaflet-bottom .leaflet-control { + margin-bottom: 10px; +} +.leaflet-left .leaflet-control { + margin-left: 10px; +} +.leaflet-right .leaflet-control { + margin-right: 10px; +} +.leaflet-fade-anim .leaflet-tile, +.leaflet-fade-anim .leaflet-popup { + opacity: 0; + -webkit-transition: opacity 0.2s linear; + -moz-transition: opacity 0.2s linear; + -o-transition: opacity 0.2s linear; + transition: opacity 0.2s linear; +} +.leaflet-fade-anim .leaflet-tile-loaded, +.leaflet-fade-anim .leaflet-map-pane .leaflet-popup { + opacity: 1; +} +.leaflet-zoom-anim .leaflet-zoom-animated { + -webkit-transition: -webkit-transform 0.25s cubic-bezier(0, 0, 0.25, 1); + -moz-transition: -moz-transform 0.25s cubic-bezier(0, 0, 0.25, 1); + -o-transition: -o-transform 0.25s cubic-bezier(0, 0, 0.25, 1); + transition: transform 0.25s cubic-bezier(0, 0, 0.25, 1); +} +.leaflet-zoom-anim .leaflet-tile, +.leaflet-pan-anim .leaflet-tile, +.leaflet-touching .leaflet-zoom-animated { + -webkit-transition: none; + -moz-transition: none; + -o-transition: none; + transition: none; +} +.leaflet-zoom-anim .leaflet-zoom-hide { + visibility: hidden; +} +.leaflet-clickable { + cursor: pointer; +} +.leaflet-container { + cursor: -webkit-grab; + cursor: -moz-grab; +} +.leaflet-popup-pane, +.leaflet-control { + cursor: auto; +} +.leaflet-dragging .leaflet-container, +.leaflet-dragging .leaflet-clickable { + cursor: move; + cursor: -webkit-grabbing; + cursor: -moz-grabbing; +} +.leaflet-container { + background: #ddd; + outline: 0; +} +.leaflet-container a { + color: #0078A8; +} +.leaflet-container a.leaflet-active { + outline: 2px solid orange; +} +.leaflet-zoom-box { + border: 2px dotted #38f; + background: rgba(255, 255, 255, 0.5); +} +.leaflet-container { + font: 12px / 1.5 "Helvetica Neue", Arial, Helvetica, sans-serif; +} +.leaflet-bar { + box-shadow: 0 1px 5px rgba(0, 0, 0, 0.65); + border-radius: 4px; +} +.leaflet-bar a, +.leaflet-bar a:hover { + background-color: #fff; + border-bottom: 1px solid #ccc; + width: 26px; + height: 26px; + line-height: 26px; + display: block; + text-align: center; + text-decoration: none; + color: black; +} +.leaflet-bar a, +.leaflet-control-layers-toggle { + background-position: 50% 50%; + background-repeat: no-repeat; + display: block; +} +.leaflet-bar a:hover { + background-color: #f4f4f4; +} +.leaflet-bar a:first-child { + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} +.leaflet-bar a:last-child { + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + border-bottom: none; +} +.leaflet-bar a.leaflet-disabled { + cursor: default; + background-color: #f4f4f4; + color: #bbb; +} +.leaflet-touch .leaflet-bar a { + width: 30px; + height: 30px; + line-height: 30px; +} +.leaflet-control-zoom-in, +.leaflet-control-zoom-out { + font: bold 18px 'Lucida Console', Monaco, monospace; + text-indent: 1px; +} +.leaflet-control-zoom-out { + font-size: 20px; +} +.leaflet-touch .leaflet-control-zoom-in { + font-size: 22px; +} +.leaflet-touch .leaflet-control-zoom-out { + font-size: 24px; +} +.leaflet-control-layers { + box-shadow: 0 1px 5px rgba(0, 0, 0, 0.4); + background: #fff; + border-radius: 5px; +} +.leaflet-control-layers-toggle { + background-image: url(images/layers.png); + width: 36px; + height: 36px; +} +.leaflet-retina .leaflet-control-layers-toggle { + background-image: url(images/layers-2x.png); + background-size: 26px 26px; +} +.leaflet-touch .leaflet-control-layers-toggle { + width: 44px; + height: 44px; +} +.leaflet-control-layers .leaflet-control-layers-list, +.leaflet-control-layers-expanded .leaflet-control-layers-toggle { + display: none; +} +.leaflet-control-layers-expanded .leaflet-control-layers-list { + display: block; + position: relative; +} +.leaflet-control-layers-expanded { + padding: 6px 10px 6px 6px; + color: #333; + background: #fff; +} +.leaflet-control-layers-selector { + margin-top: 2px; + position: relative; + top: 1px; +} +.leaflet-control-layers label { + display: block; +} +.leaflet-control-layers-separator { + height: 0; + border-top: 1px solid #ddd; + margin: 5px -10px 5px -6px; +} +.leaflet-container .leaflet-control-attribution { + background: #fff; + background: rgba(255, 255, 255, 0.7); + margin: 0; +} +.leaflet-control-attribution, +.leaflet-control-scale-line { + padding: 0 5px; + color: #333; +} +.leaflet-control-attribution a { + text-decoration: none; +} +.leaflet-control-attribution a:hover { + text-decoration: underline; +} +.leaflet-container .leaflet-control-attribution, +.leaflet-container .leaflet-control-scale { + font-size: 11px; +} +.leaflet-left .leaflet-control-scale { + margin-left: 5px; +} +.leaflet-bottom .leaflet-control-scale { + margin-bottom: 5px; +} +.leaflet-control-scale-line { + border: 2px solid #777; + border-top: none; + line-height: 1.1; + padding: 2px 5px 1px; + font-size: 11px; + white-space: nowrap; + overflow: hidden; + -moz-box-sizing: content-box; + box-sizing: content-box; + background: #fff; + background: rgba(255, 255, 255, 0.5); +} +.leaflet-control-scale-line:not(:first-child) { + border-top: 2px solid #777; + border-bottom: none; + margin-top: -2px; +} +.leaflet-control-scale-line:not(:first-child):not(:last-child) { + border-bottom: 2px solid #777; +} +.leaflet-touch .leaflet-control-attribution, +.leaflet-touch .leaflet-control-layers, +.leaflet-touch .leaflet-bar { + box-shadow: none; +} +.leaflet-touch .leaflet-control-layers, +.leaflet-touch .leaflet-bar { + border: 2px solid rgba(0, 0, 0, 0.2); + background-clip: padding-box; +} +.leaflet-popup { + position: absolute; + text-align: center; +} +.leaflet-popup-content-wrapper { + padding: 1px; + text-align: left; + border-radius: 12px; +} +.leaflet-popup-content { + margin: 13px 19px; + line-height: 1.4; +} +.leaflet-popup-content p { + margin: 18px 0; +} +.leaflet-popup-tip-container { + margin: 0 auto; + width: 40px; + height: 20px; + position: relative; + overflow: hidden; +} +.leaflet-popup-tip { + width: 17px; + height: 17px; + padding: 1px; + margin: -10px auto 0; + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); +} +.leaflet-popup-content-wrapper, +.leaflet-popup-tip { + background: white; + box-shadow: 0 3px 14px rgba(0, 0, 0, 0.4); +} +.leaflet-container a.leaflet-popup-close-button { + position: absolute; + top: 0; + right: 0; + padding: 4px 4px 0 0; + text-align: center; + width: 18px; + height: 14px; + font: 16px / 14px Tahoma, Verdana, sans-serif; + color: #c3c3c3; + text-decoration: none; + font-weight: bold; + background: transparent; +} +.leaflet-container a.leaflet-popup-close-button:hover { + color: #999; +} +.leaflet-popup-scrolled { + overflow: auto; + border-bottom: 1px solid #ddd; + border-top: 1px solid #ddd; +} +.leaflet-oldie .leaflet-popup-content-wrapper { + zoom: 1; +} +.leaflet-oldie .leaflet-popup-tip { + width: 24px; + margin: 0 auto; + -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)"; + filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678); +} +.leaflet-oldie .leaflet-popup-tip-container { + margin-top: -1px; +} +.leaflet-oldie .leaflet-control-zoom, +.leaflet-oldie .leaflet-control-layers, +.leaflet-oldie .leaflet-popup-content-wrapper, +.leaflet-oldie .leaflet-popup-tip { + border: 1px solid #999; +} +.leaflet-div-icon { + background: #fff; + border: 1px solid #666; +} +.leaflet-cluster-anim .leaflet-marker-icon, +.leaflet-cluster-anim .leaflet-marker-shadow { + -webkit-transition: -webkit-transform 0.3s ease-out, opacity 0.3s ease-in; + -moz-transition: -moz-transform 0.3s ease-out, opacity 0.3s ease-in; + -o-transition: -o-transform 0.3s ease-out, opacity 0.3s ease-in; + transition: transform 0.3s ease-out, opacity 0.3s ease-in; +} +.marker-cluster-small { + background-color: rgba(181, 226, 140, 0.6); +} +.marker-cluster-small div { + background-color: rgba(110, 204, 57, 0.6); +} +.marker-cluster-medium { + background-color: rgba(241, 211, 87, 0.6); +} +.marker-cluster-medium div { + background-color: rgba(240, 194, 12, 0.6); +} +.marker-cluster-large { + background-color: rgba(253, 156, 115, 0.6); +} +.marker-cluster-large div { + background-color: rgba(241, 128, 23, 0.6); +} +.leaflet-oldie .marker-cluster-small { + background-color: #b5e28c; +} +.leaflet-oldie .marker-cluster-small div { + background-color: #6ecc39; +} +.leaflet-oldie .marker-cluster-medium { + background-color: #f1d357; +} +.leaflet-oldie .marker-cluster-medium div { + background-color: #f0c20c; +} +.leaflet-oldie .marker-cluster-large { + background-color: #fd9c73; +} +.leaflet-oldie .marker-cluster-large div { + background-color: #f18017; +} +.marker-cluster { + background-clip: padding-box; + border-radius: 20px; +} +.marker-cluster div { + width: 30px; + height: 30px; + margin-left: 5px; + margin-top: 5px; + text-align: center; + border-radius: 15px; + font: 12px "Helvetica Neue", Arial, Helvetica, sans-serif; +} +.marker-cluster span { + line-height: 30px; +} +/* Magnific Popup CSS */ +.mfp-bg { + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 1042; + overflow: hidden; + position: fixed; + background: #0b0b0b; + opacity: 0.8; + filter: alpha(opacity=80); +} +.mfp-wrap { + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 1102; + position: fixed; + outline: none !important; + -webkit-backface-visibility: hidden; +} +.mfp-container { + text-align: center; + position: absolute; + width: 100%; + height: 100%; + left: 0; + top: 0; + padding: 0 8px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.mfp-container:before { + content: ''; + display: inline-block; + height: 100%; + vertical-align: middle; +} +.mfp-align-top .mfp-container:before { + display: none; +} +.mfp-content { + position: relative; + display: inline-block; + vertical-align: middle; + margin: 0 auto; + text-align: left; + z-index: 1045; +} +.mfp-inline-holder .mfp-content, +.mfp-ajax-holder .mfp-content { + width: 100%; + cursor: auto; +} +.mfp-ajax-cur { + cursor: progress; +} +.mfp-zoom-out-cur, +.mfp-zoom-out-cur .mfp-image-holder .mfp-close { + cursor: -moz-zoom-out; + cursor: -webkit-zoom-out; + cursor: zoom-out; +} +.mfp-zoom { + cursor: pointer; + cursor: -webkit-zoom-in; + cursor: -moz-zoom-in; + cursor: zoom-in; +} +.mfp-auto-cursor .mfp-content { + cursor: auto; +} +.mfp-close, +.mfp-arrow, +.mfp-preloader, +.mfp-counter { + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} +.mfp-loading.mfp-figure { + display: none; +} +.mfp-hide { + display: none !important; +} +.mfp-preloader { + color: #cccccc; + position: absolute; + top: 50%; + width: auto; + text-align: center; + margin-top: -0.8em; + left: 8px; + right: 8px; + z-index: 1044; +} +.mfp-preloader a { + color: #cccccc; +} +.mfp-preloader a:hover { + color: white; +} +.mfp-s-ready .mfp-preloader { + display: none; +} +.mfp-s-error .mfp-content { + display: none; +} +button.mfp-close, +button.mfp-arrow { + overflow: visible; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; + display: block; + outline: none; + padding: 0; + z-index: 1046; + -webkit-box-shadow: none; + box-shadow: none; +} +button::-moz-focus-inner { + padding: 0; + border: 0; +} +.mfp-close { + width: 44px; + height: 44px; + line-height: 44px; + position: absolute; + right: 0; + top: 0; + text-decoration: none; + text-align: center; + opacity: 0.65; + filter: alpha(opacity=65); + padding: 0 0 18px 10px; + color: white; + font-style: normal; + font-size: 28px; + font-family: Arial, Baskerville, monospace; +} +.mfp-close:hover, +.mfp-close:focus { + opacity: 1; + filter: alpha(opacity=100); +} +.mfp-close:active { + top: 1px; +} +.mfp-close-btn-in .mfp-close { + color: #333333; +} +.mfp-image-holder .mfp-close, +.mfp-iframe-holder .mfp-close { + color: white; + right: -6px; + text-align: right; + padding-right: 6px; + width: 100%; +} +.mfp-counter { + position: absolute; + top: 0; + right: 0; + color: #cccccc; + font-size: 12px; + line-height: 18px; +} +.mfp-arrow { + position: absolute; + opacity: 0.65; + filter: alpha(opacity=65); + margin: 0; + top: 50%; + margin-top: -55px; + padding: 0; + width: 90px; + height: 110px; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +.mfp-arrow:active { + margin-top: -54px; +} +.mfp-arrow:hover, +.mfp-arrow:focus { + opacity: 1; + filter: alpha(opacity=100); +} +.mfp-arrow:before, +.mfp-arrow:after, +.mfp-arrow .mfp-b, +.mfp-arrow .mfp-a { + content: ''; + display: block; + width: 0; + height: 0; + position: absolute; + left: 0; + top: 0; + margin-top: 35px; + margin-left: 35px; + border: medium inset transparent; +} +.mfp-arrow:after, +.mfp-arrow .mfp-a { + border-top-width: 13px; + border-bottom-width: 13px; + top: 8px; +} +.mfp-arrow:before, +.mfp-arrow .mfp-b { + border-top-width: 21px; + border-bottom-width: 21px; + opacity: 0.7; +} +.mfp-arrow-left { + left: 0; +} +.mfp-arrow-left:after, +.mfp-arrow-left .mfp-a { + border-right: 17px solid white; + margin-left: 31px; +} +.mfp-arrow-left:before, +.mfp-arrow-left .mfp-b { + margin-left: 25px; + border-right: 27px solid #3f3f3f; +} +.mfp-arrow-right { + right: 0; +} +.mfp-arrow-right:after, +.mfp-arrow-right .mfp-a { + border-left: 17px solid white; + margin-left: 39px; +} +.mfp-arrow-right:before, +.mfp-arrow-right .mfp-b { + border-left: 27px solid #3f3f3f; +} +.mfp-iframe-holder { + padding-top: 40px; + padding-bottom: 40px; +} +.mfp-iframe-holder .mfp-content { + line-height: 0; + width: 100%; + max-width: 900px; +} +.mfp-iframe-holder .mfp-close { + top: -40px; +} +.mfp-iframe-scaler { + width: 100%; + height: 0; + overflow: hidden; + padding-top: 56.25%; +} +.mfp-iframe-scaler iframe { + position: absolute; + display: block; + top: 0; + left: 0; + width: 100%; + height: 100%; + box-shadow: 0 0 8px rgba(0, 0, 0, 0.6); + background: black; +} +/* Main image in popup */ +img.mfp-img { + width: auto; + max-width: 100%; + height: auto; + display: block; + line-height: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 40px 0 40px; + margin: 0 auto; +} +/* The shadow behind the image */ +.mfp-figure { + line-height: 0; +} +.mfp-figure:after { + content: ''; + position: absolute; + left: 0; + top: 40px; + bottom: 40px; + display: block; + right: 0; + width: auto; + height: auto; + z-index: -1; + box-shadow: 0 0 8px rgba(0, 0, 0, 0.6); + background: #444444; +} +.mfp-figure small { + color: #bdbdbd; + display: block; + font-size: 12px; + line-height: 14px; +} +.mfp-figure figure { + margin: 0; +} +.mfp-bottom-bar { + margin-top: -36px; + position: absolute; + top: 100%; + left: 0; + width: 100%; + cursor: auto; +} +.mfp-title { + text-align: left; + line-height: 18px; + color: #f3f3f3; + word-wrap: break-word; + padding-right: 36px; +} +.mfp-image-holder .mfp-content { + max-width: 100%; +} +.mfp-gallery .mfp-image-holder .mfp-figure { + cursor: pointer; +} +@media screen and (max-width: 800px) and (orientation: landscape), screen and (max-height: 300px) { + /** + * Remove all paddings around the image on small screen + */ + .mfp-img-mobile .mfp-image-holder { + padding-left: 0; + padding-right: 0; + } + .mfp-img-mobile img.mfp-img { + padding: 0; + } + .mfp-img-mobile .mfp-figure:after { + top: 0; + bottom: 0; + } + .mfp-img-mobile .mfp-figure small { + display: inline; + margin-left: 5px; + } + .mfp-img-mobile .mfp-bottom-bar { + background: rgba(0, 0, 0, 0.6); + bottom: 0; + margin: 0; + top: auto; + padding: 3px 5px; + position: fixed; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + } + .mfp-img-mobile .mfp-bottom-bar:empty { + padding: 0; + } + .mfp-img-mobile .mfp-counter { + right: 5px; + top: 3px; + } + .mfp-img-mobile .mfp-close { + top: 0; + right: 0; + width: 35px; + height: 35px; + line-height: 35px; + background: rgba(0, 0, 0, 0.6); + position: fixed; + text-align: center; + padding: 0; + } +} +@media all and (max-width: 900px) { + .mfp-arrow { + -webkit-transform: scale(0.75); + transform: scale(0.75); + } + .mfp-arrow-left { + -webkit-transform-origin: 0; + transform-origin: 0; + } + .mfp-arrow-right { + -webkit-transform-origin: 100%; + transform-origin: 100%; + } + .mfp-container { + padding-left: 6px; + padding-right: 6px; + } +} +.mfp-ie7 .mfp-img { + padding: 0; +} +.mfp-ie7 .mfp-bottom-bar { + width: 600px; + left: 50%; + margin-left: -300px; + margin-top: 5px; + padding-bottom: 5px; +} +.mfp-ie7 .mfp-container { + padding: 0; +} +.mfp-ie7 .mfp-content { + padding-top: 44px; +} +.mfp-ie7 .mfp-close { + top: 0; + right: 0; + padding-top: 0; +} +/* + +====== Zoom effect ====== + +*/ +.mfp-zoom-in { + /* start state */ + /* animate in */ + /* animate out */ +} +.mfp-zoom-in .mfp-with-anim { + opacity: 0; + filter: alpha(opacity=0); + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; + -webkit-transform: scale(0.1); + -moz-transform: scale(0.1); + -ms-transform: scale(0.1); + -o-transform: scale(0.1); + transform: scale(0.1); +} +.mfp-zoom-in.mfp-bg { + opacity: 0; + filter: alpha(opacity=0); + -webkit-transition: all 0.3s ease-out; + -moz-transition: all 0.3s ease-out; + -o-transition: all 0.3s ease-out; + transition: all 0.3s ease-out; +} +.mfp-zoom-in.mfp-ready .mfp-with-anim { + opacity: 1; + filter: alpha(opacity=100); + -webkit-transform: scale(1); + -moz-transform: scale(1); + -ms-transform: scale(1); + -o-transform: scale(1); + transform: scale(1); +} +.mfp-zoom-in.mfp-ready.mfp-bg { + opacity: 0.8; + filter: alpha(opacity=80); +} +.mfp-zoom-in.mfp-removing .mfp-with-anim { + transform: scale(0.1); + opacity: 0; + filter: alpha(opacity=0); +} +.mfp-zoom-in.mfp-removing.mfp-bg { + opacity: 0; + filter: alpha(opacity=0); +} +.clearfix { + *zoom: 1; +} +.clearfix:before, +.clearfix:after { + display: table; + content: ""; + line-height: 0; +} +.clearfix:after { + clear: both; +} +.sprite-site-icons.none { + background-image: none; +} +.sprite-site-icons.soc-0-percent { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -96px -120px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.soc-0-percent { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.soc-25-percent { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -144px -120px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.soc-25-percent { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.soc-50-percent { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -192px -120px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.soc-50-percent { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.soc-75-percent { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -240px -120px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.soc-75-percent { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.soc-100-percent { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -288px -120px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.soc-100-percent { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.consumption { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -336px -120px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.consumption { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.charging { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -384px -120px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.charging { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.weather-sunny { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -96px -168px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.weather-sunny { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.weather-cloudy { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -144px -168px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.weather-cloudy { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.weather-cloudy-with-rain { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -192px -168px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.weather-cloudy-with-rain { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.weather-partially-cloudy-with-rain { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -240px -168px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.weather-partially-cloudy-with-rain { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.weather-partially-cloudy { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -288px -168px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.weather-partially-cloudy { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.weather-thunderstorm { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -336px -168px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.weather-thunderstorm { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.clock { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -384px -168px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.clock { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.weather-thunderstorm-with-rain { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -96px -216px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.weather-thunderstorm-with-rain { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.weather-clear-night { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -144px -216px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.weather-clear-night { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.weather-partially-cloudy-night { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -192px -216px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.weather-partially-cloudy-night { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.weather-snow { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -240px -216px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.weather-snow { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.weather-snow-and-rain { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -288px -216px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.weather-snow-and-rain { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.weather-fog { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -336px -216px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.weather-fog { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.light-bulb { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -384px -216px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.light-bulb { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.mains-on { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -336px -264px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.mains-on { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.mains-off { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -384px -264px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.mains-off { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.device-solar-charger { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -96px -312px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.device-solar-charger { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.device-battery-monitor { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -144px -312px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.device-battery-monitor { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.device-gateway { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -192px -312px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.device-gateway { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.device-ve-bus { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -240px -312px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.device-ve-bus { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.device-pv-inverter { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -288px -312px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.device-pv-inverter { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.device-io-extender { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -336px -312px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.device-io-extender { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-site-icons.device-fluid-monitor { + display: inline-block; + width: 48px; + height: 48px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -384px -312px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-site-icons.device-fluid-monitor { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons { + /**************************************************************************************************************************************** + 'Deprecated triangles' (start) + + The triangles on lines 11, 12 and 13 should normally not be used. Instead use the triangles from lines 15, 16 and 17 and give the + background a color. That way we can use transitions for these triangles by changing the background color. For an example see the + dropdowns in the styleguide. + ****************************************************************************************************************************************/ + /**************************************************************************************************************************************** + 'Deprecated triangles' (end) + ****************************************************************************************************************************************/ +} +.sprite-icons.pie-chart-light { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px 0px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.pie-chart-light { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.pie-chart-dark { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px 0px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.pie-chart-dark { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.graph-bars-light { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -24px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.graph-bars-light { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.graph-bars-dark { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -24px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.graph-bars-dark { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.lightning-light { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -48px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.lightning-light { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.lightning-dark { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -48px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.lightning-dark { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.sun-light { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -72px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.sun-light { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.sun-dark { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -72px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.sun-dark { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.sun-orange { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -48px -72px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.sun-orange { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.graph-line-light { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -96px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.graph-line-light { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.graph-line-dark { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -96px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.graph-line-dark { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.graph-line-blue { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -48px -96px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.graph-line-blue { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.graph-line-orange { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -72px -96px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.graph-line-orange { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.wrench-light { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -120px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.wrench-light { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.wrench-dark { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -120px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.wrench-dark { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.cross-light { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -144px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.cross-light { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.cross-dark { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -144px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.cross-dark { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.clock-light { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -168px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.clock-light { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.clock-dark { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -168px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.clock-dark { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.clock-red { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -48px -168px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.clock-red { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.clock-white { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -72px -168px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.clock-white { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.alert-light { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -192px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.alert-light { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.alert-dark { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -192px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.alert-dark { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.alert-red { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -48px -192px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.alert-red { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.checkmark-light { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -216px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.checkmark-light { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.checkmark-dark { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -216px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.checkmark-dark { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.triangle-up-light { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -240px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.triangle-up-light { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.triangle-up-dark { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -240px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.triangle-up-dark { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.triangle-up-middle { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -48px -240px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.triangle-up-middle { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.triangle-down-light { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -264px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.triangle-down-light { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.triangle-down-dark { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -264px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.triangle-down-dark { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.triangle-down-middle { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -48px -264px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.triangle-down-middle { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.triangle-right-light { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -288px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.triangle-right-light { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.triangle-right-dark { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -288px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.triangle-right-dark { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.triangle-right-middle { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -48px -288px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.triangle-right-middle { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.triangle-right-white { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -72px -288px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.triangle-right-white { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.vertical-lines-light { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -312px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.vertical-lines-light { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.vertical-lines-dark { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -312px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.vertical-lines-dark { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.triangle-up-transparent-white { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -336px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.triangle-up-transparent-white { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.triangle-down-transparent-white { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -336px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.triangle-down-transparent-white { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.triangle-right-transparent-white { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -48px -336px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.triangle-right-transparent-white { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.triangle-up-transparent-blue { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -360px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.triangle-up-transparent-blue { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.triangle-down-transparent-blue { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -360px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.triangle-down-transparent-blue { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.triangle-right-transparent-blue { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -48px -360px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.triangle-right-transparent-blue { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.triangle-up-transparent-red { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -384px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.triangle-up-transparent-red { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.triangle-down-transparent-red { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -384px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.triangle-down-transparent-red { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.triangle-right-transparent-red { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -48px -384px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.triangle-right-transparent-red { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.magnifier-light { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -408px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.magnifier-light { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.magnifier-dark { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -408px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.magnifier-dark { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.cross-in-circle-light { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -432px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.cross-in-circle-light { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.cross-in-circle-dark { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -432px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.cross-in-circle-dark { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.cross-in-circle-white { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -48px -432px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.cross-in-circle-white { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.download-light { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -456px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.download-light { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.download-dark { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -456px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.download-dark { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.download-middle { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -48px -456px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.download-middle { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.download-white { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -72px -456px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.download-white { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.download-blue { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -72px -480px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.download-blue { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.generator-blue { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -480px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.generator-blue { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.grid-green { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -504px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.grid-green { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.grid-red { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -504px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.grid-red { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.vertical-lines-thick-light { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -528px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.vertical-lines-thick-light { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.vertical-lines-thick-dark { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -528px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.vertical-lines-thick-dark { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.horizontal-lines-thick-light { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -552px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.horizontal-lines-thick-light { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.horizontal-lines-thick-dark { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -552px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.horizontal-lines-thick-dark { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.horizontal-lines-thick-blue { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -48px -552px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.horizontal-lines-thick-blue { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.clock-advanced-white { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -600px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.clock-advanced-white { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.clock-advanced-dark { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -600px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.clock-advanced-dark { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.circle-plus-light { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -624px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.circle-plus-light { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.circle-plus-dark { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -624px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.circle-plus-dark { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.circle-plus-middle { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -48px -624px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.circle-plus-middle { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.circle-minus-light { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -648px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.circle-minus-light { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.circle-minus-dark { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -648px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.circle-minus-dark { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.circle-minus-middle { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -48px -648px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.circle-minus-middle { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.map-marker-blue { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -100px 0px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.map-marker-blue { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.map-marker-red { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -250px 0px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.map-marker-red { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.dotted-arrow-left-blue { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -48px -696px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.dotted-arrow-left-blue { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.dotted-arrow-right-blue { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -48px -720px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.dotted-arrow-right-blue { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.arrow-up-blue { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -48px -744px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.arrow-up-blue { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sprite-icons.arrow-down-blue { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -48px -768px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .sprite-icons.arrow-down-blue { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +/**************************************************************************************************************************************** +Colors (start) +****************************************************************************************************************************************/ +/**************************************************************************************************************************************** +Colors (end) +****************************************************************************************************************************************/ +/**************************************************************************************************************************************** +Fonts and sizes (start) +****************************************************************************************************************************************/ +@font-face { + font-family: 'MuseoSans-300'; + font-style: normal; + font-weight: normal; + src: url('/styling/webfonts/MuseoSans-300.eot'); + src: url('/styling/webfonts/MuseoSans-300.eot?#iefix') format('embedded-opentype'), url('/styling/webfonts/MuseoSans-300.woff') format('woff'), local('MuseoSans-300'), url('/styling/webfonts/MuseoSans-300.otf') format('opentype'), url('/styling/webfonts/MuseoSans-300.ttf') format('truetype'), url('/styling/webfonts/MuseoSans-300.svg#MuseoSans-300') format('svg'); +} +@font-face { + font-family: 'MuseoSans-700'; + font-style: normal; + font-weight: normal; + src: url('/styling/webfonts/MuseoSans-700.eot'); + src: url('/styling/webfonts/MuseoSans-700.eot?#iefix') format('embedded-opentype'), url('/styling/webfonts/MuseoSans-700.woff') format('woff'), local('MuseoSans-700'), url('/styling/webfonts/MuseoSans-700.otf') format('opentype'), url('/styling/webfonts/MuseoSans-700.ttf') format('truetype'), url('/styling/webfonts/MuseoSans-700.svg#MuseoSans-700') format('svg'); +} +@font-face { + font-family: 'screensaver-icons'; + font-style: normal; + font-weight: normal; + src: url('/styling/webfonts/icons/VRM-screensaver-icons.eot'); + src: url('/styling/webfonts/icons/VRM-screensaver-icons.eot?#iefix') format('embedded-opentype'), url('/styling/webfonts/icons/VRM-screensaver-icons.woff') format('woff'), url('/styling/webfonts/icons/VRM-screensaver-icons.otf') format('opentype'), url('/styling/webfonts/icons/VRM-screensaver-icons.ttf') format('truetype'), url('/styling/webfonts/icons/VRM-screensaver-icons.svg#VRM-screensaver-icon') format('svg'); +} +/**************************************************************************************************************************************** +Fonts and sizes (end) +****************************************************************************************************************************************/ +/**************************************************************************************************************************************** +Other defaults (start) +****************************************************************************************************************************************/ +/**************************************************************************************************************************************** +Other defaults (end) +****************************************************************************************************************************************/ +/**************************************************************************************************************************************** +HTML elements (start) +****************************************************************************************************************************************/ +body { + background-color: #e6e5e1; + color: #272622; + font-family: 'MuseoSans-300', sans-serif; + font-size: 15px; + line-height: 21px; + margin: 0; +} +h1 { + font-size: 26px; + font-weight: normal; + line-height: 26px; + margin-bottom: 30px; + margin-top: 75px; +} +h1.large { + font-size: 40px; +} +h2 { + font-size: 21px; + font-weight: normal; + line-height: 21px; + margin-bottom: 20px; + margin-top: 45px; +} +h3 { + font-size: 18px; + font-weight: normal; + line-height: 21px; + margin: 0; +} +h4 { + font-size: 15px; + font-weight: normal; + line-height: 15px; + margin: 0; + color: #387dc5; +} +a { + color: #387dc5; + text-decoration: underline; +} +a:hover { + color: #387dc5; +} +a:focus { + outline-style: none; +} +.legend { + font-family: 'Arial'; + font-size: 11px; + line-height: 21px; +} +ul { + margin: 0; + padding: 0; + list-style-type: none; +} +select { + height: 50px; +} +fieldset { + margin: 0; + border: 0; + padding: 0; +} +/**************************************************************************************************************************************** +HTML elements (end) +****************************************************************************************************************************************/ +/**************************************************************************************************************************************** +Inputs and buttons (start) +****************************************************************************************************************************************/ +.btn, +input, +textarea { + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + display: inline-block; + font-size: 18px; + line-height: 18px; + min-height: 40px; + padding: 10px 10px; + text-decoration: none; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; +} +.btn:hover, +input:hover, +textarea:hover { + text-decoration: none; +} +.btn.blue, +input.blue, +textarea.blue { + background-color: #4790d0; + border: 1px solid #387dc5; + color: #ffffff; +} +.btn.blue:hover, +input.blue:hover, +textarea.blue:hover { + background-color: #387dc5; + border: 1px solid #387dc5; +} +.btn.orange, +input.orange, +textarea.orange { + background-color: #f7ab3e; + border: 1px solid #f0962e; + color: #ffffff; +} +.btn.orange:hover, +input.orange:hover, +textarea.orange:hover { + background-color: #f0962e; + border: 1px solid #f0962e; +} +.btn.green, +input.green, +textarea.green { + background-color: #8bc964; + border: 1px solid #72b84c; + color: #ffffff; +} +.btn.green:hover, +input.green:hover, +textarea.green:hover { + background-color: #72b84c; + border: 1px solid #72b84c; +} +.btn.red, +input.red, +textarea.red { + background-color: #fa716f; + border: 1px solid #f35c58; + color: #ffffff; +} +.btn.red:hover, +input.red:hover, +textarea.red:hover { + background-color: #f35c58; + border: 1px solid #f35c58; +} +.btn.gray, +input.gray, +textarea.gray { + background-color: #e6e5e1; + border: 1px solid #dcdbd7; + color: #63625e; +} +.btn.gray:hover, +input.gray:hover, +textarea.gray:hover { + background-color: #f0efeb; + border: 1px solid #dcdbd7; +} +.btn.light, +input.light, +textarea.light { + background-color: #faf9f5; + border: 1px solid #dcdbd7; + color: #63625e; +} +.btn.light:hover, +input.light:hover, +textarea.light:hover { + background-color: #ffffff; + border: 1px solid #dcdbd7; +} +.btn.disabled, +input.disabled, +textarea.disabled, +.btn:disabled, +input:disabled, +textarea:disabled { + background-color: #e6e5e1; + border: #dcdbd7 1px solid; + border-color: #dcdbd7; + color: #63625e; + cursor: default; +} +.btn.disabled:hover, +input.disabled:hover, +textarea.disabled:hover, +.btn:disabled:hover, +input:disabled:hover, +textarea:disabled:hover { + background-color: #e6e5e1; + border: #dcdbd7 1px solid; +} +input, +button, +textarea { + outline: none; + font-family: 'MuseoSans-300', sans-serif; + padding-left: 18px; +} +input[type="text"], +input[type="email"], +input[type="password"], +input[type="tel"], +input[type="url"], +textarea { + font-size: 15px; + background-color: #f0efeb; + border: 1px solid #dcdbd7; + color: #387dc5; + height: inherit; + line-height: inherit; + padding: 10px 13px 7px; +} +input[type="text"]:hover, +input[type="email"]:hover, +input[type="password"]:hover, +input[type="tel"]:hover, +input[type="url"]:hover, +textarea:hover { + background-color: #e6e5e1; + border: 1px solid #dcdbd7; +} +input[type="text"]:-moz-placeholder, +input[type="email"]:-moz-placeholder, +input[type="password"]:-moz-placeholder, +input[type="tel"]:-moz-placeholder, +input[type="url"]:-moz-placeholder, +textarea:-moz-placeholder { + color: #63625e; + opacity: 1; +} +input[type="text"]::-moz-placeholder, +input[type="email"]::-moz-placeholder, +input[type="password"]::-moz-placeholder, +input[type="tel"]::-moz-placeholder, +input[type="url"]::-moz-placeholder, +textarea::-moz-placeholder { + color: #63625e; + opacity: 1; +} +input[type="text"]:-webkit-input-placeholder, +input[type="email"]:-webkit-input-placeholder, +input[type="password"]:-webkit-input-placeholder, +input[type="tel"]:-webkit-input-placeholder, +input[type="url"]:-webkit-input-placeholder, +textarea:-webkit-input-placeholder { + color: #63625e; + opacity: 1; +} +input[type="text"]::-webkit-input-placeholder, +input[type="email"]::-webkit-input-placeholder, +input[type="password"]::-webkit-input-placeholder, +input[type="tel"]::-webkit-input-placeholder, +input[type="url"]::-webkit-input-placeholder, +textarea::-webkit-input-placeholder { + color: #63625e; + opacity: 1; +} +input[type="text"]:-ms-input-placeholder, +input[type="email"]:-ms-input-placeholder, +input[type="password"]:-ms-input-placeholder, +input[type="tel"]:-ms-input-placeholder, +input[type="url"]:-ms-input-placeholder, +textarea:-ms-input-placeholder { + color: #63625e; + opacity: 1; +} +input[type="text"]::-ms-input-placeholder, +input[type="email"]::-ms-input-placeholder, +input[type="password"]::-ms-input-placeholder, +input[type="tel"]::-ms-input-placeholder, +input[type="url"]::-ms-input-placeholder, +textarea::-ms-input-placeholder { + color: #63625e; + opacity: 1; +} +input[type="text"]:hover, +input[type="email"]:hover, +input[type="password"]:hover, +input[type="tel"]:hover, +input[type="url"]:hover, +textarea:hover { + background-color: #ffffff; +} +input[type="text"]:focus, +input[type="email"]:focus, +input[type="password"]:focus, +input[type="tel"]:focus, +input[type="url"]:focus, +textarea:focus { + background-color: #ffffff; + border-color: #4790d0; +} +input[type="text"].completed, +input[type="email"].completed, +input[type="password"].completed, +input[type="tel"].completed, +input[type="url"].completed, +textarea.completed { + background-color: #ffffff; +} +input[type="text"].completed:hover, +input[type="email"].completed:hover, +input[type="password"].completed:hover, +input[type="tel"].completed:hover, +input[type="url"].completed:hover, +textarea.completed:hover { + border-color: #4790d0; +} +input[type="text"]:invalid, +input[type="email"]:invalid, +input[type="password"]:invalid, +input[type="tel"]:invalid, +input[type="url"]:invalid, +textarea:invalid { + box-shadow: none; +} +input[type="text"].error, +input[type="email"].error, +input[type="password"].error, +input[type="tel"].error, +input[type="url"].error, +textarea.error, +input[type="text"]:not(.needstouch):invalid:not(:focus), +input[type="email"]:not(.needstouch):invalid:not(:focus), +input[type="password"]:not(.needstouch):invalid:not(:focus), +input[type="tel"]:not(.needstouch):invalid:not(:focus), +input[type="url"]:not(.needstouch):invalid:not(:focus), +textarea:not(.needstouch):invalid:not(:focus) { + border-color: #fa716f; + color: #f35c58; +} +input[type="text"].error:hover, +input[type="email"].error:hover, +input[type="password"].error:hover, +input[type="tel"].error:hover, +input[type="url"].error:hover, +textarea.error:hover, +input[type="text"]:not(.needstouch):invalid:not(:focus):hover, +input[type="email"]:not(.needstouch):invalid:not(:focus):hover, +input[type="password"]:not(.needstouch):invalid:not(:focus):hover, +input[type="tel"]:not(.needstouch):invalid:not(:focus):hover, +input[type="url"]:not(.needstouch):invalid:not(:focus):hover, +textarea:not(.needstouch):invalid:not(:focus):hover { + border-color: #fa716f; +} +input[type="text"].disabled, +input[type="email"].disabled, +input[type="password"].disabled, +input[type="tel"].disabled, +input[type="url"].disabled, +textarea.disabled { + background-color: #e6e5e1; + border-color: #dcdbd7; + color: #63625e; +} +input[type="text"].disabled:hover, +input[type="email"].disabled:hover, +input[type="password"].disabled:hover, +input[type="tel"].disabled:hover, +input[type="url"].disabled:hover, +textarea.disabled:hover { + background-color: #f0efeb; + border-color: #dcdbd7; +} +input[type="button"], +input[type="submit"] { + border: none; + /*padding: 0;*/ + vertical-align: baseline; +} +.btn { + text-align: center; +} +/**************************************************************************************************************************************** +Inputs and buttons (end) +****************************************************************************************************************************************/ +/**************************************************************************************************************************************** +Custom select (start) +****************************************************************************************************************************************/ +.chzn-select { + visibility: hidden; +} +.chzn-select.no-search + .chzn-container .chzn-drop .chzn-results { + max-height: 259px; +} +.chzn-select.no-search + .chzn-container .chzn-drop .chzn-results .active-result:first-child { + padding-top: 20px; +} +.chzn-container { + display: block; +} +.chzn-container .chzn-single { + background-color: #ffffff; + border: 1px solid #dcdbd7; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + color: #63625e; + height: 40px; + line-height: 40px; + padding: 0 70px 0 15px; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; + z-index: 1011; +} +.chzn-container .chzn-single:hover { + border-color: #959490; + color: #272622; +} +.chzn-container .chzn-single:hover .handle { + border-left-color: #959490; +} +.chzn-container .chzn-single:hover .handle .sprite-icons { + background-color: #959490; +} +.chzn-container .chzn-single .handle { + border-left: 1px solid #dcdbd7; + height: 18px; + margin-top: 11px; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; + width: 37px; +} +.chzn-container .chzn-single .handle .sprite-icons { + background-color: #dcdbd7; + -webkit-transition-property: background-position; + -webkit-transition-duration: 0s; + -moz-transition-property: background-position; + -moz-transition-duration: 0s; + -o-transition-property: background-position; + -o-transition-duration: 0s; + -ms-transition-property: background-position; + -ms-transition-duration: 0s; + transition-property: background-position; + transition-duration: 0s; + -webkit-transition-property: background-color; + -webkit-transition-duration: 0.2s; + -moz-transition-property: background-color; + -moz-transition-duration: 0.2s; + -o-transition-property: background-color; + -o-transition-duration: 0.2s; + -ms-transition-property: background-color; + -ms-transition-duration: 0.2s; + transition-property: background-color; + transition-duration: 0.2s; + right: 8px; + position: absolute; + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -336px; + top: -2px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .chzn-container .chzn-single .handle .sprite-icons { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.chzn-container .chzn-drop { + background: #ffffff; + border: 1px solid #dcdbd7; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + margin-top: 5px; + z-index: 1012; +} +.chzn-container .chzn-drop .chzn-search { + background-color: #959490; + position: relative; + -webkit-border-top-left-radius: 5px; + -moz-border-radius-topleft: 5px; + border-top-left-radius: 5px; + -webkit-border-top-right-radius: 5px; + -moz-border-radius-topright: 5px; + border-top-right-radius: 5px; +} +.chzn-container .chzn-drop .chzn-search .sprite-icons { + left: 15px; + position: absolute; + top: 8px; +} +.chzn-container .chzn-drop .chzn-search input[type="text"] { + background-color: #959490; + border: none; + color: #ffffff; + padding-left: 55px; + width: 100% !important; +} +.chzn-container .chzn-drop .chzn-search input[type="text"]:-moz-placeholder { + color: #e6e5e1; + opacity: 1; +} +.chzn-container .chzn-drop .chzn-search input[type="text"]::-moz-placeholder { + color: #e6e5e1; + opacity: 1; +} +.chzn-container .chzn-drop .chzn-search input[type="text"]:-webkit-input-placeholder { + color: #e6e5e1; + opacity: 1; +} +.chzn-container .chzn-drop .chzn-search input[type="text"]::-webkit-input-placeholder { + color: #e6e5e1; + opacity: 1; +} +.chzn-container .chzn-drop .chzn-search input[type="text"]:-ms-input-placeholder { + color: #e6e5e1; + opacity: 1; +} +.chzn-container .chzn-drop .chzn-search input[type="text"]::-ms-input-placeholder { + color: #e6e5e1; + opacity: 1; +} +.chzn-container .chzn-drop .chzn-results { + margin: 0px; + max-height: 254px; + padding: 0px; +} +.chzn-container .chzn-drop .chzn-results .active-result { + border-top: 1px solid #dcdbd7; + color: #63625e; + min-height: 20px; + padding: 9px 15px; +} +.chzn-container .chzn-drop .chzn-results .active-result:first-child { + border-top: none; +} +.chzn-container .chzn-drop .chzn-results .active-result.highlighted { + background-color: #e6e5e1; + color: #272622; +} +.chzn-container .chzn-drop .chzn-results .active-result.result-selected { + color: #387dc5; +} +.chzn-container .chzn-drop .chzn-results .no-results { + color: #f35c58; + height: 40px; + line-height: 44px; + padding: 0 20px; +} +.chzn-container.chzn-container-active .chzn-single { + border-color: #959490; + color: #272622; +} +.chzn-container.chzn-container-active .chzn-single .handle { + border-left-color: #959490; +} +.chzn-container.chzn-container-active .chzn-single .handle .sprite-icons { + background-color: #959490; +} +.chzn-container.chzn-container-active .chzn-single.chzn-single-with-drop .handle .sprite-icons { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -336px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .chzn-container.chzn-container-active .chzn-single.chzn-single-with-drop .handle .sprite-icons { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +/**************************************************************************************************************************************** +Custom select (end) +****************************************************************************************************************************************/ +/* The functionality */ +.custom-check-and-radio:not(#OLD-IE), +.custom-toggle:not(#OLD-IE) { + position: relative; +} +.custom-check-and-radio:not(#OLD-IE) input, +.custom-toggle:not(#OLD-IE) input { + cursor: pointer; + float: left; + height: 0px; + min-height: 0px; + opacity: 0; + filter: alpha(opacity=0); + width: 0px; + padding: 0; + position: absolute; + margin: 0; +} +.custom-check-and-radio:not(#OLD-IE) .alternative-display, +.custom-toggle:not(#OLD-IE) .alternative-display { + display: block; + cursor: pointer; + left: 0px; + position: absolute; + top: 0px; +} +.custom-check-and-radio:not(#OLD-IE) input + label, +.custom-toggle:not(#OLD-IE) input + label { + cursor: pointer; + display: block; +} +/* The common styling for checkboxes and radio buttons */ +.custom-check-and-radio:not(#OLD-IE) .alternative-display { + display: block; + background-color: #f0efeb; + border: 1px solid #dcdbd7; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + height: 24px; + min-height: 0; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; + width: 24px; +} +.custom-check-and-radio:not(#OLD-IE) input + label { + /* line-height: 28px;*/ + padding: 4px 0 0 40px; +} +.custom-check-and-radio:not(#OLD-IE) input:checked + label .alternative-display { + background-color: #4790d0; +} +.custom-check-and-radio:not(#OLD-IE) input:disabled + label .alternative-display { + background-color: #959490; +} +.custom-check-and-radio:not(#OLD-IE):hover .alternative-display { + background-color: #e6e5e1; +} +.custom-check-and-radio:not(#OLD-IE):hover input:checked + label .alternative-display { + background-color: #387dc5; +} +/* The specific styling of the checkbox */ +.custom-check:not(#OLD-IE) .alternative-display { + display: block; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.custom-check:not(#OLD-IE) .alternative-display .sprite-icons { + margin-left: -1px; + margin-top: -1px; + opacity: 0; + filter: alpha(opacity=0); + display: inline-block; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -216px; + width: 24px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .custom-check:not(#OLD-IE) .alternative-display .sprite-icons { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.custom-check:not(#OLD-IE) input:checked + label .alternative-display .sprite-icons { + opacity: 1; + filter: alpha(opacity=100); +} +.custom-check:not(#OLD-IE):hover .alternative-display .sprite-icons { + opacity: 1; + filter: alpha(opacity=100); +} +/* The specific styling of the radio button */ +.custom-radio:not(#OLD-IE) .alternative-display { + display: block; + -webkit-border-radius: 12px; + -moz-border-radius: 12px; + border-radius: 12px; +} +.custom-radio:not(#OLD-IE) .alternative-display .dot { + background-color: #f0efeb; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + height: 8px; + left: 7px; + position: absolute; + top: 7px; + width: 8px; +} +.custom-radio:not(#OLD-IE) input:checked + label .alternative-display .dot { + background-color: #ffffff; +} +.custom-radio:not(#OLD-IE):hover input:checked + label .alternative-display .dot { + background-color: #ffffff; +} +/* The specific styling of the toggle */ +.custom-toggle:not(#OLD-IE).slide-over-text .alternative-display { + border: 1px solid #dcdbd7; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; + height: 40px; + width: 120px; + clear: both; +} +.custom-toggle:not(#OLD-IE).slide-over-text .alternative-display .on, +.custom-toggle:not(#OLD-IE).slide-over-text .alternative-display.toggle-blue .on { + background-color: #4790d0; + -webkit-border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; + border-top-left-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + border-bottom-left-radius: 4px; + -webkit-box-shadow: 0px 2px 0px #387dc5 inset; + -moz-box-shadow: 0px 2px 0px #387dc5 inset; + box-shadow: 0px 2px 0px #387dc5 inset; +} +.custom-toggle:not(#OLD-IE).slide-over-text .alternative-display.toggle-green .on { + background-color: #8bc964; + -webkit-box-shadow: 0px 2px 0px #72b84c inset; + -moz-box-shadow: 0px 2px 0px #72b84c inset; + box-shadow: 0px 2px 0px #72b84c inset; +} +.custom-toggle:not(#OLD-IE).slide-over-text .alternative-display.toggle-red .on { + background-color: #fa716f; + -webkit-box-shadow: 0px 2px 0px #f35c58 inset; + -moz-box-shadow: 0px 2px 0px #f35c58 inset; + box-shadow: 0px 2px 0px #f35c58 inset; +} +.custom-toggle:not(#OLD-IE).slide-over-text .alternative-display .off { + background-color: #959490; + -webkit-border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; + border-bottom-right-radius: 4px; + -webkit-box-shadow: 0px 2px 0px #8e8d89 inset; + -moz-box-shadow: 0px 2px 0px #8e8d89 inset; + box-shadow: 0px 2px 0px #8e8d89 inset; +} +.custom-toggle:not(#OLD-IE).slide-over-text .alternative-display .on, +.custom-toggle:not(#OLD-IE).slide-over-text .alternative-display .off { + display: block; + color: #ffffff; + float: left; + height: 100%; + line-height: 41px; + text-align: center; + position: relative; + width: 50%; +} +.custom-toggle:not(#OLD-IE).slide-over-text .alternative-display .knob { + display: block; + background-color: #e6e5e1; + border: 1px solid #dcdbd7; + border-bottom: 0px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + border-top: none; + -webkit-box-shadow: 5px 0px 0px #8e8d89; + -moz-box-shadow: 5px 0px 0px #8e8d89; + box-shadow: 5px 0px 0px #8e8d89; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; + height: 38px; + left: -1px; + position: absolute; + top: 0px; + width: 62px; +} +.custom-toggle:not(#OLD-IE).slide-over-text .alternative-display .knob .sprite-icons { + left: 17px; + position: absolute; + top: 8px; +} +.custom-toggle:not(#OLD-IE).slide-over-text input + label { + line-height: 44px; + padding: 0 0 0 140px; +} +.custom-toggle:not(#OLD-IE).slide-over-text.under-label label { + padding: 0px; +} +.custom-toggle:not(#OLD-IE).slide-over-text.under-label label .alternative-display { + position: relative; +} +.custom-toggle:not(#OLD-IE).slide-over-text.right-aligned input + label { + padding: 0; +} +.custom-toggle:not(#OLD-IE).slide-over-text.right-aligned .alternative-display { + left: auto; + right: 0px; +} +.custom-toggle:not(#OLD-IE).slide-over-text input:checked + label .alternative-display .knob, +.custom-toggle:not(#OLD-IE).slide-over-text input:checked + label .alternative-display.toggle-blue .knob { + -webkit-box-shadow: -5px 0px 0px #5b9bcd; + -moz-box-shadow: -5px 0px 0px #5b9bcd; + box-shadow: -5px 0px 0px #5b9bcd; + left: 57px; +} +.custom-toggle:not(#OLD-IE).slide-over-text input:checked + label .alternative-display.toggle-green .knob { + -webkit-box-shadow: -5px 0px 0px #98c478; + -moz-box-shadow: -5px 0px 0px #98c478; + box-shadow: -5px 0px 0px #98c478; +} +.custom-toggle:not(#OLD-IE).slide-over-text input:checked + label .alternative-display.toggle-red .knob { + -webkit-box-shadow: -5px 0px 0px #e66e6e; + -moz-box-shadow: -5px 0px 0px #e66e6e; + box-shadow: -5px 0px 0px #e66e6e; +} +.custom-toggle:not(#OLD-IE).slide-over-text:hover .alternative-display .knob { + background-color: #ffffff; +} +.custom-toggle:not(#OLD-IE).slide-over-text.button-variant .alternative-display { + display: block; + width: 140px; +} +.custom-toggle:not(#OLD-IE).slide-over-text.button-variant .toggle-caption { + display: block; + font-size: 15px; + margin-top: 11px; + text-align: center; +} +.custom-toggle:not(#OLD-IE).slide-over-text.button-variant .caption-on { + color: #8bc964; + display: none; +} +.custom-toggle:not(#OLD-IE).slide-over-text.button-variant .caption-off { + color: #959490; +} +.custom-toggle:not(#OLD-IE).slide-over-text.button-variant input:checked + label .alternative-display { + border-color: #8bc964; +} +.custom-toggle:not(#OLD-IE).slide-over-text.button-variant input:checked + label .caption-on { + display: block; +} +.custom-toggle:not(#OLD-IE).slide-over-text.button-variant input:checked + label .caption-off { + display: none; +} +.custom-toggle:not(#OLD-IE).slide-colors .alternative-display { + display: block; + background-color: #e6e5e1; + border: 1px solid #dcdbd7; + display: inline-block; + /*font-size: @sgFontSizeText * 10px;*/ + height: 30px; + position: relative; + width: 80px; + -webkit-border-radius: 100px; + -moz-border-radius: 100px; + border-radius: 100px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; +} +.custom-toggle:not(#OLD-IE).slide-colors .alternative-display .on { + background-color: #8bc964; + left: 10px; + width: 0; +} +.custom-toggle:not(#OLD-IE).slide-colors .alternative-display .off { + background-color: #fa716f; + right: 10px; + width: 58px; +} +.custom-toggle:not(#OLD-IE).slide-colors .alternative-display .on, +.custom-toggle:not(#OLD-IE).slide-colors .alternative-display .off { + display: block; + height: 4px; + position: absolute; + top: 12px; + -webkit-border-radius: 100px; + -moz-border-radius: 100px; + border-radius: 100px; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; +} +.custom-toggle:not(#OLD-IE).slide-colors .alternative-display .knob { + display: block; + background-color: #ffffff; + height: 24px; + left: 2px; + position: absolute; + top: 2px; + width: 24px; + -webkit-border-radius: 100px; + -moz-border-radius: 100px; + border-radius: 100px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-box-shadow: 0 2px 6px rgba(150, 149, 145, 0.5); + -moz-box-shadow: 0 2px 6px rgba(150, 149, 145, 0.5); + box-shadow: 0 2px 6px rgba(150, 149, 145, 0.5); + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; +} +.custom-toggle:not(#OLD-IE).slide-colors .alternative-display .knob .dot { + background-color: #fa716f; + height: 8px; + left: 8px; + position: absolute; + top: 8px; + width: 8px; + -webkit-border-radius: 100px; + -moz-border-radius: 100px; + border-radius: 100px; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; +} +.custom-toggle:not(#OLD-IE).slide-colors .caption-container { + display: inline-block; + vertical-align: top; +} +.custom-toggle:not(#OLD-IE).slide-colors .caption { + color: #fa716f; + line-height: 30px; + padding-left: 17px; + text-transform: uppercase; +} +.custom-toggle:not(#OLD-IE).slide-colors .caption:after { + content: "Off"; +} +.custom-toggle:not(#OLD-IE).slide-colors input + label { + line-height: 34px; +} +.custom-toggle:not(#OLD-IE).slide-colors input:checked + label .alternative-display .on { + width: 58px; +} +.custom-toggle:not(#OLD-IE).slide-colors input:checked + label .alternative-display .off { + width: 0; +} +.custom-toggle:not(#OLD-IE).slide-colors input:checked + label .alternative-display .knob { + left: 52px; +} +.custom-toggle:not(#OLD-IE).slide-colors input:checked + label .alternative-display .knob .dot { + background-color: #8bc964; +} +.custom-toggle:not(#OLD-IE).slide-colors input:checked + label .caption { + color: #8bc964; +} +.custom-toggle:not(#OLD-IE).slide-colors input:checked + label .caption:after { + content: "On"; +} +.custom-toggle:not(#OLD-IE).slide-colors:hover .alternative-display .knob { + background-color: #ffffff; +} +/**************************************************************************************************************************************** +Tabs (start) +****************************************************************************************************************************************/ +#vrm-tabs { + height: 65px; + margin: 0px; + padding: 0px; +} +#vrm-tabs li { + background-color: #63625e; + border-bottom: 4px solid #595854; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; + float: left; + height: 60px; + list-style-position: inside; + list-style-type: none; + margin-top: 5px; + width: 100px; +} +#vrm-tabs li a { + display: inline-block; + float: left; + height: 100%; + position: relative; + text-decoration: none; + width: 99px; +} +#vrm-tabs li a .sprite-icons { + left: 38px; + position: absolute; + top: 12px; +} +#vrm-tabs li a .sprite-icons.default { + z-index: 1; +} +#vrm-tabs li a .text { + color: #e6e5e1; + font-size: 11px; + margin-top: 36px; + text-align: center; +} +#vrm-tabs li.darker { + background-color: #4f4e4a; +} +#vrm-tabs li.active { + background-color: #faf9f5; + border: none; + border-color: #ffffff; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 65px; + margin-top: 0px; +} +#vrm-tabs li.active#tab-live-feed, +#vrm-tabs li.active#tab-settings { + background-color: #f0efeb; +} +#vrm-tabs li.active a .sprite-icons.default { + display: none; +} +#vrm-tabs li.active a .text { + color: #63625e; +} +#vrm-tabs li.active .divider .border { + -webkit-transition: 0s; + -moz-transition: 0s; + -o-transition: 0s; + transition: 0s; + background-color: transparent; +} +#vrm-tabs li.active + li .divider .border { + background-color: transparent; +} +#vrm-tabs li:hover { + border-color: #959490; +} +#vrm-tabs li:hover:not(.active) { + background-color: #959490; +} +#vrm-tabs li:hover:not(.active) .divider .border { + background-color: #959490; +} +#vrm-tabs li:hover.active { + border-color: #ffffff; +} +#vrm-tabs li:hover + li .divider .border { + background-color: transparent; +} +#vrm-tabs li .divider { + display: inline-block; + float: left; + width: 0.5px; +} +#vrm-tabs li .divider .border { + background-color: #4f4e4a; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; + height: 40px; + margin-top: 10px; +} +#vrm-tabs-content { + background-color: #f0efeb; +} +#vrm-tabs-content .tab-pane { + display: none; +} +#vrm-tabs-content .tab-pane .content { + padding: 10px 20px; +} +#vrm-tabs-content .active { + display: block; +} +/**************************************************************************************************************************************** +Tabs (end) +****************************************************************************************************************************************/ +/**************************************************************************************************************************************** +Form Tabs (start) +****************************************************************************************************************************************/ +.form-tabs { + list-style: none; + margin: 0; + padding: 0; +} +.form-tabs li { + border-left: 1px solid #dcdbd7; + border-bottom: 1px solid #dcdbd7; + border-right: 1px solid #dcdbd7; + background-color: #e6e5e1; +} +.form-tabs li:first-child { + border-top: 1px solid #dcdbd7; +} +.form-tabs li a { + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; + display: block; + height: 50px; + line-height: 50px; + color: #63625e; + text-decoration: none; + text-align: right; + padding-right: 25px; + position: relative; + cursor: pointer; +} +.form-tabs li a.active, +.form-tabs li a:hover { + background: white; + color: #387dc5; +} +.form-tabs li a .required { + color: #4790d0; + position: absolute; + right: 20px; +} +/**************************************************************************************************************************************** +Form Tabs (end) +****************************************************************************************************************************************/ +/**************************************************************************************************************************************** +12-column grid (start) +****************************************************************************************************************************************/ +/* This mixin sets the width of an element based on the number of columns. */ +/* This mixin sets the width of a grid item based on the number of columns. */ +.container .container-inner { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + *zoom: 1; + margin: 0 auto; + width: 960px; +} +.container .container-inner:before, +.container .container-inner:after { + display: table; + content: ""; + line-height: 0; +} +.container .container-inner:after { + clear: both; +} +.container .container-inner .grid-item { + float: left; + /* Classes for setting the width of a grid item based on the number of columns it is wide. */ +} +.container .container-inner .grid-item.one-columns-width { + margin-left: 10px; + margin-right: 10px; + width: 60px; +} +.container .container-inner .grid-item.two-columns-width { + margin-left: 10px; + margin-right: 10px; + width: 140px; +} +.container .container-inner .grid-item.three-columns-width { + margin-left: 10px; + margin-right: 10px; + width: 220px; +} +.container .container-inner .grid-item.four-columns-width { + margin-left: 10px; + margin-right: 10px; + width: 300px; +} +.container .container-inner .grid-item.five-columns-width { + margin-left: 10px; + margin-right: 10px; + width: 380px; +} +.container .container-inner .grid-item.six-columns-width { + margin-left: 10px; + margin-right: 10px; + width: 460px; +} +.container .container-inner .grid-item.seven-columns-width { + margin-left: 10px; + margin-right: 10px; + width: 540px; +} +.container .container-inner .grid-item.eight-columns-width { + margin-left: 10px; + margin-right: 10px; + width: 620px; +} +.container .container-inner .grid-item.nine-columns-width { + margin-left: 10px; + margin-right: 10px; + width: 700px; +} +.container .container-inner .grid-item.ten-columns-width { + margin-left: 10px; + margin-right: 10px; + width: 780px; +} +.container .container-inner .grid-item.eleven-columns-width { + margin-left: 10px; + margin-right: 10px; + width: 860px; +} +.container .container-inner .grid-item.twelve-columns-width { + margin-left: 10px; + margin-right: 10px; + width: 940px; +} +.container .container-inner .grid-item.offset-one { + margin-left: 90px; +} +.container .container-inner .grid-item.offset-two { + margin-left: 170px; +} +.container .container-inner .grid-item.offset-three { + margin-left: 250px; +} +.container .container-inner .grid-item.offset-four { + margin-left: 330px; +} +.container .container-inner .grid-item.offset-five { + margin-left: 410px; +} +.container .container-inner .grid-item.offset-six { + margin-left: 490px; +} +.offset-gutter { + margin-left: 20px; +} +/* Classes for setting the width of an element based on the number of columns it is wide. */ +.two-columns-width { + width: 140px; +} +.two-columns-width.force-width { + width: 140px !important; +} +.three-columns-width { + width: 220px; +} +.three-columns-width.force-width { + width: 220px !important; +} +.four-columns-width { + width: 300px; +} +.four-columns-width.force-width { + width: 300px !important; +} +/**************************************************************************************************************************************** +12-column grid (end) +****************************************************************************************************************************************/ +/* -----------[Global styling]--------------*/ +.no-display { + display: none; +} +/* -----------[Homepage]--------------*/ +.vrm.index.index .container-inner .main-image-container { + background: url(/img/homepage/main-image.png) no-repeat transparent center; + height: 539px; + left: 0px; + position: absolute; + width: 100%; + min-width: 960px; + z-index: 1; +} +.vrm.index.index .container-inner .main-image-container.christmas { + background-color: #272622; + background-image: url(/img/homepage/main-image-christmas.jpg); + height: 528px; +} +.vrm.index.index .container-inner .main-image-laptop-slideshow-container { + position: relative; +} +.vrm.index.index .container-inner .main-image-laptop-slideshow-container { + position: relative; +} +.vrm.index.index .container-inner .main-image-laptop-slideshow { + height: 303px; + overflow: hidden; + position: absolute; + right: 0; + top: 154px; + width: 443px; + z-index: 1; + -webkit-transform: matrix3d(0.75766177, -0.11351643, 0, -0.00032209, -0.19498093, 0.94274818, 0, -0.00009209, 0, 0, 1, 0, 27, 40, 0, 1); + -moz-transform: matrix3d(0.75766177, -0.11351643, 0, -0.00032209, -0.19498093, 0.94274818, 0, -0.00009209, 0, 0, 1, 0, 27, 40, 0, 1); + -ms-transform: matrix3d(0.75766177, -0.11351643, 0, -0.00032209, -0.19498093, 0.94274818, 0, -0.00009209, 0, 0, 1, 0, 27, 40, 0, 1); + -o-transform: matrix3d(0.75766177, -0.11351643, 0, -0.00032209, -0.19498093, 0.94274818, 0, -0.00009209, 0, 0, 1, 0, 27, 40, 0, 1); + transform: matrix3d(0.75766177, -0.11351643, 0, -0.00032209, -0.19498093, 0.94274818, 0, -0.00009209, 0, 0, 1, 0, 27, 40, 0, 1); + outline: 1px solid transparent; + -webkit-transform-origin: 0px 0px 0px; + transform-origin: 0px 0px 0px; +} +.vrm.index.index .container-inner .main-image-laptop-slideshow-slide-list { + height: 100%; + list-style-type: none; + margin: 0; + padding: 0; + width: 100%; +} +.vrm.index.index .container-inner .main-image-laptop-slideshow-slide { + background-color: transparent; + background-size: cover; + height: 100%; + overflow: hidden; + pointer-events: none; + position: absolute; + width: 100%; + z-index: 1; +} +.vrm.index.index .container-inner .main-image-laptop-slideshow-slide.slide-1 { + background-image: url('/img/homepage/slideshow/slide-1.jpg'); +} +.vrm.index.index .container-inner .main-image-laptop-slideshow-slide.slide-2 { + background-image: url('/img/homepage/slideshow/slide-2.jpg'); +} +.vrm.index.index .container-inner .main-image-laptop-slideshow-slide.slide-3 { + background-image: url('/img/homepage/slideshow/slide-3.jpg'); +} +.vrm.index.index .container-inner .main-image-laptop-slideshow-slide.current { + pointer-events: auto; + z-index: 100; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +.vrm.index.index .container-inner .main-image-laptop-slideshow-slide.in--next { + z-index: 50; + -webkit-animation: inNext 0.5s forwards ease-in-out; + animation: inNext 0.5s forwards ease-in-out; +} +.vrm.index.index .container-inner .main-image-laptop-slideshow-slide.out--next { + -webkit-animation: outNext 0.5s forwards ease-in-out; + animation: outNext 0.5s forwards ease-in-out; +} +@-webkit-keyframes inNext { + 0% { + -webkit-transform: translate3d(30%, 0, 0); + transform: translate3d(30%, 0, 0); + } + 100% { + -webkit-transform: none; + transform: none; + } +} +@keyframes inNext { + 0% { + -webkit-transform: translate3d(30%, 0, 0); + transform: translate3d(30%, 0, 0); + } + 100% { + -webkit-transform: none; + transform: none; + } +} +@-webkit-keyframes outNext { + 100% { + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } +} +@keyframes outNext { + 100% { + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } +} +.vrm.index.index .container-inner .main-image-overlay { + color: #f0efeb; + height: 494px; + padding-left: 7px; + padding-top: 45px; + position: relative; + min-width: 960px; + z-index: 2; +} +.vrm.index.index .container-inner .main-image-overlay .title { + font-size: 40px; + line-height: 40px; + width: 550px; +} +.vrm.index.index .container-inner .main-image-overlay .subtitle { + padding-top: 21px; + width: 325px; +} +.vrm.index.index .container-inner .main-image-overlay .sign-up { + background-color: rgba(0, 0, 0, 0.2); + -webkit-border-radius: 7px; + -moz-border-radius: 7px; + border-radius: 7px; + margin-top: 45px; + padding: 5px; + text-transform: uppercase; + width: 220px; +} +.vrm.index.index .container-inner .main-image-overlay.christmas .title, +.vrm.index.index .container-inner .main-image-overlay.christmas .subtitle { + visibility: hidden; +} +.vrm.index.index .container-inner .main-image-overlay.christmas .sign-up { + margin-top: 18px; +} +.vrm.index.index .container-inner .middle-section-container { + background-color: #ffffff; + border-bottom: 1px solid #dcdbd7; + left: 0px; + height: 759px; + margin-top: -11px; + padding-top: 13px; + position: absolute; + width: 100%; + min-width: 960px; +} +.vrm.index.index .container-inner .middle-section-container .middle-section-inner { + margin: 0 auto; + width: 960px; +} +.vrm.index.index .container-inner .middle-section-container .middle-section-inner .story-container { + margin-top: 17px; +} +.vrm.index.index .container-inner .middle-section-container .middle-section-inner .video-container { + margin-top: 42px; +} +.vrm.index.index .container-inner .middle-section-container .middle-section-inner .video-player { + width: 640px; + margin: 0 auto; +} +.vrm.index.index .container-inner .middle-section-container .middle-section-inner .main-image { + margin-top: 75px; + text-align: center; +} +.vrm.index.index .container-inner .middle-bottom-section-container { + background-color: #faf9f5; + border-bottom: 1px solid #dcdbd7; + left: 0px; + top: 1393px; + margin-top: -11px; + padding-top: 50px; + position: absolute; + width: 100%; + min-width: 960px; +} +.vrm.index.index .container-inner .middle-bottom-section-container .middle-section-inner { + margin: 0 auto; + width: 960px; +} +.vrm.index.index .container-inner .middle-bottom-section-container .middle-section-inner .main-image img { + float: right; + margin-right: -55px; +} +.vrm.index.index .container-inner .middle-bottom-section-container .middle-section-inner .app-icon { + padding-top: 108px; +} +.vrm.index.index .container-inner .middle-bottom-section-container .middle-section-inner .app-icon img { + float: right; +} +.vrm.index.index .container-inner .middle-bottom-section-container .middle-section-inner .text { + padding-top: 49px; +} +.vrm.index.index .container-inner .middle-bottom-section-container .middle-section-inner .text .btn { + margin-top: 35px; + padding: 8px 10px; +} +.vrm.index.index .container-inner .middle-bottom-section-container .middle-section-inner .text .btn.google-play { + margin-left: 15px; +} +.vrm.index.index .container-inner .middle-bottom-section-container .middle-section-inner .text .btn.google-play img { + padding-top: 4px; +} +.vrm.index.index .container-inner .bottom-section-container { + margin-top: 1228px; +} +.vrm.index.index .container-inner .bottom-section-container .bottom-section-inner .text h1 { + margin-top: 61px; +} +.vrm.index.index .container-inner .bottom-section-container .bottom-section-inner .text h3 { + color: #4790d0; + margin-top: 20px; +} +.vrm.index.index .container-inner .bottom-section-container .bottom-section-inner .text .btn { + margin-top: 55px; + padding: 16px 10px; +} +.vrm.index.index .container-inner .bottom-section-container .bottom-section-inner .main-image { + padding-top: 43px; + text-align: center; +} +.vrm.index.index .container-inner .bottom-section-container .bottom-section-inner .subscribe-to-newsletter { + background-color: #4790d0; + border: #dcdbd7 1px solid; + -webkit-border-radius: 7px; + -moz-border-radius: 7px; + border-radius: 7px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + color: #f0efeb; + font-size: 26px; + max-height: 80px; + margin-top: 50px; + padding: 16px 19px 14px 30px; + position: relative; +} +.vrm.index.index .container-inner .bottom-section-container .bottom-section-inner .subscribe-to-newsletter .caption { + display: inline-block; + margin-top: 16px; +} +.vrm.index.index .container-inner .bottom-section-container .bottom-section-inner .subscribe-to-newsletter input[type="text"], +.vrm.index.index .container-inner .bottom-section-container .bottom-section-inner .subscribe-to-newsletter input[type="email"] { + border: #8cc3f0 1px solid; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + height: 50px; + padding-right: 62px; + width: 440px; +} +.vrm.index.index .container-inner .bottom-section-container .bottom-section-inner .subscribe-to-newsletter input[type="submit"] { + /* no retina needed, homepage not visible on mobile */ + background-image: url("/img/VRM-sprite.png"); + background-position: -64px -281px; + height: 40px; + min-height: 40px; + position: absolute; + right: 24px; + top: 21px; + width: 40px; +} +#loginForm { + display: none; +} +.msie9 .main-image-laptop-slideshow-container { + display: none !important; +} +/* -----------[ Rejected browser ]--------------*/ +.browserReject .browsers { + margin-top: 15px; +} +.browserReject .browsers a { + display: inline-block; + vertical-align: top; + width: 100px; + overflow: hidden; + margin: 0 30px; + padding-top: 110px; + /* no retina needed, homepage not visible on mobile */ + background-image: url('/img/browserSprite100.png'); + background-repeat: no-repeat; + border: none; + text-decoration: none; + cursor: pointer; + color: black; +} +.browserReject .browsers a.ie { + background-position: 0px 0px; +} +.browserReject .browsers a.firefox { + background-position: -100px 0px; +} +.browserReject .browsers a.chrome { + background-position: -200px 0px; +} +.browserReject .browsers a.opera { + background-position: -300px 0px; +} +.browserReject .browsers a.safari { + background-position: -400px 0px; +} +/* -----------[Messages, could go to styleguide]--------------*/ +.global-message, +.flash-message, +.form-message { + min-height: 40px; + color: #ffffff; +} +.global-message.error, +.flash-message.error, +.form-message.error { + background-color: #fa716f; + color: #ffffff; +} +.global-message.error ul li, +.flash-message.error ul li, +.form-message.error ul li { + padding-left: 45px; +} +.global-message.error ul li .sprite-icons, +.flash-message.error ul li .sprite-icons, +.form-message.error ul li .sprite-icons { + display: inline-block; + margin-right: 20px; +} +.global-message.success, +.flash-message.success, +.form-message.success { + background-color: #8bc964; +} +.global-message.notice, +.flash-message.notice, +.form-message.notice { + background-color: #4790d0; +} +.global-message.client-side, +.flash-message.client-side, +.form-message.client-side { + display: none; +} +.global-message ul, +.flash-message ul, +.form-message ul { + padding: 15px 0; + margin: 0; + list-style-type: none; +} +.global-message ul li, +.flash-message ul li, +.form-message ul li { + position: relative; +} +.global-message ul li .sprite-icons, +.flash-message ul li .sprite-icons, +.form-message ul li .sprite-icons { + display: none; + left: 0px; + position: absolute; + top: -3px; + top: calc(50% - 12px); +} +.global-message ul li a, +.flash-message ul li a, +.form-message ul li a { + color: #ffffff; +} +.global-message .message-text, +.flash-message .message-text, +.form-message .message-text { + display: inline-block; + padding: 15px 0; +} +.global-message .message-text a, +.flash-message .message-text a, +.form-message .message-text a { + color: #ffffff; +} +.global-message .container-inner, +.flash-message .container-inner, +.form-message .container-inner { + padding-bottom: 0; +} +.flash-message ul li { + margin-top: 10px; +} +.flash-message ul li:first-child { + margin-top: 0px; +} +/* -----------[Form related styling, could go to styleguide]--------------*/ +.form-container h3 { + padding: 18px 18px 0 18px; +} +.form-container h4 { + padding: 6px 18px 6px 18px; +} +.form-container select { + width: 260px; +} +form fieldset { + border: 1px solid #dcdbd7; + background-color: #ffffff; + padding: 19px; + min-width: inherit; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +form input[type="text"], +form input[type="email"], +form input[type="password"], +form input[type="tel"], +form input[type="url"], +form input[type="submit"], +form select { + width: 100%; +} +#sitesettings > fieldset { + width: 300px; +} +#sitesettings > fieldset#fieldset-tags { + width: 100%; +} +#fieldset-summarywidget { + width: 300px; + border: 0; + background-color: transparent; + padding: 0; +} +#fieldset-summarywidget.desktop { + width: 100%; +} +#fieldset-summarywidget.desktop .sortable-summary-widgets { + width: 300px; +} +#fieldset-summarywidget.desktop .sortable-summary-widgets .placeholder { + background-color: #dcdbd7; +} +#fieldset-summarywidget.desktop .sortable-summary-widgets .site-info { + cursor: move; +} +#fieldset-summarywidget.desktop .sortable-summary-widgets .site-info label { + cursor: move; +} +#fieldset-summarywidget.desktop .summary-widget-list-disabled-container { + float: right; + position: relative; +} +#fieldset-summarywidget.desktop .summary-widget-list-disabled .placeholder { + background-color: #f0efeb; + height: 92px; + margin-bottom: 20px; +} +#fieldset-summarywidget.desktop .summary-widget-list-disabled .site-info .custom-data-toggle { + background-color: #f0efeb; +} +#fieldset-summarywidget.desktop .summary-widget-list-disabled .site-info .custom-data-toggle label { + padding: 23px 10px 24px; +} +#fieldset-summarywidget.desktop .summary-widget-list-disabled .form-element { + margin-bottom: 10px; +} +#fieldset-summarywidget.desktop .summary-widget-list-enabled-container { + float: left; + position: relative; +} +#fieldset-summarywidget.desktop .summary-widget-list-enabled-container .horizontal-line { + background-color: #dcdbd7; + height: 1px; +} +#fieldset-summarywidget.desktop .summary-widget-list-enabled-container.full .placeholder-list-item { + display: none !important; +} +#fieldset-summarywidget.desktop .summary-widget-list-header .sub-title { + color: #4790d0; +} +#fieldset-summarywidget.desktop .summary-widget-list-enabled { + -webkit-box-shadow: 0 0 10px #dcdbd7; + -moz-box-shadow: 0 0 10px #dcdbd7; + box-shadow: 0 0 10px #dcdbd7; + /* This dummy is to be able to put styling on only the list items that are actually selected items, so without the header */ +} +#fieldset-summarywidget.desktop .summary-widget-list-enabled .invisible-dummy { + display: none; +} +#fieldset-summarywidget.desktop .summary-widget-list-enabled .form-element { + margin: 0; +} +#fieldset-summarywidget.desktop .summary-widget-list-enabled .custom-data-toggle { + border: none; + padding: 0; +} +#fieldset-summarywidget.desktop .summary-widget-list-enabled .custom-data-toggle label { + padding: 0; +} +#fieldset-summarywidget.desktop .summary-widget-list-enabled .placeholder { + background: url('/img/drag-drop-placeholder-pattern.png') repeat; + background-color: #f0efeb !important; + height: 99px; + position: relative; +} +#fieldset-summarywidget.desktop .summary-widget-list-enabled .placeholder:before { + background-color: #f0efeb; + content: ' '; + left: 50%; + margin-left: -12px; + margin-top: -12px; + position: absolute; + top: 50%; + -webkit-border-radius: 100px; + -moz-border-radius: 100px; + border-radius: 100px; + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -48px -672px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + #fieldset-summarywidget.desktop .summary-widget-list-enabled .placeholder:before { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +#fieldset-summarywidget.desktop .summary-widget-list-enabled .placeholder-list-item { + background: url('/img/drag-drop-placeholder-pattern.png') repeat; + background-color: #f0efeb !important; + height: 99px; + position: relative; +} +#fieldset-summarywidget.desktop .summary-widget-list-enabled .placeholder-list-item:before { + background-color: #f0efeb; + content: ' '; + left: 50%; + margin-left: -12px; + margin-top: -12px; + position: absolute; + top: 50%; + -webkit-border-radius: 100px; + -moz-border-radius: 100px; + border-radius: 100px; + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -48px -672px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + #fieldset-summarywidget.desktop .summary-widget-list-enabled .placeholder-list-item:before { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +#fieldset-summarywidget.desktop .summary-widget-list-enabled.no-placeholder .placeholder { + display: none; +} +#fieldset-summarywidget.desktop .summary-widget-list-enabled-placeholder .invisible-dummy { + display: none; +} +.sortable-widget-list-enabled-caption { + color: #4790d0; + margin-top: 15px; + padding-right: 30px; + position: relative; + text-align: right; +} +.sortable-widget-list-enabled-caption .sprite-icons { + bottom: -1px; + right: 0; + position: absolute; +} +.sortable-widget-list-disabled-caption { + color: #4790d0; + margin-bottom: 12px; + margin-top: 46px; + padding-left: 33px; + position: relative; +} +.sortable-widget-list-disabled-caption .sprite-icons { + bottom: -1px; + left: 0; + position: absolute; +} +.ui-sortable-helper { + background-color: #ffffff !important; + border: 1px solid #dcdbd7; + -webkit-box-shadow: 0 0 10px #dcdbd7; + -moz-box-shadow: 0 0 10px #dcdbd7; + box-shadow: 0 0 10px #dcdbd7; +} +.ui-sortable-helper label { + color: #4790d0 !important; +} +.ui-sortable-helper .custom-data-toggle { + background-color: #ffffff !important; +} +.form-box input[type=file] { + font-size: 100%; +} +.form-element, +.below-fieldset-element { + margin-top: 15px; +} +.form-element:first-child, +.below-fieldset-element:first-child { + margin-top: 0px; +} +.form-element:last-child, +.below-fieldset-element:last-child { + margin-bottom: 20px; +} +.form-element ul, +.below-fieldset-element ul { + padding: 5px 0; + margin: 0; + list-style-type: none; +} +.form-element ul li, +.below-fieldset-element ul li { + color: #fa716f; +} +.form-element > label, +.below-fieldset-element > label { + display: inline-block; + margin-bottom: 5px; +} +.below-fieldset-element { + padding: 20px; + width: 260px; +} +.below-fieldset-element #submit { + width: 100%; +} +.forgot-password-link { + padding: 14px 0; + display: block; + text-align: center; +} +/* -----------[Specific form stlying for a particular parent class]--------------*/ +.button-list { + margin-top: 20px; +} +.button-list li { + padding: 0 20px; + min-height: 50px; + vertical-align: middle; +} +.button-list li .btn { + width: 100%; +} +.add-site-description, +.add-alarm-description { + color: #4790d0; + margin: 80px 0 0 0; +} +.error { + color: #fa716f; +} +.form-tabs { + margin-top: 97px; +} +.mandatory-settings { + display: inline-block; + color: #4790d0; +} +.location-help, +.summary-help { + position: absolute; + display: none; +} +body.vrm.site { + background-color: #f0efeb; +} +body.vrm.site.add .container .container-inner, +body.vrm.site.update .container .container-inner, +#form-container-sitesettings .container .container-inner { + width: 982px; +} +body.vrm.site.add .form-container, +body.vrm.site.update .form-container, +#form-container-sitesettings .form-container { + padding-bottom: 60px; +} +body.vrm.site.add #location_timezone, +body.vrm.site.update #location_timezone, +#form-container-sitesettings #location_timezone { + width: 262px; +} +body.vrm.site.add #fieldset-location.fieldset-location-map, +body.vrm.site.update #fieldset-location.fieldset-location-map, +#form-container-sitesettings #fieldset-location.fieldset-location-map { + border: none; + position: relative; + margin-right: 20px; + padding: 0; +} +body.vrm.site.add #fieldset-location.fieldset-location-map .location-map-container, +body.vrm.site.update #fieldset-location.fieldset-location-map .location-map-container, +#form-container-sitesettings #fieldset-location.fieldset-location-map .location-map-container { + border: 1px solid #dcdbd7; +} +body.vrm.site.add #fieldset-location.fieldset-location-map .location-map-container #location-map, +body.vrm.site.update #fieldset-location.fieldset-location-map .location-map-container #location-map, +#form-container-sitesettings #fieldset-location.fieldset-location-map .location-map-container #location-map { + border: 1px solid #ffffff; + height: 395px; + width: 618px; +} +body.vrm.site.add #fieldset-location.fieldset-location-map #location-info, +body.vrm.site.update #fieldset-location.fieldset-location-map #location-info, +#form-container-sitesettings #fieldset-location.fieldset-location-map #location-info { + background-color: #f0efeb; + height: 50px; + padding-top: 30px; + width: 100%; +} +body.vrm.site.add #fieldset-location.fieldset-location-map #location-info h3, +body.vrm.site.update #fieldset-location.fieldset-location-map #location-info h3, +#form-container-sitesettings #fieldset-location.fieldset-location-map #location-info h3 { + padding-top: 0; +} +body.vrm.site.add #fieldset-geofence.fieldset-geofence-map, +body.vrm.site.update #fieldset-geofence.fieldset-geofence-map, +#form-container-sitesettings #fieldset-geofence.fieldset-geofence-map { + border: none; + position: relative; + margin-right: 20px; + padding: 0; + width: 618px; + background-color: inherit; +} +body.vrm.site.add #fieldset-geofence.fieldset-geofence-map .geofence-map-container, +body.vrm.site.update #fieldset-geofence.fieldset-geofence-map .geofence-map-container, +#form-container-sitesettings #fieldset-geofence.fieldset-geofence-map .geofence-map-container { + margin-top: 20px; + border: 1px solid #dcdbd7; +} +body.vrm.site.add #fieldset-geofence.fieldset-geofence-map .geofence-map-container #geofence-map, +body.vrm.site.update #fieldset-geofence.fieldset-geofence-map .geofence-map-container #geofence-map, +#form-container-sitesettings #fieldset-geofence.fieldset-geofence-map .geofence-map-container #geofence-map { + border: 1px solid #ffffff; + height: 395px; + width: 618px; +} +body.vrm.site.add #fieldset-geofence.fieldset-geofence-map .form-element, +body.vrm.site.update #fieldset-geofence.fieldset-geofence-map .form-element, +#form-container-sitesettings #fieldset-geofence.fieldset-geofence-map .form-element { + width: 50% !important; +} +body.vrm.site.add #fieldset-geofence.fieldset-geofence-map .hint, +body.vrm.site.update #fieldset-geofence.fieldset-geofence-map .hint, +#form-container-sitesettings #fieldset-geofence.fieldset-geofence-map .hint { + color: #4790d0; +} +body.vrm.site.add #fieldset-geofence.fieldset-geofence-map .mobile-hint, +body.vrm.site.update #fieldset-geofence.fieldset-geofence-map .mobile-hint, +#form-container-sitesettings #fieldset-geofence.fieldset-geofence-map .mobile-hint { + color: #4790d0; +} +body.vrm.site.add #fieldset-geofence.fieldset-geofence-map .mobile-hint, +body.vrm.site.update #fieldset-geofence.fieldset-geofence-map .mobile-hint, +#form-container-sitesettings #fieldset-geofence.fieldset-geofence-map .mobile-hint { + display: none; +} +body.vrm.site.add #submit, +body.vrm.site.update #submit, +#form-container-sitesettings #submit { + max-width: 260px; + float: right; +} +#form-container-user-settings #toggleInviteForm { + position: absolute; + top: 4px; + right: 10px; +} +#form-container-user-settings #form-container-inviteuser { + width: 320px; +} +#form-container-user-settings #form-container-inviteuser textarea#personalMessage { + max-width: 280px; + min-width: 280px; + min-height: 100px; + height: 100px; +} +#form-container-user-settings #inviteFormExplanation { + position: absolute; + top: 100px; + right: 0; + width: 270px; + color: #4790d0; +} +#form-container-user-settings #form-user-settings-container .form-input-list .only-text { + font-size: 15px !important; +} +#form-container-user-settings #form-user-settings-container .form-input-list h4 { + color: #63625e; +} +.globalbtn { + margin-top: 20px; +} +/* -----------[User pages]--------------*/ +.vrm.user h2 { + padding-left: 20px; +} +/* ---------[Page with title and table]--------------------*/ +.vrm { + padding-bottom: 30px; +} +.vrm h2.title-with-icon { + position: relative; + padding-left: 60px; + margin-top: 48px; + margin-bottom: 38px; + line-height: 27px; +} +.vrm h2.title-with-icon .sprite-icons { + position: absolute; + left: 0px; + margin: 0px 17px; +} +/* ---------[Admin tables, could go to styleguide]------------*/ +.table-overview.registrations-per-month thead th { + text-align: center; +} +.table-overview, +.table-diagnostics { + background-color: #ffffff; + border: 1px solid #dcdbd7; + border-collapse: collapse; + margin-top: 5px; + margin-bottom: 30px; + width: 100%; + font-size: 13.5px; +} +.table-overview thead th, +.table-diagnostics thead th, +.table-overview tfoot th, +.table-diagnostics tfoot th { + text-align: left; + color: #63625e; + background-color: #f0efeb; +} +.table-overview th, +.table-diagnostics th, +.table-overview td, +.table-diagnostics td { + padding: 4px 5px 3px 5px; + border-bottom: 1px solid #dcdbd7; +} +.table-overview.table-striped thead tr, +.table-diagnostics.table-striped thead tr, +.table-overview.table-striped tfoot tr, +.table-diagnostics.table-striped tfoot tr { + background-color: #e6e5e1; +} +.table-overview.table-striped thead tr th, +.table-diagnostics.table-striped thead tr th, +.table-overview.table-striped tfoot tr th, +.table-diagnostics.table-striped tfoot tr th { + border-bottom-width: 2px; +} +.table-overview.table-striped tbody tr:nth-child(2n), +.table-diagnostics.table-striped tbody tr:nth-child(2n) { + background-color: #e6e5e1; +} +.table-overview img.gravatar, +.table-diagnostics img.gravatar { + height: 40px; + width: 40px; + -webkit-border-radius: 50%; + -moz-border-radius: 50%; + border-radius: 50%; +} +.table-overview div.gravatar-wrapper, +.table-diagnostics div.gravatar-wrapper { + height: 40px; + width: 40px; + position: relative; + text-align: center; + vertical-align: middle; + color: #4790d0; + text-transform: uppercase; + font-size: 14px; + line-height: 40px; + border: none !important; + -webkit-border-radius: 50%; + -moz-border-radius: 50%; + border-radius: 50%; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; +} +.table-overview div.gravatar-wrapper img.gravatar, +.table-diagnostics div.gravatar-wrapper img.gravatar { + position: absolute !important; + top: 0 !important; + left: 0 !important; + height: 38px !important; + width: 38px !important; + float: none !important; + margin: 0 !important; + border-width: 1px !important; + border-style: solid !important; + border-color: #dcdbd7; + background: none !important; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; +} +.table-overview img.gravatar, +.table-diagnostics img.gravatar, +.table-overview div.gravatar-wrapper img.gravatar, +.table-diagnostics div.gravatar-wrapper img.gravatar, +.table-overview div.gravatar-wrapper, +.table-diagnostics div.gravatar-wrapper { + background-color: white; +} +.chrome .table-overview img.gravatar, +.chrome .table-diagnostics img.gravatar, +.chrome .table-overview div.gravatar-wrapper img.gravatar, +.chrome .table-diagnostics div.gravatar-wrapper img.gravatar, +.chrome .table-overview div.gravatar-wrapper, +.chrome .table-diagnostics div.gravatar-wrapper, +.webkit .table-overview img.gravatar, +.webkit .table-diagnostics img.gravatar, +.webkit .table-overview div.gravatar-wrapper img.gravatar, +.webkit .table-diagnostics div.gravatar-wrapper img.gravatar, +.webkit .table-overview div.gravatar-wrapper, +.webkit .table-diagnostics div.gravatar-wrapper { + line-height: 44px; +} +/* --------[Specific tables]----------*/ +.table-system-overview { + background-color: #ffffff; + border: 1px solid #dcdbd7; + border-collapse: collapse; + margin-top: 5px; + margin-bottom: 30px; + width: 100%; +} +.table-system-overview thead th, +.table-system-overview tfoot th { + text-align: left; + color: #63625e; + background-color: #f0efeb; +} +.table-system-overview th, +.table-system-overview td { + padding: 15px 20px 13px 20px; + border-bottom: 1px solid #dcdbd7; +} +.table-system-overview th:first-child, +.table-system-overview td:first-child { + width: 200px; +} +#mobile-alarms { + display: none; +} +.table-alarms .alarmStarted { + color: #fa716f; +} +.table-alarms .alarmCleared { + color: #4790d0; +} +.table-alarms .alarmActive { + color: #fa716f; +} +.table-alarms .alarmInactive { + color: #4790d0; +} +.pagination ul { + display: inline-block; + background-color: #ffffff; + border: 1px solid #dcdbd7; + margin: 15px 0; + padding: 0 10px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +.pagination ul li { + display: inline-block; + padding: 5px; +} +.pagination ul li a { + text-decoration: none; +} +.pagination ul li.active { + font-weight: bold; + font-size: calc(16px); +} +.pagination ul li.disabled a { + color: #272622; + cursor: default; +} +.pagination.pagination-centered { + margin-left: auto; + margin-right: auto; + text-align: center; +} +/* -----------[Menu]--------------*/ +.top-menu { + background-color: #272622; + height: 35px; + position: relative; +} +.top-menu .container-inner { + height: 100%; + text-align: right; +} +.top-menu ul { + height: 100%; + margin: 0; +} +.top-menu ul li { + display: inline-block; + height: 100%; + margin-top: -13px; + padding: 0 12.5px; +} +.top-menu ul li.pull-left { + -webkit-transform: translateY(13px); + -moz-transform: translateY(13px); + -ms-transform: translateY(13px); + -o-transform: translateY(13px); + transform: translateY(13px); +} +.top-menu ul li > ul.sub-menu { + display: none; + position: absolute; + top: 100%; + z-index: 999999; + height: auto; + margin-top: -8px; + margin-left: -32.5px; + padding: 8px 20px 20px 20px; +} +.top-menu ul li > ul.sub-menu li { + display: block; + background-color: #272622; + height: 35px; + padding: 0; + margin-top: 0; + text-align: left; + border-left: 1px solid #dcdbd7; + border-right: 1px solid #dcdbd7; +} +.top-menu ul li > ul.sub-menu li a { + padding: 7px 12.5px; + box-sizing: border-box; + min-width: 100%; +} +.top-menu ul li > ul.sub-menu li:last-child { + border-bottom-right-radius: 5px; + border-bottom-left-radius: 5px; + barder-bottom: 1px solid #dcdbd7; +} +.top-menu ul li:hover > ul.sub-menu, +.top-menu ul li > ul.sub-menu.expanded { + display: block; +} +.top-menu a, +.top-menu span { + color: #ffffff; + display: inline-block; + padding-top: 7px; + text-decoration: none; +} +.top-menu a:hover { + color: #ffffff; + text-decoration: underline; +} +.top-menu .plus-sign { + color: #afe18d; +} +.top-menu .container-inner { + padding-bottom: 0; +} +.top-menu-language-selector-container { + border-left: 1px solid #63625e; + cursor: pointer; + -webkit-transform: translateY(13px); + -moz-transform: translateY(13px); + -ms-transform: translateY(13px); + -o-transform: translateY(13px); + transform: translateY(13px); +} +.top-menu-language-selector-container:hover .top-menu-language-abbreviation { + text-decoration: underline; +} +.top-menu-language-abbreviation { + color: #ffffff; + float: left; + padding-top: 7px; +} +.top-menu-language-handle { + float: left; + margin-left: 4px; + margin-top: 5px; +} +.top-menu-language-fly-out { + background-color: #ffffff; + left: 0; + overflow: hidden; + position: absolute; + top: 35px; + width: 100%; + z-index: 1100; + -webkit-box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1); + box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1); +} +.top-menu-language-fly-out-content { + text-align: left; +} +.top-menu-language-fly-out-content.transitional { + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; +} +.top-menu-language-fly-out-content.visible { + margin-top: 0 !important; +} +.top-menu-language-fly-out-title { + margin-top: 24px; +} +.top-menu-language-fly-out-language-container { + margin-bottom: 20px; + margin-top: 20px; +} +.top-menu .top-menu-language-fly-out-language-link { + color: #4790d0; +} +.top-menu .top-menu-language-fly-out-language-link:hover { + color: #4790d0; +} +.top-menu .top-menu-language-fly-out-language-current { + display: inline-block; + padding-top: 7px; + color: #272622; +} +.mobile-menu { + display: none; +} +.site-overlay-on-menu-open { + background-color: rgba(0, 0, 0, 0.6); + left: -10000px; + position: fixed; + top: 0; + height: 100%; + width: 100%; + z-index: 1099; + opacity: 0; + filter: alpha(opacity=0); +} +.mobile-menu-open-handle { + display: none; +} +.mobile-menu-close-handle { + position: fixed; + top: 20px; + right: -50px; + z-index: 1100; +} +/* -----------[Header]--------------*/ +.header { + background-color: #f0efeb; + border-bottom: 1px solid #dcdbd7; + height: 80px; +} +.header .secondary-controls { + margin: 15px 10px; +} +.header .secondary-controls .btn { + padding: 14px 10px 13px 10px; +} +.header .secondary-controls ul li { + display: inline-block; + margin-left: 15px; +} +.header .secondary-controls ul li .login { + background-color: #4790d0; + color: #ffffff; +} +.header .secondary-controls ul li .login:hover { + background-color: #387dc5; +} +.breadcrumb { + background-color: #f0efeb; + border-bottom: 1px solid #dcdbd7; + border-top: 1px solid #dcdbd7; + height: 80px; +} +.breadcrumb .breadcrumb-buttons-container { + padding-top: 20px; + text-align: right; +} +.breadcrumb .breadcrumb-buttons-container .btn { + float: right; + font-size: 15px; + margin-left: 16px; +} +.breadcrumb .breadcrumb-buttons-container .remote-console-control-icon { + fill: #ffffff; +} +.breadcrumb .breadcrumb-buttons-container .remote-console-control-icon path { + fill: #ffffff; +} +.breadcrumb .site-select { + display: inline-block; + text-align: left; +} +.breadcrumb .secondary-controls { + margin: 15px 10px; +} +.breadcrumb .secondary-controls ul li { + display: inline-block; + margin-left: 15px; +} +.breadcrumb-site-title { + display: none; + font-size: 21px; + margin: 30px 0; + text-align: left; +} +.branding-logo { + display: inline-block; + width: 240px; + height: 80px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -97px -577px; + float: left; + margin: 0; + text-decoration: none; + border: none; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .branding-logo { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.sites-statistics { + display: none; +} +.map-view .map { + height: 230px; +} +.map-overview .map { + height: 480px; +} +.siteinfo img { + position: absolute !important; + width: 372.59999999999997px; + height: 532.8px; + clip: rect(86.39999999999999px 28.799999999999997px 100.79999999999998px 14.399999999999999px); + top: -81.39999999999999px; + right: -338.8px; +} +.siteinfo .infowindow { + background-color: white; + padding: 10px; + border: 1px solid #dcdbd7; + font-family: 'MuseoSans-300', sans-serif; + font-size: 12px; + line-height: 13px; +} +.siteinfo .infowindow > *:first-child { + padding-right: 14.399999999999999px; +} +.siteinfo .infowindow > * { + margin-top: 6px; +} +.map-overview, +.map-view { + border-bottom: 1px solid #dcdbd7; + position: relative; +} +.map-overview .top-shadow, +.map-view .top-shadow, +.map-overview .bottom-shadow, +.map-view .bottom-shadow { + background-color: rgba(99, 98, 94, 0.1); + position: absolute; + width: 100%; + z-index: 3; +} +.map-overview .top-shadow, +.map-view .top-shadow { + height: 5px; +} +.map-overview .bottom-shadow, +.map-view .bottom-shadow { + bottom: 0px; + height: 10px; +} +.map .cluster { + margin-top: -31px; + margin-left: -10px; +} +#vrm-tabs { + margin-top: -65px; + padding-left: 10px; + position: absolute; + z-index: 4; +} +body.vrm.site.index .main-content { + position: relative; +} +body .site-overview { + padding-top: 50px; +} +body .site-overview h2 { + margin-top: 0; + margin-bottom: 15px; +} +body .site-overview .container-inner { + position: relative; +} +body .site-overview .container-inner .over-google-map { + position: absolute; + top: -116px; + z-index: 2; +} +body .site-overview .container-inner .over-google-map .grid-item { + margin-bottom: 20px; +} +body .site-overview .container-inner table.site-list { + background: #ffffff; + width: 100%; + border: 1px solid #dcdbd7; +} +body .site-overview .container-inner table.site-list th { + text-align: left; + height: 45px; + border-bottom: 1px solid #dcdbd7; + background: #faf9f5; + padding: 0 0 0 20px; + font-weight: normal; + color: #63625e; + width: 110px; +} +body .site-overview .container-inner table.site-list th.name { + width: 200px; +} +body .site-overview .container-inner table.site-list th.soc { + width: 125px; +} +body .site-overview .container-inner table.site-list th.alarm { + width: 55px; + padding-right: 20px; + text-align: center; +} +body .site-overview .container-inner table.site-list th.sort-column-asc::after { + content: "▴"; + margin-left: 6px; +} +body .site-overview .container-inner table.site-list th.sort-column-desc::after { + content: "▾"; + margin-left: 6px; +} +body .site-overview .container-inner table.site-list tr.has-alarm td:first-child { + border-left: 3px solid #fa716f; + padding-left: 17px; +} +body .site-overview .container-inner table.site-list td { + height: 50px; + border-bottom: 1px solid #dcdbd7; + padding: 0 0 0 20px; +} +body .site-overview .container-inner table.site-list td.has-alarm { + border-left: 3px solid #fa716f; + padding-left: 17px; +} +body .site-overview .container-inner table.site-list td .caption { + line-height: 24px; +} +body .site-overview .container-inner table.site-list td:last-child { + text-align: center; + padding-right: 20px; +} +body .site-overview .container-inner table.site-list .voltage { + color: #387dc5; +} +body .site-overview .container-inner table.site-list .current { + color: #f0962e; +} +.site-overview-controls { + background: #faf9f5; + border-bottom: 1px solid #dcdbd7; + color: #63625e; + padding: 30px 0; +} +.site-overview-controls .container-inner { + padding: 0; +} +.site-overview-controls .container-inner .grid-item .caption { + margin-bottom: 5px; +} +.site-overview-controls .container-inner .grid-item.view-toggle .view-toggle-container { + margin-left: 20px; +} +.site-overview-controls .container-inner .grid-item.view-toggle .view-toggle-container .custom-toggle { + margin: 10px 0; + text-align: right; +} +.site-overview-controls .container-inner .grid-item.view-toggle .view-toggle-container .custom-toggle .alternative-display .on .sprite-icons, +.site-overview-controls .container-inner .grid-item.view-toggle .view-toggle-container .custom-toggle .alternative-display .off .sprite-icons { + margin-top: 8px; +} +.site-overview-controls .container-inner .grid-item.view-toggle .view-toggle-container .custom-toggle .alternative-display .off { + background-color: #4790d0 !important; + -webkit-box-shadow: 0px 2px 0px #387dc5 inset !important; + -moz-box-shadow: 0px 2px 0px #387dc5 inset !important; + box-shadow: 0px 2px 0px #387dc5 inset !important; +} +.site-overview-controls .container-inner .grid-item.view-toggle .view-toggle-container .custom-toggle .alternative-display .knob { + -webkit-box-shadow: 5px 0px 0px #5b9bcd !important; + -moz-box-shadow: 5px 0px 0px #5b9bcd !important; + box-shadow: 5px 0px 0px #5b9bcd !important; +} +.site-overview-controls .container-inner .grid-item.view-toggle .view-toggle-container .custom-toggle input:checked + label .alternative-display .knob { + -webkit-box-shadow: -5px 0px 0px #5b9bcd !important; + -moz-box-shadow: -5px 0px 0px #5b9bcd !important; + box-shadow: -5px 0px 0px #5b9bcd !important; + left: 57px; +} +.site-overview-controls .container-inner .grid-item.tags { + clear: none; + padding-top: 21px; +} +.tags, +.tagsinput { + clear: both; +} +.tags span.tag, +.tagsinput span.tag { + background-color: #4790d0; + border: 1px solid #dcdbd7; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + -webkit-box-shadow: 0px 2px 0px #387dc5 inset; + -moz-box-shadow: 0px 2px 0px #387dc5 inset; + box-shadow: 0px 2px 0px #387dc5 inset; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + color: #ffffff; + display: inline-block; + min-height: 40px; + padding: 8px 45px 8px 10px; + text-decoration: none; + margin: 10px 10px 0 0; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; + position: relative; +} +.tags span.tag:hover, +.tagsinput span.tag:hover { + background-color: #387dc5; + text-decoration: none; +} +.tags span.tag a, +.tagsinput span.tag a { + color: #4790d0; + position: absolute; + right: 7px; + top: 7px; + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -48px -432px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .tags span.tag a, + .tagsinput span.tag a { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.site-view { + background-color: #f0efeb; +} +.site-view .container-inner { + position: relative; +} +.site-view .container-inner .tab-select { + display: none; +} +.site-view .container-inner.no-bottom-padding { + padding-bottom: 0px; +} +.VRM_Widget_SiteSummary { + margin-bottom: 20px; +} +.VRM_Widget_SiteSummary a { + display: block; + text-decoration: none; + color: #63625e; +} +.VRM_Widget_SiteSummary .title { + line-height: 22px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.VRM_Widget_SiteSummary .sub-title { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.VRM_Widget_SiteSummary.has-alarm .site-name { + color: #f35c58; + position: relative; +} +.VRM_Widget_SiteSummary.has-alarm .site-name .title { + padding-right: 30px; +} +.VRM_Widget_SiteSummary.has-alarm .site-name .alert-red { + position: absolute; + right: 20px; + top: 21px; +} +.VRM_Widget_SiteSummary.has-alarm a { + color: #f35c58; +} +.VRM_Widget_SolarChargerPVYield .jqplot-target .jqplot-yaxis { + color: #666666 !important; +} +.site-info-list li { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + max-height: 99px; + min-height: 99px; + border-top: 1px solid #dcdbd7; + border-left: 1px solid #dcdbd7; + border-right: 1px solid #dcdbd7; + background-color: #ffffff; + padding: 22px 20px 24px 20px; +} +.site-info-list li:first-child { + background-color: #faf9f5; + max-height: 79px; + min-height: 79px; +} +.site-info-list li:first-child .data-container .voltage { + color: #387dc5; +} +.site-info-list li:first-child .data-container .current { + color: #f0962e; +} +.site-info-list li.site-name { + padding: 0px; +} +.site-info-list li.site-name a { + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; + height: 78px; + width: 298px; +} +.site-info-list li.site-name a:hover { + background-color: #ffffff; +} +.site-info-list li.site-name .title { + font-size: 21px; + padding-left: 20px; + padding-right: 20px; + padding-top: 22px; +} +.site-info-list li.site-name .sub-title { + padding-left: 20px; +} +.site-info-list li.site-name .sub-title .caption { + vertical-align: super; +} +.site-info-list li.site-info { + *zoom: 1; +} +.site-info-list li.site-info:before, +.site-info-list li.site-info:after { + display: table; + content: ""; + line-height: 0; +} +.site-info-list li.site-info:after { + clear: both; +} +.site-info-list li.site-info .img-container { + width: 45px; + height: 45px; + float: left; +} +.site-info-list li.site-info .data-container { + float: right; + width: 170px; + padding: 5px 5px 5px 15px; +} +.site-info-list li.site-info .data-container .caption { + display: block; + font-size: 18px; +} +.site-info-list li.site-info .data-container .data-value { + display: block; +} +.site-info-list li.site-info .data-container .data-value .olddata { + color: #f35c58; +} +.site-info-list li.site-info .data-container .data-value .current { + color: #f0962e; +} +.site-info-list li.site-info .data-container .data-value .voltage { + color: #387dc5; +} +.site-info-list li.site-info .data-container .data-value .standard { + color: #387dc5; +} +.site-info-list li:last-child { + border-bottom: 1px solid #dcdbd7; +} +/* -----------[Custom data toggle]--------------*/ +.custom-data-toggle { + *zoom: 1; + background-color: #e6e5e1; + border: 1px solid #dcdbd7; + padding: 0px 10px; +} +.custom-data-toggle:before, +.custom-data-toggle:after { + display: table; + content: ""; + line-height: 0; +} +.custom-data-toggle:after { + clear: both; +} +.custom-data-toggle.checked { + background-color: #ffffff; +} +.custom-data-toggle input { + display: none; +} +.custom-data-toggle label { + display: block; + height: 50px; + padding: 20px 10px; +} +.custom-data-toggle .img-container { + width: 45px; + height: 45px; + float: left; +} +.custom-data-toggle .data-container { + float: right; + width: 180px; + padding: 5px; +} +.custom-data-toggle .data-container .caption { + display: block; +} +.custom-data-toggle .data-container .data-value { + display: block; +} +/* -------------[ Google Maps ]-------------- */ +.gm-style img { + /** Fixes that obnoxious Bootstrap responsive image hack */ + max-width: none; +} +.gmnoprint img { + max-width: inherit; +} +/* --------------[ Tabs ]--------------------*/ +#vrm-tabs-content { + color: #63625e; +} +#vrm-tabs-content .tab-pane .content { + position: relative; + padding: 0; +} +#vrm-tabs-content .tab-pane#settings #main-settings-form { + display: none; +} +#vrm-tabs-content .tab-pane#settings .content .form-tabs-container .mobile-title { + display: none; +} +#vrm-tabs-content .tab-pane#settings .content .form-tabs-container .form-tabs { + margin-top: 0px; +} +#vrm-tabs-content .tab-pane#settings .content .form-tabs-container .form-tabs li { + overflow: hidden; +} +#vrm-tabs-content .tab-pane#settings .content .form-tabs-container .form-tabs li:first-child { + -webkit-border-top-left-radius: 5px; + -moz-border-radius-topleft: 5px; + border-top-left-radius: 5px; + -webkit-border-top-right-radius: 5px; + -moz-border-radius-topright: 5px; + border-top-right-radius: 5px; +} +#vrm-tabs-content .tab-pane#settings .content .form-tabs-container .form-tabs li:first-child a { + -webkit-border-top-left-radius: 5px; + -moz-border-radius-topleft: 5px; + border-top-left-radius: 5px; + -webkit-border-top-right-radius: 5px; + -moz-border-radius-topright: 5px; + border-top-right-radius: 5px; +} +#vrm-tabs-content .tab-pane#settings .content .form-tabs-container .form-tabs li:last-child { + -webkit-border-bottom-left-radius: 5px; + -moz-border-radius-bottomleft: 5px; + border-bottom-left-radius: 5px; + -webkit-border-bottom-right-radius: 5px; + -moz-border-radius-bottomright: 5px; + border-bottom-right-radius: 5px; +} +#vrm-tabs-content .tab-pane#settings .content .form-tabs-container .form-tabs li:last-child a { + -webkit-border-bottom-left-radius: 5px; + -moz-border-radius-bottomleft: 5px; + border-bottom-left-radius: 5px; + -webkit-border-bottom-right-radius: 5px; + -moz-border-radius-bottomright: 5px; + border-bottom-right-radius: 5px; +} +#vrm-tabs-content .tab-pane#settings .content .form-tabs-container .form-tabs .error, +#vrm-tabs-content .tab-pane#settings .content .form-tabs-container .form-tabs .error .required { + color: #fa716f; +} +#vrm-tabs-content .tab-pane#settings .content #settingsButtonErrorText { + display: block; + margin-top: 20px; + text-align: center; + color: #fa716f; +} +#vrm-tabs-content .tab-pane#settings .content .remove-site-question { + margin-bottom: 20px; +} +#vrm-tabs-content .tab-pane#settings .content .remove-site-question h3 { + margin-bottom: 10px; +} +#vrm-tabs-content .tab-pane#settings .content .header { + background-color: #f0efeb; + border: 1px solid #dcdbd7; + border-bottom: none; + height: 10px; + padding: 17px 20px 22px; +} +#vrm-tabs-content .tab-pane#settings .content .header .caption-right { + float: right; + padding-right: 18px; +} +#vrm-tabs-content .tab-pane#settings .content .sortable-widgets-header { + background-color: #faf9f5; + border: 1px solid #dcdbd7; + border-bottom: none; + height: 30px; + padding: 18px 20px 2px 18px; +} +#vrm-tabs-content .tab-pane#settings .content .sortable-widgets-header .caption { + font-size: 21px; +} +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .header { + background-color: #faf9f5; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list, +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list, +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list { + background-color: #ffffff; + border: 1px solid #dcdbd7; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list .row, +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row, +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row { + border-bottom: 1px solid #f0efeb; + height: 60px; + overflow: hidden; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list .row:last-child, +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row:last-child, +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row:last-child { + border-color: #dcdbd7; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list .row .inner-container, +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container, +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container { + padding: 10px 20px 10px 20px; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list .row .inner-container .custom-toggle > input, +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container .custom-toggle > input, +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle > input { + display: none; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list .row .inner-container .custom-toggle label, +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label, +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle label { + font-size: 18px; + padding: 0px; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list .row .inner-container .custom-toggle label .alternative-display, +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label .alternative-display, +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle label .alternative-display { + left: auto; + right: 0px; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list .row .inner-container .custom-toggle label a, +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label a, +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle label a { + display: block; + position: absolute; + top: 8px; + right: 0px; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list .row .inner-container .custom-toggle label a:hover > div, +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label a:hover > div, +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle label a:hover > div { + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -432px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + #vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list .row .inner-container .custom-toggle label a:hover > div, + #vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label a:hover > div, + #vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle label a:hover > div { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list .row .inner-container .only-text, +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container .only-text, +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container .only-text { + font-size: 18px; + line-height: 44px; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list .row .inner-container .only-text .on-off, +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container .only-text .on-off, +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container .only-text .on-off { + float: right; + margin-top: -10px; + width: 170px; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list .row .inner-container .email-caption, +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container .email-caption, +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container .email-caption { + color: #387dc5; + font-size: 15px; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list:last-child, +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list:last-child, +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list:last-child { + border-bottom: none; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list.sortable-widgets, +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list.sortable-widgets, +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list.sortable-widgets { + position: relative; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list.sortable-widgets li, +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list.sortable-widgets li, +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list.sortable-widgets li { + height: 49px; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list.sortable-widgets .row, +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list.sortable-widgets .row, +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list.sortable-widgets .row { + color: #4790d0; + cursor: move; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list.sortable-widgets .row .inner-container, +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list.sortable-widgets .row .inner-container, +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list.sortable-widgets .row .inner-container { + color: #63625e; + display: block; + padding: 17px 0 12px 46px; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list.sortable-widgets .row .inner-container .custom-toggle label, +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list.sortable-widgets .row .inner-container .custom-toggle label, +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list.sortable-widgets .row .inner-container .custom-toggle label { + cursor: move; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list.sortable-widgets .row input[type="checkbox"], +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list.sortable-widgets .row input[type="checkbox"], +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list.sortable-widgets .row input[type="checkbox"] { + position: absolute; + visibility: hidden; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .form-input-list.sortable-widgets .row.ui-sortable-placeholder, +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list.sortable-widgets .row.ui-sortable-placeholder, +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list.sortable-widgets .row.ui-sortable-placeholder { + visibility: visible !important; +} +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row { + border-bottom: 1px solid #f0efeb; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .disabled-widgets-container { + float: right; + margin-right: 0px; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .disabled-widgets { + background-color: #f0efeb; + border: none; + min-height: 50px; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .disabled-widgets li { + border: 1px solid #dcdbd7; + margin-bottom: -1px; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .disabled-widgets li .inner-container { + padding-left: 37px !important; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .disabled-widgets .ui-sortable-placeholder { + border: none; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .sortable-widget-list-disabled-caption { + margin-bottom: 3px; + margin-top: 27px; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .active-widgets-container { + float: left; + margin-left: 0px; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .active-widgets-container .horizontal-line { + background-color: #dcdbd7; + height: 1px; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .active-widgets { + list-style-type: none; + margin: 0; + padding: 0; + -webkit-box-shadow: 0 0 10px #dcdbd7; + -moz-box-shadow: 0 0 10px #dcdbd7; + box-shadow: 0 0 10px #dcdbd7; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .active-widgets li { + counter-increment: customlistcounter; + list-style-position: inside; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .active-widgets li:before { + content: counter(customlistcounter) " "; + float: left; + margin-left: 20px; + margin-top: 17px; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .active-widgets li:first-child { + counter-reset: customlistcounter; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .active-widgets .placeholder-list-item { + background: url('/img/drag-drop-placeholder-pattern.png') repeat; + background-color: #f0efeb !important; + height: 99px; + position: relative; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .active-widgets .placeholder-list-item:before { + background-color: #f0efeb; + content: ' '; + left: 50%; + margin-left: -12px; + margin-top: -12px; + position: absolute; + top: 50%; + -webkit-border-radius: 100px; + -moz-border-radius: 100px; + border-radius: 100px; + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -48px -672px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + #vrm-tabs-content .tab-pane#settings .content #form-widget-settings .active-widgets .placeholder-list-item:before { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .active-widgets .ui-sortable-placeholder { + background: url('/img/drag-drop-placeholder-pattern.png') repeat; + background-color: #f0efeb !important; + height: 99px; + position: relative; +} +#vrm-tabs-content .tab-pane#settings .content #form-widget-settings .active-widgets .ui-sortable-placeholder:before { + background-color: #f0efeb; + content: ' '; + left: 50%; + margin-left: -12px; + margin-top: -12px; + position: absolute; + top: 50%; + -webkit-border-radius: 100px; + -moz-border-radius: 100px; + border-radius: 100px; + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -48px -672px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + #vrm-tabs-content .tab-pane#settings .content #form-widget-settings .active-widgets .ui-sortable-placeholder:before { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label, +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle label { + line-height: 21px; +} +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container .only-text, +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container .only-text { + line-height: 21px; +} +#vrm-tabs-content .tab-pane#settings .content #form-container-sitesettings { + margin-bottom: 20px; +} +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .header { + background-color: #faf9f5; +} +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .header .caption-right { + padding-right: 0; + width: 170px; +} +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container img.gravatar { + height: 40px; + width: 40px; + -webkit-border-radius: 50%; + -moz-border-radius: 50%; + border-radius: 50%; +} +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container div.gravatar-wrapper { + height: 40px; + width: 40px; + position: relative; + text-align: center; + vertical-align: middle; + color: #4790d0; + text-transform: uppercase; + font-size: 14px; + line-height: 40px; + border: none !important; + -webkit-border-radius: 50%; + -moz-border-radius: 50%; + border-radius: 50%; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; +} +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container div.gravatar-wrapper img.gravatar { + position: absolute !important; + top: 0 !important; + left: 0 !important; + height: 38px !important; + width: 38px !important; + float: none !important; + margin: 0 !important; + border-width: 1px !important; + border-style: solid !important; + border-color: #dcdbd7; + background: none !important; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; +} +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container img.gravatar, +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container div.gravatar-wrapper img.gravatar, +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container div.gravatar-wrapper { + float: left; + margin-right: 20px; +} +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container img.gravatar.admin, +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container div.gravatar-wrapper img.gravatar.admin, +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container div.gravatar-wrapper.admin { + color: #8bc964; + border-color: #8bc964; +} +.chrome #vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container img.gravatar, +.chrome #vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container div.gravatar-wrapper img.gravatar, +.chrome #vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container div.gravatar-wrapper, +.webkit #vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container img.gravatar, +.webkit #vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container div.gravatar-wrapper img.gravatar, +.webkit #vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container div.gravatar-wrapper { + line-height: 41px !important; +} +#vrm-tabs-content .tab-pane#settings .content #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label .alternative-display { + display: block; + right: 40px; +} +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings { + margin-bottom: 10px; +} +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row { + border-bottom: 1px solid #f0efeb; +} +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container img.gravatar { + height: 40px; + width: 40px; + -webkit-border-radius: 50%; + -moz-border-radius: 50%; + border-radius: 50%; +} +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container div.gravatar-wrapper { + height: 40px; + width: 40px; + position: relative; + text-align: center; + vertical-align: middle; + color: #4790d0; + text-transform: uppercase; + font-size: 14px; + line-height: 40px; + border: none !important; + -webkit-border-radius: 50%; + -moz-border-radius: 50%; + border-radius: 50%; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; +} +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container div.gravatar-wrapper img.gravatar { + position: absolute !important; + top: 0 !important; + left: 0 !important; + height: 38px !important; + width: 38px !important; + float: none !important; + margin: 0 !important; + border-width: 1px !important; + border-style: solid !important; + border-color: #dcdbd7; + background: none !important; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; +} +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container img.gravatar, +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container div.gravatar-wrapper img.gravatar, +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container div.gravatar-wrapper { + float: left; + margin-right: 20px; +} +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container img.gravatar.receives-notifications, +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container div.gravatar-wrapper img.gravatar.receives-notifications, +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container div.gravatar-wrapper.receives-notifications { + color: #4790d0; + border-color: #4790d0; +} +.chrome #vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container img.gravatar, +.chrome #vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container div.gravatar-wrapper img.gravatar, +.chrome #vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container div.gravatar-wrapper, +.webkit #vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container img.gravatar, +.webkit #vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container div.gravatar-wrapper img.gravatar, +.webkit #vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row .inner-container div.gravatar-wrapper { + line-height: 41px !important; +} +#vrm-tabs-content .tab-pane#settings .content #form-alarms-admin-settings .form-input-list .row:last-child { + border-bottom: 1px solid #dcdbd7; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings { + position: relative; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container { + /*width: 300px;*/ +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #alarm_notifications-label, +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #no_data-label, +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #float_limits-label, +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #enum_limits-label { + height: 0px; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #alarm_notifications-element .custom-toggle.main label .caption, +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #no_data-element .custom-toggle.main label .caption { + color: #387dc5; + font-size: 18px; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #alarm_notifications-element dt { + height: 0px; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #alarm_notifications-element .form-input-list { + margin: 0px; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #no_data-element, +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits { + position: relative; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #no_data-element fieldset dl, +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits fieldset dl { + margin: 0px; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #no_data-element fieldset dl #no_data-enabled-label, +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits fieldset dl #no_data-enabled-label { + height: 0px; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #no_data-element fieldset dl #no_data-enabled-element, +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits fieldset dl #no_data-enabled-element { + margin-bottom: 15px; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #no_data-element fieldset dl .hint, +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits fieldset dl .hint { + color: #4790d0; + position: absolute; + right: -300px; + top: 0px; + width: 270px; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-no_data { + margin-bottom: 15px; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-float_limits, +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits { + border: none; + padding: 15px; + margin-bottom: 15px; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-float_limits > dl, +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits > dl { + background-color: #f0efeb; + margin: 0px; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-float_limits > dl > dt, +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits > dl > dt { + height: 0px; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-float_limits > dl > dd, +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits > dl > dd { + position: relative; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-float_limits > dl > dd > fieldset > dl, +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits > dl > dd > fieldset > dl { + margin-top: 0px; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-float_limits > dl > dd > fieldset > dl > dt:nth-child(2), +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits > dl > dd > fieldset > dl > dt:nth-child(2) { + height: 0px; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-float_limits > dl > dd > fieldset > dl > dt:not(:first-child), +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits > dl > dd > fieldset > dl > dt:not(:first-child) { + margin-top: 15px; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-float_limits .custom-toggle.main label .caption, +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits .custom-toggle.main label .caption { + color: #387dc5; + font-size: 18px; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-float_limits .remove-alarm-button, +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form #fieldset-enum_limits .remove-alarm-button { + position: absolute; + top: 20px; + right: 20px; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .form-container form dd { + margin-left: 0px; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .above-fieldset-element { + position: absolute; + right: 0px; + top: -69px; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .above-fieldset-element .btn { + margin-left: 12px; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-alarms-settings .admin-users-box .title { + font-size: 18px; + margin: 20px 0 20px 20px; +} +#vrm-tabs-content .tab-pane#settings .content #form-user-settings .sprite-icons.cross-in-circle-dark { + vertical-align: top; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-system-overview .device-icon { + float: left; + margin-right: 5px; +} +#vrm-tabs-content .tab-pane#settings .content #forms-container-system-overview .device-icon + h3 { + line-height: 48px; +} +#vrm-tabs-content h2 { + margin: 12px 0 2px 0; +} +#vrm-tabs-content .section-heading { + *zoom: 1; + margin: 35px 0 7px 0; +} +#vrm-tabs-content .section-heading:before, +#vrm-tabs-content .section-heading:after { + display: table; + content: ""; + line-height: 0; +} +#vrm-tabs-content .section-heading:after { + clear: both; +} +#vrm-tabs-content .section-heading .sprite-icons { + float: left; + margin: 9px 21px 25px 25px; +} +#vrm-tabs-content .section-heading .information { + float: left; +} +#vrm-tabs-content .section-heading .btn { + margin-right: 10px; + margin-top: 29px; +} +#vrm-tabs-content .widget-filter-container { + margin-bottom: 20px; +} +#vrm-tabs-content .widget-filter-container #widget-filter { + width: 100%; +} +#vrm-tabs-content #advanced .section-heading { + margin: 35px 0; +} +#vrm-tabs-content .last-update-info { + color: #63625e; + padding-right: 15px; + text-align: right; + float: left; +} +#vrm-tabs-content .mobile-graph-refresh { + display: none; +} +#vrm-tabs-content .progress-meters-container { + border-top: 1px solid #dcdbd7; + height: 396px; +} +#vrm-tabs-content .progress-meters-container .progress-meter-container { + background-color: #ffffff; + border: 1px solid #dcdbd7; + border-top: none; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 20px 60px 48px 60px; + position: relative; + width: 100%; +} +#vrm-tabs-content .progress-meters-container .progress-meter-container .progress-meter, +#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter { + position: relative; + width: 100%; +} +#vrm-tabs-content .progress-meters-container .progress-meter-container .progress-meter .inner-meter-container, +#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container { + position: relative; +} +#vrm-tabs-content .progress-meters-container .progress-meter-container .progress-meter .inner-meter-container .meter, +#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .meter { + background: #e6e5e1; + float: left; + height: 10px; + margin-top: 37px; +} +#vrm-tabs-content .progress-meters-container .progress-meter-container .progress-meter .inner-meter-container .meter .progress, +#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .meter .progress { + display: block; + height: 100%; + overflow: hidden; + width: 0%; +} +#vrm-tabs-content .progress-meters-container .progress-meter-container .progress-meter .inner-meter-container .indicator, +#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .indicator { + display: inline-block; + position: absolute; + top: 0px; + visibility: hidden; + white-space: nowrap; + z-index: 1; +} +#vrm-tabs-content .progress-meters-container .progress-meter-container .progress-meter .inner-meter-container .indicator .indicator-body, +#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .indicator .indicator-body { + color: #ffffff; + background: #63625e; + line-height: 30px; + padding: 0px 6px; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; +} +#vrm-tabs-content .progress-meters-container .progress-meter-container .progress-meter .inner-meter-container .indicator .indicator-footer, +#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .indicator .indicator-footer { + height: 5px; + width: 0px; + margin: 0 auto; + border-top: 5px outset #63625e; + border-left: 5px inset rgba(0, 0, 0, 0); + border-right: 5px inset rgba(0, 0, 0, 0); +} +#vrm-tabs-content .progress-meters-container .progress-meter-container .progress-meter .inner-meter-container .icon, +#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .icon { + left: -42px; + position: absolute; + top: 30px; +} +#vrm-tabs-content .progress-meters-container .progress-meter-container .progress-meter .inner-meter-container p, +#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container p { + font-size: 11px; + position: absolute; + top: 41px; +} +#vrm-tabs-content .progress-meters-container .progress-meter-container .progress-meter .inner-meter-container p.pull-right, +#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container p.pull-right { + right: 0px; +} +#vrm-tabs-content .progress-meters-container .progress-meter-container .progress-meter .meter { + width: 100%; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; +} +#vrm-tabs-content .progress-meters-container .progress-meter-container .progress-meter .meter .progress { + background: #f7ab3e; + -webkit-border-top-left-radius: 2px; + -moz-border-radius-topleft: 2px; + border-top-left-radius: 2px; + -webkit-border-bottom-left-radius: 2px; + -moz-border-radius-bottomleft: 2px; + border-bottom-left-radius: 2px; +} +#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .meter.positive { + -webkit-border-top-left-radius: 2px; + -moz-border-radius-topleft: 2px; + border-top-left-radius: 2px; + -webkit-border-bottom-left-radius: 2px; + -moz-border-radius-bottomleft: 2px; + border-bottom-left-radius: 2px; + width: 50%; +} +#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .meter.positive .progress { + background-color: #8bc964; + float: right; +} +#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .meter.negative { + -webkit-border-top-right-radius: 2px; + -moz-border-radius-topright: 2px; + border-top-right-radius: 2px; + -webkit-border-bottom-right-radius: 2px; + -moz-border-radius-bottomright: 2px; + border-bottom-right-radius: 2px; + width: 50%; +} +#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .meter.negative .progress { + background-color: #fa716f; +} +#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .center-point { + left: 50%; + position: absolute; + top: 36px; +} +#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .center-point .divider { + background-color: #959490; + height: 18px; + width: 1px; +} +#vrm-tabs-content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .center-point .caption { + color: #959490; + font-size: 11px; + margin-left: -3px; +} +#vrm-tabs-content .progress-meters-container .progress-meter-container.power-distribution .meter { + background: #e6e5e1; +} +#vrm-tabs-content .progress-meters-container .progress-meter-container.genset-actual .progress-meter .inner-meter-container .meter .progress { + background: #4790d0; +} +#vrm-tabs-content .progress-meters-container.rows-1 { + height: 198px; +} +#vrm-tabs-content .progress-meters-container.rows-1 .progress-meter-container { + height: 199px; + padding-top: 30px; +} +#vrm-tabs-content .progress-meters-container.rows-1 .progress-meter-container .inner-meter-container { + margin-top: 5px; +} +#vrm-tabs-content .progress-meters-container.rows-2 .progress-meter-container { + height: 198px; + padding-top: 30px; +} +#vrm-tabs-content .progress-meters-container.rows-2 .progress-meter-container .inner-meter-container { + margin-top: 5px; +} +#vrm-tabs-content .progress-meters-container.rows-2 .progress-meter-container:last-child { + height: 197px; +} +#vrm-tabs-content .progress-meters-container.rows-3 .progress-meter-container { + height: 132px; +} +#vrm-tabs-content .progress-meters-container.rows-3 .progress-meter-container:last-child { + height: 131px; +} +#vrm-tabs-content .totalProduced li:first-child { + border: none; + min-height: 99px; + padding: 0; +} +#vrm-tabs-content .totalProduced li:first-child .main-section { + background: #f7ab3e; + border: 0; + color: #ffffff; + height: 74px; + float: left; + padding-left: 40px; + padding-top: 25px; + width: 260px; +} +#vrm-tabs-content .totalProduced li:first-child .main-section h1 { + margin: 4px 0 0 0; +} +#vrm-tabs-content .totalProduced li:first-child .main-section.status-ok { + background: #8bc964; +} +#vrm-tabs-content .totalProduced li:first-child .main-section.status-alarm { + background: #fa716f; +} +#vrm-tabs-content .totalProduced li:first-child .corner { + position: absolute; + right: 10px; +} +#vrm-tabs-content .totalProduced li:first-child .corner.blue { + display: inline-block; + width: 30px; + height: 60px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -432px -120px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + #vrm-tabs-content .totalProduced li:first-child .corner.blue { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +#vrm-tabs-content .totalProduced li:first-child .corner.orange { + display: inline-block; + width: 30px; + height: 60px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -462px -120px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + #vrm-tabs-content .totalProduced li:first-child .corner.orange { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +#vrm-tabs-content .totalProduced li:first-child .corner.red { + display: inline-block; + width: 30px; + height: 60px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -492px -120px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + #vrm-tabs-content .totalProduced li:first-child .corner.red { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +#vrm-tabs-content .totalProduced li:first-child .corner.green { + display: inline-block; + width: 30px; + height: 60px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -522px -120px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + #vrm-tabs-content .totalProduced li:first-child .corner.green { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +#vrm-tabs-content .totalProduced li:nth-child(2) { + border-top: none; +} +#vrm-tabs-content .tab-pane#advanced .download-data-container { + position: absolute; + top: 14px; + right: 17px; + line-height: 26px; + padding-left: 28px; + max-height: 52px; + text-align: left; +} +#vrm-tabs-content .tab-pane#advanced .download-data-container .link-text { + padding: 0 5px; +} +#vrm-tabs-content .tab-pane#batteries .section-graph, +#vrm-tabs-content .tab-pane#solar-yield .section-graph, +#vrm-tabs-content .tab-pane#consumption .section-graph { + background-color: #ffffff; + border: 1px solid #dcdbd7; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +#vrm-tabs-content .tab-pane#batteries .section-graph .dashboard-graph, +#vrm-tabs-content .tab-pane#solar-yield .section-graph .dashboard-graph, +#vrm-tabs-content .tab-pane#consumption .section-graph .dashboard-graph { + height: 324px; + margin: 40px 60px 30px 10px; +} +#vrm-tabs-content .tab-pane#batteries .section-graph .dashboard-graph.move-last-tick-to-front .jqplot-xaxis canvas:last-child, +#vrm-tabs-content .tab-pane#solar-yield .section-graph .dashboard-graph.move-last-tick-to-front .jqplot-xaxis canvas:last-child, +#vrm-tabs-content .tab-pane#consumption .section-graph .dashboard-graph.move-last-tick-to-front .jqplot-xaxis canvas:last-child { + left: 0px !important; +} +#vrm-tabs-content .tab-pane#batteries .section-graph .dashboard-legend, +#vrm-tabs-content .tab-pane#solar-yield .section-graph .dashboard-legend, +#vrm-tabs-content .tab-pane#consumption .section-graph .dashboard-legend { + background-color: #e6e5e1; + border-top: 1px solid #dcdbd7; + height: 60px; +} +#vrm-tabs-content .tab-pane#batteries .section-graph .dashboard-legend ul, +#vrm-tabs-content .tab-pane#solar-yield .section-graph .dashboard-legend ul, +#vrm-tabs-content .tab-pane#consumption .section-graph .dashboard-legend ul { + margin-left: 20px; + margin-top: 20px; +} +#vrm-tabs-content .tab-pane#batteries .section-graph .dashboard-legend ul li, +#vrm-tabs-content .tab-pane#solar-yield .section-graph .dashboard-legend ul li, +#vrm-tabs-content .tab-pane#consumption .section-graph .dashboard-legend ul li { + float: left; + margin-right: 50px; +} +#vrm-tabs-content .tab-pane#batteries .section-graph .dashboard-legend ul li .color-square, +#vrm-tabs-content .tab-pane#solar-yield .section-graph .dashboard-legend ul li .color-square, +#vrm-tabs-content .tab-pane#consumption .section-graph .dashboard-legend ul li .color-square { + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + float: left; + height: 20px; + margin-right: 9px; + width: 20px; +} +#vrm-tabs-content .tab-pane#batteries .section-graph .dashboard-legend ul li .color-square.blue, +#vrm-tabs-content .tab-pane#solar-yield .section-graph .dashboard-legend ul li .color-square.blue, +#vrm-tabs-content .tab-pane#consumption .section-graph .dashboard-legend ul li .color-square.blue { + background-color: #4790d0; +} +#vrm-tabs-content .tab-pane#batteries .section-graph .dashboard-legend ul li .color-square.green, +#vrm-tabs-content .tab-pane#solar-yield .section-graph .dashboard-legend ul li .color-square.green, +#vrm-tabs-content .tab-pane#consumption .section-graph .dashboard-legend ul li .color-square.green { + background-color: #8bc964; +} +#vrm-tabs-content .tab-pane#batteries .section-graph .dashboard-legend ul li .color-square.orange, +#vrm-tabs-content .tab-pane#solar-yield .section-graph .dashboard-legend ul li .color-square.orange, +#vrm-tabs-content .tab-pane#consumption .section-graph .dashboard-legend ul li .color-square.orange { + background-color: #f7ab3e; +} +#vrm-tabs-content .tab-pane#batteries .section-graph .dashboard-legend ul li .color-square.red, +#vrm-tabs-content .tab-pane#solar-yield .section-graph .dashboard-legend ul li .color-square.red, +#vrm-tabs-content .tab-pane#consumption .section-graph .dashboard-legend ul li .color-square.red { + background-color: #fa716f; +} +#vrm-tabs-content .tab-pane#batteries .section-graph .dashboard-legend ul li .caption, +#vrm-tabs-content .tab-pane#solar-yield .section-graph .dashboard-legend ul li .caption, +#vrm-tabs-content .tab-pane#consumption .section-graph .dashboard-legend ul li .caption { + color: #63625e; + float: left; + font-size: 11px; +} +#vrm-tabs-content .tab-pane#batteries .site-info-list li:first-child { + background-color: #ffffff; + max-height: 99px; +} +#vrm-tabs-content .tab-pane#solar-yield .site-info-list li, +#vrm-tabs-content .tab-pane#consumption .site-info-list li { + padding: 0px; +} +#vrm-tabs-content .tab-pane#solar-yield .site-info-list li:first-child, +#vrm-tabs-content .tab-pane#consumption .site-info-list li:first-child { + background-color: #ffffff; + max-height: 99px; +} +#vrm-tabs-content .tab-pane#solar-yield .site-info-list li .plot, +#vrm-tabs-content .tab-pane#consumption .site-info-list li .plot { + float: left; + height: 93px; + margin-bottom: -4px; + margin-top: 10px; + width: 99px; +} +#vrm-tabs-content .tab-pane#solar-yield .site-info-list li .plot-info, +#vrm-tabs-content .tab-pane#consumption .site-info-list li .plot-info { + float: left; + height: 99px; +} +#vrm-tabs-content .tab-pane#solar-yield .site-info-list li .plot-info .caption, +#vrm-tabs-content .tab-pane#consumption .site-info-list li .plot-info .caption { + font-size: 18px; + margin-top: 31px; +} +#vrm-tabs-content .tab-pane#solar-yield .site-info-list li .plot-info .subcaption, +#vrm-tabs-content .tab-pane#consumption .site-info-list li .plot-info .subcaption { + color: #f7ab3e; +} +#vrm-tabs-content .tab-pane#solar-yield .site-info-list li .plot-info ul li, +#vrm-tabs-content .tab-pane#consumption .site-info-list li .plot-info ul li { + border: none; + float: left; + min-height: 0px; + padding-right: 10px; +} +#vrm-tabs-content .tab-pane#solar-yield .site-info-list li .plot-info ul li.toGrid, +#vrm-tabs-content .tab-pane#consumption .site-info-list li .plot-info ul li.toGrid, +#vrm-tabs-content .tab-pane#solar-yield .site-info-list li .plot-info ul li.gridUse, +#vrm-tabs-content .tab-pane#consumption .site-info-list li .plot-info ul li.gridUse { + color: #fa716f; +} +#vrm-tabs-content .tab-pane#solar-yield .site-info-list li .plot-info ul li.toBattery, +#vrm-tabs-content .tab-pane#consumption .site-info-list li .plot-info ul li.toBattery, +#vrm-tabs-content .tab-pane#solar-yield .site-info-list li .plot-info ul li.batteryUse, +#vrm-tabs-content .tab-pane#consumption .site-info-list li .plot-info ul li.batteryUse { + color: #4790d0; +} +#vrm-tabs-content .tab-pane#solar-yield .site-info-list li .plot-info ul li.directUse, +#vrm-tabs-content .tab-pane#consumption .site-info-list li .plot-info ul li.directUse, +#vrm-tabs-content .tab-pane#solar-yield .site-info-list li .plot-info ul li.solarUse, +#vrm-tabs-content .tab-pane#consumption .site-info-list li .plot-info ul li.solarUse { + color: #f7ab3e; +} +#vrm-tabs-content .tab-pane#solar-yield .site-info-list li .plot-info ul li.gensetUse, +#vrm-tabs-content .tab-pane#consumption .site-info-list li .plot-info ul li.gensetUse { + color: #8bc964; +} +/* --------------[ Date range selectors ]--------------------*/ +.advanced-view-time-toggle .icon-24-center { + left: 17px; + position: absolute; + top: 8px; +} +.date-range-selectors, +.date-range-selectors-advanced { + display: none; + background-color: #faf9f5; + padding: 21px 0 30px 0; + border-bottom: 1px solid #e5e4e0; +} +.date-range-selectors .custom_date_selector_container, +.date-range-selectors-advanced .custom_date_selector_container { + padding-left: 20px; +} +.date-range-selectors .selector-list > li, +.date-range-selectors-advanced .selector-list > li { + float: left; + margin-left: 17px; +} +.date-range-selectors .selector-list > li.pickerOnly, +.date-range-selectors-advanced .selector-list > li.pickerOnly { + visibility: hidden; + width: 0; + height: 0; + overflow: hidden; +} +.date-range-selectors .selector-list > li:first-child, +.date-range-selectors-advanced .selector-list > li:first-child { + margin-left: 0px; +} +.date-range-selectors .js__datepicker, +.date-range-selectors-advanced .js__datepicker { + color: #63625e; +} +.date-range-selectors .set-time-label, +.date-range-selectors-advanced .set-time-label, +.date-range-selectors .set-view-label, +.date-range-selectors-advanced .set-view-label { + color: #63625e; + line-height: 30px; +} +.date-range-selectors .time-selector-simple, +.date-range-selectors-advanced .time-selector-simple { + height: 51px; +} +.date-range-selectors .time-selector-custom, +.date-range-selectors-advanced .time-selector-custom { + height: 51px; + display: none; +} +.date-range-selectors .advanced-view-time-toggle, +.date-range-selectors-advanced .advanced-view-time-toggle { + margin: 5px 0 0 0; +} +.currenttime { + display: none; +} +/* --------------[ Date picker: pickadate ]--------------------*/ +.picker__input { + cursor: pointer; + text-align: center; +} +.picker { + margin-left: 10px; + margin-right: 10px; + width: 300px; + margin: 10px 0; +} +.picker .picker__holder { + border: 1px solid #dcdbd7; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + color: #272622; +} +.picker .picker__holder .picker__header .picker__nav--prev:hover, +.picker .picker__holder .picker__header .picker__nav--next:hover { + background-color: #e6e5e1; +} +.picker .picker__holder .picker__day--highlighted { + background-color: #4790d0; +} +.picker .picker__holder .picker__day--highlighted:hover { + background-color: #4790d0 !important; +} +.picker .picker__holder .picker__day--selected { + border: none; +} +.picker .picker__holder .picker__day--infocus:hover, +.picker .picker__holder .picker__day--outfocus:hover { + background-color: #e6e5e1; +} +.picker .picker__holder .picker__footer .picker__button--today:hover { + background-color: #e6e5e1; +} +.date-range-selectors-advanced .section { + float: left; + margin-left: 20px; +} +.date-range-selectors-advanced .section:first-child { + margin-left: 0px; +} +.date-range-selectors-advanced .mobile-caption { + display: none; +} +.date-range-selectors-advanced .vrm-date-time-picker { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + height: 50px; + padding: 0; + position: relative; + display: inherit; +} +.date-range-selectors-advanced .vrm-date-time-picker .picker__input, +.date-range-selectors-advanced .vrm-date-time-picker .date-range-picker-divider { + background-color: #e6e5e1; + float: left; + min-height: 48px; + max-height: 48px; +} +.date-range-selectors-advanced .vrm-date-time-picker .picker__input.changed, +.date-range-selectors-advanced .vrm-date-time-picker .date-range-picker-divider.changed { + background-color: #ffffff; + color: #63625e; +} +.date-range-selectors-advanced .vrm-date-time-picker .js__datepicker { + border: none; + color: #63625e; + -webkit-border-top-right-radius: 0px; + -moz-border-radius-topright: 0px; + border-top-right-radius: 0px; + -webkit-border-bottom-right-radius: 0px; + -moz-border-radius-bottomright: 0px; + border-bottom-right-radius: 0px; + padding: 16px 0px 12px; + width: 121px; +} +.date-range-selectors-advanced .vrm-date-time-picker .js__timepicker { + border: none; + color: #63625e; + -webkit-border-top-left-radius: 0px; + -moz-border-radius-topleft: 0px; + border-top-left-radius: 0px; + -webkit-border-bottom-left-radius: 0px; + -moz-border-radius-bottomleft: 0px; + border-bottom-left-radius: 0px; + padding: 16px 0px 12px; + width: 95px; +} +.date-range-selectors-advanced .vrm-date-time-picker .date-range-picker-divider { + height: 100%; + width: 1px; +} +.date-range-selectors-advanced .vrm-date-time-picker .date-range-picker-divider .divider { + background-color: #dcdbd7; + height: 30px; + margin-top: 9px; +} +.date-range-selectors-advanced .vrm-date-time-picker:hover .date-range-picker-divider .divider { + background-color: #e6e5e1; +} +.date-range-selectors-advanced .vrm-date-time-picker .picker { + top: 49px; + left: -1px; +} +.date-range-selectors-advanced .set-time .btn { + cursor: pointer; + padding-bottom: 9px; + padding-top: 13px; + position: relative; +} +.date-range-selectors-advanced .set-time .btn .sprite-icons { + left: 18px; + position: absolute; + top: 13px; +} +.date-range-selectors-advanced .set-time .btn .caption { + font-size: 18px; + line-height: 25px; + padding-left: 26px; +} +.date-range-selectors-advanced .set-time .btn.disabled { + cursor: default; +} +.VRM_Widget_DateRange .header.date-range-header { + height: auto; + min-height: 64px; +} +.VRM_Widget_DateRange .header.date-range-header > h3 { + float: left; + margin: 13px 11px; +} +.VRM_Widget_DateRange .date-range-list { + margin: 0; + padding: 0; + list-style-type: none; +} +.VRM_Widget_DateRange .date-range-list > li { + float: left; + color: white; + font-weight: bold; + margin: 8px 4px; +} +.VRM_Widget_DateRange .date-range-list > li.range-button-refresh { + float: right; +} +.VRM_Widget_DateRange .date-range-list > li.range-button-download { + float: right; + margin-right: 12px; + margin-left: 6px; +} +.VRM_Widget_DateRange .date-range-list > li > input, +.VRM_Widget_DateRange .date-range-list > li > span > input { + font-size: 22px; + line-height: 28px; + width: 220px; +} +.VRM_Widget_DateRange .date-range-list > li > button.small { + margin: 2px 0px; +} +.VRM_Widget_DateRange .date-range-list > li > input:hover, +.VRM_Widget_DateRange .date-range-list > li > span > input:hover { + font-style: normal; + cursor: pointer; +} +#timeRange-desktop { + position: relative; + float: left; + overflow: hidden; + width: 100%; + height: 160px; + padding: 0 0 8px 0; + margin: 0; +} +#timeRange-desktop #timePickers-desktop { + position: absolute; + top: 10px; + left: 45px; + width: 100px; + font-family: Arial; + font-size: 11px; + font-weight: normal; +} +#timeRange-desktop #timePickers-desktop input { + width: 100%; +} +#timeRange-desktop #timeRangeSet-desktop { + position: absolute; + top: 65px; + right: 45px; +} +#timeRange-desktop .datepicker { + position: relative; + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + width: 196px; + height: 147px; + cursor: default; + display: none; + margin: 0 auto; + /* Hide border divs by default */ + /* Only display the previous/next arrows on the first/last calendars */ + /* Compensate for the space lost by not having a previous arrow */ + /* Day mode calendar body */ + /* Month mode calendar body */ + /* Year mode calendar body */ + /* Not used by default, calendar cells can be marked as special if desired (doesn't seem to be totally working) */ + /* style the 'not in month' day cell away */ + /* Datepicker border styling */ + background-color: #F7F7F7; + border: 1px solid #CCCCCC; + border-radius: 5px 5px 5px 5px; + padding: 10px; + /* Tighten up the spacing between multiple calendars */ + /* Grey background behind Month Name row, and blue text */ + /* style the day of week header cells */ + /* grey underline beneath day of week row */ + /* Black text, white background, and grey borders around day cells */ + /* blue cell color for selected days */ + /* Grey out dates in the future */ + /* yellow cell background on hover */ + /* Bold today's date */ + /* cells are wider in the clean style */ +} +#timeRange-desktop .datepicker .datepickerContainer { + position: absolute; +} +#timeRange-desktop .datepicker .datepickerBorderT, +#timeRange-desktop .datepicker .datepickerBorderB, +#timeRange-desktop .datepicker .datepickerBorderL, +#timeRange-desktop .datepicker .datepickerBorderR, +#timeRange-desktop .datepicker .datepickerBorderTL, +#timeRange-desktop .datepicker .datepickerBorderTR, +#timeRange-desktop .datepicker .datepickerBorderBL, +#timeRange-desktop .datepicker .datepickerBorderBR { + display: none; +} +#timeRange-desktop .datepicker .datepickerHidden { + display: none; +} +#timeRange-desktop .datepicker table { + border-collapse: collapse; +} +#timeRange-desktop .datepicker a { + color: black; + text-decoration: none; + cursor: default; + outline: none; +} +#timeRange-desktop .datepicker table td { + text-align: center; + padding: 0; + margin: 0; +} +#timeRange-desktop .datepicker th { + text-align: center; + color: #666666; + font-weight: normal; + padding: 0; +} +#timeRange-desktop .datepicker tbody a { + display: block; +} +#timeRange-desktop .datepicker .datepickerDays a { + width: 20px; + line-height: 16px; + height: 16px; + padding-right: 2px; +} +#timeRange-desktop .datepicker .datepickerYears a, +#timeRange-desktop .datepicker .datepickerMonths a { + width: 39px; + line-height: 36px; + height: 36px; + text-align: center; +} +#timeRange-desktop .datepicker .datepickerMonths td:first-child a, +#timeRange-desktop .datepicker .datepickerMonths td:last-child a, +#timeRange-desktop .datepicker .datepickerYears td:first-child a, +#timeRange-desktop .datepicker .datepickerYears td:last-child a { + width: 38px; +} +#timeRange-desktop .datepicker td.datepickerNotInMonth a { + color: #666666; +} +#timeRange-desktop .datepicker tbody.datepickerDays td.datepickerSelected { + background: #136A9F; +} +#timeRange-desktop .datepicker tbody.datepickerDays td.datepickerNotInMonth.datepickerSelected { + background: #17384d; +} +#timeRange-desktop .datepicker tbody.datepickerYears td.datepickerSelected, +#timeRange-desktop .datepicker tbody.datepickerMonths td.datepickerSelected { + background: #17384d; +} +#timeRange-desktop .datepicker td.datepickerSelected a { + color: white; +} +#timeRange-desktop .datepicker a:hover { + color: #88c5eb; +} +#timeRange-desktop .datepicker td.datepickerNotInMonth a:hover { + color: #999999; +} +#timeRange-desktop .datepicker .datepickerSpace div { + width: 20px; +} +#timeRange-desktop .datepicker .datepickerBlock { + vertical-align: top; +} +#timeRange-desktop .datepicker a.datepickerGoNext, +#timeRange-desktop .datepicker a.datepickerGoPrev, +#timeRange-desktop .datepicker a.datepickerMonth { + text-align: center; + height: 20px; + line-height: 20px; + float: left; +} +#timeRange-desktop .datepicker th a.datepickerGoNext, +#timeRange-desktop .datepicker th a.datepickerGoPrev { + width: 20px; + color: #666666; + display: none; +} +#timeRange-desktop .datepicker th a.datepickerMonth { + width: 114px; + display: block; +} +#timeRange-desktop .datepicker .datepickerFirstView th a.datepickerGoPrev, +#timeRange-desktop .datepicker .datepickerLastView th a.datepickerGoNext { + display: block; +} +#timeRange-desktop .datepicker th a.datepickerMonth { + margin-left: 20px; +} +#timeRange-desktop .datepicker .datepickerFirstView th a.datepickerMonth { + margin-left: 0; +} +#timeRange-desktop .datepicker table.datepickerViewDays tbody.datepickerMonths, +#timeRange-desktop .datepicker table.datepickerViewDays tbody.datepickerYears { + display: none; +} +#timeRange-desktop .datepicker table.datepickerViewMonths tbody.datepickerDays, +#timeRange-desktop .datepicker table.datepickerViewMonths tbody.datepickerYears, +#timeRange-desktop .datepicker table.datepickerViewMonths tr.datepickerDoW { + display: none; +} +#timeRange-desktop .datepicker table.datepickerViewYears tbody.datepickerDays, +#timeRange-desktop .datepicker table.datepickerViewYears tbody.datepickerMonths, +#timeRange-desktop .datepicker table.datepickerViewYears tr.datepickerDoW { + display: none; +} +#timeRange-desktop .datepicker td.datepickerDisabled a, +#timeRange-desktop .datepicker td.datepickerDisabled.datepickerNotInMonth a { + color: #555555; +} +#timeRange-desktop .datepicker td.datepickerDisabled a:hover { + color: #333333; +} +#timeRange-desktop .datepicker tbody.datepickerDays td.datepickerSpecial a { + background: #770000; + color: white; +} +#timeRange-desktop .datepicker tbody.datepickerDays td.datepickerSpecial.datepickerSelected a { + background: #aa0000; +} +#timeRange-desktop .datepicker tbody.datepickerDays td.datepickerNotInMonth.datepickerSelected { + background-color: transparent; +} +#timeRange-desktop .datepicker td.datepickerNotInMonth a span { + display: none; +} +#timeRange-desktop .datepicker td.datepickerNotInMonth a:hover span { + display: none; +} +#timeRange-desktop .datepicker tbody.datepickerDays td.datepickerNotInMonth:hover { + background-color: transparent; +} +#timeRange-desktop .datepicker .datepickerSpace div { + width: 2px; +} +#timeRange-desktop .datepicker th { + background-color: #DDDDDD; +} +#timeRange-desktop .datepicker th a.datepickerMonth { + color: #008ED6; + font-weight: normal; +} +#timeRange-desktop .datepicker th { + color: black; + font-weight: bold; +} +#timeRange-desktop .datepicker table thead tr.datepickerDoW th { + border-bottom: 1px solid #CCCCCC; +} +#timeRange-desktop .datepicker a, +#timeRange-desktop .datepicker a:hover { + color: black; +} +#timeRange-desktop .datepicker table.datepickerViewDays, +#timeRange-desktop .datepicker table.datepickerViewMonths, +#timeRange-desktop .datepicker table.datepickerViewYears { + background-color: white; +} +#timeRange-desktop .datepicker table tbody.datepickerDays td { + border: 1px solid #F7F7F7; +} +#timeRange-desktop .datepicker tbody.datepickerDays td.datepickerSelected { + background-color: #0077CC; +} +#timeRange-desktop .datepicker td.datepickerFuture a { + color: #DDDDDD; +} +#timeRange-desktop .datepicker tbody.datepickerDays td:hover { + background-color: #FFCC33; +} +#timeRange-desktop .datepicker td.datepickerToday a { + font-weight: bold; +} +#timeRange-desktop .datepicker .datepickerYears a, +#timeRange-desktop .datepicker .datepickerMonths a { + width: 42px; +} +#timeRange-desktop .datepicker .datepickerMonths td:first-child a, +#timeRange-desktop .datepicker .datepickerYears td:first-child a { + width: 39px; +} +#timeRange-desktop .datepicker th a.datepickerMonth { + width: 121px; +} +.ui-timepicker-list { + overflow-y: auto; + height: 150px; + width: 6.5em; + background: #fff; + border: 1px solid #ddd; + margin: 0; + padding: 0; + list-style: none; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + outline: none; + z-index: 10001; +} +.ui-timepicker-list.ui-timepicker-with-duration { + width: 11em; +} +.ui-timepicker-duration { + margin-left: 5px; + color: #888; +} +.ui-timepicker-list:hover .ui-timepicker-duration { + color: #888; +} +.ui-timepicker-list li { + padding: 3px 0 3px 5px; + cursor: pointer; + white-space: nowrap; + color: #000; + list-style: none; + margin: 0; +} +.ui-timepicker-list:hover .ui-timepicker-selected { + background: #fff; + color: #000; +} +li.ui-timepicker-selected, +.ui-timepicker-list li:hover, +.ui-timepicker-list:hover .ui-timepicker-selected:hover { + background: #1980EC; + color: #fff; +} +li.ui-timepicker-selected .ui-timepicker-duration, +.ui-timepicker-list li:hover .ui-timepicker-duration { + color: #ccc; +} +/* Mobile only hidden unless overriden by media.css */ +.mobile-only { + display: none; +} +#dashboard-simple-datepicker.completed { + background-color: #f0efeb; +} +/* -----------[Widgets]--------------*/ +.widget { + background-color: #ffffff; + margin-bottom: 53px; +} +.widget .btn-download { + background-color: #63625e; + border: 1px solid #dcdbd7; + border-top: none; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + color: white; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; + display: block; + font-size: 18px; + height: 79px; + line-height: 80px; + text-align: center; + text-decoration: none; + width: 100%; +} +.widget .btn-download:hover { + background-color: #4f4e4a; +} +.widget .btn-download .caption { + display: inline-block; + vertical-align: super; +} +.widget .btn-download.no-border { + border: 0; +} +.widget .header { + background-color: #faf9f5; + border: 1px solid #dcdbd7; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + min-height: 80px; + height: auto; + width: 100%; +} +.widget .header a { + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; + display: block; + height: 100%; +} +.widget .header a:hover { + background-color: #ffffff; +} +.widget .header a { + color: #63625e; + text-decoration: none; +} +.widget .header .alert-red { + display: none; +} +.widget .header .title { + font-size: 21px; + padding-left: 20px; + padding-top: 20px; +} +.widget .header .sub-title { + padding-left: 20px; +} +.widget .header .sub-title ul li { + float: left; + margin-right: 35px; +} +.widget .header .sub-title ul li .caption { + margin-left: 10px; + vertical-align: super; +} +.widget .header .sub-title ul li .caption.blue { + color: #4790d0; +} +.widget .header .sub-title ul li .caption.orange { + color: #f7ab3e; +} +.widget .header .sub-title ul li .caption.gray { + color: #63625e; +} +.widget .header .sub-title ul li.toggled { + opacity: 0.4; + filter: alpha(opacity=40); +} +.widget .header .sub-title .caption { + vertical-align: super; +} +.widget .header.no-subtitle .title { + padding-top: 30px; +} +.widget .header.has-alarm { + position: relative; +} +.widget .header.has-alarm a { + color: #f35c58; + text-decoration: none; +} +.widget .header.has-alarm .alert-red { + position: absolute; + right: 20px; + top: 28px; +} +.widget .content { + border: 1px solid #dcdbd7; + border-top: none; +} +.widget .content .graph-container { + height: 255px; + padding: 50px 28px 25px 22px; +} +.widget .content .graph-container .date-range-triggered { + height: 235px !important; +} +.widget .content .jqplot-target .jqplot-yaxis { + color: #4790d0; +} +.widget .content .jqplot-target .jqplot-y2axis { + color: #f7ab3e; +} +.widget .content .blockMsg { + top: 156px !important; +} +.widget .bottom-graph { + background-color: #f0efeb; + height: 60px; + position: relative; + text-align: right; +} +.widget .bottom-graph .graph-links { + border-top: 1px solid #dcdbd7; + height: 100%; + position: absolute; + right: 0px; + top: -1px; +} +.widget .bottom-graph .graph-links li { + background-color: #63625e; + border: none; + border-bottom: 1px solid #dcdbd7; + border-top: 1px solid #dcdbd7; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + color: #e6e5e1; + cursor: pointer; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; + float: left; + height: 100%; + line-height: 62px; + margin-top: -1px; + outline: none; + text-align: center; +} +.widget .bottom-graph .graph-links li:last-child { + border-right: 1px solid #dcdbd7; +} +.widget .bottom-graph .graph-links li:first-child { + border-left: 1px solid #dcdbd7; +} +.widget .bottom-graph .graph-links li.selected { + background-color: #ffffff; + border-left: 1px solid #dcdbd7; + border-right: 1px solid #dcdbd7; + border-top-color: #ffffff; + color: #63625e; +} +.widget .bottom-graph .graph-links li.selected .divider .border { + -webkit-transition: 0s; + -moz-transition: 0s; + -o-transition: 0s; + transition: 0s; + background-color: transparent; +} +.widget .bottom-graph .graph-links li.selected + li .divider:first-child .border { + background-color: transparent; +} +.widget .bottom-graph .graph-links li:hover:not(.selected) { + background-color: #959490; +} +.widget .bottom-graph .graph-links li:hover:not(.selected) .divider .border { + background-color: #959490; +} +.widget .bottom-graph .graph-links li:hover + li .divider:first-child .border { + background-color: transparent; +} +.widget .bottom-graph .graph-links li .caption { + display: inline-block; + float: left; + height: 100%; + width: 98px; +} +.widget .bottom-graph .graph-links li .divider { + display: inline-block; + float: left; + height: 100%; + width: 0.5px; +} +.widget .bottom-graph .graph-links li .divider .border { + background-color: #4f4e4a; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; + height: 40px; + margin-top: 10px; +} +.widget.VRM_Widget_Alarm .inner-container { + padding: 0 20px !important; +} +.widget.VRM_Widget_Alarm .inner-container .column { + display: inline-block; + float: left; +} +.widget.VRM_Widget_Alarm .inner-container .column.left { + width: 65%; +} +.widget.VRM_Widget_Alarm .inner-container .column.right { + width: 35%; +} +.widget.VRM_Widget_Alarm .inner-container .column .duration { + color: #4790d0; +} +.widget.VRM_Widget_Status .content .widget-content-list .row:first-child, +.widget.VRM_Widget_Status .content .widget-content-list .row:nth-child(2) { + height: 117px; +} +.widget.VRM_Widget_Status .content .widget-content-list .row:last-child { + border-bottom: none; +} +.widget.VRM_Widget_Status .content .widget-content-list .row .inner-container .label { + padding-bottom: 5px; +} +.widget.VRM_Widget_Status .content .widget-content-list .row .inner-container .value .column { + text-align: right; +} +.widget.VRM_Widget_HistoricData .content .widget-content-list .row:last-child { + border-bottom: none; +} +.widget.VRM_Widget_GPSWidget .widget-map { + height: 236px; + width: 100%; +} +.widget.VRM_Widget_VeConfigure .content { + height: 316px !important; +} +.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expand-trigger:hover:not(.expanded) { + background-color: #e6e5e1; + cursor: pointer; +} +.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expandable-section { + background-color: #e6e5e1; + border-bottom: none; + display: none; + height: 236px; + position: relative; +} +.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expandable-section .inner-container .close-container { + margin-bottom: 12px; + margin-top: -3px; + text-align: right; +} +.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expandable-section .inner-container .close-container ul { + cursor: pointer; + display: inline-block; +} +.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expandable-section .inner-container .close-container ul li { + display: inline-block; +} +.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expandable-section .inner-container .close-container ul:hover .caption { + text-decoration: underline; +} +.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expandable-section .inner-container .close-container .caption { + padding-top: 2px; + vertical-align: top; +} +.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expandable-section .inner-container .button-container { + bottom: 10px; + left: 10px; + position: absolute; + width: 100%; +} +.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expandable-section .inner-container .button-container .filename { + display: none; +} +.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expandable-section .inner-container .button-container input[type="button"] { + width: 134px; +} +.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expandable-section .inner-container .button-container input[type="button"]:first-child { + margin-right: 6px; +} +.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expandable-section .inner-container .button-container .file-wrapper input[type="file"] { + opacity: 0; + filter: alpha(opacity=0); + left: -10000px; + position: absolute; +} +.widget.VRM_Widget_VeConfigure .content .widget-content-list .row.expandable-section .inner-container .button-container #upload { + display: none; +} +.widget.VRM_Widget_State .content .graph-container, +.widget.VRM_Widget_VeBusWarningsAndAlarms .content .graph-container { + height: 310px; + padding: 40px 48px 0px 35px; +} +.widget.VRM_Widget_State .content .graph-container .jqplot-target, +.widget.VRM_Widget_VeBusWarningsAndAlarms .content .graph-container .jqplot-target { + height: 260px !important; +} +.widget.VRM_Widget_State .state-legend, +.widget.VRM_Widget_VeBusWarningsAndAlarms .state-legend { + background-color: #e6e5e1; + border: 1px solid #dcdbd7; + border-top: none; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + *zoom: 1; + color: #959490; + display: none; + font-size: 11px; + min-height: 60px; + padding: 20px 34px; +} +.widget.VRM_Widget_State .state-legend:before, +.widget.VRM_Widget_VeBusWarningsAndAlarms .state-legend:before, +.widget.VRM_Widget_State .state-legend:after, +.widget.VRM_Widget_VeBusWarningsAndAlarms .state-legend:after { + display: table; + content: ""; + line-height: 0; +} +.widget.VRM_Widget_State .state-legend:after, +.widget.VRM_Widget_VeBusWarningsAndAlarms .state-legend:after { + clear: both; +} +.widget.VRM_Widget_State .state-legend ul li, +.widget.VRM_Widget_VeBusWarningsAndAlarms .state-legend ul li { + float: left; + margin-right: 15px; +} +.widget.VRM_Widget_State .state-legend ul li .abbreviation, +.widget.VRM_Widget_VeBusWarningsAndAlarms .state-legend ul li .abbreviation { + color: #387dc5; + margin-right: 7px; +} +.widget.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section { + border-bottom: none; + height: 395px; + position: relative; +} +.widget.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section .inner-container .close-container { + margin-bottom: 12px; + margin-top: -3px; + text-align: right; +} +.widget.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section .inner-container .close-container ul { + cursor: pointer; + display: inline-block; +} +.widget.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section .inner-container .close-container ul li { + display: inline-block; +} +.widget.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section .inner-container .close-container ul:hover .caption { + text-decoration: underline; +} +.widget.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section .inner-container .close-container .caption { + padding-top: 2px; + vertical-align: top; +} +.widget.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section .inner-container .button-container { + bottom: 10px; + left: 10px; + position: absolute; + width: 100%; +} +.widget.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section .inner-container .button-container .filename { + display: none; +} +.widget.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section .inner-container .button-container input[type="button"] { + width: 134px; +} +.widget.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section .inner-container .button-container input[type="button"]:first-child { + margin-right: 6px; +} +.widget.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section .inner-container .button-container .file-wrapper input[type="file"] { + opacity: 0; + filter: alpha(opacity=0); + left: -10000px; + position: absolute; +} +.widget.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section .inner-container .button-container #upload { + display: none; +} +.widget.VRM_Widget_PVInverterStatus .content .widget-content-list .row { + height: 98px !important; +} +.widget.VRM_Widget_PVInverterStatus .content .widget-content-list .row:last-child { + border-bottom: none; +} +.widget.list .content { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + height: 395px; + overflow: hidden; + padding-right: 0px !important; + width: 100%; +} +.widget.list .content .widget-content-list .row { + border-bottom: 1px solid #dcdbd7; + height: 78px; + overflow: hidden; +} +.widget.list .content .widget-content-list .row .floater { + height: 50%; +} +.widget.list .content .widget-content-list .row .inner-container { + padding: 20px 20px; +} +.widget.list .content .widget-content-list .row .inner-container .label { + font-size: 18px; +} +.widget.list .content .widget-content-list .row .inner-container .label .duration { + color: #387dc5; +} +.widget.list .content .widget-content-list .row .inner-container .value { + color: #387dc5; +} +.widget.list .content .widget-content-list .row .inner-container .value .column { + float: left; + width: 33%; +} +.widget.list .content .widget-content-list .row .inner-container .value .right { + color: #f0962e; +} +.widget.list .content .widget-content-list .row .inner-container .value .voltage { + color: #387dc5; +} +.widget.list .content .widget-content-list .row .inner-container .value .current { + color: #f0962e; +} +.widget.list .content .widget-content-list .row .inner-container .value .olddata { + color: #f35c58; +} +.widget.list .content .widget-content-list .row .inner-container .datetime.alarm { + color: #f35c58; +} +.widget.list .content .widget-content-list .row.no-border-bottom { + border-bottom: none; +} +.widget.list .content.ps-active-y .ps-scrollbar-y-rail, +.widget.list .content.ps-active-y .ps-scrollbar-y-rail:hover, +.widget.list .content.ps-active-y.ps-container:hover .ps-scrollbar-y-rail { + opacity: 1; + filter: alpha(opacity=100); +} +.widget.list .content.ps-active-y.ps-container:hover .ps-scrollbar-y .row.handle { + background-color: #64635f; +} +.widget.list .content.ps-active-y.ps-container:hover .ps-scrollbar-y-rail { + background-color: #f0efeb; + border: 1px solid #dcdbd7; +} +.widget.list .content.ps-active-y .ps-scrollbar-y-rail { + background-color: rgba(240, 239, 235, 0.5); + border: 1px solid rgba(220, 219, 215, 0.5); + right: 10px !important; + margin-top: 10px; + margin-bottom: 10px; +} +.widget.list .content.ps-active-y .ps-scrollbar-y-rail .ps-scrollbar-y { + background-color: transparent; + display: table; + margin-top: -10px; +} +.widget.list .content.ps-active-y .ps-scrollbar-y-rail .ps-scrollbar-y .row { + display: table-row; +} +.widget.list .content.ps-active-y .ps-scrollbar-y-rail .ps-scrollbar-y .row .transparent-edge { + background-color: transparent; + display: table-cell; + height: 10px; + width: 100%; +} +.widget.list .content.ps-active-y .ps-scrollbar-y-rail .ps-scrollbar-y .row.handle { + background-color: #969591; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + cursor: pointer; + display: table-cell; + opacity: 1 !important; + filter: alpha(opacity=100) !important; + -webkit-transition: background-color 0.2s linear; + -moz-transition: background-color 0.2s linear; + -o-transition: background-color 0.2s linear; + transition: background-color 0.2s linear; +} +.widget.list .content.ps-active-y .ps-scrollbar-y-rail .ps-scrollbar-y .row .handle { + width: 8px; +} +/* -----------[jQuery Tags Plugin]--------------*/ +div.tagsinput { + border: 1px solid #e5e4e0; + background: #ffffff; + padding: 5px; + overflow-y: auto; +} +div.tagsinput span.tag { + display: block; + float: left; + text-decoration: none; + margin-right: 5px; + margin-bottom: 5px; + margin-top: 0px; +} +div.tagsinput span.tag a { + font-size: 0; +} +div.tagsinput input { + width: 80px !important; + margin: 0px; + border: 1px solid transparent; + padding: 5px; + background: transparent; + font-size: 15px; + color: #272622; + outline: 0px; + margin-right: 5px; + margin-bottom: 5px; + min-height: 40px; + margin-top: 0px; +} +div.tagsinput div { + display: block; + float: left; +} +div.tagsinput .tags_clear { + clear: both; + width: 100%; + height: 0px; +} +div.tagsinput .not_valid { + background: #fa716f !important; + color: #ffffff !important; +} +.VRM_Widget_CCGXDataUpload { + line-height: 19px; +} +.VRM_Widget_CCGXDataUpload .text { + border-bottom: 1px solid #dcdbd7; +} +.VRM_Widget_CCGXDataUpload .text:last-child { + border: none; +} +.VRM_Widget_CCGXDataUpload #ccgx-upload, +.VRM_Widget_CCGXDataUpload #inserted-file, +.VRM_Widget_CCGXDataUpload #ccgx-fileinput { + display: none; +} +.VRM_Widget_CCGXDataUpload .filename { + cursor: pointer; +} +.VRM_Widget_CCGXDataUpload .filename li { + float: left; + margin: 0 5px; +} +.VRM_Widget_CCGXDataUpload .filename .caption { + max-width: 210px; + overflow: hidden; + text-overflow: ellipsis; + padding: 3px 0 0 0; +} +.VRM_Widget_CCGXDataUpload .content { + overflow: visible !important; +} +.VRM_Widget_CCGXDataUpload .content .widget-content-list .row.expandable-section { + height: 316px !important; +} +.VRM_Widget_CCGXDataUpload #inserted-file { + margin: 10px 0 0 0; +} +.VRM_Widget_CCGXDataUpload .insert-ccgx-file { + background-color: #63625e; + border: 1px solid #63625e; + border-top: none; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + color: white; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; + display: block; + font-size: 18px; + height: 79px; + line-height: 80px; + text-align: center; + text-decoration: none; + width: 100%; +} +.VRM_Widget_CCGXDataUpload .insert-ccgx-file:hover { + background-color: #4f4e4a; +} +.VRM_Widget_CCGXDataUpload .insert-ccgx-file .caption { + display: inline-block; + vertical-align: super; +} +.VRM_Widget_CCGXDataUpload .insert-ccgx-file .inverted { + -webkit-transform: rotate(180deg); + /* Opera, Chrome, and Safari */ + -ms-transform: rotate(180deg); + /* IE 9 */ + transform: rotate(180deg); +} +.leaflet-control-container .leaflet-bottom.leaflet-right { + z-index: 3; +} +.leaflet-marker-text { + margin-top: -5px; + color: #4790d0; + font-size: 21px; + font-family: Arial, sans-serif; + font-weight: bold; + font-style: normal; + text-decoration: none; + text-align: center; + line-height: 64px; +} +.leaflet-marker-text-red { + color: #fa716f; +} +.icon-pointer-blue-empty { + display: inline-block; + width: 75px; + height: 64px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -472px 0px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .icon-pointer-blue-empty { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.icon-pointer-red-empty { + display: inline-block; + width: 75px; + height: 64px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -547px 0px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .icon-pointer-red-empty { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +body.map-none .map-view { + height: 65px; + background-color: rgba(99, 98, 94, 0.1); +} +body.map-none .map-view .top-shadow, +body.map-none .map-view .bottom-shadow { + display: none; +} +body.map-none.embedded .breadcrumb { + background-color: #E6E5E1; +} +body.map-none.embedded #vrm-tabs { + right: 0; +} +body.map-none.embedded #vrm-tabs li.active { + border-top: 1px solid #dcdbd7; + border-left: 1px solid #dcdbd7; + border-right: 1px solid #dcdbd7; +} +#updateForm img.gravatar, +#updateGravatarForm img.gravatar { + height: 80px; + width: 80px; + -webkit-border-radius: 50%; + -moz-border-radius: 50%; + border-radius: 50%; +} +#updateForm div.gravatar-wrapper, +#updateGravatarForm div.gravatar-wrapper { + height: 80px; + width: 80px; + position: relative; + text-align: center; + vertical-align: middle; + color: #4790d0; + text-transform: uppercase; + font-size: 14px; + line-height: 80px; + border: none !important; + -webkit-border-radius: 50%; + -moz-border-radius: 50%; + border-radius: 50%; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; +} +#updateForm div.gravatar-wrapper img.gravatar, +#updateGravatarForm div.gravatar-wrapper img.gravatar { + position: absolute !important; + top: 0 !important; + left: 0 !important; + height: 78px !important; + width: 78px !important; + float: none !important; + margin: 0 !important; + border-width: 1px !important; + border-style: solid !important; + border-color: #dcdbd7; + background: none !important; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; +} +#updateForm img.gravatar, +#updateGravatarForm img.gravatar, +#updateForm div.gravatar-wrapper img.gravatar, +#updateGravatarForm div.gravatar-wrapper img.gravatar, +#updateForm div.gravatar-wrapper, +#updateGravatarForm div.gravatar-wrapper { + margin-bottom: 20px; + display: inline-block; +} +#updateForm .change-gravatar, +#updateGravatarForm .change-gravatar { + float: right; + margin-top: 23px; +} +#updateGravatarForm { + display: none; +} +#updateGravatarForm .gravatar-file-upload { + cursor: pointer; +} +#updateGravatarForm .gravatar-file-upload .sprite-icons { + position: absolute; +} +#updateGravatarForm .gravatar-upload-label { + margin: 2px 0 2px 40px; + display: inline-block; +} +.user.update .form-tabs.profile, +.user.two-step-update .form-tabs.profile, +.user.two-step-new .form-tabs.profile, +.user.two-step-verify .form-tabs.profile, +.user.two-step-done .form-tabs.profile, +.user.update-dealer .form-tabs.profile { + margin-top: 0px; +} +/* need new section for styling settings alarms form */ +#forms-container-alarms-settings label { + line-height: 44px; +} +#forms-container-alarms-settings label[class="required"]:after { + content: "*"; + color: #4790d0; +} +#forms-container-alarms-settings .custom-radio label { + line-height: 21px; +} +#forms-container-alarms-settings .settings-alarm-header { + background-color: #faf9f5; + border: 1px solid #dcdbd7; + padding: 19px; +} +#forms-container-alarms-settings .settings-alarm-toggle { + border-top: 1px solid #f0efeb; + cursor: pointer; + position: relative; +} +#forms-container-alarms-settings .settings-alarm-toggle.one-line { + padding: 19px 45px 19px 80px; +} +#forms-container-alarms-settings .settings-alarm-toggle.two-lines { + padding: 8px 45px 8px 80px; +} +#forms-container-alarms-settings .settings-alarm-toggle.has-error:first-child::before { + position: absolute; + top: 18px; + left: -35px; + content: ' '; + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -48px -192px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + #forms-container-alarms-settings .settings-alarm-toggle.has-error:first-child::before { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +#forms-container-alarms-settings .settings-alarm-toggle .device-name { + font-size: 18px; +} +#forms-container-alarms-settings .settings-alarm-toggle .alarm-name { + display: block; + color: #4790d0; + font-size: 15px; +} +#forms-container-alarms-settings .settings-alarm-toggle .alarm-name.gray, +#forms-container-alarms-settings .settings-alarm-toggle .alarm-name .gray { + color: #63625e; +} +#forms-container-alarms-settings .settings-alarm-toggle .toggle-icon { + position: absolute; + right: 20px; + top: 18px; +} +#forms-container-alarms-settings .settings-alarm-toggle .device-icon { + position: absolute; + left: 18px; + top: 7px; +} +#forms-container-alarms-settings .settings-alarm-group { + border: 1px solid #dcdbd7; + background-color: #faf9f5; + border-top: 0; + border-bottom: 0; +} +#forms-container-alarms-settings .settings-alarm-group li.has-alarm-error { + border-left: 3px solid #fa716f; +} +#forms-container-alarms-settings .settings-alarm-group:first-child { + border-top: 1px solid #dcdbd7; +} +#forms-container-alarms-settings .settings-alarm-group:first-child .settings-alarm-toggle:first-child { + border-top: 0; +} +#forms-container-alarms-settings .settings-alarm-group .settings-alarm-toggle .icon-toggle { + background: url('/img/icon/icon-open.png') center center no-repeat; +} +#forms-container-alarms-settings .settings-alarm-group.active { + background-color: #ffffff; +} +#forms-container-alarms-settings .settings-alarm-group.active .settings-alarm-toggle { + border-bottom: 1px solid #f0efeb; +} +#forms-container-alarms-settings .settings-alarm-group.active .settings-alarm-toggle .icon-toggle { + background: url('/img/icon/icon-close.png') center center no-repeat; +} +#forms-container-alarms-settings .settings-alarm-group.below-alarms-fieldset-element { + border-top: 1px solid #f0efeb; + border-bottom: 1px solid #dcdbd7; + min-height: 60px; +} +#forms-container-alarms-settings .settings-alarm-group.below-alarms-fieldset-element a { + line-height: 60px; + margin-left: 80px; +} +#forms-container-alarms-settings .settings-alarm-group li:last-child { + margin-bottom: 19px; +} +#forms-container-alarms-settings .settings-alarm-description { + padding: 19px 19px 19px 80px; + display: none; +} +#forms-container-alarms-settings .settings-alarm-element { + padding: 19px 19px 0px 80px; + width: 240px; + float: left; + display: none; +} +#forms-container-alarms-settings .settings-alarm-element.has-error input[type="text"], +#forms-container-alarms-settings .settings-alarm-element.has-error input[type="email"], +#forms-container-alarms-settings .settings-alarm-element.has-error input[type="password"], +#forms-container-alarms-settings .settings-alarm-element.has-error input[type="tel"], +#forms-container-alarms-settings .settings-alarm-element.has-error input[type="url"], +#forms-container-alarms-settings .settings-alarm-element.has-error textarea { + border-color: #fa716f; + color: #fa716f; +} +#forms-container-alarms-settings .settings-alarm-element ul.errors li { + color: #fa716f; +} +#forms-container-alarms-settings .settings-alarm-delete { + width: 100%; +} +#forms-container-alarms-settings .settings-alarm-element:nth-child(even) { + padding: 19px 19px 0 19px; +} +#forms-container-alarms-settings .settings-alarm-toggle .settings-alarm-element:nth-child(even) { + padding: 19px 19px 0 19px; +} +#forms-container-alarms-settings .settings-alarm-toggle.no-description ~ .settings-alarm-element:nth-child(even) { + padding: 19px 19px 0 80px; +} +#forms-container-alarms-settings .settings-alarm-toggle.no-description ~ .settings-alarm-element:nth-child(odd) { + padding: 19px 19px 0 19px; +} +#forms-container-alarms-settings .settings-alarm-element:nth-child(2) { + padding-top: 5px; +} +.VRM_Widget_SiteSummary { + color: #63625e; +} +/* -----------[Screensave]--------------*/ +.screensaver { + background-color: #272622; + height: 100%; + left: 0; + position: fixed; + top: 0; + visibility: hidden; + width: 100%; + z-index: 10000; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; + opacity: 0; + filter: alpha(opacity=0); +} +.screensaver.visible { + visibility: visible; + opacity: 1; + filter: alpha(opacity=100); +} +.screensaver.on-solar .screensaver-text { + color: #f7ab3e; +} +.screensaver.on-solar .screensaver-icon:before { + color: #f7ab3e; + content: '\e603'; +} +.screensaver.on-generator .screensaver-text { + color: #4790d0; +} +.screensaver.on-generator .screensaver-icon:before { + margin-left: -50%; + color: #4790d0; + content: '\e600'; +} +.screensaver.on-battery .screensaver-text { + color: #4790d0; +} +.screensaver.on-battery .screensaver-icon:before { + color: #4790d0; + content: '\e601'; +} +.screensaver.on-grid .screensaver-text { + color: #8bc964; +} +.screensaver.on-grid .screensaver-icon:before { + color: #8bc964; + content: '\e602'; +} +.screensaver-icon { + left: 50%; + position: absolute; + top: 50%; +} +.screensaver-icon:before { + font-family: 'screensaver-icons'; + margin-top: 60%; + position: absolute; +} +.screensaver-text { + left: 50%; + position: absolute; + text-transform: uppercase; + top: 50%; +} +.screensaver-text-grid-type { + color: #ffffff; + font-family: 'MuseoSans-700'; +} +.screensaver-company-logo { + bottom: 0; + position: absolute; + right: 0; +} +.screensaver-company-logo img { + height: 100%; + width: 100%; +} +.whitelabel-active .screensaver-company-logo { + display: none; +} +.beta-badge { + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + display: inline-block; + font-size: 13px; + line-height: 11px; + min-width: 50px; + min-height: 20px; + padding-top: 5px; + text-decoration: none; + text-align: center; + background-color: #f7ab3e; + color: #ffffff; + top: -2px; + position: relative; + margin-left: 10px; +} +/* -----------[Modal popups]--------------*/ +.modal-popup-container { + background-color: #ffffff; + border: 1px solid #e5e4e0; + margin: 20px auto; + max-width: 560px; + padding: 20px 0; + position: relative; + width: auto; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +#modal-popup-container-share #guest-account-content { + margin-bottom: 25px; + margin-top: 25px; +} +#modal-popup-container-share #guest-account-content .modal-popup-content-row, +#modal-popup-container-share #guest-account-content .modal-popup-content-row-divider { + overflow: hidden; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; +} +#modal-popup-container-share #guest-account-content .modal-popup-content-row:not(.visible), +#modal-popup-container-share #guest-account-content .modal-popup-content-row-divider:not(.visible) { + height: 0; + min-height: 0; + margin: 0; + padding: 0; +} +#modal-popup-container-share #guest-account-content .modal-popup-content-left-right-container { + min-height: 50px; +} +#modal-popup-container-share #guest-account-content .modal-popup-content-left-right-container .modal-popup-content-left-max { + line-height: 40px; +} +#modal-popup-container-share #guest-account-content .modal-popup-content-left-right-container .modal-popup-content-left-max input { + line-height: 10px; +} +#modal-popup-container-share #guest-account-content .modal-popup-content-left-right-container .modal-popup-content-left-max input::-webkit-input-placeholder { + line-height: normal; +} +#modal-popup-container-share #invite-user-content { + margin-top: 30px; +} +#modal-popup-container-share #invite-user-content .modal-popup-content-left-max input, +#modal-popup-container-share #invite-user-content .modal-popup-content-left-max textarea { + margin-bottom: 10px; +} +#modal-popup-container-share .invite-user-message { + margin-top: 5px; +} +.modal-popup-content { + padding: 0 49px; +} +.modal-popup-content h1 { + margin-bottom: 21px; + margin-top: 28px; +} +.modal-popup-tab-content.hidden { + display: none; +} +.modal-popup-tabs-list { + margin-bottom: -1px; +} +.modal-popup-tabs-item { + cursor: pointer; + float: left; + font-size: 18px; + margin-right: 20px; + padding-bottom: 3px; + padding-right: 10px; +} +.modal-popup-tabs-item:hover { + border-bottom: 1px solid #4790d0; +} +.modal-popup-tabs-item.selected { + border-bottom: 2px solid #4790d0; + color: #4790d0; + cursor: default; +} +.modal-popup-tabs-container { + border-bottom: 1px solid #e5e4e0; +} +.modal-popup-content-full-width { + margin-bottom: 10px; +} +.modal-popup-content-left-right-container { + position: relative; +} +.modal-popup-content-left-right-container.password-container { + height: 0; + min-height: 0 !important; + overflow: hidden; + -webkit-transition: 0.2s; + -moz-transition: 0.2s; + -o-transition: 0.2s; + transition: 0.2s; +} +.modal-popup-content-left-right-container.password-container.visible { + height: 62px; +} +.modal-popup-content-left-right-container.renew-container .modal-popup-content-left-max { + height: 40px; + line-height: 40px; +} +.modal-popup-content-left-max { + padding-right: 90px; +} +.modal-popup-content-left-max input, +.modal-popup-content-left-max textarea { + margin-bottom: 5px; + width: 100%; +} +.modal-popup-content-right-control { + position: absolute; + right: 0; + top: 0; + width: 80px; +} +.modal-popup-content-right-control .custom-toggle.slide-colors { + margin-top: 5px; +} +.modal-popup-content-right-control input { + width: 100%; +} +.modal-popup-content-right-control.completed:before { + content: ''; + left: 28px; + position: absolute; + top: 9px; + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: 0px -216px; +} +@media print, (-webkit-min-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 3/2), (min--moz-device-pixel-ratio: 1.25), (-moz-min-device-pixel-ratio: 1.25), (-ms-min-device-pixel-ratio: 1.25), (min-device-pixel-ratio: 1.25), (min-resolution: 120dpi), (min-resolution: 1.25dppx) { + .modal-popup-content-right-control.completed:before { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +.modal-popup-content-row-divider { + background-color: #dcdbd7; + height: 1px; + margin-bottom: 15px; + margin-top: 15px; +} +.modal-popup-bottom-button-row { + padding-bottom: 29px; +} +.modal-popup-bottom-button-row .btn { + margin-top: 5px; +} +.modal-popup-bottom-button-row a { + margin-top: 16px; +} +.loading-spinner { + background-image: url('/img/loader-circle.gif'); + background-repeat: no-repeat; + background-position: center center; +} +#forms-container-system-overview .btn.site-diagnostics { + margin-right: 20px; +} +/* -----------[Remote Console]--------------*/ +.remote-console-trigger { + float: right; +} +#vrm-tabs-content #remoteConsoleButton { + margin-top: 10px; +} +.remote-console-popup-container { + background-color: #faf9f5; + border: none; + max-width: 783px; + overflow: hidden; + padding: 0; + position: relative; + width: 620px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +.remote-console-popup-container.password-needed .remote-console-login { + display: block; +} +.remote-console-popup-container.password-needed .remote-console-status { + display: none; +} +.remote-console-popup-container.password-needed .remote-console-logged-in { + display: none; +} +.remote-console-popup-container.password-needed .mfp-close { + color: #faf9f5; +} +.remote-console-popup-container.logged-in { + width: 783px; + /* This is needed to prevent the canvas becoming tiny on some occasions.. */ +} +.remote-console-popup-container.logged-in .remote-console-login { + display: none; +} +.remote-console-popup-container.logged-in .remote-console-status { + display: none; +} +.remote-console-popup-container.logged-in .remote-console-logged-in { + display: block; +} +.remote-console-popup-container.logged-in #remote-console-canvas { + height: 100% !important; + width: 100% !important; +} +.remote-console-popup-container.logged-in .mfp-close { + color: #faf9f5; +} +.remote-console-popup-container .mfp-close { + color: #4790d0; +} +.remote-console-login { + display: none; + height: 312px; + padding-right: 240px; +} +.remote-console-login .remote-console-display-container { + height: 100%; + text-align: center; + width: 100%; +} +.remote-console-login .remote-console-controls-container { + width: 240px; +} +.remote-console-login .remote-console-controls-title { + margin-top: 92px; + text-align: left; +} +.remote-console-status { + text-align: center; + height: 312px; +} +.remote-console-status.notification .remote-console-login-icon.notification { + display: inline-block; +} +.remote-console-status.alarm .remote-console-login-icon.alarm { + display: inline-block; +} +.remote-console-status .remote-console-login-icon { + display: none; +} +.remote-console-status .remote-console-login-icon.alarm { + fill: #fa716f; +} +.remote-console-status .remote-console-login-icon.alarm path { + fill: #fa716f !important; +} +.remote-console-status .remote-console-login-title { + margin-bottom: 10px; +} +.remote-console-status-content { + margin-top: -50px; + position: absolute; + top: 50%; + width: 100%; +} +.remote-console-logged-in { + display: none; +} +.remote-console-login-contents { + display: inline-block; + margin: 0 auto; + padding-top: 41px; + text-align: center; +} +.remote-console-login-icon { + display: inline-block; + height: 32px; + width: 32px; +} +.remote-console-login-icon path { + fill: #4790d0 !important; +} +.remote-console-login-title { + font-family: 'MuseoSans-700'; + margin-bottom: 37px; + margin-top: 11px; +} +.remote-console-login-fields-container { + text-align: left; +} +.remote-console-login-fields { + margin-top: 4px; +} +#remote-console-password { + margin-right: 5px; + width: 174px; +} +#remote-console-login { + line-height: 16px; +} +#remote-console-login .svg { + fill: #faf9f5; + height: 16px; + width: 16px; +} +.custom-check-and-radio { + margin-top: 20px; +} +.remote-console-title { + color: #4790d0; + display: none; + font-family: 'MuseoSans-700'; + margin-bottom: 0; + margin-top: 20px; + padding-left: 20px; +} +.remote-console-display-container { + display: table; +} +.remote-console-display { + background-color: #faf9f5; + padding: 20px; +} +.remote-console-display-inner { + position: relative; + border: 1px solid #e5e4e0; + height: 272px; + width: 480px; +} +.remote-console-display-inner .remote-console-status-text { + position: absolute; + top: 40%; + left: 0; + width: 100%; + text-align: center; + z-index: 9999; + color: #959490; +} +.remote-console-controls-container { + background-color: #4790d0; + height: 100%; + position: absolute; + right: 0; + top: 0; + width: 262px; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-user-select: none +} +.remote-console-controls-text { + padding-left: 20px; + padding-right: 20px; +} +.remote-console-controls-title { + margin-bottom: 0; + margin-top: 33px; +} +.remote-console-controls-subtitle { + line-height: 21px; + margin-top: 4px; +} +.remote-console-controls-explanation { + color: #f3f2ee; + line-height: 21px; + margin-top: 23px; +} +.remote-console-controls-title, +.remote-console-controls-subtitle { + color: #f3f2ee; + text-align: center; +} +.remote-console-controls { + bottom: 0; + height: 187px; + left: 0; + padding-bottom: 25px; + padding-top: 25px; + position: absolute; + width: 100%; +} +.remote-console-controls-row { + padding-bottom: 5px; + padding-top: 5px; + text-align: center; +} +.remote-console-controls-row:first-child { + /*margin-bottom: 20px;*/ +} +.remote-console-control-button { + cursor: pointer; + height: 40px; + margin-left: 3px; + margin-right: 3px; + padding: 0; + position: relative; + width: 40px; +} +.remote-console-control-button.wide { + width: 65px; +} +.remote-console-control-button.extra-wide { + width: 140px; +} +.remote-console-control-button .remote-console-control-icon { + color: #4790d0; + display: inline-block; + fill: #4790d0; + font-size: 17px; + height: 16px; + line-height: 20px; + margin-top: 11px; + width: 16px; +} +.remote-console-control-button .remote-console-control-icon.text { + left: 19px; + position: absolute; + top: -3px; + width: auto; +} +.remote-console-control-button .remote-console-control-icon path { + fill: #4790d0; +} +.remote-console-rotate-message-container { + background-color: #e5e4e0; + display: none; + height: 100%; + position: fixed; + top: 0; + width: 100%; + z-index: 100000; +} +.rotate-message-contents { + margin-top: -66px; + position: absolute; + text-align: center; + top: 50%; + width: 100%; +} +.rotate-message-icon { + display: inline-block; + height: 72px; + margin-bottom: 20px; + width: 72px; +} +.rotate-message-icon path { + fill: #4790d0; +} +.rotate-message-title { + font-family: 'MuseoSans-700'; + margin: 0; +} +#privateShareButtonMobile, +#remoteConsoleButtonMobile { + background-color: #8bc964; +} +#privateShareButtonMobile:hover, +#remoteConsoleButtonMobile:hover { + background-color: #72b84c; +} +/* -----------[Media queries for desktop]--------------*/ +@media screen and (min-width: 960px) { + .hide-desktop { + display: none; + } +} +/* -----------[Media queries for mobile/responsive]--------------*/ +@media screen and (max-width: 959px) { + .hide-responsive { + display: none; + } + .site-overview-controls .container-inner .grid-item.five-columns-width, + .site-overview-controls .container-inner .grid-item.six-columns-width, + .site-overview-controls .container-inner .grid-item.seven-columns-width, + .site-overview-controls .container-inner .grid-item.eight-columns-width, + .site-overview-controls .container-inner .grid-item.nine-columns-width, + .site-overview-controls .container-inner .grid-item.ten-columns-width, + .site-overview-controls .container-inner .grid-item.eleven-columns-width, + .site-overview-controls .container-inner .grid-item.twelve-columns-width { + margin-left: 10px; + margin-right: 10px; + width: 300px; + } + .site-overview-controls .container-inner .grid-item.view-toggle .view-toggle-container { + display: none; + } + .this-is-the-homepage { + display: none; + } + .vrm-date-range-selection { + margin-top: 40px; + } + .date-range-selectors { + height: 65px; + } + .date-range-selectors .current, + .date-range-selectors .previous { + display: none; + } + .date-range-selectors-advanced { + margin-bottom: 4px; + } + .date-range-selectors-advanced .section { + margin-bottom: 7px; + margin-left: 0px; + width: 100%; + } + .date-range-selectors-advanced .section .mobile-caption { + display: inline-block; + float: left; + line-height: 54px; + } + .date-range-selectors-advanced .section .vrm-date-time-picker { + float: right; + } + .date-range-selectors-advanced .section .vrm-date-time-picker .picker { + left: -80px; + } + .date-range-selectors-advanced .section.set-time { + display: none; + height: 0px; + margin-bottom: 11px; + } + .date-range-selectors-advanced .section.set-time .btn { + float: left; + } + .date-range-selectors .selector-list > li:first-child { + float: left; + } + .date-range-selectors .selector-list > li:last-child { + float: right; + } + .date-range-selectors .selector-list > li, + .date-range-selectors-advanced .selector-list > li { + margin-left: 0px; + } + .date-range-selectors .custom_date_selector_container, + .date-range-selectors-advanced .custom_date_selector_container { + float: left; + padding-left: 0px; + } + .picker { + width: 300px; + } + #alarms { + display: none; + } + #mobile-alarms { + display: block; + } + #mobile-alarms .alarmCleared, + #mobile-alarms .alarmState { + text-align: right; + } + #mobile-alarms tbody tr td { + border-bottom: 0px; + padding-bottom: 0px; + } + #mobile-alarms tbody tr:nth-child(3n) td { + border-bottom: 1px solid #dcdbd7; + padding-top: 0px; + padding-bottom: 18px; + width: 320px; + } + #mobile-alarms tbody tr:nth-child(3n) td .alarmCleared { + float: right; + } + .pagination .previous, + .pagination .next { + display: none; + } + .pagination ul li { + padding: 7px; + } + .container.site-overview-content { + margin-bottom: 40px; + } + .container .container-inner { + width: 320px; + } + .container .container-inner .secondary-controls { + display: none; + } + .container .container-inner .grid-item.eight-columns-width, + .container .container-inner .grid-item.twelve-columns-width { + margin-left: 10px; + margin-right: 10px; + width: 300px; + } + .container .container-inner .grid-item.offset-four { + margin-left: 10px; + } + .container .container-inner .over-google-map { + position: relative; + top: 0px; + } + .container .container-inner .tab-select { + display: block; + margin-top: 14px; + } + .container.top-menu { + display: none; + } + .container.breadcrumb { + background-color: #e6e5e1; + } + .container.breadcrumb .buttons-container { + display: none; + } + .container.breadcrumb .btn { + display: none; + } + .container.breadcrumb .site-select { + display: none; + } + .container.breadcrumb .breadcrumb-site-title { + display: block; + } + .container .breadcrumb-buttons-container { + padding-bottom: 12px; + } + .vrm.site.index .container.breadcrumb + .clearfix { + display: none; + } + .container.sites-statistics { + background-color: #f0efeb; + border-bottom: 1px solid #dcdbd7; + color: #959490; + display: block; + height: 80px; + } + .container.sites-statistics .grid-item { + float: none; + } + .container.sites-statistics .results .total { + padding-left: 20px; + } + .container.sites-statistics .results .alarms { + color: #f35c58; + } + .container.map-view { + display: none; + } + .container.map-overview .map { + height: 230px; + width: 100%; + } + .container.site-overview { + padding-top: 15px; + } + .container.site-view .container-inner #vrm-tabs { + display: none; + } + .container #vrm-tabs-content .tab-pane#advanced .section-heading { + margin: 35px 0 7px 0; + } + .container #vrm-tabs-content .tab-pane#advanced .download-data-container { + position: static; + top: 0; + left: 0; + float: left; + margin-bottom: 14px; + padding-left: 24px; + max-height: none; + } + .container #vrm-tabs-content .tab-pane#advanced .download-data-container .download-blue { + float: left; + } + .container #vrm-tabs-content .tab-pane#advanced .download-data-container .link-text { + float: right; + clear: right; + width: 145px; + padding: 0; + } + .container #vrm-tabs-content .tab-pane .content .last-update-info { + margin-bottom: 8px; + padding-right: 0px; + position: relative; + top: 0px; + } + .container #vrm-tabs-content .tab-pane .content .last-update-info > span:first-child { + padding-left: 27px; + } + .container #vrm-tabs-content .tab-pane .content .last-update-info .pull-right { + float: left; + } + .container #vrm-tabs-content .tab-pane .content .last-update-info .sprite-icons { + left: 0px; + position: absolute; + } + .container #vrm-tabs-content .tab-pane .content .section-heading > span, + .container #vrm-tabs-content .tab-pane .content .section-heading h2 { + display: none; + } + .container #vrm-tabs-content .tab-pane .content .mobile-graph-refresh { + display: inline-block; + width: 300px; + margin: 10px; + } + .container #vrm-tabs-content .tab-pane .content .progress-meters-container { + height: auto; + margin-bottom: 40px; + } + .container #vrm-tabs-content .tab-pane .content .progress-meters-container .progress-meter-container { + height: 150px !important; + padding: 20px 20px 48px 20px; + } + .container #vrm-tabs-content .tab-pane .content .progress-meters-container .progress-meter-container .progress-meter .inner-meter-container .icon, + .container #vrm-tabs-content .tab-pane .content .progress-meters-container .progress-meter-container .deviation-meter .inner-meter-container .icon { + left: auto !important; + right: 0px !important; + top: -30px !important; + } + .container #vrm-tabs-content .tab-pane .content .section-graph { + margin-bottom: 40px; + } + .container #vrm-tabs-content .tab-pane .content .section-graph .dashboard-graph { + height: 224px !important; + margin: 40px 20px 30px 10px !important; + } + .container #vrm-tabs-content .tab-pane .content .section-graph .dashboard-legend { + height: 90px !important; + } + .container #vrm-tabs-content .tab-pane .content .section-graph .dashboard-legend ul li { + margin-bottom: 9px; + margin-right: 0px !important; + width: 130px; + } + .container #vrm-tabs-content #solar-yield .content .section-graph .dashboard-graph.move-last-tick-to-front .jqplot-xaxis canvas:last-child, + .container #vrm-tabs-content #consumption .content .section-graph .dashboard-graph.move-last-tick-to-front .jqplot-xaxis canvas:last-child, + .container #vrm-tabs-content #batteries .content .section-graph .dashboard-graph.move-last-tick-to-front .jqplot-xaxis canvas:last-child { + left: 10px !important; + } + .container #vrm-tabs-content #settings .content .form-tabs-container { + margin-bottom: 40px; + margin-left: 10px; + margin-right: 10px; + width: 300px; + } + .container #vrm-tabs-content #settings .content .form-tabs-container .form-tabs { + margin-top: 14px; + } + .container #vrm-tabs-content #settings .content .form-tabs-container .form-tabs li a { + padding-left: 20px; + text-align: left; + } + .container #vrm-tabs-content #settings .content .form-tabs-container .btn { + width: 300px; + } + .container #vrm-tabs-content #settings .content .form-tabs-container .btn.force-width { + width: 300px !important; + } + .container #vrm-tabs-content #settings .content .form-tabs-container .mobile-title { + display: block; + margin-bottom: 0px; + margin-top: 50px; + } + .container #vrm-tabs-content #settings .content .remove-site-question .btn { + width: 300px; + } + .container #vrm-tabs-content #settings .content .remove-site-question .btn.force-width { + width: 300px !important; + } + .container #vrm-tabs-content #settings .content #form-container-sitesettings #sitesettings #fieldset-location .location-map-container #location-map { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + height: 300px; + width: 300px; + } + .container #vrm-tabs-content #settings .content #form-container-sitesettings #sitesettings #fieldset-summarywidget .summary-widget-list-enabled-caption { + margin-bottom: 13px; + padding-right: 0; + text-align: left; + } + .container #vrm-tabs-content #settings .content #form-container-sitesettings #sitesettings #fieldset-summarywidget .summary-widget-list-enabled-caption, + .container #vrm-tabs-content #settings .content #form-container-sitesettings #sitesettings #fieldset-summarywidget .summary-widget-list-disabled-caption { + margin-top: 17px; + padding-left: 37px; + } + .container #vrm-tabs-content #settings .content #form-container-sitesettings #sitesettings #fieldset-summarywidget .summary-widget-list-enabled-caption .sprite-icons, + .container #vrm-tabs-content #settings .content #form-container-sitesettings #sitesettings #fieldset-summarywidget .summary-widget-list-disabled-caption .sprite-icons { + left: 15px; + } + .container #vrm-tabs-content #settings .content #form-container-sitesettings #sitesettings #fieldset-geofence.fieldset-geofence-map { + width: auto; + } + .container #vrm-tabs-content #settings .content #form-container-sitesettings #sitesettings #fieldset-geofence.fieldset-geofence-map .form-element { + width: auto !important; + } + .container #vrm-tabs-content #settings .content #form-container-sitesettings #sitesettings #fieldset-geofence.fieldset-geofence-map .geofence-map-container { + width: auto; + } + .container #vrm-tabs-content #settings .content #form-container-sitesettings #sitesettings #fieldset-geofence.fieldset-geofence-map .geofence-map-container #geofence-map { + width: auto; + } + .container #vrm-tabs-content #settings .content .sortable-widget-list-enabled-caption { + margin-bottom: 13px; + padding-right: 0; + text-align: left; + } + .container #vrm-tabs-content #settings .content .sortable-widget-list-disabled-caption { + margin-bottom: 13px !important; + margin-top: 16px !important; + } + .container #vrm-tabs-content #settings .content .sortable-widget-list-enabled-caption, + .container #vrm-tabs-content #settings .content .sortable-widget-list-disabled-caption { + padding-left: 37px; + } + .container #vrm-tabs-content #settings .content .sortable-widget-list-enabled-caption .sprite-icons, + .container #vrm-tabs-content #settings .content .sortable-widget-list-disabled-caption .sprite-icons { + left: 15px; + } + .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-alarms-admin-settings .form-input-list .row, + .container #vrm-tabs-content #settings .content #form-container-user-settings #form-alarms-admin-settings .form-input-list .row, + .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-alarms-admin-settings .form-input-list .row, + .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-user-settings-container .form-input-list .row, + .container #vrm-tabs-content #settings .content #form-container-user-settings #form-user-settings-container .form-input-list .row, + .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-user-settings-container .form-input-list .row, + .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-widget-settings .form-input-list .row, + .container #vrm-tabs-content #settings .content #form-container-user-settings #form-widget-settings .form-input-list .row, + .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-widget-settings .form-input-list .row { + height: auto; + } + .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle label .alternative-display, + .container #vrm-tabs-content #settings .content #form-container-user-settings #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle label .alternative-display, + .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle label .alternative-display, + .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label .alternative-display, + .container #vrm-tabs-content #settings .content #form-container-user-settings #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label .alternative-display, + .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label .alternative-display, + .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-widget-settings .form-input-list .row .inner-container .custom-toggle label .alternative-display, + .container #vrm-tabs-content #settings .content #form-container-user-settings #form-widget-settings .form-input-list .row .inner-container .custom-toggle label .alternative-display, + .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-widget-settings .form-input-list .row .inner-container .custom-toggle label .alternative-display { + position: relative; + left: 0; + margin-top: 10px; + } + .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle label > a, + .container #vrm-tabs-content #settings .content #form-container-user-settings #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle label > a, + .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle label > a, + .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label > a, + .container #vrm-tabs-content #settings .content #form-container-user-settings #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label > a, + .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-user-settings-container .form-input-list .row .inner-container .custom-toggle label > a, + .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-widget-settings .form-input-list .row .inner-container .custom-toggle label > a, + .container #vrm-tabs-content #settings .content #form-container-user-settings #form-widget-settings .form-input-list .row .inner-container .custom-toggle label > a, + .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-widget-settings .form-input-list .row .inner-container .custom-toggle label > a { + top: 0; + } + .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle.adjust-margin label .caption, + .container #vrm-tabs-content #settings .content #form-container-user-settings #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle.adjust-margin label .caption, + .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle.adjust-margin label .caption, + .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-user-settings-container .form-input-list .row .inner-container .custom-toggle.adjust-margin label .caption, + .container #vrm-tabs-content #settings .content #form-container-user-settings #form-user-settings-container .form-input-list .row .inner-container .custom-toggle.adjust-margin label .caption, + .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-user-settings-container .form-input-list .row .inner-container .custom-toggle.adjust-margin label .caption, + .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-widget-settings .form-input-list .row .inner-container .custom-toggle.adjust-margin label .caption, + .container #vrm-tabs-content #settings .content #form-container-user-settings #form-widget-settings .form-input-list .row .inner-container .custom-toggle.adjust-margin label .caption, + .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-widget-settings .form-input-list .row .inner-container .custom-toggle.adjust-margin label .caption { + display: inline-block; + margin-top: 10px; + } + .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle.adjust-margin label .email-caption, + .container #vrm-tabs-content #settings .content #form-container-user-settings #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle.adjust-margin label .email-caption, + .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-alarms-admin-settings .form-input-list .row .inner-container .custom-toggle.adjust-margin label .email-caption, + .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-user-settings-container .form-input-list .row .inner-container .custom-toggle.adjust-margin label .email-caption, + .container #vrm-tabs-content #settings .content #form-container-user-settings #form-user-settings-container .form-input-list .row .inner-container .custom-toggle.adjust-margin label .email-caption, + .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-user-settings-container .form-input-list .row .inner-container .custom-toggle.adjust-margin label .email-caption, + .container #vrm-tabs-content #settings .content #forms-container-alarms-settings #form-widget-settings .form-input-list .row .inner-container .custom-toggle.adjust-margin label .email-caption, + .container #vrm-tabs-content #settings .content #form-container-user-settings #form-widget-settings .form-input-list .row .inner-container .custom-toggle.adjust-margin label .email-caption, + .container #vrm-tabs-content #settings .content #form-container-widget-settings #form-widget-settings .form-input-list .row .inner-container .custom-toggle.adjust-margin label .email-caption { + display: inline-block; + min-width: 200px; + margin-top: 6px; + } + .container #vrm-tabs-content #settings .content #form-container-user-settings #toggleInviteForm, + .container #vrm-tabs-content #settings .content #form-alarms-admin-settings #toggleInviteForm { + margin-bottom: 20px; + position: static; + width: 300px; + } + .container #vrm-tabs-content #settings .content #form-container-user-settings #toggleInviteForm.force-width, + .container #vrm-tabs-content #settings .content #form-alarms-admin-settings #toggleInviteForm.force-width { + width: 300px !important; + } + .container #vrm-tabs-content #settings .content #form-container-user-settings #inviteFormExplanation, + .container #vrm-tabs-content #settings .content #form-alarms-admin-settings #inviteFormExplanation { + position: static; + } + .container #vrm-tabs-content #settings .content #form-container-user-settings .header .caption-right, + .container #vrm-tabs-content #settings .content #form-alarms-admin-settings .header .caption-right { + float: none; + text-transform: lowercase; + } + .container #vrm-tabs-content #settings .content #form-alarms-admin-settings .header { + height: auto; + padding-top: 7px; + padding-bottom: 6px; + } + .container #vrm-tabs-content #settings .content #forms-container-alarms-settings .above-fieldset-element { + margin-bottom: 20px; + position: static; + } + .container #vrm-tabs-content #settings .content #forms-container-alarms-settings .above-fieldset-element .btn { + margin-left: 0; + margin-bottom: 12px; + width: 300px; + } + .container #vrm-tabs-content #settings .content #forms-container-alarms-settings .above-fieldset-element .btn.force-width { + width: 300px !important; + } + .container #vrm-tabs-content #settings .content #forms-container-alarms-settings .below-alarms-fieldset-element { + text-align: center; + } + .container #vrm-tabs-content #settings .content #forms-container-alarms-settings .below-alarms-fieldset-element a { + margin-left: 0; + width: 300px; + } + .container #vrm-tabs-content #settings .content #forms-container-alarms-settings .below-alarms-fieldset-element a.force-width { + width: 300px !important; + } + .container #vrm-tabs-content #settings .content #forms-container-alarms-settings .hint { + display: none; + } + /* -----------[Widgets]--------------*/ + .widget .header .sub-title ul li:nth-child(2) { + margin-top: -8px; + } + .widget .bottom-graph .graph-links li.selected:nth-child(2) .caption { + width: 97px; + } + .widget.VRM_Widget_State .content .graph-container, + .widget.VRM_Widget_VeBusWarningsAndAlarms .content .graph-container { + height: 255px; + padding: 50px 28px 25px 22px; + } + .widget.VRM_Widget_State .state-legend, + .widget.VRM_Widget_VeBusWarningsAndAlarms .state-legend { + padding: 20px 22px; + } + .widget .content.ps-container { + height: auto; + } + #forms-container-alarms-settings .settings-alarm-element { + width: 188px; + float: none; + padding: 0px 19px 19px 80px !important; + } + #forms-container-alarms-settings .settings-alarm-element:nth-child(2) { + padding-top: 5px !important; + } + /* -----------[Mobile menu]--------------*/ + .mobile-menu-open-handle { + border: 1px solid #dcdbd7; + cursor: pointer; + display: block; + height: 40px; + margin-right: 0; + position: absolute; + right: 10px; + top: 20px; + width: 40px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + } + .mobile-menu-open-handle .sprite-icons { + margin-left: 8px; + margin-top: 8px; + } + body.mobile-menu-open { + overflow: auto; + } + body.mobile-menu-open .mobile-menu-open-handle { + display: none; + } + body.mobile-menu-open .mobile-menu-close-handle { + right: 20px; + } + body.mobile-menu-open .mobile-menu { + left: 0; + } + body.mobile-menu-open .site-overlay-on-menu-open { + left: 0; + opacity: 1; + filter: alpha(opacity=100); + -webkit-transition: opacity 0.25s; + -moz-transition: opacity 0.25s; + -o-transition: opacity 0.25s; + transition: opacity 0.25s; + } + .mobile-menu { + background-color: #faf9f5; + bottom: 0; + display: block; + overflow: hidden; + position: fixed; + left: -258px; + top: 0; + z-index: 1101; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-transition: left 0.25s; + -moz-transition: left 0.25s; + -o-transition: left 0.25s; + transition: left 0.25s; + -webkit-transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); + transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); + -webkit-transform: translateZ(0); + -moz-transform: translateZ(0); + -ms-transform: translateZ(0); + -o-transform: translateZ(0); + transform: translateZ(0); + -webkit-perspective: 1000; + -moz-perspective: 1000; + -ms-perspective: 1000; + perspective: 1000; + } + .mobile-menu.has-user-search-input .hide-on-user-search-input { + display: none !important; + } + .mobile-menu .container-inner { + padding-bottom: 0; + width: 258px !important; + height: 100%; + } + .mobile-menu .container-inner ul { + position: absolute; + top: 0; + bottom: 0; + width: 100%; + margin-top: 40px; + overflow-y: scroll; + } + .mobile-menu .container-inner ul li { + padding-left: 18px; + padding-right: 18px; + } + .mobile-menu .container-inner ul li.collapsable-parent .mobile-menu-link-main { + padding-right: 20px; + } + .mobile-menu .container-inner ul li.collapsable-parent .collapsable-parent-handle { + position: absolute; + right: 13px; + top: -2px; + display: inline-block; + width: 24px; + height: 24px; + background-image: url("/img/VRM-sprite.png?v=3"); + background-size: 621px 888px; + background-repeat: no-repeat; + background-position: -24px -240px; + } + .mobile-menu .container-inner ul li.collapsable-child.collapsed { + display: none; + } + .mobile-menu .container-inner ul li a { + display: block; + text-decoration: none; + } + .mobile-menu .container-inner ul li a .plus-sign { + color: #afe18d; + } + .mobile-menu .container-inner ul li .mobile-menu-link-main { + color: #272622; + font-size: 18px; + margin-bottom: 17px; + margin-top: 35px; + } + .mobile-menu .container-inner ul li .mobile-menu-link-sub { + margin-top: 14px; + } + .mobile-menu .top-menu-language-fly-out, + .mobile-menu .top-menu-language-selector-container { + display: none; + } + .mobile-menu-search { + display: block; + height: 40px; + } + .mobile-menu-search .sprite-icons { + left: 8px; + position: absolute; + top: 8px; + } + .mobile-menu-search input { + background-color: #959490 !important; + border-color: #959490 !important; + color: #ffffff !important; + height: 100%; + padding-left: 40px; + width: 100%; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + } + .mobile-menu-search input:-moz-placeholder { + color: #e6e5e1; + opacity: 1; + } + .mobile-menu-search input::-moz-placeholder { + color: #e6e5e1; + opacity: 1; + } + .mobile-menu-search input:-webkit-input-placeholder { + color: #e6e5e1; + opacity: 1; + } + .mobile-menu-search input::-webkit-input-placeholder { + color: #e6e5e1; + opacity: 1; + } + .mobile-menu-search input:-ms-input-placeholder { + color: #e6e5e1; + opacity: 1; + } + .mobile-menu-search input::-ms-input-placeholder { + color: #e6e5e1; + opacity: 1; + } + .mobile-menu-site-title { + font-size: 21px !important; + } + .mobile-menu-buttons-container .btn { + display: inline-block !important; + font-size: 15px; + } + .mobile-menu-buttons-container .remote-console-trigger { + display: inline-block; + } + /* -----------[Admin sites overview]--------------*/ + body.diagnostics .breadcrumb .site-select, + body.site-overview .breadcrumb .site-select, + body.user-overview .breadcrumb .site-select { + display: inline-block; + } + /* -----------[Two factor login]--------------*/ + .two-step-login .mobile-menu { + display: none; + } + .user.update .container .form-tabs-container, + .user.two-step-update .container .form-tabs-container, + .user.update-dealer .container .form-tabs-container { + margin-bottom: 40px; + margin-left: 10px; + margin-right: 10px; + width: 300px; + } + .user.update .container .form-tabs-container .form-tabs, + .user.two-step-update .container .form-tabs-container .form-tabs, + .user.update-dealer .container .form-tabs-container .form-tabs { + margin-top: 14px; + } + .user.update .container .form-tabs-container .form-tabs li a, + .user.two-step-update .container .form-tabs-container .form-tabs li a, + .user.update-dealer .container .form-tabs-container .form-tabs li a { + padding-left: 20px; + text-align: left; + } + .user.update .container .form-tabs-container .btn, + .user.two-step-update .container .form-tabs-container .btn, + .user.update-dealer .container .form-tabs-container .btn { + width: 300px; + } + .user.update .container .form-tabs-container .btn.force-width, + .user.two-step-update .container .form-tabs-container .btn.force-width, + .user.update-dealer .container .form-tabs-container .btn.force-width { + width: 300px !important; + } + .user.update .container .form-tabs-container .mobile-title, + .user.two-step-update .container .form-tabs-container .mobile-title, + .user.update-dealer .container .form-tabs-container .mobile-title { + display: block; + margin-bottom: 0px; + margin-top: 50px; + } + .user.update .container .container-inner .four-columns-width, + .user.two-step-update .container .container-inner .four-columns-width, + .user.update-dealer .container .container-inner .four-columns-width { + width: 300px; + margin-left: 10px; + margin-right: 10px; + } + .remote-console-trigger { + float: none; + margin-left: 10px; + } +} +@media screen and (max-width: 959px) and print, screen and (max-width: 959px) and (-webkit-min-device-pixel-ratio: 1.25), screen and (max-width: 959px) and (-o-min-device-pixel-ratio: 3/2), screen and (max-width: 959px) and (min--moz-device-pixel-ratio: 1.25), screen and (max-width: 959px) and (-moz-min-device-pixel-ratio: 1.25), screen and (max-width: 959px) and (-ms-min-device-pixel-ratio: 1.25), screen and (max-width: 959px) and (min-device-pixel-ratio: 1.25), screen and (max-width: 959px) and (min-resolution: 120dpi), screen and (max-width: 959px) and (min-resolution: 1.25dppx) { + .mobile-menu .container-inner ul li.collapsable-parent .collapsable-parent-handle { + background-image: url("/img/VRM-sprite@2X.png?v=3"); + background-size: 621px 888px; + } +} +@media screen and (max-width: 795px) { + .remote-console-popup-container.logged-in { + width: 682px; + } + .remote-console-logged-in .remote-console-controls-title { + display: none; + } + .remote-console-title { + display: block; + } + .remote-console-display-container { + width: 100%; + } + .remote-console-display { + padding-right: 184px; + } + .remote-console-controls { + bottom: auto; + height: 230px; + top: 70px; + } + .remote-console-logged-in .remote-console-controls-container { + background-color: #faf9f5; + width: 181px; + } + .remote-console-logged-in .remote-console-controls-title, + .remote-console-logged-in .remote-console-controls-subtitle { + color: #4790d0; + } + .remote-console-logged-in .remote-console-controls-subtitle { + margin-top: 59px; + text-align: left; + } + .btn.remote-console-control-button { + background-color: #4790d0; + } + .btn.remote-console-control-button:hover { + background-color: #387dc5; + } + .btn.remote-console-control-button .remote-console-control-icon { + color: #faf9f5; + fill: #faf9f5; + } + .btn.remote-console-control-button .remote-console-control-icon path { + fill: #faf9f5; + } +} +@media screen and (max-width: 767px) { + .remote-console-popup-container { + border-radius: 0; + height: 100%; + left: 0; + margin: 0; + position: fixed; + top: 0; + width: 100%; + } + .remote-console-popup-container .mfp-close { + color: #4790d0; + } + .remote-console-popup-container.logged-in { + width: 100%; + } + .remote-console-popup-container.logged-in .mfp-close { + color: #4790d0; + } + .remote-console-display-inner { + width: 100%; + } + .remote-console-status { + height: 100%; + } +} +@media screen and (max-width: 570px) { + .remote-console-display-inner { + height: 200px !important; + } +} +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.hide { + display: none; +} +.show { + display: block; +} +.invisible { + visibility: hidden; +} +.affix { + position: fixed; +} +#cssValues.colors.blue { + color: #4790d0; +} +#cssValues.colors.blueHover { + color: #387dc5; +} +#cssValues.colors.blueShadow { + color: #5b9bcd; +} +#cssValues.colors.orange { + color: #f7ab3e; +} +#cssValues.colors.orangeHover { + color: #f0962e; +} +#cssValues.colors.green { + color: #8bc964; +} +#cssValues.colors.greenHover { + color: #72b84c; +} +#cssValues.colors.greenShadow { + color: #98c478; +} +#cssValues.colors.lightGreen { + color: #afe18d; +} +#cssValues.colors.red { + color: #fa716f; +} +#cssValues.colors.redHover { + color: #f35c58; +} +#cssValues.colors.redShadow { + color: #e66e6e; +} +#cssValues.colors.black { + color: #272622; +} +#cssValues.colors.white { + color: #ffffff; +} +#cssValues.colors.darkGray { + color: #63625e; +} +#cssValues.colors.darkGrayShadow { + color: rgba(99, 98, 94, 0.1); +} +#cssValues.colors.darkGrayLines { + color: #4f4f4b; +} +#cssValues.colors.gray { + color: #959490; +} +#cssValues.colors.grayShadow { + color: #8e8d89; +} +#cssValues.colors.lightGrayLines { + color: #dcdbd7; +} +#cssValues.colors.lightGraySurfaces { + color: #e6e5e1; +} +#cssValues.colors.lightGrayBackground { + color: #f0efeb; +} +#cssValues.colors.lightGrayWidgetHeader { + color: #faf9f5; +} +#cssValues.colors.grayLines { + color: #e5e4e0; +} +#cssValues.sprites.url { + background-image: url("/img/VRM-sprite.png?v=3"); +} +#cssValues.sprites.url2X { + background-image: url("/img/VRM-sprite@2X.png?v=3"); +} +#cssValues.sprites.width { + width: 621px; +} +#cssValues.sprites.height { + height: 888px; +} +#cssValues.fonts.fontFamily { + font-family: 'MuseoSans-300', sans-serif; +} +/*# sourceMappingURL=1a83de5aa35b26837c2042d512c73c5a_md5_7b8754c004401cfe0be061108bf9f813.css.map * + +/**************************************************************************************************************************************** +Dark mode (start) +****************************************************************************************************************************************/ +@media (prefers-color-scheme: dark) { + body, + .remote-console-rotate-message-container { + /*background-color: #1b1b1b;*/ + background-color: #101010; + color: #e6e5e1; + } + .remote-console-display { + /*background-color: #303030;*/ + background-color: #202020; + } + .remote-console-popup-container { + /*background-color: #303030;*/ + background-color: #202020; + } + .remote-console-controls-container { + background-color: #234868; + } + + .remote-console-controls-title, + .remote-console-controls-subtitle, + .remote-console-logged-in .remote-console-controls-title, + .remote-console-logged-in .remote-console-controls-subtitle { + color: #f3f2ee; + } + + .btn.light, input.light, textarea.light { + /*background-color: #7d7c7a;*/ + background-color: #303030; + /*background-color: #202020;*/ + border: 1px solid #4b4b4b; + } + .btn.light:hover, input.light:hover, textarea.light:hover { + /*background-color: #9d9d9d;*/ + background-color: #565656; + border: 1px solid #727272; + } + .remote-console-control-button .remote-console-control-icon { + color: #cfe9ff; + fill: #cfe9ff; + } + .remote-console-control-button .remote-console-control-icon path { + fill: #cfe9ff; + } + .remote-console-display-inner { + border: 1px solid #4b4b4b; + } + + @media screen and (max-width: 795px) { + .remote-console-logged-in .remote-console-controls-container { + background-color: #234868; + } + + .remote-console-controls-title, + .remote-console-controls-subtitle, + .remote-console-logged-in .remote-console-controls-title, + .remote-console-logged-in .remote-console-controls-subtitle { + color: #f3f2ee; + } + } + +} +/**************************************************************************************************************************************** +Dark mode (end) +****************************************************************************************************************************************/ diff --git a/FileSets/v3.40~10/styles.css.orig b/FileSets/v3.40~11/styles.css.orig similarity index 100% rename from FileSets/v3.40~10/styles.css.orig rename to FileSets/v3.40~11/styles.css.orig diff --git a/FileSets/v3.40~2/Battery.qml b/FileSets/v3.40~2/Battery.qml index 1f99218e..8e76916a 120000 --- a/FileSets/v3.40~2/Battery.qml +++ b/FileSets/v3.40~2/Battery.qml @@ -1 +1 @@ -../v3.40~10/Battery.qml \ No newline at end of file +../v3.40~11/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/MbEditBoxDateTime.qml b/FileSets/v3.40~2/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v3.40~2/MbEditBoxDateTime.qml +++ b/FileSets/v3.40~2/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/MbItem.qml b/FileSets/v3.40~2/MbItem.qml index 5e1bcc78..d1f5c0bb 120000 --- a/FileSets/v3.40~2/MbItem.qml +++ b/FileSets/v3.40~2/MbItem.qml @@ -1 +1 @@ -../v3.40~10/MbItem.qml \ No newline at end of file +../v3.40~11/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/MbItemDigitalInput.qml b/FileSets/v3.40~2/MbItemDigitalInput.qml index 68ec5c25..6be026f8 120000 --- a/FileSets/v3.40~2/MbItemDigitalInput.qml +++ b/FileSets/v3.40~2/MbItemDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/MbItemDigitalInput.qml \ No newline at end of file +../v3.40~11/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/MbSpinBox.qml b/FileSets/v3.40~2/MbSpinBox.qml index 8390ce03..fca806a7 120000 --- a/FileSets/v3.40~2/MbSpinBox.qml +++ b/FileSets/v3.40~2/MbSpinBox.qml @@ -1 +1 @@ -../v3.40~10/MbSpinBox.qml \ No newline at end of file +../v3.40~11/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/MbStyle.qml b/FileSets/v3.40~2/MbStyle.qml index 5d7cf621..17573562 120000 --- a/FileSets/v3.40~2/MbStyle.qml +++ b/FileSets/v3.40~2/MbStyle.qml @@ -1 +1 @@ -../v3.40~10/MbStyle.qml \ No newline at end of file +../v3.40~11/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/MbSubMenu.qml b/FileSets/v3.40~2/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v3.40~2/MbSubMenu.qml +++ b/FileSets/v3.40~2/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/Multi.qml b/FileSets/v3.40~2/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v3.40~2/Multi.qml +++ b/FileSets/v3.40~2/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/ObjectAcConnection.qml b/FileSets/v3.40~2/ObjectAcConnection.qml index 7edd9db8..8d459a07 120000 --- a/FileSets/v3.40~2/ObjectAcConnection.qml +++ b/FileSets/v3.40~2/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~10/ObjectAcConnection.qml \ No newline at end of file +../v3.40~11/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~2/OverviewAcValuesEnhanced.qml index fe5152b2..8e55e8dc 120000 --- a/FileSets/v3.40~2/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.40~2/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewBox.qml b/FileSets/v3.40~2/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v3.40~2/OverviewBox.qml +++ b/FileSets/v3.40~2/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewConnection.qml b/FileSets/v3.40~2/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v3.40~2/OverviewConnection.qml +++ b/FileSets/v3.40~2/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewConnectionEnd.qml b/FileSets/v3.40~2/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v3.40~2/OverviewConnectionEnd.qml +++ b/FileSets/v3.40~2/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~2/OverviewGeneratorEnhanced.qml index f0f8b29d..f118934b 120000 --- a/FileSets/v3.40~2/OverviewGeneratorEnhanced.qml +++ b/FileSets/v3.40~2/OverviewGeneratorEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~2/OverviewGeneratorRelayEnhanced.qml index a65e18d8..e0bbd3df 120000 --- a/FileSets/v3.40~2/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.40~2/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewMobileEnhanced.qml b/FileSets/v3.40~2/OverviewMobileEnhanced.qml index d6107e91..46ae0c55 120000 --- a/FileSets/v3.40~2/OverviewMobileEnhanced.qml +++ b/FileSets/v3.40~2/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewSolarCharger.qml b/FileSets/v3.40~2/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v3.40~2/OverviewSolarCharger.qml +++ b/FileSets/v3.40~2/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewSolarInverter.qml b/FileSets/v3.40~2/OverviewSolarInverter.qml index c31a9074..61f0bff7 120000 --- a/FileSets/v3.40~2/OverviewSolarInverter.qml +++ b/FileSets/v3.40~2/OverviewSolarInverter.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarInverter.qml \ No newline at end of file +../v3.40~11/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewTankDelegate.qml b/FileSets/v3.40~2/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v3.40~2/OverviewTankDelegate.qml +++ b/FileSets/v3.40~2/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewTanks.qml b/FileSets/v3.40~2/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v3.40~2/OverviewTanks.qml +++ b/FileSets/v3.40~2/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~2/OverviewTanksTempsDigInputs.qml index 302fd03e..26dd2c44 120000 --- a/FileSets/v3.40~2/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.40~2/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40~11/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/PageDigitalInput.qml b/FileSets/v3.40~2/PageDigitalInput.qml index f279fa05..a9b9e513 120000 --- a/FileSets/v3.40~2/PageDigitalInput.qml +++ b/FileSets/v3.40~2/PageDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/PageDigitalInput.qml \ No newline at end of file +../v3.40~11/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/PageGenerator.qml b/FileSets/v3.40~2/PageGenerator.qml index f99cb9de..7ecabc54 120000 --- a/FileSets/v3.40~2/PageGenerator.qml +++ b/FileSets/v3.40~2/PageGenerator.qml @@ -1 +1 @@ -../v3.40~10/PageGenerator.qml \ No newline at end of file +../v3.40~11/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/PageMain.qml b/FileSets/v3.40~2/PageMain.qml index a7aac8b7..0e32fc35 120000 --- a/FileSets/v3.40~2/PageMain.qml +++ b/FileSets/v3.40~2/PageMain.qml @@ -1 +1 @@ -../v3.40~10/PageMain.qml \ No newline at end of file +../v3.40~11/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/PageSettingsGenerator.qml b/FileSets/v3.40~2/PageSettingsGenerator.qml index 23140671..efd8d051 120000 --- a/FileSets/v3.40~2/PageSettingsGenerator.qml +++ b/FileSets/v3.40~2/PageSettingsGenerator.qml @@ -1 +1 @@ -../v3.40~10/PageSettingsGenerator.qml \ No newline at end of file +../v3.40~11/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/PageSettingsGuiMods.qml b/FileSets/v3.40~2/PageSettingsGuiMods.qml index 0e85c757..50a2393d 120000 --- a/FileSets/v3.40~2/PageSettingsGuiMods.qml +++ b/FileSets/v3.40~2/PageSettingsGuiMods.qml @@ -1 +1 @@ -../v3.40~10/PageSettingsGuiMods.qml \ No newline at end of file +../v3.40~11/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/PageSettingsRelay.qml b/FileSets/v3.40~2/PageSettingsRelay.qml index 72de1197..337482f3 120000 --- a/FileSets/v3.40~2/PageSettingsRelay.qml +++ b/FileSets/v3.40~2/PageSettingsRelay.qml @@ -1 +1 @@ -../v3.40~10/PageSettingsRelay.qml \ No newline at end of file +../v3.40~11/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/Tile.qml b/FileSets/v3.40~2/Tile.qml index ac462f2e..5c566101 120000 --- a/FileSets/v3.40~2/Tile.qml +++ b/FileSets/v3.40~2/Tile.qml @@ -1 +1 @@ -../v3.40~10/Tile.qml \ No newline at end of file +../v3.40~11/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/TileDigIn.qml b/FileSets/v3.40~2/TileDigIn.qml index ff43ea83..fc269e05 120000 --- a/FileSets/v3.40~2/TileDigIn.qml +++ b/FileSets/v3.40~2/TileDigIn.qml @@ -1 +1 @@ -../v3.40~10/TileDigIn.qml \ No newline at end of file +../v3.40~11/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/TileRelay.qml b/FileSets/v3.40~2/TileRelay.qml index 7e3866d3..2ebdf179 120000 --- a/FileSets/v3.40~2/TileRelay.qml +++ b/FileSets/v3.40~2/TileRelay.qml @@ -1 +1 @@ -../v3.40~10/TileRelay.qml \ No newline at end of file +../v3.40~11/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/TileText.qml b/FileSets/v3.40~2/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v3.40~2/TileText.qml +++ b/FileSets/v3.40~2/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/dbus_digitalinputs.py b/FileSets/v3.40~2/dbus_digitalinputs.py index bdaa4e12..085682ce 120000 --- a/FileSets/v3.40~2/dbus_digitalinputs.py +++ b/FileSets/v3.40~2/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~10/dbus_digitalinputs.py \ No newline at end of file +../v3.40~11/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 index 12899ddc..699b4b49 120000 --- a/FileSets/v3.40~2/dbus_generator.py +++ b/FileSets/v3.40~2/dbus_generator.py @@ -1 +1 @@ -../v3.40~10/dbus_generator.py \ No newline at end of file +../v3.40~11/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 index 749f83e6..223531e7 120000 --- a/FileSets/v3.40~2/main.qml +++ b/FileSets/v3.40~2/main.qml @@ -1 +1 @@ -../v3.40~10/main.qml \ No newline at end of file +../v3.40~11/main.qml \ No newline at end of file diff --git a/FileSets/v3.40~2/startstop.py b/FileSets/v3.40~2/startstop.py index d2ea898a..c84f296d 120000 --- a/FileSets/v3.40~2/startstop.py +++ b/FileSets/v3.40~2/startstop.py @@ -1 +1 @@ -../v3.40~10/startstop.py \ No newline at end of file +../v3.40~11/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~2/styles.css b/FileSets/v3.40~2/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v3.40~2/styles.css +++ b/FileSets/v3.40~2/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v3.40~5/Battery.qml b/FileSets/v3.40~5/Battery.qml index 1f99218e..8e76916a 120000 --- a/FileSets/v3.40~5/Battery.qml +++ b/FileSets/v3.40~5/Battery.qml @@ -1 +1 @@ -../v3.40~10/Battery.qml \ No newline at end of file +../v3.40~11/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/MbEditBoxDateTime.qml b/FileSets/v3.40~5/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v3.40~5/MbEditBoxDateTime.qml +++ b/FileSets/v3.40~5/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/MbItem.qml b/FileSets/v3.40~5/MbItem.qml index 5e1bcc78..d1f5c0bb 120000 --- a/FileSets/v3.40~5/MbItem.qml +++ b/FileSets/v3.40~5/MbItem.qml @@ -1 +1 @@ -../v3.40~10/MbItem.qml \ No newline at end of file +../v3.40~11/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/MbItemDigitalInput.qml b/FileSets/v3.40~5/MbItemDigitalInput.qml index 68ec5c25..6be026f8 120000 --- a/FileSets/v3.40~5/MbItemDigitalInput.qml +++ b/FileSets/v3.40~5/MbItemDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/MbItemDigitalInput.qml \ No newline at end of file +../v3.40~11/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/MbSpinBox.qml b/FileSets/v3.40~5/MbSpinBox.qml index 8390ce03..fca806a7 120000 --- a/FileSets/v3.40~5/MbSpinBox.qml +++ b/FileSets/v3.40~5/MbSpinBox.qml @@ -1 +1 @@ -../v3.40~10/MbSpinBox.qml \ No newline at end of file +../v3.40~11/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/MbStyle.qml b/FileSets/v3.40~5/MbStyle.qml index 5d7cf621..17573562 120000 --- a/FileSets/v3.40~5/MbStyle.qml +++ b/FileSets/v3.40~5/MbStyle.qml @@ -1 +1 @@ -../v3.40~10/MbStyle.qml \ No newline at end of file +../v3.40~11/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/MbSubMenu.qml b/FileSets/v3.40~5/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v3.40~5/MbSubMenu.qml +++ b/FileSets/v3.40~5/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/Multi.qml b/FileSets/v3.40~5/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v3.40~5/Multi.qml +++ b/FileSets/v3.40~5/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/ObjectAcConnection.qml b/FileSets/v3.40~5/ObjectAcConnection.qml index 7edd9db8..8d459a07 120000 --- a/FileSets/v3.40~5/ObjectAcConnection.qml +++ b/FileSets/v3.40~5/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~10/ObjectAcConnection.qml \ No newline at end of file +../v3.40~11/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~5/OverviewAcValuesEnhanced.qml index fe5152b2..8e55e8dc 120000 --- a/FileSets/v3.40~5/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.40~5/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewBox.qml b/FileSets/v3.40~5/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v3.40~5/OverviewBox.qml +++ b/FileSets/v3.40~5/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewConnection.qml b/FileSets/v3.40~5/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v3.40~5/OverviewConnection.qml +++ b/FileSets/v3.40~5/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewConnectionEnd.qml b/FileSets/v3.40~5/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v3.40~5/OverviewConnectionEnd.qml +++ b/FileSets/v3.40~5/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~5/OverviewGeneratorEnhanced.qml index f0f8b29d..f118934b 120000 --- a/FileSets/v3.40~5/OverviewGeneratorEnhanced.qml +++ b/FileSets/v3.40~5/OverviewGeneratorEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~5/OverviewGeneratorRelayEnhanced.qml index a65e18d8..e0bbd3df 120000 --- a/FileSets/v3.40~5/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.40~5/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewMobileEnhanced.qml b/FileSets/v3.40~5/OverviewMobileEnhanced.qml index d6107e91..46ae0c55 120000 --- a/FileSets/v3.40~5/OverviewMobileEnhanced.qml +++ b/FileSets/v3.40~5/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewSolarCharger.qml b/FileSets/v3.40~5/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v3.40~5/OverviewSolarCharger.qml +++ b/FileSets/v3.40~5/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewSolarInverter.qml b/FileSets/v3.40~5/OverviewSolarInverter.qml index c31a9074..61f0bff7 120000 --- a/FileSets/v3.40~5/OverviewSolarInverter.qml +++ b/FileSets/v3.40~5/OverviewSolarInverter.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarInverter.qml \ No newline at end of file +../v3.40~11/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewTankDelegate.qml b/FileSets/v3.40~5/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v3.40~5/OverviewTankDelegate.qml +++ b/FileSets/v3.40~5/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewTanks.qml b/FileSets/v3.40~5/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v3.40~5/OverviewTanks.qml +++ b/FileSets/v3.40~5/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~5/OverviewTanksTempsDigInputs.qml index 302fd03e..26dd2c44 120000 --- a/FileSets/v3.40~5/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.40~5/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40~11/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/PageDigitalInput.qml b/FileSets/v3.40~5/PageDigitalInput.qml index f279fa05..a9b9e513 120000 --- a/FileSets/v3.40~5/PageDigitalInput.qml +++ b/FileSets/v3.40~5/PageDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/PageDigitalInput.qml \ No newline at end of file +../v3.40~11/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/PageGenerator.qml b/FileSets/v3.40~5/PageGenerator.qml index f99cb9de..7ecabc54 120000 --- a/FileSets/v3.40~5/PageGenerator.qml +++ b/FileSets/v3.40~5/PageGenerator.qml @@ -1 +1 @@ -../v3.40~10/PageGenerator.qml \ No newline at end of file +../v3.40~11/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/PageMain.qml b/FileSets/v3.40~5/PageMain.qml index a7aac8b7..0e32fc35 120000 --- a/FileSets/v3.40~5/PageMain.qml +++ b/FileSets/v3.40~5/PageMain.qml @@ -1 +1 @@ -../v3.40~10/PageMain.qml \ No newline at end of file +../v3.40~11/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/PageSettingsGenerator.qml b/FileSets/v3.40~5/PageSettingsGenerator.qml index 23140671..efd8d051 120000 --- a/FileSets/v3.40~5/PageSettingsGenerator.qml +++ b/FileSets/v3.40~5/PageSettingsGenerator.qml @@ -1 +1 @@ -../v3.40~10/PageSettingsGenerator.qml \ No newline at end of file +../v3.40~11/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/PageSettingsGuiMods.qml b/FileSets/v3.40~5/PageSettingsGuiMods.qml index 0e85c757..50a2393d 120000 --- a/FileSets/v3.40~5/PageSettingsGuiMods.qml +++ b/FileSets/v3.40~5/PageSettingsGuiMods.qml @@ -1 +1 @@ -../v3.40~10/PageSettingsGuiMods.qml \ No newline at end of file +../v3.40~11/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/PageSettingsRelay.qml b/FileSets/v3.40~5/PageSettingsRelay.qml index 72de1197..337482f3 120000 --- a/FileSets/v3.40~5/PageSettingsRelay.qml +++ b/FileSets/v3.40~5/PageSettingsRelay.qml @@ -1 +1 @@ -../v3.40~10/PageSettingsRelay.qml \ No newline at end of file +../v3.40~11/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/Tile.qml b/FileSets/v3.40~5/Tile.qml index ac462f2e..5c566101 120000 --- a/FileSets/v3.40~5/Tile.qml +++ b/FileSets/v3.40~5/Tile.qml @@ -1 +1 @@ -../v3.40~10/Tile.qml \ No newline at end of file +../v3.40~11/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/TileDigIn.qml b/FileSets/v3.40~5/TileDigIn.qml index ff43ea83..fc269e05 120000 --- a/FileSets/v3.40~5/TileDigIn.qml +++ b/FileSets/v3.40~5/TileDigIn.qml @@ -1 +1 @@ -../v3.40~10/TileDigIn.qml \ No newline at end of file +../v3.40~11/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/TileRelay.qml b/FileSets/v3.40~5/TileRelay.qml index 7e3866d3..2ebdf179 120000 --- a/FileSets/v3.40~5/TileRelay.qml +++ b/FileSets/v3.40~5/TileRelay.qml @@ -1 +1 @@ -../v3.40~10/TileRelay.qml \ No newline at end of file +../v3.40~11/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/TileText.qml b/FileSets/v3.40~5/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v3.40~5/TileText.qml +++ b/FileSets/v3.40~5/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/dbus_digitalinputs.py b/FileSets/v3.40~5/dbus_digitalinputs.py index bdaa4e12..085682ce 120000 --- a/FileSets/v3.40~5/dbus_digitalinputs.py +++ b/FileSets/v3.40~5/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~10/dbus_digitalinputs.py \ No newline at end of file +../v3.40~11/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 index 12899ddc..699b4b49 120000 --- a/FileSets/v3.40~5/dbus_generator.py +++ b/FileSets/v3.40~5/dbus_generator.py @@ -1 +1 @@ -../v3.40~10/dbus_generator.py \ No newline at end of file +../v3.40~11/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.40~5/main.qml b/FileSets/v3.40~5/main.qml index 749f83e6..223531e7 120000 --- a/FileSets/v3.40~5/main.qml +++ b/FileSets/v3.40~5/main.qml @@ -1 +1 @@ -../v3.40~10/main.qml \ No newline at end of file +../v3.40~11/main.qml \ No newline at end of file diff --git a/FileSets/v3.40~5/startstop.py b/FileSets/v3.40~5/startstop.py index d2ea898a..c84f296d 120000 --- a/FileSets/v3.40~5/startstop.py +++ b/FileSets/v3.40~5/startstop.py @@ -1 +1 @@ -../v3.40~10/startstop.py \ No newline at end of file +../v3.40~11/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~5/styles.css b/FileSets/v3.40~5/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v3.40~5/styles.css +++ b/FileSets/v3.40~5/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v3.40~6/Battery.qml b/FileSets/v3.40~6/Battery.qml index 1f99218e..8e76916a 120000 --- a/FileSets/v3.40~6/Battery.qml +++ b/FileSets/v3.40~6/Battery.qml @@ -1 +1 @@ -../v3.40~10/Battery.qml \ No newline at end of file +../v3.40~11/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/MbEditBoxDateTime.qml b/FileSets/v3.40~6/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v3.40~6/MbEditBoxDateTime.qml +++ b/FileSets/v3.40~6/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/MbItem.qml b/FileSets/v3.40~6/MbItem.qml index 5e1bcc78..d1f5c0bb 120000 --- a/FileSets/v3.40~6/MbItem.qml +++ b/FileSets/v3.40~6/MbItem.qml @@ -1 +1 @@ -../v3.40~10/MbItem.qml \ No newline at end of file +../v3.40~11/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/MbItemDigitalInput.qml b/FileSets/v3.40~6/MbItemDigitalInput.qml index 68ec5c25..6be026f8 120000 --- a/FileSets/v3.40~6/MbItemDigitalInput.qml +++ b/FileSets/v3.40~6/MbItemDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/MbItemDigitalInput.qml \ No newline at end of file +../v3.40~11/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/MbSpinBox.qml b/FileSets/v3.40~6/MbSpinBox.qml index 8390ce03..fca806a7 120000 --- a/FileSets/v3.40~6/MbSpinBox.qml +++ b/FileSets/v3.40~6/MbSpinBox.qml @@ -1 +1 @@ -../v3.40~10/MbSpinBox.qml \ No newline at end of file +../v3.40~11/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/MbStyle.qml b/FileSets/v3.40~6/MbStyle.qml index 5d7cf621..17573562 120000 --- a/FileSets/v3.40~6/MbStyle.qml +++ b/FileSets/v3.40~6/MbStyle.qml @@ -1 +1 @@ -../v3.40~10/MbStyle.qml \ No newline at end of file +../v3.40~11/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/MbSubMenu.qml b/FileSets/v3.40~6/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v3.40~6/MbSubMenu.qml +++ b/FileSets/v3.40~6/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/Multi.qml b/FileSets/v3.40~6/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v3.40~6/Multi.qml +++ b/FileSets/v3.40~6/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/ObjectAcConnection.qml b/FileSets/v3.40~6/ObjectAcConnection.qml index 7edd9db8..8d459a07 120000 --- a/FileSets/v3.40~6/ObjectAcConnection.qml +++ b/FileSets/v3.40~6/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~10/ObjectAcConnection.qml \ No newline at end of file +../v3.40~11/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~6/OverviewAcValuesEnhanced.qml index fe5152b2..8e55e8dc 120000 --- a/FileSets/v3.40~6/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.40~6/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewBox.qml b/FileSets/v3.40~6/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v3.40~6/OverviewBox.qml +++ b/FileSets/v3.40~6/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewConnection.qml b/FileSets/v3.40~6/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v3.40~6/OverviewConnection.qml +++ b/FileSets/v3.40~6/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewConnectionEnd.qml b/FileSets/v3.40~6/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v3.40~6/OverviewConnectionEnd.qml +++ b/FileSets/v3.40~6/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~6/OverviewGeneratorEnhanced.qml index f0f8b29d..f118934b 120000 --- a/FileSets/v3.40~6/OverviewGeneratorEnhanced.qml +++ b/FileSets/v3.40~6/OverviewGeneratorEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~6/OverviewGeneratorRelayEnhanced.qml index a65e18d8..e0bbd3df 120000 --- a/FileSets/v3.40~6/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.40~6/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewMobileEnhanced.qml b/FileSets/v3.40~6/OverviewMobileEnhanced.qml index d6107e91..46ae0c55 120000 --- a/FileSets/v3.40~6/OverviewMobileEnhanced.qml +++ b/FileSets/v3.40~6/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewSolarCharger.qml b/FileSets/v3.40~6/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v3.40~6/OverviewSolarCharger.qml +++ b/FileSets/v3.40~6/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewSolarInverter.qml b/FileSets/v3.40~6/OverviewSolarInverter.qml index c31a9074..61f0bff7 120000 --- a/FileSets/v3.40~6/OverviewSolarInverter.qml +++ b/FileSets/v3.40~6/OverviewSolarInverter.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarInverter.qml \ No newline at end of file +../v3.40~11/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewTankDelegate.qml b/FileSets/v3.40~6/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v3.40~6/OverviewTankDelegate.qml +++ b/FileSets/v3.40~6/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewTanks.qml b/FileSets/v3.40~6/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v3.40~6/OverviewTanks.qml +++ b/FileSets/v3.40~6/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~6/OverviewTanksTempsDigInputs.qml index 302fd03e..26dd2c44 120000 --- a/FileSets/v3.40~6/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.40~6/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40~11/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/PageDigitalInput.qml b/FileSets/v3.40~6/PageDigitalInput.qml index f279fa05..a9b9e513 120000 --- a/FileSets/v3.40~6/PageDigitalInput.qml +++ b/FileSets/v3.40~6/PageDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/PageDigitalInput.qml \ No newline at end of file +../v3.40~11/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/PageGenerator.qml b/FileSets/v3.40~6/PageGenerator.qml index f99cb9de..7ecabc54 120000 --- a/FileSets/v3.40~6/PageGenerator.qml +++ b/FileSets/v3.40~6/PageGenerator.qml @@ -1 +1 @@ -../v3.40~10/PageGenerator.qml \ No newline at end of file +../v3.40~11/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/PageMain.qml b/FileSets/v3.40~6/PageMain.qml index a7aac8b7..0e32fc35 120000 --- a/FileSets/v3.40~6/PageMain.qml +++ b/FileSets/v3.40~6/PageMain.qml @@ -1 +1 @@ -../v3.40~10/PageMain.qml \ No newline at end of file +../v3.40~11/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/PageSettingsGenerator.qml b/FileSets/v3.40~6/PageSettingsGenerator.qml index 23140671..efd8d051 120000 --- a/FileSets/v3.40~6/PageSettingsGenerator.qml +++ b/FileSets/v3.40~6/PageSettingsGenerator.qml @@ -1 +1 @@ -../v3.40~10/PageSettingsGenerator.qml \ No newline at end of file +../v3.40~11/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/PageSettingsGuiMods.qml b/FileSets/v3.40~6/PageSettingsGuiMods.qml index 0e85c757..50a2393d 120000 --- a/FileSets/v3.40~6/PageSettingsGuiMods.qml +++ b/FileSets/v3.40~6/PageSettingsGuiMods.qml @@ -1 +1 @@ -../v3.40~10/PageSettingsGuiMods.qml \ No newline at end of file +../v3.40~11/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/PageSettingsRelay.qml b/FileSets/v3.40~6/PageSettingsRelay.qml index 72de1197..337482f3 120000 --- a/FileSets/v3.40~6/PageSettingsRelay.qml +++ b/FileSets/v3.40~6/PageSettingsRelay.qml @@ -1 +1 @@ -../v3.40~10/PageSettingsRelay.qml \ No newline at end of file +../v3.40~11/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/Tile.qml b/FileSets/v3.40~6/Tile.qml index ac462f2e..5c566101 120000 --- a/FileSets/v3.40~6/Tile.qml +++ b/FileSets/v3.40~6/Tile.qml @@ -1 +1 @@ -../v3.40~10/Tile.qml \ No newline at end of file +../v3.40~11/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/TileDigIn.qml b/FileSets/v3.40~6/TileDigIn.qml index ff43ea83..fc269e05 120000 --- a/FileSets/v3.40~6/TileDigIn.qml +++ b/FileSets/v3.40~6/TileDigIn.qml @@ -1 +1 @@ -../v3.40~10/TileDigIn.qml \ No newline at end of file +../v3.40~11/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/TileRelay.qml b/FileSets/v3.40~6/TileRelay.qml index 7e3866d3..2ebdf179 120000 --- a/FileSets/v3.40~6/TileRelay.qml +++ b/FileSets/v3.40~6/TileRelay.qml @@ -1 +1 @@ -../v3.40~10/TileRelay.qml \ No newline at end of file +../v3.40~11/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/TileText.qml b/FileSets/v3.40~6/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v3.40~6/TileText.qml +++ b/FileSets/v3.40~6/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/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 index bdaa4e12..085682ce 120000 --- a/FileSets/v3.40~6/dbus_digitalinputs.py +++ b/FileSets/v3.40~6/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~10/dbus_digitalinputs.py \ No newline at end of file +../v3.40~11/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 index 12899ddc..699b4b49 120000 --- a/FileSets/v3.40~6/dbus_generator.py +++ b/FileSets/v3.40~6/dbus_generator.py @@ -1 +1 @@ -../v3.40~10/dbus_generator.py \ No newline at end of file +../v3.40~11/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 index 749f83e6..223531e7 120000 --- a/FileSets/v3.40~6/main.qml +++ b/FileSets/v3.40~6/main.qml @@ -1 +1 @@ -../v3.40~10/main.qml \ No newline at end of file +../v3.40~11/main.qml \ No newline at end of file diff --git a/FileSets/v3.40~6/startstop.py b/FileSets/v3.40~6/startstop.py index d2ea898a..c84f296d 120000 --- a/FileSets/v3.40~6/startstop.py +++ b/FileSets/v3.40~6/startstop.py @@ -1 +1 @@ -../v3.40~10/startstop.py \ No newline at end of file +../v3.40~11/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~6/styles.css b/FileSets/v3.40~6/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v3.40~6/styles.css +++ b/FileSets/v3.40~6/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/FileSets/v3.40~8/Battery.qml b/FileSets/v3.40~8/Battery.qml index 1f99218e..8e76916a 120000 --- a/FileSets/v3.40~8/Battery.qml +++ b/FileSets/v3.40~8/Battery.qml @@ -1 +1 @@ -../v3.40~10/Battery.qml \ No newline at end of file +../v3.40~11/Battery.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/MbEditBoxDateTime.qml b/FileSets/v3.40~8/MbEditBoxDateTime.qml index ce8a323d..f2e26436 120000 --- a/FileSets/v3.40~8/MbEditBoxDateTime.qml +++ b/FileSets/v3.40~8/MbEditBoxDateTime.qml @@ -1 +1 @@ -../v3.40~10/MbEditBoxDateTime.qml \ No newline at end of file +../v3.40~11/MbEditBoxDateTime.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/MbItem.qml b/FileSets/v3.40~8/MbItem.qml index 5e1bcc78..d1f5c0bb 120000 --- a/FileSets/v3.40~8/MbItem.qml +++ b/FileSets/v3.40~8/MbItem.qml @@ -1 +1 @@ -../v3.40~10/MbItem.qml \ No newline at end of file +../v3.40~11/MbItem.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/MbItemDigitalInput.qml b/FileSets/v3.40~8/MbItemDigitalInput.qml index 68ec5c25..6be026f8 120000 --- a/FileSets/v3.40~8/MbItemDigitalInput.qml +++ b/FileSets/v3.40~8/MbItemDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/MbItemDigitalInput.qml \ No newline at end of file +../v3.40~11/MbItemDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/MbSpinBox.qml b/FileSets/v3.40~8/MbSpinBox.qml index 8390ce03..fca806a7 120000 --- a/FileSets/v3.40~8/MbSpinBox.qml +++ b/FileSets/v3.40~8/MbSpinBox.qml @@ -1 +1 @@ -../v3.40~10/MbSpinBox.qml \ No newline at end of file +../v3.40~11/MbSpinBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/MbStyle.qml b/FileSets/v3.40~8/MbStyle.qml index 5d7cf621..17573562 120000 --- a/FileSets/v3.40~8/MbStyle.qml +++ b/FileSets/v3.40~8/MbStyle.qml @@ -1 +1 @@ -../v3.40~10/MbStyle.qml \ No newline at end of file +../v3.40~11/MbStyle.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/MbSubMenu.qml b/FileSets/v3.40~8/MbSubMenu.qml index 8220dbd2..11b22a13 120000 --- a/FileSets/v3.40~8/MbSubMenu.qml +++ b/FileSets/v3.40~8/MbSubMenu.qml @@ -1 +1 @@ -../v3.40~10/MbSubMenu.qml \ No newline at end of file +../v3.40~11/MbSubMenu.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/Multi.qml b/FileSets/v3.40~8/Multi.qml index 32793247..879c4d3e 120000 --- a/FileSets/v3.40~8/Multi.qml +++ b/FileSets/v3.40~8/Multi.qml @@ -1 +1 @@ -../v3.40~10/Multi.qml \ No newline at end of file +../v3.40~11/Multi.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/ObjectAcConnection.qml b/FileSets/v3.40~8/ObjectAcConnection.qml index 7edd9db8..8d459a07 120000 --- a/FileSets/v3.40~8/ObjectAcConnection.qml +++ b/FileSets/v3.40~8/ObjectAcConnection.qml @@ -1 +1 @@ -../v3.40~10/ObjectAcConnection.qml \ No newline at end of file +../v3.40~11/ObjectAcConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/OverviewAcValuesEnhanced.qml b/FileSets/v3.40~8/OverviewAcValuesEnhanced.qml index fe5152b2..8e55e8dc 120000 --- a/FileSets/v3.40~8/OverviewAcValuesEnhanced.qml +++ b/FileSets/v3.40~8/OverviewAcValuesEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewAcValuesEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewAcValuesEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/OverviewBox.qml b/FileSets/v3.40~8/OverviewBox.qml index ac6a2619..033b4017 120000 --- a/FileSets/v3.40~8/OverviewBox.qml +++ b/FileSets/v3.40~8/OverviewBox.qml @@ -1 +1 @@ -../v3.40~10/OverviewBox.qml \ No newline at end of file +../v3.40~11/OverviewBox.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/OverviewConnection.qml b/FileSets/v3.40~8/OverviewConnection.qml index d16d3af8..cb3709b9 120000 --- a/FileSets/v3.40~8/OverviewConnection.qml +++ b/FileSets/v3.40~8/OverviewConnection.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnection.qml \ No newline at end of file +../v3.40~11/OverviewConnection.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/OverviewConnectionEnd.qml b/FileSets/v3.40~8/OverviewConnectionEnd.qml index 2513bc71..a2eab5c2 120000 --- a/FileSets/v3.40~8/OverviewConnectionEnd.qml +++ b/FileSets/v3.40~8/OverviewConnectionEnd.qml @@ -1 +1 @@ -../v3.40~10/OverviewConnectionEnd.qml \ No newline at end of file +../v3.40~11/OverviewConnectionEnd.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/OverviewGeneratorEnhanced.qml b/FileSets/v3.40~8/OverviewGeneratorEnhanced.qml index f0f8b29d..f118934b 120000 --- a/FileSets/v3.40~8/OverviewGeneratorEnhanced.qml +++ b/FileSets/v3.40~8/OverviewGeneratorEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/OverviewGeneratorRelayEnhanced.qml b/FileSets/v3.40~8/OverviewGeneratorRelayEnhanced.qml index a65e18d8..e0bbd3df 120000 --- a/FileSets/v3.40~8/OverviewGeneratorRelayEnhanced.qml +++ b/FileSets/v3.40~8/OverviewGeneratorRelayEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewGeneratorRelayEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/OverviewMobileEnhanced.qml b/FileSets/v3.40~8/OverviewMobileEnhanced.qml index d6107e91..46ae0c55 120000 --- a/FileSets/v3.40~8/OverviewMobileEnhanced.qml +++ b/FileSets/v3.40~8/OverviewMobileEnhanced.qml @@ -1 +1 @@ -../v3.40~10/OverviewMobileEnhanced.qml \ No newline at end of file +../v3.40~11/OverviewMobileEnhanced.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/OverviewSolarCharger.qml b/FileSets/v3.40~8/OverviewSolarCharger.qml index 1f35f2b0..597ead23 120000 --- a/FileSets/v3.40~8/OverviewSolarCharger.qml +++ b/FileSets/v3.40~8/OverviewSolarCharger.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarCharger.qml \ No newline at end of file +../v3.40~11/OverviewSolarCharger.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/OverviewSolarInverter.qml b/FileSets/v3.40~8/OverviewSolarInverter.qml index c31a9074..61f0bff7 120000 --- a/FileSets/v3.40~8/OverviewSolarInverter.qml +++ b/FileSets/v3.40~8/OverviewSolarInverter.qml @@ -1 +1 @@ -../v3.40~10/OverviewSolarInverter.qml \ No newline at end of file +../v3.40~11/OverviewSolarInverter.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/OverviewTankDelegate.qml b/FileSets/v3.40~8/OverviewTankDelegate.qml index 4646c122..51481985 120000 --- a/FileSets/v3.40~8/OverviewTankDelegate.qml +++ b/FileSets/v3.40~8/OverviewTankDelegate.qml @@ -1 +1 @@ -../v3.40~10/OverviewTankDelegate.qml \ No newline at end of file +../v3.40~11/OverviewTankDelegate.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/OverviewTanks.qml b/FileSets/v3.40~8/OverviewTanks.qml index fd286ac5..8d5563ca 120000 --- a/FileSets/v3.40~8/OverviewTanks.qml +++ b/FileSets/v3.40~8/OverviewTanks.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanks.qml \ No newline at end of file +../v3.40~11/OverviewTanks.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/OverviewTanksTempsDigInputs.qml b/FileSets/v3.40~8/OverviewTanksTempsDigInputs.qml index 302fd03e..26dd2c44 120000 --- a/FileSets/v3.40~8/OverviewTanksTempsDigInputs.qml +++ b/FileSets/v3.40~8/OverviewTanksTempsDigInputs.qml @@ -1 +1 @@ -../v3.40~10/OverviewTanksTempsDigInputs.qml \ No newline at end of file +../v3.40~11/OverviewTanksTempsDigInputs.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/PageDigitalInput.qml b/FileSets/v3.40~8/PageDigitalInput.qml index f279fa05..a9b9e513 120000 --- a/FileSets/v3.40~8/PageDigitalInput.qml +++ b/FileSets/v3.40~8/PageDigitalInput.qml @@ -1 +1 @@ -../v3.40~10/PageDigitalInput.qml \ No newline at end of file +../v3.40~11/PageDigitalInput.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/PageGenerator.qml b/FileSets/v3.40~8/PageGenerator.qml index f99cb9de..7ecabc54 120000 --- a/FileSets/v3.40~8/PageGenerator.qml +++ b/FileSets/v3.40~8/PageGenerator.qml @@ -1 +1 @@ -../v3.40~10/PageGenerator.qml \ No newline at end of file +../v3.40~11/PageGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/PageMain.qml b/FileSets/v3.40~8/PageMain.qml index a7aac8b7..0e32fc35 120000 --- a/FileSets/v3.40~8/PageMain.qml +++ b/FileSets/v3.40~8/PageMain.qml @@ -1 +1 @@ -../v3.40~10/PageMain.qml \ No newline at end of file +../v3.40~11/PageMain.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/PageSettingsGenerator.qml b/FileSets/v3.40~8/PageSettingsGenerator.qml index 23140671..efd8d051 120000 --- a/FileSets/v3.40~8/PageSettingsGenerator.qml +++ b/FileSets/v3.40~8/PageSettingsGenerator.qml @@ -1 +1 @@ -../v3.40~10/PageSettingsGenerator.qml \ No newline at end of file +../v3.40~11/PageSettingsGenerator.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/PageSettingsGuiMods.qml b/FileSets/v3.40~8/PageSettingsGuiMods.qml index 0e85c757..50a2393d 120000 --- a/FileSets/v3.40~8/PageSettingsGuiMods.qml +++ b/FileSets/v3.40~8/PageSettingsGuiMods.qml @@ -1 +1 @@ -../v3.40~10/PageSettingsGuiMods.qml \ No newline at end of file +../v3.40~11/PageSettingsGuiMods.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/PageSettingsRelay.qml b/FileSets/v3.40~8/PageSettingsRelay.qml index 72de1197..337482f3 120000 --- a/FileSets/v3.40~8/PageSettingsRelay.qml +++ b/FileSets/v3.40~8/PageSettingsRelay.qml @@ -1 +1 @@ -../v3.40~10/PageSettingsRelay.qml \ No newline at end of file +../v3.40~11/PageSettingsRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/Tile.qml b/FileSets/v3.40~8/Tile.qml index ac462f2e..5c566101 120000 --- a/FileSets/v3.40~8/Tile.qml +++ b/FileSets/v3.40~8/Tile.qml @@ -1 +1 @@ -../v3.40~10/Tile.qml \ No newline at end of file +../v3.40~11/Tile.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/TileDigIn.qml b/FileSets/v3.40~8/TileDigIn.qml index ff43ea83..fc269e05 120000 --- a/FileSets/v3.40~8/TileDigIn.qml +++ b/FileSets/v3.40~8/TileDigIn.qml @@ -1 +1 @@ -../v3.40~10/TileDigIn.qml \ No newline at end of file +../v3.40~11/TileDigIn.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/TileRelay.qml b/FileSets/v3.40~8/TileRelay.qml index 7e3866d3..2ebdf179 120000 --- a/FileSets/v3.40~8/TileRelay.qml +++ b/FileSets/v3.40~8/TileRelay.qml @@ -1 +1 @@ -../v3.40~10/TileRelay.qml \ No newline at end of file +../v3.40~11/TileRelay.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/TileText.qml b/FileSets/v3.40~8/TileText.qml index 53bab235..e5901c0b 120000 --- a/FileSets/v3.40~8/TileText.qml +++ b/FileSets/v3.40~8/TileText.qml @@ -1 +1 @@ -../v3.40~10/TileText.qml \ No newline at end of file +../v3.40~11/TileText.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/attributes.csv b/FileSets/v3.40~8/attributes.csv index e2ed133a..e4d1dc3a 120000 --- a/FileSets/v3.40~8/attributes.csv +++ b/FileSets/v3.40~8/attributes.csv @@ -1 +1 @@ -../v3.40~10/attributes.csv \ No newline at end of file +../v3.40~11/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 index bdaa4e12..085682ce 120000 --- a/FileSets/v3.40~8/dbus_digitalinputs.py +++ b/FileSets/v3.40~8/dbus_digitalinputs.py @@ -1 +1 @@ -../v3.40~10/dbus_digitalinputs.py \ No newline at end of file +../v3.40~11/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 index 12899ddc..699b4b49 120000 --- a/FileSets/v3.40~8/dbus_generator.py +++ b/FileSets/v3.40~8/dbus_generator.py @@ -1 +1 @@ -../v3.40~10/dbus_generator.py \ No newline at end of file +../v3.40~11/dbus_generator.py \ No newline at end of file diff --git a/FileSets/v3.40~8/main.qml b/FileSets/v3.40~8/main.qml index 749f83e6..223531e7 120000 --- a/FileSets/v3.40~8/main.qml +++ b/FileSets/v3.40~8/main.qml @@ -1 +1 @@ -../v3.40~10/main.qml \ No newline at end of file +../v3.40~11/main.qml \ No newline at end of file diff --git a/FileSets/v3.40~8/startstop.py b/FileSets/v3.40~8/startstop.py index d2ea898a..c84f296d 120000 --- a/FileSets/v3.40~8/startstop.py +++ b/FileSets/v3.40~8/startstop.py @@ -1 +1 @@ -../v3.40~10/startstop.py \ No newline at end of file +../v3.40~11/startstop.py \ No newline at end of file diff --git a/FileSets/v3.40~8/styles.css b/FileSets/v3.40~8/styles.css index 7851b50d..2a980b7d 120000 --- a/FileSets/v3.40~8/styles.css +++ b/FileSets/v3.40~8/styles.css @@ -1 +1 @@ -../v3.40~10/styles.css \ No newline at end of file +../v3.40~11/styles.css \ No newline at end of file diff --git a/changes b/changes index 79efe83f..f67b6ca5 100644 --- a/changes +++ b/changes @@ -1,3 +1,6 @@ +v10.25: + add support for v3.40~11 + v10.24: add support for v3.40~10 diff --git a/version b/version index c333e13b..bce82013 100644 --- a/version +++ b/version @@ -1 +1 @@ -v10.24 +v10.25