GridAPPS-D Platform, API, and App Documentation

GridAPPS-D™ is an open-source platform that accelerates development and deployment of portable applications for advanced distribution management and operations. It is built in a linux environment using Docker, which allows large software packages to be distributed as containers.
Its purpose is to reduce the time and cost to integrate advanced functionality into distribution operations, to create a more reliable and resilient grid.
GridAPPS-D enables standardization of data models, programming interfaces, and the data exchange interfaces for:
devices in the field
distributed apps in the systems
applications in the control room
The platform provides
robust testing tools for applications
distribution system simulation capabilities
standardized research capability
reference architecture for the industry
application development kit
The GridAPPS-D source code is publically available from GitHub. The GridAPPS-D™ project is sponsored by the U.S. Department of Energy and receives ongoing updates from a team of core developers at PNNL.
The GridAPPS-D team encourages and appreciates community involvement, including issues and pull requests on GitHub, participation in monthly app developers meetings, and posts on the discussion board.
Questions and support requests should be filed in the GridAPPS-D Forum Discussion Board
General issues and bugs can be reported in the GridAPPS-D Forum Issues Page
Bugs in the GridAPPS-D platform can be reported in full detail using the GOSS-GridAPPS-D Issues Page
Windows 10 Installation
This section contains detailed installation instructions and runtime environment tips for running GridAPPS-D and its dependencies on a Windows 10 machine.
Virtual Machine & Docker Setup
A typical Windows 10 installation does not include several of the tools needed to run the GridAPPS-D Platform Several software packages need to be installed prior to installing GridAPPS-D in the next step
Installation Steps:
It is also possible to use Virtualbox to create a virtual Ubuntu Linux machine. This approach may be used if it is desired to use Eclipse, etc. for Java development. However, performance of Virtualbox is significantly worse than WSL2 for running GridAPPS-D simulations and python application development.
System Requirements
OS:
Windows 10, Version 2004 or higher, with Build 19041 or higher
RAM:
8GB (absolute minimum for 13 and 123 node models, may encounter memory overload during installation );
16GB (preferred for small models, minimum for 8500/9500 node models);
32GB (recommended for application development)
Disk Space:
15GB required for installation
Note: The download size is quite large, so it is recommended to use a fiber or ethernet interent connection, rathered than a metered hotspot to avoid excessive data usage charges.
Windows 10 OS Build Requirments
To check your OS build, type winver
in the Cortana seach bar:
Check to see if your OS is
For x64 systems: Version 1903 or higher, with Build 18362 or higher.
For ARM64 systems: Version 2004 or higher, with Build 19041 or higher.
If not, run Windows Update to get the latest verion of Windows 10 available for your machine. It may take some time for the new OS to download. Multiple restarts are typical while upgrading the windows version.
Disconnect from Corporate VPN
There is a known issue with WSL2 and some corporate / laboratory VPNs. During WSL2 and docker installation, the Domain Name Server is set to that of your corporate intranet if your machine is connected to a VPN. This will cause issues when accessing github, etc. from within WSL2.
This issue has also been reported by users using Virtualbox VMs.
Install Windows Subsystem for Linux
GridAPPS-D and the associated docker containers will run using the Windows Subsystem for Linux (WSL), which is a new feature to Windows 10 that enables linux code to run natively in Windows without a separate virtual machine. The steps in this section are also available on the Microsoft website
Enable WSL
Open Windows PowerShell as an administrator:
Enable WSL by entering
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
Then, without restarting, enable the virtual machine platform by entering
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
When completed, restart your machine. It may take a few minutes for the new settings to be applied while restarting.
Upgrade to WSL2
Download the latest WSL2 package .msi installer from the Microsoft repository
Run the update package to install WSL2 using the wizard:
Open Windows PowerShell again and update the settings to use WSL2 by entering
wsl --set-default-version 2
Install Linux Ubuntu OS
Open the Microsoft Store app, and search for Ubuntu
and install the desired version (available versions are 16.04, 18.04, and 20.04)
When it has finished downloading, click Launch
.
Set up Ubuntu in WSL
Wait for the Ubuntu OS to install.
Select a username and password. These do not need to be the same as your Windows or Microsoft Account login.
Install Docker for Windows
Download and run Docker Desktop for Windows from Docker Hub
Be sure to select “Install required components for WSL2”
After restarting your machine, Docker should start automatically, and you will see a notification stating “Linux WSL2 containers are starting”
Installing GridAPPS-D
Clone the GridAPPS-D Docker repository
Disconnect from your corporate/laboratory VPN (if applicable) and open the Ubuntu terminal:
Clone the GridAPPS-D repository:
git clone https://github.com/GRIDAPPSD/gridappsd-docker
Install the GridAPPS-D Docker Containers
Change directories into the gridappsd-docker folder and start the latest stable release of the GridAPPS-D platform.
cd gridappsd-docker
./run.sh
It is possible to specify a particular release tag using the -t option and the release tag
./run.sh -t develop
- use thedevelop
branch with latest beta features./run.sh -t releases_2021.04.0
- use the April 2021 release./run.sh -t releases_2020.09.0
- use the September 2020 release
A complete set of releases is available in the Platform Release History
Wait for the platform to download the required docker containers. This is a very large package and will take several minutes.
After the containers have finished downloading, they will automatically be created and then launched:
Launch the GridAPPS-D Platform
When all the containers are running, the terminal will move inside the docker enviroment, which has its own internal directories and path.
Start the GridAPPS-D platform inside the docker container by running
./run-gridappsd.sh
The GridAPPS-D platform is now installed and running.
To confirm, open localhost:8080 to access the GridAPPS-D Visualization App:
Known Issues around Corporate VPN Connectivity
There is a known issue around WSL2 and Virtualbox VM compatibility with corporate VPNs.
If your machine was connected to a corporate VPN during setup, the Doman Name Server (DNS) lookup address is set to that of your corporate intranet. To reset it, open an ubuntu session and edit the resolv.conf
file
sudo nano /etc/resolv.conf
comment out existing nameserver address
add new line with
nameserver 8.8.8.8
save file and restart terminal
Installing GridAPPSD-Python and Notebook Tutorials
Install Anaconda or Miniconda
Download the latest version of the Miniconda from the Conda.io website:
Use the installation wizard with the recommended settings to complete installation.
After installation is complete, launch the Anaconda Prompt (Miniconda3) from the Start Menu or by typing anaconda
in the Cortana toolbar
The miniconda terminal window will open
Install GridAPPSD-Python
In the Miniconda terminal window, download and install GridAPPSD-Python by running
pip install gridappsd-python
to download the GridAPPSD-Python library and required packages.
GridAPPSD-Python and all dependencies should have been automatically added to your anaconda path after completion.
Install Jupyter Lab
In the miniconda terminal window, run
pip install jupyterlab
to install the Jupyter environment for executing the python notebooks. It may take a couple minutes to collect and install all the required packages.
Python Training Notebooks
The Jupyter / iPython training notebooks are the source materials for the GridAPPS-D ReadTheDocs website.
The notebooks include all the code examples and sample app materials in a format that can connect to a local GridAPPS-D platform session and interact in real-time with simulations in real-time.
Download Python Training Notebooks
In the miniconda terminal window, clone the python notebooks by running git clone https://github.com/GRIDAPPSD/gridappsd-training
to download the python training notebooks.
|win\_setup\_install\_notebooks.png|
By default, the notebooks will be saved in the directory C:\Users\username\gridappsd-training
Close the miniconda terminal
Running Python Training Notebooks
Start the Jupyter notebooks running on port 8890 (to avoid port sharing conflict with the GridAPPS-D Blazegraph database container):
jupyter notebook --port 8890
If running on a remote server (e.g. AWS cloud or university / laboratory server farm), start the notebooks by running
jupyter notebook --port 8890 --no-browser --ip='0.0.0.0'
Port Sharing between GridAPPS-D and Jupyter
By default, both Jupyter and the GridAPPS-D Blazegraph database use port 8889. If a Jupyter notebook is already running on port 8889, the Blazegraph database container will fail to start.
It is recommended to specify manually that Jupyter run on a different port:
jupyter notebook --port 8890
Ubuntu Linux Installation
This section contains detailed installation instructions and runtime environment tips for running GridAPPS-D and its dependencies on an Ubuntu Linux machine.
Installing GridAPPS-D
Clone the GridAPPS-D Repository
Clone the GridAPPS-D GitHub repository
git clone https://github.com/GRIDAPPSD/gridappsd-docker
Install Docker
The GridAPPS-D repository includes a Docker installation script. This script only works for native linux environments (not WSL2).
Change directories into gridapps-docker and run the Docker installation script
cd gridappsd-docker
./docker_install_ubuntu.sh
`
Install GridAPPS-D
After Docker finishes installing, log out or restart the Ubuntu session.
After logging back in, change directories into gridappsd-docker and start the latest stable version of the GridAPPS-D platform, which will automatically download the required docker containers.
cd gridappsd-docker
./run.sh
To install a particular release, specify the release tag using the -t
option:
./run.sh -t develop
– Install latest develop version with beta features./run.sh -t releases_2021.04.0
– Install April 2021 release./run.sh -t releases_2020.09.0
– Install September 2020 release
Wait for the docker containers to finish downloading. This will take a while due to the package size.
When the containers have finished downloading and installing, start the GridAPPS-D Platform
./run-gridappsd.sh
The GridAPPS-D platform is now installed and running.
To confirm, open localhost:8080 to access the GridAPPS-D Viz
Installing GridAPPSD-Python and Notebook Tutorials
Quick Installation
Clone the GridAPPSD-Training Repository and run the ./install.sh
script
git clone https://github.com/GRIDAPPSD/gridappsd-training.git
cd gridappsd-training
./install.sh
Accept the user terms for Miniconda and Jupyterlab.
After completion, the JupyterLab server will be running in a virtual environment with the training notebooks
To start the jupyter notebooks at a later time, change directories into gridappsd-training and run the ./run.sh
script:
cd gridappsd-training
./run.sh
Manual Installation
Install Anaconda or Miniconda
If not pip is not installed, use apt-get
to install it.
sudo apt-get install python-pip
Download the latest version of Anaconda or Miniconda and save it in the /Downloads
folder:
Use Python 3.8 install for 64-bit systems from the Conda.io website.
Use Python 3.7 install for 32-bit systems from the Conda.io website
Install Miniconda using bash
cd /Downloads
bash Miniconda3-latest-Linux-x86_64.sh
Follow the prompts on the installer screens. If you are unsure about any setting, accept the defaults. You can change them later. To make the changes take effect, close and then re-open your terminal window.
Test your installation. In your terminal window or Anaconda Prompt, run the command conda list
. A list of installed packages appears if it has been installed correctly
Install GridAPPSD-Python
Use pip to install GridAPPSD-Python, which is need to pass API Calls to GridAPPS-D platform using the GridAPPSD-Python library methods:
pip install gridappsd-python
Install Jupyter Lab
Use pip to install Jupyter Lab, which is need to open and execute the Python Training Notebooks:
pip install jupyterlab
Download Python Notebooks
The Jupyter / iPython training notebooks are the source materials for the GridAPPS-D ReadTheDocs website.
The notebooks include all the code examples and sample app materials in a format that can connect to a local GridAPPS-D platform session and interact in real-time with simulations in real-time.
Clone the python notebooks in the GridAPPSD-Training repository by running
git clone https://github.com/GRIDAPPSD/gridappsd-training
By default, the notebooks will be saved in the directory gridappsd-training
Clone the python notebooks in the GridAPPSD-Training repository by running
git clone https://github.com/GRIDAPPSD/gridappsd-training
Start the Jupyter notebooks running on port 8890 (to avoid port sharing conflict with the GridAPPS-D Blazegraph database container):
jupyter notebook --port 8890
If running on a remote server (e.g. AWS cloud or university / laboratory server farm), start the notebooks by running
jupyter notebook --port 8890 --no-browser --ip='0.0.0.0'
Port Sharing between GridAPPS-D and Jupyter
By default, both Jupyter and the GridAPPS-D Blazegraph database use port 8889. If a Jupyter notebook is already running on port 8889, the Blazegraph database container will fail to start.
It is recommended to specify manually that Jupyter run on a different port:
jupyter notebook --port 8890
Running GridAPPS-D
Starting the GridAPPS-D Platform
If you are accessing this section after completing the installation steps in the previous procedure, then the GridAPPS-D Platform is already running.
When you start your machine next time, you will need to start the GridAPPS-D Platform again. To do this, change directories into gridappsd-docker
and run the ./run.sh
script
cd gridappsd-docker
./run.sh
or./run.sh -t release_tag
A complete set of releases of the GridAPPS-D Platform is available under Platform Release History
Stopping the Platform
Stopping the Platform from Inside the Docker Container
If you are currently inside the ./run-gridappsd.sh
script inside the docker container, use Ctrl+C
to stop the platform. Some error messages may be displayed as the platform services are stopped.
Then exit the docker container using exit
. This will return to the main ubuntu bash command line:
Then run the ./stop.sh
script to shut down all the docker containers and free RAM used by the Platform:
Stopping the Platform from a New Terminal
If your terminal was reset or closed, you can stop the platform and shut down all docker containers by changing directories into gridappsd-docker
and running the ./stop.sh
script:
cd gridappsd-docker
./stop.sh
Restarting the Platform
After the Platform has been stopped, it can be restarted by running the ./run.sh
script again from within the gridappsd-docker
directory
Changing Release Tags
To change the Platform to run on a different release, run the ./stop.sh
script using the -c
option to remove the current containers.
Remove the gridappsd directory using sudo rm -r gridappsd gridappsdmysql
Then start the platform again specifying the particular release tag desired. A complete list of platform releases is available in Platform Release History
Pulling Updated Containers
The GridAPPS-D platform should automatically check for and pull updated containers each time the ./run.sh
script is run.
However, it is sometimes necessary to force docker to pull new containers (e.g. if using a custom set of containers as specified by modifying the docker-compose.yml file).
New containers can be pulled by running docker-compose pull
from within the gridappsd-docker
directory
Using the GridAPPS-D Viz
Accessing the GridAPPS-D Viz
Start the Platform using the ./run.sh
and ./run-gridappsd.sh
scripts as explained in Running GridAPPS-D. After the Platform is running, open your browser and navigate to localhost:8080 for desktop installations and your.server.ip.address:8080
for cloud installations.
You should see a splash screen with login options for various user roles. The default username and password combinations are available in the GOSS core security config file.
If the ./run-gridappsd.sh
script inside the GridAPPS-D docker container has not been started or has been interrupted, you will see a server connection error when attempting to log in:
After logging in, there are two menus in the top left and right corners. On the left is the main menu for using the VIZ features. On the right is the settings menu.
The settings menu contains options for changing the color theme from dark to light, the time zone used, and level of logging detail.
On the left is the main menu, which has options for creating simulations, comparing simulations, exploring the databases, and passing API calls through the STOMP client. Each of these will be explained in detail below.
Creating a Simulation
To create a simulation from the GridAPPS-D VIZ, select Configure New Simulation
from the main menu:
Power System Configuration
The first tab provides a set of menu options to select the desired distribution feeder on which the simulation will run. Detailed descriptions of the available test feeders inlcuded by default are provided in Available Models in Default Installation.
Simulation Configuration
The next tab provides several options for specifying
simulation start time (which determines weather and load data used)
simulation duration in seconds
simulator used
real-time
If checked, 1 sec of clock time equals 1 sec of simulation time
If unchecked, the simulation runs as fast as possible (used for generating AI training data)
simulation name
model configuration
The model creation configuration textbox enables modification of the model from the default configuration, inlcuding opening/closing switches, changing DER setpoints, and changing the load profile. Details of the syntax for custom configurations is explained in Simulation Configuration Settings
Application Configuration
The application configuration tab enables selection of which app should run during the simulation. The GridAPPS-D VIZ allows for selection of just one app at a time. Two or more apps may be run simultaneously by starting the simulation through the Simulation API and specifying the desired apps using the Application Configuration Settings
Test Manager Configuration
The Test Manager is used to create realistic operational events during the course of the simulation, including faults, communication outages, and custom event scripts.
The GridAPPS-D Viz provides a graphic interface for building TestManager event scripts, which are described in detail in Test Manager Configuration.
For large models (such as the IEEE 8500 node and 9500 node test systems), it may take several seconds for the model dictionary to load. While the power system model is being queried, a splashscreen will be displayed.
Communication outages
The first option is to create communication outages for both SCADA measurements and equipment control commands by clicking the CommOutage
radio button.
Equipment control commands can be blocked by specifying an Input Outage with options for
start time
end time
all equipment (outages all commands for all equipment if checked)
equipment type
equipment name
affected phases
CIM control attribute
To add an Input Outage, specify the desired options, click the +
button, and then click the Add event
button at the bottom of the page. The speficied outages will then be displayed on the right side under the CommOutage
tab.
Measurement sensor outages can be created with an Output Outage with options for
all measurements (all sensors outages if checked)
equipment type
equipment name
affected phases
measurement type (voltage, apparent power, position)
To add an Output Outage, specify the desired options, click the +
button, and then click the Add event
button at the bottom of the page. The speficied outages will then be displayed on the right side under the CommOutage
tab.
Equipment Faults
The next option is to create a fault on any class of equipment in the model by clicking the Fault
radio button. Options will appear to select the
equipment type
equipment name
phases to be faulted
type of fault
start time
end time
fault impedance
After setting the values, click the Add event
button. The fault will be displayed on the right side of the screen under the Fault
tab.
When the simulation reaches the event start time, the logical fault simulator traces the fault up to first upstream switch and opens that switch to clear the fault.
Note: The GridLAB-D logical fault simulator currently may not process faults in meshed networks correctly and fail to open the appropriate set of switches to clear the fault. This is a known bug with a workaround to open the appropriate switches using a custom Test Manager event file.
Custom Event Files
Custom event messages can be written in format of a CIM Difference Message. The format of custom event files is explained in Scheduled Command Events.
Event files can be uploaded by clicking the cloud-shaped button and selecting the desired files to be uploaded from your local machine. Click Open
to upload each file. The custom event will then be displayed under the Command
tab.
2.5. Service Configuration
The last tab is the GridAPPS-D service configuration. This enables selection of particular services that should be run along with the simulation, such as the Sensor Simulator or DNP3 service.
After selecting all desired simulation parameters, click Submit
to start the simulation.
Running a Simulation with VIZ
After clicking Submit
, the GridAPPS-D VIZ will generate a new oneline diagram for the desired feeder. Large models, such as the IEEE 8500 and 9500 node test systems, will take several seconds to load. A splashscreen will be displayed while the oneline diagram is being created.
The oneline diagram will then appear in the main window under the Simulation
tab.
Across the tab are three more tabs for events loaded into the simulation, applications configured to run, and SCADA alarms received during the simulation.
Simulation Tab
The Simulation Tab contains options for viewing and controlling equipment in the feeder model.
Starting, Pausing, and Stopping a Simulation
To start the simulation, click the start button shown above. A “Simulation is starting” message will be displayed while the CIM model is imported, converted, and configured to run with the specified simulation parameters.
After the simulation starts, a unique simulation ID will be created and displayed in the top left corner. This ID is used by applications to communicate with the correct simulation (as multiple simulations may be running simulateously).
The simulation may be paused or stopped using the pause and stop button in the top right corner of the simulation window.
Viewing equipment names
To view the names of devices in the feeder, zoom in using the mouse wheel and hover over the desired piece of equipment. Its name will be displayed below.
Opening and Closing Switches
Closed switches are displayed as a red breaker square. Open switches are green.
To open or close a switch, left-click on the square and select the desired state from the menu. Click Apply
Events Tab
The Events Tab shows events that were created using the TestManager and are scheduled to occur over the course of the simulation.
Alarms Tab
The GridAPPS-D Alarms service monitors the GOSS Message Bus and generates alarms for common equipment control actions, including
Switch open/close
Capacitor open/close
Regulator tap change
The Alarms Tab is the last one in the top ribbon and diplays a notification with the number of new alarms that have not been viewed:
Under the Alarms Tab is a table indicating the piece of equipment for which the alarm occured, the time of the alarm, and source of the action.
Alarms created by events defined in the TestManager (such as fault events and scheduled command events) appear as being created by testmanager1:
Alarms can be acknowledged and removed from the table by clicking the check mark button on the far left of each row.
The alarm location can be viewed by clicking on the magnifying glass button. This will switch to the Simulation tab and the particular piece of equipment will be highlighted with an expanding circle.
Creating Stripchart Plots
GridAPPS-D contains a set of basic plotting features for common power system parameters
New plots can be added by cliking the trendline button to the right of the pause and stop buttons.
A pop-up dialog will appear to select the desired plots with several options:
Created plots – edit custom plots that have already been created
Plot name – custom text string that will be displayed as plot title
Component type – Power (
VA
), Tap (Pos
), or Voltage (PNV
) measurement typeMagnitude / Angle
Apparent power & acos(power factor) for power measurements
Voltage magnitude & phase angle for voltage measurements
Component – Component name, type to search
Phases – Any combination of A, B, and C phases to plot
Be sure to click the Add component
button before clicking Done
After clicking the Done
button, the new custom plots will appear in the right-hand pane of the window.
Alternate plot colors are available by switching from the theme from dark to light:
Docker Shortcuts
Cloud Server Configuration
Configuring Remote GridAPPS-D VIZ
To access the GridAPPS-D VIZ from a local client, it is necessary to specify the IP address of the remote server in the viz.config
file located in the ~/gridappsd-docker/conf/
directory.
The configuration file is formatted as a JSON string specifying the version of the VIZ used and the IP address and port to be used:
{
"version": "remote:develop",
"host": "my.server.ip.address:61614"
}
GridAPPS-D Platform Release History
Version 2021.04.0
Install using ./run.sh -t releases_2021.04.0
New Features
Platform added the capability for Applications to send Ochre commands to the simulations.
Powergrid-Models added IEEE 13 OCHRE model update.
Resolved issue with Proven write simultion input
Source Code
goss-gridapps-d - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2021.04.0
gridappsd-viz - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2021.04.0
gridappsd-python - https://github.com/GRIDAPPSD/gridappsd-python/tree/releases/2021.04.0
cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2021.04.0
proven-cluster - https://github.com/pnnl/proven-cluster/releases/tag/v1.3.8.1
proven-client - https://github.com/pnnl/proven-client/releases/tag/v1.3.6
proven-message - https://github.com/pnnl/proven-message/releases/tag/v1.3.5.4
proven-docker - https://github.com/GRIDAPPSD/proven-docker/tree/releases/2021.04.0
gridappsd-docker-build - https://github.com/GRIDAPPSD/gridappsd-docker-build/tree/releases/2021.04.0
Version 2021.03.0
Install using ./run.sh -t releases_2021.03.0
New Features
Platform switched from using Cim2Glm to CimHub library for power grid APIs.
Powergrid-Models repository refactored to contianer only models.
CimHub repository refactored to contain CimHub library and related utility functions
Resolved issue regarding clean exit of HELICS on simulation stopped by user
Resolved issue with Proven storing test manager input messages
Viz: added timezome support
Viz: Resolved issues with powerflow direction arrows
Updated documentaiton on CimHub
Added integration tests for configuration and alarm API
Source Code
goss-gridapps-d - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2021.03.0
gridappsd-viz - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2021.03.0
gridappsd-python - https://github.com/GRIDAPPSD/gridappsd-python/tree/releases/2021.03.0
cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2021.03.0
proven-cluster - https://github.com/pnnl/proven-cluster/releases/tag/v1.3.7.4
proven-client - https://github.com/pnnl/proven-client/releases/tag/v1.3.6
proven-message - https://github.com/pnnl/proven-message/releases/tag/v1.3.5.4
proven-docker - https://github.com/GRIDAPPSD/proven-docker/tree/releases/2021.03.0
gridappsd-docker-build - https://github.com/GRIDAPPSD/gridappsd-docker-build/tree/releases/2021.03.0
gridlab-d - https://github.com/GRIDAPPSD/gridlab-d/tree/develop
sample-app - https://github.com/GRIDAPPSD/gridappsd-sample-app/tree/releases/2021.03.0
Version 2021.02.0
New Features
Added HELICS as a simulator. This included adding HELICS in GridAPPS-D docker container and adding HELICS service configuration file
Added HELICS-GOSS bridge to translate control and measurement messages between HELICS and platform.
Generated HELICS configurations for GridLAB-D
Added unit testing framework for the HELICS-GOSS bridge
Added SoC support to the HELICS-GOSS bridge.
Updated Test Manager to publish results as they are processed intead of at the end of the simulation.
Updated services to use platform log level
Added test users to test various roles
Updated to use username/password from environment variables instead of hardcoded in soruce code
Fixed APIs where response was not correct when selecting response format as XML
Added OCHRE house simulator in the GridAPPSD docker container. Tested it with GridLAB-d and HELICS.
Corrected naming of S2 69kV breaker names to match sub-transmission diagram
Updated IEEE 13Assets model. Line length issue was fixed in opendsscmd 1.2.15
Viz: Switched the arrow directions of selected lines and switches to display power flow direction.
Viz: Plotting the Time Series Simulation Vs. Time Series Simulation results.
Sample app updated to use token-based authentication.
Updated gridappsd-python library for token-based authentication
Added tests for configuration and power grid APIs
Source Code
goss-gridapps-d - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2020.02.0
gridappsd-viz - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2020.02.0
gridappsd-python - https://github.com/GRIDAPPSD/gridappsd-python/tree/releases/2020.02.0
cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2020.02.0
proven-cluster - https://github.com/pnnl/proven-cluster/releases/tag/v1.3.7.3
proven-client - https://github.com/pnnl/proven-client/releases/tag/v1.3.6
proven-message - https://github.com/pnnl/proven-message/releases/tag/v1.3.5.4
proven-docker - https://github.com/GRIDAPPSD/proven-docker/tree/releases/2020.02.0
gridappsd-docker-build - https://github.com/GRIDAPPSD/gridappsd-docker-build/tree/releases/2020.02.0
gridlab-d - https://github.com/GRIDAPPSD/gridlab-d/tree/develop
sample-app - https://github.com/GRIDAPPSD/gridappsd-sample-app/tree/releases/2020.02.0
Version 2020.12.0
New Features
Increase AMQ topic permissions for all users until more specific permissions have been defined
Update configs to support the token based authentication
Updated to new version of cim2glm
Updated to support change in goss-core where it makes the decision to use a token in the gossclient a variable that must be set
Fixed sendError change that hadn’t been updated in ProcessEvent
Updated log api to include process type
Viz: Updated to use token-based authentication
Viz: Added functionality to automatically reconnect to the platform when it is restarted
Viz: Fixed partial powerflow highlighting of lines
Viz: Corrected the values of capacitor for open and close
Source Code
goss-gridapps-d - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2020.12.0
gridappsd-viz - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2020.12.0
gridappsd-python - https://github.com/GRIDAPPSD/gridappsd-python/tree/releases/2020.12.0
cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2020.12.0
proven-cluster - https://github.com/pnnl/proven-cluster/releases/tag/v1.3.5.7
proven-client - https://github.com/pnnl/proven-client/releases/tag/v1.3.6
proven-message - https://github.com/pnnl/proven-message/releases/tag/v1.3.5.4
proven-docker - https://github.com/GRIDAPPSD/proven-docker/tree/releases/2020.12.0
gridappsd-docker-build - https://github.com/GRIDAPPSD/gridappsd-docker-build/tree/releases/2020.12.0
gridlab-d - https://github.com/GRIDAPPSD/gridlab-d/tree/develop
sample-app - https://github.com/GRIDAPPSD/gridappsd-sample-app/tree/releases/2020.12.0
Version 2020.11.0
New Features
Querying simulation file to use weather data for startime-1 minute
Moved state-estimator to gridappsd base container
Integration tests added for APIs
Viz: Changes made to notifications UI
Viz: Updated rendering positions for reverse arrows for transformers
Viz: Added buttons to zoom in and out on plots
gridappsd-python: Updates made for integration test runs
Cim2glm: Added repeatable randomization and reusable mRID for houses
Cim2glm: Saved JSON files with all node coordinates
Cim2glm: added missing s2 phase
Cim2glm: Made the SoC meaurement mRID persistent
Cim2glm: Fixes made for maven builds
Source Code
goss-gridapps-d - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2020.11.0
gridappsd-viz - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2020.11.0
gridappsd-python - https://github.com/GRIDAPPSD/gridappsd-python/tree/releases/2020.11.0
cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2020.11.0
proven-cluster - https://github.com/pnnl/proven-cluster/releases/tag/v1.3.5.7
proven-client - https://github.com/pnnl/proven-client/releases/tag/v1.3.6
proven-message - https://github.com/pnnl/proven-message/releases/tag/v1.3.5.4
proven-docker - https://github.com/GRIDAPPSD/proven-docker/tree/releases/2020.11.0
gridappsd-docker-build - https://github.com/GRIDAPPSD/gridappsd-docker-build/tree/releases/2020.11.0
gridlab-d - https://github.com/GRIDAPPSD/gridlab-d/tree/develop
sample-app - https://github.com/GRIDAPPSD/gridappsd-sample-app/tree/releases/2020.11.0
Version 2020.09.0
New Features
Reduced log published based on log level
Changed default log level to INFO
Added additional code for SoC measurement translations
Publishing simulation started message as log level INFO
Fixed type for SoC measurement translation in fncs bridge.
Updated proven version for storing simulationid and current time
Added support for SoC measurement
Viz: Fixed code that detects whether the response body can be converted to CSV or not
Viz: Changed how simulation statuses STARTED and PAUSED are detected
Viz: Add a button to upload simulation configuration object
Viz: Attaching Magnitude or Angle to plot name if it doesn’t have those suffixes already
Viz: Rendering min/average/max voltages and load demand plots
Viz: Rendering power flow direction indicators for edges/switches/capacitors/regulators during a simulation
Viz: Plotting percentages of nominal voltage by taking the average of Alo and Ahi then divide by sqrt(3)
Cim2glm: Support added for battery SoC measurement insertion and dictionary
Cim2glm: Added a query to list XY coordinates for buses
Cim2glm: Added support to insert synchronous machine
Cim2glm: Updated cim2glm version to 19.1.1
GridAPPS-D docker: Updated proven version to 1.3.7
Source Code
goss-gridapps-d - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2020.09.0
gridappsd-viz - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2020.09.0
gridappsd-python - https://github.com/GRIDAPPSD/gridappsd-python/tree/releases/2020.08.0
cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2020.09.0
proven-cluster - https://github.com/pnnl/proven-cluster/releases/tag/v1.3.7
proven-client - https://github.com/pnnl/proven-client/releases/tag/v1.3.7
proven-message - https://github.com/pnnl/proven-message/releases/tag/v1.3.7
proven-docker - https://github.com/GRIDAPPSD/proven-docker/tree/releases/2020.09.0
gridappsd-docker-build - https://github.com/GRIDAPPSD/gridappsd-docker-build/tree/releases/2020.08.0
gridlab-d - https://github.com/GRIDAPPSD/gridlab-d/tree/develop
sample-app - https://github.com/GRIDAPPSD/gridappsd-sample-app/tree/releases/2020.09.0
Version 2020.08.0
New Features
Storing alarms data in timeseries data store InfluxDB.
Converted all simulation id to string
Updated version of Cim2glm library
Viz: Upgraded dependency to fix security alert reported by GitHub
Viz: Added an input box to change the response topic for stomp client UI
Viz: Implemented expected results view
Cim2glm: Wrote VLL for primary_voltge and secondary_voltage of 3-phase transformers
Cim2glm: added bus name and coordinates to the voltage limit dictionary
Cim2glm: Fixed a case sensitivity for Ubuntu
Cim2glm: Filled missing coordinates on transactive123. Optimized the XY coordinates in voltage limit dictionary
Cim2glm: Created script that inserts DER from a text file. Able to insert, drop and re-insert DER
Cim2glm: Fixed bug in adding a DER terminal with wrong mRID
Cim2glm: Added documentation to insert DER
Cim2glm: Fixed the conversion of open switches. Fixed the shorting of fuses
Cim2glm: Added temporary fix for two-phase transformers that are missing one phase’stransformer code
Cim2glm: Added method to support buildlimitmaps with just two parameters
Cim2glm: Added bus name and coordinates to the voltage limit dictionary
Cim2glm: Fixed capacitor naming - no impact on power flow - previously lines / switches numbered 1-3 but caps numbered 0-2.
Cim2glm: Renamed Loads.dss to BalancedLoads.dss
Sample app: Calling get_message function with simulation timesatamp instead of current time.
Source Code
goss-gridapps-d - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2020.08.0
gridappsd-viz - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2020.08.0
gridappsd-python - https://github.com/GRIDAPPSD/gridappsd-python/tree/releases/2020.08.0
cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2020.08.0
proven-cluster - https://github.com/pnnl/proven-cluster/releases/tag/v1.3.5.7
proven-client - https://github.com/pnnl/proven-client/releases/tag/v1.3.6
proven-message - https://github.com/pnnl/proven-message/releases/tag/v1.3.5.4
gridlab-d - https://github.com/GRIDAPPSD/gridlab-d/tree/develop
sample-app - https://github.com/GRIDAPPSD/gridappsd-sample-app/tree/releases/2020.08.0
Version 2020.07.0
New Features
Updated opendss to version 1.2.11
Added PAUSEd to ProcessStatus list to resolve testing issue.
Updated TestManager to include comparing expected results between output of 2 simulations.
Updated TestManager to include comparing currently running simulation to result of previously ran simulation.
Added a new setting to Viz UI that allows toggling logging.
Fixed the problem in Viz where unselecting selected services didn’t remove them from the simulation configuration object
Powergrid model: Bumped mysql-connector-java from 5.1.40 to 8.0.16 in /CIM/cim-parser
More integration tests added for power grid and simuation API.
Integration tests added for alarms and timeseries API.
Source Code
goss-gridapps-d - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2020.07.0
gridappsd-viz - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2020.07.0
gridappsd-python - https://github.com/GRIDAPPSD/gridappsd-python/tree/releases/2020.07.0
cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2020.07.0
proven-cluster - https://github.com/pnnl/proven-cluster/releases/tag/v1.3.5.7
proven-client - https://github.com/pnnl/proven-client/releases/tag/v1.3.6
proven-message - https://github.com/pnnl/proven-message/releases/tag/v1.3.5.4
proven-docker - https://github.com/GRIDAPPSD/proven-docker/tree/releases/2020.07.0
gridappsd-docker-build - https://github.com/GRIDAPPSD/gridappsd-docker-build/tree/releases/2020.07.0
gridlab-d - https://github.com/GRIDAPPSD/gridlab-d/tree/develop
sample-app - https://github.com/GRIDAPPSD/gridappsd-sample-app/tree/releases/2020.07.0
Version 2020.05.0
New Features
Updated YBus export to include model_id as parameter
Made changed to work with multiple load profiles measurements in InfluxDB.
Corrected issue of no player file if schedule name is not passed in request.
Fix stomp client initialization problem for Viz app on firefox where it was getting stuck in connecting state for a long time.
Testing summary added to integration testing.
Integration tests added for power grid and simulation API.
AWS summary web page added for integration testing report.
Source Code
goss-gridapps-d - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2020.05.0
gridappsd-viz - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2020.05.0
gridappsd-python - https://github.com/GRIDAPPSD/gridappsd-python/tree/releases/2020.05.0
cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2020.05.0
proven-cluster - https://github.com/pnnl/proven-cluster/releases/tag/v1.3.5.7
proven-client - https://github.com/pnnl/proven-client/releases/tag/v1.3.6
proven-message - https://github.com/pnnl/proven-message/releases/tag/v1.3.5.4
proven-docker - https://github.com/GRIDAPPSD/proven-docker/tree/releases/2020.05.0
gridappsd-docker-build - https://github.com/GRIDAPPSD/gridappsd-docker-build/tree/releases/2020.05.0
gridlab-d - https://github.com/GRIDAPPSD/gridlab-d/tree/develop
sample-app - https://github.com/GRIDAPPSD/gridappsd-sample-app/tree/releases/2020.05.0
Version 2020.04.0
New Features
Updated Cim2GLM library version to 18.0.3
Added Configuration handler for generating limits.json file
Increased web socket message size
Corrected issue where phase count is incorrect for phase s1, s2 loads
Corrected json parse method for TimeSeriesRequest class.
Viz app: Updated to use simulation timestamp for voltage violation instead of current time.
Viz app: Show “Simulation starting” message before simulation is started and hide the Pause/Stop buttons.
Powergrid model: Added scripts and *uuid.dat files to maintain persistent mRID values
Powergrid model: Supporting OverheadLineUnbalanced, ganged regulators and unknown spacings for 1-phase and 2-phase line.
Integration testing infrastructure create with PyTest and Travis.
Source Code
goss-gridapps-d - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2020.04.0
gridappsd-viz - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2020.04.0
gridappsd-python - https://github.com/GRIDAPPSD/gridappsd-python/tree/releases/2020.04.0
cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2020.04.0
proven-cluster - https://github.com/pnnl/proven-cluster/releases/tag/v1.3.5.7
proven-client - https://github.com/pnnl/proven-client/releases/tag/v1.3.6
proven-message - https://github.com/pnnl/proven-message/releases/tag/v1.3.5.4
proven-docker - https://github.com/GRIDAPPSD/proven-docker/tree/releases/2020.04.0
gridappsd-docker-build - https://github.com/GRIDAPPSD/gridappsd-docker-build/tree/releases/2020.04.0
gridlab-d - https://github.com/GRIDAPPSD/gridlab-d/tree/develop
sample-app - https://github.com/GRIDAPPSD/gridappsd-sample-app/tree/releases/2020.04.0
Version 2020.03.0
New Features
Viz app can display lines and nodes with power outage.
Changes are made in Viz app to start and show data from State Estimator service.
Viz app can render battery nad solar panel shapes.
Fixes are made to support no player file in simulation config.
Timestamp display added for voltage violation on Viz.
Viz can start and subscribe to State-Estimator service.
Integration tests created for simulation api.
Source Code
goss-gridapps-d - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2020.03.0
gridappsd-viz - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2020.03.0
gridappsd-python - https://github.com/GRIDAPPSD/gridappsd-python/tree/releases/2020.03.0
cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2020.03.0
proven-cluster - https://github.com/pnnl/proven-cluster/releases/tag/v1.3.5.7
proven-client - https://github.com/pnnl/proven-client/releases/tag/v1.3.6
proven-message - https://github.com/pnnl/proven-message/releases/tag/v1.3.5.4
proven-docker - https://github.com/GRIDAPPSD/proven-docker/tree/releases/2020.03.0
gridappsd-docker-build - https://github.com/GRIDAPPSD/gridappsd-docker-build/tree/releases/2020.03.0
gridlab-d - https://github.com/GRIDAPPSD/gridlab-d/tree/develop
sample-app - https://github.com/GRIDAPPSD/gridappsd-sample-app/tree/releases/2020.03.0
Version 2020.02.0
New Features
Alarms status is published as Open/Close instead of 0/1.
Added resume/pause-at API for simulation.
Added the EnergyConsumer.p attribute as a writable property in the FNCS GOSS Bridge
Fixed floating switches issue on Viz app.
Added units on the plots.
Viz allow user to go to nodes by clicking on plots.
Labels added for overlapping line on Viz plots.
Operator login issue resolved.
First integration test added in gridappsd-testing repo.
Source Code
goss-gridapps-d - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2020.02.0
gridappsd-viz - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2020.02.0
gridappsd-python - https://github.com/GRIDAPPSD/gridappsd-python/tree/releases/2020.02.0
cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2020.02.0
proven-cluster - https://github.com/pnnl/proven-cluster/releases/tag/v1.3.5.7
proven-client - https://github.com/pnnl/proven-client/releases/tag/v1.3.6
proven-message - https://github.com/pnnl/proven-message/releases/tag/v1.3.5.4
proven-docker - https://github.com/GRIDAPPSD/proven-docker/tree/releases/2020.02.0
gridappsd-docker-build - https://github.com/GRIDAPPSD/gridappsd-docker-build/tree/releases/2020.02.0
gridlab-d - https://github.com/GRIDAPPSD/gridlab-d/tree/develop
sample-app - https://github.com/GRIDAPPSD/gridappsd-sample-app/tree/releases/2020.02.0
Version 2020.01.0
New Features
Alarms are varified before publishing.
Fixed floating switches issue on Viz app.
Release process documeted at gridappsd-docker-build repository readme
Created an automated, repeatable way to upload data in blazegraph
Documented model state update for starting a simulation
Source Code
goss-gridapps-d - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2020.01.0
gridappsd-viz - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2020.01.0
gridappsd-python - https://github.com/GRIDAPPSD/gridappsd-python/tree/releases/2020.01.0
cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2020.01.0
proven-cluster - https://github.com/pnnl/proven-cluster/releases/tag/v1.3.5.7
proven-client - https://github.com/pnnl/proven-client/releases/tag/v1.3.6
proven-message - https://github.com/pnnl/proven-message/releases/tag/v1.3.5.4
proven-docker - https://github.com/GRIDAPPSD/proven-docker/tree/releases/2020.01.0
gridappsd-docker-build - https://github.com/GRIDAPPSD/gridappsd-docker-build/tree/releases/2020.01.0
gridlab-d - https://github.com/GRIDAPPSD/gridlab-d/tree/develop
sample-app - https://github.com/GRIDAPPSD/gridappsd-sample-app/tree/releases/2020.01.0
Version 2019.12.0
New Features
Updated and documented MRID UUID generator to ensure compliance with UUID 4
Integrate DNP3 service with GridAPPS-D container
Created API to get user role based on login
Added a user for testmanager to distinguish between simulation commands and alarms
Removed hardcoded corrdinate identifcation from Viz
Added capability to change model state before starting a simulation.
Added feature on UI to upload a file with faults and comunication output
Created user login page on UI
Added light/dark toggle themeon UI
Wrote a SWING_PQ node for each potential island in power grid model.
Fixed issues for app eveluations as reported by app developers or evluation team
Updated ci/cd scripts for repositories to support travis.ci updates
Source Code
goss-gridapps-d - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2019.12.0
gridappsd-viz - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2019.12.0
gridappsd-python - https://github.com/GRIDAPPSD/gridappsd-python/tree/releases/2019.12.0
cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2019.12.0
proven-cluster - https://github.com/pnnl/proven-cluster/releases/tag/v1.3.5.7
proven-client - https://github.com/pnnl/proven-client/releases/tag/v1.3.6
proven-message - https://github.com/pnnl/proven-message/releases/tag/v1.3.5.4
proven-docker - https://github.com/GRIDAPPSD/proven-docker/tree/releases/2019.12.0
gridappsd-docker-build - https://github.com/GRIDAPPSD/gridappsd-docker-build/tree/releases/2019.12.0
gridlab-d - https://github.com/GRIDAPPSD/gridlab-d/tree/develop
sample-app - https://github.com/GRIDAPPSD/gridappsd-sample-app/tree/releases/2019.12.0
Version 2019.10.0
New Features
Alarms service created. It publishes alarm whenver a switch or capacitor is opened or closed. It is added as a pre-requisite for sample app.
Load profile data pre-loaded in timeseries data store InfluxDB.
Load profile file ieeezipload.player is created dynamically based on simulation start time and duration.
API updated in platform and Proven to query load profile data.
Timeseries API updated to accept timestamps in seconds instead of micro or nanosecond.
Timeseries API updated to accept query filters in an array instead of single value.
Viz app: User can search and highlight objects on network by name and mrid.
Viz app: User can re-center network graph.
Viz app: Displays alarms in a saperate tab when simulation is running. Notifies when a new alarm is received in alarm tab.
Viz app: User can upload scheduled commands json file with communication outage and faults.
Viz app: Switches are displayed as closed/opened based on simulation output value.
Viz app: Display image for switches are changes to green/red squares and moved between nodes.
Bug fixes in DSS configuration.
GridLAB-D updated to latest develop version.
OpenDSSCmd updated to 1.2.3.
Powergrid models - Updated Generator.dss to include kVA for generators.
Added kva base to glm file, so setting kw=0 does not make the kva base also 0.
Internal house loads added. Schedule file is created for simulation when useHouses=true.
Sensor service bugs fixed.
API added to export Vnom opendss file.
Source Code
goss-gridapps-d - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2019.10.0
gridappsd-viz - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2019.10.0
gridappsd-python - https://github.com/GRIDAPPSD/gridappsd-python/tree/releases/2019.10.0
cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2019.10.0
proven-cluster - https://github.com/pnnl/proven-cluster/releases/tag/v1.3.5.7
proven-client - https://github.com/pnnl/proven-client/releases/tag/v1.3.6
proven-message - https://github.com/pnnl/proven-message/releases/tag/v1.3.5.4
proven-docker - https://github.com/GRIDAPPSD/proven-docker/tree/releases/2019.10.0
gridappsd-docker-build - https://github.com/GRIDAPPSD/gridappsd-docker-build/tree/releases/2019.10.0
gridlab-d - https://github.com/GRIDAPPSD/gridlab-d/tree/develop
sample-app - https://github.com/GRIDAPPSD/gridappsd-sample-app/tree/releases/2019.10.0
Version 2019.09.1
New Features
BREAKING CHANGE: Measurements in simulation output message changed from array to dictionary.
Simulation are now working for 9500 model with houses.
Added missing measurement in blazegraph for houses.
Voltage violation service and Viz app updated to work with new simulation output format.
Faults are working with 9500 model.
Viz app: User can select services and their input parameters in simulation request form.
Viz app: Y-axis label corrected if plot value is same during the simulation run.
Simulation request API updated to take user input parameters for services.
Timezone corrected for pre-loaded weather data.
Operational limit set on the power grid models in blazegraph.
Source Code
goss-gridapps-d - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2019.09.1
gridappsd-viz - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2019.09.1
gridappsd-python - https://github.com/GRIDAPPSD/gridappsd-python/tree/releases/2019.09.1
cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2019.09.1
proven-cluster - https://github.com/pnnl/proven-cluster/releases/tag/v1.3.5.7
proven-client - https://github.com/pnnl/proven-client/releases/tag/v1.3.6
proven-message - https://github.com/pnnl/proven-message/releases/tag/v1.3.5.4
proven-docker - https://github.com/GRIDAPPSD/proven-docker/tree/releases/2019.09.1
gridappsd-docker-build - https://github.com/GRIDAPPSD/gridappsd-docker-build/tree/releases/2019.09.1
gridlab-d - https://github.com/GRIDAPPSD/gridlab-d/tree/develop
sample-app - https://github.com/GRIDAPPSD/gridappsd-sample-app/tree/releases/2019.09.1
Version 2019.09.0
New Features
Fault Processing: Faults are working on radial feeders.
Note: Faults are not working on meshed systems. If you have a meshed system then send switch open message to simulate the fault.
Source Code
goss-gridapps-d - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2019.09.0
gridappsd-viz - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2019.09.0
gridappsd-python - https://github.com/GRIDAPPSD/gridappsd-python/tree/releases/2019.09.0
cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2019.09.0
proven-cluster - https://github.com/pnnl/proven-cluster/releases/tag/v1.3.5.5
proven-client - https://github.com/pnnl/proven-client/releases/tag/v1.3.5
proven-message - https://github.com/pnnl/proven-message/releases/tag/v1.3.5.4
proven-docker - https://github.com/GRIDAPPSD/proven-docker/tree/releases/2019.09.0
gridappsd-docker-build - https://github.com/GRIDAPPSD/gridappsd-docker-build/tree/releases/2019.09.0
gridlab-d - https://github.com/GRIDAPPSD/gridlab-d/tree/develop
sample-app - https://github.com/GRIDAPPSD/gridappsd-sample-app/tree/releases/2019.09.0
Version 2019.08.1
New Features
Viz: Change simulation pause button to start button when simulation completes.
Bug fix: Simulation id dropdown is not showing selected id in Browse-data-logs.
Bug fix: Timeseries queries returning same object multiple times.
Bug fix: Weather file containes only 10 minute data even if simulation duration is longer.
Source Code
goss-gridapps-d - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2019.08.1
gridappsd-viz - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2019.08.1
gridappsd-python - https://github.com/GRIDAPPSD/gridappsd-python/tree/releases/2019.08.1
cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2019.08.0
proven-cluster - https://github.com/pnnl/proven-cluster/releases/tag/v1.3.5.5
proven-client - https://github.com/pnnl/proven-client/releases/tag/v1.3.5
proven-message - https://github.com/pnnl/proven-message/releases/tag/v1.3.5.4
proven-docker - https://github.com/GRIDAPPSD/proven-docker/tree/releases/2019.08.0
gridappsd-docker-build - https://github.com/GRIDAPPSD/gridappsd-docker-build/tree/releases/2019.08.1
gridlab-d - https://github.com/GRIDAPPSD/gridlab-d/tree/develop
sample-app - https://github.com/GRIDAPPSD/gridappsd-sample-app/tree/releases/2019.08.1
Version 2019.08.0
New Features
Viz added capability to select power/voltage/tap measurments for custom plotting
Control attributes are back for Capacitors
Added Voltage Violation service that publishes list of measurement ids with per unit voltages that are out of range every 15 minutes
Viz added display for Voltage Violation service output
Viz can display Lot/Long coordinated for 9500 node model.
Breaking Change: JSON format for timeseries query response is flattend out
Resolved 500 Internal server error for storing simulation input.
Houses are created and uploaded to Blazegraph for 123 node model
Additonal column process_type added for logs to distinguish process id for simulation
Source Code
goss-gridapps-d - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2019.08.0
gridappsd-viz - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2019.08.0
gridappsd-python - https://github.com/GRIDAPPSD/gridappsd-python/tree/releases/2019.08.0
cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2019.08.0
proven-cluster - https://github.com/pnnl/proven-cluster/releases/tag/v1.3.5.5
proven-client - https://github.com/pnnl/proven-client/releases/tag/v1.3.5
proven-message - https://github.com/pnnl/proven-message/releases/tag/v1.3.5.4
proven-docker - https://github.com/GRIDAPPSD/proven-docker/tree/releases/2019.08.0
gridappsd-docker-build - https://github.com/GRIDAPPSD/gridappsd-docker-build/tree/releases/2019.08.0
gridlab-d - https://github.com/GRIDAPPSD/gridlab-d/tree/develop
sample-app - https://github.com/GRIDAPPSD/gridappsd-sample-app/tree/releases/2019.08.0
Version 2019.07.0
Bugs Fixed
Time series query filter are updated in the API as well documentation.
Selecting houses is now working with the simulation.
Following bugs resolved for Viz
Line name is not based on previously selected values.
Removing a selected app-name closes input form
Change Event Id to Event tag
Change attribute to a multi-value select box
Help-text ‘Add input item’ does not go away on CommOutage tab
Object mrid is not correct for multiple phases selection.
Pos added for load break switches
New Features
Platform now stores input and output from services and applications output/input in time series data store.
Simulation can run with new 9500 node model
Support for synchronous machines added in CIM model in blazegraph.
End-to-end fault injecting and processing pipeline is now working.
Powergrid api added to query object id, object dictionary and object measurements.
New keys added in glm file to support faults.
Viz can display plot for new 9500 model.
Added log api in gridappsd-python
Measurement for switch positions for all models
Explicit setting for manual mode in reg and capacitora in the RegulatingControl.mode attribute.
GridAPPS base constainer has folowwing changes
Switch to openjdk
New version of fncs
CZMQ_VERSION changeed to 4.2.0
ZMQ_VERSION changes to 4.3.1
GridLAB-D switched from feature/1146 to develop
Source Code
goss-gridapps-d - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2019.07.0
gridappsd-viz - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2019.07.0
gridappsd-python - https://github.com/GRIDAPPSD/gridappsd-python/tree/releases/2019.07.0
cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2019.07.0
proven-cluster - https://github.com/pnnl/proven-cluster/releases/tag/v1.3.5.4
proven-client - https://github.com/pnnl/proven-client/releases/tag/v1.3.5
proven-message - https://github.com/pnnl/proven-message/releases/tag/v1.3.5.4
proven-docker - https://github.com/GRIDAPPSD/proven-docker/tree/releases/2019.06.0
gridappsd-docker-build - https://github.com/GRIDAPPSD/gridappsd-docker-build/tree/releases/2019.07.0
gridlab-d - https://github.com/GRIDAPPSD/gridlab-d/tree/develop
sample-app - https://github.com/GRIDAPPSD/gridappsd-sample-app/tree/releases/2019.07.0
Version 2019.06.0
Bugs Fixed
Updated configuration, power grid model and simulation API for CIM100 and app evaluation features addition.
All logs are being published to topic instead of queue.
Fixed TypError bug in gridappsd-sensor-service.
New Features
Communication outages: Platform supports input and/or output outage request with simulation for all or some selected power grid components. Outages are initiated and removed at the requested start and end time.
Fault injection: Platform can receive faults with simulation request and forwards them to co-simulator.
Viz UI updated: Input form added for communication outage and fault parameter selection. Input form moved from single page to separate tabs.
CIM version update: Updated CIM version to CIM100. Added support for Recloser and Breaker in model parsing.
New methods in Python wrapper: Capability added in gridappsd-python to start, stop and run a simulation directly from python using yaml or json.
Sample app container move to Python 3.6 as default. Updated gridappsd-sample-app to use updated container.
Debug scripts added: Added scripts in gridappsd-docker to run platform, co-simulator and simulator in separate terminals for debugging purposes.
Sensor service in available in gridappsd container by default. Sensor service is no longer required to be added in gridappsd container via docker-compose file.
Default log level is changed from DEBUG to ERROR for limiting the amount of log messages on terminal.
Breaking API change - Simulation input and output topics changed in gridappsd-python from FNCS_INPUT_TOPIC to SIMULATION_INPUT_TOPIC and FNCS_OUTPUT_TOPIC to SIMULATION_OUTPUT_TOPIC.
Breaking API change - Simulation request return a json with simulation id and list of events with their uuids instead of just simulation id.
Documentation
Using GridAPPS-D documentation section updated for new UI input form with communication outages and faults selection.
Source Code
goss-gridapps-d - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2019.06.0
gridappsd-viz - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2019.06.0
gridappsd-python - https://github.com/GRIDAPPSD/gridappsd-python/tree/releases/2019.06.0
cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2019.06.0
proven-cluster - 1.3.4 https://github.com/pnnl/proven-cluster/releases/tag/v1.3.5.3
proven-client - 1.3.4 https://github.com/pnnl/proven-client/releases/tag/v1.3.4
proven-message - https://github.com/pnnl/proven-message/releases/tag/v1.3.3
proven-docker - https://github.com/GRIDAPPSD/proven-docker/tree/releases/2019.06.0
gridappsd-docker-build - https://github.com/GRIDAPPSD/gridappsd-docker-build/tree/releases/2019.06.0
gridlab-d - https://github.com/GRIDAPPSD/gridlab-d/tree/feature/1146
sample-app - https://github.com/GRIDAPPSD/gridappsd-sample-app/tree/releases/2019.06.0
Version 2019.03.0
Bugs Fixed
Sending a command to change set point to the PV inverter has no effect.
Time series query return no data after simulation run.
Viz: Switch operations not working on Firefox browser. Time on x-axis on plots is not displayed correctly.
New Features
GridAPPS-D – VOLTTRON initial interface created. https://github.com/VOLTTRON/volttron/tree/rabbitmq-volttron/examples/GridAPPS-DAgent
Fault injection: Simulator can receive faults. Fault schema created in Test Manager. Workflow for fault processing documented on readthedocs.
Viz: Created menu for capacitors, regulators.
Proven: Facilitates direct disclosure of JSON messages to Proven via Hazelcast or REST; eliminating need for the proven-message library. Improved throughput and scalability for Proven’s data disclosure component. Disclosed data is now distributed or staged across the cluster to be used by future JET processing pipelines.
Documentation
CIM100 documented
Steps added for creating and testing an application
Updated documentation on Simulation API
Source Code
goss-gridapps-d - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2019.03.0
gridappsd-viz - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2019.03.0
gridappsd-python - https://github.com/GRIDAPPSD/gridappsd-python/tree/releases/2019.03.0
cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2019.03.0
proven-cluster - 1.3.4 https://github.com/pnnl/proven-cluster/releases/tag/v1.3.5.3
proven-client - 1.3.4 https://github.com/pnnl/proven-client/releases/tag/v1.3.4
proven-message - https://github.com/pnnl/proven-message/releases/tag/v1.3.3
proven-docker - https://github.com/GRIDAPPSD/proven-docker/tree/releases/2019.03.0
gridappsd-docker-build - https://github.com/GRIDAPPSD/gridappsd-docker-build/tree/releases/2019.03.0
gridlab-d - https://github.com/GRIDAPPSD/gridlab-d/tree/feature/1146
sample-app - https://github.com/GRIDAPPSD/gridappsd-sample-app/tree/releases/2019.03.0
Version: 2019.02.0
Release Date: Feb 2019
Fixed Bugs:
PROVEN - It can now store simulation input and output which can scale for IEEE8500 model.
PROVEN - It can store data with real-time simulation run.
PROVEN - Increased max data limit to unlimited.
FNCS Goss Bridge - Corrected the timestamp format in simulation logs.
New Features:
Viz - User can query log data from MySQL using Viz menu.
Viz - Added menu to operate switches.
FNCS GOSS bridge can do execute pause, resume and stop operations for simulation.
Update PROVEN docker container for automated builds.
Source Code:
goss-gridapps-d - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2019.02.0
gridappsd-viz - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2019.02.0
gridappsd-python - https://github.com/GRIDAPPSD/gridappsd-python/tree/releases/2019.02.0
cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2019.02.0
proven-cluster - 1.3.4 https://github.com/pnnl/proven-cluster/releases/tag/v1.3.4
proven-client - 1.3.4 https://github.com/pnnl/proven-client/releases/tag/v1.3.4
proven-message - https://github.com/pnnl/proven-message/releases/tag/v1.3.1
proven-docker - https://github.com/GRIDAPPSD/proven-docker
gridappsd-docker-build - https://github.com/GRIDAPPSD/gridappsd-docker-build/tree/releases/2019.02.0
gridlab-d - https://github.com/GRIDAPPSD/gridlab-d/tree/feature/1146
sample-app - https://github.com/GRIDAPPSD/gridappsd-sample-app/tree/releases/2019.02.0
Docker Container:
GridAPPS-D creates and starts following docker containers:
gridappsd/gridappsd:2019.01.0 - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2019.01.0 + proven-client - https://github.com/pnnl/proven-client + cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2019.01.0 + gridappsd/gridappsd-base:master - https://github.com/GRIDAPPSD/gridappsd-docker-build/tree/releases/2019.01.0 + zeromq - http://download.zeromq.org/zeromq-4.0.2.tar.gz + zeromq_czmq - https://archive.org/download/zeromq_czmq_3.0.2/czmq-3.0.2.tar.gz + activemq - http://mirror.olnevhost.net/pub/apache/activemq/activemq-cpp/3.9.4/activemq-cpp-library-3.9.4-src.tar.gz + fncs - https://github.com/GRIDAPPSD/fncs/tree/develop + gridlab-d - https://github.com/GRIDAPPSD/gridlab-d/tree/feature/1146
gridappsd/influxdb:2019.01.0 - https://github.com/GRIDAPPSD/gridappsd-data/tree/releases/2019.01.0 + influxdb:latest - https://hub.docker.com/_/influxdb
gridappsd/blazegraph - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2019.01.0 + lyrasis/lbazegraph:2.1.4 - https://hub.docker.com/r/lyrasis/blazegraph
gridappsd/proven - https://github.com/GRIDAPPSD/proven-docker + proven-cluster - https://github.com/pnnl/proven-cluster/tree/v1.3.3 + proven-message - https://github.com/pnnl/proven-message/tree/v1.3.1
gridappsd/sample-app - https://github.com/GRIDAPPSD/gridappsd-sample-app/tree/releases/2019.01.0 + gridappsd/app-container-base - (TODO: @Craig can you provide the repository?)
gridappsd/viz:2019.01.0 - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2019.01.0
redis:3.2.11-alpine - https://hub.docker.com/_/redis
mysql/mysql-server:5.7 - https://hub.docker.com/_/mysql
Version: 2019.01.0
Release Date: January 2019
Platform updates:
Simulation can run as fast as possible as well as real-time (every 3 seconds)
Simulation can run with houses if present in the model.
Following components can be controlled while the simulation is running:
Open or close capacitors
Open or close switches
Change tap setting for regulators
Changing control modes for regulators
Change inverter P & Q output
Set control modes for regulators and capacitors
Simulation request creates the input weather file.
gridappsd-python:
cim2glm:
Optional house cooling load components
Single-phase power electronics and fuse ratings
Inverter parameters changed from rotating machines to power electronics
Solar and storage
Measurements exported to the circuit metadata (JSON file); SimObject identifies the corresponding GridLAB-D object
Supplemental scripts to populate feeder with measurements and houses
Rotating machines, only parameters essential for the UAF lab microgrid
In GridLAB-D export of loads, each node or triplex_node will have separate submeters for houses, PV inverters, battery inverters and rotating machines, i.e., not patterned after net metering
Data updates:
2.1 Power grid models:
Power grid models are stored in blazegraph database in its own docker container.
Following models are pre-loaded
EPRI_DPV_J1
IEEE123
IEEE13
R2_12_47_2
IEEE8500
IEEE123_pv
User can upload customized model
2.2 Weather:
Weather data in stored in InfluxDB using Proven.
InfluxDB has its own docker container with pre-loaded weather data.
API added to query weather data.
Feature added to create weather file for a simulation
Details of pre-loaded weather data in current release
2.3 Simulation Input
Simulation input commands sent by applications/services are stored in InfluxDB using Proven.
API added to query input data.
2.4 Simulation Output
Output from simulator is stored in InfluxDB using Proven.
API added to query output data.
2.5 Logs
API added for query based on pre-defined filters or custom SQL string.
Changed logs to have epoch time format.
Applications and Services:
3.1 Viz
User can select to run simulation at real-time or as fast as possible
User can select to add houses in the simulation
User can open or close switches and capacitors by clocking on them
Cleaner display of log messages while simulation is running
User can query simulation logs after simulation is done.
Toggle switches open/close
Querying logs through Viz (still working on this)
Bug fixes
fixed the stomp client in Viz,
added missing capacitor labels
redirect non-root urls to root (localhost:8080)
3.2 Sample application:
Source code at https://github.com/GRIDAPPSD/gridappsd-sample-app
Sample app runs in its own container
Register with gridapps-d platform when platform start.
Re-register automatically if platform restart.
Redundant log messages removed.
Works with user selected model instead of hard-coded ones.
Source Code:
goss-gridapps-d - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2019.01.0
gridappsd-viz - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2019.01.0
gridappsd-python - https://github.com/GRIDAPPSD/gridappsd-python/tree/releases/2019.01.0
cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2019.01.0
proven-cluster - https://github.com/pnnl/proven-cluster (@Eric: link for release branches)
proven-docker - https://github.com/GRIDAPPSD/proven-docker
proven-client - https://github.com/pnnl/proven-client
proven-message - https://github.com/pnnl/proven-message
gridappsd-docker-build - https://github.com/GRIDAPPSD/gridappsd-docker-build/tree/releases/2019.01.0
gridlab-d - https://github.com/GRIDAPPSD/gridlab-d/tree/feature/1146
sample-app https://github.com/GRIDAPPSD/gridappsd-sample-app/tree/releases/2019.01.0
Docker Container:
GridAPPS-D creates and starts following docker containers:
gridappsd/gridappsd:2019.01.0 - https://github.com/GRIDAPPSD/GOSS-GridAPPS-D/tree/releases/2019.01.0
proven-client - https://github.com/pnnl/proven-client
cim2glm - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2019.01.0
gridappsd/gridappsd-base:master - https://github.com/GRIDAPPSD/gridappsd-docker-build/tree/releases/2019.01.0
zeromq_czmq - https://archive.org/download/zeromq_czmq_3.0.2/czmq-3.0.2.tar.gz
gridlab-d - https://github.com/GRIDAPPSD/gridlab-d/tree/feature/1146
gridappsd/influxdb:2019.01.0 - https://github.com/GRIDAPPSD/gridappsd-data/tree/releases/2019.01.0
influxdb:latest - https://hub.docker.com/_/influxdb
gridappsd/blazegraph - https://github.com/GRIDAPPSD/Powergrid-Models/tree/releases/2019.01.0
lyrasis/lbazegraph:2.1.4 - https://hub.docker.com/r/lyrasis/blazegraph
gridappsd/proven - https://github.com/GRIDAPPSD/proven-docker
proven-cluster - https://github.com/pnnl/proven-cluster/tree/v1.3.3
proven-message - https://github.com/pnnl/proven-message/tree/v1.3.1
gridappsd/sample-app - https://github.com/GRIDAPPSD/gridappsd-sample-app/tree/releases/2019.01.0
gridappsd/app-container-base - (TODO: @Craig can you provide the repository?)
gridappsd/viz:2019.01.0 - https://github.com/GRIDAPPSD/gridappsd-viz/tree/releases/2019.01.0
redis:3.2.11-alpine - https://hub.docker.com/_/redis
mysql/mysql-server:5.7 - https://hub.docker.com/_/mysql
Known VPN and Proxy Issues
There are a few known issues around WSL2 and Virtualbox VM compatibility with corporate VPNs and proxies.
DNS Configuration
This issue affects the ability of the VM to reach GitHub, clone repositories, run pip install
or open any websites from the browser.
If your machine was connected to a corporate VPN during setup, the Doman Name Server (DNS) lookup address is set to that of your corporate intranet. To reset it, open an ubuntu session and edit the resolv.conf
file
sudo nano /etc/resolv.conf
comment out existing nameserver address
add new line with
nameserver 8.8.8.8
save file and restart terminal
Proxy Server Configuration
This issue affects the ability of the server to run curl
and other commands addressing various localhost
ports
To fix this, add the NO_PROXY option by running in the Ubuntu command line
export NO_PROXY="localhost,127.0.0.1,local.home,*.yourcompany.org,*.yourintranet.org"
Note: Be sure to change the proxy URLs to those of your organization.
GridAPPS-D Introduction
What is GridAPPS-D?
GridAPPS-D™ is an open-source platform that accelerates development and deployment of portable applications for advanced distribution management and operations. It is built in a linux environment using Docker, which allows large software packages to be distributed as containers.
The GridAPPS-D™ project is sponsored by the U.S. DOE’s Office of Electricity, Advanced Grid Research. Its purpose is to reduce the time and cost to integrate advanced functionality into distribution operations, to create a more reliable and resilient grid.
GridAPPS-D enables standardization of data models, programming interfaces, and the data exchange interfaces for:
devices in the field
distributed apps in the systems
applications in the control room
The platform provides
robust testing tools for applications
distribution system simulation capabilities
standardized research capability
reference architecture for the industry
application development kit
GridAPPS-D Platform Characteristics
Vendor / Vendor Platform Independent
The GridAPPS-D Platform and application development environment is independent of any specific vendor or vendor platform, in other words vendor neutral. The results of this effort are intended to be useful and available to any vendor or application developer who wishes to apply them or incorporate them into existing or future products.
Standards-based Architecture
GridAPPS-D is the first platform for energy and distribution management systems that is designed with standards for data integration, including data models, programming interfaces, and data exchange interfaces between grid devices in the field, distributed applications in utility systems, and applications in utility control rooms. This means that the applications developed using GridAPPS-D make them broadly applicable and interchangeable across utility systems, reducing the cost and time for utilities to integrate new functionality.
To the greatest extent possible, the GridAPPS-D Platform incorporates and supports industry standards, in particular interoperability standards, including the power system model representation using the Common Information Model (CIM) and communications with other platforms / physical equipment through DNP3, IEEE 2030.5, and the open field messaging bus (OpenFMB)
Replicable
As a reference implementation of a standards-based architecture, advanced applications and services developed with GridAPPS-D Platform should be replicable, with the ability to be deployed at multiple locations on different distribution feeders with almost no code customization.
Flexible Distribution Simulation
The GridAPPS-D Platform enables users to run real-time quasi-static simulations of large distribution network models with real-time load data, thermal co-simulation of houses, real-time weather data, and real-time operation of switches, DERs, and volt-var control equipment. The platform supports multiple distribution simulators through a co-simulation bridge that abstracts the simulation configuration details to a simple API.
Data Representation & Management
A key to GridAPPS-D is providing the distribution system application developer with a standardized approach to data. The intent is to allow the developer to make logical references to data referencing standard data models and interfaces without concern for how the data is physically made available. This standardized, logical data interface is based on existing standards to the greatest extent possible.
Standards-based Data Representation
The Common Information Model (CIM) is used for all power system models, which enables rapid exchange of power system models across compliant applications and services. Using the set of standardized model queries provided by the PowerGrid Models API, a GridAPPS-D application is able to scale seamlessly across different network models with no modifications to the application code.
Standards-based Data Interfaces
The GridAPPS-D Platform and GridAPPS-D APIs provide a standardized method for interfacing with power system model data, real-time simulation data, historical data, and log data. Each of these APIs abstract the database specifics, and enable simple queries through a set of standardized messages formatted as JSON strings.
Data Translation to Non-standardized Elements
CIM Hub and the Configuration File API allow conversion of the power system model data from the standards-based CIM XML format used by the GridAPPS-D Platform to model formats used by other software packages, such as GridLAB-D and OpenDSS. This model conversion process can be performed with a simple set of standardized API calls.
Available Distribution Feeders
The GridAPPS-D platform comes pre-configured with a combination of IEEE Test Feeders, PNNL Taxanomoy feeders, and other realistic synthetic models. Additional models and actual utility feeder data can be uploaded easily as CIM XML files into the GridAPPS-D Platform, which can then be used for application testing and real-time simulation.
Real-Time Distribution Simulation
The GridAPPS-D Platform inlcudes a robust real-time distribution simulator with comparable capabilities to a Dispatcher Training Simulator. This environment enables application developers to test algorithms and application code on both the standard realistic sythetic feeders pre-configured in the GridAPPS-D Platform download and any other power system models that the user can upload through the CIM Hub package.
The distribution simulator is the source of data to the distribution system application developer enabling them to evaluate the performance of their application with ideal or realistic noisy data under different operating and performance conditions.
The GridAPPS-D platform currently supports only quasi-static simulation (i.e. simulation of electromechanical / electromagnetic transients, variable microgrid island frequency, synchro-check relays, etc. are not supported currently). These types of simulations can be performed with GridLAB-D outside of the the GridAPPS-D Platform and application development environment.
Real-Time & Faster-than-Real-Time Simulation
Simulations can be run in two modes:
Real-time mode: one second of computer clock time corresponds to one second of simulation time. The GridAPPS-D Platform runs the simulation in each time and publishes simulation data and sensor measurements every three seconds.
Faster-than-real-time mode: The GridAPPS-D runs the simulation as fast as possible and does not wait for three seconds of computer clock time to pass before it publishes the simulation data from the current time step. This mode is very useful for creating historical training data sets for AI/ML applications.
Controllable Power System Equipment
All of the power system equipment can be controlled in real-time through the Simulation API, allowing applications to open/close switches, dispatch DGs / DERs, adjust setpoints of rooftop PV, adjust regulator taps, and turn capacitor banks on or off.
Noisy / Bad Data Injection & Communication Failures
The GridAPPS-D Platform supports the Sensor Simulator Service, which is able to inject noise, bad measurements, and data packet losses into the simulation output. The frequency at which sensors publish can also be adjusted and aggregated, allowing realistic representation of real sensors, such as AMI meters that publish data every 15 minutes, rather than at each simulation time step. This allows the user to train and evaluate applications with realistic measurement for meters and sensors, rather than “pure” data created by the power flow solver.
The GridAPPS-D Platform also supports simulation of communication failures through the Test Manager during which data is not received from sensors, control commands are delivered to selected equipment, or both. This enables application developers to test algorithm performance under realistic conditions, during which physical equipment might not respond to control commands.
Reconfigurable Power System Topologies
The GridAPPS-D Platform supports simulation of both meshed and radial power system topologies, as well as reconfiguration of the power system network in real-time by opening / closing / tripping of various switching devices, such as breakers, reclosers, sectionalizers, and fuses. These switches can be controlled by an application through the Simulation API or through the GridAPPS-D Viz GUI
Real-Time Simulation Visualization
The GridAPPS-D Platform includes the Viz GUI application, which presents a simple graphic user interfaces with some of the basic functionalities found in an Dispatcher Training Simulator, inlcuding a one-line diagram of the feeder, colorized switch positions, outage locations, alarm messages, and customizable stripcharts of power flow, node voltage, and tap position.
Using the GridAPPS-D Platform
GridAPPS-D currently runs in a Linux virtual machine (VM). Although it can be built from sources, the primary form of distribution is as a set of Docker containers. Users can install the Docker infrastructure on their computer and then download the Docker containers. Several platform usage scenarios are then feasible:
Start and run the application through its browser interface. Utilities could use the platform this way to evaluate new applications, or to evaluate applications on their own circuits. The App Hosting Manager allows a user to install and configure new applications to run in the platform, by modifying configuration files but without having to write new code. GridAPPS-D will also be able to ingest any distribution circuit provided in CIM format.
Write scripted scenarios and responses using the Test Manager, and run those through GridAPPS-D. This mode can be used for a more rigorous evaluation, and also for operator training.
Write a new application, using one of the open-source examples as a template. This mode should provide a faster on-ramp for application developers to develop a standards-compliant product.
DMS vendors can use the platform to develop and test their own standards-compliant interfaces. Any GridAPPS-D code may be incorporated into a commercial product, pursuant to its BSD license terms. The goal is for an application to be deployable from one platform to another, simply by moving the program file(s) and updating local configuration files.
GridAPPS-D Architecture
GridAPPS-D Architecture
GridAPPS-D offers a standards-based, open-source platform that enables rapid integration of advanced applications and services through a robust application programming interface (API).
The architecture of the development ecosystem is illustrated below.
GridAPPS-D User Roles
The GridAPPS-D platform contains several user roles with different permissions.
Currently, the permission are only implemented in the GridAPPS-D Viz. The permissions will be extended to platform authentication and API call execution in a future release.
The user roles can be associated with individual username/password logins. These are located in the GOSS core security configuration file
Admin
This role is used by internal GridAPPS-D Platform functionalities.
All permissions are granted, inlcuding
Starting, pausing, stopping, and joining simulations
Registering / deleting applications and services
Publishing and subscribing to all API communication channels
All Viz tools (Simulation Control, STOMP Client, Data Comparison, Data Browser, Application Viewer)
Managing users (future release)
Managing permissions of applications and services (future release)
Evaluator
This role is used by observers of application evaluation activities
Permissions inlcude
Joining existing simulations
STOMP Client, Data Comparison, Data Browser
Operator
This role is used by operators for application evaluation activities
Permissions inlcude
Joining existing simulations
STOMP Client, Data Comparison, Data Browser
Test Manager
This role is used to create simulations with TestManager events
Permissions inlcude
Starting, pausing, stopping, and joining simulations
All Viz tools (Simulation Control, STOMP Client, Data Comparison, Data Browser, Application Viewer)
Application
This role is used by applications to authenticate with the GridAPPS-D Platform
Permissions inlcude
Controlling parallel simulations through Simulation API
Publishing and subscribing to all API communication channels
Service
This role is used by services to authenticate with the GridAPPS-D Platform
Permissions inlcude
Controlling parallel simulations through Simulation API
Publishing and subscribing to all API communication channels
Integration with External Vendor Systems
External vendor systems are able to interface with GridAPPS-D compliant applications and services through two means.
The first is direct integration through the standards-based API and message bus. This enables products that comply with the GridAPPS-D™ platform to * reduce utility time and cost to integrate new functionality * give utilities more choice in technology providers * scale up or down for any size utility * expand market opportunities for developers and vendors
The second method is through the standards-based services, such as the DNP3 service, IEEE 2030.5 service, etc. that enable communication between GridAPPS-D compliant applications and external vendor systems through SCADA and other control center protocols.
GridAPPS-D Applications
The GridAPPS-D platform and API enable rapid development of advanced power applications that are able to operate in a real-time environment and interface with external software and systems. Multiple power applications have already been developed on the platform, including
Volt-Var Optimization (VVO)
Fault Location Isolation and Service Restoration (FLISR)
Distributed Energy Resource Dispatch and Management (DERMS)
Solar Forecasting, Load Forecasting, etc.
and more
Applications can be containerized in Docker for direct integration into the platform or interface through the API. Applications can be written in any programming language, but API libraries are currently available in only Python and Java.
GridAPPS-D Services
The GridAPPS-D platform can host a multitude of services for processing both real-time simulation and control center data. These services can be called by any application through the GridAPPS-D API.
Some of the available services include
State Estimator
Sensor Simulator
Alarm Service
DNP3 Protocol Service
IEEE 2030.5 Protocol Service
GridAPPS-D Application Programming Interface
GridAPPS-D offers a unique standards-based application programming interface (API) that will be the focus of the lessons in this set of tutorials. The API enables any application, service, or external vendor product to interface with each other, access control center data, run a real-time simulation, and issue equipment control commands.
GridAPPS-D has several APIs to serve different needs and objectives, inlcuding * Powergrid Models API – Allows apps and services to access the power system model data * Configuration File API – Allows apps to set equipment statuses and system conditions * Simulation API – Allows apps to start a real-time simulation and issue equipment commands * Timeseries API – Allows apps to pull real-time and historical data * Logging API – Allows apps to access logs and publish log messages
Additional APIs are currently under development to enable communication and control of field devices, as well as cyber-physical network co-simulation.
GOSS Message Bus
One of the unique features of GridAPPS-D is the GOSS Message Bus, which enables integration and communication between applications, services, and external software on a publish-subscribe basis.
The GridAPPS-D platform publishes SCADA and simulation data, alarms, and other real-time data. Applications subscribe to the types of messages relevant to their objectives and publish equipment commands and control settings.
GridAPPS-D Core Services
“Under the hood” of the GridAPPS-D platform are the core services and managers.
An application developer should not need a detailed understanding of the core services, as all interaction is performed through the various APIs, which will be dicussed in detail in the upcoming tutorial lessons.
The core services provide the key functionality offered by the GridAPPS-D platform, inlcuding database access, processing API calls, handling equipment commands, and running simulations.
Some of the core services included in the GridAPPS-D platform are * Platform Manager – Coordinates all of the other managers * Process Manager – Coordinates platform component interactions * Application Manager – Manages application registration, execution, and status reporting * Configuration Manager – Manages the setup and configuration of real-time simulations * Simulation Manager – Allows users and apps to create, start, stop, and pause co-simulations * Data Manager – Coordinates the integrated repository of model, timeseries data, and metadata * Model Manager – Loads and checks CIM-based power system models * Logging Manager – Supports logging for application development and execution * Services Manager – Coordinates all services available for users and apps * Test Manager – Enables creation of simulation events, faults, and network outages
Co-Simulation Framework
The co-simulation framework serves as the simulation context for the rest of GridAPPS-D. When a simulation is requested through the GridAPPS-D plaform the simulation manager instantiates a FNCS or HELICS co-simulation federation consisting of two applications. The first application is a powerflow simulator which can be either GridLAB-D or OpenDSS that simulates real world distribution feeder or feeders. The second is a custom application that serves as bridge between the FNCS/HELICS message bus and the GOSS message bus. The data that travels between the co-simulation federation and the rest of the platform are SCADA measurement, SCADA control, and simulation status and control messages.The bridge application subscribes to the simulation input topic to recieve any SCADA control, simulation control, and simulation event messages. The bridge forwards SCADA control commands and simulation events like faults and outages to the powerflow simulator. The bridge publishes SCADA measurements from the powerflow simulator on a simulation output topic that GridAPPS-D applications and other parts of the GridAPPS-D platform subscribe to.
Database Structures
Default installation of GridAPPS-D comes with following data stores:
MySQL: It is used to store log data from platform, applications and services. For details, please see Logging API, which is covered in detail in Lesson 2.7.
Blazegraph: It is used to store power grid model data. The data contains equipments, properties and their initial measurement values. It is a triplestore that supports complex graph representation and class structure for CIM standard data model.
InfluxDB: InfluxDB is a time series data store and is used to store simulation output, simulation input, weather and load data. It also store output from services line sensor service and alarms service. For the purposes of the GridAPPS-D project, InfluxDB is managed by Proven. Proven is a database software suite supporting disclosure, collection, and management of modeling and simulation data.
For the purpose of developing applications, the data stores used should be transparent to the application as long the data model and standardized API is used.
GridAPPS-D Python Library
Intro to GridAPPSD-Python
GridAPPSD-Python is a Python library that wrapa API calls and passes them to the various GridAPPS-D APIs through the GOSS Message Bus.
The library has numerous shortcuts to help you develop applications faster and interface them with other applications, services, and GridAPPS-D compatible software packages.
The GridAPPSD-Python library requires a python version >= 3.6 and < 4 in order to work properly. (Note: no testing has been done with python 4 to date).
The GridAPPSD-Python library can be installed using pip install gridappsd-python
.
For more information, see the GridAPPSD-Python GitHub Repo and PyPi site.
Connecting to GridAPPS-D Platform
Before starting any development in the GridAPPS-D environment, it is necessary to establish a connection to the GridAPPS-D Platform.
Specifying Environment Variables (Preferred)
The preferred method for establishing a connection with the GridAPPS-D Platform is to define a set of environment variables that specify the connection address, port, username, and password.
Specifying the Environment Variables in Python Script
This method is recommended for initial application development when running in a development environment, such as PyCharm or the Jupyter Notebook tutorials.
[ ]:
# Establish connection to GridAPPS-D Platform:
from gridappsd import GridAPPSD
import os # Set username and password
os.environ['GRIDAPPSD_USER'] = 'tutorial_user'
os.environ['GRIDAPPSD_PASSWORD'] = '12345!'
os.environ['GRIDAPPSD_ADDRESS'] = 'localhost'
os.environ['GRIDAPPSD_PORT'] = '61613'
# Connect to GridAPPS-D Platform
gapps = GridAPPSD()
assert gapps.connected
Specifying the Environment Variable in ~/.bashrc Script
This method is recommended for more complete applications scripts where all the application scripts are called from a single ~/.bashrc script. In that script, the environment variables can be defined and then will be available to all scripts that need to connect the GridAPPS-D Platform.
# export allows all processes started by this shell to have access to the global variable
# address where the gridappsd server is running - default localhost
export GRIDAPPSD_ADDRESS=localhost
# port to connect to on the gridappsd server (the stomp client port)
export GRIDAPPSD_PORT=61613
# username to connect to the gridappsd server
export GRIDAPPSD_USER=app_user
# password to connect to the gridappsd server
export GRIDAPPSD_PASSWORD=1234App
# Note these should be changed on the server in a cyber secure environment!
Specifying Connection Parameters Manually
An older method of connecting to the GridAPPS-D Platform is manually specifying the connection parameters. This method is still supported, but may be deprecated in future releases.
This method is less flexible and has an in-built portability issues associated with hard-coded platform passwords.
[ ]:
gapps = GridAPPSD("('localhost', 61613)", username='system', password='manager')
GridAPPSD-utils Deprecated
GridAPPS-D Platform releases prior to 2021 used a library called utils
to establish a connection with the platform. This library has been deprecated and replaced with Java Token Authentication using the environment variable method shown above.
The authentication method below will work with 2019-2020 versions of the GridAPPS-D Platform and GridAPPSD-Python, but not with any newer releases.
# DEPRECATED authentication method
from gridappsd import GridAPPSD, utils
gapps = GridAPPSD(address=utils.get_gridappsd_address(),
username=utils.get_gridappsd_user(), password=utils.get_gridappsd_pass())
utils
– DEPRECATED A set of utilities to assist with common commands, inlcuding
utils.validate_gridappsd_uri()
– Checks if GridAPPS-D is hosted on the correct portutils.get_gridappsd_address()
– Returns the platform address such that response can be passed directly to a socket or the STOMP libraryutils.get_gridappsd_user()
– Returns the login usernameutils.get_gridappsd_pass()
– Returns the login passwordutils.get_gridappsd_application_id()
– Only applicable if the environment variable ‘GRIDAPPSD_APPLICATION_ID’ has been setutils.get_gridappsd_simulation_id()
– Retrieves the simulation id from the environment.
It is strongly recommended that applications that previously used this method replace any connection objects with environment variables to ensure compatibility with subsequent releases of the GRIDAPPS-D platform
Passing API calls with GridAPPSD-Python
There are three methods used in GridAPPSD-Python Library to pass API calls to the GridAPPS-D platform:
.get_response(self, topic, message, timeout)
– Pass a database query, response expected before timeout.subscribe(self, topic, callback)
– Subscribe to a data stream.send(self, topic, message)
– Send a command to a simulation, no response expected
Each are explained in more detail below
.get_response(topic, message)
This is the most commonly used method for passing API calls to the GridAPPS-D Platform. This method is used when a response is expected back from the GridAPPS-D platform within a particular timeout period. It is used for all database queries using
PowerGrid Models API – queries for model info, object mRIDs, measurement mRIDs
Configuration File API – queries to convert the model into other file format versions
Timeseries API – queries for weather data and historical data from prior simulations
The syntax used when calling this method is gapps.get_response(topic, message)
or alternatively, gapps.get_response(topic, message, timeout = 30)
, where
topic
is the GridAPPS-D topic for the particular API (as described in API Communication Channels.message
is the query message specifying what information the API should returntimeout =
is optional and gives the number of seconds given for the API to respond. Model conversion queries using the Configuration File API may take 30 - 60 seconds for very large models. Most other queries do not need a timeout specification.
.subscribe(topic, message)
This method is used for subscribing to the real-time data stream generated by the GridAPPS-D platform while running a simulation. It is used to subscribe to information published at each time step by the
Simulation API – simulated SCADA data and measurements created by the simulation
Logging API – log messages published by the Platform, applications, and simulation
The .subscribe()
method is also used to subscribe to streaming data generated by some of the GridAPPS-D services.
The syntax used when calling this method is gapps.subscribe(topic, message)
, where
topic
is the GridAPPS-D simulation output topic, log output topic, or service output topic for the particular real-time data stream the application needs to subscribe to, (as described in API Communication Channels.message
is the subscription message. For simulation and log outputs, it is a method or class definition, as described in Comparison of Subscription Approaches.
.send(topic, message)
This method is used for sending equipment command and simulation input messages to the GridAPPS-D platform while running a simulation. It is used to send difference messages to the Simulation API and for other generic publishing needs, such as sending a command input to a GridAPPS-D Service.
The syntax used when calling this method is gapps.send(topic, message)
, where
topic
is the simulation or service input topic(as described in API Communication Channels.message
is the API call message to be published. The most commonly used simulation input message is a Difference Message used to control equipment settings.
.unsubscribe(conn_id)
This method is used to unsubscribe from a simulation or service that was previously subscribed to using the .subscribe
method.
The syntax of this method is gapps.unsubscribe(conn_id)
, where conn_id
is the connection id obtained when previously subscribing using the conn_id = gapps.subscribe(topic, message)
.
Importing Required Python Libraries
A typical GridAPPS-D application will require several libraries to be imported from GridAPPSD-Python as well as from other Python libraries.
Required GridAPPS-D Libraries
The GridAPPS-Python API contains several libraries, which are used to query for information, subscribe to measurements, and publish commands to the GOSS message bus. These inlcude
GridAPPSD
– This is the primary library that contains numerous methods for passing API calls, connecting to the GridAPPS-D platform, and other common taskstopics
– This library contains methods for constructing the correct API channel stringsSimulation
– This library contains shortcut methods for subscribing and controlling simulationsLogger
– This library contains logging methods. It is recommended to invoke those methods using thegapps.get_logger
method rather than importing the libraryGOSS
– This library contains methods for passing API calls to the GOSS Message Bus. It is imported automatically when importing theGridAPPSD
libraryHouses
– This library populates a feeder with thermal house model loads. It is imported automatically when importing theGridAPPS
libraryutils
– Deprecated
Each of the libraries can be imported using from gridappsd import library_name
. For example,
[ ]:
from gridappsd import GridAPPSD
[ ]:
from gridappsd import topics as t
Each of the libraries are discussed in detail in the next section.
Other Required Python Libraries
Below is a list of some of the additional libraries that you may need to import.
You may not need all of these additional libraries, depending on the needs of your application
argparse
– This is the recommended command-line parsing module in Python.(Online Documentation)json
– Encoder and decoder for JavaScript Object Notation (JSON). (Online Documentation)logging
– This module defines classes and functions for event logging. (Online Documentationsys
– Python module for system specific parameters. (Online Documentation)time
– Time access and conversions. (Online Documentation)pytz
– Library to enable resolution of cross-platform time zones and ambiguous times. (Online Documentationstomp
– Python client for accessing messaging servers using the Simple Text Oriented Messaging Protocol (STOMP). (Online Documentation)os
– Miscellaneous operating system interface. Needed to set environment variables for the GridAPPS-D connection if working from a single Python script or notebook. (Online Documentation)
[ ]:
import argparse
import json
import logging
import sys
import time
import pytz
import stomp
import os
GridAPPSD-Python GridAPPSD Library
This library contains the most commonly used methods needed for building GridAPPS-D applications and services.
All of these methods are for the GridAPPS-D connection object defined using gapps = GridAPPSD()
Get Methods
This group of methods are used to get information and statuses about the GridAPPS-D platform and simulations:
.get_application_status()
– Returns the current status of an application.get_application_id()
– Returns the unique ID of an application registered with the Platform.get_houses()
– Returns houses populated in the feeder.get_logger()
– Returns a log instance for interacting with logs within the Platform.get_platform_status()
– Returns the current status of the Platform.get_service_status()
– Returns the current status of a service.get_simulation_id()
– Returns the simulation ID for the current GridAPPSD connection
Set / Send Methods
This group of methods are used to set the status of applications and services:
.set_application_status()
– Set the status of an application.set_service_status()
– Set the status of a service.set_simulation_id(simulation_id)
– Set the simulation ID if none is defined.send_simulation_status(status, message, log_level)
– Sets simulation + service status and writes to GridAPPS-D logs.send_status(status, message, log_level)
– Sets application status and writes to GridAPPS-D logs
PowerGrid Models API Methods
This group of methods run pre-built PowerGrid Models API queries for simpler query types:
query_data(query, timeout)
– Run a generic SPARQL Queryquery_model(model_id, object_type, object_id)
– Query using full CIM100 prefixquery_model_info()
– Query for dictionary of all modelsquery_model_names(model_id)
– Query for mRIDs of all modelsquery_object(object_id, model_id)
– Query for CIM attributes of an objectquery_object_dictionary(model_id, object_type, object_id)
– Query for object dictionaryquery_object_types(model_id)
– Query for CIM classes in a model
GridAPPSD-Python Topics Library
The GridAPPSD-Python topics library is used to obtain the correct API Communication Channel, which tells the GridAPPS-D platform to which database, application, or simulation a particular API call should be delivered.
Static GridAPPS-D topics (such as those for the PowerGrid Models API, Configuration File API, and Timeseries API) can be imported using
[ ]:
from gridappsd import topics as t
Dynamic GridAPPS-D topics (such as those for the Simulation API and various GridAPPS-D services) can be imported using
[ ]:
from gridappsd.topics import simulation_output_topic
[ ]:
from gridappsd.topics import simulation_input_topic
[ ]:
from gridappsd.topics import simulation_log_topic
Each of the specific methods available in the topics
library are discussed in detail in API Communication Channels.
GridAPPSD-Python Simulation Library
The GridAPPSD-Python simulation library is used for starting, running, and controlling parallel digital twin simulations. For more details on specific usage, see
The Simulation library can be imported using
[ ]:
from gridappsd.simulation import Simulation
Available methods in the Simulation
library are
.start_simulation()
– Start the simulation.pause()
– Pause the simulation.resume()
– Resume the simulation.resume_pause_at(pause_time)
– Resume the simulation, and then pause it in so many seconds.stop()
– Stop the simulation.run_loop()
– Loop the entire simulation until interrupted.simulation_id
– Returns the Simulation ID of the simulation.add_ontimestep_callback(myfunction1)
– Run the desired function on each timestep.add_onmesurement_callback(myfunction2)
– Run the desired function when a measurement is received..add_oncomplete_callback(myfunction3)
– Run the desired function when simulation is finished.add_onstart_callback(myfunction4)
– Run desired function when simulation is started
Note: method name ``.add_onmesurement`` is misspelled in the library definition!!
GridAPPSD-Python DifferenceBuilder
DifferenceBuilder
is a GridAPPSD-Python library that is used to create and correctly format difference messages that used to create equipment control commands. The usage of difference builder is given in Using DifferenceBuilder.
The DifferenceBuilder
library can be imported using
[ ]:
from gridappsd import DifferenceBuilder
my_diff_build = DifferenceBuilder(simulation_id)
GridAPPS-D Application Structure
Application Structure
The structure of a GridAPPS-D application can be broken into nine sections:
Querying for the power system model
Querying for measurement MRIDs
Querying for weather data (if needed)
Configuring parallel simulations (if needed)
App core algorithm & measurement processing
Subscribing to simulation output
Publishing equipment commands
Querying historical & timeseries data
Subscribing and publishing to logs
Each of these task sections within an application are explained below with sample code that can interact with a simulation running on the GridAPPS-D platform.
Connecting to GridAPPS-D Platform
Prior to running any of the API calls or other core application code, the application needs to establish a secure connection with the GridAPPS-D platform.
[ ]:
# Import GridAPPSD-Python Library:
from gridappsd import GridAPPSD
# When developing locally, paste Simulation ID into this variable
# When running inside docker, this is passed automatically by platform
viz_simulation_id = "242488458"
# Simulation running on IEEE 123 node model:
model_mrid = "_C1C3E687-6FFD-C753-582B-632A27E28507"
[ ]:
# Set environment variables - when developing, put environment variable in ~/.bashrc file or export in command line
# export GRIDAPPSD_USER=system
# export GRIDAPPSD_PASSWORD=manager
import os # Set username a
os.environ['GRIDAPPSD_USER'] = 'tutorial_user'
os.environ['GRIDAPPSD_PASSWORD'] = '12345!'
# Connect to GridAPPS-D Platform
gapps = GridAPPSD(viz_simulation_id)
assert gapps.connected
Querying for the Power System Model
The first portion of a GridAPPS-D application is series of queries to the PowerGrid Models API to obtain information about the power system model.
Because GridAPPS-D applications are designed to be portable across numerous power system models without any code modification, the application must query the Blazegraph database and create a set of local variables that contain the information needed by the app to run its internal code.
An application will query for the various pieces of power system equipment relevant to its objective (e.g. a VVO app will be interested in regulators and capacitors, while a FLISR app will be interested in switches and reclosers present in the model). The query will typically include requests for information about the names, location, mRIDS, and electrical parameters for the various pieces of equipment needed by the application..
Model Query Information flow
The figure below shows the information flow involved in making a query for the power system model.
The query is sent using gapps.get_response(topic, message)
on a queue channel (explained in API Communication Channels) with a response expected back from the platform within the specified timeout period.
Application passes query to GridAPPS-D Platform
First, the application creates a query message for requesting information about the desired power system components in the format of a JSON string or equivalant Python dictionary object. The syntax of this message is explained in detail in Using the PowerGrid Models API.
The application then passes the query through the PowerGrid Models API to the GridAPPS-D Platform, which publishes it to a queue channel on the GOSS Message Bus. If the app is authenticated and authorized to pass queries, the query message is delivered to the data managers, which obtain the desired information from the Blazegraph Database.
GridAPPS-D Platform responds to Application query
The data managers then publish the response from the Blazegraph Database to the appropriate queue channel. The PowerGrid Models API then returns the desired information back to the application as a JSON message or equivalant Python dictionary object.
Model Query Sample App Code
Below is a sample query of how the application will use the PowerGrid Models API to query for the details associated for all the switches in the feeder.
[ ]:
from gridappsd import topics as t
message = {
"modelId": model_mrid,
"requestType": "QUERY_OBJECT_DICT",
"resultFormat": "JSON",
"objectType": "LoadBreakSwitch"
}
response_obj = gapps.get_response(t.REQUEST_POWERGRID_DATA, message)
switch_dict = response_obj["data"]
# Filter to get mRID for switch SW2:
for index in switch_dict:
if index["IdentifiedObject.name"] == 'sw2':
sw_mrid = index["IdentifiedObject.mRID"]
print(switch_dict[0]) # Print dictionary for first switch
print('mRID of sw2 is ',sw_mrid)
Querying for Measurement mRIDs
The next portion of a GridAPPS-D application is series of queries to the PowerGrid Models API to obtain information about the measurements associated with various pieces of equipment the application is interested in. Due to structure of the Common Information Model (introduced in Intro to Common Information Model), there exist a separate set of objects associated with the positive-neutral-voltage (PNV), volt-ampere (VA), and position measurements (POS) for each line, transformer, switch, etc.
Because GridAPPS-D applications are designed to be portable across numerous power system models without any code modification, the application must query the Blazegraph Database and create a set of local variables that contain the unique mRIDS of each measurement needed by the app to run its internal code. In a subsequent step, the app will use these measurement mRIDs to subscribe to the live streaming data issued by the simulation.
Measurement Query Information Flow
The figure below shows the information flow involved in making a query for the power system model.
The query is sent using gapps.get_response(topic, message)
on a queue channel (explained in API Communication Channels) with a response expected back from the platform within the specified timeout period.
The figure below shows the information flow involved in making a query for the power system model.
Application passes query to GridAPPS-D Platform
First, the application creates a query message for requesting information about the desired power system components in the format of a JSON string or equivalant Python dictionary object. The syntax of this message is explained in detail in Using PowerGrid Models API.
The application then passes the query through the PowerGrid Models API to the GridAPPS-D Platform, which publishes it to a queue channel on the GOSS Message Bus. If the app is authenticated and authorized to pass queries, the query message is delivered to the data managers, which obtain the desired information from the Blazegraph Database.
GridAPPS-D Platform responds to Application query
The data managers then publish the response from the Blazegraph Database to the appropriate queue channel. The PowerGrid Models API then returns the desired information back to the application as a JSON message or equivalant Python dictionary object.
Measurement Query Sample App Code
Below is a sample query of how the application will use the PowerGrid Models API to query for the measurement mRIDs of all switches in the power system model
[ ]:
message = {
"modelId": model_mrid,
"requestType": "QUERY_OBJECT_MEASUREMENTS",
"resultFormat": "JSON",
"objectType": "LoadBreakSwitch"
}
response_obj = gapps.get_response(t.REQUEST_POWERGRID_DATA, message) # Pass query to PowerGrid Models API
measurements_obj = response_obj["data"]
global Pos_obj # Define global python dictionary of position measurements
Pos_obj = [k for k in measurements_obj if k['type'] == 'Pos'] # Filter measurements to just switch positions
print(Pos_obj[0]) # Print switch position measurement mRID for first switch
Querying for Weather Data
The next portion of a GridAPPS-D application is series of queries to the Timeseries API to obtain information about the weather data for the current time, including irradiation, temperature, etc. This information can be used for solar forecasting, load forecasting, etc.
Because GridAPPS-D applications are designed to be portable across numerous power system models without any code modification, the application must query the Timeseries Influx Database and create a set of local variables that contain the weather data needed by the app to run its internal code.
Weather Query Information Flow
The figure below shows the information flow involved in making a query for the power system model.
The query is sent using gapps.get_response(topic, message)
on the Timeseries queue channel (explained in API Communication Channels) with a response expected back from the platform within the specified timeout period.
Application passes query to GridAPPS-D Platform
First, the application creates a query message for requesting information about the desired power system components in the format of a JSON string or equivalant Python dictionary object. The syntax of this message is explained in detail in Using the Timeseries API.
The application then passes the query through the Timeseries API to the GridAPPS-D Platform, which publishes it to a queue channel on the GOSS Message Bus. If the app is authenticated and authorized to pass queries, the query message is delivered to the Data Managers, which obtain the desired information from the Timeseries Influx Database.
GridAPPS-D Platform responds to Application query
The Data Managers then publish the response from the Timeseries Influx Database to the appropriate queue channel. The Timeseries API then returns the desired information back to the application as a JSON message or equivalant Python dictionary object.
Weather Query Sample App Code
Below is a sample query to the Timeseries API requesting all weather data between a certain startTime and endTime (given in unix absolute time). The application can then use that weather data to feed its internal forecasting algorithm.
[ ]:
# Use queryFilter of "startTime" and "endTime"
message = {
"queryMeasurement":"weather",
"queryFilter":{"startTime":"1357048800000000",
"endTime":"1357048860000000"},
"responseFormat":"JSON"
}
response_obj = gapps.get_response(t.TIMESERIES, message) # Pass query to Timeseries API
weather_obj = response_obj["data"]
print(weather_obj[1]) # Print first line of weather data
Configuring a Parallel Simulation
Some applications may choose to run parallel simulations (similar to a digital twin), either within the GridAPPS-D platform or by exporting the model to OpenDSS, GridLAB-D, etc. This is accomplished through one or more queries to the Configuration File API to create a simulation configuration file and/or exported power system model.
The simulation configuration file contains all the necessary info to create a new simulation, including the power system model, date/time, and variations from the default basecase (i.e. re-dispatched DERs and switches that have been opened/closed).
The exported power system model is the entire model as a set of GLM or DSS that can be saved to an external file and then solved with a different power flow solver outside of the GridAPPS-D Platform.
Configuration Query Information Flow
The figure below shows the information flow involved in making a query for the power system model.
The query is sent using gapps.get_response(topic, message)
on the Configuration File queue channel (explained in API Communication Channels) with a response expected back from the platform within the specified timeout period.
Application passes query to GridAPPS-D Platform
First, the application creates a query message for requesting information about the desired power system configuration in the format of a JSON string or equivalant Python dictionary object. The syntax of this message is explained in detail in Using the Configuration File API
The application then passes the query through the Configuration File API to the GridAPPS-D Platform, which publishes it to a queue channel on the GOSS Message Bus. If the app is authenticated and authorized to pass queries, the query message is delivered to the Configuration Manager.
GridAPPS-D Platform responds to Application query
The Configuration Manager obtains the CIM XML file for the desired power system model and then converts it to the desired output format with all of the requested changes to the model. The Configuration File API then returns the desired information back to the application as a JSON message (for Y-Bus or partial models) or export the files to the directory specified in the
Configuration Query Sample App Code
Below is a sample query showing how an application would make a query through the Configuration File API to change all loads to constant current loads, convert the power system model to a set of OpenDSS files, and export them to the directory /tmp/dsssimulation
.
[ ]:
topic = "goss.gridappsd.process.request.config"
message = {
"configurationType": "DSS All",
"parameters": {
"directory": "/tmp/dsssimulation/",
"model_id": model_mrid,
"simulation_id": "12345678",
"simulation_name": "ieee123",
"simulation_start_time": "1518958800",
"simulation_duration": "60",
"simulation_broker_host": "localhost",
"simulation_broker_port": "61616",
"schedule_name": "ieeezipload",
"load_scaling_factor": "1.0",
"z_fraction": "0.0",
"i_fraction": "1.0",
"p_fraction": "0.0",
"solver_method": "NR" }
}
gapps.get_response(topic, message)
Processing Measurements & App Core Algorithm
The next portion of a GridAPPS-D application is the measurement processing and core algorithm section. This section is built as either a class or function definition with prescribed arguments. Each has its advantages and disadvantages:
The function-based approach is simpler and easier to implement. However, any parameters obtained from other APIs or methods to be used inside the function currently need to be defined as global variables.
The class-based approach is more complex, but also more powerful. It provides greater flexibility in creating additional methods, arguments, etc.
App Core Information Flow
This portion of the application does not communicate directly with the GridAPPS-D platform.
Instead, the next part of the GridAPPS-D application (Subscribing to Simulation Output) delivers the simulated SCADA measurement data to the core algorithm function / class definition. The core algorithm processes the data to extract the desired measurements and run its optimization / control agorithm.
No message from core algorithm to GridAPPS-D Platform
The core algorithm does not send any API messages to the platform
No response to core algorithm from GridAPPS-D Platform
The core algorithm receives its measurement data and other imputs from the subscription object defined next, rather than directly from the GridAPPS-D platform.
App Core Sample App Code
Below is a very simple core algorithm that determines the number of open switches in the model and prints the result for each simulation timestep. The syntax of the function / class definition is described in detail in
[ ]:
def demoSubscription1(header, message):
# Extract time and measurement values from message
timestamp = message["message"]["timestamp"]
meas_value = message["message"]["measurements"]
meas_mrid = list(meas_value.keys()) #obtain list of all mrid from message
# Filter to measurements with value of zero
open_switches = []
for index in Pos_obj:
if index["measid"] in meas_value:
mrid = index["measid"]
power = meas_value[mrid]
if power["value"] == 0:
open_switches.append(index["eqname"])
# Print message to command line
print("............")
print("Number of open switches at time", timestamp, ' is ', len(set(open_switches)))
Subscribing to Simulation Output
The next portion of a GridAPPS-D application is series of queries to the Timeseries API to obtain information about the weather data for the current time, including irradiation, temperature, etc. This information can be used for solar forecasting, load forecasting, etc.
Because GridAPPS-D applications are designed to be portable across numerous power system models without any code modification, the application must query the Timeseries Influx Database and create a set of local variables that contain the weather data needed by the app to run its internal code.
Simulation Subscription Information Flow
The figure below shows the information flow involved in subscribing to the simulation output.
The subscription request is sent using gapps.subscribe(topic, class/function object)
on the specific Simulation topic channel (explained in API Communication Channels). No immediate response is expected back from the platform. However, after the next simulation timestep, the Platform will continue to deliver a complete set of measurements back to the application for each timestep until the end of the simulation.
Application passes subscription request to GridAPPS-D Platform
The subscription request is perfromed by passing the app core algorithm function / class definition to the gapps.subscribe
method. The application then passes the subscription request through the Simulation API to the topic channel for the particular simulation on the GOSS Message Bus. If the application is authorized to access simulation output, the subscription request is delivered to the Simulation Manager.
GridAPPS-D Platform delivers published simulation output to Application
Unlike the previous queries made to the various databases, the GridAPPS-D Platform does not provide any immediate response back to the application. Instead, the Simulation Manager will start delivering measurement data back to the application through the Simulation API at each subsequent timestep until the simulation ends or the application unsubscribes. The measurement data is then passed to the core algorithm class / function, where it is processed and used to run the app’s optimization / control algorithms.
Simulation Subscription Sample App Code
Below is an example of how an application subscribes to the GridAPPS-D simulation output using the function or class definition created as part of the Measurement Processing / App Core
[ ]:
from gridappsd.topics import simulation_output_topic
output_topic = simulation_output_topic(viz_simulation_id)
gapps.subscribe(output_topic, demoSubscription1)
Publishing Equipment Commands
The next portion of a GridAPPS-D App is publishing equipment control commands based on the optimization results or objectives of the app algorithm.
Depending on the preference of the developer, this portion can be a separate function definition, or included as part of the main class definition as part of the Measurement Processing / App Core class definition described earlier.
Equipment Command Information Flow
The figure below outlines information flow involved in publishing equipment commands to the simulation input.
Unlike the various queries to the databases in the app sections earlier, equipment control commands are passed to the GridAPPS-D API using the gapps.send(topic, message)
method. No response is expected from the GridAPPS-D platform.
If the application desires to verify that the equipment control command was received and implemented, it needs to do so by 1) checking for changes in the associated measurements at the next timestep and/or 2) querying the Timeseries Database for historical simulation data associated with the equipment control command.
Application sends difference message to GridAPPS-D Platform
First, the application creates a difference message containing the current and desired future control point / state of the particular piece of power system equipment to be controlled. The difference message is a JSON string or equivalant Python dictionary object. The syntax of a difference message is explained in detail in Publishing Equipment Commands.
The application then passes the query through the Simulation API to the GridAPPS-D Platform, which publishes it on the topic channel for the particular simulation on the GOSS Message Bus. If the app is authenticated and authorized to control equipment, the difference message is delivered to the Simulation Manager. The Simulation Manager then passes the command to the simulation through the Co-Simulation Bridge (either FNCS or HELICS).
No response from GridAPPS-D Platform back to Application
The GridAPPS-D Platform does not provide any response back to the application after processing the difference message and implementing the new equipment control setpoint.
Equipment Command Sample App Code
Below is an example of an app code block
[ ]:
import time
from gridappsd import DifferenceBuilder
from gridappsd.topics import simulation_input_topic
input_topic = simulation_input_topic(viz_simulation_id)
my_open_diff = DifferenceBuilder(viz_simulation_id)
my_open_diff.add_difference(sw_mrid, "Switch.open", 1, 0) # Open switch given by sw_mrid
open_message = my_open_diff.get_message()
my_close_diff = DifferenceBuilder(viz_simulation_id)
my_close_diff.add_difference(sw_mrid, "Switch.open", 0, 1) # Close switch given by sw_mrid
close_message = my_close_diff.get_message()
while True:
time.sleep(5)
gapps.send(input_topic, open_message)
time.sleep(5)
gapps.send(input_topic, close_message)
Viewing Application Results in GridAPPS-D Viz
Return to the browser tab in which the GridAPPS-D Simulation is currently running. Switch sw5
will now be opening and closing every 5 seconds, with the downstream portion of the feeder being de-energized and reconnected with each switch operation.
The core application algorithm will also reflect this with the printed response alternating between two and three open switches every few timesteps.
Querying Historical & Timeseries Data
The next portion of a GridAPPS-D application is querying historical data from the current and/or previous simulations.
All simulation output and commands from the current and previous simulations are stored in the Timeseries Database, and can be queried to provide AI/ML training data, verify processing of equipment commands, or
Note that Timeseries Database data is cleared when the GridAPPS-D Platform is shut down with the ./stop.sh script. It is recommended to copy historical / training data to an external persistent directory using the docker cp
command, as given in Docker Shortcuts.
Historical Data Query Information Flow
The figure below outlines the information flow involved in querying for historical and timeseries data.
The query is sent using the gapps.get_response(topic, message)
method on the Timeseries queue channel with a response expected back from the GridAPPS-D platform within the specified timeout period.
Application passes query to GridAPPS-D Platform
First, the application creates a query message for requesting information about the desired power system components in the format of a JSON string or equivalant Python dictionary object. The syntax of this message is explained in detail in Querying Timeseries Data.
The application then passes the query through the Timeseries API to the GridAPPS-D Platform, which publishes it to a queue channel on the GOSS Message Bus. If the app is authenticated and authorized to pass queries, the query message is delivered to the Data Managers, which obtain the desired information from the Timeseries Influx Database.
GridAPPS-D Platform responds to Application query
The Data Managers then publish the response from the Timeseries Influx Database to the appropriate queue channel. The Timeseries API then returns the desired information back to the application as a JSON message or equivalant Python dictionary object.
Historical Data Query Sample App Code
[ ]:
import time
start_time = str(int(time.time())-10) # Start query from 10 sec ago
end_time = str(int(time.time()))
# Query for a particular set of measurments
message = {
"queryMeasurement": "simulation",
"queryFilter":{"simulation_id": simulation_id,
"startTime": start_time,
"endTime": end_time,
"measurement_mrid": pos_obj},
"responseFormat":"JSON"
}
gapps.get_response(t.TIMESERIES, message) # Pass API call
Subscribing and Publishing to Logs
The last portion of an application is subscribing and publishing to logs. This step is extremely useful for 1) informing end users of application behavior and 2) application debugging during development and demonstration.
The GridAPPS-D Logging API provides an extension of the standard Python logging library and enables applications to subscribe to real-time log messages from a simulation, query previously logged messages from the MySQL database, and publish messages to their either own log or their GridAPPS-D logs.
Logging Information Flow
The figure below shows the information flow involved in subscribing and publishing to logs.
Log Message Sample App Code
[ ]:
from gridappsd.topics import simulation_log_topic
log_topic = simulation_log_topic(viz_simulation_id)
def demoLogFunction(header, message):
timestamp = message["timestamp"]
log_message = message["logMessage"]
print("Log message received at timestamp ", timestamp, "which reads:")
print(log_message)
print("........................")
gapps.subscribe(log_topic, demoLogFunction)
GridAPPS-D Service Structure
[ ]:
Introduction to the Common Information Model
This section introduces the CIM as a model format that is used for power system data and information exchange across applications, platforms, and services. The CIM is used for all power system models in GridAPPS-D, and it is important to have an understanding of the concepts and implementation of CIM for describing power systems using unique mRIDs for each piece of equipment and associated modeling objects.
Introduction
What is the Common Information Model?
The Common Information Model (CIM) is an abstract information model that can be used to model an electrical network and the various equipment used on the network.
CIM is widely used for data exchange of bulk transmission power systems, and is now beginning to find increasing use for distribution modeling and analysis.
By using a common model, utilities, vendors, and researches from both academia and industry can reduce the effort and cost of data integration, and instead focus on developing increased functionality for managing and optimizing the smart grid of the future.
Why is Data Integration Important?
In a typical distribution utility there are hundreds and even in some cases thousands of software solutions and applications that are managed by the IT department. These applications are used and operated independently by the various groups, departments, and organizations within the utility. Whenever a business process requires data from one system or application to be transferred to another system or application, the data needs to be manually extracted from the first database and then converted to the format of the other application’s database.
Two strategies exist for dealing with extreme level of effort needed to manage, update, export, convert, and import data formats between different applications and databases.
Reduce the number of databases by purchasing a large software suite from a single vendor using a single proprietary data format that is internally-integrated and compatible with all the applications needed by utility
Adopt a common data integration platform that allows external integration between multiple software packages using a shared data format
What does CIM Provide?
CIM is an information model, that is an abstract, formal representation of objects, their attributes, the relationships between them, and the operations that can be performed on them. It is NOT a database structure or physical data store. It is a technology-agnostic model for describing the properties of physical power system equipment, power flow data, and messages that can be exchanged between various platforms and applications.
To describe various power system objects, CIM uses Class Diagrams and Sequence Diagrams created using the Unified Modeling Language (UML). It also uses the Resource Description Framework (RDF) to describe classes and attributes in an eXtensible Markup Language (XML) file format. The details of what is covered in each part of the CIM is described in detail below.
Background and Structure of the CIM
UML Class Diagrams
The Unified Modeling Language (UML) provides 13 types of diagrams to define software architecture. One of the is the UML Class Diagram, which visually represents object hierarchies and relationships.
First a review of basic concepts and terminology related to class diagrams:
An object is any thing that we want to describe.
A class represents a specific type of object.
A class hierarchy is a model of the system showing every component as a separate class. The class hierarchy should represent the real-world structure of the system.
A package is a group of classes. Think of folders in a computer file explorer.
Inheritance allows us to define very general “parent classes” and very specific “child classes”.
Attributes are the properties that describe what type of thing the class represents.
Associations are the relationships between various objects and how they are connected to each other.
Class diagrams show all the attributes and associations of various classes in a particular package in a single picture. To read a class diagram, remember that
Lines with an arrowhead indicate class inheritance. For example, in the figure below, ACLineSegment inherits from Conductor, ConductingEquipment, Equipment and then PowerSystemResource. ACLineSegment inherits all attributes and associations from its ancestors (e.g., length), in addition to its own attributes and ancestors.
Lines with a diamond indicate composition. For example, Substations make up a SubGeographicalRegion, which then make up a GeographicRegion.
Lines without a terminating symbol are associations. For example, ACLineSegment has (through inheritance) a BaseVoltage, Location and one or more Terminals.
Italicized names at the top of each class indicate the ancestor (aka superclass), in cases where the ancestor does not appear on the diagram. For example, PowerSystemResource inherits from IdentifiedObject.
A complete set of UML Class Diagrams is provided in the Advanced CIM Modeling section. This section contains class diagrams for all the objects used in GridAPPS-D and tables of properties to help you create and pass your own custom SPARQL queries to the Blazegraph Database.
UML Sequence Diagrams
UML sequence diagrams are used to model the flow of messages, events, and actions between the entities of a system. Time is represented vertically—showing the time sequence of interactions in the system. Displayed horizontally at the top of the diagram are the applications or entities in the system.
CIM uses UML diagrams to represent work flow, operations processes, and other utility use-cases. For the purposes of application development within GridAPPS-D, a detailed understanding of UML sequence diagrams is not required.
Resource Description Framework (RDF)
The Resource Description Framework (RDF) is a method of defining information models that is specified by the World Wide Web Consortium (the W3C). Detailed documentation is available on the W3C website.
RDF focuses on making statements about objects in a subject-predicate-object expression. Each expression is commonly called a “triple” in RDF terminology. The subject is defined by naming a resource, the object denotes traits or attributes associated with the subject, and the predicate expresses the relationship between the subject and the object.
The subject, or resource, in an RDF model is expressed as a Uniform Resource Identifier (URI). URIs are similar to the Uniform Resource Locators (URLs) used as web addresses but are more general because they are not limited to accessible data on the web. The predicate and object are also technically URIs and so also are just identifiers. The subject-predicate-object triplets takes the form of expressing syntactical constructs like “a substation has a name”.
RDF Schema (RDFS) files describe the classes, attributes, and relationships of an information model and typically use an .rdfs file format. RDF instance files describe object instances and typically use an .xml extension. RDF incremental files describe changes to a set of object instances as described by an instance file, and typically use an .xml extension.
CIM uses RDF instance files to define power system models with unique master resource identifier (mRID) issued by a model authority. The mRID is globally unique within an exchange context. Global uniqeness is easily achived by using a UUID for the mRID. It is strongly recommended to do this. For CIM XML data files in RDF syntax, the mRID is mapped to rdf:ID or rdf:about attributes that identify CIM object elements.
Key Concepts & Terminology from RDF
URI References – CIM and GridAPPS-D use two URI references to identify properties and resources. These identify the RDF format and the CIM classes used.
<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
<http://iec.ch/TC57/CIM100#>
__
Summary of CIM XML Classes
This section provides a brief look at the classes of equipment modeled in CIM XML and used in GridAPPS-D.
Details of each package, the class diagram, and attributes of each class are provided in the relevant sections of the reference guide to this lesson.
Names, Nodes, Terminals
The Core package provides very high level information of the distribution feeder model
IdentifiedObject
The Core package contains a class called IdentifiedObject. This class is very abstract and only contains attributes used to reference the object either by a user or in software. The attributes of IdentifiedObject include *mRID*, which is the master resource identifier that should be a globally 3-18 unique identifier of objects; the mRID does not have to be human-readable. This identifier is generally intended to be used by software systems.
The attributes name, description, aliasName, and pathName are intended for providing identifiers that are human-readable. It is common for names of objects within a utility to not be unique due to historical naming conventions, the results of mergers and acquisitions, and the inability of other software systems to manage uniqueness. For these reasons, there are no constraints on these names requiring them to be unique.
PowerSystemResource
The PowerSystemResource class inherits from IdentifiedObject and provides another relatively abstract class used in the CIM. The PowerSystemResource class supports an association to a Company class. This relationship identifies the company that operates the resource.
ConnectivityNode
The ConnectivityNode class has a relationship to the Terminal class. Each ConductingEquipment object has Terminals, which are then connected to ConnectivityNodes. The terminals can be thought of as being closely related to the conducting equipment, and the connectivity nodes are the glue that defines what equipment is connected to what other equipment.
CIM also includes the TopologicalNode class, which is used to convert breaker-switch oriented power system models to bus-branch models. This object is not used in GridAPPS-D, which does not feature transmission substation configurations (e.g. breaker-and-a-half, main-and-transfer-bus, ring-bus, etc.) that require topological processing of breaker and switch positions to determine network topology and line connectivity.
Power System Equipment
CIM XML provides a number of classes for defining physical power system equipment, including lines, switches, transformers, regulators, capacitors, and reactors.
Equipment and ConductingEquipment
The ConductingEquipment class inherits from an Equipment class which inherits from PowerSystemResource. This is the parent class for most of the physical equipment that are used to model the power system.
Conductor and ACLineSegment
Directly inheriting from ConductingEquipment is the Conductor class. This class specifies the length of the conductor.
Each segment of a distribution line is defined in a CIM model as an ACLineSegment. This class contains the electrical attributes commonly associated with a line needed for steady state analysis, including the positive-sequence and zero-sequence resistance, reactance, conductance, and susceptance.
More details are available in the `LineModel class diagram <>`__ and `list of attributes <>`__
PowerTransformer, TransformerWindings, and TapChanger
These three classes specify the portions of a step-down transformer and regulator.
The PowerTransformer class inherits from Equipment (not ConductingEquipment) and has associations to the TransformerWinding class.
The majority of the electrical characteristics associated with the transformer are actually associated with the TransformerWinding objects.
An association from the TransformerWinding class to the TapChanger class is used when the transformer has a tap changer. The TapChanger class has as attributes for things like the tap steps and nominal setting. The TapChanger class inherits from the PowerSystemResource class instead of the Equipment class, so it has few inherited attributes and associations.
References
Portions of this tutorial have reproduced verbatim text and information from the EPRI report An Introduction to the CIM for Integrating Distribution Applications and System and the CIM Ontology Diagrams
[ ]:
API Communication Channels
When communicating with the GridAPPS-D Platform through API, it is necessary to specify a communication channel, which tells the GridAPPS-D platform on which channel to communicate with the application and through which API the message should be directed.
/queue/
vs /topic/
Channels
GridAPPS-D uses two types of communication channels to determine the visibility of the API call to other applications and services.
Queue Channels
/queue/
is used for communication channels where only the GridAPPS-D Platform is listening to the API call. These API calls are processed on a first-in, first-out basis. There is only one subscriber to the communication channel.
API calls to the Blazegraph database, Logs, Timeseries database, Config files, and Platform status are all queue channels. All the GridAPPS-D Topics for queue channels typically do not change over the course of an application or simulation run.
In the GridAPPSD-Python library, it is assumed that a topic is a queue channel if not otherwise specified. These two GridAPPS-D Topic definitions are equivalent:
topic = '/queue/goss.gridappsd.process.request.data.powergridmodel'
topic = 'goss.gridappsd.process.request.data.powergridmodel'
Topic Channels
/topic/
is used for communication channels where the API call is to broadcast to all subscribers through the GOSS Message Bus, inlcuding other applications, services, FNCS Bridge, etc.
API calls to the Simulation, services, and active applications use topic channels to communicate and typically need to the specify the Simulation ID, Service ID, and Application ID. The particular topic for such an API call will change between simulations and instances, and so shortcut functions are provided in GridAPPSD-Python library to assist in generating the correct Topic.
In GridAPPSD-Python, it is necessary to specify if a GridAPPS-D Topic is a /topic/
channel broadcasting to all subscribers:
topic = "/topic/goss.gridappsd.simulation.input."+simulation_id
Static GridAPPS-D Topics
Below are a list of the most common topics and where they are used. The appropriate topic for each API call will also be listed again in the subsequent sections on each GridAPPS-D API. The list below can serve as an additional convenient reference.
These topics remain the remain the same between platform, application, and simulation instances. The GridAPPSD-Python Library shortcuts use all uppercase naming to indicate that these are static topic names.
Importing the Topics Library
When using topics in GridAPPSD-Python, it is recommended to import the topics
library from gridappsd
. This enables you to rapidly call the correct topic without needing to search for the correct topic string. This also protects your code from any changes inside the GridAPPS-D Platform if particular topic strings are deprecated or replaced – the python library names will stay persistent between all Platform releases.
For static GridAPPS-D topics, import the library by running
[ ]:
from gridappsd import topics as t
Request PowerGrid Model Data
This /queue/
channel is used to communicate with PowerGrid Models API to pull power system model info from the the Blazegraph Database. The PowerGrid Model API is covered in detail in Using the PowerGrid Models API.
The base static string used is goss.gridappsd.process.request.data.powergridmodel
, which can be called using the .REQUEST_POWERGRID_DATA
or .BLAZEGRAPH
methods from the topics library
A sample message that would be passed with this topic is
[ ]:
from gridappsd import topics as t
# Sample PowerGrid Model message
message = '{"requestType": "QUERY_MODEL_NAMES", "resultFormat": "JSON"}'
gapps.get_response(t.REQUEST_POWERGRID_DATA, message)
[ ]:
from gridappsd import topics as t
# Sample PowerGrid Model message
message = '{"requestType": "QUERY_MODEL_NAMES", "resultFormat": "JSON"}'
gapps.get_response(t.BLAZEGRAPH, message)
Request Timeseries Data
This /queue/
channel is used to communicate with the Timeseries API and Timeseries database, which stores real-time and historical data, such as weather information and AMI meter readings. The Timeseries database is covered in detail in Using the Timeseries API. A sample message that would be passed with this topic is
Text String: The topic can be specified as a static string:
topic = "goss.gridappsd.process.request.data.timeseries"
gapps.get_response(topic, message)
GridAPPSD-Python Library Method: The correct topic can also be imported from the GridAPPSD-Python topics library:
from gridappsd import topics as t
gapps.get_response(t.TIMESERIES, message)
Request Platform Status
This topic is used to check that status of the GridAPPS-D Platform.
Text String: The topic can be specified as a static string:
topic = "/queue/goss.gridappsd.process.request.status.platform"
gapps.get_response(topic, message)
GridAPPSD-Python Library Method: The correct topic can also be imported from the GridAPPSD-Python topics library.
from gridappsd import topics as t
gapps.get_response(t.PLATFORM_STATUS, message)
Querying Log Data
This topic is used to query log data in the MySQL Database using the Logging API
Note: This topic is different from the one used to subscribe to real-time log data being published by an ongoing simulation. This topic is used for querying data already stored in the database.
Text String: The topic can be specified as a static string:
topic = "goss.gridappsd.process.request.data.log"
gapps.get_response(topic, message)
GridAPPSD-Python Library Method: The correct topic can also be imported from the GridAPPSD-Python topics library:
from gridappsd import topics as t
gapps.get_response(t.LOGS, message)
Subscribing to Platform Logs
This topic is used to subscribe the to logs created by the GridAPPS-D Platform, such as which managers and core services have been started and are running.
Text String: The topic can be specified as a static string:
topic = "goss.gridappsd.process.request.data.timeseries"
gapps.get_response(topic, message)
GridAPPSD-Python Library Function: The correct topic can also be imported from the GridAPPSD-Python topics library. Note that this is a python function similar to the dynamic topics presented in the next section.
`from gridappsd.topics import platfor_log_topic
topic = platform_log_topic()
gapps.get_response(topic, message)
Dynamic GridAPPS-D Topics
Several GridAPPS-D topics are unique to each application, simulation, or service instance. These topics are dynamic and will change from instance to instance.
The GridAPPS-D Platform will require that the topic specify the particular instance so that the API call can be delivered to the correct simulation or service.
To assist with the task of creating a dynamic topic that automatically updates between instances, several function are available in the GridAPPSD-Python topics library.
The available GridAPPSD-Python functions for dynamic topics are
simulation_input_topic(simulaton_id)
– Gets the topic to write data to for the simulationsimulation_output_topic(simulation_id)
– Gets the topic for subscribing to output from the simulationsimulation_log_topic(simulation_id)
– Topic for the subscribing to the logs from the simulationservice_input_topic(service_id, simulation_id)
– Utility method for getting the input topic for a specific serviceservice_output_topic(service_id, simulation_id)
– Utility method for getting the output topic for a specific serviceapplication_input_topic(application_id, simulation_id)
– Utility method for getting the input topic for a specific applicationapplication_output_topic(application_id, simulation_id)
– Utility method for getting the output topic for a specific application
Subscribe to Simulation Output
This topic is used to communicate with the Simulation API, which is covered in detail in Controlling Simulations with Simulation API. The Simulation Output Topic is used to subscribe to the simulation output, enabling applications to listen to switching actions, obtain equipment measurements, and so on.
The GridAPPSD-Python shortcut function for generating the correct topic is
simulation_output_topic(simulation_id)
There are two ways to use the function. The first is to call the library function directly. The second is to use it as part of a class definition.
1) Call the topic function directly
[ ]:
# Import GridAPPS-D Topic Function:
from gridappsd.topics import simulation_output_topic
# Call GridAPPSD-Python Topic Function
topic = simulation_output_topic(simulation_id)
# Print to Notebook Kernel:
print(topic)
2) Use the topic function in a class definition
[ ]:
# Import GridAPPS-D Topic Function:
from gridappsd.topics import simulation_output_topic
# Define Subscription Class
class MySubscription(object):
def __init__(self,simulation_id):
self._subscribe_to_topic = simulation_output_topic(simulation_id)
# Define Main Function:
def _main():
subscription = MySubscription(simulation_id)
print(subscription._subscribe_to_topic)
# Call Main Function:
_main()
Publish to Simulation Input
This topic is used to communicate with the Simulation API, which is covered in detail in Controlling Simulations with Simulation API. The Simulation Input Topic is used to publish commands to the GOSS Message Bus, which are then broadcast to all applications, services, and simulations that are listening. Examples of actions that will use this topic include taking switching actions, adjusting DER setpoints, and changing regulator taps.
The GridAPPSD-Python shortcut function for generating the correct topic is
simulation_input_topic(simulation_id)
There are two ways to use the function. The first is to call the library function directly. The second is to use it as part of a class definition.
1) Call the topic function directly
[ ]:
# Import GridAPPS-D Topic Function:
from gridappsd.topics import simulation_input_topic
# Call GridAPPSD-Python Topic Function
topic = simulation_output_topic(simulation_id)
# Print to Notebook Kernel:
print(topic)
2) Use the topic function in a class definition
[ ]:
# Import GridAPPS-D Topic Function:
from gridappsd.topics import simulation_input_topic
# Define Subscription Class
class MySimulationPublisher(object):
def __init__(self,simulation_id):
self._publish_to_topic = simulation_input_topic(simulation_id)
# Define Main Function:
def _main():
subscription = MySimulationPublisher(simulation_id)
print(subscription._publish_to_topic)
# Call Main Function:
_main()
Subscribe to Simulation Logs
This topic is used to communicate with the Simulation API, which is covered in detail in Lesson XX. The Simulation Output Topic is used to subscribe to the simulation output, which applications use to * Listen to switching actions * Obtaining equipment measurements * *GET FULL LIST*
The GridAPPSD-Python shortcut function for generating the correct topic is
simulation_output_topic(simulation_id)
There are two ways to use the function. The first is to call the library function directly. The second is to use it as part of a class definition.
1) Call the topic function directly
[ ]:
# Import GridAPPS-D Topic Function:
from gridappsd.topics import simulation_output_topic
# Call GridAPPSD-Python Topic Function
topic = simulation_output_topic(simulation_id)
# Print to Notebook Kernel:
print(topic)
2) Use the topic function in a class definition
[ ]:
# Import GridAPPS-D Topic Function:
from gridappsd.topics import simulation_output_topic
# Define Subscription Class
class MySubscription(object):
def __init__(self,simulation_id):
self._subscribe_to_topic = simulation_output_topic(simulation_id)
# Define Main Function:
def _main():
subscription = MySubscription(simulation_id)
print(subscription._subscribe_to_topic)
# Call Main Function:
_main()
API Message Structure
This section introduces the format used for passing messages to the GridAPPS-D API and how to wrap those messages using the GridAPPSD-Python Library.
Python Dictionaries VS JSON Strings
One of the confusing aspects of passing messages to and from the GridAPPS-D Platform and APIs is the difference between Python Dictionaries and JSON scripts, which look identical.
JSON is a serialization format. That is, JSON is a way of representing structured data in the form of a textual string.
A Python Dictionary is a data structure. That is, it is a way of storing data in memory that provides certain abilities to the code: in the case of dictionaries, those abilities include rapid lookup and enumeration.
It is possible to convert between the two by importing the JSON library: import json
. Full documentation of JSON-Python interoperability and usage is available in Python Docs.
Use the json.dumps()
method to serialize a dictionary as a JSON string. Use the json.loads()
to import a JSON file and convert it into a dictionary. But the two are not the same: dictionaries are for working with data in your program, and JSON is for storing it or sending it around between programs.
With the GridAPPSD-Python Library, it is possible to pass query arguments as either a python dictionary or as a string. Both approaches will provide the same results.
1) Format API call message as a dictionary
This is the most direct approach, and will be used most often throughout this set of notebook tutorials. The format and structure of the python dictionary is explained in the next section.
[ ]:
model_mrid = "_49AD8E07-3BF9-A4E2-CB8F-C3722F837B62" # IEEE 13 Node used for all example queries
# Format message as python dictionary
message = {
"requestType": "QUERY_OBJECT_IDS",
"resultFormat": "JSON",
"modelId": model_mrid,
"objectType": "LoadBreakSwitch"
}
[ ]:
# Specify correct topic
topic = "goss.gridappsd.process.request.data.powergridmodel"
# Pass API Call to GridAPPS-D Platform
gapps.get_response(topic, message)
2) Format API call message as a string
This approach uses quotations (either ' '
or " "
) to wrap the API call (identical to the python dictionary) as JSON-formatted text, concatenated into a string.
[ ]:
model_mrid = "_49AD8E07-3BF9-A4E2-CB8F-C3722F837B62" # IEEE 13 Node used for all example queries
# Format message as JSON text wrapped as a string
message = """
{
"requestType": "QUERY_OBJECT_IDS",
"resultFormat": "JSON",
"modelId": "%s",
"objectType": "LoadBreakSwitch"
}
""" % model_mrid
[ ]:
# Specify correct topic
topic = "goss.gridappsd.process.request.data.powergridmodel"
# Pass API Call to GridAPPS-D Platform
gapps.get_response(topic, message)
Structure of a GridAPPS-D Message
The structure of messages in GridAPPS-D follows that of a Python Dictionary using a data structure that is more generally known as an associative array. An excellent tutorial on advanced usage of the python dictionary structure is available on Real Python.
A dictionary consists of a collection of key-value pairs. Each key-value pair maps the key to its associated value.
A dictionary is defined by enclosing a comma-separated list of key-value pairs in curly braces ( { } ).
A colon ( : ) separates each key from its associated value.
Square brackets ( [ ] ) are used for a list of values associated to a particular key.
Additional curly braces ( { } ) can be used for cases where multiple key-value pairs (e.g. equipment setpoints) are associated with a particular key (e.g. an equipment class).
The general dictionary format used for GridAPPS-D messages is
message = {
"key1": "value1",
"key2": ["value21", "value22"],
"key3": {
"key31": "value31",
"key32": "value32"
},
.
.
.
"key": "value"
}
Important: Be sure to pay attention to placement of commas ( , ) at the end of each line. Commas are placed at the end of each line except the last line. Incorrect comma placement will result in a syntax exception.
The particular set of key-value pairs for each GridAPPS-D API is covered in detail in Lessons 2.1 through 2.7.
Parsing Returned Data
After passing an API call, the GridAPPS-D Platform returns a JSON string that is subsequently converted into a python dictionary by the GridAPPSD-Python Library. This section will outline how to parse the data returned.
For this example, we are going to use a simple query from the PowerGrid Model API (covered in Lesson 2.2.) to obtain the details of a piece of equipment using its unique mRID (introduced in the next lesson).
[ ]:
model_mrid = "_49AD8E07-3BF9-A4E2-CB8F-C3722F837B62" # IEEE 13 Node used for all example queries
# Specify correct topic
topic = "goss.gridappsd.process.request.data.powergridmodel"
message = {
"modelId": model_mrid,
"requestType": "QUERY_OBJECT_DICT",
"resultFormat": "JSON",
"objectType": "LinearShuntCompensator",
}
# Pass API Call to GridAPPS-D Platform
response = gapps.get_response(topic, message)
import json
with open("foo.txt", 'w') as out:
out.write(json.dumps(response, indent=2))
The structure of the python dictionary returned by the API is three key-value pairs for the keys of
'data'
– this is the data you requested'responseComplete'
– true or false'id'
– unique id associated with the API response dictionary
A typical API response will the structure below:
response = {
'data': [{'key1': 'value1',
'key2': ['value21', 'value22']},
{'key1': 'value1',
'key2': ['value21', 'value22']}],
'responseComplete': True,
'id': '12345678'
}
The first step is to filter the dictionary to just the data requested: response['data']
. The result will be a list object.
Note: some API calls will also need to additional filters of [results][bindings]
. The STOMP Client presented in the next section is very helpful for previewing the structure of the dictionary returned by GridAPPS-D.
[ ]:
response = gapps.get_response(topic, message)
response_obj = response['data']
As response_obj
is of the python type list
rather than dict
, it is necessary to use numerical indices instead of keys to access the values. A simple for
loop is very helpful here.
In this example, we want to filter the results to create a list that contains just the name and mRID of the capacitor banks in the model.
[ ]:
capacitors = []
for index in response_obj:
cap_name = index['IdentifiedObject.name']
cap_mrid = index['id']
message = dict(name = cap_name,
mrid = cap_mrid)
capacitors.append(message)
Using the STOMP Client
The GridAPPS-D Visualization App includes a feature to pass API call messages through the GUI using the Simple Text Oriented Messaging Protocol (STOMP).
Open the Viz App, which is hosted on localhost:8080 (note: cloud-hosted installations will use the IP address of the server).
Select Stomp Client from the main drop-down menu:
This opens the STOMP Client, which can be used to pass a message to any of the GridAPPS-D APIs to preview results or debug the API call message.
Specifying the Topic
The appropriate GridAPPS-D topic needs to be copied and pasted into the Destination Topic box at the top of the window. The topic specifies on which channel the STOMP Client will communicate with the GridAPPS-D Platform and to which API the message needs to be delivered.
A complete list of GridAPPS-D topics was provided in API Communication Channels and will also be provided in context for each of the API calls detailed in subsequent lessons.
IMPORTANT: Remember to remove the python wrapping quotations at the beginning and end of the topic. For example, if the python-wrapped topic was
topic = "goss.gridappsd.process.request.data.powergridmodel" # Specify the topic
then the topic that is entered in the Stomp Client Destination Topic box is simply
goss.gridappsd.process.request.data.powergridmodel
IMPORTANT: The GridAPPSD-Python shortcut functions will not work in the STOMP Client. The full text string versions must be used.
Entering the Request Message
The Request box accepts an API call message identical to those provided in these notebook lessons.
IMPORTANT: Remember to remove the python wrapping at the beginning and end of the message. For example, if the python-wrapped message was
message = "{"requestType": "QUERY_MODEL_NAMES", "resultFormat": "JSON"}" # Sample PowerGrid Model API Call
then the message that is entered in the Stomp Client Request box is simply
{"requestType": "QUERY_MODEL_NAMES", "resultFormat": "JSON"}
The STOMP client will automatically flag any errors in the JSON message.
Submitting a Request
After entering the topic and message, click Send request to send the API call to the GridAPPS-D Platform. The response will be displayed in the box below.
It can be seen that the response from the STOMP Client is identical to that obtained by passing the same topic and message using the GridAPPSD-Python Library:
[ ]:
from gridappsd import GridAPPSD # Import Libraries
gapps = GridAPPSD("('localhost', 61613)", username='system', password='manager') # Connect to Platform
topic = "goss.gridappsd.process.request.data.powergridmodel" # Specify correct Topic
message = {
"requestType": "QUERY_MODEL_NAMES",
"resultFormat": "JSON"
} # Sample PowerGrid Model API message
gapps.get_response(topic, message) # Pass API call to Platform
Using the PowerGrid Models API
Introduction to the PowerGrid Model API
The PowerGrid Models API is used to pull model information from the Blazegraph Database, inlcuding the names, mRIDs, measurements, and nominal values of power system equipment in the feeder (such as lines, loads, switches, transformers, and DERs).
In the Application Components diagram (explained in detail with sample code in GridAPPS-D Application Structure), the PowerGrid Models API is used for querying for the power system model and querying for model measurement MRIDs.
API Syntax Overview
Application passes query to GridAPPS-D Platform
First, the application creates a query message for requesting information about the desired power system components in the format of a JSON string or equivalant Python dictionary object. The syntax of this message is explained in detail below.
The query is sent using gapps.get_response(topic, message)
with a response expected back from the platform within the specified timeout period.
The application then passes the query through the PowerGrid Models API to the GridAPPS-D Platform, which publishes it to the goss.gridappsd.process.request.data.powergridmodel
queue channel on the GOSS Message Bus. If the app is authenticated and authorized to pass queries, the query message is delivered to the data managers, which obtain the desired information from the Blazegraph Database.
GridAPPS-D Platform responds to Application query
The data managers then publish the response from the Blazegraph Database to the appropriate queue channel. The PowerGrid Models API then returns the desired information back to the application as a JSON message or equivalant Python dictionary object.
API Communication Channel
All queries passed to the PowerGrid Models API need to use the correct communication channel, which is obtained using the GridAPPS-D Topics library.
The PowerGrid Model API uses a /queue/
channel to pull power system model info from the the Blazegraph Database. The base static string used is goss.gridappsd.process.request.data.powergridmodel
, which can be called using the .REQUEST_POWERGRID_DATA
or .BLAZEGRAPH
methods from the topics library.
When developing in python, it is recommended to use the .REQUEST_POWERGRID_DATA
method. When using the STOMP client in GridAPPS-D VIZ, it is necessary to use the base static string.
[ ]:
from gridappsd import topics as t
topic = t.REQUEST_POWERGRID_DATA
Structure of a Query Message
Queries passed to PowerGrid Models API are formatted as python dictionaries or equivalent JSON scripts wrapped as a python string.
message = {
"requestType": "INSERT QUERY HERE",
"resultFormat": "JSON",
"modelId": "OPTIONAL INSERT MODEL mRID HERE",
"objectType": "OPTIONAL INSERT CIM CLASS HERE",
"objectId": "OPTIONAL INSERT OBJECT mRID HERE",
"filter": "OPTIONAL INSERT SPARQL FILTER HERE"
}
The components of the message are as follows:
"requestType":
– Specifies the type of query. Available requestType are listed in the next section."resultFormat":
– Specifies the format of the response, can be"JSON"
,"CSV"
, or"XML"
. (CAUTION: the PowerGridModel API uses the key resultFormat, while the Timeseries API uses the key reponseFormat. Using the wrong key for either API will result in a java.lang error.)"modelID":
– Optional. Used to filter the query to only one particular model whose mRID is specified. Be aware of spelling and capitalization differences between JSON query spelling"modelId"
and Python Library spellingmodel_id
."objectType":
– Optional. Used to filter the query to only one CIM class of equipment. Speciying the objectID will override any values specified for objectType."objectID":
– Optional. Used to filter the query to only one object whose mRID is specified. Specifying the objectID will override any values specified for objectType."filter":
– Optional. Used to filter the query using a SPARQL filter. SPARQL queries are covered in the next lesson.
The usage of each of these message components are explained in detail with code block examples below.
Important: Be sure to pay attention to placement of commas ( , ) at the end of each JSON line. Commas are placed at the end of each line except the last line. Incorrect comma placement will result in a JsonSyntaxException.
All of the queries are passed to the PowerGrid Model API using the .get_response(topic, message)
method for the GridAPPS-D platform connection variable.
Specifying the requestType
Below are the possible requestType
strings that are used to specify the type of each query. Executable code block examples are provided for each of the requests in the subsections below.
The first group of requestType key-value pairs are for queries for information related to the just the mRIDs of a set of feeders or set of equipment within a particular feeder:
"requestType": "QUERY_MODEL_NAMES"
– Query for the list of all model name mRIDs"requestType": "QUERY_OBJECT_IDS"
– Query for a list of all mRIDs for objects of a CIM class
The second group of requestType key-value pairs are for queries for Python dictionaries containing all specifics of a set of feeders or set of equipment within a particular feeder:
"requestType": "QUERY_MODEL_INFO"
– Query for the dictionary of all details for all feeders in Blazegraph"requestType": "QUERY_OBJECT_DICT"
– Query for the dictionary of all details for an object using either its *objectType* OR its *objectID*
The third group of requestType key-value pairs are for obtaining information about CIM objects and attributes:
"requestType": "QUERY_OBJECT_TYPES"
– Query for the types of CIM classes of objects in the model"requestType": "QUERY_OBJECT"
– Query for CIM attributes of an object using its unique mRID
One of the most important queries is for object measurements. Each piece of equipment has voltage, power, and/or position measurements associated with it. Each measurement has a unique mRID which is different from that of the equipment.
"requestType": "QUERY_OBJECT_MEASUREMENTS"
– Query for all measurement types and mRIDs for an object using either its *objectType* OR its *ObjectID*
The last group of requestType key-value pairs are for queries based on SPARQL filters or complete SPARQL queries. Usage of these two requestType is made in conjunction with custom SPARQL queries given in Sample SPARQL Queries.
"requestType": "QUERY_MODEL"
– Query for all part of a specified model, filtered by object type using a SPARQL filter."requestType": "QUERY"
– Query using a complete SPARQL query.
CIM Objects Supported by PowerGrid Models API
Below is a list of CIM object classes that can be queried for using the PowerGrid Models API. Other classes and associated attributes need to be queried for using a custom SPARQL query. Sample SPARQL queries for must custom queries can be found in the CIMHub queries.txt file
CIM Classes supported by the PowerGrid Models API
ACLineSegment
Breaker
ConnectivityNode
EnergyConsumer
EnergySource
Fuse
LinearShuntCompensator
LoadBreakSwitch
PowerElectronicsConnection
PowerTransformer
Recloser
SynchronousMachine
TransformerTank
CIM Classes requiring custom SPARQL queries
ACLineSegmentPhase
Analog
Asset
BaseVoltage
BatteryUnit
ConcentricNeutralCableInfo
CoordinateSystem
CurrentLimit
Discrete
EnergyConsumerPhase
Feeder
GeographicalRegion
House
IEC61970CIMVersion
LinearShuntCompensatorPhase
LoadResponseCharacteristic
Location
NoLoadTest
OperationalLimitSet
OperationalLimitType
OverheadWireInfo
PerLengthPhaseImpedance
PerLengthSequenceImpedance
PhaseImpedanceData
PhotovoltaicUnit
PositionPoint
PowerElectronicsConnectionPhase
PowerTransformerEnd
PowerTransformerInfo
RatioTapChanger
RegulatingControl
ShortCircuitTest
SubGeographicalRegion
Substation
SwitchPhase
TapChangerControl
TapChangerInfo
TapeShieldCableInfo
Terminal
TopologicalIsland
TopologicalNode
TransformerCoreAdmittance
TransformerEndInfo
TransformerMeshImpedance
TransformerTankEnd
TransformerTankInfo
VoltageLimit
WirePosition
WireSpacingInfo
Querying for Model mRIDS
Every piece of equipment has a unique mRID, as explained in Intro to Common Information Model. These mRIDs are used to identify and communicate with equipment in GridAPPS-D.
The set of queries below provide just the mRIDs of equipment matching the query filters. If the full details of equipment are desired (e.g. name and properties), use the Query for Equipment Dictionaries API calls in the next section.
This section outlines the pre-built JSON queries that can be passed to the PowerGrid Model API to obtain mRIDs and other information for all models and feeders stored in the Blazegraph Database.
Query for mRIDs of all Models
This query obtains a list of all the model MRIDs stored in the Blazegraph database.
Query requestType:
"requestType": "QUERY_MODEL_NAMES"
Allowed parameters:
"resultFormat":
– “XML” / “JSON” / “CSV” – Optional. Will return results as a list in the format selected.
[ ]:
from gridappsd import topics as t
topic = t.REQUEST_POWERGRID_DATA
message = {
"requestType": "QUERY_MODEL_NAMES",
"resultFormat": "JSON"
}
gapps.get_response(topic, message)
The same query can be passed through the STOMP client by specifying the goss.gridappsd.process.request.data.powergridmodel
topic and the same message without the python wrapping:
Python Library Method
The GridAPPSD-Python library contains a pre-built method for obtaining the mRIDs of all models, providing identical results to those obtained above.
The .query_model_names
method is associated with the GridAPPSD connection object and returns a list of all the CIM XML classes of objects present in the Blazegraph for a particular model or all models in the database.
[ ]:
gapps.query_model_names()
Query for mRIDs of Objects in a Feeder
This query is used to obtain all the mRIDs of objects of a particular CIM class in the feeder.
Query responseType is
"requestType": "QUERY_OBJECT_IDS"
Allowed parameters are:
"modelId":
“model name mRID” – When specified it searches against that model, if empty it will search against all models"objectType":
“CIM Class” – Optional. Specifies the type of objects you wish to return details for."resultFormat":
– “XML” / “JSON” / “CSV” – Will return results as a list in the format selected.
Within a particular feeder, it is possible to query for objects of all the CIM classes supported by PowerGrid Models API (discussed above in CIM Objects Supported by the API). Other types of equipment require custom SPARQL queries.
Note that the RDF URI is not included in the query, only the name of the class, such as "objectType": "ACLineSegment"
or "objectType": "LoadBreakSwitch"
.
[ ]:
from gridappsd import topics as t
topic = t.REQUEST_POWERGRID_DATA
message = {
"requestType": "QUERY_OBJECT_IDS",
"modelId": model_mrid,
"objectType": "LoadBreakSwitch",
"resultFormat": "JSON"
}
gapps.get_response(topic, message)
It is possible to then filter the response to just a list of the mRIDs:
[ ]:
response_obj = gapps.get_response(topic, message)
switch_mrids = response_obj['data']['objectIds']
print(switch_mrids)
The same query can be passed through the STOMP client by specifying the goss.gridappsd.process.request.data.powergridmodel
topic and the same message without the python wrapping:
Querying for Equipment Dictionaries
This section outlines the pre-built JSON queries that can be passed to the PowerGrid Model API to obtain mRIDs and other information for a particular object or a class of objects for one or more feeders stored in the Blazegraph Database.
All of the examples in this section use the IEEE 13 node model.
[ ]:
model_mrid = "_49AD8E07-3BF9-A4E2-CB8F-C3722F837B62" # IEEE 13 Node used for all example queries
Query for Dictionary of all Models
This query returns a list of names and MRIDs for all models, substations, subregions, and regions for all available feeders stored in the Blazegraph database.
Query requestType:
"requestType": "QUERY_MODEL_INFO"
Allowed parameters:
"resultFormat":
– “XML” / “JSON” / “CSV” – Will return results as a list in the format selected.
[ ]:
from gridappsd import topics as t
topic = t.REQUEST_POWERGRID_DATA
message = {
"requestType": "QUERY_MODEL_INFO",
"resultFormat": "JSON"
}
gapps.get_response(topic, message)
The same query can be passed through the STOMP client by specifying the goss.gridappsd.process.request.data.powergridmodel
topic and the same message without the python wrapping:
Python Library Method
The GridAPPSD-Python library contains a pre-built method for requesting the dictionary of all models.
The .query_model_info()
method is associated with the GridAPPSD connection object and runs the same query as above:
[ ]:
gapps.query_model_info()
Query for Object Dictionary
This query returns a python dictionary of all the equipment attributes and mRIDs. The query can be for 1) all objects of a particular objectType
or 2) for those connected to a particular object based on the objectId
.
If neither objectType
or objectId
is provided, the query will provide all measurements belonging to the model. Query responseType is
"requestType": "QUERY_OBJECT_DICT"
Allowed parameters are:
"modelId":
“model name mRID” – When specified it searches against that model, if empty it will search against all models"objectId":
“object mRID” – Optional. Specifies the type of objects you wish to return details for."objectType":
“CIM Class” – Optional. Specifies the type of objects you wish to return details for."resultFormat":
“XML” / “JSON” / “CSV” – Will return results as a list in the format selected.
Speciying the objectID
will override any values specified for objectType
.
Example 1: Querying for model dictionary for an objectID
[ ]:
from gridappsd import topics as t
topic = t.REQUEST_POWERGRID_DATA
message = {
"requestType": "QUERY_OBJECT_DICT",
"modelId": model_mrid,
"objectId": switch_mrids[1],
"resultFormat": "JSON"
}
gapps.get_response(topic, message)
The same query can be passed through the STOMP client by specifying the goss.gridappsd.process.request.data.powergridmodel
topic and the same message without the python wrapping:
Example 2: Querying for model dictionary for an objectType
[ ]:
from gridappsd import topics as t
topic = t.REQUEST_POWERGRID_DATA
message = {
"requestType": "QUERY_OBJECT_DICT",
"modelId": model_mrid,
"objectType": "TransformerTank",
"resultFormat": "JSON"
}
gapps.get_response(topic, message)
The same query can be passed through the STOMP client by specifying the goss.gridappsd.process.request.data.powergridmodel
topic and the same message without the python wrapping:
Python Library Method
The GridAPPSD-Python library contains a pre-built method for requesting the object dictionary
The .query_object_dictionary(model_id, object_type, object_id)
method is associated with the GridAPPSD connection object and runs the same query as above to return the object dictionary
[ ]:
gapps.query_object_dictionary(model_id = model_mrid, object_id = switch_mrids[1])
[ ]:
gapps.query_object_dictionary(model_id = model_mrid, object_type = "TransformerTank")
Querying for CIM Attributes
Query for CIM Classes of Objects in Model
This query is used to query for a list of all the CIM XML classes of objects present in the Blazegraph for a particular model or all models in the database.
Query requestType is
"requestType": "QUERY_OBJECT_TYPES"
Allowed parameters are
"modelId":
“model name mRID” – Optional. Searches only the particular model identified by the given unique mRID"resultFormat":
– “XML” / “JSON” / “CSV” – Will return results as a list in the format selected.
1) Query entire Blazegraph database
Omit the "modelId"
parameter to search the entire blazegraph database.
[ ]:
from gridappsd import topics as t
topic = t.REQUEST_POWERGRID_DATA
message = {
"requestType": "QUERY_OBJECT_TYPES",
"resultFormat": "JSON"
}
gapps.get_response(topic, message)
The same query can be passed through the STOMP client by specifying the goss.gridappsd.process.request.data.powergridmodel
topic and the same message without the python wrapping:
2) Query for only a particular model
Specify the model MRID as a python string and pass it as a parameter to the method to return only the CIM classes of objects in that particular model.
Be aware of spelling and capitalization differences between JSON query spelling "modelId"
and Python Library spelling model_id
.
[ ]:
from gridappsd import topics as t
topic = t.REQUEST_POWERGRID_DATA
message = {
"requestType": "QUERY_OBJECT_TYPES",
"modelId": model_mrid,
"resultFormat": "JSON"
}
gapps.get_response(topic, message)
The same query can be passed through the STOMP client by specifying the goss.gridappsd.process.request.data.powergridmodel
topic and the same message without the python wrapping:
Python Library Method
The GridAPPSD-Python library contains a pre-built method for obtaining all the CIM classes in the model, providing identical results to those obtained above.
The .query_object_types
method is associated with the GridAPPSD connection object and returns a list of all the CIM XML classes of objects present in the Blazegraph for a particular model or all models in the database.
Allowed parameters are
model_id (optional) - when specified, it searches only the particular model identified by the given unique mRID
1) Query entire Blazegraph database
Leave the arguments blank to search all models in the Blazegraph database
[ ]:
gapps.query_object_types()
2) Query for only a particular model
Specify the model MRID as a python string and pass it as a parameter to the method to return only the CIM classes of objects in that particular model
[ ]:
gapps.query_object_types(model_mrid)
Query for CIM Attributes of an Object
This query is used to obtain all the attributes and mRIDs of those attributes for a particular object whose mRID is specified.
Query responseType is
"requestType": "QUERY_OBJECT"
Allowed parameters are:
"modelId":
“model name mRID” – When specified it searches against that model, if empty it will search against all models"objectId":
“object mRID” – Optional. Specifies the type of objects you wish to return details for."resultFormat":
– “XML” / “JSON” / “CSV” – Will return results as a list in the format selected.
[ ]:
from gridappsd import topics as t
topic = t.REQUEST_POWERGRID_DATA
object_mrid = "_2858B6C2-0886-4269-884C-06FA8B887319"
message = {
"requestType": "QUERY_OBJECT",
"resultFormat": "JSON",
"modelId": model_mrid,
"objectId": object_mrid
}
gapps.get_response(topic, message)
The same query can be passed through the STOMP client by specifying the goss.gridappsd.process.request.data.powergridmodel
topic and the same message without the python wrapping:
Python Library Method
The GridAPPSD-Python library contains a pre-built method for obtaining the mRIDs of all models, providing identical results to those obtained above.
The .query_object
method is associated with the GridAPPSD connection object and returns a list of all the CIM XML classes of objects present in the Blazegraph for a particular model or all models in the database.
[ ]:
model_mrid = "_49AD8E07-3BF9-A4E2-CB8F-C3722F837B62" # IEEE 13 Node used for all example queries
object_mrid = "_2858B6C2-0886-4269-884C-06FA8B887319"
gapps.query_object(model_mrid, object_mrid)
Querying for Object Measurements
Object mRIDs vs Measurement mRIDs
A key concept in GridAPPS-D and CIM XML power system models is the difference between the object mRID of a piece of equipment and multiple measurement mRIDs associated with its control settings and power flow values.
Measurements differ from the state variables (e.g. those obtained from State Estimator or a power flow calculation) in that the values are measured here and not calculated or estimated. Each Measurement is associated to a PowerSystemResource, and in GridAPPS-D for now, also a Terminal that belongs to the same PowerSystemResource. (Non-electrical measurements, for example weather, would not have the Terminal).
The measurementType is a string code from IEC 61850, with the following currently suppported:
PNV – Phase to Neutral Voltage
VA – Volt-Amperes (apparent power)
A – Amperes (current)
POS – Position for switches and transformer taps
Each measurement object has a name, mRID, and phases. In GridAPPS-D, each phase is measured individually so multi-phase codes like ABC should not be used.
Pos measurements will be discrete, for such things as tap position, switch position, or capacitor bank position.
The others will be Analog, with magnitude and optional angle in degrees.
Each MeasurementValue will have a timeStamp and mRID inherited from IdentifiedObject, so the values can be traced.
Querying for Measurements
This query returns details for the measurements within a model. The query can be for 1) all objects of a particular objectType
or 2) for those connected to a particular object based on the objectId
.
If neither objectType
or objectId
is provided, the query will provide all measurements belonging to the model. Query responseType is
"requestType": "QUERY_OBJECT_MEASUREMENTS"
Allowed parameters are:
"modelId":
“model name mRID” – When specified it searches against that model, if empty it will search against all models"objectId":
“object mRID” – Optional. Specifies the type of objects you wish to return details for."objectType":
“CIM Class” – Optional. Specifies the type of objects you wish to return details for."resultFormat":
“XML” / “JSON” / “CSV” – Will return results as a list in the format selected.
Speciying the objectID
will override any values specified for objectType
.
Example 1: Querying for all measurements for an objectID
[ ]:
from gridappsd import topics as t
topic = t.REQUEST_POWERGRID_DATA
message = {
"requestType": "QUERY_OBJECT_MEASUREMENTS",
"modelId": model_mrid,
"objectId": switch_mrids[1],
"resultFormat": "JSON"
}
gapps.get_response(topic, message)
The same query can be passed through the STOMP client by specifying the goss.gridappsd.process.request.data.powergridmodel
topic and the same message without the python wrapping:
Example 2: Querying for all measurements for an objectType
[ ]:
from gridappsd import topics as t
topic = t.REQUEST_POWERGRID_DATA
message = {
"requestType": "QUERY_OBJECT_MEASUREMENTS",
"modelId": model_mrid,
"objectType": "ACLineSegment",
"resultFormat": "JSON"
}
gapps.get_response(topic, message)
The same query can be passed through the STOMP client by specifying the goss.gridappsd.process.request.data.powergridmodel
topic and the same message without the python wrapping:
Filtering Returned Data
After receiving the python dictionary of measurements, it will be necessary to parse it to inlcude just the desired set of measurements. This is done using the method presented in Parsing Returned Data
[ ]:
# Create query message to obtain measurement mRIDs for all switches
message = {
"modelId": model_mrid,
"requestType": "QUERY_OBJECT_MEASUREMENTS",
"resultFormat": "JSON",
"objectType": "LoadBreakSwitch"
}
# Pass query message to PowerGrid Models API
response_obj = gapps.get_response(t.REQUEST_POWERGRID_DATA, message)
measurements_obj = response_obj["data"]
# Switch position measurements (Pos)
Pos_obj = [k for k in measurements_obj if k['type'] == 'Pos']
# Switch terminal phase-neutral-voltage measurements (PNV)
PNV_obj = [k for k in measurements_obj if k['type'] == 'PNV']
# Switch volt-ampere apparent power measurements (VA)
VA_obj = [k for k in measurements_obj if k['type'] == 'VA']
# Switch current measurements (A)
A_obj = [k for k in measurements_obj if k['type'] == 'A']
Querying with a Custom SPARQL String
This section outlines how the PowerGrid Models API can be used to pass custom SPARQL queries for CIM objects and properties that do not have pre-built JSON string queries.
Query using a SPARQL filter
This query returns a dictionary of all objects matching the particular filter. The query can be for 1) all objects of a particular objectType
or 2) those with attributes corresponding to a particular SPARQL filter, or both.
If neither objectType
or filter
is specified, the query will provide all objects belonging to the model.
Query responseType is
"requestType": "QUERY_MODEL"
Allowed parameters are:
"modelId":
“model name mRID” – Optional. When specified it searches against that model, if empty it will search against all models"objectType":
“CIM Class” – Optional. Specifies the type of objects you wish to return details for."filter":
“SPARQL triple” – Optional. Applies the SPARQL triple filter to the query results"resultFormat":
“XML” / “JSON” / “CSV” – Will return results as a list in the format selected.
[ ]:
from gridappsd import topics as t
topic = t.REQUEST_POWERGRID_DATA
message = {
"requestType": "QUERY_MODEL",
"modelId": model_mrid,
"resultFormat": "JSON",
"filter": "?s cim:IdentifiedObject.name '650z'",
"objectType": "http://iec.ch/TC57/CIM100#ConnectivityNode"
}
gapps.get_response(topic, message)
The same query can be passed through the STOMP client by specifying the goss.gridappsd.process.request.data.powergridmodel
topic and the same message without the python wrapping:
Python Library Method
The GridAPPSD-Python library contains a pre-built method for passing very simple queries. The SPARQL filter key is not supported.
The .query_model(model_id, object_type, object_id)
method is associated with the GridAPPSD connection object and runs the generic SPARQL query on the Blazegraph database. object_type
uses the full http://iec.ch/TC57/CIM100#
prefix. object_id
is the mRID of the desired object.
[ ]:
gapps.query_model(model_id = model_mrid, object_type = "http://iec.ch/TC57/CIM100#ConnectivityNode")
[ ]:
gapps.query_model(model_id = model_mrid, object_id = "_7BEDDADD-0A14-429F-8601-9EA8B892CA6E")
Query using a Generic SPARQL Query
This query is used to pass a generic SPARQL query to the Blazegraph database.
Query responseType is
"requestType": "QUERY"
Allowed parameters are:
"modelId":
“model name mRID” – Optinal. When specified it searches against that model, if empty it will search against all models"queryString":
“SPARQL query text” – Applies the SPARQL triple filter to the query results"resultFormat":
“XML” / “JSON” / “CSV” – Will return results as a list in the format selected.
[ ]:
from gridappsd import topics as t
topic = t.REQUEST_POWERGRID_DATA
message = {
"requestType": "QUERY",
"queryString": "select ?feeder_name ?subregion_name ?region_name WHERE {?line r:type c:Feeder.?line c:IdentifiedObject.name ?feeder_name.?line c:Feeder.NormalEnergizingSubstation ?substation.?substation r:type c:Substation.?substation c:Substation.Region ?subregion.?subregion c:IdentifiedObject.name ?subregion_name .?subregion c:SubGeographicalRegion.Region ?region . ?region c:IdentifiedObject.name ?region_name}",
"resultFormat": "JSON"
}
gapps.get_response(topic, message)
Although it is possible to check these queries using the STOMP client, it is recommended to validate generic SPARQL queries using the Blazegraph Workbench hosted on localhost:8889/bigdata/#query. The STOMP client contains a JSON validator which may struggle with the line breaks included in SPARQL queries.
Python Library Method
The GridAPPSD-Python library contains a pre-built method for passing generic SPARQL queries
The .query_data(query, timeout)
method is associated with the GridAPPSD connection object and runs the generic SPARQL query on the Blazegraph database.
[ ]:
sparql_message = "select ?feeder_name ?subregion_name ?region_name WHERE {?line r:type c:Feeder.?line c:IdentifiedObject.name ?feeder_name.?line c:Feeder.NormalEnergizingSubstation ?substation.?substation r:type c:Substation.?substation c:Substation.Region ?subregion.?subregion c:IdentifiedObject.name ?subregion_name .?subregion c:SubGeographicalRegion.Region ?region . ?region c:IdentifiedObject.name ?region_name}"
gapps.query_data(query = sparql_message, timeout = 60)
Available Models in Default Installation
The GridAPPS-D Platform comes by default loaded with several distribution feeders ranging in size from 13 to 9500 nodes. Each feeder and recommended usage cases are summarized below.
Name |
Features |
Houses |
Buses |
Nodes |
Branches |
Load |
Origin |
---|---|---|---|---|---|---|---|
ACEP_PSIL |
480-volt microgrid with PV, wind and diesel |
No |
8 |
24 |
13 |
0.28 |
UAF |
EPRI_DPV_J1 |
1800 kW PV in 11 locations |
No |
3434 |
4245 |
4901 |
9.69 |
EPRI DPV |
IEEE13 |
Added CIM sampler |
No |
22 |
57 |
51 |
3.44 |
IEEE (mod) |
IEEE13_Assets |
Uses line spacings and wires |
No |
16 |
41 |
40 |
3.58 |
IEEE (mod) |
IEEE13_OCHRE |
Added 40 service transformers and triplex loads |
Yes |
74 |
160 |
75 |
0.24 |
IEEE (mod) |
IEEE37 |
Delta system |
No |
39 |
117 |
73 |
2.59 |
IEEE |
IEEE123 |
Includes switches for reconfiguration |
No |
130 |
274 |
237 |
3.62 |
IEEE |
IEEE123_PV |
Added 3320 kW PV in 14 locations |
Yes |
214 |
442 |
334 |
0.27 |
IEEE/NREL |
IEEE8500 |
Large model, balanced secondary loads |
Yes |
4876 |
8531 |
6103 |
11.98 |
IEEE |
IEEE9500 |
Added 2 grid sources and DER |
Yes |
5294 |
9499 |
6823 |
9.14 |
GridAPPS-D |
R2_12_47_2 |
Supports approximately 4000 houses |
Yes |
853 |
1631 |
1086 |
6.26 |
PNNL |
Transactive |
Added 1281 secondary loads to IEEE123 |
Yes |
1516 |
3051 |
2812 |
3.92 |
GridAPPS-D |
IEEE 13 Node Model
This is a very small distribution test feeder operating at 4.16 kV voltage level. It consists of a single voltage regulator at the substation, overhead and underground lines, shunt capacitor, and an in-line transformer. This feeder is relatively highly loaded and provides a good test of the convergence of the problem for a very unbalanced system.
This model is recommended for debugging as the model is small enough that issues can be traced by hand.
IEEE 123 Node Model
This models a medium-sized unbalanced distribution system operating at the nominal voltage of 4.16 kV. It consists of overhead and underground lines with single, two and three-phase laterals, along with step regulators and shunt capacitors for voltage regulation. The feeder model is characterized by the unbalanced loading having all combinations of load types (constant current, impedance, and power). It also includes a few switches to allow for the alternate paths for the power flow via feeder reconfiguration.
This model is recommended for initial app testing and debugging thorugh the first stages of development.
IEEE 123 Node Model with PV
This model is a derivative of the IEEE 123 Node model and includes rooftop solar throughout the system.
IEEE 8500 Node Model
This is a relatively large and realistic radial distribution feeder consisting of MV and LV (secondary) circuits [21]. Unlike other test systems, this feeder also includes 120/240V center-tapped transformers that are commonly deployed in North American power distribution systems. Thus, it allows for users to interchange between the two versions of loading conditions: balanced (208 V) and unbalanced (120 V) in the secondary transformers. Voltage control is possible using a substation LTC transformer, as well as multiple poletop regulators and capacitor banks. The feeder was created to test scalability and convergence of power flow algorithms on a large unbalanced power distribution system.
Length: 170 km
Nominal voltage: 12.47 kV, 120/240V
Topology: radial
Service transformers: yes
Customers: 1177
Peak load: 11.1 MW
Normally-open switches: no
9500 Node Test System
The 9500 Node Test System includes three radial distribution feeders with just over 12 MW of load, consisting of both medium voltage and low voltage equipment each supplied by a different distribution substation. The three distribution feeders are connected to each other through Normally-Open switches, which is representative of the way many utilities operate in North America. One feeder represents today’s grid with low penetration of customer-side renewables. The second represents a potential future grid with microgrids and 100% renewable penetration. The third has no customer resources, a district steam plant, and a utility-scale PV farm. All three feeders have customers connected by low-voltage secondary triplex lines.
This is the recommended target feeder for development of all new applications
PNNL Taxonomy Feeder
EPRI J1 Feeder
UAF Microgrid
Adding New Models to GridAPPS-D
git clone https://github.com/GRIDAPPSD/CIMHub.git
pip install SPARQLWrapper numpy pandas
Copy CIM XML file and UUID file into CIMHub directory.
Open CIMHub directory in terminal:
cd CIMHub
View the list of feeder models currently in the Blazegraph Database:
python3 ../CIMHub/utils/ListFeeders.py
Upload your new model using curl
to Blazegraph, specifying the name and MRID of your new feeder:
curl -s -D- -H 'Content-Type: application/xml' --upload-file 'yournewmodel.xml' -X POST 'http://localhost:8889/bigdata/namespace/kb/sparql'
Create the set of txt files containing the measurable objects in your new model using the ListMeasurables
script:
python3 ../CIMHub/utils/ListMeasureables.py cimhubconfig.json yournewmodel _YOUR-NEW-MODEL-FEEDER-MRID-123ABC456
Insert the measurements into Blazegraph using the InsertMeasurements
script. The measurement MRIDs will be saved into the file uuidfile.json
:
for f in `ls -1 *txt`; do python3 ../CIMHub/utils/InsertMeasurements.py cimhubconfig.json $f uuidfile.json; done
Insert houses into Blazegraph using the InsertHouses
script. The measurement MRIDs for the houses will be saved into the file uuidfile2.json
: * python3 ../CIMHub/utils/InsertHouses.py cimhubconfig.json _YOUR-NEW-MODEL-FEEDER-MRID-123ABC456 1 1 uuidfile2.json
Open the GridAPPS-D Viz in a new window and you should be able to start a simulation using your new model
Adding New Models to the PowerGrid Models GitHub Repo
All models included by default in GridAPPS-D are stored in the PowerGrid Models GitHub repository
Using the Configuration File API
Introduction to the Configuration File API
The Configuration File API is used to generate power system models that can be solved in GridLab-D or OpenDSS based on the original CIM XML model. The load profile and ZIP parameters can be modified from the nominal values prior to model creation and export.
In the Application Components diagram (explained in detail with sample code in GridAPPS-D Application Structure), the Configuration File API is used for configuring parallel simulations and exporting the power system model.
API Syntax Overview
Application passes query to GridAPPS-D Platform
First, the application creates a query message for requesting information about the desired power system configuration in the format of a JSON string or equivalant Python dictionary object. The syntax of this message is explained in detail below.
The application then passes the query through the Configuration File API to the GridAPPS-D Platform, which publishes it to a queue channel on the GOSS Message Bus. If the app is authenticated and authorized to pass queries, the query message is delivered to the Configuration Manager.
GridAPPS-D Platform responds to Application query
The Configuration Manager obtains the CIM XML file for the desired power system model and then converts it to the desired output format with all of the requested changes to the model. The Configuration File API then returns the desired information back to the application as a JSON message (for Y-Bus or partial models) or export the files to the directory specified in the
API Communication Channel
All queries passed to the PowerGrid Models API need to use the correct communication channel, which is obtained using the GridAPPS-D Topics library.
The PowerGrid Model API uses a /queue/
channel to pull power system model info from the the Blazegraph Database. The base static string used is goss.gridappsd.process.request.config
, which can be called using the .CONFIG
method from the topics library.
When developing in python, it is recommended to use the .CONFIG
method. When using the STOMP client in GridAPPS-D VIZ, it is necessary to use the base static string.
[ ]:
from gridappsd import topics as t
topic = t.CONFIG
Structure of a Query Message
Queries passed to Configuration File API are formatted as python dictionaries or equivalent JSON scripts wrapped as a python string.
The accepted set of key-value pairs for the Configuration File API query message is
message = {
"configurationType": "INSERT QUERY HERE",
"parameters": {
"key1": "value1",
"key2": "value2"}
}
The components of the message are as follows:
"configurationType":
– Specifies the type of configuration file requested."parameters":
– Specifies any specific power system model parameters. Values depend on the particular configurationType.
The usage of each of these message components are explained in detail with code block examples below.
Important: Be sure to pay attention to placement of commas ( , ) at the end of each JSON line. Commas are placed at the end of each line except the last line. Incorrect comma placement will result in a JsonSyntaxException.
All of the queries are passed to the Configuration API using the .get_response(topic, message)
method for the GridAPPS-D platform connection variable.
Specifying the configurationType
Below are the possible configurationType
key-value pairs that are used to specify the type of each query. Executable code block examples are provided for each of the requests in the subsections below.
The first group of configurationType key-value pairs are for queries for information related to the GridLab-D GLM files and settings:
"configurationType": "GridLab-D All"
– Export all GridLab-D files"configurationType": "GridLab-D Base GLM"
– Query for GridLab-D base GLM file"configurationType": "GridLab-D Symbols"
– Query for GridLab-D symbols file"configurationType": "GridLab-D Simulation Output"
– Query for available measurement types
The second group of configurationType key-value pairs are for queries for OpenDSS model files
"configurationType": "DSS All"
– Export all OpenDSS model files"configurationType": "DSS Base"
– Query for OpenDSS version of power system model"configurationType": "DSS Coordinate"
– Query for list of OpenDSS XY coordinates"configurationType": "YBus Export"
– Export Y-Bus matrix from OpenDSS
The third group of configurationType are for queries for CIM dictionary and feeder index files:
"configurationType": "CIM Dictionary"
– Query for python dictionary of CIM XML model"configurationType": "CIM Feeder Index"
– Query for python dictionary of model mRIDs
Querying for GridLab-D Configuration Files
This section outlines the details of key-value pairs for the possible queries associated with each value of the queryMeasurement
key listed above for obtaining or exporting GridLAB-D Files
Export all GridLab-D Files
This API call generates all the GLM files necessary to solve the power system model in GridLab-D. The query returns a directory where the set of GLM files are located inside the GridAPPS-D docker container.
Configuration File request key-value pair:
"configurationType": "GridLab-D All"
The parameters
key has a set of required values as well as some optional values:
"parameters": { REQUIRED KEYS REQUIRED VALUES
"model_id": mRID as string ,
"directory": output directory as string ,
"simulation_name": string ,
"simulation_start_time": epoch time number ,
"simulation_duration": number ,
"simulation_id": number ,
"simulation_broker_host": string ,
"simulation_broker_port": number ,
OPTIONAL KEYS OPTIONAL VALUES
"i_fraction": number ,
"p_fraction": number ,
"z_fraction": number ,
"load_scaling_factor": number ,
"schedule_name": string ,
"solver_method": string }
The numeric values for the key-value pairs associated with parameters
can be written as number or as strings. The key-value pairs can be specified in any order.
Example: Export IEEE 13 node model with constant current loads to GLM files :
[ ]:
from gridappsd import topics as t
topic = t.CONFIG
message = {
"configurationType": "GridLAB-D All",
"parameters": {
"directory": "/tmp/gridlabdsimulation/",
"model_id": model_mrid,
"simulation_id": "12345678",
"simulation_name": "mysimulation",
"simulation_start_time": "1518958800",
"simulation_duration": "60",
"simulation_broker_host": "localhost",
"simulation_broker_port": "61616",
"schedule_name": "ieeezipload",
"load_scaling_factor": "1.0",
"z_fraction": "0.0",
"i_fraction": "1.0",
"p_fraction": "0.0",
"solver_method": "NR" }
}
gapps.get_response(topic, message, timeout = 120)
The same query can be passed through the STOMP client by specifying the goss.gridappsd.process.request.data.config
topic and the same message without the python wrapping:
Note: The output directory is inside the GridAPPS-D Docker Container, not in your Ubuntu or Windows environment. To access the files, it is necessary to change directories to those inside the docker container.
Open a new Ubuntu terminal and run: * docker exec -it gridappsd-docker_gridappsd_1 bash
* cd /tmp/gridlabdsimulation
* ls -l
To copy the files to your regular directory, use the docker cp
command. For help using docker, see Docker Shortcuts on working with Docker containers.
Query for GridLab-D Base GLM File
This API call generates a single GLM file that contains the entire power system model that can be solved in GridLab-D. The query returns the entire model GLM file wrapped in a python dictionary.
Configuration File request key-value pair:
"configurationType": "GridLab-D Base GLM"
The parameters
key has a set of required values as well as some optional values:
"parameters": { REQUIRED KEYS REQUIRED VALUES
"model_id": mRID as string ,
OPTIONAL KEYS OPTIONAL VALUES
"i_fraction": number ,
"p_fraction": number ,
"z_fraction": number ,
"load_scaling_factor": number ,
"schedule_name": string }
The numeric values for the key-value pairs associated with parameters
can be written as number or as strings. The key-value pairs can be specified in any order.
Example 1: Create GLM base file using nominal load values:
[ ]:
from gridappsd import topics as t
topic = t.CONFIG
message = {
"configurationType": "GridLAB-D Base GLM",
"parameters": {"model_id": model_mrid}
}
gapps.get_response(topic, message, timeout = 60)
The same query can be passed through the STOMP client by specifying the goss.gridappsd.process.request.config
topic and the same message without the python wrapping:
Example 2: Create GLM base file using all constant current loads and hourly load curve:
[ ]:
from gridappsd import topics as t
topic = t.CONFIG
message = {
"configurationType": "GridLAB-D Base GLM",
"parameters": {
"model_id": model_mrid,
"load_scaling_factor": "1.0",
"z_fraction": 0.0,
"i_fraction": 1.0,
"p_fraction": "0.0",
"schedule_name": "ieeezipload"}
}
gapps.get_response(topic, message, timeout = 60)
The same query can be passed through the STOMP client by specifying the goss.gridappsd.process.request.config
topic and the same message without the python wrapping:
Query for GridLab-D Symbols File
This API call generates a python dictionary with all the XY coordinates used by GridLab-D when running a simulation.
Configuration File request key-value pair:
"configurationType": "GridLab-D Symbols"
The parameters
key has a set of required values as well as some optional values:
"parameters": { REQUIRED KEYS REQUIRED VALUES
"model_id": mRID as string ,
OPTIONAL KEYS OPTIONAL VALUES
"simulation_id": number }
The key-value pairs can be specified in any order.
[ ]:
from gridappsd import topics as t
topic = t.CONFIG
message = {
"configurationType": "GridLAB-D Symbols",
"parameters": { "model_id": model_mrid }
}
gapps.get_response(topic, message, timeout = 60)
Query for GridLab-D Measurement Types
This API call returns a list of device names and types of available measurement in the GridLab-D format (not CIM classes or measurement mRIDs)
Configuration File request key-value pair:
"configurationType": "GridLab-D Simulation Output"
The parameters
key has a set of required values as well as some optional values:
"parameters": { REQUIRED KEYS REQUIRED VALUES
"simulation_id": number or string,
OPTIONAL KEYS OPTIONAL VALUES
"model_id": mRID as string }
The key-value pairs can be specified in any order.
[ ]:
from gridappsd import topics as t
topic = t.CONFIG
message = {
"configurationType": "GridLAB-D Simulation Output",
"parameters": {"simulation_id": "paste sim_id here"}
}
gapps.get_response(topic, message, timeout = 60)
The same query can be passed through the STOMP client by specifying the goss.gridappsd.process.request.config
topic and the same message without the python wrapping:
Querying for OpenDSS Configuration Files
This section outlines the details of key-value pairs for the possible queries associated with each value of the queryMeasurement
key listed above for obtaining or exporting OpenDSS Files
Export all OpenDSS Files
This API call generates all the OpenDSS files necessary to solve the power system model in OpenDSS. The query returns a directory where the set of DSS files are located.
Configuration File request key-value pair:
"configurationType": "DSS All"
The parameters
key has a set of required values as well as some optional values:
"parameters": { REQUIRED KEYS REQUIRED VALUES
"model_id": mRID as string ,
"directory": desired output directory as string ,
"simulation_name": string ,
"simulation_start_time": epoch time number ,
"simulation_duration": number ,
"simulation_id": number ,
"simulation_broker_host": string ,
"simulation_broker_port": number ,
OPTIONAL KEYS OPTIONAL VALUES
"i_fraction": number ,
"p_fraction": number ,
"z_fraction": number ,
"load_scaling_factor": number ,
"schedule_name": string ,
"solver_method": string }
The numeric values for the key-value pairs associated with parameters
can be written as number or as strings. The key-value pairs can be specified in any order.
Example: Export IEEE 13 node model with constant current loads to DSS files :
[ ]:
from gridappsd import topics as t
topic = t.CONFIG
message = {
"configurationType": "DSS All",
"parameters": {
"directory": "/tmp/dsssimulation/",
"model_id": model_mrid,
"simulation_id": "12345678",
"simulation_name": "ieee13",
"simulation_start_time": "1518958800",
"simulation_duration": "60",
"simulation_broker_host": "localhost",
"simulation_broker_port": "61616",
"schedule_name": "ieeezipload",
"load_scaling_factor": "1.0",
"z_fraction": "0.0",
"i_fraction": "1.0",
"p_fraction": "0.0",
"solver_method": "NR" }
}
gapps.get_response(topic, message, timeout = 60)
Note: The output directory is inside the GridAPPS-D Docker Container, not in your Ubuntu or Windows environment. To access the files, it is necessary to change directories to those inside the docker container.
Open a new Ubuntu terminal and run: * docker exec -it gridappsd-docker_gridappsd_1 bash
* cd /tmp/dssdsimulation
* ls -l
To copy the files to your regular directory, use the docker cp
command. For help using docker, see Docker Shortcuts on working with Docker containers.
Query for OpenDSS Base File
This API call generates a single DSS file that contains the entire power system model that can be solved in OpenDSS. The query returns the entire model DSS file wrapped in a python dictionary.
Configuration File request key-value pair:
"configurationType": "DSS Base"
The parameters
key has a set of required values as well as some optional values:
"parameters": { REQUIRED KEYS REQUIRED VALUES
"model_id": mRID as string ,
OPTIONAL KEYS OPTIONAL VALUES
"i_fraction": number ,
"p_fraction": number ,
"z_fraction": number ,
"load_scaling_factor": number ,
"schedule_name": string }
The numeric values for the key-value pairs associated with parameters
can be written as number or as strings. The key-value pairs can be specified in any order.
Example 1: Create OpenDSS base file using nominal load values:
[ ]:
from gridappsd import topics as t
topic = t.CONFIG
message = {
"configurationType": "DSS Base",
"parameters": {"model_id": model_mrid}
}
gapps.get_response(topic, message, timeout = 60)
The same query can be passed through the STOMP client by specifying the goss.gridappsd.process.request.config
topic and the same message without the python wrapping:
Example 2: Create OpenDSS base file using all constant current loads and hourly load curve:
[ ]:
message = {
"configurationType": "DSS Base",
"parameters": {
"model_id": model_mrid,
"load_scaling_factor": "1.0",
"z_fraction": 0.0,
"i_fraction": 1.0,
"p_fraction": "0.0",
"schedule_name": "ieeezipload"}
}
gapps.get_response(topic, message, timeout = 60)
The same query can be passed through the STOMP client by specifying the goss.gridappsd.process.request.config
topic and the same message without the python wrapping:
Query for OpenDSS Coordinate File
This API call generates a file with all the XY coordinates used by OpenDSS when plotting the feeder.
Configuration File request key-value pair:
"configurationType": "DSS Coordinate"
The parameters
key has a set of required values as well as some optional values:
"parameters": { REQUIRED KEYS REQUIRED VALUES
"model_id": mRID as string ,
OPTIONAL KEYS OPTIONAL VALUES
"simulation_id": number }
The key-value pairs can be specified in any order.
[ ]:
from gridappsd import topics as t
topic = t.CONFIG
message = {
"configurationType": "DSS Coordinate",
"parameters": {"model_id": model_mrid}
}
gapps.get_response(topic, message)
The same query can be passed through the STOMP client by specifying the goss.gridappsd.process.request.config
topic and the same message without the python wrapping:
Query for Y-Bus Matrix
This API call generates a Y-Bus matrix from either the model mRID or the simulation id.
Note: The GridAPPS-D platform currently does not have an in-built topology processor, so the Y-Bus matrix is NOT updated during the simulation to reflect switching actions or transformer tap changes that happen in real time.
Real-time Y-bus matrix output will be available from the future Dynamic Y-bus Service from the GridAPPS-D App Toolbox.
Configuration File request key-value pair:
"configurationType": "YBus Export"
The parameters
key has a set of required values as well as some optional values:
"parameters": { REQUIRED KEYS REQUIRED VALUES
"model_id": mRID as string ,
OR
"simulation_id": number }
The key-value pairs can be specified in any order.
Example 1: Request Y-Bus for IEEE 13 node model using model mRID:
[ ]:
from gridappsd import topics as t
topic = t.CONFIG
message = {
"configurationType": "YBus Export",
"parameters": {"model_id": model_mrid}
}
gapps.get_response(topic, message)
The same query can be passed through the STOMP client by specifying the goss.gridappsd.process.request.config
topic and the same message without the python wrapping:
Example 2: Request Y-Bus for IEEE 13 node model with all loads set as constant current using model mRID:
[ ]:
from gridappsd import topics as t
topic = t.CONFIG
message = {
"configurationType": "YBus Export",
"parameters": {
"model_id": model_mrid,
"load_scaling_factor": "2.0",
"schedule_name": "ieeezipload",
"z_fraction": "0.4",
"i_fraction": "0.3",
"p_fraction": "0.3" }
}
gapps.get_response(topic, message)
The same query can be passed through the STOMP client by specifying the goss.gridappsd.process.request.config
topic and the same message without the python wrapping:
Example 3: Obtain Y-Bus from simulation_id:
[ ]:
viz_simulation_id = "paste id here"
[ ]:
topic = "goss.gridappsd.process.request.config"
message = {
"configurationType":"YBus Export",
"parameters":{"simulation_id": viz_simulation_id}
}
gapps.get_response(topic, message)
The same query can be passed through the STOMP client by specifying the goss.gridappsd.process.request.config
topic and the same message without the python wrapping:
Querying for CIM Dictionary Files
This section outlines the details of key-value pairs for the possible queries associated with each value of the queryMeasurement
key listed above for obtaining or dictionaries of CIM objects used for file conversion.
Query for Model Dictionary
This API generates a python dictionary which maps the CIM mRIDs of objects in the power system model to names of model objects used in other simulators.
Configuration File request key-value pair:
"configurationType": "CIM Dictionary"
The parameters
key has a set of required values as well as some optional values:
"parameters": { REQUIRED KEYS REQUIRED VALUES
"model_id": mRID as string ,
OPTIONAL KEYS OPTIONAL VALUES
"simulation_id": number }
The key-value pairs can be specified in any order.
[ ]:
topic = "goss.gridappsd.process.request.config"
message = {
"configurationType": "CIM Dictionary",
"parameters":{"model_id": model_mrid}
}
gapps.get_response(topic, message, timeout = 30)
The same query can be passed through the STOMP client by specifying the goss.gridappsd.process.request.config
topic and the same message without the python wrapping:
Query for CIM Feeder Index
This API call returns a python dictionary of the available feeders in the Blazegraph database of power system models.
Configuration File request key-value pair:
"configurationType": "CIM Feeder Index"
The parameters
key has a set of required values as well as some optional values:
"parameters": { REQUIRED KEYS REQUIRED VALUES
"model_id": mRID as string ,
OPTIONAL KEYS OPTIONAL VALUES
"simulation_id": number }
The key-value pairs can be specified in any order.
[ ]:
from gridappsd import topics as t
topic = t.CONFIG
message = {
"configurationType": "CIM Feeder Index",
"parameters":{}
}
gapps.get_response(topic, message)
The same query can be passed through the STOMP client by specifying the goss.gridappsd.process.request.config
topic and the same message without the python wrapping:
Running Simulations with the Simulation API
Introduction to the Simulation API
The Simulation API is used for all actions related to a power system simulation. It is used to start, pause, restart, and stop a simulation from the command line or inside an application. It is all used to subscribe to measurements of equipment (such as line flows, loads, and DG setpoints) and the statuses of switches, capacitors, transformer taps, etc. It is also used to publish equipment control and other simulation input commands.
In the Application Components diagram (explained in detail with sample code in GridAPPS-D Application Structure), the PowerGrid Models API is used for controlling the simulation, subscribing to measurement data, and controlling equipment.
This section covers only the portion of the API used for starting, stopping, and pausing simulations. Equipment control commands are covered in Controlling Simulation with the Simulation API
API Syntax Overview
Application passes subscription request to GridAPPS-D Platform
The subscription request is perfromed by passing the app core algorithm function / class definition to the gapps.subscribe
method. The application then passes the subscription request through the Simulation API to the topic channel for the particular simulation on the GOSS Message Bus. If the application is authorized to access simulation output, the subscription request is delivered to the Simulation Manager.
GridAPPS-D Platform delivers published simulation output to Application
Unlike the previous queries made to the various databases, the GridAPPS-D Platform does not provide any immediate response back to the application. Instead, the Simulation Manager will start delivering measurement data back to the application through the Simulation API at each subsequent timestep until the simulation ends or the application unsubscribes. The measurement data is then passed to the core algorithm class / function, where it is processed and used to run the app’s optimization / control algorithms.
API Communication Channel
The Simulation API is used to communicate with a broad range of subscribers through both static /queue/
(the type of channel used for passing databse queries) and dynamic /topic/
communication channel names.
Extreme care is needed to use the correct communication channel. For a review of GridAPPS-D topics, see API Communication Channels
The correct communication channel for each Simulation API call will be provided in the corresponding section for each API task below.
Structure of a Simulation Message
Due to the wide range of tasks accomplished by the Simualtion API, there is no single message format that is used across all API Calls.
Each message takes the form of a python dictionary or equivalent JSON script wrapped as a python string.
The structure of each Simulation API call message will be provided in the corresponding section for each API task below.
Starting a Simulation
This section explains the API call used to start simulations. For most application developers, typical use cases would be either
starting a digital twin simulation from within an app for “what-if” analysis
building an automated test script that would launch a simulation with exactly identical parameters each time.
The API message structure and start command are also used by the GridAPPS-D Viz when starting a simulation using the steps in Creating a Simulation with GridAPPS-D Viz. However, the API call and detail simulation start message are hidden from the user when using Viz.
GridAPPS-D Communication Channel
This is a static /queue/
communication channel used to quest the simulation to start. The base static string used is goss.gridappsd.process.request.simulation
, which can be called using the .REQUEST_SIMULATION
method from the topics library.
When developing in python, it is recommended to use the .REQUEST_SIMULATION
method. When using the STOMP client in GridAPPS-D VIZ, it is necessary to use the base static string.
[ ]:
from gridappsd import topics as t
topic = t.REQUEST_SIMULATION
Simulation Start Message Structure
To start a simulation from the command line or from inside an application, it is necessary to pass a message with a structure similar to that used by the Configuration File API) so that the GridAPPS-D platform can create a custom GridLab-D file from the CIM XML model stored in the Blazegraph Database.
The accepted set of key-value pairs for the Simulation API call to start a new simulation is
message = {
"power_system_config": {
"key1": "value1",
"key2": "value2"},
"simulation_config": {
"key1": "value1",
"key2": "value2",
"model_creation_config": {
"key1": "value1",
"key2": "value2",
"model_state": {
"key1": "value1",
"key2": "value2"}
}
},
"simulation_output": {
"key1": "value1",
"key2": "value2"},
"application_config": [{
"key1": "value1",
"key2": "value2"}],
"test_config": {
"events": [{,
"message": {
"forward_differences": [{
"key1": "value1",
"key2": "value2"}]
"reverse_differences": [{
"key1": "value1",
"key2": "value2"}],
"key1": "value1",
"key2": "value2"}
}]
},
"service_configs": {
"key1": "value1",
"key2": "value2"}
}
The components of the message are identical to the options in the tabs in the GridAPPS-D. Each key-value pair is explained in detail below.
Power System Configuration
This key is required and specifies the CIM XML model to be imported and used for the simulation. Required key-value pairs are
"power_system_config": { REQUIRED KEY REQUIRED VALUE
"GeographicalRegion_name": mRID as string ,
"SubGeographicalRegion_name": mRID as string ,
"Line_name": mRID as string }
As can be seen, the required key-value pairs are identical to those that are selected graphically using the GridAPPS-D Viz:
Simulation Configuration
The "simulation_config":
key is required and specifies the runtime parameters, such as simulation duration and time step. Required key-value pairs are
"simulation_config": { REQUIRED KEY REQUIRED VALUE
"start_time": epoch time string ,
"duration": number (seconds) ,
"simulator": "GridLAB-D" ,
"timestep_frequency": number (milliseconds) ,
"timestep_increment": number (milliseconds) ,
"run_realtime": true OR false ,
"simulation_name": string ,
"power_flow_solver_method": "NR" ,
"model_creation_config": key-value pairs }
The key "model_creation_config":
is one of the optional key-value pairs that can specified. This specifies the load profile and changes to the base case used for the simulation. Key-value pairs are
"model_creation_config": { KEY VALUE
"load_scaling_factor": number ,
"schedule_name": string ,
"z_fraction": number ,
"i_fraction": number ,
"p_fraction": number ,
"randomize_zipload_fractions": true OR false ,
"use_houses": true OR false ,
"model_state": key-value pairs }
The key "model_state:"
is one of the optional key-value pairs used to specify changes to switch positions and DER setpoints from the base case stored in the Blazegraph database. Key-value pairs are
"model_state": {
"synchronousmachines":[
{"name": "GLM/DSS name","p": number,"q": number},
{"name": "GLM/DSS name","p": number,"q": number}],
"switches":[
{"name":"GLM/DSS name", "open": true},
{"name":"GLM/DSS name", "open": false}]
}
As can be seen, the required key-value pairs are identical to those that are selected graphically using the GridAPPS-D Viz. By default, only the required key-value pairs are listed in the viz. The simulation launched in the Viz can be configured using any of the "model_creation_config"
and "model_state"
key-value pairs.
Application Configuration
The "application_config":
key is optional and specifies which applications will run during the simulation. The associated value is a list that specifies the name and application-specific configuration parameters.
"application_config": {
"applications": [
{
"name": "application1",
"config_string": "application-specific config string"
},
{
"name": "application2",
"config_string": "application-specific config string"
}]
}
As can be seen, the required key-value pairs are identical to those that are selected graphically using the GridAPPS-D Viz. Note: simulations started using the GridAPPS-D Viz can only run one app at a time. This is due to the GUI design and not a limitation of the Simulation API.
Test Manager Configuration
The TestManager is used to create realistic operational events during the simulation run, including faults, communication outages, and other unexpected equipment actions. These types of events can be used to test robustness of applications in variable conditions similar to those of the real world.
There are three types events supported by the TestManager and the GridAPPS-D Platform:
CIM defined fault events, used when a line is down or for taking a piece of equipment out of service.
Communication outage events which simulates measurements or control message outages.
Scheduled command at specific time which sends commands to a piece of equipment.
When starting a simulation, any combination of event categories can be specified using the "test_config":
key-value pair structure. This key is optional and specifies whether any pre-scripted events should be scheduled to occur during the simulation, such as faults, communication outages, and equipment malfunctions.
The TestManager configuration can be written within the text of the Simulation API call or imported from a JSON file. Each of the event categories are discussed in further detail below.
"test_config": {
"events": [
{
"event_type": "CommOutage",
"tag": "unique_tag",
"startDateTime": "YYYY-MM-DD HH:MM:SS" OR epoch time number,
"stopDateTime": "YYY-MM-DD HH:MM:SS" OR epoch time number,
"allInputOutage": true or false,
"inputList": [
{
"name": "equipment name",
"type": "CIM equipment type",
"mRID": "equipment object mRID",
"phases": [
{
"phaseLabel": "A" or "B" or "C",
"phaseIndex": number
}
],
"attribute": "CIM Control Attribute"
}
],
"allOutputOutage": true or false,
"outputList": [
{
"name": "equipment name",
"type": "CIM equipment type",
"mRID": "equipment object mRID",
"phases": [ "A" or "B" or "C" ],
"measurementTypes": [ "PNV" or "VA" or "POS" ]
}
]
},
{
"event_type": "Fault",
"tag": "unique_tag",
"equipmentType": "CIM object type",
"equipmentName": "equipment name",
"mRID": [
"equipment object mRID",
"equipment object mRID",
"equipment objhect mRID"
],
"phases": [
{
"phaseLabel": "A" or "B" or "C",
"phaseIndex": number
}
],
"faultKind": "lineToGround" or "lineToLine" or "lineToLineToGround",
"faultImpedance": {
"rGround": "value",
"xGround": "value"
},
"startDateTime": "YYYY-MM-DD HH:MM:SS" OR epoch time number,
"stopDateTime": "YYYY-MM-DD HH:MM:SS" OR epoch time number
},
{
"message": {
"forward_differences": [
{
"object": "control object mRID",
"attribute": "CIM Class Attribute",
"value": number
}
],
"reverse_differences": [
{
"object": "control object mRID",
"attribute": "CIM Class Attribute",
"value": number
}
]
},
"event_type": "ScheduledCommandEvent",
"occuredDateTime": "YYYY-MM-DD HH:MM:SS" OR epoch time number,
"stopDateTime": "YYYY-MM-DD HH:MM:SS" OR epoch time number
}
]
}
Fault Events
Fault Events are defined in a Test Script and define the CIM Fault events that will be intialized and cleared at scheduled times.
The phases string is all the combinations of the 3-phases plus neutral and secondary phases. Some examples are :
“A”
“AN” would be line to line.
“AB” would be line to line.
“S12N” both hot wires to ground
“S12” both hot wires together.
PhaseConnectedFaultKind is an enumeration with the following values:
lineToGround
lineToLine
lineToLineToGround
lineOpen
The key-value pairs for specifying a fault event are:
{
"PhaseConnectedFaultKind": string,
"FaultImpedance": {
"rGround": float,
"xGround": float,
"rLineToLine":float,
"xLineToLine":float },
"ObjectMRID": [string],
"phases": string,
"event_type": string,
"occuredDateTime": long,
"stopDateTime": long
}
Example 1: Fault Event Example in test script
{
"command": "new_events",
"events" : [{
"PhaseConnectedFaultKind": "lineToGround",
"FaultImpedance": {
"rGround": 0.001,
"xGround": 0.001 },
"ObjectMRID": ["_9EF94B67-7279-21F4-5CEE-B2724E3C3FE6"],
"phases": "ABC",
"event_type": "Fault",
"occuredDateTime": 1248130809,
"stopDateTime": 1248130816}
]
}
As can be seen, the required key-value pairs are identical to those that are selected graphically using the GridAPPS-D Viz. The Viz offers the equivalent options to create line faults, communications outages, or upload a custom difference message JSON file.
Example 2: Commands sent from the Test Manager to the simulation
{
"command": "update",
"input": {
"timestamp": 1553201000414,
"reverse_differences": [],
"difference_mrid": "_ee4e4055-222f-4ccf-bed1-93063bd4392c",
"forward_differences": [
{
"ObjectMRID": "12344",
"FaultImpedance": {
"xLineToLine": 0.0,
"rGround": 0.001,
"rLineToLine": 0.0,
"xGround": 0.001
},
"FaultMRID": "1233",
"PhaseCode": "AN",
"PhaseConnectedFaultKind": "lineToGround"
}
]
}
}
Example 3: Clear a Fault Command example
{
"command": "update",
"input": {
"timestamp": 1553201003561,
"reverse_differences": [{
"ObjectMRID": "12344",
"FaultImpedance": {
"xLineToLine": 0.0,
"rGround": 0.001,
"rLineToLine": 0.0,
"xGround": 0.001
},
"FaultMRID": "1233",
"PhaseCode": "AN",
"PhaseConnectedFaultKind": "lineToGround"
}
],
"difference_mrid": "_00b4668d-8454-4f1c-aed9-42d1424af149",
"forward_differences": []
}
}
Communication Outage Events
Communication Outage events are separate from the CIM events but have occuredDateTime and stopDateTime.
The inputOutageList is the list of objectMRID and attribute pair. The objectMRID is anything that can be controllable and specific control attribute i.e. “RegulatingControl.mode”.
The outputOutageList is the list of MRIDs for the measurement device that is associated to the .
If allInputOutage is True the inputOutageList is not needed as all inputs to the simulator are blocked.
If allOutputOutage is True the outputOutageList is not needed as all outputs from the simulator are blocked.
The key-value pairs for communication outage events follow the format
{
"allOutputOutage": boolean,
"allInputOutage": boolean,
"inputOutageList": [{"objectMRID":string, "attribute":string}],
"outputOutageList": [string],
"event_type": string,
"occuredDateTime": long,
"stopDateTime": long
}
Example 1: JSON Communication Outage command for the TestManager
{
"command": "new_events",
"events": [{
"allOutputOutage": false,
"allInputOutage": false,
"inputOutageList": [{
"objectMRID":"_EF2FF8C1-A6A6-4771-ADDD-A371AD929D5B",
"attribute":"ShuntCompensator.sections" },
{"objectMRID":"_C0F73227-012B-B70B-0142-55C7C991A343",
"attribute":"ShuntCompensator.sections"}],
"outputOutageList": ["_5405BE1A-BC86-5452-CBF2-BD1BA8984093"],
"event_type": "CommOutage",
"occuredDateTime": 1248130819,
"stopDateTime": 1248130824
}
]
}
As can be seen, the required key-value pairs are identical to those that are selected graphically using the GridAPPS-D Viz. The Viz offers the equivalent options to create line faults, communications outages, or upload a custom difference message JSON file.
Example 2: Communication Event to the Simulation Bridge
{
"command": "CommOutage",
"input": {
"timestamp": 1248130819,
"forward_differences": [
{
"allOutputOutage": false,
"allInputOutage": false,
"inputOutageList": [
{
"objectMRID": "_EF2FF8C1-A6A6-4771-ADDD-A371AD929D5B",
"attribute": "ShuntCompensator.sections"
},
{
"objectMRID": "_C0F73227-012B-B70B-0142-55C7C991A343",
"attribute": "ShuntCompensator.sections"
}
],
"outputOutageList": [
"_5405BE1A-BC86-5452-CBF2-BD1BA8984093"
],
"faultMRID": "_ce5ee4c9-9c41-4f5e-8c5c-f19990f9cfba",
"event_type": "CommOutage",
"occuredDateTime": 1248130819,
"stopDateTime": 1248130824
}
],
"reverse_differences": []
}
}
Scheduled Command Events
Schedule Commands are events that can be scheduled for a specific point in time of the simulation. This can be used to trigger a fault like behavior, such as changing the taps of a regular or mimicking behavior of protective devices.
Faults in topologically meshed networks need to created using a Scheduled Command event to open all switches that would be tripped by protective relaying due to a known bug in the GridLAB-D logical fault processor.
The set of key-value pairs for Scheduled Command events follow the format below. The message parameters follow the format of a difference message, which is explained in detail in Format of Difference Messages.
{
"command": "new_events",
"events":[{
"message":{
"forward_differences": [{
"object": "control object mRID",
"attribute": "CIM Class Attribute",
"value": number }],
"reverse_differences": [{
"object": "control object mRID",
"attribute": "CIM Class Attribute",
"value": number }]
},
},
"occuredDateTime":long,
"stopDateTime":long,
}
]
}
Service Configuration
The "service_configs":
key is used to start a GridAPPS-D service, such as the Sensor Service, State Estimator, or DNP3 Service. The key-value pairs for starting the service depend on the particular service and will be covered in the documentation for each GridAPPS-D Service. Note that the syntax of this key is a plural noun, unlike the other config keys.
Complete Simulation Start Message
The complete simulation message that is passed to the Simulation API is a Python dictionary / JSON string that specified the "power_system_conf":
, "application_config":
, "simulation_config":
, "test_config":
, and "service_configs":
key-value pairs.
A sample simulation start message for the IEEE 123 bus system running the Sensor Simulator service and including one Scheduled Command event is shown below.
[ ]:
run_config_123 = {
"power_system_config": {
"GeographicalRegion_name": "_73C512BD-7249-4F50-50DA-D93849B89C43",
"SubGeographicalRegion_name": "_1CD7D2EE-3C91-3248-5662-A43EFEFAC224",
"Line_name": "_C1C3E687-6FFD-C753-582B-632A27E28507"
},
"application_config": {
"applications": []
},
"simulation_config": {
"start_time": "1570041113",
"duration": "120",
"simulator": "GridLAB-D",
"timestep_frequency": "1000",
"timestep_increment": "1000",
"run_realtime": True,
"simulation_name": "ieee123",
"power_flow_solver_method": "NR",
"model_creation_config": {
"load_scaling_factor": "1",
"schedule_name": "ieeezipload",
"z_fraction": "0",
"i_fraction": "1",
"p_fraction": "0",
"randomize_zipload_fractions": False,
"use_houses": False
}
},
"test_config": {
"events": [{
"message": {
"forward_differences": [
{
"object": "_6C1FDA90-1F4E-4716-BC90-1CCB59A6D5A9",
"attribute": "Switch.open",
"value": 1
}
],
"reverse_differences": [
{
"object": "_6C1FDA90-1F4E-4716-BC90-1CCB59A6D5A9",
"attribute": "Switch.open",
"value": 0
}
]
},
"event_type": "ScheduledCommandEvent",
"occuredDateTime": 1570041140,
"stopDateTime": 1570041200
}]
},
"service_configs": [{
"id": "gridappsd-sensor-simulator",
"user_options": {
"sensors-config": {
"_99db0dc7-ccda-4ed5-a772-a7db362e9818": {
"nominal-value": 100,
"perunit-confidence-band": 0.02,
"aggregation-interval": 5,
"perunit-drop-rate": 0.01
},
"_ee65ee31-a900-4f98-bf57-e752be924c4d": {},
"_f2673c22-654b-452a-8297-45dae11b1e14": {}
},
"random-seed": 0,
"default-aggregation-interval": 30,
"passthrough-if-not-specified": False,
"default-perunit-confidence-band": 0.01,
"default-perunit-drop-rate": 0.05
}
}]
}
The simulation start message can be built from within the application or copied from the GridAPPS-D Viz by starting a new simulation and copying the start message from the log file. Pausing the simulation immediately after it starts is extremely helpful in locating the start message and copying it.
Starting the Simulation
To start the simulation, import the gridappsd.simulation
library, which provides multiple shortcut functions for running and controlling a simulation.
The simulation start message python dictionary created in the previous section is then passed as an argument to Simulation object.
The .start_simulation()
method is then used to pass the Simulation API call to the GOSS Message Bus and the GridAPPS-D Platform.
The simulation id can be obtained by invoking the .simulation_id
method.
[ ]:
from gridappsd.simulation import Simulation # Import Simulation Library
simulation_obj = Simulation(gapps_sim, run_config_123) # Create Simulation object
simulation_obj.start_simulation() # Start Simulation
simulation_id = simulation_obj.simulation_id # Obtain Simulation ID
print("Successfully started simulation with simulation_id: ", simulation_id)
The simulation start message can also be saved as a JSON file that is loaded using the json.load("filename.json")
method. The simulation is then started by passing the start message to the .start_simulation()
method.
[ ]:
import json
from gridappsd.simulation import Simulation # Import Simulation Library
run123_config = json.load(open("Run123NodeFileSimAPI.json")) # Pull simulation start message from saved file
simulation_obj = Simulation(gapps, run123_config) # Create Simulation object
simulation_obj.start_simulation() # Start Simulation
simulation_id = simulation_obj.simulation_id # Obtain Simulation ID
print("Successfully started simulation with simulation_id: ", simulation_id)
Pausing, Resuming, or Stopping a Simulation
Whether running a simulation through the GridAPPS-D Viz or a parallel digital twin simulation started from within your application, it is frequently useful to be able to pause, resume, or stop the simulation.
Using the gridappsd.simulation Python Library
For simulations that are started using the .start_simulation()
method of the gridappsd.simulation
python library, it is possible to use the associated methods to pause, resume, and stop simulations.
The library provides the following methods:
.pause()
– Pause the simulation.resume()
– Resume the simulation.resume_pause_at(pause_time)
– Resume the simulation, and then pause it in so many seconds.stop()
– Stop the simulation.run_loop()
– Loop the entire simulation until interrupted
Using a Topic + Message API Call
If the simulation was started using the GridAPPS-D Viz, then pause, resume, and stop commands need to be issued using an API call to the Simulation API specifying the topic and message.
Specifying the Topic
This is a dynamic /topic/
communication channel that is best implemented by importing the GriAPPSD-Python library function for generating the correct topic.
[ ]:
viz_simulation_id = "paste sim_id here"
[ ]:
from gridappsd.topics import simulation_input_topic
topic = simulation_input_topic(viz_simulation_id)
Pause Message
The simulation can be paused using a very simple pause message. Since no response is expected from the Simulation API, we used the .send(topic, message)
method for the GridAPPS-D connection object.
[ ]:
message = {"command": "pause"}
gapps.send(topic, message)
Resume Message
The simulation can be resumed using a very simple message. Since no response is expected from the Simulation API, we used the .send(topic, message)
method for the GridAPPS-D connection object.
[ ]:
message = {"command": "resume"}
gapps.send(topic, message)
Resume then Pause Message
The simulation can be resumed and then paused using a very simple message. Since no response is expected from the Simulation API, we used the .send(topic, message)
method for the GridAPPS-D connection object.
[ ]:
message = {
"command": "resumePauseAt",
"input": {"pauseIn": 10}
}
gapps.send(topic, message)
Publishing and Subscribing with the Simulation API
Introduction to the Simulation API
The Simulation API is used for all actions related to a power system simulation. It is used to start, pause, restart, and stop a simulation from the command line or inside an application. It is all used to subscribe to measurements of equipment (such as line flows, loads, and DG setpoints) and the statuses of switches, capacitors, transformer taps, etc. It is also used to publish equipment control and other simulation input commands.
In the Application Components diagram (explained in detail with sample code in GridAPPS-D Application Structure), the PowerGrid Models API is used for controlling the simulation, subscribing to measurement data, and controlling equipment.
This section covers only the portion of the API used for subscribing to measurements and publishing equipment control commands. Usage of the API for starting, stopping, and pausing simulations is covered in Creating and Running Simulations with Simulation API
Processing Measurements & App Core Algorithm
The central portion of a GridAPPS-D application is the measurement processing and core algorithm section. This section is built as either a class or function definition with prescribed arguments. Each has its advantages and disadvantages:
The function-based approach is simpler and easier to implement. However, any parameters obtained from other APIs or methods to be used inside the function currently need to be defined as global variables.
The class-based approach is more complex, but also more powerful. It provides greater flexibility in creating additional methods, arguments, etc.
App Core Information Flow
This portion of the application does not communicate directly with the GridAPPS-D platform.
Instead, the next part of the GridAPPS-D application (Subscribing to Simulation Output) delivers the simulated SCADA measurement data to the core algorithm function / class definition. The core algorithm processes the data to extract the desired measurements and run its optimization / control agorithm.
Structure of Simulation Output Message
The first part of the application core is parsing simulated SCADA and measurement data that is delivered to the application.
The general format of the messages received by the Simulation API is a python dictionary with the following key-value pairs:
{
"simulation_id" : string,
"message" : {
"timestamp" : epoch time number,
"measurements" : {
"meas mrid 1":{
"PNV measurement_mrid": "meas mrid 1"
"magnitude": number,
"angle": number },
"meas mrid 2":{
"VA measurement_mrid": "meas mrid 2"
"magnitude": number,
"angle": number },
"meas mrid 3":{
"Pos measurement_mrid": "meas mrid 3"
"value": number },
.
.
.
"meas mrid n":{
"measurement_mrid": "meas mrid n"
"magnitude": number,
"angle": number },
}
}
Format of Measurement Values
In the message above, note the difference in the key-value pair structure of different types of measurements:
PNV Voltage Measurements
These are specified as magnitude
and angle
key-value pairs.
Magnitude is the RMS phase-to-neutral voltage.
Angle is phase angle of the voltage at the particular node.
VA Volt-Ampere Apparent Power Measurements
These are specified as magnitude
and angle
key-value pairs. * Magnitude is the apparent power. * Angle is complex power triangle angle (i.e. acos(power factor))
Pos Position Measurements
These are specified as a value
key-value pair. * Value is the position of the particular measurement * For switch objects: value = 1 means “closed”, value = 0 means “open” * For capacitor objects, values are reversed: value = 1 means “on”, value = 0 means “off” * For regulator objects, value is the tap position, ranging from -16 to 16
Role of Measurement mRIDs
The simulation output message shown above typically contains the measurement mRIDs for all available sensors for all equipment in the power system model. The application needs to filter the simulation output message to just the set of measurements relevant to the particular application (e.g. switch positions for a FLISR app or regulator taps for a VVO app).
The equipment and measurement mRIDs are obtained in the first two sections of the application. See Query for Power System Model and Query for Measurement mRIDs for examples of how these code sections fit in a sample app.
API syntax details for the query messages to PowerGrid Models API to obtain equipment info and measurement mRIDs are given in Query for Object Dictionary and Query for Measurements.
These mRIDs will be needed to parse the simulation output message and filter it to just the desired set of measurements.
For the example below, we will be interested in only the measurement associated with switches, so we will use the PowerGrid Models API to query for the set of measurements associated with the CIM Class LoadBreakSwitch
. We then will filter those values to just the mRIDs associated with each type of measurement.
[ ]:
from gridappsd import topics as t
# Create query message to obtain measurement mRIDs for all switches
message = {
"modelId": model_mrid,
"requestType": "QUERY_OBJECT_MEASUREMENTS",
"resultFormat": "JSON",
"objectType": "LoadBreakSwitch"
}
# Pass query message to PowerGrid Models API
response_obj = gapps.get_response(t.REQUEST_POWERGRID_DATA, message)
measurements_obj = response_obj["data"]
# Switch position measurements (Pos)
Pos_obj = [k for k in measurements_obj if k['type'] == 'Pos']
# Switch phase-neutral-voltage measurements (PNV)
PNV_obj = [k for k in measurements_obj if k['type'] == 'PNV']
# Switch volt-ampere apparent power measurements (VA)
VA_obj = [k for k in measurements_obj if k['type'] == 'VA']
# Switch current measurements (A)
A_obj = [k for k in measurements_obj if k['type'] == 'A']
App Core as a Function Definition
The first approach used to build the application core is to define a function with the correct set of arguments that is then passed to the .subscribe()
method associated with the GridAPPPSD()
object.
The function does not require a specific name, and is somewhat easier to define and use. However, the arguments of the function need to be named correctly for the GridAPPSD-Python library to process the simulation output correctly.
The format for the function definition is
def mySubscribeFunction(header, message):
# do something when receive a message
# parse to get measurments
# do some calculations
# publish some equipment commands
# display some results
That function handle is then passed as an argument to the .subscribe(topic, function_handle)
method when subscribing to the simulation in the next section.
Note that the subscription function definition does not allow any additional parameters to be passed. The only allowed arguments are header
and message
.
Any other parameters, such as measurement mRIDs will need to be defined as global variables.
[ ]:
# Define global python dictionary of position measurements
global Pos_obj
Pos_obj = [k for k in measurements_obj if k['type'] == 'Pos']
# Define global python dictionary of phase-neutral-voltage measurements (PNV)
global PNV_obj
PNV_obj = [k for k in measurements_obj if k['type'] == 'PNV']
# Define global python dictionary of volt-ampere apparent power measurements (VA)
VA_obj = [k for k in measurements_obj if k['type'] == 'VA']
# Current measurements (A)
A_obj = [k for k in measurements_obj if k['type'] == 'A']
Below is the sample code for the core section of a basic application that tracks the number of open switches and the number of switches that are outaged.
[ ]:
# Only allowed arguments are `header` and `message`
# message is simulation output message in format above
def DemoAppCoreFunction(header, message):
# Extract time and measurement values from message
timestamp = message["message"]["timestamp"]
meas_value = message["message"]["measurements"]
# Obtain list of all mRIDs from message
meas_mrid = list(meas_value.keys())
# Example 1: Count the number of open switches
open_switches = []
for index in Pos_obj:
if index["measid"] in meas_value:
mrid = index["measid"]
power = meas_value[mrid]
if power["value"] == 0: # Filter to measurements with value of zero
open_switches.append(index["eqname"])
# Print message to command line
print("............")
print("Number of open switches at time", timestamp, ' is ', len(set(open_switches)))
# Example 2: Count the number of outaged switches (voltage = 0)
dead_switches = []
for index in PNV_obj:
if index["measid"] in meas_value:
mrid = index["measid"]
voltage = meas_value[mrid]
if voltage["magnitude"] == 0.0:
dead_switches.append(index["eqname"])
# Print message to command line
print("............")
print("Number of outaged switches at time", timestamp, ' is ', len(set(dead_switches)))
App Core as a Class Definition
The second approach used to build the app core and process measurements is to define a class containing two methods named __init__
and on_message
.
These methods specify 1) how your app would initialize variables and attributes at the start of the simulation and 2) how your app behaves when it receives various messages.
IMPORTANT! The GridAPPS-D Platform uses the exact names and syntax for the methods:
__init__(self, simulation_id, gapps_object, optional_objects)
– This method requires the simulation_id and GridAPPS-D connection object. It is also possible add other user-defined arguments, such as measurement mRIDs or other information required by your application.on_message(self, headers, message)
– This method allows the class to subscribe to simulation measurements. It also contains the core behavior of your application and how it responds to each type of message.
It is also possible to use the same class definition to subscribe to other topics, such as Simulation Logs. This is done by creating additional user-defined methods and then passing those methods to the .subcribe()
method associated with the GridAPPS-D connection object. An example of how this is done is provided for subcribing to simulation logs in Logging with a Class Method.
class YourSimulationClassName(object):
# Your documentation text here on what app does
def __init__(self, simulation_id, gapps_obj, meas_obj, your_obj):
# Instantiate class with specific initial state
# Attributes required by Simulation API
self._gapps = gapps_obj
self._simulation_id = simulation_id
# Attributes to publish difference measurements
self.diff = DifferenceBuilder(simulation_id)
# Custom attributes for measurements, custom info
self.meas_mrid = meas_obj
self.your_attribute1 = your_obj["key1"]
self.your_attribute2 = your_obj["key2"]
def on_message(self, headers, message):
# What app should do when it receives a subscription message
variable1 = message["message"]["key1"]
variable2 = message["message"]["key2"]
# Insert your custom app behavior here
if variable1 == foo:
bar = my_optimization_result
# Insert your custom equipment commands here
if variable2 == bar:
self.diff.add_difference(object_mrid, control_attribute, new_value, old_value)
def my_custom_method_1(self, headers, message):
# Use extra methods to subscribe to other topics, such as simulation logs
variable1 = message["key1"]
variable2 = message["key2"]
def my_custom_method_2(self, param1, param2):
# Use extra methods as desired
variable1 = foo
variable2 = bar
Below is the sample code for the core section of a basic application that tracks the number of open switches and the number of switches that are outaged.
[ ]:
# Application core built as a class definition
class DemoAppCoreClass(object):
# Subscription callback from GridAPPSD object
def __init__(self, simulation_id, gapps_obj, meas_obj):
self._gapps = gapps_obj # GridAPPS-D connection object
self._simulation_id = simulation_id # Simulation ID
self.meas_mrid = meas_obj # Dictionary of measurement mRIDs obtained earlier
def on_message(self, headers, message):
# Extract time and measurement values from message
timestamp = message["message"]["timestamp"]
meas_value = message["message"]["measurements"]
# Filter measurement mRIDs for position and voltage sensors
Pos_obj = [k for k in self.meas_mrid if k['type'] == 'Pos']
PNV_obj = [k for k in self.meas_mrid if k['type'] == 'PNV']
# Example 1: Count the number of open switches
open_switches = []
for index in Pos_obj:
if index["measid"] in meas_value:
mrid = index["measid"]
power = meas_value[mrid]
if power["value"] == 0: # Filter to measurements with value of zero
open_switches.append(index["eqname"])
# Print message to command line
print("............")
print("Number of open switches at time", timestamp, ' is ', len(set(open_switches)))
# Example 2: Count the number of outaged switches (voltage = 0)
dead_switches = []
for index in PNV_obj:
if index["measid"] in meas_value:
mrid = index["measid"]
voltage = meas_value[mrid]
if voltage["magnitude"] == 0.0:
dead_switches.append(index["eqname"])
# Print message to command line
print("............")
print("Number of outaged switches at time", timestamp, ' is ', len(set(dead_switches)))
Subscribing to Simulation Output
Simulation Subscription Information Flow
The figure below shows the information flow involved in subscribing to the simulation output.
The subscription request is sent using gapps.subscribe(topic, class/function object)
on the specific Simulation topic channel (explained in API Communication Channels). No immediate response is expected back from the platform. However, after the next simulation timestep, the Platform will continue to deliver a complete set of measurements back to the application for each timestep until the end of the simulation.
Application passes subscription request to GridAPPS-D Platform
The subscription request is perfromed by passing the app core algorithm function / class definition to the gapps.subscribe
method. The application then passes the subscription request through the Simulation API to the topic channel for the particular simulation on the GOSS Message Bus. If the application is authorized to access simulation output, the subscription request is delivered to the Simulation Manager.
GridAPPS-D Platform delivers published simulation output to Application
Unlike the previous queries made to the various databases, the GridAPPS-D Platform does not provide any immediate response back to the application. Instead, the Simulation Manager will start delivering measurement data back to the application through the Simulation API at each subsequent timestep until the simulation ends or the application unsubscribes. The measurement data is then passed to the core algorithm class / function, where it is processed and used to run the app’s optimization / control algorithms.
Subscription API Communication Channel
This is a dynamic /topic/
communication channel that is best implemented by importing the GriAPPSD-Python library function for generating the correct topic. This communication channel is used for all simulation subscription API calls.
[ ]:
from gridappsd.topics import simulation_output_topic
output_topic = simulation_output_topic(viz_simulation_id)
Comparison of Subscription Approaches
Each approach has its advantages and disadvantages.
The function-based approach is simpler and easier to implement. However, any parameters obtained from other APIs or methods to be used inside the function currently need to be defined as global variables.
The class-based approach is more complex, but also more powerful. It provides greater flexibility in creating additional methods, arguments, etc.
The Simulation Library-based approach is easiest, but only works currently for parallel digital twin simulations started using the
simulation_obj.start_simulation()
method.
The choice of which approach is used depends on the personal preferences of the application developer.
Subscription for Function-based App Core
If the application core was created as a function definition as shown in App Core as Function Definition, then the function name is passed to the .subscribe(output_topic, core_function)
method of the GridAPPS-D Connection object.
[ ]:
conn_id = gapps.subscribe(output_topic, DemoAppCoreFunction)
Subscription for Class-Based App Core
If the application core was created as a class definition as shown in App Core as Class Definition, then the function name is passed to the .subscribe(output_topic, object)
method of the GridAPPS-D connection object.
After defining the class for the application core as shown above, we create another object that will be passed to the subscription method. The required parameters for this object are the same as those defined for the __init__()
method of the app core class, typically the Simulation ID, GridAPPS-D connection object, dictionary of measurements needed by the app core, and any user-defined objects.
class_obj = AppCoreClass(simulation_id, gapps_obj, meas_obj, your_obj)
[ ]:
demo_obj = DemoAppCoreClass(viz_simulation_id, gapps, measurements_obj)
conn_id = gapps.subscribe(subscribe_topic, demo_obj)
If we wish to subscribe to an additional topic (such as the Simulation Logs, a side communication channel between two different applications, or a communication with a particular service), we can define an additional method in the class (such as my_custom_method_1 in the example class definition above) and then pass it to to the .subscribe(topic, object.method)
method associated with the GridAPPS-D connection object:
gapps.subscribe(other_topic, demo_obj.my_custom_method_1)
Subscribing to Parallel Simulations
Parallel simulations started using the Simulation API (as shown in Starting a Simulation) and the Simulation
library in GridAPPSD-Python do not need to use the gapps.subscribe
method.
Instead, the GridAPPSD-Python library contains several shortcut functions that can be used. These methods currently cannot interact with a simulation started from the Viz. This functionality will be added in a future release.
The code block below shows how a parallel simulation can be started using a simulation start message stored in a JSON file. The simulation is started using the .start_simulation()
method.
[ ]:
import json, os
from gridappsd import GridAPPSD
from gridappsd.simulation import Simulation
# Connect to GridAPPS-D Platform
os.environ['GRIDAPPSD_USER'] = 'tutorial_user'
os.environ['GRIDAPPSD_PASSWORD'] = '12345!'
gapps = GridAPPSD()
assert gapps.connected
model_mrid = "_C1C3E687-6FFD-C753-582B-632A27E28507"
run123_config = json.load(open("Run123NodeFileSimAPI.json")) # Pull simulation config from saved file
simulation_obj = Simulation(gapps, run123_config) # Create Simulation object
simulation_obj.start_simulation() # Start Simulation
print("Successfully started simulation with simulation_id: ", simulation_obj.simulation_id)
[ ]:
simulation_id = simulation_obj.simulation_id
The Simulation library provides four methods that can be used to define how the platform interacts with the simulation:
.add_ontimestep_callback(myfunction1)
– Run the desired function on each timestep.add_onmesurement_callback(myfunction2)
– Run the desired function when a measurement is received..add_oncomplete_callback(myfunction3)
– Run the desired function when simulation is finished.add_onstart_callback(myfunction4)
– Run desired function when simulation is started
Note: method name ``.add_onmesurement_callback`` is misspelled in the library definition!!
Note that the measurement callback method returns just the measurements and timestamps without any of the message formatting used in the messages received by using the gapps.subscribe(output_topic, object)
approach.
The python dictionary returned by the GridAPPS-D Simulation output to the .add_onmesurement_callback()
method is always named measurements
and uses the following key-value pairs format:
{
'_pnv_meas_mrid_1': {'angle': number,
'magnitude': number,
'measurement_mrid': '_pnv_meas_mrid_1'},
'_va_meas_mrid_2': { 'angle': number,
'magnitude': number,
'measurement_mrid': '_va_meas_mrid_2'},
'_pos_meas_mrid_3': {'measurement_mrid': '_pos_meas_mrid_3',
'value': 1},
.
.
.
'_pnv_meas_mrid_n': {'angle': number,
'magnitude': number,
'measurement_mrid': '_pnv_meas_mrid_1'}
}
To use use these methods, we define a set of functions that determine the behavior of the application for each of the four types of callbacks listed above. These functions are similar to those defined for the function-based app core algorithm.
def my_onstart_func(sim):
# Do something when the simulation starts
# Do something else when the sim starts
simulation_obj.add_onstart_callback(my_onstart_func)
def my_onmeas_func(sim, timestamp, measurements):
# Do something when app receives a measurement
# Insert your custom app behavior here
if measurements[object_mrid] == foo:
bar = my_optimization_result
simulation_obj.add_onmesurement_callback(my_onmeas_func)
def my_oncomplete_func(sim):
# Do something when simulation is complete
# example: delete all variables, close files
simulation_obj.add_oncomplete_callback(my_oncomplete_func)
The code block below shows how the same app core algorithm can be used for a parallel simulation using the .add_onmesurement_callback()
method:
[ ]:
def demo_onmeas_func(sim, timestamp, measurements):
open_switches = []
for index in Pos_obj:
if index["measid"] in measurements:
mrid = index["measid"]
power = measurements[mrid]
if power["value"] == 0:
open_switches.append(index["eqname"])
print("............")
print("Number of open switches at time", timestamp, ' is ', len(set(open_switches)))
[ ]:
simulation_obj.add_onmesurement_callback(demo_onmeas_func)
Publishing Commands to Simulation Input
The next portion of a GridAPPS-D App is publishing equipment control commands based on the optimization results or objectives of the app algorithm.
Depending on the preference of the developer, this portion can be a separate function definition, or included as part of the main class definition as part of the App Core as a Class Definition described earlier.
Equipment Command Information Flow
The figure below outlines information flow involved in publishing equipment commands to the simulation input.
Unlike the various queries to the databases in the app sections earlier, equipment control commands are passed to the GridAPPS-D API using the gapps.send(topic, message)
method. No response is expected from the GridAPPS-D platform.
If the application desires to verify that the equipment control command was received and implemented, it needs to do so by 1) checking for changes in the associated measurements at the next timestep and/or 2) querying the Timeseries Database for historical simulation data associated with the equipment control command.
Application sends difference message to GridAPPS-D Platform
First, the application creates a difference message containing the current and desired future control point / state of the particular piece of power system equipment to be controlled. The difference message is a JSON string or equivalant Python dictionary object. The syntax of a difference message is explained in detail below in Format of Difference Message.
The application then passes the query through the Simulation API to the GridAPPS-D Platform, which publishes it on the topic channel for the particular simulation on the GOSS Message Bus. If the app is authenticated and authorized to control equipment, the difference message is delivered to the Simulation Manager. The Simulation Manager then passes the command to the simulation through the Co-Simulation Bridge (either FNCS or HELICS).
No response from GridAPPS-D Platform back to Application
The GridAPPS-D Platform does not provide any response back to the application after processing the difference message and implementing the new equipment control setpoint.
Simulation Input API Channel
This is a dynamic /topic/
communication channel that is best implemented by importing the GriAPPSD-Python library function for generating the correct topic.
from gridappsd.topics import simulation_input_topic
input_topic = simulation_input_topic(simulation_id)
[ ]:
from gridappsd.topics import simulation_input_topic
input_topic = simulation_input_topic(viz_simulation_id)
Equipment Control mRIDs
The mRIDs for controlling equipment are generally the same as those obtained using the QUERY_OBJECT_DICT
key with the PowerGrid Models API, which was covered in Query for Object Dicionary.
However, the control attributes for each class of equipment in CIM use a different naming convention than those for the object types. Below is a list of "objectType"
used to query for mRIDs and the associated control attribute used in a difference message for each category of power system equipment:
Switches
CIM Class Key:
"objectType": "LoadBreakSwitch"
Control Attribute:
"attribute": "Switch.open"
Values:
1
is open,0
is closed
Capacitor Banks:
CIM Class Key:
"objectType": "LinearShuntCompensator"
Control Attribute:
"attribute": "ShuntCompensator.sections"
Values:
0
is off/open,1
is on/closed
Inverter-based DERs:
CIM Class Key:
"objectType": "PowerElectronicsConnection"
Control Attribute:
"attribute": "PowerElectronicsConnection.p"
Control Attribute:
"attribute": "PowerElectronicsConnection.q"
Values: number in Watts or VArs (not kW)
Synchronous Rotating (diesel) DGs:
CIM Class Key:
"objectType": "SynchronousMachine"
Control Attribute:
"attribute": "RotatingMachine.p"
Control Attribute:
"attribute": "RotatingMachine.q"
Values: number in Watts or VArs (not kW)
Regulating Transformer Tap:
CIM Class Key:
"objectType": "RatioTapChanger"
Control Attribute:
"attribute": "TapChanger.step"
Values: integer value for tap step
The query for RatioTapChanger is not supported in the PowerGrid Models API at the current time. A custom SPARQL query needs to be done using the sample query in `CIMHub Sample Queries <https://github.com/GRIDAPPSD/CIMHub/blob/master/queries.txt>`__
The example below shows a query to obtain the correct mRID for switch SW2 in the IEEE 123 node model:
[ ]:
from gridappsd import topics as t
message = {
"modelId": model_mrid,
"requestType": "QUERY_OBJECT_DICT",
"resultFormat": "JSON",
"objectType": "LoadBreakSwitch"
}
response_obj = gapps.get_response(t.REQUEST_POWERGRID_DATA, message)
switch_dict = response_obj["data"]
# Filter to get mRID for switch SW2:
for index in switch_dict:
if index["IdentifiedObject.name"] == 'sw2':
sw_mrid = index["IdentifiedObject.mRID"]
Format of a Difference Message
The general format for a difference message is a python dictionary or equivalent JSON string that specifies the reverse difference and the forward difference, in compliance with the CIM standard:
The reverse difference is the current status / value associated with the control attribute. It is a formatted as a list of dictionary constructs, with each dictionary specifying the equipment mRID associated with the CIM class keys above, the control attribute, and the current value of that control attribute. The list can contain reverse differences for multiple pieces of equipment.
The forward difference is the desired new status / value associated with the control attribute. It is a formatted as a list of dictionary constructs, with each dictionary specifying the equipment mRID associated with the CIM class keys above, the control attribute, and the current value of that control attribute. The list can contain foward differences for multiple pieces of equipment.
message = {
"command": "update",
"input": {
"simulation_id": "simulation id as string",
"message": {
"timestamp": epoch time number,
"difference_mrid": "optional unique mRID for command logs",
"reverse_differences": [{
"object": "first equipment mRID",
"attribute": "control attribute",
"value": current value
},
{
"object": "second equipment mRID",
"attribute": "control attribute",
"value": current value
}
],
"forward_differences": [{
"object": "first equipment mRID",
"attribute": "control attribute",
"value": new value
},
{
"object": "second equipment mRID",
"attribute": "control attribute",
"value": new value
}
]
}
}
}
Note: The GridAPPS-D platform does not validate whether "reverse_differences":
has the correct equipment control values for the current time. It is used just for compliance with the CIM standard.
Using GridAPPSD-Python DifferenceBuilder
The DifferenceBuilder
class is a GridAPPSD-Python tool that can be used to automatically build the difference message with correct formatting.
First, import DifferenceBuilder from the GridAPPSD-Python Library and create an object that will be used to create the desired difference messages.
[ ]:
from gridappsd import DifferenceBuilder
my_diff_build = DifferenceBuilder(viz_simulation_id)
We then use two methods associated with the DifferenceBuilder object:
.add_difference(self, object_mrid, control_attribute, new_value, old_value)
– Generates a correctly formatted difference message..get_message()
– Saves the message as a python dictionary that can be published usinggapps.send(topic, message)
[ ]:
my_diff_build.add_difference(sw_mrid, "Switch.open", 1, 0) # Open switch given by sw_mrid
message = my_diff_build.get_message()
The difference message is then published to the GOSS Message Bus and the Simulation API using the .send()
method associated with the GridAPPS-D connection object.
[ ]:
gapps.send(input_topic, message)
Unsubscribing from a Simulation
To unsubscribe from a simulation, pass the connection ID to .unsubscribe(conn_id)
method of the GridAPPS-D connection object. The connection ID was obtained earlier when subscribing using conn_id = gapps.subscribe(topic, message)
.
[ ]:
gapps.unsubscribe(conn_id)
Using the Timeseries API
Introduction to the Timeseries API
The Timeseries API is used to query the Influx Database, which stores measurement data from simulations. The API calls can be used to * obtain weather data * obtain measurements from simuation data using measurement mRIDs * obtain equipments commands and other simulation input data * obtain simulated field data from the Sensor Service
API Syntax Overview
Application passes query to GridAPPS-D Platform
First, the application creates a query message for requesting information about the desired power system components in the format of a JSON string or equivalant Python dictionary object. The syntax of this message is explained in detail below.
The query is sent using the gapps.get_response(topic, message)
method on the Timeseries queue channel with a response expected back from the GridAPPS-D platform within the specified timeout period.
The application then passes the query through the Timeseries API to the GridAPPS-D Platform, which publishes it to the goss.gridappsd.process.request.data.timeseries
queue channel on the GOSS Message Bus. If the app is authenticated and authorized to pass queries, the query message is delivered to the Data Managers, which obtain the desired information from the Timeseries Influx Database.
GridAPPS-D Platform responds to Application query
The Data Managers then publish the response from the Timeseries Influx Database to the appropriate queue channel. The Timeseries API then returns the desired information back to the application as a JSON message or equivalant Python dictionary object.
API Communication Channel
API calls to the timeseries databases use a static /queue/
channel, which was covered in Lesson 1.4. The topic can be specified as a text string or by importing the topics library:
Text String: The topic can be specified as a static string:
topic = "goss.gridappsd.process.request.data.timeseries"
gapps.get_response(topic, message)
GridAPPSD-Python Library Method: The correct topic can also be imported from the GridAPPSD-Python topics library:
from gridappsd import topics as t
gapps.get_response(t.TIMESERIES, message)
Structure of a Query Message
Queries passed to Timeseries API are formatted as python dictionaries or equivalent JSON scripts wrapped as a python string.
The accepted set of key-value pairs for the Timeseries API query message is
message = """
{
"queryMeasurement": "INSERT QUERY HERE",
"queryFilter": {"key1": "value1"
"key2": "value2"},
"responseFormat": "JSON"
}
The components of the message are as follows:
"queryMeasurement":
– Specifies the type of measurement being requested. Allowed queryMeasurement values are listed in the next section."queryFilter":
– Filters the measurements to just the set values desired by the application. The set of allowed values depends on the value associated with queryMeasurement."responseFormat":
– Specifies the format of the response, can be"JSON"
,"CSV"
, or"XML"
. (CAUTION: the Timeseries API uses the key reponseFormat, while the PowerGridModel API uses the key resultFormat. Using the wrong key for either API will result in a java.lang error.)
The usage of each of these message components are explained in detail with code block examples below.
Important: Be sure to pay attention to placement of commas ( , ) at the end of each line. Commas are placed at the end of each line except the last line. Incorrect comma placement will result in a JsonSyntaxException.
All of the queries are passed to the Timeseries API using the .get_response(topic, message)
method for the GridAPPS-D platform connection variable.
Specifying the queryMeasurement value
Below are the allowable values associated with the queryMeasurement
key, which are used to specify the type of data requested by each query. Executable code block examples are provided for each of the requests in the subsections below.
"queryMeasurement": "weather"
– Query for weather data"queryMeasurement": "simulation"
– Query for simulation output data and query for simulation intput data"queryMeasurement": "gridappsd-sensor-simulator"
– Query for sensor service data
Querying for Timeseries Data
This section outlines the details of key-value pairs for the possible queries associated with each value of the queryMeasurement
key listed above.
Querying for Weather Data
Interpreting GridAPPS-D Weather Data
The weather data is based on exported data collected from the Solar Radiation Research Laboratory (39.74N,105.18W,1829 meter elevation) January - December 2013. The original dataset was based in Mountain Standard Time (MST).
The original column names included engineering units, but could not be included during data import. Below is a mapping between the exported column headers and the fields in the Influx database management system.
Original Exported Data Influx Measurement Field Key Field Type
------------------------------------ ---------------------------- ----------
DATE (MM/DD/YYYY) DATE String
MST MST String
Global CM22 (vent/cor) [W/ft^2] GlobalCM22 Float
Direct CH1 [W/ft^2] DirectCH1 Float
Diffuse CM22 (vent/cor) [W/ft^2] Diffuse Float
Tower Dry Bulb Temp [deg F] TowerDryBulbTemp Float
Tower RH [%] TowerRH Float
Avg Wind Speed @ 42ft [MPH] AvgWindSpeed Float
Avg Wind Direction @ 42ft [deg from N] AvgWindDirection Float
Original Exported Data Influx Measurement Tag Type
------------------------------------ ---------------------------- ----------
n/a lat String
n/a long String
n/a place String
Querying Weather Data
GridAPPS-D contains one year of weather data (details given in next subsection), which can be obtained with the following query
Measurement request key-value pair:
"queryMeasurement": "weather"
Allowed key-value pairs for queryFilter
:
"queryFilter": { KEY VALUE
"startTime": epoch time number,
"endTime": epoch time number,
"AvgWindDirection": number,
"AvgWindSpeed": number,
"Diffuse": number,
"DirectCH1": number,
"GlobalCM22": number,
"MST": number,
"TowerDryBulbTemp": number,
"TowerRH": number,
"lat": string,
"long": string,
"place": string }
Not all of the queryFilter
key-value pairs need to be used. These are filters that can be used to restrict the returned data to particular values.
Note: The Timeseries API currently does not support querying for a range of values (e.g. all data for temperature betweeen 25 and 30C). This functionality will be added in a future release. Queries are currently limited to a single value.
Example 1: query for just the data between a given ``”startTime”`` and ``”endTime”``:
[ ]:
topic = "goss.gridappsd.process.request.data.timeseries" # Specify Timeseries API GridAPPS-D topic
# Use queryFilter of "startTime" and "endTime"
message = {
"queryMeasurement":"weather",
"queryFilter":{"startTime":"1357048800000000",
"endTime":"1357048860000000"},
"responseFormat":"JSON"
}
gapps.get_response(topic, message) # Pass API call
Example 2: Query for weather data of particular values:
[ ]:
topic = "goss.gridappsd.process.request.data.timeseries" # Specify Timeseries API GridAPPS-D topic
# Use queryFilter of "TowerDryBulbTemp" and "AvgWindSpeed"
message = {
"queryMeasurement":"weather",
"queryFilter":{"TowerDryBulbTemp": 30.0326,
"AvgWindSpeed": 7.4624},
"responseFormat":"JSON"
}
gapps.get_response(topic, message) # Pass API call
Query for Simulation Output Data
All of the measurement output from a simulation is stored in the Influx Database and can be queried with the Timeseries API
Measurement request key-value pair:
"queryMeasurement": "simulation"
Allowed key-value pairs for queryFilter
for output data
"queryFilter": { KEY VALUE
"startTime": epoch time number ,
"endTime": epoch time number ,
"measurement_mrid": string OR [array of string values] ,
"simulation_id": numeric string ,
"hasSimulationMessageType": "OUTPUT" OR "INPUT" ,
"angle": number ,
"magnitude": number }
In the Getting Started section of this tutorial, we started a demo simulation of the IEEE 123 node model. That simulation has now completed, and we can pass queries to the Timeseries API to retrieve measurements from the completed simulation.
Example 1: Query for all measurements between a ``”startTime”`` and ``”endTime”``
[ ]:
topic = "goss.gridappsd.process.request.data.timeseries" # Specify Timeseries API GridAPPS-D topic
# Use queryFilter of "startTime" and "endTime"
message = {
"queryMeasurement": "simulation",
"queryFilter": {
"simulation_id": simulation_id,
"startTime": "1570041130",
"endTime": "1570041140"},
"responseFormat": "JSON"
}
gapps.get_response(topic, message) # Pass API call
Example 2: Query for all measurements associated with list of measurement mRIDs
[ ]:
topic = "goss.gridappsd.process.request.data.timeseries" # Specify Timeseries API GridAPPS-D topic
# Query for a particular set of measurments
message = {
"queryMeasurement":"simulation",
"queryFilter":{"simulation_id": simulation_id,
"measurement_mrid":["_5efa022e-da12-4c33-b127-10186624a8f7","_4c515f50-51df-494a-a860-653c0c874fe1"]},
"responseFormat":"JSON"
}
gapps.get_response(topic, message) # Pass API call
[ ]:
topic = "goss.gridappsd.process.request.data.timeseries" # Specify Timeseries API GridAPPS-D topic
# Query for a particular set of measurments
message = {
"queryMeasurement":"simulation",
"queryFilter":{"simulation_id": "1313108762",
"measurement_mrid":"_63CDE28F-FFC9-4869-BC12-EC3244A056CA"},
"responseFormat":"JSON"
}
gapps.get_response(topic, message) # Pass API call
Query for Simulation Input Data
All of the equipment control commands and other input data from a simulation is stored in the Influx Database and can be queried with the Timeseries API
Measurement request key-value pair:
"queryMeasurement": "simulation"
Allowed key-value pairs for queryFilter
for output data
"queryFilter": { KEY VALUE
"startTime": epoch time number ,
"endTime": epoch time number ,
"measurement_mrid": mRID string OR [array of string values] ,
"simulation_id": numeric string ,
"hasSimulationMessageType": "OUTPUT" OR "INPUT" ,
hasMeasurementDifference "FORWARD" OR "REVERSE" ,
attribute string ,
difference_mrid mRID string ,
object string ,
value number }
Known issue in GridAPPS-D releases_2019.09.0: Events passed from the Test Manager or from a Configuration File are not registering correctly in the Influx database. Simulation Input from operator control actions in the viz are being stored correctly. For this example, run a simulation of the 123 Node Model in the Viz and open any switch. Then copy the simulation_id and paste it into the first code block below.
Example 1: Query for all simulation input commands
[ ]:
viz_simulation_id = "602611015"
[ ]:
topic = "goss.gridappsd.process.request.data.timeseries" # Specify Timeseries API GridAPPS-D topic
# Query for all equipment command inputs passed to simulation
message = {
"queryMeasurement": "simulation",
"queryFilter": {
"simulation_id": viz_simulation_id,
"hasSimulationMessageType": "INPUT"},
"responseFormat": "JSON"
}
gapps.get_response(topic, message) # Pass API call
Query for Sensor Service Data
Using the Sensor Service
The GridAPPS-D Sensor Service simulates the noise and packet losses of real field device measurements based upon the magnitude of “prestine” simulated values from the GridLab-D simulation. This service has been specifically designed to work within the gridappsd platform container. The GridAPPS-D platform will start the service when it is specified as a dependency of an application or when a service configuration is specified within the GridAPPS-D Visualization.
Python Application Usage: The python application using this service should require gridappsd-sensor-simulator as a requirement. In addition, the following python code shows how to get the correct topic for the service.
Service Configuration: The sensor-config in the above image shows an example of how to configure a portion of the system to have sensor output. Each mrid (such as _99db0dc7-ccda-4ed5-a772-a7db362e9818
) will be monitored by this service and either use the default values or use the specified values during the service runtime.
The general format for the Sensor Service configuration message is
{
"_99db0dc7-ccda-4ed5-a772-a7db362e9818": {
"nominal-value": 100,
"perunit-confidence-band": 0.01,
"aggregation-interval": 30,
"perunit-drop-rate": 0.01
},
"_ee65ee31-a900-4f98-bf57-e752be924c4d":{},
"_f2673c22-654b-452a-8297-45dae11b1e14": {}
}
The other options for the service are:
"default-perunit-confidence-band"
"default-aggregation-interval"
"default-perunit-drop-rate"
"passthrough-if-not-specified"
These options will be used when not specified within the sensor-config block.
Note: Currently the nominal-value is not looked up from the database. At this time services aren’t able to tell the platform when they are “ready”. This will be implemented in the near future and then all of the nominal-values will be queried from the database.
A complete example of Sensor Service configuration is available in the sample python script Run123NodeSensorServiceDemo.py for three measurements in the IEEE 123 Node Model generated over a two minute simulation.
Querying Sensor Service Data
All of the simulated field measurements created by the Sensor Service are stored in the Influx Database and can be queried using the Timeseries API:
Measurement request key-value pair:
"queryMeasurement": "gridappsd-sensor-simulator"
Allowed key-value pairs for queryFilter
for output data
"queryFilter": { KEY VALUE
"startTime": number ,
"endTime": number ,
"measurement_mrid": string OR [array of string values] ,
"simulation_id": string ,
"angle": number ,
"magnitude": number ,
"value" number }
Example 1: Query for all Sensor Service Data between a given ``”startTime”`` and ``”endTime”``:
[ ]:
topic = "goss.gridappsd.process.request.data.timeseries" # Specify Timeseries API GridAPPS-D topic
# Query for all Sensor Service Data in time range:
message = {
"queryMeasurement": "gridappsd-sensor-simulator",
"queryFilter": {"simulation_id": simulation_id,
"startTime": "1570041130",
"endTime": "1570041140"},
"responseFormat": "JSON"
}
gapps.get_response(topic, message) # Pass API call
Using the Logging API
Introduction to the Logging API
The Logging API enables applications to subscribe to real-time log messages from a simulation, query previously logged messages from the MySQL database, and publish messages to their either own log or their GridAPPS-D logs.
API Communication Channel
As with the Simulation API, the logging API uses both static /queue/
and dynamic /topic/
communication channel names depending on whether the API is being used for real-time simulation logs or historic logs that have already been saved in the database.
For a review of GridAPPS-D topics, see Lesson 1.4.
The correct topic for each Logging API call will be provided in the corresponding section for each API task below.
Message Structure
Logging messages in the GridAPPS-D environment follow the format of a python dictionary or equivalent JSON string with the format below.
{ KEY VALUE
"source": filename,
"processId": simulation_id,
"timestamp": epoch time number,
"processStatus": "STARTED" or "STOPPED" or "RUNNING" or "ERROR" or "PASSED" or "FAILED",
"logMessage": string,
"logLevel": "INFO" or "DEBUG" or "ERROR",
"storeToDb": true or false
}
All of the messages from a single instantiation will have the same format, with the only difference being the logMessage. As a result, it is possible to use the shortcuts available from the GridAPPSD-Python library to build out the repetitive portions of the message and pass just the logMessage string.
GridAPPSD-Python Logging API Extensions
The GridAPPSD-Python library uses several extensions to the standard Python logging library that enable applications to easily create log messages using the same syntax. These extensions support the additional log message formatting required by GridAPPS-D, such as simulation_id, log source, and process status.
The following code block enables the
[ ]:
import logging
import os
os.environ['GRIDAPPSD_APPLICATION_ID'] = 'gridappsd-sensor-simulator'
os.environ['GRIDAPPSD_APPLICATION_STATUS'] = 'STARTED'
os.environ['GRIDAPPSD_SIMULATION_ID'] = opts.simulation_id
Important! Run this import command *BEFORE* creating the GridAPPS-D connection object gapps = GridAPPSD(...)
.
Note: If your application is containerized in Docker and registered with the GridAPPS-D platform using the docker-compose file, these extensions will be imported automatically.
Subscribing to Simulation Logs
Similar to the two approaches used to subscribe to simulation measurements discussed in Comparison of Subscription Approaches, it is possible to use either a function or a class definition to subscribe to the simulation logs.
Subscription API Communication Channel
This is a dynamic /topic/
communication channel that is best implemented by importing the GriAPPSD-Python library function for generating the correct topic.
from gridappsd.topics import simulation_log_topic
log_topic = simulation_log_topic(simulation_id)
Note on Jupyter Notebook environment: In the examples below, the Jupyter Notebook environment does not update definitions of the subscription object or function definitions. As a result, it is necessary to restart the notebook kernel. The gapps connection object definition is included again for convenience in executing the notebook code blocks
[3]:
viz_simulation_id = "paste sim id here"
# Establish connection to GridAPPS-D Platform:
from gridappsd import GridAPPSD
# Set environment variables - when developing, put environment variable in ~/.bashrc file or export in command line
# export GRIDAPPSD_USER=system
# export GRIDAPPSD_PASSWORD=manager
import os # Set username and password
os.environ['GRIDAPPSD_USER'] = 'tutorial_user'
os.environ['GRIDAPPSD_PASSWORD'] = '12345!'
# Connect to GridAPPS-D Platform
gapps = GridAPPSD(viz_simulation_id)
assert gapps.connected
[ ]:
from gridappsd.topics import simulation_log_topic
log_topic = simulation_log_topic(viz_simulation_id)
Note on Jupyter Notebook environment: In the examples below, the Jupyter Notebook environment does not update definitions of the subscription object or function definitions. As a result, it is necessary to restart the notebook kernel. The gapps connection object definition is included again for convenience in executing the notebook code blocks
Subscribing using a Function Definition
The first approach used to subscribe to measurements is to define a function with the correct set of arguments that is then passed to the .subscribe()
method associated with the GridAPPPSD()
object.
The function does not require a specific name, and is somewhat easier to define and use. However, the arguments of the function need to be named correctly for the GridAPPSD-Python library to process the simulation output correctly.
The format for the function definition is
def myLogFunction(header, message):
# do something when receive a log message
# do something else
That function handle is then passed as an argument to the .subscribe(topic, function_handle)
method:
[ ]:
def demoLogFunction(header, message):
timestamp = message["timestamp"]
log_message = message["logMessage"]
print("Log message received at timestamp ", timestamp, "which reads:")
print(log_message)
print("........................")
[ ]:
gapps.subscribe(log_topic, demoLogFunction)
Subscribinb using a Class Definition
The second approach used to subscribe to simulation logs is to define add a custom method to the same class with __init__
and on_message
methods that was created to subscribe to measurements.
Unlike the Simulation API, the Logging API does not require a specific name for the method used to subscribe to log messages.
It is possible to create additional methods in the subscription class definition to enable the app to subscribe to additional topics, such as the simulation log topic, as shown in the example below.
[ ]:
class PlatformDemo(object):
# A simple class for interacting with simulation
def __init__(self, simulation_id, gapps_obj):
# Initialize variables and attributes
self._gapps = gapps_obj
self._simulation_id = simulation_id
# self.foo = bar
def on_message(self, headers, message):
# Do things with measurements
meas_value = message["message"]["measurements"]
# Do more stuff with measurements
def my_logging_method(self, headers, message):
timestamp = message["timestamp"]
log_message = message["logMessage"]
print("Log message received at timestamp ", timestamp, "which reads:")
print(log_message)
print("........................")
[ ]:
# Create subscription object
demo_obj = PlatformDemo(viz_simulation_id, gapps)
# Subscribe to logs using method
gapps.subscribe(log_topic, demo_obj.my_custom_method)
Publishing to Simulation Logs
The GridAPPSD-Python library enables use of the standard Python logging syntax to create logs, publish them to the GOSS Message Bus, and store them in the MySQL database.
Documentation of the standard Python logging library is available on Python Docs.
It is possible to publish to either local app logs (which are more useful for debugging) or the GridAPPS-D logs (which can be accessed by other applications and should be used for completed applications).
Publishing to Local App Logs
The first approach is to use the default Python logger to write to local app logs by importing the logging
library and then use the .getLogger()
method from the Python library.
[6]:
import logging
python_log = logging.getLogger(__name__)
Log messages can then be published by invoking the methods
python_log.debug("log message")
python_log.info("log message")
python_log.warning("log message")
python_log.error("log message")
python_log.fatal("log message")
Publishing to GridAPPS-D Logs
The second approach is to use the GridAPPS-D logs. Importing the python logging library is not necessary. Instead initialize a logging object using the .get_logger()
method associated with the GridAPPS-D connection object. Note the difference in spelling of the GridAPPS-D Library and default Python Library methods.
[5]:
gapps_log = gapps.get_logger()
Log messages can then be published by invoking the methods
gapps_log.debug("log message")
gapps_log.info("log message")
gapps_log.warning("log message")
gapps_log.error("log message")
gapps_log.fatal("log message")
Querying Saved Logs
Log messages published using the Logging API and the GOSS Message Bus are saved to the MySQL database. These log messages can be accessed with a Logging API query.
Log Query API Communication Channel
The query for logs uses a static /queue/
channel that is imported from the GridAPPS-D Topics library.
This topic is used with the .get_response(topic, message)
method associated with the GridAPPS-D connection object.
from gridappsd import topics as t
gapps.get_response(t.LOGS, message)
Structure of the Log Query Message
The first approach to querying with the Logging API is to use a python dictionary or equivalent JSON string that follows formatting similar to the query messages used by all the other GridAPPS-D APIs:
[ ]:
from gridappsd import topics as t
message = {
"source": "ProcessEvent",
"processId": viz_simulation_id,
"processStatus": "INFO",
"logLevel": "INFO"
}
gapps.get_reponse(t.LOGS, message)
Resilient Restoration (WSU)
An advanced distribution management system (ADMS) supports grid management and decision support applications to address the growing operational challenges faced by the modern electric power distribution systems while ensuring reliable and resilient operations. In this document, we describe the development of the proposed fault location, isolation, and restoration (FLISR) and it’s integration with an open-source standards-based platform for ADMS application development viz. GridAPPS-D, developed by Pacific Northwest National Laboratory (PNNL).
Essentially, an ADMS allows for applications that can readily access information from various systems including, but not limited to Distributed Energy Resource Management System (DERMS), Supervisory Control and Data Acquisition (SCADA), Outage Management Systems (OMS), Graphical Information Management Systems (GIS), and Advanced Metering Infrastructure (AMI). Recently, researchers at PNNL developed an open-source ADMS application development platform, GridAPPS-D, that provides an open-source, extensible application development environment. These new developments call for research not only on advanced applications for the distribution systems that leverage the interoperability of the ADMS platform but also on providing a proof-of-concept for integrating such advanced applications into the future ADMS.
Overview
The electric power distribution system is facing a magnitude of challenges due to an increase in severe weather events leading to widespread network outages, coupled with the growing regulatory requirements for increased reliability and resilience, reduced carbon emissions, and growing distributed energy resources (DER) penetrations. The Fault Location Isolation and Service Restoration (FLISR) is one of the most critical applications currently being adopted by the majority of distribution companies and made available by most ADMS vendors to manage system outages [CIT1].
This report documents the restoration application developed by Washington State University (WSU) and demonstrate its functionality by integrating it with a standards-based open-source platform – GridAPPS-D, developed by the Pacific Northwest National Laboratory (PNNL).
Application Architecture
The proposed restoration application can be implemented in an advanced distribution management system (ADMS) as shown in Figure 1. Figure shows the overall architecture of a modern DMS with integration of several subsystems such as customer information system (CIS), geographical information system (GIS), interactive voice response (IVR), advanced metering infrastructure (AMI), SCADA and flowchart of the proposed DSR framework. Once a power outage happens, three specific tasks are performed in the DMS to restore the power to out-of-service area:
Information Collection: To monitor the power distribution system condition and gather resource information.
Information Processing: For system model identification and fault location.
Service Restoration: To find the candidate switch and generate DER control signals for circuit reconfiguration.
Figure 1: Architecture of a modern distribution management system and flowchart of the proposed restoration application.
Leveraging the GridAPPS-D Platform
The realization of an autonomous restoration application requires a measurement and control environment that provides post-fault situational awareness and the ability to remotely deploy the decisions for restoration. GridAPPS-D is an open-source, standards-based platform designed to support the development of advanced, data-driven distribution system operation and/or planning applications that take advantage of the data-rich environment expected in modernized electric power distribution systems with smart grid technologies.
Figure 2 shows a schematic for the interaction and communication among the distribution system operational sub-system for the proposed restoration application. The platform is typically integrated with other related data and decision-support systems/subsystems such as DERMS, SCADA, OMS, GIS, AMI, CIS to: a) monitor the distribution system conditions, b) obtain the DER availability and operating conditions, and c) for load estimation and control.
Figure 2: Integration of proposed application to the GridAPPS-D platform. GOSS/FNCS is the PNNL’s platform for data exchange among subsystems. GOSS: GridOPTICS Software System; FNCS: Framework for network simulation.
Definition of Terms
Fault - Opening of normally-closed switch in response to any abnormal operating condition on its downstream.
Platform - Refers to GridAPPS-D platform.
Simulation - A real world distribution system currently done by GridLAB-D
Simulator - In current release GridLAB-D serves as the simulator.
CPLEX - A commercial optimization software package for solving the large-scale optimization problem
GridLAB-D - GridLAB-D is a distribution level powerflow simulator. It acts as the real world distribution system in GridAPPS-D.
Power System Model - A modified IEEE 8500-node feeder is used as the test case
References
- CIT1
A. Dubey, A. Bose, M. Liu and L. N. Ochoa, “Paving the Way for Advanced Distribution Management Systems Applications: Making the Most of Models and Data,” in IEEE Power and Energy Magazine, vol. 18, no. 1, pp. 63-75, Jan.-Feb. 2020
- CIT2
S. Poudel, A. Dubey and K. P. Schneider, “A Generalized Framework for Service Restoration in a Resilient Power Distribution System,” Submitted to IEEE Systems Journal (Under Revision)
- CIT3
S. Poudel and A. Dubey, “Critical Load Restoration Using Distributed Energy Resources for Resilient Power Distribution System,” in IEEE Transactions on Power Systems, vol. 34, no. 1, pp. 52-63, Jan. 2019.
- CIT4
S. Poudel, A. Dubey and A. Bose, “Risk-Based Probabilistic Quantification of Power Distribution System Operational Resilience,” in IEEE Systems Journal, doi: 10.1109/JSYST.2019.2940939.
- CIT5
S. Poudel and A. Dubey, “A Graph-theoretic Framework for Electric Power Distribution System Service Restoration,” 2018 IEEE Power & Energy Society General Meeting (PESGM), Portland, OR, 2018, pp. 1-5.
- CIT6
S. Poudel, A. Dubey, P. Sharma, and K. P. Schneider, “A Standalone FLISR Application Using GridAPPS-D – Standards-Based Open-Source ADMS Platform,” in prep for IEEE Power and Energy Technology Systems Journal
- CIT7
S. Poudel, A. Dubey, and A. Bose, “Probabilistic Quantification of Power Distribution System Operational Resilience,” 2019 IEEE Power & Energy Society General Meeting (PESGM), Atlanta, GA, 2019, pp. 1-5
- CIT8
S. Poudel, M. Mukherjee and A. Dubey, “Optimal Positioning of Mobile Emergency Resources for Resilient Restoration,” 2018 North American Power Symposium (NAPS), Fargo, ND, 2018, pp. 1-6.
- CIT9
W. H. Kersting, “Radial distribution test feeders,” in 2001 IEEE Power Engineering Society Winter Meeting. Conference Proceedings (Cat. No.01CH37194), 2001, pp. 908-912 vol.2.
- CIT10
R. F. Arritt and R. C. Dugan, “The IEEE 8500-node test feeder,” in IEEE PES T&D 2010, pp. 1-6.
Contact Us
WSU team can be reached at shiva.poudel@wsu.edu or anamika.dubey@wsu.edu.
For more information about the lab, Click Here
Installing GridAPPS-D
GridAPPS-D is available using docker containers
Requirements
git
docker version 17.12 or higher
docker-compose version 1.16.1 or higher
Install Docker on Ubuntu
Clone or download the repository
gridappsd@gridappsd-VirtualBox:~$ git clone https://github.com/GRIDAPPSD/gridappsd-docker
gridappsd@gridappsd-VirtualBox:~$ cd gridappsd-docker
run the docker-ce installation script
gridappsd@gridappsd-VirtualBox:~/gridappsd-docker$ ./docker_install_ubuntu.sh
log out of your Ubuntu session and log back in to make the docker groups change active
Application Setup
Download the application
Clone or download the repository. The updated code is in the develop branch.
gridappsd@gridappsd-VirtualBox:~$ git clone https://github.com/shpoudel/WSU-Restoration -b develop
gridappsd@gridappsd-VirtualBox:~$ cd WSU-Restoration
Creating the application container
From the command line execute the following commands to build the wsu-restoration container. Note that there is a dot at end of command.
gridappsd@gridappsd-VirtualBox:~/WSU-Restoration$ docker build --network=host -t wsu-restoration-app .
Mount the application
Add following to the docker-compose.yml file if CPLEX is available
wsu_res_app:
image: wsu-restoration-app
volumes:
- /opt/ibm/ILOG/CPLEX_Studio129/:/opt/ibm/ILOG/CPLEX_Studio129
environment:
GRIDAPPSD_URI: tcp://gridappsd:61613
depends_on:
- gridappsd
Add following to the docker-compose.yml file if CPLEX is not available. In addition, replace prob.solve(CPLEX(msg=1)) with prob.solve() in restoration_WSU.py
wsu_res_app:
image: wsu-restoration-app
environment:
GRIDAPPSD_URI: tcp://gridappsd:61613
depends_on:
- gridappsd
Starting Service
Start the docker container services
Note that this documentation is based on develop tag
gridappsd@gridappsd-VirtualBox:~/gridappsd-docker$ ./run.sh -t develop
- The run.sh does the following
download the mysql dump file
download the blazegraph data
start the docker containers
ingest the blazegraph data
connect to the gridappsd container
The message in the container looks something like this:
Starting gridappsddocker_redis_1 ...
Starting gridappsddocker_proven_1 ...
Starting gridappsddocker_blazegraph_1 ...
Starting gridappsddocker_influxdb_1 ...
Starting gridappsddocker_mysql_1 ... done
Starting gridappsddocker_gridappsd_1 ... done
Starting gridappsddocker_wsu_res_app_1 ...
Starting gridappsddocker_wsu_res_app_1 ... done
Getting blazegraph status
Checking blazegraph data
Blazegrpah data available (1954268)
Getting viz status
Containers are running
Connecting to the gridappsd container
docker exec -it gridappsddocker_gridappsd_1 /bin/bash
gridappsd@78a3d22dd2b9:/gridappsd$
Restoration application container
gridappsd@gridappsd-VirtualBox:~/WSU-Restoration$ docker exec -it gridappsddocker_wsu_res_app_1 bash
This will take you inside the application container.
root@1b762c641f24:/usr/src/gridappsd-restoration#
At this point, we should have two terminal open with gridappsd-docker container and restoration application terminal.
root@1b762c641f24:/usr/src/gridappsd-restoration#
gridappsd@78a3d22dd2b9:/gridappsd$
Installing CPLEX in container
Note that the installation command can be written inside the Dockerfile beforehand. However, we do the installation here manually before starting the platform.
root@1b762c641f24:/usr/src/gridappsd-restoration# cd /opt/ibm/ILOG/CPLEX_Studio129/cplex/python/3.6/x86-64_linux/
root@1b762c641f24:/opt/ibm/ILOG/CPLEX_Studio129/cplex/python/3.6/x86-64_linux# python setup.py install
ATTENTION: It is required that the application container has the python version compatible with the CPLEX. For example, CPLEX_STUDIO129 requires python 3.6. Thus, Python3.6 should be made available in the application container.
Executing the application container
Now, get back to the path where application is mounted.
root@1b762c641f24:/opt/ibm/ILOG/CPLEX_Studio129/cplex/python/3.6/x86-64_linux# cd /usr/src/gridappsd-restoration
The following runs the application from terminal
root@1b762c641f24:/usr/src/gridappsd-restoration# cd Restoration
root@1b762c641f24:/usr/src/gridappsd-restoration/Restoration# python main.py [simulation_ID] '{"power_system_config": {"Line_name":"_AAE94E4A-2465-6F5E-37B1-3E72183A4E44"}}'
Running application from the terminal requires Simulation_ID. To get the correct Simulatio_ID, we need to start the platform through the browser. This will be explained in detail in the next section (Visualization).
Starting GridAPPS-D Platform
Start the platform from the gridappsd-docker container
gridappsd@78a3d22dd2b9:/gridappsd$ ./run-gridappsd.sh
Following message can be seen at the end of running terminal. This confirms, the platform is running and we can start the application from the browser.
Registering user roles: application2 -- application
Registering user roles: application1 -- application
Registering user roles: operator3 -- operator
Registering user roles: operator2 -- operator
Registering user roles: evaluator2 -- evaluator,operator
Registering user roles: operator1 -- operator
Registering user roles: evaluator1 -- evaluator,operator
Registering user roles: testmanager2 -- testmanager
Registering user roles: testmanager1 -- testmanager
Registering user roles: service2 -- service
Registering user roles: service.pid -- pnnl.goss.gridappsd.security.rolefile
Registering user roles: service1 -- service
CREATING LOG DATA MGR MYSQL
{"id":"WSU_restoration","description":"Resilient Restoration Application","creator":"WSU","inputs":[],"outputs":[],"options":["(simulationId)","\u0027(request)\u0027"],"execution_path":"python /usr/src/gridappsd-restoration/Restoration/main.py","type":"REMOTE","launch_on_startup":false,"prereqs":["gridappsd-voltage-violation","gridappsd-alarms"],"multiple_instances":true}
{"heartbeatTopic":"/queue/goss.gridappsd.remoteapp.heartbeat.WSU_restoration","startControlTopic":"/topic/goss.gridappsd.remoteapp.start.WSU_restoration","stopControlTopic":"/topic/goss.gridappsd.remoteapp.stop.WSU_restoration","errorTopic":"Error","applicationId":"WSU_restoration"}
Data Model
IEEE 8500-Node Test Feeder
An IEEE Working Group specified a set of distribution test circuits [CIT9] and we have chosen the largest one of these as a sample circuit for GridAPPS-D which is IEEE 8500-Node model [CIT10]. The original 8500-Node test feeder operates at 12.47 kV and has a peak load of about 11 MW, including approximately 1100 single-phase, center-tapped transformers with triplex service drops. Loads are balanced between the two center-tapped windings. The circuit includes 4 shunt capacitor banks and 6 voltage regulator banks, making it a reasonable test for solving voltage problems such as VVO. The circuit is splitted into three substation and several new distributed energy resources (DERs) are added in the test case (See Fig. 3). In addition, 7 tie switches are added such that each substation can share the load of another substation during fault to restore the outage customers. A new set of loads is added near S2 and the region is referred to as a new neighborhood.
The detailed model of this feeder can be found at:
https://github.com/GRIDAPPSD/Powergrid-Models/tree/develop/blazegraph/test/dss/WSU
The OpenDSS data can be extracted here:
https://github.com/shpoudel/D-Net
Figure 3: Modified IEEE 85000-node feeder.
The model in GridAPPS-D came from the IEEE 8500-Node input files distributed with OpenDSS, exported to CIM from OpenDSS, and then imported to the GridAPPS-D data manager. In this automated process, four changes were implemented:
Use constant-current load models, rather than constant-power load models. This is necessary for the solution to converge at peak load. Voltages at peak load are low, and a constant-power load will draw more current under those conditions. Holding the current magnitude constant allows GridLAB-D to achieve convergence under a variety of operating conditions. This is an appropriate compromise in accuracy for real-time applications, which need to be robust through wide variations in voltage and load. In contrast, planning applications usually need more accurate load models, even at the possible expense of re-running some non-converged simulations.
Disable automatic regulator and capacitor controls. The volt-var application, described below, will supersede these settings. If a developer or user is testing the GridLAB-D model outside of GridAPPS-D, these control settings should be re-enabled in order to solve the circuit at peak load. That requires manual un-commenting edits to the GridLAB-D input file.
Substitute a variable called VSOURCE for the SWING bus nominal voltage. This needs to be set at 1.05 per-unit of nominal on the 115-kV system (i.e. 69715.065) in order to solve at peak load. Other conditions may require different source voltage values.
Use a schedule for the loads so they can vary with time during GridAPPS-D simulation. The file should be named zipload_schedule.player.
Visualization
Start a Simulation
Open your browser to http://localhost:8080/ and click the menu button.
Choose Simulations from the menu.
Change Configurations
Change the Power System Configuration, Simulation Configuration, Application Configuration, and Test Configuration as follows:
Communication outage and fault events can be added using the Test Configuration page as shown below. Event can be added using radio button or upload option.
Click the submit button to save all the configurations.
Adding an event
Since we are running the restoration application, a fault event is required to trigger the application. Before proceeding, an event file is required. There are several ways to add event in the test feeder. Here, we use the upload option and use the following JSON file.
{
"commandEvents": [
{
"message": {
"forward_differences": [
{
"object": "_24A93B95-B674-4451-8670-35391D5F51F0",
"attribute": "Switch.open",
"value": 1
}
],
"reverse_differences": [
{
"object": "_24A93B95-B674-4451-8670-35391D5F51F0",
"attribute": "Switch.open",
"value": 0
}
]
},
"event_type": "ScheduledCommandEvent",
"occuredDateTime": "2013-07-14 08:02:00",
"stopDateTime": "2013-07-14 09:00:00"
}
]
}
This event opens a switch (LN0895780_SW) in the feeder at time 2013-07-14 08:02:00 and remains open until 09:00:00. Please adjust the Start time in Simulation Configuration based on occuredDateTime of the event such that event occurs after the simulation has started.
Running the platform
After few seconds, the test-feeder will load. In the meantime, use “Edit plots” to add power, voltage and tap of different components to visualize as the simulation progress.
Click on the triangle to start the simulation. Once you get the Simulation_ID, use it to run the application in terminal. See the python command here.
Note that the WSU-Restoration application gets triggered only when the fault event is added in the test case. During normal operation, application stays quite. The occurrence of the event can be verified on the Alarm tab. Once the event has occured, the applicatin starts and runs the optimization problem to generate the candidate switches for optimal circuit reconfiguration. The candidate switches are toggled and the system is restored.
License
Battelle Memorial Institute (hereinafter Battelle) hereby grants permission to any person or entity lawfully obtaining a copy of this software and associated documentation files (hereinafter the Software) to redistribute and use the Software in source and binary forms, with or without modification. Such person or entity may use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and may permit others to do so, subject to the following conditions:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimers.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Other than as used herein, neither the name Battelle Memorial Institute or Battelle may be used in any form whatsoever without the express written consent of Battelle.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BATTELLE OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
General disclaimer for use with OSS licenses
This material was prepared as an account of work sponsored by an agency of the United States Government. Neither the United States Government nor the United States Department of Energy, nor Battelle, nor any of their employees, nor any jurisdiction or organization that has cooperated in the development of these materials, makes any warranty, express or implied, or assumes any legal liability or responsibility for the accuracy, completeness, or usefulness or any information, apparatus, product, software, or process disclosed, or represents that its use would not infringe privately owned rights.
Reference herein to any specific commercial product, process, or service by trade name, trademark, manufacturer, or otherwise does not necessarily constitute or imply its endorsement, recommendation, or favoring by the United States Government or any agency thereof, or Battelle Memorial Institute. The views and opinions of authors expressed herein do not necessarily state or reflect those of the United States Government or any agency thereof.
PACIFIC NORTHWEST NATIONAL LABORATORY
operated by
BATTELLE
for the
UNITED STATES DEPARTMENT OF ENERGY
under Contract DE-AC05-76RL01830
Volt-Var Optimization (WSU)
This repository contains the restoration application for IEEE 9500-node model (https://github.com/GRIDAPPSD/Powergrid-Models/tree/develop/blazegraph/test/dss/WSU). The application is hosted on GridAPPS-D platform.
Layout
Please clone the repository https://github.com/GRIDAPPSD/gridappsd-docker (refered to as gridappsd-docker repository) next to this repository (they should both have the same parent folder)
Creating the restoration application container
From the command line execute the following commands to build the wsu-restoration container
osboxes@osboxes> cd WSU-VVO-app osboxes@osboxes> docker build --network=host -t wsu-vvo-app .
Add the following to the gridappsd-docker/docker-compose.yml file
wsu_vvo: image: wsu-vvo-app depends_on: gridappsd
Run the docker application
osboxes@osboxes> cd gridappsd-docker osboxes@osboxes> ./run.sh # you will now be inside the container, the following starts gridappsd gridappsd@f4ede7dacb7d:/gridappsd$ ./run-gridappsd.sh
Run the application container
osboxes@osboxes> cd WSU-VVO-app osboxes@osboxes> docker exec -it gridappsddocker_wsu_vvo_1 bash # you will now be inside the application container, the following runs the application from terminal root@1b762c641f24:/usr/src/gridappsd-vvo# cd wsu_vvo root@1b762c641f24:/usr/src/gridappsd-vvo/wsu_vvo# python main.py 1234 '{"power_system_config": {"Line_name":"_AAE94E4A-2465-6F5E-37B1-3E72183A4E44"}}'
Next to start the application through the viz follow the directions here: https://gridappsd.readthedocs.io/en/latest/using_gridappsd/index.html#start-gridapps-d-platform
Forming optimization problem
In the optimization problem, test feeders are modeled as graph; G (V, E), where V is set of nodes and E is set of edges. The graph and line parameters of the test feeder can be extracted from (https://github.com/shpoudel/D-Net).
Get real-time topology and load data of the test case
First, the real time topology of the test case is extracted from the operating feeder in platform (top_identify.py). Then, load data for each node is obtained (get_Load.py) and stored in json format to be used in linear power flow while writing constraints for optimization problem.
DER Dispatch (NREL)
Purpose
The purpose of this repository is to document the chosen way of registering and running applications within a GridAPPS-D deployment.
Requirements
Docker ce version 17.12 or better. You can install this via the docker_install_ubuntu.sh script. (note for mint you will need to modify the file to work with xenial rather than ubuntu generically)
Quick Start
Please clone the repository https://github.com/GRIDAPPSD/gridappsd-docker (refered to as gridappsd-docker repository) next to this repository (they should both have the same parent folder)
git clone https://github.com/GRIDAPPSD/gridappsd-docker git clone https://github.com/GRIDAPPSD/DER-Dispatch-app ls -l drwxrwxr-x 7 osboxes osboxes 4096 Sep 4 14:56 gridappsd-docker drwxrwxr-x 5 osboxes osboxes 4096 Sep 4 19:06 DER-Dispatch-app
Creating the der-dispatch-app application container
From the command line execute the following commands to build the der-dispatch-app container
osboxes@osboxes> cd DER-Dispatch-app osboxes@osboxes> docker build --network=host -t der-dispatch-app .
Add the following to the gridappsd-docker/docker-compose.yml file
derdispatch: image: der-dispatch-app ports: - 9001:9001 environment: GRIDAPPSD_URI: tcp://gridappsd:61613 depends_on: - gridappsd volumes: - $HOME/git/DER-Dispatch-app-Public:/usr/src/gridappsd-der-dispatch
Run the docker application
osboxes@osboxes> cd gridappsd-docker osboxes@osboxes> ./run.sh # you will now be inside the container, the following starts gridappsd gridappsd@f4ede7dacb7d:/gridappsd$ ./run-gridappsd.sh
Test opt_function.pyc file.
docker exec -it gridappsd-docker_derdispatch_1 bash
cd der_dispatch_app
## This function is slow but it should not hang
python test_opt_function.py
Example output
> python test_opt_function.py
('gridappsd', 61613)
Mon Feb 24 18:20:24 2020
(9480, 9480) (9480, 10)
Mon Feb 24 18:21:22 2020
Mon Feb 24 18:21:29 2020
Application Configuration
Set start time to 2013-07-22 10:30:00
Options: Run with OPF = 0 and a specific time and duration first to get the baseline for comparison. Then Run with OPF = 1 and the same time and duration evaluate the applications performance against the baseline. run_freq - Number of seconds between appliction runs. run_on_host - True then run on the host machine. False then run in the container.
The baseline will be in this folder in the container: /usr/src/gridappsd-der-dispatch/der_dispatch_app/adms_result_ieee123pv_house_1563893400_OPF_0_
Baseline run
{
"OPF": 0,
"run_freq": 15,
"run_on_host": false,
"run_realtime": true,
"stepsize_xp": 0.2,
"stepsize_xq": 2,
"coeff_p": 0.005,
"coeff_q": 0.0005,
"Vupper": 1.025,
"Vlower": 0.95,
"stepsize_mu": 50000,
"optimizer_num_iterations": 10
}
Optimal Powerflow on Run
Set OPF to 1 and run again.
{
"OPF": 1,
"run_freq": 15,
"run_on_host": false,
"run_realtime": true,
"stepsize_xp": 0.2,
"stepsize_xq": 2,
"coeff_p": 0.005,
"coeff_q": 0.0005,
"Vupper": 1.025,
"Vlower": 0.95,
"stepsize_mu": 50000,
"optimizer_num_iterations": 10
}
docker copy command
docker cp 422635e932bb:/usr/src/gridappsd-der-dispatch/der_dispatch_app/adms_result_test9500new_1374510720_OPF_1_stepsize_xp_0_2_stepsize_xq_2_coeff_p_0_1_coeff_q_5e_neg_05_stepsize_mu_500/ $HOME/
Next to start the application through the viz follow the directions here: https://gridappsd.readthedocs.io/en/latest/using_gridappsd/index.html#start-gridapps-d-platform
python /usr/src/gridappsd-der-dispatch/der_dispatch_app/main_app_new.py 952325492 '{"power_system_config":{"SubGeographicalRegion_name":"_1CD7D2EE-3C91-3248-5662-A43EFEFAC224","GeographicalRegion_name":"_24809814-4EC6-29D2-B509-7F8BFB646437","Line_name":"_EBDB5A4A-543C-9025-243E-8CAD24307380"},"simulation_config":{"power_flow_solver_method":"NR","duration":600,"simulation_name":"ieee123","simulator":"GridLAB-D","start_time":1374510720,"run_realtime":false,"simulation_output":{},"model_creation_config":{"load_scaling_factor":1.0,"triplex":"y","encoding":"u","system_frequency":60,"voltage_multiplier":1.0,"power_unit_conversion":1.0,"unique_names":"y","schedule_name":"ieeezipload","z_fraction":0.0,"i_fraction":1.0,"p_fraction":0.0,"randomize_zipload_fractions":false,"use_houses":false},"simulation_broker_port":59469,"simulation_broker_location":"127.0.0.1"},"application_config":{"applications":[{"name":"der_dispatch_app","config_string":"{\"OPF\": 0, \"run_freq\": 60, \"run_on_host\": false, \"run_realtime\": false, \"stepsize_xp\": 0.2, \"stepsize_xq\": 2, \"coeff_p\": 0.1, \"coeff_q\": 5e-05, \"stepsize_mu\": 500}"}]},"simulation_request_type":"NEW"}' '{OPF:0,run_freq:60,run_on_host:false,run_realtime:false,stepsize_xp:0.2,stepsize_xq:2,coeff_p:0.1,coeff_q:5e-05,stepsize_mu:500}'
python /usr/src/gridappsd-der-dispatch/der_dispatch_app/main_app_new.py 1522305637 '{"power_system_config":{"SubGeographicalRegion_name":"_1CD7D2EE-3C91-3248-5662-A43EFEFAC224","GeographicalRegion_name":"_24809814-4EC6-29D2-B509-7F8BFB646437","Line_name":"_E407CBB6-8C8D-9BC9-589C-AB83FBF0826D"},"simulation_config":{"power_flow_solver_method":"NR","duration":600,"simulation_name":"ieee123","simulator":"GridLAB-D","start_time":1374510720,"run_realtime":false,"simulation_output":{},"model_creation_config":{"load_scaling_factor":1.0,"triplex":"y","encoding":"u","system_frequency":60,"voltage_multiplier":1.0,"power_unit_conversion":1.0,"unique_names":"y","schedule_name":"ieeezipload","z_fraction":0.0,"i_fraction":1.0,"p_fraction":0.0,"randomize_zipload_fractions":false,"use_houses":false},"simulation_broker_port":59469,"simulation_broker_location":"127.0.0.1"},"application_config":{"applications":[{"name":"der_dispatch_app","config_string":"{\"OPF\": 0, \"run_freq\": 60, \"run_on_host\": false, \"run_realtime\": false, \"stepsize_xp\": 0.2, \"stepsize_xq\": 2, \"coeff_p\": 0.1, \"coeff_q\": 5e-05, \"stepsize_mu\": 500}"}]},"simulation_request_type":"NEW"}' '{OPF:0,run_freq:60,run_on_host:false,run_realtime:false,stepsize_xp:0.2,stepsize_xq:2,coeff_p:0.1,coeff_q:5e-05,stepsize_mu:500}'
{"OPF": 0, "run_freq": 60, "run_on_host": false, "run_realtime": true, "stepsize_xp": 0.2, "stepsize_xq": 2, "coeff_p": 0.1, "coeff_q": 5e-05, "stepsize_mu": 500}
Solar Forecasting (NREL)
Solar-Forecast GridAPPS-D Application
Purpose
The application to forecast GHI data
Requirements
Docker ce version 17.12 or better. You can install this via the docker_install_ubuntu.sh script. (note for mint you will need to modify the file to work with xenial rather than ubuntu generically)
Quick Start
Please clone the repository https://github.com/GRIDAPPSD/gridappsd-docker (refered to as gridappsd-docker repository) next to this repository (they should both have the same parent folder)
git clone https://github.com/GRIDAPPSD/gridappsd-docker git clone https://github.nrel.gov/PSEC/Solar-Forecasting ls -l drwxrwxr-x 7 osboxes osboxes 4096 Sep 4 14:56 gridappsd-docker drwxrwxr-x 5 osboxes osboxes 4096 Sep 4 19:06 Solar-Forecasting
Creating the sample-app application container
From the command line execute the following commands to build the sample-app container
osboxes@osboxes> cd Solar-Forecasting osboxes@osboxes> docker build --network=host -t solar-forecasting-app .
Add the following to the gridappsd-docker/docker-compose.yml file
solar_forecast: image: solar-forecast-app ports: - 9002:9002 environment: GRIDAPPSD_URI: tcp://gridappsd:61613 depends_on: - gridappsd
Run the docker application
osboxes@osboxes> cd gridappsd-docker osboxes@osboxes> ./run.sh -t develop # you will now be inside the container, the following starts gridappsd gridappsd@f4ede7dacb7d:/gridappsd$ ./run-gridappsd.sh
Run bokeh on port 9002
python -m bokeh serve --show bokeh_two_plot/ --allow-websocket-origin=*:5006 --args --port 9002
Next to start the application through the viz follow the directions here: https://gridappsd.readthedocs.io/en/latest/using_gridappsd/index.html#start-gridapps-d-platform
If you want to run the application WITHOUT the viz, open another terminal window and move to the solar-forecasting GitHub directory. Perform the following commands:
user@local> export PYTHONPATH=/Users/Solar-Forecasting/
user@local> python solar_forecasting/util/post_goss_ghi.py --start_time 1357140600 --duration 720 --interval 10 -t .1
user@local> python solar_forecasting/util/post_goss_ghi.py --start_time 1370260800 --duration 43200 --interval 60 -t .1
# The above options can be changed to a desired output
Docker
Two notes to use inside a docker container:
Add 9002 to the ports in the gridappsd-docker/docker-compose.yml like this:
solar_forecasting:
image: solar-forecasting-app
ports:
- 9002:9002
environment:
GRIDAPPSD_URI: tcp://gridappsd:61613
depends_on:
- gridappsd
>python /usr/src/gridappsd-solar-forecasting/solar_forecasting/app/main.py 1112306683 '{"power_system_config": {"SubGeographicalRegion_name": "_1CD7D2EE-3C91-3248-5662-A43EFEFAC224", "GeographicalRegion_name": "_24809814-4EC6-29D2-B509-7F8BFB646437", "Line_name": "_EBDB5A4A-543C-9025-243E-8CAD24307380"}, "simulation_config": {"power_flow_solver_method": "NR", "duration": 48, "simulation_name": "ieee123", "simulator": "GridLAB-D", "start_time": 1538484951, "run_realtime": true, "simulation_output": {}, "model_creation_config": {"load_scaling_factor": 1.0, "triplex": "y", "encoding": "u", "system_frequency": 60, "voltage_multiplier": 1.0, "power_unit_conversion": 1.0, "unique_names": "y", "schedule_name": "ieeezipload", "z_fraction": 0.0, "i_fraction": 1.0, "p_fraction": 0.0, "randomize_zipload_fractions": false, "use_houses": false}, "simulation_broker_port": 52798, "simulation_broker_location": "127.0.0.1"}, "application_config": {"applications": [{"name": "der_dispatch_app", "config_string": "{\"OPF\": 1, \"run_freq\": 60, \"run_on_host\": false, \"run_realtime\": true, \"stepsize_xp\": 0.2, \"stepsize_xq\": 2, \"coeff_p\": 0.1, \"coeff_q\": 5e-05, \"stepsize_mu\": 500}"}]}, "simulation_request_type": "NEW"}'
Grid Forecasting (NREL)
Gird-Forecasting GridAPPS-D application
Purpose
The application to forecast GHI data
Requirements
Docker ce version 17.12 or better. You can install this via the docker_install_ubuntu.sh script. (note for mint you will need to modify the file to work with xenial rather than ubuntu generically)
Quick Start
Please clone the repository https://github.com/GRIDAPPSD/gridappsd-docker (refered to as gridappsd-docker repository) next to this repository (they should both have the same parent folder)
git clone https://github.com/GRIDAPPSD/gridappsd-docker git clone https://github.com/GRIDAPPSD/Grid-Forecasting ls -l drwxrwxr-x 7 osboxes osboxes 4096 Sep 4 14:56 gridappsd-docker drwxrwxr-x 5 osboxes osboxes 4096 Sep 4 19:06 Grid-Forecasting
Creating the sample-app application container
From the command line execute the following commands to build the sample-app container
osboxes@osboxes> cd Grid-Forecasting osboxes@osboxes> docker build --network=host -t grid-forecasting-app .
Add the following to the gridappsd-docker/docker-compose.yml file Add 9003 to the ports in the docker-compose.yml allows for data to be sent to the bokeh streaming tool.
grid_forecasting:
image: grid-forecasting-app
ports:
- 9003:9003
environment:
GRIDAPPSD_URI: tcp://gridappsd:61613
depends_on:
- gridappsd
volumes:
- $HOME/git/adms/Grid-Forecasting-Public:/usr/src/gridappsd-grid-forecasting
Run the docker application
osboxes@osboxes> cd gridappsd-docker osboxes@osboxes> ./run.sh # you will now be inside the container, the following starts gridappsd gridappsd@f4ede7dacb7d:/gridappsd$ ./run-gridappsd.sh
Next to start the application through the viz follow the directions here: https://gridappsd.readthedocs.io/en/latest/using_gridappsd/index.html#start-gridapps-d-platform
GridAPPS-D DNP3 Service
GridAPPS-D DNP3 service is an application service to integrate GridAPPS-D and a Distrbuted Newtork Protocol(DNP3)[1] based commercial product that allows operation, monitoring, analysis, restoration, and optimization of network operations to enable data exchange bewteen the applications. The DNP3 data exchange interface translates Common Information Model (CIM) standards data within GridAPPS-D to DNP3 packets and vice-versa to communicate with the DNP3 based software.Likewise, the service uses the existing GridAPPS-D platform to translate DNP3 data received from SurvalentONE. The use of GridAPPS-D made the development easier because of its standardized programming interface that unifies data integration.
Integration Architecture
This application is implemented as an application service consisting of python modules. DNP3 is a robust, efficient and interoperable protocol. Its compatibility with other protocols has made this integration easier. The integration is shown as a Master and Outstation link communication as shown in the figure below.
Figure 1: Integration architecture
The commercial tool used here is SurvalentONE[2], a DNP3 based SCADA system. The SurvalentONE SCADA system was configured as per the manuals provided by the Survalent Company. The Master server configuration includes creating a Station, Communication Link, Intelligent Electronic Device(IED) . The name and description of CIM measurement points of an IEEE model is added to a template (an excel sheet) containing all the DNP3 related metadata such as predefined datatypes, groups, variation. The template is created using a template maker provided by Survalent.Then the template is loaded in the Master IED of the Master server.
Once this configuration is done and the DNP3 application service is created,start the service by creating a simulation request. Since the service is added to gridapps container, it gets started as soon as the gridappsd service is started. A model dictionary file(CIM measurements) is generated for each simulation ID when a simulation request for a specific model is sent to the simulator(GridLAB-D). The simulation output from the simulator running under GridAPPS-D is received on the simulation output topic by the Message Bus.
The DNP3 service at the Outstation and also the Communication Line at the Master Server on startup initiate a connection request from the Master, to the IP address of the Outstation at port 20000. In our case, the Outstation listens on port 20000. The DNP3 points created from the CIM model dictionary file are loaded by the DNP3 service in the Outstation database with the datatype, attribute,
description etc. fields. The Master polls the Outstation every 60 seconds to update the realtime data. The service translates model dictionary data into DNP3 points as JSON structures.An example of a JSON packet loaded in the Outstation database and sent to the Master is shown below.
{
"attribute": "Switch.open",
"data_type": "DO",
"description":"Name:671692,ConductingEquipment_type:LoadBreakSwitchPhase:B,controlAttribute:Switch.open",
"group": 12,
"index": 14,
"measurement_id": "_56495819-9E14-DFEC-CC01-67526BBC9987",
"name": "564958199E14DFECCC0167526BBC9987",
"value": "0",
"variation": 1
}
The datatype, group and variation of the points are shown in the Table below.
Datatype Group Variation Examples Control/Status Sent From
-------------- ------ ---------- ---------------------- ----------------- ------------
Analog Output 42 3 Solar Panels, Capacitors, Regulators Control(Update set points) Master to Outstation
Analog Input 30 1 AC Line segment Measurement values Outstation to Master
Digital Output 12 1 Switches,reclosers Control, Enable, Disable Master to Outstation
Digital Input 1 2 Breakers Status Outstation to Master
The on_message function in the service code keeps on updating the real-time
values for all the DNP3 points in Master server. The status and amgnitude values updates can be seen in the User Interfaces(Point viewers) provided by Survalent.
SurvalentONE SCADA has the capability of controlling the points/measurements.
The output commands are generated using the point viewers’ user interface. For example, a switch can be turned ON/OFF by selecting the control option manually. Similarly, analog values the AC Line segment can also be modified. The control points can be chosen from the options in the telemetry of the points. For a binary point five different inputs can be sent. The control inputs are sent in the form of OpenDNP3 Control relay Output Block commands to the Outstation and translated to CIM difference messages, sent back to FNCS bridge and then to the simulator. OpenDNP3 is an implementation of the DNP3 communication in the form of a library which provides C++ programming APIs[3]. The analog points can also be modified in a similar way. The values can be set and sent as an OpenDNP3 AnalogOutputInt16 command. The command has the value and status as input to the Outstation.
Results
The integration was tested using a 13-bus system. The JSON stored in Oustation database as shown in the example above is created for all the CIM measurement values in the dictionary file. An example of logs from Outstation at service start-up is shown below.
Adding Point: PointDefinition 00730ee504e148bf917fe47d5be16e6f (30.1, index=0,type=Analog Input)
Recording DNP3 Analog measurement, index=88,value=564.143691452854
Recording DNP3 Binary measurement, index=10,value=True
Recording DNP3 Binary measurement, index=13,value=True
The control input from Master by sending a PULSE_OFF command for a switch which is an OpenDNP3 command sent from Master to Outstation as shown below.
cmdtype=Operate,command=<pydnp3.opendnp3.ControlRelayOutputBlock object at
0x7fd1f69527d8>,index=4,optype=OperateType.SELECT_BEFORE_OPERATE
Received DNP3 Point value ControlCode.PULSE_OFF (6ed7855451e84bc79db2c810d07509dd, 12.1.4, Operate)
command_code=CommandStatus.SUCCESS,command_code=ControlCode.PULSE_OFF,command_ontime=0
The above command was sent back by the GridAPPS-D service in the form of a CIM difference message to the simulation input topic as shown below.The forward_differences value is the current value/status and reverse_differences value contains the older value/status of the switch.
{ "command":"update",
"input":{
"simulation_id":"854814554",
"message":{ "timestamp":1568058139,
"difference_mrid":"8be2c7a6-7cef-4e0e-af91-4f5eff37cf90",
"reverse_differences":[
{
"object":"_56495819-9E14-DFEC-CC01-67526BBC9987",
"attribute":"Switch.open",
"value":1
}],
"forward_differences":[
{
"object":"_56495819-9E14-DFEC-CC01-67526BBC9987",
"attribute":"Switch.open",
"value":0 } ]
}}}
This received CIM message was processed and the below plot shows the state of the switch at Viz.
References
[1] G. R. Clarke, D. Reynders, and E. Wright, Practical modern SCADA protocols: DNP3, 60870.5 and related systems. London: Elsevier, 2008.
[2] Survalent Technology Corporation. “Survalent.”. https://www.survalent.com (accessed: Aug 2019).
[3] Automatak. “opendnp3”. https://dnp3.github.io/ (accessed: June 2019).
GridAPPS-D Sensor Simulator Service
The GridAPPSD’s Sensor Simulator simulates real devices based upon the magnitude of “prestine” simulated values. This service has been specifically designed to work within the gridappsd platform container. The GridAPPSD platform will start the service when it is specified as a dependency of an application or when a service configuration is specified within the GridAPPSD Visualization. The image below shows a portion of the configuration options available through the service configuration panel.

Python Application Usage
The python application using this service should require gridappsd-sensor-simulator as a requirement. In addition, the following python code shows how to get the correct topic for the service.
Service Configuration
The sensor-config in the above image shows an example of how to configure a portion of the system to have sensor output. Each mrid (_99db0dc7-ccda-4ed5-a772-a7db362e9818) will be monitored by this service and either use the default values or use the specified values during the service runtime.
{
"_99db0dc7-ccda-4ed5-a772-a7db362e9818": {
"nominal-value": 100,
"perunit-confidence-band": 0.01,
"aggregation-interval": 30,
"perunit-drop-rate": 0.01
},
"_ee65ee31-a900-4f98-bf57-e752be924c4d":{},
"_f2673c22-654b-452a-8297-45dae11b1e14": {}
}
The other options for the service are:
default-perunit-confidence-band
default-aggregation-interval
default-perunit-drop-rate
passthrough-if-not-specified
These options will be used when not specified within the sensor-config block.
Note
Currently the nominal-value is not looked up from the database. At this time services aren’t able to tell the platform when they are “ready”. This will be implemented in the near future and then all of the nominal-values will be queried from the database.
Request Example
The following is a full request example for use within the context of the main GridAPPSD api. This example uses the 123 node system with 3 sensors simulated. Also for this example those are the only measurements that will be published to the output sensor output topic.
{
"power_system_config": {
"GeographicalRegion_name": "_73C512BD-7249-4F50-50DA-D93849B89C43",
"SubGeographicalRegion_name": "_1CD7D2EE-3C91-3248-5662-A43EFEFAC224",
"Line_name": "_C1C3E687-6FFD-C753-582B-632A27E28507"
},
"application_config": {
"applications": []
},
"simulation_config": {
"start_time": "1570041113",
"duration": "120",
"simulator": "GridLAB-D",
"timestep_frequency": "1000",
"timestep_increment": "1000",
"run_realtime": false,
"simulation_name": "ieee123",
"power_flow_solver_method": "NR",
"model_creation_config": {
"load_scaling_factor": "1",
"schedule_name": "ieeezipload",
"z_fraction": "0",
"i_fraction": "1",
"p_fraction": "0",
"randomize_zipload_fractions": false,
"use_houses": false
}
},
"test_config": {
"events": [],
"appId": ""
},
"service_configs": [{
"id": "gridappsd-sensor-simulator",
"user_options": {
"sensors-config": {
"_99db0dc7-ccda-4ed5-a772-a7db362e9818": {
"nominal-value": 100,
"perunit-confidence-band": 0.02,
"aggregation-interval": 5,
"perunit-drop-rate": 0.01
},
"_ee65ee31-a900-4f98-bf57-e752be924c4d": {},
"_f2673c22-654b-452a-8297-45dae11b1e14": {}
},
"random-seed": 0,
"default-aggregation-interval": 30,
"passthrough-if-not-specified": false,
"default-perunit-confidence-band": 0.01,
"default-perunit-drop-rate": 0.05
}
}]
}
Further information about the GridAPPSD platform can be found at https://gridappsd.readthedocs.org.
GridAPPS-D Voltage Violation Service
Purpose
This is a GridAPPS-D service that calculates and publishes voltage voilations during a simulation. Voltage violations are published every 15 seconds by default.
Topics
Subscribes to simulation output topic /topic/goss.gridappsd.simulation.output.[simulation_id]
Publishes on topic /topic/goss.gridappsd.simulation.voltage_violation.[simulation_id].output
Message Structure
Simulation output message structure is available here: https://gridappsd.readthedocs.io/en/master/using_gridappsd/index.html#subscribe-to-simulation-output
Voltage violation service publishes a JSON message with measurement MRIDs and their per unit voltage value. For example,
{
"_00730ee5-04e1-48bf-917f-e47d5be16e6f": 1.07,
"_078cfc25-8a2e-4f34-8631-0346abe2214d": 1.06,
"_40df103f-b458-4c15-a2eb-ffe7d029ef65": 1.06,
"_51fe8d20-a89e-497f-8c4b-d5bd654449bf": 1.08
}
GridAPPS-D State Estimator Service
Purpose
The state estimator service will produce and output the best available system state from measurements for use by other applications.
State estimator service layout
The following is the structure of the state estimator:
.
├── README.md
├── LICENSE
└── state-estimator
├── include
├── src
├── bin
├── obj
├── Makefile
└── state-estimator.config
└───(Prerequisite libraries--SuiteSparse, ActiveMQ-CPP, Json)
Prerequisites
Docker ce version 17.12 or newer is required. You can install this via the docker_install_ubuntu.sh script in the gridappsd-docker repository described in the next step. (note for mint you will need to modify the file to work with xenial rather than ubuntu generically)
Clone the repository https://github.com/GRIDAPPSD/gridappsd-docker (referred to as gridappsd-docker repository).
~/git
└── gridappsd-docker
To run the gridappsd-docker platform, follow the instructions provided at https://github.com/GRIDAPPSD/gridappsd-docker/README.md.
To configure and run a simulation under the platform, follow the instructions provided at https://gridappsd.readthedocs.io/en/master/using_gridappsd.
The state estimator is distributed pre-built under the gridappsd-docker repository, but you may instead build the state estimator from source code from its own repository if you wish to modify it, run a different branch than master, or otherwise run it outside the gridappsd-docker container.
If you wish to run the state estimator provided with gridappsd-docker, follow the instructions in the following section, Running state estimator from the gridappsd-docker container.
Alternatively, to build the state estimator from source code and then run that version from the command line, skip to the section Building state estimator below.
Running state estimator from the gridappsd-docker container
Configure the simulation from the GRIDAPPSD platform web browser visualization.
Click on the “Service Configuration” tab and then click on the checkbox under the gridappsd-state-estimator section of the configuration user interface to specify that state estimator should be started with the simulation.
Click on the “Submit” button and then the play button to start the simulation.
The state estimator will process running simulation measurements producing state estimate messages for other applications.
The gridappsd-state-plotter application can be used to plot state estimator output as described at https://github.com/GRIDAPPSD/gridappsd-state-plotter.
The remainder of these instructions apply only when building the state estimator from source code and running that build from the command line.
Building state estimator
Clone the repository https://github.com/GRIDAPPSD/gridappsd-state-estimator next to the gridappsd-docker repository (they should both have the same parent folder, assumed to be ~/git in docker-compose.yml)
~/git
├── gridappsd-docker
└── gridappsd-state-estimator
Then the following two repositories should be cloned under the top-level gridappsd-state-estimator directory of the repository cloned above
- https://github.com/GRIDAPPSD/SuiteSparse
- https://github.com/GRIDAPPSD/json
The ActiveMQ C++ client library, ActiveMQ-CPP, should be downloaded from the URL below as a Unix source code distrubtion. Both the 3.9.4 and 3.9.5 releases have been successfully used with state estimator. The tar.gz or tar.bz2 distribution should be extracted under the gridappsd-state-estimator directory, the same location as the SuiteSparse and json repositories.
- https://activemq.apache.org/components/cms/download
Building prerequisite libraries requires some other packages to be installed first. The following apt-get install commands should install those packages if they are not already installed:
sudo apt-get install cmake
sudo apt-get install m4
sudo apt-get install liblapack-dev libblas-dev
sudo apt-get install libapr1 libapr1-dev
sudo apt-get install libssl-dev
From the gridappsd-state-estimator directory, run the following commands to build the prerequisite libraries and then the state-estimator executable:
cd activemq-cpp-library-*
./configure
make
sudo make install
cd ../SuiteSparse
make LAPACK=-llapack BLAS=-lblas
cd ../state-estimator
make
The executable application will be placed in bin/state-estimator. The Json distribution consists entirely of include files and therefore is not compiled separately from the application using it.
Running state estimator from the command line
Edit the run-se.sh script in the state-estimator subdirectory of the top-level gridappsd-state-estimator repository, uncomment the appropriate SIMREQ variable for the model being run based on the comment at the end of each SIMREQ line denoting the corresponding model, and save changes.
Configure and start the simulation from the GRIDAPPSD platform web browser visualization, click on the “Simulation ID” value in the upper left corner of the simulation diagram to copy the value to the clipboard.
Invoke the script “./run-se.sh” from the command line with the Simulation ID value pasted from the clipboard as the command line argument to the script.
The state estimator will process running simulation measurements producing state estimate messages for other applications along with diagnostic log output to the terminal.
The gridappsd-state-plotter application can be used to plot state estimator output as described at https://github.com/GRIDAPPSD/gridappsd-state-plotter.
404: Not Found
GridAPPS-D Alarm Service
This service publishes alarms.