Repository: XKNX/xknx
Pull request #1135 (2023-01-06 19:11:00)

Add new sensor type DPT 9.009 "air_flow"
<!--
  You are awesome! Thanks for contributing to our project!
  Please, DO NOT DELETE ANY TEXT from this template!.
-->
## Description
<!--
Please include a summary of the change and which issue is fixed.
Please also include relevant motivation and context.
List any dependencies that are required for this change.
-->


Fixes # (issue)

## Type of change
<!--
Please tick the applicable options.
NOTE: Ticking multiple options most likely indicates
that your change is to big and it is suggested to split it into several smaller PRs.
-->

- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] This change requires a documentation update

## Checklist:

- [ ] The documentation has been adjusted accordingly
- [ ] Tests have been added that prove the fix is effective or that the feature works
- [ ] The changes are documented in the changelog (docs/changelog.md)

codecov[bot]: # [Codecov](https://codecov.io/gh/XKNX/xknx/pull/1135?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=XKNX) Report
> Merging [#1135](https://codecov.io/gh/XKNX/xknx/pull/1135?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=XKNX) (c31b090) into [main](https://codecov.io/gh/XKNX/xknx/commit/3ead49e95bc041792897a5a6b95e219a8ecc7c5b?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=XKNX) (3ead49e) will **decrease** coverage by `0.01%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/XKNX/xknx/pull/1135/graphs/tree.svg?width=650&height=150&src=pr&token=irWbIygS84&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=XKNX)](https://codecov.io/gh/XKNX/xknx/pull/1135?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=XKNX)

```diff
@@            Coverage Diff             @@
##             main    #1135      +/-   ##
==========================================
- Coverage   96.35%   96.33%   -0.02%     
==========================================
  Files         138      138              
  Lines        8659     8650       -9     
==========================================
- Hits         8343     8333      -10     
- Misses        316      317       +1     
```


| [Impacted Files](https://codecov.io/gh/XKNX/xknx/pull/1135?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=XKNX) | Coverage Δ | |
|---|---|---|
| [xknx/dpt/\_\_init\_\_.py](https://codecov.io/gh/XKNX/xknx/pull/1135?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=XKNX#diff-eGtueC9kcHQvX19pbml0X18ucHk=) | `100.00% <ø> (ø)` | |
| [xknx/dpt/dpt\_2byte\_float.py](https://codecov.io/gh/XKNX/xknx/pull/1135?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=XKNX#diff-eGtueC9kcHQvZHB0XzJieXRlX2Zsb2F0LnB5) | `100.00% <100.00%> (ø)` | |
| [xknx/telegram/telegram.py](https://codecov.io/gh/XKNX/xknx/pull/1135?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=XKNX#diff-eGtueC90ZWxlZ3JhbS90ZWxlZ3JhbS5weQ==) | `93.02% <0.00%> (-2.33%)` | :arrow_down: |
| [xknx/io/tunnel.py](https://codecov.io/gh/XKNX/xknx/pull/1135?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=XKNX#diff-eGtueC9pby90dW5uZWwucHk=) | `87.68% <0.00%> (-0.70%)` | :arrow_down: |
| [xknx/io/routing.py](https://codecov.io/gh/XKNX/xknx/pull/1135?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=XKNX#diff-eGtueC9pby9yb3V0aW5nLnB5) | `91.66% <0.00%> (-0.25%)` | :arrow_down: |
| [xknx/management/management.py](https://codecov.io/gh/XKNX/xknx/pull/1135?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=XKNX#diff-eGtueC9tYW5hZ2VtZW50L21hbmFnZW1lbnQucHk=) | `88.19% <0.00%> (-0.08%)` | :arrow_down: |
| [xknx/io/interface.py](https://codecov.io/gh/XKNX/xknx/pull/1135?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=XKNX#diff-eGtueC9pby9pbnRlcmZhY2UucHk=) | `100.00% <0.00%> (ø)` | |
| [xknx/io/knxip\_interface.py](https://codecov.io/gh/XKNX/xknx/pull/1135?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=XKNX#diff-eGtueC9pby9rbnhpcF9pbnRlcmZhY2UucHk=) | `84.76% <0.00%> (+0.47%)` | :arrow_up: |

farmio: To satisfy Codecov consider doing a rebase from current `main`. 

Patch:
diff --git a/xknx/dpt/__init__.py b/xknx/dpt/__init__.py
index cea33e90..434f8c29 100644
--- a/xknx/dpt/__init__.py
+++ b/xknx/dpt/__init__.py
@@ -17,6 +17,7 @@ from .dpt_1byte_uint import (
 )
 from .dpt_2byte_float import (
     DPT2ByteFloat,
+    DPTAirFlow,
     DPTCurrent,
     DPTEnthalpy,
     DPTHumidity,
diff --git a/xknx/dpt/dpt_2byte_float.py b/xknx/dpt/dpt_2byte_float.py
index f3ff8c43..b3d46c03 100644
--- a/xknx/dpt/dpt_2byte_float.py
+++ b/xknx/dpt/dpt_2byte_float.py
@@ -173,6 +173,15 @@ class DPTPartsPerMillion(DPT2ByteFloat):
     unit = "ppm"
 
 
+class DPTAirFlow(DPT2ByteFloat):
+    """DPT 9.009 DPT_Value_AirFlow."""
+
+    dpt_main_number = 9
+    dpt_sub_number = 9
+    value_type = "air_flow"
+    unit = "m³/h"
+
+
 class DPTTime1(DPT2ByteFloat):
     """DPT 9.010 DPT_Value_Time1 (s)."""
 


Test patch:
diff --git a/test/dpt_tests/dpt_float_test.py b/test/dpt_tests/dpt_float_test.py
index 083fa7c1..630e7a68 100644
--- a/test/dpt_tests/dpt_float_test.py
+++ b/test/dpt_tests/dpt_float_test.py
@@ -8,6 +8,7 @@ import pytest
 from xknx.dpt import (
     DPT2ByteFloat,
     DPT4ByteFloat,
+    DPTAirFlow,
     DPTElectricCurrent,
     DPTElectricPotential,
     DPTEnthalpy,
@@ -190,6 +191,13 @@ class TestDPTFloat:
         """Test attributes of DPTPartsPerMillion."""
         assert DPTPartsPerMillion.unit == "ppm"
 
+    #
+    # DPTAirFlow
+    #
+    def test_airflow_settings(self):
+        """Test attributes of DPTPartsPerMillion."""
+        assert DPTAirFlow.unit == "m³/h"
+
     #
     # DPTVoltage
     #