Skip to main content

Fetching Network Model

In this tutorial, we will explore a Python script that utilizes the APIs to fetch information about an electrical network from the Energy Workbench. The script connects to the EWB Server, retrieves data about a specific feeder, and prints details about the network equipment such as conductors, transformers, energy consumers, and switches.

Getting Started

Ensure that you have imported necessary modules from the Zepben library.

from zepben.evolve import Conductor, PowerTransformer, SyncNetworkConsumerClient, ConductingEquipment, EnergyConsumer, Switch, \
connect_insecure
from zepben.protobuf.nc.nc_requests_pb2 import INCLUDE_ENERGIZED_LV_FEEDERS, INCLUDE_ENERGIZED_FEEDERS, INCLUDE_ENERGIZING_SUBSTATIONS, \
INCLUDE_ENERGIZING_FEEDERS

Also ensure that you have connected to the EWB Server. In this example, the connect_insecure function is used to connect to the EWB Server but you will need the connection mechanism appropriate for your server.

channel = connect_insecure(host="EWB Hostname", rpc_port=1234)

You will need to replace the host and port with the appropriate values for your environment. More information about connecting to the EWB Server using different methods can be found in the Connecting to the EWB Server guide.

Note: All other examples relating to using the EWB server can use any of the connection methods depending on the configuration of the EWB server.

Fetch Feeder Information

You will need to specify the mRID of the feeder that you want to fetch, ensuring that the feeder with the specified mRID exists. Then, create a SyncNetworkConsumerClient and retrieve the network service. The get_equipment_container method is used to fetch information about the specified feeder (feeder_mrid). The INCLUDE_ENERGIZED_LV_FEEDERS flag indicates that the client should include information about energized LV (Low Voltage) feeders in the response.

Note: You should create a new client for each Feeder you retrieve. There is also a NetworkConsumerClient that is asyncio compatible, with the same API.

feeder_mrid = "LV007"
client = SyncNetworkConsumerClient(channel=channel)
network = client.service
client.get_equipment_container(feeder_mrid, include_energized_containers=INCLUDE_ENERGIZED_LV_FEEDERS).throw_on_error()

There are other methods available to fetch a container. Some of them are explained below:

  • Fetching substation equipment and including equipment from HV/MV feeders powered by it:
client.get_equipment_container("substation ID", include_energized_containers=INCLUDE_ENERGIZED_FEEDERS)
  • Same as above, but also fetching equipment from LV feeders powered by the HV/MV feeders
client.get_equipment_container("substation ID", include_energized_containers=INCLUDE_ENERGIZED_LV_FEEDERS)
  • Fetching feeder equipment without fetching any additional equipment from powering/powered containers
client.get_equipment_container("feeder ID")
  • Fetching HV/MV feeder equipment, the equipment from the substation powering it, and the equipment from the LV feeders it powers
client.get_equipment_container("feeder ID",
include_energizing_containers=INCLUDE_ENERGIZING_SUBSTATIONS,
include_energized_containers=INCLUDE_ENERGIZED_LV_FEEDERS)
  • Fetching LV feeder equipment and including equipment from HV/MV feeders powering it
client.get_equipment_container("LV feeder ID", include_energizing_containers=INCLUDE_ENERGIZING_FEEDERS)
  • Same as above, but also fetching equipment from the substations powering the HV/MV feeders
client.get_equipment_container("LV feeder ID", include_energizing_containers=INCLUDE_ENERGIZING_SUBSTATIONS)

Analysing Network Objects

This example prints the total number of objects in the network and provides a breakdown of the number of objects for each type of ConductingEquipment. It utilizes the len_of method to get the total count and iterates through the unique types present in the network.

print(f"Total Number of objects: {client.service.len_of()}")
types = set(type(x) for x in network.objects(ConductingEquipment))
for t in types:
print(f"Number of {t.__name__}'s = {len(list(network.objects(t)))}")

Output:

A sample output for a feeder is shown below (for demonstration purpose only). Note that the results will vary for different feeders depending on the network.

Calculating Conductor Length

You can also calculate the total length of conductors in the feeder. In this example, the provided python code iterates through all objects of type Conductor, checks if each conductor has a valid length attribute, and accumulates the lengths.

total_length = 0
for conductor in network.objects(Conductor):
try:
if conductor.length is not None:
total_length += conductor.length
except AttributeError:
print(f"Warning: Conductor {conductor} does not have a 'length' attribute.")

Output:

Retrieving Objects from the Feeder

This example demonstrates how the script can be used to retrieve and print the feeder object from the network. For the sake of demonstration, we will retrieve and display only a few objects from the network, including power transformers, energy consumers, and switches.

Example 1: Retrieving Power Transformers

In this example, we retrieve and print the transformers from the network. First, the provided code retrieves a feeder object from the network using the feeder_mrid as a parameter. Then, the code iterates over the equipment in the feeder. For each equipment item, it checks if it is an instance of the PowerTransformer class. If it is, it prints information about the transformer, including its representation (eq), vector group, and function.

feeder = network.get(feeder_mrid)
print("Transformers:")
for eq in feeder.equipment:
if isinstance(eq, PowerTransformer):
print(f" {eq} - Vector Group: {eq.vector_group.short_name}, Function: {eq.function.short_name}")

Output:

For demonstration purpose, only the first few transformers are shown as the output.

Example 2: Retrieving Energy Consumers

In this example, the code iterates over objects in the network that are instances of the EnergyConsumer class. For each energy consumer (ec), it prints information, including its representation (ec), real power draw (ec.q), and reactive power draw (ec.p).

print("Energy Consumers:")
for ec in network.objects(EnergyConsumer):
print(f" {ec} - Real power draw: {ec.q}W, Reactive power draw: {ec.p}VAr")

Output:

For demonstration purpose, only a few energy consumers are shown as the output.

Example 3: Retrieving Switches

In this example, the code iterates over objects in the network that are instances of the Switch class. For each switch (switch), it prints information about the switch, including its representation (switch) and the open status obtained using switch.get_state().

print("Switches:")
for switch in network.objects(Switch):
print(f" {switch} - Open status: {switch.get_state():04b}")

Output:

For demonstration purpose, only a few switches are shown as the output.