This program implements the Ayla Networks LAN API to interact with HiSense WiFi Air Conditioner module, models AEH-W4B1 and AEH-W4E1.
As discussed here, the program doesn't seem to fit the AEH-W4A1 module, which relies on entirely different protocol (implemented by the apps Hi-Smart Life, AirConnect, Smart Cool, AC WIFI and טורנדו WiFi). Please let me know if you have a different experience, or tried it with other modules.
The module is installed in A/Cs and humidifiers that are either manufactured or only branded by many other companies. These include Beko, Westinghouse, Winia, Tornado, York and more.
This program is not affiliated with Ayla Networks, HiSense, any of it's subsidiaries, or any of its resellers.
-
Air Conditioner with HiSense AEH-W4B1 or AEH-W4E1 installed.
-
Have Python 3.7 installed. If using Raspberry Pi, either upgrade to Raspbian Buster, or manually install it in Raspbian Stretch.
-
Install additional libraries:
pip3.7 install dataclasses_json paho-mqtt pycryptodome
-
Configure the A/C with the dedicated app. Links to each app are available in the table below. Log into the app, associate the A/C and connect it to the network, as described in the app documentation.
-
Once everything has been configured, the A/C can be blocked from connecting to the internet, as it will no longer be needed. Set it a static IP address in the router, and write it down.
-
Download and run query_cli.py, to fetch the LAN keys that will allow connecting to the A/C. Pass it your login credentials, as well as the code for your app from the list below:
For example:
./query_cli.py --user foo@example.com --passwd my_pass --app tornado-us --config config.json
The CLI will generate a config file, that needs to be passed to the A/C control server below. If you have more than one A/C that you would like to control, create a separate config file for each A/C, and run a separate control process. You can select the A/C that the config is generated for by setting the
--device
flag to the device name you configured in the app.
- Download hisense.py.
- Test out that you can run the server, e.g.:
Parameters:
./hisense.py --port 8888 --ip 10.0.0.40 --config config.json --mqtt_host localhost
--port
or-p
- Port for the web server.--ip
- The IP address for the A/C.--config
- The config file with the credentials to connect to the A/C.--mqtt_host
- The MQTT broker hostname or IP address. Must be set to enable MQTT.--mqtt_port
- The MQTT broker port. Default is 1883.--mqtt_client_id
- The MQTT client ID. If not set, a random client ID will be generated.--mqtt_user
- <user:password> for the MQTT channel. If not set, no authentication is used.--mqtt_topic
- The MQTT root topic. Default is "hisense_ac". The server will listen on topic <{mqtt_topic}/command> and publish to <{mqtt_topic}/status>.--log_level
- The minimal log level to send to syslog. Default is WARNING.
- Access e.g. using curl:
curl -ik 'http://localhost:8888/hisense/status' curl -ik 'http://localhost:8888/hisense/command?property=t_power&value=ON'
- Create a dedicated directory for the script files, and move the files to it.
Pass the ownership to root. e.g.:
sudo mkdir /usr/lib/hisense sudo mv hisense.py config.json /usr/lib/hisense sudo chown root:root /usr/lib/hisense/*
- Create a service configuration file (as root), e.g.
/lib/systemd/system/hisense.service
:[Unit] Description=Hisense A/C server After=network.target [Service] ExecStart=/usr/bin/python3.7 -u hisense.py --port 8888 --ip 10.0.0.40 --config config.json --mqtt_host localhost WorkingDirectory=/usr/lib/hisense StandardOutput=inherit StandardError=inherit Restart=always [Install] WantedBy=multi-user.target
- Link to it from
/etc/systemd/system/
:sudo ln -s /lib/systemd/system/hisense.service /etc/systemd/system/multi-user.target.wants/hisense.service
- Enable and start the new service:
sudo systemctl enable hisense.service sudo systemctl start hisense.service
- If you use MQTT for HomeAssistant or openHAB, the broker should now provide the updated status of the A/C, and accepts commands.
Listed here are the properties available through the API:
Property | Read Only | Values | Comment |
---|---|---|---|
f_electricity | x | Integer | |
f_e_arkgrille | x | 0, 1 | |
f_e_incoiltemp | x | 0, 1 | |
f_e_incom | x | 0, 1 | |
f_e_indisplay | x | 0, 1 | |
f_e_ineeprom | x | 0, 1 | |
f_e_inele | x | 0, 1 | |
f_e_infanmotor | x | 0, 1 | |
f_e_inhumidity | x | 0, 1 | |
f_e_inkeys | x | 0, 1 | |
f_e_inlow | x | 0, 1 | |
f_e_intemp | x | 0, 1 | |
f_e_invzero | x | 0, 1 | |
f_e_outcoiltemp | x | 0, 1 | |
f_e_outeeprom | x | 0, 1 | |
f_e_outgastemp | x | 0, 1 | |
f_e_outmachine2 | x | 0, 1 | |
f_e_outmachine | x | 0, 1 | |
f_e_outtemp | x | 0, 1 | |
f_e_outtemplow | x | 0, 1 | |
f_e_push | x | 0, 1 | |
f_filterclean | x | 0, 1 | Does the filter require cleaning |
f_humidity | x | Integer | Relative humidity percent |
f_power_display | x | 0, 1 | |
f_temp_in | x | Decimal | Environment temperature in Fahrenheit |
f_voltage | x | Integer | |
t_backlight | ON, OFF | Turn the display on/off | |
t_device_info | 0, 1 | ||
t_display_power | 0, 1 | ||
t_eco | OFF, ON | Economy mode | |
t_fan_leftright | OFF, ON | Horizontal air flow | |
t_fan_mute | OFF, ON | Quite mode | |
t_fan_power | OFF, ON | Vertical air flow | |
t_fan_speed | AUTO, LOWER, LOW, MEDIUM, HIGH, HIGHER | Fan Speed | |
t_ftkt_start | Integer | ||
t_power | OFF, ON | Power | |
t_run_mode | OFF, ON | Double frequency | |
t_setmulti_value | Integer | ||
t_sleep | STOP, ONE, TWO, THREE, FOUR | Sleep mode | |
t_temp | Integer | Temperature in Fahrenheit | |
t_temptype | CELSIUS, FAHRENHEIT | Displayed temperature unit | |
t_temp_eight | OFF, ON | Eight heat mode | |
t_temp_heatcold | OFF, ON | Fast cool heat | |
t_work_mode | FAN, HEAT, COOL, DRY, AUTO | Work mode |
I have built a groovy script to enable SmartThings integration with the Air Conditioner, through the control server above. It currently implements the main functionality (turn on/off, AC mode, fan speed, dimmer etc.).
The groovy file is available here, for download and installation through the Groovy IDE. As I'm continuously improving this script, it would be more efficient to use the IDE's github integration, in order to stay up-to-date.