Integration with Daikin Skyfi app (Air conditioning)

here is my logs for this version. I will give the test-environment atry tomorrow.

/ # pydaikin -p ##### -a -v 192.168.1.2
DEBUG:asyncio:Using selector: EpollSelector
DEBUG:pydaikin.daikin_base:Updating [‘ac.cgi?’, ‘zones.cgi?’]
DEBUG:pydaikin.daikin_skyfi:Parsing opmode=0&units=.&settemp=26.0&fanspeed=3&fanflags=1&acmode=8&tonact=0&toffact=0&prog=0&time=20:49&day=0&roomtemp=21&outsidetemp=19&louvre=0&zone=32&flt=0&test=0&errcode=&sensors=1
DEBUG:pydaikin.daikin_skyfi:Parsing nz=4&zone1=Bed%202%2C3%2C4&zone2=Bed%201%2C%20upsta&zone3=Family&zone4=Bed%205%2C%20lower
DEBUG:pydaikin.daikin_base:Represent: acmode, acmode, 8
acmode: 8
DEBUG:pydaikin.daikin_base:Represent: day, day, 0
day: 0
DEBUG:pydaikin.daikin_base:Represent: errcode, errcode,
errcode:
DEBUG:pydaikin.daikin_base:Represent: fanflags, fanflags, 1
fanflags: 1
DEBUG:pydaikin.daikin_base:Represent: fanspeed, fanspeed, 3
fanspeed: 3
DEBUG:pydaikin.daikin_base:Represent: flt, flt, 0
flt: 0
DEBUG:pydaikin.daikin_base:Represent: louvre, louvre, 0
louvre: 0
DEBUG:pydaikin.daikin_base:Represent: nz, nz, 4
nz: 4
DEBUG:pydaikin.daikin_base:Represent: opmode, opmode, 0
opmode: 0
DEBUG:pydaikin.daikin_base:Represent: outsidetemp, outsidetemp, 19
outsidetemp: 19
DEBUG:pydaikin.daikin_base:Represent: prog, prog, 0
prog: 0
DEBUG:pydaikin.daikin_base:Represent: roomtemp, roomtemp, 21
roomtemp: 21
DEBUG:pydaikin.daikin_base:Represent: sensors, sensors, 1
sensors: 1
DEBUG:pydaikin.daikin_base:Represent: settemp, settemp, 26.0
settemp: 26.0
DEBUG:pydaikin.daikin_base:Represent: test, test, 0
test: 0
DEBUG:pydaikin.daikin_base:Represent: time, time, 20:49
time: 20:49
DEBUG:pydaikin.daikin_base:Represent: toffact, toffact, 0
toffact: 0
DEBUG:pydaikin.daikin_base:Represent: tonact, tonact, 0
tonact: 0
DEBUG:pydaikin.daikin_base:Represent: units, units, .
units: .
DEBUG:pydaikin.daikin_base:Represent: zone, zone, 32
Traceback (most recent call last):
File “/usr/local/bin/pydaikin”, line 116, in
daikin.show_values(only_summary)
File “/usr/local/lib/python3.8/site-packages/pydaikin/daikin_base.py”, line 220, in show_values
(k, val) = self._represent(key)
File “/usr/local/lib/python3.8/site-packages/pydaikin/daikin_skyfi.py”, line 107, in _represent
val = list(str(bin(int(self[key])) + 256))[3:]
TypeError: can only concatenate str (not “int”) to str

Great! I’ve found that error too. I think we are quite close. Would be fun to see how the HA integration comes out.

I created a new VM and did exactly the docker command you said, this is the result:

    raise client_error(req.connection_key, exc) from exc
aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host 192.168.X.XX:80 ssl:None [Connect call failed ('192.168.X.XX', 80)]

192.168.X.XX is not a valid IP address…

Seriously, I’m not sure what is going on perhaps we need to make sure the pydaikin command works first.

Happy to test whatever commands you need.

I’ve decided there is no harm in showing you the internal IP address of my Daikin AC, so here is the full putty window:

2020-04-27 12:39:07 ERROR (MainThread) [homeassistant.components.daikin.config_flow] ClientError
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/aiohttp/connector.py", line 936, in _wrap_create_connection
    return await self._loop.create_connection(*args, **kwargs)  # type: ignore  # noqa
  File "/usr/local/lib/python3.8/asyncio/base_events.py", line 1025, in create_connection
    raise exceptions[0]
  File "/usr/local/lib/python3.8/asyncio/base_events.py", line 1010, in create_connection
    sock = await self._connect_sock(
  File "/usr/local/lib/python3.8/asyncio/base_events.py", line 924, in _connect_sock
    await self.sock_connect(sock, address)
  File "/usr/local/lib/python3.8/asyncio/selector_events.py", line 494, in sock_connect
    return await fut
  File "/usr/local/lib/python3.8/asyncio/selector_events.py", line 526, in _sock_connect_cb
    raise OSError(err, f'Connect call failed {address}')
ConnectionRefusedError: [Errno 111] Connect call failed ('192.168.1.48', 80)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home-assistant/homeassistant/components/daikin/config_flow.py", line 59, in _create_device
    device = await Appliance.factory(
  File "/usr/local/lib/python3.8/site-packages/pydaikin/daikin_base.py", line 74, in factory
    await appl.update_status(appl.HTTP_RESOURCES[:1])
  File "/usr/local/lib/python3.8/site-packages/pydaikin/daikin_base.py", line 165, in update_status
    self.values.update(await self._get_resource(resource))
  File "/usr/local/lib/python3.8/site-packages/pydaikin/daikin_base.py", line 143, in _get_resource
    return await self._run_get_resource(resource)
  File "/usr/local/lib/python3.8/site-packages/pydaikin/daikin_base.py", line 154, in _run_get_resource
    async with self.session.get(f'http://{self._device_ip}/{resource}') as resp:
  File "/usr/local/lib/python3.8/site-packages/aiohttp/client.py", line 1012, in __aenter__
    self._resp = await self._coro
  File "/usr/local/lib/python3.8/site-packages/aiohttp/client.py", line 480, in _request
    conn = await self._connector.connect(
  File "/usr/local/lib/python3.8/site-packages/aiohttp/connector.py", line 523, in connect
    proto = await self._create_connection(req, traces, timeout)
  File "/usr/local/lib/python3.8/site-packages/aiohttp/connector.py", line 858, in _create_connection
    _, proto = await self._create_direct_connection(
  File "/usr/local/lib/python3.8/site-packages/aiohttp/connector.py", line 1004, in _create_direct_connection
    raise last_exc
  File "/usr/local/lib/python3.8/site-packages/aiohttp/connector.py", line 980, in _create_direct_connection
    transp, proto = await self._wrap_create_connection(
  File "/usr/local/lib/python3.8/site-packages/aiohttp/connector.py", line 943, in _wrap_create_connection
    raise client_error(req.connection_key, exc) from exc
aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host 192.168.1.48:80 ssl:None [Connect call failed ('192.168.1.48', 80)]
^C
root@ubuntu:~# ping 192.168.1.48
PING 192.168.1.48 (192.168.1.48) 56(84) bytes of data.
64 bytes from 192.168.1.48: icmp_seq=1 ttl=255 time=2.11 ms
64 bytes from 192.168.1.48: icmp_seq=2 ttl=255 time=1.86 ms
64 bytes from 192.168.1.48: icmp_seq=3 ttl=255 time=1.89 ms
64 bytes from 192.168.1.48: icmp_seq=4 ttl=255 time=1.98 ms
64 bytes from 192.168.1.48: icmp_seq=5 ttl=255 time=1.84 ms
64 bytes from 192.168.1.48: icmp_seq=6 ttl=255 time=7.84 ms
^C
--- 192.168.1.48 ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5008ms
rtt min/avg/max/mdev = 1.842/2.924/7.846/2.203 ms

I get the same result.
Im pretty sure this should be using port 2000 not 80.

I’m going to take a moment here to publicly commend @fredrike for his extreme patience, persistence and skill in sorting this platform integration out.

Great work @fredrike!!! :clap: :clap: :clap:

For those wanting to see the latest version of the Daikin integration which incorporates SkyFi it is currently on the dev branch and working well. Presumably you could install it as a custom component and it will show up after a FULL hassio restart.

The SkyFi module is sensitive to everything, command order, http sessions, latency, you name it. As an early IOT device, I guess it is fair to say that it (SkyFi) solved the initial problem well enough, but by todays standards it is shall we say behind the times.

The SkyFi module is a Roving Networks RN171, essentially a customisable serial to network/web converter, it is also known as WiFly. If anyone feels the need to try and dig into the firmware, it is likely reasonably easy to break into and code adjusted: http://ww1.microchip.com/downloads/en/DeviceDoc/50002230B.pdf

2 Likes

A sincere thank you to @fredrike and everyone else who has contributed toward getting the SkyFi (BRP15A61) integration working :pray:

I’ve been running some very spaghetti-like node-red to automate my Daikin SkyFi system for a few years, and am now working to convert this to Home Assistant.

The most useful reference for SkiFi commands that I have found is this one; https://github.com/pabloNZ/DaikinSkyFiNZ/blob/826ad0f82e6c768bfe23bf695bcaeac85754a138/SkyFi%20http.txt , which will refer to below. I have found a few issues with this integration as follows:

  1. On these systems, the “auto” fan mode is in addition to the fan speed, not an alturnate to the fan speed (lines 19 to 32 of the link refers). In my node-red spaghetti when I send power on or off (/set.cgi?pass=XXXXX&p=1 or 0), the fan auto setting is retained at the previous state. When I use this integration to power off and then power on, fan auto is always set off. I notice that when my air con is running at “MED/AUTO” the reported state on the States page is “fan_mode: Medium”, which isn’t completely right. Fan auto state is idenitfyable from the “fanflags” attribute from the /ac.cgi or /set.cgi response.

  2. Only the first two of my three zones have been recognised (lines 72 to 85). The output of my /zones.cgi?pass=XXXXX is “nz=3&zone1=Lounge&zone2=Guest%20Room&zone3=Spare%20Room”, but a switch has not been created for the last zone. I’m not sure if there is a way to refresh the zone detection?

  3. The zone switches always show “off”, even with the zone on. When I toggle the zone switch on, it reverts to off within a few seconds. The log details are as follows:

Logger: homeassistant.core
Source: deps/lib/python3.8/site-packages/pydaikin/daikin_base.py:157
First occurred: 7:49:24 PM (1 occurrences)
Last logged: 7:49:24 PM

Error executing service: <ServiceCall climate.set_hvac_mode (c:a86ffc4b785d4a089aa7852247e4f22e): entity_id=['climate.daikin_ac'], hvac_mode=heat>
Traceback (most recent call last):
  File "/home/homeassistant/.pyenv/versions/3.8.0/lib/python3.8/site-packages/homeassistant/core.py", line 1269, in catch_exceptions
    await coro_or_task
  File "/home/homeassistant/.pyenv/versions/3.8.0/lib/python3.8/site-packages/homeassistant/core.py", line 1288, in _execute_service
    await handler.func(service_call)
  File "/home/homeassistant/.pyenv/versions/3.8.0/lib/python3.8/site-packages/homeassistant/helpers/entity_component.py", line 212, in handle_service
    await self.hass.helpers.service.entity_service_call(
  File "/home/homeassistant/.pyenv/versions/3.8.0/lib/python3.8/site-packages/homeassistant/helpers/service.py", line 453, in entity_service_call
    future.result()  # pop exception if have
  File "/home/homeassistant/.pyenv/versions/3.8.0/lib/python3.8/site-packages/homeassistant/helpers/entity.py", line 597, in async_request_call
    await coro
  File "/home/homeassistant/.pyenv/versions/3.8.0/lib/python3.8/site-packages/homeassistant/helpers/service.py", line 484, in _handle_entity_call
    await result
  File "/home/homeassistant/.pyenv/versions/3.8.0/lib/python3.8/site-packages/homeassistant/components/daikin/climate.py", line 192, in async_set_hvac_mode
    await self._set({ATTR_HVAC_MODE: hvac_mode})
  File "/home/homeassistant/.pyenv/versions/3.8.0/lib/python3.8/site-packages/homeassistant/components/daikin/climate.py", line 138, in _set
    await self._api.device.set(values)
  File "/mnt/dietpi_userdata/homeassistant/deps/lib/python3.8/site-packages/pydaikin/daikin_skyfi.py", line 141, in set
    await self.update_status([query_c])
  File "/mnt/dietpi_userdata/homeassistant/deps/lib/python3.8/site-packages/pydaikin/daikin_base.py", line 168, in update_status
    self.values.update(await self._get_resource(resource))
  File "/mnt/dietpi_userdata/homeassistant/deps/lib/python3.8/site-packages/pydaikin/daikin_base.py", line 144, in _get_resource
    return await self._run_get_resource(resource)
  File "/mnt/dietpi_userdata/homeassistant/deps/lib/python3.8/site-packages/pydaikin/daikin_skyfi.py", line 99, in _run_get_resource
    return await super()._run_get_resource(resource)
  File "/mnt/dietpi_userdata/homeassistant/deps/lib/python3.8/site-packages/pydaikin/daikin_base.py", line 157, in _run_get_resource
    return self.parse_response(await resp.text())
  File "/home/homeassistant/.pyenv/versions/3.8.0/lib/python3.8/site-packages/aiohttp/client_reqrep.py", line 1009, in text
    await self.read()
  File "/home/homeassistant/.pyenv/versions/3.8.0/lib/python3.8/site-packages/aiohttp/client_reqrep.py", line 973, in read
    self._body = await self.content.read()
  File "/home/homeassistant/.pyenv/versions/3.8.0/lib/python3.8/site-packages/aiohttp/streams.py", line 358, in read
    block = await self.readany()
  File "/home/homeassistant/.pyenv/versions/3.8.0/lib/python3.8/site-packages/aiohttp/streams.py", line 380, in readany
    await self._wait('readany')
  File "/home/homeassistant/.pyenv/versions/3.8.0/lib/python3.8/site-packages/aiohttp/streams.py", line 296, in _wait
    await waiter
  File "/home/homeassistant/.pyenv/versions/3.8.0/lib/python3.8/site-packages/aiohttp/helpers.py", line 586, in __exit__
    raise asyncio.TimeoutError from None
asyncio.exceptions.TimeoutError
  1. My logs are filled with updates failing or taking too long. I understand the connectivity of these units is flakey despite a decent signal strength, indeed a lot of my node-red spaghetti involves catching errors or re-sending if the state fails to change. In my experimentation I found the polling interval sweet-spot to be 20 seconds; more frequently and the device gets overloaded, less frequently and it seems to go to sleep. It definately cannot queue commands.

I’m very new to Home Assistant, so will not be surprised if there is something I have missed at my end. Now that I have this up and running, I would be pleased to do what I can to help test and troubleshoot to get this integration working as best we can.

Oh that seems complex… Could you send me a couple of examples?

edit, are you referring to: SkyFi http.txt#L34-L49 ? Home-Assistant only support a few modes: const.py#L25-L33. Or are you talking about more fan-modes?

edit2, I think you mean fan-rate and I’ve added a suggestion here: Bitbucket

It’s clearly a bug. The zone code have not been tested and is built from the information I found on the whirlpool forum.

edit, found the issue and updated the code @ Bitbucket

That log is just an example of timeout when setting mode to your unit. Do you always get that kind of log?

edit, found the issue and updated the code @ Bitbucket

Could you please paste some of the logs, I do retry five times with a slight delay between. But we probably should lower the logging. The updates take place every 60 seconds and that is currently not configurable.

I’m having trouble getting this integration working again after upgrade to your latest commit.

I’m running Home Assistant Core dev branch on DietPi. I tried switching to the python env and did pip3 list, but pydiakin wasn’t listed. So I just downloaded your BitBucket repository, and swapped in the latest versions of pydiakin, diakin_base.py and diakin_skyfi.py .

This resulted in the error:

Logger: homeassistant.components.daikin
Source: components/daikin/__init__.py:64
Integration: Daikin AC (documentation, issues)
First occurred: 2:46:11 PM (1 occurrences)
Last logged: 2:46:11 PM

Unexpected error creating device 192.168.1.10

I next tried entering the Python environment and upgrading to the latest version of the dev branch using pip3 install --upgrade git+git://github.com/home-assistant/home-assistant.git@dev. This didn’t work either.

Thinking I probably messed this up myself, I then reverted to my last backup (without HA installed), and reinstalled Home Assistant Core dev branch from scratch.

Now I am getting an “unexpected error” installing the Diakin AC integration. Log output is as follows:

Logger: homeassistant.components.daikin.config_flow
Source: deps/lib/python3.8/site-packages/pydaikin/daikin_skyfi.py:92
Integration: Daikin AC (documentation, issues)
First occurred: 8:23:54 PM (1 occurrences)
Last logged: 8:23:54 PM

Unexpected error creating device
Traceback (most recent call last):
  File "/home/homeassistant/.pyenv/versions/3.8.0/lib/python3.8/site-packages/homeassistant/components/daikin/config_flow.py", line 72, in _create_device
    device = await Appliance.factory(
  File "/mnt/dietpi_userdata/homeassistant/deps/lib/python3.8/site-packages/pydaikin/daikin_base.py", line 78, in factory
    await appl.init()
  File "/mnt/dietpi_userdata/homeassistant/deps/lib/python3.8/site-packages/pydaikin/daikin_skyfi.py", line 67, in init
    await self.update_status(self.HTTP_RESOURCES)
  File "/mnt/dietpi_userdata/homeassistant/deps/lib/python3.8/site-packages/pydaikin/daikin_base.py", line 168, in update_status
    self.values.update(await self._get_resource(resource))
  File "/mnt/dietpi_userdata/homeassistant/deps/lib/python3.8/site-packages/pydaikin/daikin_base.py", line 144, in _get_resource
    return await self._run_get_resource(resource)
  File "/mnt/dietpi_userdata/homeassistant/deps/lib/python3.8/site-packages/pydaikin/daikin_skyfi.py", line 107, in _run_get_resource
    return await super()._run_get_resource(resource)
  File "/mnt/dietpi_userdata/homeassistant/deps/lib/python3.8/site-packages/pydaikin/daikin_base.py", line 157, in _run_get_resource
    return self.parse_response(await resp.text())
  File "/mnt/dietpi_userdata/homeassistant/deps/lib/python3.8/site-packages/pydaikin/daikin_skyfi.py", line 92, in parse_response
    if response['fanflags'] == '3':
KeyError: 'fanflags'

Not sure if this a new bug in the integration, or if there something else amiss at my end? Any advise as to the smartest way to upgrade the integration only would be appreciated too.

It looks like an error from my side:

I’ve updated the code so if you replace the file /mnt/dietpi_userdata/homeassistant/deps/lib/python3.8/site-packages/pydaikin/daikin_skyfi.py with this one: https://bitbucket.org/mustang51/pydaikin/src/28302e6e5418488c600f10674e66f57a6db53d96/pydaikin/daikin_skyfi.py it should work (I made a stupid mistake in the parsing of the response).

That was simple enough to update, thanks.

Issue #1 appears solved; fanauto state is now retained when I toggle power off/on.

Issue #2; I’ve now only got the first of my three zones recognised with a switch created.

Issue #3; no change, but I agree the log previously provided was coincidental and not associated with toggling the switch.

Issue #4; error frequency seems reduced now. The most common error is:

Log Details (WARNING)
Logger: homeassistant.helpers.entity
Source: __main__.py:356
First occurred: 7:58:25 PM (5 occurrences)
Last logged: 8:09:37 PM

Update of sensor.daikin_ac_inside_temperature is taking over 10 seconds
Update of climate.daikin_ac is taking over 10 seconds

Not sure if there is much that can be done about that other than increasing the timeout?

I’ve had a database crash (after not paying attention to the size of it…) and the Daikin Integration wouldn’t work. So I figured simply deleting and re-adding would fix it, however it will not let me re-add:
image

Log entry:

2020-05-27 08:56:33 ERROR (MainThread) [homeassistant.components.daikin.config_flow] Unexpected error creating device
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/daikin/config_flow.py", line 77, in _create_device
    password=password,
  File "/usr/local/lib/python3.7/site-packages/pydaikin/daikin_base.py", line 78, in factory
    await appl.init()
  File "/usr/local/lib/python3.7/site-packages/pydaikin/daikin_skyfi.py", line 67, in init
    await self.update_status(self.HTTP_RESOURCES)
  File "/usr/local/lib/python3.7/site-packages/pydaikin/daikin_base.py", line 168, in update_status
    self.values.update(await self._get_resource(resource))
  File "/usr/local/lib/python3.7/site-packages/pydaikin/daikin_base.py", line 144, in _get_resource
    return await self._run_get_resource(resource)
  File "/usr/local/lib/python3.7/site-packages/pydaikin/daikin_skyfi.py", line 107, in _run_get_resource
    return await super()._run_get_resource(resource)
  File "/usr/local/lib/python3.7/site-packages/pydaikin/daikin_base.py", line 157, in _run_get_resource
    return self.parse_response(await resp.text())
  File "/usr/local/lib/python3.7/site-packages/pydaikin/daikin_skyfi.py", line 92, in parse_response
    if response['fanflags'] == '3':
KeyError: 'fanflags'

Ah ha!
helping a mate brand new to HA setup - and he has a original SkyFi for his Daikin and we tried to setup it and got the same error it seems… He is currently on 1.110.3

File "/usr/local/lib/python3.7/site-packages/pydaikin/daikin_skyfi.py", line 92, in parse_response
    if response['fanflags'] == '3':
KeyError: 'fanflags'

Initially was wondering if this old SkyFi was even support but i think it should be?

Thoughts for this error now?

This basics are/were definitely working, I’d suspect this is part of getting the zone controller integration right. As I don’t have zone controllers, I couldn’t help with testing of that part.

@Borgy, @markss: While trying to add support for more fanmodes as suggested in #169 I actually broke the integration. The fix is already in pydaikin #173 but I couldn’t get the changes into 0.110.4 (Bump pydaikin version to 2.1.0 by fredrike · Pull Request #36217 · home-assistant/core · GitHub).

There exists two options, either downgrade to 0.110.0 or replace /usr/local/lib/python3.7/site-packages/pydaikin/daikin_skyfi.py with this one: Bitbucket.
The real fix will show up in 0.111.0…

1 Like

@fredrike and @markss - Sorry I haven’t been able to help out more I have been out of the loop for a while. @fredrike has done a great job integrating skyfi into HA. Well done.

Hats Off to Great Work!
By any chance, could someone please help me with a step by step instruction on how to do this integration to HA? Thanks in advance.

Hey @sajesh if your HA is up to date, it is added via integration - DAIKIN

Thanks Mark, I have tried to do the integration already, unfortunately I get the unexpected error message for some reason and I though I might be missing a prerequisite for this to work. Currently I control my skyfi module using command line switches, it is bit of a pain but works most of the time.Error