Преглед на файлове

新增转出json的算法

wenjia Li преди 4 месеца
родител
ревизия
8ccb6c2eb4

+ 9 - 9
dataAnalysisBusiness/algorithm/faultAnalyst.py

@@ -20,7 +20,6 @@ class FaultAnalyst(AnalystNotFilter):
     def turbinesAnalysis(self,outputAnalysisDir, conf: Contract, turbineCodes):
         dictionary = self.processTurbineData(turbineCodes,conf,self.selectColumns())
         dataFrameMerge = self.userDataFrame(dictionary,conf.dataContract.configAnalysis,self)
-        
         return self.get_result(dataFrameMerge, outputAnalysisDir, conf)
 
     def get_result(self, dataFrame: pd.DataFrame, outputAnalysisDir: str, conf: Contract):
@@ -52,14 +51,15 @@ class FaultAnalyst(AnalystNotFilter):
         # 合并所有风机的故障统计结果
         turbine_fault_summary = pd.concat(results, ignore_index=True)
         turbine_fault_sorted = turbine_fault_summary.sort_values(by='fault_time', ascending=False)
-
+        # 故障类型前十名
+        draw_results=turbine_fault_sorted.head(10)
         # 保存结果
-        results_row = []
+        result_rows = []
 
         filePathOfturbinefault = os.path.join(outputAnalysisDir, f"turbine_fault_result{CSVSuffix}")
-        turbine_fault_sorted.to_csv(filePathOfturbinefault, index=False)
+        turbine_fault_sorted.to_csv(filePathOfturbinefault, index=False,encoding='utf-8-sig')
 
-        results_row.append({
+        result_rows.append({
             Field_Return_TypeAnalyst: self.typeAnalyst(),
             Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID,
             Field_Return_BatchCode: conf.dataContract.dataFilter.dataBatchNum,
@@ -69,9 +69,9 @@ class FaultAnalyst(AnalystNotFilter):
         })
 
         filePathOftotalfault = os.path.join(outputAnalysisDir, f"total_fault_result{CSVSuffix}")
-        fault_summary_sorted.to_csv(filePathOftotalfault, index=False)
+        fault_summary_sorted.to_csv(filePathOftotalfault, index=False,encoding='utf-8-sig')
 
-        results_row.append({
+        result_rows.append({
             Field_Return_TypeAnalyst: self.typeAnalyst(),
             Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID,
             Field_Return_BatchCode: conf.dataContract.dataFilter.dataBatchNum,
@@ -79,5 +79,5 @@ class FaultAnalyst(AnalystNotFilter):
             Field_Return_FilePath: filePathOftotalfault,
             Field_Return_IsSaveDatabase: True
         })
-
-        return results_row
+        result_df = pd.DataFrame(result_rows)
+        return result_df

+ 13 - 14
dataAnalysisBusiness/algorithm/powerScatter2DAnalyst.py

@@ -103,8 +103,7 @@ class PowerScatter2DAnalyst(AnalystWithGoodBadPoint):
             "#3E409C"
 
         ]
-        # 新建一个列表存储输出json格式的数据
-        turbine_data_list = []
+
         # 遍历每个设备的数据
         for name, group in grouped:
             fig = make_subplots()
@@ -226,10 +225,10 @@ class PowerScatter2DAnalyst(AnalystWithGoodBadPoint):
             pngFilePath = os.path.join(outputAnalysisDir, pngFileName)
             fig.write_image(pngFilePath, scale=3)
 
-            # 保存HTML
-            htmlFileName = f"{name[0]}-scatter.html"
-            htmlFilePath = os.path.join(outputAnalysisDir, htmlFileName)
-            fig.write_html(htmlFilePath)
+            # # 保存HTML
+            # htmlFileName = f"{name[0]}-scatter.html"
+            # htmlFilePath = os.path.join(outputAnalysisDir, htmlFileName)
+            # fig.write_html(htmlFilePath)
 
 
             # 将JSON对象保存到文件
@@ -257,14 +256,14 @@ class PowerScatter2DAnalyst(AnalystWithGoodBadPoint):
                 Field_Return_IsSaveDatabase: False
             })
 
-            result_rows.append({
-                Field_Return_TypeAnalyst: self.typeAnalyst(),
-                Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID,
-                Field_Return_BatchCode: conf.dataContract.dataFilter.dataBatchNum,
-                Field_CodeOfTurbine: name[1],
-                Field_Return_FilePath: htmlFilePath,
-                Field_Return_IsSaveDatabase: True
-            })
+            # result_rows.append({
+            #     Field_Return_TypeAnalyst: self.typeAnalyst(),
+            #     Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID,
+            #     Field_Return_BatchCode: conf.dataContract.dataFilter.dataBatchNum,
+            #     Field_CodeOfTurbine: name[1],
+            #     Field_Return_FilePath: htmlFilePath,
+            #     Field_Return_IsSaveDatabase: True
+            # })
        
 
         result_df = pd.DataFrame(result_rows)

+ 93 - 46
dataAnalysisBusiness/algorithm/ratedPowerWindSpeedAnalyst.py

@@ -19,27 +19,9 @@ class RatedPowerWindSpeedAnalyst(AnalystWithGoodBadPoint):
 
     def turbinesAnalysis(self, outputAnalysisDir, conf: Contract, turbineCodes):
         dictionary=self.processTurbineData(turbineCodes,conf,[Field_DeviceCode,Field_Time,Field_EnvTemp,Field_WindSpeed,Field_ActiverPower])
-        # dataFrameMerge=self.userDataFrame(dictionary,conf.dataContract.configAnalysis,self)
-        dataFrameOfTurbines = self.userDataFrame(
-            dictionary, conf.dataContract.configAnalysis, self)
-
-        turbrineInfos = self.common.getTurbineInfos(
-            conf.dataContract.dataFilter.powerFarmID, turbineCodes, self.turbineInfo)
-
-        groupedOfTurbineModel = turbrineInfos.groupby(Field_MillTypeCode)
-
-        returnDatas = []
-        for turbineModelCode, group in groupedOfTurbineModel:
-            currTurbineCodes = group[Field_CodeOfTurbine].unique().tolist()
-            currTurbineModeInfo = self.common.getTurbineModelByCode(
-                turbineModelCode, self.turbineModelInfo)
-            currDataFrameOfTurbines = dataFrameOfTurbines[dataFrameOfTurbines[Field_CodeOfTurbine].isin(
-                currTurbineCodes)]
-            returnData= self.draw(currDataFrameOfTurbines, outputAnalysisDir, conf,currTurbineModeInfo)
-            returnDatas.append(returnData)
-
-        returnResult = pd.concat(returnDatas, ignore_index=True) 
-        return returnResult
+        dataFrameMerge=self.userDataFrame(dictionary,conf.dataContract.configAnalysis,self)
+        turbineInfos = self.common.getTurbineInfos(conf.dataContract.dataFilter.powerFarmID, turbineCodes, self.turbineInfo)
+        return self.draw(dataFrameMerge, outputAnalysisDir, conf,turbineInfos)
 
     def draw(self, dataFrameMerge: pd.DataFrame, outputAnalysisDir, conf: Contract,turbineModelInfo: pd.Series):
         """
@@ -98,37 +80,73 @@ class RatedPowerWindSpeedAnalyst(AnalystWithGoodBadPoint):
         fig.update_xaxes(title_text='机组', type='category',
                          tickangle=-45, tickfont=dict(size=10))
         fig.update_layout(title={
-                          'text': f'额定功率分布(环境温度>=25摄氏度)-{turbineModelInfo[Field_MachineTypeCode]}', 'x': 0.5}, boxmode='group')
-
+                          'text': f'额定功率分布(环境温度>=25摄氏度)', 'x': 0.5}, boxmode='group')
+        # 确保从 Series 中提取的是具体的值
+        engineTypeCode = turbineModelInfo.get(Field_MillTypeCode, "")
+        if isinstance(engineTypeCode, pd.Series):
+            engineTypeCode = engineTypeCode.iloc[0]
+        engineTypeName = turbineModelInfo.get(Field_MachineTypeCode, "")
+        if isinstance(engineTypeName, pd.Series):
+            engineTypeName = engineTypeName.iloc[0]
+        # 构建最终的JSON对象
+        json_output = {
+            "analysisTypeCode": "额定功率和风速分析",
+            "engineCode":  engineTypeCode,    
+            "engineTypeName": engineTypeName, 
+            "xaixs": "机组",
+            "yaixs": "功率(kw)",
+            "data": [{
+                    "title":f'额定功率分布(环境温度>=25摄氏度)',
+                    "xData": over_temp[Field_NameOfTurbine].tolist(),
+                    "yData": over_temp[Field_ActiverPower].tolist(),
+                    "linecolor":'black', 
+                    "linewidth":1,
+                    "fillcolor":'dodgerblue'
+                    }]
+        }
         result_rows = []
         # 保存图像
         pngFileName = "额定满发风速功率分布(10min)(环境温度大于25度).png"
         pngFilePath = os.path.join(outputAnalysisDir, pngFileName)
         fig.write_image(pngFilePath, scale=3)
-
-        # 保存HTML
-        htmlFileName = "额定满发风速功率分布(10min)(环境温度大于25度).html"
-        htmlFilePath = os.path.join(outputAnalysisDir, htmlFileName)
-        fig.write_html(htmlFilePath)
-
+       
+        # # 保存HTML
+        # htmlFileName = "额定满发风速功率分布(10min)(环境温度大于25度).html"
+        # htmlFilePath = os.path.join(outputAnalysisDir, htmlFileName)
+        # fig.write_html(htmlFilePath)
+        # 保存Json
+        # 将JSON对象保存到文件
+        output_json_path = os.path.join(outputAnalysisDir, "额定满发风速功率分布(10min)(环境温度大于25度).json")
+        with open(output_json_path, 'w', encoding='utf-8') as f:
+            import json
+            json.dump(json_output, f, ensure_ascii=False, indent=4)
+        # 如果需要返回DataFrame,可以包含文件路径
         result_rows.append({
             Field_Return_TypeAnalyst: self.typeAnalyst(),
             Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID,
             Field_Return_BatchCode: conf.dataContract.dataFilter.dataBatchNum,
             Field_CodeOfTurbine: 'total',
-            Field_Return_FilePath: pngFilePath,
-            Field_Return_IsSaveDatabase: False
+            Field_Return_FilePath: output_json_path,
+            Field_Return_IsSaveDatabase: True
         })
-
         result_rows.append({
             Field_Return_TypeAnalyst: self.typeAnalyst(),
             Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID,
             Field_Return_BatchCode: conf.dataContract.dataFilter.dataBatchNum,
             Field_CodeOfTurbine: 'total',
-            Field_Return_FilePath: htmlFilePath,
-            Field_Return_IsSaveDatabase: True
+            Field_Return_FilePath: pngFilePath,
+            Field_Return_IsSaveDatabase: False
         })
 
+        # result_rows.append({
+        #     Field_Return_TypeAnalyst: self.typeAnalyst(),
+        #     Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID,
+        #     Field_Return_BatchCode: conf.dataContract.dataFilter.dataBatchNum,
+        #     Field_CodeOfTurbine: 'total',
+        #     Field_Return_FilePath: htmlFilePath,
+        #     Field_Return_IsSaveDatabase: True
+        # })
+
         # 绘制环境温度小于25℃的功率分布图
         fig = make_subplots(rows=1, cols=1)
         fig.add_trace(go.Box(y=below_temp[Field_ActiverPower], x=below_temp[Field_NameOfTurbine],
@@ -160,36 +178,65 @@ class RatedPowerWindSpeedAnalyst(AnalystWithGoodBadPoint):
         fig.update_xaxes(title_text='机组', type='category',
                          tickangle=-45, tickfont=dict(size=10))
         fig.update_layout(title={
-                          'text': f'额定功率分布(环境温度<25摄氏度)-{turbineModelInfo[Field_MachineTypeCode]}', 'x': 0.5}, boxmode='group')
-
+                          'text': f'额定功率分布(环境温度<25摄氏度)', 'x': 0.5}, boxmode='group')
+        # 构建最终的JSON对象2
+        json_output2 = {
+            "analysisTypeCode": "额定功率和风速分析",
+            "engineCode":  engineTypeCode,    
+            "engineTypeName": engineTypeName, 
+            "xaixs": "机组",
+            "yaixs": "功率(kw)",
+            "data": [{
+                    "title":f'额定功率分布(环境温度<25摄氏度)',
+                    "xData": below_temp[Field_NameOfTurbine].tolist(),
+                    "yData": below_temp[Field_ActiverPower].tolist(),
+                    "linecolor":'black', 
+                    "linewidth":1,
+                    "fillcolor":'dodgerblue'
+                    }]
+        }
         # 保存图像
         pngFileName = "额定满发风速功率分布(10min)(环境温度小于25度).png"
         pngFilePath = os.path.join(outputAnalysisDir, pngFileName)
         fig.write_image(pngFilePath, scale=3)
 
-        # 保存HTML
-        htmlFileName = "额定满发风速功率分布(10min)(环境温度小于25度).html"
-        htmlFilePath = os.path.join(outputAnalysisDir, htmlFileName)
-        fig.write_html(htmlFilePath)
-
+        # # 保存HTML
+        # htmlFileName = "额定满发风速功率分布(10min)(环境温度小于25度).html"
+        # htmlFilePath = os.path.join(outputAnalysisDir, htmlFileName)
+        # fig.write_html(htmlFilePath)
+                # 保存Json
+        # 将JSON对象保存到文件
+        output_json_path2 = os.path.join(outputAnalysisDir, "额定满发风速功率分布(10min)(环境温度小于25度).json")
+        with open(output_json_path2, 'w', encoding='utf-8') as f:
+            import json
+            json.dump(json_output2, f, ensure_ascii=False, indent=4)
+        # 如果需要返回DataFrame,可以包含文件路径
         result_rows.append({
             Field_Return_TypeAnalyst: self.typeAnalyst(),
             Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID,
             Field_Return_BatchCode: conf.dataContract.dataFilter.dataBatchNum,
             Field_CodeOfTurbine: 'total',
-            Field_Return_FilePath: pngFilePath,
-            Field_Return_IsSaveDatabase: False
+            Field_Return_FilePath: output_json_path2,
+            Field_Return_IsSaveDatabase: True
         })
-
         result_rows.append({
             Field_Return_TypeAnalyst: self.typeAnalyst(),
             Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID,
             Field_Return_BatchCode: conf.dataContract.dataFilter.dataBatchNum,
             Field_CodeOfTurbine: 'total',
-            Field_Return_FilePath: htmlFilePath,
-            Field_Return_IsSaveDatabase: True
+            Field_Return_FilePath: pngFilePath,
+            Field_Return_IsSaveDatabase: False
         })
 
+        # result_rows.append({
+        #     Field_Return_TypeAnalyst: self.typeAnalyst(),
+        #     Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID,
+        #     Field_Return_BatchCode: conf.dataContract.dataFilter.dataBatchNum,
+        #     Field_CodeOfTurbine: 'total',
+        #     Field_Return_FilePath: htmlFilePath,
+        #     Field_Return_IsSaveDatabase: True
+        # })
+
         result_df = pd.DataFrame(result_rows)
 
         return result_df

+ 77 - 63
dataAnalysisBusiness/algorithm/windDirectionFrequencyAnalyst.py

@@ -227,8 +227,8 @@ class WindDirectionFrequencyAnalyst(AnalystNotFilter):
             # 保存图像
             filePathOfImage = os.path.join(outputAnalysisDir, f"{name[0]}.png")
             fig.write_image(filePathOfImage, scale=3)
-            filePathOfHtml  = os.path.join(outputAnalysisDir, f"{name[0]}.html")
-            fig.write_html(filePathOfHtml)
+            # filePathOfHtml  = os.path.join(outputAnalysisDir, f"{name[0]}.html")
+            # fig.write_html(filePathOfHtml)
 
             result_rows.append({
                 Field_Return_TypeAnalyst: self.typeAnalyst(),
@@ -239,14 +239,14 @@ class WindDirectionFrequencyAnalyst(AnalystNotFilter):
                 Field_Return_IsSaveDatabase: False
             })
 
-            result_rows.append({
-                Field_Return_TypeAnalyst: self.typeAnalyst(),
-                Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID, 
-                Field_Return_BatchCode: conf.dataContract.dataFilter.dataBatchNum,
-                Field_CodeOfTurbine: name[1],
-                Field_Return_FilePath: filePathOfHtml,
-                Field_Return_IsSaveDatabase: True
-            })
+            # result_rows.append({
+            #     Field_Return_TypeAnalyst: self.typeAnalyst(),
+            #     Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID, 
+            #     Field_Return_BatchCode: conf.dataContract.dataFilter.dataBatchNum,
+            #     Field_CodeOfTurbine: name[1],
+            #     Field_Return_FilePath: filePathOfHtml,
+            #     Field_Return_IsSaveDatabase: True
+            # })
 
         result_df = pd.DataFrame(result_rows)
 
@@ -255,23 +255,39 @@ class WindDirectionFrequencyAnalyst(AnalystNotFilter):
     
     def outputJsonData(self, conf: Contract, outputAnalysisDir: str, turbineModelInfo: pd.Series, dataFrameMerge: pd.DataFrame) -> pd.DataFrame:
         turbineCodes = dataFrameMerge[Field_CodeOfTurbine].unique()
-        jsonDictionary = self.convert2Json(turbineModelInfo, turbineCodes=turbineCodes, dataFrameOfTurbines=dataFrameMerge)
-        jsonFileName = f"风向玫瑰图.json"
-        jsonFilePath = os.path.join(outputAnalysisDir, jsonFileName)
-    
-        JsonUtil.write_json(jsonDictionary, file_path=jsonFilePath)
+        
         result_rows = []
+        for turbineCode in turbineCodes:
+            jsonDictionary = self.convert2Json(turbineModelInfo, turbineCodes=turbineCode, dataFrameOfTurbines=dataFrameMerge)
+            jsonFileName = f"风向玫瑰图{turbineCode}.json"
+            jsonFilePath = os.path.join(outputAnalysisDir, jsonFileName)
+            JsonUtil.write_json(jsonDictionary, file_path=jsonFilePath)
+            result_rows.append({
+                Field_Return_TypeAnalyst: self.typeAnalyst(),
+                Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID,
+                Field_Return_BatchCode: conf.dataContract.dataFilter.dataBatchNum,
+                Field_CodeOfTurbine: turbineCode,
+                Field_Return_FilePath: jsonFilePath,
+                Field_Return_IsSaveDatabase: True
+            })
     
-        # result_rows.append({
-        #     Field_Return_TypeAnalyst: self.typeAnalyst(),
-        #     Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID,
-        #     Field_Return_BatchCode: conf.dataContract.dataFilter.dataBatchNum,
-        #     Field_CodeOfTurbine: Const_Output_Total,
-        #     Field_Return_FilePath: jsonFilePath,
-        #     Field_Return_IsSaveDatabase: True
-        # })
-    
+        returnDatas = pd.DataFrame(result_rows)
+        return returnDatas
+
+    def outputJsonData(self, conf: Contract, outputAnalysisDir: str, turbineModelInfo: pd.Series, dataFrameMerge: pd.DataFrame) -> pd.DataFrame:
+        turbineCodes = dataFrameMerge[Field_CodeOfTurbine].unique()
+        
+        result_rows = []
         for turbineCode in turbineCodes:
+            if turbineCode in self.frequency_data:
+                # 确保 enginName 是具体的值
+                enginName = dataFrameMerge[dataFrameMerge[Field_CodeOfTurbine] == turbineCode][Field_NameOfTurbine].iloc[0]
+                if isinstance(enginName, pd.Series):
+                    enginName = enginName.iloc[0]
+            jsonDictionary = self.convert2Json(turbineModelInfo, turbineCode, dataFrameMerge)
+            jsonFileName = f"风向玫瑰图_{enginName}.json"
+            jsonFilePath = os.path.join(outputAnalysisDir, jsonFileName)
+            JsonUtil.write_json(jsonDictionary, file_path=jsonFilePath)
             result_rows.append({
                 Field_Return_TypeAnalyst: self.typeAnalyst(),
                 Field_PowerFarmCode: conf.dataContract.dataFilter.powerFarmID,
@@ -284,7 +300,7 @@ class WindDirectionFrequencyAnalyst(AnalystNotFilter):
         returnDatas = pd.DataFrame(result_rows)
         return returnDatas
 
-    def convert2Json(self, turbineModelInfo: pd.Series, turbineCodes, dataFrameOfTurbines: pd.DataFrame):
+    def convert2Json(self, turbineModelInfo: pd.Series, turbineCode, dataFrameOfTurbines: pd.DataFrame):
         # 确保从 Series 中提取的是具体的值
         engineTypeCode = turbineModelInfo.get(Field_MillTypeCode, "")
         if isinstance(engineTypeCode, pd.Series):
@@ -294,42 +310,40 @@ class WindDirectionFrequencyAnalyst(AnalystNotFilter):
         if isinstance(engineTypeName, pd.Series):
             engineTypeName = engineTypeName.iloc[0]
 
-        result = {
-            "analysisTypeCode": "风向玫瑰分析",
-            "engineTypeCode": engineTypeCode,
-            "engineTypeName": engineTypeName,
-            "axes": {
-                "radial": "频率百分比",
-                "angular": "风向",
-                "levelname":"风速"
-            },
-            "data": []
-        }
-
-        for turbineCode in turbineCodes:
-            if turbineCode in self.frequency_data:
-                # 确保 enginName 是具体的值
-                enginName = dataFrameOfTurbines[dataFrameOfTurbines[Field_CodeOfTurbine]==turbineCode][Field_NameOfTurbine].iloc[0]
-                if isinstance(enginName, pd.Series):
-                    enginName = enginName.iloc[0]
+        if turbineCode in self.frequency_data:
+            # 确保 enginName 是具体的值
+            enginName = dataFrameOfTurbines[dataFrameOfTurbines[Field_CodeOfTurbine] == turbineCode][Field_NameOfTurbine].iloc[0]
+            if isinstance(enginName, pd.Series):
+                enginName = enginName.iloc[0]
+
+            turbine_info = {
+                "enginName": enginName,
+                "enginCode": turbineCode,
+                "title": self.frequency_data[turbineCode]['title'],
+                "windRoseData": []
+            }
+
+            for speed_label, direction_data in self.frequency_data[turbineCode].items():
+                if speed_label == 'title':
+                    continue
+                for direction, freq in direction_data.items():
+                    turbine_info["windRoseData"].append({
+                        "windDirection": float(direction),
+                        "windSpeedRange": speed_label,
+                        "frequency": float(freq)
+                    })
+
+            result = {
+                "analysisTypeCode": "风向玫瑰分析",
+                "engineTypeCode": engineTypeCode,
+                "engineTypeName": engineTypeName,
+                "axes": {
+                    "radial": "频率百分比",
+                    "angular": "风向",
+                    "levelname": "风速"
+                },
+                "data": [turbine_info]
+            }
 
-                turbine_info = {
-                    "enginName": enginName,
-                    "enginCode": turbineCode,
-                    "title": self.frequency_data[turbineCode]['title'],
-                    "windRoseData": []
-                }
-
-                for speed_label, direction_data in self.frequency_data[turbineCode].items():
-                    if speed_label == 'title':
-                        continue
-                    for direction, freq in direction_data.items():
-                        turbine_info["windRoseData"].append({
-                            "windDirection": float(direction),
-                            "windSpeedRange": speed_label,
-                            "frequency": float(freq)
-                        })
-
-                result["data"].append(turbine_info)
-
-        return result
+            return result
+        return {}