Advantage Air MyAir3 Integration

I’m just trying to get my MyAir3 system up and running with HA, and my initial thoughts of an easy task based on an existing integration has been somewhat tempered by realising that (at least the standard) Advantage Air integration is probably not going to work for my MyAir3 system.

It seems that the standard integration " Advantage Air" is built for MyAir4 and later systems that used an android app running on a tablet that exposes a control API, on port 2525. In the case of MyAir3, the screen is a proprietary one, and the API is exposed from an ethernet controlled logic board on the main air conditioning controller (on port 80).

I’ve done a bit of analysis on the protocol, and it looks like it has some similarities, and seems be be based on what was called the XML API, vs the API exposed by the android app which is JSON based.

Looking at what I see back from the initial getSystemData request:

Most of that data seem to be there, and useable,

It’s all feasible to build something, as I have successfully called the “old” APIs, but I thought I’d check to see if there might be some existing work for the old API for HA.

The system is around 8 years old now, and was the first of the Advantage Air systems that seemed to expose a control API.

Any help would be greatly appreciated. If there’s nothing, then I guess I have a holiday project :slight_smile:

Hi Geoff,

This XML protocol looks similar to that used in the early days of myair 5 and as I understand it is still used as the serial protocol between the myair5 tablet and the controller in the roof.

My early commits in pymyair/myair.py at 167d2e58e63bce4400d336e3b3174ce907e8b646 · smallsam/pymyair · GitHub
may be of some use with the parsing and some of the retry logic you may want but I’d certainly be basing your work on Brett Adam’s work that’s now native in home assistant.

Aside some some of my very kludgy parsing, the most notable difference is that I don’t do async http and instead use plain requests http library, which can be slightly detrimental to home assistant’s responsiveness.

1 Like

Thanks So much Sam for replying… yeah looks like the MyAir3 stuff was circa 2013 when HA was in its infancy, and so no one was trying to drive proprietary AC systems… Anyhow I have pretty much all I need… the scaffold of code from the existing integration (I’m a C guy, so bit of work to get up to speed on Python won’t hurt)… and I’ve wiresharked all the commands and XML formats from the app, trialled a couple of calls through Postman successfully… so now all I need to do is get my head around the existing codebase and get a working one for me, I guess with all the other stuff that comes for free with HA, a little bit of sweat on my part for my old HVAC isn’t too much to ask :smiley:

I’ve made some modifications to the site-package init code, and have this running now with my MyAir3 system, using the old XML API, and seems to work quite well… it’s a bit hacky by just piggybacking over the existing JSON based code and just translating the JSON to XML calls, but I thought is probably the best approach to not reinvent the wheel…

I’m wondering what my next steps should be… It runs OK if I just hack it into my own system, I’m happy to put this back into the repo, if people think it’s of value, or of quality good enough. I’d be keen to know the feeling from those looking after the code now, if it’s of any value… Perhaps there just may not be enough MyAir3 systems around to be of value…

Let me know… If it’s considered of value, I might need some assistance in working out where the site package stuff goes in git, also it’s my first attempt at Python, so please be gentle :slight_smile:

The other problem I have is I don’t have a real MyAir4 or above system to test I’ve not broken anything, but I’ve kept it all quite separated, so I don’t think it will break the existing integration, but would be awesome if someone could give it a quick test for me

~/hacore/venv/lib/python3.10/site-packages/advantage_air

1 Like

@geoffwoz
I am new to HASS and trying to integrate my old MyAir3. I find it complicated to integrate MyAir3 and been digging the internet how to do it. Do you mine sharing the steps you did to fully integrate your MyAir3 to HASS? Pardon me I’m a new user of HASS and have very basic knowledge. Thank you.

@geoffwoz I have a MyAir3 system too installed ~10 years ago and I am trying to integrate it to HASS.
Can you please shed a light how did you get a successful query to your MyAir3 system? I don’t know what I am missing. I have been advised by AdvantageAir that MyAir3 does not provide API, which I don’t believe 100% since I saw you post.

When I tried to query via web browser http://192.168.0.xxx/getSystemData I get this reply:

MyApp Version: 7.2
Control Box Version: 4.2
UnitControlLevel: 4

Any help greatly appreciated. Thanks

Hey! I’m new to HASS but I managed to get the MyAir3 system to sing and dance…

I’m using Windows bat files that call curl and netcat (i’m an old bastard) but here are a few:

This one is how I figured out to “Discover” a MyAir3 system on a network the same way the Phone App does, it uses this config.ini file:

DaikinIP	
DaikinMAC	
Broadcast	192.168.1.255

Then it sends a packet to the broadcast address to port 3000 and listens on 3001. The MyAir3 sends back a packet giving you the IP and MAC address of the unit.

@echo off

for /f "tokens=1,2" %%a in (config.ini) do (
	if "%%a"=="Broadcast" set broadcast=%%b
)

for /f "tokens=4 delims= " %%a in ('route print ^| find " 0.0.0.0"') do (
	if not %%a==1 if not "%%a"=="Default" set localip=%%a
)

start /MIN "Listening" ncat -luo dump.tmp %localip% 3001
echo|set /p="identify" | ncat -4u -w1 -p 3000 %broadcast% 3000

ping -n 3 localhost > nul
TASKKILL /F /IM ncat.exe > nul
ping -n 1 localhost > nul

for /f "tokens=4,25 delims=</> " %%a in (dump.tmp) do set mac=%%a && set ip=%%b
echo IP address:%ip%    Mac address: %mac%
del /Q dump.tmp> nul

set nocopy=pass
for /f "tokens=1,2" %%a in (config.ini) do (
	if "%%a"=="DaikinIP" echo DaikinIP	%ip%>> config.tmp
	if "%%a"=="DaikinIP" if "%ip%"=="" set nocopy=fail
	if "%%a"=="DaikinMAC" echo DaikinMAC	%mac%>> config.tmp
	if "%%a"=="DaikinMAC" if "%mac%"=="" set nocopy=fail
)
echo Broadcast	%broadcast%>> config.tmp

if "%nocopy%"=="pass" move /Y config.tmp config.ini> nul
if "%nocopy%"=="fail" del /Q config.tmp> nul

pause

Then you need to “Authenticate” like this:

The password for my system was the default “password” so I hope it’s the same for all of them, I have no idea how or if it can be changed.

@echo off

for /f "tokens=1,2" %%a in (config.ini) do (
	if "%%a"=="DaikinIP" set ip=%%b
)

bin\bin\curl -X GET http://%ip%/login?password=password
pause

Then once you’re “Authenticated” you have a time window you can issue requests like these:

GetSystemData

@echo off

for /f "tokens=1,2" %%a in (config.ini) do (
	if "%%a"=="DaikinIP" set ip=%%b
)

bin\bin\curl -X GET http://%ip%/getSystemData
pause

GetZoneData (May need to add more to get all your zones):

@echo off

for /f "tokens=1,2" %%a in (config.ini) do (
	if "%%a"=="DaikinIP" set ip=%%b
)

bin\bin\curl -X GET http://%ip%/getZoneData?zone=1
echo.
bin\bin\curl -X GET http://%ip%/getZoneData?zone=2
echo.
bin\bin\curl -X GET http://%ip%/getZoneData?zone=3
echo.
bin\bin\curl -X GET http://%ip%/getZoneData?zone=4
echo.
bin\bin\curl -X GET http://%ip%/getZoneData?zone=5
echo.
bin\bin\curl -X GET http://%ip%/getZoneData?zone=6
echo.
bin\bin\curl -X GET http://%ip%/getZoneData?zone=7
pause

Here are a few commands you can use once you’re authenticated (you can put them in bat files like the ones above or run them from curl directly:

Turn the unit on:

curl -X GET http://%ip%/setSystemData?airconOnOff=1

Turn the unit off:

curl -X GET http://%ip%/setSystemData?airconOnOff=0

Set a 1 hour timer:

curl -X GET http://%ip%/setZoneTimer?startTimeHours=0^&startTimeMinutes=0^&endTimeHours=1^&endTimeMinutes=0^&scheduleStatus=2
)

Cancel a timer:

curl -X GET http://%ip%/setZoneTimer?startTimeHours=0^&startTimeMinutes=0^&endTimeHours=0^&endTimeMinutes=0^&scheduleStatus=0

Here’s an example of a bat file that does it all, set’s the zone percentages, fan speed etc…

Change the “Roomname” to the name of your zones.

@echo off

REM FAN (1=Low 2=Med 3=High)
set fan=1

REM MODE (1=Cool 2=Heat 3=FanOnly)
set mode=1

REM TEMP (16.0 to 32.0)
set temp=26.0

REM ZONES
set zones=7
set zone1state=OFF	& set zone1prcnt=100	& set zone1name=Roomname1
set zone2state=OFF	& set zone2prcnt=100	& set zone2name=Roomname2
set zone3state=OFF	& set zone3prcnt=10	& set zone3name=Roomname3
set zone4state=OFF	& set zone4prcnt=60	& set zone4name=Roomname4
set zone5state=ON	& set zone5prcnt=100	& set zone5name=Roomname5
set zone6state=OFF	& set zone6prcnt=100	& set zone6name=Roomname6
set zone7state=OFF	& set zone7prcnt=80	& set zone7name=Roomname7

REM TIMER (HOURS/MINUTES)
set Htimer=1
set Mtimer=0

REM STATE (ON/OFF)
set state=ON

set broadcast=192.168.0.255
set password=password

REM ------------------------------------------DO NOT EDIT BELOW THIS LINE (UNLESS NOT 7 ZONES)------------------------------------------

if %fan%==1 set fantxt=LOW
if %fan%==2 set fantxt=MED
if %fan%==3 set fantxt=HIGH
if %mode%==1 set modetxt=COOL
if %mode%==2 set modetxt=HEAT
if %mode%==3 set modetxt=FAN
set zone1prcnt=%zone1prcnt:	=%
set zone2prcnt=%zone2prcnt:	=%
set zone3prcnt=%zone3prcnt:	=%
set zone4prcnt=%zone4prcnt:	=%
set zone5prcnt=%zone5prcnt:	=%
set zone6prcnt=%zone6prcnt:	=%
set zone7prcnt=%zone7prcnt:	=%
if "%zone1state%"=="ON	" set zone1num=1&set zone1state=ON
if "%zone1state%"=="OFF	" set zone1num=0&set zone1state=OFF
if "%zone2state%"=="ON	" set zone2num=1&set zone2state=ON
if "%zone2state%"=="OFF	" set zone2num=0&set zone2state=OFF
if "%zone3state%"=="ON	" set zone3num=1&set zone3state=ON
if "%zone3state%"=="OFF	" set zone3num=0&set zone3state=OFF
if "%zone4state%"=="ON	" set zone4num=1&set zone4state=ON
if "%zone4state%"=="OFF	" set zone4num=0&set zone4state=OFF
if "%zone5state%"=="ON	" set zone5num=1&set zone5state=ON
if "%zone5state%"=="OFF	" set zone5num=0&set zone5state=OFF
if "%zone6state%"=="ON	" set zone6num=1&set zone6state=ON
if "%zone6state%"=="OFF	" set zone6num=0&set zone6state=OFF
if "%zone7state%"=="ON	" set zone7num=1&set zone7state=ON
if "%zone7state%"=="OFF	" set zone7num=0&set zone7state=OFF
if "%state%"=="ON" set statenum=1
if "%state%"=="OFF" set statenum=0

REM ----------------------------------------------------DO NOT EDIT BELOW THIS LINE-----------------------------------------------------

for /f "tokens=4 delims= " %%a in ('route print ^| find " 0.0.0.0"') do (
	if not %%a==1 if not "%%a"=="Default" set localip=%%a
)

start /MIN "Listening" ncat -luo dump.tmp %localip% 3001
echo|set /p="identify" | ncat -4u -w1 -p 3000 %broadcast% 3000

ping -n 3 localhost > nul
TASKKILL /F /IM ncat.exe > nul
ping -n 1 localhost > nul

for /f "tokens=4,25 delims=</> " %%a in (dump.tmp) do set mac=%%a && set ip=%%b
del /Q dump.tmp> nul

if "%ip%"=="" echo Connection failed... && goto end

echo Configuring preferences...
REM Authenticate
bin\bin\curl --silent -X GET http://%ip%/login?password=%password% > temp.txt
for /f "tokens=3 delims=-.: " %%i in ('find /C "<authenticated>1</authenticated>" temp.txt') do (
	IF %%i==1 (echo Authenticated... & del /Q temp.txt) ELSE (echo Failed to Authenticate... & del /Q temp.txt & goto end)
)
echo.

REM Fan Speed
bin\bin\curl --silent -X GET http://%ip%/setSystemData?fanSpeed=%fan% > temp.txt
for /f "tokens=3 delims=-.: " %%i in ('find /C "<ack>1</ack>" temp.txt') do (
	IF %%i==1 (echo Fan Speed:	%fantxt% & del /Q temp.txt) ELSE (echo Failed to Set Fan Speed... & del /Q temp.txt & goto end)
)

REM Mode
bin\bin\curl --silent -X GET http://%ip%/setSystemData?mode=%mode% > temp.txt
for /f "tokens=3 delims=-.: " %%i in ('find /C "<ack>1</ack>" temp.txt') do (
	IF %%i==1 (echo Mode:		%modetxt% & del /Q temp.txt) ELSE (echo Failed to Set Mode... & del /Q temp.txt & goto end)
)

REM Temperature
bin\bin\curl --silent -X GET http://%ip%/setSystemData?centralDesiredTemp=%temp% > temp.txt
for /f "tokens=3 delims=-.: " %%i in ('find /C "<ack>1</ack>" temp.txt') do (
	IF %%i==1 (echo Temp:		%temp% C & del /Q temp.txt) ELSE (echo Failed to Set Temperature... & del /Q temp.txt & goto end)
)

REM Set Zones
setlocal enableDelayedExpansion
for /L %%i in (1,1,%zones%) do (
	if !zone%%inum!==0 (
		bin\bin\curl --silent -X GET http://%ip%/setZoneData?zone=%%i^&zoneSetting=!zone%%inum! > temp.txt
		for /f "tokens=3 delims=-.: " %%a in ('find /C "<ack>1</ack>" temp.txt') do (
			IF %%a==1 (echo Zone:%%i	!zone%%iname!	!zone%%istate!) ELSE (echo Failed to Set Zone...)
		)
	)
	if !zone%%inum!==1 (
		bin\bin\curl --silent -X GET http://%ip%/setZoneData?zone=%%i^&zoneSetting=!zone%%inum!^&userPercentSetting=!zone%%iprcnt! > temp.txt
		for /f "tokens=3 delims=-.: " %%a in ('find /C "<ack>1</ack>" temp.txt') do (
			IF %%a==1 (echo Zone:%%i	!zone%%iname!	!zone%%istate!	!zone%%iprcnt! Percent Open) ELSE (echo Failed to Set Zone...)
		)
	)
)
setlocal disableDelayedExpansion
if "%zone1state%"=="OFF" bin\bin\curl --silent -X GET http://%ip%/setZoneData?zone=1^&zoneSetting=%zone1num% > temp.txt

REM TimerOFF then TimerON
set /a "timesum=%Htimer%+Mtimer"
if %timesum% GTR 0 (
	REM ----Stop any running timers----
	bin\bin\curl --silent -X GET http://%ip%/setZoneTimer?startTimeHours=0^&startTimeMinutes=0^&endTimeHours=0^&endTimeMinutes=0^&scheduleStatus=0 > temp.txt
	for /f "tokens=3 delims=-.: " %%i in ('find /C "<ack>1</ack>" temp.txt') do (
		IF %%i==1 (echo Timer:		Reset & del /Q temp.txt) ELSE (echo Failed to Clear Timer... & del /Q temp.txt & goto end)
	)
	REM ----Add time to current time----
	for /f "tokens=1,2 delims=:" %%a in ('powershell "(get-date %time%).AddHours(%Htimer%).AddMinutes(%Mtimer%).ToString('HH:mm')"') do (
		REM ----Start timer with new time----
		bin\bin\curl --silent -X GET http://%ip%/setZoneTimer?startTimeHours=0^&startTimeMinutes=0^&endTimeHours=%%a^&endTimeMinutes=%%b^&scheduleStatus=2 > temp.txt
		for /f "tokens=3 delims=-.: " %%i in ('find /C "<ack>1</ack>" temp.txt') do (
			IF %%i==1 (
				IF %Htimer%==1 echo Timer:		Set to %Htimer% Hour and %Mtimer% Minutes & del /Q temp.txt
				IF NOT %Htimer%==1 echo Timer:		Set to %Htimer% Hours and %Mtimer% Minutes & del /Q temp.txt
			) ELSE (
				echo Failed to Set Temperature... & del /Q temp.txt & goto end
			)
		)
	)
)

REM ON/OFF (0=OFF 1=ON)
bin\bin\curl --silent -X GET http://%ip%/setSystemData?airconOnOff=%statenum% > temp.txt
for /f "tokens=3 delims=-.: " %%i in ('find /C "<ack>1</ack>" temp.txt') do (
	IF %%i==1 (echo UNIT:		%state% & del /Q temp.txt) ELSE (echo Failed to Set State... & del /Q temp.txt & goto end)
)
echo.
echo Settings Completed.
:end
pause

If anyone ever get’s it to work in HASS I would really appreciate it!

1 Like

If all of my horrible .bat files are too confusing, here are the direct curl commands:

#Authenticate
curl -s -m 20 -H "Accept: application/xml" -X GET http://192.168.10.20/login\?password\=password | xmllint --xpath "/iZS10.3/authenticated/text()" -

#Get System Data
curl -s -m 20 -H "Accept: application/xml" -X GET http://192.168.10.20/getSystemData | xmllint --format -

Example:

<?xml version="1.0" encoding="UTF-8"?>
<iZS10.3>
  <request>getSystemData</request>
  <mac>0004a38f3a1a</mac>
  <authenticated>1</authenticated>
  <system>
    <type>12</type>
    <name>HOME</name>
    <MyAppRev>7.4</MyAppRev>
    <zoneStationHasUnitControl>1</zoneStationHasUnitControl>
    <dhcp>1</dhcp>
    <ip>192.168.10.20</ip>
    <netmask>255.255.255.0</netmask>
    <gateway>192.168.10.1</gateway>
    <unitcontrol>
      <airconOnOff>1</airconOnOff>
      <fanSpeed>2</fanSpeed>
      <mode>3</mode>
      <unitControlTempsSetting>0</unitControlTempsSetting>
      <centralActualTemp>25.6</centralActualTemp>
      <centralDesiredTemp>23.0</centralDesiredTemp>
      <airConErrorCode>    </airConErrorCode>
      <activationCodeStatus>0</activationCodeStatus>
      <numberOfZones>7</numberOfZones>
      <maxUserTemp>32.0</maxUserTemp>
      <minUserTemp>16.0</minUserTemp>
      <availableSchedules>8</availableSchedules>
    </unitcontrol>
    <zs103TechSettings>
      <numberofConstantZones>1</numberofConstantZones>
      <zsConstantZone1>1</zsConstantZone1>
      <zsConstantZone2>0</zsConstantZone2>
      <zsConstantZone3>0</zsConstantZone3>
      <tempSensorSelect>0</tempSensorSelect>
      <returnAirOffset>0.0</returnAirOffset>
      <controlZoneNumber>0</controlZoneNumber>
      <newAirFitted>0</newAirFitted>
      <ACinfo>1</ACinfo>
      <systemID>16</systemID>
    </zs103TechSettings>
  </system>
</iZS10.3>

#Get Specific Zone by Number
curl -s -m 20 -H "Accept: application/xml" -X GET http://192.168.10.20/getZoneData?zone=1 | xmllint --format -

Example:

<?xml version="1.0" encoding="UTF-8"?>
<iZS10.3>
  <request>getZoneData</request>
  <mac>0004a38f3a1a</mac>
  <authenticated>1</authenticated>
  <zone1>
    <name>KITCHEN</name>
    <setting>0</setting>
    <userPercentSetting>100</userPercentSetting>
    <maxDamper>100</maxDamper>
    <minDamper>0</minDamper>
    <userPercentAvail>1</userPercentAvail>
    <actualTemp>0.0</actualTemp>
    <desiredTemp>24.0</desiredTemp>
    <RFstrength>0</RFstrength>
    <hasLowBatt>0</hasLowBatt>
    <hasMotorError>0</hasMotorError>
    <hasClimateControl>0</hasClimateControl>
  </zone1>
</iZS10.3>

#On
curl -s -m 20 -H "Accept: application/xml" -X GET http://192.168.10.20/setSystemData?airconOnOff=1 | xmllint --xpath "/iZS10.3/ack/text()" -

#Off
curl -s -m 20 -H "Accept: application/xml" -X GET http://192.168.10.20/setSystemData?airconOnOff=0 | xmllint --xpath "/iZS10.3/ack/text()" -

#Fan Speed LOW
curl -s -m 20 -H "Accept: application/xml" -X GET http://192.168.10.20/setSystemData?fanSpeed=1 | xmllint --xpath "/iZS10.3/ack/text()" -

#Fan Speed MED
curl -s -m 20 -H "Accept: application/xml" -X GET http://192.168.10.20/setSystemData?fanSpeed=2 | xmllint --xpath "/iZS10.3/ack/text()" -

#Fan Speed HIGH
curl -s -m 20 -H "Accept: application/xml" -X GET http://192.168.10.20/setSystemData?fanSpeed=3 | xmllint --xpath "/iZS10.3/ack/text()" -

#Mode COOL
curl -s -m 20 -H "Accept: application/xml" -X GET http://192.168.10.20/setSystemData?mode=1 | xmllint --xpath "/iZS10.3/ack/text()" -

#Mode HEAT
curl -s -m 20 -H "Accept: application/xml" -X GET http://192.168.10.20/setSystemData?mode=2 | xmllint --xpath "/iZS10.3/ack/text()" -

#Mode FAN
curl -s -m 20 -H "Accept: application/xml" -X GET http://192.168.10.20/setSystemData?mode=3 | xmllint --xpath "/iZS10.3/ack/text()" -

#Temperature for HEAT / COOL
curl -s -m 20 -H "Accept: application/xml" -X GET http://192.168.10.20/setSystemData?centralDesiredTemp=24.0 | xmllint --xpath "/iZS10.3/ack/text()" -

#Enable Zone 1
curl -s -m 20 -H "Accept: application/xml" -X GET http://192.168.10.20/setZoneData?zone=1&zoneSetting=1 | xmllint --xpath "/iZS10.3/ack/text()" -

#Disable Zone 1
curl -s -m 20 -H "Accept: application/xml" -X GET http://192.168.10.20/setZoneData?zone=1&zoneSetting=0 | xmllint --xpath "/iZS10.3/ack/text()" -

#Enable Zone 1 and set Percentage to 50%
curl -s -m 20 -H "Accept: application/xml" -X GET http://192.168.10.20/setZoneData?zone=1&zoneSetting=1&userPercentSetting=50 | xmllint --xpath "/iZS10.3/ack/text()" -

#Disable Zone 1 and set Percentage to 50%
curl -s -m 20 -H "Accept: application/xml" -X GET http://192.168.10.20/setZoneData?zone=1&zoneSetting=0&userPercentSetting=50 | xmllint --xpath "/iZS10.3/ack/text()" -

#Set Timer (clock time to stop, e.g. if it's 10pm and you want to stop in 1 hour and 30 minutes, set endTimeHours to 23 and endTimeMinutes to 30
curl -s -m 20 -H "Accept: application/xml" -X GET http://192.168.10.20/setZoneTimer?startTimeHours=0&startTimeMinutes=0&endTimeHours=23&endTimeMinutes=30&scheduleStatus=2 | xmllint --xpath "/iZS10.3/ack/text()" -

#Clear Timer
curl -s -m 20 -H "Accept: application/xml" -X GET http://192.168.10.20/setZoneTimer?startTimeHours=0&startTimeMinutes=0&endTimeHours=0&endTimeMinutes=0&scheduleStatus=0 | xmllint --xpath "/iZS10.3/ack/text()" -

1 Like

@Tacmatricx thank you for posting this. I will play with the curl commands next weekend and will let you know how it goes.

1 Like

Anyone still interested in seeing support for MyAir3 in HA, please vote on:

If I could vote 100 times, I would.