Can't read Hue light values
Posted: Fri Mar 10, 2023 2:08 am
Hi
I'm trying to use an ESP32 as a BLE client to interact with a Hue light to see if I can turn it on/off. I can't write a value to any characteristic, and I can only read characteristics that contain manufacturer information. My current assumption is that it is related to pairing with the device.
I can use the nRF Connect App on my android phone to turn the hue light on and off without issue. (reading/writing to any characteristic apart from manufacturer information triggers a pairing request, assuming this might be related to my issue). I would like to recreate this behaviour in my esp32 dev board.
readValue comes back empty
writeValue simply does nothing
I'd love a hand if anyone has any idea what's going wrong.
Here is my script
I'm trying to use an ESP32 as a BLE client to interact with a Hue light to see if I can turn it on/off. I can't write a value to any characteristic, and I can only read characteristics that contain manufacturer information. My current assumption is that it is related to pairing with the device.
I can use the nRF Connect App on my android phone to turn the hue light on and off without issue. (reading/writing to any characteristic apart from manufacturer information triggers a pairing request, assuming this might be related to my issue). I would like to recreate this behaviour in my esp32 dev board.
readValue comes back empty
writeValue simply does nothing
I'd love a hand if anyone has any idea what's going wrong.
Here is my script
Code: Select all
#include "BLEDevice.h"
/* UUID's of the service, characteristic that we want to read*/
static BLEUUID service("0000fe0f-0000-1000-8000-00805f9b34fb");
// BLE Service
static BLEUUID bmeServiceUUID("91bad492-b950-4226-aa2b-4ede9fa42f59");
static BLEUUID temperatureCharacteristicUUID("cba1d466-344c-4be3-ab3f-189f80dd7518");
//Flags stating if should begin connecting and if the connection is up
static boolean doConnect = false;
static boolean connected = false;
//Address of the peripheral device. Address will be found during scanning...
static BLEAddress *pServerAddress;
static BLEAdvertisedDevice* myDevice;
//Characteristicd that we want to read
static BLERemoteCharacteristic* temperatureCharacteristic;
static BLERemoteCharacteristic* humidityCharacteristic;
static BLERemoteCharacteristic* hueBulb;
//Activate notify
const uint8_t notificationOn[] = {0x01};
const uint8_t notificationOff[] = {0x0, 0x0};
class MyClientCallback : public BLEClientCallbacks {
void onConnect(BLEClient* pclient) {
Serial.println(" - Connected to server");
Serial.println(" - Connected to server");
}
void onDisconnect(BLEClient* pclient) {
connected = false;
Serial.println("onDisconnect");
}
};
//Connect to the BLE Server that has the name, Service, and Characteristics
bool connectToServer() {
BLEClient* pClient = BLEDevice::createClient();
pClient->setClientCallbacks(new MyClientCallback());
pClient->connect(myDevice);
std::map<std::string, BLERemoteService*>* services = pClient->getServices();
std::map<std::string, BLERemoteService*>::iterator iter;
for(iter = services->begin(); iter != services->end(); iter++){
Serial.println(" - Connected to server");
BLERemoteService* service = iter->second;
std::map<std::string, BLERemoteCharacteristic*>* characteristics = service->getCharacteristics();
std::map<std::string, BLERemoteCharacteristic*>::iterator it;
for(it = characteristics->begin(); it != characteristics->end(); it++){
BLERemoteCharacteristic* characteristic = it->second;
Serial.print(characteristic->getUUID().toString().c_str());
Serial.println(characteristic->readUInt8());
if(characteristic->canWrite() && characteristic->getUUID().toString().compare(std::string("932c32bd-0002-47a2-835a-a8d455b859dd")) == 0){
hueBulb = characteristic;
}
}
}
return true;
}
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
Serial.println(advertisedDevice.getServiceUUID().toString().c_str());
Serial.println(advertisedDevice.getName().c_str());
if (advertisedDevice.getServiceUUID().toString().compare(service.toString()) == 0) { //Check if the name of the advertiser matches
advertisedDevice.getScan()->stop(); //Scan can be stopped, we found what we are looking for
myDevice = new BLEAdvertisedDevice(advertisedDevice);
doConnect = true; //Set indicator, stating that we are ready to connect
Serial.println("Device found. Connecting!");
}
}
};
void gattcEventHandler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param)
{
if (event == ESP_GATTC_CONNECT_EVT)
{
// esp_ble_set_encryption(param->connect.remote_bda, ESP_BLE_SEC_ENCRYPT);
}
}
void setup() {
Serial.begin(115200);
Serial.println("Starting Arduino BLE Client application...");
BLEDevice::init("");
BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT);
BLEDevice::setCustomGattcHandler(gattcEventHandler);
BLEScan* pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true);
pBLEScan->start(30);
}
int i = 0;
void loop() {
if (doConnect == true) {
if (connectToServer()) {
Serial.println("We are now connected to the BLE Server.");
connected = true;
} else {
Serial.println("We have failed to connect to the server; Restart your device to scan for nearby BLE server again.");
}
doConnect = false;
}
if (hueBulb != nullptr){
if(i == 0){
Serial.println(hueBulb->readValue().c_str());
// write on
i = 1;
} else {
Serial.println(hueBulb->readValue().c_str());
// write off
i = 0;
}
delay(3000); // Delay a second between loops.
}
delay(1000); // Delay a second between loops.
}