Skip to content

Commit

Permalink
Show all com.victronenergy.battery services in Device List
Browse files Browse the repository at this point in the history
gui-v2 need two separate battery lists, like this:

- In the Overview Battery drilldown, show all batteries from the list
in com.victronenergy.system/Batteries
- In the Device List, show all battery services under
com.victronenergy.battery.*

Fix Global.batteries.model to contain all battery services under
com.victronenergy.battery.*. The Overview Battery list can be created
specifically when requested, when the Battery widget is clicked.

Fixes regression from 5ebe756.

Fixes #1357
  • Loading branch information
blammit committed Aug 1, 2024
1 parent 3cd751a commit b68f912
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 49 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,7 @@ endif()
# Dbus_QML_MODULE
set(Dbus_QML_MODULE_SOURCES
data/dbus/AcSystemDevicesImpl.qml
data/dbus/BatteriesImpl.qml
data/dbus/ChargersImpl.qml
data/dbus/DBusDataManager.qml
data/dbus/DcInputsImpl.qml
Expand Down Expand Up @@ -926,6 +927,7 @@ endif()
# Mqtt_QML_MODULE
set(Mqtt_QML_MODULE_SOURCES
data/mqtt/AcSystemDevicesImpl.qml
data/mqtt/BatteriesImpl.qml
data/mqtt/ChargersImpl.qml
data/mqtt/DcInputsImpl.qml
data/mqtt/DcLoadsImpl.qml
Expand Down
33 changes: 23 additions & 10 deletions components/widgets/BatteryWidget.qml
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,34 @@ OverviewWidget {
id: root

onClicked: {
if (Global.batteries.model.count === 1) {
const firstBattery = Global.batteries.model.firstObject
if (BackendConnection.serviceTypeFromUid(firstBattery.serviceUid) === "vebus") {
const deviceIndex = Global.inverterChargers.veBusDevices.indexOf(firstBattery.serviceUid)
// If com.victronenergy.system/Batteries has only one battery, then show the device
// settings for that battery; otherwise, show the full battery list using BatteryListPage.
if (batteries.value.length === 1) {
const batteryUids = batteries.value.map((info) => BackendConnection.serviceUidFromName(info.id, info.instance))

// Show the vebus page if the battery is from a vebus service.
if (BackendConnection.serviceTypeFromUid(batteryUids[0]) === "vebus") {
const deviceIndex = Global.inverterChargers.veBusDevices.indexOf(batteryUids[0])
if (deviceIndex >= 0) {
const veBusDevice = Global.inverterChargers.veBusDevices.deviceAt(deviceIndex)
Global.pageManager.pushPage( "/pages/vebusdevice/PageVeBus.qml", {
"title": veBusDevice.name,
"veBusDevice": veBusDevice
})
return
}
return
}

// Assume this is a battery service
Global.pageManager.pushPage("/pages/settings/devicelist/battery/PageBattery.qml",
{ "battery": firstBattery })
} else {
Global.pageManager.pushPage("/pages/battery/BatteryListPage.qml")
const batteryIndex = Global.batteries.model.indexOf(batteryUids[0])
if (batteryIndex >= 0) {
Global.pageManager.pushPage("/pages/settings/devicelist/battery/PageBattery.qml",
{ "battery": Global.batteries.model.deviceAt(batteryIndex) })
return
}
}

Global.pageManager.pushPage("/pages/battery/BatteryListPage.qml")
}

readonly property var batteryData: Global.batteries.system
Expand Down Expand Up @@ -60,10 +68,15 @@ OverviewWidget {
font.family: Global.quantityFontFamily
}

VeQuickItem {
id: batteries
uid: Global.system.serviceUid + "/Batteries"
}

title: CommonWords.battery
icon.source: batteryData.icon
type: VenusOS.OverviewWidget_Type_Battery
enabled: Global.batteries.model.count > 0
enabled: batteries.isValid

quantityLabel.value: batteryData.stateOfCharge
quantityLabel.unit: VenusOS.Units_Percentage
Expand Down
38 changes: 0 additions & 38 deletions data/Batteries.qml
Original file line number Diff line number Diff line change
Expand Up @@ -64,43 +64,5 @@ QtObject {
}
}

readonly property VeQuickItem _batteries: VeQuickItem {
uid: Global.system.serviceUid + "/Batteries"
onValueChanged: {
let i
if (!isValid) {
root.model.deleteAllAndClear()
return
}
// Value is a list of key-value pairs with info about each battery.
const batteryUids = value.map((info) => BackendConnection.serviceUidFromName(info.id, info.instance))

// Remove batteries from Global.batteries.model that are not in this list
root.model.intersect(batteryUids)

// Add new entries to Global.batteries.model
for (i = 0; i < batteryUids.length; ++i) {
if (root.model.indexOf(batteryUids[i]) < 0) {
_batteryComponent.createObject(root, { serviceUid: batteryUids[i] })
}
}
}
}

property Component _batteryComponent: Component {
Battery {
id: battery

onValidChanged: {
if (valid) {
root.addBattery(battery)
} else {
root.removeBattery(battery.serviceUid)
battery.destroy()
}
}
}
}

Component.onCompleted: Global.batteries = root
}
33 changes: 33 additions & 0 deletions data/dbus/BatteriesImpl.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
** Copyright (C) 2023 Victron Energy B.V.
** See LICENSE.txt for license information.
*/

import QtQuick
import Victron.VenusOS

QtObject {
property Instantiator batteryObjects: Instantiator {
model: VeQItemSortTableModel {
dynamicSortFilter: true
filterRole: VeQItemTableModel.UniqueIdRole
filterRegExp: "^dbus/com\.victronenergy\.battery\."
model: Global.dataServiceModel
}

delegate: Battery {
id: battery
serviceUid: model.uid

onValidChanged: {
if (!!Global.batteries) {
if (valid) {
Global.batteries.addBattery(battery)
} else {
Global.batteries.removeBattery(battery)
}
}
}
}
}
}
1 change: 1 addition & 0 deletions data/dbus/DBusDataManager.qml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ QtObject {

property var acSystemDevices: AcSystemDevicesImpl { }
property var chargers: ChargersImpl { }
property var batteries: BatteriesImpl { }
property var dcInputs: DcInputsImpl { }
property var dcLoads: DcLoadsImpl { }
property var digitalInputs: DigitalInputsImpl {}
Expand Down
1 change: 1 addition & 0 deletions data/mock/BatteriesImpl.qml
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ QtObject {
root.initLynxBattery(dummyBattery)

Global.batteries.system = dummyBattery
Global.batteries.addBattery(dummyBattery)

const batteryList = [{
id: "com.victronenergy.battery.ttyUSB1",
Expand Down
31 changes: 31 additions & 0 deletions data/mqtt/BatteriesImpl.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
** Copyright (C) 2023 Victron Energy B.V.
** See LICENSE.txt for license information.
*/

import QtQuick
import Victron.VenusOS

QtObject {
property Instantiator batteryObjects: Instantiator {
model: VeQItemTableModel {
uids: ["mqtt/battery"]
flags: VeQItemTableModel.AddChildren | VeQItemTableModel.AddNonLeaves | VeQItemTableModel.DontAddItem
}

delegate: Battery {
id: battery
serviceUid: model.uid

onValidChanged: {
if (!!Global.batteries) {
if (valid) {
Global.batteries.addBattery(battery)
} else {
Global.batteries.removeBattery(battery)
}
}
}
}
}
}
1 change: 1 addition & 0 deletions data/mqtt/MqttDataManager.qml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ QtObject {

property var acSystemDevices: AcSystemDevicesImpl { }
property var chargers: ChargersImpl { }
property var batteries: BatteriesImpl { }
property var dcInputs: DcInputsImpl { }
property var dcLoads: DcLoadsImpl { }
property var digitalInputs: DigitalInputsImpl {}
Expand Down
47 changes: 46 additions & 1 deletion pages/battery/BatteryListPage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Page {
id: root

GradientListView {
model: Global.batteries.model
model: batteryModel
spacing: Theme.geometry_gradientList_spacing
delegate: ListItemBackground {
height: Theme.geometry_batteryListPage_item_height
Expand Down Expand Up @@ -127,4 +127,49 @@ Page {
}
}
}

// A model of Battery objects, generated from com.victronenergy.system/Batteries.
DeviceModel {
id: batteryModel
}

VeQuickItem {
uid: Global.system.serviceUid + "/Batteries"
onValueChanged: {
let i
if (!isValid) {
batteryModel.deleteAllAndClear()
return
}
// Value is a list of key-value pairs with info about each battery.
const batteryUids = value.map((info) => BackendConnection.serviceUidFromName(info.id, info.instance))

// Remove batteries that are not in this list
batteryModel.intersect(batteryUids)

// Add new battery objects
for (i = 0; i < batteryUids.length; ++i) {
if (batteryModel.indexOf(batteryUids[i]) < 0) {
batteryComponent.createObject(batteryModel, { serviceUid: batteryUids[i] })
}
}
}
}

Component {
id: batteryComponent

Battery {
id: battery

onValidChanged: {
if (valid) {
batteryModel.addDevice(battery)
} else {
batteryModel.removeDevice(battery.serviceUid)
battery.destroy()
}
}
}
}
}

0 comments on commit b68f912

Please sign in to comment.