For anyone who needs to integrate this thermometer model, I was able to extract some data: the probe temperature, along with the battery charge level of both the probe and the booster.
You only need to change the MAC address value to that of your device.
VERY IMPORTANT!
Set an initial recipe on your device through the official app. Without this setting, the booster turns off after 10 minutes.
### This is a package related to the Inkbird INT-11I-B thermometer.
### The code acquires the probe temperature data and the battery status (for both the booster and the probe).
### It also provides the connection status of the probe and the booster.
### Replace the MAC address with that of your own device.
### VERY IMPORTANT! Set an initial recipe on your device through the official app. Without this setting, the booster turns off after 10 minutes.
substitutions:
inkbird_mac: "00:00:00:00:00:00" #### REPLACE WITH YOUR DEVICE MAC
esphome:
name: inkbird
friendly_name: Inkbird
on_boot:
priority: 200.0
then:
- lambda: |-
// Stato iniziale: "scollegati" finché non arrivano dati
id(inkbird_last_valid_temp_ms) = 0;
id(inkbird_last_station_batt_ms) = 0;
id(inkbird_station_connected).publish_state(false);
id(inkbird_probe_connected).publish_state(false);
esp32:
board: esp32dev
framework:
type: esp-idf
logger:
globals:
# Timestamp ultimo valore valido di temperatura (sonda)
- id: inkbird_last_valid_temp_ms
type: uint32_t
restore_value: no
initial_value: '0'
# Timestamp ultimo valore ricevuto di batteria stazione base
- id: inkbird_last_station_batt_ms
type: uint32_t
restore_value: no
initial_value: '0'
binary_sensor:
- platform: template
name: "Connessione Base"
id: inkbird_station_connected
device_class: connectivity
- platform: template
name: "Connessione Sonda"
id: inkbird_probe_connected
device_class: connectivity
api:
encryption:
key: "yourkey"
ota:
- platform: esphome
password: "yourpassword"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# manual_ip:
# static_ip: 192.168.1.55
# gateway: 192.168.1.254
# subnet: 255.255.255.0
# dns1: 192.168.1.254
time:
- platform: sntp
id: ntp_time
timezone: Europe/Rome
interval:
- interval: 5s
then:
- lambda: |-
// Watchdog 2 minuti
const uint32_t now = millis();
const bool base_ok =
(id(inkbird_last_station_batt_ms) != 0) &&
(now - id(inkbird_last_station_batt_ms) < 120000); // 2 min
// Se la base non è ok, la sonda è forzata OFF
bool probe_ok = false;
if (base_ok) {
probe_ok =
(id(inkbird_last_valid_temp_ms) != 0) &&
(now - id(inkbird_last_valid_temp_ms) < 120000); // 2 min
}
if (id(inkbird_station_connected).state != base_ok) {
id(inkbird_station_connected).publish_state(base_ok);
}
if (id(inkbird_probe_connected).state != probe_ok) {
id(inkbird_probe_connected).publish_state(probe_ok);
}
ble_client:
- mac_address: ${inkbird_mac}
id: inkbird
auto_connect: true
on_connect:
then:
- lambda: |-
ESP_LOGI("inkbird", "Connesso a ${inkbird_mac}");
//inkbird_on_connect();
on_disconnect:
then:
- lambda: |-
ESP_LOGW("inkbird", "Disconnesso – auto_connect si riconnette automaticamente");
// Non forziamo qui i sensori: decide tutto il watchdog a 2 minuti
sensor:
- platform: template
name: "Temperatura"
id: inkbird_temperature
unit_of_measurement: '°C'
device_class: temperature
accuracy_decimals: 1
update_interval: never
- platform: ble_client
type: characteristic
ble_client_id: inkbird
internal: true
id: inkbird_internal_raw
service_uuid: 0000FF00-0000-1000-8000-00805F9B34FB
characteristic_uuid: 0000FF01-0000-1000-8000-00805F9B34FB
unit_of_measurement: '°C'
accuracy_decimals: 1
notify: true
lambda: |-
char hex_buf[128];
int pos = 0;
for (size_t i = 0; i < x.size() && pos < (int)sizeof(hex_buf) - 4; i++) {
pos += snprintf(hex_buf + pos, sizeof(hex_buf) - pos,
"%02X%s", x[i], (i + 1 < x.size() ? "-" : ""));
}
ESP_LOGW("INKBIRD_RAW", "FF01: %s", hex_buf);
if (x.size() >= 2) {
uint16_t raw_fahrenheit = (x[1] << 8) | x[0];
float fahrenheit = raw_fahrenheit / 100.0f;
float celsius = (fahrenheit - 32.0f) * 5.0f / 9.0f;
float celsius_r = roundf(celsius * 10.0f) / 10.0f;
ESP_LOGI("TEMP_DECODER", "F: %.2f -> C: %.1f", fahrenheit, celsius_r);
return celsius_r;
}
return NAN;
on_value:
then:
- lambda: |-
const float t = id(inkbird_internal_raw).state;
// "Valido" = non NaN e range plausibile
if (!isnan(t) && t >= -40.0f && t <= 100.0f) {
id(inkbird_temperature).publish_state(t);
// Timestamp ultima temperatura valida
id(inkbird_last_valid_temp_ms) = millis();
// Se la base risulta connessa, accendiamo subito la sonda (senza aspettare l'interval)
if (id(inkbird_station_connected).state && !id(inkbird_probe_connected).state) {
id(inkbird_probe_connected).publish_state(true);
}
}
- platform: template
id: inkbird_battery_station
name: "Batteria Stazione"
unit_of_measurement: "%"
device_class: battery
accuracy_decimals: 0
- platform: template
id: inkbird_battery_probe
name: "Batteria Sonda"
unit_of_measurement: "%"
device_class: battery
accuracy_decimals: 0
- platform: ble_client
type: characteristic
ble_client_id: inkbird
internal: true
id: inkbird_battery_raw
service_uuid: 0000FF00-0000-1000-8000-00805F9B34FB
characteristic_uuid: 00002A19-0000-1000-8000-00805F9B34FB
update_interval: 1min
notify: false
lambda: |-
if (x.size() < 2) return NAN;
char buf[64];
int pos = 0;
for (size_t i = 0; i < x.size() && pos < (int)sizeof(buf)-4; i++) {
pos += snprintf(buf + pos, sizeof(buf) - pos, "%02X%s", x[i], (i+1<x.size() ? " " : ""));
}
ESP_LOGD("INKBIRD_BATT", "Battery raw: %s", buf);
uint8_t batt_station = x[0];
uint8_t batt_probe = x[1];
ESP_LOGI("INKBIRD_BATT", "Stazione: %u%%, Sonda: %u%%", batt_station, batt_probe);
// Pubblica batteria stazione + aggiorna "connessione base" se valido
if (batt_station >= 1 && batt_station <= 100) {
id(inkbird_battery_station).publish_state((float)batt_station);
// Timestamp ultimo pacchetto batteria base valido
id(inkbird_last_station_batt_ms) = millis();
// Accendi subito la base (senza aspettare l'interval)
if (!id(inkbird_station_connected).state) {
id(inkbird_station_connected).publish_state(true);
}
}
// Pubblica batteria sonda (solo informativo, NON usato per connettività sonda)
if (batt_probe >= 1 && batt_probe <= 100) {
id(inkbird_battery_probe).publish_state((float)batt_probe);
}
return (float)batt_station;
