Fujitsu Air Conditioning integration - Airstage dongle

Try this for size.

It should fix the being able to turn off via the mode dropdown, and if set to off and you select a mode it should turn on.

Sadly, it doesn’t show the off state in the UI yet (I need to fix the hvac_mode_template to first detect if it is off, and only if it is not off to detect the mode…)

Let me know if this works for you

# See the HA Community thread https://community.home-assistant.io/t/fujitsu-air-conditioning-integration-airstage-dongle/589679
# Integration for Fujitsu wi-fi adpaters that use Airstage app (n.b. will NOT work with the older/withdrawn FGLair app)
#
# 1) Install 'Climate IP' via the HACS integration manager https://github.com/jcwillox/hass-template-climate
# 2) Using 'Studio Code Server' from the HA add-ons store is useful
# 3) Use seach&replace funcitonality is useful!
# 4) Save this file as e.g. 'upstairs_aircon.yaml'. 
# 5) Place this file in the same folder as your configuration.yaml
# 6) Search & replace all '192.168.1.188' with the IP address of your aircon (assign a static IP to this device)
# 7) Search & replace all 'E8FB1CFF5FF5' with the MAC address of your aircon (do not put any : in the address)
# 8) Search & replace all instances of 'upstairs' with what you want to name the new aircon device (n.b. needs to be in lower case except where indicated)
# 9) Have a look through at # out sections to see if you want to enable
# 10) Add the following lines to your configuration.yaml (ensure it refers to the correct filename & you remove the #'s')
###############
#homeassistant:
#  packages:
#    pack_1: !include upstairs_aircon.yaml 
###############
#
# **swing mode is not tested as my device does not have that function** (please report back in the thread if it works)
# 
# Thanks to all the people in the aforemetnioned thread including @pietervanh @ravenland

rest_command:
  upstairs_aircon_setmode:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: >
      {% set aircomodes = {"auto": '"iu_op_mode":"0"',"cool": '"iu_op_mode":"1"',"dry": '"iu_op_mode":"2"',"fan_only": '"iu_op_mode":"3"',"heat": '"iu_op_mode":"4"',"off": '"iu_onoff":"0"'} %}
      {% set opmode = aircomodes.get(hvac_mode, 0) %}
      {"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{ {{opmode}} }} 
  upstairs_aircon_settemp:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: >
      {% set setroomtemp = (target_temp | float   * 10) | int %}
      {"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_set_tmp":"{{ setroomtemp }}"}}
  upstairs_aircon_set_fan_speed:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: >
      {% set fanspds = {"auto": 0, "Quiet": 2,"low": 5,"medium": 8,"high": 11} %}
      {% set spd = fanspds.get(fan_mode, 0) %}
      {"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_fan_spd":"{{ spd }}"}}

# enable if your device has a swing mode
#  upstairs_aircon_set_swing_mode:
#    url: http://192.168.1.188/SetParam
#    method: POST
#    payload: >
#      {% set mode = {"off": 0, "on": 1} %}
#      {% set swing = mode.get(swing_mode, 0) %}
#      {"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_fan_spd":"{{ swing }}"}}
    
# not all units especially ducted have powerful mode. Powerful runs for a short period then stops
  upstairs_aircon_pwrfull_on:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_powerfull":"1"}}'
  upstairs_aircon_pwrfull_off:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_powerfull":"0"}}'

# these aren't used by the template but included for completion
  upstairs_aircon_on:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_onoff":"1"}}'
  upstairs_aircon_off:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_onoff":"0"}}'
  upstairs_aircon_eco_on:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_economy":"1"}}'
  upstairs_aircon_eco_off:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_economy":"0"}}'
  upstairs_aircon_fanctrl_on:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_fan_ctrl":"1"}}'
  upstairs_aircon_fanctrl_off:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_fan_ctrl":"0"}}'

rest:
  - resource: http://192.168.1.188/GetParam
    scan_interval: 60
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"03","list":["iu_set_tmp","iu_indoor_tmp","iu_outdoor_tmp","iu_onoff","iu_economy","iu_fan_ctrl","iu_fan_ctrl","iu_powerful","ou_low_noise","iu_op_mode","iu_fan_spd","iu_af_swg_vrt"]}'
    sensor:
      - name: "Temp Outside upstairs Aircon"
        value_template: "{{ (((value_json['value']['iu_outdoor_tmp'] | float  / 100 ) - 32 ) * 5/9) | round(2) }}"
        unit_of_measurement: "°C"
      - name: "Temp Inside upstairs Aircon"
        value_template: "{{ (((value_json['value']['iu_indoor_tmp'] | float  / 100 ) - 32 ) * 5/9) | round(2) }}"
        unit_of_measurement: "°C"
      - name: "Requested Temp upstairs Aircon"
        value_template: "{{ (value_json['value']['iu_set_tmp'] | float / 10 )| round(2) }}"
        unit_of_measurement: "°C"
      - name: "Mode upstairs Aircon"
        value_template: >
          {% set mapper ={'0': 'auto','1': 'cool','2': 'dry','3': 'fan_only','4': 'heat'} %}
          {% set state =  value_json['value']['iu_op_mode'] %}
          {{ mapper[state] if state in mapper else 'Unknown' }}
      - name: "Fan Speed Upstairs Aircon"
        value_template: >
          {% set mapper ={'0': 'auto','2': 'Quiet','5': 'low','8': 'medium','11': 'high'} %}
          {% set state =  value_json['value']['iu_fan_spd'] %}
          {{ mapper[state] if state in mapper else 'Unknown' }}

# enable if your device has a swing mode
#      - name: "Swing Mode Upstairs Aircon"
#        value_template: >
#          {% set mapper ={'0': 'off','1': 'on'} %}
#          {% set state =  value_json['value']['iu_af_swg_vrt'] %}
#          {{ mapper[state] if state in mapper else 'Unknown' }}



climate:
  - platform: climate_template
# the name: can have capital letters if desired
    name: Upstairs Aircon
    modes: 
      - "auto"
      - "dry"
      - "off"
      - "cool"
      - "fan_only"
      - "heat"
    fan_modes:
      - "auto"
      - "Quiet"
      - "low"
      - "medium"
      - "high"

# enable if your device has a swing mode
#    swing_modes:
#      - "on"
#      - "off"

    min_temp: 15
    max_temp: 30

    current_temperature_template: "{{ states('sensor.temp_inside_upstairs_aircon') }}"

    hvac_mode_template: "{{ states('sensor.mode_upstairs_aircon') }}"
    
    target_temperature_template: "{{ states('sensor.requested_temp_upstairs_aircon') }}"
    
    fan_mode_template: "{{ states('sensor.fan_speed_upstairs_aircon') }}"

# enable if your device has a swing mode
#    swing_mode_template: "{{ states('sensor.swing_mode_upstairs_aircon') }}"

    set_hvac_mode:
      - service: rest_command.upstairs_aircon_on
      - delay: 1
      - service: rest_command.upstairs_aircon_setmode
        data:
          hvac_mode: "{{ hvac_mode }}"
      - delay: 2
      - service: homeassistant.update_entity
        entity_id: sensor.mode_upstairs_aircon

    set_temperature:
      - service: rest_command.upstairs_aircon_settemp
        data:
          target_temp: "{{ temperature }}"
      - delay: 2
      - service: homeassistant.update_entity
        entity_id: sensor.requested_temp_upstairs_aircon

    set_fan_mode:
      - service: rest_command.upstairs_aircon_set_fan_speed
        data:
          fan_mode: "{{ fan_mode }}"
      - delay: 2
      - service: homeassistant.update_entity
        entity_id: sensor.fan_speed_upstairs_aircon

# enable if your device has a swing mode
#    set_swing_mode:
#      - service: rest_command.upstairs_aircon_set_swing_mode
#        data:
#          swing_mode: "{{ swing_mode }}"
#      - delay: 2
#      - service: homeassistant.update_entity
#        entity_id: sensor.swing_mode_upstairs_aircon
1 Like

Turn off via mode and turn on by selecting a mode works now! Show the off state in the UI would be nice. :slight_smile:

I think I have cracked it. Not bad for someone with little/no coding knowledge!

Changes (in case you don’t want to re-do the whole file)

  • Added the rest binary_sensor for on/off (~line 115)
  • Changed the template for hvac_mode to first check if the power is off (~line 156)

Updated yaml:

# Integration for Fujitsu wi-fi adapters that use Airstage app (n.b. will NOT work with the older/discontinued adapters that use FGLair app)
# See the HA Community thread https://community.home-assistant.io/t/fujitsu-air-conditioning-integration-airstage-dongle/589679
#
# 1) Install 'Climate IP' via the HACS integration manager https://github.com/jcwillox/hass-template-climate
# 2) Using 'Studio Code Server' from the HA add-ons store is useful
# 3) Use seach&replace funcitonality is useful!
# 4) Save this file as e.g. 'upstairs_aircon.yaml'. 
# 5) Place this file in the same folder as your configuration.yaml
# 6) Search & replace all '192.168.1.188' with the IP address of your aircon (assign a static IP to this device)
# 7) Search & replace all 'E8FB1CFF5FF5' with the MAC address of your aircon (do not put any : in the address)
# 8) Search & replace all instances of 'upstairs' with what you want to name the new aircon device (n.b. needs to be in lower case except where indicated)
# 9) Have a look through at # out sections to see if you want to enable
# 10) Add the following lines to your configuration.yaml (ensure it refers to the correct filename & you remove the #'s')
###############
#homeassistant:
#  packages:
#    pack_1: !include upstairs_aircon.yaml 
###############
#
# ***you will need to do a 'proper'' restart of HA rather than just a quick reload ***
#
# **swing mode is not tested as my device does not have that function** (please report back in the thread if it works)
# 
# Thanks to all the people in the aforemetnioned thread including @pietervanh @ravenland

rest_command:
  upstairs_aircon_setmode:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: >
      {% set aircomodes = {"auto": '"iu_op_mode":"0"',"cool": '"iu_op_mode":"1"',"dry": '"iu_op_mode":"2"',"fan_only": '"iu_op_mode":"3"',"heat": '"iu_op_mode":"4"',"off": '"iu_onoff":"0"'} %}
      {% set opmode = aircomodes.get(hvac_mode, 0) %}
      {"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{ {{opmode}} }} 
  upstairs_aircon_settemp:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: >
      {% set setroomtemp = (target_temp | float   * 10) | int %}
      {"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_set_tmp":"{{ setroomtemp }}"}}
  upstairs_aircon_set_fan_speed:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: >
      {% set fanspds = {"auto": 0, "Quiet": 2,"low": 5,"medium": 8,"high": 11} %}
      {% set spd = fanspds.get(fan_mode, 0) %}
      {"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_fan_spd":"{{ spd }}"}}

# enable if your device has a swing mode
#  upstairs_aircon_set_swing_mode:
#    url: http://192.168.1.188/SetParam
#    method: POST
#    payload: >
#      {% set mode = {"off": 0, "on": 1} %}
#      {% set swing = mode.get(swing_mode, 0) %}
#      {"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_fan_spd":"{{ swing }}"}}
    
# not all units especially ducted have powerful mode. Powerful runs for a short period then stops
  upstairs_aircon_pwrfull_on:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_powerfull":"1"}}'
  upstairs_aircon_pwrfull_off:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_powerfull":"0"}}'

# these aren't used by the template but included for completion
  upstairs_aircon_on:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_onoff":"1"}}'
  upstairs_aircon_off:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_onoff":"0"}}'
  upstairs_aircon_eco_on:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_economy":"1"}}'
  upstairs_aircon_eco_off:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_economy":"0"}}'
  upstairs_aircon_fanctrl_on:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_fan_ctrl":"1"}}'
  upstairs_aircon_fanctrl_off:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_fan_ctrl":"0"}}'

rest:
  - resource: http://192.168.1.188/GetParam
    scan_interval: 60
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"03","list":["iu_set_tmp","iu_indoor_tmp","iu_outdoor_tmp","iu_onoff","iu_economy","iu_fan_ctrl","iu_fan_ctrl","iu_powerful","ou_low_noise","iu_op_mode","iu_fan_spd","iu_af_swg_vrt"]}'
    sensor:
      - name: "Temp Outside upstairs Aircon"
        value_template: "{{ (((value_json['value']['iu_outdoor_tmp'] | float  / 100 ) - 32 ) * 5/9) | round(2) }}"
        unit_of_measurement: "°C"
      - name: "Temp Inside upstairs Aircon"
        value_template: "{{ (((value_json['value']['iu_indoor_tmp'] | float  / 100 ) - 32 ) * 5/9) | round(2) }}"
        unit_of_measurement: "°C"
      - name: "Requested Temp upstairs Aircon"
        value_template: "{{ (value_json['value']['iu_set_tmp'] | float / 10 )| round(2) }}"
        unit_of_measurement: "°C"
      - name: "Mode upstairs Aircon"
        value_template: >
          {% set mapper ={'0': 'auto','1': 'cool','2': 'dry','3': 'fan_only','4': 'heat'} %}
          {% set state =  value_json['value']['iu_op_mode'] %}
          {{ mapper[state] if state in mapper else 'Unknown' }}
      - name: "Fan Speed Upstairs Aircon"
        value_template: >
          {% set mapper ={'0': 'auto','2': 'Quiet','5': 'low','8': 'medium','11': 'high'} %}
          {% set state =  value_json['value']['iu_fan_spd'] %}
          {{ mapper[state] if state in mapper else 'Unknown' }}
    binary_sensor:
      - name: "Power Status upstairs Aircon"
        value_template: "{{ (value_json['value']['iu_onoff']) }}"

# enable if your device has a swing mode
#      - name: "Swing Mode Upstairs Aircon"
#        value_template: >
#          {% set mapper ={'0': 'off','1': 'on'} %}
#          {% set state =  value_json['value']['iu_af_swg_vrt'] %}
#          {{ mapper[state] if state in mapper else 'Unknown' }}



climate:
  - platform: climate_template
# the name: can have capital letters if desired
    name: Upstairs Aircon
    modes: 
      - "auto"
      - "dry"
      - "off"
      - "cool"
      - "fan_only"
      - "heat"
    fan_modes:
      - "auto"
      - "Quiet"
      - "low"
      - "medium"
      - "high"

# enable if your device has a swing mode
#    swing_modes:
#      - "on"
#      - "off"

    min_temp: 15
    max_temp: 30

    current_temperature_template: "{{ states('sensor.temp_inside_upstairs_aircon') }}"

    hvac_mode_template: >
      {% if is_state('binary_sensor.power_status_upstairs_aircon', 'off') %}
        off
      {% else %}
        {{ states('sensor.mode_upstairs_aircon') }}
      {% endif %}
    
    target_temperature_template: "{{ states('sensor.requested_temp_upstairs_aircon') }}"
    
    fan_mode_template: "{{ states('sensor.fan_speed_upstairs_aircon') }}"

# enable if your device has a swing mode
#    swing_mode_template: "{{ states('sensor.swing_mode_upstairs_aircon') }}"

    set_hvac_mode:
      - service: rest_command.upstairs_aircon_on
      - delay: 1
      - service: rest_command.upstairs_aircon_setmode
        data:
          hvac_mode: "{{ hvac_mode }}"
      - delay: 2
      - service: homeassistant.update_entity
        entity_id: sensor.mode_upstairs_aircon

    set_temperature:
      - service: rest_command.upstairs_aircon_settemp
        data:
          target_temp: "{{ temperature }}"
      - delay: 2
      - service: homeassistant.update_entity
        entity_id: sensor.requested_temp_upstairs_aircon

    set_fan_mode:
      - service: rest_command.upstairs_aircon_set_fan_speed
        data:
          fan_mode: "{{ fan_mode }}"
      - delay: 2
      - service: homeassistant.update_entity
        entity_id: sensor.fan_speed_upstairs_aircon

# enable if your device has a swing mode
#    set_swing_mode:
#      - service: rest_command.upstairs_aircon_set_swing_mode
#        data:
#          swing_mode: "{{ swing_mode }}"
#      - delay: 2
#      - service: homeassistant.update_entity
#        entity_id: sensor.swing_mode_upstairs_aircon 

3 Likes

Good job, now it is a realy nice soultion to control the ac.
Thanks to you and all other people here.

Can you confirm if the swing control is working?

Would be good if someone could convert it into a HACS integration! (With minimal config file editing)

Swing control does not work.
Fix:

#  upstairs_aircon_set_swing_mode:
#    url: http://192.168.1.188/SetParam
#    method: POST
#    payload: >
#      {% set mode = {"off": 0, "on": 1} %}
#      {% set swing = mode.get(swing_mode, 0) %}
#      {"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_af_swg_vrt":"{{ swing }}"}}

Turn swing on works after fix but sensor always shows state off, even if swing is on.

My schoolboy error in the rest_command!

To debug the status can you put this as a template in developer tools? (Changing the name of the Aircon device to suit your setup)

{{ states(‘sensor.swing_mode_upstairs_aircon’) }}

Have you removed the # on both the bonary_sensor section and all three parts of the climate section?

If the above template isn’t working then try replacing the binary_sensor with this:

      - name: "Swing Mode upstairs Aircon"
        value_template: "{{ (value_json['value']['iu_af_swg_vrt']) }}"

Fixed it with this changes:

# enable if your device has a swing mode
    swing_mode_template: "{{ states('binary_sensor.swing_mode_upstairs_aircon') }}"

# enable if your device has a swing mode
    set_swing_mode:
      - service: rest_command.upstairs_aircon_set_swing_mode
        data:
          swing_mode: "{{ swing_mode }}"
      - delay: 2
      - service: homeassistant.update_entity
        entity_id: binary_sensor.swing_mode_upstairs_aircon

Swing control does work now :slight_smile:

I’ve tried combining all these changes into the one file but getting the error

Invalid config for [rest]: [swing_mode_template] is an invalid option for [rest]. Check: rest->rest->0->swing_mode_template. (See ?, line ?).

EDIT: oops my bad, missed a section when copying and pasting. Works now!

One thing that took me a while to debug: on my system, this whole thing only worked when I put the MAC address in capitals, for some reason when copying it out of my router data it came in with lower case letters. Might want to update the comments at top to make that clear.

This all seems to work with the exception of the swing mode. I’m getting ‘unknown’ for the sensor.swing_mode_xxx

Here’s my yaml for reference:

rest_command:
  bed2_aircon_setmode:
    url: http://192.168.8.36/SetParam
    method: POST
    payload: >
      {% set aircomodes = {"auto": '"iu_op_mode":"0"',"cool": '"iu_op_mode":"1"',"dry": '"iu_op_mode":"2"',"fan_only": '"iu_op_mode":"3"',"heat": '"iu_op_mode":"4"',"off": '"iu_onoff":"0"'} %}
      {% set opmode = aircomodes.get(hvac_mode, 0) %}
      {"device_id":"106838462EC1","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{ {{opmode}} }} 
  bed2_aircon_settemp:
    url: http://192.168.8.36/SetParam
    method: POST
    payload: >
      {% set setroomtemp = (target_temp | float   * 10) | int %}
      {"device_id":"106838462EC1","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_set_tmp":"{{ setroomtemp }}"}}
  bed2_aircon_set_fan_speed:
    url: http://192.168.8.36/SetParam
    method: POST
    payload: >
      {% set fanspds = {"auto": 0, "Quiet": 2,"low": 5,"medium": 8,"high": 11} %}
      {% set spd = fanspds.get(fan_mode, 0) %}
      {"device_id":"106838462EC1","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_fan_spd":"{{ spd }}"}}

# enable if your device has a swing mode
  bed2_aircon_set_swing_mode:
    url: http://192.168.8.36/SetParam
    method: POST
    payload: >
      {% set mode = {"off": 0, "on": 1} %}
      {% set swing = mode.get(swing_mode, 0) %}
      {"device_id":"106838462EC1","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_fan_spd":"{{ swing }}"}}
    
# not all units especially ducted have powerful mode. Powerful runs for a short period then stops
  bed2_aircon_pwrfull_on:
    url: http://192.168.8.36/SetParam
    method: POST
    payload: '{"device_id":"106838462EC1","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_powerfull":"1"}}'
  bed2_aircon_pwrfull_off:
    url: http://192.168.8.36/SetParam
    method: POST
    payload: '{"device_id":"106838462EC1","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_powerfull":"0"}}'

# these aren't used by the template but included for completion
  bed2_aircon_on:
    url: http://192.168.8.36/SetParam
    method: POST
    payload: '{"device_id":"106838462EC1","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_onoff":"1"}}'
  bed2_aircon_off:
    url: http://192.168.8.36/SetParam
    method: POST
    payload: '{"device_id":"106838462EC1","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_onoff":"0"}}'
  bed2_aircon_eco_on:
    url: http://192.168.8.36/SetParam
    method: POST
    payload: '{"device_id":"106838462EC1","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_economy":"1"}}'
  bed2_aircon_eco_off:
    url: http://192.168.8.36/SetParam
    method: POST
    payload: '{"device_id":"106838462EC1","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_economy":"0"}}'
  bed2_aircon_fanctrl_on:
    url: http://192.168.8.36/SetParam
    method: POST
    payload: '{"device_id":"106838462EC1","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_fan_ctrl":"1"}}'
  bed2_aircon_fanctrl_off:
    url: http://192.168.8.36/SetParam
    method: POST
    payload: '{"device_id":"106838462EC1","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_fan_ctrl":"0"}}'

rest:
  - resource: http://192.168.8.36/GetParam
    scan_interval: 60
    payload: '{"device_id":"106838462EC1","device_sub_id":0,"req_id":"","modified_by":"","set_level":"03","list":["iu_set_tmp","iu_indoor_tmp","iu_outdoor_tmp","iu_onoff","iu_economy","iu_fan_ctrl","iu_fan_ctrl","iu_powerful","ou_low_noise","iu_op_mode","iu_fan_spd","iu_af_swg_vrt"]}'
    sensor:
      - name: "Temp Outside bed2 Aircon"
        value_template: "{{ (((value_json['value']['iu_outdoor_tmp'] | float  / 100 ) - 32 ) * 5/9) | round(2) }}"
        unit_of_measurement: "°C"
      - name: "Temp Inside bed2 Aircon"
        value_template: "{{ (((value_json['value']['iu_indoor_tmp'] | float  / 100 ) - 32 ) * 5/9) | round(2) }}"
        unit_of_measurement: "°C"
      - name: "Requested Temp bed2 Aircon"
        value_template: "{{ (value_json['value']['iu_set_tmp'] | float / 10 )| round(2) }}"
        unit_of_measurement: "°C"
      - name: "Mode bed2 Aircon"
        value_template: >
          {% set mapper ={'0': 'auto','1': 'cool','2': 'dry','3': 'fan_only','4': 'heat'} %}
          {% set state =  value_json['value']['iu_op_mode'] %}
          {{ mapper[state] if state in mapper else 'Unknown' }}
      - name: "Fan Speed bed2 Aircon"
        value_template: >
          {% set mapper ={'0': 'auto','2': 'Quiet','5': 'low','8': 'medium','11': 'high'} %}
          {% set state =  value_json['value']['iu_fan_spd'] %}
          {{ mapper[state] if state in mapper else 'Unknown' }}
    binary_sensor:
      - name: "Power Status bed2 Aircon"
        value_template: "{{ (value_json['value']['iu_onoff']) }}"

# enable if your device has a swing mode
      - name: "Swing Mode bed2 Aircon"
        value_template: >
          {% set mapper ={'0': 'off','1': 'on'} %}
          {% set state =  value_json['value']['iu_af_swg_vrt'] %}
          {{ mapper[state] if state in mapper else 'Unknown' }}



climate:
  - platform: climate_template
# the name: can have capital letters if desired
    name: bed2 Aircon
    modes: 
      - "auto"
      - "dry"
      - "off"
      - "cool"
      - "fan_only"
      - "heat"
    fan_modes:
      - "auto"
      - "Quiet"
      - "low"
      - "medium"
      - "high"

# enable if your device has a swing mode
    swing_modes:
      - "on"
      - "off"

    min_temp: 15
    max_temp: 30

    current_temperature_template: "{{ states('sensor.temp_inside_bed2_aircon') }}"

    hvac_mode_template: >
      {% if is_state('binary_sensor.power_status_bed2_aircon', 'off') %}
        off
      {% else %}
        {{ states('sensor.mode_bed2_aircon') }}
      {% endif %}
    
    target_temperature_template: "{{ states('sensor.requested_temp_bed2_aircon') }}"
    
    fan_mode_template: "{{ states('sensor.fan_speed_bed2_aircon') }}"

# enable if your device has a swing mode
    swing_mode_template: "{{ states('binary_sensor.swing_mode_bed2_aircon') }}"

    set_hvac_mode:
      - service: rest_command.bed2_aircon_on
      - delay: 1
      - service: rest_command.bed2_aircon_setmode
        data:
          hvac_mode: "{{ hvac_mode }}"
      - delay: 2
      - service: homeassistant.update_entity
        entity_id: sensor.mode_bed2_aircon

    set_temperature:
      - service: rest_command.bed2_aircon_settemp
        data:
          target_temp: "{{ temperature }}"
      - delay: 2
      - service: homeassistant.update_entity
        entity_id: sensor.requested_temp_bed2_aircon

    set_fan_mode:
      - service: rest_command.bed2_aircon_set_fan_speed
        data:
          fan_mode: "{{ fan_mode }}"
      - delay: 2
      - service: homeassistant.update_entity
        entity_id: sensor.fan_speed_bed2_aircon

# enable if your device has a swing mode
    set_swing_mode:
      - service: rest_command.bed2_aircon_set_swing_mode
        data:
          swing_mode: "{{ swing_mode }}"
      - delay: 2
      - service: homeassistant.update_entity
        entity_id: binary_sensor.swing_mode_bed2_aircon

you need this fix for swing mode: Fujitsu Air Conditioning integration - Airstage dongle - #80 by mow

sensor.swing_mode_xxx is unkown because it is wrong.
binary_sensor.swing_mode_xxx is correct.

Hey! I think I included all those fixes in the yaml here.

However if I change the swing mode in HA from Off to On, it just swaps back to Off after a few seconds. It has no effect on the actual AC unit, and as far as I can tell the state of the swing mode on the unit is not being read by the GetParam REST call.

You missed one fix in your yaml.
Here is the latest code from gorstj with all my swing fixes included.

# Integration for Fujitsu wi-fi adapters that use Airstage app (n.b. will NOT work with the older/discontinued adapters that use FGLair app)
# See the HA Community thread https://community.home-assistant.io/t/fujitsu-air-conditioning-integration-airstage-dongle/589679
#
# 1) Install 'Climate Template' via the HACS integration manager https://github.com/jcwillox/hass-template-climate
# 2) Using 'Studio Code Server' from the HA add-ons store is useful
# 3) Use seach&replace funcitonality is useful!
# 4) Save this file as e.g. 'upstairs_aircon.yaml'. 
# 5) Place this file in the same folder as your configuration.yaml
# 6) Search & replace all '192.168.1.188' with the IP address of your aircon (assign a static IP to this device)
# 7) Search & replace all 'E8FB1CFF5FF5' with the MAC address of your aircon (do not put any : in the address)
# 8) Search & replace all instances of 'upstairs' with what you want to name the new aircon device (n.b. needs to be in lower case except where indicated)
# 9) Have a look through at # out sections to see if you want to enable
# 10) Add the following lines to your configuration.yaml (ensure it refers to the correct filename & you remove the #'s')
###############
#homeassistant:
#  packages:
#    pack_1: !include upstairs_aircon.yaml 
###############
#
# ***you will need to do a 'proper'' restart of HA rather than just a quick reload ***
#
# **swing mode is not tested as my device does not have that function** (please report back in the thread if it works)
# 
# Thanks to all the people in the aforemetnioned thread including @pietervanh @ravenland

rest_command:
  upstairs_aircon_setmode:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: >
      {% set aircomodes = {"auto": '"iu_op_mode":"0"',"cool": '"iu_op_mode":"1"',"dry": '"iu_op_mode":"2"',"fan_only": '"iu_op_mode":"3"',"heat": '"iu_op_mode":"4"',"off": '"iu_onoff":"0"'} %}
      {% set opmode = aircomodes.get(hvac_mode, 0) %}
      {"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{ {{opmode}} }} 
  upstairs_aircon_settemp:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: >
      {% set setroomtemp = (target_temp | float   * 10) | int %}
      {"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_set_tmp":"{{ setroomtemp }}"}}
  upstairs_aircon_set_fan_speed:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: >
      {% set fanspds = {"auto": 0, "Quiet": 2,"low": 5,"medium": 8,"high": 11} %}
      {% set spd = fanspds.get(fan_mode, 0) %}
      {"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_fan_spd":"{{ spd }}"}}

# enable if your device has a swing mode
#  upstairs_aircon_set_swing_mode:
#    url: http://192.168.1.188/SetParam
#    method: POST
#    payload: >
#      {% set mode = {"off": 0, "on": 1} %}
#      {% set swing = mode.get(swing_mode, 0) %}
#      {"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_af_swg_vrt":"{{ swing }}"}}
    
# not all units especially ducted have powerful mode. Powerful runs for a short period then stops
  upstairs_aircon_pwrfull_on:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_powerfull":"1"}}'
  upstairs_aircon_pwrfull_off:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_powerfull":"0"}}'

# these aren't used by the template but included for completion
  upstairs_aircon_on:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_onoff":"1"}}'
  upstairs_aircon_off:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_onoff":"0"}}'
  upstairs_aircon_eco_on:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_economy":"1"}}'
  upstairs_aircon_eco_off:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_economy":"0"}}'
  upstairs_aircon_fanctrl_on:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_fan_ctrl":"1"}}'
  upstairs_aircon_fanctrl_off:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_fan_ctrl":"0"}}'

rest:
  - resource: http://192.168.1.188/GetParam
    scan_interval: 60
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"03","list":["iu_set_tmp","iu_indoor_tmp","iu_outdoor_tmp","iu_onoff","iu_economy","iu_fan_ctrl","iu_fan_ctrl","iu_powerful","ou_low_noise","iu_op_mode","iu_fan_spd","iu_af_swg_vrt"]}'
    sensor:
      - name: "Temp Outside upstairs Aircon"
        value_template: "{{ (((value_json['value']['iu_outdoor_tmp'] | float  / 100 ) - 32 ) * 5/9) | round(2) }}"
        unit_of_measurement: "°C"
      - name: "Temp Inside upstairs Aircon"
        value_template: "{{ (((value_json['value']['iu_indoor_tmp'] | float  / 100 ) - 32 ) * 5/9) | round(2) }}"
        unit_of_measurement: "°C"
      - name: "Requested Temp upstairs Aircon"
        value_template: "{{ (value_json['value']['iu_set_tmp'] | float / 10 )| round(2) }}"
        unit_of_measurement: "°C"
      - name: "Mode upstairs Aircon"
        value_template: >
          {% set mapper ={'0': 'auto','1': 'cool','2': 'dry','3': 'fan_only','4': 'heat'} %}
          {% set state =  value_json['value']['iu_op_mode'] %}
          {{ mapper[state] if state in mapper else 'Unknown' }}
      - name: "Fan Speed Upstairs Aircon"
        value_template: >
          {% set mapper ={'0': 'auto','2': 'Quiet','5': 'low','8': 'medium','11': 'high'} %}
          {% set state =  value_json['value']['iu_fan_spd'] %}
          {{ mapper[state] if state in mapper else 'Unknown' }}
    binary_sensor:
      - name: "Power Status upstairs Aircon"
        value_template: "{{ (value_json['value']['iu_onoff']) }}"

# enable if your device has a swing mode
#      - name: "Swing Mode Upstairs Aircon"
#        value_template: >
#          {% set mapper ={'0': 'off','1': 'on'} %}
#          {% set state =  value_json['value']['iu_af_swg_vrt'] %}
#          {{ mapper[state] if state in mapper else 'Unknown' }}



climate:
  - platform: climate_template
# the name: can have capital letters if desired
    name: Upstairs Aircon
    modes: 
      - "auto"
      - "dry"
      - "off"
      - "cool"
      - "fan_only"
      - "heat"
    fan_modes:
      - "auto"
      - "Quiet"
      - "low"
      - "medium"
      - "high"

# enable if your device has a swing mode
#    swing_modes:
#      - "on"
#      - "off"

    min_temp: 15
    max_temp: 30

    current_temperature_template: "{{ states('sensor.temp_inside_upstairs_aircon') }}"

    hvac_mode_template: >
      {% if is_state('binary_sensor.power_status_upstairs_aircon', 'off') %}
        off
      {% else %}
        {{ states('sensor.mode_upstairs_aircon') }}
      {% endif %}
    
    target_temperature_template: "{{ states('sensor.requested_temp_upstairs_aircon') }}"
    
    fan_mode_template: "{{ states('sensor.fan_speed_upstairs_aircon') }}"

# enable if your device has a swing mode
#    swing_mode_template: "{{ states('binary_sensor.swing_mode_upstairs_aircon') }}"

    set_hvac_mode:
      - service: rest_command.upstairs_aircon_on
      - delay: 1
      - service: rest_command.upstairs_aircon_setmode
        data:
          hvac_mode: "{{ hvac_mode }}"
      - delay: 2
      - service: homeassistant.update_entity
        entity_id: sensor.mode_upstairs_aircon

    set_temperature:
      - service: rest_command.upstairs_aircon_settemp
        data:
          target_temp: "{{ temperature }}"
      - delay: 2
      - service: homeassistant.update_entity
        entity_id: sensor.requested_temp_upstairs_aircon

    set_fan_mode:
      - service: rest_command.upstairs_aircon_set_fan_speed
        data:
          fan_mode: "{{ fan_mode }}"
      - delay: 2
      - service: homeassistant.update_entity
        entity_id: sensor.fan_speed_upstairs_aircon

# enable if your device has a swing mode
#    set_swing_mode:
#      - service: rest_command.upstairs_aircon_set_swing_mode
#        data:
#          swing_mode: "{{ swing_mode }}"
#      - delay: 2
#      - service: homeassistant.update_entity
#        entity_id: binary_sensor.swing_mode_upstairs_aircon
1 Like

nice job @gorstj why don’t we use secrets as well for the airco ip / airco mac?

Thank you! Works perfectly. The only remaining uncontrolled thing on my system is being able to choose a vertical angle for the airflow (when swing mode is not on)… I think I saw somewhere that is possible to control with the REST commands but can live without it.

I have a Unifi router and I have one or two units which keep associating but not joining IP. I will try the standalone network…

@ptruman have you looked at the following post for what someone tried who was having issues connecting with wifi?

https://community.home-assistant.io/t/fujitsu-air-conditioning-integration-airstage-dongle/589679/33?u=gorstj

1 Like

For controlling the direction when swing is off try adding this to the file in the rest_command section: (editing the relevant name, IP and MAC):

rest_command:
  airco_bedroom_direction:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_af_dir_vrt":"{{ direction }}"}}'

Then developer tools → service try the following YAML:

service: rest_command.upstairs_aircon_direction
data:
  direction: 1

(can try 1 to 4 for different directions).

The only way to integrate with the Climate IP template (GitHub - jcwillox/hass-template-climate: ❄️Templatable Climate Device for Home Assistant, Supports Running Actions On Service Calls.) would be to have it in the list of Swing modes which could either be “On” or “Position 1”…“Position 4”.

Should be quite simple to do (copy from other elements of the code) but as I can’t test it I don’t want to try!

Latest version of file which includes tweaks for swing control as as posted by @mow
Also added tip to use capitals for the MAC address

To-do: (volunteers?)

  • !secrets for IP address and MAC address (but not sure if this will make it simpler or not as additional file)
  • change swing control options from On/Off to being ‘On’ or ‘Position 1…4’ (need volunteer as I don’t have a device with swing control)
# Integration for Fujitsu wi-fi adapters that use Airstage app (n.b. will NOT work with the older/discontinued adapters that use FGLair app)
# See the HA Community thread https://community.home-assistant.io/t/fujitsu-air-conditioning-integration-airstage-dongle/589679
#
# 1) Install 'Climate Template' via the HACS integration manager https://github.com/jcwillox/hass-template-climate
# 2) Using 'Studio Code Server' from the HA add-ons store is useful
# 3) Use seach&replace funcitonality is useful!
# 4) Save this file as e.g. 'upstairs_aircon.yaml'. 
# 5) Place this file in the same folder as your configuration.yaml
# 6) Search & replace all '192.168.1.188' with the IP address of your aircon (assign a static IP to this device)
# 7) Search & replace all 'E8FB1CFF5FF5' with the MAC address of your aircon (use CAPITALS and do not put any : in the address)
# 8) Search & replace all instances of 'upstairs' with what you want to name the new aircon device (n.b. needs to be in lower case except where indicated)
# 9) Have a look through at # out sections to see if you want to enable
# 10) Add the following lines to your configuration.yaml (ensure it refers to the correct filename & you remove the #'s')
###############
#homeassistant:
#  packages:
#    pack_1: !include upstairs_aircon.yaml 
###############
#
# ***you will need to do a 'proper'' restart of HA rather than just a quick reload ***
#
# **swing mode is not tested as my device does not have that function** (please report back in the thread if it works)
# 
# Thanks to all the people in the aforemetnioned thread including @pietervanh @ravenland

rest_command:
  upstairs_aircon_setmode:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: >
      {% set aircomodes = {"auto": '"iu_op_mode":"0"',"cool": '"iu_op_mode":"1"',"dry": '"iu_op_mode":"2"',"fan_only": '"iu_op_mode":"3"',"heat": '"iu_op_mode":"4"',"off": '"iu_onoff":"0"'} %}
      {% set opmode = aircomodes.get(hvac_mode, 0) %}
      {"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{ {{opmode}} }} 
  upstairs_aircon_settemp:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: >
      {% set setroomtemp = (target_temp | float   * 10) | int %}
      {"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_set_tmp":"{{ setroomtemp }}"}}
  upstairs_aircon_set_fan_speed:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: >
      {% set fanspds = {"auto": 0, "Quiet": 2,"low": 5,"medium": 8,"high": 11} %}
      {% set spd = fanspds.get(fan_mode, 0) %}
      {"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_fan_spd":"{{ spd }}"}}

# enable if your device has a swing mode
#  upstairs_aircon_set_swing_mode:
#    url: http://192.168.1.188/SetParam
#    method: POST
#    payload: >
#      {% set mode = {"off": 0, "on": 1} %}
#      {% set swing = mode.get(swing_mode, 0) %}
#      {"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_af_swg_vrt":"{{ swing }}"}}
    
# not all units especially ducted have powerful mode. Powerful runs for a short period then stops
  upstairs_aircon_pwrfull_on:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_powerfull":"1"}}'
  upstairs_aircon_pwrfull_off:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_powerfull":"0"}}'

# these aren't used by the template but included for completion
  upstairs_aircon_on:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_onoff":"1"}}'
  upstairs_aircon_off:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_onoff":"0"}}'
  upstairs_aircon_eco_on:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_economy":"1"}}'
  upstairs_aircon_eco_off:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_economy":"0"}}'
  upstairs_aircon_fanctrl_on:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_fan_ctrl":"1"}}'
  upstairs_aircon_fanctrl_off:
    url: http://192.168.1.188/SetParam
    method: POST
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_fan_ctrl":"0"}}'

rest:
  - resource: http://192.168.1.188/GetParam
    scan_interval: 60
    payload: '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"03","list":["iu_set_tmp","iu_indoor_tmp","iu_outdoor_tmp","iu_onoff","iu_economy","iu_fan_ctrl","iu_fan_ctrl","iu_powerful","ou_low_noise","iu_op_mode","iu_fan_spd","iu_af_swg_vrt"]}'
    sensor:
      - name: "Temp Outside upstairs Aircon"
        value_template: "{{ (((value_json['value']['iu_outdoor_tmp'] | float  / 100 ) - 32 ) * 5/9) | round(2) }}"
        unit_of_measurement: "°C"
      - name: "Temp Inside upstairs Aircon"
        value_template: "{{ (((value_json['value']['iu_indoor_tmp'] | float  / 100 ) - 32 ) * 5/9) | round(2) }}"
        unit_of_measurement: "°C"
      - name: "Requested Temp upstairs Aircon"
        value_template: "{{ (value_json['value']['iu_set_tmp'] | float / 10 )| round(2) }}"
        unit_of_measurement: "°C"
      - name: "Mode upstairs Aircon"
        value_template: >
          {% set mapper ={'0': 'auto','1': 'cool','2': 'dry','3': 'fan_only','4': 'heat'} %}
          {% set state =  value_json['value']['iu_op_mode'] %}
          {{ mapper[state] if state in mapper else 'Unknown' }}
      - name: "Fan Speed Upstairs Aircon"
        value_template: >
          {% set mapper ={'0': 'auto','2': 'Quiet','5': 'low','8': 'medium','11': 'high'} %}
          {% set state =  value_json['value']['iu_fan_spd'] %}
          {{ mapper[state] if state in mapper else 'Unknown' }}
    binary_sensor:
      - name: "Power Status upstairs Aircon"
        value_template: "{{ (value_json['value']['iu_onoff']) }}"

# enable if your device has a swing mode
#      - name: "Swing Mode Upstairs Aircon"
#        value_template: >
#          {% set mapper ={'0': 'off','1': 'on'} %}
#          {% set state =  value_json['value']['iu_af_swg_vrt'] %}
#          {{ mapper[state] if state in mapper else 'Unknown' }}



climate:
  - platform: climate_template
# the name: can have capital letters if desired
    name: Upstairs Aircon
    modes: 
      - "auto"
      - "dry"
      - "off"
      - "cool"
      - "fan_only"
      - "heat"
    fan_modes:
      - "auto"
      - "Quiet"
      - "low"
      - "medium"
      - "high"

# enable if your device has a swing mode
#    swing_modes:
#      - "on"
#      - "off"

    min_temp: 15
    max_temp: 30

    current_temperature_template: "{{ states('sensor.temp_inside_upstairs_aircon') }}"

    hvac_mode_template: >
      {% if is_state('binary_sensor.power_status_upstairs_aircon', 'off') %}
        off
      {% else %}
        {{ states('sensor.mode_upstairs_aircon') }}
      {% endif %}
    
    target_temperature_template: "{{ states('sensor.requested_temp_upstairs_aircon') }}"
    
    fan_mode_template: "{{ states('sensor.fan_speed_upstairs_aircon') }}"

# enable if your device has a swing mode
#    swing_mode_template: "{{ states('binary_sensor.swing_mode_upstairs_aircon') }}"

    set_hvac_mode:
      - service: rest_command.upstairs_aircon_on
      - delay: 1
      - service: rest_command.upstairs_aircon_setmode
        data:
          hvac_mode: "{{ hvac_mode }}"
      - delay: 2
      - service: homeassistant.update_entity
        entity_id: sensor.mode_upstairs_aircon

    set_temperature:
      - service: rest_command.upstairs_aircon_settemp
        data:
          target_temp: "{{ temperature }}"
      - delay: 2
      - service: homeassistant.update_entity
        entity_id: sensor.requested_temp_upstairs_aircon

    set_fan_mode:
      - service: rest_command.upstairs_aircon_set_fan_speed
        data:
          fan_mode: "{{ fan_mode }}"
      - delay: 2
      - service: homeassistant.update_entity
        entity_id: sensor.fan_speed_upstairs_aircon

# enable if your device has a swing mode
#    set_swing_mode:
#      - service: rest_command.upstairs_aircon_set_swing_mode
#        data:
#          swing_mode: "{{ swing_mode }}"
#      - delay: 2
#      - service: homeassistant.update_entity
#        entity_id: binary_sensor.swing_mode_upstairs_aircon

I’ll give the swing position tweak a go later on.