soc.py 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. import numpy as np
  2. import datetime
  3. from scipy import interpolate
  4. import logging
  5. import pandas as pd
  6. # 电压范围3.0 - 3.5
  7. 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,
  8. 0.90, 0.95, 1.00]
  9. 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,
  10. 3.3277, 3.3277, 3.3280, 3.3286, 3.3289, 3.3296, 3.3311, 3.3795] # 磷酸铁锂
  11. SocLook = interpolate.interp1d(DisOcvCurve, SocCurve, kind='slinear')
  12. ChgNearFullVol = 3.5 # v
  13. DisNearFullVol = 3.0 # v
  14. logger = logging.getLogger(__file__)
  15. def str_to_date(date_string, format='%Y-%m-%d %H:%M:%S', alternative=None):
  16. try:
  17. return datetime.datetime.strptime(date_string, format)
  18. except Exception as e:
  19. pass
  20. return alternative
  21. # 安时积分法
  22. def AhCalculate(soc, cur, deltaTime, capacity):
  23. try:
  24. soc = soc + cur * deltaTime / capacity / 3600
  25. except Exception as exc:
  26. logger.warning(exc)
  27. return soc
  28. # 判断充放电状态
  29. def ChgStatus(cur, chg_time, dis_time, shelve_time):
  30. flag = False
  31. if cur > 1:
  32. chg_time += 1
  33. if cur < -1:
  34. dis_time += 1
  35. flag = True
  36. if cur == 0:
  37. shelve_time += 1
  38. chg_time = 0
  39. dis_time = 0
  40. return chg_time, dis_time, shelve_time, flag
  41. # 电芯容量校正
  42. def CapacityCalculate(soc, soc_zero, cumulative_capacity, t_capacity):
  43. s = soc - soc_zero
  44. c = cumulative_capacity - t_capacity
  45. try:
  46. capacity = c / s
  47. except Exception as exc:
  48. logger.warning(exc)
  49. capacity = 120
  50. return capacity
  51. # 累积容量计算
  52. def CumulativeCapacity(capacity, cur, deltaTime):
  53. capacity = capacity + cur * deltaTime / 3600
  54. return capacity
  55. # 电池包容量计算
  56. def PackCapacityCalculate(soc_arr, capacity):
  57. pack_capacity = np.min(soc_arr * capacity) + np.min(capacity - soc_arr * capacity)
  58. return pack_capacity
  59. # 满电校正
  60. def ChgFullFunc(soc, vol):
  61. for index in range(120):
  62. if vol[index] > ChgNearFullVol:
  63. soc[index] = 1
  64. return soc
  65. # 满放校正
  66. def DisFullFunc(soc, vol):
  67. for index in range(120):
  68. if vol[index] < DisNearFullVol:
  69. soc[index] = 0
  70. return soc
  71. # 电池包soc计算
  72. def PackSocCalculate(soc_arr, pack_capacity, capacity):
  73. try:
  74. pack_soc = np.min(soc_arr * capacity) / pack_capacity
  75. if pack_soc > 1:
  76. pack_soc = 1
  77. if pack_soc < 0:
  78. pack_soc = 0
  79. return pack_soc
  80. except Exception as exc:
  81. logger.warning(exc)
  82. SOC_DATA = []
  83. # 执行函数,最后返回的是dataframe形式,有对应的上传时间和soc,应该要关联设备id,这块没有加
  84. def soc_test(sn, data):
  85. try:
  86. global SOC_DATA
  87. capacity = 120 # ah
  88. chg_time = 0
  89. dis_time = 0
  90. shelve_time = 0
  91. c_capacity = 0
  92. soc_zero = []
  93. if SOC_DATA:
  94. for ram in SOC_DATA:
  95. if ram['sn'] == sn:
  96. capacity = ram['capacity']
  97. chg_time = ram['chg_time']
  98. dis_time = ram['dis_time']
  99. shelve_time = ram['shelve_time']
  100. c_capacity = ram['c_capacity']
  101. soc_zero = ram['soc_zero']
  102. vol_array = data[
  103. ['单体电压1', '单体电压2', '单体电压3', '单体电压4', '单体电压5', '单体电压6', '单体电压7', '单体电压8', '单体电压9', '单体电压10', '单体电压11', '单体电压12',
  104. '单体电压13', '单体电压14', '单体电压15', '单体电压16', '单体电压17', '单体电压18', '单体电压19', '单体电压20', '单体电压21', '单体电压22', '单体电压23',
  105. '单体电压24', '单体电压25', '单体电压26', '单体电压27', '单体电压28', '单体电压29', '单体电压30', '单体电压31', '单体电压32', '单体电压33', '单体电压34',
  106. '单体电压35', '单体电压36', '单体电压37', '单体电压38', '单体电压39', '单体电压40', '单体电压41', '单体电压42', '单体电压43', '单体电压44', '单体电压45',
  107. '单体电压46', '单体电压47', '单体电压48', '单体电压49', '单体电压50', '单体电压51', '单体电压52', '单体电压53', '单体电压54', '单体电压55', '单体电压56',
  108. '单体电压57', '单体电压58', '单体电压59', '单体电压60', '单体电压61', '单体电压62', '单体电压63', '单体电压64', '单体电压65', '单体电压66', '单体电压67',
  109. '单体电压68', '单体电压69', '单体电压70', '单体电压71', '单体电压72', '单体电压73', '单体电压74', '单体电压75', '单体电压76', '单体电压77', '单体电压78',
  110. '单体电压79', '单体电压80', '单体电压81', '单体电压82', '单体电压83', '单体电压84', '单体电压85', '单体电压86', '单体电压87', '单体电压88', '单体电压89',
  111. '单体电压90', '单体电压91', '单体电压92', '单体电压93', '单体电压94', '单体电压95', '单体电压96', '单体电压97', '单体电压98', '单体电压99', '单体电压100',
  112. '单体电压101', '单体电压102', '单体电压103', '单体电压104', '单体电压105', '单体电压106', '单体电压107', '单体电压108', '单体电压109', '单体电压110',
  113. '单体电压111', '单体电压112', '单体电压113', '单体电压114', '单体电压115', '单体电压116', '单体电压117', '单体电压118', '单体电压119',
  114. '单体电压120']].values
  115. vol_array = vol_array.astype(float)
  116. cur_array = data['总电流[A]'].values
  117. upload_time = data['时间戳'].values
  118. pack_soc_arr = np.zeros(len(cur_array))
  119. vol_array_zero = vol_array[0] / 1000
  120. vol_array_zero[vol_array_zero > 3.3795] = 3.37
  121. if ~len(soc_zero):
  122. soc_zero = SocLook(vol_array_zero)
  123. pack_capacity = PackCapacityCalculate(soc_zero, capacity)
  124. pack_soc_arr[0] = PackSocCalculate(soc_zero, pack_capacity, capacity)
  125. for index in range(len(data) - 1):
  126. if abs(cur_array[index]) >= 100:
  127. if index > 1:
  128. vol_array[index] = vol_array[index - 1]
  129. cur_array[index] = cur_array[index - 1]
  130. if index == 0:
  131. upload_time[index + 1] = str_to_date(upload_time[index + 1])
  132. upload_time[index] = str_to_date(upload_time[index])
  133. else:
  134. upload_time[index + 1] = str_to_date(upload_time[index + 1])
  135. deltaTime = upload_time[index + 1] - upload_time[index]
  136. # deltaTime = str_to_date(upload_time[index + 1]) - str_to_date(upload_time[index])
  137. deltaTime = float(deltaTime.seconds)
  138. soc = AhCalculate(soc_zero, cur_array[index], deltaTime, pack_capacity)
  139. chg_time, dis_time, shelve_time, flag = ChgStatus(cur_array[index], chg_time, dis_time, shelve_time)
  140. if chg_time > 600:
  141. soc = ChgFullFunc(soc, vol_array[index])
  142. if dis_time > 600:
  143. soc = DisFullFunc(soc, vol_array[index])
  144. if shelve_time > 1800:
  145. if vol_array[index][0] > 3.328 or vol_array[index][0] < 3.285:
  146. soc_zero = SocLook(vol_array[index])
  147. if flag:
  148. if np.min(vol_array[index]) >= 3.0:
  149. c_capacity = CumulativeCapacity(c_capacity, cur_array[index], deltaTime)
  150. if not flag and c_capacity != 0:
  151. capacity = c_capacity
  152. pack_soc = PackSocCalculate(soc, pack_capacity, capacity)
  153. pack_soc_arr[index + 1] = pack_soc
  154. ram_result = {'sn': sn, 'capacity': capacity, 'chg_time': chg_time, 'dis_time': dis_time, 'shelve_time': shelve_time,
  155. 'soc_zero': soc_zero, 'c_capacity': c_capacity}
  156. sn_list = []
  157. if SOC_DATA:
  158. for ram in SOC_DATA:
  159. sn_list.append(ram['sn'])
  160. if ram['sn'] == sn:
  161. ram['capacity'] = capacity
  162. ram['chg_time'] = chg_time
  163. ram['dis_time'] = dis_time
  164. ram['shelve_time'] = shelve_time
  165. ram['soc_zero'] = soc_zero
  166. ram['c_capacity'] = c_capacity
  167. if sn not in sn_list:
  168. SOC_DATA.append(ram_result)
  169. else:
  170. SOC_DATA.append(ram_result)
  171. pack_soc_arr = pack_soc_arr * 100
  172. result = {'SN': sn, 'SOC': pack_soc_arr[-1], 'UploadTime': upload_time[-1]}
  173. result = pd.DataFrame(result, index=[0])
  174. # pack_soc_frame = pd.DataFrame(pack_soc_arr, columns=['SOC'])
  175. # result = pack_soc_frame.assign(UploadTime=upload_time)
  176. return result
  177. except Exception as exc:
  178. logger.warning(exc)