Page 1 of 1

Can't read Hue light values

Posted: Fri Mar 10, 2023 2:08 am
by batzz00
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
Image

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.
}