Skip to content

Instantly share code, notes, and snippets.

@MortenVinding
Last active December 2, 2025 10:55
Show Gist options
  • Select an option

  • Save MortenVinding/a513c0094d0df41a4425612257b3cabc to your computer and use it in GitHub Desktop.

Select an option

Save MortenVinding/a513c0094d0df41a4425612257b3cabc to your computer and use it in GitHub Desktop.
ESPHome yaml config to integrate a MEATER cooking thermometer in to Home Assistant
esphome:
name: meater
friendly_name: MEATER
esp32:
board: esp32dev
#board: esp32-c3-devkitm-1
framework:
#type: esp-idf
type: arduino
# Enable logging
logger:
#level: VERBOSE
#level: VERY_VERBOSE
# Enable Home Assistant API
api:
ota:
password: "3e657a40432cc48a6b1b22d566b9eed8"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Meater Fallback Hotspot"
password: "1JX0qX8Co7KL"
# Example configuration entry for finding
# Service UUIDs and iBeacon UUIDs and identifiers
#esp32_ble_tracker:
ble_client:
- mac_address: B8:1F:5E:1C:42:95 # Replace with your MEATER's mac address
id: meater
text_sensor:
- platform: template
name: "MEATER firmware"
id: meater_firmware
sensor:
- platform: ble_client
type: characteristic
ble_client_id: meater
name: "MEATER tip temperature"
service_uuid: 'a75cc7fc-c956-488f-ac2a-2dbc08b63a04'
characteristic_uuid: '7edda774-045e-4bbf-909b-45d1991a2876'
icon: 'mdi:thermometer'
unit_of_measurement: '°C'
accuracy_decimals: 2
notify: true
lambda: |-
float tip_temp = (x[0] + (x[1] << 8) + 8.0) / 16.0;
return tip_temp;
- platform: ble_client
type: characteristic
ble_client_id: meater
name: "MEATER ambient temperature"
service_uuid: 'a75cc7fc-c956-488f-ac2a-2dbc08b63a04'
characteristic_uuid: '7edda774-045e-4bbf-909b-45d1991a2876'
icon: 'mdi:thermometer'
unit_of_measurement: '°C'
accuracy_decimals: 2
notify: true
lambda: |-
uint16_t tip = x[0] + (x[1] << 8);
uint16_t ra = x[2] + (x[3] << 8);
uint16_t oa = x[4] + (x[5] << 8);
uint16_t min_val = 48;
float ambient = (tip + std::max(0, (((ra - std::min(min_val, oa)) * 16 * 589) / 1487)) + 8.0) / 16;
return ambient;
- platform: ble_client
type: characteristic
ble_client_id: meater
name: "MEATER battery level"
service_uuid: 'a75cc7fc-c956-488f-ac2a-2dbc08b63a04'
characteristic_uuid: '2adb4877-68d8-4884-bd3c-d83853bf27b8'
icon: 'mdi:battery'
unit_of_measurement: '%'
notify: true
lambda: |-
uint16_t battery = (x[0] + x[1]) * 10;
return (float)battery;
- platform: ble_client
type: characteristic
ble_client_id: meater
id: firmware
service_uuid: '180A'
characteristic_uuid: '00002a26-0000-1000-8000-00805f9b34fb'
lambda: |-
std::string data_string(x.begin(), x.end());
id(meater_firmware).publish_state(data_string.c_str());
return (float)x.size();
- platform: ble_client
type: rssi
ble_client_id: meater
name: "MEATER RSSI"
@moorgrove
Copy link

One suggestion is to run the code below to scan for new devices.

# Example configuration entry for finding Service UUIDs, iBeacon UUIDs and identifiers
esp32_ble_tracker:
  on_ble_advertise:
    - then:
logger:
  level: VERY_VERBOSE

@R00S
Copy link

R00S commented Oct 17, 2025

Been using this for a while now. I simply pull the plug on the esp32 when i want to use the app. But i wonder, would there be a technical obsticle with the esp32 presenting itself as a probe or the block itself and relaying the information to the app or is it just not implemented?

@dredzik
Copy link

dredzik commented Oct 19, 2025

One bug fix. Don't use uint16_t to calculate the temperatures. Use floats. You are cutting out a lot of information. When using meater for a 12 hour slow cook, you want to observe fractional changes over minutes.

    lambda: |-
      float tip_temp = (x[0] + (x[1] << 8) + 8.0) / 16.0;
      return tip_temp;

and

    lambda: |-
      uint16_t tip = x[0] + (x[1] << 8);
      uint16_t ra = x[2] + (x[3] << 8);
      uint16_t oa = x[4] + (x[5] << 8);
      uint16_t min_val = 48;
      float ambient = (tip + std::max(0, (((ra - std::min(min_val, oa)) * 16 * 589) / 1487)) + 8.0) / 16;
      return ambient;

solve this issue.

@MortenVinding
Copy link
Author

One bug fix. Don't use uint16_t to calculate the temperatures. Use floats. You are cutting out a lot of information. When using meater for a 12 hour slow cook, you want to observe fractional changes over minutes.

Thanks for the suggestion!
I have updated the code with you changes now 👍

@tobiassod
Copy link

tobiassod commented Nov 27, 2025

Hi,

Thanks for a good solution. Im trying to connect a Meater 2 Plus in the same way but I only see Meater firmware and RSSI. The tip temperature, ambient and battery level does not appear. Any idea what to do next? Do I need to change anything else than the MAC-adress?

Big thanks in advance...

image

@R00S
Copy link

R00S commented Dec 2, 2025

I have been training myself in using different ai-systems as code slaves on this project. I used this for a client in a esp32 and i have tried to create a server emulating a meater block (udp) and an original meater (ble). The ble part is somewhat promising, but in the end i ended that and instead implemented an app replacement as a home assistant integration that uses this code to get the meater temps into the integration. It can be installed and tested with hacs from https://github.com/R00S/meater-in-local-haos. Dont blame me if it does ruin your meat, there are still no alerts when the food is getting ready. I will try to remidy that and some more and then expand it into a more extensive cooking helper with more features.

The halted ble and udp servers attempts are still there and there are documents describing what i found out about the protocols.

Thanks for creating this esphome code, i have used it extensivly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment