Skip to content

Commit 1f90afd

Browse files
committed
Update readme.md
1 parent 7d9f4a4 commit 1f90afd

File tree

14 files changed

+449
-167
lines changed

14 files changed

+449
-167
lines changed

README.md

Lines changed: 1 addition & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -37,130 +37,6 @@ Both of these configuration files should be placed in the current working direct
3737
### Example openssl.cnf
3838

3939
```ini
40-
#
41-
# OpenSSL example configuration file.
42-
# This is mostly being used for generation of certificate requests.
43-
#
44-
45-
# This definition stops the following lines choking if HOME isn't
46-
# defined.
47-
HOME = .
48-
RANDFILE = $ENV::HOME/.rnd
49-
50-
# Extra OBJECT IDENTIFIER info:
51-
#oid_file = $ENV::HOME/.oid
52-
oid_section = new_oids
53-
54-
# To use this configuration file with the "-extfile" option of the
55-
# "openssl x509" utility, name here the section containing the
56-
# X.509v3 extensions to use:
57-
# extensions =
58-
# (Alternatively, use a configuration file that has only
59-
# X.509v3 extensions in its main [= default] section.)
60-
61-
[ new_oids ]
62-
63-
# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
64-
# Add a simple OID like this:
65-
# testoid1=1.2.3.4
66-
# Or use config file substitution like this:
67-
# testoid2=${testoid1}.5.6
68-
69-
# Policies used by the TSA examples.
70-
tsa_policy1 = 1.2.3.4.1
71-
tsa_policy2 = 1.2.3.4.5.6
72-
tsa_policy3 = 1.2.3.4.5.7
73-
74-
####################################################################
75-
[ ca ]
76-
default_ca = CA_default # The default ca section
77-
78-
[ CA_default ]
79-
dir = /home/gridappsd/tls # Where everything is kept
80-
certs = $dir/certs # Where the issued certs are kept
81-
database = $dir/index.txt # database index file.
82-
# several certs with same subject.
83-
new_certs_dir = $dir/certs # default place for new certs.
84-
certificate = $dir/certs/ec-cacert.pem # The CA certificate
85-
serial = $dir/serial # The current serial number
86-
crlnumber = $dir/crlnumber # the current crl number
87-
# must be commented out to leave a V1 CRL
88-
private_key = $dir/private/ec-cakey.pem # The private key
89-
90-
name_opt = ca_default # Subject Name options
91-
cert_opt = ca_default # Certificate field options
92-
93-
default_days = 365 # how long to certify for
94-
default_crl_days= 30 # how long before next CRL
95-
default_md = sha256 # use SHA-256 by default
96-
preserve = no # keep passed DN ordering
97-
policy = policy_match
98-
99-
# For the CA policy
100-
[ policy_match ]
101-
countryName = optional
102-
stateOrProvinceName = optional
103-
organizationName = optional
104-
organizationalUnitName = optional
105-
commonName = optional
106-
emailAddress = optional
107-
108-
[ policy_anything ]
109-
countryName = optional
110-
stateOrProvinceName = optional
111-
localityName = optional
112-
organizationName = optional
113-
organizationalUnitName = optional
114-
commonName = optional
115-
emailAddress = optional
116-
117-
####################################################################
118-
[ req ]
119-
default_bits = 2048
120-
default_md = sha256
121-
default_keyfile = privkey.pem
122-
#distinguished_name = req_distinguished_name
123-
#attributes = req_attributes
124-
x509_extensions = v3_ca # The extentions to add to the self signed cert
125-
126-
[ req_distinguished_name ]
127-
#countryName = Country Name (2 letter code)
128-
#countryName_default = US
129-
#countryName_min = 2
130-
#countryName_max = 2
131-
#stateOrProvinceName = State or Province Name (full name)
132-
#stateOrProvinceName_default = Washington
133-
#localityName = Locality Name (eg, city)
134-
#localityName_default = Richland
135-
#0.organizationName = Organization Name (eg, company)
136-
#0.organizationName_default =
137-
#organizationalUnitName = Organizational Unit Name (eg, section)
138-
#commonName = Common Name (eg, your name or your server\'s hostname)
139-
#commonName_max = 64
140-
#emailAddress = Email Address
141-
#emailAddress_max = 64
142-
143-
[ req_attributes ]
144-
challengePassword = A challenge password
145-
challengePassword_min = 4
146-
challengePassword_max = 20
147-
unstructuredName = An optional company name
148-
149-
150-
[ v3_req ]
151-
# Extensions to add to a certificate request
152-
basicConstraints = CA:FALSE
153-
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
154-
155-
[ v3_ca ]
156-
# Extensions for a typical CA
157-
subjectKeyIdentifier=hash
158-
authorityKeyIdentifier=keyid:always,issuer
159-
basicConstraints = critical,CA:true
160-
161-
[ crl_ext ]
162-
# issuerAltName=issuer:copy
163-
authorityKeyIdentifier=keyid:always#
16440
# OpenSSL example configuration file.
16541
# This is mostly being used for generation of certificate requests.
16642
#
@@ -199,7 +75,7 @@ tsa_policy3 = 1.2.3.4.5.7
19975
default_ca = CA_default # The default ca section
20076

20177
[ CA_default ]
202-
dir = /home/gridappsd/tls # Where everything is kept
78+
dir = $ENV::HOME/tls # Where everything is kept
20379
certs = $dir/certs # Where the issued certs are kept
20480
database = $dir/index.txt # database index file.
20581
# several certs with same subject.

cli-client.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import textual
2+
import yaml
3+
from textual.app import App
4+
from textual.widget import Widget
5+
from textual.widgets import TreeItem, TreeWidget
6+
7+
8+
class MyTreeWidget(TreeWidget):
9+
10+
def __init__(self, data):
11+
super().__init__(data)
12+
13+
# Create the root node of the tree
14+
root = TreeItem(text="Root", expanded=True)
15+
self.add_top_level_item(root)
16+
17+
# Recursively add child nodes to the root node
18+
self._add_child_items(root, data)
19+
20+
def _add_child_items(self, parent_node, data):
21+
# Loop through the keys and values in the current data object
22+
for key, value in data.items():
23+
# Create a new TreeItem for the current key
24+
item = TreeItem(text=key)
25+
26+
# If the current value is a dictionary, recursively add its child nodes
27+
if isinstance(value, dict):
28+
self._add_child_items(item, value)
29+
30+
# Add the new TreeItem to the parent node
31+
parent_node.add_child_item(item)
32+
33+
34+
class MyTreeWidgetContainer(Widget):
35+
36+
def __init__(self, data):
37+
super().__init__()
38+
self.tree_widget = MyTreeWidget(data)
39+
self.add_subview(self.tree_widget)
40+
41+
42+
class MyCLIApp(App):
43+
44+
async def on_load(self, event):
45+
# Load the data from the YAML file
46+
with open("my_data.yaml") as file:
47+
data = yaml.load(file, Loader=yaml.FullLoader)
48+
49+
# Create the tree widget container and add it to the app
50+
tree_widget_container = MyTreeWidgetContainer(data)
51+
self.add_root_widget(tree_widget_container)
52+
53+
54+
MyCLIApp.run()

config.yml

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,16 @@ devices:
4141
deviceCategory: FUEL_CELL
4242
pin: 111115
4343

44-
programs:
45-
- description: Program 1
44+
# programs:
45+
# - description: Program 1
4646

4747
# nameplate:
4848
# rtgMaxW: 6000
4949
ders:
5050
- capabilities:
5151
modesSupported: "1110000000000000"
5252
type: 83
53+
program: Program 1
5354

5455
- capabilities:
5556
# Bitmask with the following structure.
@@ -182,7 +183,9 @@ programs:
182183
- Curve 1
183184
primacy: 89
184185

185-
# - description: Program 2
186+
- description: Program 2
187+
default_control: Control 3
188+
primacy: 20
186189
# default_control: Control 2
187190
# - description: Program 3
188191
# default_control: Control 2
@@ -205,9 +208,6 @@ controls:
205208
- description: Control 2
206209
- description: Control 3
207210

208-
events:
209-
- control: 0
210-
211211
curves:
212212
# Each element will can have the following structure.
213213
# autonomousVRefEnable: If the curveType is opModVoltVar, then
@@ -286,23 +286,3 @@ curves:
286286
- exitation: 10
287287
xvalue: 5
288288
yvalue: 5
289-
#{
290-
# "devices": [
291-
# {
292-
# "sfdi": "097935300833",
293-
# "lfdi": "247bd68e3378fe57ba604e3c8bdf9e3f78a3d743",
294-
# "load_shed_device_category": "0200",
295-
# "pin_code": "130178"
296-
# },
297-
# {
298-
# "sfdi": "111576577659",
299-
# "lfdi": "2990c58a59935a7d5838c952b1a453c967341a07",
300-
# "load_shed_device_category": "0200",
301-
# "pin_code": "130178"
302-
# }
303-
# ],
304-
# "IEEE2030_5_server_sfdi": "413707194130",
305-
# "IEEE2030_5_server_lfdi": "29834592834729384728374562039847629",
306-
# "load_shed_device_category": "0020",
307-
# "timezone": "America/Los_Angeles"
308-
#}

gui/der_programs.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import random
2+
import uuid
3+
from datetime import datetime, timedelta
4+
5+
from nicegui import app, ui
6+
from router import global_router as router
7+
from session import backend_session, endpoint
8+
9+
import ieee_2030_5.models as m
10+
from ieee_2030_5.utils import dataclass_to_xml, uuid_2030_5, xml_to_dataclass
11+
12+
13+
def datachange(data, prop, x):
14+
if hasattr(x, "value"):
15+
value = x.value
16+
else:
17+
value = x
18+
setattr(data, prop, value)
19+
return getattr(data, prop)
20+
21+
def add_control_event(program_index: int):
22+
der_control = m.DERControl()
23+
24+
25+
def post_der_control():
26+
resp = backend_session.post(endpoint(f'/derp/{program_index}/derc'), dataclass_to_xml(der_control))
27+
if resp.ok:
28+
ui.open("/derp")
29+
30+
31+
32+
with ui.column():
33+
with ui.row():
34+
der_control.mRID = uuid_2030_5()
35+
ui.input('mRID', value=der_control.mRID, on_change=lambda e: datachange(der_control, "mRID", e))
36+
with ui.row():
37+
currentdate = datetime.utcnow()
38+
fmtstring = '%Y-%m-%d %H:%M:%S'
39+
ui.label(f"Current time UTC: {currentdate.strftime(fmtstring)}")
40+
with ui.row():
41+
ui.input("Event Start Date Time", value=f"{(datetime.utcnow() + timedelta(seconds=90)).strftime(fmtstring)}", on_change=lambda e: datachange(der_control, "interval.start", e))
42+
43+
with ui.row():
44+
duration = ui.input("duration", on_change=lambda e: datachange(der_control, "interval.duration", int(e.value)))
45+
ui.button("Save", on_click=lambda: post_der_control())
46+
47+
@router.add('/derp')
48+
def programs_list():
49+
resp = backend_session.get(endpoint('/derp'))
50+
derps: m.DERProgramList = xml_to_dataclass(resp.text)
51+
52+
for index, derp in enumerate(derps.DERProgram):
53+
router.add_route(f"/derp/{index}/derc/add", lambda: add_control_event(index))
54+
with ui.row():
55+
with ui.column():
56+
ui.label(f"Description: {derp.description}")
57+
ui.label(f"mRID: {derp.mRID}")
58+
ui.label(f"primacy: {derp.primacy}")
59+
60+
if derp.ActiveDERControlListLink:
61+
ui.label(derp.ActiveDERControlListLink.href)
62+
if derp.DefaultDERControlLink:
63+
ui.label(derp.DefaultDERControlLink.href)
64+
if derp.DERControlListLink:
65+
ui.label(derp.DERControlListLink.href)
66+
67+
ui.button('Control Event', on_click=lambda: router.open(f"/derp/{index}/derc/add"))
68+
69+
ui.button('Create New Program', on_click=lambda: router.open(f'/derp/add'))
70+
71+
@app.get('/derp/{max}')
72+
def generate_random_number(max: int):
73+
with ui.column():
74+
ui.label("foo")
75+
#return {'min': 0, 'max': max, 'value': random.randint(0, max)}
76+
77+
78+
@router.add('/derp/add')
79+
def program_add():
80+
data = m.DERProgram()
81+
82+
83+
def create_derp():
84+
resp = backend_session.post(endpoint("derp"), data=dataclass_to_xml(data))
85+
if resp.ok:
86+
ui.open("/derp")
87+
88+
with ui.column():
89+
ui.input("mRID", on_change=lambda x: datachange(data, "mRID", x))
90+
ui.input("description", on_change=lambda x: datachange(data, "description", x))
91+
ui.input("primacy", on_change=lambda x: datachange(data, "primacy", x))
92+
ui.button("Save", on_click=lambda: create_derp())
93+
94+
#ui.run()
95+

gui/enddevices.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,21 @@ def show_list(enddevices: m.EndDeviceList):
2424
value = getattr(ed, fld.name)
2525
if value and fld.type in ('Optional[str]', 'str'):
2626
if isinstance(value, str):
27-
ui.label(f"{fld.name}, {value}, {fld.type}")
27+
ui.label(f"{fld.name} -> {value}")
2828
else:
29-
ui.label(f"{fld.name}, {value.decode('utf-8')}, {fld.type}")
29+
ui.label(f"{fld.name} -> {value.decode('utf-8')}")
30+
elif value and fld.type in ('int'):
31+
ui.label(f"{fld.name} -> {value}")
32+
elif value:
33+
34+
if isinstance(value, bytes):
35+
ui.label(f"{fld.name} -> {value}")
36+
elif isinstance(value, int):
37+
ui.label(f"{fld.name} -> {value}")
38+
elif getattr(value, 'href'):
39+
ui.label(f"{fld.name} -> {getattr(value, 'href')}")
40+
else:
41+
ui.label(f"Type is: {fld.type}")
3042
# value = getattr(ed, fld.name)
3143
# if value and value.decode('utf-8'):
3244
# ui.label(f"{fld.name} => {value.decode('utf-8')}")

0 commit comments

Comments
 (0)