Daikin wifi

From Domoticz
Jump to: navigation, search

Purpose

With this script you will be able to control your Daikin Air Source Heatpump connected with the optional wifi controller. A version using the native reading support in Domoticz is described first. A custom Lua script is added to not only read the settings but to also control the Daikin. Two legacy version are retained afterwards, one based on bash scripting and one based on python.

Domoticz integrated Daikin support

The Daikin is now partially supported out-of-the-box in the current version.

  • Setup -> Hardware
  • For type select Daikin, for remote addess set the ip of you Daikin and for port set 80
  • Press Add
  • Setup -> Devices will show three new sensors, the inside temperature, the outside temperature and the target temperature.

The target temperature cannot be used to actually set the target temperature. Thus, you will have the data from your Daikin in Domoticz, but you cannot operate the unit from domoticz, you will still need the remote or the app.

LUA script to control the Daikin

  • Setup -> Hardware
  • For type select Dummy
  • Press Add
  • Press the create virtual sensors blue bubble on the new device that appeared on the top
  • Type DaikinMode for the name and select Selector for the type
  • Press the create virtual sensors blue bubble again
  • Type DaikinFrate for the name and select Selector for the type
  • Press the create virtual sensors blue bubble again
  • Type DaikingSetTarget for the name and select Thermostat Setpoint for the type

You should now have a DaikinMode and DaikinFrate under the switches tab and a DaikinSetTarget under the Utility tab. Go to the switched tab, then to the DaikinMode switch en press edit. You will have to set 5 levels, off (already there), Heat, Cool, Auto an Dry.

DaikinModeLevels.png

Save the settings, go back to the switches tab and edit the DaikinFrate switch. Add the levels Auto, Silent, l1, l2, l3, l4 and l5. Now, tick the checkbox named 'Hide Off Level' (the fan cannot be off when the Daikin is on).

DaikingFrateLevels.png

Now login to your server, e.g. using SSH, and do the following:

  • run 'sudo apt-get install curl' to install curl

Finally, go to Setup -> More options -> Events. Type Daikin under name and select Lua instead of blockly. Remove the code that appears and paste the following script (do not forget to change the IP address for the daikin_ip).

commandArray = {}
if (devicechanged['DaikinMode']) or (devicechanged['DaikinSetTarget']) or (devicechanged['DaikinFrate']) or (devicechanged['DaikinPOWER']) then
    daikin_ip = '192.168.10.26'
    stemp = otherdevices_svalues['DaikinSetTarget']
    if (otherdevices['DaikinMode'] == 'Off') then
        pow = 0
        mode = 0
    else
        pow = 1
        if (otherdevices['DaikinMode'] == 'Heat') then
            mode = 4
        elseif (otherdevices['DaikinMode'] == 'Cool') then
            mode = 3
        elseif (otherdevices['DaikinMode'] == 'Auto') then
            mode = 0
        elseif (otherdevices['DaikinMode'] == 'Dry') then
            mode = 2
        end
    end
    if (otherdevices['DaikinFrate'] == 'Auto') then
        f_rate = 'A'
    elseif (otherdevices['DaikinFrate'] == 'Silent') then
        f_rate = 'B'
    elseif (otherdevices['DaikinFrate'] == 'l1') then
        f_rate = '3'
    elseif (otherdevices['DaikinFrate'] == 'l2') then
        f_rate = '4'
    elseif (otherdevices['DaikinFrate'] == 'l3') then
        f_rate = '5'
    elseif (otherdevices['DaikinFrate'] == 'l4') then
        f_rate = '6'
    elseif (otherdevices['DaikinFrate'] == 'l5') then
        f_rate = '7'
    end
    cmd = 'curl "http://' .. daikin_ip .. '/aircon/set_control_info?pow='..pow..'&mode='..mode..'&stemp='..stemp..'&shum=0&f_rate='..f_rate..'&f_dir=0"'
    os.execute(cmd)
end
return commandArray

Click save and you should be ready to go!

  • A minor nuisance is that you have two set temperatures, on that reads and one that sets. This can be avoided by making a custom LUA script that polls the unit, circumventing the native support. An example of this:
commandArray = {}

local printPrefix = '<span style="font-weight: bold; font-color: green;">[Daikin - Poll status]&nbsp;</span>'
local daikin_ip = '192.168.0.112'

-- Domoticz devices used in script
local device_daikin_mode = 'DaikinMode'
--local device_daikin_mode_idx = 59
local device_daikin_fan_rate = 'DaikinFrate'
--local device_daikin_fan_rate_idx = 60
local device_daikin_set_target = 'DaikinSetTarget'
local device_daikin_set_target_idx = 61
local device_bedroom_fans = 'Slaapkamer fans'

local function checkAndUpdateDevice(deviceName, targetValue)
    if (otherdevices[deviceName] ~= targetValue) then
        commandArray[deviceName] = '' .. targetValue
        print(printPrefix .. 'Device \'' .. deviceName .. '\' has been updated to \'' .. targetValue .. '\' (was \'' .. otherdevices[deviceName] .. '\').')
    end
end
local function checkAndUpdateSelectorSwitch(deviceName, targetValue, targetPercentage)
    if (otherdevices[deviceName] ~= targetValue) then
        commandArray[deviceName] = 'Set Level: ' .. targetPercentage
        print(printPrefix .. 'Device \'' .. deviceName .. '\' has been updated to \'' .. targetValue .. '\' (was \'' .. otherdevices[deviceName] .. '\').')
    end
end
local function checkAndUpdateDeviceByStringValue(deviceName, deviceIdx, targetValue)
    if (otherdevices_svalues[deviceName] ~= targetValue) then
        commandArray['UpdateDevice'] = '' .. deviceIdx .. '|0|' .. targetValue
        print(printPrefix .. 'Device \'' .. deviceName .. '\' has been updated to \'' .. targetValue .. '\' (was \'' .. otherdevices[deviceName] .. '\').')
    end
end

-- Get current Domoticz device values
local daikin_domoticz_mode = otherdevices[device_daikin_mode]
local daikin_domoticz_fan_rate = otherdevices[device_daikin_fan_rate]
local daikin_domoticz_set_target = otherdevices[device_daikin_set_target]

local daikin_actual_mode
local daikin_actual_mode_percentage
local daikin_actual_fan_rate
local daikin_actual_fan_rate_percentage
local daikin_actual_set_target

-- Retrieve actual Daikin state
local command = 'curl "http://' .. daikin_ip .. '/aircon/get_control_info"'
local handle = io.popen(command)
local result = handle:read("*a")
handle:close()
--print(printPrefix .. 'Daikin get_control_info result: ' .. result)

local daikin_result_pow_idx = string.find(result, 'pow=')
local daikin_result_pow = string.sub(result, daikin_result_pow_idx + 4, daikin_result_pow_idx + 4)

local daikin_result_mode_idx = string.find(result, 'mode=')
local daikin_result_mode = string.sub(result, daikin_result_mode_idx + 5, daikin_result_mode_idx + 5)

local daikin_result_fan_rate_idx = string.find(result, 'f_rate=')
local daikin_result_fan_rate = string.sub(result, daikin_result_fan_rate_idx + 7, daikin_result_fan_rate_idx + 7)

local daikin_result_set_temp_start_idx = string.find(result, 'stemp=')
local daikin_result_set_temp_end_idx = string.find(result, ',', daikin_result_set_temp_start_idx)
local daikin_result_set_temp = string.sub(result, daikin_result_set_temp_start_idx + 6, daikin_result_set_temp_end_idx - 1)

-- Convert Daikin result to Domoticz device values
if daikin_result_pow == '0' then
    --print ('Airconditioning is powered off')
    daikin_actual_mode = 'Off'
    daikin_actual_mode_percentage = 0
else
    --print ('Airconditioning is powered on')

    -- Convert actual mode
    --print (daikin_result_mode)
    if daikin_result_mode == '4' then
        daikin_actual_mode = 'Heat'
        daikin_actual_mode_percentage = 10
    elseif daikin_result_mode == '3' then
        daikin_actual_mode = 'Cool'
        daikin_actual_mode_percentage = 20
    elseif daikin_result_mode == '0' then
        daikin_actual_mode = 'Auto'
        daikin_actual_mode_percentage = 30
    elseif daikin_result_mode == '2' then
        daikin_actual_mode = 'Dry'
        daikin_actual_mode_percentage = 40
    end
    --print (daikin_actual_mode)
end

-- Convert fan rate
--print (daikin_result_fan_rate)
if daikin_result_fan_rate == 'A' then
    daikin_actual_fan_rate = 'Auto'
    daikin_actual_fan_rate_percentage = 10
elseif daikin_result_fan_rate == 'B' then
    daikin_actual_fan_rate = 'Silent'
    daikin_actual_fan_rate_percentage = 20
elseif daikin_result_fan_rate == '3' then
    daikin_actual_fan_rate = 'l1'
    daikin_actual_fan_rate_percentage = 30
elseif daikin_result_fan_rate == '4' then
    daikin_actual_fan_rate = 'l2'
    daikin_actual_fan_rate_percentage = 40
elseif daikin_result_fan_rate == '5' then
    daikin_actual_fan_rate = 'l3'
    daikin_actual_fan_rate_percentage = 50
elseif daikin_result_fan_rate == '6' then
    daikin_actual_fan_rate = 'l4'
    daikin_actual_fan_rate_percentage = 60
elseif daikin_result_fan_rate == '7' then
    daikin_actual_fan_rate = 'l5'
    daikin_actual_fan_rate_percentage = 70
end
--print (printPrefix .. daikin_actual_fan_rate)

-- Convert set target (needs two decimals)
--print (printPrefix .. daikin_result_set_temp)
daikin_actual_set_target = daikin_result_set_temp .. '0'
--print (printPrefix .. daikin_actual_set_target)

-- Compare actual device values with Domoticz values
-- TODO Does not work yet.
checkAndUpdateSelectorSwitch(device_daikin_mode, daikin_actual_mode, daikin_actual_mode_percentage)
checkAndUpdateSelectorSwitch(device_daikin_fan_rate, daikin_actual_fan_rate, daikin_actual_fan_rate_percentage)
checkAndUpdateDeviceByStringValue(device_daikin_set_target, device_daikin_set_target_idx, daikin_actual_set_target)

-- Start/stop bedroom fans
if daikin_actual_mode == 'Off' then
    checkAndUpdateDevice(device_bedroom_fans, 'Off')
else
    checkAndUpdateDevice(device_bedroom_fans, 'On')
end

return commandArray


Dependencies - hardware / software / operating system

Compatible devices

Compatible units in combination with BRP069A41:
FTXG20LV1BW, FTXG20LV1BS , FTXG25LV1BW, FTXG25LV1BS, FTXG35LV1BW, FTXG35LV1BS, FTXG50LV1BW, FTXG50LV1BS, FTXJ20LV1BW, FTXJ20LV1BS, FTXJ25LV1BW, FTXJ25LV1BS, FTXJ35LV1BW, FTXJ35LV1BS, FTXJ50LV1BW, FTXJ50LV1BS ,

Compatible units in combination with BRP069A42:
FTXZ25NV1B, FTXZ35NV1B, FTXZ50NV1B, FTXS35K2V1B, FTXS35K3V1B, FTXS42K2V1B, FTXS42K3V1B, FTXS50K2V1B, FTXS50K3V1B, FTXLS25K2V1B, FTXLS35K2V1B,FTXM35K3V1B, FTXM42K3V1B, FTXM50K3V1B, , FTXS60GV1B, FTXS71GV1B, , ATXS35K2V1B, ATXS35K3V1B, ATXS50K2V1B, ATXS50K3V1B, , FTX50GV1B, FTX60GV1B, FTX71GV1B, , FVXG25K2V1B, FVXG35K2V1B, FVXG50K2V1B, , FVXS25FV1B, FVXS35FV1B, FVXS50FV1B, , FLXS25BAVMB, FLXS25BVMA, FLXS25BVMB, FLXS35BAVMB, FLXS35BAVMB9, FLXS35BVMA, FLXS35BVMB, FLXS50BAVMB, FLXS50BVMA, FLXS50BVMB, FLXS60BAVMB, FLXS60BVMA, FLXS60BVMB,

Compatible units in combination with BRP069A43:
CTXS15K2V1B, CTXS15K3V1B, FTXS20K2V1B, FTXS20K3V1B, FTXS25K2V1B, FTXS25K3V1B, CTXS35K2V1B, CTXS35K3V1B, , FTXM20K3V1B, FTXM25K3V1B, , ATXS20K2V1B, ATXS20K3V1B, ATXS25K2V1B, ATXS25K3V1B, , FTX20J2V1B, FTX25J2V1B, FTX35J2V1B, FTX20J3V1B, FTX25J3V1B, FTX35J3V1B, , FTXL25J2V1B, FTXL35J2V1B, , FTX20KV1B, FTX25KV1B, FTX35KV1B, , FTX20GV1B, FTX25GV1B, FTX35GV1B, , ATX20J2V1B, ATX20J3V1B, ATX25J2V1B, ATX25J3V1B, ATX35J2V1B, ATX35J3V1B, , ATX20KV1B, ATX25KV1B, ATX35KV1B, , ATXL25J2V1B, ATXL35J2V1B,

Compatible units in combination with BRP069A44:
FTX50KV1B, FTX60KV1B

Configure your router to give out static DHCP leases

This script needs the device you want to check to have a static IP. You can configure the device to use a static IP, or configure your router to grant a 'Static DHCP lease' to the device, based on the MAC-address of the device.
This last method is the most preferred, because it doesn't involve making changes on the device, which decreases the risk of errors. Also, by configuring a static IP on your device, you could encounter trouble when connecting to a different network.
Read the manual of your router on how to configure a static DHCP lease.

Installing Dependancies

The script needs curl to be installed. You can install this by running:

sudo apt-get install curl

from the terminal on the Pi.
If it says that 'curl' is already installed, you can continue further with this tutorial.

Install and build jq

There is currently no install package for the raspberry Pi so you need to build it yourself. You need to install: Flex, Bison, GCC, Make, Autotools

sudo apt-get install flex -y
sudo apt-get install bison -y
sudo apt-get install gcc -y
sudo apt-get install make -y
sudo apt-get install autotools -y

Then just fetch the latest tarball:


curl -O http://stedolan.github.io/jq/download/source/jq-1.4.tar.gz
tar xfvz jq-1.4.tar.gz
cd jq-1.4
./configure
make
sudo make install

Copy jq to /usr/bin

cp jq /usr/bin

Domoticz Setup - creating virtual hardware dummy and virtual switches

This script needs a virtual switch and a virtual Thermostat.

Create virtual hardware

Open domoticz in your webbrowser, go to setup and then hardware.
We are going to make a new Dummy device, make sure enabled is on.
Name: Daikin
Type: Dummy (Does nothing, use for virtual switches only)

press Add

You will have the new hardware called Daikin in your list.

Create virtual switches

Now click create virtual sensors behind your newly created hardware.
From the dropdownlist choose Thermostat Setpoint and click add.
Create another virtual sensor and select switch.


Now you need to know the ID of the switch.
Go to setup-> devices sort the list descending on IDX, you will see the newly created sensors in the top of the list.
Note down the IDX number of both, you will need them later on.
On the right side of the new sensors you will see a blue green arrow, click them so the become blue, the devices will now be visible on the tabs in Domoticz.
Find the temperature device in "utility" and give it the name "DaikinTemp" (if you want another name, you need to also change the Lua script)
Find the on off device in switches and name it "DaikinHeat"

Installation instructions

Install the scripts

Script can be found here Domoticz Forum

or type in your terminal session:

sudo nano /home/pi/domoticz/scipts/daikin.sh

and paste this script and save it:

#!/bin/bash
argument="$1"
#
# Domoticz control for Daikin airconditioner/Heatpump systems with 
# online wifi controller.
# For this script to work you need to have installed curl and jq
# Read the post or wiki for installation instructions
#
# This script comes with no warranty ...use at own risk 
# Copyright (C) 2015  Peter H. Roubos, you can use this script or parts of this scripts to
# your own liking, but please share your edits and or comments with the community.
# 
# This program is free software; you can redistribute it and/or modify 
# it under the terms of the GNU General Public License as published by 
# the Free Software Foundation; version 2 of the License. 
# 
# This program is distributed in the hope that it will be useful, 
# but WITHOUT ANY WARRANTY; without even the implied warranty of 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
# GNU General Public License for more details. 
# 
# I use it in Domoticz but should work on every linux system
# Version 1.0 03/27/2015
#
# Change variables to your liking here

# Settings:
# Daikin IP Adress
	DIP=192.168.1.xx

# Domoticz port
	DomPort=8080

# On/Off button idx
	OoIdx=xx

# Temp idx
	TempIdx=xx

############################################################
# NO CHANGES AFTER THIS LINE ## NO CHANGES AFTER THIS LINE #
############################################################

# Control info url path
control="/aircon/get_control_info"
# Sensor info url path
sensors="/aircon/get_sensor_info"

# Get Domotics information on/off
DomOo=`curl -s "http://127.0.0.1:$DomPort/json.htm?type=devices&rid=$OoIdx" | jq '.result[0].Data'  | tr -d '"' `
# Get Domotics information Temperature
DomTemp=`curl -s "http://127.0.0.1:$DomPort/json.htm?type=devices&rid=$TempIdx" | jq '.result[0].Data'  | tr -d '"' `

# Set complete path for Daikin Contol
ControlInfoPath=http://$DIP$control
# Set complete path for Daikin Sensors
SensorsInfoPath=http://$DIP$sensors
ControlInfo=$(curl -s $ControlInfoPath)
SensorsInfo=$(curl -s $SensorsInfoPath)

# Get relevant control information from Daikin
ControlInfo=${ControlInfo//,/ [}
ControlInfo='['${ControlInfo//=/]=}
eval declare -A pump=($ControlInfo)

pow=( ${pump[pow]} )
mode=( ${pump[mode]} )
stemp=( ${pump[stemp]} )
shum=( ${pump[shum]} )
f_rate=( ${pump[f_rate]} )
f_dir=( ${pump[f_dir]} )



# Get Sensor information
SensorsInfo=${SensorsInfo//,/ [}
SensorsInfo='['${SensorsInfo//=/]=}
eval declare -A DaiSens=($SensorsInfo)

htemp=( ${DaiSens[htemp]} )
otemp=( ${DaiSens[otemp]} )
hhum=( ${DaiSens[hhum]} )

# If house temp is smaller than wanted temp then heat, else cool
if [ $htemp < $stemp ]; then
Daimode=4
else
Daimode=3
            fi
			
			
if [ $pow = "1" ]; then
Daipow=On
else
Daipow=Off
            fi
			
if [ $DomOo = "On" ]; then
Dompow=1
else
Dompow=0
            fi

if [ $argument = "check" ]; then

	if [ $Dompow != $pow ]; then
		curl  "http://127.0.0.1:$DomPort/json.htm?type=command&param=switchlight&idx=$OoIdx&switchcmd=$Daipow"
		fi
	
	if [ $stemp != $DomTemp ]; then
		curl  "http://127.0.0.1:$DomPort/json.htm?type=command&param=udevice&idx=$TempIdx&nvalue=0&svalue=$stemp"
		fi
	
else
curl --data "pow=$Dompow&mode=$Daimode&stemp=$DomTemp&shum=0&f_rate=A&f_dir=0" http://$DIP/aircon/set_control_info
	fi

Then type in your terminal session:

sudo nano /home/pi/domoticz/scipts/lua/script_device_DaikinTemp.lua
commandArray = {}

if(devicechanged['DaikinTemp']) then
    os.execute('/home/pi/domoticz/scripts/daikin.sh&')
end
return commandArray

and paste this script and save it:

Then type in your terminal session:

sudo nano /home/pi/domoticz/scipts/lua/script_device_DaikinHeat.lua
commandArray = {}

if(devicechanged['DaikinHeat']) then
    os.execute('/home/pi/domoticz/scripts/daikin.sh&')
end
return commandArray

and paste this script and save it:

Or download the zip file and extract the 3 scripts.
Put daikin.sh in /home/pi/domoticz/scipts
put the lua scripts in /home/pi/domoticz/scipts/lua

Make script executable

sudo chmod +x /home/pi/domoticz/scripts/daikin.sh

Putting your variables in the script

In your terminal type:

sudo nano /home/pi/domoticz/scipts/daikin.sh


and change the settings:


# Daikin IP Adress
   DIP=192.168.1.xx                                         #Put the ip adress of your Daikin wifi controller here

# Domoticz port
   DomPort=8080                                               #If domoticz is running on a different port then change it here
# On/Off button idx
   OoIdx=xx                                                      # The IDX of your DaikinHeat on of switch
# Temp idx
  TempIdx=xx                                                  # The IDX of your DaikinTemp Virtual Thermostat

Python alternative

If you prefer python as alternative to bash scripting you can use the following method.

  • Configure the router as described before to get static IP adresses.
  • You do not need jq and curl, so no need to install these (because the script uses json and urllib2 provided with every python installation, 'batteries included').
  • You do need python, which can be installed using 'sudo apt-get install python'.
  • Create the same virtual hardware and virtual switches as with the bash script, but also create virtual switches named 'DaikinCool' and 'DaikinQuiet' for the Daikin virtual hardware (the first to start cooling mode, the second to start silent operation). I chose not to auto-switch between cooling and heating, because generally you will want either of them and know which one.
  • You should create one lua script to launch the python script if you start heating, cooling, silent mode or change the temperature. This script is called script_device_Daikin.lua and is placed in /home/pi/domoticz/scripts/lua. It contains:
commandArray = {}
if(devicechanged['DaikinCool']) or (devicechanged['DaikinTemp']) or (devicechanged['DaikinHeat']) or (devicechanged['DaikinQuiet']) then
    os.execute('python /home/pi/domoticz/scripts/daikin.py&')
end
return commandArray
  • You have to change the IP address for the Daikin and the domoticz raspberry in the script to mimic your home network.
  • I currently do not synchronize the status of the Daikin if you start it with the app or the remote. You can therefore not see the change status if you use app/remote, but the domoticz interface will operate as expected.
  • Finally, create a file /home/pi/domoticz/scripts/daikin.py with the following content (replace the numbers in dom_names with the numbers in your own Domoticz setup):
import json
import urllib2

daikin_ip = '192.168.178.25'  # IP address of the Daikin
dom_ip =  '192.168.178.24' # IP address of Domoticz
dom_names = {'heat': 63, 'cool': 68, 'quiet': 69, 'setpoint': 62}

# Retrieve the domoticz state
dom_settings = {}
for dom_name, dom_idx in dom_names.items():
    data = urllib2.urlopen("http://{0}:8080/json.htm?type=devices&rid={1}".format(dom_ip, dom_idx)).read()
    data_dict = json.loads(data)  # Convert json string to python dictionary
    dom_settings[dom_name] = data_dict['result'][0]['Data']

# Create the correct settings for Daikin
print(dom_settings)
daikin_power = 1
daikin_mode = 0
if 'On' in dom_settings['cool'] and 'Off' in dom_settings['heat']:
    daikin_mode = 3 # Cool
elif 'Off' in dom_settings['cool'] and 'On' in dom_settings['heat']:
    daikin_mode = 4 # Heat
elif 'On' in dom_settings['cool'] and 'On' in dom_settings['heat']:
    daikin_mode = 0 # Auto
else:
    daikin_power = 0
daikin_setpoint = dom_settings['setpoint']
daikin_f_rate = 'B' if 'On' in dom_settings['quiet'] else 'A' # B=quiet mode, A=auto mode

# Provide the setings to the Daikin
urllib2.urlopen("http://{0}/aircon/set_control_info?pow={1}&mode={2}&stemp={3}&shum=0&f_rate={4}&f_dir=0".format(daikin_ip, daikin_power, daikin_mode, daikin_setpoint, daikin_f_rate))
print('Set Daikin to {0} and temperature {1} and mode to {2} and f_rate to {3}'.format(daikin_power, daikin_setpoint, daikin_mode, daikin_f_rate))

Let the script run every x minutes (cron)

The script needs to check if the heatpump changed state (by using the remote)

On the terminal, run crontab -e. In the screen that opens, this line

*/1 * * * * /home/pi/domoticz/scripts/daikin.sh check &

This will check the state of the daikin every minute, if you want it less frequent you can change the 1 (after */) in the number of minutes you want to check.

Thats it, now you can have fun, schedule, make blockly thingies etc...