Bladeren bron

Merge remote-tracking branch 'origin/dev' into pro

lmstack 3 jaren geleden
bovenliggende
commit
358d2b5f73
25 gewijzigde bestanden met toevoegingen van 1269 en 492 verwijderingen
  1. 1 2
      LIB/BACKEND/Log.py
  2. 150 0
      LIB/FRONTEND/day_sta.py
  3. 14 8
      LIB/MIDDLE/CellStateEstimation/Common/BatParam.py
  4. 0 0
      LIB/MIDDLE/CellStateEstimation/Common/DBDownload.py
  5. 0 0
      LIB/MIDDLE/CellStateEstimation/Common/log.py
  6. 565 0
      LIB/MIDDLE/CellStateEstimation/InterShort/V1_0_0/CBMSBatInterShort.py
  7. BIN
      LIB/MIDDLE/CellStateEstimation/InterShort/V1_0_0/InterShort表单.xlsx
  8. 80 0
      LIB/MIDDLE/CellStateEstimation/InterShort/main.py
  9. 41 45
      LIB/MIDDLE/CellStateEstimation/SOH/V1_0_0/CBMSBatSoh.py
  10. 12 11
      LIB/MIDDLE/CellStateEstimation/SOH/main.py
  11. 0 91
      LIB/MIDDLE/CellStateEstimation/Uniform/V1_0_0/BatParam.py
  12. 26 26
      LIB/MIDDLE/CellStateEstimation/Uniform/V1_0_0/CBMSBatUniform.py
  13. 0 24
      LIB/MIDDLE/CellStateEstimation/Uniform/V1_0_0/log.py
  14. 0 73
      LIB/MIDDLE/CellStateEstimation/Uniform/V1_0_0/main.py
  15. 7 2
      LIB/MIDDLE/CellStateEstimation/Uniform/main.py
  16. BIN
      LIB/MIDDLE/CellStateEstimation/算法运行周期.xlsx
  17. 199 0
      LIB/MIDDLE/IndexStaByOneCycle.py
  18. 174 0
      LIB/MIDDLE/IndexStaByPeriod.py
  19. 0 160
      LIB/MIDDLE/LeakCurrent/LFPLeakCurrent20210812.py
  20. 0 23
      LIB/MIDDLE/LeakCurrent/LeakCurrent表头及数据类型.xlsx
  21. 0 27
      LIB/MIDDLE/LeakCurrent/main.py
  22. BIN
      PARAMETER/PARAMETER/DTC/平台故障信号定义1.1.xlsx
  23. BIN
      PARAMETER/PARAMETER/DTC/格林美7255电池故障定义.docx
  24. BIN
      PARAMETER/PARAMETER/OCV/安驰55Ah-SOC-OCV-20210618.xlsx
  25. BIN
      PARAMETER/PARAMETER/OCV/格林美7255电池OCV.xlsx

+ 1 - 2
LIB/BACKEND/Log.py

@@ -58,5 +58,4 @@ class Mylog:
         if log_level == 'warning':
             self.logger.setLevel(logging.WARNING)
         if log_level == 'error':
-            self.logger.setLevel(logging.ERROR)
-
+            self.logger.setLevel(logging.ERROR)

+ 150 - 0
LIB/FRONTEND/day_sta.py

@@ -1,4 +1,153 @@
+<<<<<<< HEAD
+<<<<<<< HEAD
+__author__ = 'lmstack'
+
+# 每日指标统计函数
+import CONFIGURE.PathSetting as PathSetting
+import sys
+sys.path.append(PathSetting.backend_path)
+sys.path.append(PathSetting.middle_path)
+import DBManager
+import Tools
+import DataPreProcess
+import IndexStaByPeriod
+import Log
+import IndexStaByPeriod
+import importlib
+import datetime
+import os
+import pandas as pd
+import time
+importlib.reload(IndexStaByPeriod)
+
+dbManager = DBManager.DBManager()
+dataPrePro = DataPreProcess.DataPreProcess()
+indexPerSta = IndexStaByPeriod.IndexStaByPeriod()
+
+# log 文件配置
+myLog = Log.Mylog('day_sta')
+myLog.set_file_hl(file_name=r'D:\Platform\platform\FRONTEND\day_sta\day_sta.log', log_level='info')
+myLog.set_stream_hl(log_level='info')
+logger = myLog.get_logger()
+logger.info(str(os.getpid()))
+
+# sn文件读取
+sn_list = list(pd.read_excel('D:\Platform\platform\苏州电池列表.xlsx')['sn'])
+sn_list.extend(list(pd.read_excel('D:\Platform\platform\骑享北京6040电池包统计更新20210407.xlsx')['SN号']))
+
+sn = sn_list[0]
+
+# 字段设置及结果文件生成
+columns = ['sn', 'time',  'sumDriveTime', 'sumDriveSoc', 'sumDriveAh', 'sumDriveEnergy']
+st = datetime.datetime.strptime('00:00:00', '%H:%M:%S')
+for i in range(96):
+    et = st + datetime.timedelta(minutes=15)
+    columns.append(st.strftime('%H:%M') + '-' + et.strftime('%H:%M'))
+    st = et
+result_path = r'D:\Platform\platform\FRONTEND\day_sta\result.csv'
+df_res = pd.DataFrame(columns=columns)
+if not os.path.exists(result_path):
+    df_res.to_csv(result_path, index=False)
+    
+# 时间范围设置
+start_time = '{} 00:00:00'.format('2020-01-01')
+end_time = '{} 00:00:00'.format('2021-06-01')
+sta_days = (datetime.datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S') - datetime.datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S')).days
+
+count= 0
+sn_result = {}
+for sn in sn_list[:]:
+    count += 1
+    logger.info('{} start,  {}/{} '.format(sn, str(count), str(len(sn_list))))
+    if sn[2:5] == '500':
+        cap = 40
+    elif sn[2:5] == '504':
+        cap = 55
+    else:
+        logger.info('{} cap error'.format(sn))
+        cap = None
+        continue
+        
+    sn_result.update({'sn':sn})
+    logger.info('{} :{} to {} start'.format(sn, str(start_time), str(end_time)))
+    
+    # 获取数据
+    df_bms, df_gps = dbManager.get_data(sn=sn, start_time=start_time, end_time=end_time, gps_switch=True, mode=0)
+    if df_bms.empty:
+        continue
+    # 数据预处理
+    
+    # 时间完全相同的数据仅保留一行
+    df_bms_pro, df_gps_pro = dataPrePro.time_filter(df_bms, df_gps)
+    
+    # bms数据按照电流和状态分段, 然后在状态分段内部,根据时间跳变继续分段(解决段内数据丢失)
+    df_bms_pro = dataPrePro.data_split_by_status(df_bms_pro)
+    df_bms_pro = dataPrePro.data_split_by_time(df_bms_pro)
+
+    # bms数据将两次充电间的状态合并
+    df_bms_pro = dataPrePro.combine_drive_stand(df_bms_pro)
+    # bms 数据计算行车和充电开始前后的静置时间
+    df_bms_pro = dataPrePro.cal_stand_time(df_bms_pro)
+    # gps 数据可靠性判断, 并增加里程和速度至gps数据(根据未合并的数据段判断)
+    df_bms_pro, df_gps_pro, res_record= dataPrePro.gps_data_judge(df_bms_pro, df_gps_pro)
+    # gps 数据可靠性判断, 并增加里程和速度至gps数据(根据已合并的数据段判断)
+    df_bms_pro, df_gps_pro, res_record= dataPrePro.data_gps_judge_after_combine(df_bms_pro, df_gps_pro)
+    
+    for sta_day in range(sta_days):
+        try:
+            st_ = datetime.datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S') + datetime.timedelta(days=sta_day)
+            et_ =datetime.datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S') + datetime.timedelta(days=sta_day+1)
+
+        # 按天统计指标
+            sn_result.update({'time':st_.strftime('%Y-%m-%d')})
+
+            df_bms_period = df_bms_pro[(df_bms_pro['时间戳'] > st_.strftime('%Y-%m-%d %H:%M:%S')) & (df_bms_pro['时间戳'] <= et_.strftime('%Y-%m-%d %H:%M:%S'))]
+            #df_gps_period = df_gps_pro[(df_gps_pro['时间戳'] > st_.strftime('%Y-%m-%d %H:%M:%S')) & (df_gps_pro['时间戳'] <= et_.strftime('%Y-%m-%d %H:%M:%S'))]
+            sn_result.update({'sumDriveTime':[indexPerSta.drive_time_sta(df_bms_period)]})
+            sn_result.update({'sumDriveSoc':[indexPerSta.drive_soc_sta(df_bms_period)]})
+            sn_result.update({'sumDriveAh':[indexPerSta.drive_capacity_sta(cap, df_bms_period)]})
+            sn_result.update({'sumDriveEnergy':[indexPerSta.drive_energy_sta(cap, df_bms_period)]})
+
+            # 每天间隔15分钟 统计一次
+            for i in range(96):
+                cur_result = []
+                st__ = st_ + datetime.timedelta(minutes=15 * i)
+                et__ = st_ + datetime.timedelta(minutes=15 * (i+1))
+                df_bms_period = df_bms_pro[(df_bms_pro['时间戳'] > st__.strftime('%Y-%m-%d %H:%M:%S')) & (df_bms_pro['时间戳'] <= et__.strftime('%Y-%m-%d %H:%M:%S'))]
+                #df_gps_period = df_gps_pro[(df_gps_pro['时间戳'] > st__.strftime('%Y-%m-%d %H:%M:%S')) & (df_gps_pro['时间戳'] <= et__.strftime('%Y-%m-%d %H:%M:%S'))]
+                cur_result.append(indexPerSta.drive_time_sta(df_bms_period))
+                cur_result.append(indexPerSta.drive_soc_sta(df_bms_period))
+                cur_result.append(indexPerSta.drive_capacity_sta(cap, df_bms_period))
+                cur_result.append(indexPerSta.drive_energy_sta(cap, df_bms_period))
+                key = st__.strftime('%H:%M') + '-' + et__.strftime('%H:%M')
+                sn_result.update({key:[cur_result]})
+            df_cur_res = pd.DataFrame(sn_result)
+            df_cur_res = df_cur_res[columns]
+
+            # 防止写入结果时,结果文件被打开
+            write_flag = False
+            while not write_flag:
+                try:
+                    df_cur_res.to_csv(result_path, mode='a+', index=False,  header=False)
+                except PermissionError as e:
+                    logger.info('{} error:{}'.format(sn, str(e)))
+                    time.sleep(10)
+                    continue
+                else:
+                    write_flag = True 
+        except Exception as e:
+                logger.info('{} {}_{} error: {}'.format(sn, st_.strftime('%Y-%m-%d %H:%M:%S'), et_.strftime('%Y-%m-%d %H:%M:%S'), str(e)))
+                continue
+        else:
+            continue
+    logger.info('{} done,  {}/{} '.format(sn, str(count), str(len(sn_list))))
+ 
+        
+=======
+__author__ = 'Wang Liming'
+=======
 __author__ = 'lmstack'
+>>>>>>> 0fdacae7667a378900d95748e2f53901ada95b8c
 
 # 每日指标统计函数
 # import CONFIGURE.PathSetting as PathSetting
@@ -142,3 +291,4 @@ for sn in sn_list[:]:
     logger.info('{} done,  {}/{} '.format(sn, str(count), str(len(sn_list))))
  
         
+>>>>>>> 65a87ae16013552e359df047df19f46fc4e6eb08

+ 14 - 8
LIB/MIDDLE/CellStateEstimation/SOH/V1_0_0/BatParam.py → LIB/MIDDLE/CellStateEstimation/Common/BatParam.py

@@ -30,8 +30,9 @@ class BatParam:
             self.FullChrgSoc=98
             self.PeakSoc=57
             self.PackCrntDec=1
-            self.LookTab_SOC = [0,	    3.5348,	8.3581,	13.181,	18.004,	22.827,	27.651,	32.474,	37.297,	42.120,	46.944,	51.767,	56.590,	61.413,	66.237,	71.060,	75.883,	80.707,	85.530,	90.353,	95.176,	100]
-            self.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]
+            self.BalCurrent=0.025
+            self.LookTab_SOC = [0,	    3.5348,	8.3581,	13.181,	18.004,	22.827,	27.651,	32.474,	37.297,	42.120,	46.944,	51.767,	56.590,	61.413,	66.237,	71.060,	75.883,	80.707,	85.530,	90.353,	95.176,	100,   105]
+            self.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, 4.263]
         
         elif celltype==2: #4840
             self.Capacity = 41
@@ -42,8 +43,9 @@ class BatParam:
             self.FullChrgSoc=98
             self.PeakSoc=57
             self.PackCrntDec=1
-            self.LookTab_SOC = [0,	    3.5348,	8.3581,	13.181,	18.004,	22.827,	27.651,	32.474,	37.297,	42.120,	46.944,	51.767,	56.590,	61.413,	66.237,	71.060,	75.883,	80.707,	85.530,	90.353,	95.176,	100]
-            self.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]
+            self.BalCurrent=0.025
+            self.LookTab_SOC = [0,	    3.5348,	8.3581,	13.181,	18.004,	22.827,	27.651,	32.474,	37.297,	42.120,	46.944,	51.767,	56.590,	61.413,	66.237,	71.060,	75.883,	80.707,	85.530,	90.353,	95.176,	100,   105]
+            self.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, 4.263]
         
         elif celltype==3:   #力信50ah三元电芯
             self.Capacity = 51
@@ -54,8 +56,9 @@ class BatParam:
             self.FullChrgSoc=98
             self.PeakSoc=57
             self.PackCrntDec=1
-            self.LookTab_SOC = [0,	    5,	    10,	    15,	    20,	    25,	    30,	    35,	    40,	    45,	    50,	    55,	    60,	    65,	    70,	    75,	    80,	    85,	    90,	    95,	    100]
-            self.LookTab_OCV = [3.357, 	3.455, 	3.493, 	3.540, 	3.577, 	3.605, 	3.622, 	3.638, 	3.655, 	3.677, 	3.707, 	3.757, 	3.815, 	3.866, 	3.920, 	3.976, 	4.036, 	4.099, 	4.166, 	4.237, 	4.325]
+            self.BalCurrent=0.025
+            self.LookTab_SOC = [0,	    5,	    10,	    15,	    20,	    25,	    30,	    35,	    40,	    45,	    50,	    55,	    60,	    65,	    70,	    75,	    80,	    85,	    90,	    95,	    100,   105]
+            self.LookTab_OCV = [3.357, 	3.455, 	3.493, 	3.540, 	3.577, 	3.605, 	3.622, 	3.638, 	3.655, 	3.677, 	3.707, 	3.757, 	3.815, 	3.866, 	3.920, 	3.976, 	4.036, 	4.099, 	4.166, 	4.237, 	4.325, 4.415]
         
         elif celltype==4:   #CATL 50ah三元电芯
             self.Capacity = 50
@@ -66,8 +69,9 @@ class BatParam:
             self.FullChrgSoc=98
             self.PeakSoc=57
             self.PackCrntDec=-1
-            self.LookTab_SOC = [0,	    5,	    10,	    15,	    20,	    25,	    30,	    35,	    40,	    45,	    50,	    55,	    60,	    65,	    70,	    75,	    80,	    85,	    90,	    95,	    100]
-            self.LookTab_OCV = [3.152, 	3.397, 	3.438, 	3.481, 	3.523, 	3.560, 	3.586, 	3.604, 	3.620, 	3.638, 	3.661, 	3.693, 	3.748, 	3.803, 	3.853, 	3.903, 	3.953, 	4.006, 	4.063, 	4.121, 	4.183]
+            self.BalCurrent=0.025
+            self.LookTab_SOC = [0,	    5,	    10,	    15,	    20,	    25,	    30,	    35,	    40,	    45,	    50,	    55,	    60,	    65,	    70,	    75,	    80,	    85,	    90,	    95,	    100,   105]
+            self.LookTab_OCV = [3.152, 	3.397, 	3.438, 	3.481, 	3.523, 	3.560, 	3.586, 	3.604, 	3.620, 	3.638, 	3.661, 	3.693, 	3.748, 	3.803, 	3.853, 	3.903, 	3.953, 	4.006, 	4.063, 	4.121, 	4.183, 4.253]
         
         elif celltype==99:   #60ah磷酸铁锂电芯
             self.Capacity = 54
@@ -81,7 +85,9 @@ class BatParam:
             self.CellTempNums=4
             self.FullChrgSoc=98
             self.PeakSoc=60.5
+            self.PeakCellVolt=[3.357,3.358,3.359,3.36,3.361]
             self.PackCrntDec=1
+            self.BalCurrent=0.025
             self.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]
             self.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]
         

+ 0 - 0
LIB/MIDDLE/CellStateEstimation/SOH/V1_0_0/DBDownload.py → LIB/MIDDLE/CellStateEstimation/Common/DBDownload.py


+ 0 - 0
LIB/MIDDLE/CellStateEstimation/SOH/V1_0_0/log.py → LIB/MIDDLE/CellStateEstimation/Common/log.py


+ 565 - 0
LIB/MIDDLE/CellStateEstimation/InterShort/V1_0_0/CBMSBatInterShort.py

@@ -0,0 +1,565 @@
+import pandas as pd
+import numpy as np
+import matplotlib.pyplot as plt
+from pymysql import paramstyle
+from LIB.MIDDLE.CellStateEstimation.Common import BatParam
+from LIB.MIDDLE.CellStateEstimation.Common import DBDownload
+
+class BatInterShort:
+    def __init__(self,sn,celltype,df_bms, host, port, db, user, password, tablename):  #参数初始化
+
+        self.sn=sn
+        self.celltype=celltype
+        self.param=BatParam.BatParam(celltype)
+        self.df_bms=df_bms
+        self.packcrnt=df_bms['总电流[A]']*self.param.PackCrntDec
+        self.packvolt=df_bms['总电压[V]']
+        self.bms_soc=df_bms['SOC[%]']
+        self.bmstime= pd.to_datetime(df_bms['时间戳'], format='%Y-%m-%d %H:%M:%S')
+
+        self.host=host
+        self.port=port
+        self.db=db
+        self.user=user
+        self.password=password
+        self.tablename=tablename
+    
+    def intershort(self):
+        if self.celltype==1 or self.celltype==2 or self.celltype==3 or self.celltype==4:
+            df_res=self._ncm_intershort()
+            return df_res
+            
+        elif self.celltype==99:
+            df_res=self._lfp_intershort()
+            return df_res
+        
+        else:
+            return pd.DataFrame()
+    
+    #获取预算结果库的结果...............................................................................
+    def getdata(self):  
+        DBManager=DBDownload.DBDownload(self.host, self.port, self.db, self.user, self.password)
+        with DBManager as DBManager:
+            self.df_soh=DBManager.getdata('time_st','time_sp','sn','method','soh','cellsoh', tablename='soh_result', sn=self.sn)
+
+    #定义滑动滤波函数....................................................................................
+    def _np_move_avg(self,a, n, mode="same"): 
+        return (np.convolve(a, np.ones((n,)) / n, mode=mode))
+    
+    #寻找当前行数据的最小温度值.............................................................................
+    def _celltemp_weight(self,num):   
+        celltemp = []
+        for j in range(1, self.param.CellTempNums+1):
+            s = str(j)
+            celltemp.append(self.df_bms.loc[num,'单体温度' + s])
+        celltemp=np.mean(celltemp)
+        self.celltemp=celltemp
+        if self.celltype==99:
+            if celltemp>=20:
+                self.tempweight=1
+                self.StandardStandingTime=3600
+            elif celltemp>=10:
+                self.tempweight=0.6
+                self.StandardStandingTime=7200
+            elif celltemp>=5:
+                self.tempweight=0.
+                self.StandardStandingTime=7200
+            else:
+                self.tempweight=0.1
+                self.StandardStandingTime=10800
+        else:
+            if celltemp>=20:
+                self.tempweight=1
+                self.StandardStandingTime=3600
+            elif celltemp>=10:
+                self.tempweight=0.8
+                self.StandardStandingTime=3600
+            elif celltemp>=5:
+                self.tempweight=0.6
+                self.StandardStandingTime=7200
+            else:
+                self.tempweight=0.2
+                self.StandardStandingTime=10800
+
+    #获取当前行所有电压数据........................................................................................
+    def _cellvolt_get(self,num): 
+        cellvolt=[]
+        for j in range(1, self.param.CellVoltNums+1): 
+            s = str(j)
+            cellvolt.append(self.df_bms.loc[num,'单体电压' + s]/1000)
+        return cellvolt
+
+    #获取当前行所有soc差...........................................................................................
+    def _celldeltsoc_get(self,num,dict_baltime,capacity): 
+        cellsoc=[]
+        celldeltsoc=[]
+        for j in range(1, self.param.CellVoltNums+1):   #获取每个电芯电压对应的SOC值
+            cellvolt=self.df_bms.loc[num,'单体电压' + str(j)]/1000
+            ocv_soc=np.interp(cellvolt,self.param.LookTab_OCV,self.param.LookTab_SOC)
+            if j in dict_baltime.keys():
+                ocv_soc=ocv_soc+dict_baltime[j]*self.param.BalCurrent/(capacity*3600)   #补偿均衡电流
+            else:
+                pass
+            cellsoc.append(ocv_soc)
+        
+        if self.celltype==1 or self.celltype==2:
+            consum_num=7
+            cellsoc1=cellsoc[:self.param.CellVoltNums-consum_num]    #切片,将bms耗电的电芯和非耗电的电芯分离开
+            cellsocmean1=(sum(cellsoc1)-max(cellsoc1)-min(cellsoc1))/(len(cellsoc1)-2)
+            cellsoc2=cellsoc[self.param.CellVoltNums-consum_num:]
+            cellsocmean2=(sum(cellsoc2)-max(cellsoc2)-min(cellsoc2))/(len(cellsoc2)-2)
+            
+            for j in range(len(cellsoc)):   #计算每个电芯的soc差
+                if j<self.param.CellVoltNums-consum_num:
+                    celldeltsoc.append(cellsoc[j]-cellsocmean1)
+                else:
+                    celldeltsoc.append(cellsoc[j]-cellsocmean2)
+            return celldeltsoc
+
+        else:
+            cellsocmean=(sum(cellsoc)-max(cellsoc)-min(cellsoc))/(len(cellsoc)-2)
+            for j in range(len(cellsoc)):   #计算每个电芯的soc差
+                celldeltsoc.append(cellsoc[j]-cellsocmean)
+            return celldeltsoc
+ 
+    #获取所有电芯的As差
+    def _cellDeltAs_get(self,chrg_st,chrg_end,dict_baltime):
+        cellAs=[]
+        celldeltAs=[]
+        for j in range(1, self.param.CellVoltNums+1):   #获取每个电芯电压>峰值电压的充入As数
+            if j in dict_baltime.keys():    #补偿均衡电流
+                As=-self.param.BalCurrent*dict_baltime[j]
+            else:    
+                As=0
+            As_tatol=0
+            symbol=0
+            for m in range(chrg_st+1,chrg_end):
+                As=As-self.packcrnt[m]*(self.bmstime[m]-self.bmstime[m-1]).total_seconds()
+                if symbol<5:
+                    if self.df_bms.loc[m,'单体电压'+str(j)]/1000>self.param.PeakCellVolt[symbol]:
+                        As_tatol=As_tatol+As
+                        symbol=symbol+1
+                    else:
+                        continue
+                else:
+                    cellAs.append(As_tatol/5)
+                    break
+        
+        if self.celltype==99:
+            consum_num=10
+            cellAs1=cellAs[:self.param.CellVoltNums-consum_num]    #切片,将bms耗电的电芯和非耗电的电芯分离开
+            cellAsmean1=(sum(cellAs1)-max(cellAs1)-min(cellAs1))/(len(cellAs1)-2)
+            cellAs2=cellAs[self.param.CellVoltNums-consum_num:]
+            cellAsmean2=(sum(cellAs2)-max(cellAs2)-min(cellAs2))/(len(cellAs2)-2)
+            
+            for j in range(len(cellAs)):   #计算每个电芯的soc差
+                if j<self.param.CellVoltNums-consum_num:
+                    celldeltAs.append(cellAs[j]-cellAsmean1)
+                else:
+                    celldeltAs.append(cellAs[j]-cellAsmean2)
+        else:
+            cellAsmean=(sum(cellAs)-max(cellAs)-min(cellAs))/(len(cellAs)-2)
+            for j in range(len(cellAs)):   #计算每个电芯的soc差
+                celldeltAs.append(cellAs[j]-cellAsmean)
+            
+        return celldeltAs
+
+    #计算每个电芯的均衡时长..........................................................................................................................
+    def _bal_time(self,dict_bal):
+        dict_baltime={}
+        dict_baltime1={}
+        for key in dict_bal:
+            count=1
+            x=eval(key)
+            while x>0:
+                if x & 1==1:    #判断最后一位是否为1
+                    if count in dict_baltime.keys():
+                        dict_baltime[count] = dict_baltime[count] + dict_bal[key]
+                    else:
+                        dict_baltime[count] = dict_bal[key]
+                else:
+                    pass
+                count += 1
+                x >>= 1    #右移一位
+        
+        dict_baltime=dict(sorted(dict_baltime.items(),key=lambda dict_baltime:dict_baltime[0]))
+        for key in dict_baltime:    #解析均衡的电芯编号
+            if self.celltype==1:    #科易6040
+                if key<14:
+                    dict_baltime1[key]=dict_baltime[key]
+                elif key<18:
+                    dict_baltime1[key-1]=dict_baltime[key]
+                else:
+                    dict_baltime1[key-3]=dict_baltime[key]
+            elif self.celltype==1:    #科易4840
+                if key<4:
+                    dict_baltime1[key-1]=dict_baltime[key]
+                elif key<8:
+                    dict_baltime1[key-1]=dict_baltime[key]
+                elif key<14:
+                    dict_baltime1[key-3]=dict_baltime[key]
+                elif key<18:
+                    dict_baltime1[key-4]=dict_baltime[key]
+                else:
+                    dict_baltime1[key-6]=dict_baltime[key]
+            else:
+                dict_baltime1=dict_baltime
+        return dict_baltime1
+
+    #三元电池的内短路电流计算...........................................................................................................................................................
+    def _ncm_intershort(self):
+        column_name=['time_st', 'time_sp', 'sn', 'method','short_current','baltime']
+        df_res=pd.DataFrame(columns=column_name)
+        
+        if not self.df_bms.empty:
+            self.getdata()  #获取电池包的soh
+            if self.df_soh.empty:
+                batsoh=self.df_bms.loc[0,'SOH[%]']
+                capacity=self.param.Capacity*batsoh/100
+            else:
+                batsoh=self.df_soh.loc[len(self.df_soh)-1,'soh']
+                capacity=self.param.Capacity*batsoh/100
+            standingtime=0
+            standingtime1=0
+            firsttime=1
+            firsttime1=1
+            dict_bal={}
+            dict_bal1={}
+
+            for i in range(2,len(self.df_bms)-2):
+
+                if firsttime1==0:   #满电静置算法--计算均衡状态对应的均衡时间
+                    try:
+                        balstat=int(self.df_bms.loc[i,'单体均衡状态'])
+                        if balstat>0.5:
+                            bal_step=(self.bmstime[i+1]-self.bmstime[i]).total_seconds()  #均衡步长
+                            bal_step=int(bal_step)
+                            if str(balstat) in dict_bal1.keys():
+                                dict_bal1[str(balstat)]=dict_bal1[str(balstat)]+bal_step
+                            else:
+                                dict_bal1[str(balstat)]=bal_step
+                        else:
+                            pass
+                    except:
+                        dict_bal1={}
+                else:
+                    pass
+
+                if abs(self.packcrnt[i]) < 0.1 and abs(self.packcrnt[i-1]) < 0.1:     
+                    delttime=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
+                    standingtime=standingtime+delttime
+                    standingtime1=standingtime1+delttime
+                    self._celltemp_weight(i)
+
+                    #静置法计算内短路-开始.....................................................................................................................................
+                    if firsttime==1:    
+                        if standingtime>self.StandardStandingTime:      #静置时间满足要求
+                            dict_baltime=self._bal_time(dict_bal)   #获取每个电芯的均衡时间
+                            deltsoc_last=self._celldeltsoc_get(i,dict_baltime,capacity)
+                            time_last=self.bmstime[i]
+                            firsttime=0
+                            standingtime=0
+                        else:
+                            pass                
+                    elif standingtime>3600*12:
+                        standingtime=0
+                        dict_baltime=self._bal_time(dict_bal)   #获取每个电芯的均衡时间
+                        deltsoc_now=self._celldeltsoc_get(i,dict_baltime,capacity)
+                        time_now=self.bmstime[i]
+                        
+                        list_sub=[a-b for a, b in zip(deltsoc_now, deltsoc_last)]
+                        list_pud=[0.01*capacity*3600*1000/(time_now-time_last).total_seconds()]*self.param.CellVoltNums
+                        leak_current=[a*b for a,b in zip(list_sub,list_pud)]
+                        leak_current=np.array(leak_current)
+                        leak_current=np.round(leak_current,3)
+                        leak_current=list(leak_current)
+                        
+                        df_res.loc[len(df_res)]=[time_last,time_now,self.sn,1,str(leak_current),str(dict_baltime)]  #计算结果存入Dataframe
+                        time_last=time_now  #更新时间
+                        deltsoc_last=deltsoc_now    #更新soc差
+                        dict_bal={}
+                    else: 
+                        try:  
+                            balstat=int(self.df_bms.loc[i,'单体均衡状态'])
+                            if balstat>0.5:
+                                bal_step=(self.bmstime[i+1]-self.bmstime[i]).total_seconds()  #均衡步长
+                                bal_step=int(bal_step)
+                                if str(balstat) in dict_bal.keys():
+                                    dict_bal[str(balstat)]=dict_bal[str(balstat)]+bal_step
+                                else:
+                                    dict_bal[str(balstat)]=bal_step
+                            else:
+                                pass
+                        except:
+                            dict_bal={}
+
+                    #满电静置法计算内短路-开始.....................................................................................................................................................
+                    if standingtime1>self.StandardStandingTime and abs(self.packcrnt[i+2]) >= 0.1:  
+                        standingtime1=0
+                        cellvolt_now1=self._cellvolt_get(i)
+                        cellsoc_now1=np.interp(max(cellvolt_now1),self.param.LookTab_OCV,self.param.LookTab_SOC)
+                        if cellsoc_now1>=self.param.FullChrgSoc-3:
+                            if firsttime1==1:
+                                dict_baltime1=self._bal_time(dict_bal1)   #获取每个电芯的均衡时间
+                                deltsoc_last1=self._celldeltsoc_get(i,dict_baltime1,capacity)
+                                time_last1=self.bmstime[i]
+                                firsttime1=0
+                            else:
+                                dict_baltime1=self._bal_time(dict_bal1)   #获取每个电芯的均衡时间
+                                deltsoc_now1=self._celldeltsoc_get(i,dict_baltime1,capacity)
+                                time_now1=self.bmstime[i]
+
+                                list_sub1=[a-b for a, b in zip(deltsoc_now1, deltsoc_last1)]
+                                list_pud1=[0.01*capacity*3600*1000/(time_now1-time_last1).total_seconds()]*self.param.CellVoltNums
+                                leak_current1=[a*b for a,b in zip(list_sub1,list_pud1)]
+                                leak_current1=np.array(leak_current1)
+                                leak_current1=np.round(leak_current1,3)
+                                leak_current1=list(leak_current1)
+                                
+                                df_res.loc[len(df_res)]=[time_last1,time_now1,self.sn,2,str(leak_current1),str(dict_baltime1)]  #计算结果存入Dataframe
+                                time_last1=time_now1  #更新时间
+                                deltsoc_last1=deltsoc_now1    #更新soc差
+                                dict_bal1={}
+                        else:
+                            pass
+                    else:   
+                        pass
+
+                else:
+                    dict_bal={} 
+                    firsttime=1
+                    standingtime=0
+                    standingtime1=0
+                    pass
+
+        if df_res.empty:    #返回计算结果
+            return pd.DataFrame()
+        else:
+            return df_res
+
+    #磷酸铁锂电池内短路计算程序.............................................................................................................................
+    def _lfp_intershort(self):
+        column_name=['time_st', 'time_sp', 'sn', 'method','short_current','baltime']
+        df_res=pd.DataFrame(columns=column_name)
+        if not self.df_bms.empty:
+            self.getdata()  #获取电池包的soh
+            if self.df_soh.empty:
+                batsoh=self.df_bms.loc[0,'SOH[%]']
+                capacity=self.param.Capacity*batsoh/100
+            else:
+                batsoh=self.df_soh.loc[len(self.df_soh)-1,'soh']
+                capacity=self.param.Capacity*batsoh/100
+            standingtime=0
+            standingtime1=0
+            firsttime=1
+            firsttime1=1
+            dict_bal={}
+            dict_bal1={}
+
+            chrg_start=[]
+            chrg_end=[]
+            dict_bal_list=[]
+            charging=0
+            dict_bal3={}
+
+            for i in range(3,len(self.df_bms)-3):
+
+                #静置法计算内短路..........................................................................................................................
+                if firsttime1==0:   #满电静置算法--计算均衡状态对应的均衡时间
+                    try:
+                        balstat=int(self.df_bms.loc[i,'单体均衡状态'])
+                        if balstat>0.5:
+                            bal_step=(self.bmstime[i+1]-self.bmstime[i]).total_seconds()  #均衡步长
+                            bal_step=int(bal_step)
+                            if str(balstat) in dict_bal1.keys():
+                                dict_bal1[str(balstat)]=dict_bal1[str(balstat)]+bal_step
+                            else:
+                                dict_bal1[str(balstat)]=bal_step
+                        else:
+                            pass
+                    except:
+                        dict_bal1={}
+                else:
+                    pass
+
+                if abs(self.packcrnt[i]) < 0.1 and abs(self.packcrnt[i-1]) < 0.1:     
+                    delttime=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
+                    standingtime=standingtime+delttime
+                    standingtime1=standingtime1+delttime
+                    self._celltemp_weight(i)
+
+                    #静置法计算内短路-开始.....................................................................................................................................
+                    if firsttime==1:    
+                        if standingtime>self.StandardStandingTime:      #静置时间满足要求
+                            cellvolt=self._cellvolt_get(i)
+                            if max(cellvolt)<self.param.OcvInflexionBelow-0.002:
+                                dict_baltime=self._bal_time(dict_bal)   #获取每个电芯的均衡时间
+                                deltsoc_last=self._celldeltsoc_get(i,dict_baltime,capacity)
+                                time_last=self.bmstime[i]
+                                firsttime=0
+                                standingtime=0
+                            else:
+                                pass
+                        else:
+                            pass                
+                    elif standingtime>3600*12:
+                        cellvolt=self._cellvolt_get(i)
+                        if max(cellvolt)<self.param.OcvInflexionBelow-0.002:
+                            standingtime=0
+                            dict_baltime=self._bal_time(dict_bal)   #获取每个电芯的均衡时间
+                            deltsoc_now=self._celldeltsoc_get(i, dict_baltime,capacity)    #获取每个电芯的SOC差
+                            time_now=self.bmstime[i]
+
+                            list_sub=[a-b for a, b in zip(deltsoc_now, deltsoc_last)]
+                            list_pud=[0.01*capacity*3600*1000/(time_now-time_last).total_seconds()]*self.param.CellVoltNums
+                            leak_current=[a*b for a,b in zip(list_sub,list_pud)]
+                            leak_current=np.array(leak_current)
+                            leak_current=np.round(leak_current,3)
+                            leak_current=list(leak_current)
+                            
+                            df_res.loc[len(df_res)]=[time_last,time_now,self.sn,1,str(leak_current),str(dict_baltime)]  #计算结果存入Dataframe
+                            time_last=time_now  #更新时间
+                            deltsoc_last=deltsoc_now    #更新soc差
+                            dict_bal={}
+                        else:
+                            pass
+                    else: 
+                        try:  
+                            balstat=int(self.df_bms.loc[i,'单体均衡状态'])
+                            if balstat>0.5:
+                                bal_step=(self.bmstime[i+1]-self.bmstime[i]).total_seconds()  #均衡步长
+                                bal_step=int(bal_step)
+                                if str(balstat) in dict_bal.keys():
+                                    dict_bal[str(balstat)]=dict_bal[str(balstat)]+bal_step
+                                else:
+                                    dict_bal[str(balstat)]=bal_step
+                            else:
+                                pass
+                        except:
+                            dict_bal={}
+
+                    #非平台区间静置法计算内短路-开始.....................................................................................................................................................
+                    if standingtime1>self.StandardStandingTime and abs(self.packcrnt[i+2]) >= 0.1:  
+                        standingtime1=0
+                        cellvolt_now1=self._cellvolt_get(i)
+                        if max(cellvolt_now1)<self.param.OcvInflexionBelow-0.002:
+                            if firsttime1==1:
+                                dict_baltime1=self._bal_time(dict_bal1)   #获取每个电芯的均衡时间
+                                deltsoc_last1=self._celldeltsoc_get(i,dict_baltime1,capacity)
+                                time_last1=self.bmstime[i]
+                                firsttime1=0
+                            else:
+                                dict_baltime1=self._bal_time(dict_bal1)   #获取每个电芯的均衡时间
+                                deltsoc_now1=self._celldeltsoc_get(i,dict_baltime1,capacity)
+                                time_now1=self.bmstime[i]
+
+                                if abs(max(deltsoc_now1)-max(deltsoc_last1))<10:
+                                    list_sub1=[a-b for a, b in zip(deltsoc_now1, deltsoc_last1)]
+                                    list_pud1=[0.01*capacity*3600*1000/(time_now1-time_last1).total_seconds()]*self.param.CellVoltNums
+                                    leak_current1=[a*b for a,b in zip(list_sub1,list_pud1)]
+                                    leak_current1=np.array(leak_current1)
+                                    leak_current1=np.round(leak_current1,3)
+                                    leak_current1=list(leak_current1)
+                                
+                                    
+                                    df_res.loc[len(df_res)]=[time_last1,time_now1,self.sn,2,str(leak_current1),str(dict_baltime1)]  #计算结果存入Dataframe
+                                else:
+                                    pass
+                                time_last1=time_now1  #更新时间
+                                deltsoc_last1=deltsoc_now1    #更新soc差
+                                dict_bal1={}
+                        else:
+                            pass
+                    else:   
+                        pass
+
+                else:
+                    dict_bal={} 
+                    firsttime=1
+                    standingtime=0
+                    standingtime1=0
+                    pass
+
+                #获取充电数据——开始..............................................................................................................
+                try:
+                    balstat=int(self.df_bms.loc[i,'单体均衡状态'])  #统计均衡状态
+                    if balstat>0.5:
+                        bal_step=(self.bmstime[i+1]-self.bmstime[i]).total_seconds()  #均衡步长
+                        bal_step=int(bal_step)
+                        if str(balstat) in dict_bal3.keys():
+                            dict_bal3[str(balstat)]=dict_bal3[str(balstat)]+bal_step
+                        else:
+                            dict_bal3[str(balstat)]=bal_step
+                    else:
+                        pass
+                except:
+                    dict_bal3={}
+
+                if charging==0:
+                    
+                    if self.packcrnt[i]<=-1 and self.packcrnt[i+1]<=-1 and self.packcrnt[i+2]<=-1 and self.bms_soc[i]<40:     #判断充电开始
+                        cellvolt_now=self._cellvolt_get(i)
+                        if min(cellvolt_now)<self.param.CellFullChrgVolt-0.15:
+                            charging=1
+                            if len(chrg_start)>len(chrg_end):
+                                chrg_start[-1]=i
+                            else:
+                                chrg_start.append(i)
+                        else:
+                            pass
+                    else:
+                        pass
+
+                else: #充电中
+                    if (self.bmstime[i+1]-self.bmstime[i]).total_seconds()>180:  #如果充电过程中时间间隔>180s,则舍弃该次充电
+                        chrg_start.remove(chrg_start[-1])
+                        charging=0
+                        continue
+                    elif self.packcrnt[i]<=-1 and self.packcrnt[i+1]<=-1 and  self.packcrnt[i+2]<-1:  
+                        cellvolt_now=self._cellvolt_get(i)
+                        if min(cellvolt_now)>self.param.CellFullChrgVolt-0.13:   #电压>满充电压-0.13V,即3.37V
+                            self._celltemp_weight(i)
+                            if i-chrg_start[-1]>10 and self.celltemp>10:
+                                chrg_end.append(i+1)
+                                dict_bal_list.append(dict_bal3)
+                                dict_bal3={}
+                                charging=0                       
+                                continue
+                            else:
+                                chrg_start.remove(chrg_start[-1])
+                                charging=0
+                                continue
+                        else:
+                            pass
+                    else:
+                        pass   
+            
+            #基于充电数据计算单体电芯的漏电流..........................................................................................................
+            if len(chrg_end)>1:    
+                for i in range(len(chrg_end)):
+                    if i<1:
+                        dict_baltime={}
+                        deltAs_last=self._cellDeltAs_get(chrg_start[i],chrg_end[i],dict_baltime)
+                        time_last=self.bmstime[chrg_end[i]]
+                    else:
+                        dict_baltime=self._bal_time(dict_bal_list[i])   #获取每个电芯的均衡时间
+                        deltAs_now=self._cellDeltAs_get(chrg_start[i],chrg_end[i],dict_baltime)  #获取每个电芯的As差
+                        time_now=self.bmstime[chrg_end[i]]
+
+                        list_sub=[a-b for a, b in zip(deltAs_now, deltAs_last)]
+                        list_pud=[-1000/(time_now-time_last).total_seconds()]*self.param.CellVoltNums
+                        leak_current=[a*b for a,b in zip(list_sub,list_pud)]
+                        leak_current=np.array(leak_current)
+                        leak_current=np.round(leak_current,3)
+                        leak_current=list(leak_current)
+
+                        df_res.loc[len(df_res)]=[time_last,time_now,self.sn,3,str(leak_current),str(dict_baltime)]  #计算结果存入Dataframe
+                        deltAs_last=deltAs_now
+                        time_last=time_now
+            else:
+                pass
+
+        if df_res.empty:
+            return pd.DataFrame()
+        else:
+            return df_res

BIN
LIB/MIDDLE/CellStateEstimation/InterShort/V1_0_0/InterShort表单.xlsx


+ 80 - 0
LIB/MIDDLE/CellStateEstimation/InterShort/main.py

@@ -0,0 +1,80 @@
+import CBMSBatInterShort
+import log
+
+#coding=utf-8
+import sys
+import datetime
+import pandas as pd
+from LIB.BACKEND import DBManager, Log
+from sqlalchemy import create_engine
+import time, datetime
+
+host='rm-bp10j10qy42bzy0q77o.mysql.rds.aliyuncs.com'
+port=3306
+db='qx_cas'
+user='qx_read'
+password='Qx@123456'
+tablename='soh_result'
+
+dbManager = DBManager.DBManager()
+if __name__ == "__main__":
+    excelpath=r'D:\Platform\platform_python\data_analyze_platform\USER\01qixiang\sn-20210903.xlsx'
+    SNdata_6060 = pd.read_excel(excelpath, sheet_name='科易6060')
+    SNdata_6040 = pd.read_excel(excelpath, sheet_name='科易6040')
+    SNdata_4840 = pd.read_excel(excelpath, sheet_name='科易4840')
+    SNdata_L7255 = pd.read_excel(excelpath, sheet_name='格林美-力信7255')
+    SNdata_C7255 = pd.read_excel(excelpath, sheet_name='格林美-CATL7255')
+    SNdata_U7255 = pd.read_excel(excelpath, sheet_name='优旦7255')
+    SNnums_6060=SNdata_6060['SN号'].tolist()
+    SNnums_6040=SNdata_6040['SN号'].tolist()
+    SNnums_4840=SNdata_4840['SN号'].tolist()
+    SNnums_L7255=SNdata_L7255['SN号'].tolist()
+    SNnums_C7255=SNdata_C7255['SN号'].tolist()
+    SNnums_U7255=SNdata_U7255['SN号'].tolist()
+    SNnums= SNnums_L7255 + SNnums_C7255 + SNnums_6040 + SNnums_4840 + SNnums_6060 + SNnums_U7255
+    
+    now_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
+    now_time=datetime.datetime.strptime(now_time,'%Y-%m-%d %H:%M:%S')
+    start_time=now_time-datetime.timedelta(days=30)
+    end_time=str(now_time)
+    start_time=str(start_time)
+
+    #log信息配置
+    mylog=log.Mylog('log.txt','error')
+    mylog.logcfg()
+
+    for sn in SNnums:
+        try:
+            if 'PK500' in sn:
+                celltype=1 #6040三元电芯
+            elif 'PK502' in sn:
+                celltype=2 #4840三元电芯
+            elif 'K504B' in sn:
+                celltype=99    #60ah林磷酸铁锂电芯
+            elif 'MGMLXN750' in sn:
+                celltype=3 #力信50ah三元电芯
+            elif 'MGMCLN750' or 'UD' in sn: 
+                celltype=4 #CATL 50ah三元电芯
+            else:
+                print('SN:{},未找到对应电池类型!!!'.format(sn))
+                continue
+                # sys.exit()
+            
+            # sn='MGMCLN750N215H001'
+            # celltype=2
+            start_time='2021-08-02 09:12:26'
+            end_time='2021-09-03 19:12:26'
+
+            dbManager = DBManager.DBManager()
+            df_data = dbManager.get_data(sn=sn, start_time=start_time, end_time=end_time, data_groups=['bms'])
+            df_bms = df_data['bms']
+            # df_bms.to_csv(r'D:\Platform\platform_python\data_analyze_platform\USER\01qixiang\99Result\\''BMS_'+sn+'.csv',encoding='GB18030')
+            
+            BatInterShort=CBMSBatInterShort.BatInterShort(sn,celltype,df_bms,host, port, db, user, password, tablename)
+            df_res=BatInterShort.intershort()
+            df_res.to_csv(r'D:\Platform\platform_python\data_analyze_platform\USER\01qixiang\99Result\\'+'CBMS_Short_'+sn+'_1.csv',encoding='GB18030')
+        
+        except Exception as e:
+            print(repr(e))
+            mylog.logopt(sn,e)
+            pass

+ 41 - 45
LIB/MIDDLE/CellStateEstimation/SOH/V1_0_0/CBMSBatSoh.py

@@ -3,8 +3,8 @@ import numpy as np
 import datetime
 import bisect
 import matplotlib.pyplot as plt
-from LIB.MIDDLE.CellStateEstimation.SOH.V1_0_0 import BatParam
-from LIB.MIDDLE.CellStateEstimation.SOH.V1_0_0 import DBDownload
+from LIB.MIDDLE.CellStateEstimation.Common import BatParam
+from LIB.MIDDLE.CellStateEstimation.Common import DBDownload
 
 class BatSoh:
     def __init__(self,sn,celltype,df_bms,df_accum, host, port, db, user, password, tablename):  #参数初始化
@@ -42,15 +42,18 @@ class BatSoh:
         else:
             return pd.DataFrame()
 
-    def getdata(self):  #获取预算结果库的结果
+    #获取预算结果库的结果....................................................................................................................
+    def getdata(self):  
         DBManager=DBDownload.DBDownload(self.host, self.port, self.db, self.user, self.password)
         with DBManager as DBManager:
             self.df_soh=DBManager.getdata('time_st','time_sp','sn','method','soh','cellsoh', tablename='soh_result', sn=self.sn)
     
-    def _np_move_avg(self,a, n, mode="same"): #定义滑动滤波函数
+    #定义滑动滤波函数.........................................................................................................................
+    def _np_move_avg(self,a, n, mode="same"):
         return (np.convolve(a, np.ones((n,)) / n, mode=mode))
 
-    def _chrgdata(self):    #筛选充电数据
+    #筛选充电数据..............................................................................................................................
+    def _chrgdata(self):    
         self.ChgStart=[]
         self.ChgEnd=[]
         if len(self.packvolt)>100:
@@ -64,7 +67,8 @@ class BatSoh:
                 elif i == (len(self.bmstime) - 4) and self.bmsstat[len(self.bmsstat)-1] == 2 and self.bmsstat[len(self.bmsstat)-2] == 2:
                     self.ChgEnd.append(len(self.bmstime)-2)
     
-    def _celltemp_weight(self,num):   #寻找当前行数据的最小温度值
+    #寻找当前行数据的最小温度值.................................................................................................................
+    def _celltemp_weight(self,num):   
         celltemp = []
         for j in range(1, self.param.CellTempNums+1):
             s = str(j)
@@ -97,7 +101,8 @@ class BatSoh:
                 self.tempweight=0.1
                 self.StandardStandingTime=3600
 
-    def _deltsoc_weight(self,deltsoc):   #获取SOC差对应的SOH权重值
+    #获取SOC差对应的SOH权重值...................................................................................................................
+    def _deltsoc_weight(self,deltsoc):   
         if deltsoc>60:   
             deltsoc_weight=1
         elif deltsoc>50:
@@ -112,14 +117,16 @@ class BatSoh:
             deltsoc_weight=0
         return deltsoc_weight
 
-    def _cellvolt_get(self,num): #获取当前行所有电压数据
+    #获取当前行所有电压数据......................................................................................................................
+    def _cellvolt_get(self,num): 
         cellvolt=[]
         for j in range(1, self.param.CellVoltNums+1): 
             s = str(j)
             cellvolt.append(self.df_bms.loc[num,'单体电压' + s]/1000)
         return cellvolt
     
-    def _dvdq_soh(self, chrg_st, chrg_end,cellvolt):    #dvdq方法计算soh
+    #dvdq方法计算soh...........................................................................................................................
+    def _dvdq_soh(self, chrg_st, chrg_end,cellvolt):    
         Ah = 0  #参数赋初始值
         Volt = cellvolt[chrg_st]
         DV_Volt=[]
@@ -220,7 +227,8 @@ class BatSoh:
         else:
             return 0
                 
-    def _ncmsoh_chrg(self):     #NCM充电数据soh计算 
+    #NCM充电数据soh计算.........................................................................................................................
+    def _ncmsoh_chrg(self):      
         self._chrgdata()
         self.getdata()
         ChgStartValid=[]
@@ -283,6 +291,7 @@ class BatSoh:
             return df_res
         return pd.DataFrame()
 
+    #两点法计算三元SOH.........................................................................................................................
     def _ncmsoh_twopoint(self):
         standingpoint_st=[]
         standingpoint_sp=[]
@@ -290,7 +299,7 @@ class BatSoh:
         standingtime=0
         for i in range(3,len(self.df_bms)-3):
 
-            if abs(self.packcrnt[i]) < 0.3:     #电流为0
+            if abs(self.packcrnt[i]) < 0.1 and abs(self.packcrnt[i-1]) < 0.1:     #电流为0
                 delttime=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
                 standingtime=standingtime+delttime
                 self._celltemp_weight(i)     #获取不同温度对应的静置时间
@@ -304,7 +313,7 @@ class BatSoh:
                             minocv_socst=np.interp(min(cellvolt_st),self.param.LookTab_OCV,self.param.LookTab_SOC)
 
                             if abs(minocv_socst-minocv_socnow)>=40:   #当前时刻SOC与开始时刻SOC差>=20
-                                if abs(self.packcrnt[i+2])>=0.3:    #如果下一时刻电流>=0.5,则压入当前索引
+                                if abs(self.packcrnt[i+2])>=0.1:    #如果下一时刻电流>=0.5,则压入当前索引
                                     standingpoint_sp.append(i)
                                     standingpoint_st.append(i)
                                     tempweightlist.append(self.tempweight)
@@ -327,14 +336,14 @@ class BatSoh:
                                 else:
                                     continue
                         else:
-                            if abs(self.packcrnt[i+2])>=0.5:
+                            if abs(self.packcrnt[i+2])>=0.1:
                                 standingpoint_st.append(i)
                                 standingtime=0
                                 continue
                             else:
                                 continue
                     else:
-                        if abs(self.packcrnt[i+2])>0.5:
+                        if abs(self.packcrnt[i+2])>0.1:
                             standingpoint_st.append(i)
                             standingtime=0
                             continue
@@ -346,6 +355,7 @@ class BatSoh:
                 standingtime=0
                 continue
 
+        #计算SOH......................................................................................................................
         if standingpoint_sp:
             self.getdata()  #获取已计算的soh
             column_name=['time_st','time_sp','sn','method','soh','cellsoh']
@@ -451,6 +461,7 @@ class BatSoh:
                 return df_res
         return pd.DataFrame()
 
+    #两点法和DVDQ法计算磷酸铁锂电池SOH..................................................................................................................
     def _lfpsoh(self):
         standingpoint_st=[]
         standingpoint_sp=[]
@@ -465,13 +476,13 @@ class BatSoh:
 
         for i in range(3,len(self.df_bms)-3):
 
-            #获取两点法法所需数据-开始
-            if abs(self.packcrnt[i]) < 0.2:     #判断非平台区静置状态
+            #获取两点法法所需数据-开始.................................................................................................................
+            if abs(self.packcrnt[i]) < 0.1 and abs(self.packcrnt[i-1]) < 0.1:     #判断非平台区静置状态
                 delttime=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
                 standingtime=standingtime+delttime
                 self._celltemp_weight(i)     #获取不同温度对应的静置时间
 
-                if standingtime>self.StandardStandingTime and abs(self.packcrnt[i+2])>0.1:  #静置时间满足要求,且下一时刻电流>0.1A
+                if standingtime>self.StandardStandingTime and abs(self.packcrnt[i+2])>=0.1:  #静置时间满足要求,且下一时刻电流>0.1A
                     standingtime=0
                     cellvolt_now=self._cellvolt_get(i)
                     if max(cellvolt_now)<self.param.OcvInflexionBelow:      #当前最大电芯电压<OCV下拐点
@@ -522,16 +533,10 @@ class BatSoh:
             else:
                 standingtime=0
                 pass
-            #获取两点法所需数据-结束
 
-            #获取DVDQ算法所需数据——开始
-            if i==3 and self.packcrnt[1]<=-1 and self.packcrnt[2]<=-1 and self.packcrnt[3]<=-1:
-                self._celltemp_weight(i)
-                chrg_start.append(i)
-                tempweightlist2.append(self.tempweight)
-                charging=1
-            elif self.packcrnt[i-1]>-1 and self.packcrnt[i]<=-1 and self.packcrnt[i+1]<=-1 and self.packcrnt[i+2]<=-1:     #判断充电开始
-                if self.bms_soc[i]<45:
+            #获取DVDQ算法所需数据——开始.............................................................................................................
+            if charging==0:
+                if self.packcrnt[i]<=-1 and self.packcrnt[i+1]<=-1 and self.packcrnt[i+2]<=-1 and self.bms_soc[i]<45:     #充电开始
                     self._celltemp_weight(i)
                     charging=1
                     if len(chrg_start)>len(chrg_end):
@@ -542,10 +547,8 @@ class BatSoh:
                         tempweightlist2.append(self.tempweight)
                 else:
                     pass
-            else:
-                pass
 
-            if charging==1: #充电中
+            else: #充电中
                 if (self.bmstime[i+1]-self.bmstime[i]).total_seconds()>180:  #如果充电过程中时间间隔>180s,则舍弃该次充电
                     chrg_start.remove(chrg_start[-1])
                     tempweightlist2.remove(tempweightlist2[-1])
@@ -560,7 +563,7 @@ class BatSoh:
                         continue
                     else:
                         pass
-                elif self.packcrnt[i+1]>-0.1 and self.packcrnt[i+2]>-0.1 and self.packcrnt[i+3]>-0.1:   #判断充电结束
+                elif self.packcrnt[i+1]>-0.1 and self.packcrnt[i+2]>-0.1:   #判断充电结束
                     charging=0
                     if len(chrg_start)>len(chrg_end):
                         chrg_start.remove(chrg_start[-1])
@@ -581,17 +584,18 @@ class BatSoh:
                             tempweightlist2.remove(tempweightlist2[-1])
                             continue
                     else:
-                        continue   
-            else:
-                pass
-            #获取DVDQ算法所需数据——结束
+                        continue  
+                else:
+                    continue 
         
-        if standingpoint_sp or chrg_end:       #开始计算SOH
+        #开始计算SOH.............................................................................................................................................
+        if standingpoint_sp or chrg_end:       
             self.getdata()  #获取已计算的soh
             column_name=['time_st','time_sp','sn','method','soh','cellsoh']
             df_res=pd.DataFrame(columns=column_name)
         
-            if standingpoint_sp:    #两点法计算SOH
+            #两点法计算SOH........................................................................................................................................
+            if standingpoint_sp:    
                 for i in range(len(standingpoint_sp)):  #判断为满充点或者下拐点
                     if self.packcrnt[standingpoint_sp[i]]<=-1:
                         cellocv_st=self._cellvolt_get(standingpoint_st[i])    
@@ -683,6 +687,7 @@ class BatSoh:
             else:
                 pass
 
+            #DVDQ法计算SOH.......................................................................................................................................
             if chrg_end:
                 for i in range(len(chrg_end)):
                     cellvolt_max = self.df_bms['单体电压' + str(cellmaxvolt_number2[i]+1)] / 1000     #获取最大电压
@@ -725,12 +730,3 @@ class BatSoh:
         return pd.DataFrame()
 
 
-
-
-
-
-
-
-            
-                
-

+ 12 - 11
LIB/MIDDLE/CellStateEstimation/SOH/main.py

@@ -1,16 +1,11 @@
 import CBMSBatSoh
 import log
 #coding=utf-8
-import os
-import sys
 import datetime
 import pandas as pd
 from LIB.BACKEND import DBManager, Log
-# from LIB.MIDDLE import SignalMonitor
 from sqlalchemy import create_engine
-from sqlalchemy.orm import sessionmaker
 import time, datetime
-from urllib import parse
 
 host='rm-bp10j10qy42bzy0q77o.mysql.rds.aliyuncs.com'
 port=3306
@@ -21,16 +16,17 @@ tablename='soh_result'
 
 dbManager = DBManager.DBManager()
 if __name__ == "__main__":
-    SNdata_6040 = pd.read_excel('骑享资产梳理-20210621.xlsx', sheet_name='6040骑享')
-    SNdata_6060 = pd.read_excel('骑享资产梳理-20210621.xlsx', sheet_name='6060')
-    SNdata_4840 = pd.read_excel('骑享资产梳理-20210621.xlsx', sheet_name='4840骑享')
-    SNdata_7250 = pd.read_excel('骑享资产梳理-20210621.xlsx', sheet_name='7250')
+    excelpath=r'D:\Platform\platform_python\data_analyze_platform\USER\01qixiang\骑享资产梳理-20210621.xlsx'
+    SNdata_6040 = pd.read_excel(excelpath, sheet_name='6040骑享')
+    SNdata_6060 = pd.read_excel(excelpath, sheet_name='6060')
+    SNdata_4840 = pd.read_excel(excelpath, sheet_name='4840骑享')
+    SNdata_7250 = pd.read_excel(excelpath, sheet_name='7250')
     SNnums_6060=SNdata_6060['SN号']
     SNnums_6040=SNdata_6040['SN号']
     SNnums_4840=SNdata_4840['SN号']
     SNnums_7250=SNdata_7250['SN号']
 
-    SNnums=SNnums_6040.tolist()+SNnums_6060.tolist()+SNnums_4840.tolist()
+    SNnums=SNnums_6060.tolist()+SNnums_6040.tolist()+SNnums_4840.tolist()
     now_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
     now_time=datetime.datetime.strptime(now_time,'%Y-%m-%d %H:%M:%S')
     start_time=now_time-datetime.timedelta(days=30)
@@ -55,7 +51,12 @@ if __name__ == "__main__":
                 celltype=4 #CATL 50ah三元电芯
             else:
                 print('未找到对应电池编号!!!')
-                sys.exit()
+                # sys.exit()
+            
+            # sn='MGMCLN750N215H001'
+            # start_time='2021-08-01 18:52:08'
+            # end_time='2021-08-31 18:52:08'
+            
             dbManager = DBManager.DBManager()
             df_data = dbManager.get_data(sn=sn, start_time=start_time, end_time=end_time, data_groups=['bms','accum'])
             df_bms = df_data['bms']

+ 0 - 91
LIB/MIDDLE/CellStateEstimation/Uniform/V1_0_0/BatParam.py

@@ -1,91 +0,0 @@
-
-#定义电池参数
-from types import CellType
-import sys
-
-class BatParam:
-
-    def __init__(self,celltype):
-
-        # if 'PK500' in sn:
-        #     self.celltype=1 #6040三元电芯
-        # elif 'PK502' in sn:
-        #     self.celltype=2 #4840三元电芯
-        # elif 'PK504' in sn:
-        #     self.celltype=99    #60ah林磷酸铁锂电芯
-        # elif 'MGMLXN750' in sn:
-        #     self.celltype=3 #力信50ah三元电芯
-        # elif 'MGMCLN750' in sn: 
-        #     self.celltype=4 #CATL 50ah三元电芯
-        # else:
-        #     print('未找到对应电池编号!!!')
-        #     sys.exit()
-
-        if celltype==1: #6040
-            self.Capacity = 41
-            self.PackFullChrgVolt=69.99
-            self.CellFullChrgVolt=4.2
-            self.CellVoltNums=17
-            self.CellTempNums=4
-            self.FullChrgSoc=98
-            self.PeakSoc=57
-            self.PackCrntDec=1
-            self.LookTab_SOC = [0,	    3.5348,	8.3581,	13.181,	18.004,	22.827,	27.651,	32.474,	37.297,	42.120,	46.944,	51.767,	56.590,	61.413,	66.237,	71.060,	75.883,	80.707,	85.530,	90.353,	95.176,	100]
-            self.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]
-        
-        elif celltype==2: #4840
-            self.Capacity = 41
-            self.PackFullChrgVolt=69.99
-            self.CellFullChrgVolt=4.2
-            self.CellVoltNums=14
-            self.CellTempNums=4
-            self.FullChrgSoc=98
-            self.PeakSoc=57
-            self.PackCrntDec=1
-            self.LookTab_SOC = [0,	    3.5348,	8.3581,	13.181,	18.004,	22.827,	27.651,	32.474,	37.297,	42.120,	46.944,	51.767,	56.590,	61.413,	66.237,	71.060,	75.883,	80.707,	85.530,	90.353,	95.176,	100]
-            self.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]
-        
-        elif celltype==3:   #力信50ah三元电芯
-            self.Capacity = 51
-            self.PackFullChrgVolt=80
-            self.CellFullChrgVolt=4.2
-            self.CellVoltNums=20
-            self.CellTempNums=4
-            self.FullChrgSoc=98
-            self.PeakSoc=57
-            self.PackCrntDec=1
-            self.LookTab_SOC = [0,	    5,	    10,	    15,	    20,	    25,	    30,	    35,	    40,	    45,	    50,	    55,	    60,	    65,	    70,	    75,	    80,	    85,	    90,	    95,	    100]
-            self.LookTab_OCV = [3.357, 	3.455, 	3.493, 	3.540, 	3.577, 	3.605, 	3.622, 	3.638, 	3.655, 	3.677, 	3.707, 	3.757, 	3.815, 	3.866, 	3.920, 	3.976, 	4.036, 	4.099, 	4.166, 	4.237, 	4.325]
-        
-        elif celltype==4:   #CATL 50ah三元电芯
-            self.Capacity = 50
-            self.PackFullChrgVolt=80
-            self.CellFullChrgVolt=4.2
-            self.CellVoltNums=20
-            self.CellTempNums=2
-            self.FullChrgSoc=98
-            self.PeakSoc=57
-            self.PackCrntDec=-1
-            self.LookTab_SOC = [0,	    5,	    10,	    15,	    20,	    25,	    30,	    35,	    40,	    45,	    50,	    55,	    60,	    65,	    70,	    75,	    80,	    85,	    90,	    95,	    100]
-            self.LookTab_OCV = [3.152, 	3.397, 	3.438, 	3.481, 	3.523, 	3.560, 	3.586, 	3.604, 	3.620, 	3.638, 	3.661, 	3.693, 	3.748, 	3.803, 	3.853, 	3.903, 	3.953, 	4.006, 	4.063, 	4.121, 	4.183]
-        
-        elif celltype==99:   #60ah磷酸铁锂电芯
-            self.Capacity = 54
-            self.PackFullChrgVolt=69.99
-            self.CellFullChrgVolt=3.5
-            self.OcvInflexionBelow=3.285
-            self.OcvInflexion2=3.296
-            self.OcvInflexion3=3.328
-            self.OcvInflexionAbove=3.4
-            self.CellVoltNums=20
-            self.CellTempNums=4
-            self.FullChrgSoc=98
-            self.PeakSoc=60.5
-            self.PackCrntDec=1
-            self.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]
-            self.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]
-        
-        else:
-            print('未找到对应电池编号!!!')
-            # sys.exit()
-

+ 26 - 26
LIB/MIDDLE/CellStateEstimation/Uniform/V1_0_0/CBMSBatUniform.py

@@ -3,7 +3,7 @@ import numpy as np
 import datetime
 import bisect
 import matplotlib.pyplot as plt
-from LIB.MIDDLE.CellStateEstimation.SOH.V1_0_0 import BatParam
+from LIB.MIDDLE.CellStateEstimation.Common import BatParam
 
 class BatUniform:
     def __init__(self,sn,celltype,df_bms):  #参数初始化
@@ -21,7 +21,7 @@ class BatUniform:
         if self.celltype==1 or self.celltype==2 or self.celltype==3 or self.celltype==4:
             df_res=self._ncm_uniform()
             return df_res
-            
+                     
         elif self.celltype==99:
             df_res=self._lfp_uniform()
             return df_res
@@ -29,10 +29,12 @@ class BatUniform:
         else:
             return pd.DataFrame()
     
-    def _np_move_avg(self,a, n, mode="same"): #定义滑动滤波函数
+    #定义滑动滤波函数........................................................................................................................................
+    def _np_move_avg(self,a, n, mode="same"): 
         return (np.convolve(a, np.ones((n,)) / n, mode=mode))
     
-    def _celltemp_weight(self,num):   #寻找当前行数据的最小温度值
+    #寻找当前行数据的最小温度值................................................................................................................................
+    def _celltemp_weight(self,num):   
         celltemp = []
         for j in range(1, self.param.CellTempNums+1):
             s = str(j)
@@ -65,14 +67,16 @@ class BatUniform:
                 self.tempweight=0.2
                 self.StandardStandingTime=3600
 
-    def _cellvolt_get(self,num): #获取当前行所有电压数据
+    #获取当前行所有电压数据............................................................................................................................
+    def _cellvolt_get(self,num):
         cellvolt=[]
         for j in range(1, self.param.CellVoltNums+1): 
             s = str(j)
             cellvolt.append(self.df_bms.loc[num,'单体电压' + s]/1000)
         return(cellvolt)
 
-    def _dvdq_peak(self, time, soc, cellvolt, packcrnt):    #寻找DVDQ的峰值点,并返回
+    #寻找DVDQ的峰值点,并返回..........................................................................................................................
+    def _dvdq_peak(self, time, soc, cellvolt, packcrnt):    
         cellvolt1 = self._np_move_avg(cellvolt, 5, mode="same")
         Soc = 0
         Ah = 0
@@ -154,6 +158,7 @@ class BatUniform:
         else:
             return 0
  
+    #三元电池一致性计算.................................................................................................................................
     def _ncm_uniform(self):
         column_name=['time','sn','cellsoc_diff','cellvolt_diff','cellmin_num','cellmax_num']
         df_res=pd.DataFrame(columns=column_name)
@@ -161,13 +166,13 @@ class BatUniform:
 
         for i in range(1,len(self.df_bms)-2):
 
-            if abs(self.packcrnt[i]) < 0.3:     #电流为0
-                delttime=(self.bmstime[i+1]-self.bmstime[i]).total_seconds()
+            if abs(self.packcrnt[i]) < 0.1 and abs(self.packcrnt[i-1]) < 0.1:     #电流为0
+                delttime=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
                 standingtime=standingtime+delttime
                 self._celltemp_weight(i)     #获取不同温度对应的静置时间
 
                 if standingtime>self.StandardStandingTime:      #静置时间满足要求
-                    if abs(self.packcrnt[i+2]) >= 0.3:
+                    if abs(self.packcrnt[i+2]) >= 0.1:
                         standingtime=0                    
                         cellvolt_now=self._cellvolt_get(i)     #获取当前行电压数据
                         cellvolt_min=min(cellvolt_now)
@@ -223,6 +228,7 @@ class BatUniform:
         else:
             return df_res
 
+    #磷酸铁锂电池一致性计算.........................................................................................................................
     def _lfp_uniform(self):
         column_name=['time','sn','cellsoc_diff','cellvolt_diff','cellmin_num','cellmax_num']
         df_res=pd.DataFrame(columns=column_name)
@@ -234,8 +240,8 @@ class BatUniform:
         for i in range(3,len(self.df_bms)-3):
 
             #静置电压法计算电芯一致性
-            if abs(self.packcrnt[i]) < 0.2:     #电流为0
-                delttime=(self.bmstime[i+1]-self.bmstime[i]).total_seconds()
+            if abs(self.packcrnt[i]) < 0.1 and abs(self.packcrnt[i-1]) < 0.1:     #电流为0
+                delttime=(self.bmstime[i]-self.bmstime[i-1]).total_seconds()
                 standingtime=standingtime+delttime
                 self._celltemp_weight(i)     #获取不同温度对应的静置时间
 
@@ -243,7 +249,7 @@ class BatUniform:
                     cellvolt_now=self._cellvolt_get(i)     #获取当前行电压数据
                     cellvolt_min=min(cellvolt_now)
                     cellvolt_max=max(cellvolt_now)
-                    if abs(self.packcrnt[i+2]) >= 0.2 and cellvolt_max < self.param.OcvInflexionBelow:     
+                    if abs(self.packcrnt[i+2]) >= 0.1 and cellvolt_max < self.param.OcvInflexionBelow:     
                         standingtime=0                   
                         cellmin_num=cellvolt_now.index(cellvolt_min)+1
                         cellmax_num=cellvolt_now.index(cellvolt_max)+1
@@ -273,12 +279,9 @@ class BatUniform:
                 standingtime=0
                 pass   
 
-            #获取DVDQ算法所需数据——开始
-            if i==3 and self.packcrnt[1]<=-1 and self.packcrnt[2]<=-1 and self.packcrnt[3]<=-1:
-                chrg_start.append(i)
-                charging=1
-            elif self.packcrnt[i-1]>-1 and self.packcrnt[i]<=-1 and self.packcrnt[i+1]<=-1 and self.packcrnt[i+2]<=-1:     #判断充电开始
-                if self.bms_soc[i]<45:
+            #获取DVDQ算法所需数据——开始............................................................................................................
+            if charging==0: #判断充电开始
+                if self.packcrnt[i]<=-1 and self.packcrnt[i+1]<=-1 and self.packcrnt[i+2]<=-1 and self.bms_soc[i]<45:     #充电开始
                     charging=1
                     if len(chrg_start)>len(chrg_end):
                         chrg_start[-1]=i
@@ -286,10 +289,8 @@ class BatUniform:
                         chrg_start.append(i)
                 else:
                     pass
-            else:
-                pass
 
-            if charging==1: #充电中
+            else: #充电中
                 if (self.bmstime[i+1]-self.bmstime[i]).total_seconds()>180:  #如果充电过程中时间间隔>180s,则舍弃该次充电
                     chrg_start.remove(chrg_start[-1])
                     charging=0
@@ -302,7 +303,7 @@ class BatUniform:
                         continue
                     else:
                         pass
-                elif self.packcrnt[i+1]>-0.1 and self.packcrnt[i+2]>-0.1 and self.packcrnt[i+3]>-0.1:   #判断充电结束
+                elif self.packcrnt[i+1]>-0.1 and self.packcrnt[i+2]>-0.1:   #判断充电结束
                     charging=0
                     if len(chrg_start)>len(chrg_end):
                         if self.bms_soc[i]>90:
@@ -322,10 +323,9 @@ class BatUniform:
                             chrg_start.remove(chrg_start[-1])
                             continue
                     else:
-                        continue   
-            else:
-                pass
-            #获取DVDQ算法所需数据——结束
+                        continue
+                else:
+                    continue   
 
         if chrg_end:    #DVDQ方法计算soc差
             peaksoc_list=[]

+ 0 - 24
LIB/MIDDLE/CellStateEstimation/Uniform/V1_0_0/log.py

@@ -1,24 +0,0 @@
-import logging
-import traceback
-
-class Mylog:
-
-    def __init__(self,log_name,log_level):
-        self.name=log_name
-        self.level=log_level
-    
-    def logcfg(self):
-        if len(self.level) > 0:
-            if self.level == 'debug':
-                Level=logging.DEBUG
-            elif self.level == 'info':
-                Level=logging.INFO
-            elif self.level == 'warning':
-                Level=logging.WARNING
-            else:
-                Level=logging.ERROR
-        logging.basicConfig(filename=self.name, level=Level,format='%(asctime)s - %(levelname)s - %(message)s')
-
-    def logopt(self,*info):
-        logging.error(info)
-        logging.error(traceback.format_exc())

+ 0 - 73
LIB/MIDDLE/CellStateEstimation/Uniform/V1_0_0/main.py

@@ -1,73 +0,0 @@
-import CBMSBatUniform
-import log
-
-#coding=utf-8
-import os
-import sys
-import datetime
-import pandas as pd
-from LIB.BACKEND import DBManager, Log
-# from LIB.MIDDLE import SignalMonitor
-from sqlalchemy import create_engine
-from sqlalchemy.orm import sessionmaker
-import time, datetime
-from LIB.MIDDLE.soh import NCMSoh_20210716 as NCMSoh
-from LIB.MIDDLE.soh import LFPSoh_20210711 as LFPSoh
-from urllib import parse
-
-dbManager = DBManager.DBManager()
-if __name__ == "__main__":
-    SNdata_6040 = pd.read_excel('骑享资产梳理-20210621.xlsx', sheet_name='6040骑享')
-    SNdata_6060 = pd.read_excel('骑享资产梳理-20210621.xlsx', sheet_name='6060')
-    SNdata_4840 = pd.read_excel('骑享资产梳理-20210621.xlsx', sheet_name='4840骑享')
-    SNdata_7250 = pd.read_excel('骑享资产梳理-20210621.xlsx', sheet_name='7250')
-    SNnums_6060=SNdata_6060['SN号']
-    SNnums_6040=SNdata_6040['SN号']
-    SNnums_4840=SNdata_4840['SN号']
-    SNnums_7250=SNdata_7250['SN号']
-
-    SNnums=SNnums_6040.tolist()+SNnums_6060.tolist()+SNnums_4840.tolist()+SNnums_7250.tolist()
-    now_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
-    now_time=datetime.datetime.strptime(now_time,'%Y-%m-%d %H:%M:%S')
-    start_time=now_time-datetime.timedelta(days=5)
-    end_time=str(now_time)
-    start_time=str(start_time)
-
-    #log信息配置
-    mylog=log.Mylog('log.txt','error')
-    mylog.logcfg()
-
-    for sn in SNnums:
-        try:
-            if 'PK500' in sn:
-                celltype=1 #6040三元电芯
-            elif 'PK502' in sn:
-                celltype=2 #4840三元电芯
-            elif 'PK504' in sn:
-                celltype=99    #60ah林磷酸铁锂电芯
-            elif 'MGMLXN750' in sn:
-                celltype=3 #力信50ah三元电芯
-            elif 'MGMCLN750' in sn: 
-                celltype=4 #CATL 50ah三元电芯
-            else:
-                print('未找到对应电池编号!!!')
-                sys.exit()
-            
-            # sn='PK50001A100000035'
-            # start_time='2021-08-10 9:49:37'
-            # end_time='2021-08-29 19:49:37'
-
-            dbManager = DBManager.DBManager()
-            df_data = dbManager.get_data(sn=sn, start_time=start_time, end_time=end_time, data_groups=['bms'])
-            df_bms = df_data['bms']
-            # df_bms.to_csv('BMS_'+sn+'.csv',encoding='GB18030')
-
-            BatUniform=CBMSBatUniform.BatUniform(sn,celltype,df_bms)
-            df_res=BatUniform.batuniform()
-            df_res.to_csv('CBMS_Uniform_'+sn+'.csv',encoding='GB18030')
-        
-        
-        except IndexError as e:
-            print(repr(e))
-            mylog.logopt(sn,e)
-            pass

+ 7 - 2
LIB/MIDDLE/CellStateEstimation/Uniform/main.py

@@ -15,6 +15,11 @@ from urllib import parse
 
 dbManager = DBManager.DBManager()
 if __name__ == "__main__":
+    excelpath=r'D:\Platform\platform_python\data_analyze_platform\USER\01qixiang\骑享资产梳理-20210621.xlsx'
+    SNdata_6040 = pd.read_excel(excelpath, sheet_name='6040骑享')
+    SNdata_6060 = pd.read_excel(excelpath, sheet_name='6060')
+    SNdata_4840 = pd.read_excel(excelpath, sheet_name='4840骑享')
+    SNdata_7250 = pd.read_excel(excelpath, sheet_name='7250')
     SNdata_6040 = pd.read_excel('骑享资产梳理-20210621.xlsx', sheet_name='6040骑享')
     SNdata_6060 = pd.read_excel('骑享资产梳理-20210621.xlsx', sheet_name='6060')
     SNdata_4840 = pd.read_excel('骑享资产梳理-20210621.xlsx', sheet_name='4840骑享')
@@ -24,10 +29,10 @@ if __name__ == "__main__":
     SNnums_4840=SNdata_4840['SN号']
     SNnums_7250=SNdata_7250['SN号']
 
-    SNnums=SNnums_6040.tolist()+SNnums_6060.tolist()+SNnums_4840.tolist()+SNnums_7250.tolist()
+    SNnums=SNnums_6060.tolist()+SNnums_6040.tolist()+SNnums_4840.tolist()+SNnums_7250.tolist()
     now_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
     now_time=datetime.datetime.strptime(now_time,'%Y-%m-%d %H:%M:%S')
-    start_time=now_time-datetime.timedelta(days=5)
+    start_time=now_time-datetime.timedelta(days=20)
     end_time=str(now_time)
     start_time=str(start_time)
 

BIN
LIB/MIDDLE/CellStateEstimation/算法运行周期.xlsx


+ 199 - 0
LIB/MIDDLE/IndexStaByOneCycle.py

@@ -1,3 +1,201 @@
+<<<<<<< HEAD
+'''
+基于单一状态(一次行车、一次静置、一次充电)的指标统计库
+
+'''
+__author__ = 'lmstack'
+
+import CONFIGURE.PathSetting as PathSetting
+import sys
+sys.path.append(PathSetting.backend_path)
+import datetime
+import Tools
+import pandas as pd
+import numpy as np
+
+class IndexStaByOneCycle():
+    def __init__(self):
+        pass
+
+    def odo_sta(self, odo_array):
+        '''
+        一次行车行驶里程统计
+        ---------输入参数------------
+        odo_array : 一次行车对应的odo数据
+        ---------输出参数------------
+        如果gps 可信,则输出本次行车的累积行驶里程;
+        否则,输出None
+        '''
+        odo_array = odo_array[~pd.isnull(odo_array)]
+        if len(odo_array) > 0:
+            return np.sum(odo_array)
+        else:
+            return None
+
+    def capacity_sta(self, cap, soc_array, soh_array):
+        '''
+        一个cycle净累积ah统计
+        ---------输入参数------------
+        cap : 标称容量
+        soc_array : 一个cycle对应的soc数据
+        soh_array : 一个cycle对应的soh数据
+        ---------输出参数------------
+        本次行车的累积ah
+        '''
+        soc_array = soc_array[~pd.isnull(soc_array)]
+        soh_array = soh_array[~pd.isnull(soh_array)]
+        if len(soc_array) > 0 and len(soh_array) > 0 :
+            return (soc_array[0] - soc_array[-1]) * np.mean(soh_array) * cap / 100.0 / 100.0
+        else:
+            return None
+    def energy_sta(self, cap, soc_array, soh_array, volt_array):
+        '''
+        一个cycle净累积能量统计
+        ---------输入参数------------
+        cap : 标称容量
+        soc_array : 一个cycle对应的soc数据
+        soh_array : 一个cycle对应的soh数据
+        volt_array : 一个cycle对应的volt数据
+        ---------输出参数------------
+        本次行车的累积能量
+        '''
+        soc_array = soc_array[~pd.isnull(soc_array)]
+        soh_array = soh_array[~pd.isnull(soh_array)]
+        volt_array = volt_array[~pd.isnull(volt_array)]
+        if len(soc_array) > 0 and len(soh_array) > 0 and len(volt_array)>0:
+            cap = self.capacity_sta(cap, soc_array, soh_array)
+            return cap * np.mean(volt_array) / 1000.0
+        else:
+            return None
+
+
+
+    def acc_time_sta(self, time_array):
+        '''
+        一个cycle的持续时间
+        ---------输入参数------------
+        time_array : 一次cycle对应的time数据
+        ---------输出参数------------
+        本cycle的持续时间,单位 h
+        '''
+        time_array = time_array[~pd.isnull(time_array)]
+        if len(time_array) > 0:
+            return float(abs(time_array[0] - time_array[-1]))/1e9/3600.0
+        else:
+            return None
+
+    def mean_temp_sta(self, temp_array):
+        '''
+        一个cycle的单体平均温度
+        ---------输入参数------------
+        temp_array : 一个cycle对应的某个单体的temp数据
+        ---------输出参数------------
+        本cycle的单体平均温度
+        '''
+        temp_array = temp_array[~pd.isnull(temp_array)]
+        if len(temp_array) > 0:
+            return np.mean(temp_array)
+        else:
+            return None
+
+    def temp_change_rate_sta(self, time_array, temp_array):
+        '''
+        一个cycle的单体温度变化率
+        ---------输入参数------------
+        time_array : 一个cycle对应的time数据
+        temp_array : 一个cycle对应的temp数据
+        ---------输出参数------------
+        本cycle的单体温度变化率
+        '''
+        time_array = time_array[~pd.isnull(time_array)]
+        temp_array = temp_array[~pd.isnull(temp_array)]
+        if len(temp_array) > 0 and len(time_array) > 0:
+            return abs(temp_array[0] - temp_array[-1])/\
+                (float(abs(time_array[0] - time_array[-1]))/1e9/3600.0)
+        else:
+            return None
+
+    def dischrg_max_pwr_sta(self, volt_array, crnt_array):
+        '''
+        一个cycle的放电功率最大值
+        ---------输入参数------------
+        volt_array : 一个cycle对应的volt数据
+        crnt_array : 一个cycle对应的crnt数据
+        ---------输出参数------------
+        本cycle的放电功率最大值
+        '''
+        volt_array = volt_array[~pd.isnull(volt_array)]
+        crnt_array = crnt_array[~pd.isnull(crnt_array)]
+        if len(volt_array) > 0 and len(crnt_array) > 0:
+            pwr = volt_array * crnt_array / 1000.0
+            pwr = pwr[pwr > 0]
+            return np.max(pwr)
+        else:
+            return None
+
+    def chrg_max_pwr_sta(self, volt_array, crnt_array):
+        '''
+        一个cycle的充电功率最大值
+        ---------输入参数------------
+        volt_array : 一个cycle对应的volt数据
+        crnt_array : 一个cycle对应的crnt数据
+        ---------输出参数------------
+        本cycle的充电功率最大值
+        '''
+        volt_array = volt_array[~pd.isnull(volt_array)]
+        crnt_array = crnt_array[~pd.isnull(crnt_array)]
+        if len(volt_array) > 0 and len(crnt_array) > 0:
+            pwr = volt_array * crnt_array / 1000.0
+            pwr = pwr[pwr < 0]
+            return np.max(abs(pwr))
+        else:
+            return None
+
+    def regen_count_sta(self, crnt_array):
+        '''
+        一个行车cycle的regen 行数
+        ---------输入参数------------
+        crnt_array : 一个行车cycle对应的crnt数据
+        ---------输出参数------------
+        本行车cycle的regen行数, 总行数
+        '''
+        crnt_array = crnt_array[~pd.isnull(crnt_array)]
+        if  len(crnt_array) > 0:
+            return len(crnt_array[crnt_array < -1]), len(crnt_array)
+        else:
+            return None, None
+
+    def speed_sta(self, sum_odo, acc_time, speed_array):
+        '''
+        一个行车cycle的平均速度和最大瞬时速度
+        ---------输入参数------------
+        sum_odo : 一个行车cycle对应的累积odo数据
+        acc_time : 一个行车cycle对应的累积time数据
+        speed_array : 一个行车cycle对应的speed数据
+        ---------输出参数------------
+        本行车cycle的平均速度和最大速度
+        '''
+        speed_array = speed_array[~pd.isnull(speed_array)]
+        if  ~pd.isnull(sum_odo) and ~pd.isnull(acc_time) and len(speed_array) > 0:
+            return sum_odo/acc_time, np.max(speed_array)
+        else:
+            return None, None
+
+    def speed_sta(self, sum_odo, acc_time, speed_array):
+        '''
+        一个行车cycle的平均速度和最大瞬时速度
+        ---------输入参数------------
+        sum_odo : 一个行车cycle对应的累积odo数据
+        acc_time : 一个行车cycle对应的累积time数据
+        speed_array : 一个行车cycle对应的speed数据
+        ---------输出参数------------
+        本行车cycle的平均速度和最大速度
+        '''
+        speed_array = speed_array[~pd.isnull(speed_array)]
+        if  ~pd.isnull(sum_odo) and ~pd.isnull(acc_time) and len(speed_array) > 0:
+            return sum_odo/acc_time, np.max(speed_array)
+        else:
+=======
 '''
 基于单一状态(一次行车、一次静置、一次充电)的指标统计库
 
@@ -194,4 +392,5 @@ class IndexStaByOneCycle():
         if  ~pd.isnull(sum_odo) and ~pd.isnull(acc_time) and len(speed_array) > 0:
             return sum_odo/acc_time, np.max(speed_array)
         else:
+>>>>>>> 65a87ae16013552e359df047df19f46fc4e6eb08
             return None, None

+ 174 - 0
LIB/MIDDLE/IndexStaByPeriod.py

@@ -1,3 +1,176 @@
+<<<<<<< HEAD
+'''
+基于某个周期(一天,一周...)的指标统计库
+
+'''
+__author__ = 'lmstack'
+
+import CONFIGURE.PathSetting as PathSetting
+import sys
+sys.path.append(PathSetting.backend_path)
+sys.path.append(PathSetting.middle_path)
+import datetime
+import Tools
+import pandas as pd
+import numpy as np
+import IndexStaByOneCycle
+
+class IndexStaByPeriod():
+    def __init__(self):
+        self.indexStaByOneCycle = IndexStaByOneCycle.IndexStaByOneCycle()
+        pass
+
+    def drive_odo_sta(self, df_bms, df_gps):
+        '''
+        计算周期内行车累积行驶里程
+        ---------输入参数------------
+        df_bms : 一段周期内的预处理后的bms数据
+        df_gps : 一段周期内的预处理后的gps数据
+        ---------输出参数------------
+        sum_odo : 累积里程, 如果该周期内gps均无效,则返回None
+        invalid_rate : 该周期内gps无效的bms数据行所占比例
+        '''
+        invalid_count = 0
+        total_count = 0
+        sum_odo = 0
+        data_number_list = sorted(list(set(df_bms[(df_bms['data_status'].isin(['drive']))]['data_split_by_status_after_combine'])))
+        if len(data_number_list) == 0:
+            return {'sum_odo':0, 'invalid_rate':0}
+        for data_number in data_number_list[:]:
+            df_sel_bms = df_bms[df_bms['data_split_by_status_after_combine'] == data_number]
+            df_sel_bms = df_sel_bms.reset_index(drop=True)
+
+            total_count += len(df_sel_bms)
+            if df_sel_bms.loc[0, 'gps_rely'] != 1:
+                invalid_count += len(df_sel_bms)
+                continue
+            else:
+                df_sel_gps = df_gps[(df_gps['时间戳']>df_sel_bms.loc[0,'时间戳']) & (df_gps['时间戳']<df_sel_bms.loc[len(df_sel_bms)-1,'时间戳'])]
+                df_sel_gps = df_sel_gps.reset_index(drop=True)
+                odo = self.indexStaByOneCycle.odo_sta(np.array(df_sel_gps['odo']))
+                if not pd.isnull(odo):
+                    sum_odo += odo
+        invalid_rate = invalid_count/total_count
+        return {'sum_odo':sum_odo, 'invalid_rate':invalid_rate}
+    
+    
+    #该函数未完成, TODO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+    def _energy_consump_sta(self, cap, df_bms, df_gps):
+        '''
+        计算周期内百公里能耗
+        ---------输入参数------------
+        df_bms : 本周期内的bms数据
+        df_gps : 本周期内的gps数据
+        ---------输出参数------------
+        本周期内的百公里能耗
+        '''
+        if not df_bms.empty and not df_gps.empty:
+            # 计算能耗
+            energy_sum = 0
+            data_number_list = sorted(list(set(df_bms[(df_bms['data_status'].isin(['drive']))]['data_split_by_status_time'])))
+            for data_number in data_number_list[:]:
+                df_sel_bms = df_bms[df_bms['data_split_by_status_time'] == data_number]
+                df_sel_bms = df_sel_bms.reset_index(drop=True)
+                soc_array = np.array(df_sel_bms['SOC[%]'])
+                soh_array = np.array(df_sel_bms['SOH[%]'])
+                volt_array = np.array(df_sel_bms['总电压[V]'])
+                energy = self.indexStaByOneCycle.energy_sta(cap, soc_array, soh_array, volt_array)
+                if not pd.isnull(energy):
+                    energy_sum += energy
+            # 计算里程
+            pass # TODO!!!!!!!!!!!!!!!!!!!!!
+            return 0
+        else:
+            return None
+
+    def drive_soc_sta(self, df_bms):
+        '''
+        计算周期内行车净累积soc
+        ---------输入参数------------
+        cap : 标称容量
+        df_bms : 一段周期内的预处理后的bms数据
+        df_gps : 一段周期内的预处理后的gps数据
+        ---------输出参数------------
+        sum_ah : 本周期的净累积soc
+       '''   
+
+        sum_soc = 0
+        data_number_list = sorted(list(set(df_bms[(df_bms['data_status'].isin(['drive']))]['data_split_by_status_time'])))
+        if len(data_number_list) == 0:
+            return sum_soc
+        for data_number in data_number_list[:]:
+            df_sel_bms = df_bms[df_bms['data_split_by_status_time'] == data_number]
+            df_sel_bms = df_sel_bms.reset_index(drop=True)
+            sum_soc += abs(df_sel_bms.loc[0, 'SOC[%]'] - df_sel_bms.loc[len(df_sel_bms)-1, 'SOC[%]'])
+        return sum_soc
+
+    def drive_time_sta(self, df_bms):
+        '''
+        计算周期内累计行车时长/h
+        ---------输入参数------------
+        cap : 标称容量
+        df_bms : 一段周期内的预处理后的bms数据
+        df_gps : 一段周期内的预处理后的gps数据
+        ---------输出参数------------
+        sum_ah : 本周期的累计行车时长
+       '''   
+
+        sum_time = 0
+        data_number_list = sorted(list(set(df_bms[(df_bms['data_status'].isin(['drive']))]['data_split_by_status_time'])))
+        if len(data_number_list) == 0:
+            return sum_time
+        for data_number in data_number_list[:]:
+            df_sel_bms = df_bms[df_bms['data_split_by_status_time'] == data_number]
+            df_sel_bms = df_sel_bms.reset_index(drop=True)
+            sum_time += (df_sel_bms.loc[len(df_sel_bms)-1, '时间戳'] - df_sel_bms.loc[0, '时间戳']).total_seconds()
+        return sum_time / 3600.0
+
+    def drive_capacity_sta(self, cap, df_bms):
+        '''
+        计算周期内行车净累积ah
+        ---------输入参数------------
+        cap : 标称容量
+        df_bms : 一段周期内的预处理后的bms数据
+        df_gps : 一段周期内的预处理后的gps数据
+        ---------输出参数------------
+        sum_ah : 本周期的净累积ah
+       '''   
+
+        sum_ah = 0
+        data_number_list = sorted(list(set(df_bms[(df_bms['data_status'].isin(['drive']))]['data_split_by_status_time'])))
+        if len(data_number_list) == 0:
+            return sum_ah
+        for data_number in data_number_list[:]:
+            df_sel_bms = df_bms[df_bms['data_split_by_status_time'] == data_number]
+            df_sel_bms = df_sel_bms.reset_index(drop=True)
+            soc_array = np.array(df_sel_bms['SOC[%]'])
+            soh_array = np.array(df_sel_bms['SOH[%]'])
+            sum_ah += self.indexStaByOneCycle.capacity_sta(cap, soc_array, soh_array)
+        return sum_ah
+
+    def drive_energy_sta(self, cap, df_bms):
+        '''
+        计算周期内行车净累积能量
+        ---------输入参数------------
+        cap : 标称容量
+        df_bms : 一段周期内的预处理后的bms数据
+        df_gps : 一段周期内的预处理后的gps数据
+        ---------输出参数------------
+        sum_ah : 本周期的净累积能量
+       '''   
+
+        sum_energy = 0
+        data_number_list = sorted(list(set(df_bms[(df_bms['data_status'].isin(['drive']))]['data_split_by_status_time'])))
+        if len(data_number_list) == 0:
+            return sum_energy
+        for data_number in data_number_list[:]:
+            df_sel_bms = df_bms[df_bms['data_split_by_status_time'] == data_number]
+            df_sel_bms = df_sel_bms.reset_index(drop=True)
+            soc_array = np.array(df_sel_bms['SOC[%]'])
+            soh_array = np.array(df_sel_bms['SOH[%]'])
+            volt_array = np.array(df_sel_bms['总电压[V]'])
+            sum_energy += self.indexStaByOneCycle.energy_sta(cap, soc_array, soh_array, volt_array)
+=======
 '''
 基于某个周期(一天,一周...)的指标统计库
 
@@ -169,4 +342,5 @@ class IndexStaByPeriod():
             soh_array = np.array(df_sel_bms['SOH[%]'])
             volt_array = np.array(df_sel_bms['总电压[V]'])
             sum_energy += self.indexStaByOneCycle.energy_sta(cap, soc_array, soh_array, volt_array)
+>>>>>>> 65a87ae16013552e359df047df19f46fc4e6eb08
         return sum_energy

+ 0 - 160
LIB/MIDDLE/LeakCurrent/LFPLeakCurrent20210812.py

@@ -1,160 +0,0 @@
-# 获取数据
-from LIB.BACKEND import DBManager
-
-import os
-import pandas as pd
-import numpy as np
-import bisect
-import datetime
-# import matplotlib.pyplot as plt
-
-#参数输入
-Capacity = 53.6
-PackFullChrgVolt=69.99
-CellFullChrgVolt=3.37
-CellVoltNums=20
-CellTempNums=4
-FullChrgSoc=98
-CellVoltPort=[3.357,3.358,3.359,3.36,3.361]
-PeakSoc=57
-# #40Ah-OCV
-# LookTab_SOC = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100]
-# LookTab_OCV = [3.3159, 3.4502, 3.4904, 3.5277, 3.5590, 3.5888, 3.6146, 3.6312, 3.6467, 3.6642, 3.6865, 3.7171, 3.7617,
-#                3.8031, 3.8440, 3.8888, 3.9376, 3.9891, 4.0451, 4.1068, 4.1830]
-#55Ah-OCV
-LookTab_SOC = [0,  10,  20,  30,  40,  50,  60,  70,  80,  90,  100]
-LookTab_OCV = [3.1820, 3.2250, 3.2730, 3.2840, 3.2860, 3.2920, 3.3210, 3.3260, 3.3270, 3.3270, 3.3640]
-
-# 获取数据时间段
-def cal_LFPLeakCurrent(sn, end_time, start_time):
-    end_time = end_time
-    strat_time = start_time
-
-    sn = sn
-    st = strat_time
-    et = end_time
-
-    dbManager = DBManager.DBManager()
-    df_data = dbManager.get_data(sn=sn, start_time=st, end_time=et, data_groups=['bms'])
-    df_bms = df_data['bms']
-
-    #寻找电压最大值
-    packcrnt=df_bms['总电流[A]']
-    SOC=df_bms['SOC[%]']
-    bmsstat=df_bms['充电状态']
-    time= pd.to_datetime(df_bms['时间戳'], format='%Y-%m-%d %H:%M:%S')
-
-    #第一步:筛选充电数据
-    ChgStart=[]
-    ChgEnd=[]
-    for i in range(3, len(time) - 3):
-        if i==3 and bmsstat[i]==2 and bmsstat[i+1]==2 and bmsstat[i+2]==2:
-            ChgStart.append(i)
-        elif bmsstat[i-2]!=2 and bmsstat[i-1]!=2 and bmsstat[i]==2:
-            ChgStart.append(i)
-        elif bmsstat[i-1]==2 and bmsstat[i]!=2 and bmsstat[i+1]!=2:
-            ChgEnd.append(i)
-        elif i == (len(time) - 4) and bmsstat[len(bmsstat)-1] == 2 and bmsstat[len(bmsstat)-2] == 2:
-            ChgEnd.append(len(time)-1)
-
-    #第二步:筛选充电起始Soc<45%,且单体最小电压>3.37V的数据
-    ChgStartValid=[]
-    ChgEndValid=[]
-    if ChgStart:
-        for i in range(len(ChgEnd)):
-            #寻找最小电压值
-            cellvolt = []
-            for j in range(1, CellVoltNums+1):
-                s = str(j)
-                volt = df_bms['单体电压' + s]/1000
-                cellvolt.append(max(volt[ChgStart[i]:ChgEnd[i]]))
-            if min(cellvolt)>CellFullChrgVolt and SOC[ChgStart[i]]<40 and (ChgEnd[i]-ChgStart[i])>10:
-                if ((time[ChgEnd[i]]-time[ChgStart[i]]).total_seconds())/(ChgEnd[i]-ChgStart[i])<30:
-                    ChgStartValid.append(ChgStart[i])
-                    ChgEndValid.append(ChgEnd[i])
-
-    #第三步:计算充电每个单体到达3.368V的Ah差
-    #定义寻找电压3.368V的数据点
-    def data_search(data1,data2,data3,data4):
-        Soc=0
-        for m in range(1,len(data1)):
-            t=(data2[m]-data2[m-1]).total_seconds()
-            Soc=Soc-data3[m]*t/(3600*Capacity)
-            if data1[m]>data4:
-                DetaT=(data2[m]-data2[0]).total_seconds()
-                return Soc,m
-                break
-    
-    if ChgStartValid:
-        df_DetaTime=pd.DataFrame()
-        df_DetaTime1=pd.DataFrame()
-        df_detatime=pd.DataFrame()
-        for i in range(len(ChgStartValid)):
-            DetaSoc1=[]
-            DetaSoc2 = []
-            DetaSoc=[]
-            a=list(range(5))
-            b=list(range(5))
-            #计算1-10号电芯到达特定电压值得时间和SOC
-            for j in range(1, CellVoltNums-9):
-                s = str(j)
-                cellvolt = df_bms['单体电压' + s]/1000
-                cellvolt=list(cellvolt[ChgStartValid[i]:ChgEndValid[i]])
-                Time=list(time[ChgStartValid[i]:ChgEndValid[i]])
-                Packcrnt=list(packcrnt[ChgStartValid[i]:ChgEndValid[i]])
-                for k in range(len(CellVoltPort)):
-                    a[k],b[k]=data_search(cellvolt,Time,Packcrnt,CellVoltPort[k])
-                DetaSoc1.append(np.mean(a))  #计算到达3.368V的时长
-                # DetaT.append((Time[b]-Time[0]).total_seconds())
-
-            #计算1-10号电芯到达特定电压值的平均Soc
-            Socmean1=(sum(DetaSoc1)-max(DetaSoc1)-min(DetaSoc1))/(len(DetaSoc1)-2)
-            # Tmean=np.mean(DetaT)
-
-            ##计算11-20号电芯到达特定电压值得时间和SOC
-            for j in range(11, CellVoltNums+1):
-                s = str(j)
-                cellvolt = df_bms['单体电压' + s]/1000
-                cellvolt=list(cellvolt[ChgStartValid[i]:ChgEndValid[i]])
-                Time=list(time[ChgStartValid[i]:ChgEndValid[i]])
-                Packcrnt=list(packcrnt[ChgStartValid[i]:ChgEndValid[i]])
-                for k in range(len(CellVoltPort)):
-                    a[k],b[k]=data_search(cellvolt,Time,Packcrnt,CellVoltPort[k])
-                DetaSoc2.append(np.mean(a))  #计算到达3.368V的时长
-
-            #计算11-20号电芯到达特定电压值的平均Soc
-            Socmean2=(sum(DetaSoc2)-max(DetaSoc2)-min(DetaSoc2))/(len(DetaSoc2)-2)
-
-            #计算每个电芯的Soc差
-
-            DetaSoc3=DetaSoc1+DetaSoc2
-            for j in range(len(DetaSoc3)):
-                if j<10:
-                    Socmean=Socmean1
-                else:
-                    Socmean=Socmean2
-                DetaSoc.append(DetaSoc3[j]-Socmean)
-                # DetaSoc.append((DetaT[j]-Tmean)*9.5/(Capacity*3600))
-            df_DetaTime[time[ChgStartValid[i]]]=DetaSoc
-        #漏电流计算
-        column=[]
-        time1=[]
-        sn1=[]
-
-        for index, row in df_DetaTime.iteritems():
-            column.append(index) #提取列名称
-
-        for  i in range(1,len(column)):#计算漏电流值
-            df_DetaTime1[column[i]] = df_DetaTime.apply(lambda x: (x[column[i-1]] -  x[column[i]])*1000*Capacity*3600/((column[i]-column[i-1]).total_seconds()), axis=1)
-            time1.append(column[i])
-            sn1.append(sn)
-        df_detatime['time']=time1
-        df_detatime['sn']=sn1
-
-        for i in range(CellVoltNums):
-            cell=[]
-            for j in range(1,len(column)):
-                cell.append(df_DetaTime1[column[j]][i])
-            df_detatime['cell'+str(i+1)]=cell
-        return df_detatime
-    return pd.DataFrame()

+ 0 - 23
LIB/MIDDLE/LeakCurrent/LeakCurrent表头及数据类型.xlsx

@@ -1,23 +0,0 @@
-ąí͡	ĂűłĆ	ĘýžÝŔŕĐÍ
-time	time	timestamps
-SN	sn	str
-cell1	cell1	float64
-cell2	cell2	float64
-cell3	cell3	float64
-cell4	cell4	float64
-cell5	cell5	float64
-cell6	cell6	float64
-cell7	cell7	float64
-cell8	cell8	float64
-cell9	cell9	float64
-cell10	cell10	float64
-cell11	cell11	float64
-cell12	cell12	float64
-cell13	cell13	float64
-cell14	cell14	float64
-cell15	cell15	float64
-cell16	cell16	float64
-cell17	cell17	float64
-cell18	cell18	float64
-cell19	cell19	float64
-cell20	cell20	float64

+ 0 - 27
LIB/MIDDLE/LeakCurrent/main.py

@@ -1,27 +0,0 @@
-#coding=utf-8
-import os
-import datetime
-import pandas as pd
-from LIB.BACKEND import DBManager, Log
-from LIB.MIDDLE import SignalMonitor
-from sqlalchemy import create_engine
-from sqlalchemy.orm import sessionmaker
-import time, datetime
-import traceback
-import LFPLeakCurrent20210812 as LFPLeakCurrent
-
-from urllib import parse
-
-dbManager = DBManager.DBManager()
-if __name__ == "__main__":
-    SNdata_6060 = pd.read_excel('骑享资产梳理-20210621.xlsx', sheet_name='6060')
-    SNnums_6060=SNdata_6060['SN号']
-    now_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
-    now_time=datetime.datetime.strptime(now_time,'%Y-%m-%d %H:%M:%S')
-    start_time=now_time-datetime.timedelta(days=31)
-    end_time=str(now_time)
-    start_time=str(start_time)
-
-    for sn in SNnums_6060.tolist():
-        res = LFPLeakCurrent.cal_LFPLeakCurrent(sn, end_time, start_time)
-        res.to_csv('BMS_LeakCurrent_'+sn+'.csv',encoding='GB18030')

BIN
PARAMETER/PARAMETER/DTC/平台故障信号定义1.1.xlsx


BIN
PARAMETER/PARAMETER/DTC/格林美7255电池故障定义.docx


BIN
PARAMETER/PARAMETER/OCV/安驰55Ah-SOC-OCV-20210618.xlsx


BIN
PARAMETER/PARAMETER/OCV/格林美7255电池OCV.xlsx