How To: Control a non-supported BLE light with ESPHOME

I had a problem adding a BLE strip I have (see GitHub issue here). That bug/problem is until now not fix.

Since I really wanted to control that strip, I ended up creating a virtual light. Maybe this helps to another person on with the same problem.

This is the code I used:

esp32-board.ymal

substitutions:
  bluetooth_virtual_light_mac: THE:LBE:MAC:HERE

packages:
  bluetooth_virtual_light: !include common/bluetooth-virtual-light.yaml

common/bluetooth-virtual-light.yaml

esphome:
  includes: 
    - common/bluetooth-virtual-light.h

###############################
########## BLUETOOTH #########
#############################
# bluetooth_proxy:
#   active: true

      
# esp32_ble_tracker:
#   scan_parameters:
#     # We currently use the defaults to ensure Bluetooth
#     # can co-exist with WiFi In the future we may be able to
#     # enable the built-in coexistence logic in ESP-IDF
#     active: false

binary_sensor: 
  - platform: template
    name: "Led BLE Connected"
    id: led_ble_connected_sensor


ble_client:
  - mac_address: ${bluetooth_virtual_light_mac}
    id: led_strip_ble_client
    on_connect:
      then:
        - lambda: |-
            ESP_LOGD("virtual_ble_light", "Connected to BLE device");
        - binary_sensor.template.publish:
            id: led_ble_connected_sensor
            state: ON
        - switch.turn_off: led_ble_on_off_switch

    on_disconnect:
      then:
        - lambda: |-
            ESP_LOGD("virtual_ble_light", "Disconnected to BLE device");
        - binary_sensor.template.publish:
            id: led_ble_connected_sensor
            state: OFF

light:
  - platform: rgb
    id: rbg_led
    name: BLE LED
    red: red_channel_output
    green: green_channel_output
    blue: blue_channel_output
    default_transition_length: 0.25s
    on_state: 
      - lambda: |-
          ESP_LOGD("virtual_ble_light", "State Send");
    on_turn_on:
      - lambda: |-
          id(led_ble_on_off_switch).turn_on();
    on_turn_off:
      - lambda: |-
          id(led_ble_on_off_switch).turn_off();

output: 
  - platform: template
    id: red_channel_output
    type: float
    min_power: 0.003
    zero_means_zero: true
    write_action:
      - lambda: |-
            SSDBluetoothVirtualLight::updateRed(state);
            // char buf[30];
            // sprintf(buf, "red_channel_output=%.6f", state);
            // ESP_LOGI("virtual_ble_light", buf);
  - platform: template
    id: green_channel_output
    type: float
    min_power: 0.003
    zero_means_zero: true
    write_action:
      - lambda: |-
            SSDBluetoothVirtualLight::updateGreen(state);
            // char buf[30];
            // sprintf(buf, "green_channel_output=%.6f", state);
            // ESP_LOGI("virtual_ble_light", buf);
  - platform: template
    id: blue_channel_output
    type: float
    min_power: 0.003
    zero_means_zero: true
    write_action:
      - lambda: |-
            SSDBluetoothVirtualLight::updateBlue(state);
            // char buf[30];
            // sprintf(buf, "blue_channel_output=%.6f", state);
            // ESP_LOGI("virtual_ble_light", buf);
      - ble_client.ble_write:
          id: led_strip_ble_client
          service_uuid: FFE0
          characteristic_uuid: FFE1
          value: !lambda |- 
            return SSDBluetoothVirtualLight::getCreateColorUpdateArray();


switch:
  - platform: ble_client
    ble_client_id: led_strip_ble_client
    name: "Enable Bluetooth"
    internal: true

  - platform: template
    id: led_ble_on_off_switch
    name: "Turn On Led"
    internal: true
    restore_mode: ALWAYS_OFF
    turn_on_action:
      - ble_client.ble_write:
          id: led_strip_ble_client
          service_uuid: FFE0
          characteristic_uuid: FFE1
          value: !lambda |- 
            return SSDBluetoothVirtualLight::turnOnArray;

    turn_off_action:
      - ble_client.ble_write:
          id: led_strip_ble_client
          service_uuid: FFE0
          characteristic_uuid: FFE1
          value: !lambda |- 
            return SSDBluetoothVirtualLight::turnOffArray;
      - lambda: |-
            ESP_LOGD(SSDBluetoothVirtualLight::logTag, "SEND MESSAGE TO TURN OFF");

bluetooth-virtual-light.h

// #include <esphome.h>
#include <vector>
namespace SSDBluetoothVirtualLight {
  const char* logTag = "ssd_virtual_bluetooth_light";
  const std::vector<uint8_t> turnOffArray = {126, 255, 4, 0, 255, 255, 255, 255, 239};
  const std::vector<uint8_t> turnOnArray =  {126, 255, 4, 1, 255, 255, 255, 255, 239};
  const std::vector<uint8_t> noColorArray =  {126, 255, 5, 3, 0, 0, 0, 255, 239};

  float red = 0;
  float green = 0;
  float blue = 0;

    std::vector<uint8_t> getCreateColorUpdateArray()
    {
      
      uint8_t convertedRed = static_cast<uint8_t>(red * 255);
      uint8_t convertedGreen = static_cast<uint8_t>(green * 255);
      uint8_t convertedBlue = static_cast<uint8_t>(blue * 255);
      
      return {126, 255, 5, 3, convertedRed, convertedGreen, convertedBlue, 255, 239};
  }    
  
  

  void updateRed(float value){
    red = value;
  }
  
  void updateGreen(float value){
    green = value;
  }

  void updateBlue(float value){
    blue = value;
  }


}

Enjoy!

3 Likes