import numpy as np import datetime from scipy import interpolate import logging import pandas as pd # 电压范围3.0 - 3.5 SocCurve = [0.00, 0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40, 0.45, 0.50, 0.55, 0.60, 0.65, 0.70, 0.75, 0.80, 0.85, 0.90, 0.95, 1.00] DisOcvCurve = [2.8977, 3.1587, 3.2040, 3.2269, 3.2521, 3.2691, 3.2846, 3.2865, 3.2871, 3.2880, 3.2886, 3.2971, 3.3190, 3.3277, 3.3277, 3.3280, 3.3286, 3.3289, 3.3296, 3.3311, 3.3795] # 磷酸铁锂 SocLook = interpolate.interp1d(DisOcvCurve, SocCurve, kind='slinear') ChgNearFullVol = 3.5 # v DisNearFullVol = 3.0 # v logger = logging.getLogger(__file__) def str_to_date(date_string, format='%Y-%m-%d %H:%M:%S', alternative=None): try: return datetime.datetime.strptime(date_string, format) except Exception as e: pass return alternative # 安时积分法 def AhCalculate(soc, cur, deltaTime, capacity): try: soc = soc + cur * deltaTime / capacity / 3600 except Exception as exc: logger.warning(exc) return soc # 判断充放电状态 def ChgStatus(cur, chg_time, dis_time, shelve_time): flag = False if cur > 1: chg_time += 1 if cur < -1: dis_time += 1 flag = True if cur == 0: shelve_time += 1 chg_time = 0 dis_time = 0 return chg_time, dis_time, shelve_time, flag # 电芯容量校正 def CapacityCalculate(soc, soc_zero, cumulative_capacity, t_capacity): s = soc - soc_zero c = cumulative_capacity - t_capacity try: capacity = c / s except Exception as exc: logger.warning(exc) capacity = 120 return capacity # 累积容量计算 def CumulativeCapacity(capacity, cur, deltaTime): capacity = capacity + cur * deltaTime / 3600 return capacity # 电池包容量计算 def PackCapacityCalculate(soc_arr, capacity): pack_capacity = np.min(soc_arr * capacity) + np.min(capacity - soc_arr * capacity) return pack_capacity # 满电校正 def ChgFullFunc(soc, vol): for index in range(120): if vol[index] > ChgNearFullVol: soc[index] = 1 return soc # 满放校正 def DisFullFunc(soc, vol): for index in range(120): if vol[index] < DisNearFullVol: soc[index] = 0 return soc # 电池包soc计算 def PackSocCalculate(soc_arr, pack_capacity, capacity): try: pack_soc = np.min(soc_arr * capacity) / pack_capacity if pack_soc > 1: pack_soc = 1 if pack_soc < 0: pack_soc = 0 return pack_soc except Exception as exc: logger.warning(exc) SOC_DATA = [] # 执行函数,最后返回的是dataframe形式,有对应的上传时间和soc,应该要关联设备id,这块没有加 def soc_test(sn, data): try: global SOC_DATA capacity = 120 # ah chg_time = 0 dis_time = 0 shelve_time = 0 c_capacity = 0 soc_zero = [] if SOC_DATA: for ram in SOC_DATA: if ram['sn'] == sn: capacity = ram['capacity'] chg_time = ram['chg_time'] dis_time = ram['dis_time'] shelve_time = ram['shelve_time'] c_capacity = ram['c_capacity'] soc_zero = ram['soc_zero'] vol_array = data[ ['单体电压1', '单体电压2', '单体电压3', '单体电压4', '单体电压5', '单体电压6', '单体电压7', '单体电压8', '单体电压9', '单体电压10', '单体电压11', '单体电压12', '单体电压13', '单体电压14', '单体电压15', '单体电压16', '单体电压17', '单体电压18', '单体电压19', '单体电压20', '单体电压21', '单体电压22', '单体电压23', '单体电压24', '单体电压25', '单体电压26', '单体电压27', '单体电压28', '单体电压29', '单体电压30', '单体电压31', '单体电压32', '单体电压33', '单体电压34', '单体电压35', '单体电压36', '单体电压37', '单体电压38', '单体电压39', '单体电压40', '单体电压41', '单体电压42', '单体电压43', '单体电压44', '单体电压45', '单体电压46', '单体电压47', '单体电压48', '单体电压49', '单体电压50', '单体电压51', '单体电压52', '单体电压53', '单体电压54', '单体电压55', '单体电压56', '单体电压57', '单体电压58', '单体电压59', '单体电压60', '单体电压61', '单体电压62', '单体电压63', '单体电压64', '单体电压65', '单体电压66', '单体电压67', '单体电压68', '单体电压69', '单体电压70', '单体电压71', '单体电压72', '单体电压73', '单体电压74', '单体电压75', '单体电压76', '单体电压77', '单体电压78', '单体电压79', '单体电压80', '单体电压81', '单体电压82', '单体电压83', '单体电压84', '单体电压85', '单体电压86', '单体电压87', '单体电压88', '单体电压89', '单体电压90', '单体电压91', '单体电压92', '单体电压93', '单体电压94', '单体电压95', '单体电压96', '单体电压97', '单体电压98', '单体电压99', '单体电压100', '单体电压101', '单体电压102', '单体电压103', '单体电压104', '单体电压105', '单体电压106', '单体电压107', '单体电压108', '单体电压109', '单体电压110', '单体电压111', '单体电压112', '单体电压113', '单体电压114', '单体电压115', '单体电压116', '单体电压117', '单体电压118', '单体电压119', '单体电压120']].values vol_array = vol_array.astype(float) cur_array = data['总电流[A]'].values upload_time = data['时间戳'].values pack_soc_arr = np.zeros(len(cur_array)) vol_array_zero = vol_array[0] / 1000 vol_array_zero[vol_array_zero > 3.3795] = 3.37 if ~len(soc_zero): soc_zero = SocLook(vol_array_zero) pack_capacity = PackCapacityCalculate(soc_zero, capacity) pack_soc_arr[0] = PackSocCalculate(soc_zero, pack_capacity, capacity) for index in range(len(data) - 1): if abs(cur_array[index]) >= 100: if index > 1: vol_array[index] = vol_array[index - 1] cur_array[index] = cur_array[index - 1] if index == 0: upload_time[index + 1] = str_to_date(upload_time[index + 1]) upload_time[index] = str_to_date(upload_time[index]) else: upload_time[index + 1] = str_to_date(upload_time[index + 1]) deltaTime = upload_time[index + 1] - upload_time[index] # deltaTime = str_to_date(upload_time[index + 1]) - str_to_date(upload_time[index]) deltaTime = float(deltaTime.seconds) soc = AhCalculate(soc_zero, cur_array[index], deltaTime, pack_capacity) chg_time, dis_time, shelve_time, flag = ChgStatus(cur_array[index], chg_time, dis_time, shelve_time) if chg_time > 600: soc = ChgFullFunc(soc, vol_array[index]) if dis_time > 600: soc = DisFullFunc(soc, vol_array[index]) if shelve_time > 1800: if vol_array[index][0] > 3.328 or vol_array[index][0] < 3.285: soc_zero = SocLook(vol_array[index]) if flag: if np.min(vol_array[index]) >= 3.0: c_capacity = CumulativeCapacity(c_capacity, cur_array[index], deltaTime) if not flag and c_capacity != 0: capacity = c_capacity pack_soc = PackSocCalculate(soc, pack_capacity, capacity) pack_soc_arr[index + 1] = pack_soc ram_result = {'sn': sn, 'capacity': capacity, 'chg_time': chg_time, 'dis_time': dis_time, 'shelve_time': shelve_time, 'soc_zero': soc_zero, 'c_capacity': c_capacity} sn_list = [] if SOC_DATA: for ram in SOC_DATA: sn_list.append(ram['sn']) if ram['sn'] == sn: ram['capacity'] = capacity ram['chg_time'] = chg_time ram['dis_time'] = dis_time ram['shelve_time'] = shelve_time ram['soc_zero'] = soc_zero ram['c_capacity'] = c_capacity if sn not in sn_list: SOC_DATA.append(ram_result) else: SOC_DATA.append(ram_result) pack_soc_arr = pack_soc_arr * 100 result = {'SN': sn, 'SOC': pack_soc_arr[-1], 'UploadTime': upload_time[-1]} result = pd.DataFrame(result, index=[0]) # pack_soc_frame = pd.DataFrame(pack_soc_arr, columns=['SOC']) # result = pack_soc_frame.assign(UploadTime=upload_time) return result except Exception as exc: logger.warning(exc)