So here is the final yaml. As mentioned above I did not get the probe ‘clear alarm’ working, but as a work around decided to add a ‘mute sound for 2 minutes’ button.
Please note:
- It is not possible to change a WBR3 for a ESP8266 12f without extra mods. You will miss a couple of crucial pullup resistors for the ESP to run. I decided to use a small D1 mini pro board and feed it from the orginal 3.3V power of the WBR3 chip. You only need four wires (GND, 3.3V, TX and RX) to connect the ESP to the inkbird. I did remove the WBR3, but be aware that you don’t burn the underlaying LCD! I decided to remove the LCD during desoldering the WBR3. Maybe leaving the WBR3 in the PCB and disabling is by cutting the Enable pin is better idea, but I did not try that.
As for the code, here are the mappings I roughly found out:
Datapoint 102: int value (value: 15) -> Backlight timer
Datapoint 13: bitmask (value: a100060) -> General info LSB = probe alerts, next byte is probe precense, bit 18 is charger connected
Datapoint 107: int value (value: 5361) -> T Probe 1
Datapoint 108: int value (value: 327661) -> T Probe 2
Datapoint 109: int value (value: 327661) -> T Probe 3
Datapoint 110: int value (value: 5361) -> T probe 4
Datapoint 112: int value (value: 10) -> ?
Datapoint 1: switch (value: ON) -> Power on button?
Datapoint 19: enum (value: 0) -> ?
Datapoint 101: int value (value: 100) -> battery value
Datapoint 123: raw (value: 00.00.00.00.00 (5)) -> Probe 1 alerts (10.x.x.x is active, 0.x.x.x is not. in F, factor 10, temperature bytes switched around)
Datapoint 120: raw (value: 00.00.00.00.00 (5)) -> Probe 2 alerts
Datapoint 121: raw (value: 00.00.00.00.00 (5)) -> Probe 3 alerts
Datapoint 122: raw (value: 00.00.00.00.00 (5)) -> Probe 4 alerts
Datapoint 103: raw (value: 11.01) -> Alarm repeat interval
Datapoint 106: raw (value: 80.54.6E.77.X.X) -> Bluetooth MAC
Datapoint 113: raw (value: 01.02.03.04) -> ?
Datapoint 111: switch (value: OFF) -> backlight on/off
Datapoint 104: switch (value: ON) -> mute device on/off
The ESP YAML file, please note:
- it is for degrees C (where F is used, HA automatically converts is to C already)
- I did drop the low-temperature alert support as the original app does not support that and I don’t need it.
- Backlight always on is not supported by this device, in the code is a workaround to directly activate it when it goes off after 1 hour and was set to always on.
esphome:
name: esp-bbq-thermometer
friendly_name: ESP BBQ thermometer
on_boot:
then:
- delay: 5s
- number.set:
id: probe_1_high_temp
value: 180
- number.set:
id: probe_2_high_temp
value: 180
- number.set:
id: probe_3_high_temp
value: 180
- number.set:
id: probe_4_high_temp
value: 180
- select.set:
id: screen_timeout
option: "Never" #personal preferences, add your own default value here
api:
ota:
- platform: esphome
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
esp8266:
board: esp01_1m
logger:
baud_rate: 0
uart:
rx_pin: GPIO2
tx_pin: GPIO4
baud_rate: 115200
tuya:
id: mcu
time_id: homeassistant_time
on_datapoint_update:
- sensor_datapoint: 13
datapoint_type: bitmask
then:
lambda: |-
std::bitset<8> probes(x);
probes.flip();
id(probe_1_present).publish_state(probes.test(4));
id(probe_2_present).publish_state(probes.test(5));
id(probe_3_present).publish_state(probes.test(6));
id(probe_4_present).publish_state(probes.test(7));
- sensor_datapoint: 13
datapoint_type: bitmask
then:
lambda: |-
std::bitset<20> alerts(x);
id(probe_1_alert).publish_state(alerts.test(0));
id(probe_2_alert).publish_state(alerts.test(1));
id(probe_3_alert).publish_state(alerts.test(2));
id(probe_4_alert).publish_state(alerts.test(3));
id(charging).publish_state(alerts.test(18));
text_sensor:
- platform: version
name: ESPHome Version
internal: true
time:
- platform: homeassistant
id: homeassistant_time
button:
- platform: template
name: "iBBQ Mute for 2 mins"
id: mute_2mins
icon: "mdi:volume-mute"
on_press:
then:
- switch.turn_on: mute
- delay: 120s
- switch.turn_off: mute
switch:
- platform: restart
id: rebootswitch
name: "ESP restart"
- platform: "tuya"
name: "iBBQ Backlight"
id: light
switch_datapoint: 111
icon: "mdi:television-ambient-light"
#forever backlight ON not supported, setting it ON after turn OFF instantly is the workaround.
on_turn_off:
if:
condition:
lambda: |-
return id(screen_timeout).state == "Never";
then:
- delay: 0.1s
- switch.turn_on: light
- platform: "tuya"
name: "iBBQ Mute"
id: mute
inverted: true
switch_datapoint: 104
icon: "mdi:volume-mute"
- platform: template
name: "iBBQ Probe 1 Alerts"
id: probe_1_alerts
icon: "mdi:thermometer-alert"
optimistic: true
on_turn_off:
- lambda: |-
std::vector<uint8_t> raw(5,0);
int temp = 5270; //default temp of 300gr C instead o 0gr to prevent direct alarm when activating
raw.at(0) = 0;
raw.at(1) = temp & 0xFF;
raw.at(2) = temp >> 8;
raw.at(3) = 0;
raw.at(4) = 0;
id(mcu).set_raw_datapoint_value(120,raw);
on_turn_on:
- lambda: |-
std::vector<uint8_t> raw(5,0);
int temp = ((int)id(probe_1_high_temp).state * (9.0/5.0) + 32.0)* 10; //get setpoint from number input
raw.at(0) = 16;
raw.at(1) = temp & 0xFF;
raw.at(2) = temp >> 8;
id(mcu).set_raw_datapoint_value(120,raw);
- platform: template
name: "iBBQ Probe 2 Alerts"
id: probe_2_alerts
icon: "mdi:thermometer-alert"
optimistic: true
on_turn_off:
- lambda: |-
std::vector<uint8_t> raw(5,0);
int temp = 5270; //default temp of 300gr C instead o 0gr to prevent direct alarm when activating
raw.at(0) = 0;
raw.at(1) = temp & 0xFF;
raw.at(2) = temp >> 8;
raw.at(3) = 0;
raw.at(4) = 0;
id(mcu).set_raw_datapoint_value(121,raw);
on_turn_on:
- lambda: |-
std::vector<uint8_t> raw(5,0);
int temp = ((int)id(probe_2_high_temp).state * (9.0/5.0) + 32.0)* 10; //get setpoint from number input
raw.at(0) = 16;
raw.at(1) = temp & 0xFF;
raw.at(2) = temp >> 8;
id(mcu).set_raw_datapoint_value(121,raw);
- platform: template
name: "iBBQ Probe 3 Alerts"
id: probe_3_alerts
icon: "mdi:thermometer-alert"
optimistic: true
on_turn_off:
- lambda: |-
std::vector<uint8_t> raw(5,0);
int temp = 5270; //default temp of 300gr C instead o 0gr to prevent direct alarm when activating
raw.at(0) = 0;
raw.at(1) = temp & 0xFF;
raw.at(2) = temp >> 8;
raw.at(3) = 0;
raw.at(4) = 0;
id(mcu).set_raw_datapoint_value(122,raw);
on_turn_on:
- lambda: |-
std::vector<uint8_t> raw(5,0);
int temp = ((int)id(probe_3_high_temp).state * (9.0/5.0) + 32.0)* 10; //get setpoint from number input
raw.at(0) = 16;
raw.at(1) = temp & 0xFF;
raw.at(2) = temp >> 8;
id(mcu).set_raw_datapoint_value(122,raw);
- platform: template
name: "iBBQ Probe 4 Alerts"
id: probe_4_alerts
icon: "mdi:thermometer-alert"
optimistic: true
on_turn_off:
- lambda: |-
std::vector<uint8_t> raw(5,0);
int temp = 5270; //default temp of 300gr C instead o 0gr to prevent direct alarm when activating
raw.at(0) = 0;
raw.at(1) = temp & 0xFF;
raw.at(2) = temp >> 8;
raw.at(3) = 0;
raw.at(4) = 0;
id(mcu).set_raw_datapoint_value(123,raw);
on_turn_on:
- lambda: |-
std::vector<uint8_t> raw(5,0);
int temp = ((int)id(probe_4_high_temp).state * (9.0/5.0) + 32.0)* 10; //get setpoint from number input
raw.at(0) = 16;
raw.at(1) = temp & 0xFF;
raw.at(2) = temp >> 8;
id(mcu).set_raw_datapoint_value(123,raw);
number:
- platform: template
name: "iBBQ Probe 1 High Temperature"
id: probe_1_high_temp
unit_of_measurement: "°C"
icon: "mdi:fire-alert"
optimistic: true
min_value: 0
max_value: 300
step: 1
on_value:
then:
- delay: 3s
- lambda: |-
std::vector<uint8_t> raw(5,0);
int temp = ((int)id(probe_1_high_temp).state * (9.0/5.0) + 32.0)* 10; //get setpoint from number input
if (id(probe_1_alerts).state) raw.at(0) = 16;
else raw.at(0) = 0;
raw.at(1) = temp & 0xFF;
raw.at(2) = temp >> 8;
id(mcu).set_raw_datapoint_value(120,raw);
- platform: template
name: "iBBQ Probe 2 High Temperature"
id: probe_2_high_temp
unit_of_measurement: "°C"
icon: "mdi:fire-alert"
optimistic: true
min_value: 0
max_value: 300
step: 1
on_value:
then:
- delay: 3s
- lambda: |-
std::vector<uint8_t> raw(5,0);
int temp = ((int)id(probe_2_high_temp).state * (9.0/5.0) + 32.0)* 10; //get setpoint from number input
if (id(probe_2_alerts).state) raw.at(0) = 16;
else raw.at(0) = 0;
raw.at(1) = temp & 0xFF;
raw.at(2) = temp >> 8;
id(mcu).set_raw_datapoint_value(121,raw);
- platform: template
name: "iBBQ Probe 3 High Temperature"
id: probe_3_high_temp
unit_of_measurement: "°C"
icon: "mdi:fire-alert"
optimistic: true
min_value: 0
max_value: 300
step: 1
on_value:
then:
- delay: 3s
- lambda: |-
std::vector<uint8_t> raw(5,0);
int temp = ((int)id(probe_3_high_temp).state * (9.0/5.0) + 32.0)* 10; //get setpoint from number input
if (id(probe_3_alerts).state) raw.at(0) = 16;
else raw.at(0) = 0;
raw.at(1) = temp & 0xFF;
raw.at(2) = temp >> 8;
id(mcu).set_raw_datapoint_value(122,raw);
- platform: template
name: "iBBQ Probe 4 High Temperature"
id: probe_4_high_temp
unit_of_measurement: "°C"
icon: "mdi:fire-alert"
optimistic: true
min_value: 0
max_value: 300
step: 1
on_value:
then:
- delay: 3s
- lambda: |-
std::vector<uint8_t> raw(5,0);
int temp = ((int)id(probe_4_high_temp).state * (9.0/5.0) + 32.0)* 10; //get setpoint from number input
if (id(probe_4_alerts).state) raw.at(0) = 16;
else raw.at(0) = 0;
raw.at(1) = temp & 0xFF;
raw.at(2) = temp >> 8;
id(mcu).set_raw_datapoint_value(123,raw);
sensor:
- platform: wifi_signal
name: ESP BBQ WiFi Signal
update_interval: 12h
internal: true
- platform: tuya
name: "iBBQ Probe 1 Temperature"
id: probe_1_temperature
icon: "mdi:thermometer"
sensor_datapoint: 107
unit_of_measurement: "°F"
device_class: "temperature"
state_class: "measurement"
accuracy_decimals: 1
filters:
- lambda: |-
if (x < 100000) return x * 0.01;
else return {};
- platform: tuya
name: "iBBQ Probe 2 Temperature"
id: probe_2_temperature
icon: "mdi:thermometer"
sensor_datapoint: 108
unit_of_measurement: "°F"
device_class: "temperature"
state_class: "measurement"
accuracy_decimals: 1
filters:
- lambda: |-
if (x < 100000) return x * 0.01;
else return {};
- platform: tuya
name: "iBBQ Probe 3 Temperature"
id: probe_3_temperature
icon: "mdi:thermometer"
sensor_datapoint: 109
unit_of_measurement: "°F"
device_class: "temperature"
state_class: "measurement"
accuracy_decimals: 1
filters:
- lambda: |-
if (x < 100000) return x * 0.01;
else return {};
- platform: tuya
name: "iBBQ Probe 4 Temperature"
id: probe_4_temperature
icon: "mdi:thermometer"
sensor_datapoint: 110
unit_of_measurement: "°F"
device_class: "temperature"
state_class: "measurement"
accuracy_decimals: 1
filters:
- lambda: |-
if (x < 100000) return x * 0.01;
else return {};
- platform: tuya
name: "iBBQ Battery"
id: battery
sensor_datapoint: 101
unit_of_measurement: "%"
device_class: "battery"
state_class: "measurement"
binary_sensor:
- platform: template
name: "iBBQ Charging"
id: charging
icon: "mdi:battery-charging"
- platform: template
name: "iBBQ Probe 1 Presence"
id: probe_1_present
icon: "mdi:connection"
- platform: template
name: "iBBQ Probe 2 Presence"
id: probe_2_present
icon: "mdi:connection"
- platform: template
name: "iBBQ Probe 3 Presence"
id: probe_3_present
icon: "mdi:connection"
- platform: template
name: "iBBQ Probe 4 Presence"
id: probe_4_present
icon: "mdi:connection"
- platform: template
name: "iBBQ Probe 1 Alert"
id: probe_1_alert
icon: "mdi:alert"
- platform: template
name: "iBBQ Probe 2 Alert"
id: probe_2_alert
icon: "mdi:alert"
- platform: template
name: "iBBQ Probe 3 Alert"
id: probe_3_alert
icon: "mdi:alert"
- platform: template
name: "iBBQ Probe 4 Alert"
id: probe_4_alert
icon: "mdi:alert"
select:
- platform: tuya
name: "iBBQ Units"
enum_datapoint: 19
optimistic: true
options:
0: Celsius
1: Fahrenheit
- platform: template
name: "iBBQ Screen Timeout"
id: screen_timeout
icon: "mdi:power-sleep"
optimistic: true
restore_value: true
options:
- "15 Seconds"
- "30 Seconds"
- "1 Minute"
- "5 Minutes"
- "15 Minutes"
- "30 Mintues"
- "1 Hour"
- "Never"
on_value:
- lambda: |-
switch(i) {
case 0:
id(mcu).set_integer_datapoint_value(102,15);
break;
case 1:
id(mcu).set_integer_datapoint_value(102,30);
break;
case 2:
id(mcu).set_integer_datapoint_value(102,60);
break;
case 3:
id(mcu).set_integer_datapoint_value(102,300);
break;
case 4:
id(mcu).set_integer_datapoint_value(102,900);
break;
case 5:
id(mcu).set_integer_datapoint_value(102,1800);
break;
case 6:
id(mcu).set_integer_datapoint_value(102,3600);
break;
case 7:
id(mcu).set_integer_datapoint_value(102,3600); //3601 and 0 not working on this unit
break;
}
Hope it helps others. It was a fun project to do, and many thanks to @kcraig73 for making the fundament for this.