Fujitsu Air Conditioning integration - Airstage dongle

It doesn’t matter.
Basically sending the exact same command I sniffed from wshark.
Even with complete same header as the iOS app uses.

Ok I have it working, and I am actually an idiot, it was malformed JSON, so that is at least consistent with eh WH3E module. I have just got it to return the query data. Granted it is giving me temps in Fahrenheit rather than Celsius but it is indeed a start.

So I wonder if it is due to module differences that it is not working.

Well that’s weird… Not sure if there is any special provisioning going on while connecting them via Airstage the first time but in my case there was just the normal onboarding workflow.
Btw we were not able to connect them via FGLair neither on iOS nor Android due to a broken workflow. Did you previously connect them to FGLair or is some other kind of lock present? Do they have an open webserver on 80?

Never tried FGLair.
Both my Airco’s have also WH3E in the SSID name. So I presume also a WH3E module.

Oh my I got a reply. I have 2 units. And I’m blind so I mixed up the macaddresses.
Thunderclient in VS Code didn’t work but the curl command from vs code terminal on ha works.
Both my airco’s under full control now.
Now going to try to set it up with the following integrations RESTful Sensor - Home Assistant
RESTful Command - Home Assistant



sensor:
  - platform: rest
    scan_interval: 60
    name: airco_living_temp
    resource: http://aircoip/GetParams
    method: POST
    payload: '{"device_id":"deviceid","device_sub_id":0,"req_id":"","modified_by":"","set_level":"03","list":["iu_indoor_tmp"]}'
    value_template: "{{ value_json['value']['iu_indoor_tmp'] }}"
    unit_of_measurement: "°F"

rest_command:
  airco_on:
    url: http://aircoip/SetParam
    method: POST
    payload: '{"device_id":"deviceid","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_onoff":"1"}}'
  airco_off:
    url: http://aircoip/SetParam
    method: POST
    payload: '{"device_id":"deviceid","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_onoff":"0"}}'

Works great not the nicest setup but it’s late and it works for now…

The SetTemp is in Celcius * 10
The Inside and Outside Temp /100 are in Farenheit

See post below with more fullfledged example

2 Likes

Anyways you get pretty far already with standard rest integration and some scripts and conditional cards

configuration.yaml just paste at bottom and offcourse replace the AIRCOIP and AIRCOMAC in the copied text → restart HA after for configuration to take

rest_command:
  airco_bedroom_on:
    url: http://aircoip/SetParam
    method: POST
    payload: '{"device_id":"aircomac","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_onoff":"1"}}'
  airco_bedroom_off:
    url: http://aircoip/SetParam
    method: POST
    payload: '{"device_id":"aircomac","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_onoff":"0"}}'
  airco_bedroom_eco_on:
    url: http://aircoip/SetParam
    method: POST
    payload: '{"device_id":"aircomac","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_economy":"1"}}'
  airco_bedroom_eco_off:
    url: http://aircoip/SetParam
    method: POST
    payload: '{"device_id":"aircomac","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_economy":"0"}}'
  airco_bedroom_fanctrl_on:
    url: http://aircoip/SetParam
    method: POST
    payload: '{"device_id":"aircomac","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_fan_ctrl":"1"}}'
  airco_bedroom_fanctrl_off:
    url: http://aircoip/SetParam
    method: POST
    payload: '{"device_id":"aircomac","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_fan_ctrl":"0"}}'
  airco_bedroom_pwrfull_on:
    url: http://aircoip/SetParam
    method: POST
    payload: '{"device_id":"aircomac","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_powerfull":"1"}}'
  airco_bedroom_pwrfull_off:
    url: http://aircoip/SetParam
    method: POST
    payload: '{"device_id":"aircomac","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_powerfull":"0"}}'
  airco_bedroom_set_temp:
    url: http://aircoip/SetParam
    method: POST
    payload: >
      {% set bedroomtemp = (states('input_number.setaircotempbedroom') | float  * 10) | int %}
      {"device_id":"aircomac","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_set_tmp":"{{ bedroomtemp }}"}}
  airco_bedroom_setmode:
    url: http://aircoip/SetParam
    method: POST
    payload: >
      {% set aircomodes = {"Auto": 0, "Cooling": 1,"Dry": 2,"Fan": 3,"Heating": 4} %}
      {% set opmode = aircomodes[states('input_select.setaircoopmodebedroom')]  %}
      {"device_id":"aircomac","device_sub_id":0,"req_id":"","modified_by":"","set_level":"02","value":{"iu_op_mode":"{{ opmode }}"}}
  

rest:
  - resource: http://aircoip/GetParam
    scan_interval: 60
    payload: '{"device_id":"aircomac","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"]}'
    binary_sensor:
      - name: "Airco Bedroom On"
        value_template: "{{ value_json['value']['iu_onoff'] }}"
      - name: "Airco Bedroom Economy"
        value_template: "{{ value_json['value']['iu_economy'] }}"
        icon: mdi:leaf
      - name: "Airco Bedroom Fan Control"
        value_template: "{{ value_json['value']['iu_fan_ctrl'] }}"
        icon: mdi:fan
      - name: "Airco Bedroom Powerfull"
        value_template: "{{ value_json['value']['iu_powerful'] }}"
        icon: mdi:fan-plus
      - name: "Airco Bedroom Low Noise"
        value_template: "{{ value_json['value']['ou_low_noise'] }}"
        icon: mdi:sleep
    sensor:
      - name: "Temp Outside Airco Bedroom"
        value_template: "{{ (((value_json['value']['iu_outdoor_tmp'] | float  / 100 ) - 32 ) * 5/9) | round(2) }}"
        unit_of_measurement: "°C"
      - name: "Temp Inside Airco Bedroom"
        value_template: "{{ (((value_json['value']['iu_indoor_tmp'] | float  / 100 ) - 32 ) * 5/9) | round(2) }}"
        unit_of_measurement: "°C"
      - name: "Requested Temp Airco Bedroom"
        value_template: "{{ (value_json['value']['iu_set_tmp'] | float / 10 )| round(2) }}"
        unit_of_measurement: "°C"

Scripts ( Settings > Automations & Scenes > Scripts) Add 2 scripts and paste the 2 scripts yaml

alias: Turn On Airco Bedroom
sequence:
  - service: rest_command.airco_bedroom_on
    data: {}
  - service: homeassistant.update_entity
    data: {}
    target:
      entity_id: binary_sensor.airco_bedroom_on
mode: single
icon: mdi:air-conditioner

alias: Turn Off Airco Bedroom
sequence:
  - service: rest_command.airco_bedroom_off
    data: {}
  - service: homeassistant.update_entity
    data: {}
    target:
      entity_id: binary_sensor.airco_bedroom_on
mode: single
icon: mdi:air-conditioner

Dashboard on / off button
image

Paste in yaml in a new manual card replace code with below

square: true
type: grid
cards:
  - type: conditional
    conditions:
      - entity: binary_sensor.airco_bedroom_on
        state: 'off'
    card:
      show_name: true
      show_icon: true
      type: button
      tap_action:
        action: call-service
        service: script.turn_on_airco_bedroom
        target: {}
      hold_action:
        action: none
      icon: mdi:air-conditioner
      name: Airco
      show_state: false
      entity: binary_sensor.airco_bedroom_on
  - type: conditional
    conditions:
      - entity: binary_sensor.airco_bedroom_on
        state: 'on'
    card:
      show_name: true
      show_icon: true
      type: button
      tap_action:
        action: call-service
        service: script.turn_off_airco_bedroom
        target: {}
      hold_action:
        action: none
      icon: mdi:air-conditioner
      name: Airco
      show_state: false
      entity: binary_sensor.airco_bedroom_on
columns: 4

Automation to update requested Temperature based on helper:
Create Helper under Settings > Devices and Entities > Helpers > Create helper


Input Helper for the dropdown to change mode

Automation , create 2 automations in gui and paste the yaml

alias: Airco bedroom temp Update
description: ""
trigger:
  - platform: state
    entity_id:
      - input_number.setaircotempbedroom
condition: []
action:
  - service: rest_command.airco_bedroom_set_temp
    data: {}
  - service: homeassistant.update_entity
    data: {}
    target:
      entity_id: sensor.requested_temp_airco_bedroom
mode: single

alias: Airco bedroom mode change
description: ""
trigger:
  - platform: state
    entity_id:
      - input_select.setaircoopmodebedroom
condition: []
action:
  - service: rest_command.airco_bedroom_setmode
    data: {}
  - service: homeassistant.update_entity
    data: {}
    target:
      entity_id: sensor.requested_temp_airco_bedroom
mode: single


image

4 Likes

This is looking great, I am working on a NodeRed setup with taking HTTP POST and translating them to MQTT. I have had powerful and eco working fine here. What I am getting is a disparity between the temperatures reported by the app and what the HTTP POST is returning. Are you experiencing the same? It’s about 1 deg c out, but not sure that is consistent.

3 Likes

Can you share the requests for enabling disabling powerful mode and setting the temperature?
About temparature difference between app and post have not checked.
But the temparature from the http post seems quite in line with the other temp sensors I have in the same room.

1 Like

Sure.

The payload I use for setting the temp is.

{
        device_id:"DEVICEID",
        device_sub_id:0,
        req_id:"",
        modified_by:"",
        set_level:"02",
        value: {
                iu_set_tmp: "TEMPVAL"
            }
}

The payload for powerful is

{
        device_id:"DEVICEID",
        device_sub_id:0,
        req_id:"",
        modified_by:"",
        set_level:"02",
        value: {
                iu_powerful: "0 or 1"
            }
}

Hmm ok so maybe the reported temps are right and the app is wrong, I will measure with a probe and check.

Edit: Further thought, you can only set powerful when the aircon is on. A quirk of the system, but you can set eco if it is on or off. I suspect this is bug.

Massive progress been made here!

I will have some time Saturday evening to debug with a Mac if there are any other API commands that need checking.

Let me know a lisr

Guys, sorry for posting this somehow offtopic question. I do have 5 new ACs with airstage dongle “WH3E” as mentioned earlier. I tried to install 2 of the devices and I can get them connected to the wireless router, however the app is crashing during the cloud registration process every time on any of my 3 iOS devices. Did you encounter any such issues? I searched the internet, but I can not find any hints. Interestingly I can add a device in local mode to the app.
Actually I like to hook them all in my home assistant system. so I’m eagerly following this thread and I’m also willing to contribute as soon as I get the decives running.

Worked first time for me using the iOS app an an iPhone 14.
You can load the app on a Mac laptop (search on the app store) - maybe that will work better?

How is it crashing? Timeout? or exits?
Is it a 2.4ghz vs 5ghz wifi issue? (the dongle will only connect to 2.4ghz)

There appears something wrong with the temperature conversion

My app currently says:
Indoor: 22c
Outdoor: 16c

In HA it is saying:
Indoor: 22.36
Outdoor: 18.89

Using Curl on the command line I get:

curl -vv -X POST --data '{"device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"03","list":["iu_wifi_led","iu_af_inc_hrz","iu_af_inc_vrt","iu_indoor_tmp","iu_outdoor_tmp","iu_hmn_det","iu_main_ver","iu_eep_ver","iu_has_upd_main","iu_has_upd_eep","iu_fld_set80"]}' 'http://192.168.1.187/GetParam'

{"value":{"iu_wifi_led":"65535","iu_af_inc_hrz":"0","iu_af_inc_vrt":"0","iu_indoor_tmp":"7225","iu_outdoor_tmp":"6600","iu_hmn_det":"0","iu_main_ver":"","iu_eep_ver":"","iu_has_upd_main":"65535","iu_has_upd_eep":"65535","iu_fld_set80":"65535"},"read_res":"ack","device_id":"E8FB1CFF5FF5","device_sub_id":0,"req_id":"","modified_by":"","set_level":"03","cause":"","result":"OK","error":""}

I have an iPhone 12. The crash happens directly after I press the button to start the registration after the wireless connetion. The AC stays connected with the router, but the app crashes immediatly. there is this progress bar with the 3 dots and it just is gone - no timeout, no error report. My eero router tells me it is properly connected to the nearest AP @ 2,5GHz. I’m wondering if I should try to use a different country in the setup…
I will try the app on the MAC now…

If it is connected to your wifi then try the curl command in my last post (substituting your IP address and MAC address) to see if you can interact with it without registering with the app.

If we get a decent HA integration you may not need the airstage app!

@gorstj
ok now I managed to send the correct command with MAC and IP address. And it seems to work fine. Here is the result:

curl -vv -X POST --data '{"device_id":"505A6550B005","device_sub_id":0,"req_id":"","modified_by":"","set_level":"03","list":["iu_wifi_led","iu_af_inc_hrz","iu_af_inc_vrt","iu_indoor_tmp","iu_outdoor_tmp","iu_hmn_det","iu_main_ver","iu_eep_ver","iu_has_upd_main","iu_has_upd_eep","iu_fld_set80"]}' 'http://192.168.5.65/GetParam'
Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 192.168.5.65:80...
* Connected to 192.168.5.65 (192.168.5.65) port 80 (#0)
> POST /GetParam HTTP/1.1
> Host: 192.168.5.65
> User-Agent: curl/7.88.1
> Accept: */*
> Content-Length: 270
> Content-Type: application/x-www-form-urlencoded
> 
< HTTP/1.1 200 OK
< Content-Type: application/json
< Content-Length: 406
< 
* Connection #0 to host 192.168.5.65 left intact
{"value":{"iu_wifi_led":"1","iu_af_inc_hrz":"0","iu_af_inc_vrt":"4","iu_indoor_tmp":"7200","iu_outdoor_tmp":"6600","iu_hmn_det":"0","iu_main_ver":"E101V03P00L02-1","iu_eep_ver":"E000V02P00L01-1","iu_has_upd_main":"1","iu_has_upd_eep":"1","iu_fld_set80":"65535"},"read_res":"ack","device_id":"505A6550B005","device_sub_id":0,"req_id":"","modified_by":"","set_level":"03","cause":"","result":"OK","error":""}%   

Great news.
Now we just need a full on integration!
I’m going to try but I’m a hopeless dabbler in programming!

1 Like

Yes! I’m also not the best one, but I can try helping or debugging. I also have some friends I might be able to activate. I tried some other CURL commands as well I found in this post and I can start/stop the AC as well.

Actually you don’t need the app at all.
Installation Flow:
Connect to the local Airco WIFI with a device.
Find out the Airco IP
Open browser and fill in http://aircoipaddress/aplist?lang=0
Select the local WIFI network you want to join + give in password.
Then the Airco joins your local wifi network.
Find out local ip of the airco that is joined to your wifi network.
Then you can use the rest integration stuff I posted (where you replace it with your airco ip offcourse) and most of it should work.

2 Likes

Yeah no clue on the temperature conversion. I just assumed it was Farenheit * 1000…