Ver Fonte

refactor(model): 重构 DHU_AB 模型并优化数据加载流程

- 更新配置文件路径,使用新的 DHU_AB 配置
- 修正数据加载方法,增加点位剔除功能
- 改进模型初始化,增加存在回风口和补风口的参数
- 优化模型输入,根据实际需求动态添加混合空气参数
- 更新模型结构,替换蒸汽盘管为加热盘管
- 调整结果输出格式,统一命名 conventions
zhangshenhao há 6 meses atrás
pai
commit
466453de33
5 ficheiros alterados com 101 adições e 67 exclusões
  1. 3 3
      apps/optimize/optimize.py
  2. 27 11
      apps/train/train.py
  3. 45 37
      model/DHU/DHU_AB.py
  4. 3 3
      tools/config_reader.py
  5. 23 13
      tools/data_loader.py

+ 3 - 3
apps/optimize/optimize.py

@@ -21,7 +21,7 @@ def optimize(*inputs,config=None):
         config_reader_path = '/mnt/workflow_data'
         config_reader_path = '/mnt/workflow_data'
         data_URL           = 'http://basedataportal-svc:8080/data/getpointsdata'
         data_URL           = 'http://basedataportal-svc:8080/data/getpointsdata'
         
         
-    config_reader = ConfigReader(path=f'{config_reader_path}/DHU_A配置.xlsx')
+    config_reader = ConfigReader(path=f'{config_reader_path}/DHU_AB配置.xlsx')
     
     
     ALL_RESULT = {
     ALL_RESULT = {
         'EXCEPTION':{
         'EXCEPTION':{
@@ -82,7 +82,7 @@ def optimize(*inputs,config=None):
                 start_time = NOW - timedelta(minutes=room_steady_len),
                 start_time = NOW - timedelta(minutes=room_steady_len),
                 end_time   = NOW
                 end_time   = NOW
             )
             )
-            room_data_loader.dowload_equp_data(
+            room_data_loader.download_equp_data(
                 equp_name   = each_eaup_name,
                 equp_name   = each_eaup_name,
                 point       = config_reader.get_equp_point(each_eaup_name,equp_class=['C']),
                 point       = config_reader.get_equp_point(each_eaup_name,equp_class=['C']),
                 url         = data_URL,
                 url         = data_URL,
@@ -121,7 +121,7 @@ def optimize(*inputs,config=None):
                     start_time = NOW - timedelta(minutes=dhu_steady_len),
                     start_time = NOW - timedelta(minutes=dhu_steady_len),
                     end_time   = NOW
                     end_time   = NOW
                 )
                 )
-                .dowload_equp_data(
+                .download_equp_data(
                     equp_name   = each_eaup_name,
                     equp_name   = each_eaup_name,
                     point       = data_input_point,
                     point       = data_input_point,
                     url         = data_URL,
                     url         = data_URL,

+ 27 - 11
apps/train/train.py

@@ -26,7 +26,7 @@ def train(*inputs,config=None):
         data_URL           = 'http://basedataportal-svc:8080/data/getpointsdata'
         data_URL           = 'http://basedataportal-svc:8080/data/getpointsdata'
         plot_metric        = False
         plot_metric        = False
         
         
-    config_reader = ConfigReader(path=f'{config_reader_path}/DHU_A配置.xlsx')
+    config_reader = ConfigReader(path=f'{config_reader_path}/DHU_AB配置.xlsx')
     
     
     ALL_RESULT = {
     ALL_RESULT = {
         'EXCEPTION':{
         'EXCEPTION':{
@@ -41,16 +41,26 @@ def train(*inputs,config=None):
         
         
         # 获取数据
         # 获取数据
         try:
         try:
+            # 部分情况下设备不需要部分点位表中的点位
+            rm_point_name = []
+            if not config_reader.get_equp_info(each_eaup_name,'存在回风口','bool'):
+                rm_point_name += ['mixed_1_TinM','mixed_1_DinM']
+            if not config_reader.get_equp_info(each_eaup_name,'存在补风口','bool'):
+                rm_point_name += ['mixed_2_TinM','mixed_2_DinM']
+            
+            # 获取历史数据
             data_loader = DataLoader(
             data_loader = DataLoader(
                 path       = f'{config_reader_path}/data/train/data_his/',
                 path       = f'{config_reader_path}/data/train/data_his/',
                 start_time = config_reader.get_app_info(each_eaup_name,app_type='模型训练',key='开始时间',info_type='datetime'),
                 start_time = config_reader.get_app_info(each_eaup_name,app_type='模型训练',key='开始时间',info_type='datetime'),
-                end_time   = config_reader.get_app_info(each_eaup_name,app_type='模型训练',key='结束时间',info_type='datetime')
+                end_time   = config_reader.get_app_info(each_eaup_name,app_type='模型训练',key='结束时间',info_type='datetime'),
+                print_process = config_reader.get_app_info(each_eaup_name,app_type='模型训练',key='打印取数日志',info_type='bool'),
             )
             )
-            data_loader.dowload_equp_data(
-                equp_name   = each_eaup_name,
-                point       = config_reader.get_equp_point(each_eaup_name,equp_type,equp_class=['A','B']),
-                url         = data_URL,
-                clean_cache = False
+            data_loader.download_equp_data(
+                equp_name     = each_eaup_name,
+                point         = config_reader.get_equp_point(each_eaup_name,equp_type,equp_class=['A','B']),
+                url           = data_URL,
+                clean_cache   = False,
+                rm_point_name = rm_point_name
             )
             )
             equp_data = data_loader.get_equp_data(each_eaup_name)
             equp_data = data_loader.get_equp_data(each_eaup_name)
             save_data(f'{config_reader_path}/data/train/data_his_raw',f'{each_eaup_name}.pkl',equp_data)
             save_data(f'{config_reader_path}/data/train/data_his_raw',f'{each_eaup_name}.pkl',equp_data)
@@ -58,9 +68,16 @@ def train(*inputs,config=None):
             ALL_RESULT['EXCEPTION']['Data'][each_eaup_name] = E
             ALL_RESULT['EXCEPTION']['Data'][each_eaup_name] = E
             continue
             continue
         
         
+        if not config_reader.get_app_info(each_eaup_name,'模型训练','训练模型','bool'):
+            continue
+        
         # 训练模型 
         # 训练模型 
         try:
         try:
-            equp_model = DHU_AB(DHU_type=equp_type)
+            equp_model = DHU_AB(
+                DHU_type   = equp_type,
+                exist_Fa_H = config_reader.get_equp_info(each_eaup_name,'存在回风口','bool'),
+                exist_Fa_B = config_reader.get_equp_info(each_eaup_name,'存在补风口','bool'),
+            )
             
             
             # 清洗数据
             # 清洗数据
             Path(f'{config_reader_path}/data/train/clean_log/').mkdir(parents=True, exist_ok=True)
             Path(f'{config_reader_path}/data/train/clean_log/').mkdir(parents=True, exist_ok=True)
@@ -80,8 +97,6 @@ def train(*inputs,config=None):
                 observed_data = equp_data,
                 observed_data = equp_data,
                 plot_TVP      = False,
                 plot_TVP      = False,
                 rw_FA_val     = True, #TODO
                 rw_FA_val     = True, #TODO
-                exist_Fa_H    = config_reader.get_equp_info(each_eaup_name,'存在回风口','bool'),
-                exist_Fa_B    = config_reader.get_equp_info(each_eaup_name,'存在补风口','bool'),
             )
             )
             Path(f'{config_reader_path}/model').mkdir(parents=True, exist_ok=True)
             Path(f'{config_reader_path}/model').mkdir(parents=True, exist_ok=True)
             equp_model.save(f'{config_reader_path}/model/{each_eaup_name}.pkl')
             equp_model.save(f'{config_reader_path}/model/{each_eaup_name}.pkl')
@@ -136,4 +151,5 @@ def save_data(dir,file:str,data:pd.DataFrame):
     elif file.endswith('.pkl'):
     elif file.endswith('.pkl'):
         data.to_pickle(os.path.join(dir,file))
         data.to_pickle(os.path.join(dir,file))
     else:
     else:
-        raise Exception('file type error')
+        raise Exception('file type error')
+

+ 45 - 37
model/DHU/DHU_AB.py

@@ -26,6 +26,8 @@ class DHU_AB(BaseDevice):
     def __init__(
     def __init__(
         self,
         self,
         DHU_type      = 'A',
         DHU_type      = 'A',
+        exist_Fa_H    = True,
+        exist_Fa_B    = True,
         wheel_1       = None,
         wheel_1       = None,
         wheel_2       = 'WheelS3',
         wheel_2       = 'WheelS3',
         coolingcoil_2 = 'CoolingCoil2',
         coolingcoil_2 = 'CoolingCoil2',
@@ -38,7 +40,6 @@ class DHU_AB(BaseDevice):
     ) -> None:
     ) -> None:
         super().__init__()
         super().__init__()
         self.DHU_type = DHU_type.replace('DHU_','')
         self.DHU_type = DHU_type.replace('DHU_','')
-        
         if self.DHU_type == 'A':
         if self.DHU_type == 'A':
             wheel_1 = wheel_1 if wheel_1 is not None else 'WheelS3'
             wheel_1 = wheel_1 if wheel_1 is not None else 'WheelS3'
         elif self.DHU_type == 'B':
         elif self.DHU_type == 'B':
@@ -59,7 +60,14 @@ class DHU_AB(BaseDevice):
                 'mixed_1'      : mixed_1,
                 'mixed_1'      : mixed_1,
                 'mixed_2'      : mixed_2
                 'mixed_2'      : mixed_2
             }
             }
-        self.record_load_info(components=self.components,DHU_type=DHU_type)
+        self.exist_Fa_H = exist_Fa_H
+        self.exist_Fa_B = exist_Fa_B
+        self.record_load_info(
+            components = self.components,
+            DHU_type   = self.DHU_type,
+            exist_Fa_H = self.exist_Fa_H,
+            exist_Fa_B = self.exist_Fa_B
+        )
         self.components = {k:eval(v)(k) for k,v in self.components.items()}
         self.components = {k:eval(v)(k) for k,v in self.components.items()}
         
         
         for idx in [1,2]:
         for idx in [1,2]:
@@ -89,11 +97,13 @@ class DHU_AB(BaseDevice):
             'coil_3_Val'  : 'coil_3_Val',
             'coil_3_Val'  : 'coil_3_Val',
             'wheel_1_TinR': 'wheel_1_TinR',
             'wheel_1_TinR': 'wheel_1_TinR',
             'wheel_2_TinR': 'wheel_2_TinR',
             'wheel_2_TinR': 'wheel_2_TinR',
-            'mixed_1_TinM': 'mixed_1_TinM',
-            'mixed_2_TinM': 'mixed_2_TinM',
-            'mixed_1_HinM': 'mixed_1_HinM',
-            'mixed_2_HinM': 'mixed_2_HinM',
         }
         }
+        if self.exist_Fa_H:
+            columns['mixed_1_TinM'] = 'mixed_1_TinM'
+            columns['mixed_1_HinM'] = 'mixed_1_HinM'
+        if self.exist_Fa_B:
+            columns['mixed_2_TinM'] = 'mixed_2_TinM'
+            columns['mixed_2_HinM'] = 'mixed_2_HinM'
         return columns
         return columns
     
     
     @property
     @property
@@ -116,8 +126,6 @@ class DHU_AB(BaseDevice):
         self,
         self,
         input_data   : pd.DataFrame,
         input_data   : pd.DataFrame,
         observed_data: pd.DataFrame,
         observed_data: pd.DataFrame,
-        exist_Fa_H   : bool,
-        exist_Fa_B   : bool,
         rw_FA_val    : bool = False,
         rw_FA_val    : bool = False,
         plot_TVP     : bool = True,
         plot_TVP     : bool = True,
     ):
     ):
@@ -129,8 +137,8 @@ class DHU_AB(BaseDevice):
             param_prior['F_air'] = AirFlow_DHU_AB.prior(
             param_prior['F_air'] = AirFlow_DHU_AB.prior(
                 rw_FA_val  = rw_FA_val,
                 rw_FA_val  = rw_FA_val,
                 N          = len(input_data),
                 N          = len(input_data),
-                exist_Fa_H = exist_Fa_H,
-                exist_Fa_B = exist_Fa_B
+                exist_Fa_H = self.exist_Fa_H,
+                exist_Fa_B = self.exist_Fa_B
             )
             )
             
             
             res = self.model(
             res = self.model(
@@ -279,13 +287,13 @@ def model_A(
     coil_3_Val,   # 后表冷阀门开度
     coil_3_Val,   # 后表冷阀门开度
     wheel_1_TinR, # 前转轮再生侧温度
     wheel_1_TinR, # 前转轮再生侧温度
     wheel_2_TinR, # 后转轮再生侧温度
     wheel_2_TinR, # 后转轮再生侧温度
-    mixed_1_TinM, # 回风温度(处理侧)
-    mixed_1_HinM, # 回风湿度(处理侧)
-    mixed_2_TinM, # 补风温度(再生侧)
-    mixed_2_HinM, # 补风湿度(再生侧)
     engine    : str,
     engine    : str,
     components: dict,
     components: dict,
     param     : dict,
     param     : dict,
+    mixed_1_TinM = 0, # 回风温度(处理侧)
+    mixed_1_HinM = 0, # 回风湿度(处理侧)
+    mixed_2_TinM = 0, # 补风温度(再生侧)
+    mixed_2_HinM = 0, # 补风湿度(再生侧)
 ) ->  dict:
 ) ->  dict:
     
     
     # 水的质量流量
     # 水的质量流量
@@ -444,13 +452,13 @@ def model_B(
     coil_3_Val,   # 后表冷阀门开度
     coil_3_Val,   # 后表冷阀门开度
     wheel_1_TinR, # 前转轮再生侧温度
     wheel_1_TinR, # 前转轮再生侧温度
     wheel_2_TinR, # 后转轮再生侧温度
     wheel_2_TinR, # 后转轮再生侧温度
-    mixed_1_TinM, # 回风温度(处理侧)
-    mixed_1_HinM, # 回风湿度(处理侧)
-    mixed_2_TinM, # 补风温度(再生侧)
-    mixed_2_HinM, # 补风湿度(再生侧)
     engine    : str,
     engine    : str,
     components: dict,
     components: dict,
     param     : dict,
     param     : dict,
+    mixed_1_TinM = 0, # 回风温度(处理侧)
+    mixed_1_HinM = 0, # 回风湿度(处理侧)
+    mixed_2_TinM = 0, # 补风温度(再生侧)
+    mixed_2_HinM = 0, # 补风湿度(再生侧)
 ) ->  dict:
 ) ->  dict:
     
     
     # 水的质量流量
     # 水的质量流量
@@ -468,7 +476,7 @@ def model_B(
         HinR   = 0,
         HinR   = 0,
         FR     = air_flow['wheel_1_FaR'],
         FR     = air_flow['wheel_1_FaR'],
         engine = engine,
         engine = engine,
-        param  = param,
+        param  = param['wheel_1'],
     )
     )
     
     
     # 处理侧混风(回风)
     # 处理侧混风(回风)
@@ -555,39 +563,39 @@ def model_B(
         HinR   = mixed_2_res['HoutA'],
         HinR   = mixed_2_res['HoutA'],
         FR     = air_flow['wheel_1_FaR'],
         FR     = air_flow['wheel_1_FaR'],
         engine = engine,
         engine = engine,
-        param  = param,
+        param  = param['wheel_1'],
     )
     )
     
     
     # 前蒸气盘管
     # 前蒸气盘管
-    steamcoil_1_res = components['steamcoil_1'].model(
+    heatingcoil_1_res = components['heatingcoil_1'].model(
         TinA   = mixed_2_res['ToutA'],
         TinA   = mixed_2_res['ToutA'],
         ToutA  = wheel_1_TinR,
         ToutA  = wheel_1_TinR,
-        FA     = air_flow['steamcoil_1_Fa'],
-        param  = param['steamcoil_1'],
+        FA     = air_flow['heatingcoil_1_Fa'],
+        param  = param['heatingcoil_1'],
         engine = engine
         engine = engine
     )
     )
     
     
     # 后蒸气盘管
     # 后蒸气盘管
-    steamcoil_2_res = components['steamcoil_2'].model(
+    heatingcoil_2_res = components['heatingcoil_2'].model(
         TinA   = wheel_2_res_adj['ToutC'],
         TinA   = wheel_2_res_adj['ToutC'],
         ToutA  = wheel_2_TinR,
         ToutA  = wheel_2_TinR,
-        FA     = air_flow['steamcoil_2_Fa'],
-        param  = param['steamcoil_2'],
+        FA     = air_flow['heatingcoil_2_Fa'],
+        param  = param['heatingcoil_2'],
         engine = engine
         engine = engine
     )
     )
     
     
     return {
     return {
-        'coil_2'     : coil_2_res,
-        'coil_3'     : coil_3_res,
-        'wheel_1'    : wheel_1_res_adj,
-        'wheel_2'    : wheel_2_res_adj,
-        'mixed_1'    : mixed_1_res,
-        'mixed_2'    : mixed_2_res,
-        'steamcoil_1': steamcoil_1_res,
-        'steamcoil_2': steamcoil_2_res,
-        'Fa'         : air_flow,
-        'summary'    : {
-            'Fs':steamcoil_1_res['Fs'] + steamcoil_2_res['Fs'],
+        'coil_2'       : coil_2_res,
+        'coil_3'       : coil_3_res,
+        'wheel_1'      : wheel_1_res_adj,
+        'wheel_2'      : wheel_2_res_adj,
+        'mixed_1'      : mixed_1_res,
+        'mixed_2'      : mixed_2_res,
+        'heatingcoil_1': heatingcoil_1_res,
+        'heatingcoil_2': heatingcoil_2_res,
+        'Fa'           : air_flow,
+        'summary'      : {
+            'Fs':heatingcoil_1_res['Fs'] + heatingcoil_2_res['Fs'],
         }
         }
     }
     }
     
     

+ 3 - 3
tools/config_reader.py

@@ -11,8 +11,8 @@ class ConfigReader:
         self.equp  = pd.read_excel(self.path,sheet_name='设备')
         self.equp  = pd.read_excel(self.path,sheet_name='设备')
         self.point = pd.read_excel(self.path,sheet_name='点位')
         self.point = pd.read_excel(self.path,sheet_name='点位')
         self.app   = pd.read_excel(self.path,sheet_name='程序')
         self.app   = pd.read_excel(self.path,sheet_name='程序')
-        self.meta  = pd.read_excel(self.path,sheet_name='元数据')
-        self.meta  = {self.meta.loc[:,'Key'].iat[i]:self.meta.loc[:,'Value'].iat[i] for i in range(len(self.meta))}
+        # self.meta  = pd.read_excel(self.path,sheet_name='元数据')
+        # self.meta  = {self.meta.loc[:,'Key'].iat[i]:self.meta.loc[:,'Value'].iat[i] for i in range(len(self.meta))}
     
     
     @property
     @property
     def all_equp_names(self):
     def all_equp_names(self):
@@ -62,7 +62,7 @@ class ConfigReader:
         # 更新全局配置
         # 更新全局配置
         if equp_name in value.columns:
         if equp_name in value.columns:
             equp_value = value.loc[:,equp_name].iat[0]
             equp_value = value.loc[:,equp_name].iat[0]
-            if isinstance(equp_value,str):
+            if isinstance(equp_value,(str,float)) and not np.isnan(equp_value):
                 info_value = equp_value
                 info_value = equp_value
         # 调整数据类型
         # 调整数据类型
         info_value = convert_info_type(info_value,info_type)
         info_value = convert_info_type(info_value,info_type)

+ 23 - 13
tools/data_loader.py

@@ -1,4 +1,6 @@
 import os
 import os
+import sys
+import io
 import re
 import re
 from pathlib import Path
 from pathlib import Path
 import shutil
 import shutil
@@ -14,21 +16,23 @@ get_Hr  = np.vectorize(psychrolib.GetHumRatioFromTDewPoint)
 from .._data.main import get_data
 from .._data.main import get_data
 
 
 class DataLoader:
 class DataLoader:
-    def __init__(self,path,start_time,end_time):
-        self.path        = path
-        self.start_time  = start_time
-        self.end_time    = end_time
-        self.int_time    = 'min'
-        self.date_range  = pd.date_range(start=self.start_time,end=self.end_time,freq=self.int_time)
-        
+    def __init__(self,path,start_time,end_time,print_process=True):
+        self.path          = path
+        self.start_time    = start_time
+        self.end_time      = end_time
+        self.int_time      = 'min'
+        self.date_range    = pd.date_range(start=self.start_time,end=self.end_time,freq=self.int_time)
+        self.print_process = print_process
     
     
-    def dowload_equp_data(
+    def download_equp_data(
         self,
         self,
-        equp_name  : str,
-        point      : dict,
-        url        : str,
-        clean_cache: bool
+        equp_name    : str,
+        point        : dict,
+        url          : str,
+        clean_cache  : bool,
+        rm_point_name: list = None
     ):
     ):
+        
         equp_path = os.path.join(self.path,equp_name)
         equp_path = os.path.join(self.path,equp_name)
         if clean_cache and os.path.exists(equp_path):
         if clean_cache and os.path.exists(equp_path):
             shutil.rmtree(equp_path)
             shutil.rmtree(equp_path)
@@ -36,6 +40,11 @@ class DataLoader:
             os.makedirs(equp_path)
             os.makedirs(equp_path)
         
         
         for point_name,point_class in point.items():
         for point_name,point_class in point.items():
+            
+            # 剔除一些point name
+            if isinstance(rm_point_name,list) and point_name in rm_point_name:
+                continue
+            
             point_path  = os.path.join(equp_path,f'{point_name}.pkl')
             point_path  = os.path.join(equp_path,f'{point_name}.pkl')
             point_class = str(point_class)
             point_class = str(point_class)
             
             
@@ -102,6 +111,7 @@ class DataLoader:
                 RH  = pd.read_pickle(os.path.join(equp_path,file.replace('_T','_R'))).iloc[:,0].values
                 RH  = pd.read_pickle(os.path.join(equp_path,file.replace('_T','_R'))).iloc[:,0].values
                 Dew = pd.DataFrame({file.replace('_T','_D'):get_Dew(Tdb,np.clip(RH,0,100)/100)},index=self.date_range)
                 Dew = pd.DataFrame({file.replace('_T','_D'):get_Dew(Tdb,np.clip(RH,0,100)/100)},index=self.date_range)
                 pd.to_pickle(Dew,os.path.join(equp_path,file.replace('_T','_D')))
                 pd.to_pickle(Dew,os.path.join(equp_path,file.replace('_T','_D')))
+        all_file_path = os.listdir(equp_path)
         for file in all_file_path:
         for file in all_file_path:
             # 通过露点计算绝对湿度
             # 通过露点计算绝对湿度
             if '_D' in file:
             if '_D' in file:
@@ -129,4 +139,4 @@ class DataLoader:
         if len(all_data) == 0:
         if len(all_data) == 0:
             raise Exception(f'没有找到指定数据{all_file_path}')
             raise Exception(f'没有找到指定数据{all_file_path}')
         all_data = pd.concat(all_data,axis=1)
         all_data = pd.concat(all_data,axis=1)
-        return all_data
+        return all_data