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:
1 parent
ac23235327
commit
7cfbd3d050
5 files changed
+251
-2
No files matched your search
@@ -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
|
||||
Reference in new issue
Block a user