From 1b5fe17dd765a0882c0e27a519de4d651c42e3af Mon Sep 17 00:00:00 2001 From: ortega-herguetamar Date: Thu, 17 Jan 2019 09:52:50 +0100 Subject: [PATCH 1/8] IIDM Importer Post processor tutorial --- docs/tutorials/iidm/importerPostProcessor.md | 343 +++++++++++++++++++ 1 file changed, 343 insertions(+) create mode 100644 docs/tutorials/iidm/importerPostProcessor.md diff --git a/docs/tutorials/iidm/importerPostProcessor.md b/docs/tutorials/iidm/importerPostProcessor.md new file mode 100644 index 00000000..8a2f599a --- /dev/null +++ b/docs/tutorials/iidm/importerPostProcessor.md @@ -0,0 +1,343 @@ +--- +title: How to write an import post processor + +layout: default +--- + +`ImportPostProcessor` is an interface which can be used to modify a network model, right after it's been read by an [importer](../../iidm/importer/index.md) . Powsybl-core includes [some implementations](../../iidm/importer/post-processor/index.md) of this interface and allows to create new ones. + +In this tutorial you will see how to write a new post processor, for increasing the loads' active power of a network by a fixed percentage: + +- through a Groovy script, using the [groovyScript](../../iidm/importer/post-processor/GroovyScriptPostProcessor.md) post processor +- through a JavaScript script, using the [javaScript](../../iidm/importer/post-processor/JavaScriptPostProcessor.md) post processor +- implementing a new import post processor, in a dedicated java module + +Groovy script and java module post processor, will execute also a loadflow. + + +# Groovy script (for the groovy script post processor) + +The Groovy script can be found [here](https://github.com/powsybl/powsybl-core/blob/docs/docs/samples/groovyScriptPostProcessor/increase-active-power-postprocessor.groovy). + +You have to: + +1. Write a `Groovy` script that implements the processor's business logic. + +```xml + +package com.powsybl.samples.groovyScriptPostProcessor + +import com.powsybl.iidm.network.Load +import com.powsybl.iidm.network.Network +import com.powsybl.loadflow.LoadFlowFactory +import com.powsybl.loadflow.LoadFlowParameters +import com.powsybl.commons.config.ComponentDefaultConfig + +println " Imported Network's Data: Network Id: " + network.getId() + " Generators: " + network.getGeneratorCount()+ " Lines : " + network.getLineCount() +" Loads: " + network.getLoadCount() + +println "\nDump LOADS " +println " id | p | p+1%" + +// change the network +def percent = 1.01 + +network.getLoads().each { load -> + if ( load.getTerminal != null) { + def currentValue = load.getTerminal().getP() + load.getTerminal().setP(currentValue * percent) + def newVal = load.getTerminal().getP() + println " "+load.getId() + "| " +currentValue + "| " + newVal + } +} + +// execute a LF +println "\nExecute a LF" + +def defaultConfig = ComponentDefaultConfig.load() +loadFlowFactory = defaultConfig.newFactoryImpl(LoadFlowFactory.class) +loadFlowParameters = new LoadFlowParameters(LoadFlowParameters.VoltageInitMode.UNIFORM_VALUES) +loadFlow = loadFlowFactory.create(network, computationManager, 0) +result = loadFlow.run(network.getStateManager().getWorkingStateId(),loadFlowParameters).join() + +println " LF results - converge:" + result.ok + " ; metrics: " +result.getMetrics() + +``` + +This script uses the `network` variable, that is binded by the [groovyScript](../../iidm/importer/post-processor/GroovyScriptPostProcessor.md) post processor. + +ComponenteDefaultConfig load configuration from [powsybl configuration file](../../configuration/modules/componentDefaultConfig.md). It provide access to loadFlow implemantation. + +2. Declare the `groovyScript` post processor (for more details refer to [import](../../configuration/modules/index.md)) in the configuration file: + +### YAML version + +```yaml +import: + postProcessors: groovyScript +``` + +### XML version + +```xml + + groovyScript + +``` + +and configure the groovy script's path to use in the [groovy-post-processor](../../configuration/modules/groovy-post-processor.md) module section, also in the configuration file: + +### YAML version + +```yaml +groovy-post-processor: + script: /groovyScriptPostProcessor/increase-active-power-postprocessor.groovy +``` + +### XML version + +```xml + + + +``` + +3. Configure the `loadFlow` + +The configuration for the loadflow is defined in [powsybl configuration file](../../configuration/modules/index.md). + +The loadflow implementation to use is read from the `LoadFlowFactory` tag of the `componentDefaultConfig` section. + +Here is an example of a minimal configuration for a mock loadflow (i.e. an implementation that does nothing on the network). If you want to execute a true computation, you should configure a 'real' loadflow implementation (e.g. RTE's [Hades2LF](http://www.rte.itesla-pst.org/), is currently free to use for academic/non commercial purposes). + +### YAML version + +```yaml +componentDefaultConfig: + LoadFlowFactory: com.powsybl.loadflow.mock.LoadFlowFactoryMock +``` + +### XML version + +```xml + + com.powsybl.loadflow.mock.LoadFlowFactoryMock + +``` + + + +# Java script (for the JavaScript post processor) + +The 'JavaScript' code can be found [here](https://github.com/powsybl/powsybl-core/blob/docs/docs/samples/javaScriptPostProcessor/increaseActivePowerPostProcessor.js). + +1 Write a `JavaScript` code that implements the processor's business logic. + +```java +var debug = true; + +function increaseLoadActivePower( load, percent) { + if (load != null) { + var p = load.getTerminal().getP(); + load.getTerminal().setP(p * percent); + if (debug) + print("Load id: "+load.getId() +" Increase load active power, from " + p + " to " + load.getTerminal().getP()); + } + +} + +var percent = 1.01; + +if (network == null) { + throw new NullPointerException() +} + +for each (load in network.getLoads()) { + increaseLoadActivePower(load , percent); +} + +``` + + +This script uses the network variable, that is binded by the [javaScript](../../iidm/importer/post-processor/JavaScriptPostProcessor.md) post processor. + +2 Declare the javaScript post processor (for more details refer to [import](../../configuration/modules/index.md)) in the configuration file: + + +### YAML version +```yaml +import: + postProcessors: javaScript +``` + + +### XML version +```xml + + javaScript + +``` + +and configure the javaScript code's path to use in the [javascript-post-processor](../../configuration/modules/javaScriptPostProcessor.md) module section, also in the configuration file: + +```xml + + + +``` + +# JavaPostProcessor + +In order to implement a `JavaPostProcessor` you have to: + +1. Write an implementation of `com.powsybl.iidm.import_.ImportPostProcessor` interface and declare it as a service implementation with `@AutoService` annotation. +2. Add the new post processor to the configuration file. +3. Compile your project, add the jar to your powsybl installation + +Here is an empty class template that implements `com.powsybl.iidm.import_ImportPostProcessor` interface, where you will put the code to increase loads active power of the network. + +```java +@AutoService(ImportPostProcessor.class) +public class IncreaseActivePowerPostProcessor implements ImportPostProcessor { + + @Override + public String getName() { + return null; + } + + @Override + public void process(Network network, ComputationManager computationManager) throws Exception { + } + +} +``` + +You have to declare the class as a service implementation, using `@Autoservice` annotation. This will allow you to have the new post processor available and recognized by the platform. +The methods of the `ImportPostProcessor` interface to override in your class are: + +- `getName` method, that returns the processor's name; it must be used to configure it. +- `process` method, that executes the processing on the imported network + +```java +@AutoService(ImportPostProcessor.class) +public class IncreaseActivePowerPostProcessor implements ImportPostProcessor { + + private static final Logger LOGGER = LoggerFactory.getLogger(IncreaseActivePowerPostProcessor.class); + + private static final String NAME = "increaseActivePower"; + + @Override + public String getName() { + return NAME; + } + + @Override + public void process(Network network, ComputationManager computationManager) { + Objects.requireNonNull(network); + LOGGER.info("Execute {} post processor on network {}", getName(), network.getId()); + double percent = 1.01; + LOGGER.info(" Dump LOADS "); + LOGGER.info(" id | p | p+1%"); + network.getLoadStream().forEach(load -> { + if ( load.getTerminal() != null) { + double p = load.getTerminal().getP(); + load.getTerminal().setP(p * percent); + LOGGER.info(" {} | {} | {}", load.getId(), p, load.getTerminal().getP()); + } + }); + + LOGGER.info("Execute loadFlow"); + ComponentDefaultConfig defaultConfig = ComponentDefaultConfig.load(); + LoadFlowParameters loadFlowParameters = new LoadFlowParameters(LoadFlowParameters.VoltageInitMode.UNIFORM_VALUES); + LoadFlow loadFlow = defaultConfig.newFactoryImpl(LoadFlowFactory.class).create(network, computationManager, 0); + LoadFlowResult results = loadFlow.run(network.getStateManager().getWorkingStateId(), loadFlowParameters).join(); + LOGGER.info("LoadFlow results {}, Metrics {} ", results.isOk(), results.getMetrics().toString()); + + } +} + +``` + +The `process` method is in charge of executing your processing, implementing your business logic. +The `network` parameter provides access to the imported network (see `com.powsybl.iidm.network.Network` class), you can work on it using the IIDM API. In the sample code we use it to get the list of all network loads (`network.getLoads()`). +The `computationManager` parameter provides you access to the computation platform. It can be used to distribute the computation (e.g. if you need to run a loadflow on the imported network, or some other kind of heavy computation). +The rest of the code in our sample class, increases of 1% the active power of each load, using the IIDM API, and log old and updated values. For the logging we use the `org.slf4j.Logger` class. + +JavaPostProcessor requires the following dependencies: + +- `com.google.auto.service`: configuration/metadata generator for java.util.ServiceLoader-style service providers +- `powsybl-iidm-converter-api`: API to import and export IIDM network. +- `powsybl-loadflow-api` : API to run loadflow. + +If you use maven, add them to your pom.xml file: + +```xml + + com.google.auto.service + auto-service + 1.0-rc2 + + + com.powsybl + powsybl-iidm-converter-api + ${powsybl.version} + + + com.powsybl + powsybl-loadflow-api + ${powsybl.version} + +``` + +In your project you also need to add the other dependencies required by your post processor business logic implementation. + +# Update your installation with the new import post processor + +In the following sections we refer to installation and sample directories as: + +- <[POWSYBL_HOME](https://github.com/powsybl/powsybl-core/blob/docs/docs/configuration/directoryList.md)> +- <[POWSYBL_SAMPLES](https://github.com/powsybl/powsybl-core/blob/docs/docs/configuration/directoryList.md)> + +Run the following command to create your project jar: + +```bash +$> cd +$> mvn install +``` + +The generated jar will be located under the target folder of your project: Copy the generated jar to `/share/java/` folder (you might need to copy in this directory other dependencies jars, specific to your new post processor). + +In order to enable the post processor on powsybl platform, you must declare its name in the [configuration file](../../configuration/modules/index.md) : add the NAME specified for your processor to the `postProcessors` tag of the `import` section. In our example it will be `increaseActivePower`. + +```xml + + increaseActivePower + +``` + +In the example above, there is just one post processor enabled. More processors names can be specified in the `postProcessors` tag, as a comma separated list - ref. [post-processors](../../configuration/modules/index.md) + +Before test your postProcessor `increaseActivePower`, you must `configure a load flow implementation`. Referring to `Configure the loadFlow` described in Groovy script (for the groovy script post processor) section of this document. + +In order to execute the new post processor run a command that involve a network import, for instance [run the convert-network command](../../tools/convert-network.md) : + +```bash +$> cd /bin +$> ./itools convert-network --input-file NetworkfileName --output-format XIIDM --output-file /tmp/networkfilename.xiidm +``` + +where `NetworkfileName` is a the path of the input network file. + +The log file will show: + +- Imported newtwork file: networkfileName imported + +- Network Id: (networkId) Generators: (numGenerators) Lines: (numLines) Loads: (numLoads) + +- Dump LOADS: + +list of id | p | p+1% + +- LF results - converge:true ; metrics: [:] + +The converted network, will have the active power of all loads increased by 1%. + From 9973f4112add164811dda4ac54a2e7bde465a5c6 Mon Sep 17 00:00:00 2001 From: ortega-herguetamar Date: Thu, 17 Jan 2019 14:49:37 +0100 Subject: [PATCH 2/8] IIDM Importer Post processor tutorial --- docs/configuration/modules/javaScriptPostProcessor.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration/modules/javaScriptPostProcessor.md b/docs/configuration/modules/javaScriptPostProcessor.md index 26e50a0d..b14f150b 100644 --- a/docs/configuration/modules/javaScriptPostProcessor.md +++ b/docs/configuration/modules/javaScriptPostProcessor.md @@ -16,7 +16,7 @@ default value of this property is `true`. ## script The `script` property is an optional property that defines the absolute path of the javascript script to apply to use. The default value of this property is `import-post-processors.js`. This file is read from the -[powsybl configuration folder](../itools.md#powsybl_config_dirs). +[powsybl configuration folder](../../iidm/importer/post-processor/JavaScriptPostProcessor.html). # Examples From 7aaed546c6c25f32eaba04a6fd068879e5928883 Mon Sep 17 00:00:00 2001 From: ortega-herguetamar Date: Thu, 17 Jan 2019 14:50:14 +0100 Subject: [PATCH 3/8] New link to IIDM importer post processor tutorial --- docs/tutorials/index.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/tutorials/index.md b/docs/tutorials/index.md index 291eb46b..229c1d2b 100644 --- a/docs/tutorials/index.md +++ b/docs/tutorials/index.md @@ -19,4 +19,5 @@ layout: default - [How to extend AFS]() - [How to write an IIDM exporter](iidm/exporter.md) - [How to write an IIDM importer](iidm/importer.md) -- [How to extend iTools]() \ No newline at end of file +- [How to write an IIDM importer post processor](iidm/importerPostProcessor.md) +- [How to extend iTools]() From c2e1ce9e53a95790fa3f8d0ead4cd225f0e3795c Mon Sep 17 00:00:00 2001 From: ortega-herguetamar Date: Thu, 17 Jan 2019 14:50:29 +0100 Subject: [PATCH 4/8] New link to IIDM importer post processor tutorial --- docs/tutorials/iidm/importerPostProcessor.md | 24 ++++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/docs/tutorials/iidm/importerPostProcessor.md b/docs/tutorials/iidm/importerPostProcessor.md index 8a2f599a..cfa8b945 100644 --- a/docs/tutorials/iidm/importerPostProcessor.md +++ b/docs/tutorials/iidm/importerPostProcessor.md @@ -17,13 +17,13 @@ Groovy script and java module post processor, will execute also a loadflow. # Groovy script (for the groovy script post processor) -The Groovy script can be found [here](https://github.com/powsybl/powsybl-core/blob/docs/docs/samples/groovyScriptPostProcessor/increase-active-power-postprocessor.groovy). +The Groovy script can be found [here](https://github.com/powsybl/powsybl-tutorials). You have to: 1. Write a `Groovy` script that implements the processor's business logic. -```xml +```groovy package com.powsybl.samples.groovyScriptPostProcessor @@ -65,7 +65,7 @@ println " LF results - converge:" + result.ok + " ; metrics: " +result.getMetric This script uses the `network` variable, that is binded by the [groovyScript](../../iidm/importer/post-processor/GroovyScriptPostProcessor.md) post processor. -ComponenteDefaultConfig load configuration from [powsybl configuration file](../../configuration/modules/componentDefaultConfig.md). It provide access to loadFlow implemantation. +ComponenteDefaultConfig loads configuration from [powsybl configuration file](../../configuration/modules/componentDefaultConfig.md). It provide access to loadFlow implemantation. 2. Declare the `groovyScript` post processor (for more details refer to [import](../../configuration/modules/index.md)) in the configuration file: @@ -128,11 +128,11 @@ componentDefaultConfig: # Java script (for the JavaScript post processor) -The 'JavaScript' code can be found [here](https://github.com/powsybl/powsybl-core/blob/docs/docs/samples/javaScriptPostProcessor/increaseActivePowerPostProcessor.js). +The 'JavaScript' code can be found [here](https://github.com/powsybl/powsybl-tutorials). 1 Write a `JavaScript` code that implements the processor's business logic. -```java +```javascript var debug = true; function increaseLoadActivePower( load, percent) { @@ -179,6 +179,14 @@ import: and configure the javaScript code's path to use in the [javascript-post-processor](../../configuration/modules/javaScriptPostProcessor.md) module section, also in the configuration file: +### YAML version +```yaml +javaScriptPostProcessor: + script: /javaScriptPostProcessor/increase-active-power-postprocessor.js +``` + +### XML version + ```xml @@ -294,8 +302,8 @@ In your project you also need to add the other dependencies required by your pos In the following sections we refer to installation and sample directories as: -- <[POWSYBL_HOME](https://github.com/powsybl/powsybl-core/blob/docs/docs/configuration/directoryList.md)> -- <[POWSYBL_SAMPLES](https://github.com/powsybl/powsybl-core/blob/docs/docs/configuration/directoryList.md)> +- <[POWSYBL_HOME](https://github.com/powsybl/powsybl-tutorials)> +- <[POWSYBL_SAMPLES](https://github.com/powsybl/powsybl-tutorials)> Run the following command to create your project jar: @@ -329,6 +337,7 @@ where `NetworkfileName` is a the path of the input network file. The log file will show: +```markdown - Imported newtwork file: networkfileName imported - Network Id: (networkId) Generators: (numGenerators) Lines: (numLines) Loads: (numLoads) @@ -338,6 +347,7 @@ The log file will show: list of id | p | p+1% - LF results - converge:true ; metrics: [:] +``` The converted network, will have the active power of all loads increased by 1%. From a26ea1528f9928f9a47f2e7eaab72fa95b026497 Mon Sep 17 00:00:00 2001 From: ortega-herguetamar Date: Thu, 17 Jan 2019 18:18:36 +0100 Subject: [PATCH 5/8] Correction configuration JavaScript --- .../iidm/importer/post-processor/JavaScriptPostProcessor.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/iidm/importer/post-processor/JavaScriptPostProcessor.md b/docs/iidm/importer/post-processor/JavaScriptPostProcessor.md index fc77ab27..efeeed1b 100644 --- a/docs/iidm/importer/post-processor/JavaScriptPostProcessor.md +++ b/docs/iidm/importer/post-processor/JavaScriptPostProcessor.md @@ -23,7 +23,7 @@ set the path of the JS script. import: postProcessors: javaScript -groovy-post-processor: +javaScriptPostProcessor: script: /tmp/script.js ``` @@ -32,9 +32,9 @@ groovy-post-processor: javaScript - + - + ``` # Examples From a5694823b585f01467c8c58c329d5b04fb9a9b83 Mon Sep 17 00:00:00 2001 From: ortega-herguetamar Date: Thu, 17 Jan 2019 18:19:12 +0100 Subject: [PATCH 6/8] Correction Link configuration JavaScript --- docs/configuration/modules/javaScriptPostProcessor.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration/modules/javaScriptPostProcessor.md b/docs/configuration/modules/javaScriptPostProcessor.md index b14f150b..26e50a0d 100644 --- a/docs/configuration/modules/javaScriptPostProcessor.md +++ b/docs/configuration/modules/javaScriptPostProcessor.md @@ -16,7 +16,7 @@ default value of this property is `true`. ## script The `script` property is an optional property that defines the absolute path of the javascript script to apply to use. The default value of this property is `import-post-processors.js`. This file is read from the -[powsybl configuration folder](../../iidm/importer/post-processor/JavaScriptPostProcessor.html). +[powsybl configuration folder](../itools.md#powsybl_config_dirs). # Examples From 4a35b5df2999f5c50e05954b168d6b242f313af0 Mon Sep 17 00:00:00 2001 From: ortega-herguetamar Date: Thu, 17 Jan 2019 18:21:38 +0100 Subject: [PATCH 7/8] Rename obsolete methods getStateManager and getWorkingStateId by getVariantManager and getWorkingVariantId. --- docs/tutorials/iidm/importerPostProcessor.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tutorials/iidm/importerPostProcessor.md b/docs/tutorials/iidm/importerPostProcessor.md index cfa8b945..bc62bc3b 100644 --- a/docs/tutorials/iidm/importerPostProcessor.md +++ b/docs/tutorials/iidm/importerPostProcessor.md @@ -57,7 +57,7 @@ def defaultConfig = ComponentDefaultConfig.load() loadFlowFactory = defaultConfig.newFactoryImpl(LoadFlowFactory.class) loadFlowParameters = new LoadFlowParameters(LoadFlowParameters.VoltageInitMode.UNIFORM_VALUES) loadFlow = loadFlowFactory.create(network, computationManager, 0) -result = loadFlow.run(network.getStateManager().getWorkingStateId(),loadFlowParameters).join() +result = loadFlow.run(network.getVariantManager().getWorkingVariantId(),loadFlowParameters).join() println " LF results - converge:" + result.ok + " ; metrics: " +result.getMetrics() @@ -65,7 +65,7 @@ println " LF results - converge:" + result.ok + " ; metrics: " +result.getMetric This script uses the `network` variable, that is binded by the [groovyScript](../../iidm/importer/post-processor/GroovyScriptPostProcessor.md) post processor. -ComponenteDefaultConfig loads configuration from [powsybl configuration file](../../configuration/modules/componentDefaultConfig.md). It provide access to loadFlow implemantation. +ComponenteDefaultConfig provides configuration from [powsybl configuration file](../../configuration/modules/componentDefaultConfig.md). It provides access to loadFlow implemantation. 2. Declare the `groovyScript` post processor (for more details refer to [import](../../configuration/modules/index.md)) in the configuration file: @@ -257,7 +257,7 @@ public class IncreaseActivePowerPostProcessor implements ImportPostProcessor { ComponentDefaultConfig defaultConfig = ComponentDefaultConfig.load(); LoadFlowParameters loadFlowParameters = new LoadFlowParameters(LoadFlowParameters.VoltageInitMode.UNIFORM_VALUES); LoadFlow loadFlow = defaultConfig.newFactoryImpl(LoadFlowFactory.class).create(network, computationManager, 0); - LoadFlowResult results = loadFlow.run(network.getStateManager().getWorkingStateId(), loadFlowParameters).join(); + LoadFlowResult results = loadFlow.run(network.getVariantManager().getWorkingVariantId(), loadFlowParameters).join(); LOGGER.info("LoadFlow results {}, Metrics {} ", results.isOk(), results.getMetrics().toString()); } From 8edb92a251e2437c006f0bef3b9190eee009afd9 Mon Sep 17 00:00:00 2001 From: Mathieu BAGUE Date: Mon, 21 Jan 2019 21:25:44 +0100 Subject: [PATCH 8/8] Lot of fixes in importerPostProcessor tutorial --- docs/tutorials/iidm/importerPostProcessor.md | 251 +++++++++++-------- 1 file changed, 140 insertions(+), 111 deletions(-) diff --git a/docs/tutorials/iidm/importerPostProcessor.md b/docs/tutorials/iidm/importerPostProcessor.md index bc62bc3b..e16f0918 100644 --- a/docs/tutorials/iidm/importerPostProcessor.md +++ b/docs/tutorials/iidm/importerPostProcessor.md @@ -1,19 +1,21 @@ --- -title: How to write an import post processor - +title: How to write an import post processor layout: default --- -`ImportPostProcessor` is an interface which can be used to modify a network model, right after it's been read by an [importer](../../iidm/importer/index.md) . Powsybl-core includes [some implementations](../../iidm/importer/post-processor/index.md) of this interface and allows to create new ones. - -In this tutorial you will see how to write a new post processor, for increasing the loads' active power of a network by a fixed percentage: +`ImportPostProcessor` is an interface that can be used to modify a network model, right after it's been read by an +[importer](../../iidm/importer). Powsybl provides [some implementations](../../iidm/importer/post-processor) of this +interface and allows to create new ones. -- through a Groovy script, using the [groovyScript](../../iidm/importer/post-processor/GroovyScriptPostProcessor.md) post processor -- through a JavaScript script, using the [javaScript](../../iidm/importer/post-processor/JavaScriptPostProcessor.md) post processor -- implementing a new import post processor, in a dedicated java module - -Groovy script and java module post processor, will execute also a loadflow. +In this tutorial you will see how to write a new post processor, for increasing the loads' active power of a network by +a fixed percentage: +- through a Groovy script, using the [groovyScript](../../iidm/importer/post-processor/GroovyScriptPostProcessor.md) +post processor +- through a JavaScript script, using the [javaScript](../../iidm/importer/post-processor/JavaScriptPostProcessor.md) +post processor +- implementing a new import post processor, in a dedicated java module +Groovy script and java module post processor, will also run a loadflow. # Groovy script (for the groovy script post processor) @@ -24,7 +26,6 @@ You have to: 1. Write a `Groovy` script that implements the processor's business logic. ```groovy - package com.powsybl.samples.groovyScriptPostProcessor import com.powsybl.iidm.network.Load @@ -33,109 +34,108 @@ import com.powsybl.loadflow.LoadFlowFactory import com.powsybl.loadflow.LoadFlowParameters import com.powsybl.commons.config.ComponentDefaultConfig -println " Imported Network's Data: Network Id: " + network.getId() + " Generators: " + network.getGeneratorCount()+ " Lines : " + network.getLineCount() +" Loads: " + network.getLoadCount() - -println "\nDump LOADS " -println " id | p | p+1%" +println "Imported Network's Data: Network Id: " + network.getId() + + " Generators: " + network.getGeneratorCount() + + " Lines: " + network.getLineCount() + + " Loads: " + network.getLoadCount() +println "" // change the network -def percent = 1.01 +def percent = 1.01 +println "Dump LOADS" +println "id\tp\tp+1%" network.getLoads().each { load -> - if ( load.getTerminal != null) { + if (load.getTerminal != null) { def currentValue = load.getTerminal().getP() load.getTerminal().setP(currentValue * percent) def newVal = load.getTerminal().getP() - println " "+load.getId() + "| " +currentValue + "| " + newVal + + println load.getId() + "\t" + currentValue + "\t" + newVal } } +println "" // execute a LF -println "\nExecute a LF" - +println "Execute a LF" def defaultConfig = ComponentDefaultConfig.load() loadFlowFactory = defaultConfig.newFactoryImpl(LoadFlowFactory.class) loadFlowParameters = new LoadFlowParameters(LoadFlowParameters.VoltageInitMode.UNIFORM_VALUES) loadFlow = loadFlowFactory.create(network, computationManager, 0) result = loadFlow.run(network.getVariantManager().getWorkingVariantId(),loadFlowParameters).join() -println " LF results - converge:" + result.ok + " ; metrics: " +result.getMetrics() - +println "LF results - converge: " + result.ok + " ; metrics: " + result.getMetrics() ``` -This script uses the `network` variable, that is binded by the [groovyScript](../../iidm/importer/post-processor/GroovyScriptPostProcessor.md) post processor. +Note that this script uses the `network` variable, that is automatically binded to the network that has been previously +loaded. The `ComponentDefaultConfig` class provides configuration loaded from the +[powsybl configuration file](../../configuration/modules/componentDefaultConfig.md). In this example, we use the +configuration to get the loadflow implementation to use. -ComponenteDefaultConfig provides configuration from [powsybl configuration file](../../configuration/modules/componentDefaultConfig.md). It provides access to loadFlow implemantation. - -2. Declare the `groovyScript` post processor (for more details refer to [import](../../configuration/modules/index.md)) in the configuration file: - -### YAML version +2. Declare the `groovyScript` post processor in your configuration file: +### YAML ```yaml import: postProcessors: groovyScript ``` -### XML version - +### XML ```xml groovyScript ``` -and configure the groovy script's path to use in the [groovy-post-processor](../../configuration/modules/groovy-post-processor.md) module section, also in the configuration file: - -### YAML version +and configure the groovy script's path to use in the [groovy-post-processor](../../configuration/modules/groovy-post-processor.md) +module section, also in the configuration file: +### YAML ```yaml groovy-post-processor: - script: /groovyScriptPostProcessor/increase-active-power-postprocessor.groovy + script: /home/user/increase-active-power-postprocessor.groovy ``` -### XML version - +### XML ```xml - + ``` 3. Configure the `loadFlow` -The configuration for the loadflow is defined in [powsybl configuration file](../../configuration/modules/index.md). - -The loadflow implementation to use is read from the `LoadFlowFactory` tag of the `componentDefaultConfig` section. - -Here is an example of a minimal configuration for a mock loadflow (i.e. an implementation that does nothing on the network). If you want to execute a true computation, you should configure a 'real' loadflow implementation (e.g. RTE's [Hades2LF](http://www.rte.itesla-pst.org/), is currently free to use for academic/non commercial purposes). - -### YAML version +The configuration for the loadflow is also defined in [powsybl configuration file](../../configuration/modules/index.md). +The loadflow implementation to use is read from the `LoadFlowFactory` property of the `componentDefaultConfig` section. +Here is an example of a minimal configuration for a mock loadflow (i.e. an implementation that does nothing on the network). +### YAML ```yaml componentDefaultConfig: LoadFlowFactory: com.powsybl.loadflow.mock.LoadFlowFactoryMock ``` -### XML version - +### XML ```xml com.powsybl.loadflow.mock.LoadFlowFactoryMock ``` - +If you want to execute a true computation, you should configure a 'real' loadflow implementation. Please refer to this +documentation [page](https://rte-france.github.io/hades2/index.html) to learn how to configure powsybl to use RTE's +implementation. # Java script (for the JavaScript post processor) -The 'JavaScript' code can be found [here](https://github.com/powsybl/powsybl-tutorials). +The JavaScript code can be found [here](https://github.com/powsybl/powsybl-tutorials). -1 Write a `JavaScript` code that implements the processor's business logic. +1. Write a `JavaScript` code that implements the processor's business logic. ```javascript var debug = true; -function increaseLoadActivePower( load, percent) { +function increaseLoadActivePower(load, percent) { if (load != null) { var p = load.getTerminal().getP(); load.getTerminal().setP(p * percent); @@ -154,56 +154,60 @@ if (network == null) { for each (load in network.getLoads()) { increaseLoadActivePower(load , percent); } - ``` +Note that this script uses the `network` variable, that is automatically binded to the network that has been previously +loaded. -This script uses the network variable, that is binded by the [javaScript](../../iidm/importer/post-processor/JavaScriptPostProcessor.md) post processor. +2. Declare the javaScript post processor in your configuration file: -2 Declare the javaScript post processor (for more details refer to [import](../../configuration/modules/index.md)) in the configuration file: - - -### YAML version +### YAML ```yaml import: postProcessors: javaScript ``` - -### XML version +### XML ```xml javaScript ``` -and configure the javaScript code's path to use in the [javascript-post-processor](../../configuration/modules/javaScriptPostProcessor.md) module section, also in the configuration file: +and configure the javaScript code's path to use in the [javascript-post-processor](../../configuration/modules/javaScriptPostProcessor.md) +module section, also in the configuration file: -### YAML version +### YAML ```yaml javaScriptPostProcessor: - script: /javaScriptPostProcessor/increase-active-power-postprocessor.js + script: /home/user/increase-active-power-postprocessor.js ``` -### XML version - +### XML ```xml - + ``` -# JavaPostProcessor +# Java implementation -In order to implement a `JavaPostProcessor` you have to: +In order to implement a `PostProcessor` in Java, you have to: -1. Write an implementation of `com.powsybl.iidm.import_.ImportPostProcessor` interface and declare it as a service implementation with `@AutoService` annotation. -2. Add the new post processor to the configuration file. -3. Compile your project, add the jar to your powsybl installation +1. Write an implementation of `com.powsybl.iidm.import_.ImportPostProcessor` interface and declare it as a service, using +the `@AutoService` annotation. +2. Compile your project, add the jar to your powsybl installation. +3. Add the new post processor to the configuration file. -Here is an empty class template that implements `com.powsybl.iidm.import_ImportPostProcessor` interface, where you will put the code to increase loads active power of the network. +Here is an empty class template that implements `com.powsybl.iidm.import_ImportPostProcessor` interface, where you will +put the code to increase loads active power of the network. ```java +import com.google.auto.service.AutoService; +import com.powsybl.computation.ComputationManager; +import com.powsybl.iidm.import_.ImportPostProcessor; +import com.powsybl.iidm.network.Network; + @AutoService(ImportPostProcessor.class) public class IncreaseActivePowerPostProcessor implements ImportPostProcessor { @@ -213,17 +217,17 @@ public class IncreaseActivePowerPostProcessor implements ImportPostProcessor { } @Override - public void process(Network network, ComputationManager computationManager) throws Exception { + public void process(Network network, ComputationManager computationManager) { } - } ``` -You have to declare the class as a service implementation, using `@Autoservice` annotation. This will allow you to have the new post processor available and recognized by the platform. -The methods of the `ImportPostProcessor` interface to override in your class are: +You have to declare the class as a service implementation, using `@Autoservice` annotation. This will allow you to have +the new post processor available and recognized by the platform. -- `getName` method, that returns the processor's name; it must be used to configure it. -- `process` method, that executes the processing on the imported network +The methods of the `ImportPostProcessor` interface to override in your class are: +- the `getName` method, that returns the processor's name; it must be used to configure it. +- the `process` method, that executes the processing on the imported network ```java @AutoService(ImportPostProcessor.class) @@ -242,14 +246,15 @@ public class IncreaseActivePowerPostProcessor implements ImportPostProcessor { public void process(Network network, ComputationManager computationManager) { Objects.requireNonNull(network); LOGGER.info("Execute {} post processor on network {}", getName(), network.getId()); + double percent = 1.01; - LOGGER.info(" Dump LOADS "); - LOGGER.info(" id | p | p+1%"); + LOGGER.info("Dump LOADS"); + LOGGER.info("id\tp\tp+1%"); network.getLoadStream().forEach(load -> { - if ( load.getTerminal() != null) { + if (load.getTerminal() != null) { double p = load.getTerminal().getP(); load.getTerminal().setP(p * percent); - LOGGER.info(" {} | {} | {}", load.getId(), p, load.getTerminal().getP()); + LOGGER.info("{}\t{}\t{}", load.getId(), p, load.getTerminal().getP()); } }); @@ -258,26 +263,27 @@ public class IncreaseActivePowerPostProcessor implements ImportPostProcessor { LoadFlowParameters loadFlowParameters = new LoadFlowParameters(LoadFlowParameters.VoltageInitMode.UNIFORM_VALUES); LoadFlow loadFlow = defaultConfig.newFactoryImpl(LoadFlowFactory.class).create(network, computationManager, 0); LoadFlowResult results = loadFlow.run(network.getVariantManager().getWorkingVariantId(), loadFlowParameters).join(); - LOGGER.info("LoadFlow results {}, Metrics {} ", results.isOk(), results.getMetrics().toString()); - + LOGGER.info("LF results - converge: {} ; metrics {} ", results.isOk(), results.getMetrics().toString()); } } - ``` -The `process` method is in charge of executing your processing, implementing your business logic. -The `network` parameter provides access to the imported network (see `com.powsybl.iidm.network.Network` class), you can work on it using the IIDM API. In the sample code we use it to get the list of all network loads (`network.getLoads()`). -The `computationManager` parameter provides you access to the computation platform. It can be used to distribute the computation (e.g. if you need to run a loadflow on the imported network, or some other kind of heavy computation). -The rest of the code in our sample class, increases of 1% the active power of each load, using the IIDM API, and log old and updated values. For the logging we use the `org.slf4j.Logger` class. +The `process` method is in charge of executing your processing, implementing your business logic. The `network` parameter +provides access to the imported network (see `com.powsybl.iidm.network.Network` class), you can work on it using the IIDM +API. In the sample code we use it to get the list of all network loads, using the `network.getLoads()` method. -JavaPostProcessor requires the following dependencies: +The `computationManager` parameter provides you access to the computation platform. It can be used to distribute the +computation (e.g. if you need to run a loadflow on the imported network, or some other kind of heavy computation). -- `com.google.auto.service`: configuration/metadata generator for java.util.ServiceLoader-style service providers -- `powsybl-iidm-converter-api`: API to import and export IIDM network. -- `powsybl-loadflow-api` : API to run loadflow. +The rest of the code in our sample class, increases of 1% the active power of each load, using the IIDM API, and log old +and updated values. For the logging we use the `org.slf4j.Logger` class. -If you use maven, add them to your pom.xml file: +JavaPostProcessor requires the following dependencies: +- `com.google.auto.service`: configuration/metadata generator for `java.util.ServiceLoader`-style service providers. +- `powsybl-iidm-converter-api`: API to import and export IIDM network. +- `powsybl-loadflow-api`: API to run loadflow. +If you use maven, add them to your `pom.xml` file: ```xml com.google.auto.service @@ -298,23 +304,26 @@ If you use maven, add them to your pom.xml file: In your project you also need to add the other dependencies required by your post processor business logic implementation. -# Update your installation with the new import post processor - -In the following sections we refer to installation and sample directories as: - -- <[POWSYBL_HOME](https://github.com/powsybl/powsybl-tutorials)> -- <[POWSYBL_SAMPLES](https://github.com/powsybl/powsybl-tutorials)> - -Run the following command to create your project jar: +## Build and update your installation with the new post processor +To build your post processor, run the following command: ```bash -$> cd -$> mvn install +$> mvn package ``` -The generated jar will be located under the target folder of your project: Copy the generated jar to `/share/java/` folder (you might need to copy in this directory other dependencies jars, specific to your new post processor). +The generated jar will be located under the target folder of your project. Copy the generated jar to `share/java/` folder +of your powsybl distribution (you might need to copy in this directory other dependencies jars, specific to your new post +processor). -In order to enable the post processor on powsybl platform, you must declare its name in the [configuration file](../../configuration/modules/index.md) : add the NAME specified for your processor to the `postProcessors` tag of the `import` section. In our example it will be `increaseActivePower`. +In order to enable the post processor, you must declare its name in the [configuration file](../../configuration/modules/index.md): +add the NAME specified for your processor to the `postProcessors` property of the `import` module. In our example it will +be `increaseActivePower`. + +### YAML +```yaml +import: + postProcessors: increaseActivePower +``` ```xml @@ -322,23 +331,43 @@ In order to enable the post processor on powsybl platform, you must declare its ``` -In the example above, there is just one post processor enabled. More processors names can be specified in the `postProcessors` tag, as a comma separated list - ref. [post-processors](../../configuration/modules/index.md) +In the example above, there is just one post processor enabled. More processors names can be specified in the `postProcessors` +property, as a comma separated list. -Before test your postProcessor `increaseActivePower`, you must `configure a load flow implementation`. Referring to `Configure the loadFlow` described in Groovy script (for the groovy script post processor) section of this document. +Before testing your post processor `increaseActivePower`, you must configure a load flow implementation in [powsybl +configuration file](../../configuration/modules/index.md). The loadflow implementation to use is read from the `LoadFlowFactory` +property of the `componentDefaultConfig` section. Here is an example of a minimal configuration for a mock loadflow (i.e. +an implementation that does nothing on the network). -In order to execute the new post processor run a command that involve a network import, for instance [run the convert-network command](../../tools/convert-network.md) : +### YAML +```yaml +componentDefaultConfig: + LoadFlowFactory: com.powsybl.loadflow.mock.LoadFlowFactoryMock +``` +### XML +```xml + + com.powsybl.loadflow.mock.LoadFlowFactoryMock + +``` + +If you want to execute a true computation, you should configure a 'real' loadflow implementation. Please refer to this +documentation [page](https://rte-france.github.io/hades2/index.html) to learn how to configure powsybl to use RTE's +implementation. + +# Test +In order to execute the new post processor run a command that involve a network import, for instance run the +[convert-network](../../tools/convert-network.md) command: ```bash $> cd /bin -$> ./itools convert-network --input-file NetworkfileName --output-format XIIDM --output-file /tmp/networkfilename.xiidm +$> ./itools convert-network --input-file network.xiidm --output-format XIIDM --output-file /tmp/network.xiidm ``` -where `NetworkfileName` is a the path of the input network file. - The log file will show: ```markdown -- Imported newtwork file: networkfileName imported +- Imported newtwork file: network.xiidm imported - Network Id: (networkId) Generators: (numGenerators) Lines: (numLines) Loads: (numLoads)