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