Rozwijając urządzenie przygotowane w ramach tematu o termometrze XAOMI (viewtopic.php?t=11193) narodził mi się w głowie pomysł bramki dla urządzeń BLE.
Mogę głównie się oprzeć na kodzie z biblioteki, która odnalazłem dla urządzeń BLE (do dekodowania) oraz części z kodu z linka do wysyłania dla SUPLI
Wyzwania do rozwiązania dla mnie (nie jestem obeznany w tym języku programowania jak i supli):
- test urządzeń z obszernej listy, którą biblioteka obsługuje na podstawie kodu z biblioteki (liczę na społeczność)
- zmienne, do przemyślenia jak zmienić model z obsługi termometrów na bardziej optymalny. Czujników może być sporo więc trzeba przemyśleć by nie zadeklarować tablice dla liczbę czujników x liczba danych
- być może próba z ominięciem zmiennych by za jednym razem zaraz po odczytaniu przesyłać dane na suple
- zarządzanie kanałami (modyfikacja kolejności macadresów nie wpływała na przesył (kolejność) danych, podobnie usunięcie macadresu)
- moduł konfiguracji web
Prace nad kodem trwają powoli, nie ma się jeszcze czym chwalić.
Zależy mi na ten moment by chętni zainstalowali sobie bibliotekę i przetestowali co tam serial wypluje z siebie.
U mnie to wygląda tak:
Code: Select all
Scanning...
Advertised Device: Name: ATC_61263A, Address: a4:c1:38:61:26:3a
Service Data:
UUID: 0x181a, Data: ��8a&:
TheengsDecoder found device: {"id":"A4:C1:38:61:26:3A","name":"ATC_61263A","rssi":-90,"brand":"Xiaomi","model":"TH Sensor","model_id":"LYWSD03MMC/MJWSD05MMC_ATC","tempc":20.1,"tempf":68.18,"hum":57,"batt":59,"volt":2.744,"mac":"A4:C1:38:61:26:3A"}
Advertised Device: Name: ATC_A84299, Address: a4:c1:38:a8:42:99
Service Data:
UUID: 0x181a, Data: ��8�B�
TheengsDecoder found device: {"id":"A4:C1:38:A8:42:99","name":"ATC_A84299","rssi":-77,"brand":"Xiaomi","model":"TH Sensor","model_id":"LYWSD03MMC/MJWSD05MMC_ATC","tempc":20.9,"tempf":69.62,"hum":56,"batt":82,"volt":2.946,"mac":"A4:C1:38:A8:42:99"}
Advertised Device: Name: ATC_511184, Address: a4:c1:38:51:11:84
Service Data:
UUID: 0x181a, Data: ��8Q�
TheengsDecoder found device: {"id":"A4:C1:38:51:11:84","name":"ATC_511184","rssi":-85,"brand":"Xiaomi","model":"TH Sensor","model_id":"LYWSD03MMC/MJWSD05MMC_ATC","tempc":21.1,"tempf":69.98,"hum":60,"batt":65,"volt":2.797,"mac":"A4:C1:38:51:11:84"}
Advertised Device: Name: ATC_7B61C9, Address: a4:c1:38:7b:61:c9
Service Data:
UUID: 0x181a, Data: ��8{a�
TheengsDecoder found device: {"id":"A4:C1:38:7B:61:C9","name":"ATC_7B61C9","rssi":-30,"brand":"Xiaomi","model":"TH Sensor","model_id":"LYWSD03MMC/MJWSD05MMC_ATC","tempc":21,"tempf":69.8,"hum":58,"batt":73,"volt":2.877,"mac":"A4:C1:38:7B:61:C9"}
Code: Select all
#include <Arduino.h>
#define ARDUINOJSON_USE_LONG_LONG 1
#include "ArduinoJson.h"
#include "NimBLEDevice.h"
#include "decoder.h"
NimBLEScan* pBLEScan;
TheengsDecoder decoder;
StaticJsonDocument<512> doc;
class MyAdvertisedDeviceCallbacks: public NimBLEAdvertisedDeviceCallbacks {
std::string convertServiceData(std::string deviceServiceData) {
int serviceDataLength = (int)deviceServiceData.length();
char spr[2 * serviceDataLength + 1];
for (int i = 0; i < serviceDataLength; i++) sprintf(spr + 2 * i, "%.2x", (unsigned char)deviceServiceData[i]);
spr[2 * serviceDataLength] = 0;
return spr;
}
void onResult(BLEAdvertisedDevice* advertisedDevice) {
Serial.printf("Advertised Device: %s \n", advertisedDevice->toString().c_str());
JsonObject BLEdata = doc.to<JsonObject>();
String mac_adress = advertisedDevice->getAddress().toString().c_str();
mac_adress.toUpperCase();
BLEdata["id"] = (char*)mac_adress.c_str();
if (advertisedDevice->haveName())
BLEdata["name"] = (char*)advertisedDevice->getName().c_str();
if (advertisedDevice->haveManufacturerData()) {
char* manufacturerdata = BLEUtils::buildHexData(NULL, (uint8_t*)advertisedDevice->getManufacturerData().data(), advertisedDevice->getManufacturerData().length());
BLEdata["manufacturerdata"] = manufacturerdata;
free(manufacturerdata);
}
if (advertisedDevice->haveRSSI())
BLEdata["rssi"] = (int)advertisedDevice->getRSSI();
if (advertisedDevice->haveTXPower())
BLEdata["txpower"] = (int8_t)advertisedDevice->getTXPower();
if (advertisedDevice->haveServiceData()) {
int serviceDataCount = advertisedDevice->getServiceDataCount();
for (int j = 0; j < serviceDataCount; j++) {
std::string service_data = convertServiceData(advertisedDevice->getServiceData(j));
BLEdata["servicedata"] = (char*)service_data.c_str();
std::string serviceDatauuid = advertisedDevice->getServiceDataUUID(j).toString();
BLEdata["servicedatauuid"] = (char*)serviceDatauuid.c_str();
}
}
if (decoder.decodeBLEJson(BLEdata)) {
BLEdata.remove("manufacturerdata");
BLEdata.remove("servicedata");
BLEdata.remove("servicedatauuid");
BLEdata.remove("type");
BLEdata.remove("cidc");
BLEdata.remove("acts");
BLEdata.remove("cont");
BLEdata.remove("track");
Serial.print("TheengsDecoder found device: ");
serializeJson(BLEdata, Serial);
Serial.println("");
}
}
};
void setup() {
Serial.begin(115200);
Serial.println("Scanning...");
NimBLEDevice::setScanFilterMode(CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE);
NimBLEDevice::setScanDuplicateCacheSize(200);
NimBLEDevice::init("");
pBLEScan = NimBLEDevice::getScan(); //create new scan
// Set the callback for when devices are discovered, no duplicates.
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks(), false);
pBLEScan->setActiveScan(true); // Set active scanning, this will get more data from the advertiser.
pBLEScan->setInterval(97); // How often the scan occurs / switches channels; in milliseconds,
pBLEScan->setWindow(37); // How long to scan during the interval; in milliseconds.
pBLEScan->setMaxResults(0); // do not store the scan results, use callback only.
}
void loop() {
// If an error occurs that stops the scan, it will be restarted here.
if(pBLEScan->isScanning() == false) {
// Start scan with: duration = 0 seconds(forever), no scan end callback, not a continuation of a previous scan.
pBLEScan->start(0, nullptr, false);
}
delay(2000);
}
Biblioteki do zainstalowania:
- ArduinoJson
- NimBLE-Arduino
- TheengsDecoder
https://decoder.theengs.io/devices/devices.html
Aktualnie około 100 urządzeń, listę zawsze można rozszerzyć.