Work Flow

Find below some tips for a better workflow for using windPRO Scripting.

Determing what properties correspond

In the Overview Services you can see the arguments of the methods provided by the windPRO SCRIPTING interface. Often those are properties of a windPRO object or calculation. The naming of the properties are usually quite telling on what they are corresponding in the windPRO GUI. But it is not always easily possible to determine how to set them correctly. At the same time, we usually know what we want to set in the GUI.

There is a good workflow to determine how to change the setting for an object that you want to use. You can get the object or calculation (with the associated Get method). This gives you all the properties of the object as they are at that moment. Now you can change the properties in the GUI and save those changes. You can now get the object again, setting it to another variable and compare the properties of the two objects.

There is helper function in the python package that we provide called windproapi.compare_objects(zeep_dict, zeep_dict_compare). This function will print out properties that are different between the objects. Even if only one change, e.g. only one box was ticked in the GUI, multiple properties might have changed. You can now use this information to change the properties of object in your code.

For example, if you want to add a new noise sensitive area object and want to set it to a certain country (or loop through a list of different settings).

  • Create object via scripting

  • Get object with ObjNSAService.GetNSAObject

  • Open oject in the GUI and change the country setting

  • Get object again with ObjNSAService.GetNSAObject

  • use compare_obejcts to see the differences

The code example below indicates the workflow with changes that we want to determine commented out.

# Changing the country
new_obj = objects_service.AddObject(apiObjType='NSA',
                                lat=56.02,
                                lng=10.66,
                                userDesc='Script added ')
nsa_obj = obj_NSA_service.GetNSAObject(new_obj.Handle)
nsa_obj_default = deepcopy(nsa_obj)

# Execute until here and make changes in the GUI to the
# nsa_obj.PreDefinedCountry = 1
# nsa_obj.PreDefinedType = 1
# nsa_obj.PreDefined = 2
# nsa_obj.KindOfDemand = 'kodAbsolute'
# nan_to_skipvalue(nsa_obj)
# obj_NSA_service.SetNSAObject(nsa_obj)

# Compare the object after the GUI changes to the initially generated one.
nsa_obj = obj_NSA_service.GetNSAObject(nsa_obj.Handle)
print(compare_objects(nsa_obj, nsa_obj_default))

The output form compare_objects will shows the following

[{'double': [[0.0, 0.0], [0.0]]},
 {'double': [[37.0, 39.0], [0.0]]},
 {'KindOfDemand': ['kodAbsolute', 'kodUnknown']},
 {'PreDefinedCountry': [1, 0]},
 {'PreDefinedType': [1, 0]},
 {'PreDefined': [2, 0]},
 {'NoiseDemandWindSpeedDependent': [True, False]},
 {'NoiseDemandWindSpeedFrom': [6.0, 0.0]},
 {'NoiseDemandWindSpeedTo': [8.0, 0.0]},
 {'NoiseDemandWindSpeedStep': [2.0, 0.0]}]

In this example there are more changes to the property than just the country. Differences in ‘PreDefinedCountry’, ‘PreDefinedType’, and ‘PreDefined’ clearly stand out as important to the choice of country. Additionally, KindOfDemand needs to be set as well (in 4.0). The other parameters that have changed are the consequence of changing the country settings.

Starting Scripts from the GUI

You can now also start scripts from the windPRO GUI. Click on the Scripting button under the Tools menu. You will have a window opening that will allow you to allow you activate and deactivate the scripting mode where you can also choose a port number. For executing scripts you need to define a batch or exe file that is called from windPRO. WindPRO will give this file two positional arguments: the full path to the python file selected and the port number. You can select additional command line arguments that will be passed to the batch file in an extra field.

The example batch file below shows how to call python from windPRO with setting conda environemnts. You will need to adapt this to fit the python setup on your machine.

set PATH=%PATH%;C:\Users\USER\AppData\Local\miniconda3\;C:\Users\USER\AppData\Local\miniconda3\Scripts
call conda init cmd.exe
call conda activate windproapi
set PYTHONPATH=%PYTHONPATH%;C:\Users\USER\code\windPRO\python
python -u %*

Calling a script from windPRO will open a dialog box where the stdout and stderr are displayed. You can click on the button called “Terminate Script” which executes this command to kill the python process.

taskkill.exe /t /F /pid %d

This will kill the python execution where it is and might leave your project in a compromised state.

Using long command line arguments is not practical for many scripts. It is up to the user to define and decide how to best execute script and get the necessary inputs. One option is to use Excel and define functionality and the calling of scripts from there. Another option is to use a light weight python interface like Streamlit to have a browser based setup to interact with windPRO via Scripting. A short example how to use streamlit would be a batch file like this:

set PATH=%PATH%;%userprofile%\AppData\Local\miniconda3\;%userprofile%\AppData\Local\miniconda3\Scripts
call %userprofile%\AppData\Local\miniconda3\Library\bin\conda.bat init cmd.exe
call conda activate cons_scripting
set PYTHONPATH=%PYTHONPATH%;%userprofile%\code\cons_scripting
python -m streamlit run %1 -- %2

With a mininal python example of a python file that lets you choose between existing Park calculations in your project.

import streamlit as st
import sys
from windproapi import nan_to_skipvalue
from windproapi import WindProApi

api_port = int(sys.argv[1])

# Opening windPRO
_windproapi = WindProApi(api_port=api_port)

calculation_service = _windproapi.get_service('CalculationService')
mcp_calcs = calculation_service.GetCalcs('CalcPark')
if mcp_calcs is None:
    mcp_calcs = []

park_name = st.selectbox('Park calculation', [d.Name for d in mcp_calcs])
st.text(f'{park_name}')