I apologize, had some other stuff going on Installed per your instructions and it seems to be working. Only thing I noticed so far is setting “auto” via HomeKit gives “ERROR (SyncWorker_9) [homeassistant.components.daikinskyport.climate] Invalid mode for set_hvac_mode: heat_cool”. But its looking great!
It should be set to “auto” instead of “heat_cool”. Looks like an issue with how Homekit is trying to call the service. I don’t have any Homekit stuff, so I’m not much help in how to fix that.
I’ve added weather and made a few minor updates. I noticed that when dehumidification kicks in, cooling load goes to 0, so I added that as an attribute.
Does your hold until next schedule work? Mine reverts back after only a few seconds and doesn’t wait for the schedule. I disabled HA and it still does it.
Notice the dip in setpoints. That’s when my girlfriend tried to set a hold. I even rebooted the thermostat and it still happens. I think it’s a software bug.
EDIT: Nevermind, I must have sent it a bad value at some point. Nothing was selected when I looked at the hold settings. Selecting until next schedule works now.
Great! And I’m really not worried about the HomeKit auto setting. I usually just leave mine in cool mode and switch it during the few weeks in winter we need it down here! Plus I’m on the Apple beta’s, and they have been a little quirky at times.
And I just remembered in your first post, your said you weren’t “the best programmer”. I think you can edit that out now! Congrats on a great job!
Thanks. I got it working, but I’d still say the code is pretty bad. The ecobee code isn’t great either, though, so I don’t feel too bad. It was a big help that the ecobee is similar, so I was able to figure out what I needed to do. Without that code, I’d have been lost.
I’m still trying to figure out how I can make setting things more responsive. It’s not a huge deal, but when you change a setting, it’ll switch back and look like it didn’t work because HA polled the state before the thermostat wrote the new state to the API. My thought is maybe have the function check what info was sent to the thermostat and verify that it’s changed before updating HA. Do a retry like 5 times and then continue anyway if it still doesn’t show the correct state.
I have a guess based on my experience with the thermostat. I struggled trying to figure out why it wasn’t acting as I expected it to. The adjust mode doesn’t work the way it did on the Honeywell. Even when manually adjusting it then going back to schedule, I have to make sure both the adjust and schedule settings get modified. Seemed I was was having to make sure if I turned schedule on, I also had to manually turn adjust to off and vice versa. Is it possible that’s the same thing you are seeing?
No, the issue I’m seeing is if I for instance change from Auto to Cool in HA, it’ll send the command, then do an update to get the latest status from the thermostat, but the thermostat hasn’t had a chance to switch to Cool, yet. In HA, it looks like your setting didn’t work since it goes back to Auto, but if you wait 30 seconds or so, it’ll switch to Cool after the next update from the API.
So what I’m thinking is, look into the request being sent from HA and see what values should be different, then check the API every 2 seconds or so, up to 5x/10s or until the setting shows what you expect, then update HA. This should prevent that transient period.
Oh, and I did have a similar problem where after setting up my schedule the thermostat wouldn’t adhere to it. I just unplugged it and plugged it back in. Seems to work properly now.
Hey TrickerZ,
You’ve done some awesome work here! We’re getting a new AC and DaikinOne+ thermostat installed today and HA integration was one of my concerns when we decided to go with the Daikin. I am an active Python developer (or at least I so a good deal of Python programming as an electrical engineer), so I’ll definitely spend some time playing with your integration.
Thanks for all the work you’ve put into this already!
Thanks for your interest, I’m glad someone who knows what they’re doing can finally take a look. I have no idea why the services don’t work. I gave up. That’s the one major thing that needs fixing. I’ve made some little tweaks and fixes here and there, but haven’t changed a whole lot since the first few days I worked on it. I use it all the time, so other than the services, it works well. The other major task would be getting it into the HA github and pip. I asked around for help on that and never got a response. Since it works as is, I didn’t have the motivation to read through all the docs and figure it out.
Dude! I’m really just digging into everything you’ve done to get this up and going. Very nice work! Seriously, well done!
I have found a few small bugs in the code, but my HA install was woefully out of date and updating seems to have borked my entire setup, so I have no way of testing at the moment. I’ll keep going on this when I have time. Do you prefer I send you pull requests? Or should I just fork the repo and see where I get to?
Thanks! Do pull requests for now. Eventually I’d like to merge into the main home assistant github and just keep this for API info.
I just had a DaikinOne+ thermostat installed yesterday and I am curious if there have been any more updates to this integration. Sadly I’m not a programmer (at least not a very good one) so I can’t help with development but I’d be happy to test it out and give feedback.
Thanks,
No new updates. Everything works except the services as far as I can tell. @pdenson was going to start working on it, but I haven’t heard anything or seen any pull requests.
Hey everyone,
I did spend some hours getting into this and came up with a few changes, but nothing significant enough to warrant a pull or for everyone to update. Then our family got hit with flu and then winter break/vacation. I hope to be getting back into a regular with pattern soon. I’ll definitely keep everyone posted.
I’m finally getting around to trying to integrate the Daikin thermostat, does anybody have any further updates?
Only update has been that the integration can now be run properly from the custom components folder. I was hoping someone would help me with the services, but no luck yet.
Thanks for your excellent work decoding the Oneplus API. I had two installed last year with Daikin FIT systems. I replaced two Nest with the promise directly from a Daikin rep that an API and remote temperature sensors were coming. I like to get Temp and Hum data from the thermostats to display on in house HA web pages,an ISY 994 HA controller and to add to a mySQL DB for trending against outdoor weather and power consumption etc.
I converted your CURL statements to PHP to read the parameters from the two thermostats. With the FIT systems I get 1128 constants and variables from each unit. I use the attached PHP as an include file in my in house pages and cron scripts. I’ll probably modify it in the future to allow mode and set point changes.
Thanks again, it all works like a champ.
<?php
//This is PHP script to get readings from Daikin One Plus thermostats to incorporate into databases and web pages, etc.
//Based on the excellent work at https://github.com/apetrycki/daikinskyport
//CURL to PHP converted with help from https://incarnate.github.io/curl-to-php/
//This script was written for dual Daikin FIT systems. Each unit returns 1128 variables.
//Timer, used only to measure speed of site load. Should be removed if used as an include file in other pages.
$time = microtime();
$time = explode(' ', $time);
$time = $time[1] + $time[0];
$start = $time;
//end Timer
//Logon info
$myEmail = "YOUR EMAIL";
$myPassword = "YOUR PASSWORD";
//Convert Temperature celsius to fahrenheit
function c_to_f($temp)
{
$fahrenheit=$temp*9/5+32;
return $fahrenheit ;
}
//Get tokens from API
function getAPItokens($email,$pass){
$data = "{\"email\": \"$email\", \"password\": \"$pass\"}";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.daikinskyport.com/users/auth/login');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$headers = array();
$headers[] = 'Accept: application/json';
$headers[] = 'Content-Type: application/json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
function parseAPItokens($jsonFile){ //Parse token JSON file
$parsedJSON = json_decode($jsonFile);
$Out['accessToken'] = $parsedJSON->{'accessToken'};
$Out['accessTokenExpiresIn'] = $parsedJSON->{'accessTokenExpiresIn'};
$Out['refreshToken'] = $parsedJSON->{'refreshToken'};
$Out['tokenType'] = $parsedJSON->{'tokenType'};
return $Out;
}
function getDevices($accessToken){ //Get ONEPLUS devices
$data = "Authorization: Bearer $accessToken";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.daikinskyport.com/devices');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$headers = array();
$headers[] = 'Accept: application/json';
$headers[] = 'Content-Type: application/json';
$headers[] = $data;
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
function getParameters($device,$accessToken) {
//CURL the individual device parameters
$data = "Authorization: Bearer $accessToken";
$tempURL = "https://api.daikinskyport.com/deviceData/".$device;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $tempURL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$headers = array();
$headers[] = 'Accept: application/json';
$headers[] = $data;
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$deviceParam = curl_exec($ch);
curl_close($ch);
//----------------------------------------
return $deviceParam;
}
//main();
//Get API access and refresh tokens
$apiResult = getAPItokens($myEmail,$myPassword);
$apiData=parseAPItokens($apiResult);
//Assign tokens to variable
$apiToken = $apiData['accessToken'];
$apiRefreshToken = $apiData['refreshToken'];
//Get ONEPLUS Devices
$oneplusDevices = getDevices($apiToken);
//Split output into two files, one for each of two thermostats
$deviceJSON = str_split($oneplusDevices,strrpos($oneplusDevices,",{"));
$deviceJSON[0] = ltrim($deviceJSON[0],"[");
$deviceJSON[1] = ltrim($deviceJSON[1],",");
$deviceJSON[1] = rtrim($deviceJSON[1],"]");
//parse JSON
$deviceJSON0=json_decode($deviceJSON[0]);
$deviceJSON1=json_decode($deviceJSON[1]);
//Get Device ID and Name
$device1ID=$deviceJSON0->{'id'};
$device2ID=$deviceJSON1->{'id'};
$device1name=$deviceJSON0->{'name'};
$device2name=$deviceJSON1->{'name'};
//Get parameters from each device
$device1 = getParameters($device1ID,$apiToken);
$device1 = json_decode($device1);
$device2 = getParameters($device2ID,$apiToken);
$device2 = json_decode($device2);
//finally get the important info. on my FIT systems there are 1128 variables available per unit. Below are a few I am interested in.
//the function getParameters returns the available variables. Echo $device1 to see them all .
$tempOutdoor=$device1->{'tempOutdoor'};
$tempOutdoor=c_to_f($tempOutdoor);
$humOutdoor=$device1->{'humOutdoor'};
$tempIndoor1=$device1->{'tempIndoor'};
$tempIndoor1=c_to_f($tempIndoor1); //convert to fahrenheit
$spCool1=$device1->{'cspActive'};
$spCool1=c_to_f($spCool1); //convert to fahrenheit
$spHeat1=$device1->{'hspActive'};
$spHeat1=c_to_f($spHeat1); //convert to fahrenheit
$humIndoor1=$device1->{'humIndoor'};
$status1=$device1->{'equipmentStatus'};
if ($status1 == 1) {
$status1 = "Cooling";
}elseif ($status1 == 2) {
$status1 = "Dehumidifying";
}elseif ($status1 == 3) {
$status1 = "Heating";
}elseif ($status1 == 4) {
$status1 = "Fan";
}else{
$status1 = "Off";
}
$circFan1=$device1->{'fanCirculate'};
if ($circFan1 == 1) {
$circFan1 = "On";
}else{
$circFan1 = "Off";
}
$oneClean1=$device1->{'oneCleanFanActive'};
if ($oneClean1 == 1) {
$oneClean1 = "On";
}else{
$oneClean1 = "Off";
}
$indoorAirFlow1=$device1->{'ctIFCIndoorBlowerAirflow'};
$coilTemp1=$device1->{'ctOutdoorCoilTemperature'};
$liquidTemp1=$device1->{'ctOutdoorLiquidTemperature'};
$mode1=$device1->{'mode'};
if ($mode1 == 3) {
$mode1 = "Auto Heat/Cool";
}elseif ($mode1 == 2) {
$mode1 = "Cooling";
}elseif ($mode1 == 1) {
$mode1 = "Heating";
}else{
$mode1 = "Off";
}
$tempIndoor2=$device2->{'tempIndoor'};
$tempIndoor2=c_to_f($tempIndoor2); //convert to fahrenheit
$spCool2=$device2->{'cspActive'};
$spCool2=c_to_f($spCool2); //convert to fahrenheit
$spHeat2=$device2->{'hspActive'};
$spHeat2=c_to_f($spHeat2); //convert to fahrenheit
$humIndoor2=$device2->{'humIndoor'};
$status2=$device2->{'equipmentStatus'};
if ($status2 == 1) {
$status2 = "Cooling";
}elseif ($status2 == 2) {
$status2 = "Dehumidifying";
}elseif ($status2 == 3) {
$status2 = "Heating";
}elseif ($status2 == 4) {
$status2 = "Fan";
}else{
$status2 = "Off";
}
$circFan2=$device2->{'fanCirculate'};
if ($circFan2 == 1) {
$circFan2 = "On";
}else{
$circFan2 = "Off";
}
$oneClean2=$device2->{'oneCleanFanActive'};
if ($oneClean2 == 1) {
$oneClean2 = "On";
}else{
$oneClean2 = "Off";
}
$indoorAirFlow2=$device2->{'ctIFCIndoorBlowerAirflow'};
$coilTemp2=$device2->{'ctOutdoorCoilTemperature'};
$liquidTemp2=$device2->{'ctOutdoorLiquidTemperature'};
$mode2=$device2->{'mode'};
if ($mode2 == 3) {
$mode2 = "Auto Heat/Cool";
}elseif ($mode2 == 2) {
$mode2 = "Cooling";
}elseif ($mode2 == 1) {
$mode2 = "Heating";
}else{
$mode2 = "Off";
}
//I use the above as an include/required file, below is for demonstration.
//In time test this whole thing takes on average from 2 to 2.5 seconds on a RPI3 with a 1G connection, longer than I hoped.
echo "<br>--------Outdoor------------<br>";
echo " Temp:".$tempOutdoor."<br>";
echo " Hum:".$humOutdoor."<br>";
echo "<br>-------- ".$device2name." ------------<br>";
echo " Setpoints:".round($spHeat2,0)." / ".round($spCool2,0)."<br>";
echo " Temp:".$tempIndoor2."<br>";
echo " Hum:".$humIndoor2."<br>";
echo " Set Mode:".$mode2."<br>";
echo " Status:".$status2."<br>";
echo " Circulate:".$circFan2."<br>";
echo " One Clean:".$oneClean2."<br>";
echo " Air Flow:".$indoorAirFlow2."<br>";
echo " Coil Temp:".$coilTemp2."<br>";
echo " Liquid Temp:".$liquidTemp2."<br>";
echo " Cool %:".$testx."<br>";
echo "<br>-------- ".$device1name." ------------<br>";
echo " Setpoints:".round($spHeat1,0)." / ".round($spCool1,0)."<br>";
echo " Temp:".$tempIndoor1."<br>";
echo " Hum:".$humIndoor1."<br>";
echo " Set Mode:".$mode1."<br>";
echo " Status:".$status1."<br>";
echo " Circulate:".$circFan1."<br>";
echo " One Clean:".$oneClean1."<br>";
echo " Air Flow:".$indoorAirFlow1."<br>";
echo " Coil Temp:".$coilTemp1."<br>";
echo " Liquid Temp:".$liquidTemp1."<br>";
//Timer, used only to measure speed of site load. Should be removed if used as an include file in other pages.
$time = microtime();
$time = explode(' ', $time);
$time = $time[1] + $time[0];
$finish = $time;
$total_time = round(($finish - $start), 4);
echo "<br><i><div style='font-size:8pt';>Page generated in ".$total_time." seconds.</i></div>";
// end timer
?>
Very cool. Glad to see other people are using this.
If you’re using HA already, you may want to just add the extra info you want to the component and let HA poll it. I included most of the ones you’re grabbing already. I have HA save to influxdb and use grafana to display, but you could use pretty much anything. Not sure if that works for what you’re trying to do, but could speed up your loading instead of using the php.
Thanks, I am not using Home Assistant. I looked at it a few years ago and decided to develop my own pages and run them on and Raspberry Pi since at the time I found it easier to connect cameras and the ISY 994, pool controller etc. I have read HASS has come a long way so I plan to try the io implementation in a vbox machine when I get around to it, and I’ll certainly use your component especially if it is faster.
Thanks again for your work on this. I have given up on an official api.
I’m trying to implement it for my HA but I get the following error:
Error occurred loading configuration flow for integration daikinskyport: No module named 'custom_components.daikinskyport.config_flow'
Was wodnering if someone would be able to help?
I see daikinskyport.conf is created and seems to get the Token without issues.