Skip to content
Open
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
16 changes: 13 additions & 3 deletions src/pyvesync/devices/vesynckitchen.py
Original file line number Diff line number Diff line change
Expand Up @@ -500,14 +500,21 @@ async def get_details(self) -> None:
if _current_temp is not None and self.temp_unit == TemperatureUnits.FAHRENHEIT:
_current_temp = round(_current_temp * 9 / 5 + 32)

# The API reports preheatSetTime as 0 when the program has no preheat.
# Pass None in that case so the state does not read as a preheat.
_preheat_set_time = resp_model.preheatSetTime or None
_preheat_last_time = (
resp_model.preheatLastTime if _preheat_set_time is not None else None
)

self.state_chamber_1.set_state(
cook_status=self.status_map[resp_model.cookStatus],
cook_time=cook_step.cookSetTime,
cook_last_time=cook_step.cookLastTime,
cook_temp=cook_step.cookTemp,
cook_mode=cook_step.mode,
preheat_set_time=resp_model.preheatSetTime,
preheat_last_time=resp_model.preheatLastTime,
preheat_set_time=_preheat_set_time,
preheat_last_time=_preheat_last_time,
current_temp=_current_temp,
)

Expand All @@ -533,7 +540,10 @@ async def set_mode_from_recipe(self, recipe: AirFryerPresetRecipe) -> bool:
self.state.set_standby()
return False
self.state.set_state(
cook_status=AirFryerCookStatus.COOKING,
# A program with preheat starts in the preheat phase.
cook_status=AirFryerCookStatus.HEATING
if recipe.preheat_time
else AirFryerCookStatus.COOKING,
cook_time=recipe.cook_time,
cook_last_time=recipe.cook_time,
cook_temp=recipe.target_temp,
Expand Down
78 changes: 78 additions & 0 deletions src/tests/test_fryer_turboblaze_state.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
"""State tests for bypassV2 (TurboBlaze class) fryers around preheat.

Covers the local state after starting a program with preheat, and how a
pulled-out basket is classified when the API reports ``preheatSetTime`` as 0.
"""

from copy import deepcopy

import call_json_fryers
from base_test_cases import TestBase
from defaults import build_bypass_v2_response

from pyvesync.const import AirFryerCookStatus

MODEL = 'CAF-DC601S'


class TestTurboBlazePreheatState(TestBase):
"""Preheat state handling for VeSyncTurboBlazeFryer."""

def _update_with(self, fryer, **overrides):
details = deepcopy(call_json_fryers.AIR_FRYER_COOKING_DETAILS[MODEL])
details.update(overrides)
self.mock_api.return_value = (
build_bypass_v2_response(inner_result=details),
200,
)
self.run_in_loop(fryer.update)

def test_set_mode_with_preheat_starts_in_heating(self):
fryer = self.get_device('air_fryers', MODEL)
self.mock_api.return_value = (build_bypass_v2_response(inner_result={}), 200)

result = self.run_in_loop(
fryer.set_mode, cook_time=600, cook_temp=350, preheat_time=300
)

assert result is True
assert fryer.state.cook_status == AirFryerCookStatus.HEATING
assert fryer.state.is_in_preheat_mode is True
assert fryer.state.preheat_set_time == 300
assert fryer.state.cook_set_time == 600
assert fryer.state.cook_set_temp == 350

def test_set_mode_without_preheat_starts_in_cooking(self):
fryer = self.get_device('air_fryers', MODEL)
self.mock_api.return_value = (build_bypass_v2_response(inner_result={}), 200)

result = self.run_in_loop(fryer.set_mode, cook_time=600, cook_temp=350)

assert result is True
assert fryer.state.cook_status == AirFryerCookStatus.COOKING
assert fryer.state.is_in_preheat_mode is False
assert fryer.state.preheat_set_time is None

def test_pull_out_during_cook_is_cook_mode(self):
"""preheatSetTime 0 from the API means the program has no preheat."""
fryer = self.get_device('air_fryers', MODEL)
self._update_with(
fryer, cookStatus='pullOut', preheatSetTime=0, preheatLastTime=0
)

assert fryer.state.cook_status == AirFryerCookStatus.PULL_OUT
assert fryer.state.preheat_set_time is None
assert fryer.state.is_in_preheat_mode is False
assert fryer.state.is_in_cook_mode is True

def test_pull_out_during_preheat_is_preheat_mode(self):
fryer = self.get_device('air_fryers', MODEL)
self._update_with(
fryer, cookStatus='pullOut', preheatSetTime=300, preheatLastTime=120
)

assert fryer.state.cook_status == AirFryerCookStatus.PULL_OUT
assert fryer.state.preheat_set_time == 300
assert fryer.state.preheat_last_time == 120
assert fryer.state.is_in_preheat_mode is True
assert fryer.state.is_in_cook_mode is False
Loading