Meater through the api

Hi,

Sorry I’m new at this forum so i don’t know if this is the right place. But i wanted to share my integration with the Meater temperature stick.
First you need to find your Meater api code. This is done by starting this curl script (reference: https://github.com/apption-labs/meater-cloud-public-rest-api) :

curl --location --request POST 'https://public-api.cloud.meater.com/v1/login' \
--header 'Content-Type: application/json' \
--data-raw '{
  "email": "<MEATER Cloud Email Address>",
  "password": "<MEATER Cloud Password>"
}' 

It will respond with this:

{
    "status": "OK",
    "statusCode": 200,
    "data": {
        "token": "<JWT>",
        "userId": "<User ID>"
    },
    "meta": {}
}

Note the token and place that in the secrets.yaml like this:

meater: Bearer fksjldlfkju4393928ereio2jfo3rfnfwdklqjfiow9

After that is done you can place this in configuration.yaml:

- platform: rest
    name: meater
    json_attributes:
      - data
    resource: https://public-api.cloud.meater.com/v1/devices/
    headers:
      Authorization: !secret meater
    value_template: "OK"
  - platform: template
    sensors:
      meattemp:
        friendly_name: Meat temperature
        value_template: '{{ states.sensor.meater.attributes["data"]["devices"][0]["temperature"]["internal"] }}'

      ambient:
        friendly_name: BBQ Temperature
        value_template: '{{ states.sensor.meater.attributes["data"]["devices"][0]["temperature"]["ambient"] }}'

After reloading you’ll have 3 new sensors. sensor.meater, sensor.meattemp and sensor.ambient.

Any ideas how to tweak this even further?

Thanks,

Peter

10 Likes

Here is an example if you have more than one Meater, and some more templates for °F.

      meattemp_2:
        friendly_name: Meat Temperature 2
        value_template: '{{ states.sensor.meater.attributes["data"]["devices"][1]["temperature"]["internal"] }}'
      ambient_2:
        friendly_name: BBQ Temperature 2
        value_template: '{{ states.sensor.meater.attributes["data"]["devices"][1]["temperature"]["ambient"] }}'
  - platform: template
    sensors:
      meattemp_1_f:
        unit_of_measurement: '°F'
        friendly_name: "Meat #1"
        value_template: "{{ '%.1f' | format(states('sensor.meattemp_1') | float * (9/5) + 32) }}"
        icon_template: mdi:food-steak
      ambient_1_f:
        unit_of_measurement: '°F'
        friendly_name: "Grill #1"
        value_template: "{{ '%.1f' | format(states('sensor.ambient_1') | float * (9/5) + 32) }}"
        icon_template: mdi:grill
      meattemp_2_f:
        unit_of_measurement: '°F'
        friendly_name: "Meat #2"
        value_template: "{{ '%.1f' | format(states('sensor.meattemp_2') | float * (9/5) + 32) }}"
        icon_template: mdi:food-steak
      ambient_2_f:
        unit_of_measurement: '°F'
        friendly_name: "Grill #2"
        value_template: "{{ '%.1f' | format(states('sensor.ambient_2') | float * (9/5) + 32) }}"
        icon_template: mdi:grill  
1 Like

Just an additional note:

The update interval is 30 seconds and it doesn’t seem that you can override it.

Platform Rest Scan Interval

I use my Meaters a lot. I wanted to capture the rest of the information from the Meater Cloud REST API so here goes…

I aligned the sensor names with the API documentation.

  - platform: template
    sensors:
      internal_temperature_1:
        friendly_name: Internal Temperature 1
        icon_template: mdi:food-steak
        value_template: '{{ states.sensor.meater.attributes["data"]["devices"][0]["temperature"]["internal"] }}'
      ambient_temperature_1:
        friendly_name: Ambient Temperature 1
        icon_template: mdi:grill
        value_template: '{{ states.sensor.meater.attributes["data"]["devices"][0]["temperature"]["ambient"] }}'
      cook_id_1:
        friendly_name: Cook ID 1
        value_template: '{{ states.sensor.meater.attributes["data"]["devices"][0]["cook"]["id"] }}'
      cook_name_1:
        friendly_name: Cook Name
        icon_template: mdi:chef-hat
        value_template: '{{ states.sensor.meater.attributes["data"]["devices"][0]["cook"]["name"] }}'
      cook_state_1:
        friendly_name: Cook State 1
        value_template: '{{ states.sensor.meater.attributes["data"]["devices"][0]["cook"]["state"] }}'
      cook_temperature_target_1:
        friendly_name: Cook Temperature Target 1
        value_template: '{{ states.sensor.meater.attributes["data"]["devices"][0]["cook"]["temperature"]["target"] }}'
      cook_temperature_peak_1:
        friendly_name: Cook Temperature Peak 1
        value_template: '{{ states.sensor.meater.attributes["data"]["devices"][0]["cook"]["temperature"]["peak"] }}'
      cook_time_elapsed_1:
        friendly_name: Cook Time Elapsed 1
        value_template: '{{ states.sensor.meater.attributes["data"]["devices"][0]["cook"]["time"]["elapsed"] }}'
      cook_time_remaining_1:
        friendly_name: Cook Time Remaining 1
        value_template: '{{ states.sensor.meater.attributes["data"]["devices"][0]["cook"]["time"]["remaining"] }}'
      updated_at_1:
        friendly_name: Last Updated 1
        value_template: '{{ states.sensor.meater.attributes["data"]["devices"][0]["updated_at"] }}'

I formatted the temperatures to fahrenheit, converted the elapsed time and remaining time to Days, HH:MM, and converted the “updated_at” time from its UNIX timestamp to something useful.

To leave the temperatures in celsius just delete the ‘* (9/5) + 32’ from the value_template and the change the ‘°F’ to ‘°C’ in the unit_of_meaurement.

  - platform: template
    sensors:
      internal_temperature_1_f:
        unit_of_measurement: '°F'
        friendly_name: "Meat Temperature"
        icon_template: mdi:food-steak
        value_template: "{{ '%.1f' | format(states('sensor.internal_temperature_1') | float * (9/5) + 32) }}"
      ambient_temperature_1_f:
        unit_of_measurement: '°F'
        friendly_name: "Grill Temperature"
        value_template: "{{ '%.1f' | format(states('sensor.ambient_temperature_1') | float * (9/5) + 32) }}"
        icon_template: mdi:grill
      cook_temperature_target_1_f:
        unit_of_measurement: '°F'
        friendly_name: "Target Temperature"
        value_template: "{{ '%.1f' | format(states('sensor.cook_temperature_target_1') | float * (9/5) + 32) }}"
        icon_template: mdi:thermometer-lines
      cook_temperature_peak_1_f:
        unit_of_measurement: '°F'
        friendly_name: "Peak Temperature"
        value_template: "{{ '%.1f' | format(states('sensor.cook_temperature_peak_1') | float * (9/5) + 32) }}"        
        icon_template: mdi:thermometer-lines
      cook_time_elapsed_1_formatted:
        friendly_name: "Elapsed Time"
        icon_template: mdi:timer-sand
        value_template: >-
          {% set time = (states('sensor.cook_time_elapsed_1') | int * 100) | int %}
          {% set minutes = ((time % 360000) / 6000) | int %}
          {% set hours = ((time % 8640000) / 360000) | int %}
          {% set days = (time / 8640000) | int %}
          {%- if time < 6000 -%}
          Less than a minute
          {%- else -%}
          {%- if days > 0 -%}
            {{ days }}d
          {%- endif -%}
          {%- if hours > 0 -%}
            {%- if days > 0 -%}
              {{ ' ' }}
            {%- endif -%}
           {{ hours }}h
          {%- endif -%}
          {%- if minutes > 0 -%}
            {%- if days > 0 or hours > 0 -%}
              {{ ' ' }}
            {%- endif -%}
            {{ minutes }}m
          {%- endif -%}
          {%- endif -%}    
      cook_time_remaining_1_formatted:
        friendly_name: "Remaining Time"
        icon_template: mdi:timer-sand
        value_template: >-
          {% set time = (states('sensor.cook_time_remaining_1') | int * 100) | int %}
          {% set minutes = ((time % 360000) / 6000) | int %}
          {% set hours = ((time % 8640000) / 360000) | int %}
          {% set days = (time / 8640000) | int %}
          {%- if time < 6000 -%}
          Unknown
          {%- else -%}
          {%- if days > 0 -%}
            {{ days }}d
          {%- endif -%}
          {%- if hours > 0 -%}
            {%- if days > 0 -%}
              {{ ' ' }}
            {%- endif -%}
           {{ hours }}h
          {%- endif -%}
          {%- if minutes > 0 -%}
            {%- if days > 0 or hours > 0 -%}
              {{ ' ' }}
            {%- endif -%}
            {{ minutes }}m
          {%- endif -%}
          {%- endif -%}  
      updated_at_1_formatted:
        friendly_name: "Last Updated"
        value_template: "{{ states.sensor.updated_at_1.state | int | timestamp_custom('%-I:%M %p')}}"
        icon_template: mdi:update

Thank you PeterFleur for starting all this, I had seen the API but hadn’t gotten around to playing with it.

8 Likes

Hello, i am working on a similar project where i’m attempting to get MEATER temperatures sent to a Raspberry Pi via Python, and using those values as triggers. May I ask what software you are using to code this?

This is all default yaml code of Home Assistant

Just got some of this working with Node-RED dashboard. Thank you!

The only problems I’m having are:

Elapsed time always shows “Less than a minute” - both on Lovelace and Node-RED
Updated shows “Unavailable”

Well, I was searching for a way to connect a Meater block to a temperature controller.
Any idea how I should do that?
With a short google search I saw that it might be possible to achieve this with HA.

I didn’t buy anything yet, but I was thinking about a flameboss or a Smobot. Maybe even a combination of the two.
I also wondered if I could use a BBQ Dragon Chimny fan instead as I can use that for multiple purchases.

Hi There,
First of all: Nice integration of the meater!!
I’m a bit of a noob. I have my token and placed it in my secrets.
I copied the parts of @PeterFleur and teh part of @afishe2000 in my configuration.yaml :


# Meater        
meater:
  - platform: rest
    name: meater
    json_attributes:
      - data
    resource: https://public-api.cloud.meater.com/v1/devices/
    headers:
      Authorization: !secret meater
    value_template: "OK"
  - platform: template
    sensors:
      internal_temperature_1_f:
        unit_of_measurement: '°F'
        friendly_name: "Meat Temperature"
        icon_template: mdi:food-steak
        value_template: "{{ '%.1f' | format(states('sensor.internal_temperature_1') | float * (9/5) + 32) }}"
      ambient_temperature_1_f:
        unit_of_measurement: '°F'
        friendly_name: "Grill Temperature"
        value_template: "{{ '%.1f' | format(states('sensor.ambient_temperature_1') | float * (9/5) + 32) }}"
        icon_template: mdi:grill
      cook_temperature_target_1_f:
        unit_of_measurement: '°F'
        friendly_name: "Target Temperature"
        value_template: "{{ '%.1f' | format(states('sensor.cook_temperature_target_1') | float * (9/5) + 32) }}"
        icon_template: mdi:thermometer-lines
      cook_temperature_peak_1_f:
        unit_of_measurement: '°F'
        friendly_name: "Peak Temperature"
        value_template: "{{ '%.1f' | format(states('sensor.cook_temperature_peak_1') | float * (9/5) + 32) }}"        
        icon_template: mdi:thermometer-lines
      cook_time_elapsed_1_formatted:
        friendly_name: "Elapsed Time"
        icon_template: mdi:timer-sand
        value_template: >-
          {% set time = (states('sensor.cook_time_elapsed_1') | int * 100) | int %}
          {% set minutes = ((time % 360000) / 6000) | int %}
          {% set hours = ((time % 8640000) / 360000) | int %}
          {% set days = (time / 8640000) | int %}
          {%- if time < 6000 -%}
          Less than a minute
          {%- else -%}
          {%- if days > 0 -%}
            {{ days }}d
          {%- endif -%}
          {%- if hours > 0 -%}
            {%- if days > 0 -%}
              {{ ' ' }}
            {%- endif -%}
           {{ hours }}h
          {%- endif -%}
          {%- if minutes > 0 -%}
            {%- if days > 0 or hours > 0 -%}
              {{ ' ' }}
            {%- endif -%}
            {{ minutes }}m
          {%- endif -%}
          {%- endif -%}    
      cook_time_remaining_1_formatted:
        friendly_name: "Remaining Time"
        icon_template: mdi:timer-sand
        value_template: >-
          {% set time = (states('sensor.cook_time_remaining_1') | int * 100) | int %}
          {% set minutes = ((time % 360000) / 6000) | int %}
          {% set hours = ((time % 8640000) / 360000) | int %}
          {% set days = (time / 8640000) | int %}
          {%- if time < 6000 -%}
          Unknown
          {%- else -%}
          {%- if days > 0 -%}
            {{ days }}d
          {%- endif -%}
          {%- if hours > 0 -%}
            {%- if days > 0 -%}
              {{ ' ' }}
            {%- endif -%}
           {{ hours }}h
          {%- endif -%}
          {%- if minutes > 0 -%}
            {%- if days > 0 or hours > 0 -%}
              {{ ' ' }}
            {%- endif -%}
            {{ minutes }}m
          {%- endif -%}
          {%- endif -%}  
      updated_at_1_formatted:
        friendly_name: "Last Updated"
        value_template: "{{ states.sensor.updated_at_1.state | int | timestamp_custom('%-I:%M %p')}}"
        icon_template: mdi:update

When I restart Hass I get the folowing error.
The system cannot restart because the configuration is not valid: Component error: meater - Integration ‘meater’ not found.

Probably i do something very stupid. please help me.
Thanks!

ok, i think i figured it out. I will post the to do steps for other noobs like me:

  • make sure that you have a custum integration of the Sotolotls meater component:
    Meater thermometer - #124 by rodak

  • copy the files to the /config/custum_components as described

  • Change the manisfest file if you have version 2021.6 or higher of ha as described here:
    Meater thermometer - #162 by brg468

  • Restart a couple of times, that is what I read multiple times

  • Go to integration and add the meater integration, it will be in the list of possible integrations and configure it with your cloud credentials.

No erros anymore so I hope this works
UPDATE: yes it works, but only with internal and external temp. seems like not all the options are available this way

2 Likes

More options will come once the integration is official, they want to keep the PR as small as possible to get it merged. Then add functionality.

ok. thanks, hope it will be officially added soon

Any news on the integration?

I’m also wondering if there’s any news on an official integration

It doesn’t seem like the author is making updates to the PR anymore…

Isn’t it pending review from HA right now?

It was reviewed back in July but none of the requested changes seem to have been made. The last changes made were 4 months ago.

1 Like

Thanks for your work on this! I just put it into my setup.

Very interested in how this works as far as lamens term and I have the meater+. Will it work with that?

someone give instructions on how to install this? I am fairly new at this home assistant and not sure how to follow the MEATER Cloud REST API raspatory. I been able to install UI stuff but I think this isnt in the UI yet. I assume I have to install it in a card manually?