deiger / AirCon

Scripts for controlling Air Conditioners, e.g. with HiSense modules.
GNU General Public License v3.0
218 stars 58 forks source link

Request: support for FGLAir app #16

Open Jagohu opened 4 years ago

Jagohu commented 4 years ago

Hi,

I have been looking into controlling my Fujitsu air conditioners with wifi module from my RPI4 as well, and since I couldn't find anything what would work from either command-line or through my OpenHAB, I started to reverse-engineer it. I have sniffed some packets and it looks like the local_lan registration packets are the same as you have in your script. TEXT:

POST /local_reg.json HTTP/1.1
Accept: application/json
Connection: Keep-Alive
Content-Type: application/json
User-Agent: Dalvik/2.1.0 (Linux; U; Android 10; SM-G975F Build/QP1A.190711.020)
Host: 192.168.0.8
Accept-Encoding: gzip
Content-Length: 78

JSON:

{"local_reg":{"ip":"192.168.0.43","notify":0,"port":10275,"uri":"/local_lan"}}
HTTP/1.1 202 Accepted

I just don't know exactly how to add the app (FGLAir)'s server to your script, but I'd appreciate any help. When it comes to an internet connection, the FGLAir app tries to connect to 3.121.23.175:443 (ec2-3-121-23-175.eu-central-1.compute.amazonaws.com). Since the data is SSL-encrypted, I don't exactly know what or how is transmitted.

Thank you for your efforts!

deiger commented 4 years ago

Hi,

I've had a look at the app, and you're correct, it is using the same API. I'll add its keys to the CLI script.

Jagohu commented 4 years ago

Thank you very much!!

deiger commented 4 years ago

OK, added it, use fglair-eu as the app code for the CLI. Please lmk if it controls the AC properly, since the actual commands sometimes vary.

Jagohu commented 4 years ago
python3 /home/pi/opt/fujitsu/query_cli.py --user [email] --passwd [mypass] --app fglair-eu --config config.json
E0512 21:25:01.573  query_cli.py:152] Failed to login to Hisense server:
Status 401: 'Unauthorized'

any ideas what to do differently?

deiger commented 4 years ago

That's strange. I'm not seeing any reason for it not to work. Are you sure you entered the password correctly? Alternatively, you can install a sniffer like Packet Capture, on your phone, and set it to be a proxy with certificates. It will allow you to see the actual packets being sent on the SSL channel to the server.

Jagohu commented 4 years ago

Um, I have allowed Packet Capture to deal with certificates I think - in it's settings it says Status - Installed to trusted credentials. Is that what you meant? I still get empty SSL packets when I capture though.

deiger commented 4 years ago

It's likely that your phone's OS is too new, Google did a lot of tricks to prevent this MITM attack. If you have an old phone lying around, try running Packet Capture and the AC's app on it.

Jagohu commented 4 years ago

Hi,

Sorry, it took a while. I don't know what you changed in it, but now it works nicely for the query bit< got the ACs and their IPS nicely. Then when I try with python3 /home/pi/opt/fujitsu/hisense.py --config config.json --mqtt_host localhost --ip 192.168.0.11 --port 8888

I get this:

_192.168.0.11 - - [05/Jun/2020 08:46:20] "POST /local_lan/keyexchange.json HTTP/1.1" 404 -

In the system.log I find this: _Old ID was 47472; new ID is 3192. Jun 5 08:46:19 raspberrypi4 python3[11939]: E0605 08:46:19.995 hisense.py:572] The key_id has been replaced!! Old ID was 47472; new ID is 3192. Jun 5 08:46:20 raspberrypi4 python3[11939]: E0605 08:46:20.008 hisense.py:572] The keyid has been replaced!!

Do you have any idea what is going on or what should I do? Thank you!

deiger commented 4 years ago

This means that your config has the wrong ID for the AC. If you have more than one AC set up, could it be that you chose the wrong one when you ran the CLI? If you wish to control multiple ACs you need to create a separate config file for each one, I've detailed the process in the documentation.

Jagohu commented 4 years ago

Thank you!

How do I generate "separate" config files? I can't find any option to select for which device I'd like the config.json to be generated...

python3 /home/pi/opt/fujitsu/query_cli.py --user myusername@gmail.com --passwd mypassword --app fglair-eu --config config.json - this gave me this:

I0605 13:15:40.971 query_cli.py:196] Found devices: [{'device': {'product_name': 'AC000W002858698', 'model': 'AY001MTS1', 'dsn': 'AC000W002858698', 'oem_model': 'AP-WB2E', 'sw_version': 'bc 2.6.15-fgl 02/04/20 12:25:04 ID phunt/bf51432', 'template_id': 4904, 'mac': 'a0cc2beca01c', 'unique_hardware_id': None, 'hwsig': 'mac-a0cc2beca01c', 'lan_ip': '192.168.0.8', 'connected_at': '2020-05-15T12:12:49Z', 'key': 390149, 'lan_enabled': True, 'has_properties': True, 'product_class': 'demo', 'connection_status': 'Online', 'lat': '50xxx', 'lng': 'xxx', 'locality': 'xxxx', 'device_type': 'Wifi'}}, {'device': {'product_name': 'AC000W002818514', 'model': 'AY001MTS1', 'dsn': 'AC000W002818514', 'oem_model': 'AP-WB2E', 'sw_version': 'bc 2.6.15-fgl 02/04/20 12:25:04 ID phunt/bf51432', 'template_id': 4904, 'mac': 'a0cc2bec460c', 'unique_hardware_id': None, 'hwsig': 'mac-a0cc2bec460c', 'lan_ip': '192.168.0.9', 'connected_at': '2020-05-15T12:12:56Z', 'key': 390695, 'lan_enabled': True, 'has_properties': True, 'product_class': 'demo', 'connection_status': 'Online', 'lat': '50.xxx', 'lng': '5.xx', 'locality': 'xxx', 'device_type': 'Wifi'}}, {'device': {'product_name': 'AC000W002858699', 'model': 'AY001MTS1', 'dsn': 'AC000W002858699', 'oem_model': 'AP-WB2E', 'sw_version': 'bc 2.6.15-fgl 02/04/20 12:25:04 ID phunt/bf51432', 'template_id': 4904, 'mac': 'a0cc2bec113a', 'unique_hardware_id': None, 'hwsig': 'mac-a0cc2bec113a', 'lan_ip': '192.168.0.11', 'connected_at': '2020-05-15T12:12:59Z', 'key': 391402, 'lan_enabled': True, 'has_properties': True, 'product_class': 'demo', 'connection_status': 'Online', 'lat': '50.xxx', 'lng': 'xxx', 'locality': 'xxxx', 'device_type': 'Wifi'}}]

Additonally I got a file /root/config.json which doesn't mention which device it is for, plus the test_token.cache. What should I be looking for? Sorry, went through the documentation but couldn't figure it out.

deiger commented 4 years ago

Use e.g. --device AC000W002858699 to choose the third device. Store the generated config file in a separate location. Then follow this paragraph to create the separate services. If you do not set the device argument, the tool defaults to the first one on the list.

Jagohu commented 4 years ago

Okay, thanks - I think I did that and now it's different - It seems like it's running and with a curl I can get the statuses. However if I do the curl -ik 'http://localhost:8888/hisense/command?property=t_power&value=ON', or post "ON" to topic _hisense_ac/tpower/command I get the acknowledgement, but nothing happens with the airco. It is shown in the status with the curl or I can see "on" in the topic hisense_ac/t_power/status getting published, but the airco doesn't do anything.

curl -ik 'http://localhost:8888/hisense/status'

HTTP/1.0 200 OK
Server: BaseHTTP/0.6 Python/3.7.3
Date: Fri, 05 Jun 2020 16:46:23 GMT
Content-type: application/json

{"f_electricity": 100, "f_e_arkgrille": 0, "f_e_incoiltemp": 0, "f_e_incom": 0, "f_e_indisplay": 0, "f_e_ineeprom": 0, "f_e_inele": 0, "f_e_infanmotor": 0, "f_e_inhumidity": 0, "f_e_inkeys": 0, "f_e_inlow": 0, "f_e_intemp": 0, "f_e_invzero": 0, "f_e_outcoiltemp": 0, "f_e_outeeprom": 0, "f_e_outgastemp": 0, "f_e_outmachine2": 0, "f_e_outmachine": 0, "f_e_outtemp": 0, "f_e_outtemplow": 0, "f_e_push": 0, "f_filterclean": 0, "f_humidity": 50, "f_power_display": 0, "f_temp_in": 81.0, "f_voltage": 0, "t_backlight": "OFF", "t_control_value": null, "t_device_info": 0, "t_display_power": null, "t_eco": "OFF", "t_fan_leftright": "OFF", "t_fan_mute": "OFF", "t_fan_power": "OFF", "t_fan_speed": "AUTO", "t_ftkt_start": null, "t_power": "ON", "t_run_mode": "OFF", "t_setmulti_value": null, "t_sleep": "STOP", "t_temp": 81, "t_temptype": "FAHRENHEIT", "t_temp_eight": "OFF", "t_temp_heatcold": "OFF", "t_work_mode": "AUTO"}

python3 /home/pi/opt/fujitsu/hisense.py --config configliving.json --mqtt_host localhost --ip 192.168.0.8 --port 8888 I do have this for about 30 times upon starting the script:

192.168.0.8 - - [05/Jun/2020 18:58:49] "GET /local_lan/commands.json HTTP/1.1" 200 -
192.168.0.8 - - [05/Jun/2020 18:58:49] "POST /local_lan/property/datapoint.json?cmd_id=44&status=500 HTTP/1.1" 404 -
deiger commented 4 years ago

OK, as I suspected, the protocol is the same, but the parameters are entirely different. This is the list of parameters supported by your ACs (AP-WB2E): operation_mode, fan_speed, adjust_temperature, af_vertical_move_step1, af_horizontal_move_step1, economy_mode, master_timer_on_off_1, master_timer_on_off_2, error_code, demand_control, filter_sign_reset_display, op_status, device_name, building_name, wifi_led_enable, service_contact_name, service_contact_phone, service_contact_email, device_capabilities, refresh And I don't yet have a value type (including enums) for each...

Jagohu commented 4 years ago

Hi, Thanks, okay. I've tried to send commands with these parameters, but it says "Bad request". Let me know please when you have time to have a look at it :)

deiger commented 4 years ago

OK, try it out with --device_type fgl_b. There might be more parameters you're interested in, please let me know.

Jagohu commented 4 years ago

Awesome, you're great man. It works! This is what I get back on a status curl:

HTTP/1.0 200 OK
Server: BaseHTTP/0.6 Python/3.7.3
Date: Mon, 08 Jun 2020 09:01:25 GMT
Content-type: application/json

{"operation_mode": "OFF", "fan_speed": "AUTO", "adjust_temperature": 210, "af_vertical_move_step1": 0, "af_horizontal_move_step1": 0, "economy_mode": "OFF"}

This also works

curl -ik 'http://localhost:8888/hisense/command?property=operation_mode&value=ON'
curl -ik 'http://localhost:8888/hisense/command?property=operation_mode&value=OFF'
curl -ik 'http://localhost:8888/hisense/command?property=adjust_temperature&value=220'

Temperature is in Celsius*10 -> 22=220 - I suppose you could give 225 to get 22.5 but haven't tried it yet. Operating Modes: "COOL", "DRY", "HEAT", "AUTO", "FAN" Fan speeds: "QUIET", "LOW", "MEDIUM", "HIGH", "AUTO"

Again, thank you very much!!

Jagohu commented 4 years ago

I have created a guide for OpenHAB integration of your script, I hope you don't mind - it's referring to your github page and again, BIG THANKS for all your work!

https://community.openhab.org/t/anyone-using-intesishome-wifi-control-of-mini-split-ac/11031/76?u=jagohu

deiger commented 4 years ago

Sure thing, you're most welcome. If you have an OpenHAB configuration, I can add it as a file here (like I did for Home Assistant and SmartThings).

Corne008 commented 3 years ago

Hi, I have about the same issue.... but fgl_b doesn't resolve my problem ;-) Our Fijutsi UTY-TFSXW1 WiFi module returns

HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Content-Length: 205 Date: Fri, 01 Jan 2021 18:45:42 GMT Server: Python/3.7 aiohttp/3.6.2

{"devices": [{"ip": "192.168.2.107", "props": {"operation_mode": "OFF", "fan_speed": "AUTO", "adjust_temperature": 210, "af_vertical_move_step1": 3, "af_horizontal_move_step1": 3, "economy_mode": "OFF"}}]}

with the command: curl -ik 'http://192.168.2.252:10000/hisense/status'

with the curl -ik 'http://192.168.2.252:10000/hisense/command?property=operation_mode&value=ON' the output is 'Bad Request'. HTTP/1.1 400 Bad Request Content-Type: text/plain; charset=utf-8 Content-Length: 16 Date: Fri, 01 Jan 2021 18:45:53 GMT Server: Python/3.7 aiohttp/3.6.2

Using the remote control to turn the AC on the MQTT message is "hisense_ac/a0cc2bf0xxxxx/operation_mode/status auto"

Any idea if it is possible to control the AC using curl or mosquitto_pub?

Thanx...

acansmart commented 3 years ago

Sure thing, you're most welcome. If you have an OpenHAB configuration, I can add it as a file here (like I did for Home Assistant and SmartThings).

Do you have the Home Assistant configuration available ? It says Page Not Found in github. Thanks

deiger commented 3 years ago

Sure thing, you're most welcome. If you have an OpenHAB configuration, I can add it as a file here (like I did for Home Assistant and SmartThings).

Do you have the Home Assistant configuration available ? It says Page Not Found in github. Thanks

I've recently deleted it, as now the configuration is published through MQTT discovery, rendering it redundant. You can still find it here.

deiger commented 3 years ago

Hi, I have about the same issue.... but fgl_b doesn't resolve my problem ;-) Our Fijutsi UTY-TFSXW1 WiFi module returns

HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Content-Length: 205 Date: Fri, 01 Jan 2021 18:45:42 GMT Server: Python/3.7 aiohttp/3.6.2

{"devices": [{"ip": "192.168.2.107", "props": {"operation_mode": "OFF", "fan_speed": "AUTO", "adjust_temperature": 210, "af_vertical_move_step1": 3, "af_horizontal_move_step1": 3, "economy_mode": "OFF"}}]}

with the command: curl -ik 'http://192.168.2.252:10000/hisense/status'

with the curl -ik 'http://192.168.2.252:10000/hisense/command?property=operation_mode&value=ON' the output is 'Bad Request'. HTTP/1.1 400 Bad Request Content-Type: text/plain; charset=utf-8 Content-Length: 16 Date: Fri, 01 Jan 2021 18:45:53 GMT Server: Python/3.7 aiohttp/3.6.2

Using the remote control to turn the AC on the MQTT message is "hisense_ac/a0cc2bf0xxxxx/operation_mode/status auto"

Any idea if it is possible to control the AC using curl or mosquitto_pub?

Thanx...

It is possible, through both MQTT and curl. In curl you need to pass the property name as specified here. The MQTT setup is according to HomeAssistant's spec, detailed here.