|
@@ -10,7 +10,9 @@ from app.controllers.equipment.controller import EquipmentController
|
|
|
from app.models.domain.devices import (
|
|
|
ACATFC2InstructionsRequest,
|
|
|
ACATFC4InstructionsRequest,
|
|
|
+ Speed,
|
|
|
)
|
|
|
+from app.models.domain.feedback import FeedbackValue
|
|
|
from app.schemas.equipment import AirValveSpeed, FCU
|
|
|
from app.schemas.instructions import ACATFCInstructions
|
|
|
from app.schemas.space import Space
|
|
@@ -182,15 +184,69 @@ class FCUControllerV2(EquipmentController):
|
|
|
return self.equipment
|
|
|
|
|
|
|
|
|
+class SpeedController:
|
|
|
+ def __init__(self, current_speed: Speed, running_status: bool) -> None:
|
|
|
+ if running_status:
|
|
|
+ self.current_speed = current_speed
|
|
|
+ else:
|
|
|
+ self.current_speed = Speed.off
|
|
|
+ self.next_speed = current_speed
|
|
|
+
|
|
|
+ def turn_up(self) -> Speed:
|
|
|
+ if self.current_speed == Speed.off:
|
|
|
+ self.next_speed = Speed.low
|
|
|
+ elif self.current_speed == Speed.low:
|
|
|
+ self.next_speed = Speed.medium
|
|
|
+ elif self.current_speed == Speed.medium:
|
|
|
+ self.next_speed = Speed.high
|
|
|
+
|
|
|
+ return self.next_speed
|
|
|
+
|
|
|
+ def turn_down(self) -> Speed:
|
|
|
+ if self.current_speed == Speed.high:
|
|
|
+ self.next_speed = Speed.medium
|
|
|
+ elif self.current_speed == Speed.medium:
|
|
|
+ self.next_speed = Speed.low
|
|
|
+ elif self.current_speed == Speed.low:
|
|
|
+ self.next_speed = Speed.off
|
|
|
+
|
|
|
+ return self.next_speed
|
|
|
+
|
|
|
+ def turn_on(self) -> Speed:
|
|
|
+ self.next_speed = Speed.medium
|
|
|
+
|
|
|
+ return self.next_speed
|
|
|
+
|
|
|
+ def turn_off(self) -> Speed:
|
|
|
+ self.next_speed = Speed.off
|
|
|
+
|
|
|
+ return self.next_speed
|
|
|
+
|
|
|
+ def get_next_speed(self) -> Speed:
|
|
|
+ return self.next_speed
|
|
|
+
|
|
|
+
|
|
|
class ATFC2Controller:
|
|
|
"""Two-wipe ATFC logic"""
|
|
|
|
|
|
- def __init__(self, space_target: float, space_realtime: float, season: Season):
|
|
|
+ def __init__(
|
|
|
+ self,
|
|
|
+ space_target: float,
|
|
|
+ space_realtime: float,
|
|
|
+ season: Season,
|
|
|
+ feedback: FeedbackValue,
|
|
|
+ running_status: bool,
|
|
|
+ speed: Speed,
|
|
|
+ ):
|
|
|
self.space_target = space_target
|
|
|
self.space_realtime = space_realtime
|
|
|
self.season = season
|
|
|
+ self.feedback = feedback
|
|
|
+ self.running_status = running_status
|
|
|
+ self.speed = speed
|
|
|
|
|
|
- def build_speed_set(self) -> str:
|
|
|
+ def build_speed_set(self) -> Speed:
|
|
|
+ speed_controller = SpeedController(self.speed, self.running_status)
|
|
|
if self.space_realtime > 0.0 and self.space_target > 0.0:
|
|
|
if self.season == Season.cooling:
|
|
|
diff = self.space_realtime - self.space_target
|
|
@@ -199,24 +255,47 @@ class ATFC2Controller:
|
|
|
else:
|
|
|
diff = 0.0
|
|
|
|
|
|
- if diff <= 0.0:
|
|
|
- speed = "off"
|
|
|
+ if diff <= -0.2:
|
|
|
+ speed = Speed.off
|
|
|
+ elif diff <= 0.2:
|
|
|
+ speed = Speed.hold
|
|
|
elif diff < 0.5:
|
|
|
- speed = "low"
|
|
|
+ speed = Speed.low
|
|
|
elif diff < 1.5:
|
|
|
- speed = "medium"
|
|
|
+ speed = Speed.medium
|
|
|
else:
|
|
|
- speed = "high"
|
|
|
+ speed = Speed.high
|
|
|
else:
|
|
|
- speed = "hold"
|
|
|
+ speed = Speed.hold
|
|
|
if self.space_target < 0.0:
|
|
|
- speed = "off"
|
|
|
+ speed = Speed.off
|
|
|
+ else:
|
|
|
+ if self.feedback == FeedbackValue.switch_on:
|
|
|
+ speed = Speed.medium
|
|
|
+ elif (
|
|
|
+ self.feedback == FeedbackValue.so_hot
|
|
|
+ or self.feedback == FeedbackValue.a_little_hot
|
|
|
+ ):
|
|
|
+ if self.season == Season.cooling:
|
|
|
+ speed = speed_controller.turn_up()
|
|
|
+ elif self.season == Season.heating:
|
|
|
+ speed = speed_controller.turn_down()
|
|
|
+ elif (
|
|
|
+ self.feedback == FeedbackValue.so_cold
|
|
|
+ or self.feedback == FeedbackValue.a_little_cold
|
|
|
+ ):
|
|
|
+ if self.season == Season.cooling:
|
|
|
+ speed = speed_controller.turn_down()
|
|
|
+ elif self.season == Season.heating:
|
|
|
+ speed = speed_controller.turn_up()
|
|
|
|
|
|
return speed
|
|
|
|
|
|
- def build_switch_set(self, new_speed_set: str) -> str:
|
|
|
- if new_speed_set == "off":
|
|
|
+ def build_switch_set(self, new_speed_set: Speed) -> str:
|
|
|
+ if new_speed_set == Speed.off:
|
|
|
switch_set = "off"
|
|
|
+ elif new_speed_set == Speed.hold:
|
|
|
+ switch_set = "hold"
|
|
|
else:
|
|
|
switch_set = "on"
|
|
|
|
|
@@ -242,22 +321,49 @@ class ATFC2Controller:
|
|
|
class ATFC4Controller(ATFC2Controller):
|
|
|
"""Four-wipe ATFC logic"""
|
|
|
|
|
|
- def __init__(self, space_target: float, space_realtime: float, season: Season):
|
|
|
- super().__init__(space_target, space_realtime, season)
|
|
|
+ def __init__(
|
|
|
+ self,
|
|
|
+ space_target: float,
|
|
|
+ space_realtime: float,
|
|
|
+ season: Season,
|
|
|
+ feedback: FeedbackValue,
|
|
|
+ running_status: bool,
|
|
|
+ speed: Speed,
|
|
|
+ ):
|
|
|
+ super().__init__(
|
|
|
+ space_target, space_realtime, season, feedback, running_status, speed
|
|
|
+ )
|
|
|
|
|
|
- def build_speed_set(self) -> str:
|
|
|
+ def build_speed_set(self) -> Speed:
|
|
|
speed = super().build_speed_set()
|
|
|
if self.season == Season.heating:
|
|
|
+ speed_controller = SpeedController(self.speed, self.running_status)
|
|
|
if self.space_target > 0.0 and self.space_realtime > 0.0:
|
|
|
diff = abs(self.space_realtime - self.space_target)
|
|
|
if diff < 0.2:
|
|
|
- speed = "off"
|
|
|
- elif diff < 0.8:
|
|
|
- speed = "low"
|
|
|
+ speed = Speed.hold
|
|
|
+ elif diff < 0.5:
|
|
|
+ speed = Speed.low
|
|
|
elif diff < 1.5:
|
|
|
- speed = "medium"
|
|
|
+ speed = Speed.medium
|
|
|
+ else:
|
|
|
+ speed = Speed.high
|
|
|
+ else:
|
|
|
+ if self.space_target < 0.0:
|
|
|
+ speed = Speed.off
|
|
|
else:
|
|
|
- speed = "high"
|
|
|
+ if self.feedback == FeedbackValue.switch_on:
|
|
|
+ speed = Speed.medium
|
|
|
+ elif (
|
|
|
+ self.feedback == FeedbackValue.so_hot
|
|
|
+ or self.feedback == FeedbackValue.a_little_hot
|
|
|
+ ):
|
|
|
+ speed = speed_controller.turn_up()
|
|
|
+ elif (
|
|
|
+ self.feedback == FeedbackValue.so_cold
|
|
|
+ or self.feedback == FeedbackValue.a_little_cold
|
|
|
+ ):
|
|
|
+ speed = speed_controller.turn_up()
|
|
|
|
|
|
return speed
|
|
|
|
|
@@ -268,15 +374,33 @@ class ATFC4Controller(ATFC2Controller):
|
|
|
else:
|
|
|
if self.season == Season.heating:
|
|
|
if self.space_realtime > 0.0:
|
|
|
- if self.space_realtime > self.space_target:
|
|
|
+ if self.space_realtime - self.space_target >= 0.2:
|
|
|
chill_water_valve_set = "on"
|
|
|
hot_water_valve_set = "off"
|
|
|
- else:
|
|
|
+ elif self.space_target - self.space_realtime >= 0.2:
|
|
|
chill_water_valve_set = "off"
|
|
|
hot_water_valve_set = "on"
|
|
|
+ else:
|
|
|
+ chill_water_valve_set = "hold"
|
|
|
+ hot_water_valve_set = "hold"
|
|
|
else:
|
|
|
chill_water_valve_set = "hold"
|
|
|
hot_water_valve_set = "hold"
|
|
|
+ if self.feedback == FeedbackValue.switch_on:
|
|
|
+ chill_water_valve_set = "off"
|
|
|
+ hot_water_valve_set = "on"
|
|
|
+ elif (
|
|
|
+ self.feedback == FeedbackValue.so_hot
|
|
|
+ or self.feedback == FeedbackValue.a_little_hot
|
|
|
+ ):
|
|
|
+ chill_water_valve_set = "on"
|
|
|
+ hot_water_valve_set = "off"
|
|
|
+ elif (
|
|
|
+ self.feedback == FeedbackValue.so_cold
|
|
|
+ or self.feedback == FeedbackValue.a_little_cold
|
|
|
+ ):
|
|
|
+ chill_water_valve_set = "off"
|
|
|
+ hot_water_valve_set = "on"
|
|
|
else:
|
|
|
chill_water_valve_set = "on"
|
|
|
hot_water_valve_set = "off"
|
|
@@ -411,7 +535,12 @@ async def build_acatfc2_instructions_v2(params: ACATFC2InstructionsRequest) -> d
|
|
|
params.space_realtime_temperature if params.space_realtime_temperature else -1
|
|
|
)
|
|
|
controller = ATFC2Controller(
|
|
|
- params.space_temperature_target, space_realtime, Season(params.season)
|
|
|
+ params.space_temperature_target,
|
|
|
+ space_realtime,
|
|
|
+ Season(params.season),
|
|
|
+ params.feedback,
|
|
|
+ params.running_status,
|
|
|
+ params.speed,
|
|
|
)
|
|
|
instructions = controller.run()
|
|
|
|
|
@@ -424,7 +553,12 @@ async def build_acatfc4_instructions_v2(params: ACATFC4InstructionsRequest) -> d
|
|
|
params.space_realtime_temperature if params.space_realtime_temperature else -1
|
|
|
)
|
|
|
controller = ATFC4Controller(
|
|
|
- params.space_temperature_target, space_realtime, Season(params.season)
|
|
|
+ params.space_temperature_target,
|
|
|
+ space_realtime,
|
|
|
+ Season(params.season),
|
|
|
+ params.feedback,
|
|
|
+ params.running_status,
|
|
|
+ params.speed,
|
|
|
)
|
|
|
instructions = controller.run()
|
|
|
|