Esempio n. 1
0
 def opposite_ends(self):
     """Shortcut for finding the opposite ends for a list of PowerTransformerEnd or Terminals"""
     if self.has_type("PowerTransformerEnd"):
         end_numbers = {a.end_number for a in self.data}
         if end_numbers != {1} and end_numbers != {2}:
             raise ValueError(
                 f"Can't get opposite end for list with end number(s) {end_numbers}, should be either all 1 or all 2"
             )
         opposite_end_number = 1 if list(end_numbers)[0] == 2 else 2
         return self.power_transformers().power_transformer_ends(
             end_number=opposite_end_number)
     if self.has_type("Terminal"):
         seq_numbers = {a.sequence_number for a in self.data}
         if seq_numbers != {1} and seq_numbers != {2}:
             raise ValueError(
                 f"Can't get opposite end for list with sequence number(s) {seq_numbers}, should be either all 1 or all 2"
             )
         opposite_seq_number = 1 if list(seq_numbers)[0] == 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")
             return pte.opposite_ends().terminals(
                 sequence_number=opposite_seq_number)
         return al.terminals(sequence_number=opposite_seq_number)
     else:
         raise WrongPowerTypeError(
             f"Can't get opposite ends for a list of {self.type}")
Esempio n. 2
0
    def generating_units(
        self,
        power_type: Optional[Union[str,
                                   List[str]]] = None) -> "PowerAssetList":
        """Shortcut for finding the associated GeneratingUnit for a list of Substations

        Args:
            power_type: type of generating unit, default is ["HydroGeneratingUnit","WindGeneratingUnit","ThermalGeneratingUnit"] """
        if power_type is None:
            power_type = [
                "HydroGeneratingUnit", "WindGeneratingUnit",
                "ThermalGeneratingUnit"
            ]
        if isinstance(power_type, str):
            power_type = [power_type]
        if self.has_type("Substation"):
            return PowerAssetList(
                sum([self.relationship_sources(pt) for pt in power_type], []),
                cognite_client=self._cognite_client,
            )
        elif not self.data:
            return PowerAssetList([], cognite_client=self._cognite_client)
        else:
            raise WrongPowerTypeError(
                f"Can't get Generating Units [{power_type}] for a list of {self.type}"
            )
Esempio n. 3
0
 def non_conform_loads(self, base_voltage: Iterable = None) -> "PowerAssetList":
     if self.has_type("Substation"):
         return self.relationship_sources("NonConformLoad", base_voltage=base_voltage)
     elif not self.data:
         return PowerAssetList([], cognite_client=self._cognite_client)
     else:
         raise WrongPowerTypeError(f"Can't get NonConformLoad for a list of {self.type}")
Esempio n. 4
0
 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":
     """See ACLineSegment#load_duration_curve"""
     if self.type not in [
             "ACLineSegment", "PowerTransformerEnd", "SynchronousMachine"
     ]:  # , "PowerTransferCorridor"
         raise WrongPowerTypeError(
             f"Can't get load duration curves dataframe for a list of {self.type}"
         )
     if len(self.data) > 1000:
         raise ValueError(
             "Too many line segments in this list to get load duration curves"
         )
     res_list = execute_tasks_concurrently(
         ACLineSegment.load_duration_curve,
         [(a, start, end, terminal, measurement_type, timeseries_type,
           granularity, dropna, index_granularity) for a in self],
         max_workers=10,
     )
     return pd.concat(res_list.joined_results(), axis=1)
Esempio n. 5
0
 def busbar_sections(self, base_voltage: Iterable = None):
     if self.has_type("Substation"):
         return self.relationship_sources("BusbarSection", base_voltage=base_voltage)
     elif not self.data:
         return PowerAssetList([], cognite_client=self._cognite_client)
     else:
         raise WrongPowerTypeError(f"Can't get ConformLoads for a list of {self.type}")
Esempio n. 6
0
 def current_limits_overview(self) -> "pd.DataFrame":
     """See ACLineSegment#current_limits_overview"""
     if not self.has_type("ACLineSegment"):
         raise WrongPowerTypeError(f"Can't get connected current limits dataframe for a list of {self.type}")
     res_list = execute_tasks_concurrently(
         ACLineSegment.current_limits_overview, [(a,) for a in self], max_workers=10
     )
     return pd.concat(res_list.joined_results())
Esempio n. 7
0
 def shunt_compensators(self):
     if self.has_type("Substation"):
         return self.relationship_sources("ShuntCompensator")
     elif not self.data:
         return PowerAssetList([], cognite_client=self._cognite_client)
     else:
         raise WrongPowerTypeError(
             f"Can't get ShuntCompensator for a list of {self.type}")
Esempio n. 8
0
 def power_transformers(self, grid_type: Optional[str] = None) -> "PowerAssetList":
     """Shortcut for finding the associated PowerTransformer for a list of PowerTransformerEnd or Substation"""
     if self.has_type("PowerTransformerEnd"):
         return self.relationship_targets("PowerTransformer", grid_type=grid_type)
     elif self.has_type("Substation"):
         return self.relationship_sources("PowerTransformer", grid_type=grid_type)
     elif not self.data:
         return PowerAssetList([])
     else:
         raise WrongPowerTypeError(f"Can't get PowerTransformers for a list of {self.type}")
Esempio n. 9
0
 def ac_line_segments(self, base_voltage: Iterable = None, grid_type: Optional[str] = None):
     """Shortcut for finding the associated ACLineSegment for a list of PowerTransformer, Substation or Terminal"""
     if self.has_type("Substation"):
         return self.terminals().ac_line_segments(base_voltage=base_voltage, grid_type=grid_type)
     elif self.has_type("Terminal"):
         return self.relationship_targets(
             "ACLineSegment", relationship_type="connectsTo", base_voltage=base_voltage, grid_type=grid_type
         )
     elif not self.data:
         return PowerAssetList([], cognite_client=self._cognite_client)
     else:
         raise WrongPowerTypeError(f"Can't get ACLineSegments for a list of {self.type}")
Esempio n. 10
0
    def connected_substations(
        self,
        level: int = 1,
        exact: bool = False,
        include_lines=False,
        base_voltage: Iterable = None,
        grid_type: Optional[str] = None,
    ) -> "PowerAssetList":
        """Retrieves substations connected within level connections through ac_line_segments with base voltages within the specified range

        Args:
                level: number of connections to traverse
                exact: only return substations whose minimum distance is exactly level
                include_lines: also return ACLineSegments that make up the connections. Can not be used in combination with exact.
                base_voltage: only consider ACLineSegments with these base voltage
                grid_type:  only consider ACLineSegments of this grid type
        """
        if exact and include_lines:
            raise ValueError(
                "Can not include lines when an exact distance is requested")
        if not self.has_type("Substation"):
            raise WrongPowerTypeError(
                f"Can't get connected substations for a list of {self.type}")
        visited_substations = set(self.data)
        visited_lines = set()
        substations_at_level = self
        for i in range(level):
            ac_line_segments = substations_at_level.ac_line_segments(
                base_voltage=base_voltage, grid_type=grid_type)
            substations_at_level = ac_line_segments.substations()
            substations_at_level.data = [
                a for a in substations_at_level.data
                if a not in visited_substations
            ]
            if not substations_at_level:
                break
            visited_lines.update(ac_line_segments)
            visited_substations.update(substations_at_level)
        if exact:
            returned_assets = substations_at_level
        elif include_lines:
            returned_assets = list(visited_substations) + list(visited_lines)
        else:
            returned_assets = visited_substations
        return PowerAssetList(list(returned_assets),
                              cognite_client=self._cognite_client)
Esempio n. 11
0
 def substations(self) -> "PowerAssetList":
     """Shortcut for finding the associated Substations for a list of PowerTransformer, GeneratingUnit, (Non)ConformLoad, ACLineSegment or Terminal"""
     if (self.has_type("PowerTransformer") or self.has_type("Terminal")
             or self.has_type("ConformLoad")
             or self.has_type("NonConformLoad")
             or self.has_type("WindGeneratingUnit")
             or self.has_type("ThermalGeneratingUnit")
             or self.has_type("HydroGeneratingUnit")
             or self.has_type("BusbarSection")):
         return self.relationship_targets("Substation")
     elif self.has_type("ACLineSegment"):
         return self.terminals().substations()
     elif not self.data:
         return PowerAssetList([], cognite_client=self._cognite_client)
     else:
         raise WrongPowerTypeError(
             f"Can't get substations for a list of {self.type}")