Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CIM-Graph refactor #33

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 169 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,173 @@
# GridAPPS-D Toolbox Topology Processor
# GridAPPS-D Topology Processor

The Topology Processor is a lightweight service based on the LinkNet(TM) open-source data structure for mapping CIM ConnectivityNodes and Terminals developed by IncSys Corp. LinkNet(TM) is a trademark of Incremental Systems Corporation and is used with permission.
![GitHub Tag](https://img.shields.io/github/v/tag/GRIDAPPSD/topology-processor)
![GitHub Release Date](https://img.shields.io/github/release-date-pre/GRIDAPPSD/topology-processor)
![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/GRIDAPPSD/topology-processor/deploy-dev-release.yml)
![Libraries.io dependency status for GitHub repo](https://img.shields.io/librariesio/github/GRIDAPPSD/topology-processor)



![GitHub Issues or Pull Requests](https://img.shields.io/github/issues/GRIDAPPSD/topology-processor)
![GitHub Issues or Pull Requests](https://img.shields.io/github/issues-pr/GRIDAPPSD/topology-processor)
![GitHub commit activity](https://img.shields.io/github/commit-activity/t/GRIDAPPSD/topology-processor)

![GitHub Downloads (all assets, all releases)](https://img.shields.io/github/downloads/GRIDAPPSD/topology-processor/total?label=git%20downloads)
![GitHub License](https://img.shields.io/github/license/GRIDAPPSD/topology-processor)
![https://doi.org/10.1109/access.2022.3221132](https://img.shields.io/badge/doi-10.1109/access.2022.3221132-blue)

This repo contains the GridAPPS-D services for transmission and distribution topology. The core algorithms are currently being migrated to https://github.com/PNNL-CIM-Tools/CIM-Graph-Topology-Processor and rebuilt using CIMantic Graphs labeled property graphs instead of the linked list data structures used in this repo.

The original topology processor services have been moved into the `archive` directory and based on the LinkNet(TM) open-source data structure for mapping CIM ConnectivityNodes and Terminals developed by IncSys Corp. LinkNet(TM) is a trademark of Incremental Systems Corporation and is used with permission.

## Switch-Delimited Topology Areas for Distributed Apps and Context Manager

### Service Call

The topology service uses a new topic and keyword. `mRID` can be that of a `cim:Feeder`, `cim:FeederArea`, or `cim:DistributionArea`.

```python
topic = "goss.gridappsd.request.data.cimtopology"

message = {
"requestType": "GET_DISTRIBUTED_AREAS",
"mRID": "FEEDER-1234-ABCD-MRID",
"resultFormat": "JSON"
}

message = gapps.get_response(topic, message, timeout=30)
```

### Service Response

The new topology processor response will be formatted as JSON-LD, with `mRID` replaced with `@id` and `@type`:

```json
{
"DistributionArea": {
"@id": "uuid-string",
"@type": "DistributionArea",
"Substations": [
{
"@id": "uuid-string",
"@type": "Substation",
"NormalEnergizedFeeder": [
{
"@id": "uuid-string",
"@type": "Feeder",
"FeederArea": {
"@id": "uuid-string",
"@type": "FeederArea",
"BoundaryTerminals": [
{
"@id": "uuid-string",
"@type": "Terminal"
}
],
"AddressableEquipment": [
{
"@id": "uuid-string",
"@type": "Breaker"
},
],
"UnaddressableEquipment": [
{
"@id": "uuid-string",
"@type": "PowerTransformer"
},
{
"@id": "uuid-string",
"@type": "EnergySource"
}
],
"Measurements": [
{
"@id": "uuid-string",
"@type": "Analog"
},
{
"@id": "uuid-string",
"@type": "Discrete"
}
],
"SwitchAreas": [
{
"@id": "uuid-string",
"@type": "SwitchArea",
"FeederArea": {
"@id": "uuid-string",
"@type": "FeederArea"
},
"BoundaryTerminals": [
{
"@id": "uuid-string",
"@type": "Terminal"
}
],
"AddressableEquipment": [
{
"@id": "uuid-string",
"@type": "LinearShuntCompensator"
}
],
"UnaddressableEquipment": [
{
"@id": "uuid-string",
"@type": "ACLineSegment"
}
"Measurements": [
{
"@id": "uuid-string",
"@type": "Analog"
},
{
"@id": "uuid-string",
"@type": "Discrete"
}
],
"SecondaryAreas": [
{
"@id": "uuid-string",
"@type": "SecondaryArea",
"SwitchArea": {
"@id": "uuid-string",
"@type": "SwitchArea"
},
"BoundaryTerminals": [
{
"@id": "9d06670e-f8ad-46a1-9854-bba7adaf1cf0",
"@type": "Terminal"
}
],
"AddressableEquipment": [
{
"@id": "uuid-string",
"@type": "PowerElectronicsConnection"
}
],
"UnaddressableEquipment": [
{
"@id": "uuid-string",
"@type": "EnergyConsumer"
}
],
"Measurements": [
{
"@id": "uuid-string",
"@type": "Analog"
}
]
}
]
}
]
}
}
]
}
]
}
}
```

## Real-time Topology Processor Service

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
7 changes: 5 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@ repository = "https://github.com/GRIDAPPSD/topology-processor"
documentation = "https://github.com/GRIDAPPSD/topology-processor"

[tool.poetry.dependencies]
python = "^3.8"
gridappsd-python = {version = "^2023.5.1a9", allow-prereleases = true}
python = "^3.10"
gridappsd-python = {version = "^2024.6.0", allow-prereleases = true}
cim-topology = { git = "https://github.com/PNNL-CIM-Tools/CIM-Graph-Topology-Processor", branch = "cimgraph-refactor"}
cim-graph = { git = "https://github.com/PNNL-CIM-Tools/CIM-Graph.git", branch = "feature/68"}


[tool.poetry.group.dev.dependencies]
mock = "^5.0.2"
Expand Down
14 changes: 14 additions & 0 deletions topo_background_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"id":"gridappsd-topology-background-service",
"description": "Topology Processor Background Service",
"creator":"PNNL",
"inputs":[],
"outputs":[],
"static_args":[],
"execution_path":"/gridappsd/services/gridappsd-topology-processor/topo_background_service.py",
"type":"PYTHON",
"launch_on_startup": true,
"prereqs":[],
"multiple_instances":false,
"environmentVariables":[]
}
105 changes: 105 additions & 0 deletions topo_background_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import os
import json
import time
import logging
from gridappsd import GridAPPSD
from gridappsd.topics import service_input_topic, service_output_topic
from cimgraph.databases import ConnectionParameters, BlazegraphConnection

from cimtopology.utils import DistributedTopologyMessage
import cimgraph.data_profile.cimhub_2023 as cim

class TopologyProcessor(GridAPPSD):

def __init__(self):
os.environ['GRIDAPPSD_APPLICATION_ID'] = 'topology-background-service'
os.environ['GRIDAPPSD_APPLICATION_STATUS'] = 'STARTED'
os.environ['GRIDAPPSD_USER'] = 'app_user'
os.environ['GRIDAPPSD_PASSWORD'] = '1234App'
gapps = GridAPPSD()
assert gapps.connected
self.gapps = gapps
self.log = self.gapps.get_logger()
params = ConnectionParameters(url = "http://localhost:8889/bigdata/namespace/kb/sparql", cim_profile='cimhub_2023', iec61970_301=8)
self.blazegraph = BlazegraphConnection(params)


self.log.info('Topology Background Service Started')


# GridAPPS-D service
def on_message(self, headers, message):
model_mrid = message['mRID']
reply_to = headers['reply-to']


if message['requestType'] == 'GET_DISTRIBUTED_AREAS':

self.log.info(f'Building Distributed Areas for {model_mrid}')

topo_message = DistributedTopologyMessage()
container = self.blazegraph.get_object(mrid=model_mrid)

if isinstance(container, cim.Feeder):
topo_message.get_context_from_feeder(container, self.blazegraph)

elif isinstance(container, cim.FeederArea):
topo_message.get_context_from_feeder_area(container, self.blazegraph)

elif isinstance(container, cim.DistributionArea):
topo_message.get_context_from_distribution_area(container, self.blazegraph)

return_message = json.dumps(topo_message.message, indent=4)
del topo_message
self.gapps.send(reply_to, return_message)

elif message['requestType'] == 'GET_BASE_TOPOLOGY':
Topology = self.get_base_topology(model_mrid)
return_message = {
"response": "not yet supported"
# 'modelID': model_mrid,
# 'feeders': Topology.Feeders,
# 'islands': Topology.Islands,
# 'connectivity': Topology.ConnNodeDict,
# 'equipment': Topology.EquipDict
}
self.gapps.send(reply_to, message)

elif message['requestType'] == 'GET_SNAPSHOT_TOPOLOGY':
# [Topology, timestamp] = self.get_snapshot_topology(model_mrid, message['simulationID'], message['timestamp'])
message = {
"response": "not yet supported"
# 'modelID': model_mrid,
# 'feeders': Topology.Feeders,
# 'islands': Topology.Islands,
# 'timestamp': timestamp
}
self.gapps.send(reply_to, message)
else:
message = "No valid requestType specified"
self.gapps.send(reply_to, message)

def get_switch_areas(self, model_mrid):
self.log.info('Building switch areas for ' + str(model_mrid))
# DistTopo = DistributedTopology(self.gapps, model_mrid)
# message = DistTopo.create_switch_areas(model_mrid)
# return message






def _main():
topic = "goss.gridappsd.request.data.cimtopology"
os.environ['GRIDAPPSD_USER'] = 'app_user'
os.environ['GRIDAPPSD_PASSWORD'] = '1234App'
gapps = GridAPPSD()
assert gapps.connected
topology = TopologyProcessor()
gapps.subscribe(topic, topology)
while True:
time.sleep(0.1)

if __name__ == "__main__":
_main()