From 404112e1efb263d2899045d2b7ee5ab750870ba6 Mon Sep 17 00:00:00 2001 From: Chris Jowett <421501+cryptk@users.noreply.github.com> Date: Fri, 8 May 2026 20:52:22 +0000 Subject: [PATCH] feat(pump,filter): add support for dual speed pumps and filters --- pyomnilogic_local/filter.py | 37 ++++++++++++++++++++++++++++++++++++- pyomnilogic_local/pump.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/pyomnilogic_local/filter.py b/pyomnilogic_local/filter.py index 5c30d41..1ced2de 100644 --- a/pyomnilogic_local/filter.py +++ b/pyomnilogic_local/filter.py @@ -223,7 +223,8 @@ async def turn_on(self) -> None: # This matches the behavior of the OmniLogic phone app target_speed: int = 100 match self.equip_type: - case FilterType.VARIABLE_SPEED: + # Dual speed filters are controlled similar to VSPs, but they only support speed values of 0, 50, and 100 + case FilterType.VARIABLE_SPEED | FilterType.DUAL_SPEED: if self.last_speed >= self.min_percent and self.last_speed <= self.max_percent: target_speed = self.last_speed case FilterType.SINGLE_SPEED: @@ -310,3 +311,37 @@ async def set_speed(self, speed: int) -> None: equipment_id=self.system_id, speed=speed, ) + + @control_method + async def set_dual_speed(self, speed: FilterSpeedPresets) -> None: + """Set the filter to a specific speed for dual speed filters. + + For Dual Speed filters, LOW and MEDIUM presets will set the filter to 50% speed, while HIGH will set it to 100%. + Semantically, it is preferred to only use LOW and HIGH presets for dual speed filters but MEDIUM is accepted for convenience + + Args: + speed: The preset speed to use (LOW, or HIGH) + + Raises: + OmniEquipmentNotInitializedError: If bow_id or system_id is None. + ValueError: If an invalid speed preset is provided or if the filter is not a dual speed filter. + """ + if self.equip_type != FilterType.DUAL_SPEED: + msg = "set_dual_speed can only be used with dual speed filters" + raise ValueError(msg) + + if self.bow_id is None or self.system_id is None: + msg = "Filter bow_id and system_id must be set" + raise OmniEquipmentNotInitializedError(msg) + + speed_value: int + match speed: + case FilterSpeedPresets.LOW | FilterSpeedPresets.MEDIUM: + speed_value = 50 + case FilterSpeedPresets.HIGH: + speed_value = 100 + case _: + msg = f"Invalid speed preset: {speed}" + raise ValueError(msg) + + await self.set_speed(speed_value) diff --git a/pyomnilogic_local/pump.py b/pyomnilogic_local/pump.py index bc5b672..2881b87 100644 --- a/pyomnilogic_local/pump.py +++ b/pyomnilogic_local/pump.py @@ -291,3 +291,37 @@ async def set_speed(self, speed: int) -> None: equipment_id=self.system_id, is_on=speed, ) + + @control_method + async def set_dual_speed(self, speed: PumpSpeedPresets) -> None: + """Set the pump to a specific speed for dual speed pumps. + + For Dual Speed pumps, LOW and MEDIUM presets will set the pump to 50% speed, while HIGH will set it to 100%. + Semantically, it is preferred to only use LOW and HIGH presets for dual speed pumps but MEDIUM is accepted for convenience + + Args: + speed: The preset speed to use (LOW, or HIGH) + + Raises: + OmniEquipmentNotInitializedError: If bow_id or system_id is None. + ValueError: If an invalid speed preset is provided or if the pump is not a dual speed pump. + """ + if self.equip_type != PumpType.DUAL_SPEED: + msg = "set_dual_speed can only be used with dual speed pumps" + raise ValueError(msg) + + if self.bow_id is None or self.system_id is None: + msg = "Pump bow_id and system_id must be set" + raise OmniEquipmentNotInitializedError(msg) + + speed_value: int + match speed: + case PumpSpeedPresets.LOW | PumpSpeedPresets.MEDIUM: + speed_value = 50 + case PumpSpeedPresets.HIGH: + speed_value = 100 + case _: + msg = f"Invalid speed preset: {speed}" + raise ValueError(msg) + + await self.set_speed(speed_value)