home-assistant / core

:house_with_garden: Open source home automation that puts local control and privacy first.
https://www.home-assistant.io
Apache License 2.0
72.81k stars 30.51k forks source link

KNX Connection loss results in loss of devices in Homebridge #11432

Closed jigfox closed 6 years ago

jigfox commented 6 years ago

Make sure you are running the latest version of Home Assistant before reporting an issue.

You should only file an issue if you found a bug. Feature and enhancement requests should go in the Feature Requests section of our community forum:

Home Assistant release (hass --version): 0.60.0

Python release (python3 --version): don't know I use hass.io on rpi

Component/platform: knx

Description of problem: if I loose the tunnel connection to the knx ip gateway, hass will report that the knx config is invalid, but it is valid, the gateway just couldn't be reached. And another Problem is that than the Homebridge add-on looses all devices, the home app looses the devices and associated scenes and rooms. after I reestablished the knx connection, I have to restart hass and Homebridge, the devices are added again to the home app, but all in the default room and without scenes created in Home App.

invalid

Expected: All devices will still show, but are marked as unavailable, this way you don't have to reorders the devices in their corresponding rooms in home APP.

Problem-relevant configuration.yaml entries and steps to reproduce:

knx:
  tunneling:
    host: '192.168.13.124'
    port: 3671
    local_ip: '192.168.13.60'
light:
  - platform: knx
    name: sleeping_main
    address: '0/0/22'
    state_address: '0/2/22'
  1. start hassio with disconnected knx
  2. start Homebridge add-on
  3. it starts with 0 devices, but it should have all configured devices

Additional info:

I really appreciate all your efforts to make this available as open source and since I am a software engineer I'd like to contribute, if someone could point me in the right direction where to look

Julius2342 commented 6 years ago

Hmm, see your point. So would de-couple the fact that the knx gateway could not be reached from adding the knx devices to hass - even if they then can't be connected.

I wonder if this would have any side effects.

Within async_setup_platform of knx lights I check the following:

    if DATA_KNX not in hass.data \
            or not hass.data[DATA_KNX].initialized:
        return False

We could set this earlier, even if the tunnel connection cant be established. We then just have to make sure that the connections is established afterwards if the tunnelling device becomes reachable again.

Julius2342 commented 6 years ago

This would be my approach to mitigate this:

 revert-knx-timeout-implementation*  julius@lars ~/Desktop/homeautomation/home-assistant:$ git diff
diff --git a/homeassistant/components/knx.py b/homeassistant/components/knx.py
index 3966b490f..2f492efb8 100644
--- a/homeassistant/components/knx.py
+++ b/homeassistant/components/knx.py
@@ -80,8 +80,11 @@ def async_setup(hass, config):
         yield from hass.data[DATA_KNX].start()

     except XKNXException as ex:
-        _LOGGER.exception("Can't connect to KNX interface: %s", ex)
-        return False
+        _LOGGER.warning("Can't connect to KNX interface: %s", ex)
+        hass.components.persistent_notification.async_create(
+            "Can't connect to KNX interface: <br>"
+            "<b>{0}</b>".format(ex),
+            title="KNX")

     for component, discovery_type in (
             ('switch', 'Switch'),
@@ -120,9 +123,9 @@ class KNXModule(object):
         """Initialization of KNXModule."""
         self.hass = hass
         self.config = config
-        self.initialized = False
         self.init_xknx()
         self.register_callbacks()
+        self.initialized = True

     def init_xknx(self):
         """Initialization of KNX object."""
@@ -139,7 +142,6 @@ class KNXModule(object):
             state_updater=self.config[DOMAIN][CONF_KNX_STATE_UPDATER],
             connection_config=connection_config)
         self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, self.stop)
-        self.initialized = True

     @asyncio.coroutine
     def stop(self, event):

If no gateway could be reached (e.g. bc of a temporary networking issue) it does not stop initializing the component and instead shows a persistent notification.

But if have no idea if this is "the HASS way" of doing this.

jigfox commented 6 years ago

Wow, that was fast, thank you all!

Julius2342 commented 6 years ago

@jigfox : May you try it out? (It worked on my env, but you never know). Its now within current dev branch of home-assistant.

jigfox commented 6 years ago

@Julius2342 it doesn't work for me, this is how I tried:

git checkout dev
git pull
git rev-parse HEAD # => 2ba9d825a074f50bd9a12185633805b12cb64c4c
docker build -t me/hass .
docker run -v /home/jigfox/config:/config -e "TZ=Europe/Berlin" -p 8123:8123 me/hass

with following config:

homeassistant:
  name: Home
  latitude: 52.7
  longitude: 5.4
  elevation: 40
  unit_system: metric
  time_zone: Europe/Berlin

frontend:

config:

http:

knx:
  tunneling:
    host: 192.168.13.124
    port: 3671
    local_ip: 192.168.13.60

light:
  - platform: knx
    name: office
    address: 0/0/15
    state_address: 0/2/15

I get still the same message and no switches in home assistant UI and also in homebridge. The Homebridge log looks like this:

[1/8/2018, 3:32:19 PM] Loaded plugin: homebridge-homeassistant
[1/8/2018, 3:32:19 PM] Registering platform 'homebridge-homeassistant.HomeAssistant'
[1/8/2018, 3:32:19 PM] ---
[1/8/2018, 3:32:19 PM] Loaded config.json with 0 accessories and 1 platforms.
[1/8/2018, 3:32:19 PM] ---
[1/8/2018, 3:32:19 PM] Loading 1 platforms...
[1/8/2018, 3:32:19 PM] [HomeAssistant] Initializing HomeAssistant platform...
[1/8/2018, 3:32:19 PM] [HomeAssistant] Fetching HomeAssistant devices.
[1/8/2018, 3:32:19 PM] Loading 0 accessories...
[1/8/2018, 3:32:19 PM] [HomeAssistant] Received event: ping
Julius2342 commented 6 years ago

hi @jigfox , i cant reproduce it here. I configured a tunnel gateway which is not reachable:

knx:
  tunneling:
    host: 192.168.0.132  <-- no gateway on this IP
    local_ip: 192.168.0.134

But the devices show up within hass:

not-available

Do you see anything within hass-logfiles?

jigfox commented 6 years ago

okay, I took a closer look at the logs from home-assistant:

2018-01-08 06:32:22 ERROR (MainThread) [homeassistant.setup] Error during setup of component knx
Traceback (most recent call last):
  File "/usr/src/app/homeassistant/setup.py", line 196, in _async_setup_component
    result = yield from component.async_setup(hass, processed_config)
  File "/usr/src/app/homeassistant/components/knx.py", line 80, in async_setup
    yield from hass.data[DATA_KNX].start()
  File "/usr/src/app/homeassistant/components/knx.py", line 144, in start
    connection_config=connection_config)
  File "/usr/local/lib/python3.6/site-packages/xknx/xknx.py", line 66, in start
    yield from self.knxip_interface.start()
  File "/usr/local/lib/python3.6/site-packages/xknx/io/knxip_interface.py", line 76, in start
    self.connection_config.gateway_port)
  File "/usr/local/lib/python3.6/site-packages/xknx/io/knxip_interface.py", line 106, in start_tunnelling
    yield from self.interface.start()
  File "/usr/local/lib/python3.6/site-packages/xknx/io/tunnel.py", line 73, in start
    yield from self.connect_udp()
  File "/usr/local/lib/python3.6/site-packages/xknx/io/tunnel.py", line 79, in connect_udp
    yield from self.udp_client.connect()
  File "/usr/local/lib/python3.6/site-packages/xknx/io/udp_client.py", line 167, in connect
    remote_addr=self.remote_addr)
  File "uvloop/loop.pyx", line 2673, in create_datagram_endpoint
  File "uvloop/loop.pyx", line 2658, in uvloop.loop.Loop.create_datagram_endpoint
OSError: [Errno 99] Cannot assign requested address
2018-01-08 06:32:22 INFO (MainThread) [homeassistant.core] Bus:Handling <Event call_service[L]: domain=persistent_notification, service=create, service_data=title=Invalid config, message=The following components and platforms could not be set up:

 - [knx](https://home-assistant.io/components/knx/)

Please check your config., notification_id=invalid_config, service_call_id=139862871707096-1>
2018-01-08 06:32:22 INFO (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=persistent_notification.invalid_config, old_state=None, new_state=<state persistent_notification.invalid_config=notifying; title=Invalid config, message=The following components and platforms could not be set up:

 - [knx](https://home-assistant.io/components/knx/)

Please check your config. @ 2018-01-08T15:32:22.859593+01:00>>
2018-01-08 06:32:22 INFO (MainThread) [homeassistant.core] Bus:Handling <Event service_executed[L]: service_call_id=139862871707096-1>
2018-01-08 06:32:22 ERROR (MainThread) [homeassistant.setup] Unable to setup dependencies of light.knx. Setup failed for dependencies: knx
2018-01-08 06:32:22 ERROR (MainThread) [homeassistant.setup] Unable to prepare setup for platform light.knx: Could not setup all dependencies.

it looks like there is a general knx problem, any ideas?

Julius2342 commented 6 years ago

Hi @jigfox,

if seen this error message previously when the tunnel configuration contained IP addresses from a different local network. This has to be solved within XKNX itself, i already created a ticket for this: https://github.com/XKNX/xknx/issues/89

(These networking errors have to be caught and properly handled).

jigfox commented 6 years ago

Hi @Julius2342,

thanks for your fast responses, since I'm working with a Mac --net=host doesn't work like on linux. But when I start the docker with --net=host it doesn't log any errors, but just warnings. It also initialises the switch for the one light. So I assume it is working. Thanks again, I really appreciate it!

2018-01-08 08:29:03 WARNING (MainThread) [homeassistant.components.knx] Can't connect to KNX interface: Could not establish connection
2018-01-08 08:29:03 INFO (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=light.office, old_state=None, new_state=<state light.office=unavailable; friendly_name=office, supported_features=0 @ 2018-01-08T17:29:03.085156+01:00>>
2018-01-08 08:29:03 INFO (MainThread) [homeassistant.loader] Loaded switch.knx from homeassistant.components.switch.knx
2018-01-08 08:29:03 INFO (MainThread) [homeassistant.components.climate] Setting up climate.knx
2018-01-08 08:29:03 INFO (MainThread) [homeassistant.loader] Loaded cover.knx from homeassistant.components.cover.knx
2018-01-08 08:29:03 INFO (MainThread) [homeassistant.components.sensor] Setting up sensor.knx
2018-01-08 08:29:03 INFO (MainThread) [homeassistant.components.binary_sensor] Setting up binary_sensor.knx
2018-01-08 08:29:03 INFO (MainThread) [homeassistant.components.notify] Setting up notify.knx
2018-01-08 08:29:03 INFO (MainThread) [homeassistant.core] Bus:Handling <Event call_service[L]: domain=group, service=set, service_data=object_id=all_lights, name=all lights, entities=['light.office'], visible=False, service_call_id=139884417719824-2>
2018-01-08 08:29:03 INFO (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=group.all_lights, old_state=None, new_state=<state group.all_lights=unknown; entity_id=('light.office',), order=0, auto=True, friendly_name=all lights, hidden=True, assumed_state=False @ 2018-01-08T17:29:03.092904+01:00>>