Improve behavior on connection loss
This commit is contained in:
parent
4fe6a91771
commit
796a27e0ff
@ -86,6 +86,27 @@ EqivaBluetooth::EqivaBluetooth(BluetoothLowEnergyManager *bluetoothManager, cons
|
|||||||
m_refreshTimer.setInterval(5000);
|
m_refreshTimer.setInterval(5000);
|
||||||
m_refreshTimer.setSingleShot(true);
|
m_refreshTimer.setSingleShot(true);
|
||||||
connect(&m_refreshTimer, &QTimer::timeout, this, &EqivaBluetooth::sendDate);
|
connect(&m_refreshTimer, &QTimer::timeout, this, &EqivaBluetooth::sendDate);
|
||||||
|
|
||||||
|
m_reconnectTimer.setSingleShot(true);
|
||||||
|
connect(&m_reconnectTimer, &QTimer::timeout, this, [this](){
|
||||||
|
qCDebug(dcEQ3()) << m_name << "Trying to reconnect";
|
||||||
|
m_reconnectAttempt++;
|
||||||
|
m_bluetoothDevice->connectDevice();
|
||||||
|
});
|
||||||
|
|
||||||
|
m_commandTimeout.setInterval(3000);
|
||||||
|
m_commandTimeout.setSingleShot(true);
|
||||||
|
connect(&m_commandTimeout, &QTimer::timeout, this, [this](){
|
||||||
|
// Put current command back to the queue as it didn't succeed
|
||||||
|
qCWarning(dcEQ3()) << m_name << "Command timed out:" << m_currentCommand.id << m_currentCommand.name << "Putting command back to queue";
|
||||||
|
m_commandQueue.prepend(m_currentCommand);
|
||||||
|
m_currentCommand = Command();
|
||||||
|
|
||||||
|
// and reset the connection
|
||||||
|
if (m_bluetoothDevice->connected()) {
|
||||||
|
m_bluetoothDevice->disconnectDevice();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
EqivaBluetooth::~EqivaBluetooth()
|
EqivaBluetooth::~EqivaBluetooth()
|
||||||
@ -208,24 +229,19 @@ bool EqivaBluetooth::batteryCritical() const
|
|||||||
|
|
||||||
void EqivaBluetooth::controllerStateChanged(const QLowEnergyController::ControllerState &state)
|
void EqivaBluetooth::controllerStateChanged(const QLowEnergyController::ControllerState &state)
|
||||||
{
|
{
|
||||||
qCDebug(dcEQ3()) << m_name << "Bluetooth device state changed:" << state;
|
if (state == QLowEnergyController::ConnectingState) {
|
||||||
|
// Make sure the reconnect timer is stopped when we're starting a new attempt
|
||||||
|
m_reconnectTimer.stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (state == QLowEnergyController::UnconnectedState) {
|
if (state == QLowEnergyController::UnconnectedState) {
|
||||||
int delay = qMin(m_reconnectAttempt, 30);
|
int delay = qMin(m_reconnectAttempt, 30);
|
||||||
qWarning(dcEQ3()) << m_name << "Eqiva device disconnected. Reconnecting in" << delay << "sec";
|
qWarning(dcEQ3()) << m_name << "Eqiva device disconnected. Reconnecting in" << delay << "sec";
|
||||||
m_available = false;
|
m_available = false;
|
||||||
emit availableChanged();
|
emit availableChanged();
|
||||||
|
|
||||||
if (m_currentCommand.id != -1) {
|
m_reconnectTimer.start(delay * 1000);
|
||||||
qCDebug(dcEQ3()) << m_name << "Putting command" << m_currentCommand.id << m_currentCommand.name << "back to queue";
|
|
||||||
m_commandQueue.prepend(m_currentCommand);
|
|
||||||
m_currentCommand = Command();
|
|
||||||
}
|
|
||||||
|
|
||||||
QTimer::singleShot(delay * 1000, this, [this](){
|
|
||||||
qCDebug(dcEQ3()) << m_name << "Trying to reconnect";
|
|
||||||
m_reconnectAttempt++;
|
|
||||||
m_bluetoothDevice->connectDevice();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state != QLowEnergyController::DiscoveredState) {
|
if (state != QLowEnergyController::DiscoveredState) {
|
||||||
@ -293,7 +309,10 @@ void EqivaBluetooth::controllerStateChanged(const QLowEnergyController::Controll
|
|||||||
|
|
||||||
});
|
});
|
||||||
connect(m_eqivaService, &QLowEnergyService::characteristicWritten, this, [this](const QLowEnergyCharacteristic &info, const QByteArray &value){
|
connect(m_eqivaService, &QLowEnergyService::characteristicWritten, this, [this](const QLowEnergyCharacteristic &info, const QByteArray &value){
|
||||||
qCDebug(dcEQ3()) << m_name << "Characteristic written:" << info.name() << info.uuid() << value.toHex();
|
Q_UNUSED(info) // We're only writing one...
|
||||||
|
Q_UNUSED(value)
|
||||||
|
qCDebug(dcEQ3()) << m_name << "Command sent:" << m_currentCommand.id << m_currentCommand.name;
|
||||||
|
m_commandTimeout.stop();
|
||||||
emit commandResult(m_currentCommand.id, true);
|
emit commandResult(m_currentCommand.id, true);
|
||||||
m_currentCommand.id = -1;
|
m_currentCommand.id = -1;
|
||||||
processCommandQueue();
|
processCommandQueue();
|
||||||
@ -333,14 +352,19 @@ void EqivaBluetooth::serviceStateChanged(QLowEnergyService::ServiceState newStat
|
|||||||
// Enable notifications
|
// Enable notifications
|
||||||
QLowEnergyCharacteristic characteristic = m_eqivaService->characteristic(notificationCharacteristicUuid);
|
QLowEnergyCharacteristic characteristic = m_eqivaService->characteristic(notificationCharacteristicUuid);
|
||||||
QLowEnergyDescriptor notificationDescriptor = characteristic.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
|
QLowEnergyDescriptor notificationDescriptor = characteristic.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
|
||||||
m_eqivaService->writeDescriptor(notificationDescriptor, QByteArray::fromHex("0000"));
|
// m_eqivaService->writeDescriptor(notificationDescriptor, QByteArray::fromHex("0000"));
|
||||||
m_eqivaService->writeDescriptor(notificationDescriptor, QByteArray::fromHex("0100"));
|
m_eqivaService->writeDescriptor(notificationDescriptor, QByteArray::fromHex("0100"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EqivaBluetooth::characteristicChanged(const QLowEnergyCharacteristic &info, const QByteArray &value)
|
void EqivaBluetooth::characteristicChanged(const QLowEnergyCharacteristic &info, const QByteArray &value)
|
||||||
{
|
{
|
||||||
qCDebug(dcEQ3()) << m_name << "Notification received" << info.uuid() << value.toHex();
|
// qCDebug(dcEQ3()) << m_name << "Notification received" << info.uuid() << value.toHex();
|
||||||
|
|
||||||
|
if (info.uuid() != notificationCharacteristicUuid) {
|
||||||
|
qCWarning(dcEQ3()) << m_name << "Received a notification from a characteristic we did't expect:" << info.uuid() << value.toHex();
|
||||||
|
return;
|
||||||
|
}
|
||||||
m_refreshTimer.start();
|
m_refreshTimer.start();
|
||||||
|
|
||||||
QByteArray data(value);
|
QByteArray data(value);
|
||||||
@ -442,20 +466,18 @@ void EqivaBluetooth::sendDate()
|
|||||||
stream << static_cast<quint8>(now.time().second());
|
stream << static_cast<quint8>(now.time().second());
|
||||||
|
|
||||||
// Example: 03130117172315 -> 03YYMMDDHHMMSS
|
// Example: 03130117172315 -> 03YYMMDDHHMMSS
|
||||||
qCDebug(dcEQ3()) << m_name << "Updating date on device...";
|
// qCDebug(dcEQ3()) << m_name << "Updating date on device...";
|
||||||
enqueue("SetDate", data);
|
enqueue("SetDate", data);
|
||||||
}
|
}
|
||||||
|
|
||||||
int EqivaBluetooth::enqueue(const QString &name, const QByteArray &data)
|
int EqivaBluetooth::enqueue(const QString &name, const QByteArray &data)
|
||||||
{
|
{
|
||||||
static int nextId = 0;
|
|
||||||
|
|
||||||
Command cmd;
|
Command cmd;
|
||||||
cmd.name = name;
|
cmd.name = name;
|
||||||
cmd.id = nextId++;
|
cmd.id = m_nextCommandId++;
|
||||||
cmd.data = data;
|
cmd.data = data;
|
||||||
m_commandQueue.append(cmd);
|
m_commandQueue.append(cmd);
|
||||||
qCDebug(dcEQ3()) << m_name << "Enqueued command" << cmd.name << "Command queue length:" << m_commandQueue.length();
|
// qCDebug(dcEQ3()) << m_name << "Enqueued command" << cmd.name << "Command queue length:" << m_commandQueue.length();
|
||||||
processCommandQueue();
|
processCommandQueue();
|
||||||
return cmd.id;
|
return cmd.id;
|
||||||
}
|
}
|
||||||
@ -468,7 +490,7 @@ void EqivaBluetooth::processCommandQueue()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_commandQueue.isEmpty()) {
|
if (m_commandQueue.isEmpty()) {
|
||||||
qCDebug(dcEQ3()) << m_name << "Command queue is empty. Nothing to do...";
|
// qCDebug(dcEQ3()) << m_name << "Command queue is empty. Nothing to do...";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -479,6 +501,7 @@ void EqivaBluetooth::processCommandQueue()
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_currentCommand = m_commandQueue.takeFirst();
|
m_currentCommand = m_commandQueue.takeFirst();
|
||||||
|
m_commandTimeout.start();
|
||||||
qCDebug(dcEQ3()) << m_name << "Sending command" << m_currentCommand.id << m_currentCommand.name << m_currentCommand.data.toHex();
|
qCDebug(dcEQ3()) << m_name << "Sending command" << m_currentCommand.id << m_currentCommand.name << m_currentCommand.data.toHex();
|
||||||
writeCharacteristic(commandCharacteristicUuid, m_currentCommand.data);
|
writeCharacteristic(commandCharacteristicUuid, m_currentCommand.data);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -87,17 +87,19 @@ private:
|
|||||||
quint8 m_valveOpen = 0;
|
quint8 m_valveOpen = 0;
|
||||||
bool m_batteryCritical = false;
|
bool m_batteryCritical = false;
|
||||||
|
|
||||||
|
QTimer m_reconnectTimer;
|
||||||
int m_reconnectAttempt = 0;
|
int m_reconnectAttempt = 0;
|
||||||
|
|
||||||
struct Command {
|
struct Command {
|
||||||
QString name; // For debug prints
|
QString name; // For debug prints
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
int id = -1;
|
qint32 id = -1;
|
||||||
};
|
};
|
||||||
QList<Command> m_commandQueue;
|
QList<Command> m_commandQueue;
|
||||||
Command m_currentCommand;
|
Command m_currentCommand;
|
||||||
|
QTimer m_commandTimeout;
|
||||||
|
|
||||||
int m_nextCommandId = 0;
|
quint16 m_nextCommandId = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class EqivaBluetoothDiscovery: public QObject
|
class EqivaBluetoothDiscovery: public QObject
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user