This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

Daikin AC control via WiFi online controller
#1
Hi,

Most new Daikin aricons are already shipped with or can be added with a nice WiFi online controller which uses an HTTP API to communicate with its supplied smartphone app.

Recently I bought one and started to intercept its traffic with tools like Fiddler, so I found all the api calls and responses.
For example, if you type to a web browser this:

http://IPADDRESS/aircon/get_sensor_info?

it responds like this:

ret=OK,htemp=29.0,hhum=-,otemp=31.0,err=0,cmpfreq=0

The same way you can get much more info, as well as send commands by using "http://IPADDRESS/aircon/set_control_info?" followed by the parameters separated by "&".

Is there an example or a simple guide to follow so I can send a request and then parse the respond and read for example the returned "otemp" value (outside temperature measured by the outdoor unit) and write it to a KNX temp object?

Thank you in advance.
Reply
#2
Hi,

Take a look at this example, it's for another service but does basicly the same with "& arguments' parsing.

http://openrb.com/send-instant-messages-...s-with-lm/

BR,

Erwin
Reply
#3
Thanks Erwin,

I think the pushover example is for sending parameters.
My need is to read the response and parse its returned parameters to convert them to usable variables.


Thanks again.
Reply
#4
There's a similar script which uses HTTP for communication:
http://forum.logicmachine.net/showthread.php?tid=320

Example for your AC system:
Code:
function parse(txt)
  local chunks, key, value, result

  chunks = txt:split(',')
  result = {}
  for _, chunk in ipairs(chunks) do
    key, value = unpack(chunk:split('='))
    result[ key ] = value
  end

  return result
end

ip = '192.168.1.1'
http = require('socket.http')
url = 'http://' .. ip .. '/aircon/get_sensor_info?'

result, err = http.request(url)
if result then
  data = parse(result)
  -- log(data)
  grp.update('1/1/1', data.otemp)
else
  alert('HTTP request failed: ' .. tostring(err))
end
Reply
#5
Thank you Edgars so much for your help!

Following your example with some modifications, I am now capable to read full info from the AC controller (mode, compressor frequency, outdoor temp, indoor temp, fan speed, wings mode, power consumption etc) as well as control it to power on/off and change it's temperature setpoint! 

This has open my appetite for more things to do.... Next I will try to create a complete AC widget so I can monitor and control all other parameters as well, like fan speed, fan direction, operation mode etc. (I will need relative icons though as it seems there aren't any). Talking about widgets, what happen to the Mosaic visualization? Will it continue its development (there isn't any similar widget to control AC for example)? Has it been upgraded in the upcoming release? And talking about firmware Shy , where can I find the latest beta and when the final release will be ready? 

I am quoting below the rest of the code I used (function parse(txt) from previous post has been created as a user library) if anyone else want to use it.

Resident script to read sensors and operational status:
Code:
ip = '192.168.1.1' -- Daikin WiFi controller IP
http = require('socket.http')
ACON = grp.getvalue('ACON/OFF')
ACpow, ACmode, ACstemp, ACshum, ACfdir = 0
ACfrate=''

----------------------------------------------------------
url = 'http://' .. ip .. '/aircon/get_sensor_info?'
result, err = http.request(url)
if result then
data = parse(result)
grp.update('outtemp', tonumber(data.otemp), dt.float16, 1)
grp.update('intemp', tonumber(data.htemp), dt.float16, 1)
grp.update('compressorfreq', tonumber(data.cmpfreq))
else
 alert('HTTP request failed: ' .. tostring(err))
end
----------------------------------------------------------
url = 'http://' .. ip .. '/aircon/get_control_info?'  
result, err = http.request(url)
if result then
 data = parse(result)
 ACpow = tonumber(data.pow)
 ACmode = tonumber(data.mode)
 ACstemp = tonumber(data.stemp)
 ACfrate = data.f_rate
 ACfdir = tonumber(data.f_dir)
 grp.update('ACpower', ACpow)
 grp.update('ACsetpoint', ACstemp, dt.float16, 1)
 grp.update('ACopmode', ACmode)
 grp.update('ACfandir', ACfdir)
 grp.update('ACfanrate', ACfrate)
else
 alert('HTTP request failed: ' .. tostring(err))
end

Event-based script to power on/off:

Code:
ACIO = event.getvalue()
ip = '192.168.1.1'
http = require('socket.http')
ACpow = tostring(grp.getvalue('ACpower'))
ACmode = tostring(grp.getvalue('ACopmode'))
ACstemp = grp.getvalue('ACsetpoint')
ACfdir = tostring(grp.getvalue('ACfandir'))
ACfrate = grp.getvalue('ACfanrate')

if ACIO then ACpow = 1 else ACpow = 0 end

 url = 'http://' .. ip .. '/aircon/set_control_info?pow=' .. ACpow ..'&mode=' .. ACmode .. '&stemp=' .. ACstemp ..'&shum=0&frate=' .. ACfrate .. '&fdir=' .. ACfdir
 result, err = http.request(url)
  if result then
   log(url)
  else
   alert('HTTP request failed: ' .. tostring(err))
  end
 
Event-based script to change temperature:

Code:
setpoint = event.getvalue()
ip = '192.168.1.1'
http = require('socket.http')
ACpow = tostring(grp.getvalue('ACpower'))
ACmode = tostring(grp.getvalue('ACopmode'))
ACstemp = grp.getvalue('ACsetpoint')
ACstempNEW = tostring(setpoint)
ACfdir = tostring(grp.getvalue('ACfandir'))
ACfrate = grp.getvalue('ACfanrate')

url = 'http://' .. ip .. '/aircon/set_control_info?pow=' .. ACpow ..'&mode=' .. ACmode .. '&stemp=' .. ACstempNEW ..'&shum=0&frate=' .. ACfrate .. '&fdir=' .. ACfdir
result, err = http.request(url)
if result then
 log(url)
 else
   alert('HTTP request failed: ' .. tostring(err))
 end
Scheduled script (every 15 mins) for gathering hourly consumption:
Code:
local chunks, i, value
ip = '192.168.1.1'
http = require('socket.http')
url = 'http://' .. ip .. '/aircon/get_day_power_ex?'

result, err = http.request(url)
if result then
 data = parse(result)
 chunks = data.curr_day_cool:split('/')
 i = os.date("*t").hour
 value = tonumber(chunks[i])
 grp.update('ACkWh', value/10 , dt.float16, 1)
else
  alert('HTTP request failed: ' .. tostring(err))
end
Reply
#6
A new version of Mosaic will be available together with new FW. We plan to have a final testing pre-release this week.
Reply
#7
(11.07.2016, 12:16)admin Wrote: A new version of Mosaic will be available together with new FW. We plan to have a final testing pre-release this week.

Thank you. 
Will the new Mosaic have new widgets like for for VoIP Intercom, AC control etc? Is there any change log?
Reply
#8
(05.07.2016, 05:58)admin Wrote: There's a similar script which uses HTTP for communication:
http://forum.logicmachine.net/showthread.php?tid=320

Example for your AC system:
Code:
function parse(txt)
  local chunks, key, value, result

  chunks = txt:split(',')
  result = {}
  for _, chunk in ipairs(chunks) do
    key, value = unpack(chunk:split('='))
    result[ key ] = value
  end

  return result
end

ip = '192.168.1.1'
http = require('socket.http')
url = 'http://' .. ip .. '/aircon/get_sensor_info?'

result, err = http.request(url)
if result then
  data = parse(result)
  -- log(data)
  grp.update('1/1/1', data.otemp)
else
  alert('HTTP request failed: ' .. tostring(err))
end

i hope someone can help me,
i try to use this script, but i got a fail
it said
Quote:Resident script:11: attempt to call global 'parse' (a nil value)
stack traceback:
For me it looks like he cant connect to my airco?

I changed the IP adres on line 1 to the IP adres of my airco
add the group adresses to my Wiser/LM

and if i open my browser and browse to 'http://192.168.11.99/aircon/get_sensor_info?'
i see the next line: 'ret=OK,htemp=18.0,hhum=-,otemp=15.0,err=0,cmpfreq=0,mompow=1'
like the names on line 12, 13 and 14.

what is what im doing wrong.

i need to say this is the first time, i try to get http request.
Reply
#9
You have to copy the parse function into your script
Reply
#10
Thanks, yes it is working
Reply
#11
(11.07.2016, 08:21)jetsetter Wrote: Thank you Edgars so much for your help!

Following your example with some modifications, I am now capable to read full info from the AC controller (mode, compressor frequency, outdoor temp, indoor temp, fan speed, wings mode, power consumption etc) as well as control it to power on/off and change it's temperature setpoint! 

This has open my appetite for more things to do.... Next I will try to create a complete AC widget so I can monitor and control all other parameters as well, like fan speed, fan direction, operation mode etc. (I will need relative icons though as it seems there aren't any). Talking about widgets, what happen to the Mosaic visualization? Will it continue its development (there isn't any similar widget to control AC for example)? Has it been upgraded in the upcoming release? And talking about firmware Shy , where can I find the latest beta and when the final release will be ready? 

I am quoting below the rest of the code I used (function parse(txt) from previous post has been created as a user library) if anyone else want to use it.

Resident script to read sensors and operational status:
Code:
ip = '192.168.1.1' -- Daikin WiFi controller IP
http = require('socket.http')
ACON = grp.getvalue('ACON/OFF')
ACpow, ACmode, ACstemp, ACshum, ACfdir = 0
ACfrate=''

----------------------------------------------------------
url = 'http://' .. ip .. '/aircon/get_sensor_info?'
result, err = http.request(url)
if result then
data = parse(result)
grp.update('outtemp', tonumber(data.otemp), dt.float16, 1)
grp.update('intemp', tonumber(data.htemp), dt.float16, 1)
grp.update('compressorfreq', tonumber(data.cmpfreq))
else
 alert('HTTP request failed: ' .. tostring(err))
end
----------------------------------------------------------
url = 'http://' .. ip .. '/aircon/get_control_info?'  
result, err = http.request(url)
if result then
 data = parse(result)
 ACpow = tonumber(data.pow)
 ACmode = tonumber(data.mode)
 ACstemp = tonumber(data.stemp)
 ACfrate = data.f_rate
 ACfdir = tonumber(data.f_dir)
 grp.update('ACpower', ACpow)
 grp.update('ACsetpoint', ACstemp, dt.float16, 1)
 grp.update('ACopmode', ACmode)
 grp.update('ACfandir', ACfdir)
 grp.update('ACfanrate', ACfrate)
else
 alert('HTTP request failed: ' .. tostring(err))
end

I have a question about the next line
Code:
  grp.update('ACsetpoint', ACstemp, dt.float16, 1)
Is there a reason to add ', dt.float16, 1)' on the line?
*line 12, 13, 29

I understand it is a conversion to float16.1 but it looks like it isnt needed?

If I leave it away, it has the same results on the objects (log). (i use 09.001 Temperature)
The reason I did try was because I would just only see the update of information, when it changed.
So I change 'update' with 'changeupdate' and this isn't working with this add on the line.

I can add a extra rule to check the value before i sent it to the groupaddres.
Reply
#12
Not changeupdate only grp.checkupdate.
This command does not have dpt so you can remove it only make sure your group has it set correctly.
https://openrb.com/docs/lua.htm#grp.write
------------------------------
Ctrl+F5
Reply
#13
Thank you, Daniel, yes i mean grp.checkupdate.
And it was already working, but i was curious if the ', dt.float16, 1)' was really needed, but the answer is no, thanks a lot.
Reply
#14
grp.checkupdate('1/1/1', value, dt.float16, 1) is equal to grp.checkupdate('1/1/1', value, 9), since dt.float16 is a numeric constant but status object address must be a string so number (1) is ignored.
Reply
#15
(11.07.2016, 08:21)jetsetter Wrote: Thank you Edgars so much for your help!

Following your example with some modifications, I am now capable to read full info from the AC controller (mode, compressor frequency, outdoor temp, indoor temp, fan speed, wings mode, power consumption etc) as well as control it to power on/off and change it's temperature setpoint! 

This has open my appetite for more things to do.... Next I will try to create a complete AC widget so I can monitor and control all other parameters as well, like fan speed, fan direction, operation mode etc. (I will need relative icons though as it seems there aren't any). Talking about widgets, what happen to the Mosaic visualization? Will it continue its development (there isn't any similar widget to control AC for example)? Has it been upgraded in the upcoming release? And talking about firmware Shy , where can I find the latest beta and when the final release will be ready? 

I am quoting below the rest of the code I used (function parse(txt) from previous post has been created as a user library) if anyone else want to use it.

Resident script to read sensors and operational status:
Code:
ip = '192.168.1.1' -- Daikin WiFi controller IP
http = require('socket.http')
ACON = grp.getvalue('ACON/OFF')
ACpow, ACmode, ACstemp, ACshum, ACfdir = 0
ACfrate=''

----------------------------------------------------------
url = 'http://' .. ip .. '/aircon/get_sensor_info?'
result, err = http.request(url)
if result then
data = parse(result)
grp.update('outtemp', tonumber(data.otemp), dt.float16, 1)
grp.update('intemp', tonumber(data.htemp), dt.float16, 1)
grp.update('compressorfreq', tonumber(data.cmpfreq))
else
 alert('HTTP request failed: ' .. tostring(err))
end
----------------------------------------------------------
url = 'http://' .. ip .. '/aircon/get_control_info?'  
result, err = http.request(url)
if result then
 data = parse(result)
 ACpow = tonumber(data.pow)
 ACmode = tonumber(data.mode)
 ACstemp = tonumber(data.stemp)
 ACfrate = data.f_rate
 ACfdir = tonumber(data.f_dir)
 grp.update('ACpower', ACpow)
 grp.update('ACsetpoint', ACstemp, dt.float16, 1)
 grp.update('ACopmode', ACmode)
 grp.update('ACfandir', ACfdir)
 grp.update('ACfanrate', ACfrate)
else
 alert('HTTP request failed: ' .. tostring(err))
end

Event-based script to power on/off:

Code:
ACIO = event.getvalue()
ip = '192.168.1.1'
http = require('socket.http')
ACpow = tostring(grp.getvalue('ACpower'))
ACmode = tostring(grp.getvalue('ACopmode'))
ACstemp = grp.getvalue('ACsetpoint')
ACfdir = tostring(grp.getvalue('ACfandir'))
ACfrate = grp.getvalue('ACfanrate')

if ACIO then ACpow = 1 else ACpow = 0 end

 url = 'http://' .. ip .. '/aircon/set_control_info?pow=' .. ACpow ..'&mode=' .. ACmode .. '&stemp=' .. ACstemp ..'&shum=0&frate=' .. ACfrate .. '&fdir=' .. ACfdir
 result, err = http.request(url)
  if result then
   log(url)
  else
   alert('HTTP request failed: ' .. tostring(err))
  end
 
Event-based script to change temperature:

Code:
setpoint = event.getvalue()
ip = '192.168.1.1'
http = require('socket.http')
ACpow = tostring(grp.getvalue('ACpower'))
ACmode = tostring(grp.getvalue('ACopmode'))
ACstemp = grp.getvalue('ACsetpoint')
ACstempNEW = tostring(setpoint)
ACfdir = tostring(grp.getvalue('ACfandir'))
ACfrate = grp.getvalue('ACfanrate')

url = 'http://' .. ip .. '/aircon/set_control_info?pow=' .. ACpow ..'&mode=' .. ACmode .. '&stemp=' .. ACstempNEW ..'&shum=0&frate=' .. ACfrate .. '&fdir=' .. ACfdir
result, err = http.request(url)
if result then
 log(url)
 else
   alert('HTTP request failed: ' .. tostring(err))
 end
Scheduled script (every 15 mins) for gathering hourly consumption:
Code:
local chunks, i, value
ip = '192.168.1.1'
http = require('socket.http')
url = 'http://' .. ip .. '/aircon/get_day_power_ex?'

result, err = http.request(url)
if result then
 data = parse(result)
 chunks = data.curr_day_cool:split('/')
 i = os.date("*t").hour
 value = tonumber(chunks[i])
 grp.update('ACkWh', value/10 , dt.float16, 1)
else
  alert('HTTP request failed: ' .. tostring(err))
end

I will use these scripts to control en read my airco.
i can control my airco on multiple ways like IR remote or app or LM.
My question is.
Is it possible to just sent one of the value's (the value i will change)?
like just turn on/off, or change temperature?
I tried but the ways i tried didnt work.


or do i need to look at another way for doing this?
Like read the values (except the value i will change) and sent a new comment with all the value's?
Reply
#16
According to unofficial docs all these parameters are required. But it also states that frate and fdir should be f_rate and f_dir.
Check the get_control_info request. You can use it to retrieve the current status that can be used if you only want to change a single parameter.
Reply
#17
Admin, thanks for the reply, i was already afraid of this.

I already have a scheduled script who read the value every 15 minutes, can i execute this script by a command in a event-based script (at the moment when i ask).
Reply
#18
You can wrap it into a function and place it into Common Functions. This way you can call it from both event and scheduled scripts. Also use grp.checkupdate so the same values are not sent on each function call.
Reply
#19
@Admin
Thanks again.

I will look at the common functions, its the first time i wiill use it, so i have to find out how to use it.

About the 'grp.checkupdate' yes it is what i always try to use, for not overload of information, thanks.
Reply
#20
Any code placed into Common functions will be included by all scripts. So don't place any code that runs on it's own there, only code wrapped into functions that scripts can call if needed.
Reply


Forum Jump: