Skip to content

Commit

Permalink
Assume hvac action based on current/target temp (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewturner authored Feb 27, 2024
1 parent 9dfbea0 commit 03d6bd8
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 7 deletions.
28 changes: 28 additions & 0 deletions salusfy/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
from .web_client import WebClient
from .ha_temperature_client import HaTemperatureClient

from homeassistant.components.climate.const import (
HVACMode,
HVACAction
)

_LOGGER = logging.getLogger(__name__)

class Client:
Expand All @@ -26,6 +31,10 @@ async def set_temperature(self, temperature):

await self._web_client.set_temperature(temperature)

self._state.target_temperature = temperature

self.assume_hvac_action()


async def set_hvac_mode(self, hvac_mode):
"""Set HVAC mode, via URL commands."""
Expand All @@ -34,6 +43,25 @@ async def set_hvac_mode(self, hvac_mode):

await self._web_client.set_hvac_mode(hvac_mode)

self._state.mode = hvac_mode

self.assume_hvac_action()


def assume_hvac_action(self):
if self._state.mode == HVACMode.OFF:
_LOGGER.info("Assuming action is IDLE...")
self._state.action = HVACAction.IDLE
return

if self._state.target_temperature > self._state.current_temperature:
_LOGGER.info("Assuming action is HEATING based on target temperature...")
self._state.action = HVACAction.HEATING
return

_LOGGER.info("Assuming action is IDLE based on target temperature...")
self._state.action = HVACAction.IDLE


async def get_state(self):
"""Retrieves the status"""
Expand Down
101 changes: 94 additions & 7 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

from salusfy import ( Client, State, WebClient, HaTemperatureClient )
from homeassistant.components.climate.const import (
HVACMode
HVACMode,
HVACAction
)

@pytest.fixture
Expand All @@ -28,7 +29,7 @@ def mock_ha_client():


@pytest.mark.asyncio
async def test_entity_returns_target_temp_from_web_client(mock_client, mock_ha_client):
async def test_client_returns_target_temp_from_web_client(mock_client, mock_ha_client):
target = Client(mock_client, mock_ha_client)

actual = await target.get_state()
Expand All @@ -37,7 +38,7 @@ async def test_entity_returns_target_temp_from_web_client(mock_client, mock_ha_c


@pytest.mark.asyncio
async def test_entity_returns_target_temp_from_home_assistant_client(mock_client, mock_ha_client):
async def test_client_returns_target_temp_from_home_assistant_client(mock_client, mock_ha_client):
target = Client(mock_client, mock_ha_client)

actual = await target.get_state()
Expand All @@ -46,7 +47,7 @@ async def test_entity_returns_target_temp_from_home_assistant_client(mock_client


@pytest.mark.asyncio
async def test_entity_call_salus_client_only_once(mock_client, mock_ha_client):
async def test_client_call_salus_client_only_once(mock_client, mock_ha_client):
target = Client(mock_client, mock_ha_client)

await target.get_state()
Expand All @@ -59,18 +60,104 @@ async def test_entity_call_salus_client_only_once(mock_client, mock_ha_client):


@pytest.mark.asyncio
async def test_entity_delegates_set_temperature_salus_client(mock_client, mock_ha_client):
async def test_client_delegates_set_temperature_salus_client(mock_client, mock_ha_client):
target = Client(mock_client, mock_ha_client)

await target.get_state()

await target.set_temperature(temperature=29.9)

mock_client.set_temperature.assert_called_once_with(29.9)


@pytest.mark.asyncio
async def test_entity_delegates_set_hvac_mode_to_salus_client(mock_client, mock_ha_client):
async def test_client_delegates_set_hvac_mode_to_salus_client(mock_client, mock_ha_client):
target = Client(mock_client, mock_ha_client)

await target.get_state()

await target.set_hvac_mode(hvac_mode=HVACMode.HEAT)

mock_client.set_hvac_mode.assert_called_once_with(HVACMode.HEAT)


@pytest.mark.asyncio
async def test_client_assumes_hvac_action_as_idle_when_mode_is_off(mock_client, mock_ha_client):
target = Client(mock_client, mock_ha_client)

await target.get_state()

await target.set_hvac_mode(hvac_mode=HVACMode.OFF)

actual = await target.get_state()

assert actual.action == HVACAction.IDLE


@pytest.mark.asyncio
async def test_client_sets_hvac_mode(mock_client, mock_ha_client):
target = Client(mock_client, mock_ha_client)

await target.get_state()

await target.set_hvac_mode(hvac_mode=HVACMode.OFF)

actual = await target.get_state()

assert actual.mode == HVACMode.OFF


@pytest.mark.asyncio
async def test_client_assumes_hvac_action_as_heat_when_mode_is_heat_and_target_temp_is_high(mock_client, mock_ha_client):
target = Client(mock_client, mock_ha_client)

await target.get_state()

await target.set_temperature(temperature=30)
await target.set_hvac_mode(hvac_mode=HVACMode.HEAT)

actual = await target.get_state()

assert actual.action == HVACAction.HEATING


@pytest.mark.asyncio
async def test_client_assumes_hvac_action_as_idle_when_mode_is_heat_and_target_temp_is_low(mock_client, mock_ha_client):
target = Client(mock_client, mock_ha_client)

await target.get_state()

await target.set_temperature(temperature=4)
await target.set_hvac_mode(hvac_mode=HVACMode.HEAT)

actual = await target.get_state()

assert actual.action == HVACAction.IDLE


@pytest.mark.asyncio
async def test_client_assumes_hvac_action_as_heat_when_mode_is_heat_and_target_temp_is_set_high(mock_client, mock_ha_client):
target = Client(mock_client, mock_ha_client)

await target.get_state()

await target.set_hvac_mode(hvac_mode=HVACMode.HEAT)
await target.set_temperature(temperature=33)

mock_client.set_hvac_mode.assert_called_once_with(HVACMode.HEAT)
actual = await target.get_state()

assert actual.action == HVACAction.HEATING


@pytest.mark.asyncio
async def test_client_assumes_hvac_action_as_idle_when_mode_is_heat_and_target_temp_is_set_low(mock_client, mock_ha_client):
target = Client(mock_client, mock_ha_client)

await target.get_state()

await target.set_hvac_mode(hvac_mode=HVACMode.HEAT)
await target.set_temperature(temperature=4)

actual = await target.get_state()

assert actual.action == HVACAction.IDLE

0 comments on commit 03d6bd8

Please sign in to comment.