Daikin Component - no climate entities created - task exception

Yes…paste the error trace to see whats the pb @monkey-house

Here is what I get with “daikon:”:

2018-02-03 15:21:43 ERROR (MainThread) [homeassistant.components.sensor] Error while setting up platform daikin
Traceback (most recent call last):
  File "/usr/src/app/homeassistant/helpers/entity_component.py", line 189, in _async_setup_platform
    SLOW_SETUP_MAX_WAIT, loop=self.hass.loop)
  File "/usr/local/lib/python3.6/asyncio/tasks.py", line 358, in wait_for
    return fut.result()
  File "/usr/local/lib/python3.6/asyncio/futures.py", line 243, in result
    raise self._exception
  File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 56, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/app/homeassistant/components/sensor/daikin.py", line 48, in setup_platform
    api = daikin_api_setup(hass, host, name)
  File "/usr/src/app/homeassistant/components/daikin.py", line 105, in daikin_api_setup
    device = appliance.Appliance(host)
  File "/usr/local/lib/python3.6/site-packages/pydaikin/appliance.py", line 110, in __init__
    self.values.update(self.get_resource(resource))
  File "/usr/local/lib/python3.6/site-packages/pydaikin/appliance.py", line 115, in get_resource
    return self.parse_response(r.text)
  File "/usr/local/lib/python3.6/site-packages/pydaikin/entity.py", line 28, in parse_response
    raise ValueError("non-OK return on response")
ValueError: non-OK return on response

I have a few questions @monkey-house:

  1. Is it a Daikin or Daikon ?!?
  2. What operations can u control from the ios/android application ? Do u see both inside and outside temperature on the app ?
  3. Can you tell me if you enter in each of those links:
http://[daikin.ip]common/basic_info
http://[daikin.ip]/common/get_remote_method
http://[daikin.ip]/aircon/get_sensor_info
http://[daikin.ip]/aircon/get_model_info
http://[daikin.ip]/aircon/get_control_info
http://[daikin.ip]/aircon/get_timer
http://[daikin.ip]/aircon/get_target
http://[daikin.ip]/aircon/get_price
http://[daikin.ip]/aircon/get_program
http://[daikin.ip]/common/get_holiday
http://[daikin.ip]/common/get_notify
http://[daikin.ip]/aircon/get_week_power
http://[daikin.ip]/aircon/get_year_power
http://[daikin.ip]/aircon/get_scdltimer

Which are the ones that DON’T start their response with ret=OK ? I don’t need the entire response, just the links that don’t return that ret=OK.

In any case the pb seems to appear from a library that is not maintained anymore and the fix could take quite some time.

1 Like

Hi @rofrantz,
It is a Daikin model. Sorry for the typo. The unit is Thai. The adapter is European. These sell for half the rate of the Asian version and have more support on the Open Source scene.
In the EU Daikin app, I can change mode (dry, heat, fan, heating & cooling), change the target temp in relevant modes and see both indoor and outdoor temps. No control on fan speed and no humidity sensor available unfortunately.
I’ll run each command line when at home at a computer. Prob later today.
To be honest, I’m testing this way to compare with Broadlink RM 3 mini’s integration. Then I’ll make an informed decision concerning the other 5 units…

So all return ok, except:
Get_timer, get_program, get_holiday, get_notify & scdl_timer: ret=PARAM NG,msg=404 Not Found

I hope this helps & we can find a solution for the library…

Yes, it does. It means I need to make a small PR in that external library in order to avoid querying those endpoints that we don’t even need and then it will work 100%.
We have one option right now: u cand test locally a small change and confirm that everything is ok and then I’ll submit the PR since I dont wanna waste my free time for fixing a bug for an user that wants to combine an assian chicken head (the unit is Thai) with a european leg (the adapter is EU) and says that his Frankenstain doesn’t work. Beside u may not even buy this combination since u’re testing things that may not be even used by other people, so again I would waste time for this.

Please try to be honest and let know if u want to pursuit with this so u can apply that local change or if I should drop this.
Thanks in advance.

Basically, I ll keep that one ac unit working with the adapter no matter what. I may choose a different path for my other units depending on how well the integration works. You ll find that a lot of ther users from Australia and other places are doing the same with the mixing of heads and legs…
Please let me know what local changes are needed and whether these changes need to be reapplied on installation of updates of HA.
Thanks for your trouble!

Edit /usr/local/lib/python3.6/site-packages/pydaikin/appliance.py from the error trace and just delete the enpoints u mentioned earlier to me. They are in the 1st lines of code. Afyer that just restart HA and let me know if everything’s ok @monkey-house.

1 Like

Ok, will check asap and revert. Cheers

Ok, just tried this and here is the error message I got:

Log Details (ERROR)
Mon Feb 05 2018 14:42:39 GMT+0800 (WITA)

Error while setting up platform daikin
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/urllib3/connection.py", line 141, in _new_conn
    (self.host, self.port), self.timeout, **extra_kw)
  File "/usr/local/lib/python3.6/site-packages/urllib3/util/connection.py", line 83, in create_connection
    raise err
  File "/usr/local/lib/python3.6/site-packages/urllib3/util/connection.py", line 73, in create_connection
    sock.connect(sa)
OSError: [Errno 113] No route to host

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py", line 601, in urlopen
    chunked=chunked)
  File "/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py", line 357, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/usr/local/lib/python3.6/http/client.py", line 1239, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/usr/local/lib/python3.6/http/client.py", line 1285, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/usr/local/lib/python3.6/http/client.py", line 1234, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/usr/local/lib/python3.6/http/client.py", line 1026, in _send_output
    self.send(msg)
  File "/usr/local/lib/python3.6/http/client.py", line 964, in send
    self.connect()
  File "/usr/local/lib/python3.6/site-packages/urllib3/connection.py", line 166, in connect
    conn = self._new_conn()
  File "/usr/local/lib/python3.6/site-packages/urllib3/connection.py", line 150, in _new_conn
    self, "Failed to establish a new connection: %s" % e)
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0x7f326053cbe0>: Failed to establish a new connection: [Errno 113] No route to host

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/requests/adapters.py", line 440, in send
    timeout=timeout
  File "/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py", line 639, in urlopen
    _stacktrace=sys.exc_info()[2])
  File "/usr/local/lib/python3.6/site-packages/urllib3/util/retry.py", line 388, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='192.168.86.81', port=80): Max retries exceeded with url: /common/basic_info (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f326053cbe0>: Failed to establish a new connection: [Errno 113] No route to host',))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/src/app/homeassistant/helpers/entity_component.py", line 189, in _async_setup_platform
    SLOW_SETUP_MAX_WAIT, loop=self.hass.loop)
  File "/usr/local/lib/python3.6/asyncio/tasks.py", line 358, in wait_for
    return fut.result()
  File "/usr/local/lib/python3.6/asyncio/futures.py", line 243, in result
    raise self._exception
  File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 56, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/app/homeassistant/components/sensor/daikin.py", line 48, in setup_platform
    api = daikin_api_setup(hass, host, name)
  File "/usr/src/app/homeassistant/components/daikin.py", line 105, in daikin_api_setup
    device = appliance.Appliance(host)
  File "/usr/local/lib/python3.6/site-packages/pydaikin/appliance.py", line 110, in __init__
    self.values.update(self.get_resource(resource))
  File "/usr/local/lib/python3.6/site-packages/pydaikin/appliance.py", line 113, in get_resource
    r = self.session.get('http://%s/%s' % (self.ip, resource))
  File "/usr/local/lib/python3.6/site-packages/requests/sessions.py", line 521, in get
    return self.request('GET', url, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/requests/sessions.py", line 508, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python3.6/site-packages/requests/sessions.py", line 618, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/requests/adapters.py", line 508, in send
    raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='192.168.86.81', port=80): Max retries exceeded with url: /common/basic_info (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f326053cbe0>: Failed to establish a new connection: [Errno 113] No route to host',))

No component is created unfortunately. I understand if you do not wish to spend more time on my Frankenstein setup…

I think u modified wrong that file. Can u paste it here ?
U should’ve just removed thos endpoitns but i think u modified them instead of JUST DELETE a coupLe of lines. DO NOT MODIFY, just delete the lines taht contain: Get_timer, get_program, get_holiday, get_notify & scdl_time in the HTTP_RESOURCES constatnt. Nothing more

1 Like

Here is the code with deleted entries:

import pydaikin.entity as entity
import pydaikin.discovery as discovery

import socket
import requests

HTTP_RESOURCES = ['common/basic_info'
                  , 'common/get_remote_method'
                  , 'aircon/get_sensor_info'
                  , 'aircon/get_model_info'
                  , 'aircon/get_control_info'
                  , 'aircon/get_target'
                  , 'aircon/get_price'
                  , 'aircon/get_week_power'
                  , 'aircon/get_year_power'
              ]

VALUES_SUMMARY = ['name', 'ip', 'mac', 'mode', 'f_rate', 'f_dir'
                  , 'htemp', 'otemp', 'stemp'
                  , 'cmpfreq', 'en_hol', 'err']

VALUES_TRANSLATION = {
    'otemp'    : 'outside temp'
    , 'htemp'  : 'inside temp'
    , 'stemp'  : 'target temp'
    , 'ver'    : 'firmware adapter'
    , 'pow'    : 'power'
    , 'cmpfreq': 'compressor demand'
    , 'f_rate' : 'fan rate'
    , 'f_dir'  : 'fan direction'
    , 'err'    : 'error code'
    , 'en_hol' : 'away_mode'
}

TRANSLATIONS = {
    'mode' : {
        '2': 'dry',
        '3': 'cool',
        '4': 'hot',
        '6': 'fan',
        '0': 'auto',
        '1': 'auto-1',
        '7': 'auto-7',
        '10': 'off'
    },
    'f_rate' : {
        'A': 'auto',
        'B': 'silence',
        '3': '1',
        '4': '2',
        '5': '3',
        '6': '4',
        '7': '5'
    },
    'f_dir' : {
        '0': 'off',
        '1': 'vertical',
        '2': 'horizontal',
        '3': '3d'
    },
    'en_hol' : {
        '0': 'off',
        '1': 'on'
    }
}

def daikin_to_human(dimension, value):
    if value in TRANSLATIONS[dimension].keys():
        return TRANSLATIONS[dimension][value]
    else:
        return "UNKNOWN (%s)" % value

def human_to_daikin(dimension, value):
    ivd = {v: k for k, v in TRANSLATIONS[dimension].items()}
    return ivd[value]

def daikin_values(dimension):
    return sorted(list(TRANSLATIONS[dimension].values()))

class Appliance(entity.Entity):
    def __init__(self, id):

        entity.Entity.__init__(self)

        try:
            socket.inet_aton(id)
            ip = id  # id is an IP
        except socket.error:
            ip = None

        if None == ip:
            # id is a common name, try discovery
            e = discovery.get_name(id)
            if None == e:
                raise ValueError("no device found for %s" % id)

            ip = e['ip']

        self.ip = ip

        self.values['ip'] = ip

        with requests.Session() as self.session:
            for resource in HTTP_RESOURCES:
                self.values.update(self.get_resource(resource))

    def get_resource(self, resource):
        r = self.session.get('http://%s/%s' % (self.ip, resource))

        return self.parse_response(r.text)

    def show_values(self, only_summary = False):
        if only_summary:
            keys = VALUES_SUMMARY
        else:
            keys = sorted(self.values.keys())

        for key in keys:
            if key in self.values:
                (k, v) = self.represent(key)
                print ("%18s: %s" % (k, v))

    def translate_mac(self, value):
        r = ""
        for b in range(0, len(value)):
            r += value[b]
            if 1 == (b % 2) and b < len(value) - 1:
                r += ":"

        return r

    def represent(self, key):
        # adapt the key
        if key in VALUES_TRANSLATION:
            k = VALUES_TRANSLATION[key]
        else:
            k = key

        # adapt the value
        v = self.values[key]

        if (key == 'mode'):
            if self.values['pow'] == '0':
                v = 'off'
            else:
                v = daikin_to_human(key, v)

        elif (key in TRANSLATIONS.keys()):
            v = daikin_to_human(key, v)
        elif key == 'mac':
            v = self.translate_mac(v)

        return (k, v)

    def set(self, settings):
        # start with current values
        pow   = self.values['pow']
        mode  = self.values['mode']
        temp  = self.values['stemp']
        hum   = self.values['shum']
        fan   = self.values['f_rate']
        dir   = self.values['f_dir']
        hol   = self.values['en_hol']

        # update them with the ones requested
        if 'mode' in settings:
            # we are using an extra mode "off" to power off the unit
            if settings['mode'] == 'off':
                pow = '0'
                mode = human_to_daikin('mode', 'auto')
            else:
                if hol != "0":
                    raise ValueError("device is in holiday mode")

                pow = '1'
                mode = human_to_daikin('mode', settings['mode'])

        if 'stemp' in settings:
            temp = settings['stemp']

        if 'shum' in settings:
            hum = settings['shum']

        if 'f_rate' in settings:
            fan = human_to_daikin('f_rate', settings['f_rate'])

        if 'f_dir' in settings:
            dir = human_to_daikin('f_dir', settings['f_dir'])

        if 'en_hol' in settings:
            hol = human_to_daikin('en_hol', settings['en_hol'])    

        if not hum.isdigit():
            hum = '0'

        if not temp.isdigit():
            temp = '22'

        query_c = 'aircon/set_control_info?'
        query_c += ('pow=%s&mode=%s&stemp=%s&shum=%s&f_rate=%s&f_dir=%s' %
                    (pow, mode, temp, hum, fan, dir))

        query_h = 'common/set_holiday?'
        query_h += ('en_hol=%s' % hol)

        with requests.Session() as self.session:
            self.get_resource(query_h)
            if (hol == "0"):
                self.get_resource(query_c)

Is this what it should be? Do the changes to the .py file persist when changing to a different version of HA, say for example if I try the dev push?

The modificationa look ok. No route to host means u have network connections pbs. Can u try restarting both ur daikin and ur HA computer and see if the pbs persists ?
Indeed these changes will be lost if u upgrade HA but as i’ve told u earlier this is a temporary fix before i’ll fix it for good in that external library to make sure ot works first.
Let me know if its ok or not after u retry

Hi @rofrantz,

I had made a mistake and misspelled the appliance.py…

This is now working great on last night’s dev push. I can try it on 62.1 if that would help you troublshoot.

I have access to all modes that I can change on Daikin Europe’s app. The only thing that is unavailable is the outdoor sensor. I guess this is normal under HA’s Climate component rules. Can this still be accessed using the Daikin sensor component?

Thanks a lot for the help.

So basically my suggested fix works and I can apply it for real so u dont have to update it each time.
Regarding outside temperature if u cant see it in the ios/android app then I cant get it either. Try to turn on ur Daikin because also one my units reports it only when the ac is on. However in ur case I didnt saw otemp value in the common_info endpoint u pasted me in the begining.
Let me know.

Great news man. Good job. Do you think we’ll see this in 0.63?

The real fix consists in a pr in that external library as u saw and that library is not maintained as i’ve said earlier. I’ve tried to contact the mainer since last week but no feedback so far so i cant promise anything since its not depending on me but i’ll do my best.
U didnt told me if outside temps works from ios/android app or ha if u turn on ur ac unit

I can access outdoor temp in the Daikin app but not on HA:

climate.electric_room	Cool	current_temperature: 25
min_temp: 7
max_temp: 35
temperature: 25
target_temp_step: 1
operation_mode: Cool
operation_list: Cool,Auto,Dry,Fan,Hot,Off
unit_of_measurement: °C
friendly_name: Electric room
supported_features: 129

And which out of those values u “think” represents the outside temperature because my guess is that temperature = current temperature which represents the inside temperature.