EQ-3: Add support for Bluetooth pairing
latest firmware of those devices requires BT pairing
This commit is contained in:
parent
8509e44104
commit
218017cacf
@ -426,16 +426,16 @@ void IntegrationPluginElgato::discoverThings(ThingDiscoveryInfo *info)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (const QBluetoothDeviceInfo &deviceInfo, reply->discoveredDevices()) {
|
foreach (const auto &deviceInfo, reply->discoveredDevices()) {
|
||||||
if (deviceInfo.name().contains("Avea")) {
|
if (deviceInfo.first.name().contains("Avea")) {
|
||||||
if (!verifyExistingDevices(deviceInfo)) {
|
if (!verifyExistingDevices(deviceInfo.first)) {
|
||||||
ThingDescriptor descriptor(aveaThingClassId, "Avea", deviceInfo.address().toString());
|
ThingDescriptor descriptor(aveaThingClassId, "Avea", deviceInfo.first.address().toString());
|
||||||
ParamList params;
|
ParamList params;
|
||||||
params.append(Param(aveaThingNameParamTypeId, deviceInfo.name()));
|
params.append(Param(aveaThingNameParamTypeId, deviceInfo.first.name()));
|
||||||
params.append(Param(aveaThingMacAddressParamTypeId, deviceInfo.address().toString()));
|
params.append(Param(aveaThingMacAddressParamTypeId, deviceInfo.first.address().toString()));
|
||||||
descriptor.setParams(params);
|
descriptor.setParams(params);
|
||||||
foreach (Thing *existingThing, myThings()) {
|
foreach (Thing *existingThing, myThings()) {
|
||||||
if (existingThing->paramValue(aveaThingMacAddressParamTypeId).toString() == deviceInfo.address().toString()) {
|
if (existingThing->paramValue(aveaThingMacAddressParamTypeId).toString() == deviceInfo.first.address().toString()) {
|
||||||
descriptor.setThingId(existingThing->id());
|
descriptor.setThingId(existingThing->id());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -549,17 +549,18 @@ void EqivaBluetoothDiscovery::deviceDiscoveryDone()
|
|||||||
BluetoothDiscoveryReply *reply = static_cast<BluetoothDiscoveryReply *>(sender());
|
BluetoothDiscoveryReply *reply = static_cast<BluetoothDiscoveryReply *>(sender());
|
||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
|
|
||||||
|
QList<EqivaBluetoothDiscovery::DiscoveryResult> results;
|
||||||
|
|
||||||
if (reply->error() != BluetoothDiscoveryReply::BluetoothDiscoveryReplyErrorNoError) {
|
if (reply->error() != BluetoothDiscoveryReply::BluetoothDiscoveryReplyErrorNoError) {
|
||||||
qCWarning(dcEQ3()) << "Bluetooth discovery error:" << reply->error();
|
qCWarning(dcEQ3()) << "Bluetooth discovery error:" << reply->error();
|
||||||
|
emit finished(results);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList results;
|
foreach (const auto &deviceInfo, reply->discoveredDevices()) {
|
||||||
|
qCDebug(dcEQ3()) << "Discovered Bluetooth device" << deviceInfo.first.name() << deviceInfo.first.address().toString();
|
||||||
foreach (const QBluetoothDeviceInfo &deviceInfo, reply->discoveredDevices()) {
|
if (deviceInfo.first.name().contains("CC-RT-BLE")) {
|
||||||
qCDebug(dcEQ3()) << "Discovered Bluetooth device" << deviceInfo.name() << deviceInfo.address().toString();
|
results.append({deviceInfo.first, deviceInfo.second});
|
||||||
if (deviceInfo.name().contains("CC-RT-BLE")) {
|
|
||||||
results.append(deviceInfo.address().toString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -133,6 +133,10 @@ class EqivaBluetoothDiscovery: public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
struct DiscoveryResult {
|
||||||
|
QBluetoothDeviceInfo deviceInfo;
|
||||||
|
QBluetoothHostInfo adapter;
|
||||||
|
};
|
||||||
EqivaBluetoothDiscovery(BluetoothLowEnergyManager *bluetoothManager, QObject *parent = nullptr);
|
EqivaBluetoothDiscovery(BluetoothLowEnergyManager *bluetoothManager, QObject *parent = nullptr);
|
||||||
|
|
||||||
bool startDiscovery();
|
bool startDiscovery();
|
||||||
@ -141,7 +145,7 @@ private slots:
|
|||||||
void deviceDiscoveryDone();
|
void deviceDiscoveryDone();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void finished(const QStringList &results);
|
void finished(const QList<DiscoveryResult> &results);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BluetoothLowEnergyManager *m_bluetoothManager = nullptr;
|
BluetoothLowEnergyManager *m_bluetoothManager = nullptr;
|
||||||
|
|||||||
@ -100,20 +100,19 @@ void IntegrationPluginEQ3::discoverThings(ThingDiscoveryInfo *info)
|
|||||||
connect(info, &QObject::destroyed, eqivaBluetoothDiscovery, &EqivaBluetoothDiscovery::deleteLater);
|
connect(info, &QObject::destroyed, eqivaBluetoothDiscovery, &EqivaBluetoothDiscovery::deleteLater);
|
||||||
|
|
||||||
// Discovery result handler
|
// Discovery result handler
|
||||||
connect(eqivaBluetoothDiscovery, &EqivaBluetoothDiscovery::finished, info, [this, info](const QStringList results){
|
connect(eqivaBluetoothDiscovery, &EqivaBluetoothDiscovery::finished, info, [this, info](const QList<EqivaBluetoothDiscovery::DiscoveryResult> results){
|
||||||
qCDebug(dcEQ3()) << "Discovery finished";
|
qCDebug(dcEQ3()) << "Discovery finished";
|
||||||
|
|
||||||
foreach (const QString &result, results) {
|
foreach (const EqivaBluetoothDiscovery::DiscoveryResult &result, results) {
|
||||||
qCDebug(dcEQ3()) << "Discovered EQ-3 device" << result;
|
qCDebug(dcEQ3()) << "Discovered EQ-3 device" << result.deviceInfo.address().toString();
|
||||||
ThingDescriptor descriptor(eqivaBluetoothThingClassId, "Eqiva Bluetooth Thermostat", result);
|
ThingDescriptor descriptor(eqivaBluetoothThingClassId, "Eqiva Bluetooth Thermostat", result.deviceInfo.address().toString() + " ( via " + result.adapter.address().toString() + ")");
|
||||||
ParamList params;
|
ParamList params;
|
||||||
params << Param(eqivaBluetoothThingMacAddressParamTypeId, result);
|
params << Param(eqivaBluetoothThingMacAddressParamTypeId, result.deviceInfo.address().toString());
|
||||||
|
params << Param(eqivaBluetoothThingAdapterParamTypeId, result.adapter.address().toString());
|
||||||
descriptor.setParams(params);
|
descriptor.setParams(params);
|
||||||
foreach (Thing* existingThing, myThings()) {
|
Thing *existingThing = myThings().findByParams(params);
|
||||||
if (existingThing->paramValue(eqivaBluetoothThingMacAddressParamTypeId).toString() == result) {
|
if (existingThing) {
|
||||||
descriptor.setThingId(existingThing->id());
|
descriptor.setThingId(existingThing->id());
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
info->addThingDescriptor(descriptor);
|
info->addThingDescriptor(descriptor);
|
||||||
}
|
}
|
||||||
@ -132,6 +131,36 @@ void IntegrationPluginEQ3::discoverThings(ThingDiscoveryInfo *info)
|
|||||||
info->finish(Thing::ThingErrorThingClassNotFound);
|
info->finish(Thing::ThingErrorThingClassNotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IntegrationPluginEQ3::startPairing(ThingPairingInfo *info)
|
||||||
|
{
|
||||||
|
qCDebug(dcEQ3()) << "Start pairing" << info->thingClassId();
|
||||||
|
info->finish(Thing::ThingErrorNoError, QT_TR_NOOP("Press and hold the rotary button on the device to obtain the passkey."));
|
||||||
|
}
|
||||||
|
|
||||||
|
void IntegrationPluginEQ3::confirmPairing(ThingPairingInfo *info, const QString &user, const QString &secret)
|
||||||
|
{
|
||||||
|
qCDebug(dcEQ3()) << "confirm" << info->thingName() << secret << user;
|
||||||
|
QBluetoothAddress device(info->params().paramValue(eqivaBluetoothThingMacAddressParamTypeId).toString());
|
||||||
|
QBluetoothAddress localDevice(info->params().paramValue(eqivaBluetoothThingAdapterParamTypeId).toString());
|
||||||
|
BluetoothPairingJob *job = hardwareManager()->bluetoothLowEnergyManager()->pairDevice(device, localDevice);
|
||||||
|
if (job->isFinished() && !job->success()) {
|
||||||
|
info->finish(Thing::ThingErrorHardwareFailure, QT_TR_NOOP("Unable to initiate pairing with Bluetooth device."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
connect(job, &BluetoothPairingJob::passKeyRequested, info, [secret, job](){
|
||||||
|
qCDebug(dcEQ3()) << "Pin code requested.";
|
||||||
|
job->passKeyEntered(secret);
|
||||||
|
});
|
||||||
|
connect(job, &BluetoothPairingJob::finished, info, [=](bool success){
|
||||||
|
if (!success) {
|
||||||
|
info->finish(Thing::ThingErrorHardwareFailure, QT_TR_NOOP("An error happened during Bluetooth pairing. Please try again."));
|
||||||
|
} else {
|
||||||
|
info->finish(Thing::ThingErrorNoError);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void IntegrationPluginEQ3::setupThing(ThingSetupInfo *info)
|
void IntegrationPluginEQ3::setupThing(ThingSetupInfo *info)
|
||||||
{
|
{
|
||||||
@ -231,6 +260,8 @@ void IntegrationPluginEQ3::thingRemoved(Thing *thing)
|
|||||||
|
|
||||||
if (thing->thingClassId() == eqivaBluetoothThingClassId) {
|
if (thing->thingClassId() == eqivaBluetoothThingClassId) {
|
||||||
qCDebug(dcEQ3) << "Removing Eqiva device" << thing->name();
|
qCDebug(dcEQ3) << "Removing Eqiva device" << thing->name();
|
||||||
|
hardwareManager()->bluetoothLowEnergyManager()->unpairDevice(QBluetoothAddress(thing->paramValue(eqivaBluetoothThingMacAddressParamTypeId).toString()),
|
||||||
|
QBluetoothAddress(thing->paramValue(eqivaBluetoothThingAdapterParamTypeId).toString()));
|
||||||
m_eqivaDevices.take(thing)->deleteLater();
|
m_eqivaDevices.take(thing)->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -54,6 +54,9 @@ public:
|
|||||||
void init() override;
|
void init() override;
|
||||||
void discoverThings(ThingDiscoveryInfo *info) override;
|
void discoverThings(ThingDiscoveryInfo *info) override;
|
||||||
|
|
||||||
|
void startPairing(ThingPairingInfo *info) override;
|
||||||
|
void confirmPairing(ThingPairingInfo *info, const QString &user, const QString &secret) override;
|
||||||
|
|
||||||
void setupThing(ThingSetupInfo *info) override;
|
void setupThing(ThingSetupInfo *info) override;
|
||||||
void thingRemoved(Thing *thing) override;
|
void thingRemoved(Thing *thing) override;
|
||||||
|
|
||||||
|
|||||||
@ -535,13 +535,19 @@
|
|||||||
"displayName": "Eqiva Bluetooth Smart Radiator Thermostat",
|
"displayName": "Eqiva Bluetooth Smart Radiator Thermostat",
|
||||||
"interfaces": ["thermostat", "wirelessconnectable", "battery"],
|
"interfaces": ["thermostat", "wirelessconnectable", "battery"],
|
||||||
"createMethods": ["discovery"],
|
"createMethods": ["discovery"],
|
||||||
"setupMethod": "JustAdd",
|
"setupMethod": "EnterPin",
|
||||||
"paramTypes": [
|
"paramTypes": [
|
||||||
{
|
{
|
||||||
"id": "56a77560-e1a3-44fa-8136-57fe5a8d1cbe",
|
"id": "56a77560-e1a3-44fa-8136-57fe5a8d1cbe",
|
||||||
"name": "macAddress",
|
"name": "macAddress",
|
||||||
"displayName": "MAC Address",
|
"displayName": "MAC Address",
|
||||||
"type": "QString"
|
"type": "QString"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "37915a7a-65a4-48ed-8d86-d83500b38f3e",
|
||||||
|
"name": "adapter",
|
||||||
|
"displayName": "Adapter",
|
||||||
|
"type": "QString"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"stateTypes": [
|
"stateTypes": [
|
||||||
|
|||||||
@ -79,15 +79,15 @@ void IntegrationPluginFlowercare::discoverThings(ThingDiscoveryInfo *info)
|
|||||||
|
|
||||||
qCDebug(dcFlowerCare()) << "Discovery finished";
|
qCDebug(dcFlowerCare()) << "Discovery finished";
|
||||||
|
|
||||||
foreach (const QBluetoothDeviceInfo &deviceInfo, reply->discoveredDevices()) {
|
foreach (const auto &deviceInfo, reply->discoveredDevices()) {
|
||||||
qCDebug(dcFlowerCare()) << "Discovered device" << deviceInfo.name();
|
qCDebug(dcFlowerCare()) << "Discovered device" << deviceInfo.first.name();
|
||||||
if (deviceInfo.name().contains("Flower care")) {
|
if (deviceInfo.first.name().contains("Flower care")) {
|
||||||
ThingDescriptor descriptor(flowerCareThingClassId, deviceInfo.name(), deviceInfo.address().toString());
|
ThingDescriptor descriptor(flowerCareThingClassId, deviceInfo.first.name(), deviceInfo.first.address().toString());
|
||||||
ParamList params;
|
ParamList params;
|
||||||
params << Param(flowerCareThingMacParamTypeId, deviceInfo.address().toString());
|
params << Param(flowerCareThingMacParamTypeId, deviceInfo.first.address().toString());
|
||||||
descriptor.setParams(params);
|
descriptor.setParams(params);
|
||||||
foreach (Thing *existingThing, myThings()) {
|
foreach (Thing *existingThing, myThings()) {
|
||||||
if (existingThing->paramValue(flowerCareThingMacParamTypeId).toString() == deviceInfo.address().toString()) {
|
if (existingThing->paramValue(flowerCareThingMacParamTypeId).toString() == deviceInfo.first.address().toString()) {
|
||||||
descriptor.setThingId(existingThing->id());
|
descriptor.setThingId(existingThing->id());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -65,18 +65,18 @@ void IntegrationPluginSenic::discoverThings(ThingDiscoveryInfo *info)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (const QBluetoothDeviceInfo &deviceInfo, reply->discoveredDevices()) {
|
foreach (const auto &deviceInfo, reply->discoveredDevices()) {
|
||||||
if (deviceInfo.name().contains("Nuimo")) {
|
if (deviceInfo.first.name().contains("Nuimo")) {
|
||||||
ThingDescriptor descriptor(nuimoThingClassId, "Nuimo", deviceInfo.name() + " (" + deviceInfo.address().toString() + ")");
|
ThingDescriptor descriptor(nuimoThingClassId, "Nuimo", deviceInfo.first.name() + " (" + deviceInfo.first.address().toString() + ")");
|
||||||
ParamList params;
|
ParamList params;
|
||||||
|
|
||||||
foreach (Thing *existingThing, myThings()) {
|
foreach (Thing *existingThing, myThings()) {
|
||||||
if (existingThing->paramValue(nuimoThingMacParamTypeId).toString() == deviceInfo.address().toString()) {
|
if (existingThing->paramValue(nuimoThingMacParamTypeId).toString() == deviceInfo.first.address().toString()) {
|
||||||
descriptor.setThingId(existingThing->id());
|
descriptor.setThingId(existingThing->id());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
params.append(Param(nuimoThingMacParamTypeId, deviceInfo.address().toString()));
|
params.append(Param(nuimoThingMacParamTypeId, deviceInfo.first.address().toString()));
|
||||||
descriptor.setParams(params);
|
descriptor.setParams(params);
|
||||||
info->addThingDescriptor(descriptor);
|
info->addThingDescriptor(descriptor);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,21 +66,21 @@ void IntegrationPluginTexasInstruments::discoverThings(ThingDiscoveryInfo *info)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (const QBluetoothDeviceInfo &deviceInfo, reply->discoveredDevices()) {
|
foreach (const auto &deviceInfo, reply->discoveredDevices()) {
|
||||||
|
|
||||||
if (deviceInfo.name().contains("SensorTag")) {
|
if (deviceInfo.first.name().contains("SensorTag")) {
|
||||||
|
|
||||||
ThingDescriptor descriptor(sensorTagThingClassId, "Sensor Tag", deviceInfo.address().toString());
|
ThingDescriptor descriptor(sensorTagThingClassId, "Sensor Tag", deviceInfo.first.address().toString());
|
||||||
|
|
||||||
Things existingThing = myThings().filterByParam(sensorTagThingMacParamTypeId, deviceInfo.address().toString());
|
Things existingThing = myThings().filterByParam(sensorTagThingMacParamTypeId, deviceInfo.first.address().toString());
|
||||||
if (!existingThing.isEmpty()) {
|
if (!existingThing.isEmpty()) {
|
||||||
descriptor.setThingId(existingThing.first()->id());
|
descriptor.setThingId(existingThing.first()->id());
|
||||||
}
|
}
|
||||||
|
|
||||||
ParamList params;
|
ParamList params;
|
||||||
params.append(Param(sensorTagThingMacParamTypeId, deviceInfo.address().toString()));
|
params.append(Param(sensorTagThingMacParamTypeId, deviceInfo.first.address().toString()));
|
||||||
foreach (Thing *existingThing, myThings()) {
|
foreach (Thing *existingThing, myThings()) {
|
||||||
if (existingThing->paramValue(sensorTagThingMacParamTypeId).toString() == deviceInfo.address().toString()) {
|
if (existingThing->paramValue(sensorTagThingMacParamTypeId).toString() == deviceInfo.first.address().toString()) {
|
||||||
descriptor.setThingId(existingThing->id());
|
descriptor.setThingId(existingThing->id());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user