{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Using the PowerGrid Models API" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Introduction to the PowerGrid Model API\n", "\n", "\n", "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).\n", "\n", "In the Application Components diagram (explained in detail with sample code in [GridAPPS-D Application Structure](../overview/2.4-GridAPPS-D-Application-Structure.ipynb)), the PowerGrid Models API is used for querying for the power system model and querying for model measurement MRIDs." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![power grid models](images/3.3/power_grid_models_usage.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## API Syntax Overview\n", "\n", "__Application passes query to GridAPPS-D Platform__\n", "\n", "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.\n", "\n", "The query is sent using `gapps.get_response(topic, message)` with a response expected back from the platform within the specified timeout period.\n", "\n", "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. \n", "\n", "__GridAPPS-D Platform responds to Application query__\n", "\n", "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." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### API Communication Channel\n", "\n", "All queries passed to the PowerGrid Models API need to use the correct communication channel, which is obtained using the [GridAPPS-D Topics library](3.1-API-Communication-Channels.ipynb). \n", "\n", "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.\n", "\n", "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." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from gridappsd import topics as t\n", "topic = t.REQUEST_POWERGRID_DATA" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Structure of a Query Message\n", "\n", "Queries passed to PowerGrid Models API are formatted as python dictionaries or equivalent JSON scripts wrapped as a python string. \n", "\n", "```\n", "message = {\n", " \"requestType\": \"INSERT QUERY HERE\",\n", " \"resultFormat\": \"JSON\",\n", " \"modelId\": \"OPTIONAL INSERT MODEL mRID HERE\",\n", " \"objectType\": \"OPTIONAL INSERT CIM CLASS HERE\",\n", " \"objectId\": \"OPTIONAL INSERT OBJECT mRID HERE\",\n", " \"filter\": \"OPTIONAL INSERT SPARQL FILTER HERE\"\n", "}\n", "```\n", "\n", "The components of the message are as follows:\n", "\n", "* `\"requestType\":` -- Specifies the type of query. Available requestType are listed in the next section.\n", "\n", "\n", "* `\"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.)\n", "\n", "\n", "* `\"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 spelling `model_id`.\n", "\n", "\n", "* `\"objectType\":` -- Optional. Used to filter the query to only one CIM class of equipment. Speciying the _objectID_ will override any values specified for _objectType_. \n", "\n", "\n", "* `\"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_. \n", "\n", "\n", "* `\"filter\":` -- Optional. Used to filter the query using a SPARQL filter. SPARQL queries are covered in the next lesson.\n", "\n", "\n", "The usage of each of these message components are explained in detail with code block examples below. \n", "\n", "__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. \n", "\n", "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." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Specifying the requestType\n", "\n", "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.\n", "\n", "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:\n", "\n", "* `\"requestType\": \"QUERY_MODEL_NAMES\"` -- [Query for the list of all model name mRIDs](#Query-for-mRIDs-of-all-Models)\n", "\n", "\n", "* `\"requestType\": \"QUERY_OBJECT_IDS\"` -- [Query for a list of all mRIDs for objects of a CIM class](#Query-for-mRIDs-of-Objects-in-a-Feeder)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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:\n", "\n", "* `\"requestType\": \"QUERY_MODEL_INFO\"` -- [Query for the dictionary of all details for all feeders in Blazegraph](#Query-for-Details-Dictionary-of-all-Models)\n", "\n", "\n", "* `\"requestType\": \"QUERY_OBJECT_DICT\"` -- [Query for the dictionary of all details for an object using either its _objectType_ OR its _objectID_](#Query-for-Object-Dictionary)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The third group of _requestType_ key-value pairs are for obtaining information about CIM objects and attributes:\n", "\n", "* `\"requestType\": \"QUERY_OBJECT_TYPES\"` -- [Query for the types of CIM classes of objects in the model](#Query-for-CIM-Classes-of-Objects-in-Model)\n", "\n", "\n", "* `\"requestType\": \"QUERY_OBJECT\"` -- [Query for CIM attributes of an object using its unique mRID](#Query-for-CIM-Attributes-of-an-Object)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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.\n", "\n", "* `\"requestType\": \"QUERY_OBJECT_MEASUREMENTS\"` -- [Query for all measurement types and mRIDs for an object using either its _objectType_ OR its _ObjectID_](#Querying-for-Measurements)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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](https://github.com/GRIDAPPSD/CIMHub/blob/master/queries.txt).\n", "\n", "* `\"requestType\": \"QUERY_MODEL\"` -- Query for all part of a specified model, filtered by object type using a SPARQL filter.\n", "\n", "\n", "* `\"requestType\": \"QUERY\"` -- Query using a complete SPARQL query." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## CIM Objects Supported by PowerGrid Models API\n", "\n", "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](https://github.com/GRIDAPPSD/CIMHub/blob/master/queries.txt)\n", "\n", "__CIM Classes supported by the PowerGrid Models API__\n", "\n", "* `ACLineSegment`\n", "* `Breaker`\n", "* `ConnectivityNode`\n", "* `EnergyConsumer`\n", "* `EnergySource`\n", "* `Fuse`\n", "* `LinearShuntCompensator`\n", "* `LoadBreakSwitch`\n", "* `PowerElectronicsConnection`\n", "* `PowerTransformer`\n", "* `Recloser`\n", "* `SynchronousMachine`\n", "* `TransformerTank`\n", "\n", "__CIM Classes requiring custom SPARQL queries__\n", "\n", "* `ACLineSegmentPhase`\n", "* `Analog`\n", "* `Asset`\n", "* `BaseVoltage`\n", "* `BatteryUnit`\n", "* `ConcentricNeutralCableInfo`\n", "* `CoordinateSystem`\n", "* `CurrentLimit`\n", "* `Discrete`\n", "* `EnergyConsumerPhase`\n", "* `Feeder`\n", "* `GeographicalRegion`\n", "* `House`\n", "* `IEC61970CIMVersion`\n", "* `LinearShuntCompensatorPhase`\n", "* `LoadResponseCharacteristic`\n", "* `Location`\n", "* `NoLoadTest`\n", "* `OperationalLimitSet`\n", "* `OperationalLimitType`\n", "* `OverheadWireInfo`\n", "* `PerLengthPhaseImpedance`\n", "* `PerLengthSequenceImpedance`\n", "* `PhaseImpedanceData`\n", "* `PhotovoltaicUnit`\n", "* `PositionPoint`\n", "* `PowerElectronicsConnectionPhase`\n", "* `PowerTransformerEnd`\n", "* `PowerTransformerInfo`\n", "* `RatioTapChanger`\n", "* `RegulatingControl`\n", "* `ShortCircuitTest`\n", "* `SubGeographicalRegion`\n", "* `Substation`\n", "* `SwitchPhase`\n", "* `TapChangerControl`\n", "* `TapChangerInfo`\n", "* `TapeShieldCableInfo`\n", "* `Terminal`\n", "* `TopologicalIsland`\n", "* `TopologicalNode`\n", "* `TransformerCoreAdmittance`\n", "* `TransformerEndInfo`\n", "* `TransformerMeshImpedance`\n", "* `TransformerTankEnd`\n", "* `TransformerTankInfo`\n", "* `VoltageLimit`\n", "* `WirePosition`\n", "* `WireSpacingInfo`\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Object mRIDs vs Measurement mRIDs\n", "\n", "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.\n", "\n", "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) it is also associated with a Terminal that belongs to the same _PowerSystemResource_. (Non-electrical measurements, for example weather, would not have the Terminal association). \n", "\n", "The _measurementType_ is a string code from IEC 61850, with the following currently suppported:\n", "\n", "* __PNV__ -- Phase to Neutral Voltage\n", "\n", "\n", "* __VA__ -- Volt-Amperes (apparent power)\n", "\n", "\n", "* __A__ -- Amperes (current)\n", "\n", "\n", "* __POS__ -- Position for switches and transformer taps\n", "\n", "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. \n", "\n", "Pos measurements will be discrete, for such things as tap position, switch position, or capacitor bank position. \n", "\n", "The others will be Analog, with magnitude and optional angle in degrees. \n", "\n", "Each MeasurementValue will have a timeStamp and mRID inherited from IdentifiedObject, so the values can be traced.\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Object Classes vs Control Attributes\n", "\n", "The mRIDs for controlling equipment are generally the same as those obtained using the `QUERY_OBJECT_DICT` key with the PowerGrid Models API, which is covered below in [Query for Object Dicionary](#Query-for-Object-Dictionary).\n", "\n", "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 using PowerGrid Models API and the associated control `\"attribute\"` used in a [difference message with Simulation API](../api_usage/3.6-Controlling-Simulation-API.ipynb#Publishing-Commands-to-Simulation-Input) for each category of power system equipment that are currently supported by the HELICS-GOSS Bridge. \n", "\n", "* __Switches__\n", " * CIM Class Key: `\"objectType\": \"LoadBreakSwitch\"`\n", " \n", " * Control Attribute: `\"attribute\": \"Switch.open\"`\n", " * Values: `1` is open, `0` is closed\n", "\n", "\n", "* __Capacitor Banks:__\n", " * CIM Class Key: `\"objectType\": \"LinearShuntCompensator\"`\n", " \n", " * Control Attribute: `\"attribute\": \"ShuntCompensator.sections\"`\n", " * Values: `0` is off/open, `1` is on/closed\n", " \n", " * Control Attribute: `\"attribute\": \"RegulatingControl.enabled\"`\n", " * Values: `false` is manual control, `true` is auto control by GridLab-D\n", " * If controlling cap banks with an app, set value to `false`\n", " \n", " * Control Attribute: `\"attribute\": \"RegulatingControl.mode\"`\n", " * Values: `0` is voltage, `1` is manual, `2` is reactive power, `3` is current\n", " * Setting this attibute will override any commands from application\n", " \n", " * Control Attribute: `\"attribute\": \"RegulatingControl.targetDeadband\"`\n", " * Values: number (float) for control deadband\n", " \n", " * Control Attribute: `\"attribute\": \"RegulatingControl.targetValue\"`\n", " * Values: number (float) for control target value\n", " \n", " * Control Attribute: `\"attribute\": \"ShuntCompensator.aVRDelay\"`\n", " * Values: number (float) for control delay in seconds\n", " \n", " \n", "* __Inverter-based DERs:__\n", " * CIM Class Key: `\"objectType\": \"PowerElectronicsConnection\"`\n", " \n", " * Control Attribute: `\"attribute\": \"PowerElectronicsConnection.p\"`\n", " * Values: number (float) in Watts (not kW)\n", " \n", " * Control Attribute: `\"attribute\": \"PowerElectronicsConnection.q\"`\n", " * Values: number (float) in VArs (not kVAr)\n", " \n", " \n", "* __Synchronous Rotating (diesel/LNG) DGs:__\n", " * CIM Class Key: `\"objectType\": \"SynchronousMachine\"`\n", " \n", " * Control Attribute: `\"attribute\": \"RotatingMachine.p\"`\n", " * Values: number (float) in Watts (not kW)\n", " \n", " * Control Attribute: `\"attribute\": \"RotatingMachine.q\"`\n", " * Values: number (float) in VArs (not kVAr)\n", " \n", " \n", "* __Regulating Transformer Tap:__\n", " * CIM Class Key: `\"objectType\": \"RatioTapChanger\"`\n", " \n", " * Control Attribute: `\"attribute\": \"TapChanger.step\"`\n", " * Values: integer value for tap step from -16 to 16\n", " \n", " * Control Attribute: `\"attribute\": \"TapChanger.initialDelay\"`\n", " * Values: number (float) for time delay to change tap\n", " \n", " * Control Attribute: `\"attribute\": \"TapChanger.lineDropCompensation\"`\n", " * Values: `0` is manual, `1` is automatic\n", " * If controlling tap position with an app, value should be set to `0`\n", " \n", " * Control Attribute: `\"attribute\": \"TapChanger.LineDropR\"`\n", " * Values: number (float) for line resistance\n", " * Setting this value will override any commands from application\n", " \n", " * Control Attribute: `\"attribute\": \"TapChanger.LineDropX\"`\n", " * Values: number (float) for line reactance\n", " * Setting this value will override any commands from application\n", " \n", " \n", "* __Energy Consumer:__\n", " * CIM Class Key: `\"objectType\": \"EnergyConsumer\"`\n", " \n", " * Control Attribute: `\"attribute\": \"EnergyConsumer.p\"`\n", " * Values: number (float) for base power of load\n", " \n", " \n", "__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)__" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Querying for Model mRIDS\n", "\n", "Every piece of equipment has a unique mRID, as explained in [Intro to Common Information Model](../overview/2.6-Common-Information-Model.ipynb). These mRIDs are used to identify and communicate with equipment in GridAPPS-D. \n", "\n", "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](#Querying-for-Equipment-Dictionaries) API calls in the next section. \n", "\n", "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." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Query for mRIDs of all Models\n", "\n", "This query obtains a list of all the model MRIDs stored in the Blazegraph database. \n", "\n", "Query requestType:\n", "\n", "* `\"requestType\": \"QUERY_MODEL_NAMES\"`\n", "\n", "Allowed parameters:\n", "\n", "* `\"resultFormat\":` – \"XML\" / \"JSON\" / \"CSV\" -- Optional. Will return results as a list in the format selected. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from gridappsd import topics as t\n", "topic = t.REQUEST_POWERGRID_DATA\n", "\n", "message = {\n", " \"requestType\": \"QUERY_MODEL_NAMES\",\n", " \"resultFormat\": \"JSON\"\n", "}\n", "\n", "gapps.get_response(topic, message)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![query-object-ids](images/3.3/QUERY_MODEL_NAMES.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__Python Library Method__\n", "\n", "The GridAPPSD-Python library contains a pre-built method for obtaining the mRIDs of all models, providing identical results to those obtained above.\n", "\n", "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." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "gapps.query_model_names()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Query for mRIDs of Objects in a Feeder\n", "\n", "This query is used to obtain all the mRIDs of objects of a particular CIM class in the feeder. \n", "\n", "Query responseType is\n", "\n", "* `\"requestType\": \"QUERY_OBJECT_IDS\"`\n", "\n", "Allowed parameters are:\n", "\n", "* `\"modelId\":` \"model name mRID\" -- When specified it searches against that model, if empty it will search against all models\n", "* `\"objectType\":` \"CIM Class\" -- Optional. Specifies the type of objects you wish to return details for.\n", "* `\"resultFormat\":` – \"XML\" / \"JSON\" / \"CSV\" -- Will return results as a list in the format selected. \n", "\n", "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](#CIM-Objects-Supported-by-PowerGrid-Models-API)). Other types of equipment require custom SPARQL queries.\n", "\n", "Note that the RDF URI is not included in the query, only the name of the class, such as `\"objectType\": \"ACLineSegment\"` or `\"objectType\": \"LoadBreakSwitch\"`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from gridappsd import topics as t\n", "topic = t.REQUEST_POWERGRID_DATA\n", "\n", "message = {\n", " \"requestType\": \"QUERY_OBJECT_IDS\",\n", " \"modelId\": model_mrid,\n", " \"objectType\": \"LoadBreakSwitch\",\n", " \"resultFormat\": \"JSON\"\n", "} \n", "\n", "gapps.get_response(topic, message)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It is possible to then filter the response to just a list of the mRIDs:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "response_obj = gapps.get_response(topic, message)\n", "switch_mrids = response_obj['data']['objectIds']\n", "print(switch_mrids)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![query-object-ids](images/3.3/QUERY_OBJECT_IDS.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Querying for Equipment Dictionaries\n", "\n", "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.\n", "\n", "All of the examples in this section use the IEEE 13 node model." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "model_mrid = \"_49AD8E07-3BF9-A4E2-CB8F-C3722F837B62\" # IEEE 13 Node used for all example queries" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Query for Dictionary of all Models\n", "\n", "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.\n", "\n", "Query requestType:\n", "\n", "* `\"requestType\": \"QUERY_MODEL_INFO\"`\n", "\n", "Allowed parameters:\n", "\n", "* `\"resultFormat\":` – \"XML\" / \"JSON\" / \"CSV\" -- Will return results as a list in the format selected." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from gridappsd import topics as t\n", "topic = t.REQUEST_POWERGRID_DATA\n", "\n", "message = {\n", " \"requestType\": \"QUERY_MODEL_INFO\",\n", " \"resultFormat\": \"JSON\"\n", "}\n", "\n", "gapps.get_response(topic, message)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![query-model-info](images/3.3/QUERY_MODEL_INFO.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__Python Library Method__\n", "\n", "The GridAPPSD-Python library contains a pre-built method for requesting the dictionary of all models.\n", "\n", "The `query_model_info()` method is associated with the GridAPPSD connection object and runs the same query as above:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "gapps.query_model_info()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Query for Object Dictionary\n", "\n", "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`. \n", "\n", "If neither `objectType` or `objectId` is provided, the query will provide the attributes of all the equipment in the power system model.\n", "\n", "Query requestType is\n", "\n", "* `\"requestType\": \"QUERY_OBJECT_DICT\"`\n", "\n", "Allowed parameters are\n", "\n", "* `\"modelId\":` \"model name mRID\" -- When specified it searches against that model, if empty it will search against all models\n", "\n", "* `\"objectId\":` \"object mRID\" -- Optional. Specifies the type of objects you wish to return details for.\n", "\n", "* `\"objectType\":` \"CIM Class\" -- Optional. Specifies the type of objects you wish to return details for.\n", "\n", "* `\"resultFormat\":` \"XML\" / \"JSON\" / \"CSV\" -- Will return results as a list in the format selected.\n", "\n", "Speciying the `objectId` will override any values specified for `objectType`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__Example 1: Querying for model dictionary for an objectID__" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from gridappsd import topics as t\n", "topic = t.REQUEST_POWERGRID_DATA\n", "\n", "message = {\n", " \"requestType\": \"QUERY_OBJECT_DICT\",\n", " \"modelId\": model_mrid,\n", " \"objectId\": switch_mrids[1],\n", " \"resultFormat\": \"JSON\"\n", "}\n", "\n", "gapps.get_response(topic, message)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![query-object-dict](images/3.3/QUERY_OBJECT_DICT_2.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__Example 2: Querying for model dictionary for an objectType__" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from gridappsd import topics as t\n", "topic = t.REQUEST_POWERGRID_DATA\n", "\n", "message = {\n", " \"requestType\": \"QUERY_OBJECT_DICT\",\n", " \"modelId\": model_mrid,\n", " \"objectType\": \"TransformerTank\",\n", " \"resultFormat\": \"JSON\"\n", "}\n", "\n", "gapps.get_response(topic, message)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![query-object-dict](images/3.3/QUERY_OBJECT_DICT.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__Python Library Method__\n", "\n", "The GridAPPSD-Python library contains a pre-built method for requesting the object dictionary\n", "\n", "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" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "gapps.query_object_dictionary(model_id = model_mrid, object_id = switch_mrids[1])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "gapps.query_object_dictionary(model_id = model_mrid, object_type = \"TransformerTank\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Querying for CIM Attributes\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Query for CIM Classes of Objects in Model\n", "\n", "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 (if model name mRID is empty) in the database.\n", "\n", "Query requestType is\n", "\n", "* `\"requestType\": \"QUERY_OBJECT_TYPES\"`\n", "\n", "Allowed parameters are\n", "\n", "* `\"modelId\":` \"model name mRID\" -- Optional. Searches only the particular model identified by the given unique mRID\n", "* `\"resultFormat\":` – \"XML\" / \"JSON\" / \"CSV\" -- Will return results as a list in the format selected. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__1) Query entire Blazegraph database__\n", "\n", "Omit the `\"modelId\"` parameter to search the entire blazegraph database. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from gridappsd import topics as t\n", "topic = t.REQUEST_POWERGRID_DATA\n", "\n", "message = {\n", " \"requestType\": \"QUERY_OBJECT_TYPES\",\n", " \"resultFormat\": \"JSON\"\n", "}\n", "\n", "gapps.get_response(topic, message)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![query-object-types](images/3.3/QUERY_OBJECT_TYPES.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__2) Query for only a particular model__\n", "\n", "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. \n", "\n", "Be aware of spelling and capitalization differences between JSON query spelling `\"modelId\"` and Python Library spelling `model_id`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from gridappsd import topics as t\n", "topic = t.REQUEST_POWERGRID_DATA\n", "\n", "message = {\n", " \"requestType\": \"QUERY_OBJECT_TYPES\",\n", " \"modelId\": model_mrid,\n", " \"resultFormat\": \"JSON\"\n", "}\n", "\n", "gapps.get_response(topic, message)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![query-object-types-2](images/3.3/QUERY_OBJECT_TYPES_2.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__Python Library Method__\n", "\n", "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.\n", "\n", "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.\n", "\n", "Allowed parameters are\n", "\n", "* model_id (optional) - when specified, it searches only the particular model identified by the given unique mRID" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__1) Query entire Blazegraph database__\n", "\n", "Leave the arguments blank to search all models in the Blazegraph database" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "gapps.query_object_types()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__2) Query for only a particular model__\n", "\n", "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" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "gapps.query_object_types(model_mrid)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Query for CIM Attributes of an Object\n", "\n", "This query is used to obtain all the attributes and mRIDs of those attributes for a particular object whose mRID is specified. \n", "\n", "Query responseType is\n", "\n", "* `\"requestType\": \"QUERY_OBJECT\"`\n", "\n", "Allowed parameters are:\n", "\n", "* `\"modelId\":` \"model name mRID\" -- When specified it searches against that model, if empty it will search against all models\n", "* `\"objectId\":` \"object mRID\" -- Optional. Specifies the type of objects you wish to return details for.\n", "* `\"resultFormat\":` – \"XML\" / \"JSON\" / \"CSV\" -- Will return results as a list in the format selected.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from gridappsd import topics as t\n", "topic = t.REQUEST_POWERGRID_DATA\n", "\n", "object_mrid = \"_2858B6C2-0886-4269-884C-06FA8B887319\"\n", "\n", "message = {\n", " \"requestType\": \"QUERY_OBJECT\",\n", " \"resultFormat\": \"JSON\",\n", " \"modelId\": model_mrid,\n", " \"objectId\": object_mrid\n", "}\n", "\n", "gapps.get_response(topic, message)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![query-object](images/3.3/QUERY_OBJECT.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__Python Library Method__\n", "\n", "The GridAPPSD-Python library contains a pre-built method for obtaining the mRIDs of all models, providing identical results to those obtained above.\n", "\n", "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." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "model_mrid = \"_49AD8E07-3BF9-A4E2-CB8F-C3722F837B62\" # IEEE 13 Node used for all example queries\n", "object_mrid = \"_2858B6C2-0886-4269-884C-06FA8B887319\"\n", "\n", "gapps.query_object(model_mrid, object_mrid)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Querying for Object Measurements" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Querying for Measurements\n", "\n", "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`. \n", "\n", "If neither `objectType` or `objectId` is provided, the query will provide all measurements belonging to the model.\n", "Query responseType is\n", "\n", "* `\"requestType\": \"QUERY_OBJECT_MEASUREMENTS\"`\n", "\n", "Allowed parameters are:\n", "\n", "* `\"modelId\":` \"model name mRID\" -- When specified it searches against that model, if empty it will search against all models\n", "\n", "* `\"objectId\":` \"object mRID\" -- Optional. Specifies the type of objects you wish to return details for.\n", "\n", "* `\"objectType\":` \"CIM Class\" -- Optional. Specifies the type of objects you wish to return details for.\n", "\n", "* `\"resultFormat\":` \"XML\" / \"JSON\" / \"CSV\" -- Will return results as a list in the format selected.\n", "\n", "Speciying the `objectId` will override any values specified for `objectType`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__Example 1: Querying for all measurements for an objectID__" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from gridappsd import topics as t\n", "topic = t.REQUEST_POWERGRID_DATA\n", "\n", "message = {\n", " \"requestType\": \"QUERY_OBJECT_MEASUREMENTS\",\n", " \"modelId\": model_mrid,\n", " \"objectId\": switch_mrids[1],\n", " \"resultFormat\": \"JSON\"\n", "}\n", "\n", "gapps.get_response(topic, message)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![query-object](images/3.3/QUERY_OBJECT_MEASUREMENTS.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__Example 2: Querying for all measurements for an objectType__" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from gridappsd import topics as t\n", "topic = t.REQUEST_POWERGRID_DATA\n", "\n", "message = {\n", " \"requestType\": \"QUERY_OBJECT_MEASUREMENTS\",\n", " \"modelId\": model_mrid,\n", " \"objectType\": \"ACLineSegment\",\n", " \"resultFormat\": \"JSON\"\n", "}\n", "\n", "gapps.get_response(topic, message)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![query-object](images/3.3/QUERY_OBJECT_MEASUREMENTS_2.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Filtering Returned Data\n", "\n", "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](3.2-API-Message-Structure.ipynb#Parsing-Returned-Data)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Create query message to obtain measurement mRIDs for all switches\n", "message = {\n", " \"modelId\": model_mrid,\n", " \"requestType\": \"QUERY_OBJECT_MEASUREMENTS\",\n", " \"resultFormat\": \"JSON\",\n", " \"objectType\": \"LoadBreakSwitch\"\n", "}\n", "\n", "# Pass query message to PowerGrid Models API\n", "response_obj = gapps.get_response(t.REQUEST_POWERGRID_DATA, message)\n", "measurements_obj = response_obj[\"data\"]\n", "\n", "# Switch position measurements (Pos)\n", "Pos_obj = [k for k in measurements_obj if k['type'] == 'Pos']\n", "\n", "# Switch terminal phase-neutral-voltage measurements (PNV)\n", "PNV_obj = [k for k in measurements_obj if k['type'] == 'PNV']\n", "\n", "# Switch volt-ampere apparent power measurements (VA)\n", "VA_obj = [k for k in measurements_obj if k['type'] == 'VA']\n", "\n", "# Switch current measurements (A)\n", "A_obj = [k for k in measurements_obj if k['type'] == 'A']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Querying with a Custom SPARQL String\n", "\n", "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." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Query using a SPARQL filter\n", "\n", "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. \n", "\n", "If neither `objectType` or `filter` is specified, the query will provide all objects belonging to the model.\n", "\n", "\n", "Query responseType is\n", "\n", "* `\"requestType\": \"QUERY_MODEL\"`\n", "\n", "Allowed parameters are:\n", "\n", "* `\"modelId\":` \"model name mRID\" -- Optional. When specified it searches against that model, if empty it will search against all models\n", "\n", "* `\"objectType\":` \"CIM Class\" -- Optional. Specifies the type of objects you wish to return details for.\n", "\n", "* `\"filter\":` \"SPARQL triple\" -- Optional. Applies the SPARQL triple filter to the query results\n", "\n", "* `\"resultFormat\":` \"XML\" / \"JSON\" / \"CSV\" -- Will return results as a list in the format selected.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from gridappsd import topics as t\n", "topic = t.REQUEST_POWERGRID_DATA\n", "\n", "message = {\n", " \"requestType\": \"QUERY_MODEL\",\n", " \"modelId\": \"_49AD8E07-3BF9-A4E2-CB8F-C3722F837B62\" ,\n", " \"resultFormat\": \"JSON\",\n", " \"filter\": \"?s cim:IdentifiedObject.name '650z'\",\n", " \"objectType\": \"http://iec.ch/TC57/CIM100#ConnectivityNode\"\n", "}\n", "\n", "gapps.get_response(topic, message, timeout = 60)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![query-model](images/3.3/QUERY_MODEL.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__Python Library Method__\n", "\n", "The GridAPPSD-Python library contains a pre-built method for passing very simple queries. The SPARQL filter key is not supported. \n", "\n", "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." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "gapps.query_model(model_id = model_mrid, object_type = \"http://iec.ch/TC57/CIM100#ConnectivityNode\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "gapps.query_model(model_id = model_mrid, object_id = \"_7BEDDADD-0A14-429F-8601-9EA8B892CA6E\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Query using a Generic SPARQL Query\n", "\n", "This query is used to pass a generic SPARQL query to the Blazegraph database. \n", "\n", "Query responseType is\n", "\n", "* `\"requestType\": \"QUERY\"`\n", "\n", "\n", "Allowed parameters are:\n", "\n", "* `\"modelId\":` \"model name mRID\" -- Optinal. When specified it searches against that model, if empty it will search against all models\n", "\n", "* `\"queryString\":` \"SPARQL query text\" -- Applies the SPARQL triple filter to the query results\n", "\n", "* `\"resultFormat\":` \"XML\" / \"JSON\" / \"CSV\" -- Will return results as a list in the format selected.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from gridappsd import topics as t\n", "topic = t.REQUEST_POWERGRID_DATA\n", "\n", "message = {\n", " \"requestType\": \"QUERY\",\n", " \"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}\",\n", " \"resultFormat\": \"JSON\"\n", "}\n", "\n", "gapps.get_response(topic, message)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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](localhost:8889/bigdata/#query). The STOMP client contains a JSON validator which may struggle with the line breaks included in SPARQL queries." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "__Python Library Method__\n", "\n", "The GridAPPSD-Python library contains a pre-built method for passing generic SPARQL queries\n", "\n", "The `query_data(query, timeout)` method is associated with the GridAPPSD connection object and runs the generic SPARQL query on the Blazegraph database." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "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}\"\n", "\n", "gapps.query_data(query = sparql_message, timeout = 60)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Available Models in Default Installation\n", "\n", "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.\n", "\n", "|Name|Features|Houses|Buses|Nodes|Branches|Load|Origin|\n", "|----|--------|------|-----|-----|--------|----|------|\n", "|ACEP_PSIL|480-volt microgrid with PV, wind and diesel|No|8|24|13|0.28|UAF|\n", "|EPRI_DPV_J1|1800 kW PV in 11 locations|No|3434|4245|4901|9.69|EPRI DPV|\n", "|IEEE13|Added CIM sampler|No|22|57|51|3.44|IEEE (mod)|\n", "|IEEE13_Assets|Uses line spacings and wires|No|16|41|40|3.58|IEEE (mod)|\n", "|IEEE13_OCHRE|Added 40 service transformers and triplex loads|Yes|74|160|75|0.24|IEEE (mod)|\n", "|IEEE37|Delta system|No|39|117|73|2.59|IEEE|\n", "|IEEE123|Includes switches for reconfiguration|No|130|274|237|3.62|IEEE|\n", "|IEEE123_PV|Added 3320 kW PV in 14 locations|Yes|214|442|334|0.27|IEEE/NREL|\n", "|IEEE8500|Large model, balanced secondary loads|Yes|4876|8531|6103|11.98|IEEE|\n", "|IEEE9500|Added 2 grid sources and DER|Yes|5294|9499|6823|9.14|GridAPPS-D|\n", "|R2_12_47_2|Supports approximately 4000 houses|Yes|853|1631|1086|6.26|PNNL|\n", "|Transactive|Added 1281 secondary loads to IEEE123|Yes|1516|3051|2812|3.92|GridAPPS-D|" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### IEEE 13 Node Model\n", "\n", "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.\n", "\n", "This model is recommended for debugging as the model is small enough that issues can be traced by hand.\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### IEEE 123 Node Model\n", "\n", "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.\n", "\n", "This model is recommended for initial app testing and debugging thorugh the first stages of development.\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### IEEE 123 Node Model with PV\n", "\n", "This model is a derivative of the IEEE 123 Node model and includes rooftop solar throughout the system." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### IEEE 8500 Node Model\n", "\n", "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.\n", "\n", "* Length: 170 km\n", "* Nominal voltage: 12.47 kV, 120/240V\n", "* Topology: radial\n", "* Service transformers: yes\n", "* Customers: 1177\n", "* Peak load: 11.1 MW\n", "* Normally-open switches: no" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 9500 Node Test System\n", "\n", "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. \n", "\n", "This is the recommended target feeder for development of all new applications" ] }, { "cell_type": "markdown", "metadata": {}, "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![9500-node-DGs](images/3.3/9500-node-DGs.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### PNNL Taxonomy Feeder" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### EPRI J1 Feeder" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### UAF Microgrid" ] }, { "cell_type": "markdown", "metadata": {}, "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Adding New Models to GridAPPS-D\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "* `git clone https://github.com/GRIDAPPSD/CIMHub.git`\n", "\n", "* `pip install SPARQLWrapper numpy pandas`\n", "\n", "Copy CIM XML file and UUID file into CIMHub directory. \n", "\n", "Open CIMHub directory in terminal:\n", "\n", "* `cd CIMHub`\n", "\n", "View the list of feeder models currently in the Blazegraph Database:\n", "\n", "* `python3 ../CIMHub/utils/ListFeeders.py` \n", "\n", "Upload your new model using `curl` to Blazegraph, specifying the name and MRID of your new feeder:\n", "\n", "* `curl -s -D- -H 'Content-Type: application/xml' --upload-file 'yournewmodel.xml' -X POST 'http://localhost:8889/bigdata/namespace/kb/sparql'`\n", "\n", "Create the set of txt files containing the measurable objects in your new model using the `ListMeasurables` script:\n", "\n", "* `python3 ../CIMHub/utils/ListMeasureables.py cimhubconfig.json yournewmodel _YOUR-NEW-MODEL-FEEDER-MRID-123ABC456`\n", "\n", "Insert the measurements into Blazegraph using the `InsertMeasurements` script. The measurement MRIDs will be saved into the file `uuidfile.json`:\n", "\n", "* ```for f in `ls -1 *txt`; do python3 ../CIMHub/utils/InsertMeasurements.py cimhubconfig.json $f uuidfile.json; done```\n", "\n", "Insert houses into Blazegraph using the `InsertHouses` script. The measurement MRIDs for the houses will be saved into the file `uuidfile2.json`:\n", "* `python3 ../CIMHub/utils/InsertHouses.py cimhubconfig.json _YOUR-NEW-MODEL-FEEDER-MRID-123ABC456 1 1 uuidfile2.json`\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Open the GridAPPS-D Viz in a new window and you should be able to start a simulation using your new model\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Adding New Models to the PowerGrid Models GitHub Repo\n", "\n", "All models included by default in GridAPPS-D are stored in the [PowerGrid Models GitHub repository](https://github.com/GRIDAPPSD/Powergrid-Models/)\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![GridAPPS-D-narrow.png](../images/GridAPPS-D_narrow.png)" ] } ], "metadata": { "celltoolbar": "Tags", "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.5" } }, "nbformat": 4, "nbformat_minor": 4 }