Skip to content

Commit 1c838f0

Browse files
committed
EXPERIMENTAL: Ble read/write characteristics over MQTT.
Uses 1technophile#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}
1 parent 792807e commit 1c838f0

File tree

4 files changed

+117
-1
lines changed

4 files changed

+117
-1
lines changed

main/ZgatewayBLEConnect.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#ifdef ESP32
55
# include "ArduinoJson.h"
66
# include "NimBLEDevice.h"
7+
# include "config_BT.h"
78

89
extern void pubBT(JsonObject& data);
910

@@ -13,6 +14,9 @@ class zBLEConnect {
1314
TaskHandle_t m_taskHandle = nullptr;
1415
zBLEConnect(NimBLEAddress& addr) { m_pClient = NimBLEDevice::createClient(addr); }
1516
virtual ~zBLEConnect() { NimBLEDevice::deleteClient(m_pClient); }
17+
virtual bool writeData(BLEAction* action);
18+
virtual bool readData(BLEAction* action);
19+
virtual bool processActions(std::vector<BLEAction>& actions);
1620
virtual void publishData() {}
1721
virtual NimBLERemoteCharacteristic* getCharacteristic(const NimBLEUUID& service, const NimBLEUUID& characteristic);
1822
};

main/ZgatewayBLEConnect.ino

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
# include "ArduinoJson.h"
55
# include "ArduinoLog.h"
66
# include "ZgatewayBLEConnect.h"
7-
# include "config_BT.h"
87

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

@@ -35,6 +34,57 @@ NimBLERemoteCharacteristic* zBLEConnect::getCharacteristic(const NimBLEUUID& ser
3534
return pRemoteCharacteristic;
3635
}
3736

37+
bool zBLEConnect::writeData(BLEAction* action) {
38+
NimBLERemoteCharacteristic* pChar = getCharacteristic(action->service, action->characteristic);
39+
40+
if (pChar && pChar->canWrite()) {
41+
return pChar->writeValue(action->value);
42+
}
43+
return false;
44+
}
45+
46+
bool zBLEConnect::readData(BLEAction* action) {
47+
NimBLERemoteCharacteristic* pChar = getCharacteristic(action->service, action->characteristic);
48+
49+
if (pChar && pChar->canRead()) {
50+
action->value = pChar->readValue();
51+
if (action->value != "") {
52+
return true;
53+
}
54+
}
55+
return false;
56+
}
57+
58+
bool zBLEConnect::processActions(std::vector<BLEAction>& actions) {
59+
bool result = false;
60+
if (actions.size() > 0) {
61+
for (auto& it : actions) {
62+
if (NimBLEAddress(it.addr) == m_pClient->getPeerAddress()) {
63+
JsonObject& BLEresult = getBTJsonObject();
64+
BLEresult.set("id", it.addr);
65+
BLEresult.set("service", (char*)it.service.toString().c_str());
66+
BLEresult.set("characteristic", (char*)it.characteristic.toString().c_str());
67+
68+
if (it.write) {
69+
Log.trace(F("processing BLE write" CR));
70+
BLEresult.set("write", it.value.c_str());
71+
result = writeData(&it);
72+
} else {
73+
Log.trace(F("processing BLE read" CR));
74+
result = readData(&it);
75+
BLEresult.set("read", it.value.c_str());
76+
}
77+
78+
it.complete = true;
79+
BLEresult.set("success", result);
80+
pubBT(BLEresult);
81+
}
82+
}
83+
}
84+
85+
return result;
86+
}
87+
3888
/*-----------------------LYWSD03MMC && MHO_C401 HANDLING-----------------------*/
3989
void LYWSD03MMC_connect::notifyCB(NimBLERemoteCharacteristic* pChar, uint8_t* pData, size_t length, bool isNotify) {
4090
if (m_taskHandle == nullptr) {
@@ -158,5 +208,6 @@ void DT24_connect::publishData() {
158208
}
159209
}
160210
}
211+
161212
# endif //ZgatewayBT
162213
#endif //ESP32

main/ZgatewayBT.ino

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ struct decompose {
7171
bool reverse;
7272
};
7373

74+
# ifdef ESP32
75+
vector<BLEAction> BLEactions;
76+
# endif
77+
7478
vector<BLEdevice*> devices;
7579
int newDevices = 0;
7680

@@ -727,21 +731,33 @@ void BLEconnect() {
727731
if (p->connect) {
728732
Log.trace(F("Model to connect found: %s" CR), p->macAdr);
729733
NimBLEAddress addr(std::string(p->macAdr));
734+
730735
switch (p->sensorModel) {
731736
case LYWSD03MMC:
732737
case MHO_C401: {
733738
LYWSD03MMC_connect BLEclient(addr);
739+
BLEclient.processActions(BLEactions);
734740
BLEclient.publishData();
735741
break;
736742
}
737743
case DT24: {
738744
DT24_connect BLEclient(addr);
745+
BLEclient.processActions(BLEactions);
739746
BLEclient.publishData();
740747
break;
741748
}
742749
default:
743750
break;
744751
}
752+
if (BLEactions.size() > 0) {
753+
std::vector<BLEAction> swap;
754+
for (auto& it : BLEactions) {
755+
if (!it.complete && --it.ttl) {
756+
swap.push_back(it);
757+
}
758+
}
759+
std::swap(BLEactions, swap);
760+
}
745761
}
746762
}
747763
Log.notice(F("BLE Connect end" CR));
@@ -1661,6 +1677,36 @@ void BTforceScan() {
16611677
}
16621678
}
16631679

1680+
void MQTTtoBTAction(JsonObject& BTdata) {
1681+
# ifdef ESP32
1682+
BLEAction action;
1683+
action.ttl = BTdata.containsKey("ttl") ? (uint8_t)BTdata["ttl"] : 1;
1684+
Log.trace(F("BLE ACTION TTL = %u" CR), action.ttl);
1685+
action.complete = false;
1686+
if (BTdata.containsKey("ble_write_address") &&
1687+
BTdata.containsKey("ble_write_service") &&
1688+
BTdata.containsKey("ble_write_char") &&
1689+
BTdata.containsKey("ble_write_value")) {
1690+
strcpy(action.addr, (const char*)BTdata["ble_write_address"]);
1691+
action.service = NimBLEUUID((const char*)BTdata["ble_write_service"]);
1692+
action.characteristic = NimBLEUUID((const char*)BTdata["ble_write_char"]);
1693+
action.value = std::string((const char*)BTdata["ble_write_value"]);
1694+
action.write = true;
1695+
} else if (BTdata.containsKey("ble_read_address") &&
1696+
BTdata.containsKey("ble_read_service") &&
1697+
BTdata.containsKey("ble_read_char")) {
1698+
strcpy(action.addr, (const char*)BTdata["ble_read_address"]);
1699+
action.service = NimBLEUUID((const char*)BTdata["ble_read_service"]);
1700+
action.characteristic = NimBLEUUID((const char*)BTdata["ble_read_char"]);
1701+
action.write = false;
1702+
} else {
1703+
return;
1704+
}
1705+
1706+
BLEactions.push_back(action);
1707+
# endif
1708+
}
1709+
16641710
void MQTTtoBT(char* topicOri, JsonObject& BTdata) { // json object decoding
16651711
if (cmpToMainTopic(topicOri, subjectMQTTtoBTset)) {
16661712
Log.trace(F("MQTTtoBT json set" CR));
@@ -1722,6 +1768,8 @@ void MQTTtoBT(char* topicOri, JsonObject& BTdata) { // json object decoding
17221768
if (BTdata.containsKey("lowpowermode")) {
17231769
changelowpowermode((int)BTdata["lowpowermode"]);
17241770
}
1771+
1772+
MQTTtoBTAction(BTdata);
17251773
# endif
17261774
// MinRSSI set
17271775
if (BTdata.containsKey("minrssi")) {

main/config_BT.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ bool bleConnect = AttemptBLECOnnect;
4646
# ifndef BLE_FILTER_CONNECTABLE
4747
# define BLE_FILTER_CONNECTABLE 1
4848
# endif
49+
# include "NimBLEDevice.h"
4950
#endif
5051

5152
/*----------------------BT topics & parameters-------------------------*/
@@ -168,6 +169,18 @@ enum ble_sensor_model {
168169
#endif
169170

170171
/*---------------INTERNAL USE: DO NOT MODIFY--------------*/
172+
#ifdef ESP32
173+
struct BLEAction {
174+
std::string value;
175+
char addr[18];
176+
NimBLEUUID service;
177+
NimBLEUUID characteristic;
178+
bool write;
179+
bool complete;
180+
uint8_t ttl;
181+
};
182+
#endif
183+
171184
struct BLEdevice {
172185
char macAdr[18];
173186
bool isDisc;

0 commit comments

Comments
 (0)