Skip to content

Commit e29ecf2

Browse files
committed
bluetooth: normalize signal strength instead of raw rssi
1 parent 154a116 commit e29ecf2

File tree

3 files changed

+33
-18
lines changed

3 files changed

+33
-18
lines changed

src/bluetooth/device.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "device.hpp"
2+
#include <algorithm>
23

34
#include <qcontainerfwd.h>
45
#include <qdbusconnection.h>
@@ -46,12 +47,35 @@ BluetoothDevice::BluetoothDevice(const QString& path, QObject* parent): QObject(
4647
}
4748

4849
this->properties.setInterface(this->mInterface);
50+
51+
this->bRssi.subscribe([this]() { emit this->signalStrengthChanged(); });
4952
}
5053

5154
BluetoothAdapter* BluetoothDevice::adapter() const {
5255
return Bluez::instance()->adapter(this->bAdapterPath.value().path());
5356
}
5457

58+
qint32 BluetoothDevice::signalStrength() const {
59+
// Convert RSSI (dBm) to a normalized 0-100 scale
60+
// Based on practical Bluetooth RSSI ranges:
61+
// -30 to -40 dBm = 85-100
62+
// -40 to -55 dBm = 65-85
63+
// -55 to -65 dBm = 45-65
64+
// -65 to -75 dBm = 25-45
65+
// -75 to -85 dBm = 10-25
66+
// <= -85 dBm = 0-10
67+
68+
auto rssiValue = this->bRssi.value();
69+
if (rssiValue == 0) {
70+
return 0;
71+
}
72+
73+
auto rssi = std::max(static_cast<qint16>(-100), std::min(static_cast<qint16>(-30), rssiValue));
74+
auto normalized = static_cast<qint32>(((rssi + 100) / 70.0) * 100.0);
75+
76+
return std::max(0, std::min(100, normalized));
77+
}
78+
5579
void BluetoothDevice::setConnected(bool connected) {
5680
if (connected == this->bConnected) return;
5781

src/bluetooth/device.hpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,8 @@ class BluetoothDevice: public QObject {
9999
Q_PROPERTY(bool batteryAvailable READ batteryAvailable NOTIFY batteryAvailableChanged);
100100
/// Battery level of the connected device, from `0.0` to `1.0`. Only valid if @@batteryAvailable is true.
101101
Q_PROPERTY(qreal battery READ default NOTIFY batteryChanged BINDABLE bindableBattery);
102-
/// Received Signal Strength Indicator in dBm. Only valid when device is discoverable/advertising.
103-
/// Typical values range from -30 (very close) to -90 (far away). Values of 0 indicate no signal data.
104-
Q_PROPERTY(qint16 rssi READ rssi NOTIFY rssiChanged BINDABLE bindableRssi);
102+
/// Signal strength as a normalized score from 0 to 100, where higher is better (stronger signal).
103+
Q_PROPERTY(qint32 signalStrength READ signalStrength NOTIFY signalStrengthChanged BINDABLE bindableSignalStrength);
105104
/// The Bluetooth adapter this device belongs to.
106105
Q_PROPERTY(BluetoothAdapter* adapter READ adapter NOTIFY adapterChanged);
107106
/// DBus path of the device under the `org.bluez` system service.
@@ -148,7 +147,7 @@ class BluetoothDevice: public QObject {
148147
[[nodiscard]] bool wakeAllowed() const { return this->bWakeAllowed; }
149148
void setWakeAllowed(bool wakeAllowed);
150149

151-
[[nodiscard]] qint16 rssi() const { return this->bRssi; }
150+
[[nodiscard]] qint32 signalStrength() const;
152151

153152
[[nodiscard]] bool pairing() const { return this->bPairing; }
154153

@@ -164,7 +163,7 @@ class BluetoothDevice: public QObject {
164163
[[nodiscard]] QBindable<QString> bindableIcon() { return &this->bIcon; }
165164
[[nodiscard]] QBindable<qreal> bindableBattery() { return &this->bBattery; }
166165
[[nodiscard]] QBindable<BluetoothDeviceState::Enum> bindableState() { return &this->bState; }
167-
[[nodiscard]] QBindable<qint16> bindableRssi() { return &this->bRssi; }
166+
[[nodiscard]] QBindable<qint32> bindableSignalStrength() { return &this->bSignalStrength; }
168167

169168
void addInterface(const QString& interface, const QVariantMap& properties);
170169
void removeInterface(const QString& interface);
@@ -184,7 +183,7 @@ class BluetoothDevice: public QObject {
184183
void iconChanged();
185184
void batteryAvailableChanged();
186185
void batteryChanged();
187-
void rssiChanged();
186+
void signalStrengthChanged();
188187
void adapterChanged();
189188

190189
private:
@@ -208,7 +207,8 @@ class BluetoothDevice: public QObject {
208207
Q_OBJECT_BINDABLE_PROPERTY(BluetoothDevice, qreal, bBattery, &BluetoothDevice::batteryChanged);
209208
Q_OBJECT_BINDABLE_PROPERTY(BluetoothDevice, BluetoothDeviceState::Enum, bState, &BluetoothDevice::stateChanged);
210209
Q_OBJECT_BINDABLE_PROPERTY(BluetoothDevice, bool, bPairing, &BluetoothDevice::pairingChanged);
211-
Q_OBJECT_BINDABLE_PROPERTY(BluetoothDevice, qint16, bRssi, &BluetoothDevice::rssiChanged);
210+
Q_OBJECT_BINDABLE_PROPERTY(BluetoothDevice, qint32, bSignalStrength, &BluetoothDevice::signalStrengthChanged);
211+
Q_OBJECT_BINDABLE_PROPERTY(BluetoothDevice, qint16, bRssi);
212212

213213
QS_DBUS_BINDABLE_PROPERTY_GROUP(BluetoothDevice, properties);
214214
QS_DBUS_PROPERTY_BINDING(BluetoothDevice, pAddress, bAddress, properties, "Address");

src/dbus/properties.cpp

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -248,17 +248,8 @@ void DBusPropertyGroup::requestPropertyUpdate(DBusPropertyCore* property) {
248248
const QDBusPendingReply<QDBusVariant> reply = *call;
249249

250250
if (reply.isError()) {
251-
const auto& error = reply.error();
252-
// For optional properties, suppress "No such property" errors specifically
253-
if (!property->isRequired() && error.type() == QDBusError::InvalidArgs
254-
&& error.message().contains("No such property"))
255-
{
256-
qCDebug(logDbusProperties).noquote() << "Error updating optional property" << propStr;
257-
qCDebug(logDbusProperties) << error;
258-
} else {
259-
qCWarning(logDbusProperties).noquote() << "Error updating property" << propStr;
260-
qCWarning(logDbusProperties) << error;
261-
}
251+
qCWarning(logDbusProperties).noquote() << "Error updating property" << propStr;
252+
qCWarning(logDbusProperties) << reply.error();
262253
} else {
263254
this->tryUpdateProperty(property, reply.value().variant());
264255
}

0 commit comments

Comments
 (0)