KNX Cookbook

Tags: #<Tag:0x00007f73b48b7890> #<Tag:0x00007f73b48b7728> #<Tag:0x00007f73b48b7638>

This guide explores all the aspects of the KNX integration of Home Assistant.

[UPDATE 2019-08-15 by @Jpsy ]:
Sensor property address changed to state_address to reflect breaking changes in HA 0.97.
[UPDATE 2019-08-17 by @Jpsy]:
Cover invert_position property changed from true to false as old XKNX bug has been resolved by @farmio.
[UPDATE 2019-11-25 by @Jpsy]:
Details added about KNX IP Interfaces/Routers and basic configuration of the KNX integration.
[UPDATE 2020-05-09 by @Jpsy]:
Section “KNX switches and the state_address” added.
[UPDATE 2020-05-29 by @Jpsy]:
More details added to section “KNX switches and the state_address”.
[UPDATE 2020-06-01 by @Jpsy]:
Added: Exposing HA attributes to KNX. Note about KNX expose responding to GroupValueRead requests. Both pointed out by @farmio. Thanks Matthias!
[UPDATE 2020-09-20 by @Jpsy]:
All KNX examples updated to the new syntax of HA 0.115.
See: https://www.home-assistant.io/blog/2020/09/17/release-115/


Activate Home Assistant’s KNX integration

The KNX integration is a standard part of Home Assistant. To connect KNX to HA you will need a KNX IP Interface or a KNX IP Router. The difference between both is beyond the scope of this cookbook. But to summarize it in one sentence: The IP Interface is only capable of a limited number (often 5) of point-to-point connections between IP addresses and KNX addresses. The IP Router can do the same, but additionally provides a multicast IP address (default 224.0.23.1) that can connect an unlimited number of IP addresses to the KNX bus. According to the docs, HA’s KNX integration can handle both types of connections, but in my trials I was never able to establish a connection using the multicast method.

Luckily the KNX integration has a built in auto detection, that will try to automatically find your KNX IP Interface or IP Router for you. So all you have to do is to add this single line to your configuration.yaml and restart HA:

knx:

Check the log after restart to see whether the KNX integration succeeded in finding your KNX installation over the IP network.

If the auto detection fails, you can configure the KNX integration manually:

knx: 
  tunneling:
    host: 192.168.178.198
    port: 3671
    local_ip: 192.168.178.180

host is the IP address of your KNX IP Interface/Router.
local_ip is the IP address of your HA installation.
Both IP addresses can be looked up in your LAN router’s DHCP table. I strongly recommend, that you provided fixed IP addresses for both partners. This can usually be done in the settings of your DHCP server in your LAN router.

Both the auto detection as well as the manual configuration with tunneling: will create point-to-point connections between HA and your KNX installation.

I already mentioned that I was not able to create a multicast connection. I believe that this is a bug in the KNX integration. If you still want to try for yourself, here is the config that should establish the multicast routing connection:

knx: 
  routing:
    local_ip: 192.168.178.180

Again local_ip is the IP address of your HA installation.

General KNX setup

Now that your KNX integration is up and running let’s add some sensors and some actors.
The following example informs HA about sensors and actors on the KNX bus and connects them to new entities in HA. These entities will allow you to read the KNX sensor values within HA and to control the KNX actors out of HA.

knx:
  # As said above this should be all you need to get the KNX component up and running.
  # Auto config works nicely and usually no config data for your KNX ip tunnel is needed. 

  sensor:
    # get some sensor data from KNX into HA
    - name: Helligkeit Treppe oben
      state_address: '6/1/0'
      type: 'illuminance'
      # The entity_id of this sensor will be generated from the name by a slug function.
      # In this case, it will be sensor.helligkeit_treppe_oben
      # See dev tools' state page (icons at the bottom of left side menu) for a list of all entity_ids

  light:
    - name: 'Eltern Decke'
      # switched light
      address: '1/2/10'
      state_address: '1/2/11'
      # See "sensor" remarks above for an explanation of the resulting entity_ids
    - name: 'Eltern Bett'
      # dimmed light
      address: '1/2/12'
      state_address: '1/2/15'
      brightness_address: '1/2/13'
      brightness_state_address: '1/2/16' 

  cover:
    # KNX Covers are roller shutters and blinds.
    # See "sensor" remarks above for an explanation of the resulting entity_ids
    - name: "Eltern"
      move_long_address: '3/2/0'
      move_short_address: '3/2/1'
      position_address: '3/2/3'
      position_state_address: '3/2/2'
      travelling_time_up: 23
      travelling_time_down: 21
      invert_position: false
    - name: "Büro"
      move_long_address: '3/2/4'
      move_short_address: '3/2/5'
      position_address: '3/2/7'
      position_state_address: '3/2/6'
      travelling_time_up: 23
      travelling_time_down: 21
      invert_position: false

Using some values from HA within KNX

You may also want to send some sensor data from HA to KNX group addresses.
I.E. I found, that I do not need a costly KNX weather station. Instead I let HA read weather data from a free Internet provider (in this case: Dark Sky) and expose that data to KNX group addresses so it can be used by any module on the KNX bus.

# configuration.yaml example
sensor:
# Register with Dark Sky to retrieve current environment data.
# Registration is free for the amount of requests we need here.
  - platform: darksky
    api_key: YOUR_API_KEY
    language: en
    forecast:
      - 0
    hourly_forecast:
      - 0
    monitored_conditions:
      - temperature
      - humidity
      - pressure
      - wind_speed
      - wind_bearing

knx: 
  # Expose some of the above sensor data from HA to KNX group addresses.
  # To find the right "type" setting for each parameter, create a group address in ETS, 
  # add a consuming actor for this kind of parameter to it and check the properties pane. 
  # ETS will show you a data type (DPT) that you can compare to the available DPTs in the 
  # documentation of the HA KNX component.
  expose:
    - type: 'temperature'
      entity_id: 'sensor.dark_sky_temperature'
      address: '0/1/10'
    - type: 'humidity'
      entity_id: 'sensor.dark_sky_humidity'
      address: '0/1/11'
    - type: 'pressure'
      entity_id: 'sensor.dark_sky_pressure'
      address: '0/1/12'
    - type: 'DPT-9'
      entity_id: 'sensor.dark_sky_wind_speed'
      address: '0/1/13'
    - type: 'DPT-14'
      entity_id: 'sensor.dark_sky_wind_bearing'
      address: '0/1/14'

It is not only possible to expose HA device states to KNX but also HA device attributes.
Here is an example (courtesy of @farmio):

knx:
  expose:
    - type: 'percentU8'
      entity_id: 'light.any_platform.office'
      attribute: 'brightness'
      default: 0
      address: '1/2/3'

This way you can eg. visualize your Hue lamps brightness in KNX without an automation.
Just keep in mind that attributes may not always be set. Eg. a turned off light has no brightness attribute so you need to set a default .

Basic KNX automation

This example uses an automation that is activated by a KNX switch.

The automation then triggers a script that controls a KNX light and dims it down in 5 steps from 80% to 0% over a time span of 5 minutes.

Care must be taken to stop the script, when the light is otherwise switched (i.e., by its normal on/off KNX switch). If we don’t do that, the light will first switch correctly, but then the script will continue to run in the background and after the next delay has passed it will kick in again and activate its next dim level.

knx: 
  switch:
    - name: "Licht, Eltern Bett"
      # The normal on/off switch for the light
      address: '1/2/12'
    - name: "Licht, Eltern Bett, Fadeout"
      # The switch that triggers the dim script
      # This switch must be configured in ETS to send on when pressed and off when released
      address: '1/2/17'
  light:
    - name: 'Eltern Bett'
      # This is the light that we want to dim (more precisely it is the dimming actuator of the light).
      # It is directly controlled through the first switch above.
      # (Note that the switch shares its group address with this light and thus controls it over the KNX bus.)
      address: '1/2/12'
      state_address: '1/2/15'
      brightness_address: '1/2/13'
      brightness_state_address: '1/2/16' 

automation:
# start the dim script, if the dim switch is pressed
- id: light_eltern_bett_fadeout
  alias: Licht Eltern Bett Fade-Out
  trigger:
  - entity_id: switch.licht_eltern_bett_fadeout
    platform: state
    to: 'on'
  condition: []
  action:
  # in case the script was already running, we first stop it
  - service: script.turn_off
    entity_id: script.light_eltern_bett_fadeout
  - service: script.turn_on
    entity_id: script.light_eltern_bett_fadeout

# stop the dim script, if light is switched manually
- id: light_eltern_bett_fadeout_stop
  alias: Licht Eltern Bett Fade-Out STOP
  trigger:
  - entity_id: switch.licht_eltern_bett
    platform: state
    # no argument here = trigger with ANY state change
  condition: []
  action:
  - service: script.turn_off
    entity_id: script.light_eltern_bett_fadeout

script:
  light_eltern_bett_fadeout:
    alias: Licht Eltern Bett Fade-Out
    sequence:
      - service: light.turn_on
        entity_id: light.eltern_bett
        data:
          brightness_pct: 80
      - delay: '00:01:00'
      - service: light.turn_on
        entity_id: light.eltern_bett
        data:
          brightness_pct: 60
      - delay: '00:01:00'
      - service: light.turn_on
        entity_id: light.eltern_bett
        data:
          brightness_pct: 40
      - delay: '00:01:00'
      - service: light.turn_on
        entity_id: light.eltern_bett
        data:
          brightness_pct: 20
      - delay: '00:01:00'
      - service: light.turn_on
        entity_id: light.eltern_bett
        data:
          brightness_pct: 10
      - delay: '00:01:00'
      - service: light.turn_off
        entity_id: light.eltern_bett

Use KNX switches to control Philips Hue or Ikea Trådfri

In this example we will use two KNX switches to control the brightness and the color temperature of some Hue White Ambiance bulbs. We will also switch an Osram Smart+ (AKA Lightify) on-off-plug together with the Hues. This code is gerneric and should also work with other Zigbee based systems like Ikea Trådfri.

My personal setup uses two switches programmed on an MDT Glass Push Buttons II Smart device. Both switches are programmed to circle through a set of percent values with each push. One switch sends percent values for the brightness of the Hues (0, 1, 50, 100%), and the other one sends percent values for three different color temperatures (0, 50, 100%), which are mapped to warmest, medium, and coldest light temperature of the Hues. The MDT devices do in fact offer specialized controls to softly dim up and down through brightness and color, but I very much prefer fast switching between some predefined values.

Before you start, make sure that you have activated the Hue integration in HA, paired HA with your Hue bridge and that your Hue bulbs appear in HA’s overview page. In the example below the Hues have the entity_ids light.hue_couch_1, ...2, ...3. These entity_ids are derived from the names that you store in the Hue bridge through the Hue app. As always, use the dev tools’ state page (icons at the bottom of the left side menu) to check the available entity_ids in your own system.

knx: 

  sensor:
    - name: "Licht, Couch DimAbs"
      state_address: '1/1/52'
      type: "percent"    
    - name: "Licht, Couch FarbTemp"
      state_address: '1/1/54'
      type: "percent"

automation:
# handle brightness values > 0
- id: light_knx_to_hue_couch_percent
  alias: Licht Couch KNX an Hue PROZENT
  initial_state: 'on'
  trigger:
  - platform: state
    entity_id: sensor.licht_couch_dimabs
  condition:
  - condition: template
    value_template: '{{ (float(trigger.to_state.state) > 0) }}'
  action:
  # turn on / set brightness for the Hue bulbs
  - service: light.turn_on
    data_template:
      entity_id: light.hue_couch_1, light.hue_couch_2, light.hue_couch_3
      brightness: '{{ (float(trigger.to_state.state) * 255 / 100) | round(0) }}'
  # turn on the Osram on-off-plug
  - service: light.turn_on
    entity_id: light.steckdosenschalter_couch

# handle brightness value == 0  (which means OFF)
- id: light_knx_to_hue_couch_percent_off
  alias: Licht Couch KNX an Hue PROZENT AUS
  initial_state: 'on'
  trigger:
  - platform: state
    entity_id: sensor.licht_couch_dimabs
    to: '0'
  condition:
  action:
  - service: light.turn_off
    entity_id: light.hue_couch_1, light.hue_couch_2, light.hue_couch_3, light.steckdosenschalter_couch

# Handle color temp values
- id: light_knx_to_hue_couch_color
  alias: Licht Couch KNX an Hue FARBE
  initial_state: 'on'
  trigger:
  - platform: state
    entity_id: sensor.licht_couch_farbtemp
  condition:
  action:
  - service: light.turn_on
    data_template:
      entity_id: light.hue_couch_1, light.hue_couch_2, light.hue_couch_3
      # Do some math to convert 0...100% into the min/medium/max color temperature of your bulbs.
      # The color temperature is defined in Mireds instead of Kelvin (Mired = 1,000,000 / Kelvin).
      # The lowest and highest available Mired value is read from the attributes of one of the bulbs, 
      # so this works with Hue as well as Trådfri. 
      color_temp: '{{ ((1 - float(trigger.to_state.state) / 100) * (states.light.hue_couch_1.attributes.max_mireds - states.light.hue_couch_1.attributes.min_mireds) + states.light.hue_couch_1.attributes.min_mireds) | round(0) }}'

Remarks:

  • It would have been nicer to use numeric_state triggers instead of state triggers for these automations. But I did not have any luck with numeric_state. I guess this is because the percentage values from the KNX bus are read into HA as strings rather than integers. As we cannot use numeric_state, we have to do checks like above: 0 through conditions and value templates. This makes the automation blocks a bit more complex. On the other hand value templates are much more flexible, if you want to implement more complex behavior.

  • Instead of naming all of your single bulbs again and again in the above code, you can also group them into a “room” in the Hue app and use the entity_id of that room. This will shorten the code:

    ...
      data_template:
        entity_id: light.hue_raum_couch
    ...
    - service: light.turn_off
      entity_id: light.hue_raum_couch, light.steckdosenschalter_couch
    ...
      data_template:
        entity_id: light.hue_raum_couch
        color_temp: '{{ ((1 - float(trigger.to_state.state) / 100) * (states.light.hue_raum_couch.attributes.max_mireds - states.light.hue_raum_couch.attributes.min_mireds) + states.light.hue_raum_couch.attributes.min_mireds) | round(0) }}'
    

KNX switches and the state_address

In my examples above, I have defined KNX switch entities with an address property but without a state_address. I recommend, NOT to do that for most of your switches! If you omit the state_address, HA will not sync the state of its entity with the real KNX switch. HA will only be able to send to the switch but will not receive any changes of the switch state from the KNX bus. This is sometimes ok for simple trigger switches that are only “on” as long as you press them (as in my above examples). But if you want to show KNX switches in HA that really sync with the real state on the KNX bus you definitely have to add a state_address.

Here are two examples:

  switch:
    - name: "Sommer/Winter"
      address: '0/0/5'
      state_address: '0/0/5'
    - name: "Licht, Eltern Bett"
      address: '1/2/12'
      state_address: '1/2/15'

The second example is the typical setup where you have a group address (GA) for the switch actions and a separate GA for the status telegrams.
The first example shows a KNX setup that uses the same GA for both.

Quick background info:

Both setups are possible in KNX. The question whether you need two separate GAs for actions and status is beyond the scope of this posting. It depends on the available communication objects of your KNX devices and on the complexity of the logic that you are implementing in KNX. Usually you will want to implement separate GAs whenever possible. But for simple setups, an identical address is also fine. Especially if you use KNX switches that are only used to control HA and are not connected to any KNX actor, you will most definitely need to use a common GA for both. This is because otherwise there would be no device on the status GA that would answer GroupValueRead requests. HA’s KNX switches do NOT respond to GroupValueRead requests!
While this is true for KNX switches in HA, please also note that values that are exposed from HA to KNX through knx: expose: do answer to GroupValueRead requests. This can potentially cause problems when other KNX devices on the same GA also have their Read flag set.
Recommendation: Use the ETS diagnosis tool to understand the telegrams of your switches, actors and services on the KNX side and on the HA side.

Coming soon

Next chapters I plan to add to the KNX Cookbook:

  • How to debug KNX events and communication
  • How to send flags, values and strings to the KNX bus
  • Node RED and KNX
7 Likes

The KNX Cookbook was started before the Community Guides section existed and has now been moved over to here.

All discussions from before the move can be found in the original location:

1 Like

Hello, Thanks for your work.
I already have almost all my KNX devices working in Home Assistant but I need help to retrieve a temperature data from a sonoff sensor that I have exposed from HA to the KNX bus.
In the group monitor I see the temperature sent by the exposed entity but I cannot read that data again in HA to use it in a climate.

How I should proceed?

This is what I have:

/config/configuration.yaml

knx:
  expose:
  - type: 'temperature'
    entity_id: 'sensor.sensor_temperatura_00_01_00_habitacion_de_teo_interior'
    address: '3/3/1'

/config/knx_climate.yaml

  - name: 'floor_room_heating_00_02_00_first_floor_interior'
    temperature_address: '3/3/1'
    target_temperature_address: '3/1/5'
    target_temperature_state_address: '3/2/5'
    operation_mode_address: '3/1/4'
    operation_mode_state_address: '3/2/4'
    on_off_address: '3/0/6'
    on_off_state_address: '3/0/12'
    min_temp: 7.0
    max_temp: 25.0

I have also tried creating a sensor but it does not update the temperature either.

/config/knx_sensor.yaml

  - name: sensor.temperature_room_teo_00_02_00_first_plant_interior
    state_address: '3/3/1'
    type: 'temperature'

I hope you can understand, sorry if I had translation errors.

When I write the value manually in the KNX group monitor, then the value appears in HA, so I know I am on the right track.

What do I have to do to be able to recover the values ​​sent by the temperature sensor?

Update to HA 0.116 - this bug is fixed there. Good luck!

2 Likes

Perfect, it’s fixed. I’ve been with it for days and I didn’t see anything from the update. thanks

May I have another question?
If it’s not the right place, please don’t hesitate to point me in the right direction.

Now I have a similar problem with updating the Climate modes. Do you know if it will be fixed in an update?

Some modes update but not always do well, they go to standby mode and I don’t know why. With the Eco mode, it does not allow you to change the temperature manually, it returns to 7ºC alone and it gets stuck but change the mode.

Do you know anything about this?
Where can I see if they solve the error?
I’ve been looking here They say the error has been fixed but not for me.

/config/knx_climate.yaml

  - name: 'floor_room_heating_00_02_00_first_floor_interior'
    temperature_address: '3/3/1'
    target_temperature_address: '3/1/5'
    target_temperature_state_address: '3/2/5'
    operation_mode_address: '3/1/4'
    operation_mode_state_address: '3/2/4'
    on_off_address: '3/0/6'
    on_off_state_address: '3/0/12'
    min_temp: 7.0
    max_temp: 25.0

Hi @kachytronico,
did you monitor the communication on the KNX bus using ETS? It is important to find whether HA sends unexpected telegrams to the bus or whether HA does its job but the devices on the bus respond in an unexpected way. By debugging with ETS you can find logical flaws in your setup like wrong GA assignments, wrong KNX flags etc. There are many easy ways to break a KNX system. And the climate devices are definitely not the simplest on the bus. :wink:

1 Like

Hi @Jpsy,

Thanks four your guide! I have three questions, maybe you or some KNX guys here have some tipps for me :slight_smile:

Since Home Assistant and KNX only have entities and no devices in the integration, which recommendation would you give when naming many group addresses? I would like to find them easiely in the scene and automations GUI. Because in many rooms you have ceiling lights and you can’t add an HA area to the ‘entiey’ since it has no UUID?

I would like to use scenes in HA to get KNX driven lights and some other smart devices. Since there is no nesting for roomscenes to home scenes (like home scene night, enables room scenes night in every room) I use an automation here, but is it intended to activate multiple scenes at one time? I am asking because, yesterday I implemented that and had some stange behavior of some lights :rofl:

I would like to have an watchdog for the KNX communication, since either my gateway isn’t the best one or the Communication between Hass.io’s home assistant isn’t stable enought… you have an idea? I try to get information about the last event on the bus and with a threshold of 5min the connection should be checked. For now I check the latest of three values of my weather station but this is only a workaround I think.

I am looking forward four your debugging guide! I try to get an busmonitor with knxd working to check with the HA logbook what happens if I trigger the automation.

Thanks and best regards!
Eddy

Hi Eddy!

Groups:
I use nested light groups. Please note that there are really LIGHT groups available in HA. They do more than normal groups, i.e. they inherit more attributes from the grouped lights and they can control more properties of the grouped lights. Consistently these groups appear in the light domain, not in the group domain.

My scheme of nested light groups looks like this:

  light:
    - platform: group
        name: Alle Lichter
        entities:
        - light.innen
        - light.aussen
    # alias Alle Lichter -> Alles Licht
    - platform: group
        name: Alles Licht
        entities:
        - light.alle_lichter

    - platform: group
        name: innen
        entities:
        - light.obergeschoss
        - light.erdgeschoss
        - light.untergeschoss
    # alias innen -> drinnen
    - platform: group
        name: drinnen
        entities:
        - light.innen

    - platform: group
        name: aussen
        entities:
        - light.hauseingang
        - light.terrasse
        - light.balkon
        - light.garage_aussen
    # alias aussen -> draussen
    - platform: group
        name: draußen
        entities:
        - light.aussen

    - platform: group
        name: Obergeschoss
        entities:
        - light.eltern
        - light.buro
        - light.eltern_bad
        - light.kind
        - light.kind_bad
        - light.garderobe_og
        - light.galerie
    - platform: group
        name: Eltern
        entities:
        - light.eltern_bett
        - light.eltern_decke
    - platform: group
        name: Büro
        entities:
        - light.buro_decke
    - platform: group
        name: Eltern Bad
        entities:
        - light.eltern_bad_decke
        - light.eltern_bad_spiegel
    - platform: group
        name: Kind
        entities:
        - light.kind_schiene
        - light.kind_bett
    - platform: group
        name: Kind Bad
        entities:
        - light.kind_bad_decke
        - light.kind_bad_spiegel


    - platform: group
        name: Erdgeschoss
        entities:
        - light.kuche
        - light.kuche_tisch
        - light.esstisch
        - light.couch
        - light.bogenlampe
        - light.vorraum

    - platform: group
        name: Küche
        entities:
        - light.kuche_schiene
        - light.kuche_downlights
        - light.kuche_schranke
    - platform: group
        name: Küche ohne Schränke
        entities:
        - light.kuche_schiene
        - light.kuche_downlights

    # and so on
    # ...

Scenes:
I am currently not using scenes in HA. So no experience with nesting them.

Debugging:
To debug the communication on the KNX bus you do not need any extra tools. ETS contains a full monitoring and debugging suite.
If you have problems with your gateway you should really try to nail them down and solve them.
To rule out bus or LAN problems:
Usually your KNX bus power supply device is able to give you statistics on the KNX bus. So you can check for bus errors there. For your LAN I strongly recommend to use a LAN tester to check all your cables (~100 to 150 EUR). This is an invaluable device!
And: Don’t use WLAN anywhere between KNX and HA. This will never result in a stable system.

1 Like

Hi, I have setup the KNX integration and can control all the lights. I have one problem. If I restart Home Assistant I don´t get the states of the lights automatically. Is there a way to read the status of the lights after restart?

Hi @ingvarg, did you enter correct state_address GAs for your lights in the HA config? If so, did you monitor in ETS whether HA requests the light status on startup? And if so, does any KNX device answers to these status requests?

1 Like

Hi. The status of the lights updates in HA if I toggle the lights with the wall switches so I think the state_address is correct. I am not familiar with ETS. What tool is that?

Hi @ingvarg, this is a bit beyond this forum and this guide. But in a nutshell:

  • ETS is the programming software for KNX. I am confused that you don’t know about it. How did you program your KNX installation?
  • Switching a KNX light on is issued through a GroupValueWrite telegram on the bus. This is usually sent by a switch (but also by HA if you toggle the state of a KNX entity in HA). A corresponding KNX actor will listen to it and will switch on/off the lights. The KNX Group Address (GA) that is used for this communication is the one that must be entered as address in HA’s KNX config. HA listens to that address (just like the KNX actor does) to update the state of its corresponding entity.
    But there are also GroupValueRead telegrams that are answered by GroupValueResponse telegrams. These two are used if some device on the bus wants to know the current state of a device without changing it. The GA that is used for this communication is often called “State GA”. This is the one that must be entered as state_address in HA’s KNX config.
    When HA is restarted it actually issues a series of GroupValueReads to ask for the current state of all its KNX entities. If this communication fails, your HA entities are not synced with the state of the corresponding KNX devices.
    So if you have a correct address GA defined but a wrong state_address GA, your system will show exactly the malfunction that you have described. It is also possible, that the state GAs are not correctly defined within KNX itself. But as said - this forum is about HA, not about the depths of KNX.
1 Like

Hi, I did not do the installation of the KNX system. Thank you very much for you help

Oh, I see.
Then you should ask your integrator for a complete list of all GAs that s/he has defined in ETS.
ETS can create an export in XML and CSV format. Here is an example what you should expect (if you import CSV into Excel):

Note the pairs of GAs and state GAs starting at 1/0/10.
These are the pairs that you have to enter for KNX light entities in HA!