diff --git a/src/modules/sensors/Ble/Ble.cpp b/src/modules/sensors/Ble/Ble.cpp index 8632fd97..1c83f442 100644 --- a/src/modules/sensors/Ble/Ble.cpp +++ b/src/modules/sensors/Ble/Ble.cpp @@ -1,27 +1,120 @@ #include "Global.h" #include "classes/IoTItem.h" #include -#ifdef ESP32 #include #include +#include // Создаем переменную для хранения данных с датчиков bluetooth -StaticJsonDocument BLEbuffer; -JsonObject extBLEdata = BLEbuffer.to(); +// StaticJsonDocument BLEbuffer; +// DynamicJsonDocument extBLEdata(JSON_BUFFER_SIZE * 4); +// JsonObject extBLEdata = BLEbuffer.to(); +class BleSens; +std::vector BleSensArray; -BLEScan *pBLEScan; -TheengsDecoder decoder; -StaticJsonDocument<512> doc; +class BleSens : public IoTItem +{ +private: + // описание параметров передаваемых из настроек датчика из веба + String _MAC; + String _sensor; + +public: + String whoIAm(/*String &mac, String &sens*/) + { + // mac = _MAC; + // sens = _sensor; + return _MAC; + } + + void setBLEdata(JsonObject extBLEdata) + { + if (_sensor == "last") + { + int valInt = extBLEdata[_sensor].as(); + char *s; + s = TimeToString(millis() / 1000 - valInt / 1000); + value.isDecimal = 0; + if (valInt > 0) + { + value.valS = s; + } + else + { + value.valS = ""; + } + regEvent(value.valS, _id); + } + else + { + String valStr = extBLEdata[_sensor].as(); + if (valStr != "null") + { + if (value.isDecimal == isDigitDotCommaStr(valStr)) + { + value.isDecimal = 1; + value.valD = valStr.toFloat(); + regEvent(value.valD, _id); + } + else + { + value.isDecimal = 0; + value.valS = valStr; + regEvent(value.valS, _id); + } + } + else + { + value.isDecimal = 0; + value.valS = ""; + regEvent(value.valS, _id); + } + } + } + char *TimeToString(unsigned long t) + { + static char str[12]; + long h = t / 3600; + t = t % 3600; + int m = t / 60; + int s = t % 60; + sprintf(str, "%02ld:%02d:%02d", h, m, s); + return str; + } + + BleSens(String parameters) : IoTItem(parameters) + { + _MAC = jsonReadStr(parameters, "MAC"); + _sensor = jsonReadStr(parameters, "sensor"); + BleSensArray.push_back(this); + } + + ~BleSens(){}; +}; + +//======================================================================================================= + +/** Callback to process the results of the last scan or restart it */ +void scanEndedCB(NimBLEScanResults results) +{ + int count = results.getCount(); + SerialPrint("i", F("BLE"), "Scan done! "); // +"Devices found: " + String(count)); + // pBLEScan->clearResults(); +} class BleScan : public IoTItem, BLEAdvertisedDeviceCallbacks { private: - //описание параметров передаваемых из настроек датчика из веба + // описание параметров передаваемых из настроек датчика из веба int _scanDuration; String _filter; + bool _debug; + + StaticJsonDocument<512> doc; + BLEScan *pBLEScan; + TheengsDecoder decoder; public: - //======================================================================================================= std::string convertServiceData(std::string deviceServiceData) { int serviceDataLength = (int)deviceServiceData.length(); @@ -67,169 +160,77 @@ public: if (decoder.decodeBLEJson(BLEdata)) { - BLEdata.remove("manufacturerdata"); BLEdata.remove("servicedata"); + BLEdata.remove("type"); + BLEdata.remove("cidc"); + BLEdata.remove("acts"); + BLEdata.remove("cont"); + BLEdata.remove("track"); String mac_address = BLEdata["id"].as(); mac_address.replace(":", ""); - - if (_filter != "") + // дописываем время прихода пакета данных + BLEdata["last"] = millis(); + if (_debug) { - if (BLEdata[_filter]) + if ((_filter != "" && BLEdata[_filter]) || _filter == "") { - for (JsonPair kv : BLEdata) - { - extBLEdata[mac_address][kv.key()] = BLEdata[kv.key()]; - } - - // дописываем время прихода пакета данных - extBLEdata[mac_address]["last"] = millis(); + // for (JsonPair kv : BLEdata) + // { + // String val = BLEdata.as(); + String output; + serializeJson(BLEdata, output); + SerialPrint("i", F("BLE"), _id + " " + output); + //} } } - else + BLEdata.remove("servicedatauuid"); + SerialPrint("i", F("BLE"), "found: " + mac_address); + // Перебираем все зарегистрированные сенсоры BleSens + for (std::vector::iterator it = BleSensArray.begin(); + it != BleSensArray.end(); ++it) { - for (JsonPair kv : BLEdata) - { - extBLEdata[mac_address][kv.key()] = BLEdata[kv.key()]; - } - // дописываем время прихода пакета данных - extBLEdata[mac_address]["last"] = millis(); + // Если это данные для нужного сенсора (по его МАКУ) + if ((*it)->whoIAm() == mac_address) + // то передаем ему json, дальше он сам разберется + (*it)->setBLEdata(BLEdata); } - }; + } } BleScan(String parameters) : IoTItem(parameters) { _scanDuration = jsonReadInt(parameters, "scanDuration"); _filter = jsonReadStr(parameters, "filter"); + jsonRead(parameters, "debug", _debug); - if (pBLEScan->isScanning() == false) - { - SerialPrint("i", F("BLE"), "Start Scanning..."); - BLEDevice::init(""); - pBLEScan = BLEDevice::getScan(); // create new scan - pBLEScan->setAdvertisedDeviceCallbacks(this); - pBLEScan->setActiveScan(false); // active scan uses more power, but get results faster - pBLEScan->setInterval(100); - pBLEScan->setWindow(99); // less or equal setInterval value - } + BLEDevice::init(""); + pBLEScan = BLEDevice::getScan(); // create new scan + pBLEScan->setAdvertisedDeviceCallbacks(this); + pBLEScan->setActiveScan(false); // active scan uses more power, but get results faster + pBLEScan->setInterval(100); + pBLEScan->setWindow(99); // less or equal setInterval value + pBLEScan->setMaxResults(0); // do not store the scan results, use callback only. } - //======================================================================================================= - // doByInterval() void doByInterval() { - - if (_scanDuration > 0) + if (pBLEScan->isScanning() == false) { - BLEScanResults foundDevices = pBLEScan->start(_scanDuration, true); - int count = foundDevices.getCount(); - SerialPrint("i", F("BLE"), "Devices found: " + String(count)); - SerialPrint("i", F("BLE"), "Scan done!"); - pBLEScan->clearResults(); - } - for (JsonPair kv : extBLEdata) - { - String val = extBLEdata[kv.key()].as(); - SerialPrint("i", F("BLE"), _id + " " + kv.key().c_str() + " " + val); + if (_scanDuration > 0) + { + SerialPrint("i", F("BLE"), "Start Scanning..."); + pBLEScan->start(_scanDuration, scanEndedCB, false); + } } } - //======================================================================================================= - ~BleScan(){}; }; -class BleSens : public IoTItem -{ -private: - //описание параметров передаваемых из настроек датчика из веба - String _MAC; - String _sensor; - -public: - //======================================================================================================= - char *TimeToString(unsigned long t) - { - static char str[12]; - long h = t / 3600; - t = t % 3600; - int m = t / 60; - int s = t % 60; - sprintf(str, "%02ld:%02d:%02d", h, m, s); - return str; - } - - BleSens(String parameters) : IoTItem(parameters) - { - _MAC = jsonReadStr(parameters, "MAC"); - _sensor = jsonReadStr(parameters, "sensor"); - } - - //======================================================================================================= - - // doByInterval() - void doByInterval() - { - if (_sensor == "last") - { - int valInt = extBLEdata[_MAC][_sensor].as(); - char *s; - s = TimeToString(millis() / 1000 - valInt / 1000); - value.isDecimal = 0; - if (valInt > 0) - { - value.valS = s; - } - else - { - value.valS = ""; - } - regEvent(value.valS, _id); - } - else - { - String valStr = extBLEdata[_MAC][_sensor].as(); - if (valStr != "null") - { - if (value.isDecimal = isDigitDotCommaStr(valStr)) - { - value.isDecimal = 1; - value.valD = valStr.toFloat(); - regEvent(value.valD, _id); - } - else - { - value.isDecimal = 0; - value.valS = valStr; - regEvent(value.valS, _id); - } - } - else - { - value.isDecimal = 0; - value.valS = ""; - regEvent(value.valS, _id); - } - } - } - //======================================================================================================= - - ~BleSens(){}; -}; -#endif - -// Заглушка для ESP8266 -#ifdef ESP8266 -class Ble : public IoTItem -{ -private: -public: - Ble(String parameters) : IoTItem(parameters) {} -}; -#endif +//======================================================================================================= void *getAPI_Ble(String subtype, String param) { diff --git a/src/modules/sensors/Ble/modinfo.json b/src/modules/sensors/Ble/modinfo.json index 090ccb24..0bd08eea 100644 --- a/src/modules/sensors/Ble/modinfo.json +++ b/src/modules/sensors/Ble/modinfo.json @@ -3,7 +3,6 @@ "configItem": [ { "name": "bluetooth сканер", - "num": 1, "type": "Reading", "subtype": "BleScan", "id": "BleScan", @@ -12,11 +11,11 @@ "descr": "", "int": 135, "scanDuration": 10, - "filter": "servicedatauuid" + "filter": "servicedatauuid", + "debug":1 }, { "name": "bluetooth датчик", - "num": 1, "type": "Reading", "subtype": "BleSens", "id": "BleSens", @@ -26,18 +25,17 @@ "needSave": 0, "global": 0, "round": 1, - "int": 60, "MAC": "", "sensor": "" } ], "about": { - "authorName": "AVAKS", - "authorContact": "https://t.me/@avaks_dev", - "authorGit": "https://github.com/avaksru", + "authorName": "AVAKS, v3 - Mit4bmw", + "authorContact": "https://t.me/@avaks, https://t.me/Mit4bmw", + "authorGit": "https://github.com/avaksru, https://github.com/Mit4el", "specialThanks": "@Serghei63", "moduleName": "Ble", - "moduleVersion": "1.0", + "moduleVersion": "3.0", "usedRam": { "esp32_4mb": 1261449, "esp8266_4mb": 0 @@ -50,9 +48,9 @@ "moduleDesc": "Позволяет получить данные с Bluetooth часов и термометров Mijia, Xiaomi, Cleargrass, ...", "propInfo": { "round": "Округление после запятой.", - "int": "Интервал сканирования BLE окружения (BleScan) / Интервал отправки собранной телеметрии в MQTT (BleSens)", + "int": "Интервал сканирования BLE окружения (BleScan) / В BleSens не используется, там обновляется по мене сканирования/поступления", "scanDuration": "Длительность сканирования ", - "filter": "Позволяет установить фильтр по параметру передаваемому датчиком. Данные будут считываться только с датчиков у которых есть передаваемый параметр указанный в фильтре", + "filter": "Позволяет установить фильтр по параметру передаваемому датчиком. Влияет только на вывод лога при debug=1, что бы было легче найти датчики, если много устройств в эфире", "MAC": "MAC адрес беспроводного датчика", "sensor": "Тип сенсора: температура / влажность / время / ... " } @@ -63,11 +61,23 @@ "https://github.com/h2zero/NimBLE-Arduino.git", "https://github.com/avaksru/decoder.git" ], - "esp32_4mb3f": [ + "esp32_16mb": [ "https://github.com/h2zero/NimBLE-Arduino.git", "https://github.com/avaksru/decoder.git" ], - "esp32cam_4mb": [ + "esp32_4mb3f": [ + "https://github.com/h2zero/NimBLE-Arduino.git", + "https://github.com/avaksru/decoder.git" + ], + "esp32s2_4mb": [ + "https://github.com/h2zero/NimBLE-Arduino.git", + "https://github.com/avaksru/decoder.git" + ], + "esp32s3_16mb": [ + "https://github.com/h2zero/NimBLE-Arduino.git", + "https://github.com/avaksru/decoder.git" + ], + "esp32c3m_4mb": [ "https://github.com/h2zero/NimBLE-Arduino.git", "https://github.com/avaksru/decoder.git" ]