瀏覽代碼

feat(optimize): 实现除湿机实时优化功能

- 加载模型并进行稳态判断
- 根据房间露点和模型精度确定优化模式
- 实施实时优化并生成推送策略
- 更新数据加载和异常处理逻辑
zhangshenhao 7 月之前
父節點
當前提交
9062772b60
共有 6 個文件被更改,包括 230 次插入48 次删除
  1. 126 20
      apps/optimize/optimize.py
  2. 5 4
      apps/train/train.py
  3. 83 18
      doc/框架.drawio
  4. 5 5
      model/DHU/DHU_A.py
  5. 6 0
      tools/config_reader.py
  6. 5 1
      tools/data_loader.py

+ 126 - 20
apps/optimize/optimize.py

@@ -1,6 +1,7 @@
 import os
-from datetime import datetime
+from datetime import datetime,timedelta
 from pathlib import Path
+from pprint import pprint
 
 import pandas as pd
 
@@ -9,6 +10,7 @@ from ...model.DHU.DHU_B import DHU_B
 from ...tools.config_reader import ConfigReader
 from ...tools.data_loader import DataLoader
 
+NOW = datetime.now().replace(second=0,microsecond=0)
 
 def optimize(*inputs,config=None):
     config = {} if config is None else config
@@ -30,40 +32,144 @@ def optimize(*inputs,config=None):
     
     ALL_RESULT = {
         'EXCEPTION':{
-            'Data': {},
-            'Fit' : {},
-            'Save': {}
+            'Mod'      : {},
+            'Data_Room': {},
+            'Data_ATD' : {},
+            'Opt'      : {},
+            'Push'     : {}
+        },
+        'STATUS':{
+            'Mode_Steady': [],
+            'Mode_Low'   : [],
+            'Mode_stop'  : []
         }
     }
     
     for each_eaup_name in config_reader.all_equp_names:
+        # 加载模型
         # 加载数据
         # 运行判断
         #   稳态判断:房间露点设定值与反馈值是否接近
+        #   模型调整
         #   模型判断:模型精度是否满足要求
         #   模式判断:
         #       1. 基于当前露点优化模式:基于房间露点设定值减偏差
         #       2. 快速提升送风露点模式:约束送风露点保持不变
         
+        # 加载模型
+        try:
+            if config_reader.get_app_info(
+                each_eaup_name,
+                app_type  = '实时优化',
+                key       = '使用临时模型',
+                info_type = 'bool'
+            ):
+                # 从文件夹中获取临时模型
+                MODEL = MODEL.load(path=f'{config_reader_path}/model/{each_eaup_name}.pkl')
+            else:
+                MODEL = MODEL.load_from_platform(
+                    source   = 'id',
+                    model_id = config_reader.get_equp_info(
+                        equp_name = each_eaup_name,
+                        key       = '模型编号',
+                        info_type = 'str'
+                    )
+                )
+        except Exception as e:
+            ALL_RESULT['EXCEPTION']['Mod'][each_eaup_name] = e
+            continue
         
-        
-        
-        # 获取数据
+        # 加载房间数据
         try:
-            data_loader = DataLoader(
-                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'),
-                end_time   = config_reader.get_app_info(each_eaup_name,app_type='模型训练',key='结束时间',info_type='datetime')
+            room_steady_len = config_reader.get_app_info(each_eaup_name,'实时优化','房间稳态判断时长','float')
+            room_data_loader = DataLoader(
+                path       = f'{config_reader_path}/data/optimize/data_cur/',
+                start_time = NOW - timedelta(minutes=room_steady_len),
+                end_time   = NOW
             )
-            data_loader.dowload_equp_data(
+            room_data_loader.dowload_equp_data(
                 equp_name   = each_eaup_name,
-                point       = config_reader.get_equp_point(each_eaup_name,equp_class=['A','B']),
+                point       = config_reader.get_equp_point(each_eaup_name,equp_class=['C']),
                 url         = data_URL,
-                clean_cache = False
+                clean_cache = True
+            )
+            room_data       = room_data_loader.get_equp_data(each_eaup_name)
+            room_Dew_SP_adj = config_reader.get_app_info(each_eaup_name,'实时优化','房间露点设定值偏差','float')
+            room_Dew_SP     = room_data.room_DSP.mean() + room_Dew_SP_adj
+            room_Dew_PV     = room_data.room_DPV.mean()
+            room_Dew_diff_dwlim = config_reader.get_app_info(each_eaup_name,'实时优化','房间露点过低阈值','float')
+            
+            # 模式判断
+            is_room_Dew_steady = (room_Dew_PV < room_Dew_SP + 0.5) or (room_Dew_PV > room_Dew_SP - 0.5)
+            is_room_Dew_low    = room_Dew_PV - room_Dew_SP < room_Dew_diff_dwlim
+            
+            if is_room_Dew_steady:
+                DewOut_constrain = 'coil_3_DoutA-[coil_3_DoutA]<0'
+                ALL_RESULT['STATUS']['Mode_Steady'].append(each_eaup_name)
+            elif is_room_Dew_low:
+                DewOut_constrain = f'coil_3_DoutA-{room_Dew_SP-4}<0'   #TODO 这个4度比较粗糙,待改进
+                ALL_RESULT['STATUS']['Mode_Low'].append(each_eaup_name)
+            else:
+                ALL_RESULT['STATUS']['Mode_stop'].append(each_eaup_name)
+                continue
+        except Exception as e:
+            ALL_RESULT['STATUS']['Data_Room'][each_eaup_name] = e
+            continue
+        
+        # 加载除湿机数据
+        try:
+            dhu_steady_len   = config_reader.get_app_info(each_eaup_name,'实时优化','除湿机工况均值时长','float')
+            data_input_point = config_reader.get_equp_point(each_eaup_name,equp_class=['A','B'])
+            data_cur = (
+                DataLoader(
+                    path       = f'{config_reader_path}/data/optimize/data_cur/',
+                    start_time = NOW - timedelta(minutes=dhu_steady_len),
+                    end_time   = NOW
+                )
+                .dowload_equp_data(
+                    equp_name   = each_eaup_name,
+                    point       = data_input_point,
+                    url         = data_URL,
+                    clean_cache = True
+                )
+                .get_equp_data(
+                    equp_name = each_eaup_name,
+                )
+                .mean(axis=0)
+                .to_frame().T
             )
-            equp_data = data_loader.get_equp_data(each_eaup_name)
-            equp_data = clean_data(equp_data)
-            save_data(f'{config_reader_path}/data/train/data_his_clean',f'{each_eaup_name}.pkl',equp_data)
-        except Exception as E:
-            ALL_RESULT['EXCEPTION']['Data'][each_eaup_name] = E
-            continue
+        except Exception as e:
+            ALL_RESULT['EXCEPTION']['Data_ATD'][each_eaup_name] = e
+        
+        try:
+            # 模型精度判断
+            predict  = MODEL.predict_system(input_data=data_cur)
+            TVP_data = (
+                predict.T.set_axis(['pred'],axis=1)
+                .join(
+                    data_cur.T.set_axis(['real'],axis=1),
+                    how = 'left'
+                )
+                .dropna(axis=0)
+            )
+            print(TVP_data)
+            
+            # 实时优化
+            constrains = [DewOut_constrain]
+            opt_res = MODEL.optimize(
+                cur_input_data  = data_cur,
+                wheel_1_TinR_ub = config_reader.get_app_info(each_eaup_name,'实时优化','前再生盘管温度上限','float'),
+                wheel_1_TinR_lb = config_reader.get_app_info(each_eaup_name,'实时优化','前再生盘管温度下限','float'),
+                wheel_2_TinR_ub = config_reader.get_app_info(each_eaup_name,'实时优化','后再生盘管温度上限','float'),
+                wheel_2_TinR_lb = config_reader.get_app_info(each_eaup_name,'实时优化','后再生盘管温度下限','float'),
+                constrains      = constrains,
+                logging         = False
+            )
+            opt_summary = opt_res['opt_summary']
+            opt_var     = opt_res['opt_var']
+        
+        except Exception as e:
+            ALL_RESULT['EXCEPTION']['Opt'][each_eaup_name] = e
+    
+    pprint(ALL_RESULT)
+        

+ 5 - 4
apps/train/train.py

@@ -1,6 +1,7 @@
 import os
 from datetime import datetime
 from pathlib import Path
+from pprint import pprint
 
 import pandas as pd
 
@@ -9,7 +10,7 @@ from ...model.DHU.DHU_B import DHU_B
 from ...tools.config_reader import ConfigReader
 from ...tools.data_loader import DataLoader
 
-NOW             = datetime.now()
+NOW             = datetime.now().replace(second=0,microsecond=0)
 PATH            = os.path.dirname(os.path.realpath(__file__)).replace('\\','/')
 MODEL_FUNC_PATH = f'{PATH}/model_func.py'
 MODEL_FILE_PATH = f'./model.pkl'
@@ -73,8 +74,8 @@ def train(*inputs,config=None):
                 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/model').mkdir(parents=True, exist_ok=True)
-            equp_model.save(f'{config_reader_path}/data/train/model/{each_eaup_name}.pkl')
+            Path(f'{config_reader_path}/model').mkdir(parents=True, exist_ok=True)
+            equp_model.save(f'{config_reader_path}/model/{each_eaup_name}.pkl')
             save_data(f'{config_reader_path}/data/train/data_TVP',f'{each_eaup_name}.csv',equp_model.TVP_data)
             save_data(f'{config_reader_path}/data/train/data_metric',f'{each_eaup_name}.csv',equp_model.TVP_metric)
         except Exception as E:
@@ -111,7 +112,7 @@ def train(*inputs,config=None):
             ALL_RESULT['EXCEPTION']['Save'][each_eaup_name] = E
             continue
     
-    print(ALL_RESULT)
+    pprint(ALL_RESULT)
 
 def clean_data(data) -> pd.DataFrame:
     data = (

+ 83 - 18
doc/框架.drawio

@@ -4,60 +4,125 @@
             <root>
                 <mxCell id="0"/>
                 <mxCell id="1" parent="0"/>
-                <mxCell id="23" value="训练模型" style="swimlane;whiteSpace=wrap;html=1;" vertex="1" parent="1">
+                <mxCell id="23" value="训练模型" style="swimlane;whiteSpace=wrap;html=1;" parent="1" vertex="1">
                     <mxGeometry x="140" y="-940" width="250" height="690" as="geometry"/>
                 </mxCell>
-                <mxCell id="25" value="" style="edgeStyle=none;html=1;" edge="1" parent="23" source="22" target="24">
+                <mxCell id="25" value="" style="edgeStyle=none;html=1;" parent="23" source="22" target="24" edge="1">
                     <mxGeometry relative="1" as="geometry"/>
                 </mxCell>
-                <mxCell id="22" value="加载数据" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="23">
+                <mxCell id="22" value="加载数据" style="rounded=0;whiteSpace=wrap;html=1;" parent="23" vertex="1">
                     <mxGeometry x="65" y="80" width="120" height="60" as="geometry"/>
                 </mxCell>
-                <mxCell id="27" value="" style="edgeStyle=none;html=1;" edge="1" parent="23" source="24" target="26">
+                <mxCell id="27" value="" style="edgeStyle=none;html=1;" parent="23" source="24" target="26" edge="1">
                     <mxGeometry relative="1" as="geometry"/>
                 </mxCell>
-                <mxCell id="24" value="数据清洗" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="23">
+                <mxCell id="24" value="数据清洗" style="rounded=0;whiteSpace=wrap;html=1;" parent="23" vertex="1">
                     <mxGeometry x="65" y="220" width="120" height="60" as="geometry"/>
                 </mxCell>
-                <mxCell id="29" value="" style="edgeStyle=none;html=1;" edge="1" parent="23" source="26" target="28">
+                <mxCell id="29" value="" style="edgeStyle=none;html=1;" parent="23" source="26" target="28" edge="1">
                     <mxGeometry relative="1" as="geometry"/>
                 </mxCell>
-                <mxCell id="26" value="训练模型" style="whiteSpace=wrap;html=1;rounded=0;" vertex="1" parent="23">
+                <mxCell id="26" value="训练模型" style="whiteSpace=wrap;html=1;rounded=0;" parent="23" vertex="1">
                     <mxGeometry x="65" y="360" width="120" height="60" as="geometry"/>
                 </mxCell>
-                <mxCell id="28" value="写入模型" style="whiteSpace=wrap;html=1;rounded=0;" vertex="1" parent="23">
+                <mxCell id="28" value="写入模型" style="whiteSpace=wrap;html=1;rounded=0;" parent="23" vertex="1">
                     <mxGeometry x="65" y="500" width="120" height="60" as="geometry"/>
                 </mxCell>
-                <mxCell id="30" value="模型监控" style="swimlane;whiteSpace=wrap;html=1;" vertex="1" parent="1">
+                <mxCell id="30" value="模型监控" style="swimlane;whiteSpace=wrap;html=1;" parent="1" vertex="1">
                     <mxGeometry x="500" y="-940" width="420" height="620" as="geometry"/>
                 </mxCell>
-                <mxCell id="33" value="" style="edgeStyle=none;html=1;" edge="1" parent="30" source="31" target="32">
+                <mxCell id="33" value="" style="edgeStyle=none;html=1;" parent="30" source="31" target="32" edge="1">
                     <mxGeometry relative="1" as="geometry"/>
                 </mxCell>
-                <mxCell id="31" value="加载数据" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="30">
+                <mxCell id="31" value="加载数据" style="rounded=0;whiteSpace=wrap;html=1;" parent="30" vertex="1">
                     <mxGeometry x="40" y="70" width="120" height="60" as="geometry"/>
                 </mxCell>
-                <mxCell id="35" value="" style="edgeStyle=none;html=1;" edge="1" parent="30" source="32" target="34">
+                <mxCell id="35" value="" style="edgeStyle=none;html=1;" parent="30" source="32" target="34" edge="1">
                     <mxGeometry relative="1" as="geometry"/>
                 </mxCell>
-                <mxCell id="32" value="数据清洗" style="whiteSpace=wrap;html=1;rounded=0;" vertex="1" parent="30">
+                <mxCell id="32" value="数据清洗" style="whiteSpace=wrap;html=1;rounded=0;" parent="30" vertex="1">
                     <mxGeometry x="40" y="210" width="120" height="60" as="geometry"/>
                 </mxCell>
-                <mxCell id="39" value="" style="edgeStyle=none;html=1;" edge="1" parent="30" source="34" target="38">
+                <mxCell id="39" value="" style="edgeStyle=none;html=1;" parent="30" source="34" target="38" edge="1">
                     <mxGeometry relative="1" as="geometry"/>
                 </mxCell>
-                <mxCell id="34" value="实时预测" style="whiteSpace=wrap;html=1;rounded=0;" vertex="1" parent="30">
+                <mxCell id="34" value="实时预测" style="whiteSpace=wrap;html=1;rounded=0;" parent="30" vertex="1">
                     <mxGeometry x="40" y="350" width="120" height="60" as="geometry"/>
                 </mxCell>
-                <mxCell id="37" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="30" source="36" target="34">
+                <mxCell id="37" style="edgeStyle=none;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="30" source="36" target="34" edge="1">
                     <mxGeometry relative="1" as="geometry"/>
                 </mxCell>
-                <mxCell id="36" value="加载模型" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="30">
+                <mxCell id="36" value="加载模型" style="rounded=0;whiteSpace=wrap;html=1;" parent="30" vertex="1">
                     <mxGeometry x="250" y="350" width="120" height="60" as="geometry"/>
                 </mxCell>
-                <mxCell id="38" value="写入监控" style="whiteSpace=wrap;html=1;rounded=0;" vertex="1" parent="30">
+                <mxCell id="38" value="写入监控" style="whiteSpace=wrap;html=1;rounded=0;" parent="30" vertex="1">
                     <mxGeometry x="40" y="490" width="120" height="60" as="geometry"/>
                 </mxCell>
+                <mxCell id="40" value="优化流程" style="swimlane;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+                    <mxGeometry x="320" y="-160" width="750" height="700" as="geometry">
+                        <mxRectangle x="320" y="-160" width="90" height="30" as="alternateBounds"/>
+                    </mxGeometry>
+                </mxCell>
+                <mxCell id="45" value="" style="edgeStyle=none;html=1;" parent="40" source="41" target="44" edge="1">
+                    <mxGeometry relative="1" as="geometry"/>
+                </mxCell>
+                <mxCell id="41" value="加载最近10分钟数据" style="rounded=0;whiteSpace=wrap;html=1;" parent="40" vertex="1">
+                    <mxGeometry x="420" y="72.5" width="120" height="60" as="geometry"/>
+                </mxCell>
+                <mxCell id="54" style="edgeStyle=none;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="40" source="44" target="50" edge="1">
+                    <mxGeometry relative="1" as="geometry"/>
+                </mxCell>
+                <mxCell id="61" value="" style="edgeStyle=none;html=1;" parent="40" source="44" target="60" edge="1">
+                    <mxGeometry relative="1" as="geometry"/>
+                </mxCell>
+                <mxCell id="44" value="房间露点&lt;br&gt;稳定" style="rhombus;whiteSpace=wrap;html=1;rounded=0;" parent="40" vertex="1">
+                    <mxGeometry x="440" y="212.5" width="80" height="80" as="geometry"/>
+                </mxCell>
+                <mxCell id="53" value="" style="edgeStyle=none;html=1;" parent="40" source="50" target="52" edge="1">
+                    <mxGeometry relative="1" as="geometry"/>
+                </mxCell>
+                <mxCell id="58" value="" style="edgeStyle=none;html=1;" parent="40" source="50" target="57" edge="1">
+                    <mxGeometry relative="1" as="geometry"/>
+                </mxCell>
+                <mxCell id="50" value="模型精度&lt;br&gt;达标" style="rhombus;whiteSpace=wrap;html=1;" parent="40" vertex="1">
+                    <mxGeometry x="440" y="382.5" width="80" height="80" as="geometry"/>
+                </mxCell>
+                <mxCell id="52" value="基于当前送风露点推送策略" style="whiteSpace=wrap;html=1;" parent="40" vertex="1">
+                    <mxGeometry x="420" y="567.5" width="120" height="60" as="geometry"/>
+                </mxCell>
+                <mxCell id="55" value="是" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="40" vertex="1">
+                    <mxGeometry x="460" y="312.5" width="60" height="30" as="geometry"/>
+                </mxCell>
+                <mxCell id="56" value="是" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="40" vertex="1">
+                    <mxGeometry x="460" y="492.5" width="60" height="30" as="geometry"/>
+                </mxCell>
+                <mxCell id="57" value="推出当前设定值" style="whiteSpace=wrap;html=1;" parent="40" vertex="1">
+                    <mxGeometry x="610" y="392.5" width="120" height="60" as="geometry"/>
+                </mxCell>
+                <mxCell id="59" value="否" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="40" vertex="1">
+                    <mxGeometry x="530" y="422.5" width="60" height="30" as="geometry"/>
+                </mxCell>
+                <mxCell id="65" value="" style="edgeStyle=none;html=1;" parent="40" source="60" target="64" edge="1">
+                    <mxGeometry relative="1" as="geometry"/>
+                </mxCell>
+                <mxCell id="69" value="" style="edgeStyle=none;html=1;" parent="40" source="60" target="68" edge="1">
+                    <mxGeometry relative="1" as="geometry"/>
+                </mxCell>
+                <mxCell id="60" value="房间露点&lt;br&gt;过低" style="rhombus;whiteSpace=wrap;html=1;rounded=0;" parent="40" vertex="1">
+                    <mxGeometry x="280" y="212.5" width="80" height="80" as="geometry"/>
+                </mxCell>
+                <mxCell id="62" value="否" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="40" vertex="1">
+                    <mxGeometry x="370" y="250" width="60" height="30" as="geometry"/>
+                </mxCell>
+                <mxCell id="64" value="结束" style="whiteSpace=wrap;html=1;rounded=0;" parent="40" vertex="1">
+                    <mxGeometry x="60" y="222.5" width="120" height="60" as="geometry"/>
+                </mxCell>
+                <mxCell id="66" value="否" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="40" vertex="1">
+                    <mxGeometry x="210" y="250" width="60" height="30" as="geometry"/>
+                </mxCell>
+                <mxCell id="68" value="基于设定温差推送策略" style="whiteSpace=wrap;html=1;rounded=0;" parent="40" vertex="1">
+                    <mxGeometry x="260" y="382.5" width="120" height="60" as="geometry"/>
+                </mxCell>
             </root>
         </mxGraphModel>
     </diagram>

+ 5 - 5
model/DHU/DHU_A.py

@@ -44,10 +44,10 @@ class DHU_A(BaseDevice):
         'wheel_2_ToutP'  : 'wheel_2_ToutP',
         'wheel_2_DoutP'  : 'wheel_2_DoutP',
         'wheel_2_ToutR'  : 'wheel_2_ToutR',
-        'steamcoil_1_FP' : 'steamcoil_1_FP',
-        'steamcoil_2_FP' : 'steamcoil_2_FP',
-        'steamcoil_1_Fs' : 'steamcoil_1_Fs',
-        'steamcoil_2_Fs' : 'steamcoil_2_Fs',
+        # 'steamcoil_1_FP' : 'steamcoil_1_FP',
+        # 'steamcoil_2_FP' : 'steamcoil_2_FP',
+        # 'steamcoil_1_Fs' : 'steamcoil_1_Fs',
+        # 'steamcoil_2_Fs' : 'steamcoil_2_Fs',
         # 'steamcoil_1_Val': 'steamcoil_1_Val',
         # 'steamcoil_2_Val': 'steamcoil_2_Val',
     }
@@ -163,7 +163,7 @@ class DHU_A(BaseDevice):
             opt_var_boundary = opt_var_boundary,
             opt_var_value    = opt_var_value,
             oth_var_value    = oth_var_value,
-            target           = 'Fs',
+            target           = 'summary_Fs',
             target_min       = True,
             constrains       = constrains,
             logging          = logging,

+ 6 - 0
tools/config_reader.py

@@ -1,6 +1,7 @@
 from typing import Union
 from datetime import datetime
 
+import numpy as np
 import pandas as pd
 
 class ConfigReader:
@@ -34,6 +35,11 @@ class ConfigReader:
         equp_class = [equp_class] if isinstance(equp_class,str) else equp_class
         point_info = self.point.loc[self.point.类型.isin(equp_class)]
         point_map  = dict(zip(point_info.编号.to_list(),point_info.点位.to_list()))
+        
+        for point_name,point_id in point_map.items():
+            if not isinstance(point_id,str) and np.isnan(point_id):
+                raise Exception(f'点位{point_name}的点位ID缺失')
+        
         # 根据配置情况更新全局点位
         if equp_name in self.point.columns:
             for point_name in point_map.keys():

+ 5 - 1
tools/data_loader.py

@@ -30,7 +30,7 @@ class DataLoader:
         clean_cache: bool
     ):
         equp_path = os.path.join(self.path,equp_name)
-        if clean_cache:
+        if clean_cache and os.path.exists(equp_path):
             shutil.rmtree(equp_path)
         if not os.path.exists(equp_path): 
             os.makedirs(equp_path)
@@ -102,6 +102,8 @@ class DataLoader:
                 Dew = pd.read_pickle(os.path.join(equp_path,file)).iloc[:,0].values
                 Hr  = pd.DataFrame({file.replace('_D','_H'):get_Hr(Dew,101325)},index=self.date_range)
                 pd.to_pickle(Hr,os.path.join(equp_path,file.replace('_D','_H')))
+    
+        return self
                 
     
     def get_equp_data(self,equp_name:str) -> pd.DataFrame:
@@ -118,5 +120,7 @@ class DataLoader:
                 .loc[self.start_time:self.end_time,:]
             )
             all_data.append(data)
+        if len(all_data) == 0:
+            raise Exception(f'没有找到指定数据{all_file_path}')
         all_data = pd.concat(all_data,axis=1)
         return all_data