mirror of
https://github.com/Laxilef/OTGateway.git
synced 2025-12-11 18:54:28 +05:00
refactor: improved work with BLE sensors
This commit is contained in:
@@ -8,6 +8,45 @@
|
|||||||
|
|
||||||
extern FileData fsSensorsSettings;
|
extern FileData fsSensorsSettings;
|
||||||
|
|
||||||
|
#if USE_BLE
|
||||||
|
class BluetoothClientCallbacks : public NimBLEClientCallbacks {
|
||||||
|
public:
|
||||||
|
BluetoothClientCallbacks(uint8_t sensorId) : sensorId(sensorId) {}
|
||||||
|
|
||||||
|
void onConnect(NimBLEClient* pClient) {
|
||||||
|
auto& sSensor = Sensors::settings[this->sensorId];
|
||||||
|
|
||||||
|
Log.sinfoln(
|
||||||
|
FPSTR(L_SENSORS_BLE), F("Sensor #%hhu '%s': connected to %s"),
|
||||||
|
sensorId, sSensor.name, pClient->getPeerAddress().toString().c_str()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onDisconnect(NimBLEClient* pClient, int reason) {
|
||||||
|
auto& sSensor = Sensors::settings[this->sensorId];
|
||||||
|
|
||||||
|
Log.sinfoln(
|
||||||
|
FPSTR(L_SENSORS_BLE), F("Sensor #%hhu '%s': disconnected, reason %i"),
|
||||||
|
sensorId, sSensor.name, reason
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onConnectFail(NimBLEClient* pClient, int reason) {
|
||||||
|
auto& sSensor = Sensors::settings[this->sensorId];
|
||||||
|
|
||||||
|
Log.sinfoln(
|
||||||
|
FPSTR(L_SENSORS_BLE), F("Sensor #%hhu '%s': failed to connect, reason %i"),
|
||||||
|
sensorId, sSensor.name, reason
|
||||||
|
);
|
||||||
|
|
||||||
|
pClient->cancelConnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint8_t sensorId;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
class SensorsTask : public LeanTask {
|
class SensorsTask : public LeanTask {
|
||||||
public:
|
public:
|
||||||
SensorsTask(bool _enabled = false, unsigned long _interval = 0) : LeanTask(_enabled, _interval) {
|
SensorsTask(bool _enabled = false, unsigned long _interval = 0) : LeanTask(_enabled, _interval) {
|
||||||
@@ -41,6 +80,7 @@ protected:
|
|||||||
std::unordered_map<uint8_t, bool> dallasPolling;
|
std::unordered_map<uint8_t, bool> dallasPolling;
|
||||||
std::unordered_map<uint8_t, unsigned long> dallasLastPollingTime;
|
std::unordered_map<uint8_t, unsigned long> dallasLastPollingTime;
|
||||||
#if USE_BLE
|
#if USE_BLE
|
||||||
|
std::unordered_map<uint8_t, NimBLEClient*> bleClients;
|
||||||
std::unordered_map<uint8_t, bool> bleSubscribed;
|
std::unordered_map<uint8_t, bool> bleSubscribed;
|
||||||
std::unordered_map<uint8_t, unsigned long> bleLastSetDtTime;
|
std::unordered_map<uint8_t, unsigned long> bleLastSetDtTime;
|
||||||
#endif
|
#endif
|
||||||
@@ -409,36 +449,18 @@ protected:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto client : NimBLEDevice::getConnectedClients()) {
|
for (auto& [sensorId, pClient]: this->bleClients) {
|
||||||
auto address = client->getPeerAddress();
|
auto& sSensor = Sensors::settings[sensorId];
|
||||||
bool used = false;
|
|
||||||
|
|
||||||
for (uint8_t sensorId = 0; sensorId <= Sensors::getMaxSensorId(); sensorId++) {
|
if (!sSensor.enabled || sSensor.type != Sensors::Type::BLUETOOTH || sSensor.purpose == Sensors::Purpose::NOT_CONFIGURED) {
|
||||||
auto& sSensor = Sensors::settings[sensorId];
|
|
||||||
|
|
||||||
if (!sSensor.enabled || sSensor.type != Sensors::Type::BLUETOOTH || sSensor.purpose == Sensors::Purpose::NOT_CONFIGURED) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto pAddress = address.getVal();
|
|
||||||
uint8_t addr[] = {
|
|
||||||
pAddress[5], pAddress[4], pAddress[3],
|
|
||||||
pAddress[2], pAddress[1], pAddress[0]
|
|
||||||
};
|
|
||||||
|
|
||||||
if (isEqualAddress(addr, sSensor.address, sizeof(addr))) {
|
|
||||||
used = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!used) {
|
|
||||||
Log.sinfoln(
|
Log.sinfoln(
|
||||||
FPSTR(L_SENSORS_BLE), F("Deleted unused client connected to %s"),
|
FPSTR(L_SENSORS_BLE), F("Sensor #%hhu '%s', deleted unused client, address: %s"),
|
||||||
address.toString().c_str()
|
sensorId, sSensor.name,
|
||||||
|
pClient->getPeerAddress().toString().c_str()
|
||||||
);
|
);
|
||||||
|
|
||||||
NimBLEDevice::deleteClient(client);
|
NimBLEDevice::deleteClient(pClient);
|
||||||
|
pClient = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -462,38 +484,27 @@ protected:
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto client = this->getBleClient(sensorId);
|
auto pClient = this->getBleClient(sensorId);
|
||||||
if (client == nullptr) {
|
if (pClient == nullptr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!client->isConnected()) {
|
if (!pClient->isConnected()) {
|
||||||
this->bleSubscribed[sensorId] = false;
|
this->bleSubscribed[sensorId] = false;
|
||||||
this->bleLastSetDtTime[sensorId] = 0;
|
this->bleLastSetDtTime[sensorId] = 0;
|
||||||
|
|
||||||
if (client->connect()) {
|
pClient->connect(true, true, true);
|
||||||
Log.sinfoln(
|
|
||||||
FPSTR(L_SENSORS_BLE), F("Sensor #%hhu '%s': connected to %s"),
|
|
||||||
sensorId, sSensor.name, client->getPeerAddress().toString().c_str()
|
|
||||||
);
|
|
||||||
|
|
||||||
} else {
|
continue;
|
||||||
Log.swarningln(
|
|
||||||
FPSTR(L_SENSORS_BLE), F("Sensor #%hhu '%s': failed connecting to %s"),
|
|
||||||
sensorId, sSensor.name, client->getPeerAddress().toString().c_str()
|
|
||||||
);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this->bleSubscribed[sensorId]) {
|
if (!this->bleSubscribed[sensorId]) {
|
||||||
if (this->subscribeToBleDevice(sensorId, client)) {
|
if (this->subscribeToBleDevice(sensorId, pClient)) {
|
||||||
this->bleSubscribed[sensorId] = true;
|
this->bleSubscribed[sensorId] = true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
this->bleSubscribed[sensorId] = false;
|
this->bleSubscribed[sensorId] = false;
|
||||||
client->disconnect();
|
pClient->disconnect();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -505,7 +516,7 @@ protected:
|
|||||||
struct tm ti;
|
struct tm ti;
|
||||||
|
|
||||||
if (getLocalTime(&ti)) {
|
if (getLocalTime(&ti)) {
|
||||||
if (this->setDateOnBleSensor(client, &ti)) {
|
if (this->setDateOnBleSensor(pClient, &ti)) {
|
||||||
Log.sinfoln(
|
Log.sinfoln(
|
||||||
FPSTR(L_SENSORS_BLE), F("Sensor #%hhu '%s', successfully set date: %02d.%02d.%04d %02d:%02d:%02d"),
|
FPSTR(L_SENSORS_BLE), F("Sensor #%hhu '%s', successfully set date: %02d.%02d.%04d %02d:%02d:%02d"),
|
||||||
sensorId, sSensor.name,
|
sensorId, sSensor.name,
|
||||||
@@ -538,41 +549,32 @@ protected:
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t addr[6] = {
|
const auto address = NimBLEAddress(sSensor.address, 0);
|
||||||
sSensor.address[0], sSensor.address[1], sSensor.address[2],
|
if (address.isNull()) {
|
||||||
sSensor.address[3], sSensor.address[4], sSensor.address[5]
|
return nullptr;
|
||||||
};
|
}
|
||||||
const auto address = NimBLEAddress(addr, 0);
|
|
||||||
|
if (this->bleClients[sensorId] && this->bleClients[sensorId] != nullptr) {
|
||||||
NimBLEClient* pClient = NimBLEDevice::getClientByPeerAddress(address);
|
return this->bleClients[sensorId];
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pClient = NimBLEDevice::createClient(address);
|
||||||
if (pClient == nullptr) {
|
if (pClient == nullptr) {
|
||||||
pClient = NimBLEDevice::getDisconnectedClient();
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pClient == nullptr) {
|
/**
|
||||||
if (NimBLEDevice::getCreatedClientCount() >= NIMBLE_MAX_CONNECTIONS) {
|
* Set initial connection parameters:
|
||||||
return nullptr;
|
* These settings are safe for 3 clients to connect reliably, can go faster if you have less
|
||||||
}
|
* connections. Timeout should be a multiple of the interval, minimum is 100ms.
|
||||||
|
* Min interval: 12 * 1.25ms = 15, Max interval: 12 * 1.25ms = 15, 0 latency, 1000 * 10ms = 10000ms timeout
|
||||||
|
*/
|
||||||
|
pClient->setConnectionParams(12, 12, 0, 1000);
|
||||||
|
pClient->setConnectTimeout(10000);
|
||||||
|
pClient->setSelfDelete(false, false);
|
||||||
|
pClient->setClientCallbacks(new BluetoothClientCallbacks(sensorId), true);
|
||||||
|
|
||||||
pClient = NimBLEDevice::createClient();
|
this->bleClients[sensorId] = pClient;
|
||||||
if (pClient == nullptr) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set initial connection parameters:
|
|
||||||
* These settings are safe for 3 clients to connect reliably, can go faster if you have less
|
|
||||||
* connections. Timeout should be a multiple of the interval, minimum is 100ms.
|
|
||||||
* Min interval: 12 * 1.25ms = 15, Max interval: 12 * 1.25ms = 15, 0 latency, 1000 * 10ms = 10000ms timeout
|
|
||||||
*/
|
|
||||||
pClient->setConnectionParams(12, 12, 0, 1000);
|
|
||||||
pClient->setConnectTimeout(5000);
|
|
||||||
pClient->setSelfDelete(false, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pClient->isConnected()) {
|
|
||||||
pClient->setPeerAddress(address);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pClient;
|
return pClient;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user