excess_temp_modify.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. import pandas as pd
  2. import datetime
  3. from data_initialize_standard.constant import *
  4. from communication.iotdb_util import *
  5. # from logs_conf.logger import *
  6. from logs.logger import *
  7. class ExcessTempModify(object):
  8. def __init__(self, data_excess, dict_code, chiller_outer):
  9. self.data_excess = data_excess
  10. self.config = dict_code
  11. # 由于不同项目末端监测点的采样周期不一致,若无温湿度采样周期则将无法按预期算法修正末端监测点温湿度限制
  12. # self.modify = modify_data
  13. self.chiller_outer = chiller_outer
  14. self.modify = {'stationData': {}, 'terminalData': {}, 'chillerData': {}}
  15. self.chiller_mode = dict_code['runMode']
  16. self.sampling_nums = 60/dict_code['samplePeriod']*10 # 根据采样周期进行计算
  17. def get_modify_data(self):
  18. IotDbClient('192.168.1.70', username='root', password='root')
  19. org_id = self.chiller_outer['orgId']
  20. controller_id = self.chiller_outer['controllerId']
  21. chiller_ids = self.chiller_outer['allChillersInfo']['chillerId']
  22. power_rates = self.chiller_outer['allChillersInfo']['powerRated']
  23. terminal_ids = list(self.data_excess['ahuMeterId'])
  24. trigger_time_stamp = pd.to_datetime(self.chiller_outer['triggerTime']).timestamp()
  25. self.modify['terminalData'] = get_terminal_modify_data(org_id, terminal_ids, trigger_time_stamp)
  26. self.modify['chillerData'] = get_chiller_modify_data(org_id, chiller_ids, power_rates, trigger_time_stamp)
  27. self.modify['stationData'] = get_station_modify_data(org_id, controller_id, trigger_time_stamp)
  28. def data_judge(self):
  29. self.get_modify_data()
  30. is_success = 1
  31. if not self.modify.get('stationData'): # 冷站数据为{}
  32. is_success = 0
  33. for terminal in self.modify.get('terminalData', {}).values(): # 监测点数据为{}
  34. if not terminal:
  35. is_success = 0
  36. if self.config["mainTempMode"] == 0:
  37. for chiller in self.modify.get('chillerData', {}).values(): # 监测点数据为{}
  38. if not chiller:
  39. is_success = 0
  40. if is_success:
  41. all_chillers = self.chiller_outer["allChillersInfo"]
  42. # 使用zip组合两个列表并创建字典
  43. control_mode = {cid: mode
  44. for cid, mode in zip(all_chillers["chillerId"], all_chillers["waterTempControlMode"])}
  45. capacity_rated = {cid: mode
  46. for cid, mode in zip(all_chillers["chillerId"], all_chillers["capacityRated"])}
  47. for chiller_id, data in self.modify['chillerData'].items():
  48. if chiller_id in control_mode:
  49. data["waterTempControlMode"] = control_mode[chiller_id]
  50. data["capacityRated"] = capacity_rated[chiller_id]
  51. else:
  52. is_success = 0
  53. return is_success
  54. def transform_dict_to_dataformat(self, station_data, sensor_data, chiller_data):
  55. """数据格式的转化"""
  56. # chiller_mode = self.config['runMode']
  57. time_stamp = station_data['dateTime']
  58. # 温湿度数据合并
  59. sensor_data_list = []
  60. for key in sensor_data.keys():
  61. sensor_data_list.append(pd.DataFrame(sensor_data[key], index=time_stamp))
  62. # temp_humi_sensor_id = [int(key) for key in sensor_data.keys()]
  63. temp_humi_sensor_id = [key for key in sensor_data.keys()]
  64. sensor_data_df = pd.concat(sensor_data_list, keys=temp_humi_sensor_id, axis=1)
  65. # sensor_data_df.index = pd.to_datetime([int(i + 28800000) for i in sensor_data_df.index], unit='ms')
  66. # 通过配置判断总管温度是直接读取还是加权计算-------------------------------------------------------------
  67. if self.config["mainTempMode"] == 1: # 直接读取总管温度
  68. water_temp_df = self.main_water_temp(station_data)
  69. else: # 计算加权水温
  70. # 通过负载率删选冷机数据,并将所有冷机数据合并
  71. chiller_data_list = []
  72. for key in chiller_data.keys():
  73. val = pd.DataFrame(chiller_data[key], index=time_stamp)
  74. val.loc[(val['loadRate'] <= 10) | (val['chillerPowerRatio'] <= 10), ['loadRate', 'chillerPowerRatio']] = 0
  75. val.fillna(0, inplace=True)
  76. chiller_data_list.append(val)
  77. # chiller_id_list = [int(key) for key in chiller_data.keys()]
  78. chiller_id_list = [key for key in chiller_data.keys()]
  79. chiller_data_df = pd.concat(chiller_data_list, keys=chiller_id_list, axis=1)
  80. water_temp_df = self.cal_weighted_water_temp(chiller_data_df, chiller_id_list)
  81. # water_temp_df.index = pd.to_datetime([int(i + 28800000) for i in chiller_data_df.index], unit='ms')
  82. return sensor_data_df, water_temp_df
  83. def main_water_temp(self, station_data):
  84. """直接读取总管温度"""
  85. weighted_water_temp = pd.DataFrame(index=station_data['dateTime'], columns=['weighted_water_temp', 'init_water_temp'])
  86. weighted_water_temp['init_water_temp'] = self.config["chillerWaterTempSetInitial"]
  87. if set(self.config['allChillerControlSelect']) == {0}: # 均为供水控制模式
  88. if self.chiller_mode == 0:
  89. weighted_water_temp['weighted_water_temp'] = station_data["chilledWaterMainTempOut"]
  90. elif self.chiller_mode == 1:
  91. weighted_water_temp['weighted_water_temp'] = station_data["coolingWaterMainTempOut"]
  92. else:
  93. ValueError('chiller mode input error!')
  94. elif set(self.config['allChillerControlSelect']) == {1}: # 均为回水控制模式
  95. if self.chiller_mode == 0:
  96. weighted_water_temp['weighted_water_temp'] = station_data["chilledWaterMainTempIn"]
  97. elif self.chiller_mode == 1:
  98. weighted_water_temp['weighted_water_temp'] = station_data["coolingWaterMainTempIn"]
  99. else:
  100. ValueError('chiller mode input error!')
  101. else:
  102. weighted_water_temp = pd.DataFrame(columns=['weighted_water_temp', 'init_water_temp'])
  103. return weighted_water_temp
  104. def cal_weighted_water_temp(self, chiller_data, chiller_id_list):
  105. """计算加权水温"""
  106. water_temp_control_mode_index = []
  107. # water_temp_set_initial_index, water_temp_in_set_initial_index = [], []
  108. if self.chiller_mode == 0:
  109. for chiller_id in chiller_id_list:
  110. water_temp_control_mode_index.append((chiller_id, 'waterTempControlMode'))
  111. # water_temp_set_initial_index.append((chiller_id, 'chillerWaterTempSetInitial'))
  112. # water_temp_in_set_initial_index.append((chiller_id, 'chillerWaterTempInSetInitial'))
  113. elif self.chiller_mode == 1:
  114. for chiller_id in chiller_id_list:
  115. water_temp_control_mode_index.append((chiller_id, 'waterTempControlMode'))
  116. # water_temp_set_initial_index.append((chiller_id, 'heatingWaterTempSetInitial'))
  117. # water_temp_in_set_initial_index.append((chiller_id, 'heatingWaterTempInSetInitial'))
  118. #################制热的水温和之前表示不大一样,到底是热水还是冷却水?后期保持一致#########################
  119. else:
  120. ValueError('chiller mode input error!')
  121. # 筛选出相同水温控制模式、相同初始出水温度设定值和相同初始进水温度设定值的数据集,同一时间戳下各冷机的对应参数唯一则代表相同
  122. chiller_data = chiller_data[chiller_data[water_temp_control_mode_index].nunique(axis=1) == 1]
  123. # chiller_data = chiller_data[chiller_data[water_temp_set_initial_index].nunique(axis=1) == 1]#这里好像无必要
  124. # chiller_data = chiller_data[chiller_data[water_temp_in_set_initial_index].nunique(axis=1) == 1]#这里好像无必要
  125. chiller_data_lwtcm = chiller_data[chiller_data[water_temp_control_mode_index[0]] == 0] # 控制模式为供水
  126. chiller_data_rwtcm = chiller_data[chiller_data[water_temp_control_mode_index[0]] == 1] # 控制模式为回水
  127. is_cal = 0 if chiller_data.empty else 1
  128. if is_cal:
  129. weighted_water_temp_lwtcm = pd.DataFrame(columns=['weighted_water_temp', 'init_water_temp'])
  130. weighted_water_temp_rwtcm = pd.DataFrame(columns=['weighted_water_temp', 'init_water_temp'])
  131. if not chiller_data_lwtcm.empty:
  132. chiller_data_lwtcm['denominator'], chiller_data_lwtcm['numerator'] = 0.01, 0
  133. for chiller_id in chiller_id_list:
  134. chiller_data_lwtcm['denominator'] += chiller_data_lwtcm[(chiller_id, 'chillerPowerRatio')] * \
  135. chiller_data_lwtcm[(chiller_id, 'capacityRated')].astype("float")
  136. if self.chiller_mode == 0:
  137. chiller_data_lwtcm['numerator'] += chiller_data_lwtcm[(chiller_id, 'chillerWaterTempOut')] * \
  138. chiller_data_lwtcm[(chiller_id, 'chillerPowerRatio')] * \
  139. chiller_data_lwtcm[(chiller_id, 'capacityRated')].astype("float")
  140. elif self.chiller_mode == 1:
  141. chiller_data_lwtcm['numerator'] += chiller_data_lwtcm[(chiller_id, 'heatingWaterTempOut')] * \
  142. chiller_data_lwtcm[(chiller_id, 'chillerPowerRatio')] * \
  143. chiller_data_lwtcm[(chiller_id, 'capacityRated')].astype("float")
  144. else:
  145. ValueError('chiller mode input error!')
  146. weighted_water_temp_lwtcm['weighted_water_temp'] = \
  147. round(chiller_data_lwtcm['numerator'] / chiller_data_lwtcm['denominator'], 2)
  148. # weighted_water_temp_lwtcm['init_water_temp'] = chiller_data_lwtcm[water_temp_set_initial_index[0]]
  149. weighted_water_temp_lwtcm['init_water_temp'] = self.config['chillerWaterTempSetInitial']
  150. if not chiller_data_rwtcm.empty:
  151. chiller_data_rwtcm['denominator'], chiller_data_rwtcm['numerator'] = 0.01, 0
  152. for chiller_id in chiller_id_list:
  153. chiller_data_rwtcm['denominator'] += chiller_data_rwtcm[(chiller_id, 'chillerPowerRatio')] * \
  154. chiller_data_rwtcm[(chiller_id, 'capacityRated')].astype("float")
  155. if self.chiller_mode == 0:
  156. chiller_data_rwtcm['numerator'] += chiller_data_rwtcm[(chiller_id, 'chillerWaterTempIn')] * \
  157. chiller_data_rwtcm[(chiller_id, 'chillerPowerRatio')] * \
  158. chiller_data_rwtcm[(chiller_id, 'capacityRated')].astype("float")
  159. elif self.chiller_mode == 1:
  160. chiller_data_rwtcm['numerator'] += chiller_data_rwtcm[(chiller_id, 'heatingWaterTempIn')] * \
  161. chiller_data_rwtcm[(chiller_id, 'chillerPowerRatio')] * \
  162. chiller_data_rwtcm[(chiller_id, 'capacityRated')].astype("float")
  163. else:
  164. ValueError('chiller mode input error!')
  165. weighted_water_temp_rwtcm['weighted_water_temp'] = \
  166. round(chiller_data_rwtcm['numerator'] / chiller_data_rwtcm['denominator'], 2)
  167. # weighted_water_temp_rwtcm['init_water_temp'] = chiller_data_rwtcm[water_temp_in_set_initial_index[0]]
  168. weighted_water_temp_rwtcm['init_water_temp'] = self.config['chillerWaterTempInSetInitial']
  169. weighted_water_temp = pd.concat([weighted_water_temp_lwtcm, weighted_water_temp_rwtcm])
  170. weighted_water_temp = weighted_water_temp.sort_index(axis=0)
  171. else:
  172. weighted_water_temp = pd.DataFrame(columns=['weighted_water_temp', 'init_water_temp'])
  173. return weighted_water_temp
  174. def modify_air_temp_humi(self, sensor_id_list, sensor_data, water_temp):
  175. threshold = ModifyTempHumiPara['threshold'] # 修正阈值
  176. quantile = ModifyTempHumiPara['quantile'] # 修正分位数
  177. modified_air_temp_dic = {}
  178. modified_air_humi_dic = {}
  179. water_temp = water_temp[water_temp['weighted_water_temp'] != 0]
  180. column_names = sensor_data.columns.tolist() # [(id, 参数名),(id, 参数名), ...] # sensor_data
  181. for sensor_id in sensor_id_list:
  182. # su_sensor_id = config[config['returnAirMeterId'] == re_sensor_id].iloc[0]['supplyAirMeterId']
  183. # if ((re_sensor_id, 'temperature') in column_names) and ((su_sensor_id, 'temperature') in column_names):
  184. index_df = self.data_excess[self.data_excess['ahuMeterId'] == sensor_id].index.tolist()[0]
  185. if ((sensor_id, 'tempReal') in column_names) :
  186. # AHU_start = sensor_data[abs(sensor_data[(sensor_id, 'tempReal')] -
  187. # sensor_data[(sensor_id, 'tempSupply')]) > 2.0] # 筛选出开启的监测点
  188. AHU_start = sensor_data[sensor_data[(sensor_id, 'status')] == 1] # 筛选出开启的监测点
  189. dataset = pd.concat([AHU_start[(sensor_id, 'tempReal')], AHU_start[(sensor_id, 'humiReal')],
  190. water_temp['weighted_water_temp'], water_temp['init_water_temp']], sort=False,
  191. keys=['temp', 'humi', 'weighted_water_temp', 'init_water_temp'], axis=1)
  192. dataset = dataset.dropna()
  193. if self.chiller_mode == 0:
  194. upper_temp_limit = self.data_excess.loc[index_df, 'coolingTempUpper']
  195. upper_humi_limit = self.data_excess.loc[index_df, 'coolingHumiUpper']
  196. dataset = dataset[dataset['weighted_water_temp'] <= dataset['init_water_temp'] + 0.5]
  197. # 这里没有考虑其他两种步长的场景,如果要是考虑的话如何考虑呢,如站内冷机的步长不同的情况下
  198. dataset_temp = dataset[dataset['temp'] >= upper_temp_limit]
  199. dataset_humi = dataset[dataset['humi'] >= upper_humi_limit]
  200. if len(dataset_temp) > self.sampling_nums:
  201. temp_series = dataset_temp.quantile(q=quantile)
  202. modified_temp_limit = round(temp_series['temp'], 3) + threshold
  203. else:
  204. modified_temp_limit = upper_temp_limit
  205. if len(dataset_humi) > self.sampling_nums:
  206. humi_series = dataset_humi.quantile(q=quantile)
  207. modified_humi_limit = min(round(humi_series['humi'], 3) + 10 * threshold, 100)
  208. else:
  209. modified_humi_limit = upper_humi_limit
  210. elif self.chiller_mode == 1:
  211. # lower_temp_limit = config[config['returnAirMeterId'] == re_sensor_id].iloc[0]['heatingTempDown']
  212. # lower_temp_limit = sensor_data[(sensor_id, 'heatingTempDown')].iloc[0]
  213. lower_temp_limit = self.data_excess.loc[index_df, 'heatingTempDown']
  214. dataset = dataset[dataset['weighted_water_temp'] >= dataset['init_water_temp'] - 0.5]
  215. # 这里没有考虑其他两种步长的场景,如果要是考虑的话如何考虑呢,如站内冷机的步长不同的情况下
  216. dataset_temp = dataset[dataset['temp'] <= lower_temp_limit]
  217. if len(dataset_temp) > self.sampling_nums:
  218. temp_series = dataset_temp.quantile(q=1-quantile)
  219. modified_temp_limit = round(temp_series['temp'], 3) - threshold
  220. else:
  221. modified_temp_limit = lower_temp_limit
  222. modified_humi_limit = ''
  223. else:
  224. raise ValueError('chiller mode input error!')
  225. modified_air_temp_dic[sensor_id] = modified_temp_limit
  226. modified_air_humi_dic[sensor_id] = modified_humi_limit
  227. return modified_air_temp_dic, modified_air_humi_dic
  228. def get_modified_air_temp_humi(self):
  229. logger.critical("============温湿度超标点限值修正模块中关键参数:runMode:%s,threshold:%s,quantile:%s============" %
  230. (self.config['runMode'], ModifyTempHumiPara['threshold'], ModifyTempHumiPara['quantile']))
  231. sensor_data_df, chiller_water_temp_df = self.transform_dict_to_dataformat(self.modify['stationData'],
  232. self.modify['terminalData'],
  233. self.modify['chillerData'])
  234. excess_sensor_id = list(self.data_excess['ahuMeterId']) # 超标监测点数据的id列表
  235. modified_air_temp, modified_air_humi = self.modify_air_temp_humi(excess_sensor_id, sensor_data_df,
  236. chiller_water_temp_df)
  237. # re_sensor_id_list = station_data['config']['returnAirMeterId'] # 这里应该是所有监测点的数据
  238. modified_meter_id = list(modified_air_temp.keys()) # 有修正的监测点Id列表
  239. for sensor in excess_sensor_id:
  240. if sensor in modified_meter_id:
  241. index_df = self.data_excess[self.data_excess['ahuMeterId'] == sensor].index.tolist()[0]
  242. if self.chiller_mode == 0:
  243. self.data_excess.loc[index_df, 'coolingTempUpper'] = modified_air_temp[sensor]
  244. self.data_excess.loc[index_df, 'coolingHumiUpper'] = modified_air_humi[sensor]
  245. elif self.chiller_mode == 1:
  246. self.data_excess.loc[index_df, 'heatingTempDown'] = modified_air_temp[sensor]
  247. else:
  248. raise ValueError('chiller mode input error!')
  249. return self.data_excess
  250. # if __name__ == '__main__':
  251. # data_temp_humi = pd.DataFrame({
  252. # "ahuMeterId": ["3000638", "3000694", "3000654"],
  253. # "terminalName": ["监测点A", "监测点B", "监测点C"],
  254. # "coolingTempUpper": [25.0, 26.0, 24],
  255. # "coolingHumiUpper": [60.0, 65.0, 65],
  256. # "heatingTempDown": [18.0, 17.5, 18],
  257. # "tempReal": [24.5, 25.3, 25],
  258. # "humiReal": [50, 50, 50],
  259. # })
  260. #
  261. # station_data_ = {"chilledWaterMainTempOut": [7, 7, 7],
  262. # 'dateTime': ["2025-4-3 12:00:00", "2025-4-4 12:00:00", "2025-4-5 12:00:00"]}
  263. # sensor_data_ = {
  264. # "3000638": {"name": "sensor1", "tempReal": [10, 20, 30], "humiReal": [10, 20, 30], "tempSupply": [1, 2, 3]},
  265. # "3000694": {"name": "sensor2", "tempReal": [10, 20, 30], "humiReal": [10, 20, 30], "tempSupply": [1, 2, 3]},
  266. # "3000654": {"name": "sensor3", "tempReal": [10, 20, 30], "humiReal": [10, 20, 30], "tempSupply": [1, 2, 3]}}
  267. # # 冷机的历史7天数据
  268. # chiller_data_ = {"301": {"name": 1, "loadRate": [20, 20, 30], "chillerPowerRatio": [50, 50, 50],
  269. # "chillerWaterTempOut": [7, 7, 7],
  270. # 'waterTempControlMode': 0, 'capacityRated': 10},
  271. # "302": {"name": 1, "loadRate": [10, 20, 30], "chillerPowerRatio": [50, 50, 50],
  272. # "chillerWaterTempOut": [7, 7, 7],
  273. # 'waterTempControlMode': 0, 'capacityRated': 10}}
  274. # modify_data = {'terminalData': sensor_data_, 'chillerData': chiller_data_, 'stationData': station_data_}
  275. # config_info = {"handleService": 1, "controlMode": 1, "isHardwareControl": 1, "calPeriod": 3,
  276. # "minControlStep": 0.1, "chillerWaterTempSetInitial": 7, "chillerWaterTempSetUpper": 12,
  277. # "chillerWaterTempSetLower": 7, "energyMode": 1, "controlBasis": 0, "tempMargin": 0.2,
  278. # "humiMargin": 2, "mainTempMode": 0, "samplePeriod": 60, "upTempControlPeriod": 10,
  279. # "downTempControlPeriod": 12, 'runMode': 0, 'allChillerControlSelect': [0, 0, 0]}
  280. # etm = ExcessTempModify(data_temp_humi, config_info, modify_data)
  281. # data = etm.get_modified_air_temp_humi()
  282. # print(data)