Skip to content

Commit

Permalink
Update for agent.
Browse files Browse the repository at this point in the history
  • Loading branch information
craig8 committed Oct 23, 2023
1 parent 77ff786 commit ec72e24
Show file tree
Hide file tree
Showing 9 changed files with 208 additions and 143 deletions.
30 changes: 23 additions & 7 deletions scripts/pycharm-launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@

def write_required_statement(out=sys.stderr):
out.write("""Required Environment Variables
AGENT_VIP_IDENTITY - Required
AGENT_VIP_IDENTITY - Required
Optional Environmental Variables
AGENT_CONFIG - Set to <agent directory>/config by default
VOLTTRON_HOME - Set to ~/.volttron by default
Expand Down Expand Up @@ -113,9 +113,14 @@ def write_required_statement(out=sys.stderr):
sys.exit(10)

if agent_identity:
new_dir = os.path.join(volttron_home, 'keystores', agent_identity)
if not os.path.exists(new_dir):
os.makedirs(new_dir)
agent_keystore_dir = os.path.join(volttron_home, 'keystores', agent_identity)
if os.path.exists(agent_keystore_dir):
with open(agent_keystore_dir + '/keystore.json', 'r') as fin:
json_obj = jsonapi.loads(fin.read())
pubkey = json_obj['public']
secret = json_obj['secret']
else:
os.makedirs(agent_keystore_dir)
try:
output = subprocess.check_output(['vctl', 'auth', 'keypair'],
env=os.environ.copy(),
Expand All @@ -126,16 +131,17 @@ def write_required_statement(out=sys.stderr):
sys.stderr.write("Call was:\n\tvctl auth keypair\n")
sys.stderr.write("Output of command: {}".format(e.output))
sys.stderr.write("Your environment might not be setup correctly!")
os.rmdir(new_dir)
os.rmdir(agent_keystore_dir)
write_required_statement()
sys.exit(20)
else:
keystore_file = os.path.join(new_dir, "keystore.json")
keystore_file = os.path.join(agent_keystore_dir, "keystore.json")
json_obj = jsonapi.loads(output)
with open(keystore_file, 'w') as fout:
fout.write(output)

pubkey = json_obj['public']
secret = json_obj['secret']
try:
params = [
'vctl', 'auth', 'add', '--credentials', "{}".format(pubkey), '--user_id',
Expand All @@ -149,13 +155,23 @@ def write_required_statement(out=sys.stderr):
except subprocess.CalledProcessError as e:
sys.stderr.write(str(e))
sys.stderr.write("Command returned following output: {}".format(e.output))
shutil.rmtree(new_dir)
shutil.rmtree(agent_keystore_dir)
sys.stderr.write("Couldn't authenticate agent id: {}\n".format(agent_identity))
sys.stderr.write("Call was: {}\n".format(params))
sys.stderr.write("Your environment might not be setup correctly!")
write_required_statement()
sys.exit(20)

if not pubkey or not secret:
raise ValueError(f"Missing publickey or secretkey for {agent_identity}")

# Populate the serverkey
with open(os.path.join(volttron_home, "keystore"), 'r') as fin:
json_obj = jsonapi.loads(fin.read())
os.environ['VOLTTRON_SERVERKEY'] = json_obj['public']

os.environ['AGENT_PUBLICKEY'] = pubkey
os.environ['AGENT_SECRETKEY'] = secret
if not parsed.silence:
sys.stdout.write("For your information (-s) to not print this message.")
write_required_statement(sys.stdout)
Expand Down
63 changes: 45 additions & 18 deletions services/core/IEEE_2030_5/AGENTDEMO.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,31 @@
# 2030.5 Agent Demo

This readme walks through a demo of an inverter publishing points to the VOLTTRON message bus where the 2030.5 agent will receive it. The 2030.5 agent will then create MirrorUsagePoints and POST MirrorMeterReadings to the 2030.5 server. In addition, the demo will also allow the user to create a DERControl event. During the activation of the event, the agent will log messages to the 2030.5 server.
# 2030.5 Agent Demo #

The demo will require three terminal windows to be open. The first will be for executing the main VOLTTRON process. The second will be for executing the 2030.5 server. The third will be for executing the agent demo through a web interface. For the rest of this document, VOLTTRON_ROOT is assumed to be where one has cloned the volttron repository.
This readme walks through a demo of an inverter publishing points to the
VOLTTRON message bus where the 2030.5 agent will receive it. The
2030.5 agent will then create MirrorUsagePoints and POST
MirrorMeterReadings to the 2030.5 server. In addition,
the demo will also allow the user to create a DERControl event. During the
activation of the event, the agent will log messages to the 2030.5 server.

First configure the server then the VOLTTRON instance and findally the web based demo.
The demo will require three terminal windows to be open. The first will be for
executing the main VOLTTRON process. The second will be for executing the
2030.5 server. The third will be for executing the agent demo through a
web interface. For the rest of this document, VOLTTRON_ROOT is assumed to be
where one has cloned the volttron repository.

## 2030.5 Server
First configure the server then the VOLTTRON instance and findally the web based
demo.

For the server software we will be using a server from a team at PNNL. The GridAPPS-D team has created a 2030.5 server and it is available at <https://pypi.org/project/gridappsd-2030-5/>. The source code is still in a private repo, but will be released at some time in the future.
## 2030.5 Server ##

1. In a new terminal create a new virtual environment and install the gridappsd server. **This directory should be outside the main volttron tree**
For the server software we will be using a server from a team at PNNL. The
GridAPPS-D team has created a 2030.5 server and it is available at
<https://pypi.org/project/gridappsd-2030-5/>. The source code is still in
a private repo, but will be released at some time in the future.

1. In a new terminal create a new virtual environment and install the
gridappsd server. **This directory should be outside the main volttron tree**

```bash
> mkdir 2030_5_server
Expand All @@ -24,7 +39,10 @@ For the server software we will be using a server from a team at PNNL. The Grid
(serverenv)> pip install gridappsd-2030-5
```

1. The server is now installed. Next copy the openssl.cnf and server.yml file from the $VOLTTRON_ROOT/services/core/IEEE_2030_5/demo directory to the newly created 2030_5_server directory. After copying the current directory should look like the following.
1. The server is now installed. Next copy the openssl.cnf and server.yml file
from the $VOLTTRON_ROOT/services/core/IEEE_2030_5/demo directory to the newly
created 2030_5_server directory. After copying the current directory should
look like the following.

```bash
(serverenv)> ls -l
Expand All @@ -33,11 +51,16 @@ For the server software we will be using a server from a team at PNNL. The Grid
server.yml
```

1. Modify the openssl.cnf to include the correct values for [req_distinguished_name]. Or use the defaults. The server will create self-signed certificates for the client to use.
1. Modify the openssl.cnf to include the correct values for [req_distinguished_name].
Or use the defaults. The server will create self-signed certificates for the
client to use.

1. Modify the server.yml file. The default server.yml file contains a device (id: dev1) and DERProgram. **dev1 must be present for the demo to run smoothly.**
1. Modify the server.yml file. The default server.yml file contains a device (id: dev1) and
DERProgram. **dev1 must be present for the demo to run smoothly.**

1. Start the server from the activated serverenv **This step will create development certificates for you**. By default the certificates will be generated and stored in ~/tls. One can change this location in the server.yml configuration file.
1. Start the server from the activated serverenv **This step will create development certificates
for you**. By default the certificates will be generated and stored in ~/tls. One can change
this location in the server.yml configuration file.

```bash
(serverenv)> 2030_5_server server.yml --no-validate
Expand All @@ -46,9 +69,10 @@ For the server software we will be using a server from a team at PNNL. The Grid
# (serverenv)> 2030_5_server server.yml --no-validate --no-create-certs
```

## Demo Requirements
## Demo Requirements ##

For this demo, start a VOLTTRON default instance from the command line. The following command will start VOLTTRON in the background writing to a volttron.log file.
For this demo, start a VOLTTRON default instance from the command line. The following command will
start VOLTTRON in the background writing to a volttron.log file.

1. Activate and start the volttron instance.

Expand All @@ -71,8 +95,9 @@ For this demo, start a VOLTTRON default instance from the command line. The fol
<mark>Note ed1 is the identity that needs to be in the configuration on the web demo</mark>
1. Open another terminal to run a simulated platform.driver. In this case, an inverter with a connected battery is being simulated.
1. Open another terminal to run a simulated platform.driver. In this case, an inverter with a
connected battery is being simulated.
```bash
> cd $VOLTTRON_ROOT
> source env/bin/activate
Expand All @@ -81,7 +106,7 @@ For this demo, start a VOLTTRON default instance from the command line. The fol
This process will start publishing "all" messages for the inverter to the VOLTTRON message bus.
1. Open another terminal to start the demo server in.
1. Open another terminal to start the demo server in.
```bash
> cd $VOLTTRON_ROOT
Expand All @@ -91,15 +116,17 @@ For this demo, start a VOLTTRON default instance from the command line. The fol
...
```
1. Run the webgui.py script using the python interpretor. This should open a webpage allowing one to test the functionality of the 2030.5 agent. By default it will open at <http://0.0.0.0:8080>.
1. Run the webgui.py script using the python interpretor. This should open a webpage allowing one
to test the functionality of the 2030.5 agent. By default it will open at <http://0.0.0.0:8080>.
```bash
(volttron)> python demo/webgui.py
```
## The Demo
The demo starts with local time in the top followed by 2030.5's GMT time as a intenger. The integer is how 2030.5 communicates datetimes within the protocol. Five tabs are displayable and are
The demo starts with local time in the top followed by 2030.5's GMT time as a intenger. The integer
is how 2030.5 communicates datetimes within the protocol. Five tabs are displayable and are
pictured below:

![Configuration Tab](./demo/images/configuration.png)
Expand Down
30 changes: 17 additions & 13 deletions services/core/IEEE_2030_5/demo/inverter_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,18 +171,22 @@ def run_inverter(timesteps=50) -> Generator:
i_ac = (s_ac / v_ac) * 1000
print(
f"p_ac = {p_ac}, s_ac = {s_ac}, q_ac= {q_ac}, PF = {PF}, v_ac = {v_ac}, i_ac = {i_ac}")
yield dict(v_mp=dc['v_mp'],
p_mp=dc['p_mp'],
i_x=dc['i_x'],
i_xx=dc['i_xx'],
v_oc=dc['v_oc'],
i_sc=dc['i_sc'],
p_ac=p_ac,
s_ac=p_ac,
q_ac=q_ac,
v_ac=v_ac,
i_ac=i_ac,
PF=PF)
yield dict(INV_REAL_PWR=p_ac,
INV_REAC_PWR=q_ac,
BAT_SOC=int(v_ac / p_ac),
INV_OP_STATUS_MODE=3)
# v_mp=dc['v_mp'],
# p_mp=dc['p_mp'],
# i_x=dc['i_x'],
# i_xx=dc['i_xx'],
# v_oc=dc['v_oc'],
# i_sc=dc['i_sc'],
# p_ac=p_ac,
# s_ac=p_ac,
# q_ac=q_ac,
# v_ac=v_ac,
# i_ac=i_ac,
# PF=PF)
# single phase circuit calculation


Expand Down Expand Up @@ -249,4 +253,4 @@ def run_inverter(timesteps=50) -> Generator:
# fp.write(json.dumps(dict(headers=headers, message=points.forbus())) + "\n")
gevent.sleep(10)

agent.core.stop()
agent.core.stop()
43 changes: 23 additions & 20 deletions services/core/IEEE_2030_5/demo/server.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ devices:
- fsa1
- fsa2
ders:
- der1
programs:
- Program 1
- description: DER 1

- id: dev2
device_categories:
Expand All @@ -60,40 +58,45 @@ devices:
fsas:
- fsa2
ders:
- der2
- description: DER 2


fsa:
fsas:
- description: fsa1
programs:
- Program 1
- description: fsa2
programs:
- Program 1



programs:
- description: Program 1
primacy: 0
DefaultDERControl:
setESDelay: 30
setGradW: 1000

DERControlBase:
opModConnect: true
opModEnergize: true


ders:
- description: der1
program: Program 1

- description: der2
program: Program 1

curves:
- description: Curve 1
curveType: opModVoltVar
curveType: 11
CurveData:
- xvalue: 5
yvalue: 10


- xvalue: 99
yvalue: 50
- xvalue: 103
yvalue: -50
- xvalue: 101
yvalue: -50
- xvalue: 97
yvalue: 50
rampDecTms: 600
rampIncTms: 600
rampPT1Tms: 10
xMultiplier: 0
yMultiplier: 0
yRefType: 3
8 changes: 4 additions & 4 deletions services/core/IEEE_2030_5/example.config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ keyfile: ~/tls/private/dev1.pem
certfile: ~/tls/certs/dev1.crt
server_hostname: 127.0.0.1
# the pin number is used to verify the server is the correct server
pin: 12345
pin: 111115

# Log the request and responses from the server.
log_req_resp: true
Expand All @@ -18,7 +18,7 @@ default_der_control_poll: 60

MirrorUsagePointList:
# MirrorMeterReading based on Table E.2 IEEE Std 2030.5-18
- subscription_point: p_ac
- subscription_point: INV_REAL_PWR
mRID: 5509D69F8B3535950000000000009182
description: DER Inverter Real Power
roleFlags: 49
Expand All @@ -34,7 +34,7 @@ MirrorUsagePointList:
intervalLength: 300
powerOfTenMultiplier: 0
uom: 38
- subscription_point: q_ac
- subscription_point: INV_REAC_PWR
mRID: 5509D69F8B3535950000000000009184
description: DER Inverter Reactive Power
roleFlags: 49
Expand Down Expand Up @@ -80,6 +80,6 @@ DERSettings:
setMaxW:
multiplier: 0
value: 0

# Note this file MUST be in the config store or this agent will not run properly.
point_map: config:///inverter_sample.csv
Loading

0 comments on commit ec72e24

Please sign in to comment.