gridappsd-python 2024.6.0__tar.gz → 2025.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (19) hide show
  1. {gridappsd_python-2024.6.0 → gridappsd_python-2025.2.1}/PKG-INFO +6 -7
  2. {gridappsd_python-2024.6.0 → gridappsd_python-2025.2.1}/gridappsd/difference_builder.py +11 -7
  3. gridappsd_python-2025.2.1/gridappsd/field_interface/__init__.py +32 -0
  4. {gridappsd_python-2024.6.0 → gridappsd_python-2025.2.1}/gridappsd/goss.py +8 -3
  5. {gridappsd_python-2024.6.0 → gridappsd_python-2025.2.1}/gridappsd/topics.py +24 -15
  6. {gridappsd_python-2024.6.0 → gridappsd_python-2025.2.1}/pyproject.toml +5 -4
  7. {gridappsd_python-2024.6.0 → gridappsd_python-2025.2.1}/README.md +0 -0
  8. {gridappsd_python-2024.6.0 → gridappsd_python-2025.2.1}/gridappsd/__init__.py +0 -0
  9. {gridappsd_python-2024.6.0 → gridappsd_python-2025.2.1}/gridappsd/__main__.py +0 -0
  10. {gridappsd_python-2024.6.0 → gridappsd_python-2025.2.1}/gridappsd/app_registration.py +0 -0
  11. {gridappsd_python-2024.6.0 → gridappsd_python-2025.2.1}/gridappsd/docker_handler.py +0 -0
  12. {gridappsd_python-2024.6.0 → gridappsd_python-2025.2.1}/gridappsd/gridappsd.py +0 -0
  13. {gridappsd_python-2024.6.0 → gridappsd_python-2025.2.1}/gridappsd/houses.py +0 -0
  14. {gridappsd_python-2024.6.0 → gridappsd_python-2025.2.1}/gridappsd/json_extension.py +0 -0
  15. {gridappsd_python-2024.6.0 → gridappsd_python-2025.2.1}/gridappsd/loghandler.py +0 -0
  16. {gridappsd_python-2024.6.0 → gridappsd_python-2025.2.1}/gridappsd/register_app.py +0 -0
  17. {gridappsd_python-2024.6.0 → gridappsd_python-2025.2.1}/gridappsd/simulation.py +0 -0
  18. {gridappsd_python-2024.6.0 → gridappsd_python-2025.2.1}/gridappsd/timeseries.py +0 -0
  19. {gridappsd_python-2024.6.0 → gridappsd_python-2025.2.1}/gridappsd/utils.py +0 -0
@@ -1,25 +1,24 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: gridappsd-python
3
- Version: 2024.6.0
3
+ Version: 2025.2.1
4
4
  Summary: A GridAPPS-D Python Adapter
5
- Home-page: https://gridappsd.readthedocs.io
6
5
  License: BSD-3-Clause
7
- Keywords: gridappsd,grid,activmq,powergrid,simulation,library
6
+ Keywords: gridappsd,grid,activemq,powergrid,simulation,library
8
7
  Author: C. Allwardt
9
8
  Author-email: 3979063+craig8@users.noreply.github.com
10
- Requires-Python: >=3.7.9,<4.0
9
+ Requires-Python: >=3.10,<4.0
11
10
  Classifier: License :: OSI Approved :: BSD License
12
11
  Classifier: Programming Language :: Python :: 3
13
- Classifier: Programming Language :: Python :: 3.8
14
- Classifier: Programming Language :: Python :: 3.9
15
12
  Classifier: Programming Language :: Python :: 3.10
16
13
  Classifier: Programming Language :: Python :: 3.11
17
14
  Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
18
16
  Requires-Dist: PyYAML (>=6.0,<7.0)
19
17
  Requires-Dist: dateutils (>=0.6.7,<0.7.0)
20
18
  Requires-Dist: pytz (>=2022.7,<2023.0)
21
19
  Requires-Dist: requests (==2.28.2)
22
20
  Requires-Dist: stomp-py (==6.0.0)
21
+ Project-URL: Homepage, https://gridappsd.readthedocs.io
23
22
  Project-URL: Repository, https://github.com/GRIDAPPSD/gridappsd-python
24
23
  Description-Content-Type: text/markdown
25
24
 
@@ -42,19 +42,17 @@ import calendar
42
42
  from uuid import uuid4
43
43
  import time
44
44
 
45
- import pytz
46
-
47
45
 
48
46
  class DifferenceBuilder(object):
49
47
  """ Automates the building of forward and reverse cim differences
50
48
 
51
49
  """
52
50
 
53
- def __init__(self, simulation_id):
51
+ def __init__(self, simulation_id: str | int | None = None):
54
52
 
55
53
  self._simulation_id = simulation_id
56
- self._forward = []
57
- self._reverse = []
54
+ self._forward: list[dict] = []
55
+ self._reverse: list[dict] = []
58
56
 
59
57
  def add_difference(self, object_id, attribute, forward_value, reverse_value):
60
58
  """ Add forward and reverse unit for an object attribute.
@@ -67,16 +65,22 @@ class DifferenceBuilder(object):
67
65
  self._reverse.append(reverse)
68
66
 
69
67
  def clear(self):
68
+ """ Clear the forward and reverse differences """
70
69
  self._forward = []
71
70
  self._reverse = []
72
71
 
73
72
  def get_message(self, epoch=None):
73
+ """ Get the message to send to the GOSS message bus
74
+
75
+ :param epoch: The epoch time to use for the message timestamp. If None, the current time (GMT) is used.
76
+ """
74
77
  if epoch is None:
75
78
  epoch = calendar.timegm(time.gmtime())
76
79
  msg = dict(command="update",
77
- input=dict(simulation_id=self._simulation_id,
78
- message=dict(timestamp=epoch,
80
+ input=dict(message=dict(timestamp=epoch,
79
81
  difference_mrid=str(uuid4()),
80
82
  reverse_differences=self._reverse,
81
83
  forward_differences=self._forward)))
84
+ if self._simulation_id is not None:
85
+ msg['input']['simulation_id'] = self._simulation_id
82
86
  return msg.copy()
@@ -0,0 +1,32 @@
1
+ import logging
2
+ import sys
3
+
4
+ _log = logging.getLogger(__name__)
5
+
6
+ try:
7
+ import warnings
8
+
9
+ import gridappsd_field_bus.field_interface.context as _context
10
+ import gridappsd_field_bus.field_interface.context_managers as _context_managers
11
+ import gridappsd_field_bus.field_interface as _field_interface
12
+ import gridappsd_field_bus.field_interface.agents as _agents
13
+ import gridappsd_field_bus.field_interface.field_proxy_forwarder as _field_proxy_forwarder
14
+ import gridappsd_field_bus.field_interface.gridappsd_field_bus as _gridappsd_field_bus
15
+ import gridappsd_field_bus.field_interface.interfaces as _interfaces
16
+
17
+ sys.modules['gridappsd.field_interface'] = _field_interface
18
+ sys.modules['gridappsd.field_interface.interfaces'] = _interfaces
19
+ sys.modules['gridappsd.field_interface.context_managers'] = _context_managers
20
+ sys.modules['gridappsd_.context_managers'] = _context_managers
21
+ sys.modules['gridappsd.field_interface.agents'] = _agents
22
+ sys.modules['gridappsd.field_interface.field_proxy_forwarder'] = _field_proxy_forwarder
23
+ sys.modules['gridappsd.field_interface.gridappsd_field_bus'] = _gridappsd_field_bus
24
+
25
+
26
+
27
+
28
+
29
+ warnings.warn(message="gridappsd.field_interface is deprecated and will be removed in a future release. Use gridappsd_field_bus.field_interface instead.",
30
+ category=DeprecationWarning)
31
+ except ImportError:
32
+ _log.error("Could not import field_interface install gridappsd-field-bus to get those functions.")
@@ -88,7 +88,8 @@ class GOSS(object):
88
88
  attempt_connection=True,
89
89
  override_threading=None,
90
90
  stomp_log_level=logging.WARNING,
91
- goss_log_level=logging.INFO):
91
+ goss_log_level=logging.INFO,
92
+ use_auth_token=True):
92
93
 
93
94
  logging.getLogger('stomp.py').setLevel(stomp_log_level)
94
95
  logging.getLogger('goss').setLevel(goss_log_level)
@@ -97,6 +98,7 @@ class GOSS(object):
97
98
  self.__pass__ = password
98
99
  self.stomp_address = stomp_address
99
100
  self.stomp_port = stomp_port
101
+ self.use_auth_token = use_auth_token
100
102
 
101
103
  # Environmental variables should overrule the passed arguments.
102
104
  if os.environ.get(GRIDAPPSD_ENV_ENUM.GRIDAPPSD_USER.value):
@@ -289,7 +291,7 @@ class GOSS(object):
289
291
  def _make_connection(self):
290
292
  if self._conn is None or not self._conn.is_connected():
291
293
  _log.debug("Creating connection")
292
- if not self.__token:
294
+ if self.use_auth_token is True and not self.__token:
293
295
 
294
296
  # get token
295
297
  # get initial connection
@@ -351,7 +353,10 @@ class GOSS(object):
351
353
  if self._override_thread_fc is not None:
352
354
  self._conn.transport.override_threading(self._override_thread_fc)
353
355
  try:
354
- self._conn.connect(self.__token, "", wait=True)
356
+ if self.use_auth_token and self.__token is not None:
357
+ self._conn.connect(self.__token, "", wait=True)
358
+ else:
359
+ self._conn.connect(self.__user__,self.__pass__, wait=True)
355
360
  except TypeError as e:
356
361
  _log.error("TypeError: {e}".format(e=e))
357
362
  except NotConnectedException as e:
@@ -80,7 +80,7 @@ def platform_log_topic():
80
80
  return "/topic/{}.{}".format(BASE_TOPIC_PREFIX, "platform.log")
81
81
 
82
82
 
83
- def service_input_topic(service_id, simulation_id):
83
+ def service_input_topic(service_id: str, simulation_id: int | str | None = None):
84
84
  """ Utility method for getting the input topic for a specific service.
85
85
 
86
86
  The service id should be the registered service with the platform. One
@@ -95,11 +95,14 @@ def service_input_topic(service_id, simulation_id):
95
95
  :return:
96
96
  """
97
97
  assert service_id, "service_id cannot be empty"
98
- assert simulation_id, "simulation_id cannot be empty"
99
- return "{}.{}.{}.input".format(BASE_SIMULATION_TOPIC, service_id, simulation_id)
100
98
 
99
+ if simulation_id:
100
+ return f"{BASE_SIMULATION_TOPIC}.{service_id}.{simulation_id}.input"
101
101
 
102
- def service_output_topic(service_id, simulation_id):
102
+ return f"{BASE_SIMULATION_TOPIC}.{service_id}.input"
103
+
104
+
105
+ def service_output_topic(service_id: str, simulation_id: int | str | None = None):
103
106
  """ Utility method for getting the output topic for a specific service.
104
107
 
105
108
  The service id should be the registered service with the platform. One
@@ -114,11 +117,14 @@ def service_output_topic(service_id, simulation_id):
114
117
  :return:str: Topic to subscribe to for service specific output.
115
118
  """
116
119
  assert service_id, "Service id cannot be empty"
117
- assert simulation_id, "Simulation id cannot be empty"
118
- return "{}.{}.{}.output".format(BASE_SIMULATION_TOPIC, service_id, simulation_id)
119
120
 
121
+ if simulation_id:
122
+ return f"{BASE_SIMULATION_TOPIC}.{service_id}.{simulation_id}.output"
123
+
124
+ return f"{BASE_SIMULATION_TOPIC}.{service_id}.output"
120
125
 
121
- def application_input_topic(application_id, simulation_id):
126
+
127
+ def application_input_topic(application_id: str, simulation_id: int | str | None = None):
122
128
  """ Utility method for getting the input topic for a specific application.
123
129
 
124
130
  The application_id should be the registered service with the platform. One
@@ -130,11 +136,14 @@ def application_input_topic(application_id, simulation_id):
130
136
  :return:str: Topic to publish to for a specific application.
131
137
  """
132
138
  assert application_id, "application_id cannot be empty"
133
- assert simulation_id, "simulation_id cannot be empty"
134
- return "{}.{}.{}.input".format(BASE_SIMULATION_TOPIC, application_id, simulation_id)
135
139
 
140
+ if simulation_id:
141
+ return f"{BASE_SIMULATION_TOPIC}.{application_id}.{simulation_id}.input"
142
+
143
+ return f"{BASE_TOPIC}.{application_id}.input"
136
144
 
137
- def application_output_topic(application_id, simulation_id):
145
+
146
+ def application_output_topic(application_id: str, simulation_id: int | str | None = None):
138
147
  """ Utility method for getting the output topic for a specific application.
139
148
 
140
149
  The application_id should be the registered service with the platform. One
@@ -146,11 +155,11 @@ def application_output_topic(application_id, simulation_id):
146
155
  :return: str: Topic to subscribe to for application specific output.
147
156
  """
148
157
  assert application_id, "application_id cannot be empty"
149
- #assert simulation_id, "simulation_id cannot be empty"
150
- if simulation_id is None:
151
- return "{}.{}.output".format(BASE_TOPIC, application_id)
152
- else:
153
- return "{}.{}.{}.output".format(BASE_SIMULATION_TOPIC, application_id, simulation_id)
158
+
159
+ if simulation_id:
160
+ return f"{BASE_SIMULATION_TOPIC}.{application_id}.{simulation_id}.output"
161
+
162
+ return f"{BASE_TOPIC}.{application_id}.output"
154
163
 
155
164
 
156
165
  def simulation_output_topic(simulation_id):
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "gridappsd-python"
3
- version = "2024.6.0"
3
+ version = "2025.02.1"
4
4
  description = "A GridAPPS-D Python Adapter"
5
5
  authors = [
6
6
  "C. Allwardt <3979063+craig8@users.noreply.github.com>",
@@ -12,7 +12,7 @@ license = "BSD-3-Clause"
12
12
  repository = "https://github.com/GRIDAPPSD/gridappsd-python"
13
13
  homepage = "https://gridappsd.readthedocs.io"
14
14
 
15
- keywords = ["gridappsd", "grid", "activmq", "powergrid", "simulation", "library"]
15
+ keywords = ["gridappsd", "grid", "activemq", "powergrid", "simulation", "library"]
16
16
 
17
17
  readme = "README.md"
18
18
 
@@ -29,7 +29,7 @@ gridappsd-cli = 'gridappsd.cli:_main'
29
29
 
30
30
 
31
31
  [tool.poetry.dependencies]
32
- python = ">=3.7.9,<4.0"
32
+ python = ">=3.10,<4.0"
33
33
  PyYAML = "^6.0"
34
34
  pytz = "^2022.7"
35
35
  dateutils = "^0.6.7"
@@ -37,13 +37,14 @@ stomp-py = "6.0.0"
37
37
  requests = "2.28.2"
38
38
 
39
39
  [tool.poetry.group.dev.dependencies]
40
- pytest = "^6.2.2"
40
+ pytest = "^8.3.4"
41
41
  pytest-html = "^3.1.1"
42
42
  mock = "^4.0.3"
43
43
  yapf = "^0.32.0"
44
44
  mypy = "^1.3.0"
45
45
  python-on-whales = "^0.60.1"
46
46
  gitpython = "^3.1.31"
47
+ pre-commit = "^4.1.0"
47
48
 
48
49
  [build-system]
49
50
  requires = ["poetry-core>=1.2.0"]