2025 - Recteq Smoker Home Assistant via TuyaLocal

On this post they used a Lovelace (dashboard) thermostat card called simple-thermostat for the dashboard. I think it works well so let’s install it using HACS

Now let’s make some helpers. http://homeassistant.local:8123/config/helpers Note the type of helper is shown in the EntityID

Name: Smoker Target Temperature
Icon mdi:thermometer
Unit of Measurement: °F
Display Precision: 0
EntityID: sensor.smoker_target_temperature
Template: {{ states('number.set_temp') | round(0, default=0) }}
Unit of Measurement: °F
Device Class: temperature
State Class: Measurement


Name: Smoker Probe-A Target
Icon mdi:thermometer
EntityID: input_number.smoker_probe_a_target
Min Value: 0
Max value: 250
Step size: 5
Unit of Measurement: °F


Name: Smoker Probe-B Target
Icon mdi:thermometer
EntityID: input_number.smoker_probe_b_target
Min Value: 0
Max value: 250
Step size: 5
Unit of Measurement: °F


Name: Smoker Probe-A Status
Icon mdi:food-steak
EntityID: sensor.smoker_probe_a_status
Template: 
{% if states('sensor.smoker_probe_a_temperature') != unavailable %}
          {% set target = states('input_number.smoker_probe_a_target')|int %}
          {% set actual = states('sensor.probe_a')|int %}
          {% set offset = actual - target %}
          {% if offset > 5 %}Over Temp!
          {% elif offset > -5 %}At Target
          {% elif offset > -15 %}Approaching...
          {% else %}Not Cooked Enough{% endif %}
{%- endif %}


Name: Smoker Probe-B Status
Icon mdi:food-steak
EntityID: sensor.smoker_probe_b_status
Template: 
{% if states('sensor.smoker_probe_b_temperature') != unavailable %}
          {% set target = states('input_number.smoker_probe_b_target')|int %}
          {% set actual = states('sensor.probe_b')|int %}
          {% set offset = actual - target %}
          {% if offset > 5 %}Over Temp!
          {% elif offset > -5 %}At Target
          {% elif offset > -15 %}Approaching...
          {% else %}Not Cooked Enough{% endif %}
{%- endif %}


Name: Probe-A Percent
Icon mdi:food-steak
Display Precision: 0
EntityID: sensor.probe_a_percent
Template: 
{% if states('sensor.smoker_probe_a_temperature') != unavailable %}
          {% set target = states('input_number.smoker_probe_a_target')|float %}
          {% set actual = states('sensor.probe_a')|float %}
          {% set percent = (actual / target) * 100 %}
          {{percent}}
{%- endif %}
Unit of Measurement: %
State Class: Measurement


Name: Probe-B Percent
Icon mdi:food-steak
Display Precision: 0
EntityID: sensor.probe_b_percent
Template: 
{% if states('sensor.smoker_probe_b_temperature') != unavailable %}
          {% set target = states('input_number.smoker_probe_b_target')|float %}
          {% set actual = states('sensor.probe_b')|float %}
          {% set percent = (actual / target) * 100 %}
          {{percent}}
{%- endif %}
Unit of Measurement: %
State Class: Measurement

We need to set some limits to the climate controller. Apparently this has to be done in the raw config yaml files. I happen to have Studio Code Server installed which makes that super easy to do.

Lovelace Thermostat Card Fix

This is required because the LocalTuya configuration for the entity will not take free-text values and none of the DPS parameters from the smoker itself provide the max/min. We are going to hard-code these. I assume you’ve never configured a customization before below. If you have, you know where to start :slight_smile:

  1. Create a new customize.yaml file in the root of the config folder. I use the Visual Code Studio host add-on so this is very easy from within HA.
  2. Include the following in the new customize.yaml file, replacing the climate.smoker_temperature with the appropriate entity ID:
climate.smoker:
  max_temp: 500
  min_temp: 180
  1. Save the file.
  2. Open the configuration.yaml file and locate a line that states homeassistant:; if this does not exist, add it on a new line at the bottom.
  3. Indent two spaces, and add customize: !include customize.yaml and save the file. The added text should be:
homeassistant:
  customize: !include customize.yaml

Restart HA

OK, that was a lot. Let’s make a dashboard. I used a lot of the details (again) from this post

But the setup is different in Home Assistant now and I couldn’t just copy/paste it, so I got to do “New dashboard from scratch.” Once that is made, you can choose to either use the following information to make the dashboard using the GUI (like I did), or you can try pasting it into the “{}raw configuration editor” and see if it works:

views:
  - title: Smoker
    sections:
      - type: grid
        cards:
          - type: conditional
            conditions:
              - condition: state
                entity: switch.smoker_on_off
                state: 'off'
            card:
              type: glance
              entities:
                - entity: switch.smoker_on_off
          - type: conditional
            conditions:
              - condition: state
                entity: switch.smoker_on_off
                state: 'on'
            card:
              type: custom:simple-thermostat
              entity: climate.smoker_set_temp
              decimals: 0
              step_size: 5
              hide:
                state: true
              header:
                toggle:
                  entity: switch.smoker_on_off
              layout:
                step: row
                mode:
                  headings: false
                  icons: false
                  names: false
          - type: conditional
            conditions:
              - condition: state
                entity: switch.smoker_on_off
                state: 'on'
              - condition: numeric_state
                entity: sensor.probe_a
                above: 0
              - condition: numeric_state
                entity: sensor.probe_b
                below: 1
            card:
              type: history-graph
              entities:
                - entity: sensor.probe_a
                  name: Probe-A
                - entity: sensor.smoker_target_temperature
                  name: Target
                - entity: sensor.actual_temperature
                  name: Actual
              hours_to_show: 8
          - type: conditional
            conditions:
              - condition: state
                entity: switch.smoker_on_off
                state: 'on'
              - condition: numeric_state
                entity: sensor.probe_a
                above: 1
              - condition: numeric_state
                entity: sensor.probe_b
                below: 0
            card:
              type: history-graph
              entities:
                - entity: sensor.probe_b
                  name: Probe-B
                - entity: sensor.smoker_target_temperature
                  name: Target
                - entity: sensor.actual_temperature
                  name: Actual
              hours_to_show: 8
          - type: conditional
            conditions:
              - condition: state
                entity: switch.smoker_on_off
                state: 'on'
              - entity: sensor.probe_a
                state: unavailable
              - entity: sensor.probe_b
                state: unavailable
            card:
              type: history-graph
              entities:
                - entity: sensor.smoker_target_temperature
                  name: Target
                - entity: sensor.actual_temperature
                  name: Actual
              hours_to_show: 8
          - type: conditional
            conditions:
              - condition: state
                entity: switch.smoker_on_off
                state: 'on'
              - condition: numeric_state
                entity: sensor.probe_a
                above: 0
              - condition: numeric_state
                entity: sensor.probe_b
                above: 0
            card:
              type: history-graph
              entities:
                - entity: sensor.probe_a
                  name: Probe-A
                - entity: sensor.probe_b
                  name: Probe-B
                - entity: sensor.smoker_target_temperature
                  name: Target
                - entity: sensor.actual_temperature
                  name: Actual
              hours_to_show: 8
      - type: grid
        cards:
          - type: picture
            image: >-
              https://support.recteq.com/hc/theming_assets/01HZPQW9TJCNCSY7DCNFCGC2BX
          - type: conditional
            conditions:
              - condition: state
                entity: switch.smoker_on_off
                state: 'on'
              - condition: numeric_state
                entity: sensor.probe_a
                above: 0
            card:
              type: glance
              entities:
                - entity: sensor.probe_a
                  name: Probe-A
                - entity: input_number.smoker_probe_a_target
                  name: Target
                - entity: sensor.smoker_probe_a_status
                  name: Status
                - entity: sensor.probe_a_percent
          - type: conditional
            conditions:
              - condition: state
                entity: switch.smoker_on_off
                state: 'on'
              - condition: numeric_state
                entity: sensor.probe_a
                above: 0
            card:
              type: gauge
              entity: sensor.probe_a_percent
              severity:
                green: 60
                yellow: 80
                red: 90
              needle: true
          - type: conditional
            conditions:
              - condition: state
                entity: switch.smoker_on_off
                state: 'on'
              - condition: numeric_state
                entity: sensor.probe_b
                above: 0
            card:
              type: glance
              entities:
                - entity: sensor.probe_b
                  name: Probe-B
                - entity: input_number.smoker_probe_b_target
                  name: Target
                - entity: sensor.smoker_probe_b_status
                  name: Status
                - entity: sensor.probe_b_percent
          - type: conditional
            conditions:
              - condition: state
                entity: switch.smoker_on_off
                state: 'on'
              - condition: numeric_state
                entity: sensor.probe_b
                above: 0
            card:
              type: gauge
              entity: sensor.probe_b_percent
              severity:
                green: 60
                yellow: 80
                red: 90
              needle: true
    type: sections
    max_columns: 2
    icon: mdi:grill
    cards: []

You’ll notice that a lot of the entries show and hide based on what the smoker is doing. If the smoker is off, it only shows the main switch, then it shows different graphs and such depending on if the probe is plugged in or not.

So… that’s it so far as I can remember =)

2 Likes