From b2e12bc36d219273da1706aa8a6c7a2aac7826bf Mon Sep 17 00:00:00 2001 From: Mit4el Date: Mon, 30 Oct 2023 22:52:45 +0300 Subject: [PATCH 1/7] fix Ble --- src/modules/sensors/Ble/Ble.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/modules/sensors/Ble/Ble.cpp b/src/modules/sensors/Ble/Ble.cpp index 6811e436..1e57957a 100644 --- a/src/modules/sensors/Ble/Ble.cpp +++ b/src/modules/sensors/Ble/Ble.cpp @@ -246,7 +246,9 @@ public: } } - ~BleScan(){}; + ~BleScan(){ + BleSensArray.clear(); + }; }; //======================================================================================================= From 8cd131bda2a2e2ec15fac4a194dad700a984faaf Mon Sep 17 00:00:00 2001 From: Mit4el Date: Tue, 31 Oct 2023 22:03:33 +0300 Subject: [PATCH 2/7] bugfix Ble --- src/modules/sensors/Ble/Ble.cpp | 80 ++++++++++++++++++++++++---- src/modules/sensors/Ble/modinfo.json | 26 +++++---- 2 files changed, 87 insertions(+), 19 deletions(-) diff --git a/src/modules/sensors/Ble/Ble.cpp b/src/modules/sensors/Ble/Ble.cpp index 1e57957a..45b3658d 100644 --- a/src/modules/sensors/Ble/Ble.cpp +++ b/src/modules/sensors/Ble/Ble.cpp @@ -18,7 +18,15 @@ private: // описание параметров передаваемых из настроек датчика из веба String _MAC; String _sensor; - int timeRecv; + int timeRecv = 0; + int _minutesPassed = 0; + String json = "{}"; + int orange = 0; + int red = 0; + int offline = 0; + int _int; + bool dataFromNode = false; + public: String whoIAm(/*String &mac, String &sens*/) { @@ -38,6 +46,9 @@ public: if (timeRecv > 0) { value.valS = s; + dataFromNode = true; + _minutesPassed = 0; + setNewWidgetAttributes(); } else { @@ -55,12 +66,18 @@ public: value.isDecimal = 1; value.valD = valStr.toFloat(); regEvent(value.valD, _id); + dataFromNode = true; + _minutesPassed = 0; + setNewWidgetAttributes(); } else { value.isDecimal = 0; value.valS = valStr; regEvent(value.valS, _id); + dataFromNode = true; + _minutesPassed = 0; + setNewWidgetAttributes(); } } else @@ -99,12 +116,56 @@ public: } regEvent(value.valS, _id); } + _minutesPassed++; + setNewWidgetAttributes(); + } + void onMqttWsAppConnectEvent() + { + setNewWidgetAttributes(); + } + void setNewWidgetAttributes() + { + + int minutes_ = _minutesPassed * _int / 60; + jsonWriteStr(json, F("info"), prettyMinutsTimeout(minutes_)); + if (dataFromNode) + { + if (orange != 0 && red != 0 && offline != 0) + { + if (minutes_ < orange) + { + jsonWriteStr(json, F("color"), ""); + } + if (minutes_ >= orange && minutes_ < red) + { + jsonWriteStr(json, F("color"), F("orange")); // сделаем виджет оранжевым + } + if (minutes_ >= red && minutes_ < offline) + { + jsonWriteStr(json, F("color"), F("red")); // сделаем виджет красным + } + if (minutes_ >= offline) + { + jsonWriteStr(json, F("info"), F("offline")); + } + } + } + else + { + jsonWriteStr(json, F("info"), F("awaiting")); + } + sendSubWidgetsValues(_id, json); } BleSens(String parameters) : IoTItem(parameters) { _MAC = jsonReadStr(parameters, "MAC"); _sensor = jsonReadStr(parameters, "sensor"); + jsonRead(parameters, F("orange"), orange); + jsonRead(parameters, F("red"), red); + jsonRead(parameters, F("offline"), offline); + jsonRead(parameters, F("int"), _int); + dataFromNode = false; BleSensArray.push_back(this); } @@ -186,8 +247,9 @@ public: BLEdata.remove("acts"); BLEdata.remove("cont"); BLEdata.remove("track"); + BLEdata.remove("id"); - String mac_address = BLEdata["id"].as(); + String mac_address = BLEdata["MAC"].as(); mac_address.replace(":", ""); // дописываем время прихода пакета данных BLEdata["last"] = millis(); @@ -199,13 +261,15 @@ public: // { // String val = BLEdata.as(); String output; + BLEdata.remove("servicedatauuid"); serializeJson(BLEdata, output); - SerialPrint("i", F("BLE"), _id + " " + output); + SerialPrint("i", F("BLE"), mac_address + " " + output); //} } + + SerialPrint("i", F("BLE"), "found: " + mac_address); } - BLEdata.remove("servicedatauuid"); - SerialPrint("i", F("BLE"), "found: " + mac_address); + // Перебираем все зарегистрированные сенсоры BleSens for (std::vector::iterator it = BleSensArray.begin(); it != BleSensArray.end(); ++it) @@ -246,9 +310,7 @@ public: } } - ~BleScan(){ - BleSensArray.clear(); - }; + ~BleScan() { BleSensArray.clear(); }; }; //======================================================================================================= @@ -267,4 +329,4 @@ void *getAPI_Ble(String subtype, String param) { return nullptr; } -} +} \ No newline at end of file diff --git a/src/modules/sensors/Ble/modinfo.json b/src/modules/sensors/Ble/modinfo.json index b46fe322..a3ef4e58 100644 --- a/src/modules/sensors/Ble/modinfo.json +++ b/src/modules/sensors/Ble/modinfo.json @@ -12,7 +12,7 @@ "int": 135, "scanDuration": 10, "filter": "servicedatauuid", - "debug":1 + "debug": 1 }, { "name": "bluetooth датчик", @@ -26,6 +26,9 @@ "int": 30, "global": 0, "round": 1, + "orange": 60, + "red": 120, + "offline": 180, "MAC": "", "sensor": "" } @@ -49,6 +52,9 @@ "moduleDesc": "Позволяет получить данные с Bluetooth часов и термометров Mijia, Xiaomi, Cleargrass, ...", "propInfo": { "round": "Округление после запятой.", + "orange": "количество минут после которого окрасить виджет в оранжевый цвет", + "red": "количество минут после которого окрасить виджет в красный цвет", + "offline": "количество минут после которого отобразить что устройство offline, если все три orange red и offline поставить в ноль - то функция окраски выключится", "int": "Интервал сканирования BLE окружения (BleScan) / В BleSens темп обновления времнени поступления данных, сами даные обновляются по мене сканирования/поступления", "scanDuration": "Длительность сканирования ", "filter": "Позволяет установить фильтр по параметру передаваемому датчиком. Влияет только на вывод лога при debug=1, что бы было легче найти датчики, если много устройств в эфире", @@ -59,27 +65,27 @@ "defActive": false, "usedLibs": { "esp32_4mb": [ - "https://github.com/h2zero/NimBLE-Arduino.git", + "https://github.com/Mit4el/NimBLE-Arduino.git", "https://github.com/Mit4el/decoder.git" ], "esp32_16mb": [ - "https://github.com/h2zero/NimBLE-Arduino.git", + "https://github.com/Mit4el/NimBLE-Arduino.git", "https://github.com/Mit4el/decoder.git" ], "esp32_4mb3f": [ - "https://github.com/h2zero/NimBLE-Arduino.git", + "https://github.com/Mit4el/NimBLE-Arduino.git", "https://github.com/Mit4el/decoder.git" - ], + ], "esp32cam_4mb": [ - "https://github.com/h2zero/NimBLE-Arduino.git", + "https://github.com/Mit4el/NimBLE-Arduino.git", "https://github.com/Mit4el/decoder.git" - ], + ], "esp32s3_16mb": [ - "https://github.com/h2zero/NimBLE-Arduino.git", + "https://github.com/Mit4el/NimBLE-Arduino.git", "https://github.com/Mit4el/decoder.git" - ], + ], "esp32c3m_4mb": [ - "https://github.com/h2zero/NimBLE-Arduino.git", + "https://github.com/Mit4el/NimBLE-Arduino.git", "https://github.com/Mit4el/decoder.git" ] } From 8ae5c07302789bb278a606162667d4e781b4b358 Mon Sep 17 00:00:00 2001 From: Mit4el Date: Mon, 13 Nov 2023 23:36:40 +0300 Subject: [PATCH 3/7] bugfix Ble --- src/modules/sensors/Ble/Ble.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/modules/sensors/Ble/Ble.cpp b/src/modules/sensors/Ble/Ble.cpp index 45b3658d..0d433c8e 100644 --- a/src/modules/sensors/Ble/Ble.cpp +++ b/src/modules/sensors/Ble/Ble.cpp @@ -80,12 +80,6 @@ public: setNewWidgetAttributes(); } } - else - { - value.isDecimal = 0; - value.valS = ""; - regEvent(value.valS, _id); - } } } char *TimeToString(unsigned long t) @@ -240,6 +234,14 @@ public: if (decoder.decodeBLEJson(BLEdata)) { + String mac_address = BLEdata["MAC"].as(); + if (mac_address == "") + { + BLEdata["MAC"] = BLEdata["id"]; + mac_address = BLEdata["id"].as(); + } + mac_address.replace(":", ""); + BLEdata.remove("manufacturerdata"); BLEdata.remove("servicedata"); BLEdata.remove("type"); @@ -249,8 +251,6 @@ public: BLEdata.remove("track"); BLEdata.remove("id"); - String mac_address = BLEdata["MAC"].as(); - mac_address.replace(":", ""); // дописываем время прихода пакета данных BLEdata["last"] = millis(); if (_debug) @@ -267,7 +267,7 @@ public: //} } - SerialPrint("i", F("BLE"), "found: " + mac_address); + SerialPrint("i", F("BLE"), "found: " + String(BLEdata["MAC"].as())); } // Перебираем все зарегистрированные сенсоры BleSens From 5f1a9b23e5c97cf7b63bd0e711cabfeb00763466 Mon Sep 17 00:00:00 2001 From: Mit4el Date: Mon, 13 Nov 2023 23:55:05 +0300 Subject: [PATCH 4/7] new NextionUpload + Telegram_v2 --- include/classes/IoTItem.h | 3 + src/classes/IoTItem.cpp | 3 + .../display/NextionUpload/NextionUpload.cpp | 160 ++++++++++++++++++ .../display/NextionUpload/modinfo.json | 63 +++++++ src/modules/exec/Telegram_v2/Telegram_v2.cpp | 7 +- 5 files changed, 233 insertions(+), 3 deletions(-) create mode 100644 src/modules/display/NextionUpload/NextionUpload.cpp create mode 100644 src/modules/display/NextionUpload/modinfo.json diff --git a/include/classes/IoTItem.h b/include/classes/IoTItem.h index 3ad344f8..8eab3261 100644 --- a/include/classes/IoTItem.h +++ b/include/classes/IoTItem.h @@ -74,6 +74,9 @@ class IoTItem { virtual void onModuleOrder(String& key, String& value); virtual void onTrackingValue(IoTItem* item); // момент, когда ядро заметило изменение отслеживаемого значения + // для обновления экрана Nextion из телеграм + virtual void uploadNextionTlgrm(String &url); + // методы для графиков (будет упрощено) virtual void publishValue(); virtual void clearValue(); diff --git a/src/classes/IoTItem.cpp b/src/classes/IoTItem.cpp index 798ec902..ee588dc2 100644 --- a/src/classes/IoTItem.cpp +++ b/src/classes/IoTItem.cpp @@ -206,6 +206,9 @@ bool IoTItem::isTracking(IoTItem* item) { void IoTItem::sendTelegramMsg(bool often, String msg) {} void IoTItem::sendFoto(uint8_t *buf, uint32_t length, const String &name) {} void IoTItem::editFoto(uint8_t *buf, uint32_t length, const String &name) {} +// для обновления экрана Nextion из телеграм +void IoTItem::uploadNextionTlgrm(String &url) {} + // методы для графиков (будет упрощено) void IoTItem::publishValue() {} void IoTItem::clearValue() {} diff --git a/src/modules/display/NextionUpload/NextionUpload.cpp b/src/modules/display/NextionUpload/NextionUpload.cpp new file mode 100644 index 00000000..65ae8dd6 --- /dev/null +++ b/src/modules/display/NextionUpload/NextionUpload.cpp @@ -0,0 +1,160 @@ + +#define DEBUG_SERIAL_ENABLE +#include "Global.h" +#include "classes/IoTItem.h" +#include "ESPNexUpload.h" +bool updated = false; + +class NextionUpload : public IoTItem +{ +private: + String _url; + String _host; + int _NEXT_RX; + int _NEXT_TX; + bool _UpTelegram; + +public: + NextionUpload(String parameters) : IoTItem(parameters) + { + _url = jsonReadStr(parameters, "url"); + _url = "/" + _url; + _host = jsonReadStr(parameters, "host"); + + _NEXT_RX = jsonReadInt(parameters, "NEXT_RX"); + _NEXT_TX = jsonReadInt(parameters, "NEXT_TX"); + jsonRead(parameters, "UpTelegram", _UpTelegram); + +#define NEXT_RX _NEXT_RX // Nextion RX pin | Default 16 +#define NEXT_TX _NEXT_TX // Nextion TX pin | Default 17 + } + + IoTValue execute(String command, std::vector ¶m) + { + + if (command == "Update") + { + SerialPrint("I", F("NextionUpdate"), "Update .... "); + + if (!updated) + { + SerialPrint("I", F("NextionUpdate"), "connecting to " + (String)_host); + HTTPClient http; + +#if defined ESP8266 + if (!http.begin(_host, 80, _url)) + { + // Serial.println("connection failed"); + SerialPrint("I", F("NextionUpdate"), "connection failed "); + } +#elif defined ESP32 + if (!http.begin(String("http://") + _host + _url)) + { + // Serial.println("connection failed"); + SerialPrint("I", F("NextionUpdate"), "connection failed "); + } +#endif + + SerialPrint("I", F("NextionUpdate"), "Requesting file: " + (String)_url); + int code = http.GET(); + // Update the nextion display + if (code == 200) + { + flashNextion(http); + } + else + { + SerialPrint("I", F("NextionUpdate"), "HTTP error: " + (String)http.errorToString(code).c_str()); + } + + http.end(); + SerialPrint("I", F("NextionUpdate"), "Closing connection "); + } + } + + return {}; + } + + void uploadNextionTlgrm(String &url) + { + if (!_UpTelegram) + return; + if (!updated) + { + SerialPrint("I", F("NextionUpdate"), "connecting to " + url); + + HTTPClient http; + +#ifdef ESP8266 // esp8266 требует SSl + return; + // BearSSL::WiFiClientSecure client; + // client.setInsecure(); + // http.begin(client, url); // пингуем файл +#else // esp32 сама умеет SSL + if (!http.begin(url)) // пингуем файл + { + SerialPrint("I", F("NextionUpdate"), "connection failed "); + } +#endif + SerialPrint("I", F("NextionUpdate"), "Requesting file: " + (String)_url); + int code = http.GET(); + // Update the nextion display + if (code == 200) + { // файл доступен + flashNextion(http); + } + else + { + SerialPrint("I", F("NextionUpdate"), "HTTP error: " + (String)http.errorToString(code).c_str()); + } + + http.end(); + SerialPrint("I", F("NextionUpdate"), "Closing connection "); + } + } + + void flashNextion(HTTPClient &http) + { + int contentLength = http.getSize(); + SerialPrint("I", F("NextionUpdate"), "File received. Update Nextion... "); + bool result; + ESPNexUpload nextion(115200); + nextion.setUpdateProgressCallback([]() + { SerialPrint("I", F("NextionUpdate"), "... "); }); + + result = nextion.prepareUpload(contentLength); + if (!result) + { + SerialPrint("I", F("NextionUpdate"), "Error: " + (String)nextion.statusMessage); + } + else + { + SerialPrint("I", F("NextionUpdate"), "Start upload. File size is: " + (String)contentLength); + result = nextion.upload(*http.getStreamPtr()); + if (result) + { + updated = true; + SerialPrint("I", F("NextionUpdate"), "Succesfully updated Nextion! "); + } + else + { + SerialPrint("I", F("NextionUpdate"), "Error updating Nextion: " + (String)nextion.statusMessage); + } + nextion.end(); + } + } + + ~NextionUpload(){}; +}; + +void *getAPI_NextionUpload(String subtype, String param) +{ + if (subtype == F("NextionUpload")) + { + return new NextionUpload(param); + } + else + { + return nullptr; + } +} diff --git a/src/modules/display/NextionUpload/modinfo.json b/src/modules/display/NextionUpload/modinfo.json new file mode 100644 index 00000000..aed9d0ce --- /dev/null +++ b/src/modules/display/NextionUpload/modinfo.json @@ -0,0 +1,63 @@ +{ + "menuSection": "screens", + "configItem": [ + { + "global": 0, + "name": "Nextion Uploud", + "type": "Reading", + "subtype": "NextionUpload", + "id": "Nextion", + "widget": "", + "page": "", + "descr": "", + "host": "192.168.1.10", + "url": "nextion.tft", + "NEXT_TX": 16, + "NEXT_RX": 17, + "UpTelegram": 1 + } + ], + "about": { + "authorName": "AVAKS", + "authorContact": "https://t.me/@avaks_dev", + "authorGit": "https://github.com/avaksru", + "specialThanks": "", + "moduleName": "NextionUpload", + "moduleVersion": "1.1", + "usedRam": { + "esp32_4mb": 15, + "esp8266_4mb": 15 + }, + "title": "Nextion Upload", + "moduleDesc": "загрузка прошивки в дисплей Nextion. Команда для запуска обновления дисплея: Nextion.Update(); ", + "propInfo": { + "host": "Сервер обновления. Можно использовать LiveServer из VisualCode, указывать ip адрес", + "url": "файл прошивки экрана, указывать с расширением, например nextion.tft или iotm/test.tft", + "UpTelegram": "1 - разрешает прошивать экран через модуль Telegram_v2" + } + }, + "defActive": false, + "usedLibs": { + "esp32_4mb": [ + "https://github.com/Nredor/ESPNexUpload.git" + ], + "esp32_4mb3f": [ + "https://github.com/Nredor/ESPNexUpload.git" + ], + "esp8266_4mb": [ + "https://github.com/Nredor/ESPNexUpload.git" + ], + "esp8266_1mb": [ + "https://github.com/Nredor/ESPNexUpload.git" + ], + "esp8266_1mb_ota": [ + "https://github.com/Nredor/ESPNexUpload.git" + ], + "esp8285_1mb": [ + "https://github.com/Nredor/ESPNexUpload.git" + ], + "esp8285_1mb_ota": [ + "https://github.com/Nredor/ESPNexUpload.git" + ] + } +} \ No newline at end of file diff --git a/src/modules/exec/Telegram_v2/Telegram_v2.cpp b/src/modules/exec/Telegram_v2/Telegram_v2.cpp index ed50c7e1..ecaaaa4e 100644 --- a/src/modules/exec/Telegram_v2/Telegram_v2.cpp +++ b/src/modules/exec/Telegram_v2/Telegram_v2.cpp @@ -240,11 +240,12 @@ public: } else if (msg.text.indexOf("nextion") != -1 && msg.chatID == _chatID) { - if (downloadFile(msg)) - { - // flashNextion(); + for (std::list::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it) { + if ((*it)->getSubtype() == "NextionUpload") { + (*it)->uploadNextionTlgrm(msg.fileUrl); } } + } } else if (msg.text.indexOf("help") != -1) { From e5781dc424fc6e2dfd31d0eb0087873e1b59d76a Mon Sep 17 00:00:00 2001 From: Mit4el Date: Wed, 15 Nov 2023 21:54:02 +0300 Subject: [PATCH 5/7] new Ble ver, 2 parts --- lib/decoder/include/shared/theengs.h | 39 + lib/decoder/src/decoder.h | 1112 +++++++++++++++++ lib/decoder/src/devices.h | 245 ++++ lib/decoder/src/devices/ABN03_json.h | 55 + lib/decoder/src/devices/ABN07_json.h | 52 + lib/decoder/src/devices/ABTemp_json.h | 68 + lib/decoder/src/devices/APPLE_json.h | 40 + lib/decoder/src/devices/Amphiro_json.h | 55 + lib/decoder/src/devices/BC08_json.h | 59 + lib/decoder/src/devices/BM1IN1_json.h | 33 + lib/decoder/src/devices/BM2_json.h | 33 + lib/decoder/src/devices/BM3IN1_json.h | 49 + lib/decoder/src/devices/BM4IN1_json.h | 49 + lib/decoder/src/devices/BM6_json.h | 32 + lib/decoder/src/devices/BPARASITE_json.h | 72 ++ lib/decoder/src/devices/BWBSDOO_json.h | 32 + lib/decoder/src/devices/CGD1_json.h | 31 + lib/decoder/src/devices/CGDK2_json.h | 87 ++ lib/decoder/src/devices/CGDN1_json.h | 55 + lib/decoder/src/devices/CGG1_json.h | 125 ++ lib/decoder/src/devices/CGH1_json.h | 37 + lib/decoder/src/devices/CGP1W_json.h | 49 + lib/decoder/src/devices/CGPR1_json.h | 58 + lib/decoder/src/devices/GAEN_json.h | 33 + lib/decoder/src/devices/H5055_json.h | 74 ++ lib/decoder/src/devices/H5072_json.h | 33 + lib/decoder/src/devices/H5074_json.h | 26 + lib/decoder/src/devices/H5102_json.h | 33 + lib/decoder/src/devices/H5106_json.h | 52 + lib/decoder/src/devices/H5179_json.h | 26 + lib/decoder/src/devices/HHCCJCY01HHCC_json.h | 58 + lib/decoder/src/devices/HHCCJCY10_json.h | 54 + lib/decoder/src/devices/HHCCPOT002_json.h | 41 + lib/decoder/src/devices/IBS_THBP01B_json.h | 51 + lib/decoder/src/devices/IBT_2X_json.h | 70 ++ lib/decoder/src/devices/IBT_4XS_json.h | 62 + lib/decoder/src/devices/IBT_6XS_SOLIS6_json.h | 80 ++ lib/decoder/src/devices/JHT_F525_json.h | 26 + lib/decoder/src/devices/JQJCY01YM_json.h | 60 + lib/decoder/src/devices/KKM_K6P_json.h | 50 + lib/decoder/src/devices/KKM_K9_json.h | 74 ++ lib/decoder/src/devices/LYWSD02_json.h | 32 + .../src/devices/LYWSD03MMC_ENCR_json.h | 39 + lib/decoder/src/devices/LYWSD03MMC_json.h | 85 ++ lib/decoder/src/devices/LYWSDCGQ_json.h | 37 + lib/decoder/src/devices/MBXPRO_json.h | 82 ++ lib/decoder/src/devices/MS_CDP_json.h | 25 + lib/decoder/src/devices/MUE4094RT_json.h | 34 + lib/decoder/src/devices/Miband_json.h | 49 + lib/decoder/src/devices/Mokobeacon_json.h | 49 + lib/decoder/src/devices/Mopeka_json.h | 91 ++ lib/decoder/src/devices/OralB_json.h | 78 ++ lib/decoder/src/devices/PH10_json.h | 25 + lib/decoder/src/devices/RDL52832_json.h | 154 +++ lib/decoder/src/devices/RuuviTag_RAWv1_json.h | 73 ++ lib/decoder/src/devices/RuuviTag_RAWv2_json.h | 103 ++ lib/decoder/src/devices/SBBT_002C_ENCR_json.h | 47 + lib/decoder/src/devices/SBBT_002C_json.h | 50 + lib/decoder/src/devices/SBCS_json.h | 83 ++ lib/decoder/src/devices/SBCU_json.h | 55 + lib/decoder/src/devices/SBDW_002C_ENCR_json.h | 47 + lib/decoder/src/devices/SBDW_002C_json.h | 68 + lib/decoder/src/devices/SBMO_003Z_ENCR_json.h | 47 + lib/decoder/src/devices/SBMO_003Z_json.h | 59 + lib/decoder/src/devices/SBMS_json.h | 71 ++ lib/decoder/src/devices/SBMT_json.h | 37 + lib/decoder/src/devices/SBOT_json.h | 40 + lib/decoder/src/devices/SBS1_json.h | 40 + lib/decoder/src/devices/SCD4X_json.h | 43 + lib/decoder/src/devices/SHT4X_json.h | 24 + lib/decoder/src/devices/ServiceData_json.h | 25 + lib/decoder/src/devices/Skale_json.h | 26 + lib/decoder/src/devices/SmartDry_json.h | 54 + lib/decoder/src/devices/T201_json.h | 29 + lib/decoder/src/devices/T301_json.h | 29 + lib/decoder/src/devices/TPMS_json.h | 64 + lib/decoder/src/devices/TPTH_json.h | 22 + lib/decoder/src/devices/ThermoBeacon_json.h | 94 ++ lib/decoder/src/devices/XMTZC04HMKG_json.h | 40 + lib/decoder/src/devices/XMTZC04HMLB_json.h | 40 + lib/decoder/src/devices/XMTZC05HMKG_json.h | 48 + lib/decoder/src/devices/XMTZC05HMLB_json.h | 48 + lib/decoder/src/devices/common_props.h | 90 ++ lib/decoder/src/devices/iBeacon_json.h | 64 + lib/decoder/src/devices/iNodeEM_json.h | 72 ++ lib/decoder/src/devices/tracker_json.h | 85 ++ src/modules/sensors/Ble/Ble.cpp | 33 +- src/modules/sensors/Ble/modinfo.json | 24 +- src/modules/sensors/Ble_part1/Ble_p1.cpp | 338 +++++ src/modules/sensors/Ble_part1/modinfo.json | 86 ++ src/modules/sensors/Ble_part2/Ble_p2.cpp | 339 +++++ src/modules/sensors/Ble_part2/modinfo.json | 86 ++ 92 files changed, 6745 insertions(+), 28 deletions(-) create mode 100644 lib/decoder/include/shared/theengs.h create mode 100644 lib/decoder/src/decoder.h create mode 100644 lib/decoder/src/devices.h create mode 100644 lib/decoder/src/devices/ABN03_json.h create mode 100644 lib/decoder/src/devices/ABN07_json.h create mode 100644 lib/decoder/src/devices/ABTemp_json.h create mode 100644 lib/decoder/src/devices/APPLE_json.h create mode 100644 lib/decoder/src/devices/Amphiro_json.h create mode 100644 lib/decoder/src/devices/BC08_json.h create mode 100644 lib/decoder/src/devices/BM1IN1_json.h create mode 100644 lib/decoder/src/devices/BM2_json.h create mode 100644 lib/decoder/src/devices/BM3IN1_json.h create mode 100644 lib/decoder/src/devices/BM4IN1_json.h create mode 100644 lib/decoder/src/devices/BM6_json.h create mode 100644 lib/decoder/src/devices/BPARASITE_json.h create mode 100644 lib/decoder/src/devices/BWBSDOO_json.h create mode 100644 lib/decoder/src/devices/CGD1_json.h create mode 100644 lib/decoder/src/devices/CGDK2_json.h create mode 100644 lib/decoder/src/devices/CGDN1_json.h create mode 100644 lib/decoder/src/devices/CGG1_json.h create mode 100644 lib/decoder/src/devices/CGH1_json.h create mode 100644 lib/decoder/src/devices/CGP1W_json.h create mode 100644 lib/decoder/src/devices/CGPR1_json.h create mode 100644 lib/decoder/src/devices/GAEN_json.h create mode 100644 lib/decoder/src/devices/H5055_json.h create mode 100644 lib/decoder/src/devices/H5072_json.h create mode 100644 lib/decoder/src/devices/H5074_json.h create mode 100644 lib/decoder/src/devices/H5102_json.h create mode 100644 lib/decoder/src/devices/H5106_json.h create mode 100644 lib/decoder/src/devices/H5179_json.h create mode 100644 lib/decoder/src/devices/HHCCJCY01HHCC_json.h create mode 100644 lib/decoder/src/devices/HHCCJCY10_json.h create mode 100644 lib/decoder/src/devices/HHCCPOT002_json.h create mode 100644 lib/decoder/src/devices/IBS_THBP01B_json.h create mode 100644 lib/decoder/src/devices/IBT_2X_json.h create mode 100644 lib/decoder/src/devices/IBT_4XS_json.h create mode 100644 lib/decoder/src/devices/IBT_6XS_SOLIS6_json.h create mode 100644 lib/decoder/src/devices/JHT_F525_json.h create mode 100644 lib/decoder/src/devices/JQJCY01YM_json.h create mode 100644 lib/decoder/src/devices/KKM_K6P_json.h create mode 100644 lib/decoder/src/devices/KKM_K9_json.h create mode 100644 lib/decoder/src/devices/LYWSD02_json.h create mode 100644 lib/decoder/src/devices/LYWSD03MMC_ENCR_json.h create mode 100644 lib/decoder/src/devices/LYWSD03MMC_json.h create mode 100644 lib/decoder/src/devices/LYWSDCGQ_json.h create mode 100644 lib/decoder/src/devices/MBXPRO_json.h create mode 100644 lib/decoder/src/devices/MS_CDP_json.h create mode 100644 lib/decoder/src/devices/MUE4094RT_json.h create mode 100644 lib/decoder/src/devices/Miband_json.h create mode 100644 lib/decoder/src/devices/Mokobeacon_json.h create mode 100644 lib/decoder/src/devices/Mopeka_json.h create mode 100644 lib/decoder/src/devices/OralB_json.h create mode 100644 lib/decoder/src/devices/PH10_json.h create mode 100644 lib/decoder/src/devices/RDL52832_json.h create mode 100644 lib/decoder/src/devices/RuuviTag_RAWv1_json.h create mode 100644 lib/decoder/src/devices/RuuviTag_RAWv2_json.h create mode 100644 lib/decoder/src/devices/SBBT_002C_ENCR_json.h create mode 100644 lib/decoder/src/devices/SBBT_002C_json.h create mode 100644 lib/decoder/src/devices/SBCS_json.h create mode 100644 lib/decoder/src/devices/SBCU_json.h create mode 100644 lib/decoder/src/devices/SBDW_002C_ENCR_json.h create mode 100644 lib/decoder/src/devices/SBDW_002C_json.h create mode 100644 lib/decoder/src/devices/SBMO_003Z_ENCR_json.h create mode 100644 lib/decoder/src/devices/SBMO_003Z_json.h create mode 100644 lib/decoder/src/devices/SBMS_json.h create mode 100644 lib/decoder/src/devices/SBMT_json.h create mode 100644 lib/decoder/src/devices/SBOT_json.h create mode 100644 lib/decoder/src/devices/SBS1_json.h create mode 100644 lib/decoder/src/devices/SCD4X_json.h create mode 100644 lib/decoder/src/devices/SHT4X_json.h create mode 100644 lib/decoder/src/devices/ServiceData_json.h create mode 100644 lib/decoder/src/devices/Skale_json.h create mode 100644 lib/decoder/src/devices/SmartDry_json.h create mode 100644 lib/decoder/src/devices/T201_json.h create mode 100644 lib/decoder/src/devices/T301_json.h create mode 100644 lib/decoder/src/devices/TPMS_json.h create mode 100644 lib/decoder/src/devices/TPTH_json.h create mode 100644 lib/decoder/src/devices/ThermoBeacon_json.h create mode 100644 lib/decoder/src/devices/XMTZC04HMKG_json.h create mode 100644 lib/decoder/src/devices/XMTZC04HMLB_json.h create mode 100644 lib/decoder/src/devices/XMTZC05HMKG_json.h create mode 100644 lib/decoder/src/devices/XMTZC05HMLB_json.h create mode 100644 lib/decoder/src/devices/common_props.h create mode 100644 lib/decoder/src/devices/iBeacon_json.h create mode 100644 lib/decoder/src/devices/iNodeEM_json.h create mode 100644 lib/decoder/src/devices/tracker_json.h create mode 100644 src/modules/sensors/Ble_part1/Ble_p1.cpp create mode 100644 src/modules/sensors/Ble_part1/modinfo.json create mode 100644 src/modules/sensors/Ble_part2/Ble_p2.cpp create mode 100644 src/modules/sensors/Ble_part2/modinfo.json diff --git a/lib/decoder/include/shared/theengs.h b/lib/decoder/include/shared/theengs.h new file mode 100644 index 00000000..3ed58da7 --- /dev/null +++ b/lib/decoder/include/shared/theengs.h @@ -0,0 +1,39 @@ +/* + TheengsDecoder - Decode things and devices + + Copyright: (c)Florian ROBERT + + This file is part of TheengsDecoder. + + TheengsDecoder is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + TheengsDecoder is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _THEENGS_H_ +#define _THEENGS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +void* Theengs_NewDecoder(); +void Theengs_DestroyDecoder(void* decoder); +const char* Theengs_DecodeBLE(void* decoder, const char* json_data); +const char* Theengs_GetProperties(void* decoder, const char* model_id); +const char* Theengs_GetAttribute(void* decoder, const char* model_id, const char* attribute); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _THEENGS_H_ \ No newline at end of file diff --git a/lib/decoder/src/decoder.h b/lib/decoder/src/decoder.h new file mode 100644 index 00000000..f31e131d --- /dev/null +++ b/lib/decoder/src/decoder.h @@ -0,0 +1,1112 @@ +/* + TheengsDecoder - Decode things and devices + + Copyright: (c)Florian ROBERT + + This file is part of TheengsDecoder. + + TheengsDecoder is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + TheengsDecoder is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +//#define DEBUG_DECODER +#ifdef BLE_PART1 +#define PART1_XIAOMI +#endif +#ifdef BLE_PART2 +#define PART2_OTHER +#endif + + +#ifndef _DECODER_H_ +#define _DECODER_H_ + +//#define ARDUINOJSON_USE_LONG_LONG 1 +#include "ArduinoJson.h" + + + +#include +#include + +#include "devices.h" + +#ifdef DEBUG_DECODER +# include +# define DEBUG_PRINT(...) \ + { printf(__VA_ARGS__); } +#else +# define DEBUG_PRINT(...) \ + {} +#endif + +#ifdef UNIT_TESTING +# define TEST_MAX_DOC 16384UL +# include +static size_t peakDocSize = 0; +#endif + +#define SVC_DATA "servicedata" +#define MFG_DATA "manufacturerdata" + +class TheengsDecoder; +typedef double (TheengsDecoder::*decoder_function)(const char* data_str, + int offset, int data_length, + bool reverse, bool canBeNegative, bool isFloat); + +typedef double (TheengsDecoder::*staticbitdecoder_function)(const char* data_str, + const char* source_str, int offset, int bitindex, + const char* falseresult, const char* trueresult); + + + +class TheengsDecoder { +public: + + TheengsDecoder() {} + ~TheengsDecoder() {} +/* + int decodeBLEJson(JsonObject& jsondata); + void setMinServiceDataLen(size_t len); + void setMinManufacturerDataLen(size_t len); + std::string getTheengProperties(const char* model_id); + std::string getTheengProperties(int mod_index); + std::string getTheengAttribute(const char* model_id, const char* attribute); + std::string getTheengAttribute(int model_id, const char* attribute); + int getTheengModel(JsonDocument& doc, const char* model_id); +#ifdef UNIT_TESTING + int testDocMax(); +#endif +*/ + enum BLE_ID_NUM { + UNKNOWN_MODEL = -1, + HHCCJCY01HHCC = 0, + LYWSD02, + LYWSDCGQ, + CGP1W, + CGG1_STOCK, + CGG1_ATC1441, + CGG1_PVVX, + CGG1_STOCK_2, + CGDN1, + CGD1, + CGDK2_STOCK, + CGDK2_PVVX, + CGDK2_ATC1441, + CGH1, + JQJCY01YM, + IBSTHBP01B, + IBT_2X, + IBT_2XS, + IBT4XS, + IBT6XS_SOLIS, + MIBAND, + XMTZC04HMKG, + XMTZC04HMLB, + XMTZC05HMKG, + XMTZC05HMLB, + TPMS, + KKM_K6P, + KKM_K9, + LYWSD03MMC_ATC, + LYWSD03MMC_PVVX, + LYWSD03MMC_PVVX_DECR, + LYWSD03MMC_PVVX_ENCR, + CGPR1, + THERMOBEACON, + H5055, + H5072, + H5074, + H5102, + H5106, + H5179, + HHCCJCY10, + MUE4094RT, + MOKOBEACON, + MOKOBEACONXPRO, + INODEEM, + RUUVITAG_RAWV1, + RUUVITAG_RAWV2, + SBCS, + SBCU, + SBMS, + SBMT, + SBOT, + SBS1, + SHT4X, + SCD4X, + SKALE, + SMARTDRY, + BC08, + BM1IN1, + BM3IN1, + BM4IN1, + MS_CDP, + GAEN, + HHCCPOT002, + BPARASITE, + BWBSDOO, + BM2, + BM6, + RDL52832, + ABN03, + ABN07, + ABTEMP, + AMPHIRO, + ORALB_BT, + PH10, + TPTH, + MOPEKA, + T201, + T301, + NUT, + ITAG, + TAGIT, + TILE, + TILEN, + JHT_F525, + IBEACON, + APPLE_CONT, + APPLE_CONTAT, + SERVICE_DATA, + SBBT_002C, + SBBT_002C_ENCR, + SBDW_002C, + SBDW_002C_ENCR, + SBMO_003Z, + SBMO_003Z_ENCR, + BLE_ID_MAX + }; +/* +private: + void reverse_hex_data(const char* in, char* out, int l); + double value_from_hex_string(const char* data_str, int offset, int data_length, bool reverse, bool canBeNegative = true, bool isFloat = false); + double bf_value_from_hex_string(const char* data_str, int offset, int data_length, bool reverse, bool canBeNegative = true, bool isFloat = false); + bool data_index_is_valid(const char* str, size_t index, size_t len); + bool data_length_is_valid(size_t data_len, size_t default_min, const JsonArray& condition, int *idx); + uint8_t getBinaryData(char ch); + bool evaluateDatalength(std::string op, size_t data_len, size_t req_len); + bool checkPropCondition(const JsonArray& prop, const char* svc_data, const char* mfg_data); + bool checkDeviceMatch(const JsonArray& condition, const char* svc_data, const char* mfg_data, + const char* dev_name, const char* svc_uuid, const char* mac_id); + std::string sanitizeJsonKey(const char* key_in); + */ + + size_t m_docMax = 12000; + size_t m_minSvcDataLen = 20; + size_t m_minMfgDataLen = 16; + + + +/* + * @brief Revert the string data 2 by 2 to get the correct endianness + */ +void reverse_hex_data(const char* in, char* out, int l) { + int i = l, j = 0; + while (i) { + out[j] = in[i - 2]; + out[j + 1] = in[i - 1]; + i -= 2; + j += 2; + } + out[l] = '\0'; +} + +double bf_value_from_hex_string(const char* data_str, + int offset, int data_length, + bool reverse, bool canBeNegative, bool isFloat) { + DEBUG_PRINT("extracting BCF data\n"); + + long value = (long)value_from_hex_string(data_str, offset, data_length, reverse, false, false); + double d_value = ((((value >> 8) * 100) + (uint8_t)value)) / 100.0; + + if (canBeNegative) { + if (data_length == 4 && value > SHRT_MAX) { + d_value = -d_value + (SCHAR_MAX + 1); + } + } + + return d_value; +} + +/* + * @brief Extracts the data value from the data string + */ +double value_from_hex_string(const char* data_str, + int offset, int data_length, + bool reverse, bool canBeNegative, bool isFloat) { + DEBUG_PRINT("offset: %d, len %d, rev %u, neg, %u, flo, %u\n", + offset, data_length, reverse, canBeNegative, isFloat); + std::string data(&data_str[offset], data_length); + + if (reverse) { + reverse_hex_data(&data_str[offset], &data[0], data_length); + } + + double value = 0; + if (!isFloat) { + value = strtoll(data.c_str(), NULL, 16); + DEBUG_PRINT("extracted value from %s = %lld\n", data.c_str(), (long long)value); + } else { + long longV = strtol(data.c_str(), NULL, 16); + float floatV = *((float*)&longV); + DEBUG_PRINT("extracted float value from %s = %f\n", data.c_str(), floatV); + value = floatV; + } + + if (canBeNegative) { + if (data_length <= 2 && value > SCHAR_MAX) { + value -= (UCHAR_MAX + 1); + } else if (data_length == 4 && value > SHRT_MAX) { + value -= (USHRT_MAX + 1); + } + } + + return value; +} + +/* + * @brief Removes the underscores at the beginning of key strings + * when duplicate properties exist in a device. + */ +std::string sanitizeJsonKey(const char* key_in) { + unsigned int key_index = 0; + while (key_in[key_index] == '_') { + key_index++; + } + return std::string(key_in + key_index); +} + +/* + * @brief Checks to ensure accessing data at the index + length of the string is valid. + */ +bool data_index_is_valid(const char* str, size_t index, size_t len) { + if (strlen(str) < (index + len)) { + return false; + } + return true; +} + +bool data_length_is_valid(size_t data_len, size_t default_min, + const JsonArray& condition, int* idx) { + std::string op = condition[*idx + 1].as(); + if (!op.empty() && op.length() > 2) { + return (data_len >= default_min); + } + + if (!condition[*idx + 2].is()) { + *idx = -1; + return false; + } + + size_t req_len = condition[*idx + 2].as(); + + *idx += 2; + return evaluateDatalength(op, data_len, req_len); +} + +uint8_t getBinaryData(char ch) { + uint8_t data = 0; + if (ch >= '0' && ch <= '9') + data = ch - '0'; + else if (ch >= 'a' && ch <= 'f') + data = 10 + (ch - 'a'); + + return data; +} + +bool evaluateDatalength(std::string op, size_t data_len, size_t req_len) { + if (op == "=" && data_len == req_len) return true; + if (op == ">=" && data_len >= req_len) return true; + if (op == ">" && data_len > req_len) return true; + if (op == "<=" && data_len <= req_len) return true; + if (op == "<" && data_len < req_len) return true; + + return false; +} + +bool checkDeviceMatch(const JsonArray& condition, + const char* svc_data, + const char* mfg_data, + const char* dev_name, + const char* svc_uuid, + const char* mac_id) { + bool match = false; + int cond_size = condition.size(); + + for (int i = 0; i < cond_size;) { + if (condition[i].is()) { + DEBUG_PRINT("found nested array\n"); + match = checkDeviceMatch(condition[i], svc_data, mfg_data, dev_name, svc_uuid, mac_id); + + if (++i < cond_size) { + if (!match && *condition[i].as() == '|') { + } else if (match && *condition[i].as() == '&') { + match = false; + } else { + break; + } + i++; + } else { + break; + } + } + + const char* cmp_str = nullptr; + const char* cond_str = condition[i].as(); + if (svc_data != nullptr && strstr(cond_str, SVC_DATA) != nullptr) { + if (data_length_is_valid(strlen(svc_data), m_minSvcDataLen, condition, &i)) { + cmp_str = svc_data; + match = true; + } else { + match = false; + if (i < 0) { + break; + } + } + } else if (mfg_data != nullptr && strstr(cond_str, MFG_DATA) != nullptr) { + if (data_length_is_valid(strlen(mfg_data), m_minMfgDataLen, condition, &i)) { + cmp_str = mfg_data; + match = true; + } else { + match = false; + if (i < 0) { + break; + } + } + } else if (dev_name != nullptr && strstr(cond_str, "name") != nullptr) { + cmp_str = dev_name; + } else if (svc_uuid != nullptr && strstr(cond_str, "uuid") != nullptr) { + cmp_str = svc_uuid; + } else { + break; + } + + if (!match && cmp_str == nullptr) { + while (i < cond_size && *cond_str != '|') { + if (!condition[++i].is()) { + continue; + } + cond_str = condition[i].as(); + } + + if (i < cond_size && cond_str != nullptr) { + i++; + continue; + } + } + + cond_str = condition[++i].as(); + if (cmp_str != nullptr && cond_str != nullptr && *cond_str != '&' && *cond_str != '|') { + if (cmp_str == svc_uuid && !strncmp(cmp_str, "0x", 2)) { + cmp_str += 2; + } + + if (strstr(cond_str, "contain") != nullptr) { + if (strstr(cmp_str, condition[++i].as()) != nullptr) { + match = true; // (strstr(cond_str, "not_") != nullptr) ? false : true; + } else { + match = false; // (strstr(cond_str, "not_") != nullptr) ? true : false; + } + i++; + } else if (strstr(cond_str, "mac@index") != nullptr) { + size_t cond_index = condition[++i].as(); + size_t cond_len = 12; + const char* string_to_compare = nullptr; + std::string mac_string = mac_id; + + // remove colons and make lower case + for (int x = 0; x < mac_string.length(); x++) { + if (mac_string[x] == ':') { + mac_string.erase(x, 1); + } + mac_string[x] = tolower(mac_string[x]); + } + + string_to_compare = mac_string.c_str(); + + if (strstr(cond_str, "revmac@index") != nullptr) { + char* reverse_mac_string = (char*)malloc(strlen(string_to_compare) + 1); + + reverse_hex_data(string_to_compare, reverse_mac_string, 12); + string_to_compare = reverse_mac_string; + } + + if (!data_index_is_valid(cmp_str, cond_index, cond_len)) { + DEBUG_PRINT("Invalid data %s; skipping\n", cmp_str); + match = false; + break; + } + + DEBUG_PRINT("comparing value: %s to %s at index %zu\n", + &cmp_str[cond_index], + string_to_compare, + cond_index); + + if (strncmp(&cmp_str[cond_index], + string_to_compare, + 12) == 0) { + match = true; + } else { + match = false; + } + + i++; + } else if (strstr(cond_str, "index") != nullptr) { + size_t cond_index = condition[++i].as(); + size_t cond_len = strlen(condition[++i].as()); + + if (!data_index_is_valid(cmp_str, cond_index, cond_len)) { + DEBUG_PRINT("Invalid data %s; skipping\n", cmp_str); + match = false; + break; + } + + bool inverse = false; + if (*condition[i].as() == '!') { + inverse = true; + i++; + } + + DEBUG_PRINT("comparing value: %s to %s at index %zu\n", + &cmp_str[cond_index], + condition[i].as(), + cond_index); + + if (strncmp(&cmp_str[cond_index], + condition[i].as(), + cond_len) == 0) { + match = inverse ? false : true; + } else { + match = inverse ? true : false; + } + + i++; + } + + cond_str = condition[i].as(); + } + + if (i < cond_size && cond_str != nullptr) { + if (!match && *cond_str == '|') { + i++; + continue; + } else if (match && *cond_str == '&') { + i++; + match = false; + continue; + } else if (match) { // check for AND case before exit + while (i < cond_size && *cond_str != '&') { + if (!condition[++i].is()) { + continue; + } + cond_str = condition[i].as(); + } + + if (i < cond_size && cond_str != nullptr) { + i++; + match = false; + continue; + } + } + } + break; + } + return match; +} + +bool checkPropCondition(const JsonArray& prop_condition, + const char* svc_data, + const char* mfg_data) { + int cond_size = prop_condition.size(); + bool cond_met = prop_condition.isNull(); + + if (!cond_met) { + for (int i = 0; i < cond_size; i += 4) { + if (prop_condition[i].is()) { + DEBUG_PRINT("found nested array\n"); + cond_met = checkPropCondition(prop_condition[i], svc_data, mfg_data); + + if (++i < cond_size) { + if (!cond_met && *prop_condition[i].as() == '|') { + } else if (cond_met && *prop_condition[i].as() == '&') { + cond_met = false; + } else { + break; + } + i++; + } else { + break; + } + } + + bool inverse = 0; + const char* prop_data_src = prop_condition[i]; + const char* data_src = nullptr; + + if (svc_data && strstr(prop_data_src, SVC_DATA) != nullptr) { + data_src = svc_data; + } else if (mfg_data && strstr(prop_data_src, MFG_DATA) != nullptr) { + data_src = mfg_data; + } + + if (data_src) { + if (prop_condition[i + 1].is()) { + inverse = *(const char*)prop_condition[i + 2] == '!'; + size_t cond_len = strlen(prop_condition[i + 2 + inverse].as()); + if (strstr((const char*)prop_condition[i + 2], "bit") != nullptr) { + char ch = *(data_src + prop_condition[i + 1].as()); + uint8_t data = getBinaryData(ch); + + uint8_t shift = prop_condition[i + 3].as(); + uint8_t val = prop_condition[i + 4].as(); + if (((data >> shift) & 0x01) == val) { + cond_met = true; + } + i += 2; + } else if (!strncmp(&data_src[prop_condition[i + 1].as()], + prop_condition[i + 2 + inverse].as(), cond_len)) { + cond_met = inverse ? false : true; + } else if (strncmp(&data_src[prop_condition[i + 1].as()], + prop_condition[i + 2 + inverse].as(), cond_len)) { + cond_met = inverse ? true : false; + } + } else { + std::string op = prop_condition[i + 1].as(); + size_t data_len = strlen(data_src); + size_t req_len = prop_condition[i + 2].as(); + + cond_met = evaluateDatalength(op, data_len, req_len); + } + } else { + DEBUG_PRINT("ERROR property condition data source invalid\n"); + return false; + } + + i += inverse; + + if (cond_size > (i + 3)) { + if (!cond_met && *prop_condition[i + 3].as() == '|') { + continue; + } else if (cond_met && *prop_condition[i + 3].as() == '&') { + cond_met = false; + continue; + } else { + break; + } + } + } + } + + return cond_met; +} + +/* + * @brief Compares the input json values to the known devices and + * decodes the data if a match is found. + */ +int decodeBLEJson(JsonObject& jsondata) { +#ifdef UNIT_TESTING + DynamicJsonDocument doc(TEST_MAX_DOC); +#else + DynamicJsonDocument doc(m_docMax); +#endif + const char* svc_data = jsondata[SVC_DATA].as(); + const char* mfg_data = jsondata[MFG_DATA].as(); + const char* dev_name = jsondata["name"].as(); + const char* svc_uuid = jsondata["servicedatauuid"].as(); + const char* mac_id = jsondata["id"].as(); + int success = -1; + + // if there is no data to decode just return + if (svc_data == nullptr && mfg_data == nullptr && dev_name == nullptr) { + DEBUG_PRINT("Invalid data\n"); + return success; + } + + /* loop through the devices and attempt to match the input data to a device parameter set */ + for (auto i_main = 0; i_main < sizeof(_devices) / sizeof(_devices[0]); ++i_main) { + DeserializationError error = deserializeJson(doc, _devices[i_main][0]); + if (error) { + DEBUG_PRINT("deserializeJson() failed: %s\n", error.c_str()); +#ifdef UNIT_TESTING + assert(0); +#endif + return success; + } +#ifdef UNIT_TESTING + if (doc.memoryUsage() > peakDocSize) + peakDocSize = doc.memoryUsage(); +#endif + + /* found a match, extract the data */ + JsonArray selectedCondition; +#ifdef NO_MAC_ADDR + if (doc.containsKey("conditionnomac")) { + selectedCondition = doc["conditionnomac"]; + } else { + selectedCondition = doc["condition"]; + } +#else + selectedCondition = doc["condition"]; +#endif + if (checkDeviceMatch(selectedCondition, svc_data, mfg_data, dev_name, svc_uuid, mac_id)) { + jsondata["brand"] = doc["brand"]; + jsondata["model"] = doc["model"]; + jsondata["model_id"] = doc["model_id"]; + if (doc.containsKey("tag")) { + doc.add("type"); + doc["type"] = NULL; + + std::string tagstring = doc["tag"]; + int type = strtol(tagstring.substr(0, 2).c_str(), NULL, 16); + + switch (type) { + case 1: + doc["type"] = "THB"; // Termperature, Humidity, Battery + break; + case 2: + doc["type"] = "THBX"; // Termperature, Humidity, Battery, Extra + break; + case 3: + doc["type"] = "BBQ"; // Multip probe temperatures only + break; + case 4: + doc["type"] = "CTMO"; // Contact and/or Motion sensor + break; + case 5: + doc["type"] = "SCALE"; // weight scale + break; + case 6: + doc["type"] = "BCON"; // iBeacon protocol + break; + case 7: + doc["type"] = "ACEL"; // acceleration + break; + case 8: + doc["type"] = "BATT"; // battery + break; + case 9: + doc["type"] = "PLANT"; // plant sensors + break; + case 10: + doc["type"] = "TIRE"; // tire pressure monitoring system + break; + case 11: + doc["type"] = "BODY"; // health monitoring devices + break; + case 12: + doc["type"] = "ENRG"; // energy monitoring devices + break; + case 13: + doc["type"] = "WCVR"; // window covering + break; + case 14: + doc["type"] = "ACTR"; // ON/OFF actuators + break; + case 15: + doc["type"] = "AIR"; // air environmental monitoring devices + break; + case 16: + doc["type"] = "TRACK"; // Bluetooth tracker + break; + case 17: + doc["type"] = "BTN"; // Button + break; + case 254: + doc["type"] = "RMAC"; // random MAC address devices + break; + case 255: + doc["type"] = "UNIQ"; // unique devices + break; + } + + if (!doc["type"].isNull()) { + jsondata["type"] = doc["type"]; + } else { + DEBUG_PRINT("ERROR - no valid device type present in model tag property\n"); + } + + // Octet Byte[1] bits[7-0] - True/False tags + if (tagstring.length() >= 4) { + // bits[3-0] + uint8_t data = getBinaryData(tagstring[3]); + + if (((data >> 0) & 0x01) == 1) { // CIDC - NOT Company ID Compliant + doc.add("cidc"); + doc["cidc"] = false; + jsondata["cidc"] = doc["cidc"]; + } + + if (((data >> 1) & 0x01) == 1) { // Active Scanning required + doc.add("acts"); + doc["acts"] = true; + jsondata["acts"] = doc["acts"]; + } + + if (((data >> 2) & 0x01) == 1) { // Continuous Scanning required + doc.add("cont"); + doc["cont"] = true; + jsondata["cont"] = doc["cont"]; + } + + if (((data >> 3) & 0x01) == 1) { // Presence tracking conpatible + doc.add("track"); + doc["track"] = true; + jsondata["track"] = doc["track"]; + } + } + + // Octet Byte[2] - Encryption Model + if (tagstring.length() >= 6) { + int encrmode = strtol(tagstring.substr(4, 2).c_str(), NULL, 16); + DEBUG_PRINT("encrmode: %d\n", encrmode); + if (encrmode > 0) { + doc.add("encr"); + doc["encr"] = encrmode; + jsondata["encr"] = doc["encr"]; + } + } + } + + JsonObject properties = doc["properties"]; + + /* Loop through all the devices properties and extract the values */ + for (JsonPair kv : properties) { + JsonObject prop = kv.value().as(); + + if (checkPropCondition(prop["condition"], svc_data, mfg_data)) { + JsonArray decoder = prop["decoder"]; + if (strstr((const char*)decoder[0], "value_from_hex_data") != nullptr) { + const char* src = svc_data; + if (strstr((const char*)decoder[1], MFG_DATA)) { + src = mfg_data; + } + + /* use a double for all values and cast later if required */ + double temp_val; + static double cal_val = 0; + + if (data_index_is_valid(src, decoder[2].as(), decoder[3].as())) { + decoder_function dec_fun = &TheengsDecoder::value_from_hex_string; + + if (strstr((const char*)decoder[0], "bf") != nullptr) { + dec_fun = &TheengsDecoder::bf_value_from_hex_string; + } + + temp_val = (this->*dec_fun)(src, decoder[2].as(), + decoder[3].as(), + decoder[4].as(), + decoder[5].isNull() ? true : decoder[5].as(), + decoder[6].isNull() ? false : decoder[6].as()); + + } else { + break; + } + + /* Do any required post processing of the value */ + if (prop.containsKey("post_proc")) { + JsonArray post_proc = prop["post_proc"]; + for (unsigned int i = 0; i < post_proc.size(); i += 2) { + if (cal_val && post_proc[i + 1].as() != NULL && + strncmp(post_proc[i + 1].as(), ".cal", 4) == 0) { + switch (*post_proc[i].as()) { + case '/': + temp_val /= cal_val; + break; + case '*': + temp_val *= cal_val; + break; + case '-': + temp_val -= cal_val; + break; + case '+': + temp_val += cal_val; + break; + } + } else { + if (strlen(post_proc[i].as()) == 1) { + switch (*post_proc[i].as()) { + case '/': + temp_val /= post_proc[i + 1].as(); + break; + case '*': + temp_val *= post_proc[i + 1].as(); + break; + case '-': + temp_val -= post_proc[i + 1].as(); + break; + case '+': + temp_val += post_proc[i + 1].as(); + break; + case '%': { + long val = (long)temp_val; + temp_val = val % post_proc[i + 1].as(); + break; + } + case '<': { + long val = (long)temp_val; + temp_val = val << post_proc[i + 1].as(); + break; + } + case '>': { + long val = (long)temp_val; + temp_val = val >> post_proc[i + 1].as(); + break; + } + case '!': { + bool val = (bool)temp_val; + temp_val = !val; + break; + } + case '&': { + long long val = (long long)temp_val; + temp_val = val & post_proc[i + 1].as(); + break; + } + } + } else if (strncmp(post_proc[i].as(), "max", 3) == 0) { + if (temp_val > post_proc[i + 1].as()) { + temp_val = post_proc[i + 1].as(); + } + } else if (strncmp(post_proc[i].as(), "min", 3) == 0) { + if (temp_val < post_proc[i + 1].as()) { + temp_val = post_proc[i + 1].as(); + } + } + } + } + } + + /* If there is any underscores at the beginning of the property name, there is multiple + * properties of this type, we need remove the underscores for creating the key. + */ + std::string _key = sanitizeJsonKey(kv.key().c_str()); + + /* calculation values extracted from data are not added to the decoded output + * instead we store them temporarily to use with the next data properties. + */ + if (_key == ".cal") { + cal_val = temp_val; + continue; + } + + /* Cast to a different value type if specified */ + if (prop.containsKey("is_bool")) { + jsondata[_key] = (bool)temp_val; + } else { + jsondata[_key] = temp_val; + } + + /* If the property is temp in C, make sure to convert and add temp in F */ + if (_key.find("tempc", 0, 5) != std::string::npos) { + double tc = jsondata[_key]; + _key[4] = 'f'; + jsondata[_key] = tc * 1.8 + 32; + _key[4] = 'c'; + } + + /* If the property is with suffix _cm, make sure to convert and add length in inches */ + if (_key.find("_cm", _key.length() - 3, 3) != std::string::npos) { + double tc = jsondata[_key]; + _key.replace(_key.length() - 3, 3, "_in"); + jsondata[_key] = tc / 2.54; + _key.replace(_key.length() - 3, 3, "_cm"); + } + + success = i_main; + DEBUG_PRINT("found value = %s : %.2f\n", _key.c_str(), jsondata[_key].as()); + } else if (strstr((const char*)decoder[0], "static_value") != nullptr) { + if (strstr((const char*)decoder[0], "bit") != nullptr) { + JsonArray staticbitdecoder = prop["decoder"]; + const char* data_src = nullptr; + + if (svc_data && strstr((const char*)staticbitdecoder[1], SVC_DATA) != nullptr) { + data_src = svc_data; + } else if (mfg_data && strstr((const char*)staticbitdecoder[1], MFG_DATA) != nullptr) { + data_src = mfg_data; + } + + char ch = *(data_src + staticbitdecoder[2].as()); + uint8_t data = getBinaryData(ch); + uint8_t shift = staticbitdecoder[3].as(); + int x = 4 + ((data >> shift) & 0x01); + + jsondata[sanitizeJsonKey(kv.key().c_str())] = staticbitdecoder[x]; + success = i_main; + } else { + jsondata[sanitizeJsonKey(kv.key().c_str())] = decoder[1]; + success = i_main; + } + } else if (strstr((const char*)decoder[0], "string_from_hex_data") != nullptr) { + const char* src = svc_data; + if (strstr((const char*)decoder[1], MFG_DATA)) { + src = mfg_data; + } + + std::string value(src + decoder[2].as(), decoder[3].as()); + + /* Lookup table */ + if (prop.containsKey("lookup")) { + JsonArray lookup = prop["lookup"]; + for (unsigned int i = 0; i < lookup.size(); i += 2) { + if (lookup[i].as() == value) { + value = lookup[i + 1].as(); + jsondata[sanitizeJsonKey(kv.key().c_str())] = value; + success = i_main; + break; + } + } + } else { + jsondata[sanitizeJsonKey(kv.key().c_str())] = value; + success = i_main; + } + } else if (strstr((const char*)decoder[0], "mac_from_hex_data") != nullptr) { + const char* src = svc_data; + if (strstr((const char*)decoder[1], MFG_DATA)) { + src = mfg_data; + } + + std::string value(src + decoder[2].as(), 12); + + // reverse MAC + if (strstr((const char*)decoder[0], "revmac_from_hex_data") != nullptr) { + const char* mac_string = nullptr; + mac_string = value.c_str(); + char* reverse_mac_string = (char*)malloc(strlen(mac_string) + 1); + reverse_hex_data(mac_string, reverse_mac_string, 12); + value = reverse_mac_string; + free(reverse_mac_string); + } + + // upper case MAC + for (int x = 0; x <= 12; x++) { + value[x] = toupper(value[x]); + } + + // add colons + for (int x = 2; x <= 14; x += 3) { + value.insert(x, 1, ':'); + } + + jsondata[sanitizeJsonKey(kv.key().c_str())] = value; + success = i_main; + } + } + } + return success; + } + } + return success; +} + +int getTheengModel(JsonDocument& doc, const char* model_id) { + int mid_len = strlen(model_id); + + for (auto i = 0; i < sizeof(_devices) / sizeof(_devices[0]); ++i) { + DeserializationError error = deserializeJson(doc, _devices[i][0]); + if (error) { + DEBUG_PRINT("deserializeJson() failed: %s\n", error.c_str()); +#ifdef UNIT_TESTING + assert(0); +#endif + break; + } +#ifdef UNIT_TESTING + if (doc.memoryUsage() > peakDocSize) + peakDocSize = doc.memoryUsage(); +#endif + + if (doc.containsKey("model_id")) { + if (strlen(doc["model_id"].as()) != mid_len) { + continue; + } + if (!strncmp(model_id, doc["model_id"], mid_len)) { + return i; + } + } + } + + return -1; +} + +std::string getTheengProperties(int mod_index) { + return (mod_index < 0 || mod_index >= BLE_ID_NUM::BLE_ID_MAX) ? "" : _devices[mod_index][1]; +} + +std::string getTheengProperties(const char* model_id) { +#ifdef UNIT_TESTING + DynamicJsonDocument doc(TEST_MAX_DOC); +#else + DynamicJsonDocument doc(m_docMax); +#endif + int mod_index = getTheengModel(doc, model_id); + return (mod_index < 0 || mod_index >= BLE_ID_NUM::BLE_ID_MAX) ? "" : _devices[mod_index][1]; +} + +std::string getTheengAttribute(int model_id, const char* attribute) { +#ifdef UNIT_TESTING + DynamicJsonDocument doc(TEST_MAX_DOC); +#else + DynamicJsonDocument doc(m_docMax); +#endif + std::string ret_attr = ""; + if (model_id >= 0 && model_id < BLE_ID_NUM::BLE_ID_MAX) { + DeserializationError error = deserializeJson(doc, _devices[model_id][0]); + if (error) { + DEBUG_PRINT("deserializeJson() failed: %s\n", error.c_str()); +#ifdef UNIT_TESTING + assert(0); +#endif + } else if (!doc[attribute].isNull()) { + ret_attr = doc[attribute].as(); + } + } + + return ret_attr; +} + +std::string getTheengAttribute(const char* model_id, const char* attribute) { +#ifdef UNIT_TESTING + DynamicJsonDocument doc(TEST_MAX_DOC); +#else + DynamicJsonDocument doc(m_docMax); +#endif + int mod_index = getTheengModel(doc, model_id); + + if (mod_index >= 0 && !doc[attribute].isNull()) { + return std::string(doc[attribute].as()); + } + return ""; +} + +void setMinServiceDataLen(size_t len) { + m_minSvcDataLen = len; +} + +void setMinManufacturerDataLen(size_t len) { + m_minMfgDataLen = len; +} + +#ifdef UNIT_TESTING +int testDocMax() { + if (peakDocSize > m_docMax) { + DEBUG_PRINT("Error: peak doc size > max; peak: %lu, max: %lu\n", peakDocSize, m_docMax); + } + return m_docMax - peakDocSize; +} +#endif + + +}; + +#endif \ No newline at end of file diff --git a/lib/decoder/src/devices.h b/lib/decoder/src/devices.h new file mode 100644 index 00000000..dc2824bb --- /dev/null +++ b/lib/decoder/src/devices.h @@ -0,0 +1,245 @@ +/* + TheengsDecoder - Decode things and devices + + Copyright: (c)Florian ROBERT + + This file is part of TheengsDecoder. + + TheengsDecoder is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + TheengsDecoder is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _DEVICE_H_ +#define _DEVICE_H_ + +//ТАК странно сделано, что бы не менять порядок файлов и было проще отследить изменения в оригинальной библиотеке +//#pragma once + +#if defined(PART1_XIAOMI) +#include "devices/CGD1_json.h" +#include "devices/CGDK2_json.h" +#include "devices/CGG1_json.h" +#include "devices/CGDN1_json.h" +#include "devices/CGH1_json.h" +#include "devices/CGP1W_json.h" +#include "devices/CGPR1_json.h" +#endif +#if defined(PART2_OTHER) +#include "devices/GAEN_json.h" +#include "devices/H5055_json.h" +#include "devices/H5072_json.h" +#include "devices/H5074_json.h" +#include "devices/H5102_json.h" +#include "devices/H5106_json.h" +#include "devices/H5179_json.h" +#endif +#if defined(PART1_XIAOMI) +#include "devices/HHCCJCY10_json.h" +#include "devices/HHCCJCY01HHCC_json.h" +#include "devices/HHCCPOT002_json.h" +#include "devices/IBS_THBP01B_json.h" +#include "devices/IBT_2X_json.h" +#include "devices/IBT_4XS_json.h" +#include "devices/IBT_6XS_SOLIS6_json.h" +#include "devices/JQJCY01YM_json.h" +#include "devices/LYWSD02_json.h" +#include "devices/LYWSD03MMC_json.h" +#include "devices/LYWSD03MMC_ENCR_json.h" +#include "devices/LYWSDCGQ_json.h" +#endif +#if defined(PART2_OTHER) +#include "devices/MBXPRO_json.h" +#include "devices/MS_CDP_json.h" +#endif +#if defined(PART1_XIAOMI) +#include "devices/MUE4094RT_json.h" +#include "devices/Miband_json.h" +#include "devices/XMTZC04HMKG_json.h" +#include "devices/XMTZC04HMLB_json.h" +#include "devices/XMTZC05HMKG_json.h" +#include "devices/XMTZC05HMLB_json.h" +#endif +#if defined(PART2_OTHER) +#include "devices/Mokobeacon_json.h" +#include "devices/RDL52832_json.h" +#include "devices/RuuviTag_RAWv1_json.h" +#include "devices/RuuviTag_RAWv2_json.h" +#include "devices/SBCS_json.h" +#include "devices/SBCU_json.h" +#include "devices/SBMS_json.h" +#include "devices/SBMT_json.h" +#include "devices/SBOT_json.h" +#include "devices/SBS1_json.h" +#include "devices/SHT4X_json.h" +#include "devices/SCD4X_json.h" +#include "devices/Skale_json.h" +#include "devices/SmartDry_json.h" +#include "devices/TPMS_json.h" +#include "devices/KKM_K6P_json.h" +#include "devices/KKM_K9_json.h" +#include "devices/ThermoBeacon_json.h" +#include "devices/ABN03_json.h" +#include "devices/ABN07_json.h" +#include "devices/ABTemp_json.h" +#include "devices/Amphiro_json.h" +#include "devices/OralB_json.h" +#include "devices/PH10_json.h" +#include "devices/TPTH_json.h" +#include "devices/Mopeka_json.h" +#include "devices/T201_json.h" +#include "devices/T301_json.h" +#include "devices/tracker_json.h" +#include "devices/iNodeEM_json.h" +#include "devices/BC08_json.h" +#include "devices/BM1IN1_json.h" +#include "devices/BM3IN1_json.h" +#include "devices/BM4IN1_json.h" +#include "devices/BPARASITE_json.h" +#include "devices/BWBSDOO_json.h" +#include "devices/BM2_json.h" +#include "devices/BM6_json.h" +#include "devices/JHT_F525_json.h" +#include "devices/iBeacon_json.h" +#endif +#if defined(PART1_XIAOMI) +#include "devices/APPLE_json.h" +#include "devices/ServiceData_json.h" +#endif +#if defined(PART2_OTHER) +#include "devices/SBBT_002C_json.h" +#include "devices/SBBT_002C_ENCR_json.h" +#include "devices/SBDW_002C_json.h" +#include "devices/SBDW_002C_ENCR_json.h" +#include "devices/SBMO_003Z_json.h" +#include "devices/SBMO_003Z_ENCR_json.h" +#endif + +const char* _devices[][2] = { +#if defined(PART1_XIAOMI) + {_HHCCJCY01HHCC_json, _HHCCJCY01HHCC_json_props}, + {_LYWSD02_json, _LYWSD02_json_props}, + {_LYWSDCGQ_json, _LYWSDCGQ_json_props}, + {_CGP1W_json, _CGP1W_json_props}, + {_CGG1_json_STOCK, _CGG1_json_props}, + {_CGG1_json_ATC1441, _CGG1_json_props}, + {_CGG1_json_PVVX, _CGG1_json_props}, + {_CGG1_json_STOCK_2, _CGG1_json_props}, + {_CGDN1_json, _CGDN1_json_props}, + {_CGD1_json, _CGD1_json_props}, + {_CGDK2_json_STOCK, _CGDK2_json_props}, + {_CGDK2_json_PVVX, _CGDK2_json_props}, + {_CGDK2_json_ATC1441, _CGDK2_json_props}, + {_CGH1_json, _CGH1_json_props}, + {_JQJCY01YM_json, _JQJCY01YM_json_props}, + {_IBS_THBP01B_json, _IBS_THBP01B_json_props}, + {_IBT_2X_json_2X, _IBT_2X_json_props}, + {_IBT_2X_json_2XS, _IBT_2X_json_props}, + {_IBT_4XS_json, _IBT_4XS_json_props}, + {_IBT_6XS_SOLIS6_json, _IBT_6XS_SOLIS6_json_props}, + {_Miband_json, _Miband_json_props}, + {_XMTZC04HMKG_json, _XMTZC04HMKG_json_props}, + {_XMTZC04HMLB_json, _XMTZC04HMLB_json_props}, + {_XMTZC05HMKG_json, _XMTZC05HMKG_json_props}, + {_XMTZC05HMLB_json, _XMTZC05HMLB_json_props}, +#endif +#if defined(PART2_OTHER) + {_TPMS_json, _TPMS_json_props}, + {_KKM_K6P_json, _KKM_K6P_json_props}, + {_KKM_K9_json, _KKM_K9_json_props}, +#endif +#if defined(PART1_XIAOMI) + {_LYWSD03MMC_json_ATC, _LYWSD03MMC_json_props}, + {_LYWSD03MMC_json_PVVX, _LYWSD03MMC_json_props}, + {_LYWSD03MMC_json_PVVX_DECR, _LYWSD03MMC_json_props}, + {_LYWSD03MMC_ENCR_json_PVVX, _LYWSD03MMC_ENCR_json_props}, + {_CGPR1_json, _CGPR1_json_props}, +#endif +#if defined(PART2_OTHER) + {_ThermoBeacon_json, _ThermoBeacon_json_props}, + {_H5055_json, _H5055_json_props}, + {_H5072_json, _H5072_json_props}, + {_H5074_json, _H5074_json_props}, + {_H5102_json, _H5102_json_props}, + {_H5106_json, _H5106_json_props}, + {_H5179_json, _H5179_json_props}, +#endif +#if defined(PART1_XIAOMI) + {_HHCCJCY10_json, _HHCCJCY10_json_props}, + {_MUE4094RT_json, _MUE4094RT_json_props}, +#endif +#if defined(PART2_OTHER) + {_Mokobeacon_json, _Mokobeacon_json_props}, + {_MBXPRO_json, _MBXPRO_json_props}, + {_iNodeEM_json, _iNodeEM_json_props}, + {_RuuviTag_RAWv1_json, _RuuviTag_RAWv1_json_props}, + {_RuuviTag_RAWv2_json, _RuuviTag_RAWv2_json_props}, + {_SBCS_json, _SBCS_json_props}, + {_SBCU_json, _SBCU_json_props}, + {_SBMS_json, _SBMS_json_props}, + {_SBMT_json, _SBMT_json_props}, + {_SBOT_json, _SBOT_json_props}, + {_SBS1_json, _SBS1_json_props}, + {_SHT4X_json, _SHT4X_json_props}, + {_SCD4X_json, _SCD4X_json_props}, + {_Skale_json, _Skale_json_props}, + {_SmartDry_json, _SmartDry_json_props}, + {_BC08_json, _BC08_json_props}, + {_BM1IN1_json, _BM1IN1_json_props}, + {_BM3IN1_json, _BM3IN1_json_props}, + {_BM4IN1_json, _BM4IN1_json_props}, + {_MS_CDP_json, _MS_CDP_json_props}, + {_GAEN_json, _GAEN_json_props}, +#endif +#if defined(PART1_XIAOMI) + {_HHCCPOT002_json, _HHCCPOT002_json_props}, +#endif +#if defined(PART2_OTHER) + {_BPARASITE_json, _BPARASITE_json_props}, + {_BWBSDOO_json, _BWBSDOO_json_props}, + {_BM2_json, _BM2_json_props}, + {_BM6_json, _BM6_json_props}, + {_RDL52832_json, _RDL52832_json_props}, + {_ABN03_json, _ABN03_json_props}, + {_ABN07_json, _ABN07_json_props}, + {_ABTemp_json, _ABTemp_json_props}, + {_AMPHIRO_json, _AMPHIRO_json_props}, + {_OralB_json, _OralB_json_props}, + {_PH10_json, _PH10_json_props}, + {_TPTH_json, _TPTH_json_props}, + {_Mopeka_json, _Mopeka_json_props}, + {_T201_json, _T201_json_props}, + {_T301_json, _T301_json_props}, + {_tracker_json_nut, _tracker_json_props}, + {_tracker_json_itag, _tracker_json_props}, + {_tracker_json_tagit, _tracker_json_props}, + {_tracker_json_tile, _tracker_json_props}, + {_tracker_json_tilename, _tracker_json_props}, + {_JHT_F525_json, _JHT_F525_json_props}, + {_ibeacon_json, _ibeacon_json_props}, +#endif +#if defined(PART1_XIAOMI) + {_APPLE_json, _APPLE_json_props}, + {_APPLE_json_at, _APPLE_json_props}, + {_ServiceData_json, _ServiceData_json_props}, +#endif +#if defined(PART2_OTHER) + {_SBBT_002C_json, _SBBT_002C_json_props}, + {_SBBT_002C_ENCR_json, _SBBT_002C_ENCR_json_props}, + {_SBDW_002C_json, _SBDW_002C_json_props}, + {_SBDW_002C_ENCR_json, _SBDW_002C_ENCR_json_props}, + {_SBMO_003Z_json, _SBMO_003Z_json_props}, + {_SBMO_003Z_ENCR_json, _SBMO_003Z_ENCR_json_props}, +#endif +}; + +#endif \ No newline at end of file diff --git a/lib/decoder/src/devices/ABN03_json.h b/lib/decoder/src/devices/ABN03_json.h new file mode 100644 index 00000000..69f7fb99 --- /dev/null +++ b/lib/decoder/src/devices/ABN03_json.h @@ -0,0 +1,55 @@ +const char* _ABN03_json = "{\"brand\":\"April Brother\",\"model\":\"N03\",\"model_id\":\"ABN03\",\"tag\":\"0208\",\"condition\":[\"servicedata\",\"=\",30,\"index\",0,\"ab03\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",18,4,true,true],\"post_proc\":[\"/\",8]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",22,4,true,false],\"post_proc\":[\"/\",2]},\"lux\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",26,4,true,false]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",16,2,false,false]},\"mac\":{\"decoder\":[\"mac_from_hex_data\",\"servicedata\",4]}}}"; +/* R""""( +{ + "brand":"April Brother", + "model":"N03", + "model_id":"ABN03", + "tag":"0208", + "condition":["servicedata", "=", 30, "index", 0, "ab03"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "servicedata", 18, 4, true, true], + "post_proc":["/", 8] + }, + "hum":{ + "decoder":["value_from_hex_data", "servicedata", 22, 4, true, false], + "post_proc":["/", 2] + }, + "lux":{ + "decoder":["value_from_hex_data", "servicedata", 26, 4, true, false] + }, + "batt":{ + "decoder":["value_from_hex_data", "servicedata", 16, 2, false, false] + }, + "mac":{ + "decoder":["mac_from_hex_data", "servicedata", 4] + } + } +})"""";*/ + +const char* _ABN03_json_props = "{\"properties\":{\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"},\"lux\":{\"unit\":\"lx\",\"name\":\"illuminance\"},\"batt\":{\"unit\":\"%\",\"name\":\"battery\"},\"mac\":{\"unit\":\"string\",\"name\":\"MAC address\"}}}"; +/*R""""( +{ + "properties":{ + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "hum":{ + "unit":"%", + "name":"humidity" + }, + "lux":{ + "unit":"lx", + "name":"illuminance" + }, + "batt":{ + "unit":"%", + "name":"battery" + }, + "mac":{ + "unit":"string", + "name":"MAC address" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/ABN07_json.h b/lib/decoder/src/devices/ABN07_json.h new file mode 100644 index 00000000..0c284ed9 --- /dev/null +++ b/lib/decoder/src/devices/ABN07_json.h @@ -0,0 +1,52 @@ +const char* _ABN07_json = "{\"brand\":\"April Brother\",\"model\":\"N07\",\"model_id\":\"ABN07\",\"tag\":\"010a\",\"condition\":[\"servicedata\",\"=\",22,\"index\",0,\"40\",\"&\",\"uuid\",\"index\",0,\"fcd2\",\"&\",\"name\",\"index\",0,\"asensor_\"],\"properties\":{\"packet\":{\"condition\":[\"servicedata\",2,\"00\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",4,2,false,false]},\"batt\":{\"condition\":[\"servicedata\",6,\"01\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",8,2,false,false]},\"tempc\":{\"condition\":[\"servicedata\",10,\"02\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",12,4,true,true],\"post_proc\":[\"/\",100]},\"hum\":{\"condition\":[\"servicedata\",16,\"03\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",18,4,true,false],\"post_proc\":[\"/\",100]}}}"; +/* R""""( +{ + "brand":"April Brother", + "model":"N07", + "model_id":"ABN07", + "tag":"010a", + "condition":["servicedata", "=", 22, "index", 0, "40", "&", "uuid", "index", 0, "fcd2", "&", "name", "index", 0, "asensor_"], + "properties":{ + "packet":{ + "condition":["servicedata", 2, "00"], + "decoder":["value_from_hex_data", "servicedata", 4, 2, false, false] + }, + "batt":{ + "condition":["servicedata", 6, "01"], + "decoder":["value_from_hex_data", "servicedata", 8, 2, false, false] + }, + "tempc":{ + "condition":["servicedata", 10, "02"], + "decoder":["value_from_hex_data", "servicedata", 12, 4, true, true], + "post_proc":["/", 100] + }, + "hum":{ + "condition":["servicedata", 16, "03"], + "decoder":["value_from_hex_data", "servicedata", 18, 4, true, false], + "post_proc":["/", 100] + } + } +})"""";*/ + +const char* _ABN07_json_props = "{\"properties\":{\"packet\":{\"unit\":\"int\",\"name\":\"packet id\"},\"batt\":{\"unit\":\"%\",\"name\":\"battery\"},\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"}}}"; +/*R""""( +{ + "properties":{ + "packet":{ + "unit":"int", + "name":"packet id" + }, + "batt":{ + "unit":"%", + "name":"battery" + }, + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "hum":{ + "unit":"%", + "name":"humidity" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/ABTemp_json.h b/lib/decoder/src/devices/ABTemp_json.h new file mode 100644 index 00000000..b5afbfa4 --- /dev/null +++ b/lib/decoder/src/devices/ABTemp_json.h @@ -0,0 +1,68 @@ +const char* _ABTemp_json = "{\"brand\":\"April Brother\",\"model\":\"ABTemp\",\"model_id\":\"ABTemp\",\"tag\":\"0608\",\"condition\":[\"manufacturerdata\",\"=\",50,\"index\",0,\"4c000215b5b182c7eab14988aa99b5c1517008d9\"],\"properties\":{\"mfid\":{\"decoder\":[\"string_from_hex_data\",\"manufacturerdata\",0,4]},\"uuid\":{\"decoder\":[\"string_from_hex_data\",\"manufacturerdata\",8,32]},\"major\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",40,4,false]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",44,2,false]},\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",46,2,false]},\"txpower\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",48,2,false]},\"mac\":{\"condition\":[\"servicedata\",\"=\",22],\"decoder\":[\"revmac_from_hex_data\",\"servicedata\",0]}}}"; +/*R""""( +{ + "brand":"April Brother", + "model":"ABTemp", + "model_id":"ABTemp", + "tag":"0608", + "condition":["manufacturerdata", "=", 50, "index", 0, "4c000215b5b182c7eab14988aa99b5c1517008d9"], + "properties":{ + "mfid":{ + "decoder":["string_from_hex_data", "manufacturerdata", 0, 4] + }, + "uuid":{ + "decoder":["string_from_hex_data", "manufacturerdata", 8, 32] + }, + "major":{ + "decoder":["value_from_hex_data", "manufacturerdata", 40, 4, false] + }, + "batt":{ + "decoder":["value_from_hex_data", "manufacturerdata", 44, 2, false] + }, + "tempc":{ + "decoder":["value_from_hex_data", "manufacturerdata", 46, 2, false] + }, + "txpower":{ + "decoder":["value_from_hex_data","manufacturerdata", 48, 2, false] + }, + "mac":{ + "condition":["servicedata", "=", 22], + "decoder":["revmac_from_hex_data", "servicedata", 0] + } + } +})"""";*/ + +const char* _ABTemp_json_props = "{\"properties\":{\"mfid\":{\"unit\":\"hex\",\"name\":\"manufacturer id\"},\"uuid\":{\"unit\":\"hex\",\"name\":\"service uuid\"},\"major\":{\"unit\":\"hex\",\"name\":\"major value\"},\"batt\":{\"unit\":\"%\",\"name\":\"battery\"},\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"txpower\":{\"unit\":\"dBm\",\"name\":\"tx power @ 1 m\"},\"mac\":{\"unit\":\"string\",\"name\":\"MAC address\"}}}"; +/*R""""( +{ + "properties":{ + "mfid":{ + "unit":"hex", + "name":"manufacturer id" + }, + "uuid":{ + "unit":"hex", + "name":"service uuid" + }, + "major":{ + "unit":"hex", + "name":"major value" + }, + "batt":{ + "unit":"%", + "name":"battery" + }, + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "txpower":{ + "unit":"dBm", + "name":"tx power @ 1 m" + }, + "mac":{ + "unit":"string", + "name":"MAC address" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/APPLE_json.h b/lib/decoder/src/devices/APPLE_json.h new file mode 100644 index 00000000..59518d3d --- /dev/null +++ b/lib/decoder/src/devices/APPLE_json.h @@ -0,0 +1,40 @@ +const char* _APPLE_json = "{\"brand\":\"Apple\",\"model\":\"Apple Continuity\",\"model_id\":\"APPLE_CONT\",\"tag\":\"fe\",\"condition\":[\"manufacturerdata\",\">=\",10,\"index\",0,\"4c000\",\"|\",\"manufacturerdata\",\">=\",10,\"index\",0,\"4c001\",\"&\",\"manufacturerdata\",\"<\",50],\"properties\":{\"device\":{\"decoder\":[\"static_value\",\"Apple device\"]}}}"; +/*R""""( +{ + "brand":"Apple", + "model":"Apple Continuity", + "model_id":"APPLE_CONT", + "tag":"fe", + "condition":["manufacturerdata", ">=", 10, "index", 0, "4c000", "|", "manufacturerdata", ">=", 10, "index", 0, "4c001", "&", "manufacturerdata", "<", 50], + "properties":{ + "device":{ + "decoder":["static_value", "Apple device"] + } + } +})"""";*/ + +const char* _APPLE_json_at = "{\"brand\":\"Apple\",\"model\":\"Apple Continuity\",\"model_id\":\"APPLE_CONTAT\",\"tag\":\"fe\",\"condition\":[\"manufacturerdata\",\">\",50,\"index\",0,\"4c000\",\"|\",\"manufacturerdata\",\">\",50,\"index\",0,\"4c001\"],\"properties\":{\"device\":{\"decoder\":[\"static_value\",\"Apple device\"]}}}"; +/*R""""( +{ + "brand":"Apple", + "model":"Apple Continuity", + "model_id":"APPLE_CONTAT", + "tag":"fe", + "condition":["manufacturerdata", ">", 50, "index", 0, "4c000", "|", "manufacturerdata", ">", 50, "index", 0, "4c001"], + "properties":{ + "device":{ + "decoder":["static_value", "Apple device"] + } + } +})"""";*/ + +const char* _APPLE_json_props = "{\"properties\":{\"device\":{\"unit\":\"string\",\"name\":\"device\"}}}"; +/*R""""( +{ + "properties":{ + "device":{ + "unit":"string", + "name":"device" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/Amphiro_json.h b/lib/decoder/src/devices/Amphiro_json.h new file mode 100644 index 00000000..565fe8f5 --- /dev/null +++ b/lib/decoder/src/devices/Amphiro_json.h @@ -0,0 +1,55 @@ +const char* _AMPHIRO_json = "{\"brand\":\"Oras\",\"model\":\"Hydractiva Digital\",\"model_id\":\"ADHS\",\"tag\":\"0c01\",\"condition\":[\"manufacturerdata\",\"=\",42,\"index\",0,\"eefa\"],\"properties\":{\"session\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",4,6,false,false]},\"seconds\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",10,4,false,false]},\"litres\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",20,6,false,false],\"post_proc\":[\"/\",2560]},\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",26,2,false,false]},\"energy\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",28,4,false,false],\"post_proc\":[\"/\",100]}}}"; +/*R""""( +{ + "brand":"Oras", + "model":"Hydractiva Digital", + "model_id":"ADHS", + "tag":"0c01", + "condition":["manufacturerdata", "=", 42, "index", 0, "eefa"], + "properties":{ + "session":{ + "decoder":["value_from_hex_data", "manufacturerdata", 4, 6, false, false] + }, + "seconds":{ + "decoder":["value_from_hex_data", "manufacturerdata", 10, 4, false, false] + }, + "litres":{ + "decoder":["value_from_hex_data", "manufacturerdata", 20, 6, false, false], + "post_proc":["/", 2560] + }, + "tempc":{ + "decoder":["value_from_hex_data", "manufacturerdata", 26, 2, false, false] + }, + "energy":{ + "decoder":["value_from_hex_data", "manufacturerdata", 28, 4, false, false], + "post_proc":["/", 100] + } + } +})"""";*/ + +const char* _AMPHIRO_json_props = "{\"properties\":{\"session\":{\"unit\":\"int\",\"name\":\"session\"},\"seconds\":{\"unit\":\"s\",\"name\":\"duration\"},\"litres\":{\"unit\":\"L\",\"name\":\"volume\"},\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"energy\":{\"unit\":\"kWh\",\"name\":\"energy\"}}}"; +/*R""""( +{ + "properties":{ + "session":{ + "unit":"int", + "name":"session" + }, + "seconds":{ + "unit":"s", + "name":"duration" + }, + "litres":{ + "unit":"L", + "name":"volume" + }, + "tempc": { + "unit": "°C", + "name": "temperature" + }, + "energy":{ + "unit":"kWh", + "name":"energy" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/BC08_json.h b/lib/decoder/src/devices/BC08_json.h new file mode 100644 index 00000000..e43dab2a --- /dev/null +++ b/lib/decoder/src/devices/BC08_json.h @@ -0,0 +1,59 @@ +const char* _BC08_json = "{\"brand\":\"BlueCharm\",\"model\":\"Beacon 08/04P/021\",\"model_id\":\"KSensor\",\"tag\":\"0708\",\"condition\":[\"servicedata\",\"=\",26,\"index\",0,\"21010b\",\"&\",\"uuid\",\"index\",0,\"feaa\"],\"properties\":{\".cal\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",12,2,false,false],\"post_proc\":[\"/\",256,\"*\",100,\">\",0,\"/\",100]},\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",10,2,false,true],\"post_proc\":[\"+\",\".cal\"]},\"accx\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",14,4,false,true]},\"accy\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",18,4,false,true]},\"accz\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",22,4,false,true]},\"volt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",6,4,false,false],\"post_proc\":[\"/\",1000]}}}"; +/*R""""( +{ + "brand":"BlueCharm", + "model":"Beacon 08/04P/021", + "model_id":"KSensor", + "tag":"0708", + "condition":["servicedata", "=", 26, "index", 0, "21010b", "&", "uuid", "index", 0, "feaa"], + "properties":{ + ".cal":{ + "decoder":["value_from_hex_data", "servicedata", 12, 2, false, false], + "post_proc":["/", 256, "*", 100, ">", 0, "/", 100] + }, + "tempc":{ + "decoder":["value_from_hex_data", "servicedata", 10, 2, false, true], + "post_proc":["+", ".cal"] + }, + "accx":{ + "decoder":["value_from_hex_data", "servicedata", 14, 4, false, true] + }, + "accy":{ + "decoder":["value_from_hex_data", "servicedata", 18, 4, false, true] + }, + "accz":{ + "decoder":["value_from_hex_data", "servicedata", 22, 4, false, true] + }, + "volt":{ + "decoder":["value_from_hex_data", "servicedata", 6, 4, false, false], + "post_proc":["/", 1000] + } + } +})"""";*/ + +const char* _BC08_json_props = "{\"properties\":{\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"accx\":{\"unit\":\"m/s²\",\"name\":\"acceleration x\"},\"accy\":{\"unit\":\"m/s²\",\"name\":\"acceleration y\"},\"accz\":{\"unit\":\"m/s²\",\"name\":\"acceleration z\"},\"volt\":{\"unit\":\"V\",\"name\":\"voltage\"}}}"; +/*R""""( +{ + "properties":{ + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "accx":{ + "unit":"m/s²", + "name":"acceleration x" + }, + "accy":{ + "unit":"m/s²", + "name":"acceleration y" + }, + "accz":{ + "unit":"m/s²", + "name":"acceleration z" + }, + "volt":{ + "unit":"V", + "name":"voltage" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/BM1IN1_json.h b/lib/decoder/src/devices/BM1IN1_json.h new file mode 100644 index 00000000..de87bdef --- /dev/null +++ b/lib/decoder/src/devices/BM1IN1_json.h @@ -0,0 +1,33 @@ +const char* _BM1IN1_json = "{\"brand\":\"Blue Maestro\",\"model\":\"Tempo Disc\",\"model_id\":\"TD1in1\",\"tag\":\"0108\",\"condition\":[\"manufacturerdata\",\"index\",4,\"0d\",\"&\",\"manufacturerdata\",\"=\",24,\"index\",0,\"3301\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",16,4,false,true],\"post_proc\":[\"/\",10]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",6,2,false,false]}}}"; +/*R""""( +{ + "brand":"Blue Maestro", + "model":"Tempo Disc", + "model_id":"TD1in1", + "tag":"0108", + "condition":["manufacturerdata", "index", 4, "0d", "&", "manufacturerdata", "=", 24, "index", 0, "3301"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "manufacturerdata", 16, 4, false, true], + "post_proc":["/", 10] + }, + "batt":{ + "decoder":["value_from_hex_data", "manufacturerdata", 6, 2, false, false] + } + } +})"""";*/ + +const char* _BM1IN1_json_props = "{\"properties\":{\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"batt\":{\"unit\":\"%\",\"name\":\"battery\"}}}"; +/*R""""( +{ + "properties": { + "tempc": { + "unit": "°C", + "name": "temperature" + }, + "batt": { + "unit": "%", + "name": "battery" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/BM2_json.h b/lib/decoder/src/devices/BM2_json.h new file mode 100644 index 00000000..b715a7b4 --- /dev/null +++ b/lib/decoder/src/devices/BM2_json.h @@ -0,0 +1,33 @@ +const char* _BM2_json = "{\"brand\":\"GENERIC\",\"model\":\"BM2 Battery Monitor\",\"model_id\":\"BM2\",\"tag\":\"0808\",\"condition\":[\"manufacturerdata\",\"=\",50,\"index\",0,\"4c000215655f83caae16a10a702e31f30d58dd82\"],\"properties\":{\"batt\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",48,2,false]},\"device\":{\"decoder\":[\"static_value\",\"BM2 Tracker\"]}}}"; + +/*R""""( +{ + "brand":"GENERIC", + "model":"BM2 Battery Monitor", + "model_id":"BM2", + "tag":"0808", + "condition":["manufacturerdata", "=", 50, "index", 0, "4c000215655f83caae16a10a702e31f30d58dd82"], + "properties":{ + "batt":{ + "decoder":["value_from_hex_data", "manufacturerdata", 48, 2, false] + }, + "device":{ + "decoder":["static_value", "BM2 Tracker"] + } + } +})"""";*/ + +const char* _BM2_json_props = "{\"properties\":{\"batt\":{\"unit\":\"%\",\"name\":\"battery\"},\"device\":{\"unit\":\"string\",\"name\":\"tracker device\"}}}"; +/*R""""( +{ + "properties":{ + "batt":{ + "unit":"%", + "name":"battery" + }, + "device":{ + "unit":"string", + "name":"tracker device" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/BM3IN1_json.h b/lib/decoder/src/devices/BM3IN1_json.h new file mode 100644 index 00000000..4d9b87b5 --- /dev/null +++ b/lib/decoder/src/devices/BM3IN1_json.h @@ -0,0 +1,49 @@ +const char* _BM3IN1_json = "{\"brand\":\"Blue Maestro\",\"model\":\"Tempo Disc\",\"model_id\":\"TD3in1\",\"tag\":\"0208\",\"condition\":[\"manufacturerdata\",\"index\",4,\"16\",\"|\",\"manufacturerdata\",\"index\",4,\"17\",\"&\",\"manufacturerdata\",\"=\",32,\"index\",0,\"3301\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",16,4,false,true],\"post_proc\":[\"/\",10]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",20,4,false,false],\"post_proc\":[\"/\",10]},\"tempc2_dp\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",24,4,false,true],\"post_proc\":[\"/\",10]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",6,2,false,false]}}}"; +/*R""""( +{ + "brand":"Blue Maestro", + "model":"Tempo Disc", + "model_id":"TD3in1", + "tag":"0208", + "condition":["manufacturerdata", "index", 4, "16", "|", "manufacturerdata", "index", 4, "17", "&", "manufacturerdata", "=", 32, "index", 0, "3301"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "manufacturerdata", 16, 4, false, true], + "post_proc":["/", 10] + }, + "hum":{ + "decoder":["value_from_hex_data", "manufacturerdata", 20, 4, false, false], + "post_proc":["/", 10] + }, + "tempc2_dp":{ + "decoder":["value_from_hex_data", "manufacturerdata", 24, 4, false, true], + "post_proc":["/", 10] + }, + "batt":{ + "decoder":["value_from_hex_data", "manufacturerdata", 6, 2, false, false] + } + } +})"""";*/ + +const char* _BM3IN1_json_props = "{\"properties\":{\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"},\"tempc2_dp\":{\"unit\":\"°C\",\"name\":\"dew point\"},\"batt\":{\"unit\":\"%\",\"name\":\"battery\"}}}"; +/*R""""( +{ + "properties": { + "tempc": { + "unit": "°C", + "name": "temperature" + }, + "hum": { + "unit": "%", + "name": "humidity" + }, + "tempc2_dp": { + "unit": "°C", + "name": "dew point" + }, + "batt": { + "unit": "%", + "name": "battery" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/BM4IN1_json.h b/lib/decoder/src/devices/BM4IN1_json.h new file mode 100644 index 00000000..09481551 --- /dev/null +++ b/lib/decoder/src/devices/BM4IN1_json.h @@ -0,0 +1,49 @@ +const char* _BM4IN1_json = "{\"brand\":\"Blue Maestro\",\"model\":\"Tempo Disc\",\"model_id\":\"TD4in1\",\"tag\":\"0208\",\"condition\":[\"manufacturerdata\",\"index\",4,\"1b\",\"&\",\"manufacturerdata\",\"=\",32,\"index\",0,\"3301\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",16,4,false,true],\"post_proc\":[\"/\",10]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",20,4,false,false],\"post_proc\":[\"/\",10]},\"pres\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",24,4,false,false],\"post_proc\":[\"/\",10]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",6,2,false,false]}}}"; +/*R""""( +{ + "brand":"Blue Maestro", + "model":"Tempo Disc", + "model_id":"TD4in1", + "tag":"0208", + "condition":["manufacturerdata", "index", 4, "1b", "&", "manufacturerdata", "=", 32, "index", 0, "3301"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "manufacturerdata", 16, 4, false, true], + "post_proc":["/", 10] + }, + "hum":{ + "decoder":["value_from_hex_data", "manufacturerdata", 20, 4, false, false], + "post_proc":["/", 10] + }, + "pres":{ + "decoder":["value_from_hex_data", "manufacturerdata", 24, 4, false, false], + "post_proc":["/", 10] + }, + "batt":{ + "decoder":["value_from_hex_data", "manufacturerdata", 6, 2, false, false] + } + } +})"""";*/ + +const char* _BM4IN1_json_props = "{\"properties\":{\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"},\"pres\":{\"unit\":\"hPa\",\"name\":\"pressure\"},\"batt\":{\"unit\":\"%\",\"name\":\"battery\"}}}"; +/*R""""( +{ + "properties": { + "tempc": { + "unit": "°C", + "name": "temperature" + }, + "hum": { + "unit": "%", + "name": "humidity" + }, + "pres":{ + "unit":"hPa", + "name":"pressure" + }, + "batt": { + "unit": "%", + "name": "battery" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/BM6_json.h b/lib/decoder/src/devices/BM6_json.h new file mode 100644 index 00000000..d5f558a2 --- /dev/null +++ b/lib/decoder/src/devices/BM6_json.h @@ -0,0 +1,32 @@ +const char* _BM6_json = "{\"brand\":\"GENERIC\",\"model\":\"BM6 Battery Monitor\",\"model_id\":\"BM6\",\"tag\":\"0808\",\"condition\":[\"manufacturerdata\",\"=\",50,\"index\",0,\"4c0002153ba29cd9a42c894856badaf2606ef777\"],\"properties\":{\"batt\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",42,2,false]},\"device\":{\"decoder\":[\"static_value\",\"BM6 Tracker\"]}}}"; +/*R""""( +{ + "brand":"GENERIC", + "model":"BM6 Battery Monitor", + "model_id":"BM6", + "tag":"0808", + "condition":["manufacturerdata", "=", 50, "index", 0, "4c0002153ba29cd9a42c894856badaf2606ef777"], + "properties":{ + "batt":{ + "decoder":["value_from_hex_data", "manufacturerdata", 42, 2, false] + }, + "device":{ + "decoder":["static_value", "BM6 Tracker"] + } + } +})"""";*/ + +const char* _BM6_json_props = "{\"properties\":{\"batt\":{\"unit\":\"%\",\"name\":\"battery\"},\"device\":{\"unit\":\"string\",\"name\":\"tracker device\"}}}"; +/*R""""( +{ + "properties":{ + "batt":{ + "unit":"%", + "name":"battery" + }, + "device":{ + "unit":"string", + "name":"tracker device" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/BPARASITE_json.h b/lib/decoder/src/devices/BPARASITE_json.h new file mode 100644 index 00000000..db7b0574 --- /dev/null +++ b/lib/decoder/src/devices/BPARASITE_json.h @@ -0,0 +1,72 @@ +const char* _BPARASITE_json = "{\"brand\":\"rbaron\",\"model\":\"b-parasite\",\"model_id\":\"BPv1.0-1.2\",\"tag\":\"0904\",\"condition\":[\"servicedata\",\">=\",32,\"index\",0,\"1\",\"|\",\"servicedata\",\">=\",32,\"index\",0,\"2\",\"&\",\"uuid\",\"index\",0,\"181a\"],\"properties\":{\"tempc\":{\"condition\":[\"servicedata\",0,\"1\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",8,4,false,true],\"post_proc\":[\"/\",1000]},\"_tempc\":{\"condition\":[\"servicedata\",0,\"2\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",8,4,false,true],\"post_proc\":[\"/\",100]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",12,4,false,false],\"post_proc\":[\"/\",655.35]},\"moi\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",16,4,false,false],\"post_proc\":[\"/\",655.35]},\"lux\":{\"condition\":[\"servicedata\",1,\"bit\",0,1],\"decoder\":[\"value_from_hex_data\",\"servicedata\",32,4,false,false]},\"volt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",4,4,false,false],\"post_proc\":[\"/\",1000]},\"mac\":{\"decoder\":[\"mac_from_hex_data\",\"servicedata\",20]}}}"; + +/* R""""( +{ + "brand":"rbaron", + "model":"b-parasite", + "model_id":"BPv1.0-1.2", + "tag":"0904", + "condition":["servicedata", ">=", 32, "index", 0, "1", "|", "servicedata", ">=", 32, "index", 0, "2", "&", "uuid", "index", 0, "181a"], + "properties":{ + "tempc":{ + "condition":["servicedata", 0, "1"], + "decoder":["value_from_hex_data", "servicedata", 8, 4, false, true], + "post_proc":["/", 1000] + }, + "_tempc":{ + "condition":["servicedata", 0, "2"], + "decoder":["value_from_hex_data", "servicedata", 8, 4, false, true], + "post_proc":["/", 100] + }, + "hum":{ + "decoder":["value_from_hex_data", "servicedata", 12, 4, false, false], + "post_proc":["/", 655.35] + }, + "moi":{ + "decoder":["value_from_hex_data", "servicedata", 16, 4, false, false], + "post_proc":["/", 655.35] + }, + "lux":{ + "condition":["servicedata", 1, "bit", 0, 1], + "decoder":["value_from_hex_data", "servicedata", 32, 4, false, false] + }, + "volt":{ + "decoder":["value_from_hex_data", "servicedata", 4, 4, false, false], + "post_proc":["/", 1000] + }, + "mac":{ + "decoder":["mac_from_hex_data", "servicedata", 20] + } + } +})"""";*/ + +const char* _BPARASITE_json_props = "{\"properties\":{\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"},\"moi\":{\"unit\":\"%\",\"name\":\"moisture\"},\"lux\":{\"unit\":\"lx\",\"name\":\"illuminance\"},\"volt\":{\"unit\":\"V\",\"name\":\"voltage\"},\"mac\":{\"unit\":\"string\",\"name\":\"MAC address\"}}}"; +/*R""""( +{ + "properties":{ + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "hum":{ + "unit":"%", + "name":"humidity" + }, + "moi":{ + "unit":"%", + "name":"moisture" + }, + "lux":{ + "unit":"lx", + "name":"illuminance" + }, + "volt":{ + "unit":"V", + "name":"voltage" + }, + "mac":{ + "unit":"string", + "name":"MAC address" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/BWBSDOO_json.h b/lib/decoder/src/devices/BWBSDOO_json.h new file mode 100644 index 00000000..05b3ef77 --- /dev/null +++ b/lib/decoder/src/devices/BWBSDOO_json.h @@ -0,0 +1,32 @@ +const char* _BWBSDOO_json = "{\"brand\":\"Otio/BeeWi\",\"model\":\"Door & Window Sensor\",\"model_id\":\"BSDOO\",\"tag\":\"0405\",\"condition\":[\"manufacturerdata\",\"=\",14,\"index\",4,\"080c\"],\"properties\":{\"open\":{\"decoder\":[\"bit_static_value\",\"manufacturerdata\",9,0,false,true]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",12,2,false,false]}}}"; +/*R""""( +{ + "brand":"Otio/BeeWi", + "model":"Door & Window Sensor", + "model_id":"BSDOO", + "tag":"0405", + "condition":["manufacturerdata", "=", 14, "index", 4, "080c"], + "properties":{ + "open":{ + "decoder":["bit_static_value", "manufacturerdata", 9, 0, false, true] + }, + "batt":{ + "decoder":["value_from_hex_data", "manufacturerdata", 12, 2, false, false] + } + } +})"""";*/ + +const char* _BWBSDOO_json_props = "{\"properties\":{\"open\":{\"unit\":\"status\",\"name\":\"door\"},\"batt\":{\"unit\":\"%\",\"name\":\"battery\"}}}"; +/*R""""( +{ + "properties":{ + "open":{ + "unit":"status", + "name":"door" + }, + "batt":{ + "unit":"%", + "name":"battery" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/CGD1_json.h b/lib/decoder/src/devices/CGD1_json.h new file mode 100644 index 00000000..7ed72549 --- /dev/null +++ b/lib/decoder/src/devices/CGD1_json.h @@ -0,0 +1,31 @@ +#include "common_props.h" + +const char* _CGD1_json = "{\"brand\":\"ClearGrass/Qingping\",\"model\":\"Alarm Clock\",\"model_id\":\"CGC1/CGD1\",\"tag\":\"01\",\"condition\":[\"servicedata\",\"=\",34,\"index\",2,\"0c\",\"|\",\"servicedata\",\"=\",34,\"index\",2,\"1e\",\"&\",\"uuid\",\"index\",0,\"fdcd\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",20,4,true,true],\"post_proc\":[\"/\",10]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",24,4,true,false],\"post_proc\":[\"/\",10]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",32,2,false,false],\"post_proc\":[\"&\",127]},\"mac\":{\"decoder\":[\"revmac_from_hex_data\",\"servicedata\",4]}}}"; + +/*R""""( +{ + "brand":"ClearGrass/Qingping", + "model":"Alarm Clock", + "model_id":"CGC1/CGD1", + "tag":"01", + "condition":["servicedata", "=", 34, "index", 2, "0c", "|", "servicedata", "=", 34, "index", 2, "1e", "&", "uuid", "index", 0, "fdcd"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "servicedata", 20, 4, true, true], + "post_proc":["/", 10] + }, + "hum":{ + "decoder":["value_from_hex_data", "servicedata", 24, 4, true, false], + "post_proc":["/", 10] + }, + "batt":{ + "decoder":["value_from_hex_data", "servicedata", 32, 2, false, false], + "post_proc":["&", 127] + }, + "mac":{ + "decoder":["revmac_from_hex_data", "servicedata", 4] + } + } +})"""";*/ + +const char* _CGD1_json_props = _common_BTHM_props; diff --git a/lib/decoder/src/devices/CGDK2_json.h b/lib/decoder/src/devices/CGDK2_json.h new file mode 100644 index 00000000..9105a1a0 --- /dev/null +++ b/lib/decoder/src/devices/CGDK2_json.h @@ -0,0 +1,87 @@ +#include "common_props.h" + +const char* _CGDK2_json_STOCK = "{\"brand\":\"Qingping\",\"model\":\"TH Lite\",\"model_id\":\"CGDK2\",\"tag\":\"01\",\"condition\":[\"servicedata\",\"=\",34,\"index\",2,\"10\",\"&\",\"uuid\",\"index\",0,\"fdcd\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",20,4,true],\"post_proc\":[\"/\",10]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",24,4,true,false],\"post_proc\":[\"/\",10]},\"mac\":{\"decoder\":[\"revmac_from_hex_data\",\"servicedata\",4]}}}"; +/*R""""( +{ + "brand":"Qingping", + "model":"TH Lite", + "model_id":"CGDK2", + "tag":"01", + "condition":["servicedata", "=", 34, "index", 2, "10", "&", "uuid", "index", 0, "fdcd"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "servicedata", 20, 4, true], + "post_proc":["/", 10] + }, + "hum":{ + "decoder":["value_from_hex_data", "servicedata", 24, 4, true, false], + "post_proc":["/", 10] + }, + "mac":{ + "decoder":["revmac_from_hex_data", "servicedata", 4] + } + } +})"""";*/ + +// ATC1441 +const char* _CGDK2_json_ATC1441 = "{\"brand\":\"ClearGrass/Qingping\",\"model\":\"TH Lite\",\"model_id\":\"CGDK2_ATC1441\",\"tag\":\"0102\",\"condition\":[\"servicedata\",\"=\",26,\"&\",\"uuid\",\"index\",0,\"181a\",\"&\",\"name\",\"index\",0,\"CGDK\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",12,4,false],\"post_proc\":[\"/\",10]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",16,2,false]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",18,2,false]},\"volt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",20,4,false],\"post_proc\":[\"/\",1000]},\"mac\":{\"decoder\":[\"mac_from_hex_data\",\"servicedata\",0]}}}"; +/* R""""( +{ + "brand":"ClearGrass/Qingping", + "model":"TH Lite", + "model_id":"CGDK2_ATC1441", + "tag":"0102", + "condition":["servicedata", "=", 26, "&", "uuid", "index", 0, "181a", "&", "name", "index", 0, "CGDK"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "servicedata", 12, 4, false], + "post_proc":["/", 10] + }, + "hum":{ + "decoder":["value_from_hex_data", "servicedata", 16, 2, false] + }, + "batt":{ + "decoder":["value_from_hex_data", "servicedata", 18, 2, false] + }, + "volt":{ + "decoder":["value_from_hex_data", "servicedata", 20, 4, false], + "post_proc":["/", 1000] + }, + "mac":{ + "decoder":["mac_from_hex_data", "servicedata", 0] + } + } +})"""";*/ + +// PVVX +const char* _CGDK2_json_PVVX = "{\"brand\":\"ClearGrass/Qingping\",\"model\":\"TH Lite\",\"model_id\":\"CGDK2_PVVX\",\"tag\":\"0102\",\"condition\":[\"servicedata\",\"=\",30,\"&\",\"uuid\",\"index\",0,\"181a\",\"&\",\"name\",\"index\",0,\"CGDK\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",12,4,true],\"post_proc\":[\"/\",100]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",16,4,true],\"post_proc\":[\"/\",100]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",24,2,false]},\"volt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",20,4,true],\"post_proc\":[\"/\",1000]},\"mac\":{\"decoder\":[\"revmac_from_hex_data\",\"servicedata\",0]}}}"; +/* R""""( +{ + "brand":"ClearGrass/Qingping", + "model":"TH Lite", + "model_id":"CGDK2_PVVX", + "tag":"0102", + "condition":["servicedata", "=", 30, "&", "uuid", "index", 0, "181a", "&", "name", "index", 0, "CGDK"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "servicedata", 12, 4, true], + "post_proc":["/", 100] + }, + "hum":{ + "decoder":["value_from_hex_data", "servicedata", 16, 4, true], + "post_proc":["/", 100] + }, + "batt":{ + "decoder":["value_from_hex_data", "servicedata", 24, 2, false] + }, + "volt":{ + "decoder":["value_from_hex_data", "servicedata", 20, 4, true], + "post_proc":["/", 1000] + }, + "mac":{ + "decoder":["revmac_from_hex_data", "servicedata", 0] + } + } +})"""";*/ + +const char* _CGDK2_json_props = _common_BVTH_props; diff --git a/lib/decoder/src/devices/CGDN1_json.h b/lib/decoder/src/devices/CGDN1_json.h new file mode 100644 index 00000000..aaa38a82 --- /dev/null +++ b/lib/decoder/src/devices/CGDN1_json.h @@ -0,0 +1,55 @@ +const char* _CGDN1_json = "{\"brand\":\"Qingping\",\"model\":\"Air Monitor Lite\",\"model_id\":\"CGDN1\",\"tag\":\"0f\",\"condition\":[\"servicedata\",\"=\",48,\"index\",2,\"0e\",\"|\",\"servicedata\",\"=\",48,\"index\",2,\"24\",\"&\",\"uuid\",\"index\",0,\"fdcd\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",20,4,true,false],\"post_proc\":[\"/\",10]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",24,4,true,false],\"post_proc\":[\"/\",10]},\"pm25\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",32,4,true,false]},\"pm10\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",36,4,true,false]},\"co2\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",44,4,true,false]}}}"; +/*R""""( +{ + "brand":"Qingping", + "model":"Air Monitor Lite", + "model_id":"CGDN1", + "tag":"0f", + "condition":["servicedata", "=", 48, "index", 2, "0e", "|", "servicedata", "=", 48, "index", 2, "24", "&", "uuid", "index", 0, "fdcd"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "servicedata", 20, 4, true, false], + "post_proc":["/", 10] + }, + "hum":{ + "decoder":["value_from_hex_data", "servicedata", 24, 4, true, false], + "post_proc":["/", 10] + }, + "pm25":{ + "decoder":["value_from_hex_data", "servicedata", 32, 4, true, false] + }, + "pm10":{ + "decoder":["value_from_hex_data", "servicedata", 36, 4, true, false] + }, + "co2":{ + "decoder":["value_from_hex_data", "servicedata", 44, 4, true, false] + } + } +})"""";*/ + +const char* _CGDN1_json_props = "{\"properties\":{\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"},\"pm25\":{\"unit\":\"μg/m³\",\"name\":\"PM2.5\"},\"pm10\":{\"unit\":\"μg/m³\",\"name\":\"PM10\"},\"co2\":{\"unit\":\"ppm\",\"name\":\"carbon dioxide\"}}}"; +/*R""""( +{ + "properties":{ + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "hum":{ + "unit":"%", + "name":"humidity" + }, + "pm25":{ + "unit":"μg/m³", + "name":"PM2.5" + }, + "pm10":{ + "unit":"μg/m³", + "name":"PM10" + }, + "co2":{ + "unit":"ppm", + "name":"carbon dioxide" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/CGG1_json.h b/lib/decoder/src/devices/CGG1_json.h new file mode 100644 index 00000000..df0b6ea3 --- /dev/null +++ b/lib/decoder/src/devices/CGG1_json.h @@ -0,0 +1,125 @@ +#include "common_props.h" + +const char* _CGG1_json_STOCK = "{\"brand\":\"ClearGrass/Qingping\",\"model\":\"Round TH\",\"model_id\":\"CGG1\",\"tag\":\"01\",\"condition\":[\"servicedata\",\"=\",34,\"index\",2,\"07\",\"|\",\"servicedata\",\"=\",34,\"index\",2,\"16\",\"&\",\"uuid\",\"index\",0,\"fdcd\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",20,4,true],\"post_proc\":[\"/\",10]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",24,4,true],\"post_proc\":[\"/\",10]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",32,2,false]},\"mac\":{\"decoder\":[\"revmac_from_hex_data\",\"servicedata\",4]}}}"; +/* R""""( +{ + "brand":"ClearGrass/Qingping", + "model":"Round TH", + "model_id":"CGG1", + "tag":"01", + "condition":["servicedata", "=", 34, "index", 2, "07", "|", "servicedata", "=", 34, "index", 2, "16", "&", "uuid", "index", 0, "fdcd"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "servicedata", 20, 4, true], + "post_proc":["/", 10] + }, + "hum":{ + "decoder":["value_from_hex_data", "servicedata", 24, 4, true], + "post_proc":["/", 10] + }, + "batt":{ + "decoder":["value_from_hex_data", "servicedata", 32, 2, false] + }, + "mac":{ + "decoder":["revmac_from_hex_data", "servicedata", 4] + } + } +})"""";*/ + +// ATC1441 +const char* _CGG1_json_ATC1441 = "{\"brand\":\"ClearGrass/Qingping\",\"model\":\"Round TH\",\"model_id\":\"CGG1_ATC1441\",\"tag\":\"0102\",\"condition\":[\"servicedata\",\"=\",26,\"&\",\"uuid\",\"index\",0,\"181a\",\"&\",\"name\",\"index\",0,\"CGG\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",12,4,false],\"post_proc\":[\"/\",10]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",16,2,false]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",18,2,false]},\"volt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",20,4,false],\"post_proc\":[\"/\",1000]},\"mac\":{\"decoder\":[\"mac_from_hex_data\",\"servicedata\",0]}}}"; +/* R""""( +{ + "brand":"ClearGrass/Qingping", + "model":"Round TH", + "model_id":"CGG1_ATC1441", + "tag":"0102", + "condition":["servicedata", "=", 26, "&", "uuid", "index", 0, "181a", "&", "name", "index", 0, "CGG"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "servicedata", 12, 4, false], + "post_proc":["/", 10] + }, + "hum":{ + "decoder":["value_from_hex_data", "servicedata", 16, 2, false] + }, + "batt":{ + "decoder":["value_from_hex_data", "servicedata", 18, 2, false] + }, + "volt":{ + "decoder":["value_from_hex_data", "servicedata", 20, 4, false], + "post_proc":["/", 1000] + }, + "mac":{ + "decoder":["mac_from_hex_data", "servicedata", 0] + } + } +})"""";*/ + +// PVVX +const char* _CGG1_json_PVVX = "{\"brand\":\"ClearGrass/Qingping\",\"model\":\"Round TH\",\"model_id\":\"CGG1_PVVX\",\"tag\":\"0102\",\"condition\":[\"servicedata\",\"=\",30,\"&\",\"uuid\",\"index\",0,\"181a\",\"&\",\"name\",\"index\",0,\"CGG\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",12,4,true],\"post_proc\":[\"/\",100]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",16,4,true],\"post_proc\":[\"/\",100]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",24,2,false]},\"volt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",20,4,true],\"post_proc\":[\"/\",1000]},\"mac\":{\"decoder\":[\"revmac_from_hex_data\",\"servicedata\",0]}}}"; +/* R""""( +{ + "brand":"ClearGrass/Qingping", + "model":"Round TH", + "model_id":"CGG1_PVVX", + "tag":"0102", + "condition":["servicedata", "=", 30, "&", "uuid", "index", 0, "181a", "&", "name", "index", 0, "CGG"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "servicedata", 12, 4, true], + "post_proc":["/", 100] + }, + "hum":{ + "decoder":["value_from_hex_data", "servicedata", 16, 4, true], + "post_proc":["/", 100] + }, + "batt":{ + "decoder":["value_from_hex_data", "servicedata", 24, 2, false] + }, + "volt":{ + "decoder":["value_from_hex_data", "servicedata", 20, 4, true], + "post_proc":["/", 1000] + }, + "mac":{ + "decoder":["revmac_from_hex_data", "servicedata", 0] + } + } +})"""";*/ + +const char* _CGG1_json_STOCK_2 = "{\"brand\":\"ClearGrass/Qingping\",\"model\":\"Round TH\",\"model_id\":\"CGG1\",\"tag\":\"0102\",\"condition\":[\"servicedata\",\"=\",30,\"|\",\"servicedata\",\"=\",32,\"|\",\"servicedata\",\"=\",36,\"&\",\"name\",\"index\",0,\"Qingping Temp & RH\",\"|\",\"name\",\"index\",0,\"ClearGrass Temp & RH\",\"&\",\"uuid\",\"index\",0,\"fe95\"],\"properties\":{\"tempc\":{\"condition\":[\"servicedata\",\">=\",32,\"&\",\"servicedata\",23,\"!\",\"6\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",28,4,true],\"post_proc\":[\"/\",10]},\"hum\":{\"condition\":[\"servicedata\",\"=\",36,\"&\",\"servicedata\",23,\"!\",\"6\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",32,4,true],\"post_proc\":[\"/\",10]},\"_hum\":{\"condition\":[\"servicedata\",\"=\",32,\"&\",\"servicedata\",23,\"6\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",28,4,true],\"post_proc\":[\"/\",10]},\"batt\":{\"condition\":[\"servicedata\",\"=\",30],\"decoder\":[\"value_from_hex_data\",\"servicedata\",28,2,false]},\"mac\":{\"decoder\":[\"revmac_from_hex_data\",\"servicedata\",10]}}}"; +/* +R""""( +{ + "brand":"ClearGrass/Qingping", + "model":"Round TH", + "model_id":"CGG1", + "tag":"0102", + "condition":["servicedata", "=", 30, "|", "servicedata", "=", 32, "|", "servicedata", "=", 36, "&", "name", "index", 0, "Qingping Temp & RH", "|", "name", "index", 0, "ClearGrass Temp & RH", "&","uuid", "index", 0, "fe95"], + "properties":{ + "tempc":{ + "condition":["servicedata", ">=", 32, "&", "servicedata", 23, "!", "6"], + "decoder":["value_from_hex_data", "servicedata", 28, 4, true], + "post_proc":["/", 10] + }, + "hum":{ + "condition":["servicedata", "=", 36, "&", "servicedata", 23, "!", "6"], + "decoder":["value_from_hex_data", "servicedata", 32, 4, true], + "post_proc":["/", 10] + }, + "_hum":{ + "condition":["servicedata", "=", 32, "&", "servicedata", 23, "6"], + "decoder":["value_from_hex_data", "servicedata", 28, 4, true], + "post_proc":["/", 10] + }, + "batt":{ + "condition":["servicedata", "=", 30], + "decoder":["value_from_hex_data", "servicedata", 28, 2, false] + }, + "mac":{ + "decoder":["revmac_from_hex_data", "servicedata", 10] + } + } +})"""";*/ + +const char* _CGG1_json_props = _common_BVTH_props; diff --git a/lib/decoder/src/devices/CGH1_json.h b/lib/decoder/src/devices/CGH1_json.h new file mode 100644 index 00000000..d9235802 --- /dev/null +++ b/lib/decoder/src/devices/CGH1_json.h @@ -0,0 +1,37 @@ +const char* _CGH1_json = "{\"brand\":\"Qingping\",\"model\":\"Contact Sensor\",\"model_id\":\"CGH1\",\"tag\":\"0404\",\"condition\":[\"servicedata\",\"=\",34,\"index\",2,\"04\",\"|\",\"servicedata\",\"=\",28,\"index\",2,\"04\",\"&\",\"uuid\",\"index\",0,\"fdcd\"],\"properties\":{\"open\":{\"condition\":[\"servicedata\",\"=\",28],\"decoder\":[\"bit_static_value\",\"servicedata\",21,0,true,false]},\"_open\":{\"condition\":[\"servicedata\",\"=\",34],\"decoder\":[\"bit_static_value\",\"servicedata\",33,0,true,false]},\"mac\":{\"decoder\":[\"revmac_from_hex_data\",\"servicedata\",4]}}}"; +/*R""""( +{ + "brand":"Qingping", + "model":"Contact Sensor", + "model_id":"CGH1", + "tag":"0404", + "condition":["servicedata", "=", 34, "index", 2, "04", "|", "servicedata", "=", 28, "index", 2, "04", "&", "uuid", "index", 0, "fdcd"], + "properties":{ + "open":{ + "condition":["servicedata", "=", 28], + "decoder":["bit_static_value", "servicedata", 21, 0, true, false] + }, + "_open":{ + "condition":["servicedata", "=", 34], + "decoder":["bit_static_value", "servicedata", 33, 0, true, false] + }, + "mac":{ + "decoder":["revmac_from_hex_data", "servicedata", 4] + } + } +})"""";*/ + +const char* _CGH1_json_props = "{\"properties\":{\"open\":{\"unit\":\"status\",\"name\":\"door\"},\"mac\":{\"unit\":\"string\",\"name\":\"MAC address\"}}}"; +/*R""""( +{ + "properties":{ + "open":{ + "unit":"status", + "name":"door" + }, + "mac":{ + "unit":"string", + "name":"MAC address" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/CGP1W_json.h b/lib/decoder/src/devices/CGP1W_json.h new file mode 100644 index 00000000..228a6387 --- /dev/null +++ b/lib/decoder/src/devices/CGP1W_json.h @@ -0,0 +1,49 @@ +const char* _CGP1W_json = "{\"brand\":\"ClearGrass\",\"model\":\"Weather Station\",\"model_id\":\"CGP1W\",\"tag\":\"02\",\"condition\":[\"servicedata\",\"=\",42,\"index\",2,\"09\",\"&\",\"uuid\",\"index\",0,\"fdcd\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",20,4,true],\"post_proc\":[\"/\",10]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",24,4,true,false],\"post_proc\":[\"/\",10]},\"pres\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",32,4,true,false],\"post_proc\":[\"/\",10]},\"mac\":{\"decoder\":[\"revmac_from_hex_data\",\"servicedata\",4]}}}"; +/*R""""( +{ + "brand":"ClearGrass", + "model":"Weather Station", + "model_id":"CGP1W", + "tag":"02", + "condition":["servicedata", "=", 42, "index", 2, "09", "&", "uuid", "index", 0, "fdcd"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "servicedata", 20, 4, true], + "post_proc":["/", 10] + }, + "hum":{ + "decoder":["value_from_hex_data", "servicedata", 24, 4, true, false], + "post_proc":["/", 10] + }, + "pres":{ + "decoder":["value_from_hex_data", "servicedata", 32, 4, true, false], + "post_proc":["/", 10] + }, + "mac":{ + "decoder":["revmac_from_hex_data", "servicedata", 4] + } + } +})"""";*/ + +const char* _CGP1W_json_props = "{\"properties\":{\"pres\":{\"unit\":\"hPa\",\"name\":\"pressure\"},\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"},\"mac\":{\"unit\":\"string\",\"name\":\"MAC address\"}}}"; +/*R""""( +{ + "properties":{ + "pres":{ + "unit":"hPa", + "name":"pressure" + }, + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "hum":{ + "unit":"%", + "name":"humidity" + }, + "mac":{ + "unit":"string", + "name":"MAC address" + } + } +})"""";*/ \ No newline at end of file diff --git a/lib/decoder/src/devices/CGPR1_json.h b/lib/decoder/src/devices/CGPR1_json.h new file mode 100644 index 00000000..484177a7 --- /dev/null +++ b/lib/decoder/src/devices/CGPR1_json.h @@ -0,0 +1,58 @@ +const char* _CGPR1_json = "{\"brand\":\"Qingping\",\"model\":\"Motion & Light\",\"model_id\":\"CGPR1\",\"tag\":\"0404\",\"condition\":[\"servicedata\",\"=\",28,\"index\",2,\"12\",\"|\",\"servicedata\",\"=\",34,\"index\",2,\"12\",\"|\",\"servicedata\",\"=\",40,\"index\",2,\"12\",\"&\",\"uuid\",\"index\",0,\"fdcd\"],\"properties\":{\"lux\":{\"condition\":[\"servicedata\",\"=\",40],\"decoder\":[\"value_from_hex_data\",\"servicedata\",32,4,true,false]},\"_lux\":{\"condition\":[\"servicedata\",\"=\",34],\"decoder\":[\"value_from_hex_data\",\"servicedata\",22,4,true,false]},\"motion\":{\"condition\":[\"servicedata\",\"=\",34],\"decoder\":[\"bit_static_value\",\"servicedata\",21,0,false,true]},\"_motion\":{\"condition\":[\"servicedata\",\"=\",28],\"decoder\":[\"bit_static_value\",\"servicedata\",21,0,false,true]},\"batt\":{\"condition\":[\"servicedata\",\"=\",40],\"decoder\":[\"value_from_hex_data\",\"servicedata\",20,2,false,false]},\"mac\":{\"decoder\":[\"revmac_from_hex_data\",\"servicedata\",4]}}}"; +/* +R""""( +{ + "brand":"Qingping", + "model":"Motion & Light", + "model_id":"CGPR1", + "tag":"0404", + "condition":["servicedata", "=", 28, "index", 2, "12", "|", "servicedata", "=", 34, "index", 2, "12", "|", "servicedata", "=", 40, "index", 2, "12", "&", "uuid", "index", 0, "fdcd"], + "properties":{ + "lux":{ + "condition":["servicedata", "=", 40], + "decoder":["value_from_hex_data", "servicedata", 32, 4, true, false] + }, + "_lux":{ + "condition":["servicedata", "=", 34], + "decoder":["value_from_hex_data", "servicedata", 22, 4, true, false] + }, + "motion":{ + "condition":["servicedata", "=", 34], + "decoder":["bit_static_value", "servicedata", 21, 0, false, true] + }, + "_motion":{ + "condition":["servicedata", "=", 28], + "decoder":["bit_static_value", "servicedata", 21, 0, false, true] + }, + "batt":{ + "condition":["servicedata", "=", 40], + "decoder":["value_from_hex_data", "servicedata", 20, 2, false, false] + }, + "mac":{ + "decoder":["revmac_from_hex_data", "servicedata", 4] + } + } +})"""";*/ + +const char* _CGPR1_json_props = "{\"properties\":{\"lux\":{\"unit\":\"lx\",\"name\":\"illuminance\"},\"motion\":{\"unit\":\"status\",\"name\":\"motion\"},\"batt\":{\"unit\":\"%\",\"name\":\"battery\"},\"mac\":{\"unit\":\"string\",\"name\":\"MAC address\"}}}"; +/*R""""( +{ + "properties":{ + "lux":{ + "unit":"lx", + "name":"illuminance" + }, + "motion":{ + "unit":"status", + "name":"motion" + }, + "batt":{ + "unit":"%", + "name":"battery" + }, + "mac":{ + "unit":"string", + "name":"MAC address" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/GAEN_json.h b/lib/decoder/src/devices/GAEN_json.h new file mode 100644 index 00000000..bf61c13e --- /dev/null +++ b/lib/decoder/src/devices/GAEN_json.h @@ -0,0 +1,33 @@ +const char* _GAEN_json = "{\"brand\":\"GENERIC\",\"model\":\"GAEN\",\"model_id\":\"GAEN\",\"tag\":\"fe\",\"condition\":[\"uuid\",\"index\",0,\"fd6f\"],\"properties\":{\"rpi\":{\"decoder\":[\"string_from_hex_data\",\"servicedata\",0,32]},\"aem\":{\"decoder\":[\"string_from_hex_data\",\"servicedata\",32,8]}}}"; + +/*R""""( +{ + "brand":"GENERIC", + "model":"GAEN", + "model_id":"GAEN", + "tag":"fe", + "condition":["uuid", "index", 0, "fd6f"], + "properties":{ + "rpi":{ + "decoder":["string_from_hex_data", "servicedata", 0, 32] + }, + "aem":{ + "decoder":["string_from_hex_data", "servicedata", 32, 8] + } + } +})"""";*/ + +const char* _GAEN_json_props = "{\"properties\":{\"rpi\":{\"unit\":\"hex\",\"name\":\"rolling proximity identifier\"},\"aem\":{\"unit\":\"hex\",\"name\":\"associated encrypted metadata\"}}}"; +/*R""""( +{ + "properties":{ + "rpi":{ + "unit":"hex", + "name":"rolling proximity identifier" + }, + "aem":{ + "unit":"hex", + "name":"associated encrypted metadata" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/H5055_json.h b/lib/decoder/src/devices/H5055_json.h new file mode 100644 index 00000000..67921bd9 --- /dev/null +++ b/lib/decoder/src/devices/H5055_json.h @@ -0,0 +1,74 @@ +const char* _H5055_json = "{\"brand\":\"Govee\",\"model\":\"Bluetooth BBQ Thermometer\",\"model_id\":\"H5055\",\"tag\":\"0301\",\"condition\":[\"manufacturerdata\",\">=\",41,\"index\",12,\"06\",\"|\",\"manufacturerdata\",\">=\",41,\"index\",12,\"20\",\"&\",\"manufacturerdata\",\"index\",26,\"06\",\"|\",\"manufacturerdata\",\">=\",41,\"index\",26,\"20\",\"&\",\"manufacturerdata\",\"index\",40,\"0\"],\"properties\":{\"tempc1\":{\"condition\":[\"manufacturerdata\",14,\"!\",\"ffff\",\"&\",\"manufacturerdata\",10,\"bit\",3,0,\"&\",\"manufacturerdata\",10,\"bit\",2,0],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",14,4,true,false]},\"tempc2\":{\"condition\":[\"manufacturerdata\",28,\"!\",\"ffff\",\"&\",\"manufacturerdata\",10,\"bit\",3,0,\"&\",\"manufacturerdata\",10,\"bit\",2,0],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",28,4,true,false]},\"tempc3\":{\"condition\":[\"manufacturerdata\",14,\"!\",\"ffff\",\"&\",\"manufacturerdata\",10,\"bit\",3,0,\"&\",\"manufacturerdata\",10,\"bit\",2,1],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",14,4,true,false]},\"tempc4\":{\"condition\":[\"manufacturerdata\",28,\"!\",\"ffff\",\"&\",\"manufacturerdata\",10,\"bit\",3,0,\"&\",\"manufacturerdata\",10,\"bit\",2,1],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",28,4,true,false]},\"tempc5\":{\"condition\":[\"manufacturerdata\",14,\"!\",\"ffff\",\"&\",\"manufacturerdata\",10,\"bit\",3,1,\"&\",\"manufacturerdata\",10,\"bit\",2,0],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",14,4,true,false]},\"tempc6\":{\"condition\":[\"manufacturerdata\",28,\"!\",\"ffff\",\"&\",\"manufacturerdata\",10,\"bit\",3,1,\"&\",\"manufacturerdata\",10,\"bit\",2,0],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",28,4,true,false]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",8,2,false]}}}"; +/*R""""( +{ + "brand":"Govee", + "model":"Bluetooth BBQ Thermometer", + "model_id":"H5055", + "tag":"0301", + "condition":["manufacturerdata", ">=", 41, "index", 12, "06", "|", "manufacturerdata", ">=", 41, "index", 12, "20", "&", "manufacturerdata", "index", 26, "06", "|", "manufacturerdata", ">=", 41, "index", 26, "20", "&", "manufacturerdata", "index", 40, "0"], + "properties":{ + "tempc1":{ + "condition":["manufacturerdata", 14, "!", "ffff", "&", "manufacturerdata", 10, "bit", 3, 0, "&", "manufacturerdata", 10, "bit", 2, 0], + "decoder":["value_from_hex_data", "manufacturerdata", 14, 4, true, false] + }, + "tempc2":{ + "condition":["manufacturerdata", 28, "!", "ffff", "&", "manufacturerdata", 10, "bit", 3, 0, "&", "manufacturerdata", 10, "bit", 2, 0], + "decoder":["value_from_hex_data", "manufacturerdata", 28, 4, true, false] + }, + "tempc3":{ + "condition":["manufacturerdata", 14, "!", "ffff", "&", "manufacturerdata", 10, "bit", 3, 0, "&", "manufacturerdata", 10, "bit", 2, 1], + "decoder":["value_from_hex_data", "manufacturerdata", 14, 4, true, false] + }, + "tempc4":{ + "condition":["manufacturerdata", 28, "!", "ffff", "&", "manufacturerdata", 10, "bit", 3, 0, "&", "manufacturerdata", 10, "bit", 2, 1], + "decoder":["value_from_hex_data", "manufacturerdata", 28, 4, true, false] + }, + "tempc5":{ + "condition":["manufacturerdata", 14, "!", "ffff", "&", "manufacturerdata", 10, "bit", 3, 1, "&", "manufacturerdata", 10, "bit", 2, 0], + "decoder":["value_from_hex_data", "manufacturerdata", 14, 4, true, false] + }, + "tempc6":{ + "condition":["manufacturerdata", 28, "!", "ffff", "&", "manufacturerdata", 10, "bit", 3, 1, "&", "manufacturerdata", 10, "bit", 2, 0], + "decoder":["value_from_hex_data", "manufacturerdata", 28, 4, true, false] + }, + "batt":{ + "decoder":["value_from_hex_data", "manufacturerdata", 8, 2, false] + } + } +})"""";*/ + +const char* _H5055_json_props = "{\"properties\":{\"tempc1\":{\"unit\":\"°C\",\"name\":\"tempc1\"},\"tempc2\":{\"unit\":\"°C\",\"name\":\"tempc2\"},\"tempc3\":{\"unit\":\"°C\",\"name\":\"tempc3\"},\"tempc4\":{\"unit\":\"°C\",\"name\":\"tempc4\"},\"tempc5\":{\"unit\":\"°C\",\"name\":\"tempc5\"},\"tempc6\":{\"unit\":\"°C\",\"name\":\"tempc6\"},\"batt\":{\"unit\":\"%\",\"name\":\"battery\"}}}"; +/*R""""( +{ + "properties":{ + + "tempc1":{ + "unit":"°C", + "name":"tempc1" + }, + "tempc2":{ + "unit":"°C", + "name":"tempc2" + }, + "tempc3":{ + "unit":"°C", + "name":"tempc3" + }, + "tempc4":{ + "unit":"°C", + "name":"tempc4" + }, + "tempc5":{ + "unit":"°C", + "name":"tempc5" + }, + "tempc6":{ + "unit":"°C", + "name":"tempc6" + }, + "batt":{ + "unit":"%", + "name":"battery" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/H5072_json.h b/lib/decoder/src/devices/H5072_json.h new file mode 100644 index 00000000..190ceb58 --- /dev/null +++ b/lib/decoder/src/devices/H5072_json.h @@ -0,0 +1,33 @@ +#include "common_props.h" + +const char* _H5072_json = "{\"brand\":\"Govee\",\"model\":\"Thermo-Hygrometer\",\"model_id\":\"H5072/75\",\"tag\":\"0103\",\"condition\":[\"name\",\"index\",0,\"GVH5072\",\"|\",\"name\",\"index\",0,\"GVH5075\",\"&\",\"manufacturerdata\",\">=\",16,\"index\",0,\"88ec\"],\"properties\":{\"tempc\":{\"condition\":[\"manufacturerdata\",6,\"bit\",3,0],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",6,6,false,false],\"post_proc\":[\"/\",1000,\">\",0,\"/\",10]},\"_tempc\":{\"condition\":[\"manufacturerdata\",6,\"bit\",3,1],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",6,6,false,false],\"post_proc\":[\"-\",8388608,\"/\",10000,\"*\",-1]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",6,6,false,false],\"post_proc\":[\"%\",1000,\"/\",10]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",12,2,false,false]}}}"; + +/* R""""( +{ + "brand":"Govee", + "model":"Thermo-Hygrometer", + "model_id":"H5072/75", + "tag":"0103", + "condition":["name", "index", 0, "GVH5072", "|", "name", "index", 0, "GVH5075", "&", "manufacturerdata", ">=", 16, "index", 0, "88ec"], + "properties":{ + "tempc":{ + "condition":["manufacturerdata", 6, "bit", 3, 0], + "decoder":["value_from_hex_data", "manufacturerdata", 6, 6, false, false], + "post_proc":["/", 1000, ">", 0, "/", 10] + }, + "_tempc":{ + "condition":["manufacturerdata", 6, "bit", 3, 1], + "decoder":["value_from_hex_data", "manufacturerdata", 6, 6, false, false], + "post_proc":["-", 8388608, "/", 10000, "*", -1] + }, + "hum":{ + "decoder":["value_from_hex_data", "manufacturerdata", 6, 6, false, false], + "post_proc":["%", 1000, "/", 10] + }, + "batt":{ + "decoder":["value_from_hex_data", "manufacturerdata", 12, 2, false, false] + } + } +})"""";*/ + +const char* _H5072_json_props = _common_BTH_props; diff --git a/lib/decoder/src/devices/H5074_json.h b/lib/decoder/src/devices/H5074_json.h new file mode 100644 index 00000000..740c4f31 --- /dev/null +++ b/lib/decoder/src/devices/H5074_json.h @@ -0,0 +1,26 @@ +#include "common_props.h" + +const char* _H5074_json = "{\"brand\":\"Govee\",\"model\":\"Thermo-Hygrometer\",\"model_id\":\"H5074\",\"tag\":\"0103\",\"condition\":[\"name\",\"index\",0,\"Govee_H5074\",\"&\",\"manufacturerdata\",\">=\",18,\"index\",0,\"88ec\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",6,4,true,true],\"post_proc\":[\"/\",100]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",10,4,true,false],\"post_proc\":[\"/\",100]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",14,2,false,false]}}}"; +/* R""""( +{ + "brand":"Govee", + "model":"Thermo-Hygrometer", + "model_id":"H5074", + "tag":"0103", + "condition":["name", "index", 0, "Govee_H5074", "&", "manufacturerdata", ">=", 18, "index", 0, "88ec"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "manufacturerdata", 6, 4, true, true], + "post_proc":["/", 100] + }, + "hum":{ + "decoder":["value_from_hex_data", "manufacturerdata", 10, 4, true, false], + "post_proc":["/", 100] + }, + "batt":{ + "decoder":["value_from_hex_data", "manufacturerdata", 14, 2, false, false] + } + } +})"""";*/ + +const char* _H5074_json_props = _common_BTH_props; diff --git a/lib/decoder/src/devices/H5102_json.h b/lib/decoder/src/devices/H5102_json.h new file mode 100644 index 00000000..f6bf58ca --- /dev/null +++ b/lib/decoder/src/devices/H5102_json.h @@ -0,0 +1,33 @@ +#include "common_props.h" + +const char* _H5102_json = "{\"brand\":\"Govee\",\"model\":\"Smart Thermo-Hygrometer\",\"model_id\":\"H5100/01/02/04/74/77\",\"tag\":\"0103\",\"condition\":[\"name\",\"index\",0,\"GVH5100\",\"|\",\"name\",\"index\",0,\"GVH5101\",\"|\",\"name\",\"index\",0,\"GVH5102\",\"|\",\"name\",\"index\",0,\"GVH5104\",\"|\",\"name\",\"index\",0,\"GVH5174\",\"|\",\"name\",\"index\",0,\"GVH5177\",\"&\",\"manufacturerdata\",\">=\",16,\"index\",0,\"0100\"],\"properties\":{\"tempc\":{\"condition\":[\"manufacturerdata\",8,\"bit\",3,0],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",8,6,false,false],\"post_proc\":[\"/\",1000,\">\",0,\"/\",10]},\"_tempc\":{\"condition\":[\"manufacturerdata\",8,\"bit\",3,1],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",8,6,false,false],\"post_proc\":[\"&\",8388607,\"/\",1000,\">\",0,\"/\",10,\"*\",-1]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",8,6,false,false],\"post_proc\":[\"%\",1000,\"/\",10]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",14,2,false,false]}}}"; + +/* R""""( +{ + "brand":"Govee", + "model":"Smart Thermo-Hygrometer", + "model_id":"H5100/01/02/04/74/77", + "tag":"0103", + "condition":["name", "index", 0, "GVH5100", "|", "name", "index", 0, "GVH5101", "|", "name", "index", 0, "GVH5102", "|", "name", "index", 0, "GVH5104", "|", "name", "index", 0, "GVH5174", "|", "name", "index", 0, "GVH5177", "&", "manufacturerdata", ">=", 16, "index", 0, "0100"], + "properties":{ + "tempc":{ + "condition":["manufacturerdata", 8, "bit", 3, 0], + "decoder":["value_from_hex_data", "manufacturerdata", 8, 6, false, false], + "post_proc":["/", 1000, ">", 0, "/", 10] + }, + "_tempc":{ + "condition":["manufacturerdata", 8, "bit", 3, 1], + "decoder":["value_from_hex_data", "manufacturerdata", 8, 6, false, false], + "post_proc":["&", 8388607, "/", 1000, ">", 0, "/", 10, "*", -1] + }, + "hum":{ + "decoder":["value_from_hex_data", "manufacturerdata", 8, 6, false, false], + "post_proc":["%", 1000, "/", 10] + }, + "batt":{ + "decoder":["value_from_hex_data", "manufacturerdata", 14, 2, false, false] + } + } +})"""";*/ + +const char* _H5102_json_props = _common_BTH_props; diff --git a/lib/decoder/src/devices/H5106_json.h b/lib/decoder/src/devices/H5106_json.h new file mode 100644 index 00000000..70aa94b4 --- /dev/null +++ b/lib/decoder/src/devices/H5106_json.h @@ -0,0 +1,52 @@ +const char* _H5106_json = "{\"brand\":\"Govee\",\"model\":\"Smart Air Quality Monitor\",\"model_id\":\"H5106\",\"tag\":\"0f03\",\"condition\":[\"name\",\"index\",0,\"GVH5106\",\"&\",\"manufacturerdata\",\">=\",16,\"index\",0,\"0100\"],\"properties\":{\"tempc\":{\"condition\":[\"manufacturerdata\",8,\"bit\",3,0],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",8,8,false,false],\"post_proc\":[\"/\",1000000,\">\",0,\"/\",10]},\"_tempc\":{\"condition\":[\"manufacturerdata\",8,\"bit\",3,1],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",8,8,false,false],\"post_proc\":[\"&\",2147483647,\"/\",1000000,\">\",0,\"/\",10,\"*\",-1]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",8,8,false,false],\"post_proc\":[\"&\",2147483647,\"%\",1000000,\"/\",1000,\">\",0,\"/\",10]},\".cal\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",8,8,false,false],\"post_proc\":[\"&\",2147483647,\"/\",1000,\">\",0,\"*\",1000]},\"pm25\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",8,8,false,false],\"post_proc\":[\"&\",2147483647,\"-\",\".cal\"]}}}"; +/* R""""( +{ + "brand":"Govee", + "model":"Smart Air Quality Monitor", + "model_id":"H5106", + "tag":"0f03", + "condition":["name", "index", 0, "GVH5106", "&", "manufacturerdata", ">=", 16, "index", 0, "0100"], + "properties":{ + "tempc":{ + "condition":["manufacturerdata", 8, "bit", 3, 0], + "decoder":["value_from_hex_data", "manufacturerdata", 8, 8, false, false], + "post_proc":["/", 1000000, ">", 0, "/", 10] + }, + "_tempc":{ + "condition":["manufacturerdata", 8, "bit", 3, 1], + "decoder":["value_from_hex_data", "manufacturerdata", 8, 8, false, false], + "post_proc":["&", 2147483647, "/", 1000000, ">", 0, "/", 10, "*", -1] + }, + "hum":{ + "decoder":["value_from_hex_data", "manufacturerdata", 8, 8, false, false], + "post_proc":["&", 2147483647, "%", 1000000, "/", 1000, ">", 0, "/", 10] + }, + ".cal":{ + "decoder":["value_from_hex_data", "manufacturerdata", 8, 8, false, false], + "post_proc":["&", 2147483647, "/", 1000, ">", 0, "*", 1000] + }, + "pm25":{ + "decoder":["value_from_hex_data", "manufacturerdata", 8, 8, false, false], + "post_proc":["&", 2147483647, "-", ".cal"] + } + } +})"""";*/ + +const char* _H5106_json_props = "{\"properties\":{\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"},\"pm25\":{\"unit\":\"μg/m³\",\"name\":\"PM2.5\"}}}"; +/*R""""( +{ + "properties":{ + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "hum":{ + "unit":"%", + "name":"humidity" + }, + "pm25":{ + "unit":"μg/m³", + "name":"PM2.5" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/H5179_json.h b/lib/decoder/src/devices/H5179_json.h new file mode 100644 index 00000000..7c92eca2 --- /dev/null +++ b/lib/decoder/src/devices/H5179_json.h @@ -0,0 +1,26 @@ +#include "common_props.h" + +const char* _H5179_json = "{\"brand\":\"Govee\",\"model\":\"Thermo-Hygrometer\",\"model_id\":\"H5179\",\"tag\":\"0103\",\"condition\":[\"name\",\"index\",0,\"Govee_H5179\",\"&\",\"manufacturerdata\",\"=\",22,\"index\",0,\"0188ec\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",12,4,true,true],\"post_proc\":[\"/\",100]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",16,4,true,false],\"post_proc\":[\"/\",100]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",20,2,false,false]}}}"; +/* R""""( +{ + "brand":"Govee", + "model":"Thermo-Hygrometer", + "model_id":"H5179", + "tag":"0103", + "condition":["name", "index", 0, "Govee_H5179", "&", "manufacturerdata", "=", 22, "index", 0, "0188ec"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "manufacturerdata", 12, 4, true, true], + "post_proc":["/", 100] + }, + "hum":{ + "decoder":["value_from_hex_data", "manufacturerdata", 16, 4, true, false], + "post_proc":["/", 100] + }, + "batt":{ + "decoder":["value_from_hex_data", "manufacturerdata", 20, 2, false, false] + } + } +})"""";*/ + +const char* _H5179_json_props = _common_BTH_props; diff --git a/lib/decoder/src/devices/HHCCJCY01HHCC_json.h b/lib/decoder/src/devices/HHCCJCY01HHCC_json.h new file mode 100644 index 00000000..e404c058 --- /dev/null +++ b/lib/decoder/src/devices/HHCCJCY01HHCC_json.h @@ -0,0 +1,58 @@ +const char* _HHCCJCY01HHCC_json = "{\"brand\":\"Xiaomi/VegTrug\",\"model\":\"MiFlora\",\"model_id\":\"HHCCJCY01HHCC\",\"tag\":\"09\",\"condition\":[\"servicedata\",\"index\",4,\"9800\",\"|\",\"servicedata\",\"index\",4,\"bc03\",\"&\",\"uuid\",\"index\",0,\"fe95\"],\"properties\":{\"tempc\":{\"condition\":[\"servicedata\",24,\"0410\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",30,4,true],\"post_proc\":[\"/\",10]},\"moi\":{\"condition\":[\"servicedata\",24,\"0810\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",30,2,false]},\"lux\":{\"condition\":[\"servicedata\",24,\"0710\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",30,6,true]},\"fer\":{\"condition\":[\"servicedata\",24,\"0910\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",30,4,true]},\"mac\":{\"decoder\":[\"revmac_from_hex_data\",\"servicedata\",10]}}}"; +/*R""""( +{ + "brand":"Xiaomi/VegTrug", + "model":"MiFlora", + "model_id":"HHCCJCY01HHCC", + "tag":"09", + "condition":["servicedata", "index", 4, "9800", "|", "servicedata", "index", 4, "bc03", "&", "uuid", "index", 0, "fe95"], + "properties":{ + "tempc":{ + "condition":["servicedata", 24, "0410"], + "decoder":["value_from_hex_data", "servicedata", 30, 4, true], + "post_proc":["/", 10] + }, + "moi":{ + "condition":["servicedata", 24, "0810"], + "decoder":["value_from_hex_data", "servicedata", 30, 2, false] + }, + "lux":{ + "condition":["servicedata", 24, "0710"], + "decoder":["value_from_hex_data", "servicedata", 30, 6, true] + }, + "fer":{ + "condition":["servicedata", 24, "0910"], + "decoder":["value_from_hex_data", "servicedata", 30, 4, true] + }, + "mac":{ + "decoder":["revmac_from_hex_data", "servicedata", 10] + } + } +})"""";*/ + +const char* _HHCCJCY01HHCC_json_props = "{\"properties\":{\"lux\":{\"unit\":\"lx\",\"name\":\"illuminance\"},\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"fer\":{\"unit\":\"µS/cm\",\"name\":\"fertility\"},\"moi\":{\"unit\":\"%\",\"name\":\"moisture\"},\"mac\":{\"unit\":\"string\",\"name\":\"MAC address\"}}}"; +/*R""""( +{ + "properties":{ + "lux":{ + "unit":"lx", + "name":"illuminance" + }, + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "fer":{ + "unit":"µS/cm", + "name":"fertility" + }, + "moi":{ + "unit":"%", + "name":"moisture" + }, + "mac":{ + "unit":"string", + "name":"MAC address" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/HHCCJCY10_json.h b/lib/decoder/src/devices/HHCCJCY10_json.h new file mode 100644 index 00000000..bf303a6e --- /dev/null +++ b/lib/decoder/src/devices/HHCCJCY10_json.h @@ -0,0 +1,54 @@ +const char* _HHCCJCY10_json = "{\"brand\":\"Xiaomi/VegTrug\",\"model\":\"MiFlora\",\"model_id\":\"HHCCJCY10\",\"tag\":\"09\",\"condition\":[\"servicedata\",\"=\",18,\"&\",\"uuid\",\"index\",0,\"fd50\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",2,4,false,true],\"post_proc\":[\"/\",10]},\"moi\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",0,2,false,false]},\"lux\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",6,6,false,false]},\"fer\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",14,4,false,false]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",12,2,false,false]}}}"; +/*R""""( +{ + "brand":"Xiaomi/VegTrug", + "model":"MiFlora", + "model_id":"HHCCJCY10", + "tag":"09", + "condition":["servicedata", "=", 18, "&", "uuid", "index", 0, "fd50"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "servicedata", 2, 4, false, true], + "post_proc":["/", 10] + }, + "moi":{ + "decoder":["value_from_hex_data", "servicedata", 0, 2, false, false] + }, + "lux":{ + "decoder":["value_from_hex_data", "servicedata", 6, 6, false, false] + }, + "fer":{ + "decoder":["value_from_hex_data", "servicedata", 14, 4, false, false] + }, + "batt":{ + "decoder":["value_from_hex_data", "servicedata", 12, 2, false, false] + } + } +})"""";*/ + +const char* _HHCCJCY10_json_props = "{\"properties\":{\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"moi\":{\"unit\":\"%\",\"name\":\"moisture\"},\"lux\":{\"unit\":\"lx\",\"name\":\"illuminance\"},\"fer\":{\"unit\":\"µS/cm\",\"name\":\"fertility\"},\"batt\":{\"unit\":\"%\",\"name\":\"battery\"}}}"; +/*R""""( +{ + "properties":{ + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "moi":{ + "unit":"%", + "name":"moisture" + }, + "lux":{ + "unit":"lx", + "name":"illuminance" + }, + "fer":{ + "unit":"µS/cm", + "name":"fertility" + }, + "batt":{ + "unit":"%", + "name":"battery" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/HHCCPOT002_json.h b/lib/decoder/src/devices/HHCCPOT002_json.h new file mode 100644 index 00000000..298c808e --- /dev/null +++ b/lib/decoder/src/devices/HHCCPOT002_json.h @@ -0,0 +1,41 @@ +const char* _HHCCPOT002_json = "{\"brand\":\"Xiaomi\",\"model\":\"RoPot\",\"model_id\":\"HHCCPOT002\",\"tag\":\"09\",\"condition\":[\"servicedata\",\"index\",2,\"205d01\"],\"properties\":{\"moi\":{\"condition\":[\"servicedata\",25,\"8\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",30,2,false]},\"fer\":{\"condition\":[\"servicedata\",25,\"9\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",30,4,true]},\"mac\":{\"decoder\":[\"revmac_from_hex_data\",\"servicedata\",10]}}}"; +/*R""""( +{ + "brand":"Xiaomi", + "model":"RoPot", + "model_id":"HHCCPOT002", + "tag":"09", + "condition":["servicedata", "index", 2, "205d01"], + "properties":{ + "moi":{ + "condition":["servicedata", 25, "8"], + "decoder":["value_from_hex_data", "servicedata", 30, 2, false] + }, + "fer":{ + "condition":["servicedata", 25, "9"], + "decoder":["value_from_hex_data", "servicedata", 30, 4, true] + }, + "mac":{ + "decoder":["revmac_from_hex_data", "servicedata", 10] + } + } +})"""";*/ + +const char* _HHCCPOT002_json_props = "{\"properties\":{\"moi\":{\"unit\":\"%\",\"name\":\"moisture\"},\"fer\":{\"unit\":\"µS/cm\",\"name\":\"fertility\"},\"mac\":{\"unit\":\"string\",\"name\":\"MAC address\"}}}"; +/*R""""( +{ + "properties":{ + "moi":{ + "unit":"%", + "name":"moisture" + }, + "fer":{ + "unit":"µS/cm", + "name":"fertility" + }, + "mac":{ + "unit":"string", + "name":"MAC address" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/IBS_THBP01B_json.h b/lib/decoder/src/devices/IBS_THBP01B_json.h new file mode 100644 index 00000000..eeb8c4b9 --- /dev/null +++ b/lib/decoder/src/devices/IBS_THBP01B_json.h @@ -0,0 +1,51 @@ +const char* _IBS_THBP01B_json = "{\"brand\":\"Inkbird\",\"model\":\"T(H) Sensor\",\"model_id\":\"IBS-TH1/TH2/P01B/ITH-12S\",\"tag\":\"0103\",\"condition\":[\"name\",\"index\",0,\"sps\",\"|\",\"name\",\"index\",0,\"tps\",\"&\",\"manufacturerdata\",\"=\",18],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",0,4,true],\"post_proc\":[\"/\",100]},\"extprobe\":{\"condition\":[\"manufacturerdata\",9,\"!\",\"0\"],\"decoder\":[\"static_value\",true]},\"hum\":{\"condition\":[\"manufacturerdata\",4,\"!\",\"ffff\",\"&\",\"manufacturerdata\",4,\"!\",\"0000\"],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",4,4,true,false],\"post_proc\":[\"/\",100]},\"batt\":{\"condition\":[\"manufacturerdata\",14,\"!\",\"f\",\"&\",\"manufacturerdata\",14,\"!\",\"e\"],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",14,2,false,false]}}}"; +/*R""""( +{ + "brand":"Inkbird", + "model":"T(H) Sensor", + "model_id":"IBS-TH1/TH2/P01B/ITH-12S", + "tag":"0103", + "condition":["name", "index", 0, "sps", "|", "name", "index", 0, "tps", "&", "manufacturerdata", "=", 18], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "manufacturerdata", 0, 4, true], + "post_proc":["/", 100] + }, + "extprobe":{ + "condition":["manufacturerdata", 9, "!", "0"], + "decoder":["static_value", true] + }, + "hum":{ + "condition":["manufacturerdata", 4, "!", "ffff", "&", "manufacturerdata", 4, "!", "0000"], + "decoder":["value_from_hex_data", "manufacturerdata", 4, 4, true, false], + "post_proc":["/", 100] + }, + "batt":{ + "condition":["manufacturerdata", 14, "!", "f", "&", "manufacturerdata", 14, "!", "e"], + "decoder":["value_from_hex_data", "manufacturerdata", 14, 2, false, false] + } + } +})"""";*/ + +const char* _IBS_THBP01B_json_props = "{\"properties\":{\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"extprobe\":{\"unit\":\"status\",\"name\":\"external probe connected\"},\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"},\"batt\":{\"unit\":\"%\",\"name\":\"battery\"}}}"; +/*R""""( +{ + "properties":{ + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "extprobe":{ + "unit":"status", + "name":"external probe connected" + }, + "hum":{ + "unit":"%", + "name":"humidity" + }, + "batt":{ + "unit":"%", + "name":"battery" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/IBT_2X_json.h b/lib/decoder/src/devices/IBT_2X_json.h new file mode 100644 index 00000000..04a2c3dc --- /dev/null +++ b/lib/decoder/src/devices/IBT_2X_json.h @@ -0,0 +1,70 @@ +const char* _IBT_2X_json_2XS = "{\"brand\":\"Inkbird\",\"model\":\"iBBQ\",\"model_id\":\"IBT-2X(S)\",\"tag\":\"0301\",\"condition\":[\"manufacturerdata\",\"=\",28,\"index\",0,\"00000000\",\"&\",\"manufacturerdata\",\"mac@index\",8],\"conditionnomac\":[\"name\",\"index\",0,\"iBBQ\",\"|\",\"name\",\"index\",0,\"xBBQ\",\"&\",\"manufacturerdata\",\"=\",28,\"index\",0,\"00000000\"],\"properties\":{\"tempc\":{\"condition\":[\"manufacturerdata\",22,\"!\",\"ff\"],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",20,4,true,false],\"post_proc\":[\"/\",10]},\"tempc2\":{\"condition\":[\"manufacturerdata\",26,\"!\",\"ff\"],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",24,4,true,false],\"post_proc\":[\"/\",10]},\"mac\":{\"decoder\":[\"mac_from_hex_data\",\"manufacturerdata\",8]}}}"; +/*R""""( +{ + "brand":"Inkbird", + "model":"iBBQ", + "model_id":"IBT-2X(S)", + "tag":"0301", + "condition":["manufacturerdata", "=", 28, "index", 0, "00000000", "&", "manufacturerdata", "mac@index", 8], + "conditionnomac":["name", "index", 0, "iBBQ", "|", "name", "index", 0, "xBBQ", "&","manufacturerdata", "=", 28, "index", 0, "00000000"], + "properties":{ + "tempc":{ + "condition":["manufacturerdata", 22, "!", "ff"], + "decoder":["value_from_hex_data", "manufacturerdata", 20, 4, true, false], + "post_proc":["/", 10] + }, + "tempc2":{ + "condition":["manufacturerdata", 26, "!", "ff"], + "decoder":["value_from_hex_data", "manufacturerdata", 24, 4, true, false], + "post_proc":["/", 10] + }, + "mac":{ + "decoder":["mac_from_hex_data", "manufacturerdata", 8] + } + } +})"""";*/ + +const char* _IBT_2X_json_2X = "{\"brand\":\"Inkbird\",\"model\":\"iBBQ\",\"model_id\":\"IBT-2X(S)\",\"tag\":\"0301\",\"condition\":[\"manufacturerdata\",\"=\",28,\"index\",0,\"01000000\",\"&\",\"manufacturerdata\",\"revmac@index\",8],\"conditionnomac\":[\"name\",\"index\",0,\"iBBQ\",\"|\",\"name\",\"index\",0,\"xBBQ\",\"&\",\"manufacturerdata\",\"=\",28,\"index\",0,\"01000000\"],\"properties\":{\"tempc\":{\"condition\":[\"manufacturerdata\",22,\"!\",\"ff\"],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",20,4,true,false],\"post_proc\":[\"/\",10]},\"tempc2\":{\"condition\":[\"manufacturerdata\",26,\"!\",\"ff\"],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",24,4,true,false],\"post_proc\":[\"/\",10]},\"mac\":{\"decoder\":[\"revmac_from_hex_data\",\"manufacturerdata\",8]}}}"; +/*R""""( +{ + "brand":"Inkbird", + "model":"iBBQ", + "model_id":"IBT-2X(S)", + "tag":"0301", + "condition":["manufacturerdata", "=", 28, "index", 0, "01000000", "&", "manufacturerdata", "revmac@index", 8], + "conditionnomac":["name", "index", 0, "iBBQ", "|", "name", "index", 0, "xBBQ", "&", "manufacturerdata", "=", 28, "index", 0, "01000000"], + "properties":{ + "tempc":{ + "condition":["manufacturerdata", 22, "!", "ff"], + "decoder":["value_from_hex_data", "manufacturerdata", 20, 4, true, false], + "post_proc":["/", 10] + }, + "tempc2":{ + "condition":["manufacturerdata", 26, "!", "ff"], + "decoder":["value_from_hex_data", "manufacturerdata", 24, 4, true, false], + "post_proc":["/", 10] + }, + "mac":{ + "decoder":["revmac_from_hex_data", "manufacturerdata", 8] + } + } +})"""";*/ + +const char* _IBT_2X_json_props = "{\"properties\":{\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"tempc2\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"mac\":{\"unit\":\"string\",\"name\":\"MAC address\"}}}"; +/*R""""( +{ + "properties":{ + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "tempc2":{ + "unit":"°C", + "name":"temperature" + }, + "mac":{ + "unit":"string", + "name":"MAC address" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/IBT_4XS_json.h b/lib/decoder/src/devices/IBT_4XS_json.h new file mode 100644 index 00000000..3305ce71 --- /dev/null +++ b/lib/decoder/src/devices/IBT_4XS_json.h @@ -0,0 +1,62 @@ +const char* _IBT_4XS_json = "{\"brand\":\"Inkbird\",\"model\":\"iBBQ\",\"model_id\":\"IBT-4X(S/C)\",\"tag\":\"0301\",\"condition\":[\"manufacturerdata\",\"=\",36,\"index\",0,\"00000000\",\"&\",\"manufacturerdata\",\"mac@index\",8],\"conditionnomac\":[\"name\",\"index\",0,\"iBBQ\",\"&\",\"manufacturerdata\",\"=\",36,\"index\",0,\"00000000\"],\"properties\":{\"tempc\":{\"condition\":[\"manufacturerdata\",22,\"!\",\"ff\"],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",20,4,true,false],\"post_proc\":[\"/\",10]},\"tempc2\":{\"condition\":[\"manufacturerdata\",26,\"!\",\"ff\"],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",24,4,true,false],\"post_proc\":[\"/\",10]},\"tempc3\":{\"condition\":[\"manufacturerdata\",30,\"!\",\"ff\"],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",28,4,true,false],\"post_proc\":[\"/\",10]},\"tempc4\":{\"condition\":[\"manufacturerdata\",34,\"!\",\"ff\"],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",32,4,true,false],\"post_proc\":[\"/\",10]},\"mac\":{\"decoder\":[\"mac_from_hex_data\",\"manufacturerdata\",8]}}}"; +/*R""""( +{ + "brand":"Inkbird", + "model":"iBBQ", + "model_id":"IBT-4X(S/C)", + "tag":"0301", + "condition":["manufacturerdata", "=" ,36 ,"index", 0, "00000000", "&", "manufacturerdata", "mac@index", 8], + "conditionnomac":["name", "index", 0, "iBBQ","&","manufacturerdata", "=" ,36 ,"index", 0, "00000000"], + "properties":{ + "tempc":{ + "condition":["manufacturerdata", 22, "!", "ff"], + "decoder":["value_from_hex_data", "manufacturerdata", 20, 4, true, false], + "post_proc":["/", 10] + }, + "tempc2":{ + "condition":["manufacturerdata", 26, "!", "ff"], + "decoder":["value_from_hex_data", "manufacturerdata", 24, 4, true, false], + "post_proc":["/", 10] + }, + "tempc3":{ + "condition":["manufacturerdata", 30, "!", "ff"], + "decoder":["value_from_hex_data", "manufacturerdata", 28, 4, true, false], + "post_proc":["/", 10] + }, + "tempc4":{ + "condition":["manufacturerdata", 34, "!", "ff"], + "decoder":["value_from_hex_data", "manufacturerdata", 32, 4, true, false], + "post_proc":["/", 10] + }, + "mac":{ + "decoder":["mac_from_hex_data", "manufacturerdata", 8] + } + } +})"""";*/ + +const char* _IBT_4XS_json_props = "{\"properties\":{\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"tempc2\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"tempc3\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"tempc4\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"mac\":{\"unit\":\"string\",\"name\":\"MAC address\"}}}"; +/*R""""( +{ + "properties":{ + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "tempc2":{ + "unit":"°C", + "name":"temperature" + }, + "tempc3":{ + "unit":"°C", + "name":"temperature" + }, + "tempc4":{ + "unit":"°C", + "name":"temperature" + }, + "mac":{ + "unit":"string", + "name":"MAC address" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/IBT_6XS_SOLIS6_json.h b/lib/decoder/src/devices/IBT_6XS_SOLIS6_json.h new file mode 100644 index 00000000..b84efc07 --- /dev/null +++ b/lib/decoder/src/devices/IBT_6XS_SOLIS6_json.h @@ -0,0 +1,80 @@ +const char* _IBT_6XS_SOLIS6_json = "{\"brand\":\"Inkbird/Tenergy\",\"model\":\"iBBQ/SOLIS6\",\"model_id\":\"IBT-6XS/SOLIS-6\",\"tag\":\"0301\",\"condition\":[\"manufacturerdata\",\"=\",44,\"index\",0,\"00000000\",\"&\",\"manufacturerdata\",\"mac@index\",8],\"conditionnomac\":[\"name\",\"index\",0,\"iBBQ\",\"&\",\"manufacturerdata\",\"=\",44,\"index\",0,\"00000000\"],\"properties\":{\"tempc\":{\"condition\":[\"manufacturerdata\",22,\"!\",\"ff\"],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",20,4,true,false],\"post_proc\":[\"/\",10]},\"tempc2\":{\"condition\":[\"manufacturerdata\",26,\"!\",\"ff\"],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",24,4,true,false],\"post_proc\":[\"/\",10]},\"tempc3\":{\"condition\":[\"manufacturerdata\",30,\"!\",\"ff\"],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",28,4,true,false],\"post_proc\":[\"/\",10]},\"tempc4\":{\"condition\":[\"manufacturerdata\",34,\"!\",\"ff\"],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",32,4,true,false],\"post_proc\":[\"/\",10]},\"tempc5\":{\"condition\":[\"manufacturerdata\",38,\"!\",\"ff\"],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",36,4,true,false],\"post_proc\":[\"/\",10]},\"tempc6\":{\"condition\":[\"manufacturerdata\",42,\"!\",\"ff\"],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",40,4,true,false],\"post_proc\":[\"/\",10]},\"mac\":{\"decoder\":[\"mac_from_hex_data\",\"manufacturerdata\",8]}}}"; +/*R""""( +{ + "brand":"Inkbird/Tenergy", + "model":"iBBQ/SOLIS6", + "model_id":"IBT-6XS/SOLIS-6", + "tag":"0301", + "condition":["manufacturerdata", "=", 44, "index", 0, "00000000", "&", "manufacturerdata", "mac@index", 8], + "conditionnomac":["name", "index", 0, "iBBQ", "&", "manufacturerdata", "=", 44, "index", 0, "00000000"], + "properties":{ + "tempc":{ + "condition":["manufacturerdata", 22, "!", "ff"], + "decoder":["value_from_hex_data", "manufacturerdata", 20, 4, true, false], + "post_proc":["/", 10] + }, + "tempc2":{ + "condition":["manufacturerdata", 26, "!", "ff"], + "decoder":["value_from_hex_data", "manufacturerdata", 24, 4, true, false], + "post_proc":["/", 10] + }, + "tempc3":{ + "condition":["manufacturerdata", 30, "!", "ff"], + "decoder":["value_from_hex_data", "manufacturerdata", 28, 4, true, false], + "post_proc":["/", 10] + }, + "tempc4":{ + "condition":["manufacturerdata", 34, "!", "ff"], + "decoder":["value_from_hex_data", "manufacturerdata", 32, 4, true, false], + "post_proc":["/", 10] + }, + "tempc5":{ + "condition":["manufacturerdata", 38, "!", "ff"], + "decoder":["value_from_hex_data", "manufacturerdata", 36, 4, true, false], + "post_proc":["/", 10] + }, + "tempc6":{ + "condition":["manufacturerdata", 42, "!", "ff"], + "decoder":["value_from_hex_data", "manufacturerdata", 40, 4, true, false], + "post_proc":["/", 10] + }, + "mac":{ + "decoder":["mac_from_hex_data", "manufacturerdata", 8] + } + } +})"""";*/ + +const char* _IBT_6XS_SOLIS6_json_props = "{\"properties\":{\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"tempc2\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"tempc3\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"tempc4\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"tempc5\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"tempc6\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"mac\":{\"unit\":\"string\",\"name\":\"MAC address\"}}}"; +/*R""""( +{ + "properties":{ + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "tempc2":{ + "unit":"°C", + "name":"temperature" + }, + "tempc3":{ + "unit":"°C", + "name":"temperature" + }, + "tempc4":{ + "unit":"°C", + "name":"temperature" + }, + "tempc5":{ + "unit":"°C", + "name":"temperature" + }, + "tempc6":{ + "unit":"°C", + "name":"temperature" + }, + "mac":{ + "unit":"string", + "name":"MAC address" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/JHT_F525_json.h b/lib/decoder/src/devices/JHT_F525_json.h new file mode 100644 index 00000000..5122d67b --- /dev/null +++ b/lib/decoder/src/devices/JHT_F525_json.h @@ -0,0 +1,26 @@ +#include "common_props.h" + +const char* _JHT_F525_json = "{\"brand\":\"Jaalee\",\"model\":\"TH sensor\",\"model_id\":\"F525\",\"tag\":\"0102\",\"condition\":[\"manufacturerdata\",\"=\",52,\"&\",\"uuid\",\"contain\",\"f525\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",40,4,false],\"post_proc\":[\"*\",175.72,\"/\",65536,\"-\",46.85]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",44,4,false,false],\"post_proc\":[\"*\",125.0,\"/\",65536,\"-\",6]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",50,2,false,false]}}}"; +/* R""""( +{ + "brand":"Jaalee", + "model":"TH sensor", + "model_id":"F525", + "tag":"0102", + "condition":["manufacturerdata", "=", 52, "&", "uuid", "contain", "f525"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "manufacturerdata", 40, 4, false], + "post_proc":["*", 175.72, "/", 65536, "-", 46.85] + }, + "hum":{ + "decoder":["value_from_hex_data", "manufacturerdata", 44, 4, false, false], + "post_proc":["*", 125.0, "/", 65536, "-", 6] + }, + "batt":{ + "decoder":["value_from_hex_data", "manufacturerdata", 50, 2, false, false] + } + } +})"""";*/ + +const char* _JHT_F525_json_props = _common_BTH_props; diff --git a/lib/decoder/src/devices/JQJCY01YM_json.h b/lib/decoder/src/devices/JQJCY01YM_json.h new file mode 100644 index 00000000..7bd2f9d0 --- /dev/null +++ b/lib/decoder/src/devices/JQJCY01YM_json.h @@ -0,0 +1,60 @@ +const char* _JQJCY01YM_json = "{\"brand\":\"Xiaomi\",\"model\":\"Formaldehyde detector\",\"model_id\":\"JQJCY01YM\",\"tag\":\"0f\",\"condition\":[\"servicedata\",\"index\",2,\"20df02\"],\"properties\":{\"for\":{\"condition\":[\"servicedata\",23,\"0\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",28,4,true],\"post_proc\":[\"/\",100]},\"hum\":{\"condition\":[\"servicedata\",23,\"6\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",28,4,true,false],\"post_proc\":[\"/\",10]},\"tempc\":{\"condition\":[\"servicedata\",23,\"4\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",28,4,true,false],\"post_proc\":[\"/\",10]},\"batt\":{\"condition\":[\"servicedata\",23,\"a\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",28,2,false,false]},\"mac\":{\"decoder\":[\"revmac_from_hex_data\",\"servicedata\",10]}}}"; +/*R""""( +{ + "brand":"Xiaomi", + "model":"Formaldehyde detector", + "model_id":"JQJCY01YM", + "tag":"0f", + "condition":["servicedata", "index", 2, "20df02"], + "properties":{ + "for":{ + "condition":["servicedata", 23, "0"], + "decoder":["value_from_hex_data", "servicedata", 28, 4, true], + "post_proc":["/", 100] + }, + "hum":{ + "condition":["servicedata", 23, "6"], + "decoder":["value_from_hex_data", "servicedata", 28, 4, true, false], + "post_proc":["/", 10] + }, + "tempc":{ + "condition":["servicedata", 23, "4"], + "decoder":["value_from_hex_data", "servicedata", 28, 4, true, false], + "post_proc":["/", 10] + }, + "batt":{ + "condition":["servicedata", 23, "a"], + "decoder":["value_from_hex_data", "servicedata", 28, 2, false, false] + }, + "mac":{ + "decoder":["revmac_from_hex_data", "servicedata", 10] + } + } +})"""";*/ + +const char* _JQJCY01YM_json_props = "{\"properties\":{\"batt\":{\"unit\":\"%\",\"name\":\"battery\"},\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"},\"for\":{\"unit\":\"mg/m³\",\"name\":\"formaldehyde\"},\"mac\":{\"unit\":\"string\",\"name\":\"MAC address\"}}}"; +/*R""""( +{ + "properties":{ + "batt":{ + "unit":"%", + "name":"battery" + }, + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "hum":{ + "unit":"%", + "name":"humidity" + }, + "for":{ + "unit":"mg/m³", + "name":"formaldehyde" + }, + "mac":{ + "unit":"string", + "name":"MAC address" + } + } +})"""";*/ \ No newline at end of file diff --git a/lib/decoder/src/devices/KKM_K6P_json.h b/lib/decoder/src/devices/KKM_K6P_json.h new file mode 100644 index 00000000..ec4bba1a --- /dev/null +++ b/lib/decoder/src/devices/KKM_K6P_json.h @@ -0,0 +1,50 @@ +const char* _KKM_K6P_json = "{\"brand\":\"KKM\",\"model\":\"Long Range K6P\",\"model_id\":\"K6P\",\"tag\":\"01\",\"condition\":[\"servicedata\",\"=\",18,\"index\",0,\"210107\",\"&\",\"uuid\",\"index\",0,\"feaa\"],\"properties\":{\".cal\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",12,2,false,false],\"post_proc\":[\"/\",256,\"*\",100,\">\",0,\"/\",100]},\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",10,2,false,true],\"post_proc\":[\"+\",\".cal\"]},\"_.cal\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",16,2,false,false],\"post_proc\":[\"/\",256,\"*\",100,\">\",0,\"/\",100]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",14,2,false,false],\"post_proc\":[\"+\",\".cal\"]},\"volt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",6,4,false,false],\"post_proc\":[\"/\",1000]}}}"; +/*R""""( +{ + "brand":"KKM", + "model":"Long Range K6P", + "model_id":"K6P", + "tag":"01", + "condition":["servicedata", "=", 18, "index", 0, "210107", "&", "uuid", "index", 0, "feaa"], + "properties":{ + ".cal":{ + "decoder":["value_from_hex_data", "servicedata", 12, 2, false, false], + "post_proc":["/", 256, "*", 100, ">", 0, "/", 100] + }, + "tempc":{ + "decoder":["value_from_hex_data", "servicedata", 10, 2, false, true], + "post_proc":["+", ".cal"] + }, + "_.cal":{ + "decoder":["value_from_hex_data", "servicedata", 16, 2, false, false], + "post_proc":["/", 256, "*", 100, ">", 0, "/", 100] + }, + "hum":{ + "decoder":["value_from_hex_data", "servicedata", 14, 2, false, false], + "post_proc":["+", ".cal"] + }, + "volt":{ + "decoder":["value_from_hex_data", "servicedata", 6, 4, false, false], + "post_proc":["/", 1000] + } + } +})"""";*/ + +const char* _KKM_K6P_json_props = "{\"properties\":{\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"},\"volt\":{\"unit\":\"V\",\"name\":\"voltage\"}}}"; +/*R""""( +{ + "properties":{ + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "hum":{ + "unit":"%", + "name":"humidity" + }, + "volt":{ + "unit":"V", + "name":"voltage" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/KKM_K9_json.h b/lib/decoder/src/devices/KKM_K9_json.h new file mode 100644 index 00000000..cbd3762e --- /dev/null +++ b/lib/decoder/src/devices/KKM_K9_json.h @@ -0,0 +1,74 @@ +const char* _KKM_K9_json = "{\"brand\":\"KKM\",\"model\":\"Tracking K9\",\"model_id\":\"K9\",\"tag\":\"0708\",\"condition\":[\"servicedata\",\"=\",30,\"index\",0,\"21010f\",\"&\",\"uuid\",\"index\",0,\"feaa\"],\"properties\":{\".cal\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",12,2,false,false],\"post_proc\":[\"/\",256,\"*\",100,\">\",0,\"/\",100]},\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",10,2,false,true],\"post_proc\":[\"+\",\".cal\"]},\"_.cal\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",16,2,false,false],\"post_proc\":[\"/\",256,\"*\",100,\">\",0,\"/\",100]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",14,2,false,false],\"post_proc\":[\"+\",\".cal\"]},\"volt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",6,4,false,false],\"post_proc\":[\"/\",1000]},\"accx\":{\"condition\":[\"servicedata\",0,\"21010f\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",18,4,false,true]},\"accy\":{\"condition\":[\"servicedata\",0,\"21010f\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",22,4,false,true]},\"accz\":{\"condition\":[\"servicedata\",0,\"21010f\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",26,4,false,true]}}}"; +/*R""""( +{ + "brand":"KKM", + "model":"Tracking K9", + "model_id":"K9", + "tag":"0708", + "condition":["servicedata", "=", 30, "index", 0, "21010f", "&", "uuid", "index", 0, "feaa"], + "properties":{ + ".cal":{ + "decoder":["value_from_hex_data", "servicedata", 12, 2, false, false], + "post_proc":["/", 256, "*", 100, ">", 0, "/", 100] + }, + "tempc":{ + "decoder":["value_from_hex_data", "servicedata", 10, 2, false, true], + "post_proc":["+", ".cal"] + }, + "_.cal":{ + "decoder":["value_from_hex_data", "servicedata", 16, 2, false, false], + "post_proc":["/", 256, "*", 100, ">", 0, "/", 100] + }, + "hum":{ + "decoder":["value_from_hex_data", "servicedata", 14, 2, false, false], + "post_proc":["+", ".cal"] + }, + "volt":{ + "decoder":["value_from_hex_data", "servicedata", 6, 4, false, false], + "post_proc":["/", 1000] + }, + "accx":{ + "condition":["servicedata", 0, "21010f"], + "decoder":["value_from_hex_data", "servicedata", 18, 4, false, true] + }, + "accy":{ + "condition":["servicedata", 0, "21010f"], + "decoder":["value_from_hex_data", "servicedata", 22, 4, false, true] + }, + "accz":{ + "condition":["servicedata", 0, "21010f"], + "decoder":["value_from_hex_data", "servicedata", 26, 4, false, true] + } + } +})"""";*/ + +const char* _KKM_K9_json_props = "{\"properties\":{\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"},\"volt\":{\"unit\":\"V\",\"name\":\"voltage\"},\"accx\":{\"unit\":\"m/s²\",\"name\":\"acceleration x\"},\"accy\":{\"unit\":\"m/s²\",\"name\":\"acceleration y\"},\"accz\":{\"unit\":\"m/s²\",\"name\":\"acceleration z\"}}}"; +/*R""""( +{ + "properties":{ + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "hum":{ + "unit":"%", + "name":"humidity" + }, + "volt":{ + "unit":"V", + "name":"voltage" + }, + "accx":{ + "unit":"m/s²", + "name":"acceleration x" + }, + "accy":{ + "unit":"m/s²", + "name":"acceleration y" + }, + "accz":{ + "unit":"m/s²", + "name":"acceleration z" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/LYWSD02_json.h b/lib/decoder/src/devices/LYWSD02_json.h new file mode 100644 index 00000000..402c5840 --- /dev/null +++ b/lib/decoder/src/devices/LYWSD02_json.h @@ -0,0 +1,32 @@ +#include "common_props.h" + +const char* _LYWSD02_json = "{\"brand\":\"Xiaomi/Mijia\",\"model\":\"e-ink Clock\",\"model_id\":\"LYWSD02\",\"tag\":\"01\",\"condition\":[\"uuid\",\"index\",0,\"fe95\",\"&\",\"servicedata\",\"index\",4,\"5b04\"],\"properties\":{\"tempc\":{\"condition\":[\"servicedata\",24,\"0410\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",30,4,true],\"post_proc\":[\"/\",10]},\"hum\":{\"condition\":[\"servicedata\",24,\"0610\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",30,4,true,false],\"post_proc\":[\"/\",10]},\"batt\":{\"condition\":[\"servicedata\",24,\"0a10\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",30,2,false,false]},\"mac\":{\"decoder\":[\"revmac_from_hex_data\",\"servicedata\",10]}}}"; +/* R""""( +{ + "brand":"Xiaomi/Mijia", + "model":"e-ink Clock", + "model_id":"LYWSD02", + "tag":"01", + "condition":["uuid", "index", 0, "fe95", "&", "servicedata", "index", 4, "5b04"], + "properties":{ + "tempc":{ + "condition":["servicedata", 24, "0410"], + "decoder":["value_from_hex_data", "servicedata", 30, 4, true], + "post_proc":["/", 10] + }, + "hum":{ + "condition":["servicedata", 24, "0610"], + "decoder":["value_from_hex_data", "servicedata", 30, 4, true, false], + "post_proc":["/", 10] + }, + "batt":{ + "condition":["servicedata", 24, "0a10"], + "decoder":["value_from_hex_data", "servicedata", 30, 2, false, false] + }, + "mac":{ + "decoder":["revmac_from_hex_data", "servicedata", 10] + } + } +})"""";*/ + +const char* _LYWSD02_json_props = _common_BTHM_props; diff --git a/lib/decoder/src/devices/LYWSD03MMC_ENCR_json.h b/lib/decoder/src/devices/LYWSD03MMC_ENCR_json.h new file mode 100644 index 00000000..91f2491f --- /dev/null +++ b/lib/decoder/src/devices/LYWSD03MMC_ENCR_json.h @@ -0,0 +1,39 @@ +const char* _LYWSD03MMC_ENCR_json_PVVX = "{\"brand\":\"Xiaomi\",\"model\":\"TH Sensor\",\"model_id\":\"LYWSD03MMC/MJWSD05MMC_PVVX_ENCR\",\"tag\":\"010001\",\"condition\":[\"servicedata\",\"=\",22,\"&\",\"uuid\",\"index\",0,\"181a\"],\"properties\":{\"cipher\":{\"decoder\":[\"string_from_hex_data\",\"servicedata\",2,12]},\"ctr\":{\"decoder\":[\"string_from_hex_data\",\"servicedata\",0,2]},\"mic\":{\"decoder\":[\"string_from_hex_data\",\"servicedata\",14,8]}}}"; +/*R""""( +{ + "brand":"Xiaomi", + "model":"TH Sensor", + "model_id":"LYWSD03MMC/MJWSD05MMC_PVVX_ENCR", + "tag":"010001", + "condition":["servicedata", "=", 22, "&", "uuid", "index", 0, "181a"], + "properties":{ + "cipher":{ + "decoder":["string_from_hex_data", "servicedata", 2, 12] + }, + "ctr":{ + "decoder":["string_from_hex_data", "servicedata", 0, 2] + }, + "mic":{ + "decoder":["string_from_hex_data", "servicedata", 14, 8] + } + } +})"""";*/ + +const char* _LYWSD03MMC_ENCR_json_props = "{\"properties\":{\"cipher\":{\"unit\":\"hex\",\"name\":\"ciphertext\"},\"ctr\":{\"unit\":\"hex\",\"name\":\"counter\"},\"mic\":{\"unit\":\"hex\",\"name\":\"message integrity check\"}}}"; +/*R""""( +{ + "properties":{ + "cipher":{ + "unit":"hex", + "name":"ciphertext" + }, + "ctr":{ + "unit":"hex", + "name":"counter" + }, + "mic":{ + "unit":"hex", + "name":"message integrity check" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/LYWSD03MMC_json.h b/lib/decoder/src/devices/LYWSD03MMC_json.h new file mode 100644 index 00000000..91948ed5 --- /dev/null +++ b/lib/decoder/src/devices/LYWSD03MMC_json.h @@ -0,0 +1,85 @@ +#include "common_props.h" + +const char* _LYWSD03MMC_json_ATC = "{\"brand\":\"Xiaomi\",\"model\":\"TH Sensor\",\"model_id\":\"LYWSD03MMC/MJWSD05MMC_ATC\",\"tag\":\"01\",\"condition\":[\"servicedata\",\"=\",26,\"index\",0,\"a4c138\",\"&\",\"uuid\",\"index\",0,\"181a\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",12,4,false,true],\"post_proc\":[\"/\",10]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",16,2,false,false]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",18,2,false,false]},\"volt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",20,4,false,false],\"post_proc\":[\"/\",1000]},\"mac\":{\"decoder\":[\"mac_from_hex_data\",\"servicedata\",0]}}}"; +/* R""""( +{ + "brand":"Xiaomi", + "model":"TH Sensor", + "model_id":"LYWSD03MMC/MJWSD05MMC_ATC", + "tag":"01", + "condition":["servicedata", "=", 26, "index", 0 , "a4c138", "&", "uuid", "index", 0, "181a"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "servicedata", 12, 4, false, true], + "post_proc":["/", 10] + }, + "hum":{ + "decoder":["value_from_hex_data", "servicedata", 16, 2, false, false] + }, + "batt":{ + "decoder":["value_from_hex_data", "servicedata", 18, 2, false, false] + }, + "volt":{ + "decoder":["value_from_hex_data", "servicedata", 20, 4, false, false], + "post_proc":["/", 1000] + }, + "mac":{ + "decoder":["mac_from_hex_data", "servicedata", 0] + } + } +})"""";*/ + +const char* _LYWSD03MMC_json_PVVX = "{\"brand\":\"Xiaomi\",\"model\":\"TH Sensor\",\"model_id\":\"LYWSD03MMC/MJWSD05MMC_PVVX\",\"tag\":\"01\",\"condition\":[\"servicedata\",\"=\",30,\"index\",6,\"38c1a4\",\"&\",\"uuid\",\"index\",0,\"181a\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",12,4,true,true],\"post_proc\":[\"/\",100]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",16,4,true,false],\"post_proc\":[\"/\",100]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",24,2,false,false]},\"volt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",20,4,true,false],\"post_proc\":[\"/\",1000]},\"mac\":{\"decoder\":[\"revmac_from_hex_data\",\"servicedata\",0]}}}"; +/* R""""( +{ + "brand":"Xiaomi", + "model":"TH Sensor", + "model_id":"LYWSD03MMC/MJWSD05MMC_PVVX", + "tag":"01", + "condition":["servicedata", "=", 30, "index", 6 , "38c1a4", "&", "uuid", "index", 0, "181a"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "servicedata", 12, 4, true, true], + "post_proc":["/", 100] + }, + "hum":{ + "decoder":["value_from_hex_data", "servicedata", 16, 4, true, false], + "post_proc":["/", 100] + }, + "batt":{ + "decoder":["value_from_hex_data", "servicedata", 24, 2, false, false] + }, + "volt":{ + "decoder":["value_from_hex_data", "servicedata", 20, 4, true, false], + "post_proc":["/", 1000] + }, + "mac":{ + "decoder":["revmac_from_hex_data", "servicedata", 0] + } + } +})"""";*/ + +const char* _LYWSD03MMC_json_PVVX_DECR = "{\"brand\":\"Xiaomi\",\"model\":\"TH Sensor\",\"model_id\":\"LYWSD03MMC/MJWSD05MMC_PVVX_DECR\",\"tag\":\"01\",\"condition\":[\"servicedata\",\"=\",12,\"&\",\"uuid\",\"index\",0,\"181a\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",0,4,true,true],\"post_proc\":[\"/\",100]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",4,4,true,false],\"post_proc\":[\"/\",100]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",8,2,false,false]}}}"; +/* R""""( +{ + "brand":"Xiaomi", + "model":"TH Sensor", + "model_id":"LYWSD03MMC/MJWSD05MMC_PVVX_DECR", + "tag":"01", + "condition":["servicedata", "=", 12, "&", "uuid", "index", 0, "181a"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "servicedata", 0, 4, true, true], + "post_proc":["/", 100] + }, + "hum":{ + "decoder":["value_from_hex_data", "servicedata", 4, 4, true, false], + "post_proc":["/", 100] + }, + "batt":{ + "decoder":["value_from_hex_data", "servicedata", 8, 2, false, false] + } + } +})"""";*/ + +const char* _LYWSD03MMC_json_props = _common_BVTH_props; diff --git a/lib/decoder/src/devices/LYWSDCGQ_json.h b/lib/decoder/src/devices/LYWSDCGQ_json.h new file mode 100644 index 00000000..392210c7 --- /dev/null +++ b/lib/decoder/src/devices/LYWSDCGQ_json.h @@ -0,0 +1,37 @@ +#include "common_props.h" + +const char* _LYWSDCGQ_json = "{\"brand\":\"Xiaomi\",\"model\":\"Mi Jia round\",\"model_id\":\"LYWSDCGQ\",\"tag\":\"01\",\"condition\":[\"servicedata\",\"index\",2,\"20aa01\"],\"properties\":{\"batt\":{\"condition\":[\"servicedata\",23,\"a\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",28,2,true,false]},\"tempc\":{\"condition\":[\"servicedata\",23,\"d\",\"|\",\"servicedata\",23,\"4\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",28,4,true],\"post_proc\":[\"/\",10]},\"hum\":{\"condition\":[\"servicedata\",23,\"d\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",32,4,true,false],\"post_proc\":[\"/\",10]},\"_hum\":{\"condition\":[\"servicedata\",23,\"6\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",28,4,true,false],\"post_proc\":[\"/\",10]},\"mac\":{\"decoder\":[\"revmac_from_hex_data\",\"servicedata\",10]}}}"; +/*R""""( +{ + "brand":"Xiaomi", + "model":"Mi Jia round", + "model_id":"LYWSDCGQ", + "tag":"01", + "condition":["servicedata", "index", 2, "20aa01"], + "properties":{ + "batt":{ + "condition":["servicedata", 23, "a"], + "decoder":["value_from_hex_data", "servicedata", 28, 2, true, false] + }, + "tempc":{ + "condition":["servicedata", 23, "d", "|", "servicedata", 23, "4"], + "decoder":["value_from_hex_data", "servicedata", 28, 4, true], + "post_proc":["/", 10] + }, + "hum":{ + "condition":["servicedata", 23, "d"], + "decoder":["value_from_hex_data", "servicedata", 32, 4, true, false], + "post_proc":["/", 10] + }, + "_hum":{ + "condition":["servicedata", 23, "6"], + "decoder":["value_from_hex_data", "servicedata", 28, 4, true, false], + "post_proc":["/", 10] + }, + "mac":{ + "decoder":["revmac_from_hex_data", "servicedata", 10] + } + } +})"""";*/ + +const char* _LYWSDCGQ_json_props = _common_BTHM_props; diff --git a/lib/decoder/src/devices/MBXPRO_json.h b/lib/decoder/src/devices/MBXPRO_json.h new file mode 100644 index 00000000..d5e92a6b --- /dev/null +++ b/lib/decoder/src/devices/MBXPRO_json.h @@ -0,0 +1,82 @@ +const char* _MBXPRO_json = "{\"brand\":\"Mokosmart\",\"model\":\"BeaconX Pro\",\"model_id\":\"MBXPRO\",\"tag\":\"0708\",\"condition\":[\"uuid\",\"index\",0,\"feab\"],\"properties\":{\"volt\":{\"condition\":[\"servicedata\",0,\"40\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",6,4,false],\"post_proc\":[\"/\",1000]},\"x_axis\":{\"condition\":[\"servicedata\",0,\"60\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",12,4,false],\"post_proc\":[\"/\",10000,\"*\",9.80665]},\"y_axis\":{\"condition\":[\"servicedata\",0,\"60\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",16,4,false],\"post_proc\":[\"/\",10000,\"*\",9.80665]},\"z_axis\":{\"condition\":[\"servicedata\",0,\"60\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",20,4,false],\"post_proc\":[\"/\",10000,\"*\",9.80665]},\"_volt\":{\"condition\":[\"servicedata\",0,\"60\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",24,4,false],\"post_proc\":[\"/\",1000]},\"tempc\":{\"condition\":[\"servicedata\",0,\"70\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",6,4,false],\"post_proc\":[\"/\",10]},\"hum\":{\"condition\":[\"servicedata\",0,\"70\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",10,4,false,false],\"post_proc\":[\"/\",10]},\"__volt\":{\"condition\":[\"servicedata\",0,\"70\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",14,4,false],\"post_proc\":[\"/\",1000]}}}"; +/*R""""( +{ + "brand":"Mokosmart", + "model":"BeaconX Pro", + "model_id":"MBXPRO", + "tag":"0708", + "condition":["uuid", "index", 0, "feab"], + "properties":{ + "volt":{ + "condition":["servicedata", 0, "40"], + "decoder":["value_from_hex_data", "servicedata", 6, 4, false], + "post_proc":["/", 1000] + }, + "x_axis":{ + "condition":["servicedata", 0, "60"], + "decoder":["value_from_hex_data", "servicedata", 12, 4, false], + "post_proc":["/", 10000, "*", 9.80665] + }, + "y_axis":{ + "condition":["servicedata", 0, "60"], + "decoder":["value_from_hex_data", "servicedata", 16, 4, false], + "post_proc":["/", 10000, "*", 9.80665] + }, + "z_axis":{ + "condition":["servicedata", 0, "60"], + "decoder":["value_from_hex_data", "servicedata", 20, 4, false], + "post_proc":["/", 10000, "*", 9.80665] + }, + "_volt":{ + "condition":["servicedata", 0, "60"], + "decoder":["value_from_hex_data", "servicedata", 24, 4, false], + "post_proc":["/", 1000] + }, + "tempc":{ + "condition":["servicedata", 0, "70"], + "decoder":["value_from_hex_data", "servicedata", 6, 4, false], + "post_proc":["/", 10] + }, + "hum":{ + "condition":["servicedata", 0, "70"], + "decoder":["value_from_hex_data", "servicedata", 10, 4, false, false], + "post_proc":["/", 10] + }, + "__volt":{ + "condition":["servicedata", 0, "70"], + "decoder":["value_from_hex_data", "servicedata", 14, 4, false], + "post_proc":["/", 1000] + } + } +})"""";*/ + +const char* _MBXPRO_json_props = "{\"properties\":{\"volt\":{\"unit\":\"V\",\"name\":\"voltage\"},\"x_axis\":{\"unit\":\"m/s²\",\"name\":\"x_axis\"},\"y_axis\":{\"unit\":\"m/s²\",\"name\":\"y_axis\"},\"z_axis\":{\"unit\":\"m/s²\",\"name\":\"z_axis\"},\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"}}}"; +/*R""""( +{ + "properties":{ + "volt":{ + "unit":"V", + "name":"voltage" + }, + "x_axis":{ + "unit":"m/s²", + "name":"x_axis" + }, + "y_axis":{ + "unit":"m/s²", + "name":"y_axis" + }, + "z_axis":{ + "unit":"m/s²", + "name":"z_axis" + }, + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "hum":{ + "unit":"%", + "name":"humidity" + } + } +})"""";*/ \ No newline at end of file diff --git a/lib/decoder/src/devices/MS_CDP_json.h b/lib/decoder/src/devices/MS_CDP_json.h new file mode 100644 index 00000000..c1fc2586 --- /dev/null +++ b/lib/decoder/src/devices/MS_CDP_json.h @@ -0,0 +1,25 @@ +const char* _MS_CDP_json = "{\"brand\":\"GENERIC\",\"model\":\"MS-CDP\",\"model_id\":\"MS-CDP\",\"tag\":\"fe\",\"condition\":[\"manufacturerdata\",\"index\",0,\"060001\"],\"properties\":{\"device\":{\"decoder\":[\"static_value\",\"Microsoft advertising beacon\"]}}}"; +/*R""""( +{ + "brand":"GENERIC", + "model":"MS-CDP", + "model_id":"MS-CDP", + "tag":"fe", + "condition":["manufacturerdata", "index", 0, "060001"], + "properties":{ + "device":{ + "decoder":["static_value", "Microsoft advertising beacon"] + } + } +})"""";*/ + +const char* _MS_CDP_json_props = "{\"properties\":{\"device\":{\"unit\":\"string\",\"name\":\"device type\"}}}"; +/*R""""( +{ + "properties":{ + "device":{ + "unit":"string", + "name":"device type" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/MUE4094RT_json.h b/lib/decoder/src/devices/MUE4094RT_json.h new file mode 100644 index 00000000..fd5252b3 --- /dev/null +++ b/lib/decoder/src/devices/MUE4094RT_json.h @@ -0,0 +1,34 @@ +const char* _MUE4094RT_json = "{\"brand\":\"Xiaomi\",\"model\":\"MiLamp\",\"model_id\":\"MUE4094RT\",\"tag\":\"0404\",\"condition\":[\"servicedata\",\"index\",0,\"4030dd\"],\"properties\":{\"motion\":{\"decoder\":[\"static_value\",true],\"is_bool\":1},\"darkness\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",8,2,true]}}}"; +/* +R""""( +{ + "brand":"Xiaomi", + "model":"MiLamp", + "model_id":"MUE4094RT", + "tag":"0404", + "condition":["servicedata", "index", 0, "4030dd"], + "properties":{ + "motion":{ + "decoder":["static_value", true], + "is_bool":1 + }, + "darkness":{ + "decoder":["value_from_hex_data", "servicedata", 8, 2, true] + } + } +})"""";*/ + +const char* _MUE4094RT_json_props = "{\"properties\":{\"motion\":{\"unit\":\"status\",\"name\":\"motion\"},\"darkness\":{\"unit\":\"lx\",\"name\":\"illuminance\"}}}"; +/*R""""( +{ + "properties":{ + "motion":{ + "unit":"status", + "name":"motion" + }, + "darkness":{ + "unit":"lx", + "name":"illuminance" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/Miband_json.h b/lib/decoder/src/devices/Miband_json.h new file mode 100644 index 00000000..59f26d54 --- /dev/null +++ b/lib/decoder/src/devices/Miband_json.h @@ -0,0 +1,49 @@ +const char* _Miband_json = "{\"brand\":\"Xiaomi/Amazfit\",\"model\":\"Mi Band/Smart Watch\",\"model_id\":\"MB/SW\",\"tag\":\"0b0a\",\"condition\":[\"manufacturerdata\",\"=\",52,\"index\",0,\"5701\",\"&\",\"manufacturerdata\",\"mac@index\",40],\"conditionnomac\":[\"uuid\",\"contain\",\"fee0\"],\"properties\":{\"steps\":{\"condition\":[\"servicedata\",\"=\",8],\"decoder\":[\"value_from_hex_data\",\"servicedata\",0,4,true,false]},\"act_bpm\":{\"condition\":[\"manufacturerdata\",0,\"570102\",\"&\",\"manufacturerdata\",10,\"!\",\"f\"],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",10,2,false,false]},\"device\":{\"decoder\":[\"static_value\",\"Xiaomi/Amazfit Tracker\"]},\"mac\":{\"decoder\":[\"mac_from_hex_data\",\"manufacturerdata\",40]}}}"; +/*R""""( +{ + "brand":"Xiaomi/Amazfit", + "model":"Mi Band/Smart Watch", + "model_id":"MB/SW", + "tag":"0b0a", + "condition":["manufacturerdata", "=", 52, "index", 0, "5701", "&", "manufacturerdata", "mac@index", 40], + "conditionnomac":["uuid", "contain", "fee0"], + "properties":{ + "steps":{ + "condition":["servicedata", "=", 8], + "decoder":["value_from_hex_data", "servicedata", 0, 4, true, false] + }, + "act_bpm":{ + "condition":["manufacturerdata", 0, "570102", "&", "manufacturerdata", 10, "!", "f"], + "decoder":["value_from_hex_data", "manufacturerdata", 10, 2, false, false] + }, + "device":{ + "decoder":["static_value", "Xiaomi/Amazfit Tracker"] + }, + "mac":{ + "decoder":["mac_from_hex_data", "manufacturerdata", 40] + } + } +})"""";*/ + +const char* _Miband_json_props = "{\"properties\":{\"steps\":{\"unit\":\"int\",\"name\":\"step-count\"},\"act_bpm\":{\"unit\":\"bpm\",\"name\":\"activity heart rate\"},\"device\":{\"unit\":\"string\",\"name\":\"tracker device\"},\"mac\":{\"unit\":\"string\",\"name\":\"MAC address\"}}}"; +/*R""""( +{ + "properties":{ + "steps":{ + "unit":"int", + "name":"step-count" + }, + "act_bpm":{ + "unit":"bpm", + "name":"activity heart rate" + }, + "device":{ + "unit":"string", + "name":"tracker device" + }, + "mac":{ + "unit":"string", + "name":"MAC address" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/Mokobeacon_json.h b/lib/decoder/src/devices/Mokobeacon_json.h new file mode 100644 index 00000000..81d32f9f --- /dev/null +++ b/lib/decoder/src/devices/Mokobeacon_json.h @@ -0,0 +1,49 @@ +const char* _Mokobeacon_json = "{\"brand\":\"Mokosmart\",\"model\":\"Beacon\",\"model_id\":\"Mokobeacon\",\"tag\":\"0708\",\"condition\":[\"uuid\",\"index\",0,\"ff01\"],\"properties\":{\"batt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",0,2,false]},\"x_axis\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",14,4,false],\"post_proc\":[\"/\",10000,\"*\",9.80665]},\"y_axis\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",18,4,false],\"post_proc\":[\"/\",10000,\"*\",9.80665]},\"z_axis\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",22,4,false],\"post_proc\":[\"/\",10000,\"*\",9.80665]}}}"; +/*R""""( +{ + "brand":"Mokosmart", + "model":"Beacon", + "model_id":"Mokobeacon", + "tag":"0708", + "condition":["uuid", "index", 0, "ff01"], + "properties":{ + "batt":{ + "decoder":["value_from_hex_data", "servicedata", 0, 2, false] + }, + "x_axis":{ + "decoder":["value_from_hex_data", "servicedata", 14, 4, false], + "post_proc":["/", 10000, "*", 9.80665] + }, + "y_axis":{ + "decoder":["value_from_hex_data", "servicedata", 18, 4, false], + "post_proc":["/", 10000, "*", 9.80665] + }, + "z_axis":{ + "decoder":["value_from_hex_data", "servicedata", 22, 4, false], + "post_proc":["/", 10000, "*", 9.80665] + } + } +})"""";*/ + +const char* _Mokobeacon_json_props = "{\"properties\":{\"batt\":{\"unit\":\"%\",\"name\":\"battery\"},\"x_axis\":{\"unit\":\"m/s²\",\"name\":\"x_axis\"},\"y_axis\":{\"unit\":\"m/s²\",\"name\":\"y_axis\"},\"z_axis\":{\"unit\":\"m/s²\",\"name\":\"z_axis\"}}}"; +/*R""""( +{ + "properties":{ + "batt":{ + "unit":"%", + "name":"battery" + }, + "x_axis":{ + "unit":"m/s²", + "name":"x_axis" + }, + "y_axis":{ + "unit":"m/s²", + "name":"y_axis" + }, + "z_axis":{ + "unit":"m/s²", + "name":"z_axis" + } + } +})"""";*/ \ No newline at end of file diff --git a/lib/decoder/src/devices/Mopeka_json.h b/lib/decoder/src/devices/Mopeka_json.h new file mode 100644 index 00000000..50b4d5fa --- /dev/null +++ b/lib/decoder/src/devices/Mopeka_json.h @@ -0,0 +1,91 @@ +const char* _Mopeka_json = "{\"brand\":\"Mopeka/Lippert\",\"model\":\"Pro Check (Universal)/BottleCheck Sensor\",\"model_id\":\"M1017\",\"tag\":\"ff01\",\"condition\":[\"manufacturerdata\",\"=\",24,\"index\",0,\"590003\",\"|\",\"manufacturerdata\",\"=\",24,\"index\",0,\"590006\",\"|\",\"manufacturerdata\",\"=\",24,\"index\",0,\"59000c\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",8,2,false,true],\"post_proc\":[\"&\",127,\"-\",40,\"min\",-40]},\".cal\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",8,2,false,true],\"post_proc\":[\"&\",127]},\"_.cal\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",8,2,false,true],\"post_proc\":[\"&\",127,\"*\",\".cal\",\"*\",-0.00000535]},\"__.cal\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",8,2,false,true],\"post_proc\":[\"&\",127,\"*\",-0.002822,\"+\",0.573045,\"+\",\".cal\"]},\"lvl_cm\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",10,4,true,false],\"post_proc\":[\"&\",16383,\"*\",\".cal\",\"/\",10]},\"sync\":{\"decoder\":[\"bit_static_value\",\"manufacturerdata\",8,3,false,true]},\"volt\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",6,2,false,false],\"post_proc\":[\"&\",127,\"/\",32]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",6,2,false,false],\"post_proc\":[\"&\",127,\"/\",32,\"-\",2.2,\"/\",0.65,\"*\",100,\"max\",100,\"min\",0]},\"quality\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",12,2,false,false],\"post_proc\":[\">\",6,\"max\",3,\"min\",0]},\"accx\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",20,2,false,true]},\"accy\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",22,2,false,true]}}}"; +/* R""""( +{ + "brand":"Mopeka/Lippert", + "model":"Pro Check (Universal)/BottleCheck Sensor", + "model_id":"M1017", + "tag":"ff01", + "condition":["manufacturerdata", "=", 24, "index", 0, "590003", "|", "manufacturerdata", "=", 24, "index", 0, "590006", "|", "manufacturerdata", "=", 24, "index", 0, "59000c"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "manufacturerdata", 8, 2, false, true], + "post_proc":["&", 127, "-", 40, "min", -40] + }, + ".cal":{ + "decoder":["value_from_hex_data", "manufacturerdata", 8, 2, false, true], + "post_proc":["&", 127] + }, + "_.cal":{ + "decoder":["value_from_hex_data", "manufacturerdata", 8, 2, false, true], + "post_proc":["&", 127, "*", ".cal", "*", -0.00000535] + }, + "__.cal":{ + "decoder":["value_from_hex_data", "manufacturerdata", 8, 2, false, true], + "post_proc":["&", 127, "*", -0.002822, "+", 0.573045, "+", ".cal"] + }, + "lvl_cm":{ + "decoder":["value_from_hex_data", "manufacturerdata", 10, 4, true, false], + "post_proc":["&", 16383, "*", ".cal", "/", 10] + }, + "sync":{ + "decoder":["bit_static_value", "manufacturerdata", 8, 3, false, true] + }, + "volt":{ + "decoder":["value_from_hex_data", "manufacturerdata", 6, 2, false, false], + "post_proc":["&", 127, "/", 32] + }, + "batt":{ + "decoder":["value_from_hex_data", "manufacturerdata", 6, 2, false, false], + "post_proc":["&", 127, "/", 32, "-", 2.2, "/", 0.65, "*", 100, "max", 100, "min", 0] + }, + "quality":{ + "decoder":["value_from_hex_data", "manufacturerdata", 12, 2, false, false], + "post_proc":[">", 6, "max", 3, "min", 0] + }, + "accx":{ + "decoder":["value_from_hex_data", "manufacturerdata", 20, 2, false, true] + }, + "accy":{ + "decoder":["value_from_hex_data", "manufacturerdata", 22, 2, false, true] + } + } +})"""";*/ + +const char* _Mopeka_json_props = "{\"properties\":{\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"lvl_cm\":{\"unit\":\"cm\",\"name\":\"level in cm\"},\"sync\":{\"unit\":\"status\",\"name\":\"sync pressed\"},\"volt\":{\"unit\":\"V\",\"name\":\"voltage\"},\"batt\":{\"unit\":\"%\",\"name\":\"battery\"},\"quality\":{\"unit\":\"status\",\"name\":\"reading quality\"},\"accx\":{\"unit\":\"m/s²\",\"name\":\"acceleration x\"},\"accy\":{\"unit\":\"m/s²\",\"name\":\"acceleration y\"}}}"; +/*R""""( +{ + "properties":{ + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "lvl_cm":{ + "unit":"cm", + "name":"level in cm" + }, + "sync":{ + "unit":"status", + "name":"sync pressed" + }, + "volt":{ + "unit":"V", + "name":"voltage" + }, + "batt":{ + "unit":"%", + "name":"battery" + }, + "quality":{ + "unit":"status", + "name":"reading quality" + }, + "accx":{ + "unit":"m/s²", + "name":"acceleration x" + }, + "accy":{ + "unit":"m/s²", + "name":"acceleration y" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/OralB_json.h b/lib/decoder/src/devices/OralB_json.h new file mode 100644 index 00000000..a7eda7a4 --- /dev/null +++ b/lib/decoder/src/devices/OralB_json.h @@ -0,0 +1,78 @@ +const char* _OralB_json = "{\"brand\":\"Oral-B\",\"model\":\"BT Toothbrush\",\"model_id\":\"ORALB_BT\",\"tag\":\"0b\",\"condition\":[\"manufacturerdata\",\">=\",22,\"index\",0,\"dc00\"],\"properties\":{\"state\":{\"decoder\":[\"string_from_hex_data\",\"manufacturerdata\",10,2],\"lookup\":[\"01\",\"initialising\",\"02\",\"idle\",\"03\",\"running\",\"04\",\"charging\",\"73\",\"sleeping\"]},\"mode\":{\"decoder\":[\"string_from_hex_data\",\"manufacturerdata\",18,2],\"lookup\":[\"00\",\"off\",\"01\",\"daily clean\",\"02\",\"sensitive\",\"03\",\"massage\",\"04\",\"whitening\",\"05\",\"deep clean\",\"06\",\"tongue cleaning\",\"07\",\"turbo\"]},\"sector\":{\"decoder\":[\"string_from_hex_data\",\"manufacturerdata\",20,2],\"lookup\":[\"01\",\"sector 1\",\"02\",\"sector 2\",\"03\",\"sector 3\",\"04\",\"sector 4\",\"05\",\"sector 5\",\"06\",\"sector 6\",\"07\",\"sector 7\",\"08\",\"sector 8\"]},\"pressure\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",12,2,false,false]},\".cal\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",16,2,false,false]},\"time\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",14,2,false,false],\"post_proc\":[\"*\",60,\"+\",\".cal\"]}}}"; +/*R""""( +{ + "brand":"Oral-B", + "model":"BT Toothbrush", + "model_id":"ORALB_BT", + "tag":"0b", + "condition":["manufacturerdata", ">=", 22, "index", 0, "dc00"], + "properties":{ + "state":{ + "decoder":["string_from_hex_data", "manufacturerdata", 10, 2], + "lookup":["01", "initialising", + "02", "idle", + "03", "running", + "04", "charging", + "73", "sleeping"] + }, + "mode":{ + "decoder":["string_from_hex_data", "manufacturerdata", 18, 2], + "lookup":["00", "off", + "01", "daily clean", + "02", "sensitive", + "03", "massage", + "04", "whitening", + "05", "deep clean", + "06", "tongue cleaning", + "07", "turbo"] + }, + "sector":{ + "decoder":["string_from_hex_data", "manufacturerdata", 20, 2], + "lookup":["01", "sector 1", + "02", "sector 2", + "03", "sector 3", + "04", "sector 4", + "05", "sector 5", + "06", "sector 6", + "07", "sector 7", + "08", "sector 8"] + }, + "pressure":{ + "decoder":["value_from_hex_data", "manufacturerdata", 12, 2, false, false] + }, + ".cal":{ + "decoder":["value_from_hex_data", "manufacturerdata", 16, 2, false, false] + }, + "time":{ + "decoder":["value_from_hex_data", "manufacturerdata", 14, 2, false, false], + "post_proc":["*", 60, "+", ".cal"] + } + } +})"""";*/ + +const char* _OralB_json_props = "{\"properties\":{\"state\":{\"unit\":\"string\",\"name\":\"state\"},\"mode\":{\"unit\":\"string\",\"name\":\"mode\"},\"sector\":{\"unit\":\"string\",\"name\":\"sector\"},\"pressure\":{\"unit\":\"int\",\"name\":\"pressure\"},\"time\":{\"unit\":\"int\",\"name\":\"time\"}}}"; +/*R""""( +{ + "properties":{ + "state":{ + "unit":"string", + "name":"state" + }, + "mode":{ + "unit":"string", + "name":"mode" + }, + "sector":{ + "unit":"string", + "name":"sector" + }, + "pressure":{ + "unit":"int", + "name":"pressure" + }, + "time":{ + "unit":"int", + "name":"time" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/PH10_json.h b/lib/decoder/src/devices/PH10_json.h new file mode 100644 index 00000000..1a9cd196 --- /dev/null +++ b/lib/decoder/src/devices/PH10_json.h @@ -0,0 +1,25 @@ +const char* _PH10_json = "{\"brand\":\"Polar\",\"model\":\"Heart Rate Sensor\",\"model_id\":\"H10\",\"tag\":\"0b00\",\"condition\":[\"manufacturerdata\",\"=\",12,\"index\",0,\"6b00\"],\"properties\":{\"bpm\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",10,2,false,false]}}}"; +/*R""""( +{ + "brand":"Polar", + "model":"Heart Rate Sensor", + "model_id":"H10", + "tag":"0b00", + "condition":["manufacturerdata", "=", 12, "index", 0, "6b00"], + "properties":{ + "bpm":{ + "decoder":["value_from_hex_data", "manufacturerdata", 10, 2, false, false] + } + } +})"""";*/ + +const char* _PH10_json_props = "{\"properties\":{\"bpm\":{\"unit\":\"bpm\",\"name\":\"heart rate\"}}}"; +/*R""""( +{ + "properties":{ + "bpm":{ + "unit":"bpm", + "name":"heart rate" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/RDL52832_json.h b/lib/decoder/src/devices/RDL52832_json.h new file mode 100644 index 00000000..3c7a59f2 --- /dev/null +++ b/lib/decoder/src/devices/RDL52832_json.h @@ -0,0 +1,154 @@ +const char* _RDL52832_json = "{\"brand\":\"Radioland\",\"model\":\"RDL52832\",\"model_id\":\"RDL52832\",\"tag\":\"070a\",\"condition\":[\"manufacturerdata\",\"=\",50,\"&\",\"name\",\"index\",0,\"RDL52832\"],\"properties\":{\"mfid\":{\"decoder\":[\"string_from_hex_data\",\"manufacturerdata\",0,4]},\"uuid\":{\"decoder\":[\"string_from_hex_data\",\"manufacturerdata\",8,32]},\"major\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",40,4,false]},\"minor\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",44,4,false]},\"txpower\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",48,2,false]},\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",0,4,false,true],\"post_proc\":[\"/\",256]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",4,4,false,true],\"post_proc\":[\"/\",256]},\".cal\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",12,2,false,false],\"post_proc\":[\"/\",10]},\"accx\":{\"condition\":[\"servicedata\",8,\"0000\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",14,2,false,false],\"post_proc\":[\"/\",100,\"+\",\".cal\",\"*\",9.80665]},\"_accx\":{\"condition\":[\"servicedata\",8,\"0001\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",14,2,false,false],\"post_proc\":[\"/\",100,\"+\",\".cal\",\"+\",1,\"*\",9.80665]},\"__accx\":{\"condition\":[\"servicedata\",8,\"0100\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",14,2,false,false],\"post_proc\":[\"/\",100,\"+\",\".cal\",\"*\",-1,\"*\",9.80665]},\"___accx\":{\"condition\":[\"servicedata\",8,\"0101\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",14,2,false,false],\"post_proc\":[\"/\",100,\"+\",\".cal\",\"+\",1,\"*\",-1,\"*\",9.80665]},\"_.cal\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",20,2,false,false],\"post_proc\":[\"/\",10]},\"accy\":{\"condition\":[\"servicedata\",16,\"0000\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",22,2,false,false],\"post_proc\":[\"/\",100,\"+\",\".cal\",\"*\",9.80665]},\"_accy\":{\"condition\":[\"servicedata\",16,\"0001\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",22,2,false,false],\"post_proc\":[\"/\",100,\"+\",\".cal\",\"+\",1,\"*\",9.80665]},\"__accy\":{\"condition\":[\"servicedata\",16,\"0100\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",22,2,false,false],\"post_proc\":[\"/\",100,\"+\",\".cal\",\"*\",-1,\"*\",9.80665]},\"___accy\":{\"condition\":[\"servicedata\",16,\"0101\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",22,2,false,false],\"post_proc\":[\"/\",100,\"+\",\".cal\",\"+\",1,\"*\",-1,\"*\",9.80665]},\"__.cal\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",28,2,false,false],\"post_proc\":[\"/\",10]},\"accz\":{\"condition\":[\"servicedata\",24,\"0000\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",30,2,false,false],\"post_proc\":[\"/\",100,\"+\",\".cal\",\"*\",9.80665]},\"_accz\":{\"condition\":[\"servicedata\",24,\"0001\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",30,2,false,false],\"post_proc\":[\"/\",100,\"+\",\".cal\",\"+\",1,\"*\",9.80665]},\"__accz\":{\"condition\":[\"servicedata\",24,\"0100\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",30,2,false,false],\"post_proc\":[\"/\",100,\"+\",\".cal\",\"*\",-1,\"*\",9.80665]},\"___accz\":{\"condition\":[\"servicedata\",24,\"0101\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",30,2,false,false],\"post_proc\":[\"/\",100,\"+\",\".cal\",\"+\",1,\"*\",-1,\"*\",9.80665]}}}"; + +/*R""""( +{ + "brand":"Radioland", + "model":"RDL52832", + "model_id":"RDL52832", + "tag":"070a", + "condition":["manufacturerdata", "=", 50, "&", "name", "index", 0, "RDL52832"], + "properties":{ + "mfid":{ + "decoder":["string_from_hex_data", "manufacturerdata", 0, 4] + }, + "uuid":{ + "decoder":["string_from_hex_data", "manufacturerdata", 8, 32] + }, + "major":{ + "decoder":["value_from_hex_data", "manufacturerdata", 40, 4, false] + }, + "minor":{ + "decoder":["value_from_hex_data", "manufacturerdata", 44, 4, false] + }, + "txpower":{ + "decoder":["value_from_hex_data","manufacturerdata", 48, 2, false] + }, + "tempc":{ + "decoder":["value_from_hex_data", "servicedata", 0, 4, false, true], + "post_proc":["/", 256] + }, + "hum":{ + "decoder":["value_from_hex_data", "servicedata", 4, 4, false, true], + "post_proc":["/", 256] + }, + ".cal":{ + "decoder":["value_from_hex_data", "servicedata", 12, 2, false, false], + "post_proc":["/", 10] + }, + "accx":{ + "condition":["servicedata", 8, "0000"], + "decoder":["value_from_hex_data", "servicedata", 14, 2, false, false], + "post_proc":["/", 100, "+", ".cal", "*", 9.80665] + }, + "_accx":{ + "condition":["servicedata", 8, "0001"], + "decoder":["value_from_hex_data", "servicedata", 14, 2, false, false], + "post_proc":["/", 100, "+", ".cal", "+", 1, "*", 9.80665] + }, + "__accx":{ + "condition":["servicedata", 8, "0100"], + "decoder":["value_from_hex_data", "servicedata", 14, 2, false, false], + "post_proc":["/", 100, "+", ".cal", "*", -1, "*", 9.80665] + }, + "___accx":{ + "condition":["servicedata", 8, "0101"], + "decoder":["value_from_hex_data", "servicedata", 14, 2, false, false], + "post_proc":["/", 100, "+", ".cal", "+", 1, "*", -1, "*", 9.80665] + }, + "_.cal":{ + "decoder":["value_from_hex_data", "servicedata", 20, 2, false, false], + "post_proc":["/", 10] + }, + "accy":{ + "condition":["servicedata", 16, "0000"], + "decoder":["value_from_hex_data", "servicedata", 22, 2, false, false], + "post_proc":["/", 100, "+", ".cal", "*", 9.80665] + }, + "_accy":{ + "condition":["servicedata", 16, "0001"], + "decoder":["value_from_hex_data", "servicedata", 22, 2, false, false], + "post_proc":["/", 100, "+", ".cal", "+", 1, "*", 9.80665] + }, + "__accy":{ + "condition":["servicedata", 16, "0100"], + "decoder":["value_from_hex_data", "servicedata", 22, 2, false, false], + "post_proc":["/", 100, "+", ".cal", "*", -1, "*", 9.80665] + }, + "___accy":{ + "condition":["servicedata", 16, "0101"], + "decoder":["value_from_hex_data", "servicedata", 22, 2, false, false], + "post_proc":["/", 100, "+", ".cal", "+", 1, "*", -1, "*", 9.80665] + }, + "__.cal":{ + "decoder":["value_from_hex_data", "servicedata", 28, 2, false, false], + "post_proc":["/", 10] + }, + "accz":{ + "condition":["servicedata", 24, "0000"], + "decoder":["value_from_hex_data", "servicedata", 30, 2, false, false], + "post_proc":["/", 100, "+", ".cal", "*", 9.80665] + }, + "_accz":{ + "condition":["servicedata", 24, "0001"], + "decoder":["value_from_hex_data", "servicedata", 30, 2, false, false], + "post_proc":["/", 100, "+", ".cal", "+", 1, "*", 9.80665] + }, + "__accz":{ + "condition":["servicedata", 24, "0100"], + "decoder":["value_from_hex_data", "servicedata", 30, 2, false, false], + "post_proc":["/", 100, "+", ".cal", "*", -1, "*", 9.80665] + }, + "___accz":{ + "condition":["servicedata", 24, "0101"], + "decoder":["value_from_hex_data", "servicedata", 30, 2, false, false], + "post_proc":["/", 100, "+", ".cal", "+", 1, "*", -1, "*", 9.80665] + } + } +})"""";*/ + +const char* _RDL52832_json_props = "{\"properties\":{\"mfid\":{\"unit\":\"hex\",\"name\":\"manufacturer id\"},\"uuid\":{\"unit\":\"hex\",\"name\":\"service uuid\"},\"major\":{\"unit\":\"hex\",\"name\":\"major value\"},\"minor\":{\"unit\":\"hex\",\"name\":\"minor value\"},\"txpower\":{\"unit\":\"dBm\",\"name\":\"tx power @ 1 m\"},\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"},\"accx\":{\"unit\":\"m/s²\",\"name\":\"acceleration x\"},\"accy\":{\"unit\":\"m/s²\",\"name\":\"acceleration y\"},\"accz\":{\"unit\":\"m/s²\",\"name\":\"acceleration z\"}}}"; +/*R""""( +{ + "properties":{ + "mfid":{ + "unit":"hex", + "name":"manufacturer id" + }, + "uuid":{ + "unit":"hex", + "name":"service uuid" + }, + "major":{ + "unit":"hex", + "name":"major value" + }, + "minor":{ + "unit":"hex", + "name":"minor value" + }, + "txpower":{ + "unit":"dBm", + "name":"tx power @ 1 m" + }, + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "hum":{ + "unit":"%", + "name":"humidity" + }, + "accx":{ + "unit":"m/s²", + "name":"acceleration x" + }, + "accy":{ + "unit":"m/s²", + "name":"acceleration y" + }, + "accz":{ + "unit":"m/s²", + "name":"acceleration z" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/RuuviTag_RAWv1_json.h b/lib/decoder/src/devices/RuuviTag_RAWv1_json.h new file mode 100644 index 00000000..37c1660d --- /dev/null +++ b/lib/decoder/src/devices/RuuviTag_RAWv1_json.h @@ -0,0 +1,73 @@ +const char* _RuuviTag_RAWv1_json = "{\"brand\":\"Ruuvi\",\"model\":\"RuuviTag\",\"model_id\":\"RuuviTag_RAWv1\",\"tag\":\"0708\",\"condition\":[\"manufacturerdata\",\"=\",32,\"index\",0,\"990403\"],\"properties\":{\"hum\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",6,2,false,false],\"post_proc\":[\"/\",2]},\"tempc\":{\"decoder\":[\"bf_value_from_hex_data\",\"manufacturerdata\",8,4,false,true]},\"pres\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",12,4,false,false],\"post_proc\":[\"+\",50000,\"/\",100]},\"accx\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",16,4,false,true],\"post_proc\":[\"/\",10000,\"*\",9.80665]},\"accy\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",20,4,false,true],\"post_proc\":[\"/\",10000,\"*\",9.80665]},\"accz\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",24,4,false,true],\"post_proc\":[\"/\",10000,\"*\",9.80665]},\"volt\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",28,4,false,false],\"post_proc\":[\"/\",1000]}}}"; +/*R""""( +{ + "brand":"Ruuvi", + "model":"RuuviTag", + "model_id":"RuuviTag_RAWv1", + "tag":"0708", + "condition":["manufacturerdata", "=", 32, "index", 0, "990403"], + "properties":{ + "hum":{ + "decoder":["value_from_hex_data", "manufacturerdata", 6, 2, false, false], + "post_proc":["/", 2] + }, + "tempc":{ + "decoder":["bf_value_from_hex_data", "manufacturerdata", 8, 4, false, true] + }, + "pres":{ + "decoder":["value_from_hex_data", "manufacturerdata", 12, 4, false, false], + "post_proc":["+", 50000, "/", 100] + }, + "accx":{ + "decoder":["value_from_hex_data", "manufacturerdata", 16, 4, false, true], + "post_proc":["/", 10000, "*", 9.80665] + }, + "accy":{ + "decoder":["value_from_hex_data", "manufacturerdata", 20, 4, false, true], + "post_proc":["/", 10000, "*", 9.80665] + }, + "accz":{ + "decoder":["value_from_hex_data", "manufacturerdata", 24, 4, false, true], + "post_proc":["/", 10000, "*", 9.80665] + }, + "volt":{ + "decoder":["value_from_hex_data", "manufacturerdata", 28, 4, false, false], + "post_proc":["/", 1000] + } + } +})"""";*/ + +const char* _RuuviTag_RAWv1_json_props = "{\"properties\":{\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"},\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"pres\":{\"unit\":\"hPa\",\"name\":\"pressure\"},\"accx\":{\"unit\":\"m/s²\",\"name\":\"acceleration x\"},\"accy\":{\"unit\":\"m/s²\",\"name\":\"acceleration y\"},\"accz\":{\"unit\":\"m/s²\",\"name\":\"acceleration z\"},\"volt\":{\"unit\":\"V\",\"name\":\"voltage\"}}}"; +/*R""""( +{ + "properties":{ + "hum":{ + "unit":"%", + "name":"humidity" + }, + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "pres":{ + "unit":"hPa", + "name":"pressure" + }, + "accx":{ + "unit":"m/s²", + "name":"acceleration x" + }, + "accy":{ + "unit":"m/s²", + "name":"acceleration y" + }, + "accz":{ + "unit":"m/s²", + "name":"acceleration z" + }, + "volt":{ + "unit":"V", + "name":"voltage" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/RuuviTag_RAWv2_json.h b/lib/decoder/src/devices/RuuviTag_RAWv2_json.h new file mode 100644 index 00000000..5e9fa272 --- /dev/null +++ b/lib/decoder/src/devices/RuuviTag_RAWv2_json.h @@ -0,0 +1,103 @@ +const char* _RuuviTag_RAWv2_json = "{\"brand\":\"Ruuvi\",\"model\":\"RuuviTag\",\"model_id\":\"RuuviTag_RAWv2\",\"tag\":\"0708\",\"condition\":[\"manufacturerdata\",\"=\",52,\"index\",0,\"990405\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",6,4,false,true],\"post_proc\":[\"/\",200]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",10,4,false,false],\"post_proc\":[\"/\",400]},\"pres\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",14,4,false,false],\"post_proc\":[\"+\",50000,\"/\",100]},\"accx\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",18,4,false,true],\"post_proc\":[\"/\",10000,\"*\",9.80665]},\"accy\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",22,4,false,true],\"post_proc\":[\"/\",10000,\"*\",9.80665]},\"accz\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",26,4,false,true],\"post_proc\":[\"/\",10000,\"*\",9.80665]},\"volt\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",30,4,false,false],\"post_proc\":[\">\",5,\"+\",1600,\"/\",1000]},\"tx\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",30,4,false,false],\"post_proc\":[\"%\",32,\"*\",2,\"-\",40]},\"mov\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",34,2,false,false]},\"seq\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",36,4,false,false]},\"mac\":{\"decoder\":[\"mac_from_hex_data\",\"manufacturerdata\",40]}}}"; +/*R""""( +{ + "brand":"Ruuvi", + "model":"RuuviTag", + "model_id":"RuuviTag_RAWv2", + "tag":"0708", + "condition":["manufacturerdata", "=", 52, "index", 0, "990405"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "manufacturerdata", 6, 4, false, true], + "post_proc":["/", 200] + }, + "hum":{ + "decoder":["value_from_hex_data", "manufacturerdata", 10, 4, false, false], + "post_proc":["/", 400] + }, + "pres":{ + "decoder":["value_from_hex_data", "manufacturerdata", 14, 4, false, false], + "post_proc":["+", 50000, "/", 100] + }, + "accx":{ + "decoder":["value_from_hex_data", "manufacturerdata", 18, 4, false, true], + "post_proc":["/", 10000, "*", 9.80665] + }, + "accy":{ + "decoder":["value_from_hex_data", "manufacturerdata", 22, 4, false, true], + "post_proc":["/", 10000, "*", 9.80665] + }, + "accz":{ + "decoder":["value_from_hex_data", "manufacturerdata", 26, 4, false, true], + "post_proc":["/", 10000, "*", 9.80665] + }, + "volt":{ + "decoder":["value_from_hex_data", "manufacturerdata", 30, 4, false, false], + "post_proc":[">", 5, "+", 1600, "/", 1000] + }, + "tx":{ + "decoder":["value_from_hex_data", "manufacturerdata", 30, 4, false, false], + "post_proc":["%", 32, "*", 2, "-", 40] + }, + "mov":{ + "decoder":["value_from_hex_data", "manufacturerdata", 34, 2, false, false] + }, + "seq":{ + "decoder":["value_from_hex_data", "manufacturerdata", 36, 4, false, false] + }, + "mac":{ + "decoder":["mac_from_hex_data", "manufacturerdata", 40] + } + } +})"""";*/ + +const char* _RuuviTag_RAWv2_json_props = "{\"properties\":{\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"},\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"pres\":{\"unit\":\"hPa\",\"name\":\"pressure\"},\"accx\":{\"unit\":\"m/s²\",\"name\":\"acceleration x\"},\"accy\":{\"unit\":\"m/s²\",\"name\":\"acceleration y\"},\"accz\":{\"unit\":\"m/s²\",\"name\":\"acceleration z\"},\"volt\":{\"unit\":\"V\",\"name\":\"voltage\"},\"tx\":{\"unit\":\"dBm\",\"name\":\"tx power\"},\"mov\":{\"unit\":\"int\",\"name\":\"movement counter\"},\"seq\":{\"unit\":\"int\",\"name\":\"measurement sequence number\"},\"mac\":{\"unit\":\"string\",\"name\":\"MAC address\"}}}"; +/*R""""( +{ + "properties":{ + "hum":{ + "unit":"%", + "name":"humidity" + }, + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "pres":{ + "unit":"hPa", + "name":"pressure" + }, + "accx":{ + "unit":"m/s²", + "name":"acceleration x" + }, + "accy":{ + "unit":"m/s²", + "name":"acceleration y" + }, + "accz":{ + "unit":"m/s²", + "name":"acceleration z" + }, + "volt":{ + "unit":"V", + "name":"voltage" + }, + "tx":{ + "unit":"dBm", + "name":"tx power" + }, + "mov":{ + "unit":"int", + "name":"movement counter" + }, + "seq":{ + "unit":"int", + "name":"measurement sequence number" + }, + "mac":{ + "unit":"string", + "name":"MAC address" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/SBBT_002C_ENCR_json.h b/lib/decoder/src/devices/SBBT_002C_ENCR_json.h new file mode 100644 index 00000000..c431a9b0 --- /dev/null +++ b/lib/decoder/src/devices/SBBT_002C_ENCR_json.h @@ -0,0 +1,47 @@ +const char* _SBBT_002C_ENCR_json = "{\"brand\":\"Shelly\",\"model\":\"ShellyBLU Button1 encrypted\",\"model_id\":\"SBBT_002C_ENCR\",\"tag\":\"110602\",\"condition\":[\"servicedata\",\"index\",0,\"41\",\"|\",\"servicedata\",\"index\",0,\"45\",\"&\",\"uuid\",\"index\",0,\"fcd2\",\"&\",\"name\",\"index\",0,\"SBBT-002C\"],\"properties\":{\"cipher\":{\"decoder\":[\"string_from_hex_data\",\"servicedata\",2,12]},\"ctr\":{\"decoder\":[\"string_from_hex_data\",\"servicedata\",14,8]},\"mic\":{\"decoder\":[\"string_from_hex_data\",\"servicedata\",22,8]},\"mac\":{\"condition\":[\"manufacturerdata\",\"=\",30],\"decoder\":[\"revmac_from_hex_data\",\"manufacturerdata\",18]}}}"; +/*R""""( +{ + "brand":"Shelly", + "model":"ShellyBLU Button1 encrypted", + "model_id":"SBBT_002C_ENCR", + "tag":"110602", + "condition":["servicedata", "index", 0, "41", "|", "servicedata", "index", 0, "45", "&", "uuid", "index", 0, "fcd2", "&", "name", "index", 0, "SBBT-002C"], + "properties":{ + "cipher":{ + "decoder":["string_from_hex_data", "servicedata", 2, 12] + }, + "ctr":{ + "decoder":["string_from_hex_data", "servicedata", 14, 8] + }, + "mic":{ + "decoder":["string_from_hex_data", "servicedata", 22, 8] + }, + "mac":{ + "condition":["manufacturerdata", "=", 30], + "decoder":["revmac_from_hex_data", "manufacturerdata", 18] + } + } +})"""";*/ + +const char* _SBBT_002C_ENCR_json_props = "{\"properties\":{\"cipher\":{\"unit\":\"hex\",\"name\":\"ciphertext\"},\"ctr\":{\"unit\":\"hex\",\"name\":\"counter\"},\"mic\":{\"unit\":\"hex\",\"name\":\"message integrity check\"},\"mac\":{\"unit\":\"string\",\"name\":\"MAC address\"}}}"; +/*R""""( +{ + "properties":{ + "cipher":{ + "unit":"hex", + "name":"ciphertext" + }, + "ctr":{ + "unit":"hex", + "name":"counter" + }, + "mic":{ + "unit":"hex", + "name":"message integrity check" + }, + "mac":{ + "unit":"string", + "name":"MAC address" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/SBBT_002C_json.h b/lib/decoder/src/devices/SBBT_002C_json.h new file mode 100644 index 00000000..21c2296d --- /dev/null +++ b/lib/decoder/src/devices/SBBT_002C_json.h @@ -0,0 +1,50 @@ +const char* _SBBT_002C_json = "{\"brand\":\"Shelly\",\"model\":\"ShellyBLU Button1\",\"model_id\":\"SBBT-002C\",\"tag\":\"1106\",\"condition\":[\"servicedata\",\"=\",14,\"index\",0,\"40\",\"|\",\"servicedata\",\"=\",14,\"index\",0,\"44\",\"&\",\"uuid\",\"index\",0,\"fcd2\",\"&\",\"name\",\"index\",0,\"SBBT-002C\"],\"properties\":{\"packet\":{\"condition\":[\"servicedata\",2,\"00\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",4,2,false,false]},\"batt\":{\"condition\":[\"servicedata\",6,\"01\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",8,2,false,false]},\"press\":{\"condition\":[\"servicedata\",10,\"3a\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",12,2,false,false]},\"mac\":{\"condition\":[\"manufacturerdata\",\"=\",30],\"decoder\":[\"revmac_from_hex_data\",\"manufacturerdata\",18]}}}"; +/*R""""( +{ + "brand":"Shelly", + "model":"ShellyBLU Button1", + "model_id":"SBBT-002C", + "tag":"1106", + "condition":["servicedata", "=", 14, "index", 0, "40", "|", "servicedata", "=", 14, "index", 0, "44", "&", "uuid", "index", 0, "fcd2", "&", "name", "index", 0, "SBBT-002C"], + "properties":{ + "packet":{ + "condition":["servicedata", 2, "00"], + "decoder":["value_from_hex_data", "servicedata", 4, 2, false, false] + }, + "batt":{ + "condition":["servicedata", 6, "01"], + "decoder":["value_from_hex_data", "servicedata", 8, 2, false, false] + }, + "press":{ + "condition":["servicedata", 10, "3a"], + "decoder":["value_from_hex_data", "servicedata", 12, 2, false, false] + }, + "mac":{ + "condition":["manufacturerdata", "=", 30], + "decoder":["revmac_from_hex_data", "manufacturerdata", 18] + } + } +})"""";*/ + +const char* _SBBT_002C_json_props = "{\"properties\":{\"packet\":{\"unit\":\"int\",\"name\":\"packet id\"},\"batt\":{\"unit\":\"%\",\"name\":\"battery\"},\"press\":{\"unit\":\"int\",\"name\":\"press type\"},\"mac\":{\"unit\":\"string\",\"name\":\"MAC address\"}}}"; +/*R""""( +{ + "properties":{ + "packet":{ + "unit":"int", + "name":"packet id" + }, + "batt":{ + "unit":"%", + "name":"battery" + }, + "press":{ + "unit":"int", + "name":"press type" + }, + "mac":{ + "unit":"string", + "name":"MAC address" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/SBCS_json.h b/lib/decoder/src/devices/SBCS_json.h new file mode 100644 index 00000000..aa52a316 --- /dev/null +++ b/lib/decoder/src/devices/SBCS_json.h @@ -0,0 +1,83 @@ +const char* _SBCS_json = "{\"brand\":\"SwitchBot\",\"model\":\"Contact Sensor\",\"model_id\":\"W120150X\",\"tag\":\"0406\",\"condition\":[\"uuid\",\"index\",0,\"0d00\",\"|\",\"uuid\",\"index\",0,\"fd3d\",\"&\",\"servicedata\",\"=\",18,\"index\",0,\"64\"],\"properties\":{\"contact\":{\"condition\":[\"servicedata\",7,\"bit\",2,0],\"decoder\":[\"bit_static_value\",\"servicedata\",7,1,\"closed\",\"open\"]},\"_contact\":{\"condition\":[\"servicedata\",7,\"bit\",2,1],\"decoder\":[\"static_value\",\"timeout not closed\"]},\"motion\":{\"decoder\":[\"bit_static_value\",\"servicedata\",2,2,false,true]},\"lightlevel\":{\"decoder\":[\"bit_static_value\",\"servicedata\",7,0,\"dark\",\"bright\"]},\"scopetested\":{\"condition\":[\"servicedata\",2,\"bit\",3,0],\"decoder\":[\"static_value\",false]},\"in_ct\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",16,1,false,false],\"post_proc\":[\">\",2]},\"out_ct\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",16,1,false,false],\"post_proc\":[\"&\",3]},\"push_ct\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",17,1,false,false]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",4,2,false,false],\"post_proc\":[\"&\",127]}}}"; +/*R""""( +{ + "brand":"SwitchBot", + "model":"Contact Sensor", + "model_id":"W120150X", + "tag":"0406", + "condition":["uuid", "index", 0, "0d00", "|", "uuid", "index", 0, "fd3d", "&", "servicedata", "=", 18, "index", 0, "64"], + "properties":{ + "contact":{ + "condition":["servicedata", 7, "bit", 2, 0], + "decoder":["bit_static_value", "servicedata", 7, 1, "closed", "open"] + }, + "_contact":{ + "condition":["servicedata", 7, "bit", 2, 1], + "decoder":["static_value", "timeout not closed"] + }, + "motion":{ + "decoder":["bit_static_value", "servicedata", 2, 2, false, true] + }, + "lightlevel":{ + "decoder":["bit_static_value", "servicedata", 7, 0, "dark", "bright"] + }, + "scopetested":{ + "condition":["servicedata", 2, "bit", 3, 0], + "decoder":["static_value", false] + }, + "in_ct":{ + "decoder":["value_from_hex_data", "servicedata", 16, 1, false, false], + "post_proc":[">", 2] + }, + "out_ct":{ + "decoder":["value_from_hex_data", "servicedata", 16, 1, false, false], + "post_proc":["&", 3] + }, + "push_ct":{ + "decoder":["value_from_hex_data", "servicedata", 17, 1, false, false] + }, + "batt":{ + "decoder":["value_from_hex_data", "servicedata", 4, 2, false, false], + "post_proc":["&", 127] + } + } +})"""";*/ + +const char* _SBCS_json_props = "{\"properties\":{\"contact\":{\"unit\":\"string\",\"name\":\"contact\"},\"motion\":{\"unit\":\"status\",\"name\":\"motion\"},\"lightlevel\":{\"unit\":\"string\",\"name\":\"light level\"},\"scopetested\":{\"unit\":\"status\",\"name\":\"scope tested\"},\"in_ct\":{\"unit\":\"int\",\"name\":\"in count\"},\"out_ct\":{\"unit\":\"int\",\"name\":\"out count\"},\"push_ct\":{\"unit\":\"int\",\"name\":\"push count\"},\"batt\":{\"unit\":\"%\",\"name\":\"battery\"}}}"; +/*R""""( +{ + "properties":{ + "contact":{ + "unit":"string", + "name":"contact" + }, + "motion":{ + "unit":"status", + "name":"motion" + }, + "lightlevel":{ + "unit":"string", + "name":"light level" + }, + "scopetested":{ + "unit":"status", + "name":"scope tested" + }, + "in_ct":{ + "unit":"int", + "name":"in count" + }, + "out_ct":{ + "unit":"int", + "name":"out count" + }, + "push_ct":{ + "unit":"int", + "name":"push count" + }, + "batt":{ + "unit":"%", + "name":"battery" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/SBCU_json.h b/lib/decoder/src/devices/SBCU_json.h new file mode 100644 index 00000000..25c70313 --- /dev/null +++ b/lib/decoder/src/devices/SBCU_json.h @@ -0,0 +1,55 @@ +const char* _SBCU_json = "{\"brand\":\"SwitchBot\",\"model\":\"Curtain\",\"model_id\":\"W070160X\",\"tag\":\"0d02\",\"condition\":[\"servicedata\",\"=\",10,\"index\",0,\"63\",\"|\",\"servicedata\",\"=\",12,\"index\",0,\"63\",\"&\",[\"uuid\",\"index\",0,\"0d00\",\"|\",\"uuid\",\"index\",0,\"fd3d\"]],\"properties\":{\"moving\":{\"decoder\":[\"bit_static_value\",\"servicedata\",6,3,false,true]},\"position\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",6,2,false,false],\"post_proc\":[\"&\",127]},\"calibrated\":{\"decoder\":[\"bit_static_value\",\"servicedata\",2,2,false,true]},\"lightlevel\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",8,1,false,false]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",4,2,false,false],\"post_proc\":[\"&\",127]}}}"; +/*R""""( +{ + "brand":"SwitchBot", + "model":"Curtain", + "model_id":"W070160X", + "tag":"0d02", + "condition":["servicedata", "=", 10, "index", 0, "63", "|", "servicedata", "=", 12, "index", 0, "63", "&", ["uuid", "index", 0, "0d00", "|", "uuid", "index", 0, "fd3d"]], + "properties":{ + "moving":{ + "decoder":["bit_static_value", "servicedata", 6, 3, false, true] + }, + "position":{ + "decoder":["value_from_hex_data", "servicedata", 6, 2, false, false], + "post_proc":["&", 127] + }, + "calibrated":{ + "decoder":["bit_static_value", "servicedata", 2, 2, false, true] + }, + "lightlevel":{ + "decoder":["value_from_hex_data", "servicedata", 8, 1, false, false] + }, + "batt":{ + "decoder":["value_from_hex_data", "servicedata", 4, 2, false, false], + "post_proc":["&", 127] + } + } +})"""";*/ + +const char* _SBCU_json_props = "{\"properties\":{\"moving\":{\"unit\":\"status\",\"name\":\"moving\"},\"position\":{\"unit\":\"%\",\"name\":\"position\"},\"calibrated\":{\"unit\":\"status\",\"name\":\"calibrated\"},\"lightlevel\":{\"unit\":\"int\",\"name\":\"light level\"},\"batt\":{\"unit\":\"%\",\"name\":\"battery\"}}}"; +/*R""""( +{ + "properties":{ + "moving":{ + "unit":"status", + "name":"moving" + }, + "position":{ + "unit":"%", + "name":"position" + }, + "calibrated":{ + "unit":"status", + "name":"calibrated" + }, + "lightlevel":{ + "unit":"int", + "name":"light level" + }, + "batt":{ + "unit":"%", + "name":"battery" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/SBDW_002C_ENCR_json.h b/lib/decoder/src/devices/SBDW_002C_ENCR_json.h new file mode 100644 index 00000000..9670077a --- /dev/null +++ b/lib/decoder/src/devices/SBDW_002C_ENCR_json.h @@ -0,0 +1,47 @@ +const char* _SBDW_002C_ENCR_json = "{\"brand\":\"Shelly\",\"model\":\"ShellyBLU Door/Window encrypted\",\"model_id\":\"SBDW_002C_ENCR\",\"tag\":\"040602\",\"condition\":[\"servicedata\",\"index\",0,\"45\",\"&\",\"uuid\",\"index\",0,\"fcd2\",\"&\",\"name\",\"index\",0,\"SBDW-002C\"],\"properties\":{\"cipher\":{\"decoder\":[\"string_from_hex_data\",\"servicedata\",2,26]},\"ctr\":{\"decoder\":[\"string_from_hex_data\",\"servicedata\",28,8]},\"mic\":{\"decoder\":[\"string_from_hex_data\",\"servicedata\",36,8]},\"mac\":{\"condition\":[\"manufacturerdata\",\"=\",30],\"decoder\":[\"revmac_from_hex_data\",\"manufacturerdata\",18]}}}"; +/*R""""( +{ + "brand":"Shelly", + "model":"ShellyBLU Door/Window encrypted", + "model_id":"SBDW_002C_ENCR", + "tag":"040602", + "condition":["servicedata", "index", 0, "45", "&", "uuid", "index", 0, "fcd2", "&", "name", "index", 0, "SBDW-002C"], + "properties":{ + "cipher":{ + "decoder":["string_from_hex_data", "servicedata", 2, 26] + }, + "ctr":{ + "decoder":["string_from_hex_data", "servicedata", 28, 8] + }, + "mic":{ + "decoder":["string_from_hex_data", "servicedata", 36, 8] + }, + "mac":{ + "condition":["manufacturerdata", "=", 30], + "decoder":["revmac_from_hex_data", "manufacturerdata", 18] + } + } +})"""";*/ + +const char* _SBDW_002C_ENCR_json_props = "{\"properties\":{\"cipher\":{\"unit\":\"hex\",\"name\":\"ciphertext\"},\"ctr\":{\"unit\":\"hex\",\"name\":\"counter\"},\"mic\":{\"unit\":\"hex\",\"name\":\"message integrity check\"},\"mac\":{\"unit\":\"string\",\"name\":\"MAC address\"}}}"; +/*R""""( +{ + "properties":{ + "cipher":{ + "unit":"hex", + "name":"ciphertext" + }, + "ctr":{ + "unit":"hex", + "name":"counter" + }, + "mic":{ + "unit":"hex", + "name":"message integrity check" + }, + "mac":{ + "unit":"string", + "name":"MAC address" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/SBDW_002C_json.h b/lib/decoder/src/devices/SBDW_002C_json.h new file mode 100644 index 00000000..e7a8fdbd --- /dev/null +++ b/lib/decoder/src/devices/SBDW_002C_json.h @@ -0,0 +1,68 @@ +const char* _SBDW_002C_json = "{\"brand\":\"Shelly\",\"model\":\"ShellyBLU Door/Window\",\"model_id\":\"SBDW-002C\",\"tag\":\"0406\",\"condition\":[\"servicedata\",\"=\",28,\"index\",0,\"44\",\"&\",\"uuid\",\"index\",0,\"fcd2\",\"&\",\"name\",\"index\",0,\"SBDW-002C\"],\"properties\":{\"packet\":{\"condition\":[\"servicedata\",2,\"00\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",4,2,false,false]},\"batt\":{\"condition\":[\"servicedata\",6,\"01\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",8,2,false,false]},\"lux\":{\"condition\":[\"servicedata\",10,\"05\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",12,6,true,false],\"post_proc\":[\"/\",100]},\"open\":{\"condition\":[\"servicedata\",18,\"2d\"],\"decoder\":[\"bit_static_value\",\"servicedata\",21,0,false,true]},\"rot\":{\"condition\":[\"servicedata\",22,\"3f\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",24,4,true,true],\"post_proc\":[\"/\",10]},\"mac\":{\"condition\":[\"manufacturerdata\",\"=\",30],\"decoder\":[\"revmac_from_hex_data\",\"manufacturerdata\",18]}}}"; +/*R""""( +{ + "brand":"Shelly", + "model":"ShellyBLU Door/Window", + "model_id":"SBDW-002C", + "tag":"0406", + "condition":["servicedata", "=", 28, "index", 0, "44", "&", "uuid", "index", 0, "fcd2", "&", "name", "index", 0, "SBDW-002C"], + "properties":{ + "packet":{ + "condition":["servicedata", 2, "00"], + "decoder":["value_from_hex_data", "servicedata", 4, 2, false, false] + }, + "batt":{ + "condition":["servicedata", 6, "01"], + "decoder":["value_from_hex_data", "servicedata", 8, 2, false, false] + }, + "lux":{ + "condition":["servicedata", 10, "05"], + "decoder":["value_from_hex_data", "servicedata", 12, 6, true, false], + "post_proc":["/", 100] + }, + "open":{ + "condition":["servicedata", 18, "2d"], + "decoder":["bit_static_value", "servicedata", 21, 0, false, true] + }, + "rot":{ + "condition":["servicedata", 22, "3f"], + "decoder":["value_from_hex_data", "servicedata", 24, 4, true, true], + "post_proc":["/", 10] + }, + "mac":{ + "condition":["manufacturerdata", "=", 30], + "decoder":["revmac_from_hex_data", "manufacturerdata", 18] + } + } +})"""";*/ + +const char* _SBDW_002C_json_props = "{\"properties\":{\"packet\":{\"unit\":\"int\",\"name\":\"packet id\"},\"batt\":{\"unit\":\"%\",\"name\":\"battery\"},\"lux\":{\"unit\":\"lux\",\"name\":\"illuminance\"},\"open\":{\"unit\":\"status\",\"name\":\"door\"},\"rot\":{\"unit\":\"0\",\"name\":\"rotation\"},\"mac\":{\"unit\":\"string\",\"name\":\"MAC address\"}}}"; +/*R""""( +{ + "properties":{ + "packet":{ + "unit":"int", + "name":"packet id" + }, + "batt":{ + "unit":"%", + "name":"battery" + }, + "lux":{ + "unit":"lux", + "name":"illuminance" + }, + "open":{ + "unit":"status", + "name":"door" + }, + "rot":{ + "unit":"0", + "name":"rotation" + }, + "mac":{ + "unit":"string", + "name":"MAC address" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/SBMO_003Z_ENCR_json.h b/lib/decoder/src/devices/SBMO_003Z_ENCR_json.h new file mode 100644 index 00000000..57e546bd --- /dev/null +++ b/lib/decoder/src/devices/SBMO_003Z_ENCR_json.h @@ -0,0 +1,47 @@ +const char* _SBMO_003Z_ENCR_json = "{\"brand\":\"Shelly\",\"model\":\"ShellyBLU Motion encrypted\",\"model_id\":\"SBMO_003Z_ENCR\",\"tag\":\"040602\",\"condition\":[\"servicedata\",\"index\",0,\"45\",\"&\",\"uuid\",\"index\",0,\"fcd2\",\"&\",\"name\",\"index\",0,\"SBMO-003Z\"],\"properties\":{\"cipher\":{\"decoder\":[\"string_from_hex_data\",\"servicedata\",2,20]},\"ctr\":{\"decoder\":[\"string_from_hex_data\",\"servicedata\",22,8]},\"mic\":{\"decoder\":[\"string_from_hex_data\",\"servicedata\",30,8]},\"mac\":{\"condition\":[\"manufacturerdata\",\"=\",30],\"decoder\":[\"revmac_from_hex_data\",\"manufacturerdata\",18]}}}"; +/*R""""( +{ + "brand":"Shelly", + "model":"ShellyBLU Motion encrypted", + "model_id":"SBMO_003Z_ENCR", + "tag":"040602", + "condition":["servicedata", "index", 0, "45", "&", "uuid", "index", 0, "fcd2", "&", "name", "index", 0, "SBMO-003Z"], + "properties":{ + "cipher":{ + "decoder":["string_from_hex_data", "servicedata", 2, 20] + }, + "ctr":{ + "decoder":["string_from_hex_data", "servicedata", 22, 8] + }, + "mic":{ + "decoder":["string_from_hex_data", "servicedata", 30, 8] + }, + "mac":{ + "condition":["manufacturerdata", "=", 30], + "decoder":["revmac_from_hex_data", "manufacturerdata", 18] + } + } +})"""";*/ + +const char* _SBMO_003Z_ENCR_json_props = "{\"properties\":{\"cipher\":{\"unit\":\"hex\",\"name\":\"ciphertext\"},\"ctr\":{\"unit\":\"hex\",\"name\":\"counter\"},\"mic\":{\"unit\":\"hex\",\"name\":\"message integrity check\"},\"mac\":{\"unit\":\"string\",\"name\":\"MAC address\"}}}"; +/*R""""( +{ + "properties":{ + "cipher":{ + "unit":"hex", + "name":"ciphertext" + }, + "ctr":{ + "unit":"hex", + "name":"counter" + }, + "mic":{ + "unit":"hex", + "name":"message integrity check" + }, + "mac":{ + "unit":"string", + "name":"MAC address" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/SBMO_003Z_json.h b/lib/decoder/src/devices/SBMO_003Z_json.h new file mode 100644 index 00000000..6fe7c16c --- /dev/null +++ b/lib/decoder/src/devices/SBMO_003Z_json.h @@ -0,0 +1,59 @@ +const char* _SBMO_003Z_json = "{\"brand\":\"Shelly\",\"model\":\"ShellyBLU Motion\",\"model_id\":\"SBMO-003Z\",\"tag\":\"0406\",\"condition\":[\"servicedata\",\"=\",22,\"index\",0,\"44\",\"&\",\"uuid\",\"index\",0,\"fcd2\",\"&\",\"name\",\"index\",0,\"SBMO-003Z\"],\"properties\":{\"packet\":{\"condition\":[\"servicedata\",2,\"00\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",4,2,false,false]},\"batt\":{\"condition\":[\"servicedata\",6,\"01\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",8,2,false,false]},\"lux\":{\"condition\":[\"servicedata\",10,\"05\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",12,6,true,false],\"post_proc\":[\"/\",100]},\"motion\":{\"condition\":[\"servicedata\",18,\"21\"],\"decoder\":[\"bit_static_value\",\"servicedata\",21,0,false,true]},\"mac\":{\"condition\":[\"manufacturerdata\",\"=\",30],\"decoder\":[\"revmac_from_hex_data\",\"manufacturerdata\",18]}}}"; +/*R""""( +{ + "brand":"Shelly", + "model":"ShellyBLU Motion", + "model_id":"SBMO-003Z", + "tag":"0406", + "condition":["servicedata", "=", 22, "index", 0, "44", "&", "uuid", "index", 0, "fcd2", "&", "name", "index", 0, "SBMO-003Z"], + "properties":{ + "packet":{ + "condition":["servicedata", 2, "00"], + "decoder":["value_from_hex_data", "servicedata", 4, 2, false, false] + }, + "batt":{ + "condition":["servicedata", 6, "01"], + "decoder":["value_from_hex_data", "servicedata", 8, 2, false, false] + }, + "lux":{ + "condition":["servicedata", 10, "05"], + "decoder":["value_from_hex_data", "servicedata", 12, 6, true, false], + "post_proc":["/", 100] + }, + "motion":{ + "condition":["servicedata", 18, "21"], + "decoder":["bit_static_value", "servicedata", 21, 0, false, true] + }, + "mac":{ + "condition":["manufacturerdata", "=", 30], + "decoder":["revmac_from_hex_data", "manufacturerdata", 18] + } + } +})"""";*/ + +const char* _SBMO_003Z_json_props = "{\"properties\":{\"packet\":{\"unit\":\"int\",\"name\":\"packet id\"},\"batt\":{\"unit\":\"%\",\"name\":\"battery\"},\"lux\":{\"unit\":\"lux\",\"name\":\"illuminance\"},\"motion\":{\"unit\":\"status\",\"name\":\"motion\"},\"mac\":{\"unit\":\"string\",\"name\":\"MAC address\"}}}"; +/*R""""( +{ + "properties":{ + "packet":{ + "unit":"int", + "name":"packet id" + }, + "batt":{ + "unit":"%", + "name":"battery" + }, + "lux":{ + "unit":"lux", + "name":"illuminance" + }, + "motion":{ + "unit":"status", + "name":"motion" + }, + "mac":{ + "unit":"string", + "name":"MAC address" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/SBMS_json.h b/lib/decoder/src/devices/SBMS_json.h new file mode 100644 index 00000000..f3ca4391 --- /dev/null +++ b/lib/decoder/src/devices/SBMS_json.h @@ -0,0 +1,71 @@ +const char* _SBMS_json = "{\"brand\":\"SwitchBot\",\"model\":\"Motion Sensor\",\"model_id\":\"W110150X\",\"tag\":\"0406\",\"condition\":[\"uuid\",\"index\",0,\"0d00\",\"|\",\"uuid\",\"index\",0,\"fd3d\",\"&\",\"servicedata\",\"=\",12,\"index\",0,\"73\"],\"properties\":{\"motion\":{\"decoder\":[\"bit_static_value\",\"servicedata\",2,2,false,true]},\"led\":{\"decoder\":[\"bit_static_value\",\"servicedata\",10,1,false,true]},\"scopetested\":{\"condition\":[\"servicedata\",2,\"bit\",3,0],\"decoder\":[\"static_value\",false]},\"sensingdistance\":{\"condition\":[\"servicedata\",11,\"bit\",3,0,\"&\",\"servicedata\",11,\"bit\",2,0],\"decoder\":[\"static_value\",\"long\"]},\"_sensingdistance\":{\"condition\":[\"servicedata\",11,\"bit\",3,0,\"&\",\"servicedata\",11,\"bit\",2,1],\"decoder\":[\"static_value\",\"middle\"]},\"__sensingdistance\":{\"condition\":[\"servicedata\",11,\"bit\",3,1,\"&\",\"servicedata\",11,\"bit\",2,0],\"decoder\":[\"static_value\",\"short\"]},\"lightlevel\":{\"decoder\":[\"bit_static_value\",\"servicedata\",11,1,\"dark\",\"bright\"]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",4,2,false,false],\"post_proc\":[\"&\",127]}}}"; +/*R""""( +{ + "brand":"SwitchBot", + "model":"Motion Sensor", + "model_id":"W110150X", + "tag":"0406", + "condition":["uuid", "index", 0, "0d00", "|", "uuid", "index", 0, "fd3d", "&", "servicedata", "=", 12, "index", 0, "73"], + "properties":{ + "motion":{ + "decoder":["bit_static_value", "servicedata", 2, 2, false, true] + }, + "led":{ + "decoder":["bit_static_value", "servicedata", 10, 1, false, true] + }, + "scopetested":{ + "condition":["servicedata", 2, "bit", 3, 0], + "decoder":["static_value", false] + }, + "sensingdistance":{ + "condition":["servicedata", 11, "bit", 3, 0, "&","servicedata", 11, "bit", 2, 0], + "decoder":["static_value", "long"] + }, + "_sensingdistance":{ + "condition":["servicedata", 11, "bit", 3, 0, "&","servicedata", 11, "bit", 2, 1], + "decoder":["static_value", "middle"] + }, + "__sensingdistance":{ + "condition":["servicedata", 11, "bit", 3, 1, "&","servicedata", 11, "bit", 2, 0], + "decoder":["static_value", "short"] + }, + "lightlevel":{ + "decoder":["bit_static_value", "servicedata", 11, 1, "dark", "bright"] + }, + "batt":{ + "decoder":["value_from_hex_data", "servicedata", 4, 2, false, false], + "post_proc":["&", 127] + } + } +})"""";*/ + +const char* _SBMS_json_props = "{\"properties\":{\"motion\":{\"unit\":\"status\",\"name\":\"motion\"},\"led\":{\"unit\":\"status\",\"name\":\"LED\"},\"scopetested\":{\"unit\":\"status\",\"name\":\"scope tested\"},\"sensingdistance\":{\"unit\":\"string\",\"name\":\"sensing distance\"},\"lightlevel\":{\"unit\":\"string\",\"name\":\"light level\"},\"batt\":{\"unit\":\"%\",\"name\":\"battery\"}}}"; +/*R""""( +{ + "properties":{ + "motion":{ + "unit":"status", + "name":"motion" + }, + "led":{ + "unit":"status", + "name":"LED" + }, + "scopetested":{ + "unit":"status", + "name":"scope tested" + }, + "sensingdistance":{ + "unit":"string", + "name":"sensing distance" + }, + "lightlevel":{ + "unit":"string", + "name":"light level" + }, + "batt":{ + "unit":"%", + "name":"battery" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/SBMT_json.h b/lib/decoder/src/devices/SBMT_json.h new file mode 100644 index 00000000..440375f4 --- /dev/null +++ b/lib/decoder/src/devices/SBMT_json.h @@ -0,0 +1,37 @@ +#include "common_props.h" + +const char* _SBMT_json = "{\"brand\":\"SwitchBot\",\"model\":\"Meter (Plus)\",\"model_id\":\"THX1/W230150X\",\"tag\":\"0102\",\"condition\":[\"servicedata\",\"=\",12,\"index\",0,\"54\",\"|\",\"servicedata\",\"=\",12,\"index\",0,\"69\",\"&\",[\"uuid\",\"index\",0,\"0d00\",\"|\",\"uuid\",\"index\",0,\"fd3d\"]],\"properties\":{\".cal\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",7,1,false,false],\"post_proc\":[\"/\",10]},\"tempc\":{\"condition\":[\"servicedata\",8,\"bit\",3,0],\"decoder\":[\"value_from_hex_data\",\"servicedata\",8,2,true,false],\"post_proc\":[\"+\",\".cal\",\"*\",-1]},\"_tempc\":{\"condition\":[\"servicedata\",8,\"bit\",3,1],\"decoder\":[\"value_from_hex_data\",\"servicedata\",8,2,true,false],\"post_proc\":[\"+\",\".cal\",\"-\",128]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",10,2,false,false],\"post_proc\":[\"&\",127]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",4,2,false,false],\"post_proc\":[\"&\",127]}}}"; +/*R""""( +{ + "brand":"SwitchBot", + "model":"Meter (Plus)", + "model_id":"THX1/W230150X", + "tag":"0102", + "condition":["servicedata", "=", 12, "index", 0, "54", "|", "servicedata", "=", 12, "index", 0, "69", "&", ["uuid", "index", 0, "0d00", "|", "uuid", "index", 0, "fd3d"]], + "properties":{ + ".cal":{ + "decoder":["value_from_hex_data", "servicedata", 7, 1, false, false], + "post_proc":["/", 10] + }, + "tempc":{ + "condition":["servicedata", 8, "bit", 3, 0], + "decoder":["value_from_hex_data", "servicedata", 8, 2, true, false], + "post_proc":["+", ".cal", "*", -1] + }, + "_tempc":{ + "condition":["servicedata", 8, "bit", 3, 1], + "decoder":["value_from_hex_data", "servicedata", 8, 2, true, false], + "post_proc":["+", ".cal", "-", 128] + }, + "hum":{ + "decoder":["value_from_hex_data", "servicedata", 10, 2, false, false], + "post_proc":["&", 127] + }, + "batt":{ + "decoder":["value_from_hex_data", "servicedata", 4, 2, false, false], + "post_proc":["&", 127] + } + } +})"""";*/ + +const char* _SBMT_json_props = _common_BTH_props; diff --git a/lib/decoder/src/devices/SBOT_json.h b/lib/decoder/src/devices/SBOT_json.h new file mode 100644 index 00000000..6f15e7b5 --- /dev/null +++ b/lib/decoder/src/devices/SBOT_json.h @@ -0,0 +1,40 @@ +#include "common_props.h" + +const char* _SBOT_json = "{\"brand\":\"SwitchBot\",\"model\":\"Outdoor Meter\",\"model_id\":\"W340001X\",\"tag\":\"0102\",\"condition\":[\"servicedata\",\"=\",6,\"index\",0,\"77\",\"&\",\"uuid\",\"index\",0,\"fd3d\",\"&\",\"manufacturerdata\",\"=\",28],\"properties\":{\".cal\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",21,1,false,false],\"post_proc\":[\"/\",10]},\"tempc\":{\"condition\":[\"manufacturerdata\",22,\"bit\",3,0],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",22,2,true,false],\"post_proc\":[\"+\",\".cal\",\"*\",-1]},\"_tempc\":{\"condition\":[\"manufacturerdata\",22,\"bit\",3,1],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",22,2,true,false],\"post_proc\":[\"+\",\".cal\",\"-\",128]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",24,2,false,false],\"post_proc\":[\"&\",127]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",4,2,false,false],\"post_proc\":[\"&\",127]},\"mac\":{\"decoder\":[\"mac_from_hex_data\",\"manufacturerdata\",4]}}}"; +/*R""""( +{ + "brand":"SwitchBot", + "model":"Outdoor Meter", + "model_id":"W340001X", + "tag":"0102", + "condition":["servicedata", "=", 6, "index", 0, "77", "&", "uuid", "index", 0, "fd3d", "&", "manufacturerdata", "=", 28], + "properties":{ + ".cal":{ + "decoder":["value_from_hex_data", "manufacturerdata", 21, 1, false, false], + "post_proc":["/", 10] + }, + "tempc":{ + "condition":["manufacturerdata", 22, "bit", 3, 0], + "decoder":["value_from_hex_data", "manufacturerdata", 22, 2, true, false], + "post_proc":["+", ".cal", "*", -1] + }, + "_tempc":{ + "condition":["manufacturerdata", 22, "bit", 3, 1], + "decoder":["value_from_hex_data", "manufacturerdata", 22, 2, true, false], + "post_proc":["+", ".cal", "-", 128] + }, + "hum":{ + "decoder":["value_from_hex_data", "manufacturerdata", 24, 2, false, false], + "post_proc":["&", 127] + }, + "batt":{ + "decoder":["value_from_hex_data", "servicedata", 4, 2, false, false], + "post_proc":["&", 127] + }, + "mac":{ + "decoder":["mac_from_hex_data", "manufacturerdata", 4] + } + } +})"""";*/ + +const char* _SBOT_json_props = _common_BTHM_props; diff --git a/lib/decoder/src/devices/SBS1_json.h b/lib/decoder/src/devices/SBS1_json.h new file mode 100644 index 00000000..fadeac46 --- /dev/null +++ b/lib/decoder/src/devices/SBS1_json.h @@ -0,0 +1,40 @@ +const char* _SBS1_json = "{\"brand\":\"SwitchBot\",\"model\":\"Bot\",\"model_id\":\"X1\",\"tag\":\"0e02\",\"condition\":[\"uuid\",\"index\",0,\"0d00\",\"|\",\"uuid\",\"index\",0,\"fd3d\",\"&\",\"servicedata\",\"=\",6,\"index\",0,\"48\"],\"properties\":{\"mode\":{\"decoder\":[\"bit_static_value\",\"servicedata\",2,3,\"onestate\",\"on/off\"]},\"state\":{\"decoder\":[\"bit_static_value\",\"servicedata\",2,2,\"on\",\"off\"]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",4,2,false,false],\"post_proc\":[\"&\",127]}}}"; +/*R""""( +{ + "brand":"SwitchBot", + "model":"Bot", + "model_id":"X1", + "tag":"0e02", + "condition":["uuid", "index", 0, "0d00", "|", "uuid", "index", 0, "fd3d", "&", "servicedata", "=", 6, "index", 0, "48"], + "properties":{ + "mode":{ + "decoder":["bit_static_value", "servicedata", 2, 3, "onestate", "on/off"] + }, + "state":{ + "decoder":["bit_static_value", "servicedata", 2, 2, "on", "off"] + }, + "batt":{ + "decoder":["value_from_hex_data", "servicedata", 4, 2, false, false], + "post_proc":["&", 127] + } + } +})"""";*/ + +const char* _SBS1_json_props = "{\"properties\":{\"mode\":{\"unit\":\"string\",\"name\":\"mode\"},\"state\":{\"unit\":\"string\",\"name\":\"state\"},\"batt\":{\"unit\":\"%\",\"name\":\"battery\"}}}"; +/*R""""( +{ + "properties":{ + "mode":{ + "unit":"string", + "name":"mode" + }, + "state":{ + "unit":"string", + "name":"state" + }, + "batt":{ + "unit":"%", + "name":"battery" + } + } +})"""";*/ \ No newline at end of file diff --git a/lib/decoder/src/devices/SCD4X_json.h b/lib/decoder/src/devices/SCD4X_json.h new file mode 100644 index 00000000..d1921a0b --- /dev/null +++ b/lib/decoder/src/devices/SCD4X_json.h @@ -0,0 +1,43 @@ +const char* _SCD4X_json = "{\"brand\":\"Sensirion\",\"model\":\"MyCO₂/CO₂ Gadget\",\"model_id\":\"SCD4X\",\"tag\":\"0f\",\"condition\":[\"manufacturerdata\",\">=\",24,\"index\",0,\"d5060008\",\"|\",\"manufacturerdata\",\">=\",24,\"index\",0,\"d506000a\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",12,4,true,true],\"post_proc\":[\"*\",175,\"/\",65535,\"-\",45]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",16,4,true,false],\"post_proc\":[\"*\",100,\"/\",65535]},\"co2\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",20,4,true,false]}}}"; + +/* R""""( +{ + "brand":"Sensirion", + "model":"MyCO₂/CO₂ Gadget", + "model_id":"SCD4X", + "tag":"0f", + "condition":["manufacturerdata", ">=", 24, "index", 0, "d5060008", "|", "manufacturerdata", ">=", 24, "index", 0, "d506000a"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "manufacturerdata", 12, 4, true, true], + "post_proc":["*", 175, "/", 65535, "-", 45] + }, + "hum":{ + "decoder":["value_from_hex_data", "manufacturerdata", 16, 4, true, false], + "post_proc":["*", 100, "/", 65535] + }, + "co2":{ + "decoder":["value_from_hex_data", "manufacturerdata", 20, 4, true, false] + } + } +})"""";*/ + +const char* _SCD4X_json_props = "{\"properties\":{\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"},\"co2\":{\"unit\":\"ppm\",\"name\":\"carbon dioxide\"}}}"; + +/* R""""( +{ + "properties":{ + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "hum":{ + "unit":"%", + "name":"humidity" + }, + "co2":{ + "unit":"ppm", + "name":"carbon dioxide" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/SHT4X_json.h b/lib/decoder/src/devices/SHT4X_json.h new file mode 100644 index 00000000..c6eed65a --- /dev/null +++ b/lib/decoder/src/devices/SHT4X_json.h @@ -0,0 +1,24 @@ +#include "common_props.h" + +const char* _SHT4X_json = "{\"brand\":\"Sensirion\",\"model\":\"TH Sensor\",\"model_id\":\"SHT4X\",\"tag\":\"01\",\"condition\":[\"manufacturerdata\",\">=\",20,\"index\",0,\"d5060006\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",12,4,true,true],\"post_proc\":[\"*\",175,\"/\",65535,\"-\",45]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",16,4,true,false],\"post_proc\":[\"*\",125,\"/\",65535,\"-\",6]}}}"; + +/* R""""( +{ + "brand":"Sensirion", + "model":"TH Sensor", + "model_id":"SHT4X", + "tag":"01", + "condition":["manufacturerdata", ">=", 20, "index", 0, "d5060006"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "manufacturerdata", 12, 4, true, true], + "post_proc":["*", 175, "/", 65535, "-", 45] + }, + "hum":{ + "decoder":["value_from_hex_data", "manufacturerdata", 16, 4, true, false], + "post_proc":["*", 125, "/", 65535, "-", 6] + } + } +})"""";*/ + +const char* _SHT4X_json_props = _common_TH_props; diff --git a/lib/decoder/src/devices/ServiceData_json.h b/lib/decoder/src/devices/ServiceData_json.h new file mode 100644 index 00000000..a2cd434c --- /dev/null +++ b/lib/decoder/src/devices/ServiceData_json.h @@ -0,0 +1,25 @@ +const char* _ServiceData_json = "{\"brand\":\"GENERIC\",\"model\":\"Service data\",\"model_id\":\"ServiceData\",\"tag\":\"08\",\"condition\":[\"uuid\",\"index\",0,\"180f\"],\"properties\":{\"batt\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",0,2,false,false]}}}"; +/*R""""( +{ + "brand":"GENERIC", + "model":"Service data", + "model_id":"ServiceData", + "tag":"08", + "condition":["uuid", "index", 0, "180f"], + "properties":{ + "batt":{ + "decoder":["value_from_hex_data", "servicedata", 0, 2, false, false] + } + } +})"""";*/ + +const char* _ServiceData_json_props = "{\"properties\":{\"batt\":{\"unit\":\"%\",\"name\":\"battery\"}}}"; +/*R""""( +{ + "properties":{ + "batt":{ + "unit":"%", + "name":"battery" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/Skale_json.h b/lib/decoder/src/devices/Skale_json.h new file mode 100644 index 00000000..5603f42e --- /dev/null +++ b/lib/decoder/src/devices/Skale_json.h @@ -0,0 +1,26 @@ +const char* _Skale_json = "{\"brand\":\"Atomax\",\"model\":\"Skale I/II\",\"model_id\":\"SKALE\",\"tag\":\"0501\",\"condition\":[\"manufacturerdata\",\"=\",12,\"index\",0,\"ef81\"],\"properties\":{\"weight\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",4,4,true,true],\"post_proc\":[\"/\",10]}}}"; +/*R""""( +{ + "brand":"Atomax", + "model":"Skale I/II", + "model_id":"SKALE", + "tag":"0501", + "condition":["manufacturerdata", "=", 12, "index", 0, "ef81"], + "properties":{ + "weight":{ + "decoder":["value_from_hex_data", "manufacturerdata", 4, 4, true, true], + "post_proc":["/", 10] + } + } +})"""";*/ + +const char* _Skale_json_props = "{\"properties\":{\"weight\":{\"unit\":\"g\",\"name\":\"weight\"}}}"; +/*R""""( +{ + "properties":{ + "weight":{ + "unit":"g", + "name":"weight" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/SmartDry_json.h b/lib/decoder/src/devices/SmartDry_json.h new file mode 100644 index 00000000..ed3a4e70 --- /dev/null +++ b/lib/decoder/src/devices/SmartDry_json.h @@ -0,0 +1,54 @@ +const char* _SmartDry_json = "{\"brand\":\"SmartDry\",\"model\":\"Laundry Sensor\",\"model_id\":\"SDLS\",\"tag\":\"ff01\",\"condition\":[\"manufacturerdata\",\"=\",28,\"index\",0,\"ae01\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",4,8,true,false,true]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",12,8,true,false,true]},\"shake\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",20,4,true,false]},\"volt\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",24,2,false,false],\"post_proc\":[\"+\",\"2847\",\"/\",1000]},\"wake\":{\"decoder\":[\"bit_static_value\",\"manufacturerdata\",27,0,false,true]}}}"; +/* R""""( +{ + "brand":"SmartDry", + "model":"Laundry Sensor", + "model_id":"SDLS", + "tag":"ff01", + "condition":["manufacturerdata", "=", 28, "index", 0, "ae01"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "manufacturerdata", 4, 8, true, false, true] + }, + "hum":{ + "decoder":["value_from_hex_data", "manufacturerdata", 12, 8, true, false, true] + }, + "shake":{ + "decoder":["value_from_hex_data", "manufacturerdata", 20, 4, true, false] + }, + "volt":{ + "decoder":["value_from_hex_data", "manufacturerdata", 24, 2, false, false], + "post_proc":["+", "2847", "/", 1000] + }, + "wake":{ + "decoder":["bit_static_value", "manufacturerdata", 27, 0, false, true] + } + } +})"""";*/ + +const char* _SmartDry_json_props = "{\"properties\":{\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"},\"shake\":{\"unit\":\"int\",\"name\":\"shake\"},\"volt\":{\"unit\":\"V\",\"name\":\"voltage\"},\"wake\":{\"unit\":\"status\",\"name\":\"wake\"}}}"; +/*R""""( +{ + "properties":{ + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "hum":{ + "unit":"%", + "name":"humidity" + }, + "shake":{ + "unit":"int", + "name":"shake" + }, + "volt":{ + "unit":"V", + "name":"voltage" + }, + "wake":{ + "unit":"status", + "name":"wake" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/T201_json.h b/lib/decoder/src/devices/T201_json.h new file mode 100644 index 00000000..08fbb747 --- /dev/null +++ b/lib/decoder/src/devices/T201_json.h @@ -0,0 +1,29 @@ +#include "common_props.h" + +const char* _T201_json = "{\"brand\":\"Oria\",\"model\":\"TH Sensor\",\"model_id\":\"T201\",\"tag\":\"0103\",\"condition\":[\"name\",\"index\",0,\"T201\",\"&\",\"manufacturerdata\",\">=\",38],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",24,4,false,true],\"post_proc\":[\"/\",100]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",28,4,false,false],\"post_proc\":[\"/\",100]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",32,2,false,false]},\"mac\":{\"decoder\":[\"mac_from_hex_data\",\"manufacturerdata\",8]}}}"; +/*R""""( +{ + "brand":"Oria", + "model":"TH Sensor", + "model_id":"T201", + "tag":"0103", + "condition":["name", "index", 0, "T201", "&", "manufacturerdata", ">=", 38], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "manufacturerdata", 24, 4, false, true], + "post_proc":["/", 100] + }, + "hum":{ + "decoder":["value_from_hex_data", "manufacturerdata", 28, 4, false, false], + "post_proc":["/", 100] + }, + "batt":{ + "decoder":["value_from_hex_data", "manufacturerdata", 32, 2, false, false] + }, + "mac":{ + "decoder":["mac_from_hex_data", "manufacturerdata", 8] + } + } +})"""";*/ + +const char* _T201_json_props = _common_BTHM_props; diff --git a/lib/decoder/src/devices/T301_json.h b/lib/decoder/src/devices/T301_json.h new file mode 100644 index 00000000..10539a23 --- /dev/null +++ b/lib/decoder/src/devices/T301_json.h @@ -0,0 +1,29 @@ +#include "common_props.h" + +const char* _T301_json = "{\"brand\":\"Oria\",\"model\":\"TH Sensor\",\"model_id\":\"T301\",\"tag\":\"0103\",\"condition\":[\"name\",\"index\",0,\"T301\",\"&\",\"manufacturerdata\",\"=\",38],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",24,4,false,true],\"post_proc\":[\"/\",100]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",28,4,false,false],\"post_proc\":[\"/\",100]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",32,2,false,false]},\"mac\":{\"decoder\":[\"mac_from_hex_data\",\"manufacturerdata\",8]}}}"; +/*R""""( +{ + "brand":"Oria", + "model":"TH Sensor", + "model_id":"T301", + "tag":"0103", + "condition":["name", "index", 0, "T301", "&", "manufacturerdata", "=", 38], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "manufacturerdata", 24, 4, false, true], + "post_proc":["/", 100] + }, + "hum":{ + "decoder":["value_from_hex_data", "manufacturerdata", 28, 4, false, false], + "post_proc":["/", 100] + }, + "batt":{ + "decoder":["value_from_hex_data", "manufacturerdata", 32, 2, false, false] + }, + "mac":{ + "decoder":["mac_from_hex_data", "manufacturerdata", 8] + } + } +})"""";*/ + +const char* _T301_json_props = _common_BTHM_props; diff --git a/lib/decoder/src/devices/TPMS_json.h b/lib/decoder/src/devices/TPMS_json.h new file mode 100644 index 00000000..b177b819 --- /dev/null +++ b/lib/decoder/src/devices/TPMS_json.h @@ -0,0 +1,64 @@ +const char* _TPMS_json = "{\"brand\":\"GENERIC\",\"model\":\"TPMS\",\"model_id\":\"TPMS\",\"tag\":\"0a01\",\"condition\":[\"manufacturerdata\",\"=\",36,\"index\",0,\"000\",\"&\",\"manufacturerdata\",\"mac@index\",4],\"conditionnomac\":[\"manufacturerdata\",\"=\",36,\"&\",\"name\",\"index\",0,\"TPMS\"],\"properties\":{\"count\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",5,1,false],\"post_proc\":[\"+\",1]},\"pres\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",16,8,true],\"post_proc\":[\"/\",100000]},\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",24,8,true],\"post_proc\":[\"/\",100]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",32,2,true]},\"alarm\":{\"decoder\":[\"bit_static_value\",\"manufacturerdata\",35,0,false,true]},\"mac\":{\"decoder\":[\"mac_from_hex_data\",\"manufacturerdata\",4]}}}"; +/*R""""( +{ + "brand":"GENERIC", + "model":"TPMS", + "model_id":"TPMS", + "tag":"0a01", + "condition":["manufacturerdata", "=", 36, "index", 0, "000", "&", "manufacturerdata", "mac@index", 4], + "conditionnomac":["manufacturerdata", "=", 36, "&", "name", "index", 0, "TPMS"], + "properties":{ + "count":{ + "decoder":["value_from_hex_data", "manufacturerdata", 5, 1, false], + "post_proc":["+", 1] + }, + "pres":{ + "decoder":["value_from_hex_data", "manufacturerdata", 16, 8, true], + "post_proc":["/", 100000] + }, + "tempc":{ + "decoder":["value_from_hex_data", "manufacturerdata", 24, 8, true], + "post_proc":["/", 100] + }, + "batt":{ + "decoder":["value_from_hex_data", "manufacturerdata", 32, 2, true] + }, + "alarm":{ + "decoder":["bit_static_value", "manufacturerdata", 35, 0, false, true] + }, + "mac":{ + "decoder":["mac_from_hex_data", "manufacturerdata", 4] + } + } +})"""";*/ + +const char* _TPMS_json_props = "{\"properties\":{\"batt\":{\"unit\":\"%\",\"name\":\"battery\"},\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"pres\":{\"unit\":\"bar\",\"name\":\"pressure\"},\"count\":{\"unit\":\"int\",\"name\":\"count\"},\"alarm\":{\"unit\":\"status\",\"name\":\"alarm\"},\"mac\":{\"unit\":\"string\",\"name\":\"MAC address\"}}}"; +/*R""""( +{ + "properties":{ + "batt":{ + "unit":"%", + "name":"battery" + }, + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "pres":{ + "unit":"bar", + "name":"pressure" + }, + "count":{ + "unit":"int", + "name":"count" + }, + "alarm":{ + "unit":"status", + "name":"alarm" + }, + "mac":{ + "unit":"string", + "name":"MAC address" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/TPTH_json.h b/lib/decoder/src/devices/TPTH_json.h new file mode 100644 index 00000000..8bc38c24 --- /dev/null +++ b/lib/decoder/src/devices/TPTH_json.h @@ -0,0 +1,22 @@ +#include "common_props.h" + +const char* _TPTH_json = "{\"brand\":\"ThermoPro\",\"model\":\"TH Sensor\",\"model_id\":\"TP35X/393\",\"tag\":\"0103\",\"condition\":[\"name\",\"index\",0,\"TP357\",\"|\",\"name\",\"index\",0,\"TP358\",\"|\",\"name\",\"index\",0,\"TP359\",\"|\",\"name\",\"index\",0,\"TP393\",\"&\",\"manufacturerdata\",\">=\",12,\"index\",0,\"c2\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",2,4,true,true],\"post_proc\":[\"/\",10]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",6,2,false,false]}}}"; +/*R""""( +{ + "brand":"ThermoPro", + "model":"TH Sensor", + "model_id":"TP35X/393", + "tag":"0103", + "condition":["name", "index", 0, "TP357", "|", "name", "index", 0, "TP358", "|", "name", "index", 0, "TP359", "|", "name", "index", 0, "TP393", "&", "manufacturerdata", ">=", 12, "index", 0, "c2"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "manufacturerdata", 2, 4, true, true], + "post_proc":["/", 10] + }, + "hum":{ + "decoder":["value_from_hex_data", "manufacturerdata", 6, 2, false, false] + } + } +})"""";*/ + +const char* _TPTH_json_props = _common_TH_props; diff --git a/lib/decoder/src/devices/ThermoBeacon_json.h b/lib/decoder/src/devices/ThermoBeacon_json.h new file mode 100644 index 00000000..b060dcd9 --- /dev/null +++ b/lib/decoder/src/devices/ThermoBeacon_json.h @@ -0,0 +1,94 @@ +const char* _ThermoBeacon_json = "{\"brand\":\"GENERIC\",\"model\":\"ThermoBeacon\",\"model_id\":\"WS02/WS08\",\"tag\":\"0101\",\"condition\":[\"manufacturerdata\",\"index\",0,\"1000\",\"|\",\"manufacturerdata\",\"index\",0,\"1100\",\"|\",\"manufacturerdata\",\"index\",0,\"1500\",\"|\",\"manufacturerdata\",\"index\",0,\"1800\",\"|\",\"manufacturerdata\",\"index\",0,\"1b00\",\"&\",\"manufacturerdata\",\">=\",40],\"properties\":{\"tempc\":{\"condition\":[\"manufacturerdata\",\"=\",40],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",24,4,true],\"post_proc\":[\"/\",16]},\"hum\":{\"condition\":[\"manufacturerdata\",\"=\",40],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",28,4,true],\"post_proc\":[\"/\",16]},\"volt\":{\"condition\":[\"manufacturerdata\",\"=\",40],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",20,4,true],\"post_proc\":[\"/\",1000]},\"time\":{\"condition\":[\"manufacturerdata\",\"=\",40],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",32,8,true,false]},\"tempc_max\":{\"condition\":[\"manufacturerdata\",\"=\",44],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",20,4,true],\"post_proc\":[\"/\",16]},\"time_max\":{\"condition\":[\"manufacturerdata\",\"=\",44],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",24,8,true,false]},\"tempc_min\":{\"condition\":[\"manufacturerdata\",\"=\",44],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",32,4,true],\"post_proc\":[\"/\",16]},\"time_min\":{\"condition\":[\"manufacturerdata\",\"=\",44],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",36,8,true,false]},\"mac\":{\"decoder\":[\"revmac_from_hex_data\",\"manufacturerdata\",8]}}}"; +/*R""""( +{ + "brand":"GENERIC", + "model":"ThermoBeacon", + "model_id":"WS02/WS08", + "tag":"0101", + "condition":["manufacturerdata", "index", 0, "1000", "|", "manufacturerdata", "index", 0, "1100", "|", "manufacturerdata", "index", 0, "1500", "|", "manufacturerdata", "index", 0, "1800", "|", "manufacturerdata", "index", 0, "1b00", "&", "manufacturerdata", ">=", 40], + "properties":{ + "tempc":{ + "condition":["manufacturerdata", "=", 40], + "decoder":["value_from_hex_data", "manufacturerdata", 24, 4, true], + "post_proc":["/", 16] + }, + "hum":{ + "condition":["manufacturerdata", "=", 40], + "decoder":["value_from_hex_data", "manufacturerdata", 28, 4, true], + "post_proc":["/", 16] + }, + "volt":{ + "condition":["manufacturerdata", "=", 40], + "decoder":["value_from_hex_data", "manufacturerdata", 20, 4, true], + "post_proc":["/", 1000] + }, + "time":{ + "condition":["manufacturerdata", "=", 40], + "decoder":["value_from_hex_data", "manufacturerdata", 32, 8, true, false] + }, + "tempc_max":{ + "condition":["manufacturerdata", "=", 44], + "decoder":["value_from_hex_data", "manufacturerdata", 20, 4, true], + "post_proc":["/", 16] + }, + "time_max":{ + "condition":["manufacturerdata", "=", 44], + "decoder":["value_from_hex_data", "manufacturerdata", 24, 8, true, false] + }, + "tempc_min":{ + "condition":["manufacturerdata", "=", 44], + "decoder":["value_from_hex_data", "manufacturerdata", 32, 4, true], + "post_proc":["/", 16] + }, + "time_min":{ + "condition":["manufacturerdata", "=", 44], + "decoder":["value_from_hex_data", "manufacturerdata", 36, 8, true, false] + }, + "mac":{ + "decoder":["revmac_from_hex_data", "manufacturerdata", 8] + } + } +})"""";*/ + +const char* _ThermoBeacon_json_props = "{\"properties\":{\"volt\":{\"unit\":\"V\",\"name\":\"voltage\"},\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"},\"time\":{\"unit\":\"int\",\"name\":\"timestamp\"},\"tempc_max\":{\"unit\":\"°C\",\"name\":\"maximum temperature\"},\"time_max\":{\"unit\":\"int\",\"name\":\"maximum temperature timestamp\"},\"tempc_min\":{\"unit\":\"°C\",\"name\":\"minimum temperature\"},\"time_min\":{\"unit\":\"int\",\"name\":\"minimum temperature timestamp\"},\"mac\":{\"unit\":\"string\",\"name\":\"MAC address\"}}}"; +/*R""""( +{ + "properties":{ + "volt":{ + "unit":"V", + "name":"voltage" + }, + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "hum":{ + "unit":"%", + "name":"humidity" + }, + "time":{ + "unit":"int", + "name":"timestamp" + }, + "tempc_max":{ + "unit":"°C", + "name":"maximum temperature" + }, + "time_max":{ + "unit":"int", + "name":"maximum temperature timestamp" + }, + "tempc_min":{ + "unit":"°C", + "name":"minimum temperature" + }, + "time_min":{ + "unit":"int", + "name":"minimum temperature timestamp" + }, + "mac":{ + "unit":"string", + "name":"MAC address" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/XMTZC04HMKG_json.h b/lib/decoder/src/devices/XMTZC04HMKG_json.h new file mode 100644 index 00000000..2a200212 --- /dev/null +++ b/lib/decoder/src/devices/XMTZC04HMKG_json.h @@ -0,0 +1,40 @@ +const char* _XMTZC04HMKG_json = "{\"brand\":\"Xiaomi\",\"model\":\"Mi Smart Scale\",\"model_id\":\"XMTZC01HM/XMTZC04HM\",\"tag\":\"05\",\"condition\":[\"servicedata\",\"index\",0,\"22\",\"|\",\"servicedata\",\"index\",0,\"a2\",\"|\",\"servicedata\",\"index\",0,\"62\",\"|\",\"servicedata\",\"index\",0,\"e2\",\"&\",\"servicedata\",\"=\",20,\"&\",\"uuid\",\"contain\",\"181d\"],\"properties\":{\"weighing_mode\":{\"decoder\":[\"bit_static_value\",\"servicedata\",0,2,\"person\",\"object\"]},\"unit\":{\"decoder\":[\"static_value\",\"kg\"]},\"weight\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",2,4,true,false],\"post_proc\":[\"/\",200]}}}"; +/*R""""( +{ + "brand":"Xiaomi", + "model":"Mi Smart Scale", + "model_id":"XMTZC01HM/XMTZC04HM", + "tag":"05", + "condition":["servicedata", "index", 0, "22", "|", "servicedata", "index", 0, "a2", "|", "servicedata", "index", 0, "62", "|", "servicedata", "index", 0, "e2", "&", "servicedata", "=", 20, "&", "uuid", "contain", "181d"], + "properties":{ + "weighing_mode":{ + "decoder":["bit_static_value", "servicedata", 0, 2, "person", "object"] + }, + "unit":{ + "decoder":["static_value", "kg"] + }, + "weight":{ + "decoder":["value_from_hex_data", "servicedata", 2, 4, true, false], + "post_proc":["/", 200] + } + } +})"""";*/ + +const char* _XMTZC04HMKG_json_props = "{\"properties\":{\"weighing_mode\":{\"unit\":\"string\",\"name\":\"weighing_mode\"},\"unit\":{\"unit\":\"string\",\"name\":\"unit\"},\"weight\":{\"unit\":\"kg\",\"name\":\"weight\"}}}"; +/*R""""( +{ + "properties":{ + "weighing_mode":{ + "unit":"string", + "name":"weighing_mode" + }, + "unit":{ + "unit":"string", + "name":"unit" + }, + "weight":{ + "unit":"kg", + "name":"weight" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/XMTZC04HMLB_json.h b/lib/decoder/src/devices/XMTZC04HMLB_json.h new file mode 100644 index 00000000..f45f78d8 --- /dev/null +++ b/lib/decoder/src/devices/XMTZC04HMLB_json.h @@ -0,0 +1,40 @@ +const char* _XMTZC04HMLB_json = "{\"brand\":\"Xiaomi\",\"model\":\"Mi Smart Scale\",\"model_id\":\"XMTZC01HM/XMTZC04HM\",\"tag\":\"05\",\"condition\":[\"servicedata\",\"index\",0,\"23\",\"|\",\"servicedata\",\"index\",0,\"a3\",\"|\",\"servicedata\",\"index\",0,\"63\",\"|\",\"servicedata\",\"index\",0,\"e3\",\"&\",\"servicedata\",\"=\",20,\"&\",\"uuid\",\"contain\",\"181d\"],\"properties\":{\"weighing_mode\":{\"decoder\":[\"bit_static_value\",\"servicedata\",0,2,\"person\",\"object\"]},\"unit\":{\"decoder\":[\"static_value\",\"lb\"]},\"weight\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",2,4,true,false],\"post_proc\":[\"/\",100]}}}"; +/*R""""( +{ + "brand":"Xiaomi", + "model":"Mi Smart Scale", + "model_id":"XMTZC01HM/XMTZC04HM", + "tag":"05", + "condition":["servicedata", "index", 0, "23", "|", "servicedata", "index", 0, "a3", "|", "servicedata", "index", 0, "63", "|", "servicedata", "index", 0, "e3", "&", "servicedata", "=", 20, "&", "uuid", "contain", "181d"], + "properties":{ + "weighing_mode":{ + "decoder":["bit_static_value", "servicedata", 0, 2, "person", "object"] + }, + "unit":{ + "decoder":["static_value", "lb"] + }, + "weight":{ + "decoder":["value_from_hex_data", "servicedata", 2, 4, true, false], + "post_proc":["/", 100] + } + } +})"""";*/ + +const char* _XMTZC04HMLB_json_props = "{\"properties\":{\"weighing_mode\":{\"unit\":\"string\",\"name\":\"weighing_mode\"},\"unit\":{\"unit\":\"string\",\"name\":\"unit\"},\"weight\":{\"unit\":\"lb\",\"name\":\"weight\"}}}"; +/*R""""( +{ + "properties":{ + "weighing_mode":{ + "unit":"string", + "name":"weighing_mode" + }, + "unit":{ + "unit":"string", + "name":"unit" + }, + "weight":{ + "unit":"lb", + "name":"weight" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/XMTZC05HMKG_json.h b/lib/decoder/src/devices/XMTZC05HMKG_json.h new file mode 100644 index 00000000..45c2bd3c --- /dev/null +++ b/lib/decoder/src/devices/XMTZC05HMKG_json.h @@ -0,0 +1,48 @@ +const char* _XMTZC05HMKG_json = "{\"brand\":\"Xiaomi\",\"model\":\"Mi Body Composition Scale\",\"model_id\":\"XMTZC02HM/XMTZC05HM\",\"tag\":\"05\",\"condition\":[\"servicedata\",\"index\",1,\"22\",\"|\",\"servicedata\",\"index\",1,\"2a\",\"|\",\"servicedata\",\"index\",1,\"62\",\"|\",\"servicedata\",\"index\",1,\"6a\",\"&\",\"servicedata\",\"=\",26,\"&\",\"uuid\",\"contain\",\"181b\"],\"properties\":{\"weighing_mode\":{\"decoder\":[\"bit_static_value\",\"servicedata\",1,2,\"person\",\"object\"]},\"unit\":{\"decoder\":[\"static_value\",\"kg\"]},\"weight\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",22,4,true,false],\"post_proc\":[\"/\",200]},\"impedance\":{\"condition\":[\"servicedata\",3,\"6\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",18,4,true,false]}}}"; +/*R""""( +{ + "brand":"Xiaomi", + "model":"Mi Body Composition Scale", + "model_id":"XMTZC02HM/XMTZC05HM", + "tag":"05", + "condition":["servicedata", "index", 1, "22", "|", "servicedata", "index", 1, "2a", "|", "servicedata", "index", 1, "62", "|", "servicedata", "index", 1, "6a", "&", "servicedata", "=", 26, "&", "uuid", "contain", "181b"], + "properties":{ + "weighing_mode":{ + "decoder":["bit_static_value", "servicedata", 1, 2, "person", "object"] + }, + "unit":{ + "decoder":["static_value", "kg"] + }, + "weight":{ + "decoder":["value_from_hex_data", "servicedata", 22, 4, true, false], + "post_proc":["/", 200] + }, + "impedance":{ + "condition":["servicedata", 3, "6"], + "decoder":["value_from_hex_data", "servicedata", 18, 4, true, false] + } + } +})"""";*/ + +const char* _XMTZC05HMKG_json_props = "{\"properties\":{\"weighing_mode\":{\"unit\":\"string\",\"name\":\"weighing_mode\"},\"unit\":{\"unit\":\"string\",\"name\":\"unit\"},\"weight\":{\"unit\":\"kg\",\"name\":\"weight\"},\"impedance\":{\"unit\":\"Ω\",\"name\":\"impedance\"}}}"; +/*R""""( +{ + "properties":{ + "weighing_mode":{ + "unit":"string", + "name":"weighing_mode" + }, + "unit":{ + "unit":"string", + "name":"unit" + }, + "weight":{ + "unit":"kg", + "name":"weight" + }, + "impedance":{ + "unit":"Ω", + "name":"impedance" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/XMTZC05HMLB_json.h b/lib/decoder/src/devices/XMTZC05HMLB_json.h new file mode 100644 index 00000000..e53fade5 --- /dev/null +++ b/lib/decoder/src/devices/XMTZC05HMLB_json.h @@ -0,0 +1,48 @@ +const char* _XMTZC05HMLB_json = "{\"brand\":\"Xiaomi\",\"model\":\"Mi Body Composition Scale\",\"model_id\":\"XMTZC02HM/XMTZC05HM\",\"tag\":\"05\",\"condition\":[\"servicedata\",\"index\",1,\"32\",\"|\",\"servicedata\",\"index\",1,\"3a\",\"|\",\"servicedata\",\"index\",1,\"72\",\"|\",\"servicedata\",\"index\",1,\"7a\",\"&\",\"servicedata\",\"=\",26,\"&\",\"uuid\",\"contain\",\"181b\"],\"properties\":{\"weighing_mode\":{\"decoder\":[\"bit_static_value\",\"servicedata\",1,2,\"person\",\"object\"]},\"unit\":{\"decoder\":[\"static_value\",\"lb\"]},\"weight\":{\"decoder\":[\"value_from_hex_data\",\"servicedata\",22,4,true,false],\"post_proc\":[\"/\",100]},\"impedance\":{\"condition\":[\"servicedata\",3,\"6\"],\"decoder\":[\"value_from_hex_data\",\"servicedata\",18,4,true,false]}}}"; +/*R""""( +{ + "brand":"Xiaomi", + "model":"Mi Body Composition Scale", + "model_id":"XMTZC02HM/XMTZC05HM", + "tag":"05", + "condition":["servicedata", "index", 1, "32", "|", "servicedata", "index", 1, "3a", "|", "servicedata", "index", 1, "72", "|", "servicedata", "index", 1, "7a", "&", "servicedata", "=", 26, "&", "uuid", "contain", "181b"], + "properties":{ + "weighing_mode":{ + "decoder":["bit_static_value", "servicedata", 1, 2, "person", "object"] + }, + "unit":{ + "decoder":["static_value", "lb"] + }, + "weight":{ + "decoder":["value_from_hex_data", "servicedata", 22, 4, true, false], + "post_proc":["/", 100] + }, + "impedance":{ + "condition":["servicedata", 3, "6"], + "decoder":["value_from_hex_data", "servicedata", 18, 4, true, false] + } + } +})"""";*/ + +const char* _XMTZC05HMLB_json_props = "{\"properties\":{\"weighing_mode\":{\"unit\":\"string\",\"name\":\"weighing_mode\"},\"unit\":{\"unit\":\"string\",\"name\":\"unit\"},\"weight\":{\"unit\":\"lb\",\"name\":\"weight\"},\"impedance\":{\"unit\":\"Ω\",\"name\":\"impedance\"}}}"; +/*R""""( +{ + "properties":{ + "weighing_mode":{ + "unit":"string", + "name":"weighing_mode" + }, + "unit":{ + "unit":"string", + "name":"unit" + }, + "weight":{ + "unit":"lb", + "name":"weight" + }, + "impedance":{ + "unit":"Ω", + "name":"impedance" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/common_props.h b/lib/decoder/src/devices/common_props.h new file mode 100644 index 00000000..509bd33c --- /dev/null +++ b/lib/decoder/src/devices/common_props.h @@ -0,0 +1,90 @@ +#ifndef _DECODER_COMMON_PROPS +#define _DECODER_COMMON_PROPS + +const char* _common_TH_props = "{\"properties\":{\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"}}}"; +/*R""""( +{ + "properties":{ + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "hum":{ + "unit":"%", + "name":"humidity" + } + } +})"""";*/ + +const char* _common_BTH_props = "{\"properties\":{\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"},\"batt\":{\"unit\":\"%\",\"name\":\"battery\"}}}"; +/* +R""""( +{ + "properties":{ + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "hum":{ + "unit":"%", + "name":"humidity" + }, + "batt":{ + "unit":"%", + "name":"battery" + } + } +})"""";*/ + +const char* _common_BTHM_props = "{\"properties\":{\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"},\"batt\":{\"unit\":\"%\",\"name\":\"battery\"},\"mac\":{\"unit\":\"string\",\"name\":\"MAC address\"}}}"; +/* +R""""( +{ + "properties":{ + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "hum":{ + "unit":"%", + "name":"humidity" + }, + "batt":{ + "unit":"%", + "name":"battery" + }, + "mac":{ + "unit":"string", + "name":"MAC address" + } + } +})"""";*/ + +const char* _common_BVTH_props = "{\"properties\":{\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"},\"batt\":{\"unit\":\"%\",\"name\":\"battery\"},\"volt\":{\"unit\":\"V\",\"name\":\"voltage\"},\"mac\":{\"unit\":\"string\",\"name\":\"MAC address\"}}}"; +/*R""""( +{ + "properties":{ + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "hum":{ + "unit":"%", + "name":"humidity" + }, + "batt":{ + "unit":"%", + "name":"battery" + }, + "volt":{ + "unit":"V", + "name":"voltage" + }, + "mac":{ + "unit":"string", + "name":"MAC address" + } + } +})"""";*/ + +#endif diff --git a/lib/decoder/src/devices/iBeacon_json.h b/lib/decoder/src/devices/iBeacon_json.h new file mode 100644 index 00000000..a97f80f4 --- /dev/null +++ b/lib/decoder/src/devices/iBeacon_json.h @@ -0,0 +1,64 @@ +const char* _ibeacon_json = "{\"brand\":\"GENERIC\",\"model\":\"iBeacon\",\"model_id\":\"IBEACON\",\"tag\":\"06\",\"condition\":[\"manufacturerdata\",\"=\",50,\"index\",0,\"4c00\"],\"properties\":{\"mfid\":{\"decoder\":[\"string_from_hex_data\",\"manufacturerdata\",0,4]},\"uuid\":{\"decoder\":[\"string_from_hex_data\",\"manufacturerdata\",8,32]},\"major\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",40,4,false]},\"minor\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",44,4,false]},\"txpower\":{\"condition\":[\"manufacturerdata\",48,\"bit\",3,1],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",48,2,false]},\"volt\":{\"condition\":[\"manufacturerdata\",48,\"bit\",3,0],\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",48,2,false],\"post_proc\":[\"/\",10]}}}"; + +/*R""""( +{ + "brand":"GENERIC", + "model":"iBeacon", + "model_id":"IBEACON", + "tag":"06", + "condition":["manufacturerdata", "=", 50, "index", 0, "4c00"], + "properties":{ + "mfid":{ + "decoder":["string_from_hex_data", "manufacturerdata", 0, 4] + }, + "uuid":{ + "decoder":["string_from_hex_data", "manufacturerdata", 8, 32] + }, + "major":{ + "decoder":["value_from_hex_data", "manufacturerdata", 40, 4, false] + }, + "minor":{ + "decoder":["value_from_hex_data", "manufacturerdata", 44, 4, false] + }, + "txpower":{ + "condition":["manufacturerdata", 48, "bit", 3, 1], + "decoder":["value_from_hex_data","manufacturerdata", 48, 2, false] + }, + "volt":{ + "condition":["manufacturerdata", 48, "bit", 3, 0], + "decoder":["value_from_hex_data","manufacturerdata", 48, 2, false], + "post_proc":["/", 10] + } + } +})"""";*/ + +const char* _ibeacon_json_props = "{\"properties\":{\"mfid\":{\"unit\":\"hex\",\"name\":\"manufacturer id\"},\"uuid\":{\"unit\":\"hex\",\"name\":\"service uuid\"},\"major\":{\"unit\":\"hex\",\"name\":\"major value\"},\"minor\":{\"unit\":\"hex\",\"name\":\"minor value\"},\"txpower\":{\"unit\":\"dBm\",\"name\":\"tx power @ 1 m\"},\"volt\":{\"unit\":\"V\",\"name\":\"voltage\"}}}"; +/*R""""( +{ + "properties":{ + "mfid":{ + "unit":"hex", + "name":"manufacturer id" + }, + "uuid":{ + "unit":"hex", + "name":"service uuid" + }, + "major":{ + "unit":"hex", + "name":"major value" + }, + "minor":{ + "unit":"hex", + "name":"minor value" + }, + "txpower":{ + "unit":"dBm", + "name":"tx power @ 1 m" + }, + "volt":{ + "unit":"V", + "name":"voltage" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/iNodeEM_json.h b/lib/decoder/src/devices/iNodeEM_json.h new file mode 100644 index 00000000..dc033ae6 --- /dev/null +++ b/lib/decoder/src/devices/iNodeEM_json.h @@ -0,0 +1,72 @@ +const char* _iNodeEM_json = "{\"brand\":\"iNode\",\"model\":\"Energy Meter\",\"model_id\":\"INEM\",\"tag\":\"0c01\",\"condition\":[\"manufacturerdata\",\"index\",0,\"90\",\"|\",\"manufacturerdata\",\"index\",0,\"92\",\"|\",\"manufacturerdata\",\"index\",0,\"94\",\"|\",\"manufacturerdata\",\"index\",0,\"96\",\"&\",\"manufacturerdata\",\"=\",26,\"index\",2,\"82\"],\"properties\":{\".cal\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",16,4,true,false],\"post_proc\":[\"&\",16383]},\"avg\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",4,4,true,false],\"post_proc\":[\"*\",60,\"/\",\".cal\"]},\"avgu\":{\"decoder\":[\"bit_static_value\",\"manufacturerdata\",18,0,\"kW\",\"m³\"]},\"sum\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",8,4,true,false],\"post_proc\":[\"/\",\".cal\"]},\"sumu\":{\"decoder\":[\"bit_static_value\",\"manufacturerdata\",18,0,\"kWh\",\"m³\"]},\"batt\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",20,1,false,false],\"post_proc\":[\"-\",1,\"*\",10]},\"_batt\":{\"condition\":[\"manufacturerdata\",20,\"1\",\"|\",\"manufacturerdata\",20,\"c\",\"|\",\"manufacturerdata\",20,\"d\",\"|\",\"manufacturerdata\",20,\"e\",\"|\",\"manufacturerdata\",20,\"f\"],\"decoder\":[\"static_value\",\"100\"]},\"lowbatt\":{\"condition\":[\"manufacturerdata\",1,\"bit\",2,1],\"decoder\":[\"static_value\",true]}}}"; +/*R""""( +{ + "brand":"iNode", + "model":"Energy Meter", + "model_id":"INEM", + "tag":"0c01", + "condition":["manufacturerdata", "index", 0, "90", "|", "manufacturerdata", "index", 0, "92", "|", "manufacturerdata", "index", 0, "94", "|", "manufacturerdata", "index", 0, "96", "&", "manufacturerdata", "=", 26, "index", 2, "82"], + "properties":{ + ".cal":{ + "decoder":["value_from_hex_data", "manufacturerdata", 16, 4, true, false], + "post_proc":["&", 16383] + }, + "avg":{ + "decoder":["value_from_hex_data", "manufacturerdata", 4, 4, true, false], + "post_proc":[ "*", 60, "/", ".cal"] + }, + "avgu":{ + "decoder":["bit_static_value", "manufacturerdata", 18, 0, "kW", "m³"] + }, + "sum":{ + "decoder":["value_from_hex_data", "manufacturerdata", 8, 4, true, false], + "post_proc":["/", ".cal"] + }, + "sumu":{ + "decoder":["bit_static_value", "manufacturerdata", 18, 0, "kWh", "m³"] + }, + "batt":{ + "decoder":["value_from_hex_data", "manufacturerdata", 20, 1, false, false], + "post_proc":["-", 1, "*", 10] + }, + "_batt":{ + "condition":["manufacturerdata", 20, "1", "|", "manufacturerdata", 20, "c", "|", "manufacturerdata", 20, "d", "|", "manufacturerdata", 20, "e", "|", "manufacturerdata", 20, "f"], + "decoder":["static_value", "100"] + }, + "lowbatt":{ + "condition":["manufacturerdata", 1, "bit", 2, 1], + "decoder":["static_value", true] + } + } +})"""";*/ + +const char* _iNodeEM_json_props = "{\"properties\":{\"avg\":{\"unit\":\"kW/m³\",\"name\":\"average\"},\"avgu\":{\"unit\":\"string\",\"name\":\"average unit\"},\"sum\":{\"unit\":\"kWh/m³\",\"name\":\"sum\"},\"sumu\":{\"unit\":\"string\",\"name\":\"sum unit\"},\"batt\":{\"unit\":\"%\",\"name\":\"battery\"},\"lowbatt\":{\"unit\":\"status\",\"name\":\"low battery\"}}}"; +/*R""""( +{ + "properties":{ + "avg":{ + "unit":"kW/m³", + "name":"average" + }, + "avgu":{ + "unit":"string", + "name":"average unit" + }, + "sum":{ + "unit":"kWh/m³", + "name":"sum" + }, + "sumu":{ + "unit":"string", + "name":"sum unit" + }, + "batt":{ + "unit":"%", + "name":"battery" + }, + "lowbatt":{ + "unit":"status", + "name":"low battery" + } + } +})"""";*/ diff --git a/lib/decoder/src/devices/tracker_json.h b/lib/decoder/src/devices/tracker_json.h new file mode 100644 index 00000000..afe30667 --- /dev/null +++ b/lib/decoder/src/devices/tracker_json.h @@ -0,0 +1,85 @@ +const char* _tracker_json_nut = "{\"brand\":\"nut\",\"model\":\"Smart Tracker\",\"model_id\":\"NUT\",\"tag\":\"100f\",\"condition\":[\"name\",\"index\",0,\"nut\",\"&\",\"manufacturerdata\",\"=\",8,\"&\",\"uuid\",\"index\",0,\"180a\"],\"properties\":{\"device\":{\"decoder\":[\"static_value\",\"nut Tracker\"]}}}"; +/*R""""( +{ + "brand":"nut", + "model":"Smart Tracker", + "model_id":"NUT", + "tag":"100f", + "condition":["name", "index", 0, "nut", "&", "manufacturerdata", "=", 8, "&", "uuid", "index", 0, "180a"], + "properties":{ + "device":{ + "decoder":["static_value", "nut Tracker"] + } + } +})"""";*/ + +const char* _tracker_json_itag = "{\"brand\":\"iTAG\",\"model\":\"Smart Tracker\",\"model_id\":\"ITAG\",\"tag\":\"100f\",\"condition\":[\"name\",\"index\",0,\"iTAG\",\"&\",\"manufacturerdata\",\"=\",8],\"properties\":{\"device\":{\"decoder\":[\"static_value\",\"iTAG Tracker\"]}}}"; +/*R""""( +{ + "brand":"iTAG", + "model":"Smart Tracker", + "model_id":"ITAG", + "tag":"100f", + "condition":["name", "index", 0, "iTAG", "&", "manufacturerdata", "=", 8], + "properties":{ + "device":{ + "decoder":["static_value", "iTAG Tracker"] + } + } +})"""";*/ + +const char* _tracker_json_tagit = "{\"brand\":\"Tag-It\",\"model\":\"Smart Tracker\",\"model_id\":\"TAGIT\",\"tag\":\"100f\",\"condition\":[\"name\",\"index\",0,\"Tag-It\",\"&\",\"manufacturerdata\",\"=\",26],\"properties\":{\"device\":{\"decoder\":[\"static_value\",\"Tag-It Tracker\"]}}}"; +/*R""""( +{ + "brand":"Tag-It", + "model":"Smart Tracker", + "model_id":"TAGIT", + "tag":"100f", + "condition":["name", "index", 0, "Tag-It", "&", "manufacturerdata", "=", 26], + "properties":{ + "device":{ + "decoder":["static_value", "Tag-It Tracker"] + } + } +})"""";*/ + +const char* _tracker_json_tile = "{\"brand\":\"Tile\",\"model\":\"Smart Tracker\",\"model_id\":\"TILE\",\"tag\":\"100f\",\"condition\":[\"uuid\",\"index\",0,\"feed\",\"|\",\"uuid\",\"index\",0,\"feec\",\"|\",\"uuid\",\"index\",0,\"fd84\"],\"properties\":{\"device\":{\"decoder\":[\"static_value\",\"Tile Tracker\"]}}}"; +/*R""""( +{ + "brand":"Tile", + "model":"Smart Tracker", + "model_id":"TILE", + "tag":"100f", + "condition":["uuid", "index", 0, "feed", "|", "uuid", "index", 0, "feec", "|", "uuid", "index", 0, "fd84"], + "properties":{ + "device":{ + "decoder":["static_value", "Tile Tracker"] + } + } +})"""";*/ + +const char* _tracker_json_tilename = "{\"brand\":\"Tile\",\"model\":\"Smart Tracker\",\"model_id\":\"TILE\",\"tag\":\"100f\",\"condition\":[\"name\",\"index\",0,\"Tile\"],\"properties\":{\"device\":{\"decoder\":[\"static_value\",\"Tile Tracker\"]}}}"; +/*R""""( +{ + "brand":"Tile", + "model":"Smart Tracker", + "model_id":"TILE", + "tag":"100f", + "condition":["name", "index", 0, "Tile"], + "properties":{ + "device":{ + "decoder":["static_value", "Tile Tracker"] + } + } +})"""";*/ + +const char* _tracker_json_props = "{\"properties\":{\"device\":{\"unit\":\"string\",\"name\":\"tracker device\"}}}"; +/*R""""( +{ + "properties":{ + "device":{ + "unit":"string", + "name":"tracker device" + } + } +})"""";*/ diff --git a/src/modules/sensors/Ble/Ble.cpp b/src/modules/sensors/Ble/Ble.cpp index 0d433c8e..c9713e57 100644 --- a/src/modules/sensors/Ble/Ble.cpp +++ b/src/modules/sensors/Ble/Ble.cpp @@ -2,6 +2,8 @@ #include "classes/IoTItem.h" #include #include +#define BLE_PART1 +#define BLE_PART2 #include #include @@ -234,23 +236,25 @@ public: if (decoder.decodeBLEJson(BLEdata)) { - String mac_address = BLEdata["MAC"].as(); + String mac_address = BLEdata["mac"].as(); if (mac_address == "") { - BLEdata["MAC"] = BLEdata["id"]; + BLEdata["mac"] = BLEdata["id"]; mac_address = BLEdata["id"].as(); } mac_address.replace(":", ""); - BLEdata.remove("manufacturerdata"); - BLEdata.remove("servicedata"); - BLEdata.remove("type"); - BLEdata.remove("cidc"); - BLEdata.remove("acts"); - BLEdata.remove("cont"); - BLEdata.remove("track"); - BLEdata.remove("id"); - + if (_debug < 2) + { + BLEdata.remove("manufacturerdata"); + BLEdata.remove("servicedata"); + BLEdata.remove("type"); + BLEdata.remove("cidc"); + BLEdata.remove("acts"); + BLEdata.remove("cont"); + BLEdata.remove("track"); + BLEdata.remove("id"); + } // дописываем время прихода пакета данных BLEdata["last"] = millis(); if (_debug) @@ -261,13 +265,16 @@ public: // { // String val = BLEdata.as(); String output; - BLEdata.remove("servicedatauuid"); + if (_debug < 2) + { + BLEdata.remove("servicedatauuid"); + } serializeJson(BLEdata, output); SerialPrint("i", F("BLE"), mac_address + " " + output); //} } - SerialPrint("i", F("BLE"), "found: " + String(BLEdata["MAC"].as())); + SerialPrint("i", F("BLE"), "found: " + String(BLEdata["mac"].as())); } // Перебираем все зарегистрированные сенсоры BleSens diff --git a/src/modules/sensors/Ble/modinfo.json b/src/modules/sensors/Ble/modinfo.json index a3ef4e58..ac7cd8fc 100644 --- a/src/modules/sensors/Ble/modinfo.json +++ b/src/modules/sensors/Ble/modinfo.json @@ -39,9 +39,9 @@ "authorGit": "https://github.com/avaksru, https://github.com/Mit4el", "specialThanks": "@Serghei63", "moduleName": "Ble", - "moduleVersion": "3.0", + "moduleVersion": "3.1", "usedRam": { - "esp32_4mb": 1261449, + "esp32_4mb": 314692, "esp8266_4mb": 0 }, "subTypes": [ @@ -49,7 +49,7 @@ "BleScan" ], "title": "Сканер Bluetooth", - "moduleDesc": "Позволяет получить данные с Bluetooth часов и термометров Mijia, Xiaomi, Cleargrass, ...", + "moduleDesc": "Позволяет получить данные с Bluetooth часов и термометров и.т.д. Полный список (учитывать отстование нашей версии библиотеки) https://decoder.theengs.io/devices/devices.html Наш перечень в файле lib/decoder/devices.h Здесь полный перечень датчиков, для уменьшения размера модуля рекомендуется использовать модули Ble_part1 и Ble_part2", "propInfo": { "round": "Округление после запятой.", "orange": "количество минут после которого окрасить виджет в оранжевый цвет", @@ -65,28 +65,22 @@ "defActive": false, "usedLibs": { "esp32_4mb": [ - "https://github.com/Mit4el/NimBLE-Arduino.git", - "https://github.com/Mit4el/decoder.git" + "https://github.com/Mit4el/NimBLE-Arduino.git" ], "esp32_16mb": [ - "https://github.com/Mit4el/NimBLE-Arduino.git", - "https://github.com/Mit4el/decoder.git" + "https://github.com/Mit4el/NimBLE-Arduino.git" ], "esp32_4mb3f": [ - "https://github.com/Mit4el/NimBLE-Arduino.git", - "https://github.com/Mit4el/decoder.git" + "https://github.com/Mit4el/NimBLE-Arduino.git" ], "esp32cam_4mb": [ - "https://github.com/Mit4el/NimBLE-Arduino.git", - "https://github.com/Mit4el/decoder.git" + "https://github.com/Mit4el/NimBLE-Arduino.git" ], "esp32s3_16mb": [ - "https://github.com/Mit4el/NimBLE-Arduino.git", - "https://github.com/Mit4el/decoder.git" + "https://github.com/Mit4el/NimBLE-Arduino.git" ], "esp32c3m_4mb": [ - "https://github.com/Mit4el/NimBLE-Arduino.git", - "https://github.com/Mit4el/decoder.git" + "https://github.com/Mit4el/NimBLE-Arduino.git" ] } } \ No newline at end of file diff --git a/src/modules/sensors/Ble_part1/Ble_p1.cpp b/src/modules/sensors/Ble_part1/Ble_p1.cpp new file mode 100644 index 00000000..7ead4a2c --- /dev/null +++ b/src/modules/sensors/Ble_part1/Ble_p1.cpp @@ -0,0 +1,338 @@ +#include "Global.h" +#include "classes/IoTItem.h" +#include +#include +#define BLE_PART1 +// #define BLE_PART2 +#include +#include + +// Создаем переменную для хранения данных с датчиков bluetooth +// StaticJsonDocument BLEbuffer; +// DynamicJsonDocument extBLEdata(JSON_BUFFER_SIZE * 4); +// JsonObject extBLEdata = BLEbuffer.to(); +class BleSens; +std::vector BleSensArray; + +class BleSens : public IoTItem +{ +private: + // описание параметров передаваемых из настроек датчика из веба + String _MAC; + String _sensor; + int timeRecv = 0; + int _minutesPassed = 0; + String json = "{}"; + int orange = 0; + int red = 0; + int offline = 0; + int _int; + bool dataFromNode = false; + +public: + String whoIAm(/*String &mac, String &sens*/) + { + // mac = _MAC; + // sens = _sensor; + return _MAC; + } + + void setBLEdata(JsonObject extBLEdata) + { + if (_sensor == "last") + { + timeRecv = extBLEdata[_sensor].as(); + char *s; + s = TimeToString(millis() / 1000 - timeRecv / 1000); + value.isDecimal = 0; + if (timeRecv > 0) + { + value.valS = s; + dataFromNode = true; + _minutesPassed = 0; + setNewWidgetAttributes(); + } + 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); + dataFromNode = true; + _minutesPassed = 0; + setNewWidgetAttributes(); + } + else + { + value.isDecimal = 0; + value.valS = valStr; + regEvent(value.valS, _id); + dataFromNode = true; + _minutesPassed = 0; + setNewWidgetAttributes(); + } + } + } + } + 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; + } + + void doByInterval() + { + if (_sensor == "last") + { + char *s; + s = TimeToString(millis() / 1000 - timeRecv / 1000); + value.isDecimal = 0; + if (timeRecv > 0) + { + value.valS = s; + } + else + { + value.valS = ""; + } + regEvent(value.valS, _id); + } + _minutesPassed++; + setNewWidgetAttributes(); + } + void onMqttWsAppConnectEvent() + { + setNewWidgetAttributes(); + } + void setNewWidgetAttributes() + { + + int minutes_ = _minutesPassed * _int / 60; + jsonWriteStr(json, F("info"), prettyMinutsTimeout(minutes_)); + if (dataFromNode) + { + if (orange != 0 && red != 0 && offline != 0) + { + if (minutes_ < orange) + { + jsonWriteStr(json, F("color"), ""); + } + if (minutes_ >= orange && minutes_ < red) + { + jsonWriteStr(json, F("color"), F("orange")); // сделаем виджет оранжевым + } + if (minutes_ >= red && minutes_ < offline) + { + jsonWriteStr(json, F("color"), F("red")); // сделаем виджет красным + } + if (minutes_ >= offline) + { + jsonWriteStr(json, F("info"), F("offline")); + } + } + } + else + { + jsonWriteStr(json, F("info"), F("awaiting")); + } + sendSubWidgetsValues(_id, json); + } + + BleSens(String parameters) : IoTItem(parameters) + { + _MAC = jsonReadStr(parameters, "MAC"); + _sensor = jsonReadStr(parameters, "sensor"); + jsonRead(parameters, F("orange"), orange); + jsonRead(parameters, F("red"), red); + jsonRead(parameters, F("offline"), offline); + jsonRead(parameters, F("int"), _int); + dataFromNode = false; + 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(); + 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) + { + JsonObject BLEdata = doc.to(); + 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)) + { + String mac_address = BLEdata["mac"].as(); + if (mac_address == "") + { + BLEdata["mac"] = BLEdata["id"]; + mac_address = BLEdata["id"].as(); + } + mac_address.replace(":", ""); + if (_debug < 2) + { + BLEdata.remove("manufacturerdata"); + BLEdata.remove("servicedata"); + BLEdata.remove("type"); + BLEdata.remove("cidc"); + BLEdata.remove("acts"); + BLEdata.remove("cont"); + BLEdata.remove("track"); + BLEdata.remove("id"); + } + // дописываем время прихода пакета данных + BLEdata["last"] = millis(); + if (_debug) + { + if ((_filter != "" && BLEdata[_filter]) || _filter == "") + { + // for (JsonPair kv : BLEdata) + // { + // String val = BLEdata.as(); + String output; + if (_debug < 2) + { + BLEdata.remove("servicedatauuid"); + } + serializeJson(BLEdata, output); + SerialPrint("i", F("BLE"), mac_address + " " + output); + //} + } + + SerialPrint("i", F("BLE"), "found: " + String(BLEdata["mac"].as())); + } + + // Перебираем все зарегистрированные сенсоры BleSens + for (std::vector::iterator it = BleSensArray.begin(); + it != BleSensArray.end(); ++it) + { + // Если это данные для нужного сенсора (по его МАКУ) + 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); + + 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 (pBLEScan->isScanning() == false) + { + if (_scanDuration > 0) + { + SerialPrint("i", F("BLE"), "Start Scanning..."); + pBLEScan->start(_scanDuration, scanEndedCB, false); + } + } + } + + ~BleScan() { BleSensArray.clear(); }; +}; + +//======================================================================================================= + +void *getAPI_Ble_part1(String subtype, String param) +{ + if (subtype == F("BleScan_p1")) + { + return new BleScan(param); + } + else if (subtype == F("BleSens_p1")) + { + return new BleSens(param); + } + else + { + return nullptr; + } +} \ No newline at end of file diff --git a/src/modules/sensors/Ble_part1/modinfo.json b/src/modules/sensors/Ble_part1/modinfo.json new file mode 100644 index 00000000..9e990fbd --- /dev/null +++ b/src/modules/sensors/Ble_part1/modinfo.json @@ -0,0 +1,86 @@ +{ + "menuSection": "sensors", + "configItem": [ + { + "name": "bluetooth сканер", + "type": "Reading", + "subtype": "BleScan_p1", + "id": "BleScan", + "widget": "na", + "page": "", + "descr": "", + "int": 135, + "scanDuration": 10, + "filter": "servicedatauuid", + "debug": 1 + }, + { + "name": "bluetooth датчик", + "type": "Reading", + "subtype": "BleSens_p1", + "id": "BleSens", + "widget": "anydataDef", + "page": "Сенсоры", + "descr": "", + "needSave": 0, + "int": 30, + "global": 0, + "round": 1, + "orange": 60, + "red": 120, + "offline": 180, + "MAC": "", + "sensor": "" + } + ], + "about": { + "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_part1", + "moduleVersion": "3.1", + "usedRam": { + "esp32_4mb": 262796, + "esp8266_4mb": 0 + }, + "subTypes": [ + "BleSens_p1", + "BleScan_p1" + ], + "title": "Сканер Bluetooth, часть 1", + "moduleDesc": "Часть 1 популярных Bluetooth датчиков. Позволяет получить данные с Bluetooth часов и термометров Mijia, Xiaomi, Cleargrass, Qingping, Inkbird. Разделение на части сделано для уменьшения размера модуля. Обе части вместе не использовать! для всех датчиков модуль Ble! Полный список (учитывать отстование нашей версии библиотеки) https://decoder.theengs.io/devices/devices.html Наш перечень в файле lib/decoder/devices.h", + "propInfo": { + "round": "Округление после запятой.", + "orange": "количество минут после которого окрасить виджет в оранжевый цвет", + "red": "количество минут после которого окрасить виджет в красный цвет", + "offline": "количество минут после которого отобразить что устройство offline, если все три orange red и offline поставить в ноль - то функция окраски выключится", + "int": "Интервал сканирования BLE окружения (BleScan) / В BleSens темп обновления времнени поступления данных, сами даные обновляются по мене сканирования/поступления", + "scanDuration": "Длительность сканирования ", + "filter": "Позволяет установить фильтр по параметру передаваемому датчиком. Влияет только на вывод лога при debug=1, что бы было легче найти датчики, если много устройств в эфире", + "MAC": "MAC адрес беспроводного датчика", + "sensor": "Тип сенсора: температура / влажность / время / ... " + } + }, + "defActive": false, + "usedLibs": { + "esp32_4mb": [ + "https://github.com/Mit4el/NimBLE-Arduino.git" + ], + "esp32_16mb": [ + "https://github.com/Mit4el/NimBLE-Arduino.git" + ], + "esp32_4mb3f": [ + "https://github.com/Mit4el/NimBLE-Arduino.git" + ], + "esp32cam_4mb": [ + "https://github.com/Mit4el/NimBLE-Arduino.git" + ], + "esp32s3_16mb": [ + "https://github.com/Mit4el/NimBLE-Arduino.git" + ], + "esp32c3m_4mb": [ + "https://github.com/Mit4el/NimBLE-Arduino.git" + ] + } +} \ No newline at end of file diff --git a/src/modules/sensors/Ble_part2/Ble_p2.cpp b/src/modules/sensors/Ble_part2/Ble_p2.cpp new file mode 100644 index 00000000..0c8de171 --- /dev/null +++ b/src/modules/sensors/Ble_part2/Ble_p2.cpp @@ -0,0 +1,339 @@ +#include "Global.h" +#include "classes/IoTItem.h" +#include +#include +// #define BLE_PART1 +#define BLE_PART2 +#include +#include + +// Создаем переменную для хранения данных с датчиков bluetooth +// StaticJsonDocument BLEbuffer; +// DynamicJsonDocument extBLEdata(JSON_BUFFER_SIZE * 4); +// JsonObject extBLEdata = BLEbuffer.to(); +class BleSens; +std::vector BleSensArray; + +class BleSens : public IoTItem +{ +private: + // описание параметров передаваемых из настроек датчика из веба + String _MAC; + String _sensor; + int timeRecv = 0; + int _minutesPassed = 0; + String json = "{}"; + int orange = 0; + int red = 0; + int offline = 0; + int _int; + bool dataFromNode = false; + +public: + String whoIAm(/*String &mac, String &sens*/) + { + // mac = _MAC; + // sens = _sensor; + return _MAC; + } + + void setBLEdata(JsonObject extBLEdata) + { + if (_sensor == "last") + { + timeRecv = extBLEdata[_sensor].as(); + char *s; + s = TimeToString(millis() / 1000 - timeRecv / 1000); + value.isDecimal = 0; + if (timeRecv > 0) + { + value.valS = s; + dataFromNode = true; + _minutesPassed = 0; + setNewWidgetAttributes(); + } + 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); + dataFromNode = true; + _minutesPassed = 0; + setNewWidgetAttributes(); + } + else + { + value.isDecimal = 0; + value.valS = valStr; + regEvent(value.valS, _id); + dataFromNode = true; + _minutesPassed = 0; + setNewWidgetAttributes(); + } + } + } + } + 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; + } + + void doByInterval() + { + if (_sensor == "last") + { + char *s; + s = TimeToString(millis() / 1000 - timeRecv / 1000); + value.isDecimal = 0; + if (timeRecv > 0) + { + value.valS = s; + } + else + { + value.valS = ""; + } + regEvent(value.valS, _id); + } + _minutesPassed++; + setNewWidgetAttributes(); + } + void onMqttWsAppConnectEvent() + { + setNewWidgetAttributes(); + } + void setNewWidgetAttributes() + { + + int minutes_ = _minutesPassed * _int / 60; + jsonWriteStr(json, F("info"), prettyMinutsTimeout(minutes_)); + if (dataFromNode) + { + if (orange != 0 && red != 0 && offline != 0) + { + if (minutes_ < orange) + { + jsonWriteStr(json, F("color"), ""); + } + if (minutes_ >= orange && minutes_ < red) + { + jsonWriteStr(json, F("color"), F("orange")); // сделаем виджет оранжевым + } + if (minutes_ >= red && minutes_ < offline) + { + jsonWriteStr(json, F("color"), F("red")); // сделаем виджет красным + } + if (minutes_ >= offline) + { + jsonWriteStr(json, F("info"), F("offline")); + } + } + } + else + { + jsonWriteStr(json, F("info"), F("awaiting")); + } + sendSubWidgetsValues(_id, json); + } + + BleSens(String parameters) : IoTItem(parameters) + { + _MAC = jsonReadStr(parameters, "MAC"); + _sensor = jsonReadStr(parameters, "sensor"); + jsonRead(parameters, F("orange"), orange); + jsonRead(parameters, F("red"), red); + jsonRead(parameters, F("offline"), offline); + jsonRead(parameters, F("int"), _int); + dataFromNode = false; + 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(); + 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) + { + JsonObject BLEdata = doc.to(); + 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)) + { + String mac_address = BLEdata["mac"].as(); + if (mac_address == "") + { + BLEdata["mac"] = BLEdata["id"]; + mac_address = BLEdata["id"].as(); + } + mac_address.replace(":", ""); + if (_debug < 2) + { + BLEdata.remove("manufacturerdata"); + BLEdata.remove("servicedata"); + BLEdata.remove("type"); + BLEdata.remove("cidc"); + BLEdata.remove("acts"); + BLEdata.remove("cont"); + BLEdata.remove("track"); + BLEdata.remove("id"); + } + + // дописываем время прихода пакета данных + BLEdata["last"] = millis(); + if (_debug) + { + if ((_filter != "" && BLEdata[_filter]) || _filter == "") + { + // for (JsonPair kv : BLEdata) + // { + // String val = BLEdata.as(); + String output; + if (_debug < 2) + { + BLEdata.remove("servicedatauuid"); + } + serializeJson(BLEdata, output); + SerialPrint("i", F("BLE"), mac_address + " " + output); + //} + } + + SerialPrint("i", F("BLE"), "found: " + String(BLEdata["mac"].as())); + } + + // Перебираем все зарегистрированные сенсоры BleSens + for (std::vector::iterator it = BleSensArray.begin(); + it != BleSensArray.end(); ++it) + { + // Если это данные для нужного сенсора (по его МАКУ) + 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); + + 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 (pBLEScan->isScanning() == false) + { + if (_scanDuration > 0) + { + SerialPrint("i", F("BLE"), "Start Scanning..."); + pBLEScan->start(_scanDuration, scanEndedCB, false); + } + } + } + + ~BleScan() { BleSensArray.clear(); }; +}; + +//======================================================================================================= + +void *getAPI_Ble_part2(String subtype, String param) +{ + if (subtype == F("BleScan_p2")) + { + return new BleScan(param); + } + else if (subtype == F("BleSens_p2")) + { + return new BleSens(param); + } + else + { + return nullptr; + } +} \ No newline at end of file diff --git a/src/modules/sensors/Ble_part2/modinfo.json b/src/modules/sensors/Ble_part2/modinfo.json new file mode 100644 index 00000000..6c7d1634 --- /dev/null +++ b/src/modules/sensors/Ble_part2/modinfo.json @@ -0,0 +1,86 @@ +{ + "menuSection": "sensors", + "configItem": [ + { + "name": "bluetooth сканер", + "type": "Reading", + "subtype": "BleScan_p2", + "id": "BleScan", + "widget": "na", + "page": "", + "descr": "", + "int": 135, + "scanDuration": 10, + "filter": "servicedatauuid", + "debug": 1 + }, + { + "name": "bluetooth датчик", + "type": "Reading", + "subtype": "BleSens_p2", + "id": "BleSens", + "widget": "anydataDef", + "page": "Сенсоры", + "descr": "", + "needSave": 0, + "int": 30, + "global": 0, + "round": 1, + "orange": 60, + "red": 120, + "offline": 180, + "MAC": "", + "sensor": "" + } + ], + "about": { + "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_part2", + "moduleVersion": "3.1", + "usedRam": { + "esp32_4mb": 288972, + "esp8266_4mb": 0 + }, + "subTypes": [ + "BleSens_p2", + "BleScan_p2" + ], + "title": "Сканер Bluetooth, часть 2", + "moduleDesc": "Часть 2 Bluetooth датчиков. Позволяет получить данные с Bluetooth датчиков, кроме Mijia, Xiaomi, Cleargrass, Qingping, Inkbird. Обе части вместе не использовать! для всех датчиков модуль Ble! Полный список (учитывать отстование нашей версии библиотеки) https://decoder.theengs.io/devices/devices.html Наш перечень в файле lib/decoder/devices.h", + "propInfo": { + "round": "Округление после запятой.", + "orange": "количество минут после которого окрасить виджет в оранжевый цвет", + "red": "количество минут после которого окрасить виджет в красный цвет", + "offline": "количество минут после которого отобразить что устройство offline, если все три orange red и offline поставить в ноль - то функция окраски выключится", + "int": "Интервал сканирования BLE окружения (BleScan) / В BleSens темп обновления времнени поступления данных, сами даные обновляются по мене сканирования/поступления", + "scanDuration": "Длительность сканирования ", + "filter": "Позволяет установить фильтр по параметру передаваемому датчиком. Влияет только на вывод лога при debug=1, что бы было легче найти датчики, если много устройств в эфире", + "MAC": "MAC адрес беспроводного датчика", + "sensor": "Тип сенсора: температура / влажность / время / ... " + } + }, + "defActive": false, + "usedLibs": { + "esp32_4mb": [ + "https://github.com/Mit4el/NimBLE-Arduino.git" + ], + "esp32_16mb": [ + "https://github.com/Mit4el/NimBLE-Arduino.git" + ], + "esp32_4mb3f": [ + "https://github.com/Mit4el/NimBLE-Arduino.git" + ], + "esp32cam_4mb": [ + "https://github.com/Mit4el/NimBLE-Arduino.git" + ], + "esp32s3_16mb": [ + "https://github.com/Mit4el/NimBLE-Arduino.git" + ], + "esp32c3m_4mb": [ + "https://github.com/Mit4el/NimBLE-Arduino.git" + ] + } +} \ No newline at end of file From 1448fa475009ddfe214fd337a31158287a7c667e Mon Sep 17 00:00:00 2001 From: Mit4el Date: Wed, 15 Nov 2023 21:55:05 +0300 Subject: [PATCH 6/7] upd NextionUpload --- lib/ESPNexUpload/src/ESPNexUpload.cpp | 667 ++++++++++++++++++ lib/ESPNexUpload/src/ESPNexUpload.h | 273 +++++++ .../display/NextionUpload/NextionUpload.cpp | 8 +- .../display/NextionUpload/modinfo.json | 28 +- 4 files changed, 951 insertions(+), 25 deletions(-) create mode 100644 lib/ESPNexUpload/src/ESPNexUpload.cpp create mode 100644 lib/ESPNexUpload/src/ESPNexUpload.h diff --git a/lib/ESPNexUpload/src/ESPNexUpload.cpp b/lib/ESPNexUpload/src/ESPNexUpload.cpp new file mode 100644 index 00000000..0856aa5f --- /dev/null +++ b/lib/ESPNexUpload/src/ESPNexUpload.cpp @@ -0,0 +1,667 @@ +/** + * @file NexUpload.cpp + * + * The implementation of uploading tft file for nextion displays. + * + * Original version (a part of https://github.com/itead/ITEADLIB_Arduino_Nextion) + * @author Chen Zengpeng (email:) + * @date 2016/3/29 + * @copyright + * Copyright (C) 2014-2015 ITEAD Intelligent Systems Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#define DEBUG_SERIAL_ENABLE +#include "ESPNexUpload.h" + +#if defined ESP8266 + +#include + +#ifndef NEXT_RX +#define NEXT_RX 14 // Nextion RX pin | Default 14 / D5 +#define NEXT_TX 12 // Nextion TX pin | Default 12 / D6 +#endif +#ifndef nexSerial +//SoftwareSerial softSerial(NEXT_RX, NEXT_TX); +#define nexSerial softSerial +#define nexSerialBegin(a, b, c) nexSerial.begin(a) +#endif + +#elif defined ESP32 + +#ifndef NEXT_RX +#define NEXT_RX 17 // Nextion RX pin | Default 16 +#define NEXT_TX 16 // Nextion TX pin | Default 17 +#endif +#ifndef nexSerial +#define nexSerial Serial2 +#define nexSerialBegin(a, rx, tx) nexSerial.begin(a, SERIAL_8N1, rx, tx) +#endif + +#endif + +#ifdef DEBUG_SERIAL_ENABLE +#define dbSerialPrint(a) Serial.print(a) +#define dbSerialPrintHex(a) Serial.print(a, HEX) +#define dbSerialPrintln(a) Serial.println(a) +#define dbSerialBegin(a) Serial.begin(a) +#else +#define dbSerialPrint(a) \ + do \ + { \ + } while (0) +#define dbSerialPrintHex(a) \ + do \ + { \ + } while (0) +#define dbSerialPrintln(a) \ + do \ + { \ + } while (0) +#define dbSerialBegin(a) \ + do \ + { \ + } while (0) +#endif + +ESPNexUpload::ESPNexUpload(uint32_t upload_baudrate, uint8_t rx, uint8_t tx) +{ + _upload_baudrate = upload_baudrate; + if (rx == 0 || tx == 0) + { + _rx = NEXT_RX; + _tx = NEXT_TX; + }else{ + _rx = rx; + _tx = tx; + } +#if defined ESP8266 + SoftwareSerial softSerial(_rx, _tx); +#endif + +} + +bool ESPNexUpload::connect() +{ +#if defined ESP8266 + yield(); +#endif + + dbSerialBegin(115200); + _printInfoLine(F("serial tests & connect")); + + if (_getBaudrate() == 0) + { + statusMessage = F("get baudrate error"); + _printInfoLine(statusMessage); + return false; + } + + _setRunningMode(); + + if (!_echoTest("mystop_yesABC")) + { + statusMessage = F("echo test failed"); + _printInfoLine(statusMessage); + return false; + } + + if (!_handlingSleepAndDim()) + { + statusMessage = F("handling sleep and dim settings failed"); + _printInfoLine(statusMessage); + return false; + } + + if (!_setPrepareForFirmwareUpdate(_upload_baudrate)) + { + statusMessage = F("modifybaudrate error"); + _printInfoLine(statusMessage); + return false; + } + + return true; +} + +bool ESPNexUpload::prepareUpload(uint32_t file_size) +{ + _undownloadByte = file_size; + return this->connect(); +} + +uint16_t ESPNexUpload::_getBaudrate(void) +{ + + _baudrate = 0; + uint32_t baudrate_array[7] = {115200, 19200, 9600, 57600, 38400, 4800, 2400}; + for (uint8_t i = 0; i < 7; i++) + { + if (_searchBaudrate(baudrate_array[i])) + { + _baudrate = baudrate_array[i]; + _printInfoLine(F("baudrate determined")); + break; + } + delay(1500); // wait for 1500 ms + } + return _baudrate; +} + +bool ESPNexUpload::_searchBaudrate(uint32_t baudrate) +{ + +#if defined ESP8266 + yield(); +#endif + + String response = String(""); + _printInfoLine(); + dbSerialPrint(F("init nextion serial interface on baudrate: ")); + dbSerialPrintln(baudrate); + + nexSerialBegin(baudrate, _rx, _tx); + _printInfoLine(F("ESP baudrate established, try to connect to display")); + const char _nextion_FF_FF[3] = {0xFF, 0xFF, 0x00}; + + this->sendCommand("DRAKJHSUYDGBNCJHGJKSHBDN"); + this->sendCommand("", true, true); // 0x00 0xFF 0xFF 0xFF + + this->recvRetString(response); + if (response[0] != 0x1A) + { + _printInfoLine(F("first indication that baudrate is wrong")); + } + else + { + _printInfoLine(F("first respone from display, first indication that baudrate is correct")); + } + + this->sendCommand("connect"); // first connect attempt + + this->recvRetString(response); + if (response.indexOf(F("comok")) == -1) + { + _printInfoLine(F("display doesn't accept the first connect request")); + } + else + { + _printInfoLine(F("display accept the first connect request")); + } + + response = String(""); + delay(110); // based on serial analyser from Nextion editor V0.58 to Nextion display NX4024T032_011R + this->sendCommand(_nextion_FF_FF, false); + + this->sendCommand("connect"); // second attempt + this->recvRetString(response); + if (response.indexOf(F("comok")) == -1 && response[0] != 0x1A) + { + _printInfoLine(F("display doesn't accept the second connect request")); + _printInfoLine(F("conclusion, wrong baudrate")); + return 0; + } + else + { + _printInfoLine(F("display accept the second connect request")); + _printInfoLine(F("conclusion, correct baudrate")); + } + + return 1; +} + +void ESPNexUpload::sendCommand(const char *cmd, bool tail, bool null_head) +{ + +#if defined ESP8266 + yield(); +#endif + + if (null_head) + { + nexSerial.write(0x00); + } + + while (nexSerial.available()) + { + nexSerial.read(); + } + + nexSerial.print(cmd); + if (tail) + { + nexSerial.write(0xFF); + nexSerial.write(0xFF); + nexSerial.write(0xFF); + } + _printSerialData(true, cmd); +} + +uint16_t ESPNexUpload::recvRetString(String &response, uint32_t timeout, bool recv_flag) +{ + +#if defined ESP8266 + yield(); +#endif + + uint16_t ret = 0; + uint8_t c = 0; + uint8_t nr_of_FF_bytes = 0; + long start; + bool exit_flag = false; + bool ff_flag = false; + if (timeout != 500) + _printInfoLine("timeout setting serial read: " + String(timeout)); + + start = millis(); + + while (millis() - start <= timeout) + { + + while (nexSerial.available()) + { + + c = nexSerial.read(); + if (c == 0) + { + continue; + } + + if (c == 0xFF) + nr_of_FF_bytes++; + else + { + nr_of_FF_bytes = 0; + ff_flag = false; + } + + if (nr_of_FF_bytes >= 3) + ff_flag = true; + + response += (char)c; + + if (recv_flag) + { + if (response.indexOf(0x05) != -1) + { + exit_flag = true; + } + } + } + if (exit_flag || ff_flag) + { + break; + } + } + _printSerialData(false, response); + + // if the exit flag and the ff flag are both not found, than there is a timeout + // if(!exit_flag && !ff_flag) + // _printInfoLine(F("recvRetString: timeout")); + + if (ff_flag) + response = response.substring(0, response.length() - 3); // Remove last 3 0xFF + + ret = response.length(); + return ret; +} + +bool ESPNexUpload::_setPrepareForFirmwareUpdate(uint32_t upload_baudrate) +{ + +#if defined ESP8266 + yield(); +#endif + + String response = String(""); + String cmd = String(""); + + cmd = F("00"); + this->sendCommand(cmd.c_str()); + delay(0.1); + + this->recvRetString(response, 800, true); // normal response time is 400ms + + String filesize_str = String(_undownloadByte, 10); + String baudrate_str = String(upload_baudrate); + cmd = "whmi-wri " + filesize_str + "," + baudrate_str + ",0"; + + this->sendCommand(cmd.c_str()); + + // Without flush, the whmi command will NOT transmitted by the ESP in the current baudrate + // because switching to another baudrate (nexSerialBegin command) has an higher prio. + // The ESP will first jump to the new 'upload_baudrate' and than process the serial 'transmit buffer' + // The flush command forced the ESP to wait until the 'transmit buffer' is empty + nexSerial.flush(); + + nexSerialBegin(upload_baudrate, _rx, _tx); + _printInfoLine(F("changing upload baudrate...")); + _printInfoLine(String(upload_baudrate)); + + this->recvRetString(response, 800, true); // normal response time is 400ms + + // The Nextion display will, if it's ready to accept data, send a 0x05 byte. + if (response.indexOf(0x05) != -1) + { + _printInfoLine(F("preparation for firmware update done")); + return 1; + } + else + { + _printInfoLine(F("preparation for firmware update failed")); + return 0; + } +} + +void ESPNexUpload::setUpdateProgressCallback(THandlerFunction value) +{ + _updateProgressCallback = value; +} + +bool ESPNexUpload::upload(const uint8_t *file_buf, size_t buf_size) +{ + +#if defined ESP8266 + yield(); +#endif + + uint8_t c; + uint8_t timeout = 0; + String string = String(""); + + for (uint16_t i = 0; i < buf_size; i++) + { + + // Users must split the .tft file contents into 4096 byte sized packets with the final partial packet size equal to the last remaining bytes (<4096 bytes). + if (_sent_packets == 4096) + { + + // wait for the Nextion to return its 0x05 byte confirming reception and readiness to receive the next packets + this->recvRetString(string, 500, true); + if (string.indexOf(0x05) != -1) + { + + // reset sent packets counter + _sent_packets = 0; + + // reset receive String + string = ""; + } + else + { + if (timeout >= 8) + { + statusMessage = F("serial connection lost"); + _printInfoLine(statusMessage); + return false; + } + + timeout++; + } + + // delay current byte + i--; + } + else + { + + // read buffer + c = file_buf[i]; + + // write byte to nextion over serial + nexSerial.write(c); + + // update sent packets counter + _sent_packets++; + } + } + + return true; +} + +bool ESPNexUpload::upload(Stream &myFile) +{ +#if defined ESP8266 + yield(); +#endif + + // create buffer for read + uint8_t buff[2048] = {0}; + + // read all data from server + while (_undownloadByte > 0 || _undownloadByte == -1) + { + + // get available data size + size_t size = myFile.available(); + + if (size) + { + // read up to 2048 byte into the buffer + int c = myFile.readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size)); + + // Write the buffered bytes to the nextion. If this fails, return false. + if (!this->upload(buff, c)) + { + return false; + } + else + { + if (_updateProgressCallback) + { + _updateProgressCallback(); + } + } + + if (_undownloadByte > 0) + { + _undownloadByte -= c; + } + } + delay(1); + } + + return true; +} + +void ESPNexUpload::softReset(void) +{ + // soft reset nextion device + this->sendCommand("rest"); +} + +void ESPNexUpload::end() +{ + + // wait for the nextion to finish internal processes + delay(1600); + + // soft reset the nextion + this->softReset(); + + // end Serial connection + nexSerial.end(); + + // reset sent packets counter + _sent_packets = 0; + + statusMessage = F("upload ok"); + _printInfoLine(statusMessage + F("\r\n")); +} + +void ESPNexUpload::_setRunningMode(void) +{ + String cmd = String(""); + delay(100); + cmd = F("runmod=2"); + this->sendCommand(cmd.c_str()); + delay(60); +} + +bool ESPNexUpload::_echoTest(String input) +{ + String cmd = String(""); + String response = String(""); + + cmd = "print \"" + input + "\""; + this->sendCommand(cmd.c_str()); + + uint32_t duration_ms = calculateTransmissionTimeMs(cmd) * 2 + 10; // times 2 (send + receive) and 10 ms extra + this->recvRetString(response, duration_ms); + + return (response.indexOf(input) != -1); +} + +bool ESPNexUpload::_handlingSleepAndDim(void) +{ + String cmd = String(""); + String response = String(""); + bool set_sleep = false; + bool set_dim = false; + + cmd = F("get sleep"); + this->sendCommand(cmd.c_str()); + + this->recvRetString(response); + + if (response[0] != 0x71) + { + statusMessage = F("unknown response from 'get sleep' request"); + _printInfoLine(statusMessage); + return false; + } + + if (response[1] != 0x00) + { + _printInfoLine(F("sleep enabled")); + set_sleep = true; + } + else + { + _printInfoLine(F("sleep disabled")); + } + + response = String(""); + cmd = F("get dim"); + this->sendCommand(cmd.c_str()); + + this->recvRetString(response); + + if (response[0] != 0x71) + { + statusMessage = F("unknown response from 'get dim' request"); + _printInfoLine(statusMessage); + return false; + } + + if (response[1] == 0x00) + { + _printInfoLine(F("dim is 0%, backlight from display is turned off")); + set_dim = true; + } + else + { + _printInfoLine(); + dbSerialPrint(F("dim ")); + dbSerialPrint((uint8_t)response[1]); + dbSerialPrintln(F("%")); + } + + if (!_echoTest("ABC")) + { + statusMessage = F("echo test in 'handling sleep and dim' failed"); + _printInfoLine(statusMessage); + return false; + } + + if (set_sleep) + { + cmd = F("sleep=0"); + this->sendCommand(cmd.c_str()); + // Unfortunately the display doesn't send any respone on the wake up request (sleep=0) + // Let the ESP wait for one second, this is based on serial analyser from Nextion editor V0.58 to Nextion display NX4024T032_011R + // This gives the Nextion display some time to wake up + delay(1000); + } + + if (set_dim) + { + cmd = F("dim=100"); + this->sendCommand(cmd.c_str()); + delay(15); + } + + return true; +} + +void ESPNexUpload::_printSerialData(bool esp_request, String input) +{ + + char c; + if (esp_request) + dbSerialPrint(F("ESP request: ")); + else + dbSerialPrint(F("Nextion respone: ")); + + if (input.length() == 0) + { + dbSerialPrintln(F("none")); + return; + } + + for (int i = 0; i < input.length(); i++) + { + + c = input[i]; + if ((uint8_t)c >= 0x20 && (uint8_t)c <= 0x7E) + dbSerialPrint(c); + else + { + dbSerialPrint(F("0x")); + dbSerialPrintHex(c); + dbSerialPrint(F(" ")); + } + } + dbSerialPrintln(); +} + +uint32_t ESPNexUpload::calculateTransmissionTimeMs(String message) +{ + // In general, 1 second (s) = 1000 (10^-3) millisecond (ms) or + // 1 second (s) = 1000 000 (10^-6) microsecond (us). + // To calculate how much microsecond one BIT of data takes with a certain baudrate you have to divide + // the baudrate by one second. + // For example 9600 baud = 1000 000 us / 9600 ≈ 104 us + // The time to transmit one DATA byte (if we use default UART modulation) takes 10 bits. + // 8 DATA bits and one START and one STOP bit makes 10 bits. + // In this example (9600 baud) a byte will take 1041 us to send or receive. + // Multiply this value by the length of the message (number of bytes) and the total transmit/ receive time + // is calculated. + + uint32_t duration_one_byte_us = 10000000 / _baudrate; // 1000 000 * 10 bits / baudrate + uint16_t nr_of_bytes = message.length() + 3; // 3 times 0xFF byte + uint32_t duration_message_us = nr_of_bytes * duration_one_byte_us; + uint32_t return_value_ms = duration_message_us / 1000; + + _printInfoLine("calculated transmission time: " + String(return_value_ms) + " ms"); + return return_value_ms; +} + +void ESPNexUpload::_printInfoLine(String line) +{ + dbSerialPrint(F("Status info: ")); + if (line.length() != 0) + dbSerialPrintln(line); +} \ No newline at end of file diff --git a/lib/ESPNexUpload/src/ESPNexUpload.h b/lib/ESPNexUpload/src/ESPNexUpload.h new file mode 100644 index 00000000..b9cfe746 --- /dev/null +++ b/lib/ESPNexUpload/src/ESPNexUpload.h @@ -0,0 +1,273 @@ +/** + * @file NexUpload.h + * The definition of class NexUpload. + * + * + * 1 - BugFix when display baudrate is diffrent from initial ESP baudrate + * 2 - Improved debug information + * 3 - Make delay commands dependent on the baudrate + * @author Machiel Mastenbroek (machiel.mastenbroek@gmail.com) + * @date 2019/11/04 + * @version 0.5.5 + * + * Stability improvement, Nextion display doesn’t freeze after the seconds 4096 trance of firmware bytes. + * Now the firmware upload process is stabled without the need of a hard Display power off-on intervention. + * Undocumented features (not mentioned in nextion-hmi-upload-protocol-v1-1 specification) are added. + * This implementation is based in on a reverse engineering with a UART logic analyser between + * the Nextion editor v0.58 and a NX4024T032_011R Display. + * + * @author Machiel Mastenbroek (machiel.mastenbroek@gmail.com) + * @date 2019/10/24 + * @version 0.5.0 + * + * Modified to work with ESP32, HardwareSerial and removed SPIFFS dependency + * @author Onno Dirkzwager (onno.dirkzwager@gmail.com) + * @date 2018/12/26 + * @version 0.3.0 + * + * Modified to work with ESP8266 and SoftwareSerial + * @author Ville Vilpas (psoden@gmail.com) + * @date 2018/2/3 + * @version 0.2.0 + * + * Original version (a part of https://github.com/itead/ITEADLIB_Arduino_Nextion) + * @author Chen Zengpeng (email:) + * @date 2016/3/29 + * @copyright + * Copyright (C) 2014-2015 ITEAD Intelligent Systems Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#ifndef __ESPNEXUPLOAD_H__ +#define __ESPNEXUPLOAD_H__ +#include +#include +#include + +/** + * @addtogroup CoreAPI + * @{ + */ + +// callback template definition +typedef std::function THandlerFunction; + +/** + * + * Provides the API for nextion to upload the ftf file. + */ +class ESPNexUpload +{ +public: /* methods */ + // callback template definition + typedef std::function THandlerFunction; + + /** + * Constructor. + * + * @param uint32_t upload_baudrate - set upload baudrate. + */ + ESPNexUpload(uint32_t upload_baudrate, uint8_t rx=0, uint8_t tx=0); + + /** + * destructor. + * + */ + ~ESPNexUpload() {} + + /** + * Connect to Nextion over serial + * + * @return true or false. + */ + bool connect(); + + /** + * prepare upload. Set file size & Connect to Nextion over serial + * + * @return true if success, false for failure. + */ + bool prepareUpload(uint32_t file_size); + + /** + * set Update Progress Callback. (What to do during update progress) + * + * @return none + */ + void setUpdateProgressCallback(THandlerFunction value); + + /** + * start update tft file to nextion. + * + * @param const uint8_t *file_buf + * @param size_t buf_size + * @return true if success, false for failure. + */ + bool upload(const uint8_t *file_buf, size_t buf_size); + + /** + * start update tft file to nextion. + * + * @param Stream &myFile + * @return true if success, false for failure. + */ + bool upload(Stream &myFile); + + /** + * Send reset command to Nextion over serial + * + * @return none. + */ + void softReset(void); + + /** + * Send reset, end serial, reset _sent_packets & update status message + * + * @return none. + */ + void end(void); + +public: /* data */ + String statusMessage = ""; + +private: /* methods */ + /* + * get communicate baudrate. + * + * @return communicate baudrate. + * + */ + uint16_t _getBaudrate(void); + + /* + * search communicate baudrate. + * + * @param baudrate - communicate baudrate. + * + * @return true if success, false for failure. + */ + bool _searchBaudrate(uint32_t baudrate); + + /* + * set download baudrate. + * + * @param baudrate - set download baudrate. + * + * @return true if success, false for failure. + */ + bool _setPrepareForFirmwareUpdate(uint32_t upload_baudrate); + + /* + * set Nextion running mode. + * + * Undocumented feature of the Nextion protocol. + * It's used by the 'upload to Nextion device' feature of the Nextion Editor V0.58 + * + * The nextion display doesn't send any response + * + */ + void _setRunningMode(void); + + /* + * Test UART nextion connection availability + * + * @param input - echo string, + * + * @return true when the 'echo string' that is send is equal to the received string + * + * This test is used by the 'upload to Nextion device' feature of the Nextion Editor V0.58 + * + */ + bool _echoTest(String input); + + /* + * This function get the sleep and dim value from the Nextion display. + * + * If sleep = 1 meaning: sleep is enabled + * action : sleep will be disabled + * If dim = 0, meaning: the display backlight is turned off + * action : dim will be set to 100 (percent) + * + */ + bool _handlingSleepAndDim(void); + + /* + * This function (debug) print the Nextion response to a human readable string + * + * @param esp_request - true: request message from esp to nextion + * false: response message from nextion to esp + * + * @param input - string to print + * + */ + void _printSerialData(bool esp_request, String input); + + /* + * This function print a prefix debug line + * + * @param line: optional debug/ info line + */ + void _printInfoLine(String line = ""); + + /* + * Send command to Nextion. + * + * @param cmd - the string of command. + * @param tail - end the string with tripple 0xFF byte + * @param null_head - start the string with a single 0x00 byte + * + * @return none. + */ + void sendCommand(const char *cmd, bool tail = true, bool null_head = false); + + /* + * Receive string data. + * + * @param buffer - save string data. + * @param timeout - set timeout time. + * @param recv_flag - if recv_flag is true,will braak when receive 0x05. + * + * @return the length of string buffer. + * + */ + uint16_t recvRetString(String &string, uint32_t timeout = 500, bool recv_flag = false); + + /* + * + * This function calculates the transmission time, the transmission time + * is based on the length of the message and the baudrate. + * + * @param message - only used to determine the length of the message + * + * @return time in us length of string buffer. + * + */ + uint32_t calculateTransmissionTimeMs(String message); + +private: /* data */ + uint32_t _baudrate; /* nextion serail baudrate */ + uint32_t _undownloadByte; /* undownload byte of tft file */ + uint32_t _upload_baudrate; /* upload baudrate */ + uint16_t _sent_packets = 0; /* upload baudrate */ + uint8_t _rx; + uint8_t _tx; + + THandlerFunction _updateProgressCallback; +}; +/** + * @} + */ + +#endif /* #ifndef __ESPNEXUPLOAD_H__ */ \ No newline at end of file diff --git a/src/modules/display/NextionUpload/NextionUpload.cpp b/src/modules/display/NextionUpload/NextionUpload.cpp index 65ae8dd6..f2db9474 100644 --- a/src/modules/display/NextionUpload/NextionUpload.cpp +++ b/src/modules/display/NextionUpload/NextionUpload.cpp @@ -25,8 +25,8 @@ public: _NEXT_TX = jsonReadInt(parameters, "NEXT_TX"); jsonRead(parameters, "UpTelegram", _UpTelegram); -#define NEXT_RX _NEXT_RX // Nextion RX pin | Default 16 -#define NEXT_TX _NEXT_TX // Nextion TX pin | Default 17 +//#define NEXT_RX _NEXT_RX // Nextion RX pin | Default 16 +//#define NEXT_TX _NEXT_TX // Nextion TX pin | Default 17 } IoTValue execute(String command, std::vector ¶m) @@ -96,7 +96,7 @@ public: SerialPrint("I", F("NextionUpdate"), "connection failed "); } #endif - SerialPrint("I", F("NextionUpdate"), "Requesting file: " + (String)_url); + SerialPrint("I", F("NextionUpdate"), "Requesting file: OK" ); int code = http.GET(); // Update the nextion display if (code == 200) @@ -118,7 +118,7 @@ public: int contentLength = http.getSize(); SerialPrint("I", F("NextionUpdate"), "File received. Update Nextion... "); bool result; - ESPNexUpload nextion(115200); + ESPNexUpload nextion(115200, _NEXT_RX, _NEXT_TX); nextion.setUpdateProgressCallback([]() { SerialPrint("I", F("NextionUpdate"), "... "); }); diff --git a/src/modules/display/NextionUpload/modinfo.json b/src/modules/display/NextionUpload/modinfo.json index aed9d0ce..54fdb1c7 100644 --- a/src/modules/display/NextionUpload/modinfo.json +++ b/src/modules/display/NextionUpload/modinfo.json @@ -38,26 +38,12 @@ }, "defActive": false, "usedLibs": { - "esp32_4mb": [ - "https://github.com/Nredor/ESPNexUpload.git" - ], - "esp32_4mb3f": [ - "https://github.com/Nredor/ESPNexUpload.git" - ], - "esp8266_4mb": [ - "https://github.com/Nredor/ESPNexUpload.git" - ], - "esp8266_1mb": [ - "https://github.com/Nredor/ESPNexUpload.git" - ], - "esp8266_1mb_ota": [ - "https://github.com/Nredor/ESPNexUpload.git" - ], - "esp8285_1mb": [ - "https://github.com/Nredor/ESPNexUpload.git" - ], - "esp8285_1mb_ota": [ - "https://github.com/Nredor/ESPNexUpload.git" - ] + "esp32_4mb": [], + "esp32_4mb3f": [], + "esp8266_4mb": [], + "esp8266_1mb": [], + "esp8266_1mb_ota": [], + "esp8285_1mb": [], + "esp8285_1mb_ota": [] } } \ No newline at end of file From cffc6dbab52f8ce4f152496639d8c41ea838b69c Mon Sep 17 00:00:00 2001 From: Mit4el Date: Wed, 15 Nov 2023 22:06:13 +0300 Subject: [PATCH 7/7] upd profile file --- compilerProfile.json | 12 ++++++++++++ myProfile.json | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/compilerProfile.json b/compilerProfile.json index 381f87da..b87fdac3 100644 --- a/compilerProfile.json +++ b/compilerProfile.json @@ -198,6 +198,14 @@ "path": "src/modules/sensors/Ble", "active": false }, + { + "path": "src/modules/sensors/Ble_part1", + "active": false + }, + { + "path": "src/modules/sensors/Ble_part2", + "active": false + }, { "path": "src/modules/sensors/Bme280", "active": true @@ -430,6 +438,10 @@ "path": "src/modules/display/Lcd2004", "active": true }, + { + "path": "src/modules/display/NextionUpload", + "active": false + }, { "path": "src/modules/display/Oled128", "active": false diff --git a/myProfile.json b/myProfile.json index 381f87da..b87fdac3 100644 --- a/myProfile.json +++ b/myProfile.json @@ -198,6 +198,14 @@ "path": "src/modules/sensors/Ble", "active": false }, + { + "path": "src/modules/sensors/Ble_part1", + "active": false + }, + { + "path": "src/modules/sensors/Ble_part2", + "active": false + }, { "path": "src/modules/sensors/Bme280", "active": true @@ -430,6 +438,10 @@ "path": "src/modules/display/Lcd2004", "active": true }, + { + "path": "src/modules/display/NextionUpload", + "active": false + }, { "path": "src/modules/display/Oled128", "active": false