work: добавил автоматический режим
This commit is contained in:
+113
-19
@@ -7,6 +7,9 @@ from fastapi.responses import JSONResponse
|
||||
|
||||
from app.my_dataclasses import (
|
||||
TION_MAC,
|
||||
QINGPING_MAC,
|
||||
QINGPING_MQTT_HOST,
|
||||
QINGPING_MQTT_PORT,
|
||||
MIN_FAN_SPEED,
|
||||
MAX_FAN_SPEED,
|
||||
MIN_TARGET_TEMP,
|
||||
@@ -14,6 +17,13 @@ from app.my_dataclasses import (
|
||||
AIR_MODE_OUTSIDE,
|
||||
AIR_MODE_RECIRCULATION,
|
||||
SCHEDULE_FILE,
|
||||
AUTO_CONFIG_FILE,
|
||||
)
|
||||
|
||||
from app.auto import (
|
||||
AutoController,
|
||||
Co2SpeedPolicy,
|
||||
load_auto_config,
|
||||
)
|
||||
|
||||
from app.tion import (
|
||||
@@ -27,7 +37,7 @@ from schedule import (
|
||||
load_schedule,
|
||||
)
|
||||
|
||||
|
||||
from app.qingping.service import QingpingService
|
||||
|
||||
def configure_logging() -> None:
|
||||
noisy_loggers = (
|
||||
@@ -57,9 +67,19 @@ service = TionService(
|
||||
controller,
|
||||
poll_interval=5,
|
||||
)
|
||||
|
||||
qingping_service = QingpingService(
|
||||
host=QINGPING_MQTT_HOST,
|
||||
port=QINGPING_MQTT_PORT,
|
||||
mac=QINGPING_MAC,
|
||||
)
|
||||
|
||||
schedule_service: ScheduleService | None = None
|
||||
schedule_load_error: str | None = None
|
||||
|
||||
auto_controller: AutoController | None = None
|
||||
auto_load_error: str | None = None
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Application lifecycle
|
||||
# ----------------------------------------------------------------------
|
||||
@@ -68,8 +88,11 @@ schedule_load_error: str | None = None
|
||||
async def lifespan(app: FastAPI):
|
||||
global schedule_service
|
||||
global schedule_load_error
|
||||
global auto_controller
|
||||
global auto_load_error
|
||||
|
||||
await service.start()
|
||||
await qingping_service.start()
|
||||
|
||||
try:
|
||||
try:
|
||||
@@ -84,6 +107,50 @@ async def lifespan(app: FastAPI):
|
||||
await schedule_service.start()
|
||||
schedule_load_error = None
|
||||
|
||||
try:
|
||||
auto_config = load_auto_config(
|
||||
AUTO_CONFIG_FILE
|
||||
)
|
||||
|
||||
auto_policy = Co2SpeedPolicy(
|
||||
base_speed=(
|
||||
auto_config.co2.base_speed
|
||||
),
|
||||
thresholds=(
|
||||
auto_config.co2.thresholds
|
||||
),
|
||||
hysteresis=(
|
||||
auto_config.co2.hysteresis
|
||||
),
|
||||
)
|
||||
|
||||
auto_interval = (
|
||||
auto_config.check_interval
|
||||
)
|
||||
|
||||
auto_load_error = None
|
||||
|
||||
except Exception as exc:
|
||||
auto_policy = None
|
||||
|
||||
# Безопасный встроенный интервал нужен,
|
||||
# потому что auto.yaml сейчас недоступен.
|
||||
auto_interval = 5.0
|
||||
|
||||
auto_load_error = (
|
||||
f"{type(exc).__name__}: {exc}"
|
||||
)
|
||||
|
||||
auto_controller = AutoController(
|
||||
schedule_service=schedule_service,
|
||||
qingping_service=qingping_service,
|
||||
tion_service=service,
|
||||
policy=auto_policy,
|
||||
interval=auto_interval,
|
||||
)
|
||||
|
||||
await auto_controller.start()
|
||||
|
||||
except Exception as exc:
|
||||
schedule_service = None
|
||||
schedule_load_error = f"{type(exc).__name__}: {exc}"
|
||||
@@ -93,6 +160,7 @@ async def lifespan(app: FastAPI):
|
||||
if schedule_service is not None:
|
||||
await schedule_service.stop()
|
||||
|
||||
await qingping_service.stop()
|
||||
await service.stop()
|
||||
|
||||
|
||||
@@ -152,6 +220,8 @@ def get_status() -> dict:
|
||||
else None
|
||||
),
|
||||
|
||||
"qingping": qingping_service.status(),
|
||||
|
||||
"schedule": get_schedule_status(),
|
||||
}
|
||||
|
||||
@@ -349,6 +419,30 @@ def get_schedule_status() -> dict:
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
def get_auto_status() -> dict:
|
||||
|
||||
if auto_controller is None:
|
||||
return {
|
||||
"available": False,
|
||||
"state": "unavailable",
|
||||
"reason": None,
|
||||
"target_speed": None,
|
||||
"auto_speed": None,
|
||||
"last_error": None,
|
||||
"config_error": (
|
||||
auto_load_error
|
||||
),
|
||||
}
|
||||
|
||||
return {
|
||||
"available": True,
|
||||
**auto_controller.status(),
|
||||
"config_error": (
|
||||
auto_load_error
|
||||
),
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Status
|
||||
# ----------------------------------------------------------------------
|
||||
@@ -401,24 +495,6 @@ async def increase_speed():
|
||||
),
|
||||
)
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Fan speed
|
||||
# ----------------------------------------------------------------------
|
||||
@app.post("/api/tion/speed/{speed}")
|
||||
async def set_speed(
|
||||
speed: Annotated[
|
||||
int,
|
||||
Path(
|
||||
ge=MIN_FAN_SPEED,
|
||||
le=MAX_FAN_SPEED,
|
||||
),
|
||||
] ):
|
||||
|
||||
return await execute_command(
|
||||
lambda tion: tion.set_speed(speed),
|
||||
ScheduledSettings(speed=speed),
|
||||
)
|
||||
|
||||
|
||||
@app.post("/api/tion/speed/decrease")
|
||||
async def decrease_speed():
|
||||
@@ -440,6 +516,24 @@ async def decrease_speed():
|
||||
)
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Fan speed
|
||||
# ----------------------------------------------------------------------
|
||||
@app.post("/api/tion/speed/{speed}")
|
||||
async def set_speed(
|
||||
speed: Annotated[
|
||||
int,
|
||||
Path(
|
||||
ge=MIN_FAN_SPEED,
|
||||
le=MAX_FAN_SPEED,
|
||||
),
|
||||
] ):
|
||||
|
||||
return await execute_command(
|
||||
lambda tion: tion.set_speed(speed),
|
||||
ScheduledSettings(speed=speed),
|
||||
)
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Heater
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user