[BLE] Add BM6 Battery Monitor connection support (#2274)
* [BLE] Add BM6 Battery Monitor connection support Implement BLE connection support for BM6 Battery Monitor devices, following the BM2 pattern with BM6-specific protocol handling. Key features: - Encrypted command/response using AES-128 CBC - Read voltage, temperature, and State of Charge (SoC) - Home Assistant MQTT Discovery support - Device tracker integration Technical implementation: - Add BM6_connect class with encrypted command handling - Encryption key (static const): "leagend\xff\xfe0100009" - Parse hex string positions for voltage (15-17), temp (8-9), SoC (12-13) - Add discovery with 3 sensors (voltage, temperature, battery %) - Validate message signature (D15507) - Add canWrite() check before writing to characteristic - Empty stub for non-ESP32 builds Code quality improvements: - Extract AES key as static constant to avoid duplication - Use shared jsonVoltBM template for both BM2 and BM6 - Clean up commented-out reasoning in parsing logic Based on reverse engineering from: https://github.com/JeffWDH/bm6-battery-monitor Files modified: - main/gatewayBLEConnect.h: Add BM6_connect class - main/gatewayBLEConnect.cpp: Implement BM6 connection logic - main/gatewayBT.cpp: Add detection, connection, and discovery handlers - main/config_mqttDiscovery.h: Rename jsonVoltBM2 to jsonVoltBM Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * Add BM6 to exceptions --------- Co-authored-by: Florian <1technophile@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
4 files changed
+184
-5
No files matched your search
@@ -177,7 +177,7 @@ extern char discovery_prefix[];
|
|||||||
#define jsonAlarm "{{ value_json.alarm | is_defined }}"
|
#define jsonAlarm "{{ value_json.alarm | is_defined }}"
|
||||||
#define jsonInuse "{{ value_json.power | is_defined | float > 0 }}"
|
#define jsonInuse "{{ value_json.power | is_defined | float > 0 }}"
|
||||||
#define jsonInuseRN8209 "{% if value_json.power > 0.02 -%} on {% else %} off {%- endif %}"
|
#define jsonInuseRN8209 "{% if value_json.power > 0.02 -%} on {% else %} off {%- endif %}"
|
||||||
#define jsonVoltBM2 "{% if value_json.uuid is not defined and value_json.volt is defined -%} {{value_json.volt}} {%- endif %}"
|
#define jsonVoltBM "{% if value_json.uuid is not defined and value_json.volt is defined -%} {{value_json.volt}} {%- endif %}"
|
||||||
#define jsonRSSI "{{ value_json.rssi | is_defined }}"
|
#define jsonRSSI "{{ value_json.rssi | is_defined }}"
|
||||||
|
|
||||||
#define stateClassNone ""
|
#define stateClassNone ""
|
||||||
|
|||||||
@@ -332,6 +332,143 @@ void BM2_connect::publishData() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-----------------------BM6 HANDLING-----------------------*/
|
||||||
|
// BM6 AES encryption key: "leagend\xff\xfe0100009"
|
||||||
|
static const unsigned char BM6_AES_KEY[16] = {
|
||||||
|
108, // l
|
||||||
|
101, // e
|
||||||
|
97, // a
|
||||||
|
103, // g
|
||||||
|
101, // e
|
||||||
|
110, // n
|
||||||
|
100, // d
|
||||||
|
255, // 0xff
|
||||||
|
254, // 0xfe
|
||||||
|
48, // 0
|
||||||
|
49, // 1
|
||||||
|
48, // 0
|
||||||
|
48, // 0
|
||||||
|
48, // 0
|
||||||
|
48, // 0
|
||||||
|
57, // 9
|
||||||
|
};
|
||||||
|
|
||||||
|
void BM6_connect::notifyCB(NimBLERemoteCharacteristic* pChar, uint8_t* pData, size_t length, bool isNotify) {
|
||||||
|
if (m_taskHandle == nullptr) {
|
||||||
|
return; // unexpected notification
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!BTProcessLock) {
|
||||||
|
THEENGS_LOG_TRACE(F("Callback from %s characteristic" CR), pChar->getUUID().toString().c_str());
|
||||||
|
if (length == 16) {
|
||||||
|
THEENGS_LOG_TRACE(F("Device identified creating BLE buffer" CR));
|
||||||
|
DynamicJsonDocument BLEdataBuffer(JSON_MSG_BUFFER);
|
||||||
|
JsonObject BLEdata = BLEdataBuffer.to<JsonObject>();
|
||||||
|
BLEdata["model"] = "BM6 Battery Monitor";
|
||||||
|
BLEdata["id"] = m_pClient->getPeerAddress().toString();
|
||||||
|
mbedtls_aes_context aes;
|
||||||
|
mbedtls_aes_init(&aes);
|
||||||
|
unsigned char output[16];
|
||||||
|
unsigned char iv[16] = {};
|
||||||
|
mbedtls_aes_setkey_dec(&aes, BM6_AES_KEY, 128);
|
||||||
|
mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, 16, iv, (uint8_t*)&pData[0], output);
|
||||||
|
mbedtls_aes_free(&aes);
|
||||||
|
|
||||||
|
// Check for valid message signature (should start with D15507)
|
||||||
|
if (output[0] != 0xd1 || output[1] != 0x55 || output[2] != 0x07) {
|
||||||
|
THEENGS_LOG_NOTICE(F("BM6 invalid message signature" CR));
|
||||||
|
xTaskNotifyGive(m_taskHandle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse according to BM6 protocol (from https://github.com/JeffWDH/bm6-battery-monitor)
|
||||||
|
// The decrypted data is converted to a hex string for parsing:
|
||||||
|
// - Voltage: hex string positions 15-17 (3 chars) / 100
|
||||||
|
// - Temperature: hex string positions 8-9 (2 chars), negated if positions 6-7 == "01"
|
||||||
|
// - SoC (State of Charge): hex string positions 12-13 (2 chars)
|
||||||
|
char hexstr[33];
|
||||||
|
sprintf(hexstr, "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
|
||||||
|
output[0], output[1], output[2], output[3], output[4], output[5], output[6], output[7],
|
||||||
|
output[8], output[9], output[10], output[11], output[12], output[13], output[14], output[15]);
|
||||||
|
|
||||||
|
// Extract voltage (positions 15-17 in hex string)
|
||||||
|
char volt_str[4] = {hexstr[15], hexstr[16], hexstr[17], 0};
|
||||||
|
int volt_raw = (int)strtol(volt_str, NULL, 16);
|
||||||
|
float volt = volt_raw / 100.0f;
|
||||||
|
|
||||||
|
// Extract SoC (positions 12-13 in hex string)
|
||||||
|
char soc_str[3] = {hexstr[12], hexstr[13], 0};
|
||||||
|
int soc = (int)strtol(soc_str, NULL, 16);
|
||||||
|
|
||||||
|
// Extract temperature (positions 8-9 in hex string)
|
||||||
|
char temp_str[3] = {hexstr[8], hexstr[9], 0};
|
||||||
|
int temp_raw = (int)strtol(temp_str, NULL, 16);
|
||||||
|
|
||||||
|
// Check temperature sign (positions 6-7 in hex string)
|
||||||
|
char temp_sign_str[3] = {hexstr[6], hexstr[7], 0};
|
||||||
|
float temp = (strcmp(temp_sign_str, "01") == 0) ? -temp_raw : temp_raw;
|
||||||
|
|
||||||
|
BLEdata["tempc"] = temp;
|
||||||
|
BLEdata["tempf"] = (float)convertTemp_CtoF(temp);
|
||||||
|
BLEdata["volt"] = volt;
|
||||||
|
BLEdata["batt"] = soc;
|
||||||
|
// to avoid the BM6 device tracker going offline because of the voltage/temp MQTT message without an RSSI value
|
||||||
|
BLEdata["rssi"] = -60;
|
||||||
|
buildTopicFromId(BLEdata, subjectBTtoMQTT);
|
||||||
|
enqueueJsonObject(BLEdata, QueueSemaphoreTimeOutTask);
|
||||||
|
} else {
|
||||||
|
THEENGS_LOG_NOTICE(F("Invalid notification data" CR));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
THEENGS_LOG_TRACE(F("Callback process canceled by BTProcessLock" CR));
|
||||||
|
}
|
||||||
|
|
||||||
|
xTaskNotifyGive(m_taskHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BM6_connect::publishData() {
|
||||||
|
NimBLEUUID serviceUUID("fff0");
|
||||||
|
NimBLEUUID charWriteUUID("fff3");
|
||||||
|
NimBLEUUID charNotifyUUID("fff4");
|
||||||
|
|
||||||
|
// Get write characteristic to send command
|
||||||
|
NimBLERemoteCharacteristic* pCharWrite = getCharacteristic(serviceUUID, charWriteUUID);
|
||||||
|
// Get notify characteristic to receive data
|
||||||
|
NimBLERemoteCharacteristic* pCharNotify = getCharacteristic(serviceUUID, charNotifyUUID);
|
||||||
|
|
||||||
|
if (pCharWrite && (pCharWrite->canWrite() || pCharWrite->canWriteNoResponse()) &&
|
||||||
|
pCharNotify && pCharNotify->canNotify()) {
|
||||||
|
THEENGS_LOG_TRACE(F("Registering notification" CR));
|
||||||
|
if (pCharNotify->subscribe(true, std::bind(&BM6_connect::notifyCB, this,
|
||||||
|
std::placeholders::_1, std::placeholders::_2,
|
||||||
|
std::placeholders::_3, std::placeholders::_4))) {
|
||||||
|
// Encrypt the command before sending (BM6 requires encrypted commands)
|
||||||
|
uint8_t command_plain[16] = {0xd1, 0x55, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
uint8_t command_encrypted[16];
|
||||||
|
unsigned char iv[16] = {};
|
||||||
|
|
||||||
|
mbedtls_aes_context aes;
|
||||||
|
mbedtls_aes_init(&aes);
|
||||||
|
mbedtls_aes_setkey_enc(&aes, BM6_AES_KEY, 128);
|
||||||
|
mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, 16, iv, command_plain, command_encrypted);
|
||||||
|
mbedtls_aes_free(&aes);
|
||||||
|
|
||||||
|
if (pCharWrite->writeValue(command_encrypted, 16, true)) { // Use write with response
|
||||||
|
m_taskHandle = xTaskGetCurrentTaskHandle();
|
||||||
|
if (ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(BLE_CNCT_TIMEOUT)) == pdFALSE) {
|
||||||
|
m_taskHandle = nullptr;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
THEENGS_LOG_NOTICE(F("Failed to send command" CR));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
THEENGS_LOG_NOTICE(F("Failed registering notification" CR));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------HHCCJCY01HHCC HANDLING-----------------------*/
|
/*-----------------------HHCCJCY01HHCC HANDLING-----------------------*/
|
||||||
void HHCCJCY01HHCC_connect::publishData() {
|
void HHCCJCY01HHCC_connect::publishData() {
|
||||||
NimBLEUUID serviceUUID("00001204-0000-1000-8000-00805f9b34fb");
|
NimBLEUUID serviceUUID("00001204-0000-1000-8000-00805f9b34fb");
|
||||||
|
|||||||
@@ -48,6 +48,14 @@ public:
|
|||||||
void publishData() override;
|
void publishData() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class BM6_connect : public zBLEConnect {
|
||||||
|
void notifyCB(NimBLERemoteCharacteristic* pChar, uint8_t* pData, size_t length, bool isNotify);
|
||||||
|
|
||||||
|
public:
|
||||||
|
BM6_connect(NimBLEAddress& addr) : zBLEConnect(addr) {}
|
||||||
|
void publishData() override;
|
||||||
|
};
|
||||||
|
|
||||||
class GENERIC_connect : public zBLEConnect {
|
class GENERIC_connect : public zBLEConnect {
|
||||||
std::vector<uint8_t> m_data;
|
std::vector<uint8_t> m_data;
|
||||||
|
|
||||||
|
|||||||
+38
-4
@@ -514,7 +514,7 @@ void BM2Discovery(const char* mac, const char* sensorModel_id) {
|
|||||||
# define BM2parametersCount 2
|
# define BM2parametersCount 2
|
||||||
THEENGS_LOG_TRACE(F("BM2Discovery" CR));
|
THEENGS_LOG_TRACE(F("BM2Discovery" CR));
|
||||||
const char* BM2sensor[BM2parametersCount][9] = {
|
const char* BM2sensor[BM2parametersCount][9] = {
|
||||||
{HASS_TYPE_SENSOR, "volt", mac, HASS_CLASS_VOLTAGE, jsonVoltBM2, "", "", HASS_UNIT_VOLT, stateClassMeasurement}, // We use a json definition that retrieve only data from the BM2 decoder, as this sensor also advertize volt as an iBeacon
|
{HASS_TYPE_SENSOR, "volt", mac, HASS_CLASS_VOLTAGE, jsonVoltBM, "", "", HASS_UNIT_VOLT, stateClassMeasurement}, // We use a json definition that retrieve only data from the BM decoder, as this sensor also advertizes volt as an iBeacon
|
||||||
{HASS_TYPE_SENSOR, "batt", mac, HASS_CLASS_BATTERY, jsonBatt, "", "", HASS_UNIT_PERCENT, stateClassMeasurement}
|
{HASS_TYPE_SENSOR, "batt", mac, HASS_CLASS_BATTERY, jsonBatt, "", "", HASS_UNIT_PERCENT, stateClassMeasurement}
|
||||||
//component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
|
//component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
|
||||||
};
|
};
|
||||||
@@ -522,6 +522,19 @@ void BM2Discovery(const char* mac, const char* sensorModel_id) {
|
|||||||
createDiscoveryFromList(mac, BM2sensor, BM2parametersCount, "BM2", "Generic", sensorModel_id);
|
createDiscoveryFromList(mac, BM2sensor, BM2parametersCount, "BM2", "Generic", sensorModel_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BM6Discovery(const char* mac, const char* sensorModel_id) {
|
||||||
|
# define BM6parametersCount 3
|
||||||
|
THEENGS_LOG_TRACE(F("BM6Discovery" CR));
|
||||||
|
const char* BM6sensor[BM6parametersCount][9] = {
|
||||||
|
{HASS_TYPE_SENSOR, "volt", mac, HASS_CLASS_VOLTAGE, jsonVoltBM, "", "", HASS_UNIT_VOLT, stateClassMeasurement}, // We use a json definition that retrieve only data from the BM decoder, as this sensor also advertizes volt as an iBeacon
|
||||||
|
{HASS_TYPE_SENSOR, "temp", mac, HASS_CLASS_TEMPERATURE, jsonTempc, "", "", HASS_UNIT_CELSIUS, stateClassMeasurement},
|
||||||
|
{HASS_TYPE_SENSOR, "batt", mac, HASS_CLASS_BATTERY, jsonBatt, "", "", HASS_UNIT_PERCENT, stateClassMeasurement}
|
||||||
|
//component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
|
||||||
|
};
|
||||||
|
|
||||||
|
createDiscoveryFromList(mac, BM6sensor, BM6parametersCount, "BM6", "Generic", sensorModel_id);
|
||||||
|
}
|
||||||
|
|
||||||
void LYWSD03MMCDiscovery(const char* mac, const char* sensorModel) {
|
void LYWSD03MMCDiscovery(const char* mac, const char* sensorModel) {
|
||||||
# define LYWSD03MMCparametersCount 4
|
# define LYWSD03MMCparametersCount 4
|
||||||
THEENGS_LOG_TRACE(F("LYWSD03MMCDiscovery" CR));
|
THEENGS_LOG_TRACE(F("LYWSD03MMCDiscovery" CR));
|
||||||
@@ -585,6 +598,7 @@ void MHO_C401Discovery(const char* mac, const char* sensorModel) {}
|
|||||||
void HHCCJCY01HHCCDiscovery(const char* mac, const char* sensorModel) {}
|
void HHCCJCY01HHCCDiscovery(const char* mac, const char* sensorModel) {}
|
||||||
void DT24Discovery(const char* mac, const char* sensorModel_id) {}
|
void DT24Discovery(const char* mac, const char* sensorModel_id) {}
|
||||||
void BM2Discovery(const char* mac, const char* sensorModel_id) {}
|
void BM2Discovery(const char* mac, const char* sensorModel_id) {}
|
||||||
|
void BM6Discovery(const char* mac, const char* sensorModel_id) {}
|
||||||
void XMWSDJ04MMCDiscovery(const char* mac, const char* sensorModel_id) {}
|
void XMWSDJ04MMCDiscovery(const char* mac, const char* sensorModel_id) {}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
@@ -747,6 +761,10 @@ void BLEconnect() {
|
|||||||
BM2_connect BLEclient(addr);
|
BM2_connect BLEclient(addr);
|
||||||
BLEclient.processActions(BLEactions);
|
BLEclient.processActions(BLEactions);
|
||||||
BLEclient.publishData();
|
BLEclient.publishData();
|
||||||
|
} else if (p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::BM6) {
|
||||||
|
BM6_connect BLEclient(addr);
|
||||||
|
BLEclient.processActions(BLEactions);
|
||||||
|
BLEclient.publishData();
|
||||||
} else if (p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC) {
|
} else if (p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC) {
|
||||||
HHCCJCY01HHCC_connect BLEclient(addr);
|
HHCCJCY01HHCC_connect BLEclient(addr);
|
||||||
BLEclient.processActions(BLEactions);
|
BLEclient.processActions(BLEactions);
|
||||||
@@ -782,6 +800,7 @@ void BLEconnect() {
|
|||||||
p->sensorModel_id != TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC &&
|
p->sensorModel_id != TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC &&
|
||||||
p->sensorModel_id != BLEconectable::id::LYWSD03MMC &&
|
p->sensorModel_id != BLEconectable::id::LYWSD03MMC &&
|
||||||
p->sensorModel_id != TheengsDecoder::BLE_ID_NUM::BM2 &&
|
p->sensorModel_id != TheengsDecoder::BLE_ID_NUM::BM2 &&
|
||||||
|
p->sensorModel_id != TheengsDecoder::BLE_ID_NUM::BM6 &&
|
||||||
p->sensorModel_id != BLEconectable::id::MHO_C401 &&
|
p->sensorModel_id != BLEconectable::id::MHO_C401 &&
|
||||||
p->sensorModel_id != BLEconectable::id::XMWSDJ04MMC) {
|
p->sensorModel_id != BLEconectable::id::XMWSDJ04MMC) {
|
||||||
// if irregulary connected to and connection failed clear the connect flag.
|
// if irregulary connected to and connection failed clear the connect flag.
|
||||||
@@ -973,7 +992,9 @@ void launchBTDiscovery(bool overrideDiscovery) {
|
|||||||
if (!BTConfig.extDecoderEnable && // Do not decode if an external decoder is configured
|
if (!BTConfig.extDecoderEnable && // Do not decode if an external decoder is configured
|
||||||
p->sensorModel_id > UNKWNON_MODEL &&
|
p->sensorModel_id > UNKWNON_MODEL &&
|
||||||
p->sensorModel_id < TheengsDecoder::BLE_ID_NUM::BLE_ID_MAX &&
|
p->sensorModel_id < TheengsDecoder::BLE_ID_NUM::BLE_ID_MAX &&
|
||||||
p->sensorModel_id != TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC && p->sensorModel_id != TheengsDecoder::BLE_ID_NUM::BM2) { // Exception on HHCCJCY01HHCC and BM2 as these ones are discoverable and connectable
|
p->sensorModel_id != TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC &&
|
||||||
|
p->sensorModel_id != TheengsDecoder::BLE_ID_NUM::BM2 &&
|
||||||
|
p->sensorModel_id != TheengsDecoder::BLE_ID_NUM::BM6) { // Exception on HHCCJCY01HHCC and BM2/BM6 as these ones are discoverable and connectable
|
||||||
if (isTracker) {
|
if (isTracker) {
|
||||||
String tracker_name = String(model_id.c_str()) + "-tracker";
|
String tracker_name = String(model_id.c_str()) + "-tracker";
|
||||||
String tracker_id = macWOdots + "-tracker";
|
String tracker_id = macWOdots + "-tracker";
|
||||||
@@ -1124,7 +1145,7 @@ void launchBTDiscovery(bool overrideDiscovery) {
|
|||||||
} else {
|
} else {
|
||||||
if ((p->sensorModel_id > BLEconectable::id::MIN &&
|
if ((p->sensorModel_id > BLEconectable::id::MIN &&
|
||||||
p->sensorModel_id < BLEconectable::id::MAX) ||
|
p->sensorModel_id < BLEconectable::id::MAX) ||
|
||||||
p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC || p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::BM2) {
|
p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC || p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::BM2 || p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::BM6) {
|
||||||
// Discovery of sensors from which we retrieve data only by connect
|
// Discovery of sensors from which we retrieve data only by connect
|
||||||
if (p->sensorModel_id == BLEconectable::id::DT24_BLE) {
|
if (p->sensorModel_id == BLEconectable::id::DT24_BLE) {
|
||||||
DT24Discovery(macWOdots.c_str(), "DT24-BLE");
|
DT24Discovery(macWOdots.c_str(), "DT24-BLE");
|
||||||
@@ -1142,6 +1163,19 @@ void launchBTDiscovery(bool overrideDiscovery) {
|
|||||||
model.c_str(), brand.c_str(), model_id.c_str(), macWOdots.c_str(), false,
|
model.c_str(), brand.c_str(), model_id.c_str(), macWOdots.c_str(), false,
|
||||||
stateClassNone);
|
stateClassNone);
|
||||||
}
|
}
|
||||||
|
if (p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::BM6) {
|
||||||
|
// Sensor discovery
|
||||||
|
BM6Discovery(macWOdots.c_str(), "BM6");
|
||||||
|
// Device tracker discovery
|
||||||
|
String tracker_id = macWOdots + "-tracker";
|
||||||
|
createDiscovery(HASS_TYPE_DEVICE_TRACKER,
|
||||||
|
discovery_topic.c_str(), "BM6-tracker", tracker_id.c_str(),
|
||||||
|
will_Topic, "occupancy", "{% if value_json.get('rssi') -%}home{%- else -%}not_home{%- endif %}",
|
||||||
|
"", "", "",
|
||||||
|
0, "", "", false, "",
|
||||||
|
model.c_str(), brand.c_str(), model_id.c_str(), macWOdots.c_str(), false,
|
||||||
|
stateClassNone);
|
||||||
|
}
|
||||||
if (p->sensorModel_id == BLEconectable::id::LYWSD03MMC) {
|
if (p->sensorModel_id == BLEconectable::id::LYWSD03MMC) {
|
||||||
LYWSD03MMCDiscovery(macWOdots.c_str(), "LYWSD03MMC");
|
LYWSD03MMCDiscovery(macWOdots.c_str(), "LYWSD03MMC");
|
||||||
}
|
}
|
||||||
@@ -1429,7 +1463,7 @@ void process_bledata(JsonObject& BLEdata) {
|
|||||||
if ((BLEdata["type"].as<string>()).compare("RMAC") != 0 && model_id != TheengsDecoder::BLE_ID_NUM::IBEACON) { // Do not store in memory the random mac devices and iBeacons
|
if ((BLEdata["type"].as<string>()).compare("RMAC") != 0 && model_id != TheengsDecoder::BLE_ID_NUM::IBEACON) { // Do not store in memory the random mac devices and iBeacons
|
||||||
if (model_id >= 0) { // Broadcaster devices
|
if (model_id >= 0) { // Broadcaster devices
|
||||||
THEENGS_LOG_TRACE(F("Decoder found device: %s" CR), BLEdata["model_id"].as<const char*>());
|
THEENGS_LOG_TRACE(F("Decoder found device: %s" CR), BLEdata["model_id"].as<const char*>());
|
||||||
if (model_id == TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC || model_id == TheengsDecoder::BLE_ID_NUM::BM2) { // Device that broadcast and can be connected
|
if (model_id == TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC || model_id == TheengsDecoder::BLE_ID_NUM::BM2 || model_id == TheengsDecoder::BLE_ID_NUM::BM6) { // Device that broadcast and can be connected
|
||||||
createOrUpdateDevice(mac, device_flags_connect, model_id, mac_type, deviceName);
|
createOrUpdateDevice(mac, device_flags_connect, model_id, mac_type, deviceName);
|
||||||
} else {
|
} else {
|
||||||
createOrUpdateDevice(mac, device_flags_init, model_id, mac_type, deviceName);
|
createOrUpdateDevice(mac, device_flags_init, model_id, mac_type, deviceName);
|
||||||
|
|||||||
Reference in new issue
Block a user