mingyue-unimat 2 napja
commit
8c976c1df3

+ 8 - 0
.idea/chiller_temp_control.iml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="PYTHON_MODULE" version="4">
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="jdk" jdkName="Python 3.10" jdkType="Python SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 195 - 0
chiller_safety_modify/multi_comp_safety_verify.py

@@ -0,0 +1,195 @@
+import pandas as pd
+# from logs_conf.logger import *
+from logs.logger import *
+from CoolProp.CoolProp import PropsSI
+from chiller_safety_modify.pressure_diff_limit_multi_comp import PressureDiffLimitMultiComp
+from chiller_safety_modify.suction_with_liquid_multi_comp import SuctionWithLiquidMultiComp
+
+
+class MultiCompSafetyVerify(PressureDiffLimitMultiComp, SuctionWithLiquidMultiComp):
+    def __init__(self, dict_chiller_inner, dict_upper_correct):
+        super(PressureDiffLimitMultiComp, self).__init__(dict_chiller_inner, dict_upper_correct)
+
+    def data_switch_array(self):
+        """将不同压缩机数据提取出来,生成数据列表和负载率列表"""
+        list_data_general = []
+        list_load_ratio = []
+        for circuit in self.dict_upper_correct['chillerParameter']['circuitParameter']:
+            dict_circuit = {}
+            dict_circuit['condPre'] = circuit['condPre']
+            dict_circuit['evapPre'] = circuit['evapPre']
+            for compressor in circuit['compParameter']:
+                dict_comp = {}
+                dict_comp['sucTemp'] = compressor['sucTemp']
+                dict_comp['disTemp'] = compressor['disTemp']
+                dict_general = dict(dict_circuit, **dict_comp)
+                list_data_general.append(dict_general)
+                list_load_ratio.append(compressor['loadPercent'])
+        return list_data_general, list_load_ratio
+
+    def thermodynamic_parameter_cal(self, data_frame_general):
+        """中间参数计算:根据压力计算温度、计算焓值和熵值等"""
+        enthalpy_suc = []
+        entropy_suc = []
+        enthalpy_dis = []
+        data_frame_general['condPre'] += 101.325
+        data_frame_general['evapPre'] += 101.325
+        data_frame_general['evapTemp'] = data_frame_general.apply(
+            lambda x: PropsSI('T', 'P', x['evapPre'] * 1000, 'Q', 1, self.dict_upper_correct['refriType']) - 273.15, axis=1)
+        data_frame_general['condTemp'] = data_frame_general.apply(
+            lambda x: PropsSI('T', 'P', x['condPre'] * 1000, 'Q', 1, self.dict_upper_correct['refriType']) - 273.15, axis=1)
+        for index, row in data_frame_general.iterrows():
+            if row['evapTemp'] - row['sucTemp'] > 0:
+                enthalpy_suc_cal = PropsSI('H', 'T', row['evapTemp'] + 273.15, 'Q', 1, self.dict_upper_correct['refriType'])
+                entropy_suc_cal = PropsSI('S', 'T', row['evapTemp'] + 273.15, 'Q', 1, self.dict_upper_correct['refriType'])
+            else:
+                enthalpy_suc_cal = PropsSI('H', 'T', row['sucTemp'] + 273.15, 'P', row['evapPre'] * 1000,
+                                         self.dict_upper_correct['refriType'])
+                entropy_suc_cal = PropsSI('S', 'T', row['sucTemp'] + 273.15, 'P', row['evapPre'] * 1000,
+                                        self.dict_upper_correct['refriType'])
+            if row['condTemp'] - row['disTemp'] > 0:
+                enthalpy_dis_cal = PropsSI('H', 'T', row['condTemp'] + 273.15, 'Q', 1, self.dict_upper_correct['refriType'])
+            else:
+                enthalpy_dis_cal = PropsSI('H', 'T', row['disTemp'] + 273.15, 'P', row['condPre'] * 1000,
+                                         self.dict_upper_correct['refriType'])
+            enthalpy_suc.append(enthalpy_suc_cal)
+            entropy_suc.append(entropy_suc_cal)
+            enthalpy_dis.append(enthalpy_dis_cal)
+        data_frame_general['enthalpySuc'] = enthalpy_suc
+        data_frame_general['entropySuc'] = entropy_suc
+        data_frame_general['enthalpyDis'] = enthalpy_dis
+        return data_frame_general
+
+    def isen_efficiency_cal(self):
+        """计算等熵效率"""
+        self.data_general['enthalpyDisIse'] = self.data_general.apply(
+            lambda x: PropsSI('H', 'P', x['condPre'] * 1000, 'S', x['entropySuc'], self.dict_upper_correct['refriType']),
+            axis=1)
+        self.data_general['iseEfficiency'] = (self.data_general['enthalpyDisIse'] - self.data_general['enthalpySuc']) / (
+                self.data_general['enthalpyDis'] - self.data_general['enthalpySuc'])
+        ise_efficiency = self.data_general['iseEfficiency'].tolist()
+        return ise_efficiency
+
+    def circle_paramter_cal(self, list_load_ratio, list_data_general):
+        """
+        针对每一个压缩机回路判断 安全压差 、 吸气带液
+        :param list_load_ratio:
+        :param list_data_general:
+        :return:
+        """
+        list_chiller_temp = []
+        list_suction_with_liquid = []
+        list_ise_efficiency = []
+        for i in range(len(list_load_ratio)):
+            data_frame_general = pd.DataFrame(list_data_general[i])
+            print(data_frame_general)
+            data_frame_general = data_frame_general.dropna()
+            print("%%%%%%%%%%%%%%%%%%%%")
+            print(data_frame_general)
+            self.data_general = self.thermodynamic_parameter_cal(data_frame_general)
+            set_new_pres_fix = self.pressure_diff_limit(list_load_ratio[i])   # 根据安全压差调整的水温
+            list_chiller_temp.append(set_new_pres_fix) if set_new_pres_fix else []
+            ise_efficiency = self.isen_efficiency_cal()
+            judge_suction_with_liquid = self.judge_suction_with_liquid(list_load_ratio[i])  # 判断是否吸气带液
+            list_ise_efficiency.append(ise_efficiency)
+            list_suction_with_liquid.append(judge_suction_with_liquid)
+        return list_chiller_temp, list_suction_with_liquid, list_ise_efficiency
+
+    @staticmethod
+    def is_safety_issue(is_lower_oil_pre, is_suction_with_liquid, is_continuous_run_fix):
+        """满足安全压差、 吸气带液、 连续运行 任何一个则表示存在安全运行问题,即为1,否则不存在安全运行问题"""
+        if is_lower_oil_pre or is_suction_with_liquid or is_continuous_run_fix:
+            is_safety_issue = 1
+        else:
+            is_safety_issue = 0
+        return is_safety_issue
+
+    def water_temp_adjust_final(self, is_lower_oil_pre, is_suction_with_liquid, is_continuous_run_fix,
+                                water_temp_set_pre_diff, water_temp_set_liquid, water_temp_set_run_continue):
+        if is_lower_oil_pre or is_suction_with_liquid:
+            # if self.dict_chiller_inner['runMode'] == 0:
+            #     if is_lower_oil_pre and is_suction_with_liquid:
+            #         water_temp_set_new = min(water_temp_set_pre_diff, water_temp_set_liquid)  # 制冷模式取最小值
+            #     elif is_lower_oil_pre:
+            #         water_temp_set_new = water_temp_set_pre_diff
+            #     else:
+            #         water_temp_set_new = water_temp_set_liquid
+            # else:
+            #     if is_lower_oil_pre and is_suction_with_liquid:
+            #         water_temp_set_new = max(water_temp_set_pre_diff, water_temp_set_liquid)  # 制热模式取最大值,修改
+            #     elif is_lower_oil_pre:
+            #         water_temp_set_new = water_temp_set_pre_diff
+            #     else:
+            #         water_temp_set_new = water_temp_set_liquid
+            if is_lower_oil_pre and is_suction_with_liquid:
+                if self.dict_chiller_inner['runMode'] == 0:
+                    water_temp_set_new = min(water_temp_set_pre_diff, water_temp_set_liquid)  # 制冷模式取最小值
+                else:
+                    water_temp_set_new = max(water_temp_set_pre_diff, water_temp_set_liquid)  # 制热模式取最大值,修改
+                logger.critical("============存在安全运行问题3:主机同时存在安全压差与吸气带液风险,"
+                                "水温设定值从 %s ℃调整至 %s ℃============"
+                                % (self.dict_chiller_inner["chillerWaterTempSet"], round(water_temp_set_new, 1)))
+            elif is_lower_oil_pre:
+                water_temp_set_new = water_temp_set_pre_diff
+
+                logger.critical("============存在安全运行问题1:主机存在安全压差问题,水温设定值从 %s ℃调整至 %s ℃============"
+                                % (self.dict_chiller_inner["chillerWaterTempSet"], round(water_temp_set_new, 1)))
+            else:
+                water_temp_set_new = water_temp_set_liquid
+                logger.critical("============存在安全运行问题2:主机存在吸气带液风险,水温设定值从%s℃调整至%s℃============"
+                                % (self.dict_chiller_inner["chillerWaterTempSet"], round(water_temp_set_new, 1)))
+        elif is_continuous_run_fix:
+            water_temp_set_new = water_temp_set_run_continue
+            logger.critical("============存在安全运行问题4:无法保障设备连续运行,水温设定值从%s℃调整至%s℃============"
+                            % (self.dict_chiller_inner["chillerWaterTempSet"], round(water_temp_set_new, 1)))
+        else:
+            water_temp_set_new = ''
+            logger.critical("============不存在安全运行问题:经校验,设备不存在安全运行风险============")
+        return water_temp_set_new
+
+    def safety_verify(self):
+        list_data_general, list_load_ratio = self.data_switch_array()              # 参数格式转换
+        list_chiller_temp, list_suction_with_liquid, list_ise_efficiency = \
+            self.circle_paramter_cal(list_load_ratio, list_data_general)           # 中间参数计算
+        is_suction_with_liquid, ise_efficiency_liquid = \
+            self.is_suction_with_liquid(list_ise_efficiency, list_suction_with_liquid)    # 吸气带液校验
+        water_temp_set_pre_diff, is_lower_oil_pre = self.water_temp_adjust_pre_diff(list_chiller_temp)  # 安全压差校验
+        water_temp_set_liquid = ''
+        if is_suction_with_liquid:
+            water_temp_set_liquid, results_depict_liquid = self.temp_set_adjust(ise_efficiency_liquid)
+        water_temp_set_run_continue, is_continuous_run_fix = \
+            self.water_temp_adjust_continuous_run(is_lower_oil_pre, is_suction_with_liquid, list_load_ratio)  # 连续运行校验
+        is_safety_issue = self.is_safety_issue(is_lower_oil_pre, is_suction_with_liquid, is_continuous_run_fix)
+        parameter = (is_lower_oil_pre, is_suction_with_liquid, is_continuous_run_fix, water_temp_set_pre_diff, water_temp_set_liquid, water_temp_set_run_continue)
+        water_temp_set_new = self.water_temp_adjust_final(*parameter)
+        return is_safety_issue, water_temp_set_new
+
+    def safety_verify_main_process(self):
+        try:
+            if self.dict_chiller_inner['runStatus'][-1] == 0:
+                logger.critical("============冷机处于关闭状态,无需进行安全校验============")
+                is_safety_issue = 0
+                water_temp_set_new = ''
+            elif self.dict_chiller_inner['runStatus'][-1] == 1:
+                last_hour_data = self.dict_chiller_inner['runStatus'][-int(60/3):]  # 过去一个小时的运行数据
+                if all(status == 1 for status in last_hour_data):
+                    logger.critical("============冷机稳定运行,正常进行安全校验============")
+                    is_safety_issue, water_temp_set_new = self.safety_verify()
+                else:
+                    logger.critical("============冷机运行状态不稳定,无法进行安全校验============")
+                    is_safety_issue = 0
+                    water_temp_set_new = ''
+            else:
+                logger.critical("============冷机运行状态无法判断,无法进行安全校验============")
+                is_safety_issue = 0
+                water_temp_set_new = ''
+        except Exception as e:
+            logger.critical("============冷机运行状态无法判断,无法进行安全校验============")
+            result_depict = '安全校验异常,无法完成校验,退出安全校验计算' + '(' + str(e) + ')'
+            logger.critical('============{}============'.format(result_depict))
+            logger.critical('============无法完成安全校验,视为无安全运行风险============')
+            is_safety_issue = 0
+            water_temp_set_new = ''
+        return is_safety_issue, water_temp_set_new
+
+

+ 86 - 0
chiller_safety_modify/pressure_diff_limit_multi_comp.py

@@ -0,0 +1,86 @@
+# from logs_conf.logger import *
+from logs.logger import *
+from CoolProp.CoolProp import PropsSI
+import pandas as pd
+import numpy as np
+
+
+class PressureDiffLimitMultiComp(object):
+    def __init__(self, dict_chiller_inner, dict_upper_correct):
+        self.dict_chiller_inner = dict_chiller_inner
+        self.dict_upper_correct = dict_upper_correct
+        self.data_general = pd.DataFrame()
+
+    def pressure_diff_limit(self, load_ratio):
+        set_new_pres_fix = ''
+        if load_ratio > 30:
+            self.data_general['preDiff'] = self.data_general['condPre'] - self.data_general['evapPre'] - \
+                                           self.dict_chiller_inner['safetyPreDiffLowerLimit']
+            self.dict_upper_correct['preDiff'] = self.data_general['preDiff'].iloc[-1]
+            if self.dict_upper_correct['preDiff'] < 0:
+                if self.dict_chiller_inner['runMode'] == 0:
+                    evap_pre_adjust = self.data_general['evapPre'].iloc[-1] + self.dict_upper_correct['preDiff']
+                    print("@@@@@", evap_pre_adjust)
+                    evap_temp_adjust = PropsSI('T', 'P', evap_pre_adjust * 1000, 'Q', 1, self.dict_upper_correct['refriType']) - 273.15
+                    water_temp_adjust = self.data_general['evapTemp'].iloc[-1] - evap_temp_adjust
+                    # set_new_pres_fix = round(self.dict_chiller_inner['chillerWaterTempOut'][-1] - 0.5 * water_temp_adjust, 1)  # 原逻辑
+                    set_new_pres_fix = self.dict_chiller_inner['chillerWaterTempSet'] - water_temp_adjust  # 调整后
+                elif self.dict_chiller_inner['runMode'] == 1:
+                    cond_pre_adjust = self.data_general['condPre'].iloc[-1] - self.dict_upper_correct['preDiff']
+                    cond_temp_adjust = PropsSI('T', 'P', cond_pre_adjust * 1000, 'Q', 1, self.dict_upper_correct['refriType']) - 273.15
+                    water_temp_adjust = cond_temp_adjust - self.data_general['condTemp'].iloc[-1]
+                    # set_new_pres_fix = round(self.dict_chiller_inner['coolingWaterTempOut'][-1] - 0.5 * water_temp_adjust, 1)  # 原逻辑
+                    set_new_pres_fix = self.dict_chiller_inner['heatingWaterTempSet'] + water_temp_adjust  # 调整后
+                else:
+                    pass
+                    logger.critical('============冷机运行模式错误============')
+        return set_new_pres_fix
+
+    def water_temp_adjust_pre_diff(self, list_chiller_temp):
+        """
+        如果有多组参数计算,则这里取最终值,制冷模式取最低水温,制热模式取最高水温
+        :param list_chiller_temp:
+        :return:
+        """
+        if list_chiller_temp:
+            is_lower_oil_pre = 1
+            if self.dict_chiller_inner['runMode'] == 0:
+                water_temp_set_pre_diff = min(list_chiller_temp)
+            else:
+                water_temp_set_pre_diff = max(list_chiller_temp)
+        else:
+            is_lower_oil_pre = 0
+            water_temp_set_pre_diff = ''
+        return water_temp_set_pre_diff, is_lower_oil_pre
+
+    def is_continuous_run(self, list_load_ratio):
+        """
+        保障连续运行,若需要保障连续运行则判断运行负载和负载率下限,低于下限则制冷下调水温1℃,制热上调水温1℃
+        :param list_load_ratio:
+        :return:
+        """
+        water_temp_set_run_continue = ''
+        is_continuous_run_fix = 0
+        array_load_ratio = np.array(list_load_ratio)
+        array_load_ratio = np.extract(array_load_ratio > 30, array_load_ratio)
+        if len(array_load_ratio) == 1 and self.dict_chiller_inner['isContinuousRun'] == 1 \
+                and array_load_ratio < self.dict_chiller_inner['safetyLoadRatioLowerLimit']:
+            is_continuous_run_fix = 1
+            if self.dict_chiller_inner['runMode'] == 0:
+                water_temp_set_run_continue = self.dict_chiller_inner['chillerWaterTempOut'][-1] - 1.0  # 这里已修改
+            elif self.dict_chiller_inner['runMode'] == 1:
+                water_temp_set_run_continue = self.dict_chiller_inner['coolingWaterTempOut'][-1] + 1.0  # 这里已修改
+
+            else:
+                pass
+                logger.critical('============冷机运行模式输入错误============')
+        return water_temp_set_run_continue, is_continuous_run_fix
+
+    def water_temp_adjust_continuous_run(self, is_lower_oil_pre, is_suction_with_liquid, list_load_ratio):
+        if is_lower_oil_pre or is_suction_with_liquid:
+            water_temp_set_run_continue = ''
+            is_continuous_run_fix = 0
+        else:
+            water_temp_set_run_continue, is_continuous_run_fix = self.is_continuous_run(list_load_ratio)
+        return water_temp_set_run_continue, is_continuous_run_fix
+

+ 74 - 0
chiller_safety_modify/suction_with_liquid_multi_comp.py

@@ -0,0 +1,74 @@
+# from logs_conf.logger import *
+from logs.logger import *
+import pandas as pd
+
+
+class SuctionWithLiquidMultiComp(object):
+    def __init__(self, dict_chiller_inner, dict_upper_correct):
+        self.dict_chiller_inner = dict_chiller_inner
+        self.dict_upper_correct = dict_upper_correct
+        self.data_general = pd.DataFrame()
+
+    def judge_suction_with_liquid(self, load_ratio):
+        """
+        根据负载率和等熵效率判断是否是吸气带液
+        :param load_ratio: 压缩机负载率,若只有一个机头则为机组负载率
+        :return:
+        """
+        judge_suction_with_liquid = 0
+        if (max(self.data_general['iseEfficiency']) - min(self.data_general['iseEfficiency']) > 0.5) \
+                and (self.data_general['iseEfficiency'].iloc[-1] > 0.85) and load_ratio > 30:  # 第一个条件是最大值和最小值,已修改
+            judge_suction_with_liquid = 1
+        return judge_suction_with_liquid
+
+    @staticmethod
+    def is_suction_with_liquid(list_ise_efficiency, list_suction_with_liquid):
+        """
+
+        :param list_ise_efficiency:
+        :param list_suction_with_liquid:
+        :return:
+        """
+        is_suction_with_liquid = 0
+        list_ise_efficiency_liquid = []
+        ise_efficiency_liquid = ''
+        for i in range(len(list_ise_efficiency)):
+            if list_suction_with_liquid[i] == 1:
+                list_ise_efficiency_liquid.append(list_ise_efficiency[i][-1])
+                is_suction_with_liquid = 1
+        if list_ise_efficiency_liquid:
+            ise_efficiency_liquid = max(list_ise_efficiency_liquid)
+        return is_suction_with_liquid, ise_efficiency_liquid
+
+    def temp_set_adjust(self, ise_efficiency_liquid):
+        """
+        根据最大等熵效率的范围判断带液程度,确定吸气带液情况下的水温设定值
+        :param ise_efficiency_liquid:
+        :return:
+        """
+        if 0.85 < ise_efficiency_liquid < 1:
+            if self.dict_chiller_inner['runMode'] == 0:
+                water_temp_set_new = self.dict_chiller_inner['chillerWaterTempOut'][-1] - \
+                                     ise_efficiency_liquid
+            elif self.dict_chiller_inner['runMode'] == 1:
+                water_temp_set_new = self.dict_chiller_inner['coolingWaterTempOut'][-1] + \
+                                     ise_efficiency_liquid      # 此处有修改
+            else:
+                water_temp_set_new = ''
+                logger.critical('============冷机运行模式输入错误============')
+            results_depict = '压缩机出现带液,水温下调'
+        else:
+            if self.dict_chiller_inner['runMode'] == 0:
+                water_temp_set_new = self.dict_chiller_inner['chillerWaterTempOut'][-1] - 1.0
+            elif self.dict_chiller_inner['runMode'] == 1:
+                water_temp_set_new = self.dict_chiller_inner['coolingWaterTempOut'][-1] + 1.0   # 此处有修改
+            else:
+                water_temp_set_new = ''
+                logger.critical('============冷机运行模式输入错误============')
+            results_depict = '压缩机严重带液,水温下调'
+        logger.critical('============%s============' % results_depict)
+        return water_temp_set_new, results_depict
+
+
+
+

+ 285 - 0
communication/iotdb_util.py

@@ -0,0 +1,285 @@
+import datetime
+import json
+
+from iotdb.SessionPool import SessionPool, PoolConfig
+from iotdb.utils.Field import Field
+from iotdb.utils.SessionDataSet import SessionDataSet
+from iotdb.utils.IoTDBConstants import TSDataType
+from threading import Lock
+
+# 官方示例 https://github.com/apache/iotdb/blob/rc/2.0.1/iotdb-client/client-py/session_pool_example.py
+# pip install apache-iotdb==1.3.3 -i http://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com
+
+"""
+
+# 初始化客户端,只需要程序启动时初始化一次
+IotDbClient('127.0.0.1', username='root', password='root')
+# 请求数据
+dataset = IotDbClient.query('select * from root.unimat.dev_64')
+# 解析数据
+parse_dataset_to_list(dataset)
+
+"""
+
+
+class IotDbClient:
+    _instance = None
+    _lock = Lock()
+    session_pool = None
+    tz = datetime.timezone(datetime.timedelta(hours=8))
+
+    def __new__(cls, *args, **kwargs):
+        with cls._lock:
+            if not cls._instance:
+                cls._instance = super().__new__(cls)
+        return cls._instance
+
+    def __init__(self, host, username='root', password='root', port=6667, pool_size=100, timeout_ms=3000,
+                 time_zone="UTC+8", max_retry=0):
+        """
+        初始化客户端
+        :param host: 服务器地址
+        :param username: 用户名
+        :param password: 密码
+        :param port: 端口 默认 6667
+        :param pool_size: 线程池大小
+        :param timeout_ms: 请求超时
+        :param time_zone: 时区
+        :param max_retry: 最大重试次数
+        """
+        with self._lock:
+            if not self.__class__.session_pool:
+                self._pool_config = PoolConfig(host=host, port=str(port), user_name=username,
+                                               password=password, fetch_size=1024,
+                                               time_zone=time_zone, max_retry=max_retry)
+                self.__class__.session_pool = SessionPool(self._pool_config, pool_size, timeout_ms)
+
+    @classmethod
+    def query(cls, sql) -> SessionDataSet | None:
+        session = None
+        try:
+            session = IotDbClient.session_pool.get_session()
+            return session.execute_query_statement(sql)
+        except Exception as e:
+            return None
+        finally:
+            if session is not None:
+                IotDbClient.session_pool.put_back(session)
+
+
+def parse_dataset_to_list(dataset: SessionDataSet, timedela=600) -> dict:
+    """
+    解析iotdb 非last类型的查询结果
+    { "time":[],"code1":[],"code2":[],...}
+    :param dataset:
+    :param timedela: 对查询结果时间进行偏移
+    :return:
+    """
+    if dataset is None:
+        return {}
+    column_names = dataset.column_names
+    result = {}
+    timed_list = []
+    while dataset.has_next():
+        line = dataset.next()
+        fields = line.get_fields()
+        timestamp = line.get_timestamp() / 1000
+        origin_time = datetime.datetime.fromtimestamp(timestamp, IotDbClient.tz)
+        center_time = origin_time
+        if timedela is not None:
+            center_time = origin_time + datetime.timedelta(seconds=timedela)
+        str_time = center_time.strftime('%Y-%m-%d %H:%M:%S')
+        timed_list.append(str_time)
+        for index, name in enumerate(column_names[1:]):
+            code = name.split('.')[-1]
+            v = fields[index]
+            value = convert_data_type(v)
+            if code in result.keys():
+                result[code].append(value)
+            else:
+                result[code] = [value]
+        result['dateTime'] = timed_list
+    return result
+
+
+def parse_last_data_set(dataset: SessionDataSet):
+    """
+    解析last查询的结果
+    :param dataset:
+    :return:
+    """
+    if dataset is None:
+        return {}
+    result = {}
+    while dataset.has_next():
+        line = dataset.next()
+        # [ column_name, value, ts_data_type]
+        fields = line.get_fields()
+        column_name = str(fields[0]).split('.')[-1]
+        column_value = convert_last_data_type(str(fields[1]), str(fields[2]))
+        result[column_name] = {"time": line.get_timestamp(), "value": column_value}
+
+    return result
+
+
+def convert_data_type(field: Field):
+    """
+    解析iotdb数据
+    :param field:
+    :return:
+    """
+    ts_data_type = field.get_data_type()
+    if ts_data_type is None:
+        return None
+    final_value = field.get_string_value()
+    if final_value is None or final_value == 'None':
+        return None
+    if ts_data_type == TSDataType.FLOAT:
+        return float(final_value)
+    if ts_data_type == TSDataType.INT32:
+        return int(final_value)
+
+
+def convert_last_data_type(value: str, data_type_name: str):
+    """
+    解析last查询的数据类型
+    :param value:
+    :param data_type_name:
+    :return:
+    """
+    if 'FLOAT' == data_type_name:
+        return float(value)
+    elif 'INT' == data_type_name:
+        return int(value)
+    elif 'TEXT' == data_type_name:
+        return value
+    else:
+        return value
+
+
+def query_terminal_7days(dbpath="root.org_100.monitor_54", start_time="2025-05-13T19:22:53",
+                         end_time="2025-05-20T19:22:53") -> dict:
+    """
+    查询监测点7天历史数据(间隔10分钟,取该点前后10分钟的值)
+    :param dbpath: 数据库时序路径
+    :param start_time: 起始时间
+    :param end_time: 截至时间
+    :return: { 'tempReal': [], 'humiReal': [], 'status':[], ’time‘:[] }
+    """
+    sql = f"""
+           SELECT LAST_VALUE(temperature) AS 'tempReal' , LAST_VALUE(humidity) AS 'humiReal', LAST_VALUE(status) AS 'status' 
+           FROM {dbpath}
+           WHERE time >= {start_time} 
+           GROUP BY ([{start_time}, {end_time}), 20m)
+        """
+    session_data_set = IotDbClient.query(sql)
+    return parse_dataset_to_list(session_data_set, 10 * 60)
+
+
+def query_station_7days(dbpath="root.org_100.dev_159", start_time="2025-05-13T19:22:53",
+                        end_time="2025-05-20T19:22:53") -> dict:
+    """
+    查询冷站7天冷冻总管出水温度
+    :param dbpath:
+    :param start_time:
+    :param end_time:
+    :return: { 'chilledWaterMainTempOut':[], 'time':[] }
+    """
+    sql = f"""
+           SELECT LAST_VALUE(chilledWaterMainTempOut) AS 'chilledWaterMainTempOut' 
+           FROM {dbpath}
+           WHERE time >= {start_time} 
+           GROUP BY ([{start_time}, {end_time}), 20m) 
+        """
+    session_data_set = IotDbClient.query(sql)
+    return parse_dataset_to_list(session_data_set, 10 * 60)
+
+
+def query_chiller_7days(dbpath="root.org_100.dev_159", start_time="2025-05-13T19:22:53", end_time="2025-05-20T19:22:53",
+                        capacityRated=1) -> dict:
+    """
+    查询冷机7天历史数据
+    :param dbpath:
+    :param start_time:
+    :param end_time:
+    :return:
+    """
+    sql = f"""
+           SELECT LAST_VALUE(loadRatio) AS 'loadRate' , 
+                  LAST_VALUE(evapWaterTempOut) AS 'chillerWaterTempOut', 
+                  LAST_VALUE(outputActivePower) / 1 AS 'chillerPowerRatio'
+           FROM {dbpath}
+           WHERE time >= {start_time} 
+           GROUP BY ([{start_time}, {end_time}), 20m)
+        """
+    session_data_set = IotDbClient.query(sql)
+    return parse_dataset_to_list(session_data_set, 10 * 60)
+
+
+def get_terminal_modify_data(org_id, terminal_ids, trigger_time_stamp):
+    result = {}
+    if len(str(trigger_time_stamp)) == 13:
+        trigger_time_stamp = trigger_time_stamp / 1000
+    # trigger_time 向前移10分钟
+    trigger_time = datetime.datetime.fromtimestamp(trigger_time_stamp, IotDbClient.tz)
+    start_time = trigger_time - datetime.timedelta(days=7) - datetime.timedelta(minutes=10)
+
+    for terminal_id in terminal_ids:
+        dbpath = "root.org_" + str(org_id) + ".monitor_" + str(terminal_id)
+
+        data = query_terminal_7days(dbpath, start_time.strftime('%Y-%m-%dT%H:%M:00'),
+                                    trigger_time.strftime('%Y-%m-%dT%H:%M:00'))
+        result[str(terminal_id)] = data
+    return result
+
+
+def get_chiller_modify_data(org_id, chiller_ids, power_rates, trigger_time_stamp):
+    result = {}
+    if len(str(trigger_time_stamp)) == 13:
+        trigger_time_stamp = trigger_time_stamp / 1000
+    # trigger_time 向前移10分钟
+    trigger_time = datetime.datetime.fromtimestamp(trigger_time_stamp, IotDbClient.tz)
+    start_time = trigger_time - datetime.timedelta(days=7) - datetime.timedelta(minutes=10)
+    for index, chiller_id in enumerate(chiller_ids):
+        dbpath = "root.org_" + str(org_id) + ".dev_" + str(chiller_id)
+        data = query_chiller_7days(dbpath, start_time.strftime('%Y-%m-%dT%H:%M:00'),
+                                   trigger_time.strftime('%Y-%m-%dT%H:%M:00'), power_rates[index])
+        result[str(chiller_id)] = data
+
+    return result
+
+
+def get_station_modify_data(org_id, device_id, trigger_time_stamp):
+    if len(str(trigger_time_stamp)) == 13:
+        trigger_time_stamp = trigger_time_stamp / 1000
+    # trigger_time 向前移10分钟
+    trigger_time = datetime.datetime.fromtimestamp(trigger_time_stamp, IotDbClient.tz)
+    start_time = trigger_time - datetime.timedelta(days=7) - datetime.timedelta(minutes=10)
+
+    dbpath = "root.org_" + str(org_id) + ".dev_" + str(device_id)
+    data = query_station_7days(dbpath, start_time.strftime('%Y-%m-%dT%H:%M:00'),
+                               trigger_time.strftime('%Y-%m-%dT%H:%M:00'))
+    return data
+
+
+# if __name__ == '__main__':
+#     IotDbClient('192.168.1.70', username='root', password='root')
+#
+#     # 组织/租户ID
+#     org_id = 100
+#     # 冷机ID
+#     chiller_ids = [170]
+#     # 超标监测点ID
+#     terminal_ids = [58, 59, 60]
+#     # 冷机额定功率
+#     power_rates = [200]
+#     # 群控柜ID
+#     controller_id = 168
+#
+#     trigger_time_stamp = 1748517100841
+#     terminal_data = get_terminal_modify_data(org_id, terminal_ids, trigger_time_stamp)
+#     chiller_data = get_chiller_modify_data(org_id, chiller_ids, power_rates, trigger_time_stamp)
+#     station_data = get_station_modify_data(org_id, controller_id, trigger_time_stamp)
+#     print(json.dumps(terminal_data))
+#     print(json.dumps(chiller_data))
+#     print(json.dumps(station_data))

+ 147 - 0
communication/rabbitmq_link.py

@@ -0,0 +1,147 @@
+from config.communication_config import *
+import pika
+
+
+
+class PikaMessage(object):
+    def __init__(self, exchange_name, queue_name, routing_key):
+        """
+        初始化参数:
+        用户名,密码,ip,端口,交换机,交换机类型,队列名称,路由key
+        """
+        self.username = USERNAME
+        self.password = PASSWORD
+        self.host = HOST
+        self.port = PORT
+        self.virtual_host = VIRTUAL_HOST_GET
+        self.exchange = exchange_name
+        self.exchange_type = EXCHANGE_TYPE
+        self.queue_name = queue_name
+        self.routing_key = routing_key
+        self.credentials = pika.PlainCredentials(USERNAME, PASSWORD)
+        self.chillertemp_delay_exchange = "chillertemp.calc.delay.exchange"
+        self.chillertemp_delay_exchange_type = "x-delayed-message"
+        self.chillertemp_delay_queue = "chillertemp.calc.delay.input"
+        self.chillertemp_delay_key = "chillertemp.delay.input"
+
+    def connect(self):
+        """
+        建立连接
+        :return: None
+        """
+        self.connection = pika.BlockingConnection(pika.ConnectionParameters(host=self.host,
+                                                                            port=self.port,
+                                                                            virtual_host=self.virtual_host,
+                                                                            credentials=self.credentials))
+        self.channel = self.connection.channel()
+
+    def declare_exchange(self):
+        """
+        声明交换机
+        :return: None
+        """
+        self.channel.exchange_declare(exchange=self.exchange,
+                                      exchange_type=self.exchange_type,
+                                      durable=True)
+        # self.channel.exchange_declare(exchange=self.chillertemp_delay_exchange,
+        #                               exchange_type=self.chillertemp_delay_exchange_type,
+        #                               arguments={"x-delayed-type": "direct"},
+        #                               durable=True)
+
+    def declare_queue(self):
+        """
+        声明队列
+        :return: None
+        """
+        self.channel.queue_declare(queue=self.queue_name, durable=True)
+        self.channel.queue_declare(queue=self.chillertemp_delay_queue, durable=True)
+
+    def bind_queue(self):
+        """
+        将交换机下的队列名与路由key绑定起来
+        :return: None
+        """
+        self.channel.queue_bind(exchange=self.exchange,
+                                queue=self.queue_name,
+                                routing_key=self.routing_key)
+        # self.channel.queue_bind(exchange=self.chillertemp_delay_exchange,
+        #                         queue=self.chillertemp_delay_queue,
+        #                         routing_key=self.chillertemp_delay_key)
+
+    def callback(self, ch, method, properties, body):
+        """
+        将rabbitmq监听队列的消息发送到延迟队列
+        :param ch:
+        :param method:
+        :param properties:
+        :param body:
+        :return:
+        """
+        # self.publish_msg_to_delay_queue(body)
+        data_from_rabbitmq = body.decode()
+        from main import main
+        main(data_from_rabbitmq)
+
+    @staticmethod
+    def callback_delay(ch, method, properties, body):
+        data_from_rabbitmq = body.decode()
+        from main import main
+        main(data_from_rabbitmq)
+
+    def consume(self):
+        """
+        消费消息
+        :return: None
+        """
+        self.channel.basic_consume(self.queue_name, self.callback, True)
+        # self.channel.basic_consume(self.chillertemp_delay_queue, self.callback_delay, True)
+        self.channel.start_consuming()
+
+    def connection_close(self):
+        self.connection.close()
+
+    def publish_msg_to_queue(self, body):
+        """
+        发布消息
+        :return: None
+        """
+        self.channel.basic_publish(exchange=self.exchange,
+                                   routing_key=self.routing_key,
+                                   body=body)
+
+    def publish_msg_to_delay_queue(self, body):
+        """
+        发布消息到延迟队列
+        :return: None
+        """
+        self.channel.basic_publish(exchange=self.chillertemp_delay_exchange,
+                                   routing_key=self.chillertemp_delay_key,
+                                   properties=pika.BasicProperties(delivery_mode=2, headers={'x-delay': 90000}),
+                                   body=body)
+
+
+def create_connect():
+    """
+    创建连接,并且返回原始数据值
+    :param queue_name: 队列的名称
+    :param routing_key: 与队列绑定的路由key
+    :return: 原始传输数据值
+    """
+    # 从这里开始exchange_name, queue_name, routing_key
+    rabbitmq_connection_get = PikaMessage(EXCHANGE_GET, QUEUE_NAME_GET, ROUTING_KEY_GET)  # 实例化
+    rabbitmq_connection_get.connect()  # 建立连接
+    rabbitmq_connection_get.declare_exchange()  # 声明交换机
+    rabbitmq_connection_get.declare_queue()  # 声明队列
+    rabbitmq_connection_get.bind_queue()  # 绑定队列
+    rabbitmq_connection_get.consume()  # 消费
+    rabbitmq_connection_get.connection_close()  # 关闭连接
+
+
+def send_data_to_rabbitmq(body):
+    rabbitmq_connection_get = PikaMessage(EXCHANGE_SEND, QUEUE_NAME_SEND, ROUTING_KEY_SEND)  # 实例化
+    rabbitmq_connection_get.connect()  # 建立连接
+    rabbitmq_connection_get.declare_exchange()  # 声明交换机
+    rabbitmq_connection_get.publish_msg_to_queue(body)
+    rabbitmq_connection_get.connection_close()  # 关闭连接
+
+

+ 25 - 0
config/communication_config.py

@@ -0,0 +1,25 @@
+
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+# 与rabbitmq通讯相关的参数设置
+from config.config import configs, mysql_configs
+
+USERNAME = configs["rabbitmq_config"]["username"]  # 用户名
+PASSWORD = configs["rabbitmq_config"]["password"]  # 密码
+HOST = configs["rabbitmq_config"]["host"]  # ip
+PORT = configs["rabbitmq_config"]["port"]  # 端口
+EXCHANGE_TYPE = configs["rabbitmq_config"]["exchange_type"]  # 交换机方式
+
+EXCHANGE_GET = configs["rabbitmq_config"]["exchange_get"]  # 获取交换机名称
+QUEUE_NAME_GET = configs["rabbitmq_config"]["queue_name_get"]  # 获取数据的队列
+ROUTING_KEY_GET = configs["rabbitmq_config"]["routing_key_get"]  # 获取数据的routingkey
+VIRTUAL_HOST_GET = configs["rabbitmq_config"]["virtual_host"]  # 获取虚拟服务器
+
+EXCHANGE_SEND = configs["rabbitmq_config"]["exchange_send"]  # 发送交换机名称
+QUEUE_NAME_SEND = configs["rabbitmq_config"]["queue_name_send"]  # 发送数据的队列
+ROUTING_KEY_SEND = configs["rabbitmq_config"]["routing_key_send"]  # 发送数据的routingkey
+VIRTUAL_HOST_SEND = configs["rabbitmq_config"]["virtual_host"]  # 获取虚拟服务器
+
+
+emEmbaic = mysql_configs["em_embasic"]
+emBsem = mysql_configs["em_bsem"]

+ 117 - 0
data_initialize_standard/constant.py

@@ -0,0 +1,117 @@
+# ==========算法中涉及的相关变量==========
+# EnergyMode = {'极限节能': 1, '标准节能': 2, '安全节能': 3}  # 控制模式决定温度限制值,先写死,后续作为产品配置参数
+
+# 在进行温湿度计算时,按照以下温度和湿度范围进行筛选,避免异常数据导致计算发生错误
+TerminalTempRange = {'lowerLimit': 0, 'upperLimit': 50}
+TerminalHumiRange = {'lowerLimit': 0, 'upperLimit': 100}
+
+# 在进行温湿度限值修正时,用到以下阈值,先写死,后续视情况优化
+ModifyTempHumiPara = {'threshold': 0.5, 'quantile': 0.75}  # 分别代表阈值和分位数
+
+# 根据监测点情况进行水温计算时,用到以下系数,分别代表温度超标、湿度超标、露点超标、温度不超标、湿度不超标
+Coefficient = {'outTemp': 1, 'outHumi': 0.1, 'outDewPoint': 1.25, 'inTemp': 0.5, 'inHumi': 0.05}
+
+# 温湿度超标情况判断结果
+ExcessDescription = {'0': '未超标', '1': '温度超标', '2': '露点超标', '3': '湿度超标'}
+
+ExpectedStructure = {
+        "terminalInfo": ["ahuMeterId", "ahuName", "ahuStartTime", "coolingTempUpper", "coolingHumiUpper", "tempReal",
+                         "humiReal"],
+        "controlConfigInfo": ["handleService", "controlMode", "isHardwareControl", "calPeriod", "minControlStep",
+                              "chillerWaterTempSetInitial", "chillerWaterTempSetUpper", "chillerWaterTempSetLower",
+                              "energyMode", "controlBasis", "tempMargin", "humiMargin", "mainTempMode", "samplePeriod",
+                              "upTempControlPeriod", "downTempControlPeriod"],
+        "chillerConfigInfo": ["waterTempControlMode", "isContinuousRun", "coolingShutdownOffset", "coolingRestartOffset",
+                              "safetyPreDiffLowerLimit", "safetyLoadRatioLowerLimit", "chillerTempStep"],
+        "chillerSafetyPara": ["circuitNumber", "circuitParameter"],
+        "stationInfo": ["userName", "stationName", "stationId", "runMode", "triggerTime", "chilledWaterMainTempOut",
+                        "chilledWaterMainTempIn", "allChillersInfo"],
+        "chillerInfo": ["chillerId", "chillerName", "capacityRated", "refriType", "chillerWaterTempSet",
+                        "chillerOffTimeLatest", "offSetTempLatestCooling", "chillerWaterTempOut", "chillerWaterTempIn",
+                        "runStatus", "chillerPowerRatio", "loadRate", "upControlTimeLatest", "downControlTimeLatest"],
+    }
+
+
+# def check_data_integrity(dic_input):
+#     # 定义预期的数据结构
+#     missing_fields = []
+#
+#     # 检查顶层字段缺失
+#     for top_key in ExpectedStructure:
+#         if top_key not in dic_input:
+#             missing_fields.append(top_key)
+#
+#     # 检查子字段缺失
+#     # for top_key in ExpectedStructure:
+#         if top_key in dic_input:
+#             current_data = dic_input[top_key]
+#             if isinstance(current_data, dict):
+#                 expected_subkeys = ExpectedStructure[top_key]
+#                 for sub_key in expected_subkeys:
+#                     if sub_key not in current_data:
+#                         missing_fields.append(f"{top_key}.{sub_key}")
+#
+#     # 检查空值的递归函数
+#     def find_empty_fields(data, parent_path='', empty_fields=None):
+#         if empty_fields is None:
+#             empty_fields = set()
+#
+#         if isinstance(data, dict):
+#             for key, value in data.items():
+#                 new_path = f"{parent_path}.{key}" if parent_path else key
+#                 # 检查当前值是否为空
+#                 if value is None:
+#                     empty_fields.add(new_path)
+#                 elif isinstance(value, str) and value.strip() == '':
+#                     empty_fields.add(new_path)
+#                 elif isinstance(value, (list, dict)) and not value:
+#                     empty_fields.add(new_path)
+#                 # 递归检查子元素
+#                 find_empty_fields(value, new_path, empty_fields)
+#         elif isinstance(data, list):
+#             if not data:  # 空列表
+#                 empty_fields.add(parent_path)
+#             else:
+#                 for index, item in enumerate(data):
+#                     new_path = f"{parent_path}[{index}]"
+#                     # 检查当前元素是否为空
+#                     if item is None:
+#                         empty_fields.add(new_path)
+#                     elif isinstance(item, str) and item.strip() == '':
+#                         empty_fields.add(new_path)
+#                     elif isinstance(item, (list, dict)) and not item:
+#                         empty_fields.add(new_path)
+#                     # 递归检查子元素
+#                     find_empty_fields(item, new_path, empty_fields)
+#         else:
+#             # 检查字符串是否为空
+#             if isinstance(data, str) and data.strip() == '':
+#                 empty_fields.add(parent_path)
+#         return empty_fields
+#
+#     # 查找所有空值路径
+#     empty_paths = find_empty_fields(dic_input)
+#
+#     return missing_fields, empty_paths
+#
+# dic_input = {}
+#
+# # 执行检查
+# missing_fields, empty_paths = check_data_integrity(dic_input)
+#
+# # 输出结果
+# print("输入参数中缺失关键字段,退出水温智控算法计算")
+# print("输入参数中关键数据存在空值,退出水温智控算法计算")
+# print("缺失字段检查结果:")
+# if missing_fields:
+#     print("缺失字段:")
+#     print("\n".join(missing_fields))
+# else:
+#     print("无缺失字段")
+#
+# print("\n空值字段检查结果:")
+# if empty_paths:
+#     print("存在空值的字段路径:")
+#     print("\n".join(sorted(empty_paths)))
+# else:
+#     print("无空值字段")

+ 83 - 0
data_initialize_standard/data_standardization.py

@@ -0,0 +1,83 @@
+import pandas as pd
+
+
+class DataStandardization(object):
+    def __init__(self, data_dict):
+        self.data_dict = data_dict
+
+    def null_judge(self):
+        Num = 0
+        for k in self.data_dict:
+            if self.data_dict[k] == ' ' or not self.data_dict[k]:
+                Num += 1
+        return Num
+
+    def dict_standard(self):
+
+        dict_chiller_cooling = self.data_dict['chillerConfigInfo']
+        dict_chiller_outer = {}
+        dict_code = self.data_dict['controlConfigInfo']
+
+        all_chillers_info = self.data_dict['stationInfo']['allChillersInfo']
+        all_chiller_water_temp_set = []
+        all_water_temp_control_mode = []
+
+        for i in range(len(all_chillers_info['chillerId'])):
+            if all_chillers_info['runStatus'][i] == 1 and all_chillers_info['isInControl'][i] == 1:
+                all_chiller_water_temp_set.append(all_chillers_info['chillerWaterTempSet'][i])
+            if all_chillers_info['isInControl'][i] == 1:
+                all_water_temp_control_mode.append(all_chillers_info['waterTempControlMode'][i])
+
+        dict_chiller_cooling.update({
+                                     'triggerTime': self.data_dict['stationInfo']['triggerTime'],
+                                     'runMode': self.data_dict['stationInfo']['runMode'],
+                                     'runStatus': self.data_dict['chillerInfo']['runStatus'],
+                                     'chillerOffTimeLatest': self.data_dict['chillerInfo']['chillerOffTimeLatest'],
+                                     'offSetTempLatestCooling': self.data_dict['chillerInfo']['offSetTempLatestCooling'],
+                                     # 'offSetTempInLatestCooling': 12,
+                                     'allChillerWaterTempSetOn': all_chiller_water_temp_set,
+                                     # 'allChillerWaterTempInSetOn': [],
+                                     'allChillerControlSelect': all_water_temp_control_mode,
+                                     # 'allChillerPowerRatio': [],
+                                     'chillerPowerRatio': self.data_dict['chillerInfo']['chillerPowerRatio'],
+                                     'chillerWaterTempOut': self.data_dict['chillerInfo']['chillerWaterTempOut'],
+                                     'chillerWaterTempIn': self.data_dict['chillerInfo']['chillerWaterTempIn'],
+                                     'chillerWaterTempSet': self.data_dict['chillerInfo']['chillerWaterTempSet'],
+                                     'chillerWaterTempSetInitial': self.data_dict['controlConfigInfo']['chillerWaterTempSetInitial'],
+                                     'chillerWaterTempSetUpper': self.data_dict['controlConfigInfo']['chillerWaterTempSetUpper'],
+                                     # 'chillerWaterTempInSetUpper': self.data_dict,
+                                     'chillerWaterTempSetDown': self.data_dict['controlConfigInfo']['chillerWaterTempSetLower'],
+                                     })
+        dict_chiller_outer.update({
+                                   'triggerTime': self.data_dict['stationInfo']['triggerTime'],
+                                   'userName': self.data_dict['stationInfo']['userName'],
+                                   'coolingStationName': self.data_dict['stationInfo']['coolingStationName'],
+                                   'orgId': self.data_dict['stationInfo']['orgId'],
+                                   'chillerName': self.data_dict['chillerInfo']['chillerName'],
+                                   'chillerId': self.data_dict['chillerInfo']['chillerId'],
+                                   'stationId': self.data_dict['stationInfo']['stationId'],
+                                   'controllerId': self.data_dict['stationInfo']['controllerId'],
+                                   'allChillersInfo': self.data_dict['stationInfo']['allChillersInfo']})
+
+        dict_code.update({'upControlTimeLatest': self.data_dict['chillerInfo']['upControlTimeLatest'],
+                          'downControlTimeLatest': self.data_dict['chillerInfo']['downControlTimeLatest'],
+                          'triggerTime': self.data_dict['stationInfo']['triggerTime'],
+                          'runMode': self.data_dict['stationInfo']['runMode'],
+                          'calMode': 0,  # 监测点计算模式默认值为0
+                          'allChillerControlSelect': all_water_temp_control_mode})
+        return dict_chiller_cooling, dict_chiller_outer, dict_code
+
+    def dict_safety(self):
+        dict_upper_correct = {'refriType': self.data_dict['chillerInfo']['refriType'],
+                               'chillerParameter': self.data_dict['chillerSafetyPara']}
+        # dict_upper_correct.update({'refriType': self.data_dict['chillerInfo']['refriType'],
+        #                            'chillerParameter': self.data_dict['chillerSafetyPara']})
+        return dict_upper_correct
+
+    def data_multi_comp(self):
+        dict_chiller_inner, dict_chiller_outer, dict_code = self.dict_standard()
+        dict_upper_correct = self.dict_safety()
+        data_temp_humi = pd.DataFrame(self.data_dict['terminalInfo'])
+
+        return dict_chiller_inner, dict_chiller_outer, dict_code, dict_upper_correct, data_temp_humi
+

+ 144 - 0
data_initialize_standard/results.py

@@ -0,0 +1,144 @@
+import datetime
+import numpy as np
+
+
+def DictResultsNull(dict_chiller_outer, dict_chiller_inner, dict_code, results_depict):
+    if isinstance(dict_code['triggerTime'], str):
+        trigger_time = dict_code['triggerTime']
+    else:
+        trigger_time = dict_code['triggerTime'].strftime("%Y-%m-%d %H:%M:%S")
+    resultsOutput = {'userName': dict_chiller_outer['userName'],
+                     'coolingStationName': dict_chiller_outer['coolingStationName'],
+                     'chillerName': dict_chiller_outer['chillerName'],
+                     'chillerId': dict_chiller_outer['chillerId'],
+                     'isOrder': False,
+                     'waterTempSetNew': None,
+                     'controlMode': dict_code['controlMode'],
+                     'energyMode': dict_code['energyMode'],
+                     # 'triggerTime': dict_code['triggerTime'].strftime("%Y-%m-%d %H:%M:%S"),
+                     'triggerTime': trigger_time,
+                     'isHardwareControl': dict_code['isHardwareControl'],
+                     'runStatus': dict_chiller_inner['runStatus'][-1],
+                     'chillerWaterTempOut': dict_chiller_inner['chillerWaterTempOut'][-1],
+                     'chillerWaterTempSet': dict_chiller_inner['chillerWaterTempSet'],
+                     'chillerWaterTempSetUpper': dict_chiller_inner['chillerWaterTempSetUpper'],
+                     'ahuName': [],
+                     'tempReal': [],
+                     'humiReal': [],
+                     'dewTempReal': [],
+                     'tempLimit': [],
+                     'humiLimit': [],
+                     'dewTempLimit': [],
+                     'worstTerminalInfo': {},
+                     'resultsDepict': results_depict
+                     }
+    return resultsOutput
+
+
+def DictResultsNormal(is_suction_with_liquid, is_control, results_depict, water_temp_set_new, dict_chiller_inner,
+                      dict_chiller_outer, dict_code, data_temp_humi, excess_reslut, terminal_cal):
+    if isinstance(dict_code['triggerTime'], str):
+        trigger_time = dict_code['triggerTime']
+    else:
+        trigger_time = dict_code['triggerTime'].strftime("%Y-%m-%d %H:%M:%S")
+    resultsOutput = {'userName': dict_chiller_outer['userName'],
+                     'coolingStationName': dict_chiller_outer['coolingStationName'],
+                     'chillerName': dict_chiller_outer['chillerName'],
+                     'chillerId': dict_chiller_outer['chillerId'],
+                     'isOrder': is_control,
+                     'waterTempSetNew': water_temp_set_new,
+                     'controlMode': dict_code['controlMode'],
+                     'energyMode': dict_code['energyMode'],
+                     'triggerTime': trigger_time,
+                     # 'triggerTime': dict_code['triggerTime'],
+                     'isHardwareControl': dict_code['isHardwareControl'],
+                     'runStatus': dict_chiller_inner['runStatus'][-1],
+                     'chillerWaterTempOut': dict_chiller_inner['chillerWaterTempOut'][-1],
+                     'chillerWaterTempSet': dict_chiller_inner['chillerWaterTempSet'],
+                     'chillerWaterTempSetUpper': dict_chiller_inner['chillerWaterTempSetUpper'],
+                     'resultsDepict': results_depict}
+    if dict_chiller_inner['runMode'] == 0:
+        if is_suction_with_liquid == 1 or data_temp_humi.shape[0] == 0 or not terminal_cal:
+            resultsTempHumid = {'ahuName': [],
+                                'tempReal': [],
+                                'humiReal': [],
+                                'dewTempReal': [],
+                                'tempLimit': [],
+                                'humiLimit': [],
+                                'dewTempLimit': [],
+                                'worstTerminalInfo': {}}
+        else:
+            resultsTempHumid = {'ahuName': list(data_temp_humi['ahuName']),
+                                'tempReal': list(data_temp_humi['tempReal']),
+                                'humiReal': list(data_temp_humi['humiReal']),
+                                'dewTempReal': list(data_temp_humi['dewTempReal']),
+                                'tempLimit': list(data_temp_humi['tempLimit']),
+                                'humiLimit': list(data_temp_humi['humiLimit']),
+                                'dewTempLimit': list(data_temp_humi['dewTempLimit']),
+                                'worstTerminalInfo': excess_reslut,
+                                }
+
+        if dict_chiller_inner['waterTempControlMode'] == 1:  # python输出参数中冷冻水进/出水温度统一字段
+            resultsOtherOutput = {'chillerWaterTempSet': dict_chiller_inner['chillerWaterTempInSet'],
+                                  'chillerWaterTempSetUpper': dict_chiller_inner['chillerWaterTempInSetUpper'],
+                                  # 'resultsDepict': '冷冻水回水温度设定值,由%s℃调整为%s℃' % (
+                                  #     dict_chiller_inner['chillerWaterTempInSet'], water_temp_set_new)
+                                  }
+        else:
+            resultsOtherOutput = {'chillerWaterTempSet': dict_chiller_inner['chillerWaterTempSet'],
+                                  'chillerWaterTempSetUpper': dict_chiller_inner['chillerWaterTempSetUpper'],
+                                  # 'resultsDepict': '冷冻水出水温度设定值,由%s℃调整为%s℃' % (
+                                  #     dict_chiller_inner['chillerWaterTempSet'], water_temp_set_new)
+                                  }
+    else:
+        if is_suction_with_liquid == 1 or data_temp_humi.shape[0] == 0:
+            resultsTempHumid = {'tempHumiMeterId': '',
+                                'tempReal': '',
+                                'tempLimit': ''}
+        else:
+            resultsTempHumid = {'tempHumiMeterId': list(data_temp_humi['tempHumiMeterId']),
+                                'tempReal': list(data_temp_humi['tempReal']),
+                                'tempLimit': list(data_temp_humi['tempLimit'])}
+
+        if dict_chiller_inner['waterTempControlMode'] == 1:  # python输出参数中冷冻水进/出水温度统一字段
+            resultsOtherOutput = {'heatingWaterTempSet': dict_chiller_inner['heatingWaterTempInSet'],
+                                  'heatingWaterTempSetInitial': dict_chiller_inner['heatingWaterTempInSetInitial'],
+                                  'heatingWaterTempSetUpper': dict_chiller_inner['heatingWaterTempInSetUpper'],
+                                  'resultsDepict': '热水回水温度设定值,由%s℃调整为%s℃' % (
+                                      dict_chiller_inner['heatingWaterTempInSet'], water_temp_set_new)
+                                  }
+        else:
+            resultsOtherOutput = {'heatingWaterTempSet': dict_chiller_inner['heatingWaterTempSet'],
+                                  'heatingWaterTempSetInitial': dict_chiller_inner['heatingWaterTempSetInitial'],
+                                  'heatingWaterTempSetUpper': dict_chiller_inner['heatingWaterTempSetUpper'],
+                                  'resultsDepict': '热水出水温度设定值,由%s℃调整为%s℃' % (
+                                      dict_chiller_inner['heatingWaterTempSet'], water_temp_set_new)
+                                  }
+    resultsOutput.update(resultsTempHumid)
+    resultsOutput.update(resultsOtherOutput)
+    return resultsOutput
+
+
+def DictResultsAbnormal(dict_input, result_depict):
+    resultsOutput = {'userName': dict_input['stationInfo']['userName'],
+                     'coolingStationName': dict_input['stationInfo']['coolingStationName'],
+                     'chillerName': dict_input['chillerInfo']['chillerName'],
+                     'chillerId': dict_input['chillerInfo']['chillerId'],
+                     'triggerTime': dict_input['stationInfo']['triggerTime'],
+                     'isOrder': False,
+                     'waterTempSetNew': None,
+                     'resultsDepict': result_depict
+                     }
+    return resultsOutput
+
+def default_dump(obj):
+    """
+    TypeError: Object of type int64 is not JSON serializable
+    Covert numpy classes to JSON serializable objects
+    """
+    if isinstance(obj, (np.integer, np.floating, np.bool_)):
+        return obj.item()
+    elif isinstance(obj, np.ndarray):
+        return obj.tolist()
+    else:
+        return obj

+ 28 - 0
logs/logger.py

@@ -0,0 +1,28 @@
+import logging
+from logging.handlers import TimedRotatingFileHandler
+
+logger = logging.getLogger()
+logger.setLevel(level=logging.ERROR)
+
+log_file_name_local = './logs/time_rotate'
+
+# 本地轮转日志代码
+formatter = '%(asctime)s - %(message)s'
+time_rotate_file = TimedRotatingFileHandler(filename=log_file_name_local, when='H', interval=24, backupCount=24)
+time_rotate_file.setFormatter(logging.Formatter(formatter))
+time_rotate_file.setLevel(logging.ERROR)
+logger.addHandler(time_rotate_file)
+
+
+# 控制台日志代码
+console_handler = logging.StreamHandler()
+console_handler.setLevel(logging.ERROR)
+console_handler.setFormatter(logging.Formatter(formatter))
+logger.addHandler(console_handler)
+
+"""
+    S - Seconds
+    M - Minutes
+    H - Hours
+    D - Days
+"""

+ 39 - 0
main.py

@@ -0,0 +1,39 @@
+import json
+from logs.logger import *
+from service.standard_service import StandardService
+from data_initialize_standard.results import *
+from communication.rabbitmq_link import create_connect, send_data_to_rabbitmq
+
+
+def main(data_input):
+    dict_input = json.loads(data_input)
+    logger.critical("============Get data from rabbitmq============")
+    logger.critical("Input: {}".format(json.dumps(dict_input, ensure_ascii=False)))
+    try:
+        if dict_input['controlConfigInfo']['handleService'] == 1:
+            logger.critical('============算法服务开启,进入水温智控算法============')
+            mcss = StandardService(dict_input)
+            dict_results = mcss.main_multi_comp_service()
+        else:
+            logger.critical('============算法服务关闭,退出水温智控算法============')
+            dict_results = {}
+        logger.critical("============Send calculated results to rabbitmq============")
+        dict_results = json.dumps(dict_results, ensure_ascii=False)
+        logger.critical("Output: {}".format(dict_results))
+        send_data_to_rabbitmq(dict_results)
+
+    except Exception as e:
+        result_depict = '异常中断,退出水温智控算法' + "(" + str(e) + ")"
+        logger.critical('============{}============'.format(result_depict))
+        dict_results = DictResultsAbnormal(dict_input, result_depict)
+        logger.critical("============Send calculated results to rabbitmq============")
+        dict_results = json.dumps(dict_results, ensure_ascii=False, default=default_dump)
+        logger.critical("Output: {}".format(dict_results))
+        send_data_to_rabbitmq(dict_results)
+
+
+if __name__ == '__main__':
+    logger.critical("========Create connection for rabbitmq========")
+    create_connect()
+
+

+ 131 - 0
optimized_and_individal/control_period_step_adjust.py

@@ -0,0 +1,131 @@
+import pandas as pd
+# from logs_conf.logger import *
+from logs.logger import *
+
+
+class ControlPeriodStepAdjust(object):
+    def __init__(self, dict_input):
+        self.dict_input = dict_input
+        self.data_upper_correct = pd.DataFrame()
+        self.dict_code = {}
+        self.dict_chiller_inner = {}
+
+    # def step_adjust(self):
+    #     """
+    #     根据历史安全压差对步长进行调整
+    #     """
+    #     preDiffMin = self.data_upper_correct['preDiff'].min()
+    #     if preDiffMin < 50:
+    #         if self.dict_chiller_inner['waterTempControlMode'] == 0:
+    #             if self.water_temp_set_new > (self.dict_chiller_inner['chillerWaterTempSet'] + 0.3):
+    #                 self.water_temp_set_new = self.dict_chiller_inner['chillerWaterTempSet'] + 0.3
+    #         elif self.dict_chiller_inner['waterTempControlMode'] == 1:
+    #             if self.water_temp_set_new > (self.dict_chiller_inner['chillerWaterTempInSet'] + 0.3):
+    #                 self.water_temp_set_new = self.dict_chiller_inner['chillerWaterTempInSet'] + 0.3
+    #         else:
+    #             self.water_temp_set_new = ''
+    #             # logger.critical('==============冷机控制选择输入错误==============')
+    #     return None
+
+    # def control_period_adjust(self):
+    #     """
+    #     根据采样周期进行调整
+    #     采样周期不可低于80秒,否则会出现负值
+    #     :return:
+    #     """
+    #     tempLimit = 0.00125 * self.dict_code['controlPeriodNew'] - 0.1
+    #     if self.dict_chiller_inner['runMode'] == 0:
+    #         if self.dict_chiller_inner['waterTempControlMode'] == 0:
+    #             if self.water_temp_set_new > (self.dict_chiller_inner['chillerWaterTempSet'] + tempLimit):
+    #                 self.water_temp_set_new = self.dict_chiller_inner['chillerWaterTempSet'] + tempLimit
+    #         elif self.dict_chiller_inner['waterTempControlMode'] == 1:
+    #             if self.water_temp_set_new > (self.dict_chiller_inner['chillerWaterTempInSet'] + tempLimit):
+    #                 self.water_temp_set_new = self.dict_chiller_inner['chillerWaterTempInSet'] + tempLimit
+    #         else:
+    #             self.water_temp_set_new = ''
+    #             # logger.critical('==============冷机控制选择输入错误==============')
+    #     else:
+    #         if self.dict_chiller_inner['waterTempControlMode'] == 0:
+    #             if self.water_temp_set_new < (self.dict_chiller_inner['heatingWaterTempSet'] - tempLimit):
+    #                 self.water_temp_set_new = self.dict_chiller_inner['heatingWaterTempSet'] - tempLimit
+    #         elif self.dict_chiller_inner['waterTempControlMode'] == 1:
+    #             if self.water_temp_set_new < (self.dict_chiller_inner['heatingWaterTempInSet'] - tempLimit):
+    #                 self.water_temp_set_new = self.dict_chiller_inner['heatingWaterTempInSet'] - tempLimit
+    #         else:
+    #             self.water_temp_set_new = ''
+    #             # logger.critical('==============冷机控制选择输入错误==============')
+    #     return None
+
+    def control_time_diff_cal(self):
+        """
+        分别计算升温控制时间差和降温控制时间差
+        :return:
+        """
+        self.dict_chiller_inner['triggerTime'] = pd.to_datetime(self.dict_chiller_inner['triggerTime'])
+        # self.dict_code['controlTimeLatest'] = pd.to_datetime(self.dict_code['controlTimeLatest'])
+        # self.dict_code['controlTimeDiff'] = (
+        #             self.dict_chiller_inner['triggerTime'] - self.dict_code['controlTimeLatest']).total_seconds()
+        # 升温控制时间差
+
+        self.dict_code['upControlTimeLatest'] = pd.to_datetime(self.dict_code['upControlTimeLatest'])
+        self.dict_code['upControlTimeDiff'] = (
+                self.dict_chiller_inner['triggerTime'] - self.dict_code['upControlTimeLatest']).total_seconds()
+        # 降温控制时间差
+        self.dict_code['downControlTimeLatest'] = pd.to_datetime(self.dict_code['downControlTimeLatest'])
+        self.dict_code['downControlTimeDiff'] = (
+                self.dict_chiller_inner['triggerTime'] - self.dict_code['downControlTimeLatest']).total_seconds()
+
+        # self.dict_code['controlPeriodNew'] = self.dict_code['controlTimeDiff']  # 这里的赋值待确认 #######
+        return self.dict_code
+
+    def pointwise_temp_diff_cal(self):
+        """
+        逐点温差的计算,当前只考虑了出水温度数量为1的场景,若出水温度数量大于1则需要分情况计算,待迭代
+        :return:
+        """
+        temp_diff_list = []
+        if self.dict_chiller_inner['runMode'] == 0:
+            for i in range(1, len(self.dict_chiller_inner['chillerWaterTempOut'])):
+                temp_diff = self.dict_chiller_inner['chillerWaterTempOut'][i] - \
+                           self.dict_chiller_inner['chillerWaterTempOut'][i - 1]
+                temp_diff_list.append(temp_diff)
+        elif self.dict_chiller_inner['runMode'] == 1:
+            for i in range(1, len(self.dict_chiller_inner['coolingWaterTempOut'])):
+                temp_diff = self.dict_chiller_inner['coolingWaterTempOut'][i] - \
+                           self.dict_chiller_inner['coolingWaterTempOut'][i - 1]
+                temp_diff_list.append(temp_diff)
+        else:
+            logger.critical('============冷机运行模式输入错误============')
+        return temp_diff_list
+
+    def control_period_cal(self, is_safety_issue):
+        """
+        计算控制周期是否满足调控周期,满足则控制,不满足则再进一步判断安全因素
+        判断安全因素时需要计算逐点温差
+        :param is_safety_issue: 是否存在安全运行问题,三个安全校验的最终结果
+        :return:
+        """
+        self.control_time_diff_cal()
+        if self.dict_code['upControlTimeDiff'] > self.dict_code['upTempControlPeriod'] * 60 or \
+                self.dict_code['downControlTimeDiff'] > self.dict_code['downTempControlPeriod'] * 60:
+            is_control = 1
+            # self.dict_code['controlPeriodNew'] = self.dict_code['controlPeriod']  # 这里的赋值待确认 #######
+            logger.critical('============正常控制1:控制时间差已满足条件,设备正常控制============')
+        else:
+            if is_safety_issue:
+                temp_diff_list = self.pointwise_temp_diff_cal()
+                if temp_diff_list:
+                    if max(temp_diff_list) < 0.2 or (self.dict_code['upControlTimeDiff'] > 180 and
+                                                     self.dict_code['downControlTimeDiff'] > 180):  # 这里的逻辑待确认 #######
+                        is_control = 1
+                        logger.critical('============正常控制2:存在安全运行风险,设备正常控制============')
+                    else:
+                        is_control = 0
+                        logger.critical('============不控制:控制时间差不满足条件,设备不控制============')
+                else:
+                    is_control = 1
+            else:
+                is_control = 0
+                logger.critical('============不控制:控制时间差不满足条件,且不存在安全运行风险,设备不控制============')
+        return is_control
+

+ 19 - 0
optimized_and_individal/frequently_start_stop.py

@@ -0,0 +1,19 @@
+class JudgeFrequentlyStartStop(object):
+    def __init__(self, dict_code, dict_chiller_inner):
+        self.dict_chiller_inner = dict_chiller_inner
+        self.dict_code = dict_code
+
+    def is_freq_start_stop(self):
+        unit_status_str = ''
+        for i in self.dict_chiller_inner['runStatus']:
+            unit_status_str += str(i)
+        unit_status_str_split = unit_status_str.split('1')
+        # chiller_off_time_last = len(unit_status_str_split[-1]) * self.dict_code['samplePeriod']
+        chiller_off_time_last = len(unit_status_str_split[-1]) * 3 * 60  # 采样周期写死
+        chiller_off_count = len([1 for i in unit_status_str_split if i != ''])
+        if chiller_off_count > 2 and chiller_off_time_last < 2700:
+            judge_freq_start_stop = 1  # 1为频繁启停,0为正常停机
+        else:
+            judge_freq_start_stop = 0
+        return judge_freq_start_stop
+

+ 201 - 0
optimized_and_individal/temperature_step_size_05.py

@@ -0,0 +1,201 @@
+# from logs_conf.logger import *
+from logs.logger import *
+import math
+
+
+class ModifyLeavingWaterTempSetTSS05(object):
+    def __init__(self, water_temp_set_new, dict_chiller_inner):
+        self.water_temp_set_new = water_temp_set_new
+        self.dict_chiller_inner = dict_chiller_inner
+
+    def modify_temp(self):
+        if self.dict_chiller_inner['runMode'] == 0:
+            result = self.modify_temp_cooling()
+        elif self.dict_chiller_inner['runMode'] == 1:
+            result = self.modify_temp_heating()
+        else:
+            result = ''
+            logger.critical('============冷机运行模式输入错误============')
+        return result
+
+    def modify_temp_cooling(self):
+        if self.water_temp_set_new > self.dict_chiller_inner['chillerWaterTempSet']:
+            result = self.increase_temp_cooling()
+        else:
+            result = self.decrease_temp_cooling()
+        return result
+
+    def modify_temp_heating(self):
+        if self.water_temp_set_new < self.dict_chiller_inner['coolingWaterTempOut']:
+            result = self.decrease_temp_heating()
+        else:
+            result = self.increase_temp_heating()
+        return result
+
+    def increase_temp_cooling(self):
+        tempDiff = round(self.water_temp_set_new - math.floor(self.water_temp_set_new), 2)
+        if tempDiff > 0.5:  # 以0.5为步长的向上取值
+            modify_water_temp_set = math.floor(self.water_temp_set_new) + 1.0
+        else:
+            modify_water_temp_set = math.floor(self.water_temp_set_new) + 0.5
+        if modify_water_temp_set - self.dict_chiller_inner['chillerWaterTempOut'][-1] > \
+                0.75 * self.dict_chiller_inner['coolingShutdownOffset']:
+            deltaWaterTempSet = round((modify_water_temp_set - 0.5) - self.dict_chiller_inner['chillerWaterTempSet'], 2)
+            if deltaWaterTempSet >= 1.0:
+                result = self.dict_chiller_inner['chillerWaterTempSet'] + 1.0
+            elif deltaWaterTempSet >= 0.5:
+                result = self.dict_chiller_inner['chillerWaterTempSet'] + 0.5
+            else:
+                result = self.dict_chiller_inner['chillerWaterTempSet']
+        else:
+            deltaWaterTempSet = round(self.water_temp_set_new - self.dict_chiller_inner['chillerWaterTempSet'], 2)
+            if deltaWaterTempSet >= 1.0:
+                result = self.dict_chiller_inner['chillerWaterTempSet'] + 1.0
+            elif self.water_temp_set_new < 10 and deltaWaterTempSet > 0.1:
+                result = modify_water_temp_set
+            else:
+                if deltaWaterTempSet >= 0.7:
+                    result = self.dict_chiller_inner['chillerWaterTempSet'] + 1.0
+                elif deltaWaterTempSet >= 0.2:
+                    result = self.dict_chiller_inner['chillerWaterTempSet'] + 0.5
+                else:
+                    result = self.dict_chiller_inner['chillerWaterTempSet']
+        return result
+
+    def decrease_temp_cooling(self):
+        deltaWaterTempSet = round(self.water_temp_set_new - self.dict_chiller_inner['chillerWaterTempSet'], 2)
+        if abs(deltaWaterTempSet) >= 1:
+            fractionalPart = abs(deltaWaterTempSet) % 1
+            if fractionalPart >= 0.7:
+                result = self.dict_chiller_inner['chillerWaterTempSet'] - (math.floor(abs(deltaWaterTempSet)) + 1.0)
+            elif fractionalPart >= 0.2:
+                result = self.dict_chiller_inner['chillerWaterTempSet'] - (math.floor(abs(deltaWaterTempSet)) + 0.5)
+            else:
+                result = self.dict_chiller_inner['chillerWaterTempSet'] - math.floor(abs(deltaWaterTempSet))
+        elif abs(deltaWaterTempSet) >= 0.7:
+            result = self.dict_chiller_inner['chillerWaterTempSet'] - 1.0
+        elif abs(deltaWaterTempSet) >= 0.2:
+            result = self.dict_chiller_inner['chillerWaterTempSet'] - 0.5
+        else:
+            result = self.dict_chiller_inner['chillerWaterTempSet']
+        return result
+
+    def increase_temp_heating(self):
+        deltaWaterTempSet = round(self.dict_chiller_inner['coolingWaterTempOut'] - self.water_temp_set_new, 2)
+        if abs(deltaWaterTempSet) >= 1:
+            fractionalPart = abs(deltaWaterTempSet) % 1
+            if fractionalPart >= 0.7:
+                result = self.dict_chiller_inner['coolingWaterTempOut'] + (math.floor(abs(deltaWaterTempSet)) + 1.0)
+            elif fractionalPart >= 0.2:
+                result = self.dict_chiller_inner['coolingWaterTempOut'] + (math.floor(abs(deltaWaterTempSet)) + 0.5)
+            else:
+                result = self.dict_chiller_inner['coolingWaterTempOut'] + math.floor(abs(deltaWaterTempSet))
+        elif abs(deltaWaterTempSet) >= 0.7:
+            result = math.floor(self.water_temp_set_new) + 1.0
+        elif abs(deltaWaterTempSet) >= 0.2:
+            result = math.floor(self.water_temp_set_new) + 0.5
+        else:
+            result = math.floor(self.water_temp_set_new)
+        return result
+
+    def decrease_temp_heating(self):
+        tempDiff = round(self.water_temp_set_new - math.floor(self.water_temp_set_new), 2)
+        if tempDiff > 0.5:  # 以0.5为步长的向下取值
+            modify_water_temp_set = math.floor(self.water_temp_set_new) + 0.5
+        else:
+            modify_water_temp_set = math.floor(self.water_temp_set_new)
+        if self.dict_chiller_inner['coolingWaterTempOut'] - modify_water_temp_set > \
+                0.75 * self.dict_chiller_inner['heatingShutdownOffset']:
+            deltaWaterTempSet = round(self.dict_chiller_inner['coolingWaterTempOut'] - (modify_water_temp_set + 0.5), 2)
+            if deltaWaterTempSet >= 1.0:
+                result = self.dict_chiller_inner['coolingWaterTempOut'] - 1.0
+            elif deltaWaterTempSet >= 0.5:
+                result = self.dict_chiller_inner['coolingWaterTempOut'] - 0.5
+            else:
+                result = self.dict_chiller_inner['coolingWaterTempOut']
+        else:
+            deltaWaterTempSet = round(self.dict_chiller_inner['coolingWaterTempOut'] - self.water_temp_set_new, 2)
+            if deltaWaterTempSet >= 1.0:
+                result = self.dict_chiller_inner['coolingWaterTempOut'] - 1.0
+            elif self.water_temp_set_new > 50 and deltaWaterTempSet > 0.1:
+                result = modify_water_temp_set
+            else:
+                if deltaWaterTempSet >= 0.7:
+                    result = self.dict_chiller_inner['coolingWaterTempOut'] - 1.0
+                elif deltaWaterTempSet >= 0.2:
+                    result = self.dict_chiller_inner['coolingWaterTempOut'] - 0.5
+                else:
+                    result = self.dict_chiller_inner['coolingWaterTempOut']
+        return result
+
+
+class ModifyReturningWaterTempSetTSS05(object):
+    def __init__(self, water_temp_set_new, dict_chiller_inner):
+        self.water_temp_set_new = water_temp_set_new
+        self.dict_chiller_inner = dict_chiller_inner
+
+    def modify_temp(self):
+        if self.dict_chiller_inner['runMode'] == 0:
+            result = self.modify_temp_cooling()
+        elif self.dict_chiller_inner['runMode'] == 1:
+            result = ''
+            logger.critical('============制热模式和回水温度控制模式下温度修正函数未开发, Error: TSS05============')
+        else:
+            result = ''
+            logger.critical('============冷机运行模式输入错误============')
+        return result
+
+    def modify_temp_cooling(self):
+        if self.water_temp_set_new > self.dict_chiller_inner['chillerWaterTempInSet']:
+            result = self.increase_temp_cooling()
+        else:
+            result = self.decrease_temp_cooling()
+        return result
+
+    def increase_temp_cooling(self):
+        tempDiff = round(self.water_temp_set_new - math.floor(self.water_temp_set_new), 2)
+        if tempDiff > 0.5:  # 以0.5为步长的向上取值
+            modify_water_temp_set = math.floor(self.water_temp_set_new) + 1.0
+        else:
+            modify_water_temp_set = math.floor(self.water_temp_set_new) + 0.5
+        if modify_water_temp_set - self.dict_chiller_inner['chillerWaterTempIn'][-1] > \
+                0.75 * self.dict_chiller_inner['coolingShutdownOffset']:
+            deltaWaterTempSet = round((modify_water_temp_set - 0.5) - self.dict_chiller_inner['chillerWaterTempInSet'], 2)
+            if deltaWaterTempSet >= 1.0:
+                result = self.dict_chiller_inner['chillerWaterTempInSet'] + 1.0
+            elif deltaWaterTempSet >= 0.5:
+                result = self.dict_chiller_inner['chillerWaterTempInSet'] + 0.5
+            else:
+                result = self.dict_chiller_inner['chillerWaterTempInSet']
+        else:
+            deltaWaterTempSet = round(self.water_temp_set_new - self.dict_chiller_inner['chillerWaterTempInSet'], 2)
+            if deltaWaterTempSet >= 1.0:
+                result = self.dict_chiller_inner['chillerWaterTempInSet'] + 1.0
+            elif self.water_temp_set_new < 10 and deltaWaterTempSet > 0.1:
+                result = modify_water_temp_set
+            else:
+                if deltaWaterTempSet >= 0.7:
+                    result = self.dict_chiller_inner['chillerWaterTempInSet'] + 1.0
+                elif deltaWaterTempSet >= 0.2:
+                    result = self.dict_chiller_inner['chillerWaterTempInSet'] + 0.5
+                else:
+                    result = self.dict_chiller_inner['chillerWaterTempInSet']
+        return result
+
+    def decrease_temp_cooling(self):
+        deltaWaterTempSet = round(self.water_temp_set_new - self.dict_chiller_inner['chillerWaterTempInSet'], 2)
+        if abs(deltaWaterTempSet) >= 1:
+            fractionalPart = abs(deltaWaterTempSet) % 1
+            if fractionalPart >= 0.7:
+                result = self.dict_chiller_inner['chillerWaterTempInSet'] - (math.floor(abs(deltaWaterTempSet)) + 1.0)
+            elif fractionalPart >= 0.2:
+                result = self.dict_chiller_inner['chillerWaterTempInSet'] - (math.floor(abs(deltaWaterTempSet)) + 0.5)
+            else:
+                result = self.dict_chiller_inner['chillerWaterTempInSet'] - math.floor(abs(deltaWaterTempSet))
+        elif abs(deltaWaterTempSet) >= 0.7:
+            result = self.dict_chiller_inner['chillerWaterTempInSet'] - 1.0
+        elif abs(deltaWaterTempSet) >= 0.2:
+            result = self.dict_chiller_inner['chillerWaterTempInSet'] - 0.5
+        else:
+            result = self.dict_chiller_inner['chillerWaterTempInSet']
+        return result

+ 162 - 0
optimized_and_individal/temperature_step_size_10.py

@@ -0,0 +1,162 @@
+# from logs_conf.logger import *
+from logs.logger import *
+import math
+
+
+class ModifyLeavingWaterTempSetTSS10(object):
+    def __init__(self, water_temp_set_new, dict_chiller_inner):
+        self.water_temp_set_new = water_temp_set_new
+        self.dict_chiller_inner = dict_chiller_inner
+
+    def modify_temp(self):
+        if self.dict_chiller_inner['runMode'] == 0:
+            result = self.modify_temp_cooling()
+        elif self.dict_chiller_inner['runMode'] == 1:
+            result = self.modify_temp_heating()
+        else:
+            result = ''
+            logger.critical('============冷机运行模式输入错误============')
+        return result
+
+    def modify_temp_cooling(self):
+        if self.water_temp_set_new > self.dict_chiller_inner['chillerWaterTempSet']:
+            result = self.increase_temp_cooling()
+        else:
+            result = self.decrease_temp_cooling()
+        return result
+
+    def modify_temp_heating(self):
+        if self.water_temp_set_new < self.dict_chiller_inner['coolingWaterTempOut']:
+            result = self.decrease_temp_heating()
+        else:
+            result = self.increase_temp_heating()
+        return result
+
+    def increase_temp_cooling(self):
+        if math.ceil(self.water_temp_set_new) - self.dict_chiller_inner['chillerWaterTempOut'][-1] > \
+                0.75 * self.dict_chiller_inner['coolingShutdownOffset']:
+            deltaWaterTempSet = round(math.floor(self.water_temp_set_new) - self.dict_chiller_inner['chillerWaterTempSet'], 2)
+            if deltaWaterTempSet >= 1:
+                result = self.dict_chiller_inner['chillerWaterTempSet'] + 1
+            else:
+                result = self.dict_chiller_inner['chillerWaterTempSet']
+        else:
+            deltaWaterTempSet = round(self.water_temp_set_new - self.dict_chiller_inner['chillerWaterTempSet'], 2)
+            if deltaWaterTempSet >= 1:
+                result = self.dict_chiller_inner['chillerWaterTempSet'] + 1
+            elif self.water_temp_set_new < 10 and deltaWaterTempSet > 0.1:
+                result = math.ceil(self.water_temp_set_new)
+            else:
+                if deltaWaterTempSet >= 0.5:
+                    result = math.ceil(self.water_temp_set_new)
+                else:
+                    result = math.floor(self.water_temp_set_new)
+        return result
+
+    def decrease_temp_cooling(self):
+        deltaWaterTempSet = round(self.water_temp_set_new - self.dict_chiller_inner['chillerWaterTempSet'], 2)
+        if abs(deltaWaterTempSet) >= 1:
+            fractionalPart = abs(deltaWaterTempSet) % 1
+            if fractionalPart >= 0.5:
+                result = self.dict_chiller_inner['chillerWaterTempSet'] - math.ceil(abs(deltaWaterTempSet))
+            else:
+                result = self.dict_chiller_inner['chillerWaterTempSet'] - math.floor(abs(deltaWaterTempSet))
+        elif abs(deltaWaterTempSet) >= 0.25:
+            result = math.floor(self.water_temp_set_new)
+        else:
+            result = math.ceil(self.water_temp_set_new)  # 制冷模式的降温过程向上取整即取原值
+        return result
+
+    def increase_temp_heating(self):
+        deltaWaterTempSet = round(self.dict_chiller_inner['coolingWaterTempOut'] - self.water_temp_set_new, 2)
+        if abs(deltaWaterTempSet) >= 1:
+            fractionalPart = abs(deltaWaterTempSet) % 1
+            if fractionalPart >= 0.5:
+                result = self.dict_chiller_inner['coolingWaterTempOut'] + math.ceil(abs(deltaWaterTempSet))
+            else:
+                result = self.dict_chiller_inner['coolingWaterTempOut'] + math.floor(abs(deltaWaterTempSet))
+        elif abs(deltaWaterTempSet) >= 0.5:
+            result = math.ceil(self.water_temp_set_new)
+        else:
+            result = math.floor(self.water_temp_set_new)  # 制热模式的升温过程向下取整即取原值
+        return result
+
+    def decrease_temp_heating(self):
+        if self.dict_chiller_inner['coolingWaterTempOut'] - math.floor(self.water_temp_set_new) > \
+                0.75 * self.dict_chiller_inner['heatingShutdownOffset']:
+            deltaWaterTempSet = round(self.dict_chiller_inner['coolingWaterTempOut'] - math.ceil(self.water_temp_set_new), 2)
+            if deltaWaterTempSet >= 1:
+                result = self.dict_chiller_inner['coolingWaterTempOut'] - 1
+            else:
+                result = self.dict_chiller_inner['coolingWaterTempOut']
+        else:
+            deltaWaterTempSet = round(self.dict_chiller_inner['coolingWaterTempOut'] - self.water_temp_set_new, 2)
+            if deltaWaterTempSet >= 1:
+                result = self.dict_chiller_inner['coolingWaterTempOut'] - 1
+            elif self.water_temp_set_new > 50 and deltaWaterTempSet > 0.1:
+                result = math.floor(self.water_temp_set_new)
+            else:
+                if deltaWaterTempSet >= 0.5:
+                    result = math.floor(self.water_temp_set_new)
+                else:
+                    result = math.ceil(self.water_temp_set_new)
+        return result
+
+
+class ModifyReturningWaterTempSetTSS10(object):
+    def __init__(self, water_temp_set_new, dict_chiller_inner):
+        self.water_temp_set_new = water_temp_set_new
+        self.dict_chiller_inner = dict_chiller_inner
+
+    def modify_temp(self):
+        if self.dict_chiller_inner['runMode'] == 0:
+            result = self.modify_temp_cooling()
+        elif self.dict_chiller_inner['runMode'] == 1:
+            result = ''
+            logger.critical('============制热模式和回水温度控制模式下温度修正函数未开发, Error: TSS10============')
+        else:
+            result = ''
+            logger.critical('============冷机运行模式输入错误============')
+        return result
+
+    def modify_temp_cooling(self):
+        if self.water_temp_set_new > self.dict_chiller_inner['chillerWaterTempInSet']:
+            result = self.increase_temp_cooling()
+        else:
+            result = self.decrease_temp_cooling()
+        return result
+
+    def increase_temp_cooling(self):
+        if math.ceil(self.water_temp_set_new) - self.dict_chiller_inner['chillerWaterTempIn'][-1] > \
+                0.75 * self.dict_chiller_inner['coolingShutdownOffset']:
+            deltaWaterTempSet = round(math.floor(self.water_temp_set_new) - self.dict_chiller_inner['chillerWaterTempInSet'], 2)
+            if deltaWaterTempSet >= 1:
+                result = self.dict_chiller_inner['chillerWaterTempInSet'] + 1
+            else:
+                result = self.dict_chiller_inner['chillerWaterTempInSet']
+        else:
+            deltaWaterTempSet = round(self.water_temp_set_new - self.dict_chiller_inner['chillerWaterTempInSet'], 2)
+            if deltaWaterTempSet >= 1:
+                result = self.dict_chiller_inner['chillerWaterTempInSet'] + 1
+            elif self.water_temp_set_new < 10 and deltaWaterTempSet > 0.1:
+                result = math.ceil(self.water_temp_set_new)
+            else:
+                if deltaWaterTempSet >= 0.5:
+                    result = math.ceil(self.water_temp_set_new)
+                else:
+                    result = math.floor(self.water_temp_set_new)
+        return result
+
+    def decrease_temp_cooling(self):
+        deltaWaterTempSet = round(self.water_temp_set_new - self.dict_chiller_inner['chillerWaterTempInSet'], 2)
+        if abs(deltaWaterTempSet) >= 1:
+            fractionalPart = abs(deltaWaterTempSet) % 1
+            if fractionalPart >= 0.5:
+                result = self.dict_chiller_inner['chillerWaterTempInSet'] - math.ceil(abs(deltaWaterTempSet))
+            else:
+                result = self.dict_chiller_inner['chillerWaterTempInSet'] - math.floor(abs(deltaWaterTempSet))
+        elif abs(deltaWaterTempSet) >= 0.25:
+            result = math.floor(self.water_temp_set_new)
+        else:
+            result = math.ceil(self.water_temp_set_new)
+        return result

+ 235 - 0
service/public_method.py

@@ -0,0 +1,235 @@
+from data_initialize_standard.data_standardization import DataStandardization
+from water_temp_cal.water_temp_setpoint_new import SetPointStrategyOff, SetPointStrategyOnChillerOff,\
+    SetPointStrategyOnChillerOnAsynchronous, SetPointStrategyOnChillerOnSynchronous,\
+    JudgeSynchronizeAsynchronous, JudgeTempControlMode
+from data_initialize_standard.results import *
+from water_temp_cal.water_temp_set_switch import WaterTempSetVerify
+from temp_humid_cal.temp_humi_calculation import *
+from optimized_and_individal.control_period_step_adjust import ControlPeriodStepAdjust
+from optimized_and_individal.frequently_start_stop import JudgeFrequentlyStartStop
+# from logs_conf.logger import *
+from logs.logger import *
+import pandas as pd
+import time
+
+
+class PublicMethodClass(ControlPeriodStepAdjust):
+    def __init__(self, dict_input):
+        super(PublicMethodClass, self).__init__(dict_input)
+        self.dict_chiller_outer = {}
+        # self.modify_data = {}
+        self.dict_results = {}
+        self.data_temp_humi = pd.DataFrame()
+        self.isAdjustWaterTemp = 0
+        self.isControl = False
+        self.water_temp_set_new = None
+        self.results_depict = None
+        self.judge_syn_asy = ''   # 同步算法或异步算法
+        self.excess_result = {}
+        self.terminal_cal = False
+
+    # def is_null_judge(self):
+    #     self.ds = DataStandardization(self.dict_input)
+    #     dict_back_useless = self.ds.dict_useless()
+    #     Num = self.ds.null_judge()
+    #     return dict_back_useless, Num
+
+    def output_abnormal_situation(self, Num, is_control=1):
+        """
+        异常情况的输出
+        :param Num:
+        :param is_control:
+        :return:
+        """
+        if Num > 0:
+            self.results_depict = '输入参数存在空值,无计算结果'
+        elif self.dict_code['controlMode'] == 0:
+            self.results_depict = '智控开关状态关闭,无计算结果'
+        elif is_control == 0:
+            self.results_depict = '距上次下发指令周期太短,无计算结果'
+        else:
+            self.results_depict = '输入参数错误,无计算结果'
+        logger.critical("============%s============" % self.results_depict)
+        self.dict_results = DictResultsNull(self.dict_chiller_outer, self.dict_chiller_inner, self.dict_code,
+                                            self.results_depict)
+        return None
+
+    def output_normal_situation(self, is_safety_issue):
+        """
+        正常计算下的输出
+        :param is_safety_issue: 是否存在安全运行问题
+        :return:
+        """
+        # if self.isAdjustWaterTemp == 1:
+        #     if self.dict_code['isHardwareControl'] == 1:
+        #         if self.isAdjustWaterTemp == 1:
+        #             self.isControl = True
+        #     else:
+        #         self.results_depict = '计算正常,但不向硬件层发送指令'
+            # self.is_hardware_control()  # 控制模块
+        parameter = (is_safety_issue, self.isControl, self.results_depict, self.water_temp_set_new, self.dict_chiller_inner,
+                     self.dict_chiller_outer, self.dict_code, self.data_temp_humi, self.excess_result, self.terminal_cal)
+        self.dict_results = DictResultsNormal(*parameter)
+
+    def water_temp_set_verify(self, cal_mode):
+        """
+        水温验证与转换,验证是否超限,转换单位等
+        cal_mode: False表示停机状态下的水温计算;True表示运行状态下的水温计算
+        :return:
+        """
+        wtst = WaterTempSetVerify(self.water_temp_set_new, self.dict_chiller_inner)
+        if cal_mode:
+            self.water_temp_set_new = wtst.modify_verify()
+        else:
+            self.water_temp_set_new = wtst.limit_verify()
+        logger.critical('============经水温设定值校核后,最新水温设定值为 %s ℃============' % self.water_temp_set_new)
+        return self.water_temp_set_new
+
+    def is_adjust_judge(self):
+        control_time_diff = self.control_time_diff_cal()   # -----校验一下数据··········
+        if self.dict_chiller_inner['runMode'] == 0:
+            if self.dict_chiller_inner['waterTempControlMode'] == 0:
+                delta_temp = self.water_temp_set_new - self.dict_chiller_inner['chillerWaterTempSet']
+            else:
+                delta_temp = self.water_temp_set_new - self.dict_chiller_inner['chillerWaterTempInSet']
+
+            if (abs(delta_temp) < self.dict_code['minControlStep'] and self.dict_code['controlMode'] == 1 and
+                self.judge_syn_asy == 0 and self.dict_chiller_inner['runStatus'][-1] == 1) or delta_temp == 0:
+                self.results_depict = '制冷工况:计算正常,水温调整幅度太小,不进行调整'
+            else:
+                if (delta_temp > 0 and control_time_diff['upControlTimeDiff'] > control_time_diff['upTempControlPeriod']) \
+                        or (delta_temp < 0 and control_time_diff['downControlTimeDiff'] > control_time_diff['downTempControlPeriod']):
+                    self.isAdjustWaterTemp = 1
+                    self.results_depict = '制冷工况:计算正常,水温满足调整条件'
+                else:
+                    self.results_depict = '制冷工况:计算正常,不满足控制周期,不进行调整'
+        elif self.dict_chiller_inner['runMode'] == 1:
+            if self.dict_chiller_inner['waterTempControlMode'] == 0:
+                delta_temp = self.water_temp_set_new - self.dict_chiller_inner['heatingWaterTempSet']
+            else:
+                delta_temp = self.water_temp_set_new - self.dict_chiller_inner['heatingWaterTempInSet']
+
+            if (abs(delta_temp) < self.dict_code['minControlStep'] and self.dict_code['controlMode'] == 1 and
+                self.judge_syn_asy == 0 and self.dict_chiller_inner['runStatus'][-1] == 1) or delta_temp == 0:
+                self.results_depict = '制热工况:计算正常,水温调整幅度太小,不进行调整'
+            else:
+                if (delta_temp > 0 and control_time_diff['upControlTimeDiff'] > control_time_diff['upControlPeriod']) \
+                        or (delta_temp < 0 and control_time_diff['downControlTimeDiff'] > control_time_diff['downControlPeriod']):
+                    self.isAdjustWaterTemp = 1
+                    self.results_depict = '制热工况:计算正常,水温满足调整条件'
+                else:
+                    self.results_depict = '制热工况:计算正常,不满足控制周期,不进行调整'
+        else:
+            self.results_depict = '冷机运行模式输入错误'
+
+        if self.isAdjustWaterTemp == 1:
+            if self.dict_code['isHardwareControl'] == 1:
+                self.isControl = True
+            else:
+                self.results_depict += ',但不向硬件层发送指令'
+        logger.critical('============ %s ============' % self.results_depict)
+
+    # ----------------------------------------
+    # -----------------重构重构-----------------
+    def water_temp_set_cal(self):
+        # 运行冷机的水温计算主要步骤
+        # 监测点数据处理
+        # 监测点计算
+        # 监测点超标判断
+        # 同步或异步判断
+        # 进入同步或异步算法
+        # 设定值校验
+        # 监测点计算
+        logger.critical('============监测点计算开始============')
+        thf = TempHumiFunction(self.data_temp_humi, self.dict_code, self.dict_chiller_outer)  # 监测点实时数据
+        self.data_temp_humi = thf.temp_humi_cal()
+
+        if self.data_temp_humi.shape[0]:
+            # 监测点超标判断
+            judge = JudgeOutRange(self.data_temp_humi, self.dict_code)
+            self.excess_result = judge.is_out_of_range()
+            # # 判断控制模式是否唯一(供水控制还是回水控制)
+            jtcm = JudgeTempControlMode(self.dict_chiller_inner)
+            judge_sin_mul = jtcm.is_single_control_strategy()
+            if judge_sin_mul == 0 and not self.excess_result['isOutRange'] == '':
+                parameter = (self.dict_chiller_inner, self.data_temp_humi)
+                # 判断同步算法还是异步算法
+                jsa = JudgeSynchronizeAsynchronous(self.dict_chiller_inner)
+                self.judge_syn_asy = jsa.judge_synchronize_asynchronous()  # 判断同步算法还是异步算法
+                if self.judge_syn_asy == 1:
+                    logger.critical('============冷站设备异步,当前冷机水温设定值为 %s ℃,冷站内所有开机冷机设定值为 %s ============'
+                                    % (self.dict_chiller_inner['chillerWaterTempSet'],
+                                       self.dict_chiller_inner['allChillerWaterTempSetOn']))
+                    spsocoa = SetPointStrategyOnChillerOnAsynchronous(*parameter, self.excess_result)  # 异步算法
+                    water_temp_set_new = spsocoa.set_point_asynchronous()  # 异步算法
+                    logger.critical('============经过异步算法计算后,最新水温设定值为 %s ℃============' % water_temp_set_new)
+                else:
+                    logger.critical('============冷站设备同步,当前冷机水温设定值为 %s ℃,冷站内所有开机冷机设定值为 %s ============'
+                                    % (self.dict_chiller_inner['chillerWaterTempSet'],
+                                       self.dict_chiller_inner['allChillerWaterTempSetOn']))
+                    spsocos = SetPointStrategyOnChillerOnSynchronous(*parameter, self.excess_result)  # 同步算法
+                    water_temp_set_new, excess_result = spsocos.set_point_synchronous(self.dict_code['controlBasis'])  # 同步算法
+                    logger.critical('============经过同步算法计算后,最新水温设定值为 %s ℃============' % water_temp_set_new)
+                # 水温设定值限值校验
+                water_temp_set_new = WaterTempSetVerify(water_temp_set_new, self.dict_chiller_inner).limit_verify()
+                logger.critical('============当前水温设定值为 %s ℃,经限值校验后,最新水温设定值为 %s ℃============'
+                                % (self.dict_chiller_inner['chillerWaterTempSet'], water_temp_set_new))
+            else:
+                water_temp_set_new = None
+                if judge_sin_mul != 0:  # 供水和回水共存的场景暂不考虑
+                    logger.critical('============所有冷机水温控制方式不唯一,暂不适配此场景============')
+                    self.results_depict = '所有冷机水温控制方式不唯一,暂不适配此场景'
+                else:
+                    logger.critical('============监测点超标判断出现异常,不进行水温调控============')
+                    self.results_depict = '监测点超标判断出现异常,不进行水温调控'
+        else:
+            water_temp_set_new = None
+            self.results_depict = '所有末端开启时间太短,不进行水温调控'
+            logger.critical('============所有末端开启时间太短,不进行水温调控============')
+        return water_temp_set_new
+
+    def water_temp_main_process(self):
+        """
+        水温计算的主函数
+        :return:
+        """
+        parameter = (self.dict_chiller_inner, self.data_temp_humi)
+
+        if self.dict_code['controlMode'] == 0:    # 智控关闭
+            # 实际上不用做任何计算或动作,这里只是需要考虑 如果在节能评估期的初始工况日,确保冷机水温保持在设定值或以下即可(后续随产品迭代)
+            # spso = SetPointStrategyOff(*parameter)  # 智控关闭场景下,恢复模式下的水温
+            # self.water_temp_set_new = spso.self_control_strategy_off()  # 智控关闭下的水温设定,这里是恢复模式下的设定值
+            logger.critical('============智控开关为关闭,不进行水温计算============')
+        elif self.dict_code['controlMode'] == 1:  # 智控开启
+            logger.critical('============智控开关为开启,开始进行水温计算============')
+            if self.dict_chiller_inner['runStatus'][-1] == 0:  # 当前冷机状态为关机
+                jfss = JudgeFrequentlyStartStop(self.dict_code, self.dict_chiller_inner)
+                judge_freq_start_stop = jfss.is_freq_start_stop()   # 判断是正常停机还是频繁启停
+                if judge_freq_start_stop == 0:     # 非频繁启停,则是停机下水温设定
+                    logger.critical('============设备处于停机状态,水温正常调控============')
+                    spsoco = SetPointStrategyOnChillerOff(*parameter)  # 停机下水温设定值
+                    self.water_temp_set_new = spsoco.water_temp_set_confirm()  # 判断停机时长是否超过16小时
+                else:
+                    logger.critical('============设备处于频繁启停状态,水温正常调控============')
+                    self.water_temp_set_new = self.water_temp_set_cal()   # 运行冷机的水温计算
+                    self.terminal_cal = True
+            elif self.dict_chiller_inner['runStatus'][-1] == 1:  # 当前冷机状态为运行
+                logger.critical('============设备处于运行状态,水温正常调控============')
+                self.water_temp_set_new = self.water_temp_set_cal()      # 运行冷机的水温计算
+                self.terminal_cal = True
+            else:
+                self.water_temp_set_new = None
+                self.results_depict = '冷机运行状态输入错误'
+                logger.critical('============冷机运行状态输入错误============')
+        else:
+            self.water_temp_set_new = None
+            self.results_depict = '算法智控状态输入错误'
+            logger.critical('============算法智控状态输入错误============')
+        # if self.water_temp_set_new:
+        #     # 水温设定值校验
+        #     self.water_temp_set_new = round(self.water_temp_set_new, 1)
+        #     self.water_temp_set_verify(self.terminal_cal)
+        #     # 判断是否要调节水温
+        #     self.is_adjust_judge()
+        return self.water_temp_set_new
+

+ 58 - 0
service/standard_service.py

@@ -0,0 +1,58 @@
+from service.public_method import PublicMethodClass
+from chiller_safety_modify.multi_comp_safety_verify import MultiCompSafetyVerify
+from data_initialize_standard.data_standardization import DataStandardization
+from data_initialize_standard.results import *
+from logs.logger import *
+
+
+class StandardService(PublicMethodClass):
+    def __init__(self, dict_input):
+        super(StandardService, self).__init__(dict_input)
+
+    def main_multi_comp_service(self):
+        self.ds = DataStandardization(self.dict_input)
+        Num = self.ds.null_judge()
+        self.dict_chiller_inner, self.dict_chiller_outer, self.dict_code, self.dict_upper_correct, \
+            self.data_temp_humi = self.ds.data_multi_comp()
+
+        # 获取数据
+        # 数据处理
+
+        # 判断输入数据是否满足计算条件,且智控开关开启
+
+        if Num > 0 or self.dict_code['controlMode'] != 1:
+            self.output_abnormal_situation(Num)
+
+        # 数据处理正常,开启计算
+        else:
+            # 运行安全校验
+            logger.critical("============开始设备安全运行校验============")
+            mcsv = MultiCompSafetyVerify(self.dict_chiller_inner, self.dict_upper_correct)
+            is_safety_issue, self.water_temp_set_new = mcsv.safety_verify_main_process()
+            # 控制周期和控制条件判断
+            logger.critical("============开始控制周期和控制条件判断============")
+            is_control = self.control_period_cal(is_safety_issue)
+            if is_control == 1:
+                # 满足控制条件
+                if self.water_temp_set_new:
+                    # 存在安全问题
+                    self.water_temp_set_new = round(self.water_temp_set_new, 1)
+                    # 水温设定值校验
+                    logger.critical("============开始水温设定值校核============")
+                    self.water_temp_set_new = self.water_temp_set_verify(True)
+                    self.isAdjustWaterTemp = 1
+                else:
+                    # 不存在安全问题,根据监测点进行水温计算
+                    self.water_temp_set_new = self.water_temp_main_process()
+                    if self.water_temp_set_new:
+                        # 水温设定值校验
+                        logger.critical("============开始水温设定值校核============")
+                        self.water_temp_set_new = round(self.water_temp_set_new, 1)
+                        self.water_temp_set_verify(self.terminal_cal)
+                        # 判断是否要调节水温
+                        logger.critical("============开始水温调整条件判断============")
+                        self.is_adjust_judge()
+                self.output_normal_situation(is_safety_issue)
+            else:
+                self.output_abnormal_situation(Num, is_control)
+        return self.dict_results

+ 311 - 0
temp_humid_cal/excess_temp_modify.py

@@ -0,0 +1,311 @@
+import pandas as pd
+import datetime
+from data_initialize_standard.constant import *
+from communication.iotdb_util import *
+# from logs_conf.logger import *
+from logs.logger import *
+
+
+class ExcessTempModify(object):
+    def __init__(self, data_excess, dict_code, chiller_outer):
+        self.data_excess = data_excess
+        self.config = dict_code
+        # 由于不同项目末端监测点的采样周期不一致,若无温湿度采样周期则将无法按预期算法修正末端监测点温湿度限制
+        # self.modify = modify_data
+        self.chiller_outer = chiller_outer
+        self.modify = {'stationData': {}, 'terminalData': {}, 'chillerData': {}}
+        self.chiller_mode = dict_code['runMode']
+        self.sampling_nums = 60/dict_code['samplePeriod']*10   # 根据采样周期进行计算
+
+    def get_modify_data(self):
+        IotDbClient('192.168.1.70', username='root', password='root')
+        org_id = self.chiller_outer['orgId']
+        controller_id = self.chiller_outer['controllerId']
+        chiller_ids = self.chiller_outer['allChillersInfo']['chillerId']
+        power_rates = self.chiller_outer['allChillersInfo']['powerRated']
+        terminal_ids = list(self.data_excess['ahuMeterId'])
+        trigger_time_stamp = pd.to_datetime(self.chiller_outer['triggerTime']).timestamp()
+
+        self.modify['terminalData'] = get_terminal_modify_data(org_id, terminal_ids, trigger_time_stamp)
+        self.modify['chillerData'] = get_chiller_modify_data(org_id, chiller_ids, power_rates, trigger_time_stamp)
+        self.modify['stationData'] = get_station_modify_data(org_id, controller_id, trigger_time_stamp)
+
+    def data_judge(self):
+        self.get_modify_data()
+        is_success = 1
+        if not self.modify.get('stationData'):   # 冷站数据为{}
+            is_success = 0
+        for terminal in self.modify.get('terminalData', {}).values():  # 监测点数据为{}
+            if not terminal:
+                is_success = 0
+        if self.config["mainTempMode"] == 0:
+            for chiller in self.modify.get('chillerData', {}).values():  # 监测点数据为{}
+                if not chiller:
+                    is_success = 0
+            if is_success:
+                all_chillers = self.chiller_outer["allChillersInfo"]
+                # 使用zip组合两个列表并创建字典
+                control_mode = {cid: mode
+                                for cid, mode in zip(all_chillers["chillerId"], all_chillers["waterTempControlMode"])}
+                capacity_rated = {cid: mode
+                                  for cid, mode in zip(all_chillers["chillerId"], all_chillers["capacityRated"])}
+
+                for chiller_id, data in self.modify['chillerData'].items():
+                    if chiller_id in control_mode:
+                        data["waterTempControlMode"] = control_mode[chiller_id]
+                        data["capacityRated"] = capacity_rated[chiller_id]
+                    else:
+                        is_success = 0
+        return is_success
+
+    def transform_dict_to_dataformat(self, station_data, sensor_data, chiller_data):
+        """数据格式的转化"""
+        # chiller_mode = self.config['runMode']
+        time_stamp = station_data['dateTime']
+        # 温湿度数据合并
+        sensor_data_list = []
+        for key in sensor_data.keys():
+            sensor_data_list.append(pd.DataFrame(sensor_data[key], index=time_stamp))
+        # temp_humi_sensor_id = [int(key) for key in sensor_data.keys()]
+        temp_humi_sensor_id = [key for key in sensor_data.keys()]
+        sensor_data_df = pd.concat(sensor_data_list, keys=temp_humi_sensor_id, axis=1)
+        # sensor_data_df.index = pd.to_datetime([int(i + 28800000) for i in sensor_data_df.index], unit='ms')
+
+        # 通过配置判断总管温度是直接读取还是加权计算-------------------------------------------------------------
+        if self.config["mainTempMode"] == 1:  # 直接读取总管温度
+            water_temp_df = self.main_water_temp(station_data)
+        else:  # 计算加权水温
+            # 通过负载率删选冷机数据,并将所有冷机数据合并
+            chiller_data_list = []
+            for key in chiller_data.keys():
+                val = pd.DataFrame(chiller_data[key], index=time_stamp)
+                val.loc[(val['loadRate'] <= 10) | (val['chillerPowerRatio'] <= 10), ['loadRate', 'chillerPowerRatio']] = 0
+                val.fillna(0, inplace=True)
+                chiller_data_list.append(val)
+            # chiller_id_list = [int(key) for key in chiller_data.keys()]
+            chiller_id_list = [key for key in chiller_data.keys()]
+            chiller_data_df = pd.concat(chiller_data_list, keys=chiller_id_list, axis=1)
+            water_temp_df = self.cal_weighted_water_temp(chiller_data_df, chiller_id_list)
+            # water_temp_df.index = pd.to_datetime([int(i + 28800000) for i in chiller_data_df.index], unit='ms')
+        return sensor_data_df, water_temp_df
+
+    def main_water_temp(self, station_data):
+        """直接读取总管温度"""
+        weighted_water_temp = pd.DataFrame(index=station_data['dateTime'], columns=['weighted_water_temp', 'init_water_temp'])
+        weighted_water_temp['init_water_temp'] = self.config["chillerWaterTempSetInitial"]
+
+        if set(self.config['allChillerControlSelect']) == {0}:  # 均为供水控制模式
+            if self.chiller_mode == 0:
+                weighted_water_temp['weighted_water_temp'] = station_data["chilledWaterMainTempOut"]
+            elif self.chiller_mode == 1:
+                weighted_water_temp['weighted_water_temp'] = station_data["coolingWaterMainTempOut"]
+            else:
+                ValueError('chiller mode input error!')
+        elif set(self.config['allChillerControlSelect']) == {1}:  # 均为回水控制模式
+            if self.chiller_mode == 0:
+                weighted_water_temp['weighted_water_temp'] = station_data["chilledWaterMainTempIn"]
+            elif self.chiller_mode == 1:
+                weighted_water_temp['weighted_water_temp'] = station_data["coolingWaterMainTempIn"]
+            else:
+                ValueError('chiller mode input error!')
+        else:
+            weighted_water_temp = pd.DataFrame(columns=['weighted_water_temp', 'init_water_temp'])
+        return weighted_water_temp
+
+    def cal_weighted_water_temp(self, chiller_data, chiller_id_list):
+        """计算加权水温"""
+        water_temp_control_mode_index = []
+        # water_temp_set_initial_index, water_temp_in_set_initial_index = [], []
+        if self.chiller_mode == 0:
+            for chiller_id in chiller_id_list:
+                water_temp_control_mode_index.append((chiller_id, 'waterTempControlMode'))
+                # water_temp_set_initial_index.append((chiller_id, 'chillerWaterTempSetInitial'))
+                # water_temp_in_set_initial_index.append((chiller_id, 'chillerWaterTempInSetInitial'))
+        elif self.chiller_mode == 1:
+            for chiller_id in chiller_id_list:
+                water_temp_control_mode_index.append((chiller_id, 'waterTempControlMode'))
+                # water_temp_set_initial_index.append((chiller_id, 'heatingWaterTempSetInitial'))
+                # water_temp_in_set_initial_index.append((chiller_id, 'heatingWaterTempInSetInitial'))
+                #################制热的水温和之前表示不大一样,到底是热水还是冷却水?后期保持一致#########################
+        else:
+            ValueError('chiller mode input error!')
+
+        # 筛选出相同水温控制模式、相同初始出水温度设定值和相同初始进水温度设定值的数据集,同一时间戳下各冷机的对应参数唯一则代表相同
+        chiller_data = chiller_data[chiller_data[water_temp_control_mode_index].nunique(axis=1) == 1]
+        # chiller_data = chiller_data[chiller_data[water_temp_set_initial_index].nunique(axis=1) == 1]#这里好像无必要
+        # chiller_data = chiller_data[chiller_data[water_temp_in_set_initial_index].nunique(axis=1) == 1]#这里好像无必要
+        chiller_data_lwtcm = chiller_data[chiller_data[water_temp_control_mode_index[0]] == 0]  # 控制模式为供水
+        chiller_data_rwtcm = chiller_data[chiller_data[water_temp_control_mode_index[0]] == 1]  # 控制模式为回水
+        is_cal = 0 if chiller_data.empty else 1
+
+        if is_cal:
+            weighted_water_temp_lwtcm = pd.DataFrame(columns=['weighted_water_temp', 'init_water_temp'])
+            weighted_water_temp_rwtcm = pd.DataFrame(columns=['weighted_water_temp', 'init_water_temp'])
+
+            if not chiller_data_lwtcm.empty:
+                chiller_data_lwtcm['denominator'], chiller_data_lwtcm['numerator'] = 0.01, 0
+                for chiller_id in chiller_id_list:
+                    chiller_data_lwtcm['denominator'] += chiller_data_lwtcm[(chiller_id, 'chillerPowerRatio')] * \
+                                                         chiller_data_lwtcm[(chiller_id, 'capacityRated')].astype("float")
+                    if self.chiller_mode == 0:
+                        chiller_data_lwtcm['numerator'] += chiller_data_lwtcm[(chiller_id, 'chillerWaterTempOut')] * \
+                                                           chiller_data_lwtcm[(chiller_id, 'chillerPowerRatio')] * \
+                                                           chiller_data_lwtcm[(chiller_id, 'capacityRated')].astype("float")
+                    elif self.chiller_mode == 1:
+                        chiller_data_lwtcm['numerator'] += chiller_data_lwtcm[(chiller_id, 'heatingWaterTempOut')] * \
+                                                           chiller_data_lwtcm[(chiller_id, 'chillerPowerRatio')] * \
+                                                           chiller_data_lwtcm[(chiller_id, 'capacityRated')].astype("float")
+                    else:
+                        ValueError('chiller mode input error!')
+                weighted_water_temp_lwtcm['weighted_water_temp'] = \
+                    round(chiller_data_lwtcm['numerator'] / chiller_data_lwtcm['denominator'], 2)
+                # weighted_water_temp_lwtcm['init_water_temp'] = chiller_data_lwtcm[water_temp_set_initial_index[0]]
+                weighted_water_temp_lwtcm['init_water_temp'] = self.config['chillerWaterTempSetInitial']
+
+            if not chiller_data_rwtcm.empty:
+                chiller_data_rwtcm['denominator'], chiller_data_rwtcm['numerator'] = 0.01, 0
+                for chiller_id in chiller_id_list:
+                    chiller_data_rwtcm['denominator'] += chiller_data_rwtcm[(chiller_id, 'chillerPowerRatio')] * \
+                                                         chiller_data_rwtcm[(chiller_id, 'capacityRated')].astype("float")
+                    if self.chiller_mode == 0:
+                        chiller_data_rwtcm['numerator'] += chiller_data_rwtcm[(chiller_id, 'chillerWaterTempIn')] * \
+                                                           chiller_data_rwtcm[(chiller_id, 'chillerPowerRatio')] * \
+                                                           chiller_data_rwtcm[(chiller_id, 'capacityRated')].astype("float")
+                    elif self.chiller_mode == 1:
+                        chiller_data_rwtcm['numerator'] += chiller_data_rwtcm[(chiller_id, 'heatingWaterTempIn')] * \
+                                                           chiller_data_rwtcm[(chiller_id, 'chillerPowerRatio')] * \
+                                                           chiller_data_rwtcm[(chiller_id, 'capacityRated')].astype("float")
+                    else:
+                        ValueError('chiller mode input error!')
+                weighted_water_temp_rwtcm['weighted_water_temp'] = \
+                    round(chiller_data_rwtcm['numerator'] / chiller_data_rwtcm['denominator'], 2)
+                # weighted_water_temp_rwtcm['init_water_temp'] = chiller_data_rwtcm[water_temp_in_set_initial_index[0]]
+                weighted_water_temp_rwtcm['init_water_temp'] = self.config['chillerWaterTempInSetInitial']
+
+            weighted_water_temp = pd.concat([weighted_water_temp_lwtcm, weighted_water_temp_rwtcm])
+            weighted_water_temp = weighted_water_temp.sort_index(axis=0)
+        else:
+            weighted_water_temp = pd.DataFrame(columns=['weighted_water_temp', 'init_water_temp'])
+        return weighted_water_temp
+
+    def modify_air_temp_humi(self, sensor_id_list, sensor_data, water_temp):
+        threshold = ModifyTempHumiPara['threshold']  # 修正阈值
+        quantile = ModifyTempHumiPara['quantile']    # 修正分位数
+        modified_air_temp_dic = {}
+        modified_air_humi_dic = {}
+
+        water_temp = water_temp[water_temp['weighted_water_temp'] != 0]
+        column_names = sensor_data.columns.tolist()  # [(id, 参数名),(id, 参数名), ...]   # sensor_data
+        for sensor_id in sensor_id_list:
+            # su_sensor_id = config[config['returnAirMeterId'] == re_sensor_id].iloc[0]['supplyAirMeterId']
+            # if ((re_sensor_id, 'temperature') in column_names) and ((su_sensor_id, 'temperature') in column_names):
+            index_df = self.data_excess[self.data_excess['ahuMeterId'] == sensor_id].index.tolist()[0]
+            if ((sensor_id, 'tempReal') in column_names) :
+                # AHU_start = sensor_data[abs(sensor_data[(sensor_id, 'tempReal')] -
+                #                             sensor_data[(sensor_id, 'tempSupply')]) > 2.0]  # 筛选出开启的监测点
+                AHU_start = sensor_data[sensor_data[(sensor_id, 'status')] == 1]  # 筛选出开启的监测点
+                dataset = pd.concat([AHU_start[(sensor_id, 'tempReal')], AHU_start[(sensor_id, 'humiReal')],
+                                     water_temp['weighted_water_temp'], water_temp['init_water_temp']], sort=False,
+                                    keys=['temp', 'humi', 'weighted_water_temp', 'init_water_temp'], axis=1)
+                dataset = dataset.dropna()
+                if self.chiller_mode == 0:
+                    upper_temp_limit = self.data_excess.loc[index_df, 'coolingTempUpper']
+                    upper_humi_limit = self.data_excess.loc[index_df, 'coolingHumiUpper']
+
+                    dataset = dataset[dataset['weighted_water_temp'] <= dataset['init_water_temp'] + 0.5]
+                    # 这里没有考虑其他两种步长的场景,如果要是考虑的话如何考虑呢,如站内冷机的步长不同的情况下
+                    dataset_temp = dataset[dataset['temp'] >= upper_temp_limit]
+                    dataset_humi = dataset[dataset['humi'] >= upper_humi_limit]
+
+                    if len(dataset_temp) > self.sampling_nums:
+                        temp_series = dataset_temp.quantile(q=quantile)
+                        modified_temp_limit = round(temp_series['temp'], 3) + threshold
+                    else:
+                        modified_temp_limit = upper_temp_limit
+                    if len(dataset_humi) > self.sampling_nums:
+                        humi_series = dataset_humi.quantile(q=quantile)
+                        modified_humi_limit = min(round(humi_series['humi'], 3) + 10 * threshold, 100)
+                    else:
+                        modified_humi_limit = upper_humi_limit
+                elif self.chiller_mode == 1:
+                    # lower_temp_limit = config[config['returnAirMeterId'] == re_sensor_id].iloc[0]['heatingTempDown']
+                    # lower_temp_limit = sensor_data[(sensor_id, 'heatingTempDown')].iloc[0]
+                    lower_temp_limit = self.data_excess.loc[index_df, 'heatingTempDown']
+
+                    dataset = dataset[dataset['weighted_water_temp'] >= dataset['init_water_temp'] - 0.5]
+                    # 这里没有考虑其他两种步长的场景,如果要是考虑的话如何考虑呢,如站内冷机的步长不同的情况下
+                    dataset_temp = dataset[dataset['temp'] <= lower_temp_limit]
+
+                    if len(dataset_temp) > self.sampling_nums:
+                        temp_series = dataset_temp.quantile(q=1-quantile)
+                        modified_temp_limit = round(temp_series['temp'], 3) - threshold
+                    else:
+                        modified_temp_limit = lower_temp_limit
+                    modified_humi_limit = ''
+                else:
+                    raise ValueError('chiller mode input error!')
+                modified_air_temp_dic[sensor_id] = modified_temp_limit
+                modified_air_humi_dic[sensor_id] = modified_humi_limit
+        return modified_air_temp_dic, modified_air_humi_dic
+
+    def get_modified_air_temp_humi(self):
+        logger.critical("============温湿度超标点限值修正模块中关键参数:runMode:%s,threshold:%s,quantile:%s============" %
+                         (self.config['runMode'], ModifyTempHumiPara['threshold'], ModifyTempHumiPara['quantile']))
+        sensor_data_df, chiller_water_temp_df = self.transform_dict_to_dataformat(self.modify['stationData'],
+                                                                                  self.modify['terminalData'],
+                                                                                  self.modify['chillerData'])
+        excess_sensor_id = list(self.data_excess['ahuMeterId'])       # 超标监测点数据的id列表
+
+        modified_air_temp, modified_air_humi = self.modify_air_temp_humi(excess_sensor_id, sensor_data_df,
+                                                                         chiller_water_temp_df)
+        # re_sensor_id_list = station_data['config']['returnAirMeterId']  # 这里应该是所有监测点的数据
+        modified_meter_id = list(modified_air_temp.keys())    # 有修正的监测点Id列表
+
+        for sensor in excess_sensor_id:
+            if sensor in modified_meter_id:
+                index_df = self.data_excess[self.data_excess['ahuMeterId'] == sensor].index.tolist()[0]
+                if self.chiller_mode == 0:
+                    self.data_excess.loc[index_df, 'coolingTempUpper'] = modified_air_temp[sensor]
+                    self.data_excess.loc[index_df, 'coolingHumiUpper'] = modified_air_humi[sensor]
+                elif self.chiller_mode == 1:
+                    self.data_excess.loc[index_df, 'heatingTempDown'] = modified_air_temp[sensor]
+                else:
+                    raise ValueError('chiller mode input error!')
+        return self.data_excess
+
+
+# if __name__ == '__main__':
+#     data_temp_humi = pd.DataFrame({
+#         "ahuMeterId": ["3000638", "3000694", "3000654"],
+#         "terminalName": ["监测点A", "监测点B", "监测点C"],
+#         "coolingTempUpper": [25.0, 26.0, 24],
+#         "coolingHumiUpper": [60.0, 65.0, 65],
+#         "heatingTempDown": [18.0, 17.5, 18],
+#         "tempReal": [24.5, 25.3, 25],
+#         "humiReal": [50, 50, 50],
+#      })
+#
+#     station_data_ = {"chilledWaterMainTempOut": [7, 7, 7],
+#                      'dateTime': ["2025-4-3 12:00:00", "2025-4-4 12:00:00", "2025-4-5 12:00:00"]}
+#     sensor_data_ = {
+#         "3000638": {"name": "sensor1", "tempReal": [10, 20, 30], "humiReal": [10, 20, 30], "tempSupply": [1, 2, 3]},
+#         "3000694": {"name": "sensor2", "tempReal": [10, 20, 30], "humiReal": [10, 20, 30], "tempSupply": [1, 2, 3]},
+#         "3000654": {"name": "sensor3", "tempReal": [10, 20, 30], "humiReal": [10, 20, 30], "tempSupply": [1, 2, 3]}}
+#     # 冷机的历史7天数据
+#     chiller_data_ = {"301": {"name": 1, "loadRate": [20, 20, 30], "chillerPowerRatio": [50, 50, 50],
+#                             "chillerWaterTempOut": [7, 7, 7],
+#                             'waterTempControlMode': 0, 'capacityRated': 10},
+#                     "302": {"name": 1, "loadRate": [10, 20, 30], "chillerPowerRatio": [50, 50, 50],
+#                             "chillerWaterTempOut": [7, 7, 7],
+#                             'waterTempControlMode': 0, 'capacityRated': 10}}
+#     modify_data = {'terminalData': sensor_data_, 'chillerData': chiller_data_, 'stationData': station_data_}
+#     config_info = {"handleService": 1, "controlMode": 1, "isHardwareControl": 1, "calPeriod": 3,
+#                            "minControlStep": 0.1, "chillerWaterTempSetInitial": 7, "chillerWaterTempSetUpper": 12,
+#                            "chillerWaterTempSetLower": 7, "energyMode": 1, "controlBasis": 0, "tempMargin": 0.2,
+#                            "humiMargin": 2, "mainTempMode": 0, "samplePeriod": 60, "upTempControlPeriod": 10,
+#                            "downTempControlPeriod": 12, 'runMode': 0, 'allChillerControlSelect': [0, 0, 0]}
+#     etm = ExcessTempModify(data_temp_humi, config_info, modify_data)
+#     data = etm.get_modified_air_temp_humi()
+#     print(data)
+
+

+ 24 - 0
temp_humid_cal/interval_start_stop_AHU.py

@@ -0,0 +1,24 @@
+import pandas as pd
+from data_initialize_standard.constant import *
+
+class IntervalOnOffAHU(object):
+    def __init__(self, data_temp_humi, dict_code):
+        self.data_terminal = data_temp_humi
+        self.dict_code = dict_code
+
+    def exclude_ahu_short_time(self):
+        self.data_terminal['ahuStartTime'] = pd.to_datetime(self.data_terminal['ahuStartTime'])
+        self.dict_code['triggerTime'] = pd.to_datetime(self.dict_code['triggerTime'])
+        self.data_terminal['middle_value_time'] = self.dict_code['triggerTime'] - self.data_terminal['ahuStartTime']
+        self.data_terminal['ahuStartTimeDiff'] = self.data_terminal.apply(lambda x: x['middle_value_time'].total_seconds(), axis=1)
+        """
+        # 当末端未超标时,即使末端开启时间未满足设定值,水温仍调控;当末端超标时,则需要严格依据末端开启时间设定值来调控水温
+        # 若冷机开机时间满足设定值才调控,则对于末端未超标且频繁开关的工况会导致冷机水温不调控;末端未超标且无频繁开关的工况仍需长时间等待才调控
+        # 备注:无论制冷还是制热,self.data_terminal['deltaTemp'] > 0均表明末端未超标
+        """
+        self.data_terminal = self.data_terminal[(self.data_terminal['tempReal'] > TerminalTempRange['lowerLimit']) &
+                            (self.data_terminal['tempReal'] < TerminalTempRange['upperLimit'])]
+        self.data_terminal = self.data_terminal[(self.data_terminal['deltaTemp'] > 0) |
+                                                    ((self.data_terminal['ahuStartTimeDiff']) > 3600)]
+        self.data_terminal = self.data_terminal.reset_index(drop=True)
+        return self.data_terminal

+ 245 - 0
temp_humid_cal/temp_humi_calculation.py

@@ -0,0 +1,245 @@
+from CoolProp.HumidAirProp import HAPropsSI
+from temp_humid_cal.excess_temp_modify import ExcessTempModify
+from temp_humid_cal.interval_start_stop_AHU import IntervalOnOffAHU
+from data_initialize_standard.constant import *
+# from logs_conf.logger import *
+from logs.logger import *
+import pandas as pd
+import time
+
+
+class TempHumiFunction(object):
+    def __init__(self, terminal_data, code_data, chiller_outer):
+        self.data = terminal_data
+        self.config = code_data
+        # self.modify = modify_data
+        self.chiller_outer = chiller_outer
+        self.chiller_mode = code_data['runMode']
+
+    def terminal_limit_cal(self, data):
+        """
+        监测点的限值计算
+        :param data:
+        :param dict_code:
+        :return:
+        """
+        if self.chiller_mode == 0:
+            data['tempLimit'] = data['coolingTempUpper'] - self.config['tempMargin']
+            data['humiLimit'] = data['coolingHumiUpper'] - self.config['humiMargin']
+        elif self.chiller_mode == 1:
+            data['tempLimit'] = data['heatingTempDown'] + self.config['tempMargin']
+        else:
+            logger.critical("============冷机运行模式输入错误============")
+        return data
+
+    def delta_temp_humi(self, data):
+        if self.chiller_mode == 0:
+            data['deltaTemp'] = data['tempLimit'] - data['tempReal']
+            data['deltaHumi'] = data['humiLimit'] - data['humiReal']
+        elif self.chiller_mode == 1:
+            data['deltaTemp'] = data['tempReal'] - data['tempLimit']
+            data['deltaHumi'] = None
+        else:
+            logger.critical("============冷机运行模式输入错误============")
+        return data
+
+    def delta_dew_point(self, data):
+        normal_condition = (data['tempReal'] <= TerminalTempRange['upperLimit']) & (data['tempReal'] > TerminalTempRange['lowerLimit']) & \
+                           (data['humiReal'] <= TerminalHumiRange['upperLimit']) & (data['humiReal'] > TerminalHumiRange['lowerLimit'])
+        data_normal = data[normal_condition]   # 筛选出温度和湿度范围在正常区间的数据,避免异常数据(如空值或极大值)调物性时出错
+        data_abnormal = data.drop(data_normal.index)
+
+        if self.chiller_mode == 0 and not data_normal.empty:
+            data_normal.loc[:, ['dewTempReal']] = round(data_normal.apply(
+                lambda x: HAPropsSI('D', 'T', x['tempReal'] + 273.15, 'P', 101325, 'R', x['humiReal'] / 100.0),
+                axis=1) - 273.15, 1)
+            data_normal.loc[:, ['dewTempLimit']] = round(data_normal.apply(
+                lambda x: HAPropsSI('D', 'T', x['tempLimit'] + 273.15, 'P', 101325, 'R', x['humiLimit'] / 100.0),
+                axis=1) - 273.15, 1)
+            data_normal.loc[:, ['deltaDewPoint']] = data_normal['dewTempLimit'] - data_normal['dewTempReal']
+        if not data_abnormal.empty:
+            data_abnormal['dewTempReal'] = None
+            data_abnormal['dewTempLimit'] = None
+            data_abnormal['deltaDewPoint'] = None
+        data = pd.concat([data_normal, data_abnormal])
+        return data
+
+    def excess_modify(self, terminal_data):
+        data = self.delta_temp_humi(terminal_data)
+        excess_condition = (data['deltaTemp'] < 0) | (data['deltaHumi'] < 0)  # 温度或湿度超限的判断条件
+        terminal_excess = data[excess_condition]    # 温度或湿度超限的监测点
+        terminal_remain = data[~excess_condition]   # 未超限的监测点
+        if not terminal_excess.empty:
+            logger.critical("============存在监测点超限情况,开始温湿度限值修正计算============")
+            etm = ExcessTempModify(terminal_excess, self.config, self.chiller_outer)  # terminal_excess 超标的监测点数据
+            if etm.data_judge():
+                logger.critical("============监测点修正相关数据正常,进入修正计算============")
+                Time1 = time.time()
+                terminal_excess = etm.get_modified_air_temp_humi()  # 温湿度计算
+                Time2 = time.time()
+                logger.critical("============温湿度超标点限值修正计算耗时: {}s ============".format(Time2 - Time1))
+            else:
+                logger.critical("============监测点修正相关数据异常,退出温湿度限值修正计算============")
+        else:
+            logger.critical("============不存在温度或湿度超限情况,温湿度上下限不修正============")
+        data = pd.concat([terminal_excess, terminal_remain])
+        return data
+
+    def average_temp_humi(self, data_temp_humi):
+        temp_mean = data_temp_humi["tempReal"].mean()
+        humi_mean = data_temp_humi["humiReal"].mean()
+        data_mean = {"tempHumiMeterId": "average", "terminalName": "average", "coolingTempUpper": 25,
+                     "coolingHumiUpper": 60, "heatingTempDown": 29}   # 这里的上下限值实际取平均限值配置值,当前不适配写死
+        if self.chiller_mode == 0:
+            data_mean['tempLimit'] = data_mean['coolingTempUpper'] - self.config['tempMargin']
+            data_mean['humiLimit'] = data_mean['coolingHumiUpper'] - self.config['humiMargin']
+            data_mean['deltaTemp'] = data_mean['tempLimit'] - temp_mean
+            data_mean['deltaHumi'] = data_mean['humiLimit'] - humi_mean
+        elif self.chiller_mode == 1:
+            data_mean['tempLimit'] = data_mean['heatingTempDown'] + self.config['tempMargin']
+            data_mean['deltaTemp'] = data_mean['tempReal'] - data_mean['tempLimit']
+            data_mean['deltaHumi'] = None
+        else:
+            logger.critical("============冷机运行模式输入错误============")
+        data_mean_df = pd.DataFrame([data_mean])
+        if self.config['calMode'] == 1:
+            data = data_mean_df
+        else:
+            data = pd.concat([data_temp_humi, data_mean_df])
+        return data
+
+    def temp_humi_cal(self):
+        data_temp_humi = self.terminal_limit_cal(self.data)     # 确定监测点的上下限值
+        if self.config['calMode'] == 0 or self.config['calMode'] == 2:  # 监测点计算模式为常规或者综合
+            if self.config['energyMode'] == 0:   # 0为智能节能模式,1为需求优先模式
+                logger.critical("============智控模式为智能节能模式,进入温湿度上下限修正计算============")
+                data_temp_humi = self.excess_modify(data_temp_humi)
+            else:
+                logger.critical("============智控模式为需求优先模式,温湿度上下限不修正============")
+        data_temp_humi = self.delta_temp_humi(data_temp_humi)
+        data_temp_humi = self.delta_dew_point(data_temp_humi)
+        ioa = IntervalOnOffAHU(data_temp_humi, self.config)
+        data_temp_humi = ioa.exclude_ahu_short_time()
+        if self.config['calMode'] == 1 or self.config['calMode'] == 2:  # 监测点计算模式为仅平均温湿度或者综合
+            logger.critical("============监测点计算模式为仅平均温湿度或综合模式,进入平均温湿度计算============")
+            data_temp_humi = self.average_temp_humi(data_temp_humi)
+        return data_temp_humi
+
+
+class JudgeOutRange(object):
+    def __init__(self, data_temp_humi, dict_code):
+        self.data = data_temp_humi
+        self.config = dict_code
+        self.chiller_mode = dict_code['runMode']
+
+    def is_out_of_range(self):
+        """制冷模式根据 控制依据 配置项判断 温度、露点或湿度是否超标,制热模式下只判断温度是否超标"""
+        results = {'isOutRange': '', 'minDelta': '', 'minName': ''}  # 分别代表是否超标,最不利监测点对应值,最不利监测点名称
+        if self.chiller_mode == 0 and self.config['controlBasis'] == 0:  # 制冷模式,控制依据,0为仅温度,1为仅湿度,2为温度和湿度
+            if self.data['deltaTemp'].min() < 0:
+                results['isOutRange'] = 1   # 1表示温度超标
+                results['minName'] = self.data.loc[self.data['deltaTemp'].idxmin(), 'ahuName']
+                logger.critical("============监测点超标情况:温度超标,最不利监测点是 %s============" % (results['minName']))
+            elif self.data['deltaDewPoint'].min() < 0:
+                results['isOutRange'] = 2   # 2表示露点超标
+                results['minName'] = self.data.loc[self.data['deltaDewPoint'].idxmin(), 'ahuName']
+                logger.critical("============监测点超标情况:露点超标,最不利监测点是 %s============" % (results['minName']))
+            else:
+                if (self.data['deltaTemp'].min() is None) or pd.isna(self.data['deltaTemp'].min()):
+                    logger.critical("============监测点超标情况:监测点输入数据异常============")
+                else:
+                    results['isOutRange'] = 0  # 0表示不超标
+                    results['minName'] = self.data.loc[self.data['deltaTemp'].idxmin(), 'ahuName']
+                    logger.critical("============监测点超标情况:无超标情况,最不利监测点是 %s============" % (results['minName']))
+        elif self.chiller_mode == 0 and self.config['controlBasis'] == 1:
+            if self.data['deltaHumi'].min() < 0:
+                results['isOutRange'] = 3   # 3表示湿度超标
+                results['minName'] = self.data.loc[self.data['deltaHumi'].idxmin(), 'ahuName']
+                logger.critical("============监测点超标情况:湿度超标,最不利监测点是 %s============" % (results['minName']))
+            else:
+                if (self.data['deltaHumi'].min() is None) or pd.isna(self.data['deltaHumi'].min()):
+                    logger.critical("============监测点超标情况:监测点输入数据异常============")
+                else:
+                    results['isOutRange'] = 0  # 0表示不超标
+                    results['minName'] = self.data.loc[self.data['deltaHumi'].idxmin(), 'ahuName']
+                    logger.critical("============监测点超标情况:无超标情况,最不利监测点是 %s============" % (results['minName']))
+        elif self.chiller_mode == 0 and self.config['controlBasis'] == 2:
+            if self.data['deltaTemp'].min() < 0:
+                results['isOutRange'] = 1   # 1表示温度超标
+                results['minName'] = self.data.loc[self.data['deltaTemp'].idxmin(), 'ahuName']
+                logger.critical("============监测点超标情况:温度超标,最不利监测点是 %s============" % (results['minName']))
+            elif self.data['deltaHumi'].min() < 0:
+                results['isOutRange'] = 3   # 3表示湿度超标
+                results['minName'] = self.data.loc[self.data['deltaHumi'].idxmin(), 'ahuName']
+                logger.critical("============监测点超标情况:湿度超标,最不利监测点是 %s============" % (results['minName']))
+            else:
+                if (self.data['deltaTemp'].min() is None) or pd.isna(self.data['deltaTemp'].min() is None):
+                    logger.critical("============监测点超标情况:监测点输入数据异常============")
+                else:
+                    results['isOutRange'] = 0  # 0表示不超标
+                    results['minName'] = self.data.loc[self.data['deltaTemp'].idxmin(), 'ahuName']
+                    logger.critical("============监测点超标情况:无超标情况,最不利监测点是 %s============" % (results['minName']))
+        elif self.chiller_mode == 1:
+            if self.data['deltaTemp'].min() < 0:
+                results['isOutRange'] = 1  # 1表示超标, 0表示不超标
+                results['minName'] = self.data.loc[self.data['deltaTemp'].idxmin(), 'ahuName']
+                logger.critical("============监测点超标情况:温度超标,最不利监测点是 %s============" % (results['minName']))
+            else:
+                if (self.data['deltaTemp'].min() is None) or pd.isna(self.data['deltaTemp'].min()):
+                    logger.critical("============监测点超标情况:监测点输入数据异常============")
+                else:
+                    results['isOutRange'] = 0
+                    results['minName'] = self.data.loc[self.data['deltaTemp'].idxmin(), 'ahuName']
+                    logger.critical("============监测点超标情况:温度超标,最不利监测点是 %s============" % (results['minName']))
+        else:
+            logger.critical("============冷机运行模式输入错误============")
+        return results
+
+
+# if __name__ == '__main__':
+#
+#     # 监测点的实时数据
+#     data_df_cal = pd.DataFrame({
+#         "tempHumiMeterId": ["3000638", "3000694", "3000691", "3000692", "3000693"],
+#         "terminalName": ["监测点A", "监测点B", "监测点C", "监测点D", "监测点E"],
+#         'ahuStartTime': ["2025-4-10 23:00:00", "2025-4-10 23:00:00", "2025-4-10 23:00:00",
+#                          "2025-4-10 23:00:00", "2025-4-10 23:00:00"],
+#         "coolingTempUpper": [25.0, 26.0, 25, 25, 25],
+#         "coolingHumiUpper": [60.0, 65.0, 65, 65, 65],
+#         "heatingTempDown": [18.0, 17.5, 24, 24, 26],
+#         # "tempReal": [None, None, None, None, None],
+#         "tempReal": [24.5, 25.3, 24, 20, 20],
+#         "humiReal": [50, 50, 50, 50, 50],
+#         # "humiReal": [None, None, None, None, None],
+#      })
+#
+#     station_data_ = {"chilledWaterMainTempOut": [7, 7, 7],
+#                      'timeIndex': ["2025-4-3 12:00:00", "2025-4-4 12:00:00", "2025-4-5 12:00:00"]}
+#
+#     sensor_data_ = {
+#         "3000638": {"name": "sensor1", "tempReal": [10, 20, 30], "humiReal": [10, 20, 30], "tempSupply": [1, 2, 3]},
+#         "3000694": {"name": "sensor2", "tempReal": [10, 20, 30], "humiReal": [10, 20, 30], "tempSupply": [1, 2, 3]},
+#         "3000654": {"name": "sensor3", "tempReal": [10, 20, 30], "humiReal": [10, 20, 30], "tempSupply": [1, 2, 3]}}
+#     # 冷机的历史7天数据
+#     chiller_data_ = {"301": {"name": 1, "currentPercent": [20, 20, 30], "chillerPowerRatio": [50, 50, 50],
+#                              "chillerWaterTempOut": [7, 7, 7], "set": [7, 7, 7],
+#                              'waterTempControlMode': 0, 'chillerWaterTempSetInitial': 7, 'capacity': 10},
+#                      "302": {"name": 1, "currentPercent": [10, 20, 30], "chillerPowerRatio": [50, 50, 50],
+#                              "chillerWaterTempOut": [7, 7, 7], "set": [7, 7, 7],
+#                              'waterTempControlMode': 0, 'chillerWaterTempSetInitial': 7, 'capacity': 10}}
+#     modify_data = {'terminalData': sensor_data_, 'chillerData': chiller_data_, 'stationData': station_data_}
+#     config_info = {"handleService": 1, "controlMode": 1, "isHardwareControl": 1, "calPeriod": 3,
+#                    "minControlStep": 0.1, "chillerWaterTempSetInitial": 7, "chillerWaterTempSetUpper": 12,
+#                    "chillerWaterTempSetLower": 7, "energyMode": 1, "controlBasis": 0, "tempMargin": 0.2,
+#                    "humiMargin": 2, "mainTempMode": 0, "samplePeriod": 60, "upTempControlPeriod": 10,
+#                    "downTempControlPeriod": 12, 'runMode': 0, 'calMode': 0, 'allChillerControlSelect': [0, 0, 0],
+#                    'triggerTime': "2025-4-5 12:00:00"}
+#     thf = TempHumiFunction(data_df_cal, config_info, modify_data)           # 监测点实时数据,冷站数据
+#     data = thf.temp_humi_cal()   # 监测点历史数据,冷机历史数据
+#     pd.set_option('display.max_rows', None)
+#     pd.set_option('display.max_columns', None)
+#
+#     judge = JudgeOutRange(data, config_info)
+#     result = judge.is_out_of_range()
+
+

+ 143 - 0
water_temp_cal/water_temp_set_switch.py

@@ -0,0 +1,143 @@
+# from logs_conf.logger import *
+from logs.logger import *
+from optimized_and_individal.temperature_step_size_10 import ModifyLeavingWaterTempSetTSS10, ModifyReturningWaterTempSetTSS10
+from optimized_and_individal.temperature_step_size_05 import ModifyLeavingWaterTempSetTSS05, ModifyReturningWaterTempSetTSS05
+
+
+class WaterTempSetVerify(object):
+    def __init__(self, water_temp_set_new, dict_chiller_inner):
+        self.water_temp_set_new = water_temp_set_new
+        self.dict_chiller_inner = dict_chiller_inner
+        # self.dict_chiller_outer = dict_chiller_outer
+
+    def modify(self):
+        if self.dict_chiller_inner['chillerTempStep'] == 0.1:
+            result = self.water_temp_set_new
+            # logger.critical('============低工况验证============')
+        elif self.dict_chiller_inner['chillerTempStep'] == 0.5:
+            if self.dict_chiller_inner['waterTempControlMode'] == 0:
+                mlwts_tss05 = ModifyLeavingWaterTempSetTSS05(self.water_temp_set_new, self.dict_chiller_inner)
+                result = mlwts_tss05.modify_temp()
+            elif self.dict_chiller_inner['waterTempControlMode'] == 1:
+                mrwts_tss05 = ModifyReturningWaterTempSetTSS05(self.water_temp_set_new, self.dict_chiller_inner)
+                result = mrwts_tss05.modify_temp()
+            else:
+                result = ''
+                logger.critical('============冷机控制选择输入错误============')
+        elif self.dict_chiller_inner['chillerTempStep'] == 1:
+            if self.dict_chiller_inner['waterTempControlMode'] == 0:
+                mlwts_tss10 = ModifyLeavingWaterTempSetTSS10(self.water_temp_set_new, self.dict_chiller_inner)
+                result = mlwts_tss10.modify_temp()
+            elif self.dict_chiller_inner['waterTempControlMode'] == 1:
+                mrwts_tss10 = ModifyReturningWaterTempSetTSS10(self.water_temp_set_new, self.dict_chiller_inner)
+                result = mrwts_tss10.modify_temp()
+            else:
+                result = ''
+                logger.critical('============冷机控制选择输入错误============')
+        else:
+            result = ''
+            logger.critical('============冷机配置参数输入错误============')
+        return result
+
+    def limit_verify(self):
+        if self.dict_chiller_inner['runMode'] == 0:
+            if self.dict_chiller_inner['waterTempControlMode'] == 0:
+                if self.water_temp_set_new > self.dict_chiller_inner['chillerWaterTempSetUpper']:
+                    self.water_temp_set_new = self.dict_chiller_inner['chillerWaterTempSetUpper']
+                elif self.water_temp_set_new < self.dict_chiller_inner['chillerWaterTempSetDown']:
+                    self.water_temp_set_new = self.dict_chiller_inner['chillerWaterTempSetDown']
+                else:
+                    self.water_temp_set_new = self.water_temp_set_new
+            elif self.dict_chiller_inner['waterTempControlMode'] == 1:
+                if self.water_temp_set_new > self.dict_chiller_inner['chillerWaterTempInSetUpper']:
+                    self.water_temp_set_new = self.dict_chiller_inner['chillerWaterTempInSetUpper']
+                elif self.water_temp_set_new < self.dict_chiller_inner['chillerWaterTempInSetDown']:
+                    self.water_temp_set_new = self.dict_chiller_inner['chillerWaterTempInSetDown']
+                else:
+                    self.water_temp_set_new = self.water_temp_set_new
+            else:
+                self.water_temp_set_new = ''
+                logger.critical('============冷机控制选择输入错误============')
+        elif self.dict_chiller_inner['runMode'] == 1:
+            if self.dict_chiller_inner['waterTempControlMode'] == 0:
+                if self.water_temp_set_new > self.dict_chiller_inner['heatingWaterTempSetUpper']:
+                    self.water_temp_set_new = self.dict_chiller_inner['heatingWaterTempSetUpper']
+                elif self.water_temp_set_new < self.dict_chiller_inner['heatingWaterTempSetDown']:
+                    self.water_temp_set_new = self.dict_chiller_inner['heatingWaterTempSetDown']
+                else:
+                    self.water_temp_set_new = self.water_temp_set_new
+            elif self.dict_chiller_inner['waterTempControlMode'] == 1:
+                if self.water_temp_set_new > self.dict_chiller_inner['heatingWaterTempInSetUpper']:
+                    self.water_temp_set_new = self.dict_chiller_inner['heatingWaterTempInSetUpper']
+                elif self.water_temp_set_new < self.dict_chiller_inner['heatingWaterTempInSetDown']:
+                    self.water_temp_set_new = self.dict_chiller_inner['heatingWaterTempInSetDown']
+                else:
+                    self.water_temp_set_new = self.water_temp_set_new
+        else:
+            self.water_temp_set_new = ''
+            logger.critical('============冷机运行模式输入错误============')
+        return self.water_temp_set_new
+
+    def based_time_temp_range(self):
+        # 因水温的温度区间是分时设定的,避免因为不同时间段的限制导致制冷温度上升或制热温度下降
+        if self.dict_chiller_inner['runMode'] == 0:
+            if self.dict_chiller_inner['waterTempControlMode'] == 0 and \
+                    self.water_temp_set_new > self.dict_chiller_inner['chillerWaterTempSet']:
+                if self.water_temp_set_new - self.dict_chiller_inner['chillerWaterTempOut'][-1] > \
+                        0.75 * self.dict_chiller_inner['coolingShutdownOffset']:
+                    self.water_temp_set_new = self.dict_chiller_inner['chillerWaterTempOut'][-1] + \
+                                         0.75 * self.dict_chiller_inner['coolingShutdownOffset']
+            elif self.dict_chiller_inner['waterTempControlMode'] == 1 and \
+                    self.water_temp_set_new > self.dict_chiller_inner['chillerWaterTempInSet']:
+                if self.water_temp_set_new - self.dict_chiller_inner['chillerWaterTempIn'][-1] > \
+                        0.75 * self.dict_chiller_inner['coolingShutdownOffset']:
+                    self.water_temp_set_new = self.dict_chiller_inner['chillerWaterTempIn'][-1] + \
+                                         0.75 * self.dict_chiller_inner['coolingShutdownOffset']
+        elif self.dict_chiller_inner['runMode'] == 1:
+            if self.dict_chiller_inner['waterTempControlMode'] == 0 and \
+                    self.water_temp_set_new < self.dict_chiller_inner['heatingWaterTempSet']:
+                if self.dict_chiller_inner['heatingWaterTempOut'][-1] - self.water_temp_set_new > \
+                        0.75 * self.dict_chiller_inner['heatingShutdownOffset']:
+                    self.water_temp_set_new = self.dict_chiller_inner['heatingWaterTempOut'][-1] - \
+                                         0.75 * self.dict_chiller_inner['heatingShutdownOffset']
+            elif self.dict_chiller_inner['waterTempControlMode'] == 1 and \
+                    self.water_temp_set_new < self.dict_chiller_inner['heatingWaterTempInSet']:
+                if self.dict_chiller_inner['heatingWaterTempIn'][-1] - self.water_temp_set_new > \
+                        0.75 * self.dict_chiller_inner['heatingShutdownOffset']:
+                    self.water_temp_set_new = self.dict_chiller_inner['heatingWaterTempIn'][-1] - \
+                                         0.75 * self.dict_chiller_inner['heatingShutdownOffset']
+        else:
+            self.water_temp_set_new = ''
+            logger.critical('============冷机运行模式输入错误============')
+        return self.water_temp_set_new
+
+    # def switch(self):
+    #     """
+    #     根据品牌转换点表中温湿度,当前只有麦克韦尔为华氏摄氏度
+    #     :return:
+    #     """
+    #     if self.water_temp_set_new:
+    #         if self.dict_chiller_outer['chillerTempType'] == 0:  # 水温数据类型为整型
+    #             if self.dict_chiller_outer['chillerTempUnit'] == 1:  # 0表示为摄氏,1表示华氏
+    #                 results = self.water_temp_set_new * 1.8 + 32
+    #             else:
+    #                 results = self.water_temp_set_new
+    #             results = results * self.dict_chiller_outer['chillerTempScale']
+    #             results = int(round(results))
+    #         elif self.dict_chiller_outer['chillerTempType'] == 1:  # 水温数据类型为浮点型
+    #             results = self.water_temp_set_new
+    #         else:
+    #             results = ''
+    #             logger.critical('========冷机温度数据类型错误========')
+    #     else:
+    #         results = ''
+    #         logger.critical('========冷机温度设定值为空========')
+    #     return results
+
+    def modify_verify(self):
+        self.water_temp_set_new = self.modify()
+        self.water_temp_set_new = self.limit_verify()
+        self.water_temp_set_new = self.based_time_temp_range()
+        # water_temp_set_switched = self.switch()
+        return self.water_temp_set_new
+

+ 501 - 0
water_temp_cal/water_temp_setpoint_new.py

@@ -0,0 +1,501 @@
+import os
+import pandas as pd
+# from logs_conf.logger import *
+from logs.logger import *
+from data_initialize_standard.constant import *
+
+
+class SetPointStrategyOff(object):
+    """智控模式关闭状态下的水温设定值"""
+
+    def __init__(self, dict_chiller_inner, data_temp_humi):
+        # self.dict_code = dict_code
+        self.dict_chiller_inner = dict_chiller_inner
+        self.data_temp_humi = data_temp_humi
+
+    def chiller_off(self):
+        """冷机关机状态下,分制冷和制热模式,回水和进水控制四种情况,将初始设定值赋值"""
+        if self.dict_chiller_inner['runMode'] == 0:
+            if self.dict_chiller_inner['waterTempControlMode'] == 0:
+                water_temp_set_new = self.dict_chiller_inner['chillerWaterTempSetInitial']
+            elif self.dict_chiller_inner['waterTempControlMode'] == 1:
+                water_temp_set_new = self.dict_chiller_inner['chillerWaterTempInSetInitial']
+            else:
+                water_temp_set_new = ''
+                logger.critical('============冷机控制选择输入错误============')
+        elif self.dict_chiller_inner['runMode'] == 1:
+            if self.dict_chiller_inner['waterTempControlMode'] == 0:
+                water_temp_set_new = self.dict_chiller_inner['heatingWaterTempSetInitial']
+            elif self.dict_chiller_inner['waterTempControlMode'] == 1:
+                water_temp_set_new = self.dict_chiller_inner['heatingWaterTempInSetInitial']
+            else:
+                water_temp_set_new = ''
+                logger.critical('============冷机控制选择输入错误============')
+        else:
+            water_temp_set_new = ''
+            logger.critical('============冷机运行模式输入错误============')
+        return water_temp_set_new
+
+    def chiller_on(self):
+        """冷机开机状态下,分制冷和制热模式,回水和进水控制四种情况,通过对比当前设定值和初始设定值再赋值"""
+        if self.dict_chiller_inner['runMode'] == 0:
+            if self.dict_chiller_inner['waterTempControlMode'] == 0:
+                if self.dict_chiller_inner['chillerWaterTempSet'] < self.dict_chiller_inner['chillerWaterTempSetInitial']:
+                    water_temp_set_new = self.dict_chiller_inner['chillerWaterTempSet']
+                else:
+                    water_temp_set_new = self.dict_chiller_inner['chillerWaterTempSetInitial']
+            elif self.dict_chiller_inner['waterTempControlMode'] == 1:
+                if self.dict_chiller_inner['chillerWaterTempInSet'] < self.dict_chiller_inner['chillerWaterTempInSetInitial']:
+                    water_temp_set_new = self.dict_chiller_inner['chillerWaterTempInSet']
+                else:
+                    water_temp_set_new = self.dict_chiller_inner['chillerWaterTempInSetInitial']
+            else:
+                water_temp_set_new = ''
+                logger.critical('============冷机控制选择输入错误============')
+        elif self.dict_chiller_inner['runMode'] == 1:
+            if self.dict_chiller_inner['waterTempControlMode'] == 0:
+                if self.dict_chiller_inner['heatingWaterTempSet'] > self.dict_chiller_inner['heatingWaterTempSetInitial']:
+                    water_temp_set_new = self.dict_chiller_inner['heatingWaterTempSet']
+                else:
+                    water_temp_set_new = self.dict_chiller_inner['heatingWaterTempSetInitial']
+            else:
+                if self.dict_chiller_inner['heatingWaterTempInSet'] > self.dict_chiller_inner['heatingWaterTempInSetInitial']:
+                    water_temp_set_new = self.dict_chiller_inner['heatingWaterTempInSet']
+                else:
+                    water_temp_set_new = self.dict_chiller_inner['heatingWaterTempInSetInitial']
+        else:
+            water_temp_set_new = ''
+            logger.critical('============冷机运行模式输入错误============')
+        return water_temp_set_new
+
+    def self_control_strategy_off(self):
+        """判断冷机当前运行状态,进而赋值,主要是对于运行冷机有个恢复初始值的过程"""
+        if self.dict_chiller_inner['runStatus'][-1] == 0:
+            water_temp_set_new = self.chiller_off()
+        elif self.dict_chiller_inner['runStatus'][-1] == 1:
+            water_temp_set_new = self.chiller_on()
+        else:
+            water_temp_set_new = ''
+            logger.critical('============冷机运行状态输入错误============')
+        return water_temp_set_new
+
+
+class SetPointStrategyOnChillerOff(SetPointStrategyOff):
+    """冷机停机下水温设定值策略"""
+    def __init__(self, dict_chiller_inner, data_temp_humi):
+        super(SetPointStrategyOnChillerOff, self).__init__(dict_chiller_inner, data_temp_humi)
+
+    def judge_off_time(self):
+        """冷机已关机时长"""
+        off_time_latest = pd.to_datetime(self.dict_chiller_inner['chillerOffTimeLatest'])
+        date_time_now = pd.to_datetime(self.dict_chiller_inner['triggerTime'])
+        chiller_off_time = (date_time_now - off_time_latest).total_seconds()
+        if abs(chiller_off_time) < 5:
+            chiller_off_time = 0  # 终端设备时间和服务器设备时间之间小偏差修正
+        chiller_off_time = chiller_off_time / 3600.0
+        return chiller_off_time
+
+    def chiller_off_short_time(self):
+        """设定值赋值为最近一次关机时的设定值"""
+        if self.dict_chiller_inner['runMode'] == 0:
+            if self.dict_chiller_inner['waterTempControlMode'] == 0:
+                water_temp_set_new = self.dict_chiller_inner['offSetTempLatestCooling']
+            elif self.dict_chiller_inner['waterTempControlMode'] == 1:
+                water_temp_set_new = self.dict_chiller_inner['offSetTempInLatestCooling']
+            else:
+                water_temp_set_new = ''
+                logger.critical('============冷机控制选择输入错误============')
+        elif self.dict_chiller_inner['runMode'] == 1:
+            if self.dict_chiller_inner['waterTempControlMode'] == 0:
+                water_temp_set_new = self.dict_chiller_inner['offSetTempLatestHeating']
+            elif self.dict_chiller_inner['waterTempControlMode'] == 1:
+                water_temp_set_new = self.dict_chiller_inner['offSetTempInLatestHeating']
+            else:
+                water_temp_set_new = ''
+                logger.critical('============冷机控制选择输入错误============')
+        else:
+            water_temp_set_new = ''
+            logger.critical('============冷机运行状态输入错误============')
+        return water_temp_set_new
+
+    def water_temp_set_confirm(self):
+        """关机时长大于16小时,则设定值为初始设定值;关机时长在16小时以内,则设定值为最近一次关机设定值"""
+        chiller_off_time = self.judge_off_time()
+        if chiller_off_time > 16:
+            water_temp_set_new = self.chiller_off()
+        elif 16 >= chiller_off_time >= 0:
+            water_temp_set_new = self.chiller_off_short_time()
+        else:
+            water_temp_set_new = ''
+            logger.critical('============冷机停机时间输入错误============')
+        return water_temp_set_new
+
+
+class JudgeTempControlMode(object):
+    def __init__(self, dict_chiller_inner):
+        self.dict_chiller_inner = dict_chiller_inner
+
+    def is_single_control_strategy(self):
+        """判断所有冷机的冷水控制方式是否唯一,全部为供水或全部为回水
+        0表示全部供水或全部回水,1表示供水和回水共存"""
+        para_accs = pd.DataFrame(self.dict_chiller_inner['allChillerControlSelect'], columns=['para_accs'])
+        para_accs = para_accs.drop_duplicates()
+
+        if len(para_accs) > 1:  # 0为全部供水或全部回水,1为供水和回水共存
+            judge_sin_mul = 1   # 供水和回水共存的情况暂不考虑
+        elif len(para_accs) == 1:
+            judge_sin_mul = 0
+        else:
+            judge_sin_mul = ''
+            logger.critical('============所有冷机制冷控制选择输入错误============')
+        return judge_sin_mul
+
+
+class JudgeSynchronizeAsynchronous(object):
+    """判断冷机的设定值为同步还是异步"""
+    def __init__(self, dict_chiller_inner):
+        self.dict_chiller_inner = dict_chiller_inner
+
+    def parameter_middle(self):
+        """获取所有开机冷机的出水或回水温度设定值的反馈值"""
+        if self.dict_chiller_inner['runMode'] == 0:
+            """全部为供水或全部为回水,则返回对应模式下水温的设定值反馈值"""
+            if self.dict_chiller_inner['waterTempControlMode'] == 0:
+                para_middle = pd.DataFrame(self.dict_chiller_inner['allChillerWaterTempSetOn'], columns=['para_middle'])
+            elif self.dict_chiller_inner['waterTempControlMode'] == 1:
+                para_middle = pd.DataFrame(self.dict_chiller_inner['allChillerWaterTempInSetOn'], columns=['para_middle'])
+            else:
+                para_middle = ''
+                logger.critical('============冷机控制选择输入错误============')
+        elif self.dict_chiller_inner['runMode'] == 1:
+            if self.dict_chiller_inner['waterTempControlMode'] == 0:
+                para_middle = pd.DataFrame(self.dict_chiller_inner['allHeatingWaterTempSetOn'], columns=['para_middle'])
+            else:
+                para_middle = pd.DataFrame(self.dict_chiller_inner['allHeatingWaterTempInSetOn'], columns=['para_middle'])
+        else:
+            para_middle = ''
+            logger.critical('============冷机运行模式输入错误============')
+        para_middle = para_middle.drop_duplicates()
+        list_para_middle = para_middle['para_middle'].tolist()
+        return list_para_middle
+
+    def is_synchronize(self, para_middle):
+        # if self.judge_sin_mul == 0:
+        """全部为供水控制或全部为回水控制的判断,设定值一致为同步,设定值不一致为异步"""
+        if len(para_middle) > 1:
+            judge_synchronize = 1  # 1为异步,0为同步
+        elif len(para_middle) == 1:
+            judge_synchronize = 0
+        else:
+            judge_synchronize = ''
+            logger.critical('============所有开机冷机冷冻水温度设定值输入错误============')
+        # else:    # 供水和回水共存的场景暂不考虑
+        #     judge_synchronize = ''
+        #     logger.critical('============所有冷机制冷控制选择输入错误或控制方式不唯一============')
+        return judge_synchronize
+
+    def judge_synchronize_asynchronous(self):
+        para_middle = self.parameter_middle()
+        results = self.is_synchronize(para_middle)  # 若供水和回水控制共存,则输出为空值,否则1代表异步,0代表同步
+        return results
+
+
+# ①异步,制冷设定温度最高,且末端温度不超标,或制热设定温度最低,且末端温度不超标
+# ②异步,制冷设定温度不是最高,且末端温度超标,或制热设定温度不是最低,且末端温度超标
+# ③异步,制冷设定温度最高,且末端温度超标,或制热设定温度最低,且末端温度超标
+# ④异步,制冷设定温度不是最高,且末端温度不超标,或制热设定温度不是最低,且末端温度不超标
+# ⑤同步,末端温度不超标
+# ⑥同步,末端温度超标
+class SetPointStrategyOnChillerOnAsynchronous(SetPointStrategyOff):
+    def __init__(self, dict_chiller_inner, data_temp_humi, excess_result):
+        super(SetPointStrategyOnChillerOnAsynchronous, self).__init__(dict_chiller_inner, data_temp_humi)
+        self.is_out_range = excess_result['isOutRange']
+        self.excess_result = excess_result
+
+    def set_temp_bad_in_range(self):
+        """
+        异步,制冷设定温度不是最高,且末端温度不超标,或制热设定温度不是最低,且末端温度不超标
+        ## 全部为供水控制或全部为回水温度控制:制冷水温上调至 max(所有运行冷机) , 制热水温下调至min(所有运行冷机),最大步受限于停机补偿值##
+        :return:
+        """
+        # 制冷模式,不超标下的异步,水温上调至最大设定值,但最大步长通过停机补偿值限制
+        if self.dict_chiller_inner['runMode'] == 0:
+            if self.dict_chiller_inner['waterTempControlMode'] == 0:
+                water_temp_set_highest = self.dict_chiller_inner['chillerWaterTempOut'][-1] + \
+                                         0.75 * self.dict_chiller_inner['coolingShutdownOffset']
+                if water_temp_set_highest > max(self.dict_chiller_inner['allChillerWaterTempSetOn']):
+                    water_temp_set_new = max(self.dict_chiller_inner['allChillerWaterTempSetOn'])
+                else:
+                    water_temp_set_new = water_temp_set_highest
+            elif self.dict_chiller_inner['waterTempControlMode'] == 1:
+                water_temp_set_highest = self.dict_chiller_inner['chillerWaterTempIn'][-1] + \
+                                         0.75 * self.dict_chiller_inner['coolingShutdownOffset']
+                if water_temp_set_highest > max(self.dict_chiller_inner['allChillerWaterTempInSetOn']):
+                    water_temp_set_new = max(self.dict_chiller_inner['allChillerWaterTempInSetOn'])
+                else:
+                    water_temp_set_new = water_temp_set_highest
+            else:
+                water_temp_set_new = ''
+                logger.critical('============冷机控制选择输入错误============')
+        elif self.dict_chiller_inner['runMode'] == 1:
+            if self.dict_chiller_inner['waterTempControlMode'] == 0:
+                water_temp_set_lowest = self.dict_chiller_inner['heatingWaterTempOut'] - \
+                                        0.75 * self.dict_chiller_inner['heatingShutdownOffset']
+                if water_temp_set_lowest > min(self.dict_chiller_inner['allHeatingWaterTempSetOn']):
+                    water_temp_set_new = water_temp_set_lowest
+                else:
+                    water_temp_set_new = min(self.dict_chiller_inner['allHeatingWaterTempSetOn'])
+            elif self.dict_chiller_inner['waterTempControlMode'] == 1:
+                water_temp_set_lowest = self.dict_chiller_inner['heatingWaterTempIn'] - \
+                                        0.75 * self.dict_chiller_inner['heatingShutdownOffset']
+                if water_temp_set_lowest > min(self.dict_chiller_inner['allHeatingWaterTempInSetOn']):
+                    water_temp_set_new = water_temp_set_lowest
+                else:
+                    water_temp_set_new = min(self.dict_chiller_inner['allHeatingWaterTempInSetOn'])
+            else:
+                water_temp_set_new = ''
+                logger.critical('============冷机控制选择输入错误============')
+        else:
+            water_temp_set_new = ''
+            logger.critical('============冷机运行模式输入错误============')
+        return water_temp_set_new
+
+    # ----------------以下内容为重构----------------------
+    def set_point_asynchronous(self):  # ****************************************************** #
+        """
+        分两类:全部为供水温度控制(含制热模式)、全部为回水温度控制(含制热模式), 暂不支持供水和回水温度共存
+        1、全部为供水控制
+        (1)满足以下条件,设定值保持不变
+          ①异步,(制冷设定温度最高 or 制热设定温度最低) and 末端温度不超标
+          ②异步,(制冷设定温度不是最高 or 制热设定温度不是最低) and 末端温度超标
+        (2)满足以下条件,制冷设定值下调,至  min(所有运行主机的设定值);制热设定值上调
+          异步,制冷设定温度最高,且末端温度超标,或制热设定温度最低,且末端温度超标
+        (3)满足以下条件,制冷设定值上调,至  max(所有运行主机的设定值),制热设定值下调,最大调控步长受限停机补偿值
+          异步,制冷设定温度不是最高,且末端温度不超标,或制热设定温度不是最低,且末端温度不超标
+        2、全部为回水温度控制
+        调整逻辑和 全部为回水温度控制一致,只是水温设定值是进水设定值
+        :return:
+        """
+        if self.dict_chiller_inner['runMode'] == 0:
+            if self.dict_chiller_inner['waterTempControlMode'] == 0:
+                if (self.dict_chiller_inner['chillerWaterTempSet'] == max(self.dict_chiller_inner['allChillerWaterTempSetOn'])
+                    and self.is_out_range == 0) or \
+                    (self.dict_chiller_inner['chillerWaterTempSet'] < max(self.dict_chiller_inner['allChillerWaterTempSetOn'])
+                     and self.is_out_range != 0):
+                    water_temp_set_new = self.dict_chiller_inner['chillerWaterTempSet']
+                elif self.dict_chiller_inner['chillerWaterTempSet'] == max(self.dict_chiller_inner['allChillerWaterTempSetOn']) \
+                        and self.is_out_range != 0:
+                    water_temp_set_new = min(self.dict_chiller_inner['allChillerWaterTempSetOn'])
+                elif self.dict_chiller_inner['chillerWaterTempSet'] < max(self.dict_chiller_inner['allChillerWaterTempSetOn']) \
+                     and self.is_out_range == 0:
+                    water_temp_set_new = self.set_temp_bad_in_range()
+                else:
+                    water_temp_set_new = ''
+                    logger.critical('============异步状态输入参数错误============')
+
+            elif self.dict_chiller_inner['waterTempControlMode'] == 1:
+                if (self.dict_chiller_inner['chillerWaterTempInSet'] == max(self.dict_chiller_inner['allChillerWaterTempInSetOn'])
+                    and self.is_out_range == 0) or \
+                        (self.dict_chiller_inner['chillerWaterTempInSet'] < max(self.dict_chiller_inner['allChillerWaterTempInSetOn'])
+                         and self.is_out_range != 0):
+                    water_temp_set_new = self.dict_chiller_inner['chillerWaterTempInSet']
+                elif self.dict_chiller_inner['chillerWaterTempInSet'] == max(self.dict_chiller_inner['allChillerWaterTempInSetOn']) \
+                        and self.is_out_range != 0:
+                    water_temp_set_new = min(self.dict_chiller_inner['allChillerWaterTempInSetOn'])
+                elif self.dict_chiller_inner['chillerWaterTempInSet'] < max(self.dict_chiller_inner['allChillerWaterTempInSetOn']) \
+                         and self.is_out_range == 0:
+                    water_temp_set_new = self.set_temp_bad_in_range()
+                else:
+                    water_temp_set_new = ''
+                    logger.critical('============异步状态输入参数错误============')
+            else:
+                water_temp_set_new = ''
+                logger.critical('============冷机控制选择输入错误============')
+
+        elif self.dict_chiller_inner['runMode'] == 1:
+            if self.dict_chiller_inner['waterTempControlMode'] == 0:
+                if (self.dict_chiller_inner['heatingWaterTempSet'] == min(self.dict_chiller_inner['allHeatingWaterTempSetOn'])
+                    and self.is_out_range == 0) or \
+                        (self.dict_chiller_inner['heatingWaterTempSet'] > min(self.dict_chiller_inner['allHeatingWaterTempSetOn'])
+                         and self.is_out_range != 0):
+                    water_temp_set_new = self.dict_chiller_inner['heatingWaterTempSet']
+                elif self.dict_chiller_inner['heatingWaterTempSet'] == min(self.dict_chiller_inner['allHeatingWaterTempSetOn'])\
+                        and self.is_out_range != 0:
+                    water_temp_set_new = max(self.dict_chiller_inner['allHeatingWaterTempSetOn'])
+                elif self.dict_chiller_inner['heatingWaterTempSet'] > min(self.dict_chiller_inner['allHeatingWaterTempSetOn']) \
+                        and self.is_out_range == 0:
+                    water_temp_set_new = self.set_temp_bad_in_range()
+                else:
+                    water_temp_set_new = ''
+                    logger.critical('============异步状态输入参数错误============')
+
+            elif self.dict_chiller_inner['waterTempControlMode'] == 1:
+                if (self.dict_chiller_inner['heatingWaterTempInSet'] == min(self.dict_chiller_inner['allHeatingWaterTempInSetOn'])
+                    and self.is_out_range == 0) or \
+                        (self.dict_chiller_inner['heatingWaterTempInSet'] > min(self.dict_chiller_inner['allHeatingWaterTempInSetOn'])
+                         and self.is_out_range != 0):
+                    water_temp_set_new = self.dict_chiller_inner['heatingWaterTempInSet']
+                elif self.dict_chiller_inner['heatingWaterTempInSet'] == min(self.dict_chiller_inner['allHeatingWaterTempInSetOn'])\
+                        and self.is_out_range != 0:
+                    water_temp_set_new = max(self.dict_chiller_inner['allHeatingWaterTempInSetOn'])
+                elif self.dict_chiller_inner['heatingWaterTempInSet'] > min(self.dict_chiller_inner['allHeatingWaterTempInSetOn']) \
+                        and self.is_out_range == 0:
+                    water_temp_set_new = self.set_temp_bad_in_range()
+                else:
+                    water_temp_set_new = ''
+                    logger.critical('============异步状态输入参数错误============')
+            else:
+                water_temp_set_new = ''
+                logger.critical('============冷机控制选择输入错误============')
+        else:
+            water_temp_set_new = ''
+            logger.critical('============冷机运行模式输入错误============')
+        # water_temp_set_new = self.water_temp_limit_verify(water_temp_set_new)
+        return water_temp_set_new
+
+
+# 同步状态下,温度超标
+# 同步状态下,温度不超标
+class SetPointStrategyOnChillerOnSynchronous(SetPointStrategyOnChillerOnAsynchronous):
+    def __init__(self, dict_chiller_inner, data_temp_humi, excess_result):
+        super(SetPointStrategyOnChillerOnSynchronous, self).__init__(
+            dict_chiller_inner, data_temp_humi, excess_result)
+        # self.data_upper_correct = data_upper_correct
+
+    def temp_humi_in_range(self, control_bisis):
+        # 根据控制依据判断水温调节,温度、湿度、温度和湿度
+        if control_bisis == 0 and self.data_temp_humi['deltaTemp'].min():
+            delta_water_temp = self.data_temp_humi['deltaTemp'].min() * Coefficient['inTemp']
+            self.excess_result['minDelta'] = round(self.data_temp_humi['deltaTemp'].min(), 1)
+        elif control_bisis == 1 and self.data_temp_humi['deltaHumi'].min():
+            delta_water_temp = self.data_temp_humi['deltaHumi'].min() * Coefficient['inHumi']
+            self.excess_result['minDelta'] = round(self.data_temp_humi['deltaHumi'].min(), 1)
+        elif control_bisis == 2 and (self.data_temp_humi['deltaTemp'].min() or self.data_temp_humi['deltaHumi'].min()):
+            delta_water_temp = min(self.data_temp_humi['deltaTemp'].min() * Coefficient['inTemp'],
+                                   self.data_temp_humi['deltaHumi'].min() * Coefficient['inHumi'])
+            if self.data_temp_humi['deltaTemp'].min() * Coefficient['inTemp'] <= \
+                self.data_temp_humi['deltaHumi'].min() * Coefficient['inHumi']:
+                self.excess_result['minDelta'] = round(self.data_temp_humi['deltaTemp'].min(), 1)
+            else:
+                self.excess_result['minDelta'] = round(self.data_temp_humi['deltaHumi'].min(), 1)
+                self.excess_result['minName'] = self.data_temp_humi.loc[self.data_temp_humi['deltaHumi'].idxmin(), 'ahuName']
+        else:
+            delta_water_temp = 0
+
+        if self.dict_chiller_inner['runMode'] == 0:
+            if self.dict_chiller_inner['waterTempControlMode'] == 0:
+                water_temp_set_new = self.dict_chiller_inner['chillerWaterTempSet'] + delta_water_temp
+                if water_temp_set_new - self.dict_chiller_inner['chillerWaterTempOut'][-1] > \
+                        0.75 * self.dict_chiller_inner['coolingShutdownOffset']:
+                    water_temp_set_new = self.dict_chiller_inner['chillerWaterTempOut'][-1] + \
+                                         0.75 * self.dict_chiller_inner['coolingShutdownOffset']
+            elif self.dict_chiller_inner['waterTempControlMode'] == 1:
+                water_temp_set_new = self.dict_chiller_inner['chillerWaterTempInSet'] + delta_water_temp
+                if water_temp_set_new - self.dict_chiller_inner['chillerWaterTempIn'][-1] > \
+                        0.75 * self.dict_chiller_inner['coolingShutdownOffset']:
+                    water_temp_set_new = self.dict_chiller_inner['chillerWaterTempIn'][-1] + \
+                                         0.75 * self.dict_chiller_inner['coolingShutdownOffset']
+            else:
+                water_temp_set_new = ''
+                logger.critical('============冷机控制选择输入错误============')
+        elif self.dict_chiller_inner['runMode'] == 1:
+            if self.dict_chiller_inner['waterTempControlMode'] == 0:
+                water_temp_set_new = self.dict_chiller_inner['heatingWaterTempSet'] - delta_water_temp
+                if self.dict_chiller_inner['heatingWaterTempOut'][-1] - water_temp_set_new > \
+                        0.75 * self.dict_chiller_inner['heatingShutdownOffset']:
+                    water_temp_set_new = self.dict_chiller_inner['heatingWaterTempOut'][-1] - \
+                                         0.75 * self.dict_chiller_inner['heatingShutdownOffset']
+            elif self.dict_chiller_inner['waterTempControlMode'] == 1:
+                water_temp_set_new = self.dict_chiller_inner['heatingWaterTempInSet'] - delta_water_temp
+                if self.dict_chiller_inner['heatingWaterTempIn'][-1] - water_temp_set_new > \
+                        0.75 * self.dict_chiller_inner['heatingShutdownOffset']:
+                    water_temp_set_new = self.dict_chiller_inner['heatingWaterTempIn'][-1] - \
+                                         0.75 * self.dict_chiller_inner['heatingShutdownOffset']
+            else:
+                water_temp_set_new = ''
+                logger.critical('============冷机控制选择输入错误============')
+        else:
+            water_temp_set_new = ''
+            logger.critical('============冷机运行模式输入错误============')
+        return water_temp_set_new
+
+    def temp_humi_out_range(self):
+        # 1表示温度超标, 2表示露点超标, 3表示湿度超标
+        if self.is_out_range == 1 and self.data_temp_humi['deltaTemp'].min():
+            delta_water_temp = self.data_temp_humi['deltaTemp'].min() * Coefficient['outTemp']
+            self.excess_result['minDelta'] = round(self.data_temp_humi['deltaTemp'].min(), 1)
+        elif self.is_out_range == 2 and self.data_temp_humi['deltaDewPoint'].min():
+            delta_water_temp = self.data_temp_humi['deltaDewPoint'].min() * Coefficient['outDewPoint']
+            self.excess_result['minDelta'] = round(self.data_temp_humi['deltaDewPoint'].min(), 1)
+        elif self.is_out_range == 3 and self.data_temp_humi['deltaHumi'].min():
+            delta_water_temp = self.data_temp_humi['deltaHumi'].min() * Coefficient['outHumi']
+            self.excess_result['minDelta'] = round(self.data_temp_humi['deltaHumi'].min(), 1)
+        else:
+            delta_water_temp = 0
+
+        if self.dict_chiller_inner['runMode'] == 0:
+            if self.dict_chiller_inner['waterTempControlMode'] == 0:
+                water_temp_set_new = self.dict_chiller_inner['chillerWaterTempSet'] + delta_water_temp
+            elif self.dict_chiller_inner['waterTempControlMode'] == 1:
+                water_temp_set_new = self.dict_chiller_inner['chillerWaterTempInSet'] + delta_water_temp
+            else:
+                water_temp_set_new = ''
+                logger.critical('============冷机控制选择输入错误============')
+        elif self.dict_chiller_inner['runMode'] == 1:
+            if self.dict_chiller_inner['waterTempControlMode'] == 0:
+                water_temp_set_new = self.dict_chiller_inner['heatingWaterTempSet'] - delta_water_temp
+            elif self.dict_chiller_inner['waterTempControlMode'] == 1:
+                water_temp_set_new = self.dict_chiller_inner['heatingWaterTempInSet'] - delta_water_temp
+            else:
+                water_temp_set_new = ''
+                logger.critical('============冷机控制选择输入错误============')
+        else:
+            water_temp_set_new = ''
+            logger.critical('============冷机运行模式输入错误============')
+        return water_temp_set_new
+
+    def set_point_synchronous(self, control_bisis):
+        if self.is_out_range == 0:
+            water_temp_set_new = self.temp_humi_in_range(control_bisis)
+        elif self.is_out_range != 0:
+            water_temp_set_new = self.temp_humi_out_range()
+        else:
+            water_temp_set_new = ''
+            logger.critical('============温湿度超标输入错误============')
+        # water_temp_set_new = self.water_temp_limit_verify(water_temp_set_new)
+        return water_temp_set_new, self.excess_result
+
+
+# if __name__ == '__main__':
+#     data_temp_humi = pd.DataFrame({
+#         "tempHumiMeterId": ["3000638", "3000694"],
+#         "terminalName": ["监测点A", "监测点B"],
+#         "coolingTempUpper": [25.0, 26.0],
+#         "coolingHumiUpper": [60.0, 65.0],
+#         "heatingTempDown": [18.0, 17.5],
+#         "tempReal": [24.5, 25.3],
+#         "humiReal": [50, 50],
+#         "deltaTemp": [-1, 1],
+#         'deltaDewPoint': [1, 1],
+#         "deltaHumi": [1, 1],
+#      })
+#
+#     ################################# 确认这些参数是实时值还是列表
+#     dict_chiller_inner = {'runMode': 0, 'chillerWaterTempSet': 10, 'chillerWaterTempSetUpper': 15,
+#                           'chillerWaterTempOut': 9.8, 'chillerWaterTempIn': 9.8, 'coolingWaterTempSetUpper': 45,
+#                           'heatingWaterTempInSet': 40, 'heatingWaterTempSet': 43, 'chillerWaterTempInSet': 12,
+#                           'waterTempControlMode': 0, 'coolingShutdownOffset': 2, 'heatingShutdownOffset': 2,
+#                           'allHeatingWaterTempSetOn': [7, 7], 'allHeatingWaterTempInSetOn': [12, 12],
+#                           'allChillerWaterTempSetOn': [9, 10], 'allChillerWaterTempInSetOn': [40, 40],
+#                           'runStatus': [1, 1, 1, 1]}
+#     excess_result_ = {'isOutRange': 0, 'minDelta': '', 'minName': ''}
+#     parameter = (dict_chiller_inner, data_temp_humi)
+#     judge_syn_asy = 1
+#     basis = 0
+#     if judge_syn_asy == 1:
+#         spsocoa = SetPointStrategyOnChillerOnAsynchronous(*parameter, excess_result_)  # 异步算法
+#         water_temp_set = spsocoa.set_point_asynchronous()  # 异步算法
+#     else:
+#         spsocos = SetPointStrategyOnChillerOnSynchronous(*parameter, excess_result_)  # 同步算法
+#         water_temp_set = spsocos.set_point_synchronous(basis)  # 同步算法
+#     print(water_temp_set)