Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion pykumo/py_kumo.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,11 @@ def get_fan_speeds(self):
)

if speeds == 3:
valid_speeds = ["quiet", "low", "powerful"]
# Intentionally return all 5 speeds even though the profile reports
# numberOfFanSpeeds=3. These units under-report their capability:
# real hardware accepts the full superQuiet..superPowerful range,
# as confirmed on units in the field.
valid_speeds = ["superQuiet", "quiet", "low", "powerful", "superPowerful"]
Comment thread
dlarrick marked this conversation as resolved.
elif speeds == 4:
valid_speeds = ["quiet", "Low", "powerful", "superPowerful"]
else:
Expand Down
85 changes: 85 additions & 0 deletions tests/test_fan_speeds.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
"""Tests for get_fan_speeds() across all numberOfFanSpeeds values."""

import unittest
from unittest.mock import patch
from pykumo.py_kumo import PyKumo


def make_unit(num_speeds, has_auto=False):
"""Return a minimally-mocked PyKumo with the given profile."""
with patch.object(PyKumo, "__init__", lambda self, *a, **kw: None):
unit = PyKumo.__new__(PyKumo)
profile = {"numberOfFanSpeeds": num_speeds}
if has_auto:
profile["hasFanSpeedAuto"] = True
unit._profile = profile
unit._status = {}
return unit


class TestGetFanSpeeds(unittest.TestCase):
def test_3speed_full_set(self):
"""Units reporting numberOfFanSpeeds=3 expose the full 5-speed set."""
unit = make_unit(3)
speeds = unit.get_fan_speeds()
self.assertEqual(
speeds,
["superQuiet", "quiet", "low", "powerful", "superPowerful"],
)

def test_3speed_superquiet_is_first(self):
"""superQuiet should be the first option for 3-speed units."""
unit = make_unit(3)
speeds = unit.get_fan_speeds()
self.assertEqual(speeds[0], "superQuiet")

def test_3speed_superpowerful_is_last_before_auto(self):
"""superPowerful should be the last non-auto option for 3-speed units."""
unit = make_unit(3)
speeds = unit.get_fan_speeds()
self.assertEqual(speeds[-1], "superPowerful")

def test_3speed_with_auto(self):
"""3-speed + hasFanSpeedAuto appends auto at end."""
unit = make_unit(3, has_auto=True)
speeds = unit.get_fan_speeds()
self.assertEqual(
speeds,
["superQuiet", "quiet", "low", "powerful", "superPowerful", "auto"],
)

def test_4speed_unchanged(self):
"""4-speed behaviour is unchanged."""
unit = make_unit(4)
speeds = unit.get_fan_speeds()
self.assertEqual(speeds, ["quiet", "Low", "powerful", "superPowerful"])

def test_5speed_unchanged(self):
"""5-speed (default) behaviour is unchanged."""
unit = make_unit(5)
speeds = unit.get_fan_speeds()
self.assertEqual(
speeds, ["superQuiet", "quiet", "low", "powerful", "superPowerful"]
)

def test_get_fan_speeds_includes_superquiet_on_3speed(self):
"""get_fan_speeds() must include superQuiet for 3-speed units."""
with patch.object(PyKumo, "__init__", lambda self, *a, **kw: None):
unit = PyKumo.__new__(PyKumo)
unit._profile = {"numberOfFanSpeeds": 3}
unit._status = {}
valid = unit.get_fan_speeds()
self.assertIn("superQuiet", valid)

def test_get_fan_speeds_includes_superpowerful_on_3speed(self):
"""get_fan_speeds() must include superPowerful for 3-speed units."""
with patch.object(PyKumo, "__init__", lambda self, *a, **kw: None):
unit = PyKumo.__new__(PyKumo)
unit._profile = {"numberOfFanSpeeds": 3}
unit._status = {}
valid = unit.get_fan_speeds()
self.assertIn("superPowerful", valid)


if __name__ == "__main__":
unittest.main()