Explorar o código

add partial code of on ratio experiment

chenhaiyang %!s(int64=4) %!d(string=hai) anos
pai
achega
0168d57158
Modificáronse 1 ficheiros con 77 adicións e 9 borrados
  1. 77 9
      app/controllers/equipment/fcu/on_ratio.py

+ 77 - 9
app/controllers/equipment/fcu/on_ratio.py

@@ -1,17 +1,21 @@
-from typing import Dict
+import time
+from typing import Dict, Tuple
 
+import arrow
 from httpx import AsyncClient
 from loguru import logger
 
+from app.utils.math import round_half_up
+from app.utils.date import get_time_str, TIME_FMT
 
-class OffRatioController:
 
-    def __init__(self, target: float, return_air: float, period_num: int, last_off_ratio: float):
-        super(OffRatioController, self).__init__()
+class OnRatioController:
+
+    def __init__(self, target: float, return_air: float, period_num: int):
+        super(OnRatioController, self).__init__()
         self.target = target
         self.return_air = return_air
         self.period_num = period_num
-        self.last_off_ratio = last_off_ratio
 
     def select_mode(self) -> str:
         if self.target < self.return_air:
@@ -20,7 +24,7 @@ class OffRatioController:
             if self.target - self.return_air > 1:
                 mode = 'normal'
             else:
-                mode = 'off_ratio'
+                mode = 'on_ratio'
 
         return mode
 
@@ -29,7 +33,7 @@ class OffRatioController:
         if mode == 'off':
             speed = 'off'
         elif mode == 'normal':
-            if (self.return_air - last_return_air) / 10 > 0.053:
+            if (self.return_air - last_return_air) > 0.8:
                 speed = 'medium'
             else:
                 speed = 'high'
@@ -49,6 +53,70 @@ class OffRatioController:
 
         return switch
 
-    def calculate_off_ratio(self) -> float:
-        
+    def calculate_on_ratio(self, delta_on: float, delta_off: float) -> float:
+        if self.period_num == 0:
+            ratio = 0.5
+        else:
+            if delta_on <= 0:
+                ratio = 1.0
+            else:
+                try:
+                    ratio = (0.5 * (self.return_air - self.target) + delta_off) / (delta_off - delta_on)
+                except ZeroDivisionError:
+                    ratio = 0.0
+
+        return ratio
+
+
+async def send_instructions(switch: bool, speed: str, water_valve: bool) -> None:
+    pass
+
+
+async def fetch_params(device_id: str, period_time: float, last_ratio: float) -> Tuple[float, float, float, float]:
+    pass
+
 
+@logger.catch()
+async def on_ratio_experiment(device_id):
+    _TARGET = 26.0
+    _DAILY_ON_TIME = '060000'
+    _DAILY_OFF_TIME = '220000'
+
+    period_time = 10 * 60
+    period_num = 0
+    last_on_ratio = 1.0
+    life_count = 0
+    while life_count < 1000:
+        time_str = get_time_str()
+        if _DAILY_ON_TIME <= arrow.get(time_str, TIME_FMT).time().strftime('%H%M%S') < _DAILY_OFF_TIME:
+            return_air, last_return_air, delta_on, delta_off = await fetch_params(device_id, period_time, last_on_ratio)
+            controller = OnRatioController(_TARGET, return_air, period_num)
+            mode = controller.select_mode()
+            speed = controller.select_speed(last_return_air)
+            switch = False if speed == 'off' else True
+            water_valve = controller.select_water_valve()
+
+            if mode == 'on_ratio':
+                on_ratio = controller.calculate_on_ratio(delta_on, delta_off)
+                on_range = round_half_up(period_time * on_ratio)
+                off_range = period_time - on_range
+
+                await send_instructions(switch, speed, water_valve)
+                time.sleep(on_range)
+                await send_instructions(switch, speed, False)
+                time.sleep(off_range)
+
+                period_num += 1
+                last_on_ratio = on_ratio
+            else:
+                await send_instructions(switch, speed, water_valve)
+                time.sleep(period_time)
+
+                period_num = 0
+                last_on_ratio = 1.0
+
+            life_count += 1
+        else:
+            await send_instructions(False, 'off', False)
+            period_num = 0
+            last_on_ratio = 0.0