Forráskód Böngészése

fix some bugs in on ratio experiment

chenhaiyang 4 éve
szülő
commit
f4448118e4

+ 12 - 1
app/api/routers/devices.py

@@ -1,7 +1,8 @@
-from fastapi import APIRouter, Query
+from fastapi import APIRouter, BackgroundTasks, Query
 
 from app.controllers.equipment.ahu.supply_air_temperature_set import get_next_supply_air_temperature_set
 from app.controllers.equipment.ahu.thermal_mode import get_thermal_mode
+from app.controllers.equipment.fcu.on_ratio import start_on_ratio_mode
 from app.models.domain.devices import DevicesInstructionsBaseResponse
 
 
@@ -38,3 +39,13 @@ async def get_acatah_supply_air_temperature_set(
             'supplyAirTemperatureSet': next_supply_air_temperature_set
         }
     }
+
+
+@router.post('/on-ratio-experiment/fcu/{fcu_id}/target/{target}/period/{period}')
+async def run_on_ratio_experiment(fcu_id: str, target: float, period: int, background_tasks: BackgroundTasks):
+    background_tasks.add_task(start_on_ratio_mode, fcu_id, target, period)
+    return {
+        'fcu': fcu_id,
+        'target': target,
+        'period': period
+    }

+ 3 - 12
app/controllers/equipment/events.py

@@ -5,7 +5,7 @@ from httpx import AsyncClient
 
 from app.controllers.equipment.ahu.basic import get_freq_controlled
 from app.controllers.equipment.ahu.switch import ahu_switch_control
-from app.controllers.equipment.fcu.on_ratio import start_control_group_mode, start_on_ratio_mode
+from app.controllers.equipment.fcu.on_ratio import start_control_group_mode
 from app.controllers.equipment.pau.switch import pau_switch_control
 from app.controllers.equipment.ventilation_fan.switch import ventilation_fan_switch_control
 from app.services.platform import DataPlatformService
@@ -58,14 +58,5 @@ async def regulate_ventilation_fan_switch():
 
 @repeat_every(seconds=60 * 15)
 async def run_control_group():
-    _FCU_LIST = [
-        'Eq11010802593142c55b64c5492c92560d280885a2f7',
-        'Eq11010802598449efe230f444cca826e840dbf67f41'
-    ]
-    for fcu in _FCU_LIST:
-        await start_control_group_mode(fcu)
-
-
-async def run_experiment_group():
-    await start_on_ratio_mode('Eq11010802593129d7ff3d9b4fd296f30927fd8fb76d')
-    await start_on_ratio_mode('Eq1101080259ea519ed43678481c8a8c108fa85e5aa3')
+    await start_control_group_mode('Eq11010802593142c55b64c5492c92560d280885a2f7', 30.2)
+    await start_control_group_mode('Eq11010802598449efe230f444cca826e840dbf67f41', 30.1)

+ 44 - 40
app/controllers/equipment/fcu/on_ratio.py

@@ -1,5 +1,4 @@
 import asyncio
-import time
 from typing import Tuple
 
 import arrow
@@ -68,6 +67,8 @@ class OnRatioController:
             else:
                 try:
                     ratio = (0.5 * (self.return_air - self.target) + delta_off) / (delta_off - delta_on)
+                    if ratio > 1:
+                        ratio = 1.0
                 except ZeroDivisionError:
                     ratio = 0.0
 
@@ -119,62 +120,65 @@ async def fetch_params(device_id: str, period_time: int, last_ratio: float) -> T
 
 
 @logger.catch()
-async def start_on_ratio_mode(device_id):
-    _TARGET = 26.0
+async def start_on_ratio_mode(device_id: str, target: float, period_time: int):
     _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 < 10:
-        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, delta_all, 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(delta_all)
-            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(device_id, switch, speed, water_valve)
-                await asyncio.sleep(on_range)
-                await send_instructions(device_id, switch, speed, False)
-                await asyncio.sleep(off_range)
-
-                period_num += 1
-                last_on_ratio = on_ratio
+    while life_count < 2000:
+        try:
+            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, delta_all, 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(delta_all)
+                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
+                    logger.debug(f'on time: {on_range}, off time: {off_range}, on ratio: {on_ratio}')
+
+                    await send_instructions(device_id, switch, speed, water_valve)
+                    await asyncio.sleep(on_range)
+                    await send_instructions(device_id, switch, speed, False)
+                    await asyncio.sleep(off_range)
+
+                    period_num += 1
+                    last_on_ratio = on_ratio
+                else:
+                    await send_instructions(device_id, switch, speed, water_valve)
+                    await asyncio.sleep(period_time)
+
+                    period_num = 0
+                    last_on_ratio = 1.0
+
+                life_count += 1
+
+                logger.info(f'{life_count}: {device_id} - {mode}')
             else:
-                await send_instructions(device_id, switch, speed, water_valve)
-                time.sleep(period_time)
-
+                await send_instructions(device_id, False, 'off', False)
                 period_num = 0
-                last_on_ratio = 1.0
-
-            life_count += 1
-
-            logger.info(f'{life_count}: {device_id} - {mode}')
-        else:
-            await send_instructions(device_id, False, 'off', False)
-            period_num = 0
-            last_on_ratio = 0.0
+                last_on_ratio = 0.0
+                await asyncio.sleep(period_time)
+        except (KeyError, IndexError, TypeError):
+            continue
 
 
 @logger.catch()
-async def start_control_group_mode(device_id: str):
+async def start_control_group_mode(device_id: str, target: float):
     async with AsyncClient() as client:
         platform = DataPlatformService(client, 'Pj1101080259')
 
         return_air = await platform.get_realtime_data(InfoCode.return_air_temperature, device_id)
         space_params = {
             'id': device_id,
-            'temperature_target': 26.0,
+            'temperature_target': target,
             'realtime_temperature': return_air
         }
         space = Space(**space_params)

+ 1 - 3
app/core/events.py

@@ -9,8 +9,7 @@ from app.controllers.equipment.events import (
     regulate_ahu_switch,
     regulate_pau_switch,
     regulate_ventilation_fan_switch,
-    run_control_group,
-    run_experiment_group
+    run_control_group
 )
 from app.controllers.events import load_q_learning_model
 
@@ -22,7 +21,6 @@ def create_start_app_handler(app: Optional[FastAPI] = None) -> Callable:
         await regulate_ahu_switch()
         await regulate_pau_switch()
         await regulate_ventilation_fan_switch()
-        # await run_experiment_group()
         await run_control_group()
 
     return start_app