Adjustable Timing

I assume what I’m trying to do is possible but could use a hand figuring it out. I am controlling a fireplace and even if either Wifi or HASS goes down, I would like it to timeout and turn off after a default set time. (I chose 2 hours for now.)
However, when everything is functioning properly I would like to instead timeout the fire based on a motion sensor in the living room (which is attached to a separate esphome contoller because of the physical location of where the signal demarcation point is) and timeout via a user-settable timer via a home assistant input_number sensor.
I created “turn_on_fire” and “turn_off_fire” scripts to do the associated tasking because their are ancillary tasks associated with each (status LEDs that need state changes, the switch (relay) for the fire, logging, state publishing, etc.) and all of that works great. I created a third script called “fire_with_timeout” that calls the turn_on_fire script, has the default 2 hour delay, then calls the turn_fire_off script…which seems to work just fine.
To do the motion timing, I created a global variable called timeout_minutes defaulting to 30 on boot. I also created a homeassistant binary_sensor to pull in the state of that sensor and a template sensor to try and timeout on that user-set value. Everything seems to be working with the exception of the actual templating of the timing. See pertinent yaml below. Unless there’s another way to do this, my problem is templating the “minutes” (don’t even know if I can). If I do “minutes: 30” it works okay (I think) but I would like that to be an adjustable delay via the aforementioned input_number sensor.
The line(s) I am tinkering with is comment out below because they don’t compile (either one). The esphome validator says it expects a float.
Any ideas?

-J

binary_sensor:
  - platform: homeassistant
    id: motion
    entity_id: binary_sensor.living_room_motion
    on_press:
      then:
        - if:
            condition:
              switch.is_on: relay
            then:
              - logger.log:
                  format: "Motion detected while fire on, resetting timer for %f minutes."
                  args: [ 'id(timeout_minutes)']
              - script.stop: fire_with_timeout
              - script.execute: fire_with_timeout
            else:
              - logger.log: "Motion detected but fire is off."
  - platform: template
    id: timeout_template
    lambda: 'return id(motion).state;'
    filters:
      - delayed_off:
          # minutes: !lambda "return id(timeout_minutes);"
          # minutes: !lambda "return id(timeout_minutes).value;"
          # minutes: !lambda "return id(timeout_minutes).state;"
          minutes: 30
    on_release:
      then:
        - if:
            condition:
              switch.is_on: relay
            then:
              - logger.log: "Motion timeout reached while fire on, turning off fire."
              - script.execute: turn_off_fire
            else:
              - logger.log: "Motion timeout reached but fire is off."

script:
  - id: turn_on_fire
    then:
      - switch.turn_on: relay
      - switch.template.publish:
          id: fire
          state: ON
      - homeassistant.service:
         service: light.turn_on
         data: {"entity_id": "light.fp_left_indicator"}

  - id: turn_off_fire
    then:
      - script.stop: fire_with_timeout
      - switch.turn_off: relay
      - switch.template.publish:
          id: fire
          state: OFF
      - homeassistant.service:
          service: switch.turn_off
          data: {"entity_id": "switch.fireplace_fan"}
      - homeassistant.service:
          service: light.turn_off
          data: {"entity_id": "light.fp_left_indicator"}
      - script.stop: fire_with_timeout

  - id: fire_with_timeout
    then:
      - script.execute: turn_on_fire
      - logger.log: "Default timer (2hr) reset"
      - delay: '02:00:00'
      - logger.log: "Default (2hr) timeout reached. Turning off fire"
      - script.execute: turn_off_fire

You probably want to use mi!!is and another timing mechanism, interval:, time; or on_loop. The processor has an internal system clock it keeps in milliseconds called millis. What you would do is at the start of your timing event read the mi!!is and store it in a global. Then set up a timing loop like interval to every second (or your chosen time interval ) compare the current_millis - saved_millis to your timeout value. When the difference is greater trigger your script.

I have an alarm clock that has an adjustable sleep timer that is set by input_number. The input is in minutes. This is how i set it, maybe it will help you.

I’ve never seen that type of code for HA before so beyond that I’m lost. I’m curious about what you’re using there, it doesn’t look like regular HA YAML.

      - service_template: >-
          {% if is_state('input_boolean.alarm_clock_snooze', 'on') %} timer.start
          {% else %} script.null_script
          {% endif %}
        data_template:
          entity_id: timer.alarm_clock_snooze
          duration: '00:{{ states.input_number.alarm_clock_snooze_time.state | int }}'

Can I ask you what relay you are using for your fireplace? I’ve been looking at the Remotec ZFM-80 but it’s $70 CDN so I’m having a hard time justifying it.

The code is not typical HA yaml because it’s the config YAML for esphome devices. The relay I’m using is actually just a sonoff switch. The fireplace runs on a thermopile and there are two contacts that when shorted, opens the valve for the gas. So the sonoff relay just does the contact closure with the relay.

-Josh