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
61 changes: 49 additions & 12 deletions tests/test_vallox_sensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import pytest

from vallox_websocket_api import (
CellState,
DefrostMode,
Profile,
SupplyHeatingAdjustMode,
Expand Down Expand Up @@ -185,7 +186,6 @@ async def test_set_defrost_mode_with_invalid_mode(vallox):
"A_CYC_RH_BASIC_LEVEL": 58,
"A_CYC_CO2_THRESHOLD": 800,
"A_CYC_SUPPLY_HEATING_ADJUST_MODE": 0,
"A_CYC_DEFROST_MODE": 0,
},
{
"A_CYC_HOME_RH_CTRL_ENABLED": 0,
Expand All @@ -198,7 +198,6 @@ async def test_set_defrost_mode_with_invalid_mode(vallox):
"A_CYC_RH_BASIC_LEVEL": 50,
"A_CYC_CO2_THRESHOLD": 750,
"A_CYC_SUPPLY_HEATING_ADJUST_MODE": 1,
"A_CYC_DEFROST_MODE": 1,
},
{
"A_CYC_HOME_RH_CTRL_ENABLED": 0,
Expand All @@ -211,7 +210,6 @@ async def test_set_defrost_mode_with_invalid_mode(vallox):
"A_CYC_RH_BASIC_LEVEL": 60,
"A_CYC_CO2_THRESHOLD": 850,
"A_CYC_SUPPLY_HEATING_ADJUST_MODE": 2,
"A_CYC_DEFROST_MODE": 1,
},
{
"A_CYC_HOME_RH_CTRL_ENABLED": 1,
Expand All @@ -224,7 +222,6 @@ async def test_set_defrost_mode_with_invalid_mode(vallox):
"A_CYC_RH_BASIC_LEVEL": 55,
"A_CYC_CO2_THRESHOLD": 900,
"A_CYC_SUPPLY_HEATING_ADJUST_MODE": 0,
"A_CYC_DEFROST_MODE": 0,
},
],
)
Expand Down Expand Up @@ -286,14 +283,6 @@ async def test_get_sensor_controls_and_modes(vallox, metrics_response):
).name
)

# Test defrost mode
assert isinstance(data.defrost_mode, DefrostMode)
assert data.defrost_mode == DefrostMode(metrics_response["A_CYC_DEFROST_MODE"])
assert (
data.defrost_mode.name
== DefrostMode(metrics_response["A_CYC_DEFROST_MODE"]).name
)

# Test valid profiles without specific RH and CO2 sensor control metrics
with pytest.raises(ValloxInvalidInputException):
data.get_rh_sensor_control(Profile.FIREPLACE)
Expand All @@ -305,3 +294,51 @@ async def test_get_sensor_controls_and_modes(vallox, metrics_response):
data.get_co2_sensor_control(Profile.EXTRA)

vallox.fetch_metrics.assert_called_once()


@pytest.mark.parametrize(
"defrost_mode_value, expected_defrost_mode",
[
(0, DefrostMode.BYPASS),
(1, DefrostMode.FAN_STOP),
],
)
@pytest.mark.asyncio
async def test_get_defrost_mode(vallox, defrost_mode_value, expected_defrost_mode):
"""Test getting defrost mode."""
# Mock the metrics response
metrics_response = {"A_CYC_DEFROST_MODE": defrost_mode_value}
vallox.fetch_metrics = mock.AsyncMock(return_value=metrics_response)

data = await vallox.fetch_metric_data()

# Test defrost mode
assert isinstance(data.defrost_mode, DefrostMode)
assert data.defrost_mode == expected_defrost_mode

vallox.fetch_metrics.assert_called_once()


@pytest.mark.parametrize(
"cell_state_value, expected_cell_state",
[
(0, CellState.HEAT_RECOVERY),
(1, CellState.COOL_RECOVERY),
(2, CellState.BYPASS),
(3, CellState.DEFROST),
],
)
@pytest.mark.asyncio
async def test_get_cell_state(vallox, cell_state_value, expected_cell_state):
"""Test getting cell state."""
# Mock the metrics response
metrics_response = {"A_CYC_CELL_STATE": cell_state_value}
vallox.fetch_metrics = mock.AsyncMock(return_value=metrics_response)

data = await vallox.fetch_metric_data()

# Test cell state
assert isinstance(data.cell_state, CellState)
assert data.cell_state == expected_cell_state

vallox.fetch_metrics.assert_called_once()
22 changes: 17 additions & 5 deletions vallox_websocket_api/vallox.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,18 @@ def defrost_mode(self) -> Optional[DefrostMode]:
except ValueError:
return None

@property
def cell_state(self) -> Optional[CellState]:
"""Get the current cell state.
Returns:
CellState: 'Heat recovery'(0), 'Cool recovery' (1), 'Bypass' (2), or 'Defrost' (3)
"""
state = self.get("A_CYC_CELL_STATE")
try:
return CellState(state)
except ValueError:
return None

def get_temperature_setting(self, profile: Profile) -> Optional[float]:
"""Get the temperature setting for the profile"""
if profile not in PROFILE_TO_SET_TEMPERATURE_METRIC_MAP:
Expand Down Expand Up @@ -351,8 +363,8 @@ def get_remaining_profile_duration(self, profile: Profile) -> Optional[int]:
@property
def rh_sensor_manual_control_mode(self) -> Optional[bool]:
"""Return the RH sensor control mode (0 for automatic, 1 for manual)"""
mode = self.get(SET_RH_SENSOR_CONTROL_MODE)
return bool(mode) if mode is not None else None
enabled = self.get(SET_RH_SENSOR_CONTROL_MODE)
return bool(enabled) if enabled is not None else None

@property
def rh_sensor_limit(self) -> Optional[int]:
Expand Down Expand Up @@ -573,13 +585,13 @@ async def set_co2_sensor_control(self, profile: Profile, enable: bool) -> None:

await self.set_values({setting: enable})

async def set_rh_sensor_manual_control_mode(self, mode: int) -> None:
async def set_rh_sensor_manual_control_mode(self, enable: bool) -> None:
"""Set the RH sensor control mode (0 for automatic, 1 for manual)"""
if mode not in (0, 1):
if enable not in (0, 1):
raise ValloxInvalidInputException(
"RH sensor control mode must be 0 (automatic) or 1 (manual)"
)
await self.set_values({SET_RH_SENSOR_CONTROL_MODE: mode})
await self.set_values({SET_RH_SENSOR_CONTROL_MODE: enable})

async def set_rh_sensor_limit(self, percent: int) -> None:
"""Set the RH sensor limit (0-100). Only relevant if the RH sensor mode is set to 'manual'."""
Expand Down