From 77ff78605dde01b7361ac921fbccd10409a65167 Mon Sep 17 00:00:00 2001 From: "C. Allwardt" <3979063+craig8@users.noreply.github.com> Date: Thu, 19 Oct 2023 15:36:52 -0700 Subject: [PATCH] Cleanup from rebase --- scripts/pycharm-launch.py | 32 ++-- services/core/IEEE_2030_5/AGENT_DEMO.md | 112 ------------ .../core/IEEE_2030_5/demo/inverter_runner.py | 71 ++++---- services/core/IEEE_2030_5/example.config.yml | 2 +- .../core/IEEE_2030_5/ieee_2030_5/agent.py | 18 +- .../core/IEEE_2030_5/ieee_2030_5/client.py | 163 +++++++++--------- services/core/IEEE_2030_5/requirements.txt | 2 +- .../IEEE_2030_5/requirements_simulator.txt | 1 - 8 files changed, 142 insertions(+), 259 deletions(-) delete mode 100644 services/core/IEEE_2030_5/AGENT_DEMO.md delete mode 100644 services/core/IEEE_2030_5/requirements_simulator.txt diff --git a/scripts/pycharm-launch.py b/scripts/pycharm-launch.py index f203a1b243..e32787fcdf 100644 --- a/scripts/pycharm-launch.py +++ b/scripts/pycharm-launch.py @@ -38,17 +38,15 @@ dest="silence", nargs="?", help="Silence the help message.") -parser.add_argument( - "-n", - "--no-config", - action="store_true", - help="Don't include the default config in the agent directory.") +parser.add_argument("-n", + "--no-config", + action="store_true", + help="Don't include the default config in the agent directory.") parsed = parser.parse_args() mod_name = [os.path.basename(parsed.agent)] if not os.path.isfile(parsed.agent): - sys.stdout.write("Passed argument must be a python file! {}".format( - parsed.agent)) + sys.stdout.write("Passed argument must be a python file! {}".format(parsed.agent)) sys.exit() abspath = os.path.abspath(os.path.join(parsed.agent, os.pardir)) @@ -86,9 +84,8 @@ def write_required_statement(out=sys.stderr): path_found = os.path.join(abspath, cfg) break if not path_found: - sys.stderr.write( - 'AGENT_CONFIG variable not set. Either set it or ' - 'put a config file in the root of the agent dir.') + sys.stderr.write('AGENT_CONFIG variable not set. Either set it or ' + 'put a config file in the root of the agent dir.') sys.exit() os.environ['AGENT_CONFIG'] = path_found @@ -125,8 +122,7 @@ def write_required_statement(out=sys.stderr): universal_newlines=True, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as e: - sys.stderr.write("Couldn't get key pair for identity: {}\n".format( - agent_identity)) + sys.stderr.write("Couldn't get key pair for identity: {}\n".format(agent_identity)) 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!") @@ -142,21 +138,19 @@ def write_required_statement(out=sys.stderr): pubkey = json_obj['public'] try: params = [ - 'vctl', 'auth', 'add', '--credentials', "{}".format(pubkey), - '--user_id', agent_identity, '--capabilities', - "edit_config_store", '--comments', + 'vctl', 'auth', 'add', '--credentials', "{}".format(pubkey), '--user_id', + agent_identity, '--capabilities', "edit_config_store", '--comments', "Added from pycharm-launch.py script." ] + print(" ".join(params)) output = subprocess.check_output(params, env=os.environ.copy(), universal_newlines=True) except subprocess.CalledProcessError as e: sys.stderr.write(str(e)) - sys.stderr.write("Command returned following output: {}".format( - e.output)) + sys.stderr.write("Command returned following output: {}".format(e.output)) shutil.rmtree(new_dir) - sys.stderr.write( - "Couldn't authenticate agent id: {}\n".format(agent_identity)) + 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() diff --git a/services/core/IEEE_2030_5/AGENT_DEMO.md b/services/core/IEEE_2030_5/AGENT_DEMO.md deleted file mode 100644 index 26499fdcbe..0000000000 --- a/services/core/IEEE_2030_5/AGENT_DEMO.md +++ /dev/null @@ -1,112 +0,0 @@ -# 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. - -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. - -First configure the server then the VOLTTRON instance and findally the web based demo. - -## 2030.5 Server - -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 . 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 - > cd 2030_5_server - - # creates an environment 'env' in the current directory - > python3 -m venv serverenv - - > source serverenv/bin/activate - - (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. - - ```bash - (serverenv)> ls -l - serverenv - openssl.cnf - 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 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. - - ```bash - (serverenv)> 2030_5_server server.yml --no-validate - - # without creating certificates - # (serverenv)> 2030_5_server server.yml --no-validate --no-create-certs - ``` - -## 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. - -1. Activate and start the volttron instance. - - ```bash - > cd $VOLTTRON_ROOT - > source env/bin/activate - (volttron)> ./start-volttron - # Watch the volttron log - (volttron)> tail -f volttron.log - ``` - -1. Open another terminal to start the demo server in. - - ```bash - > cd $VOLTTRON_ROOT - > source env/bin/activate - (volttron)> cd service/core/IEEE_2030_5 - (volttron)> pip install -r requirements_demo.txt - ... - ``` - -1. Create an agent keypair for the 2030.5 agent to use (only needed for demo in real mode installing the agent would create this). - - ```bash - (volttron)> vctl keypair > demo/keypair.json - (volttron)> cat demo/keypair.json - { - "public": "YrRnX1ifv5hkctAtNsLMut1j3qr7dPf0gppvwH_53wE", - "secret": "C55SSFUKAM38dXZKjMSolRvFVfILbSTF9JkUQWlP8II" - } - ``` - -1. Add the publickey to VOLTTRON auth mechanism - - ```bash - (volttron)> vctl auth add --credentials "YrRnX1ifv5hkctAtNsLMut1j3qr7dPf0gppvwH_53wE" --user_id inverter1 - ``` - -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 . - - ```bash - (volttron)> python demo/webgui.py - ``` - -## The Demo - -The initial demo screen. - -![Startup Page](./demo/images/initial_conditions.png) - -Clicking on the Start Inverter and Start Agent buttons the status of Real and Reactive power should update based upon what is posted to the MirrorUsagePoints. - -![Agent and Inverter Started](./demo/images/start_agent_and_inverter.png) - -Changing the power factor to 80 and clicking on the Change Power Factor button (3) will show the scheduling, activating and completion of the event. - -![Scheduling Events Schedule](./demo/images/control_scheduled.png) - -![Scheduling Events Active](./demo/images/control_active.png) - -![Scheduling Events Complete](./demo/images/control_complete.png) diff --git a/services/core/IEEE_2030_5/demo/inverter_runner.py b/services/core/IEEE_2030_5/demo/inverter_runner.py index 442a4f8e6b..1ed84dccdb 100644 --- a/services/core/IEEE_2030_5/demo/inverter_runner.py +++ b/services/core/IEEE_2030_5/demo/inverter_runner.py @@ -14,11 +14,13 @@ import pvlib import yaml from volttron.platform.agent.utils import format_timestamp, get_aware_utc_now - +from volttron.platform.vip.agent import Agent +from volttron.platform.vip.agent.subsystems.rpc import RPC from volttron.platform.vip.agent.utils import build_agent _log = logging.getLogger(__name__) + class MyInverterAgent(Agent): def __init__(self, **kwargs): @@ -33,7 +35,7 @@ def set_point(self, point, value): @RPC.export def get_point(self, point): return self._points.get(point) - + def get_all_points(self): return self._points.keys() @@ -84,21 +86,22 @@ def run_inverter(timesteps=50, pf=0.99, latitude=32, longitude=-111.0) -> Genera # print( # f"p_ac = {p_ac}, s_ac = {s_ac}, q_ac= {q_ac}, PF = {PF}, v_ac = {v_ac}, i_ac = {i_ac}" # ) - results = dict(PF=PF, - INV_REAL_PWR=p_ac, - INV_REAC_PWR=q_ac, - #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'], - s_ac=p_ac, - #v_ac=v_ac, - BAT_SOC=int(v_ac/p_ac), - #i_ac=i_ac, - target_p=p_ac, - INV_OP_STATUS_MODE=3) + results = dict( + PF=PF, + INV_REAL_PWR=p_ac, + INV_REAC_PWR=q_ac, + #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'], + s_ac=p_ac, + #v_ac=v_ac, + BAT_SOC=int(v_ac / p_ac), + #i_ac=i_ac, + target_p=p_ac, + INV_OP_STATUS_MODE=3) yield results # single phase circuit calculation @@ -186,14 +189,12 @@ def run_inverter(timesteps=50) -> Generator: if __name__ == '__main__': import argparse parser = argparse.ArgumentParser() - - parser.add_argument("output_file", help="File to write to when data arrives on the bus") - opts = parser.parse_args() - - logging.basicConfig(level=logging.DEBUG, - force=True - ) - + + # parser.add_argument("output_file", help="File to write to when data arrives on the bus") + # opts = parser.parse_args() + + logging.basicConfig(level=logging.DEBUG, force=True) + logging.getLogger('volttron.platform.vip.agent.core').setLevel(logging.WARNING) logging.getLogger('volttron.platform.vip.agent.core').setLevel(logging.WARNING) @@ -206,7 +207,7 @@ def run_inverter(timesteps=50) -> Generator: control_path = Path('inverter.ctl') from volttron.platform.messaging import headers as t_header - + while True: gen = run_inverter() @@ -218,13 +219,13 @@ def run_inverter(timesteps=50) -> Generator: points = AllPoints() agent_points = agent.get_all_points() - + for k in agent_points: if k in inv: points.add(k, inv[k]) else: points.add(k, agent.get_point(k)) - + # Loop over points adding them to the allpoints dataclass if # they are specified. If they have been set on the agent itself # then use that value instead of the one from the generator. @@ -234,22 +235,18 @@ def run_inverter(timesteps=50) -> Generator: points.add(k, pt_set) else: points.add(k, v) - + ts = format_timestamp(get_aware_utc_now()) - headers = { - t_header.SYNC_TIMESTAMP: ts, - t_header.TIMESTAMP: ts - } - - + headers = {t_header.SYNC_TIMESTAMP: ts, t_header.TIMESTAMP: ts} + _log.info(f"Publishing {points.points}") # publish agent.vip.pubsub.publish(peer="pubsub", topic=f"{topic_to_publish}", headers=headers, message=points.forbus()) - with open(Path(opts.output_file), '+a') as fp: - fp.write(json.dumps(dict(headers=headers, message=points.forbus()))+"\n") + # with open(Path(opts.output_file), '+a') as fp: + # fp.write(json.dumps(dict(headers=headers, message=points.forbus())) + "\n") gevent.sleep(10) agent.core.stop() \ No newline at end of file diff --git a/services/core/IEEE_2030_5/example.config.yml b/services/core/IEEE_2030_5/example.config.yml index a33908e78f..3094e37d19 100644 --- a/services/core/IEEE_2030_5/example.config.yml +++ b/services/core/IEEE_2030_5/example.config.yml @@ -10,7 +10,7 @@ pin: 12345 log_req_resp: true # SSL defaults to 443 -server_ssl_port: 7443 +server_ssl_port: 8443 # http port defaults to none #server_http_port: 8080 # Number of seconds to poll for new default der settings. diff --git a/services/core/IEEE_2030_5/ieee_2030_5/agent.py b/services/core/IEEE_2030_5/ieee_2030_5/agent.py index 1be4a31b3e..b19b9df5c6 100644 --- a/services/core/IEEE_2030_5/ieee_2030_5/agent.py +++ b/services/core/IEEE_2030_5/ieee_2030_5/agent.py @@ -23,8 +23,8 @@ from typing import Any, Dict, List import ieee_2030_5.models as m -from ieee_2030_5 import AllPoints -from ieee_2030_5.client import IEEE2030_5_Client +from . import AllPoints +from .client import IEEE2030_5_Client try: # for modular from volttron import utils @@ -163,13 +163,13 @@ def __init__(self, config_path: str, **kwargs): } self._server_usage_points: m.UsagePointList - self._client = IEEE_2030_5_Client(cafile=self._cacertfile, - server_hostname=self._server_hostname, - keyfile=self._keyfile, - certfile=self._certfile, - server_ssl_port=self._server_ssl_port, - pin=self._pin, - log_req_resp=self._log_req_resp) + self._client = IEEE2030_5_Client(cafile=self._cacertfile, + server_hostname=self._server_hostname, + keyfile=self._keyfile, + certfile=self._certfile, + server_ssl_port=self._server_ssl_port, + pin=self._pin, + log_req_resp=self._log_req_resp) # Hook events up to the client so that we can send the correct information on to # the platform driver. diff --git a/services/core/IEEE_2030_5/ieee_2030_5/client.py b/services/core/IEEE_2030_5/ieee_2030_5/client.py index e77a671580..11ce22249a 100644 --- a/services/core/IEEE_2030_5/ieee_2030_5/client.py +++ b/services/core/IEEE_2030_5/ieee_2030_5/client.py @@ -92,8 +92,8 @@ def run(self) -> None: TimerThread.start() -class IEEE_2030_5_Client: - clients: set[IEEE_2030_5_Client] = set() +class IEEE2030_5_Client: + clients: set[IEEE2030_5_Client] = set() # noinspection PyUnresolvedReferences def __init__(self, @@ -177,18 +177,18 @@ def __init__(self, self._der_control_event_started_signal = Signal('der-control-event-started') self._der_control_event_ended_signal = Signal('der-control-event-ended') - + self._default_control_changed = Signal("default-control-changed") - + self._dcap_endpoint = device_capabilities_endpoint - + self._der_default_control: m.DefaultDERControl = m.DefaultDERControl() self._der_active_controls: m.DERControlList = m.DERControlList() self._config: Dict[str, Any] = {} self._lock = Semaphore() - IEEE_2030_5_Client.clients.add(self) + IEEE2030_5_Client.clients.add(self) def start(self, config: Dict[str, Any]): """Starts the client connection to the 2030.5 server configured during construction. @@ -212,7 +212,7 @@ def _tick(self, timestamp: int): def der_default_control_changed(self, fun: Callable): self._default_control_changed.connect(fun) - + def der_control_event_started(self, fun: Callable): self._der_control_event_started_signal.connect(fun) @@ -248,7 +248,7 @@ def get_der_hrefs(self) -> List[str]: def get_der(self, href: str) -> Optional[m.DER]: return self._der.get(href) - + def get_der_list(self, href: Optional[str] = None) -> m.DERList: if href is None: href = self.enddevice.DERListLink.href @@ -260,29 +260,32 @@ def put_der_availability(self, der_href: str, new_availability: m.DERAvailabilit return resp.status def put_der_capability(self, new_capability: m.DERCapability) -> int: - resp = self.__put__(list(self._der.values())[0].DERCapabilityLink, dataclass_to_xml(new_capability)) + resp = self.__put__( + list(self._der.values())[0].DERCapabilityLink, dataclass_to_xml(new_capability)) return resp.status def put_der_settings(self, new_settings: m.DERSettings) -> int: - resp = self.__put__(list(self._der.values())[0].DERSettingsLink.href, dataclass_to_xml(new_settings)) + resp = self.__put__( + list(self._der.values())[0].DERSettingsLink.href, dataclass_to_xml(new_settings)) return resp.status def put_der_status(self, new_status: m.DERStatus) -> int: if not isinstance(new_status.operationalModeStatus, m.OperationalModeStatusType): - new_status.operationalModeStatus = m.OperationalModeStatusType(self.server_time, - value=new_status.operationalModeStatus) - - resp = self.__put__(list(self._der.values())[0].DERStatusLink.href, dataclass_to_xml(new_status)) + new_status.operationalModeStatus = m.OperationalModeStatusType( + self.server_time, value=new_status.operationalModeStatus) + + resp = self.__put__( + list(self._der.values())[0].DERStatusLink.href, dataclass_to_xml(new_status)) return resp.status - + def _send_control_events(self, der_program_href: str): # Need to check this every 10 seconds for updates to conttrols program: m.DERProgram = self.__get_request__(der_program_href) - + active: m.DERControlList = self.__get_request__(program.ActiveDERControlListLink.href) default = self.__get_request__(program.DefaultDERControlLink.href) active_is_different = False - + to_add = [] for newderctl in active.DERControl: found = False @@ -292,14 +295,16 @@ def _send_control_events(self, der_program_href: str): if existingctl == newderctl: _log.debug(f"Currently in event {newderctl.mRID}") else: - _log.debug("TODO ->>>>>>>>>>>>>>>>>>>>>>>>>>> Existing mRID should superscede????") + _log.debug( + "TODO ->>>>>>>>>>>>>>>>>>>>>>>>>>> Existing mRID should superscede????" + ) break if not found: to_add.append(newderctl) - + for ctrl in to_add: self._der_control_event_started_signal.send(ctrl) - + to_remove = [] for existingctl in self._der_active_controls.DERControl: found = False @@ -309,25 +314,27 @@ def _send_control_events(self, der_program_href: str): break if not found: to_remove.append(existingctl) - + i = len(self._der_active_controls.DERControl) while i > 0: i -= 1 if self._der_active_controls.DERControl[i] in to_remove: self._der_control_event_ended_signal.send(self._der_active_controls.DERControl[i]) self._der_active_controls.DERControl.pop(i) - + self._der_active_controls = active - + if default != self._der_default_control: self._der_default_control = default _log.debug("Default control changed....") self._default_control_changed.send(default) - + # Poll every 60 if default otherwise use setting in config file. refresh_time = self._config.get("default_der_control_poll", 60) - self._update_timer_spec("der_control_event", refresh_time, fn=lambda: self._send_control_events(der_program_href)) - + self._update_timer_spec("der_control_event", + refresh_time, + fn=lambda: self._send_control_events(der_program_href)) + def _update_dcap_tree(self, endpoint: Optional[str] = None): """Retrieve device capability @@ -365,7 +372,7 @@ def _update_dcap_tree(self, endpoint: Optional[str] = None): self._update_list(dcap.EndDeviceListLink.href, "EndDevice", self._end_device_map, self._end_devices) - + for ed in self._end_devices.values(): if not self.is_end_device_registered(ed, self._pin): @@ -378,16 +385,16 @@ def _update_dcap_tree(self, endpoint: Optional[str] = None): self._der_map[derlist.href] = derlist for index, der in enumerate(derlist.DER): self._der[der.href] = der - + if derlist.DER[0].CurrentDERProgramLink: self._send_control_events(derlist.DER[0].CurrentDERProgramLink.href) - + for fsa in self._fsa.values(): if fsa.DERProgramListLink: self._der_program_map[fsa.DERProgramListLink.href] = self.__get_request__( fsa.DERProgramListLink.href) program = self._der_program_map[fsa.DERProgramListLink.href] - + if dcap.MirrorUsagePointListLink is not None and dcap.MirrorUsagePointListLink.href: self._update_list(dcap.MirrorUsagePointListLink.href, "MirrorUsagePoint", self._mirror_usage_point_map, self._mirror_usage_point) @@ -583,7 +590,7 @@ def timelink(self): def disconnect(self): self._disconnect = True self._dcap_timer.cancel() - IEEE_2030_5_Client.clients.remove(self) + IEEE2030_5_Client.clients.remove(self) def request(self, endpoint: str, body: dict = {}, method: str = "GET", headers: dict = {}): @@ -614,14 +621,14 @@ def __put__(self, url: str, data: Any, headers: Optional[Dict[str, str]] = None) if self._debug: _log_req_resp.debug(f"----> PUT REQUEST\nurl: {url}\nbody: {data}") - + try: self.http_conn.request(method="PUT", headers=headers, url=url, body=data) except http.client.CannotSendRequest as ex: self.http_conn.close() _log.debug("Reconnecting to server") self.http_conn.request(method="PUT", headers=headers, url=url, body=data) - + response = self._http_conn.getresponse() return response @@ -631,7 +638,7 @@ def __post__(self, url: str, data=None, headers: Optional[Dict[str, str]] = None if self._debug: _log_req_resp.debug(f"----> POST REQUEST\nurl: {url}\nbody: {data}") - + self.http_conn.request(method="POST", headers=headers, url=url, body=data) response = self._http_conn.getresponse() response_data = response.read().decode("utf-8") @@ -681,53 +688,51 @@ def __close__(self): # noinspection PyTypeChecker def __release_clients__(): - for x in IEEE_2030_5_Client.clients: + for x in IEEE2030_5_Client.clients: x.__close__() - IEEE_2030_5_Client.clients = None + IEEE2030_5_Client.clients = None atexit.register(__release_clients__) - - -if __name__ == '__main__': - SERVER_CA_CERT = Path("~/tls/certs/ca.crt").expanduser().resolve() - KEY_FILE = Path("~/tls/private/dev1.pem").expanduser().resolve() - CERT_FILE = Path("~/tls/certs/dev1.crt").expanduser().resolve() - - headers = {'Connection': 'Keep-Alive', 'Keep-Alive': "max=1000,timeout=30"} - - h = IEEE_2030_5_Client(cafile=SERVER_CA_CERT, - server_hostname="127.0.0.1", - server_ssl_port=8070, - keyfile=KEY_FILE, - certfile=CERT_FILE, - debug=True) - # h2 = IEEE2030_5_Client(cafile=SERVER_CA_CERT, server_hostname="me.com", ssl_port=8000, - # keyfile=KEY_FILE, certfile=KEY_FILE) - dcap = h.device_capability() - end_devices = h.end_devices() - - if not end_devices.all > 0: - print("registering end device.") - ed_href = h.register_end_device() - my_ed = h.end_devices() - - # ed = h.end_devices()[0] - # resp = h.request("/dcap", headers=headers) - # print(resp) - # resp = h.request("/dcap", headers=headers) - # print(resp) - #dcap = h.device_capability() - # get device list - #dev_list = h.request(dcap.EndDeviceListLink.href).EndDevice - - #ed = h.request(dev_list[0].href) - #print(ed) - # - # print(dcap.mirror_usage_point_list_link) - # # print(h.request(dcap.mirror_usage_point_list_link.href)) - # print(h.request("/dcap", method="post")) - - # tl = h.timelink() - #print(IEEE2030_5_Client.clients) +# if __name__ == '__main__': +# SERVER_CA_CERT = Path("~/tls/certs/ca.crt").expanduser().resolve() +# KEY_FILE = Path("~/tls/private/dev1.pem").expanduser().resolve() +# CERT_FILE = Path("~/tls/certs/dev1.crt").expanduser().resolve() + + # headers = {'Connection': 'Keep-Alive', 'Keep-Alive': "max=1000,timeout=30"} + + # h = IEEE_2030_5_Client(cafile=SERVER_CA_CERT, + # server_hostname="127.0.0.1", + # server_ssl_port=8070, + # keyfile=KEY_FILE, + # certfile=CERT_FILE, + # debug=True) + # # h2 = IEEE2030_5_Client(cafile=SERVER_CA_CERT, server_hostname="me.com", ssl_port=8000, + # # keyfile=KEY_FILE, certfile=KEY_FILE) + # dcap = h.device_capability() + # end_devices = h.end_devices() + + # if not end_devices.all > 0: + # print("registering end device.") + # ed_href = h.register_end_device() + # my_ed = h.end_devices() + + # # ed = h.end_devices()[0] + # # resp = h.request("/dcap", headers=headers) + # # print(resp) + # # resp = h.request("/dcap", headers=headers) + # # print(resp) + # #dcap = h.device_capability() + # # get device list + # #dev_list = h.request(dcap.EndDeviceListLink.href).EndDevice + + # #ed = h.request(dev_list[0].href) + # #print(ed) + # # + # # print(dcap.mirror_usage_point_list_link) + # # # print(h.request(dcap.mirror_usage_point_list_link.href)) + # # print(h.request("/dcap", method="post")) + + # # tl = h.timelink() + # #print(IEEE2030_5_Client.clients) diff --git a/services/core/IEEE_2030_5/requirements.txt b/services/core/IEEE_2030_5/requirements.txt index 6e0cbfbc31..22e8585248 100644 --- a/services/core/IEEE_2030_5/requirements.txt +++ b/services/core/IEEE_2030_5/requirements.txt @@ -1,2 +1,2 @@ -xsdata +xsdata>=23.8 blinker diff --git a/services/core/IEEE_2030_5/requirements_simulator.txt b/services/core/IEEE_2030_5/requirements_simulator.txt deleted file mode 100644 index d191e62fef..0000000000 --- a/services/core/IEEE_2030_5/requirements_simulator.txt +++ /dev/null @@ -1 +0,0 @@ -pvlib \ No newline at end of file