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

Merged
merged 5 commits into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from 4 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
14 changes: 9 additions & 5 deletions COPYRIGHT
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@ Copyright 2023, Battelle Memorial Institute. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

2. 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.
2. 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.

3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Expand Down
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.
8 changes: 5 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ 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 = "^0.1.6a0"


[tool.poetry.group.dev.dependencies]
mock = "^5.0.2"
pytest = "^7.3.1"
yapf = "^0.33.0"
pre-commit = "^3.3.2"

[build-system]
Expand Down
14 changes: 14 additions & 0 deletions topo_background.config
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 topology_processor.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()
2 changes: 2 additions & 0 deletions topology_processor/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from topology_processor.utils.addressable import *
from topology_processor.utils.distributed_topo_message import DistributedTopologyMessage
Loading