Files
ClimatController/tests/test_auto_heater_tion_target.py
T

245 lines
4.6 KiB
Python

import asyncio
from types import SimpleNamespace
from app.auto.config import TemperatureConfig
from app.auto.controller import AutoController
from app.auto.temperature_policy import TemperaturePolicy
from app.my_dataclasses import MAX_TARGET_TEMP
class FakeQingpingService:
def __init__(self):
self.online = True
self.state = SimpleNamespace(
temperature=19.0,
)
class FakeTionController:
def __init__(self):
self.calls = []
async def set_target_temperature(
self,
temperature: int,
):
self.calls.append(
(
"set_target_temperature",
temperature,
)
)
async def heater_on(self):
self.calls.append(
(
"heater_on",
None,
)
)
async def heater_off(self):
self.calls.append(
(
"heater_off",
None,
)
)
class FakeTionService:
def __init__(self):
self.online = True
self.state = SimpleNamespace(
in_temp=22,
)
self.controller = FakeTionController()
async def execute(
self,
operation,
):
return await operation(
self.controller
)
def make_controller():
qingping = FakeQingpingService()
tion = FakeTionService()
temperature_policy = TemperaturePolicy(
TemperatureConfig(
hysteresis=0.5,
)
)
controller = AutoController(
schedule_service=None,
qingping_service=qingping,
tion_service=tion,
temperature_policy=temperature_policy,
)
return (
controller,
qingping,
tion,
)
def make_resolution(
target_temp: int,
):
return SimpleNamespace(
auto_target_temp=target_temp,
)
async def test_heating_sets_tion_target_first():
controller, qingping, tion = (
make_controller()
)
resolution = make_resolution(
target_temp=20
)
# Qingping = 19.0
# AUTO target = 20
#
# Нужно греть.
#
# Сначала Tion.target_temp поднимается
# до технического максимума,
# затем включается heater.
await controller._process_heater(
resolution
)
assert tion.controller.calls == [
(
"set_target_temperature",
MAX_TARGET_TEMP,
),
(
"heater_on",
None,
),
]
assert (
controller._target_temperature
== MAX_TARGET_TEMP
)
assert (
controller._target_heater
is True
)
assert (
controller._auto_heater
is True
)
async def test_repeated_heating_does_not_repeat_commands():
controller, qingping, tion = (
make_controller()
)
resolution = make_resolution(
target_temp=20
)
await controller._process_heater(
resolution
)
tion.controller.calls.clear()
# Температура всё ещё ниже цели.
# AUTO продолжает хотеть нагрев,
# но повторно слать команды Tion не нужно.
qingping.state.temperature = 19.2
await controller._process_heater(
resolution
)
assert tion.controller.calls == []
async def test_target_reached_turns_heater_off():
controller, qingping, tion = (
make_controller()
)
resolution = make_resolution(
target_temp=20
)
# Сначала включаем нагрев.
await controller._process_heater(
resolution
)
tion.controller.calls.clear()
# Цель достигнута.
qingping.state.temperature = 20.0
await controller._process_heater(
resolution
)
# MAX_TARGET_TEMP обратно сейчас не меняем.
# Достаточно запретить нагрев.
assert tion.controller.calls == [
(
"heater_off",
None,
)
]
assert (
controller._auto_heater
is False
)
assert (
controller._target_heater
is False
)
async def main():
await test_heating_sets_tion_target_first()
await test_repeated_heating_does_not_repeat_commands()
await test_target_reached_turns_heater_off()
print()
print("=" * 70)
print(
"ALL AUTO HEATER TION TARGET "
"TESTS PASSED"
)
print("=" * 70)
if __name__ == "__main__":
asyncio.run(main())