diff --git a/src/bluetooth/device.cpp b/src/bluetooth/device.cpp index 7265b24..306ea31 100644 --- a/src/bluetooth/device.cpp +++ b/src/bluetooth/device.cpp @@ -1,4 +1,5 @@ #include "device.hpp" +#include #include #include @@ -46,12 +47,33 @@ BluetoothDevice::BluetoothDevice(const QString& path, QObject* parent): QObject( } this->properties.setInterface(this->mInterface); + + this->bRssi.subscribe([this]() { emit this->signalStrengthChanged(); }); } BluetoothAdapter* BluetoothDevice::adapter() const { return Bluez::instance()->adapter(this->bAdapterPath.value().path()); } +qint32 BluetoothDevice::signalStrength() const { + const auto rssi = this->bRssi.value(); + auto percent = 0.0; + + if (rssi == 0) { + percent = 0.0; + } else if (rssi >= -30) { + percent = 100.0; + } else if (rssi >= -60) { + percent = 75.0 + ((rssi + 60.0) / 30.0) * 25.0; + } else if (rssi >= -80) { + percent = 9.0 + ((rssi + 80.0) / 20.0) * 66.0; + } else if (rssi >= -90) { + percent = ((rssi + 90.0) / 10.0) * 9.0; + } + + return static_cast(std::lround(std::clamp(percent, 0.0, 100.0))); +} + void BluetoothDevice::setConnected(bool connected) { if (connected == this->bConnected) return; diff --git a/src/bluetooth/device.hpp b/src/bluetooth/device.hpp index 23f230f..9abacf6 100644 --- a/src/bluetooth/device.hpp +++ b/src/bluetooth/device.hpp @@ -99,6 +99,8 @@ class BluetoothDevice: public QObject { Q_PROPERTY(bool batteryAvailable READ batteryAvailable NOTIFY batteryAvailableChanged); /// Battery level of the connected device, from `0.0` to `1.0`. Only valid if @@batteryAvailable is true. Q_PROPERTY(qreal battery READ default NOTIFY batteryChanged BINDABLE bindableBattery); + /// Signal strength as a normalized score from 0 to 100, where higher is better (stronger signal). + Q_PROPERTY(qint32 signalStrength READ signalStrength NOTIFY signalStrengthChanged BINDABLE bindableSignalStrength); /// The Bluetooth adapter this device belongs to. Q_PROPERTY(BluetoothAdapter* adapter READ adapter NOTIFY adapterChanged); /// DBus path of the device under the `org.bluez` system service. @@ -145,6 +147,8 @@ class BluetoothDevice: public QObject { [[nodiscard]] bool wakeAllowed() const { return this->bWakeAllowed; } void setWakeAllowed(bool wakeAllowed); + [[nodiscard]] qint32 signalStrength() const; + [[nodiscard]] bool pairing() const { return this->bPairing; } [[nodiscard]] QBindable bindableAddress() { return &this->bAddress; } @@ -159,6 +163,7 @@ class BluetoothDevice: public QObject { [[nodiscard]] QBindable bindableIcon() { return &this->bIcon; } [[nodiscard]] QBindable bindableBattery() { return &this->bBattery; } [[nodiscard]] QBindable bindableState() { return &this->bState; } + [[nodiscard]] QBindable bindableSignalStrength() { return &this->bSignalStrength; } void addInterface(const QString& interface, const QVariantMap& properties); void removeInterface(const QString& interface); @@ -178,6 +183,7 @@ class BluetoothDevice: public QObject { void iconChanged(); void batteryAvailableChanged(); void batteryChanged(); + void signalStrengthChanged(); void adapterChanged(); private: @@ -201,6 +207,8 @@ class BluetoothDevice: public QObject { Q_OBJECT_BINDABLE_PROPERTY(BluetoothDevice, qreal, bBattery, &BluetoothDevice::batteryChanged); Q_OBJECT_BINDABLE_PROPERTY(BluetoothDevice, BluetoothDeviceState::Enum, bState, &BluetoothDevice::stateChanged); Q_OBJECT_BINDABLE_PROPERTY(BluetoothDevice, bool, bPairing, &BluetoothDevice::pairingChanged); + Q_OBJECT_BINDABLE_PROPERTY(BluetoothDevice, qint32, bSignalStrength, &BluetoothDevice::signalStrengthChanged); + Q_OBJECT_BINDABLE_PROPERTY(BluetoothDevice, qint16, bRssi); QS_DBUS_BINDABLE_PROPERTY_GROUP(BluetoothDevice, properties); QS_DBUS_PROPERTY_BINDING(BluetoothDevice, pAddress, bAddress, properties, "Address"); @@ -214,6 +222,7 @@ class BluetoothDevice: public QObject { QS_DBUS_PROPERTY_BINDING(BluetoothDevice, pWakeAllowed, bWakeAllowed, properties, "WakeAllowed"); QS_DBUS_PROPERTY_BINDING(BluetoothDevice, pIcon, bIcon, properties, "Icon"); QS_DBUS_PROPERTY_BINDING(BluetoothDevice, pAdapterPath, bAdapterPath, properties, "Adapter"); + QS_DBUS_PROPERTY_BINDING(BluetoothDevice, pRssi, bRssi, properties, "RSSI", false); QS_DBUS_BINDABLE_PROPERTY_GROUP(BluetoothDevice, batteryProperties); QS_DBUS_PROPERTY_BINDING(BluetoothDevice, BatteryPercentage, pBattery, bBattery, batteryProperties, "Percentage", true);