Skip to content

Commit

Permalink
Update pollen detection after SVG change
Browse files Browse the repository at this point in the history
  • Loading branch information
jdejaegh committed Jan 29, 2025
1 parent b666f7d commit fdec55e
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 2 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
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 fdec55e

Please sign in to comment.