NCMSoh 20210716.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. # 获取数据
  2. from LIB.BACKEND import DBManager
  3. import os
  4. import pandas as pd
  5. import numpy as np
  6. # import matplotlib.pyplot as plt
  7. #参数输入
  8. Capacity = 41
  9. PackFullChrgVolt=69.99
  10. CellFullChrgVolt=3.5
  11. CellVoltNums=17
  12. CellTempNums=4
  13. FullChrgSoc=98
  14. PeakSoc=57
  15. # #40Ah-OCV
  16. LookTab_SOC = [0, 3.534883489, 8.358178409, 13.18141871, 18.00471528, 22.82796155, 27.65123833, 32.47444668, 37.29772717, 42.12099502, 46.94423182, 51.76744813, 56.59070685, 61.4139927, 66.23719857, 71.0604667, 75.88373853, 80.70702266, 85.5302705, 90.35352009, 95.17676458, 100]
  17. LookTab_OCV = [3.3159, 3.4384, 3.4774, 3.5156, 3.5478, 3.5748, 3.6058, 3.6238, 3.638, 3.6535, 3.6715, 3.6951, 3.7279, 3.7757, 3.8126, 3.8529, 3.8969, 3.9446, 3.9946, 4.0491, 4.109, 4.183]
  18. # #55Ah-OCV
  19. # LookTab_SOC = [0.00, 2.40, 6.38, 10.37, 14.35, 18.33, 22.32, 26.30, 30.28, 35.26, 40.24, 45.22, 50.20, 54.19, 58.17, 60.16, 65.14, 70.12, 75.10, 80.08, 84.06, 88.05, 92.03, 96.02, 100.00]
  20. # LookTab_OCV = [2.7151, 3.0298, 3.1935, 3.2009, 3.2167, 3.2393, 3.2561, 3.2703, 3.2843, 3.2871, 3.2874, 3.2868, 3.2896, 3.2917, 3.2967, 3.3128, 3.3283, 3.3286, 3.3287, 3.3288, 3.3289, 3.3296, 3.3302, 3.3314, 3.3429]
  21. #参数初始化
  22. Soh3=[]
  23. Time3=[]
  24. Bms_Soh3=[]
  25. Soh_Err3=[]
  26. sn_list=[]
  27. #输入一个含有‘SN号’的xlsx
  28. SNdata = pd.read_excel('骑享资产梳理-20210621.xlsx', sheet_name='6040骑享')
  29. SNnums=SNdata['SN号']
  30. for k in range(len(SNnums)):
  31. SNnum=str(SNnums[k])
  32. sn = SNnum
  33. st = '2021-07-06 00:00:00'
  34. et = '2021-07-07 20:00:00'
  35. dbManager = DBManager.DBManager()
  36. df_data = dbManager.get_data(sn=sn, start_time=st, end_time=et, data_groups=['bms'])
  37. #
  38. data = df_data['bms']
  39. print(data)
  40. packcrnt=data['总电流[A]']
  41. packvolt=data['总电压[V]']
  42. SOC=data['SOC[%]']
  43. SOH=data['SOH[%]']
  44. bmsstat=data['充电状态']
  45. time= pd.to_datetime(data['时间戳'], format='%Y-%m-%d %H:%M:%S')
  46. #第一步:筛选充电数据
  47. if len(packcrnt)>100:
  48. ChgStart=[]
  49. ChgEnd=[]
  50. for i in range(3, len(time) - 3):
  51. if i==3 and bmsstat[i]==2 and bmsstat[i+1]==2 and bmsstat[i+2]==2:
  52. ChgStart.append(i)
  53. elif bmsstat[i-2]!=2 and bmsstat[i-1]!=2 and bmsstat[i]==2:
  54. ChgStart.append(i)
  55. elif bmsstat[i-1]==2 and bmsstat[i]!=2 and bmsstat[i+1]!=2:
  56. ChgEnd.append(i-1)
  57. elif i == (len(time) - 4) and bmsstat[len(bmsstat)-1] == 2 and bmsstat[len(bmsstat)-2] == 2:
  58. ChgEnd.append(len(time)-2)
  59. print(ChgStart)
  60. print(ChgEnd)
  61. #第二步:筛选充电起始Soc<45% & SOC>85%,电芯温度>5℃
  62. ChgStartValid1=[]
  63. ChgEndValid1=[]
  64. ChgStartValid2=[]
  65. ChgEndValid2=[]
  66. StandingNum=[]
  67. for i in range(min(len(ChgStart),len(ChgEnd))):
  68. #获取最小温度值
  69. celltemp = []
  70. for j in range(1, CellTempNums+1):
  71. s = str(j)
  72. temp = data['单体温度' + s]
  73. celltemp.append(temp[ChgEnd[i]])
  74. #去除电流0点
  75. for k in range(ChgStart[i],ChgEnd[i]):
  76. if packcrnt[k]<-0.5 and packcrnt[k+1]>-0.5 and packcrnt[k+2]>-0.5 and packcrnt[k+3]>-0.5:
  77. ChgEnd[i]=k
  78. #计算最大packvolt
  79. if len(packvolt[ChgStart[i]:ChgEnd[i]])>0:
  80. packvoltMAX=max(packvolt[ChgStart[i]:ChgEnd[i]])
  81. #筛选满足2点法计算的数据
  82. StandingTime=0
  83. StandingTime1=0
  84. StandingTime2=0
  85. if SOC[ChgEnd[i]]>85 and SOC[ChgStart[i]]<45 and min(celltemp)>5:
  86. for m in range(min(len(packcrnt)-ChgEnd[i]-2,ChgStart[i]-2)):
  87. if abs(packcrnt[ChgStart[i] - m - 1]) < 0.1:
  88. StandingTime = StandingTime + (time[ChgStart[i] - m] - time[ChgStart[i] - m - 1]).total_seconds()
  89. if abs(packcrnt[ChgEnd[i] + m + 1]) < 0.1:
  90. StandingTime1 = StandingTime1 + (time[ChgEnd[i] + m + 1] - time[ChgEnd[i] + m]).total_seconds()
  91. if StandingTime > 900 and StandingTime1>900 and ((time[ChgEnd[i]]-time[ChgStart[i]]).total_seconds())/(ChgEnd[i]-ChgStart[i])<60: #筛选静置时间>15min且慢充过程丢失数据少
  92. ChgStartValid1.append(ChgStart[i])
  93. ChgEndValid1.append(ChgEnd[i])
  94. StandingNum.append(m)
  95. break
  96. if abs(packcrnt[ChgStart[i] - m - 2])>0.5 and abs(packcrnt[ChgEnd[i] + m + 2])>0.5:
  97. break
  98. #筛选满充的数据
  99. # for m in range(min(len(packcrnt)-ChgEnd[i],ChgStart[i]-2)):
  100. # if abs(packcrnt[ChgStart[i] - m - 2]) < 0.1 and abs(packcrnt[ChgEnd[i] + m + 2]) < 0.1:
  101. # StandingTime = StandingTime + (time[ChgStart[i] - m] - time[ChgStart[i] - m - 1]).total_seconds()
  102. # if StandingTime>1200 and packvoltMAX>PackFullChrgVolt:
  103. # ChgStartValid2.append(ChgStart[i])
  104. # ChgEndValid2.append(ChgEnd[i])
  105. # break
  106. # elif abs(packcrnt[ChgStart[i] - m - 2])>0.5:
  107. # break
  108. # else:
  109. # break
  110. print(ChgStart)
  111. print(ChgEnd)
  112. print(ChgStartValid1)
  113. print(ChgEndValid1)
  114. print(StandingNum)
  115. # 计算soh
  116. Soh1=[]
  117. Soh2=[]
  118. Time1=[]
  119. Bms_Soh1=[]
  120. Soh_Err1=[]
  121. #两点法计算Soh
  122. if len(ChgStartValid1)>0:
  123. for i in range(len(ChgStartValid1)):
  124. #计算Ah
  125. Ah=0
  126. for j in range(ChgStartValid1[i],ChgEndValid1[i]):
  127. Step=(time[j+1]-time[j]).total_seconds()
  128. Ah=Ah-packcrnt[j+1]*Step/3600
  129. #计算每个电芯的Soh
  130. for j in range(1, CellVoltNums+1):
  131. s = str(j)
  132. cellvolt = data['单体电压' + s]/1000
  133. OCVStart=cellvolt[ChgStartValid1[i]-2]
  134. OCVEnd=cellvolt[ChgEndValid1[i]+StandingNum[i]]
  135. #soh
  136. Ocv_Soc1=np.interp(OCVStart,LookTab_OCV,LookTab_SOC)
  137. Ocv_Soc2=np.interp(OCVEnd,LookTab_OCV,LookTab_SOC)
  138. Soh2.append(Ah*100/((Ocv_Soc2-Ocv_Soc1)*0.01*Capacity))
  139. Soh1.append(np.mean(Soh2))
  140. Bms_Soh1.append(SOH[ChgStartValid1[i]])
  141. Soh_Err1.append(Bms_Soh1[-1]-Soh1[-1])
  142. Time1.append(time[ChgStartValid1[i]])
  143. Soh3.append(np.mean(Soh1))
  144. Bms_Soh3.append(np.mean(Bms_Soh1))
  145. Soh_Err3.append(np.mean(Soh_Err1))
  146. Time3.append(time[ChgStartValid1[-1]])
  147. sn_list.append(SNnum)
  148. # ax1 = plt.subplot(3, 1, 1)
  149. # plt.plot(xvolt[10:-10],DVDQ[10:-10],'r*-')
  150. # ax1 = plt.subplot(3, 1, 2)
  151. # plt.plot(soc2[10:-10],xvolt[10:-10],'y*-')
  152. # ax1 = plt.subplot(3, 1, 3)
  153. # plt.plot(soc2[10:-10], DVDQ[10:-10], 'r*-')
  154. # plt.show()
  155. #第四步:将数据存入Excel
  156. result_soh2={'时间': Time1,
  157. 'BMS_SOH': Bms_Soh1,
  158. 'SOH': Soh1,
  159. 'SOH误差': Soh_Err1}
  160. Result_Soh2=pd.DataFrame(result_soh2)
  161. print(Result_Soh2)
  162. Result_Soh2.to_csv('BMS_SOH_'+SNnum+'.csv',encoding='GB18030')
  163. # result_soh1={'时间': Time3,
  164. # 'SN号':sn_list,
  165. # 'BMS_SOH': Bms_Soh3,
  166. # 'SOH': Soh3,
  167. # 'SOH误差': Soh_Err3}
  168. # Result_Soh1=pd.DataFrame(result_soh1)
  169. # print(Result_Soh1)
  170. # Result_Soh1.to_csv('BMS_SOH_'+'6040'+'.csv',encoding='GB18030')