Skip to content

Commit

Permalink
Merge pull request #70 from jdejaegh/69-pollen-data
Browse files Browse the repository at this point in the history
Fix pollen data parsing
  • Loading branch information
jdejaegh authored Jan 29, 2025
2 parents 082770f + 3957eac commit 72e9d5d
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 5 deletions.
35 changes: 33 additions & 2 deletions custom_components/irm_kmi/pollen.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
class PollenParser:
"""
Extract pollen level from an SVG provided by the IRM KMI API.
To get the data, match pollen names and pollen levels that are vertically aligned. Then, map the value to the
corresponding color on the scale.
To get the data, match pollen names and pollen levels that are vertically aligned or the dot on the color scale.
Then, map the value to the corresponding color on the scale.
"""

def __init__(
Expand Down Expand Up @@ -70,9 +70,40 @@ def get_pollen_data(self) -> dict:
pollen_levels = {e.attrib.get('x', None): POLLEN_LEVEL_TO_COLOR[self._get_elem_text(e)]
for e in elements if 'tspan' in e.tag and self._get_elem_text(e) in POLLEN_LEVEL_TO_COLOR}

level_dots = {e.attrib.get('cx', None) for e in elements if 'circle' in e.tag}
print(level_dots)

# For each pollen name found, check the text just below.
# As of January 2025, the text is always 'active' and the dot shows the real level
# If text says 'active', check the dot; else trust the text
for position, pollen in pollens.items():
# Determine pollen level based on text
if position is not None and position in pollen_levels:
pollen_data[pollen] = pollen_levels[position]
print(f"{pollen} is {pollen_data[pollen]} according to text")

# If text is 'active' or if there is no text, check the dot as a fallback
if pollen_data[pollen] not in {'none', 'active'}:
_LOGGER.debug(f"{pollen} trusting text")
else:
for dot in level_dots:
try:
relative_x_position = float(position) - float(dot)
except TypeError:
pass
else:
if 24 <= relative_x_position <= 34:
pollen_data[pollen] = 'green'
elif 13 <= relative_x_position <= 23:
pollen_data[pollen] = 'yellow'
elif -5 <= relative_x_position <= 5:
pollen_data[pollen] = 'orange'
elif -23 <= relative_x_position <= -13:
pollen_data[pollen] = 'red'
elif -34 <= relative_x_position <= -24:
pollen_data[pollen] = 'purple'

_LOGGER.debug(f"{pollen} is {pollen_data[pollen]} according to dot")

_LOGGER.debug(f"Pollen data: {pollen_data}")
return pollen_data
Binary file modified img/pollens.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
aiohttp==3.11.11
async-timeout==4.0.3
homeassistant==2024.12.5
homeassistant==2025.1.4
voluptuous==0.15.2
svgwrite==1.4.3
aiofile==3.9.0
4 changes: 2 additions & 2 deletions requirements_tests.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
homeassistant==2024.12.5
pytest_homeassistant_custom_component==0.13.195
homeassistant==2025.1.4
pytest_homeassistant_custom_component==0.13.205
pytest
freezegun
isort
55 changes: 55 additions & 0 deletions tests/fixtures/pollens-2025.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions tests/test_pollen.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ def test_svg_two_pollen_parsing():
assert data == {'birch': 'none', 'oak': 'none', 'hazel': 'none', 'mugwort': 'active', 'alder': 'none',
'grasses': 'red', 'ash': 'none'}

def test_svg_two_pollen_parsing_2025_update():
with open("tests/fixtures/pollens-2025.svg", "r") as file:
svg_data = file.read()
data = PollenParser(svg_data).get_pollen_data()
assert data == {'birch': 'none', 'oak': 'none', 'hazel': 'active', 'mugwort': 'none', 'alder': 'green',
'grasses': 'none', 'ash': 'none'}

def test_pollen_options():
assert set(PollenParser.get_option_values()) == {'green', 'yellow', 'orange', 'red', 'purple', 'active', 'none'}
Expand Down

0 comments on commit 72e9d5d

Please sign in to comment.