def opposite_end(self) -> "Terminal": """Retrieves the opposite end (Sequence number 1 to 2 and vice versa), works on Terminals associated with both ACLineSegment and PowerTransformerEnd""" seq_number = self.sequence_number if seq_number not in [1, 2]: raise ValueError( f"Can't get opposite end for terminal with sequence number {seq_number}, should be 1 or 2" ) opposite_seq_number = 1 if seq_number == 2 else 2 al = self.relationship_targets(power_type="ACLineSegment", relationship_type="connectsTo") if not al: pte = self.relationship_targets(power_type="PowerTransformerEnd", relationship_type="connectsTo") if not pte: raise SinglePowerAssetExpected( al, f"Could not find any ACLineSegment or PowerTransformerEnd connected to terminal {self.external_id}", ) return assert_single_result( assert_single_result(pte).opposite_end().terminals( sequence_number=opposite_seq_number)) return assert_single_result( assert_single_result(al).terminals( sequence_number=opposite_seq_number))
def retrieve_name( self, name: Union[List[str], str], asset_type: str = None, bidding_area: Union[str, List[str]] = None ) -> Union[PowerAsset, PowerAssetList]: """Retrieve one or more assets by exact name match. Fails if not exactly one asset is found. Args: name (Union[List[str], str]): One or more names to search for. asset_type (Union[str, List[str]]): filter on these asset types. Automatically populated for specific APIs bidding_area (Union[str, List[str]]): filters on assets being in the bidding areas with this name. Returns: Union[PowerAsset,PowerAssetList]: The requested asset(s). """ if isinstance(name, str): filters = self._create_filter(asset_type=asset_type, bidding_area=bidding_area) result = assert_single_result(super().list(name=name, **filters)) return PowerAsset._load_from_asset(result, self.power_type or asset_type, self._cognite_client) else: return PowerAssetList( [ self.retrieve_name(name=n, asset_type=asset_type, bidding_area=bidding_area) for n in name ], cognite_client=self._cognite_client, )
def generating_unit(self) -> GeneratingUnit: """Shortcut for finding the associated GeneratingUnit for a SynchronousMachine""" return PowerAsset._load_from_asset( assert_single_result([a for a in self.relationship_sources() if "GeneratingUnit" in a.type]), "GeneratingUnit", self._cognite_client, )
def time_series(self): term = self.terminal().time_series( measurement_type=self.measurement_type, timeseries_type=self.timeseries_type) return assert_single_result( term, f"Expected a single time series with measurement type {self.measurement_type} and timeseries type {self.timeseries_type} for {self.asset.name}, but found {len(term)}", )
def opposite_end(self): """Gets the PowerTransformerEnd's opposite end (end number 1->2 and 2->1)""" end_number = self.end_number if end_number not in [1, 2]: raise ValueError( f"Can't get opposite end for PowerTransformerEnd with end number {end_number}, should be 1 or 2" ) opposite_end_number = 1 if end_number == 2 else 2 return assert_single_result(self.power_transformer().power_transformer_ends(end_number=opposite_end_number))
def load_duration_curve( self, start, end="now", terminal=1, measurement_type="ThreePhaseActivePower", timeseries_type="estimated_value", granularity="1h", dropna=True, index_granularity=0.1, ) -> "pd.DataFrame": """Calculates a load-duration curve. Args: start, end: string, timestamp or datetime for start and end, as in datapoints.retrieve terminal, measurement_type, timeseries_type: which measurement of which terminal to retrieve. granularity: granularity to be used in retrieving time series data. dropna: whether to drop NaN values / gaps index_granularity: spacing of the regularized return value in %, e.g. 0.1 gives back 1001 elements. Returns: pd.DataFrame: dataframe with a load duration curve """ ts = assert_single_result( self.terminals(sequence_number=terminal).time_series( measurement_type=measurement_type, timeseries_type=timeseries_type)) df = self._cognite_client.datapoints.retrieve_dataframe( id=ts.id, start=start, end=end, granularity=granularity, aggregates=["interpolation"], complete="fill") if dropna: df = df.dropna() index = np.linspace(start=0, stop=1, num=round(100 / index_granularity + 1)) regular_spacing = np.interp( index, np.linspace(start=0, stop=1, num=df.shape[0]), df.iloc[:, 0].sort_values(ascending=False).values) return pd.DataFrame(index=index, data=regular_spacing, columns=[self.name])
def terminal(self): term = [self.asset.terminals(sequence_number=self.sequence_number)] return assert_single_result( term, f"Expected a single terminal with sequence number {self.sequence_number} for {self.asset.name}, but found {len(term)}", )
def power_transformer(self) -> "PowerTransformer": """Shortcut for finding the PowerTransformer for a PowerTransformerEnd""" return assert_single_result( self.relationship_targets("PowerTransformer"))
def substation(self) -> "Substation": """Shortcut for finding the substation for a PowerTransformer""" return assert_single_result(self.relationship_targets("Substation"))
def substation(self) -> "Substation": """Shortcut for finding the substation for a PetersenCoil""" return assert_single_result(self.relationship_targets("Substation"))
def substation(self) -> "Substation": """Shortcut for finding the substation for a StaticVarCompensator""" return assert_single_result(self.relationship_targets("Substation"))