Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BT] Add BM2 voltage #1495

Merged
merged 2 commits into from
Mar 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/prerequisites/devices.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Added to that it retrieves the measures from the devices below. By default the d
| BlueMaestro|TempoDisc 1 in 1|temperature/battery|
| BlueMaestro|TempoDisc 3 in 1|temperature/humidity/dew point/battery|
| BlueMaestro|TempoDisc 4 in 1|temperature/humidity/pressure/battery|
| BM2 Battery Monitor|BM2|battery|
| BM2 Battery Monitor|BM2|battery/volt(c)|
| ClearGrass|CGG1|temperature/humidity/battery/voltage (depending on which CGG1 firmware is installed)|
| ClearGrass alarm clock|CGD1|temperature/humidity/battery|
| ClearGrass alarm clock|CGC1|temperature/humidity/battery|
Expand Down Expand Up @@ -84,7 +84,7 @@ Added to that it retrieves the measures from the devices below. By default the d
| ThermoPro|TP393|temperature/humidity|
| TPMS|TPMS|temperature/pressure/battery/alarm/count|
| Vegtrug||temperature/moisture/luminance/fertility|
| XIAOMI Mi Flora|HHCCJCY01HHCC|temperature/moisture/luminance/fertility/battery(1)(c)|
| XIAOMI Mi Flora|HHCCJCY01HHCC|temperature/moisture/luminance/fertility/battery(c)|
| XIAOMI Ropot|HHCCPOT002|temperature/moisture/fertility|
| XIAOMI Mi Jia|LYWSDCGO|temperature/humidity/battery|
| XIAOMI Mi Jia|LYWSD02|temperature/humidity/battery|
Expand Down
9 changes: 9 additions & 0 deletions main/ZgatewayBLEConnect.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@ class DT24_connect : public zBLEConnect {
void publishData() override;
};

class BM2_connect : public zBLEConnect {
//std::vector<uint8_t> m_data;
void notifyCB(NimBLERemoteCharacteristic* pChar, uint8_t* pData, size_t length, bool isNotify);

public:
BM2_connect(NimBLEAddress& addr) : zBLEConnect(addr) {}
void publishData() override;
};

class GENERIC_connect : public zBLEConnect {
std::vector<uint8_t> m_data;

Expand Down
76 changes: 75 additions & 1 deletion main/ZgatewayBLEConnect.ino
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
# include "ArduinoJson.h"
# include "ArduinoLog.h"
# include "ZgatewayBLEConnect.h"

# define convertTemp_CtoF(c) ((c * 1.8) + 32)

extern bool ProcessLock;
Expand Down Expand Up @@ -255,6 +254,81 @@ void DT24_connect::publishData() {
}
}

/*-----------------------BM2 HANDLING-----------------------*/
void BM2_connect::notifyCB(NimBLERemoteCharacteristic* pChar, uint8_t* pData, size_t length, bool isNotify) {
if (m_taskHandle == nullptr) {
return; // unexpected notification
}

if (!ProcessLock) {
Log.trace(F("Callback from %s characteristic" CR), pChar->getUUID().toString().c_str());
if (length == 16) {
Log.trace(F("Device identified creating BLE buffer" CR));
JsonObject& BLEdata = getBTJsonObject();
String mac_address = m_pClient->getPeerAddress().toString().c_str();
mac_address.toUpperCase();
BLEdata["model"] = "BM2 Battery Monitor";
BLEdata["id"] = (char*)mac_address.c_str();
mbedtls_aes_context aes;
mbedtls_aes_init(&aes);
unsigned char output[16];
unsigned char iv[16] = {};
unsigned char key[16] = {
108,
101,
97,
103,
101,
110,
100,
255,
254,
49,
56,
56,
50,
52,
54,
54,
};
mbedtls_aes_setkey_dec(&aes, key, 128);
mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, 16, iv, (uint8_t*)&pData[0], output);
mbedtls_aes_free(&aes);
float volt = ((output[2] | (output[1] << 8)) >> 4) / 100.0f;
BLEdata["volt"] = volt;
Log.trace(F("volt: %F" CR), volt);
pubBT(BLEdata);
} else {
Log.notice(F("Invalid notification data" CR));
return;
}
} else {
Log.trace(F("Callback process canceled by processLock" CR));
}

xTaskNotifyGive(m_taskHandle);
}

void BM2_connect::publishData() {
NimBLEUUID serviceUUID("fff0");
NimBLEUUID charUUID("fff4");
NimBLERemoteCharacteristic* pChar = getCharacteristic(serviceUUID, charUUID);

if (pChar && pChar->canNotify()) {
Log.trace(F("Registering notification" CR));
if (pChar->subscribe(true, std::bind(&BM2_connect::notifyCB, this,
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3, std::placeholders::_4))) {
m_taskHandle = xTaskGetCurrentTaskHandle();
if (ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(BLE_CNCT_TIMEOUT)) == pdFALSE) {
m_taskHandle = nullptr;
}
} else {
Log.notice(F("Failed registering notification" CR));
}
}
}

/*-----------------------HHCCJCY01HHCC HANDLING-----------------------*/
void HHCCJCY01HHCC_connect::publishData() {
NimBLEUUID serviceUUID("00001204-0000-1000-8000-00805f9b34fb");
Expand Down
27 changes: 25 additions & 2 deletions main/ZgatewayBT.ino
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,18 @@ void DT24Discovery(const char* mac, const char* sensorModel_id) {
createDiscoveryFromList(mac, DT24sensor, DT24parametersCount, "DT24", "ATorch", sensorModel_id);
}

void BM2Discovery(const char* mac, const char* sensorModel_id) {
# define BM2parametersCount 2
Log.trace(F("BM2Discovery" CR));
const char* BM2sensor[BM2parametersCount][9] = {
{"sensor", "volt", mac, "voltage", jsonVolt, "", "", "V", stateClassMeasurement},
{"sensor", "batt", mac, "battery", jsonBatt, "", "", "%", stateClassMeasurement}
//component type,name,availability topic,device class,value template,payload on, payload off, unit of measurement
};

createDiscoveryFromList(mac, BM2sensor, BM2parametersCount, "BM2", "Generic", sensorModel_id);
}

void LYWSD03MMCDiscovery(const char* mac, const char* sensorModel) {
# define LYWSD03MMCparametersCount 4
Log.trace(F("LYWSD03MMCDiscovery" CR));
Expand Down Expand Up @@ -529,6 +541,7 @@ void LYWSD03MMCDiscovery(const char* mac, const char* sensorModel) {}
void MHO_C401Discovery(const char* mac, const char* sensorModel) {}
void HHCCJCY01HHCCDiscovery(const char* mac, const char* sensorModel) {}
void DT24Discovery(const char* mac, const char* sensorModel_id) {}
void BM2Discovery(const char* mac, const char* sensorModel_id) {}
void XMWSDJ04MMCDiscovery(const char* mac, const char* sensorModel_id) {}
# endif

Expand Down Expand Up @@ -668,6 +681,10 @@ void BLEconnect() {
DT24_connect BLEclient(addr);
BLEclient.processActions(BLEactions);
BLEclient.publishData();
} else if (p->sensorModel_id == BLEconectable::id::BM2) {
BM2_connect BLEclient(addr);
BLEclient.processActions(BLEactions);
BLEclient.publishData();
} else if (p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC) {
HHCCJCY01HHCC_connect BLEclient(addr);
BLEclient.processActions(BLEactions);
Expand Down Expand Up @@ -696,6 +713,7 @@ void BLEconnect() {
if (p->sensorModel_id != BLEconectable::id::DT24_BLE &&
p->sensorModel_id != TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC &&
p->sensorModel_id != BLEconectable::id::LYWSD03MMC &&
p->sensorModel_id != BLEconectable::id::BM2 &&
p->sensorModel_id != BLEconectable::id::MHO_C401 &&
p->sensorModel_id != BLEconectable::id::XMWSDJ04MMC) {
// if irregulary connected to and connection failed clear the connect flag.
Expand Down Expand Up @@ -906,7 +924,7 @@ void launchBTDiscovery(bool overrideDiscovery) {
if (!BTConfig.extDecoderEnable && // Do not decode if an external decoder is configured
p->sensorModel_id > TheengsDecoder::BLE_ID_NUM::UNKNOWN_MODEL &&
p->sensorModel_id < TheengsDecoder::BLE_ID_NUM::BLE_ID_MAX &&
p->sensorModel_id != TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC) { // Exception on HHCCJCY01HHCC as this one is discoverable and connectable for battery retrieving
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
Log.trace(F("Looking for Model_id: %d" CR), p->sensorModel_id);
std::string properties = decoder.getTheengProperties(p->sensorModel_id);
Log.trace(F("properties: %s" CR), properties.c_str());
Expand Down Expand Up @@ -952,11 +970,14 @@ void launchBTDiscovery(bool overrideDiscovery) {
} else {
if (p->sensorModel_id > BLEconectable::id::MIN &&
p->sensorModel_id < BLEconectable::id::MAX ||
p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC) {
p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC || p->sensorModel_id == TheengsDecoder::BLE_ID_NUM::BM2) {
// Discovery of sensors from which we retrieve data only by connect
if (p->sensorModel_id == BLEconectable::id::DT24_BLE) {
DT24Discovery(macWOdots.c_str(), "DT24-BLE");
}
if (p->sensorModel_id == BLEconectable::id::BM2) {
BM2Discovery(macWOdots.c_str(), "BM2");
}
if (p->sensorModel_id == BLEconectable::id::LYWSD03MMC) {
LYWSD03MMCDiscovery(macWOdots.c_str(), "LYWSD03MMC");
}
Expand Down Expand Up @@ -1046,6 +1067,8 @@ void process_bledata(JsonObject& BLEdata) {
model_id = BLEconectable::id::LYWSD03MMC;
else if (name.compare("DT24-BLE") == 0)
model_id = BLEconectable::id::DT24_BLE;
else if (name.compare("Battery Monitor") == 0)
model_id = BLEconectable::id::BM2;
else if (name.compare("MHO-C401") == 0)
model_id = BLEconectable::id::MHO_C401;
else if (name.compare("XMWSDJ04MMC") == 0)
Expand Down
1 change: 1 addition & 0 deletions main/config_BT.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ class BLEconectable {
LYWSD03MMC,
MHO_C401,
DT24_BLE,
BM2,
XMWSDJ04MMC,
MAX,
};
Expand Down