Ble read/write characteristics over MQTT. (#988)

* EXPERIMENTAL: Ble read/write characteristics over MQTT.

Uses #979

This allows reading and writing BLE characteristics from an MQTT message.

Example format:
mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"ble_write_address":"AA:BB:CC:DD:EE:FF", "ble_write_service":"cba20d00-224d-11e6-9fb8-0002a5d5c51b", "ble_write_char":"cba20002-224d-11e6-9fb8-0002a5d5c51b", "ble_write_value":"TEST", "ttl":4 }'
mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"ble_read_address":"30:AE:A4:7C:3C:A6", "ble_read_service":"cba20d00-224d-11e6-9fb8-0002a5d5c51b", "ble_read_char":"cba20002-224d-11e6-9fb8-0002a5d5c51b", "ttl": 2 }'
The ttl parameter is the number of calls to connect (defaults to 1), which occur after the BLE scan completes.

A response is provided over MQTT in the format:
write : {"id":"30:AE:A4:7C:3C:A6","service":"cba20d00-224d-11e6-9fb8-0002a5d5c51b","characteristic":"cba20002-224d-11e6-9fb8-0002a5d5c51b","write":"TEST","success":true}
read : {"id":"30:AE:A4:7C:3C:A6","service":"cba20d00-224d-11e6-9fb8-0002a5d5c51b","characteristic":"cba20002-224d-11e6-9fb8-0002a5d5c51b","read":"TEST","success":true}

* Add generic BLE connect class and read data as hex.

* Add value_type parameter and document usage

* Add note to docs
This commit is contained in:
h2zero authored and GitHub committed 2021-06-21 20:27:06 -05:00
1 parent ac23235327
commit 7cfbd3d050
5 files changed
+251 -2

No files matched your search

+94 -1
View File
@@ -4,7 +4,6 @@
# include "ArduinoJson.h"
# include "ArduinoLog.h"
# include "ZgatewayBLEConnect.h"
# include "config_BT.h"
# define convertTemp_CtoF(c) ((c * 1.8) + 32)
@@ -35,6 +34,99 @@ NimBLERemoteCharacteristic* zBLEConnect::getCharacteristic(const NimBLEUUID& ser
return pRemoteCharacteristic;
}
bool zBLEConnect::writeData(BLEAction* action) {
NimBLERemoteCharacteristic* pChar = getCharacteristic(action->service, action->characteristic);
if (pChar && pChar->canWrite()) {
switch (action->value_type) {
case BLE_VAL_HEX: {
int len = action->value.length();
if (len % 2) {
Log.error(F("Invalid HEX value length" CR));
return false;
}
std::vector<uint8_t> buf;
for (auto i = 0; i < len; i += 2) {
std::string temp = action->value.substr(i, 2);
buf.push_back((uint8_t)strtoul(temp.c_str(), nullptr, 16));
}
return pChar->writeValue((const uint8_t*)&buf[0], buf.size());
}
case BLE_VAL_INT:
return pChar->writeValue(strtol(action->value.c_str(), nullptr, 0));
case BLE_VAL_FLOAT:
return pChar->writeValue(strtod(action->value.c_str(), nullptr));
default:
return pChar->writeValue(action->value);
}
}
return false;
}
bool zBLEConnect::readData(BLEAction* action) {
NimBLERemoteCharacteristic* pChar = getCharacteristic(action->service, action->characteristic);
if (pChar && pChar->canRead()) {
action->value = pChar->readValue();
if (action->value != "") {
return true;
}
}
return false;
}
bool zBLEConnect::processActions(std::vector<BLEAction>& actions) {
bool result = false;
if (actions.size() > 0) {
for (auto& it : actions) {
if (NimBLEAddress(it.addr) == m_pClient->getPeerAddress()) {
JsonObject& BLEresult = getBTJsonObject();
BLEresult.set("id", it.addr);
BLEresult.set("service", (char*)it.service.toString().c_str());
BLEresult.set("characteristic", (char*)it.characteristic.toString().c_str());
if (it.write) {
Log.trace(F("processing BLE write" CR));
BLEresult.set("write", it.value.c_str());
result = writeData(&it);
} else {
Log.trace(F("processing BLE read" CR));
result = readData(&it);
if (result) {
switch (it.value_type) {
case BLE_VAL_HEX: {
char* pHex = NimBLEUtils::buildHexData(nullptr, (uint8_t*)it.value.c_str(), it.value.length());
BLEresult.set("read", pHex);
free(pHex);
break;
}
case BLE_VAL_INT: {
int ival = *(int*)it.value.data();
BLEresult.set<int>("read", ival);
break;
}
case BLE_VAL_FLOAT: {
float fval = *(double*)it.value.data();
BLEresult.set<float>("read", fval);
break;
}
default:
BLEresult.set("read", it.value.c_str());
break;
}
}
}
it.complete = true;
BLEresult.set("success", result);
pubBT(BLEresult);
}
}
}
return result;
}
/*-----------------------LYWSD03MMC && MHO_C401 HANDLING-----------------------*/
void LYWSD03MMC_connect::notifyCB(NimBLERemoteCharacteristic* pChar, uint8_t* pData, size_t length, bool isNotify) {
if (m_taskHandle == nullptr) {
@@ -160,5 +252,6 @@ void DT24_connect::publishData() {
}
}
}
# endif //ZgatewayBT
#endif //ESP32