Przeglądaj źródła

Merge branch 'dev' of lmstack/data_analyze_platform into master

lmstack 3 lat temu
rodzic
commit
0970bc3f57

+ 1 - 1
.gitignore

@@ -12,7 +12,6 @@
 *.ppt
 *.tmp
 !/demo.ipynb
-/手册
 !.gitignore
 # *.*
 /CONFIGURE/PathSetting.py
@@ -20,4 +19,5 @@
 /demo.ipynb
 /*/*/deploy.py
 /*/*/*/deploy.py
+!数据分析平台手册.doc
 

+ 7 - 5
LIB/BACKEND/DBManager.py

@@ -210,10 +210,13 @@ class DBManager():
             st = time.time()
             for line in DBManager._download_json_data(urls):
                 et = time.time()
-                if i==0:
-                    data_blocks,CellUNum,CellTNum,OtherTNumm = DBManager._convert_to_dataframe_bms(line, mode)
-                    i+=1
-                    continue
+                try:
+                    if i==0:
+                        data_blocks,CellUNum,CellTNum,OtherTNumm = DBManager._convert_to_dataframe_bms(line, mode)
+                        i+=1
+                        continue
+                except:
+                    i = 0
                 try:
                     data_block,CellUNum,CellTNum,OtherTNumm = DBManager._convert_to_dataframe_bms(line, mode)
                 except:
@@ -225,7 +228,6 @@ class DBManager():
                     'all the input array dimensions except for the concatenation axis must match exactly'  in str(e):
                         pass
                     else:
-                        pdb.set_trace()
                         raise e
   
                 # print('\r'+str(i),end=" ")

+ 19 - 4
LIB/BACKEND/Log.py

@@ -6,6 +6,7 @@ __author__ = 'lmstack'
 
 
 import logging
+from logging import handlers
 import os
 
 class Mylog:
@@ -19,12 +20,19 @@ class Mylog:
     def get_logger(self):
         return self.logger
     
-    def set_file_hl(self, file_name='all.log', log_level='info'):
-        fh = logging.FileHandler(filename=file_name)
+    def set_file_hl(self, file_name='all.log', log_level='info', size=1):
+        fh = handlers.RotatingFileHandler(file_name, maxBytes=size, backupCount=10)
         fh_formatter = logging.Formatter('%(asctime)s:%(created)f:%(name)s:%(module)s:%(funcName)s:%(levelname)s:%(message)s')
         fh.setFormatter(fh_formatter)
         if len(log_level) > 0:
-            self._set_log_level(log_level)
+            if log_level == 'debug':
+                fh.setLevel(logging.DEBUG)
+            if log_level == 'info':
+                fh.setLevel(logging.INFO)
+            if log_level == 'warning':
+                fh.setLevel(logging.WARNING)
+            if log_level == 'error':
+                fh.setLevel(logging.ERROR)
         self.logger.addHandler(fh)
 
     def set_stream_hl(self, log_level='info'):
@@ -32,7 +40,14 @@ class Mylog:
         sh_formatter = logging.Formatter('%(asctime)s:%(created)f:%(name)s:%(module)s:%(funcName)s:%(levelname)s:%(message)s')
         sh.setFormatter(sh_formatter)
         if len(log_level) > 0:
-            self._set_log_level(log_level)
+            if log_level == 'debug':
+                sh.setLevel(logging.DEBUG)
+            if log_level == 'info':
+                sh.setLevel(logging.INFO)
+            if log_level == 'warning':
+                sh.setLevel(logging.WARNING)
+            if log_level == 'error':
+                sh.setLevel(logging.ERROR)
         self.logger.addHandler(sh)  
 
     def _set_log_level(self, log_level):

+ 1 - 1
LIB/BACKEND/Tools.py

@@ -9,7 +9,7 @@ __author__ = 'lmstack'
 # import sys
 # sys.path.append(PathSetting.backend_path)
 from LIB.BACKEND import DBManager
-import DBManager
+# import DBManager
 import pandas as pd
 import numpy as np
 import math

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

@@ -0,0 +1,27 @@
+#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
+from LIB.MIDDLE.LeakCurrent 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')

+ 157 - 0
LIB/FRONTEND/deltsoc/LFPDeltSoc20210804.py

@@ -0,0 +1,157 @@
+# 获取数据
+from LIB.BACKEND import DBManager
+
+import os
+import pandas as pd
+import numpy as np
+import datetime
+# import matplotlib.pyplot as plt
+#参数初始化
+Capacity = 53.6
+PackFullChrgVolt=69.99
+CellFullChrgVolt=3.6
+CellVoltNums=20
+CellTempNums=4
+FullChrgSoc=98
+PeakSoc=57
+
+#获取数据时间段
+def cal_deltsoc(sn, end_time, start_time):
+    end_time = end_time
+    strat_time = start_time
+    SNnum=str(sn)
+
+    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']
+    # 计算电芯Soc差
+    packcrnt = df_bms['总电流[A]']
+    packvolt = df_bms['总电压[V]']
+    SOC = df_bms['SOC[%]']
+    SOH = df_bms['SOH[%]']
+    bmsstat = (df_bms['充电状态']).astype(int)
+    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<46%,电芯温度>15℃的数据
+    if ChgStart:
+        ChgStartValid = []
+        ChgEndValid = []
+
+        for i in range(min(len(ChgStart),len(ChgEnd))):
+            # 获取最小温度值
+            celltemp = []
+            for j in range(1, CellTempNums + 1):
+                s = str(j)
+                temp = df_bms['单体温度' + s]
+                celltemp.append(temp[ChgEnd[i]])
+
+            if SOC[ChgStart[i]] < 46 and SOC[ChgEnd[i]]>80 and min(celltemp) > 10:
+                if ((time[ChgEnd[i]]-time[ChgStart[i]]).total_seconds())/(ChgEnd[i]-ChgStart[i])<30:
+                    ChgStartValid.append(ChgStart[i])
+                    ChgEndValid.append(ChgEnd[i])
+
+    # 计算充电每个单体到达DVDQ峰值的Ah差
+    # 定义滑动平均滤波函数
+    def np_move_avg(a, n, mode="same"):
+        return (np.convolve(a, np.ones((n,)) / n, mode=mode))
+
+
+    # 定义函数:切片Soc>50且Soc<80,并寻找峰值返回峰值点的时间
+    def data_search(t, soc, cellvolt1, packcrnt1):
+        cellvolt2 = np_move_avg(cellvolt1, 5, mode="same")
+        Soc = 0
+        Ah = 0
+        Volt = [cellvolt2[0]]
+        DV_Volt = []
+        DQ_Ah = []
+        DVDQ = []
+        time1 = []
+        soc1 = []
+        soc2 = []
+
+        for m in range(1, len(t)):
+            Step = (t[m] - t[m - 1]).total_seconds()
+            Soc = Soc - packcrnt1[m] * Step * 100 / (3600 * Capacity)
+            Ah = Ah - packcrnt1[m] * Step / 3600
+            if (cellvolt2[m] - Volt[-1]) > 0.9 and Ah>0:
+                DQ_Ah.append(Ah)
+                Volt.append(cellvolt2[m])
+                DV_Volt.append(Volt[-1] - Volt[-2])
+                DVDQ.append((DV_Volt[-1]) / DQ_Ah[-1])
+                Ah = 0
+                time1.append(t[m])
+                soc1.append(Soc)
+                soc2.append(soc[m])
+        df_Data1 = pd.DataFrame({'Time': time1,
+                                'SOC': soc2,
+                                'DVDQ': DVDQ,
+                                'AhSOC': soc1})
+
+        df_Data1 = df_Data1[(df_Data1['SOC'] > 50) & (df_Data1['SOC'] < 75)]
+        # 寻找峰值点,且峰值点个数>3
+        if len(df_Data1['DVDQ'])>2:
+            PeakIndex = df_Data1['DVDQ'].idxmax()
+            df_Data2 = df_Data1[
+                (df_Data1['SOC'] > (df_Data1['SOC'][PeakIndex] - 0.5)) & (df_Data1['SOC'] < (df_Data1['SOC'][PeakIndex] + 0.5))]
+            if len(df_Data2) > 3:
+                return df_Data1['AhSOC'][PeakIndex]
+            else:
+                df_Data1 = df_Data1.drop([PeakIndex])
+                PeakIndex = df_Data1['DVDQ'].idxmax()
+                return df_Data1['AhSOC'][PeakIndex]
+
+
+    # 计算最大最小Soc差
+    if ChgStartValid:
+        DetaSoc2 = []
+        DetaSoc=[]
+        DetaSoc_SN=[]
+        DetaSoc_time=[]
+        for i in range(len(ChgStartValid)):
+            DetaSoc1 = []
+            for j in range(1, CellVoltNums + 1):
+                s = str(j)
+                cellvolt = df_bms['单体电压' + s]
+                cellvolt = list(cellvolt[ChgStartValid[i]:ChgEndValid[i]])
+                Time = list(time[ChgStartValid[i]:ChgEndValid[i]])
+                Packcrnt = list(packcrnt[ChgStartValid[i]:ChgEndValid[i]])
+                SOC1 = list(SOC[ChgStartValid[i]:ChgEndValid[i]])
+                a = data_search(Time, SOC1, cellvolt, Packcrnt)
+                if a:
+                    DetaSoc1.append(a)  # 计算到达峰值点的累计Soc
+            if DetaSoc1:
+                DetaSoc2.append(max(DetaSoc1) - min(DetaSoc1))
+
+        DetaSocMean = np.mean(DetaSoc2)
+        DetaSoc.append(DetaSocMean)
+        DetaSoc_SN.append(SNnum)
+        DetaSoc_time.append(time[ChgStartValid[-1]])
+
+
+        result_DetaSoc={'time':DetaSoc_time,
+                        'SN号':DetaSoc_SN,
+                        'Soc差':DetaSoc}
+        Result_DetaSoc=pd.DataFrame(result_DetaSoc)
+        return Result_DetaSoc
+    return pd.DataFrame()
+
+

+ 4 - 0
LIB/FRONTEND/deltsoc/detaSOC表头及数据类型.xlsx

@@ -0,0 +1,4 @@
+±íÍ·	Ãû³Æ	Êý¾ÝÀàÐÍ
+time	time	timestamps
+SNºÅ	sn	str
+Soc²î	deta_soc	float64

+ 27 - 0
LIB/FRONTEND/deltsoc/main.py

@@ -0,0 +1,27 @@
+#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
+from LIB.MIDDLE.DeltSoc import LFPDeltSoc20210804 as LFPDeltSoc
+
+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 = LFPDeltSoc.cal_deltsoc(sn, end_time, start_time)
+        res.to_csv('BMS_DetaSoc_'+sn+'.csv',encoding='GB18030')

BIN
LIB/FRONTEND/deltsoc/骑享资产梳理-20210621.xlsx


+ 155 - 0
LIB/MIDDLE/DeltSoc/LFPDeltSoc20210804.py

@@ -0,0 +1,155 @@
+# 获取数据
+from LIB.BACKEND import DBManager
+
+import os
+import pandas as pd
+import numpy as np
+import datetime
+# import matplotlib.pyplot as plt
+#参数初始化
+Capacity = 53.6
+PackFullChrgVolt=69.99
+CellFullChrgVolt=3.6
+CellVoltNums=20
+CellTempNums=4
+FullChrgSoc=98
+PeakSoc=57
+
+#获取数据时间段
+def cal_deltsoc(sn, end_time, start_time):
+    end_time = end_time
+    strat_time = start_time
+    SNnum=str(sn)
+
+    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']
+    # 计算电芯Soc差
+    packcrnt = df_bms['总电流[A]']
+    packvolt = df_bms['总电压[V]']
+    SOC = df_bms['SOC[%]']
+    SOH = df_bms['SOH[%]']
+    bmsstat = (df_bms['充电状态']).astype(int)
+    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<46%,电芯温度>15℃的数据
+    ChgStartValid = []
+    ChgEndValid = []
+    if ChgStart:
+        for i in range(min(len(ChgStart),len(ChgEnd))):
+            # 获取最小温度值
+            celltemp = []
+            for j in range(1, CellTempNums + 1):
+                s = str(j)
+                temp = df_bms['单体温度' + s]
+                celltemp.append(temp[ChgEnd[i]])
+
+            if SOC[ChgStart[i]] < 46 and SOC[ChgEnd[i]]>85 and min(celltemp) > 10 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])
+
+    # 计算充电每个单体到达DVDQ峰值的Ah差
+    # 定义滑动平均滤波函数
+    def np_move_avg(a, n, mode="same"):
+        return (np.convolve(a, np.ones((n,)) / n, mode=mode))
+
+
+    # 定义函数:切片Soc>50且Soc<80,并寻找峰值返回峰值点的时间
+    def data_search(t, soc, cellvolt1, packcrnt1):
+        cellvolt2 = np_move_avg(cellvolt1, 5, mode="same")
+        Soc = 0
+        Ah = 0
+        Volt = [cellvolt2[0]]
+        DV_Volt = []
+        DQ_Ah = []
+        DVDQ = []
+        time1 = []
+        soc1 = []
+        soc2 = []
+
+        for m in range(1, len(t)):
+            Step = (t[m] - t[m - 1]).total_seconds()
+            Soc = Soc - packcrnt1[m] * Step * 100 / (3600 * Capacity)
+            Ah = Ah - packcrnt1[m] * Step / 3600
+            if (cellvolt2[m] - Volt[-1]) > 0.9 and Ah>0:
+                DQ_Ah.append(Ah)
+                Volt.append(cellvolt2[m])
+                DV_Volt.append(Volt[-1] - Volt[-2])
+                DVDQ.append((DV_Volt[-1]) / DQ_Ah[-1])
+                Ah = 0
+                time1.append(t[m])
+                soc1.append(Soc)
+                soc2.append(soc[m])
+        df_Data1 = pd.DataFrame({'Time': time1,
+                                'SOC': soc2,
+                                'DVDQ': DVDQ,
+                                'AhSOC': soc1})
+
+        df_Data1 = df_Data1[(df_Data1['SOC'] > 50) & (df_Data1['SOC'] < 80)]
+        # 寻找峰值点,且峰值点个数>3
+        if len(df_Data1['DVDQ'])>2:
+            PeakIndex = df_Data1['DVDQ'].idxmax()
+            df_Data2 = df_Data1[
+                (df_Data1['SOC'] > (df_Data1['SOC'][PeakIndex] - 0.5)) & (df_Data1['SOC'] < (df_Data1['SOC'][PeakIndex] + 0.5))]
+            if len(df_Data2) > 3:
+                return df_Data1['AhSOC'][PeakIndex]
+            else:
+                df_Data1 = df_Data1.drop([PeakIndex])
+                PeakIndex = df_Data1['DVDQ'].idxmax()
+                return df_Data1['AhSOC'][PeakIndex]
+
+
+    # 计算最大最小Soc差
+    if ChgStartValid:
+        DetaSoc2 = []
+        DetaSoc=[]
+        DetaSoc_SN=[]
+        DetaSoc_time=[]
+        for i in range(len(ChgStartValid)):
+            DetaSoc1 = []
+            for j in range(1, CellVoltNums + 1):
+                s = str(j)
+                cellvolt = df_bms['单体电压' + s]
+                cellvolt = list(cellvolt[ChgStartValid[i]:ChgEndValid[i]])
+                Time = list(time[ChgStartValid[i]:ChgEndValid[i]])
+                Packcrnt = list(packcrnt[ChgStartValid[i]:ChgEndValid[i]])
+                SOC1 = list(SOC[ChgStartValid[i]:ChgEndValid[i]])
+                a = data_search(Time, SOC1, cellvolt, Packcrnt)
+                if a:
+                    DetaSoc1.append(a)  # 计算到达峰值点的累计Soc
+            if DetaSoc1:
+                DetaSoc2.append(max(DetaSoc1) - min(DetaSoc1))
+
+        DetaSocMean = np.mean(DetaSoc2)
+        DetaSoc.append(DetaSocMean)
+        DetaSoc_SN.append(SNnum)
+        DetaSoc_time.append(time[ChgStartValid[-1]])
+
+
+        result_DetaSoc={'time':DetaSoc_time,
+                        'SN号':DetaSoc_SN,
+                        'Soc差':DetaSoc}
+        Result_DetaSoc=pd.DataFrame(result_DetaSoc)
+        return Result_DetaSoc
+    return pd.DataFrame()
+
+

+ 4 - 0
LIB/MIDDLE/DeltSoc/detaSOC表头及数据类型.xlsx

@@ -0,0 +1,4 @@
+±íÍ·	Ãû³Æ	Êý¾ÝÀàÐÍ
+time	time	timestamps
+SNºÅ	sn	str
+Soc²î	deta_soc	float64

BIN
LIB/MIDDLE/DeltSoc/骑享资产梳理-20210621.xlsx


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

@@ -0,0 +1,160 @@
+# 获取数据
+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()

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

@@ -0,0 +1,23 @@
+ąí͡	ĂűłĆ	ĘýžÝŔŕĐÍ
+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

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

@@ -0,0 +1,27 @@
+#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
LIB/MIDDLE/odo/__pycache__/CalDist.cpython-38.pyc


+ 169 - 0
LIB/MIDDLE/soh/NCMSoh_4842.py

@@ -0,0 +1,169 @@
+# 获取数据
+from LIB.BACKEND import DBManager
+
+import os
+import pandas as pd
+import numpy as np
+import datetime
+# import matplotlib.pyplot as plt
+
+#参数输入
+Capacity = 41
+PackFullChrgVolt=69.99
+CellFullChrgVolt=3.5
+CellVoltNums=14
+CellTempNums=4
+FullChrgSoc=98
+PeakSoc=57
+# #40Ah-OCV
+LookTab_SOC = [0,	3.534883489,	8.358178409,	13.18141871,	18.00471528,	22.82796155,	27.65123833,	32.47444668,	37.29772717,	42.12099502,	46.94423182,	51.76744813,	56.59070685,	61.4139927,	66.23719857,	71.0604667,	75.88373853,	80.70702266,	85.5302705,	90.35352009,	95.17676458,	100]
+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]
+# #55Ah-OCV
+# 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]
+# 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]
+
+#参数初始化
+Soh3=[]
+Time3=[]
+Bms_Soh3=[]
+Soh_Err3=[]
+sn_list=[]
+
+#获取数据时间段
+
+def cal_soh(sn, end_time, start_time):
+    end_time = end_time
+    strat_time = start_time
+    SNnum=str(sn)
+
+    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'])
+    data = df_data['bms']
+    # print(data)
+
+    packcrnt=data['总电流[A]']
+    packvolt=data['总电压[V]']
+    SOC=data['SOC[%]']
+    SOH=data['SOH[%]']
+    bmsstat=data['充电状态']
+    time= pd.to_datetime(data['时间戳'], format='%Y-%m-%d %H:%M:%S')
+
+    #第一步:筛选充电数据
+    if len(packcrnt)>100:
+        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-1)
+            elif i == (len(time) - 4) and bmsstat[len(bmsstat)-1] == 2 and bmsstat[len(bmsstat)-2] == 2:
+                ChgEnd.append(len(time)-2)
+
+        #第二步:筛选充电起始Soc<45% & SOC>85%,电芯温度>5℃
+        ChgStartValid1=[]
+        ChgEndValid1=[]
+        ChgStartValid2=[]
+        ChgEndValid2=[]
+        StandingNum=[]
+
+        for i in range(min(len(ChgStart),len(ChgEnd))):
+
+            #获取最小温度值
+            celltemp = []
+            for j in range(1, CellTempNums+1):
+                s = str(j)
+                temp = data['单体温度' + s]
+                celltemp.append(temp[ChgEnd[i]])
+            
+            #去除电流0点   
+            for k in range(ChgStart[i],ChgEnd[i]):
+                if packcrnt[k]<-0.5 and packcrnt[k+1]>-0.5 and packcrnt[k+2]>-0.5 and packcrnt[k+3]>-0.5:
+                    ChgEnd[i]=k
+            
+            #计算最大packvolt
+            if len(packvolt[ChgStart[i]:ChgEnd[i]])>0:
+                packvoltMAX=max(packvolt[ChgStart[i]:ChgEnd[i]])
+
+                #筛选满足2点法计算的数据
+                StandingTime=0
+                StandingTime1=0
+                StandingTime2=0
+                if SOC[ChgEnd[i]]>85 and SOC[ChgStart[i]]<45 and min(celltemp)>5:
+                    for m in range(min(len(packcrnt)-ChgEnd[i]-2,ChgStart[i]-2)):
+                        if abs(packcrnt[ChgStart[i] - m - 1]) < 0.1:
+                            StandingTime = StandingTime + (time[ChgStart[i] - m] - time[ChgStart[i] - m - 1]).total_seconds()
+                        if abs(packcrnt[ChgEnd[i] + m + 1]) < 0.1:
+                            StandingTime1 = StandingTime1 + (time[ChgEnd[i] + m + 1] - time[ChgEnd[i] + m]).total_seconds()
+                        if StandingTime > 900 and StandingTime1>900 and ((time[ChgEnd[i]]-time[ChgStart[i]]).total_seconds())/(ChgEnd[i]-ChgStart[i])<60:  #筛选静置时间>15min且慢充过程丢失数据少
+                            ChgStartValid1.append(ChgStart[i])
+                            ChgEndValid1.append(ChgEnd[i])
+                            StandingNum.append(m)
+                            break
+                        if abs(packcrnt[ChgStart[i] - m - 2])>0.5 and abs(packcrnt[ChgEnd[i] + m + 2])>0.5:
+                            break
+
+        # 计算soh
+        Soh1=[]
+        Soh2=[]
+        Time1=[]
+        Bms_Soh1=[]
+        Soh_Err1=[]
+        sn_list1=[]
+        #两点法计算Soh
+        if len(ChgStartValid1)>0:
+            for i in range(len(ChgStartValid1)):
+                #计算Ah
+                Ah=0
+                for j in range(ChgStartValid1[i],ChgEndValid1[i]):
+                    Step=(time[j+1]-time[j]).total_seconds()
+                    Ah=Ah-packcrnt[j+1]*Step/3600
+                #计算每个电芯的Soh
+                for j in range(1, CellVoltNums+1):
+                    s = str(j)
+                    cellvolt = data['单体电压' + s]/1000
+                    OCVStart=cellvolt[ChgStartValid1[i]-2]
+                    OCVEnd=cellvolt[ChgEndValid1[i]+StandingNum[i]]
+                    #soh
+                    Ocv_Soc1=np.interp(OCVStart,LookTab_OCV,LookTab_SOC)
+                    Ocv_Soc2=np.interp(OCVEnd,LookTab_OCV,LookTab_SOC)
+                    Soh2.append(Ah*100/((Ocv_Soc2-Ocv_Soc1)*0.01*Capacity))
+                Soh1.append(np.mean(Soh2))
+                Bms_Soh1.append(SOH[ChgStartValid1[i]])
+                Soh_Err1.append(Bms_Soh1[-1]-Soh1[-1])
+                Time1.append(time[ChgStartValid1[i]])
+                sn_list1.append(SNnum)
+       
+            # Soh3.append(np.mean(Soh1))
+            # Bms_Soh3.append(np.mean(Bms_Soh1))
+            # Soh_Err3.append(np.mean(Soh_Err1))
+            # Time3.append(time[ChgStartValid1[-1]])
+            # sn_list.append(SNnum)
+
+        #第四步:将数据存入Excel
+            result_soh2={'时间': Time1,
+                'SN号': sn_list1,
+                'BMS_SOH': Bms_Soh1,
+                'SOH': Soh1,
+                'SOH误差': Soh_Err1}
+
+            Result_Soh2=pd.DataFrame(result_soh2)
+            # Result_Soh2.to_csv('BMS_SOH_'+SNnum+'.csv',encoding='GB18030')
+            return Result_Soh2
+    return pd.DataFrame()
+
+#     result_soh1={'时间': Time3,
+#         'SN号':sn_list,
+#         'BMS_SOH': Bms_Soh3,
+#         'SOH': Soh3,
+#         'SOH误差': Soh_Err3}
+
+# Result_Soh1=pd.DataFrame(result_soh1)
+# print(Result_Soh1)
+# Result_Soh1.to_csv('BMS_SOH_'+'6040'+'.csv',encoding='GB18030')

+ 22 - 0
demo.ipynb

@@ -132,6 +132,28 @@
    ],
    "metadata": {}
   },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "source": [
+    "from LIB.BACKEND import DBManager, Log\r\n",
+    "log = Log.Mylog(log_name='signal_monitor', log_level = 'info')\r\n",
+    "log.set_file_hl(file_name='info.log', log_level='info')\r\n",
+    "log.set_file_hl(file_name='error.log', log_level='error')\r\n",
+    "logger = log.get_logger()\r\n"
+   ],
+   "outputs": [],
+   "metadata": {}
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "source": [
+    "logger.error(\"ttt5\")"
+   ],
+   "outputs": [],
+   "metadata": {}
+  },
   {
    "cell_type": "code",
    "execution_count": null,

BIN
数据分析平台手册.doc


BIN
数据分析平台手册.pdf