Inkbird ISC-007BW BBQ controller via bluetooth

Finally got it! Basically I use global variables to store the settings of 2 services (FFF1 and FFF3). They get updated via the sensors (handle 1 and handle 3) so that if you change a setting on the device, it also reflects in home assistant. After changing any setting in home assistant, I update the global variables, and call a script. The script calculates the crc values and sends them to the inkbird controller. Now the next step will be to use a PID integration. Or I might give a custom component in HA a try, so you would not have to use an ESP. Not sure yet :slight_smile: I did not include all the settings in sensors but they can be done in the same way, using the mapping of bytes in my post above.

esphome:
  name: esp32

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

esp32_ble_tracker:

globals:
  - id: isc_blecommand1
    type: std::vector<unsigned char>
    initial_value: '{0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x32, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}'
  
  - id: isc_blecommand3
    type: std::vector<unsigned char>
    initial_value: '{0x00, 0x00, 0x00, 0x64, 0x00, 0x64, 0x00, 0x96, 0x00, 0x4e, 0x02, 0x90, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}'
    

ble_client:
  - mac_address: 49:22:04:02:00:F8
    id: isc007bw
    on_connect:
      then:
        - lambda: |-
            ESP_LOGD("ble_client_lambda", "Connected to BLE device");    

# input number for setting the wanted grill temp for auto fan-mode.
number:
  - platform: template
    name: "isc_wanted_grill_temp"
    device_class: "temperature"
    min_value: 0
    max_value: 315
    step: 1
    lambda: return (int)id(isc_blecommand3)[3];
    set_action: 
      - lambda: id(isc_blecommand3)[3] = (uint8_t)x;
      - script.execute: isc_command_send


sensor:
  - platform: ble_client
    type: characteristic
    ble_client_id: isc007bw
    id: fanspeed
    name: "Fan Speed"
    service_uuid: 'FFF0'  # device service
    characteristic_uuid: 'FFF6'  # subsciption
    notify: true
    lambda: |-
      uint8_t speed = x[6];
      uint16_t temp1 = x[0] | x[1] <<8;
      id(isc_probe1).publish_state((float)temp1 /10 );
      uint16_t temp2 = x[2] | x[3] <<8;
      id(isc_probe2).publish_state((float)temp2 /10 );
      uint16_t temp3 = x[4] | x[5] <<8;
      id(isc_probe3).publish_state((float)temp3 /10 );
      return (float)speed ;
    unit_of_measurement: '%'
    icon: "mdi:fan"

  - platform: ble_client
    type: characteristic
    ble_client_id: isc007bw
    name: "isc handle 1"
    service_uuid: 'FFF0'  # device service
    characteristic_uuid: 'FFF1'  # subsciption
    update_interval: 60s
    lambda: |-
      for (int i = 0; i < x.size(); i++) {
        id(isc_blecommand1)[i] = (uint8_t)x[i]; }
      return (float)x.size();

  - platform: ble_client
    type: characteristic
    ble_client_id: isc007bw
    name: "isc handle 3"
    service_uuid: 'FFF0'  # device service
    characteristic_uuid: 'FFF3'  # subsciption
    update_interval: 60s
    lambda: |-
      for (int i = 0; i < x.size(); i++) {
        id(isc_blecommand3)[i] = (uint8_t)x[i]; }
      return (float)x.size();
  
  - platform: template
    id: isc_probe1
    name: "isc probe 1"
    device_class: "temperature"
    unit_of_measurement: '°F'
  
  - platform: template
    id: isc_probe2
    name: "isc probe 2"
    device_class: "temperature"
    unit_of_measurement: '°F'
  
  - platform: template
    id: isc_probe3
    name: "isc probe 3"
    device_class: "temperature"
    unit_of_measurement: '°F'

output:
  - platform: template
    id: isc_output
    type: float
    write_action:
      - if:
          condition:
            fan.is_on: isc_fan
          then:
            - lambda: id(isc_blecommand1)[6] = (uint8_t)id(isc_fan).speed;
            - script.execute: isc_command_send

fan:
  - platform: speed
    id: isc_fan
    output: isc_output
    speed_count: 100
    name: "ISC-007BW fan"
    on_turn_on:
      - lambda: id(isc_blecommand1)[0] = (uint8_t)1;
      - script.execute: isc_command_send
      - logger.log: "Fan turned on"     
    on_turn_off:
      - lambda: id(isc_blecommand1)[0] = (uint8_t)0;
      - script.execute: isc_command_send
      - logger.log: "Fan turned off"
    on_speed_set:
      - logger.log: "Fan Speed was changed!"      

select:
  - platform: template
    name: "BBQ type"
    id: "isc_bbq_select"
    lambda: |-
      auto index = int(id(isc_blecommand1)[7]);
      auto val = id(isc_bbq_select).at(index);
      return {val};
    options:
      - "Kamado 22"
      - "Kamado 15"
      - "Kettle 22"
      - "Kettle 15"
      - "WSM 18"
    set_action:
      - lambda: |-
          if (x == "Kamado 22") {
            id(isc_blecommand1)[7]=(uint8_t)0;}
          if (x == "Kamado 18") {
            id(isc_blecommand1)[7]=(uint8_t)1;}
          if (x == "Kettle 22") {
            id(isc_blecommand1)[7]=(uint8_t)2;}
          if (x == "Kettle 15") {
            id(isc_blecommand1)[7]=(uint8_t)3;}
          if (x == "WSM 18") {
            id(isc_blecommand1)[7]=(uint8_t)4;}
          id(isc_bbq_select).publish_state(x);
      - script.execute: isc_command_send


switch:
  - platform: ble_client
    ble_client_id: isc007bw
    name: "ISC-007BW"
    id: isc007bwswitch
  
  - platform: template
    name: "Fan BBQ auto"
    id: "isc_auto_fan_switch"
    lambda: |-
      return id(isc_blecommand1)[1];
    turn_on_action:
      - lambda: id(isc_blecommand1)[1] = 0x01;
      - script.execute: isc_command_send
    turn_off_action:
      - lambda: id(isc_blecommand1)[1] = 0x00;
      - script.execute: isc_command_send
  
script:
  - id: isc_command_send
    then:
      - lambda: |-
          uint16_t crc = 0xFFFF;
          // Calculate CRC for the first 11 bytes
          for (int pos = 0; pos < 11; pos++) {
          crc = crc ^ (uint16_t)(id(isc_blecommand1)[pos] );
          for (int i = 8; i != 0; i--) {
          if ((crc & 0x0001) != 0) {
          crc >>= 1; 
          crc ^= 0xA001;
              }
          else                            // Else LSB is not set
          crc >>= 1;                    // Just shift right
            }
          }
          id(isc_blecommand1)[11] = crc & 0xFF; // little endian
          id(isc_blecommand1)[12] = (crc >> 8) & 0xFF; // little endian
      - ble_client.ble_write:
          id: isc007bw
          service_uuid: FFF0
          characteristic_uuid: FFF1
          value: !lambda 'return id(isc_blecommand1);'
      - lambda: |-
          uint16_t crc = 0xFFFF;
          // Calculate CRC for the first 11 bytes
          for (int pos = 0; pos < 11; pos++) {
          crc = crc ^ (uint16_t)(id(isc_blecommand3)[pos] );
          for (int i = 8; i != 0; i--) {
          if ((crc & 0x0001) != 0) {
          crc >>= 1; 
          crc ^= 0xA001;
              }
          else                            // Else LSB is not set
          crc >>= 1;                    // Just shift right
            }
          }
          id(isc_blecommand3)[11] = crc & 0xFF; // little endian
          id(isc_blecommand3)[12] = (crc >> 8) & 0xFF; // little endian
      - ble_client.ble_write:
          id: isc007bw
          service_uuid: FFF0
          characteristic_uuid: FFF3
          value: !lambda 'return id(isc_blecommand3);'
1 Like