Toshiba home AC control

I have a multisplit outdoor unit with 3 indoor units, Each AC has a module, it also looks like the WiFi modules are ESP based so maybe its also possible to flash them with a custom firmware in the future

I do have the same AC (with the wireless adapter) and I am having the same problem. Therefore I tried to reverse-engineer the app.

I started by downloading the APK from https://apkpure.com/toshiba-home-ac-control/com.toshibatctc.SmartAC/versions - I used the oldest version as it was the smallest and so I assumed was the easiest to start with.
The APK is basically a zip file that holds the android application - usually a .tex file where the java code needs to be extracted. In this case the app uses assemblies - meaning there are like 100 .dll files that are used as a library.
Those can be easily copied and looked into using tools like ILSpy (Releases · icsharpcode/ILSpy · GitHub) or dnSpy (Releases · dnSpy/dnSpy · GitHub).
I noted that there is a SmartAC.dll which seems to handle most of the logic and the communication of the app.
In this dll I also found out about the propertyStore on the phone which holds some mapping information about the connected ACs (see later).

Here are my findings so far:

The app uses two interfaces:

  1. a normal HTTP API to get the current state of the AC and stuff like pairing and programmSettings
  2. a MQTT (or better an AMQPS) interface to update the current state (like change temperature or modes)

I made a small PHP script that is able to connect to the HTTP API and get some basic informations - see here: Toshiba AC API Client - Get status and settings from Toshiba AC Services (used e.g. in RAS-18PKVSG-E + RAS-18PAVSG-E + WIFI Adapter RB-N103S-G) · GitHub

The the problem with the AMQPS interface is, that I can’t find a working client. I tried it with py-amqp without success.

The AMQPS connection seems to be opened to:
amqps://toshibasmaciothubprod.azure-devices.net:5671/devices/XXXXX/messages/events

whereas XXXXX is your deviceId.

I have extract that part directly from my phone propertyStore using adb.
basically you install android studio, connect your phone to your PC, start the app, start the debugger and run:

adb shell
su
cat /data/user/0/com.toshibatctc.SmartAC/files/.config/.isolated-storage/PropertyStore.forms

this did work for me on a non-rooted phone and gave me an output similar to this:

@ArrayOfKeyValueOfstringanyTyp9http://schemas.microsoft.com/2003/10/Serialization/Arrays       i)http://www.w3.org/2001/XMLSchema-instance@KeyValueOfstringanyType@
  Key�[email protected]:string    a http://www.w3.org/2001/XMLSchema�en@KeyValueOfstringanyType@
  [email protected]:string  a http://www.w3.org/2001/XMLSchemaXXXXXXX@KeyValueOfstringanyType@
  Key�[email protected]:string a http://www.w3.org/2001/XMLSchema�$5XXXXXXX3@KeyValueOfstringanyType@
  Key�[email protected]:string a http://www.w3.org/2001/XMLSchema�@4XXXXb@KeyValueOfstringanyType@
  Key�   [email protected]�a:int a http://www.w3.org/2001/XMLSchema�@KeyValueOfstringanyType@
  Key�[email protected]�
a:dateTime      a http://www.w3.org/2001/XMLSchema�>�
ݼ\I@KeyValueOfstringanyType@
  Key�[email protected]�a:base64Binary     a http://www.w3.org/2001/XMLSchema�xxx@KeyValueOfstringanyType@
  [email protected]:string    a http://www.w3.org/2001/XMLSchema�'toshibasmaciothubprod.azure-devices.net@KeyValueOfstringanyType@
  [email protected]:string        a http://www.w3.org/2001/XMLSchema�pxxxb@KeyValueOfstringanyType@
  Key�[email protected]:string     a http://www.w3.org/2001/XMLSchema�,oxx8=

From here I extracted:

  • the UserName
  • a ConsumerID (which is the same when using the HTTP API)
  • the HostName: toshibasmaciothubprod.azure-devices.net (which differs from the http api)
  • my DeviceID (which included my Username and is used for the amqps connection)
  • and a SharedAceeskey (yes it has this typo)

Using another APP (Packet Capture https://play.google.com/store/apps/details?id=app.greyshirts.sslcapture&hl=en_US&gl=US) I was able to read out the communication from the app to the server - unfortunatelly this amqps seems to be some kind of binary protocol and a single on/off request, results in multible queue entries like this:

[RANDOMBYTES]
IoThub-methodname: smmobile
{"sourceId":"4xx8","messageId":"0000000a68","targetId":["pxxxA"],"cmd":"CMD_FCU_FROM_AC","payload":{"data":"ffffffff31ffffffffffffffffffffffffffff"},"timeStamp":"0060dce13c"}
[MORERANDOMBYTES]

So far I found out that data is just a string of all attributes as 2-byte hex-values concationated - where ff means that it did not change. Position 9+10 - like above - is reserved for the air swing mode and 31 means its off. 41 would swing it vertically.
In the HTTP API this data/payload is named ACStateDataForProgram - in my example it has the value: 31421a3131640010197ffe0b00001002010000 - 31 … means currently off, 42 … is cooling mode, 1a … is hex for 26 degrees target temperature and so on…

So - I really hope someone with more experience using amqps will pick it up from here and we can somehow get a working integration out of this.

5 Likes

very interesting discovery, I will try your script on my installation asap
this works very well, putting out some information

because I wanted to have the firmware I have postponed the firmware update since the airco’s got installed, I’ve now managed to get the firmware with help of your script, in the file there are some mentions of MQTT, I will report back when I have better information

I’ve dumped the firmwarefile ota_0000_3201.bin onto wetransfer if it is of any interest for you: https://we.tl/t-LqWN1ULlme
fyi I have the Toshiba RB-N104S-G, it seems to be based on Realtek Ameba RTL8195A platform

1 Like

I started to port the script to python and prepare a home-assistant integration:

(currently only the example.py works - the rest is scaffolded from home-assistant)

the plan is to use the daily scheduler to send start and stop events to the AC unit. this may not be the best (or even the right) way, but until someone figures out how to do it correctly this could be sufficient.

foreseeable downsides:

  • the device will not react immediatly to any changes - it will be necessary to post status updates with at least one minute (probably more) lead time.
  • you will not be able to use the scheduler as intended, due to the updates made to it.

I just stumbled over this thread. :slight_smile:

I’m not an owner of a Toshiba unit, but in another corner here in this forum, there is a group of people working on an ESPHome component for Midea A/Cs. :slight_smile: As we started to put a list of all manufacturers (label) together, I noticed that someone is using the ESPHome component for Midea in combination with a Toshiba A/C.

Would someone of you check, if your A/Cs would work with this component? Maybe there is already a working component for the integration in HA. :slight_smile:

Here is the thread with some pics and instructions:

And here is the thread with the list of working devices:

1 Like

Hello everyone, i also got a ras-b13n4kvrg-e installed today, unfortunately my dad bought the wrong model so now i’m stuck with this smartish yet stilish AC.
Anyway i’ve got the app up and running on a rooted phone if it can be of any help (especially to @h4de5).
I also setup the google home link, but it’s very embarassing, it exposes only the on/off status to google home :face_with_raised_eyebrow:
I even tried @h4de5’s example.py and it works flawlessly.

All this to say that I, my AC and my phone are at your disposal!

What kind of wifi-module is in the A/C?
if it is a OSK-102 or OSK-103 probably the ESPhome solution would work for you, as i noticed two other Toshibe A/C’s are confirmed working allready😉

It does require some diy work, but it is not difficult, and would cost around €7.50

Unfortunately my model has integrated wifi module and no port USB at all and also no reachable serial without voiding the warranty, so the cloud-interfacing option is the only way in my case.

Unfortunately I’m in the same boat with my Toshiba Haori, which also has the integrated wifi module :expressionless:

1 Like

I’ve opened the AC and the module is a WRE-T00BJ10, it has no USB at all but a 6pin connector with just 4 wires connected to it. Any guesses?

Hard to guess…
might be +5v / tx / tx / gnd but could be anything….

a small update here:

I added some more example code. it is possible to update the scheduler now.

Beware: the example code will reset the program for the current day, activate all ACs for 5 minutes and turn them off again afterwards.

the updated program is also shown within the app, but, at least mine, is not turned on automatically yet.

Hello Everyone,

My first time on this forum.

I have set up a Toshiba AC system with this wifi controlled system you are talking about, in our offices.

However i have trouble connecting the module to our wifi network, as we have a firewall that prevents all “foreign” connections. My IT department is asking me what web port have they got to open to make it work?

I’ve been frantically searching online and haven’t found any hope… until i came across this forum.

Anyone coud help me on that one?

Thanks a lot.

hello and welcome.
the wifi adapter is making an connection to the outside: 51.144.118.31 to port 8883 and uses a tls encrypted amqp protocol.
your app is also connecting to that server, so normally no direct connection is necessary. unless maybe during pairing. if the company wifi is too restrictive i would take a second mobile phone open an wifi hotspot with the same credentials and do the initial pairing there.

good luck.

hello
the code should be used in home assistant or separately?
how does it work?

@h4de5 I have digged a bit into AMQP connection. I’ve managed to capture some decrypted communication in wireshark (with mitmproxy) but it stops working when establishing AMQP communication. It seems like we have multiple levels of encapsulation. Firts TLS connection is established with toshibasmaciothubprod.azure-devices.net, then websocket is created:

Hypertext Transfer Protocol
    GET /$iothub/websocket HTTP/1.1\r\n
    Host: toshibasmaciothubprod.azure-devices.net:443\r\n
    Connection: Upgrade\r\n
    Upgrade: websocket\r\n
    Sec-WebSocket-Version: 13\r\n
    Sec-WebSocket-Key: ######
    Sec-WebSocket-Protocol: AMQPWSB10\r\n
    \r\n
    [Full request URI: https://toshibasmaciothubprod.azure-devices.net:443/$iothub/websocket]
    [HTTP request 1/1]
    [Response in frame: 1822]

Server accepts websocket communication:

Hypertext Transfer Protocol
    HTTP/1.1 101 Switching Protocols\r\n
    Upgrade: websocket\r\n
    Server: Microsoft-HTTPAPI/2.0\r\n
    Sec-WebSocket-Protocol: AMQPWSB10\r\n
    Connection: Upgrade\r\n
    Sec-WebSocket-Accept: ######
    Date: Fri, 20 Aug 2021 12:16:45 GMT\r\n
    \r\n
    [HTTP response 1/1]
    [Time since request: 0.033266349 seconds]
    [Request in frame: 1821]
    [Request URI: https://toshibasmaciothubprod.azure-devices.net:443/$iothub/websocket]

This should create websocket with protocol AMQPWSB10 which is AMQP version 1.0. Unfortunately at this stage my connection is breaking - mitmproxy has some problem handling this further.

As this is MS Azure AMQP API this may help: GitHub - Azure/azure-uamqp-python: AMQP 1.0 client library for Python, but I haven’t tried it yet.

@h4de5 I have mannaged to connect to AMQP and I’m receiving state change notifications for my AC.

I’ve done this with azure-iot-device python package and following code: Toshiba Home AC AMQP connection · GitHub. You have to fill your device id and shared key.

When I change something on my AC it generates output similar to this:

Method handler
smmobile
1
{'sourceId': '######', 'messageId': '######', 'targetId': ['######'], 'cmd': 'CMD_FCU_FROM_AC', 'payload': {'data': '30ffffffffffffffffffffffffffffffffffff'}, 'timeStamp': '21:44:55.5649670'}

Now I need to add encoder/decoder for state of AC and try to control it from python.

Can we use your script to generate device id and shared key or this is something we can only read from android property store?

nice.
unfortunatelly I did not find another way to get those ids.

@Didier3L the script needs to run stand alone at the moment, even it was planed to be integrated into HA. but for the whole “idea” to use the scheduler to send updates to the AC: this did not turn out to be working. so think I’ll retire that again.

but I will definitelly have a look into the AMQP setup asap.

I just tried it too - and I do get updates from the API - can you prepare a script which will send something to the API server?

example data:

turn off:
{‘sourceId’: ‘xxxx’, ‘messageId’: ‘0000000090’, ‘targetId’: [‘yyyyyy’], ‘cmd’: ‘CMD_FCU_TO_AC’, ‘payload’: {‘data’: ‘31ffffffffffffffffffffffffffffffffffff’}, ‘timeStamp’: ‘0061217209’}

turn on and change fanspeed to low:
{‘sourceId’: ‘xxxx’, ‘messageId’: ‘0000000090’, ‘targetId’: [‘yyyyyy’], ‘cmd’: ‘CMD_FCU_TO_AC’, ‘payload’: {‘data’: ‘30ffff20ffffffffffffffffffffffffffffff’}, ‘timeStamp’: ‘0061217209’}

timeStamp: current timestamp converted to hex + two leading zeros

payload:

example fan speed settings (and for a little more see const.py in github code)

quiet = 0x1F,
low = 0x20,
lowPlus = 33,
medium = 34,
mediumPlus = 35,
high = 36

here you can see what those positions actually means - while ff always declare not to change any settings for this function:

# see: SmartAC.Services.MQTTServices.MqttSendCmdJson

_operationStatus = "ff";
_mode = "ff";
_temp = "ff";
_fanSpeed = "ff";
_airSwing = "ff";
_powerSelection = "ff";
_meritFeature = "ff";
_pure = "ff";
_indoorTemp = "ff";
_outdoorTemp = "ff";
_errorCode = "ff";
_timerType = "ff";
_relativeHours = "ff";
_relativeMins = "ff";
_selfCleaning = "ff";
_ledStatus = "ff";
_schedulerStatus = "ff";
_utcHours = "ff";
_utcMins = "ff";

return _operationStatus + _mode + _temp + _fanSpeed + _airSwing + _powerSelection + _meritFeature + _pure + _indoorTemp + _outdoorTemp + _errorCode + _timerType + _relativeHours + _relativeMins + _selfCleaning + _ledStatus + _schedulerStatus + _utcHours + _utcMins;

@h4de5 I have made some progress - I can turn on/off my AC from python. Rest of the commands just needs further parsing and creating some API for them. I have created library here: GitHub - KaSroka/Toshiba-AC-control: Python controller for Toshiba AC please check its README for further info.

What’s missing:

  • Load current state from HTTP API (as discovered by @h4de5) as AMQP only notifies about changes - we need to know initial state after connection. Loading current state on init, also reloading from HTTP periodically as well (just in case).
  • Parse all the fields from fcu reports (currently only some information is parsed)
  • Extract SHARED_ACCESS_KEY, DEVICE_ID and AC_ID from HTTP API (@h4de5 in decompiled SmartAC.Services.ACServices.ACDeviceServices there is a method called GetACDeviceProvisioned which returns RegisterMobileDeviceRespObj that should contain shared access key - can you please check if this works? It requests /api/AC/GetRegisteredACByUniqueId with HTTP GET and ACUniqueId set to device ID) Done, now APP login info is only required.

EDIT: Latest version uses APP login info to fetch all required data, initial AC state and required tokens are fetched using HTTP API and further state updates are handled by AMQP.

Heartbeat notification also provides some nice data.

2 Likes