Calling a service with inputs from Dashboard to control AC from Switchbot Hub

I’m trying to control one of my air conditioners which only accepts IR inputs. I have it working using the switchbot hub mini and the best way I’ve found to bring this into Home Assistant is using this pyscript GitHub - SiriosDev/SwitchBot-API-Script-Caller: SwitchBot API (Ver. 1.1) Script Caller, using pyscript for the scripting (happy for any other suggestions but interfacing with the switchbot API seems to be the best approach)

I have the script working and by using the Dev tools with the inputs I can successfully send commands.

Now I need to find a nice way to put some controls on my dashboard. I thought I could setup some helpers to store the different variables and then call the service each time one of the helpers is changed but I’m not sure that’s the best way to do it

I’d really like some advice

Why don’t you implement a climate entity in home assistant?

Back to your question, you can generate number entities with your own internal state and supply the value of number entities into service at call time.

How would I implement a climate entity with the above service in mind?

If you go through the documentation, it seems to be inline your entity.

Off, HVAC Modes, Temperate and Fan

Wouldn’t I still need to call the service though? HA has no idea about my AC because the only way it’s controlled is via the python script

This is what the service has to send (all attributes every time)

service: pyscript.switchbot_hvac
data:
  deviceId: some_device_id
  temperature: 21
  mode: 2
  fan_speed: 1
  state: "on"

so, you are not writing a custom integration right, you just want to use pyscript.

If that is the case, you can create a template climate (GitHub - jcwillox/hass-template-climate: ❄️Templatable Climate Device for Home Assistant, Supports Running Actions On Service Calls.) and set the actions to same identical service. All HVAC, temperature, fan actions would point to same service (if any of these had changed, service would be called)

Ok I think I’m getting somewhere but something is wrong with my YAML. I think I’ve narrowed it down to the if statements I’m using for mode, fan_speed, state. If I remove those it doesn’t error

climate:
  - platform: climate_template
    name: Downstairs AC - Template
    unique_id: '65bfec75-873e-43f4-9190-02aab52d3591'
    modes:
      - "auto"
      - "dry"
      - "off"
      - "cool"
      - "fan_only"
      - "heat"

    fan_modes:
      - "auto"
      - "low"
      - "medium"
      - "high"

    min_temp: 16
    max_temp: 30

    # get current temp.
    current_temperature_template: "{{ states('sensor.downstairs_universal_remote_temperature') }}"

    # get current humidity.
    current_humidity_template: "{{ states('sensor.downstairs_universal_remote_humidity') }}"

    # example action
    set_temperature:
      # send the climates current state to esphome.
      - service: pyscript.switchbot_hvac
        data:
          deviceId: "some_device_id"
          temperature: "{{ state_attr('climate.downstairs_ac', 'temperature') | int }}"
          mode: >
            {% if is_state('climate.downstairs_ac', 'auto') %} 1
            {% if is_state('climate.downstairs_ac', 'dry') %} 3
            {% if is_state('climate.downstairs_ac', 'off') %} 1
            {% if is_state('climate.downstairs_ac', 'cool') %} 2
            {% if is_state('climate.downstairs_ac', 'fan_only') %} 4
            {% if is_state('climate.downstairs_ac', 'heat') %} 5
            {% else %} 1
            {% endif %}

          fan_speed: >
            {% if is_state_attr('climate.bedroom_aircon', 'fan_mode', 'auto') %} 1
            {% if is_state_attr('climate.bedroom_aircon', 'fan_mode', 'low') %} 2
            {% if is_state_attr('climate.bedroom_aircon', 'fan_mode', 'medium') %} 3
            {% if is_state_attr('climate.bedroom_aircon', 'fan_mode', 'high') %} 4
            {% else %} 1
            {% endif %}

          state: >
            {% if states('climate.downstairs_ac') != "off" %} "on"
            {% else %} "off"

The template tester in Dev tools is giving me this

TemplateSyntaxError: Unexpected end of template. Jinja was looking for the following tags: ‘endif’. The innermost block that needs to be closed is ‘if’.

and the YAML checker is giving me this

Invalid config for [climate.climate_template]: template value should be a string for dictionary value @ data[‘set_temperature’][0][‘data’]. Got OrderedDict([(‘deviceId’, ‘01-202212062000-53025061’), (‘temperature’, “{{ state_attr(‘climate.downstairs_ac’, ‘temperature’) | int }}”), (‘mode’, “{% if is_state(‘climate.downstairs_ac’, ‘auto’) %} 1 {% if is_state(‘climate.downstairs_ac’, ‘dry’) %} 3 {% if is_state(‘climate.downstairs_ac’, ‘off’) %} 1 {% if is_state(‘climate.downstairs_ac’, ‘cool’) %} 2 {% if is_state(‘climate.downstairs_ac’, ‘fan_only’) %} 4 {% if is_state(‘climate.downstairs_ac’, ‘heat’) %} 5 {% else %} 1 {% endif %}\n”),… (See ?, line ?).

I think, you can only use one IF and the rest should be ELIF (else if)

            {% if is_state('climate.downstairs_ac', 'auto') %} 1
            {% elif is_state('climate.downstairs_ac', 'dry') %} 3
            {% elif is_state('climate.downstairs_ac', 'off') %} 1
            {% elif is_state('climate.downstairs_ac', 'cool') %} 2
            {% elif is_state('climate.downstairs_ac', 'fan_only') %} 4
            {% elif is_state('climate.downstairs_ac', 'heat') %} 5
            {% else %} 1
            {% endif %}

Yup that did it!

For anyone wanting the full config here it is

climate:
  - platform: climate_template
    name: Downstairs AC
    unique_id: '65bfec75-873e-43f4-9190-02aab52d3591'
    modes:
      - "auto"
      - "dry"
      - "off"
      - "cool"
      - "fan_only"
      - "heat"
    fan_modes:
      - "auto"
      - "low"
      - "medium"
      - "high"
    min_temp: 16
    max_temp: 30

    # get current temp.
    current_temperature_template: "{{ states('sensor.downstairs_universal_remote_temperature') }}"

    # get current humidity.
    current_humidity_template: "{{ states('sensor.downstairs_universal_remote_humidity') }}"

    # example action
    set_temperature:
      - service: pyscript.switchbot_hvac
        data:
          deviceId: "some_device_id"
          temperature: "{{ state_attr('climate.downstairs_ac', 'temperature') | int }}"
          mode: >
            {% if is_state('climate.downstairs_ac', 'auto') %} 1
            {% elif is_state('climate.downstairs_ac', 'dry') %} 3
            {% elif is_state('climate.downstairs_ac', 'off') %} 1
            {% elif is_state('climate.downstairs_ac', 'cool') %} 2
            {% elif is_state('climate.downstairs_ac', 'fan_only') %} 4
            {% elif is_state('climate.downstairs_ac', 'heat') %} 5
            {% else %} 1
            {% endif %}
          fan_speed: >
            {% if is_state_attr('climate.downstairs_ac', 'fan_mode', 'auto') %} 1
            {% elif is_state_attr('climate.downstairs_ac', 'fan_mode', 'low') %} 2
            {% elif is_state_attr('climate.downstairs_ac', 'fan_mode', 'medium') %} 3
            {% elif is_state_attr('climate.downstairs_ac', 'fan_mode', 'high') %} 4
            {% else %} 1
            {% endif %}
          state: >
            {% if states('climate.downstairs_ac') != "off" %} on
            {% else %} off
            {% endif %}
      
    set_hvac_mode:
      - service: pyscript.switchbot_hvac
        data:
          deviceId: "some_device_id"
          temperature: "{{ state_attr('climate.downstairs_ac', 'temperature') | int }}"
          mode: >
            {% if is_state('climate.downstairs_ac', 'auto') %} 1
            {% elif is_state('climate.downstairs_ac', 'dry') %} 3
            {% elif is_state('climate.downstairs_ac', 'off') %} 1
            {% elif is_state('climate.downstairs_ac', 'cool') %} 2
            {% elif is_state('climate.downstairs_ac', 'fan_only') %} 4
            {% elif is_state('climate.downstairs_ac', 'heat') %} 5
            {% else %} 1
            {% endif %}
          fan_speed: >
            {% if is_state_attr('climate.downstairs_ac', 'fan_mode', 'auto') %} 1
            {% elif is_state_attr('climate.downstairs_ac', 'fan_mode', 'low') %} 2
            {% elif is_state_attr('climate.downstairs_ac', 'fan_mode', 'medium') %} 3
            {% elif is_state_attr('climate.downstairs_ac', 'fan_mode', 'high') %} 4
            {% else %} 1
            {% endif %}
          state: >
            {% if states('climate.downstairs_ac') != "off" %} on
            {% else %} off
            {% endif %}

    set_fan_mode:
      - service: pyscript.switchbot_hvac
        data:
          deviceId: "some_device_id"
          temperature: "{{ state_attr('climate.downstairs_ac', 'temperature') | int }}"
          mode: >
            {% if is_state('climate.downstairs_ac', 'auto') %} 1
            {% elif is_state('climate.downstairs_ac', 'dry') %} 3
            {% elif is_state('climate.downstairs_ac', 'off') %} 1
            {% elif is_state('climate.downstairs_ac', 'cool') %} 2
            {% elif is_state('climate.downstairs_ac', 'fan_only') %} 4
            {% elif is_state('climate.downstairs_ac', 'heat') %} 5
            {% else %} 1
            {% endif %}
          fan_speed: >
            {% if is_state_attr('climate.downstairs_ac', 'fan_mode', 'auto') %} 1
            {% elif is_state_attr('climate.downstairs_ac', 'fan_mode', 'low') %} 2
            {% elif is_state_attr('climate.downstairs_ac', 'fan_mode', 'medium') %} 3
            {% elif is_state_attr('climate.downstairs_ac', 'fan_mode', 'high') %} 4
            {% else %} 1
            {% endif %}
          state: >
            {% if states('climate.downstairs_ac') != "off" %} on
            {% else %} off
            {% endif %}