from abc import ABC, abstractmethod import pandas as pd from utils.directoryUtil import DirectoryUtil as dir from algorithmContract.confBusiness import * from common.commonBusiness import CommonBusiness class BaseAnalyst(ABC): def __init__(self, confData: ConfBusiness): self.common = CommonBusiness() self.confData = confData self.node_filter_value_state_turbine = "filter_value_state_turbine" self.node_angle_pitch_min = "angle_pitch_min" self.node_angle_pitch_max = "angle_pitch_max" self.node_speed_wind_cut_in = "speed_wind_cut_in" self.node_speed_wind_cut_out = "speed_wind_cut_out" self.node_active_power_min = "active_power_min" self.node_active_power_max = "active_power_max" self.node_speed_generator_min = "speed_generator_min" self.node_speed_generator_max = "speed_generator_max" self.node_activePowerAvailable = "activePowerAvailable" self.dataFrameContractOfTurbine = self.processContractData(confData) def processContractData(self, confData: ConfBusiness): dataFrameContractOfTurbine = self.common.contractGuaranteePowerCurveData( confData.turbineGuaranteedPowerCurveFilePathCSV, confData) self.common.calculateCp2( dataFrameContractOfTurbine, confData.density_air, confData.rotor_diameter, "风速", "有功功率") return dataFrameContractOfTurbine @abstractmethod def typeAnalyst(self): pass def getOutputAnalysisDir(self): """ 获取当前分析的输出目录 """ outputAnalysisDir = r"{}/{}".format( self.confData.output_path, self.typeAnalyst()) dir.create_directory(outputAnalysisDir) return outputAnalysisDir def filterCommon(self, dataFrame: pd.DataFrame, confData: ConfBusiness): if not self.common.isNone(confData.field_wind_speed) and self.node_speed_wind_cut_in in confData.filter \ and not self.common.isNone(confData.filter[self.node_speed_wind_cut_in]) \ and self.node_speed_wind_cut_out in confData.filter \ and not self.common.isNone(confData.filter[self.node_speed_wind_cut_out]) \ and not self.common.isNone(confData.field_power): windSpeedCutIn = float( confData.filter[self.node_speed_wind_cut_in]) windSpeedCutOut = float( confData.filter[self.node_speed_wind_cut_out]) dataFrame = dataFrame[~((dataFrame[confData.field_wind_speed] > windSpeedCutOut) | ( dataFrame[confData.field_wind_speed] < windSpeedCutIn))] dataFrame = dataFrame[~((dataFrame[confData.field_wind_speed] > windSpeedCutIn) & ( dataFrame[confData.field_power] < confData.rated_power*0.01))] if not self.common.isNone(confData.field_power) and confData.field_power in dataFrame.columns \ and not self.common.isNone(confData.field_pitch_angle1) and confData.field_pitch_angle1 in dataFrame.columns \ and self.node_angle_pitch_min in confData.filter and not self.common.isNone(confData.filter[self.node_angle_pitch_min]): anglePitchMin = float(confData.filter[self.node_angle_pitch_min]) dataFrame = dataFrame[~(( dataFrame[confData.field_power] <= confData.rated_power*0.9) & (dataFrame[confData.field_pitch_angle1] >anglePitchMin) )] # if not self.common.isNone(confData.rated_WindSpeed) and not self.common.isNone(confData.field_pitch_angle1) \ # and self.node_angle_pitch_min in confData.filter and not self.common.isNone(confData.filter[self.node_angle_pitch_min]): # anglePitchMin = float(confData.filter[self.node_angle_pitch_min]) # dataFrame = dataFrame[~((dataFrame[confData.field_wind_speed] < confData.rated_WindSpeed) & ( # dataFrame[confData.field_pitch_angle1] > anglePitchMin))] # Filter rows where turbine state if not self.common.isNone(confData.field_gen_speed) and confData.field_gen_speed in dataFrame.columns: dataFrame = dataFrame[(dataFrame[confData.field_gen_speed] > 0)] # Filter rows where turbine state if not self.common.isNone(confData.field_turbine_state) and self.node_filter_value_state_turbine in confData.filter and not self.common.isNone(confData.filter[self.node_filter_value_state_turbine]): stateTurbine = confData.filter[self.node_filter_value_state_turbine] dataFrame = dataFrame[dataFrame[confData.field_turbine_state].isin( stateTurbine)] if not self.common.isNone(confData.rated_WindSpeed) and not self.common.isNone(confData.field_wind_speed) \ and not self.common.isNone(confData.field_gen_speed) \ and self.node_speed_generator_max in confData.filter \ and not self.common.isNone(confData.filter[self.node_speed_generator_max]): speedGeneratorMax = float( confData.filter[self.node_speed_generator_max]) dataFrame = dataFrame[~((dataFrame[confData.field_wind_speed] >= confData.rated_WindSpeed) & ( dataFrame[confData.field_gen_speed] < speedGeneratorMax*0.9))] if not self.common.isNone(confData.field_gen_speed) \ and self.node_speed_generator_max in confData.filter \ and not self.common.isNone(confData.filter[self.node_speed_generator_min]) \ and not self.common.isNone(confData.filter[self.node_speed_generator_max]): speedGeneratorMin = float( confData.filter[self.node_speed_generator_min]) speedGeneratorMax = float( confData.filter[self.node_speed_generator_max]) dataFrame = dataFrame[~((dataFrame[confData.field_gen_speed] < speedGeneratorMin) | ( dataFrame[confData.field_gen_speed] > speedGeneratorMax))] if not self.common.isNone(confData.field_activePowerSet) and confData.field_activePowerSet in dataFrame.columns: dataFrame = dataFrame[dataFrame[confData.field_activePowerSet] == confData.rated_power] if not self.common.isNone(confData.field_activePowerAvailable) and confData.field_activePowerAvailable in dataFrame.columns \ and self.node_activePowerAvailable in confData.filter and not self.common.isNone(confData.filter[self.node_activePowerAvailable]): state = confData.filter[self.node_activePowerAvailable] dataFrame = dataFrame[dataFrame[confData.field_activePowerAvailable].isin( state)] # # Filter rows where pitch # if not self.common.isNone(confData.field_pitch_angle1) and self.node_angle_pitch_min in confData.filter and not self.common.isNone(confData.filter[self.node_angle_pitch_min]): # anglePitchMin = float(confData.filter[self.node_angle_pitch_min]) # dataFrame = dataFrame[( # dataFrame[confData.field_pitch_angle1] < anglePitchMin)] # if not self.common.isNone(confData.field_pitch_angle1) and self.node_angle_pitch_max in confData.filter and not self.common.isNone(confData.filter[self.node_angle_pitch_max]): # anglePitchMax = float(confData.filter[self.node_angle_pitch_max]) # dataFrame = dataFrame[( # dataFrame[confData.field_pitch_angle1] <= anglePitchMax)] # # Filter rows where wind speed # if not self.common.isNone(confData.field_wind_speed) and self.node_speed_wind_cut_in in confData.filter and not self.common.isNone(confData.filter[self.node_speed_wind_cut_in]): # windSpeedCutIn = float(confData.filter[self.node_speed_wind_cut_in]) # dataFrame = dataFrame[( # dataFrame[confData.field_wind_speed] >= windSpeedCutIn)] # if not self.common.isNone(confData.field_wind_speed) and self.node_speed_wind_cut_out in confData.filter and not self.common.isNone(confData.filter[self.node_speed_wind_cut_out]): # windSpeedCutOut = float(confData.filter[self.node_speed_wind_cut_out]) # dataFrame = dataFrame[( # dataFrame[confData.field_wind_speed] < windSpeedCutOut)] # # Filter rows where power # if not self.common.isNone(confData.field_power) and self.node_active_power_min in confData.filter and not self.common.isNone(confData.filter[self.node_active_power_min]): # activePowerMin = float(confData.filter[self.node_active_power_min]) # dataFrame = dataFrame[( # dataFrame[confData.field_power] >= activePowerMin)] # if not self.common.isNone(confData.field_power) and self.node_active_power_max in confData.filter and not self.common.isNone(confData.filter[self.node_active_power_max]): # activePowerMax = float(confData.filter[self.node_active_power_max]) # dataFrame = dataFrame[( # dataFrame[confData.field_power] < activePowerMax)] return dataFrame def filterCustomForTurbine(self, dataFrame: pd.DataFrame, confData: ConfBusiness): return self.filterCommon(dataFrame, confData) def analysisOfTurbine(self, dataFrame: pd.DataFrame, outputAnalysisDir, outputFilePath, confData: ConfBusiness, turbineName): dataFrame = self.filterCustomForTurbine(dataFrame, confData) self.turbineAnalysis(dataFrame, outputAnalysisDir, outputFilePath, confData, turbineName) def turbineAnalysis(self, dataFrame: pd.DataFrame, outputAnalysisDir, outputFilePath, confData: ConfBusiness, turbineName): pass def filterCustomForTurbines(self, dataFrame: pd.DataFrame, confData: ConfBusiness): return self.filterCommon(dataFrame, confData) def analysisOfTurbines(self, dataFrameMerge: pd.DataFrame, outputAnalysisDir, confData: ConfBusiness): dataFrameMerge = self.filterCustomForTurbines(dataFrameMerge, confData) self.turbinesAnalysis(dataFrameMerge, outputAnalysisDir, confData) def turbinesAnalysis(self, dataFrameMerge: pd.DataFrame, outputAnalysisDir, confData: ConfBusiness): pass