OH2: Daikin BRP069B control. Http & rule based. (since OH1 binding is currently broken)

The OH1 Daikin binding is broken and does no longer work (at least not with my BRP069B device)

Here is an example how to gain control of your AC using the http binding and the REGEX transformation.
(install both in Paper UI !)

One ‘http://“ip”/aircon/get_control_info?’ returns multiple parameters. (try it in your browser)
Here are my items for picking out single values from the cache string:
ret=OK,pow=1,mode=4,adv=,stemp=24.0,shum=0,dt1=25.0,dt2=M,dt3=25.0,dt4=24.0,dt5=24.0,dt7=25.0,dh1=AUTO,dh2=50,dh3=0,dh4=0,dh5=0,dh7=AUTO,dhh=50,b_mode=4,b_stemp=24.0,b_shum=0,alert=255,f_rate=A,f_dir=0,b_f_rate=A,b_f_dir=0,dfr1=5,dfr2=5,dfr3=5,dfr4=A,dfr5=A,dfr6=5,dfr7=5,dfrh=5,dfd1=0,dfd2=0,dfd3=0,dfd4=0,dfd5=0,dfd6=0,dfd7=0,dfdh=0

http.cfg: (exchange 192.168.1.8 with your IP, set interval times to your liking)

# configuration of the first cache item
ACcache.url=http://192.168.1.8/aircon/get_control_info?
ACcache.updateInterval=10000
# configuration of the second cache item  
ACsensorCache.url=http://192.168.1.8/aircon/get_sensor_info?
ACsensorCache.updateInterval=60000

AC.items

// virtual items
Switch vACpowerState                                                           // 1=ON, 0=OFF
Number vACsetTemp        "Target temperature [%.0f °C]"       <temperature>
String vACmode           "Mode"                               <heating>
String vACfanRate        "Fan"                                <fan>

// http items
String ACpowerState                                                   {http="<[ACcache:6000:REGEX(.*?pow=.*?([0-9]*).*)]"}
String ACsetTemp                                                      {http="<[ACcache:1000:REGEX(.*?stemp=.*?([0-9\\.0-9]*).*)]"}
String ACmode                                                         {http="<[ACcache:1000:REGEX(.*?mode=.*?([0-9]*).*)]"}
String ACfanRate                                                      {http="<[ACcache:1000:REGEX(.*?f_rate=.*?([AB34567]*).*)]"}
String ACfanDir                                                       {http="<[ACcache:1000:REGEX(.*?f_dir=.*?([0-9\\.0-9]*).*)]"}
String ACinDoorTemp      "Inside temperature [%s °C]"  <temperature>  {http="<[ACsensorCache:1000:REGEX(.*?htemp=.*?([0-9\\.0-9]*).*)]"}
String ACoutDoorTemp     "Outside temperature [%s °C]" <temperature>  {http="<[ACsensorCache:1000:REGEX(.*?otemp=.*?([0-9\\.0-9]*).*)]"}
String NoDaikACinTempOut "Outside temperature not available (< 0 °C)" <temperature> // show this when outside temp == "" aka < 0 °C

.sitemap (proudly stolen from original binding example)

Text item=ac label="AC" icon="climate" {
	  Frame label="Settings"{
			Switch item=vACpowerState label="On/Off"
			Setpoint item=vACsetTemp minValue=18 maxValue=30 step=1 
			Switch item=vACmode mappings=["4"="Heat", "3"="Cool", "6"="Fan", "0"="Auto" ] label="Mode"                // not used: 2="Dry"  
			Switch item=vACfanRate mappings=[ "3"="1", "4"="2", "5"="3", "6"="4", "7"="5", "A"="Auto" ] label="Fan"   // not used: B="Silent" when setting B, AC returns A
	  }
	  Frame label="Temperature values" {
			Text item=ACoutDoorTemp   visibility=[ACoutDoorTemp != ""] 
			Text item=NoDaikACinTempOut visibility=[ACoutDoorTemp == ""] labelcolor=[ACoutDoorTemp== "" ="grey"]
			Text item=ACinDoorTemp 
	  }				
 }

ac.rules

var String acHost = "http://192.168.1.8:80/"
var String acCommandString = ""

 
rule "System start"
when
    System started
then
    // force an update to current values. A '-' could be sent to the AC, but is just ignored
    postUpdate(ACpowerState, "-")
    postUpdate(ACsetTemp,    "-")
    postUpdate(ACmode,       "-")
    postUpdate(ACfanRate,    "-")
end


// virtual AC items changed
rule 'vACpowerState'
when
    Item vACpowerState changed
then
    logInfo("vACpowerState", "vACpowerState=" + vACpowerState.state);
    var String newState
    if (vACpowerState.state == ON) newState="1" else newState="0"
    acCommandString = "aircon/set_control_info?pow=" + newState + "&mode=" + ACmode.state + "&stemp=" + ACsetTemp.state + "&shum=0&f_rate=" + ACfanRate.state + "&f_dir=" + ACfanDir.state     
    logInfo("vACpowerState", "acCommandString=" + acCommandString)
    logInfo("vACpowerState", "sendHttpPostRequest() returns: " + sendHttpPostRequest(acHost + acCommandString, 5000))
end      

rule 'vACsetTemp'
when
    Item vACsetTemp changed
then
    logInfo("ACsetTemp", "vACsetTemp=" + vACsetTemp.state)
    acCommandString = "aircon/set_control_info?pow=" + ACpowerState.state + "&mode=" + ACmode.state + "&stemp=" + vACsetTemp.state + ".0&shum=0&f_rate=" + ACfanRate.state + "&f_dir=" + ACfanDir.state     
    logInfo("ACsetTemp", "acCommandString=" + acCommandString)    
    logInfo("ACsetTemp", "sendHttpPostRequest() returns: " + sendHttpPostRequest(acHost + acCommandString, 5000))
end      

rule 'vACmode'
when
    Item vACmode changed
then
    logInfo("vACmode", "vACmode=" + vACmode.state) 
    acCommandString = "aircon/set_control_info?pow=" + ACpowerState.state + "&mode=" + vACmode.state + "&stemp=" + ACsetTemp.state + ".0&shum=0&f_rate=" + ACfanRate.state + "&f_dir=" + ACfanDir.state     
    logInfo("vACmode", "acCommandString=" + acCommandString)    
    logInfo("vACmode", "sendHttpPostRequest() returns: " + sendHttpPostRequest(acHost + acCommandString, 5000)) 
end      

rule 'vACfanRate'
when
    Item vACfanRate changed
then
    logInfo("vACfanRate", "vACfanRate=" + vACfanRate.state)
    acCommandString = "aircon/set_control_info?pow=" + ACpowerState.state + "&mode=" + ACmode.state + "&stemp=" + ACsetTemp.state + ".0&shum=0&f_rate=" + vACfanRate.state + "&f_dir=" + ACfanDir.state     
    logInfo("vACfanRate", "acCommandString=" + acCommandString)    
    logInfo("vACfanRate", "sendHttpPostRequest() returns: " + sendHttpPostRequest(acHost + acCommandString, 5000))
end      



// AC settings changed from APP or IR remote (remember: IR remote does not reflect changes made by APP or OH)
rule 'ACpowerUpdate'
when
    Item ACpowerState changed
then
    if (ACpowerState.state != "-") {
        if (ACpowerState.state == "1") postUpdate(vACpowerState, ON) else if (ACpowerState.state == "0") postUpdate(vACpowerState, OFF)
        logInfo("ACpowerUpdate", "vACpowerState=" + vACpowerState.state)
    }
end      

rule 'ACsetTempUpdate'
when
    Item ACsetTemp changed
then
    if (ACsetTemp.state != "-") {
        logInfo("ACsetTempUpdate", "ACsetTemp=" + ACsetTemp.state)
        postUpdate(vACsetTemp, Double::parseDouble(ACsetTemp.state.toString))
    }
end      

rule 'ACmodeUpdate'
when
    Item ACmode changed
then
    if (ACmode.state != "-") {
        logInfo("ACmode", "ACmode=" + ACmode.state)
        postUpdate(vACmode, ACmode.state)
    }
end      

rule 'ACfanRateUpdate'
when
    Item ACfanRate changed
then
    if (ACfanRate.state != "-") {
        logInfo("ACfanRate", "ACfanRate=" + ACfanRate.state)
        postUpdate(vACfanRate, ACfanRate.state)
    }
end      

Basic UI:

To change setting from any other rule, postUpdate to the virtual item.
Example; set temperature to 20 degrees: postUpdate(vACsetTemp, 20)

Have fun!
Please report back if this works on other WiFi adapters as well.

Daikin API

4 Likes

One hint from my side: If you want to draw charts of the temperatures, then you need number items you can persist and drawing charts of. Since the REGEX transformation always returns strings, it’s necessary to transform the strings into numbers. I did it this way (found here somewhere in the forum):

rule "Daikin SZ String to Number"
when
    Item DaikinSZTempIn_STR changed or DaikinSZTempOut_STR changed
then
    DaikinSZTempIn.postUpdate(Float::parseFloat(String::format("%s",DaikinSZTempIn_STR.state).replace(' ','')))
    DaikinSZTempOut.postUpdate(Float::parseFloat(String::format("%s",DaikinSZTempOut_STR.state).replace(' ','')))
end

Regarding compatibility: It works for me, but can’t tell what adapter I do use since my AC’s are built into furniture. But as long as it offers the http rest interface it should work.

Thanks for putting this together. Your timing coincides with my own work on this for my unit. I have a slightly different model of SkyFi (the NZ/AU BRP15A61 model) which I have found to be less than reliable with its stability. Specifically, sometimes i’ll request info from it, and the page will 404. Plus it has a slightly different return string than the other models i’ve encountered.

Because of this, last week I wrote a shell script to request info from the unit once rather than several times in the hopes of not overloading it. The shell script handles all the OH item updates by PUT.

The purpose of this script is simply to synchronise the state of the controller with my openHAB instance. I’m in the process of writing appropriate rules/scripts to allow control from OH but still need to iron out the kinks with regards to the times when the controller doesn’t respond and I need the rule to automatically retry until successful. Seeing yours has given me a few ideas, so thanks for that.

If anyone is interested, the script i’ve got working is below. Any tips on simplification are appreciated heh.

#!/bin/bash
argument="$1"

# This script GET's data from the SkyFi unit and updates OH to match.
# Version 1.0 03/10/2016

## Daikin Settings
# Daikin IP Address and Port
	DIP=192.168.1.39:2000
# Daikin SkyFi Password
  DPass=xxxxx

## OH Settings
# OH IP Address and Port
	OIP=192.168.1.20:8080
# On/Off button item name
	OoId=heatingDaikinPower
# Temp item name
	TempId=heatingDaikinTemp
# Temp sensor data
	TempIn=heatingDaikinTempIn
	TempOut=heatingDaikinTempOut
# Mode item name
	ModeId=heatingDaikinMode
# Fan speed item name
	FanSpId=heatingDaikinFanSp
# Fan speed item name
	FanModeId=heatingDaikinFanMode

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

# SkyFi info url path
skyfi="$DIP/ac.cgi?pass=$DPass"
skyfiset="$DIP/set.cgi?pass=$DPass"

# Set complete path for Daikin SkyFi Contol
SkyFiInfoPath=http://$skyfi
SkyFiInfo=$(curl --silent --header 'Content-Type: application/json' $SkyFiInfoPath)

#sleep 10

#echo $SkyFiInfo

# SkyFiInfo Will retun something like: opmode=0&units=.&settemp=24.0&fanspeed=3&fanflags=1&acmode=4&tonact=0&toffact=0&prog=0&time=21:27&day=4&roomtemp=14&outsidetemp=14&louvre=1&zone=0&flt=0&test0&errcode=&sensors=1

# Get relevant information from Daikin SkyFi unit
daikinArray=($SkyFiInfo)

IFS='&' read -r -a daikinArray <<<"$SkyFiInfo"
powStr=${daikinArray[0]}
stempStr=${daikinArray[2]}
f_rateStr=${daikinArray[3]}
f_modeStr=${daikinArray[4]}
modeStr=${daikinArray[5]}
htempStr=${daikinArray[11]}
otempStr=${daikinArray[12]}
dzoneStr=${daikinArray[14]}
filterStr=${daikinArray[15]}

# Variables from returned string
pow=${powStr//[^0-9]/} #Power on(1)/off(0)
mode=${modeStr//[^0-9]/}	#Mode (1=auto,2=heat,4=dry,8=cool,16=fan,9=cool/auto,3=heat/auto)
stemp=${stempStr:(-4)}	#Temperature set point
f_rate=${f_rateStr//[^0-9]/}	#Fan speed (1=low,2=med,3=high,5=low/auto,6=med/auto,7=high/auto)
f_mode=${f_modeStr//[^0-9]/}		#Fan (1 = Manual, 3= Auto)
htemp=${htempStr//[^0-9]/}	 	#Current Room Temp
otemp=${otempStr//[^0-9]/}	 	#Current Outside Temp
dzone=${dzoneStr//[^0-9]/}  	#Zones Enabled (Zone 1 = 128 Zone 2 = 64 Zone 3 = 32 Zone 4 = 16 Zone 5 = 8 Zone 6 = 4 Zone 7 = 2 Zone 8 = 1)
filter=${filterStr//[^0-9]/}	#Filter clean 1=yes

if [ "$pow" = "" ]; then
    echo error reading daikin controller
		exit
fi

###################################################
# POST temperature values to the openHAB REST API #
###################################################
curl --silent --header 'Content-Type: text/plain' --request PUT "http://$OIP/rest/items/$TempIn/state" --data $htemp
curl --silent --header 'Content-Type: text/plain' --request PUT "http://$OIP/rest/items/$TempOut/state" --data $otemp
curl --silent --header 'Content-Type: text/plain' --request PUT "http://$OIP/rest/items/$TempId/state" --data $stemp
curl --silent --header 'Content-Type: text/plain' --request PUT "http://$OIP/rest/items/$ModeId/state" --data $mode
curl --silent --header 'Content-Type: text/plain' --request PUT "http://$OIP/rest/items/$FanSpId/state" --data $f_rate
curl --silent --header 'Content-Type: text/plain' --request PUT "http://$OIP/rest/items/$FanModeId/state" --data $f_mode
#curl --silent --header 'Content-Type: text/plain' --request PUT "http://$OIP/rest/items/$OoId/state" --data $pow

case $pow in
     "0")
        curl --silent --header 'Content-Type: text/plain' --request PUT "http://$OIP/rest/items/$OoId/state" --data "OFF"
        ;;
     "1")
        curl --silent --header 'Content-Type: text/plain' --request PUT "http://$OIP/rest/items/$OoId/state" --data "ON"
        ;;
     *)
esac

echo Set power to $pow, mode to $mode, setpoint to $stemp, fan speed to $f_rate, fan mode to $f_mode, room temp to $htemp, and outside temp to $otemp.

Items

// Daikin
Switch  heatingDaikinPower      "Daikin Power"                  <switch>		        (gHeatpump)   
Number  heatingDaikinTemp       "Set Temp [%.1f °C]"		    <temperature_set>		(gHeatpump)   [ "TargetTemperature" ] 
Number  heatingDaikinTempIn     "Temp Inside [%.1f °C]"		    <temperature_inside>	(gHeatpump)
Number  heatingDaikinTempOut    "Temp Outside [%.1f °C]"		<temperature_outside>	(gHeatpump)    
String  heatingDaikinMode       "Mode [MAP(mode.map):%s]"            <mode>		            (gHeatpump)   [ "homekit:HeatingCoolingMode" ] 
String  heatingDaikinFanSp      "Fan Speed [MAP(fanspeed.map):%s]"   <fan>		            (gHeatpump)   
String  heatingDaikinFanMode    "Fan Mode [MAP(fanmode.map):%s]"     <fan_mode>		        (gHeatpump)   


String		heatingDaikinSync      												    { channel="exec:command:daikinSync:output" }
Switch		heatingDaikinSyncRun			"Grab latest sensor data"		<play>	{ channel="exec:command:daikinSync:run" }
Number		heatingDaikinSyncExit													{ channel="exec:command:daikinSync:exit" }
DateTime	heatingDaikinSyncLastExecution	"Last grabbed: [%1$tH:%1$tM]"	<clock>	{ channel="exec:command:daikinSync:lastexecution" }

Thing

//Daikin Sync from controller to OH
Thing exec:command:daikinSync "Daikin Sync to openHAB" @ "Heating" [command="/var/lib/openhab2/scripts/daikinSync.sh", interval=900, timeout=30, autorun=true]

I also started out with a script, but then I ‘saw the light’ with the HTTP binding :slight_smile:
My interface is, luckily, rock steady, quite close to my router.
Anyway, with this approach it is possible to tune into many variations of this theme.
I found an WEB regex parser most helpful for figuring out the regex transforms.
Also the openHAB plugin for Visual Studio Code is golden. (not M$ VS!)

Hello. Just a hint. I’m working on a MQTT based Daikin interface. It’s not natively for OH and requires some additional infrastructure (a server which hosts the interface and a MQTT broker).
However might be an option.
It’s work in progress but should be ready for (european) summer season.

I just tried this method on my 3 units and its is confirmed working with a BRP069B43 and BRP069B42 controller. They are essentially the same wifi units but one with has an additional controller. My Units are European build in 2014.

I have the room temperature already displayed in the homekit binding which is great as I can monitor room temps easily.

OMR this is really great work. Many thanks and respect for your hard work!! :+1:

1 Like

Gents, let me shift your focus to a new OH2-Daikin binding which is under development:
https://github.com/openhab/openhab2-addons/pull/3044
If that works, the workarounds with http & co will not be necessary anymore.

Thanks for pointing people to my new binding Boby. I’ve posted it up on the Eclipse IoT marketplace so while it is waiting to be merged with OpenHAB you can get it by following the steps here and then searching for OpenDaikin.

1 Like

Same here - I do confirm it’s working pretty fine with BRP069B42 and BRP069B43 (and yes - they are practically the same - just B43 has one more PCB as small AC units (25000 BTU or less) need additional module to connect the wi-fi adapter. My 3 units are 2012 (also European build). Already 3 months connected - flawlessly.

Great job and many thanks to the author of the binding!

If anyone else tries this, I’ve discovered my November 2018 Daikin US07 unit on OH V2.4 needs “sendHttpPostRequest” replacing with “sendHttpGetRequest,” and it doesn’t send back FAN and Airflow Direction Settings

Thanks for this. I just installed a BRP15B61 wifi adapter to a Daikin ducted system here in Australia.

The API is quite similar to the above, with some tweaks :slight_smile: Some details of what I discovered with Wireshark are at https://forums.whirlpool.net.au/forum-replies.cfm?t=2768285

The major difference is the location of scripts in /skyfi/aircon/get_control_info? vs /aircon/get_control_info?

Also some difference in the values for mode to set heat/cool/etc; and that there are only 3 fan speeds vs the 5 that get setup

Still working on fixing the tweaks, I’ll post the full changes once I’m done.

2 Likes

I’ve just ordered one of these, good luck.

I have some stuff ready for others to test, sing out when you get your adapter!

Cheers,

Paul