diff --git a/homeassistant/components/knx/climate.py b/homeassistant/components/knx/climate.py
index 2eb3b913195e85c8422bb7f8337b3d361f4c431f..879e1421bd4996eb0218ba1b4b760f3a1be21460 100644
--- a/homeassistant/components/knx/climate.py
+++ b/homeassistant/components/knx/climate.py
@@ -10,10 +10,15 @@ from xknx.devices import (
     ClimateMode as XknxClimateMode,
     Device as XknxDevice,
 )
+from xknx.devices.fan import FanSpeedMode
 from xknx.dpt.dpt_20 import HVACControllerMode, HVACOperationMode
 
 from homeassistant import config_entries
 from homeassistant.components.climate import (
+    FAN_HIGH,
+    FAN_LOW,
+    FAN_MEDIUM,
+    FAN_ON,
     ClimateEntity,
     ClimateEntityFeature,
     HVACAction,
@@ -126,6 +131,11 @@ def _create_climate(xknx: XKNX, config: ConfigType) -> XknxClimate:
         min_temp=config.get(ClimateSchema.CONF_MIN_TEMP),
         max_temp=config.get(ClimateSchema.CONF_MAX_TEMP),
         mode=climate_mode,
+        group_address_fan_speed=config.get(ClimateSchema.CONF_FAN_SPEED_ADDRESS),
+        group_address_fan_speed_state=config.get(
+            ClimateSchema.CONF_FAN_SPEED_STATE_ADDRESS
+        ),
+        fan_speed_mode=config[ClimateSchema.CONF_FAN_SPEED_MODE],
     )
 
 
@@ -166,6 +176,36 @@ class KNXClimate(KnxYamlEntity, ClimateEntity):
             self._attr_preset_modes = [
                 mode.name.lower() for mode in self._device.mode.operation_modes
             ]
+
+        fan_max_step = config[ClimateSchema.CONF_FAN_MAX_STEP]
+        self._fan_modes_percentages = [
+            int(100 * i / fan_max_step) for i in range(fan_max_step + 1)
+        ]
+        self.fan_zero_mode: str = config[ClimateSchema.CONF_FAN_ZERO_MODE]
+
+        if self._device.fan_speed is not None and self._device.fan_speed.initialized:
+            self._attr_supported_features |= ClimateEntityFeature.FAN_MODE
+
+            if fan_max_step == 3:
+                self._attr_fan_modes = [
+                    self.fan_zero_mode,
+                    FAN_LOW,
+                    FAN_MEDIUM,
+                    FAN_HIGH,
+                ]
+            elif fan_max_step == 2:
+                self._attr_fan_modes = [self.fan_zero_mode, FAN_LOW, FAN_HIGH]
+            elif fan_max_step == 1:
+                self._attr_fan_modes = [self.fan_zero_mode, FAN_ON]
+            elif self._device.fan_speed_mode == FanSpeedMode.STEP:
+                self._attr_fan_modes = [self.fan_zero_mode] + [
+                    str(i) for i in range(1, fan_max_step + 1)
+                ]
+            else:
+                self._attr_fan_modes = [self.fan_zero_mode] + [
+                    f"{percentage}%" for percentage in self._fan_modes_percentages[1:]
+                ]
+
         self._attr_target_temperature_step = self._device.temperature_step
         self._attr_unique_id = (
             f"{self._device.temperature.group_address_state}_"
@@ -322,6 +362,41 @@ class KNXClimate(KnxYamlEntity, ClimateEntity):
             )
             self.async_write_ha_state()
 
+    @property
+    def fan_mode(self) -> str:
+        """Return the fan setting."""
+
+        fan_speed = self._device.current_fan_speed
+
+        if not fan_speed or self._attr_fan_modes is None:
+            return self.fan_zero_mode
+
+        if self._device.fan_speed_mode == FanSpeedMode.STEP:
+            return self._attr_fan_modes[fan_speed]
+
+        # Find the closest fan mode percentage
+        closest_percentage = min(
+            self._fan_modes_percentages[1:],  # fan_speed == 0 is handled above
+            key=lambda x: abs(x - fan_speed),
+        )
+        return self._attr_fan_modes[
+            self._fan_modes_percentages.index(closest_percentage)
+        ]
+
+    async def async_set_fan_mode(self, fan_mode: str) -> None:
+        """Set fan mode."""
+
+        if self._attr_fan_modes is None:
+            return
+
+        fan_mode_index = self._attr_fan_modes.index(fan_mode)
+
+        if self._device.fan_speed_mode == FanSpeedMode.STEP:
+            await self._device.set_fan_speed(fan_mode_index)
+            return
+
+        await self._device.set_fan_speed(self._fan_modes_percentages[fan_mode_index])
+
     @property
     def extra_state_attributes(self) -> dict[str, Any] | None:
         """Return device specific state attributes."""
diff --git a/homeassistant/components/knx/const.py b/homeassistant/components/knx/const.py
index a7aee79426434d9f162fdf4ba91d8fc9d74537be..e22546d380696e531442fce5f1308a60ae9d888c 100644
--- a/homeassistant/components/knx/const.py
+++ b/homeassistant/components/knx/const.py
@@ -3,13 +3,13 @@
 from __future__ import annotations
 
 from collections.abc import Awaitable, Callable
-from enum import Enum
+from enum import Enum, StrEnum
 from typing import TYPE_CHECKING, Final, TypedDict
 
 from xknx.dpt.dpt_20 import HVACControllerMode
 from xknx.telegram import Telegram
 
-from homeassistant.components.climate import HVACAction, HVACMode
+from homeassistant.components.climate import FAN_AUTO, FAN_OFF, HVACAction, HVACMode
 from homeassistant.const import Platform
 from homeassistant.util.hass_dict import HassKey
 
@@ -129,6 +129,13 @@ class ColorTempModes(Enum):
     RELATIVE = "5.001"
 
 
+class FanZeroMode(StrEnum):
+    """Enum for setting the fan zero mode."""
+
+    OFF = FAN_OFF
+    AUTO = FAN_AUTO
+
+
 SUPPORTED_PLATFORMS_YAML: Final = {
     Platform.BINARY_SENSOR,
     Platform.BUTTON,
diff --git a/homeassistant/components/knx/schema.py b/homeassistant/components/knx/schema.py
index c31b3d30ad0693d758e493c4b2c326db527c98c9..cc65a399da7e0c2970dced407d83cc20589d52f7 100644
--- a/homeassistant/components/knx/schema.py
+++ b/homeassistant/components/knx/schema.py
@@ -7,7 +7,7 @@ from collections import OrderedDict
 from typing import ClassVar, Final
 
 import voluptuous as vol
-from xknx.devices.climate import SetpointShiftMode
+from xknx.devices.climate import FanSpeedMode, SetpointShiftMode
 from xknx.dpt import DPTBase, DPTNumeric
 from xknx.dpt.dpt_20 import HVACControllerMode, HVACOperationMode
 from xknx.exceptions import ConversionError, CouldNotParseTelegram
@@ -15,7 +15,7 @@ from xknx.exceptions import ConversionError, CouldNotParseTelegram
 from homeassistant.components.binary_sensor import (
     DEVICE_CLASSES_SCHEMA as BINARY_SENSOR_DEVICE_CLASSES_SCHEMA,
 )
-from homeassistant.components.climate import HVACMode
+from homeassistant.components.climate import FAN_OFF, HVACMode
 from homeassistant.components.cover import (
     DEVICE_CLASSES_SCHEMA as COVER_DEVICE_CLASSES_SCHEMA,
 )
@@ -54,6 +54,7 @@ from .const import (
     CONF_SYNC_STATE,
     KNX_ADDRESS,
     ColorTempModes,
+    FanZeroMode,
 )
 from .validation import (
     backwards_compatible_xknx_climate_enum_member,
@@ -341,6 +342,11 @@ class ClimateSchema(KNXPlatformSchema):
     CONF_ON_OFF_INVERT = "on_off_invert"
     CONF_MIN_TEMP = "min_temp"
     CONF_MAX_TEMP = "max_temp"
+    CONF_FAN_SPEED_ADDRESS = "fan_speed_address"
+    CONF_FAN_SPEED_STATE_ADDRESS = "fan_speed_state_address"
+    CONF_FAN_MAX_STEP = "fan_max_step"
+    CONF_FAN_SPEED_MODE = "fan_speed_mode"
+    CONF_FAN_ZERO_MODE = "fan_zero_mode"
 
     DEFAULT_NAME = "KNX Climate"
     DEFAULT_SETPOINT_SHIFT_MODE = "DPT6010"
@@ -348,6 +354,7 @@ class ClimateSchema(KNXPlatformSchema):
     DEFAULT_SETPOINT_SHIFT_MIN = -6
     DEFAULT_TEMPERATURE_STEP = 0.1
     DEFAULT_ON_OFF_INVERT = False
+    DEFAULT_FAN_SPEED_MODE = "percent"
 
     ENTITY_SCHEMA = vol.All(
         # deprecated since September 2020
@@ -423,6 +430,15 @@ class ClimateSchema(KNXPlatformSchema):
                 vol.Optional(CONF_MIN_TEMP): vol.Coerce(float),
                 vol.Optional(CONF_MAX_TEMP): vol.Coerce(float),
                 vol.Optional(CONF_ENTITY_CATEGORY): ENTITY_CATEGORIES_SCHEMA,
+                vol.Optional(CONF_FAN_SPEED_ADDRESS): ga_list_validator,
+                vol.Optional(CONF_FAN_SPEED_STATE_ADDRESS): ga_list_validator,
+                vol.Optional(CONF_FAN_MAX_STEP, default=3): cv.byte,
+                vol.Optional(
+                    CONF_FAN_SPEED_MODE, default=DEFAULT_FAN_SPEED_MODE
+                ): vol.All(vol.Upper, cv.enum(FanSpeedMode)),
+                vol.Optional(CONF_FAN_ZERO_MODE, default=FAN_OFF): vol.Coerce(
+                    FanZeroMode
+                ),
             }
         ),
     )
diff --git a/tests/components/knx/test_climate.py b/tests/components/knx/test_climate.py
index ec0498dc44798dda2edc1120ebac0ca5ea4fa111..487fab5d7232c4a588f21a4c3b575baf152071d8 100644
--- a/tests/components/knx/test_climate.py
+++ b/tests/components/knx/test_climate.py
@@ -439,3 +439,383 @@ async def test_command_value_idle_mode(hass: HomeAssistant, knx: KNXTestKit) ->
     knx.assert_state(
         "climate.test", HVACMode.HEAT, command_value=0, hvac_action=STATE_IDLE
     )
+
+
+async def test_fan_speed_3_steps(hass: HomeAssistant, knx: KNXTestKit) -> None:
+    """Test KNX climate fan speed 3 steps."""
+    await knx.setup_integration(
+        {
+            ClimateSchema.PLATFORM: {
+                CONF_NAME: "test",
+                ClimateSchema.CONF_TEMPERATURE_ADDRESS: "1/2/3",
+                ClimateSchema.CONF_TARGET_TEMPERATURE_ADDRESS: "1/2/4",
+                ClimateSchema.CONF_TARGET_TEMPERATURE_STATE_ADDRESS: "1/2/5",
+                ClimateSchema.CONF_FAN_SPEED_ADDRESS: "1/2/6",
+                ClimateSchema.CONF_FAN_SPEED_STATE_ADDRESS: "1/2/7",
+                ClimateSchema.CONF_FAN_SPEED_MODE: "step",
+                ClimateSchema.CONF_FAN_MAX_STEP: 3,
+            }
+        }
+    )
+
+    # read states state updater
+    await knx.assert_read("1/2/3")
+    await knx.assert_read("1/2/5")
+
+    # StateUpdater initialize state
+    await knx.receive_response("1/2/5", RAW_FLOAT_22_0)
+    await knx.receive_response("1/2/3", RAW_FLOAT_21_0)
+
+    # Query status
+    await knx.assert_read("1/2/7")
+    await knx.receive_response("1/2/7", (0x01,))
+    knx.assert_state(
+        "climate.test",
+        HVACMode.HEAT,
+        fan_mode="low",
+        fan_modes=["off", "low", "medium", "high"],
+    )
+
+    # set fan mode
+    await hass.services.async_call(
+        "climate",
+        "set_fan_mode",
+        {"entity_id": "climate.test", "fan_mode": "medium"},
+        blocking=True,
+    )
+    await knx.assert_write("1/2/6", (0x02,))
+    knx.assert_state("climate.test", HVACMode.HEAT, fan_mode="medium")
+
+    # turn off
+    await hass.services.async_call(
+        "climate",
+        "set_fan_mode",
+        {"entity_id": "climate.test", "fan_mode": "off"},
+        blocking=True,
+    )
+    await knx.assert_write("1/2/6", (0x0,))
+    knx.assert_state("climate.test", HVACMode.HEAT, fan_mode="off")
+
+
+async def test_fan_speed_2_steps(hass: HomeAssistant, knx: KNXTestKit) -> None:
+    """Test KNX climate fan speed 2 steps."""
+    await knx.setup_integration(
+        {
+            ClimateSchema.PLATFORM: {
+                CONF_NAME: "test",
+                ClimateSchema.CONF_TEMPERATURE_ADDRESS: "1/2/3",
+                ClimateSchema.CONF_TARGET_TEMPERATURE_ADDRESS: "1/2/4",
+                ClimateSchema.CONF_TARGET_TEMPERATURE_STATE_ADDRESS: "1/2/5",
+                ClimateSchema.CONF_FAN_SPEED_ADDRESS: "1/2/6",
+                ClimateSchema.CONF_FAN_SPEED_STATE_ADDRESS: "1/2/7",
+                ClimateSchema.CONF_FAN_SPEED_MODE: "step",
+                ClimateSchema.CONF_FAN_MAX_STEP: 2,
+            }
+        }
+    )
+
+    # read states state updater
+    await knx.assert_read("1/2/3")
+    await knx.assert_read("1/2/5")
+
+    # StateUpdater initialize state
+    await knx.receive_response("1/2/5", RAW_FLOAT_22_0)
+    await knx.receive_response("1/2/3", RAW_FLOAT_21_0)
+
+    # Query status
+    await knx.assert_read("1/2/7")
+    await knx.receive_response("1/2/7", (0x01,))
+    knx.assert_state(
+        "climate.test", HVACMode.HEAT, fan_mode="low", fan_modes=["off", "low", "high"]
+    )
+
+    # set fan mode
+    await hass.services.async_call(
+        "climate",
+        "set_fan_mode",
+        {"entity_id": "climate.test", "fan_mode": "high"},
+        blocking=True,
+    )
+    await knx.assert_write("1/2/6", (0x02,))
+    knx.assert_state("climate.test", HVACMode.HEAT, fan_mode="high")
+
+    # turn off
+    await hass.services.async_call(
+        "climate",
+        "set_fan_mode",
+        {"entity_id": "climate.test", "fan_mode": "off"},
+        blocking=True,
+    )
+    await knx.assert_write("1/2/6", (0x0,))
+    knx.assert_state("climate.test", HVACMode.HEAT, fan_mode="off")
+
+
+async def test_fan_speed_1_step(hass: HomeAssistant, knx: KNXTestKit) -> None:
+    """Test KNX climate fan speed 1 step."""
+    await knx.setup_integration(
+        {
+            ClimateSchema.PLATFORM: {
+                CONF_NAME: "test",
+                ClimateSchema.CONF_TEMPERATURE_ADDRESS: "1/2/3",
+                ClimateSchema.CONF_TARGET_TEMPERATURE_ADDRESS: "1/2/4",
+                ClimateSchema.CONF_TARGET_TEMPERATURE_STATE_ADDRESS: "1/2/5",
+                ClimateSchema.CONF_FAN_SPEED_ADDRESS: "1/2/6",
+                ClimateSchema.CONF_FAN_SPEED_STATE_ADDRESS: "1/2/7",
+                ClimateSchema.CONF_FAN_SPEED_MODE: "step",
+                ClimateSchema.CONF_FAN_MAX_STEP: 1,
+            }
+        }
+    )
+
+    # read states state updater
+    await knx.assert_read("1/2/3")
+    await knx.assert_read("1/2/5")
+
+    # StateUpdater initialize state
+    await knx.receive_response("1/2/5", RAW_FLOAT_22_0)
+    await knx.receive_response("1/2/3", RAW_FLOAT_21_0)
+
+    # Query status
+    await knx.assert_read("1/2/7")
+    await knx.receive_response("1/2/7", (0x01,))
+    knx.assert_state(
+        "climate.test", HVACMode.HEAT, fan_mode="on", fan_modes=["off", "on"]
+    )
+
+    # turn off
+    await hass.services.async_call(
+        "climate",
+        "set_fan_mode",
+        {"entity_id": "climate.test", "fan_mode": "off"},
+        blocking=True,
+    )
+    await knx.assert_write("1/2/6", (0x0,))
+    knx.assert_state("climate.test", HVACMode.HEAT, fan_mode="off")
+
+
+async def test_fan_speed_5_steps(hass: HomeAssistant, knx: KNXTestKit) -> None:
+    """Test KNX climate fan speed 5 steps."""
+    await knx.setup_integration(
+        {
+            ClimateSchema.PLATFORM: {
+                CONF_NAME: "test",
+                ClimateSchema.CONF_TEMPERATURE_ADDRESS: "1/2/3",
+                ClimateSchema.CONF_TARGET_TEMPERATURE_ADDRESS: "1/2/4",
+                ClimateSchema.CONF_TARGET_TEMPERATURE_STATE_ADDRESS: "1/2/5",
+                ClimateSchema.CONF_FAN_SPEED_ADDRESS: "1/2/6",
+                ClimateSchema.CONF_FAN_SPEED_STATE_ADDRESS: "1/2/7",
+                ClimateSchema.CONF_FAN_SPEED_MODE: "step",
+                ClimateSchema.CONF_FAN_MAX_STEP: 5,
+            }
+        }
+    )
+
+    # read states state updater
+    await knx.assert_read("1/2/3")
+    await knx.assert_read("1/2/5")
+
+    # StateUpdater initialize state
+    await knx.receive_response("1/2/5", RAW_FLOAT_22_0)
+    await knx.receive_response("1/2/3", RAW_FLOAT_21_0)
+
+    # Query status
+    await knx.assert_read("1/2/7")
+    await knx.receive_response("1/2/7", (0x01,))
+    knx.assert_state(
+        "climate.test",
+        HVACMode.HEAT,
+        fan_mode="1",
+        fan_modes=["off", "1", "2", "3", "4", "5"],
+    )
+
+    # set fan mode
+    await hass.services.async_call(
+        "climate",
+        "set_fan_mode",
+        {"entity_id": "climate.test", "fan_mode": "4"},
+        blocking=True,
+    )
+    await knx.assert_write("1/2/6", (0x04,))
+    knx.assert_state("climate.test", HVACMode.HEAT, fan_mode="4")
+
+    # turn off
+    await hass.services.async_call(
+        "climate",
+        "set_fan_mode",
+        {"entity_id": "climate.test", "fan_mode": "off"},
+        blocking=True,
+    )
+    await knx.assert_write("1/2/6", (0x0,))
+    knx.assert_state("climate.test", HVACMode.HEAT, fan_mode="off")
+
+
+async def test_fan_speed_percentage(hass: HomeAssistant, knx: KNXTestKit) -> None:
+    """Test KNX climate fan speed percentage."""
+    await knx.setup_integration(
+        {
+            ClimateSchema.PLATFORM: {
+                CONF_NAME: "test",
+                ClimateSchema.CONF_TEMPERATURE_ADDRESS: "1/2/3",
+                ClimateSchema.CONF_TARGET_TEMPERATURE_ADDRESS: "1/2/4",
+                ClimateSchema.CONF_TARGET_TEMPERATURE_STATE_ADDRESS: "1/2/5",
+                ClimateSchema.CONF_FAN_SPEED_ADDRESS: "1/2/6",
+                ClimateSchema.CONF_FAN_SPEED_STATE_ADDRESS: "1/2/7",
+                ClimateSchema.CONF_FAN_SPEED_MODE: "percent",
+            }
+        }
+    )
+
+    # read states state updater
+    await knx.assert_read("1/2/3")
+    await knx.assert_read("1/2/5")
+
+    # StateUpdater initialize state
+    await knx.receive_response("1/2/5", RAW_FLOAT_22_0)
+    await knx.receive_response("1/2/3", RAW_FLOAT_21_0)
+
+    # Query status
+    await knx.assert_read("1/2/7")
+    await knx.receive_response("1/2/7", (84,))  # 84 / 255 = 33%
+    knx.assert_state(
+        "climate.test",
+        HVACMode.HEAT,
+        fan_mode="low",
+        fan_modes=["off", "low", "medium", "high"],
+    )
+
+    # set fan mode
+    await hass.services.async_call(
+        "climate",
+        "set_fan_mode",
+        {"entity_id": "climate.test", "fan_mode": "medium"},
+        blocking=True,
+    )
+    await knx.assert_write("1/2/6", (168,))  # 168 / 255 = 66%
+    knx.assert_state("climate.test", HVACMode.HEAT, fan_mode="medium")
+
+    # turn off
+    await hass.services.async_call(
+        "climate",
+        "set_fan_mode",
+        {"entity_id": "climate.test", "fan_mode": "off"},
+        blocking=True,
+    )
+    await knx.assert_write("1/2/6", (0x0,))
+    knx.assert_state("climate.test", HVACMode.HEAT, fan_mode="off")
+
+    # check fan mode that is not in the fan modes list
+    await knx.receive_write("1/2/6", (127,))  # 127 / 255 = 50%
+    knx.assert_state("climate.test", HVACMode.HEAT, fan_mode="medium")
+
+    # check FAN_OFF is not picked when fan_speed is closest to zero
+    await knx.receive_write("1/2/6", (3,))
+    knx.assert_state("climate.test", HVACMode.HEAT, fan_mode="low")
+
+
+async def test_fan_speed_percentage_4_steps(
+    hass: HomeAssistant, knx: KNXTestKit
+) -> None:
+    """Test KNX climate fan speed percentage with 4 steps."""
+    await knx.setup_integration(
+        {
+            ClimateSchema.PLATFORM: {
+                CONF_NAME: "test",
+                ClimateSchema.CONF_TEMPERATURE_ADDRESS: "1/2/3",
+                ClimateSchema.CONF_TARGET_TEMPERATURE_ADDRESS: "1/2/4",
+                ClimateSchema.CONF_TARGET_TEMPERATURE_STATE_ADDRESS: "1/2/5",
+                ClimateSchema.CONF_FAN_SPEED_ADDRESS: "1/2/6",
+                ClimateSchema.CONF_FAN_SPEED_STATE_ADDRESS: "1/2/7",
+                ClimateSchema.CONF_FAN_SPEED_MODE: "percent",
+                ClimateSchema.CONF_FAN_MAX_STEP: 4,
+            }
+        }
+    )
+
+    # read states state updater
+    await knx.assert_read("1/2/3")
+    await knx.assert_read("1/2/5")
+
+    # StateUpdater initialize state
+    await knx.receive_response("1/2/5", RAW_FLOAT_22_0)
+    await knx.receive_response("1/2/3", RAW_FLOAT_21_0)
+
+    # Query status
+    await knx.assert_read("1/2/7")
+    await knx.receive_response("1/2/7", (64,))  # 64 / 255 = 25%
+    knx.assert_state(
+        "climate.test",
+        HVACMode.HEAT,
+        fan_mode="25%",
+        fan_modes=["off", "25%", "50%", "75%", "100%"],
+    )
+
+    # set fan mode
+    await hass.services.async_call(
+        "climate",
+        "set_fan_mode",
+        {"entity_id": "climate.test", "fan_mode": "50%"},
+        blocking=True,
+    )
+    await knx.assert_write("1/2/6", (128,))  # 128 / 255 = 50%
+    knx.assert_state("climate.test", HVACMode.HEAT, fan_mode="50%")
+
+    # turn off
+    await hass.services.async_call(
+        "climate",
+        "set_fan_mode",
+        {"entity_id": "climate.test", "fan_mode": "off"},
+        blocking=True,
+    )
+    await knx.assert_write("1/2/6", (0x0,))
+    knx.assert_state("climate.test", HVACMode.HEAT, fan_mode="off")
+
+    # check fan mode that is not in the fan modes list
+    await knx.receive_write("1/2/6", (168,))  # 168 / 255 = 66%
+    knx.assert_state("climate.test", HVACMode.HEAT, fan_mode="75%")
+
+
+async def test_fan_speed_zero_mode_auto(hass: HomeAssistant, knx: KNXTestKit) -> None:
+    """Test KNX climate fan speed 3 steps."""
+    await knx.setup_integration(
+        {
+            ClimateSchema.PLATFORM: {
+                CONF_NAME: "test",
+                ClimateSchema.CONF_TEMPERATURE_ADDRESS: "1/2/3",
+                ClimateSchema.CONF_TARGET_TEMPERATURE_ADDRESS: "1/2/4",
+                ClimateSchema.CONF_TARGET_TEMPERATURE_STATE_ADDRESS: "1/2/5",
+                ClimateSchema.CONF_FAN_SPEED_ADDRESS: "1/2/6",
+                ClimateSchema.CONF_FAN_SPEED_STATE_ADDRESS: "1/2/7",
+                ClimateSchema.CONF_FAN_MAX_STEP: 3,
+                ClimateSchema.CONF_FAN_SPEED_MODE: "step",
+                ClimateSchema.CONF_FAN_ZERO_MODE: "auto",
+            }
+        }
+    )
+
+    # read states state updater
+    await knx.assert_read("1/2/3")
+    await knx.assert_read("1/2/5")
+
+    # StateUpdater initialize state
+    await knx.receive_response("1/2/5", RAW_FLOAT_22_0)
+    await knx.receive_response("1/2/3", RAW_FLOAT_21_0)
+
+    # Query status
+    await knx.assert_read("1/2/7")
+    await knx.receive_response("1/2/7", (0x01,))
+    knx.assert_state(
+        "climate.test",
+        HVACMode.HEAT,
+        fan_mode="low",
+        fan_modes=["auto", "low", "medium", "high"],
+    )
+
+    # set auto
+    await hass.services.async_call(
+        "climate",
+        "set_fan_mode",
+        {"entity_id": "climate.test", "fan_mode": "auto"},
+        blocking=True,
+    )
+    await knx.assert_write("1/2/6", (0x0,))
+    knx.assert_state("climate.test", HVACMode.HEAT, fan_mode="auto")