From cdb3cbf8bd90cfcef669dccbcdd84011be0e50e7 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Wed, 26 Jun 2024 15:03:50 +1000 Subject: [PATCH] Do not show invalid devices in the Device List Invalid devices may still have a valid /DeviceInstance, so tighten the device validity check to also test for /ProductId and /ProductName. Do the validity check in BaseDevice so that the test condition is the same for all devices. Fixes #1233 --- components/Device.qml | 11 ++++--- data/common/InverterCharger.qml | 5 --- data/common/Tank.qml | 3 +- data/mock/AcInputsImpl.qml | 4 --- data/mock/AcSystemDevicesImpl.qml | 1 + data/mock/ChargersImpl.qml | 1 + data/mock/DcInputsImpl.qml | 10 +++--- data/mock/DcLoadsImpl.qml | 1 + data/mock/EnvironmentInputsImpl.qml | 1 + data/mock/GeneratorsImpl.qml | 1 + data/mock/PvInvertersImpl.qml | 1 + data/mock/SolarChargersImpl.qml | 1 + data/mock/TanksImpl.qml | 1 + src/basedevicemodel.cpp | 47 +++++++++++++++++++++++++++++ src/basedevicemodel.h | 16 ++++++++++ 15 files changed, 83 insertions(+), 21 deletions(-) diff --git a/components/Device.qml b/components/Device.qml index 30937c299..4524cc41f 100644 --- a/components/Device.qml +++ b/components/Device.qml @@ -9,10 +9,7 @@ import Victron.VenusOS BaseDevice { id: root - property bool valid: deviceInstance >= 0 - readonly property string customName: _customName.value || "" - readonly property string productName: _productName.value || "" readonly property VeQuickItem _deviceInstance: VeQuickItem { uid: root.serviceUid ? root.serviceUid + "/DeviceInstance" : "" @@ -22,11 +19,17 @@ BaseDevice { uid: root.serviceUid ? root.serviceUid + "/CustomName" : "" } + readonly property VeQuickItem _productId: VeQuickItem { + uid: root.serviceUid ? root.serviceUid + "/ProductId" : "" + } + readonly property VeQuickItem _productName: VeQuickItem { uid: root.serviceUid ? root.serviceUid + "/ProductName" : "" } - deviceInstance: _deviceInstance.value === undefined ? -1 : _deviceInstance.value + deviceInstance: _deviceInstance.isValid ? _deviceInstance.value : -1 + productId: _productId.isValid ? _productId.value : 0 + productName: _productName.value || "" name: _customName.value || _productName.value || "" description: name } diff --git a/data/common/InverterCharger.qml b/data/common/InverterCharger.qml index 77f6ca47c..96f1b58d6 100644 --- a/data/common/InverterCharger.qml +++ b/data/common/InverterCharger.qml @@ -23,7 +23,6 @@ Device { numberOfAcInputs: _numberOfAcInputs.value || 0 } - readonly property int productId: _productId.value === undefined ? -1 : _productId.value readonly property int productType: _productUpperByte === 0x19 || _productUpperByte === 0x26 ? VenusOS.VeBusDevice_ProductType_EuProduct : (_productUpperByte === 0x20 || _productUpperByte === 0x27 ? VenusOS.VeBusDevice_ProductType_UsProduct : -1) @@ -43,10 +42,6 @@ Device { uid: inverterCharger.serviceUid + "/State" } - readonly property VeQuickItem _productId: VeQuickItem { - uid: inverterCharger.serviceUid + "/ProductId" - } - readonly property VeQuickItem _nominalInverterPower: VeQuickItem { uid: inverterCharger.serviceUid + "/Ac/Out/NominalInverterPower" onValueChanged: if (!!Global.inverterChargers) Global.inverterChargers.refreshNominalInverterPower() diff --git a/data/common/Tank.qml b/data/common/Tank.qml index 24a6cfab1..580869fd3 100644 --- a/data/common/Tank.qml +++ b/data/common/Tank.qml @@ -44,12 +44,11 @@ Device { Component.onCompleted: Qt.callLater(tank._updateMeasurements) } - valid: deviceInstance >= 0 && type >= 0 onValidChanged: Qt.callLater(tank._updateModel) onTypeChanged: Qt.callLater(tank._updateModel) function _updateModel() { - if (valid) { + if (valid && type >= 0) { if (_tankModel && _tankModel.type !== type) { _tankModel.removeDevice(tank.serviceUid) } diff --git a/data/mock/AcInputsImpl.qml b/data/mock/AcInputsImpl.qml index a1a77e280..1b9fbc682 100644 --- a/data/mock/AcInputsImpl.qml +++ b/data/mock/AcInputsImpl.qml @@ -86,10 +86,6 @@ QtObject { required property var modelData readonly property Device device: Device { - readonly property VeQuickItem _productId: VeQuickItem { - uid: device.serviceUid ? device.serviceUid + "/ProductId" : "" - } - Component.onCompleted: { serviceUid = "mock/" + input.modelData["serviceName"] _deviceInstance.setValue(input.index) diff --git a/data/mock/AcSystemDevicesImpl.qml b/data/mock/AcSystemDevicesImpl.qml index 9eb91b9b2..6856b1720 100644 --- a/data/mock/AcSystemDevicesImpl.qml +++ b/data/mock/AcSystemDevicesImpl.qml @@ -67,6 +67,7 @@ Item { serviceUid = "mock/com.victronenergy.acsystem.ttyUSB" + deviceInstanceNum _deviceInstance.setValue(deviceInstanceNum) _productName.setValue("RS 48/6000") + _productId.setValue(123) _customName.setValue("AC System " + deviceInstanceNum) acSystem.setMockValue("/Ac/NumberOfPhases", 3) acSystem.setMockValue("/Ac/NumberOfAcInputs", 2) diff --git a/data/mock/ChargersImpl.qml b/data/mock/ChargersImpl.qml index 95295a190..d85e56fc7 100644 --- a/data/mock/ChargersImpl.qml +++ b/data/mock/ChargersImpl.qml @@ -46,6 +46,7 @@ Item { serviceUid = "mock/com.victronenergy.charger.ttyUSB" + deviceInstanceNum _deviceInstance.setValue(deviceInstanceNum) _customName.setValue("AC Charger " + deviceInstanceNum) + _productId.setValue(123) charger.setMockValue("/Mode", 1) charger.setMockValue("/State", Math.floor(Math.random() * VenusOS.System_State_FaultCondition)) charger.setMockValue("/Ac/In/CurrentLimit", Math.random() * 30) diff --git a/data/mock/DcInputsImpl.qml b/data/mock/DcInputsImpl.qml index 6ad05779f..af1063623 100644 --- a/data/mock/DcInputsImpl.qml +++ b/data/mock/DcInputsImpl.qml @@ -91,12 +91,9 @@ QtObject { } } - property VeQuickItem _productId: VeQuickItem { - uid: input.serviceUid + "/ProductId" - onValueChanged: { - if (value === 0xA3F0) { - initOrionXSValues() - } + onProductIdChanged: { + if (productId === 0xA3F0) { + initOrionXSValues() } } @@ -142,6 +139,7 @@ QtObject { serviceUid = "mock/com.victronenergy." + serviceType + ".ttyUSB" + deviceInstanceNum _deviceInstance.setValue(deviceInstanceNum) _productName.setValue("DC device (%1)".arg(serviceType)) + _productId.setValue(123) setMockValue("/State", 4) } } diff --git a/data/mock/DcLoadsImpl.qml b/data/mock/DcLoadsImpl.qml index 0b07dfae5..8977b934c 100644 --- a/data/mock/DcLoadsImpl.qml +++ b/data/mock/DcLoadsImpl.qml @@ -68,6 +68,7 @@ QtObject { serviceUid = "mock/com.victronenergy." + serviceType + ".ttyUSB" + deviceInstanceNum _deviceInstance.setValue(deviceInstanceNum) _productName.setValue("DC Load (%1)".arg(serviceType)) + _productId.setValue(123) setMockValue("/Mode", 4) setMockValue("/State", 5) setMockValue("/Error", 0) diff --git a/data/mock/EnvironmentInputsImpl.qml b/data/mock/EnvironmentInputsImpl.qml index b6123c382..2df3a269f 100644 --- a/data/mock/EnvironmentInputsImpl.qml +++ b/data/mock/EnvironmentInputsImpl.qml @@ -62,6 +62,7 @@ Item { serviceUid = "mock/com.victronenergy.temperature.ttyUSB" + deviceInstanceNum _deviceInstance.setValue(deviceInstanceNum) _productName.setValue("Generic Temperature Sensor") + _productId.setValue(123) _status.setValue(VenusOS.EnvironmentInput_Status_Ok) } diff --git a/data/mock/GeneratorsImpl.qml b/data/mock/GeneratorsImpl.qml index 16e4a09d3..42aeeaea6 100644 --- a/data/mock/GeneratorsImpl.qml +++ b/data/mock/GeneratorsImpl.qml @@ -31,6 +31,7 @@ QtObject { Component.onCompleted: { _deviceInstance.setValue(0) _productName.setValue("Start/Stop generator") + _productId.setValue(123) _state.setValue(VenusOS.Generators_State_Running) _runningBy.setValue(VenusOS.Generators_RunningBy_Soc) setAutoStart(true) diff --git a/data/mock/PvInvertersImpl.qml b/data/mock/PvInvertersImpl.qml index e78a632a5..8006f8fbf 100644 --- a/data/mock/PvInvertersImpl.qml +++ b/data/mock/PvInvertersImpl.qml @@ -75,6 +75,7 @@ QtObject { serviceUid = "mock/com.victronenergy.pvinverter.ttyUSB" + deviceInstanceNum _deviceInstance.setValue(deviceInstanceNum) _productName.setValue("PV Inverter") + _productId.setValue(123) _customName.setValue("My PV Inverter " + deviceInstanceNum) _statusCode.setValue(Math.random() * VenusOS.PvInverter_StatusCode_Error) diff --git a/data/mock/SolarChargersImpl.qml b/data/mock/SolarChargersImpl.qml index 9a326ba38..1f632b677 100644 --- a/data/mock/SolarChargersImpl.qml +++ b/data/mock/SolarChargersImpl.qml @@ -168,6 +168,7 @@ QtObject { serviceUid = "mock/com.victronenergy.solarcharger.ttyUSB" + deviceInstanceNum _deviceInstance.setValue(deviceInstanceNum) _productName.setValue("SmartSolar Charger MPPT 100/50") + _productId.setValue(123) _customName.setValue("My Solar Charger " + deviceInstanceNum) _state.setValue(VenusOS.SolarCharger_State_ExternalControl) _errorCode.setValue(0) diff --git a/data/mock/TanksImpl.qml b/data/mock/TanksImpl.qml index 335935def..a7c171971 100644 --- a/data/mock/TanksImpl.qml +++ b/data/mock/TanksImpl.qml @@ -67,6 +67,7 @@ QtObject { serviceUid = "mock/com.victronenergy.tank.ttyUSB" + deviceInstanceNum _deviceInstance.setValue(deviceInstanceNum) _productName.setValue("Generic Tank Input") + _productId.setValue(123) _status.setValue(VenusOS.Tank_Status_Ok) } diff --git a/src/basedevicemodel.cpp b/src/basedevicemodel.cpp index 066fba621..c89b2bfca 100644 --- a/src/basedevicemodel.cpp +++ b/src/basedevicemodel.cpp @@ -15,6 +15,11 @@ BaseDevice::BaseDevice(QObject *parent) { } +bool BaseDevice::isValid() const +{ + return !m_serviceUid.isEmpty() && !m_productName.isEmpty() && m_deviceInstance >= 0 && m_productId > 0; +} + QString BaseDevice::serviceUid() const { return m_serviceUid; @@ -23,8 +28,12 @@ QString BaseDevice::serviceUid() const void BaseDevice::setServiceUid(const QString &serviceUid) { if (m_serviceUid != serviceUid) { + const bool prevValid = isValid(); m_serviceUid = serviceUid; emit serviceUidChanged(); + if (prevValid != isValid()) { + emit validChanged(); + } } } @@ -36,8 +45,46 @@ int BaseDevice::deviceInstance() const void BaseDevice::setDeviceInstance(int deviceInstance) { if (m_deviceInstance != deviceInstance) { + const bool prevValid = isValid(); m_deviceInstance = deviceInstance; emit deviceInstanceChanged(); + if (prevValid != isValid()) { + emit validChanged(); + } + } +} + +int BaseDevice::productId() const +{ + return m_productId; +} + +void BaseDevice::setProductId(int productId) +{ + if (m_productId != productId) { + const bool prevValid = isValid(); + m_productId = productId; + emit productIdChanged(); + if (prevValid != isValid()) { + emit validChanged(); + } + } +} + +QString BaseDevice::productName() const +{ + return m_productName; +} + +void BaseDevice::setProductName(const QString &productName) +{ + if (m_productName != productName) { + const bool prevValid = isValid(); + m_productName = productName; + emit productNameChanged(); + if (prevValid != isValid()) { + emit validChanged(); + } } } diff --git a/src/basedevicemodel.h b/src/basedevicemodel.h index c65395289..9b1c6ca82 100644 --- a/src/basedevicemodel.h +++ b/src/basedevicemodel.h @@ -18,20 +18,31 @@ class BaseDevice : public QObject { Q_OBJECT QML_ELEMENT + Q_PROPERTY(bool valid READ isValid NOTIFY validChanged) Q_PROPERTY(QString serviceUid READ serviceUid WRITE setServiceUid NOTIFY serviceUidChanged) Q_PROPERTY(int deviceInstance READ deviceInstance WRITE setDeviceInstance NOTIFY deviceInstanceChanged) + Q_PROPERTY(int productId READ productId WRITE setProductId NOTIFY productIdChanged) + Q_PROPERTY(QString productName READ productName WRITE setProductName NOTIFY productNameChanged) Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged) public: explicit BaseDevice(QObject *parent = nullptr); + bool isValid() const; + QString serviceUid() const; void setServiceUid(const QString &serviceUid); int deviceInstance() const; void setDeviceInstance(int deviceInstance); + int productId() const; + void setProductId(int productId); + + QString productName() const; + void setProductName(const QString &productName); + QString name() const; void setName(const QString &name); @@ -39,8 +50,11 @@ class BaseDevice : public QObject void setDescription(const QString &description); Q_SIGNALS: + void validChanged(); void serviceUidChanged(); void deviceInstanceChanged(); + void productNameChanged(); + void productIdChanged(); void nameChanged(); void descriptionChanged(); @@ -48,7 +62,9 @@ class BaseDevice : public QObject QString m_serviceUid; QString m_name; QString m_description; + QString m_productName; int m_deviceInstance = -1; + int m_productId = 0; };