PyAres 0.1.4__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.
- pyares-0.1.4/LICENSE +21 -0
- pyares-0.1.4/PKG-INFO +13 -0
- pyares-0.1.4/PyAres/Analyzing/__init__.py +9 -0
- pyares-0.1.4/PyAres/Analyzing/analysis_service.py +263 -0
- pyares-0.1.4/PyAres/Analyzing/analyzer_models.py +47 -0
- pyares-0.1.4/PyAres/Device/__init__.py +3 -0
- pyares-0.1.4/PyAres/Device/device_models.py +40 -0
- pyares-0.1.4/PyAres/Device/device_service.py +285 -0
- pyares-0.1.4/PyAres/Device/device_warnings.py +2 -0
- pyares-0.1.4/PyAres/Models/__init__.py +7 -0
- pyares-0.1.4/PyAres/Models/ares_data_models.py +27 -0
- pyares-0.1.4/PyAres/Planning/__init__.py +9 -0
- pyares-0.1.4/PyAres/Planning/planner_models.py +83 -0
- pyares-0.1.4/PyAres/Planning/planning_service.py +252 -0
- pyares-0.1.4/PyAres/Test/analyzer_test.py +27 -0
- pyares-0.1.4/PyAres/Test/device_test.py +48 -0
- pyares-0.1.4/PyAres/Test/planner_test.py +85 -0
- pyares-0.1.4/PyAres/Utils/ares_data_schema_utils.py +44 -0
- pyares-0.1.4/PyAres/Utils/ares_data_type_utils.py +36 -0
- pyares-0.1.4/PyAres/Utils/ares_device_command_utils.py +43 -0
- pyares-0.1.4/PyAres/Utils/ares_outcome_utils.py +10 -0
- pyares-0.1.4/PyAres/Utils/ares_struct_utils.py +208 -0
- pyares-0.1.4/PyAres/Utils/ares_value_utils.py +214 -0
- pyares-0.1.4/PyAres/__init__.py +14 -0
- pyares-0.1.4/PyAres.egg-info/PKG-INFO +13 -0
- pyares-0.1.4/PyAres.egg-info/SOURCES.txt +32 -0
- pyares-0.1.4/PyAres.egg-info/dependency_links.txt +1 -0
- pyares-0.1.4/PyAres.egg-info/requires.txt +3 -0
- pyares-0.1.4/PyAres.egg-info/top_level.txt +1 -0
- pyares-0.1.4/README.md +148 -0
- pyares-0.1.4/pyproject.toml +30 -0
- pyares-0.1.4/setup.cfg +4 -0
- pyares-0.1.4/setup.py +3 -0
pyares-0.1.4/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 AFRL-ARES
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
pyares-0.1.4/PKG-INFO
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: PyAres
|
|
3
|
+
Version: 0.1.4
|
|
4
|
+
Summary: The official Python library for ARES.
|
|
5
|
+
Author-email: AFRL <AFRL.RX.AREScontact@us.af.mil>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/AFRL-ARES
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Dist: grpcio-tools>=1.75.1
|
|
11
|
+
Requires-Dist: grpcio<2.0.0,>=1.71.0
|
|
12
|
+
Requires-Dist: ares-datamodel>=0.13.2b1
|
|
13
|
+
Dynamic: license-file
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
# Standard Imports
|
|
2
|
+
import grpc
|
|
3
|
+
from concurrent import futures
|
|
4
|
+
from typing import Callable, Awaitable, Union, Mapping, Dict
|
|
5
|
+
|
|
6
|
+
# Import generated protobuf and gRPC stubs
|
|
7
|
+
from ares_datamodel.analyzing.remote import ares_remote_analyzer_service_pb2 as analyzer_service
|
|
8
|
+
from ares_datamodel.analyzing.remote import ares_remote_analyzer_service_pb2_grpc as analyzer_service_grpc
|
|
9
|
+
from ares_datamodel.analyzing import analysis_pb2
|
|
10
|
+
from ares_datamodel.analyzing import analyzer_capabilities_pb2
|
|
11
|
+
from ares_datamodel.connection import connection_state_pb2
|
|
12
|
+
from ares_datamodel.connection import connection_status_pb2
|
|
13
|
+
from ares_datamodel.connection import connection_info_pb2
|
|
14
|
+
from ares_datamodel import ares_data_type_pb2
|
|
15
|
+
from ares_datamodel import ares_data_schema_pb2
|
|
16
|
+
from ares_datamodel import ares_outcome_enum_pb2
|
|
17
|
+
|
|
18
|
+
# Import Utilities
|
|
19
|
+
from ..Utils import ares_struct_utils
|
|
20
|
+
from ..Utils import ares_data_schema_utils
|
|
21
|
+
from ..Utils import ares_outcome_utils
|
|
22
|
+
|
|
23
|
+
# Import python models
|
|
24
|
+
from ..Models import ares_data_models, RequestMetadata
|
|
25
|
+
from .analyzer_models import AnalysisRequest, Analysis, InfoResponse
|
|
26
|
+
|
|
27
|
+
# Type hints for the user's custom logic
|
|
28
|
+
AnalyzeLogicFunction = Callable[[AnalysisRequest], Union[Analysis, Awaitable[Analysis]]]
|
|
29
|
+
|
|
30
|
+
class AresAnalyzerServiceWrapper(analyzer_service_grpc.AresRemoteAnalyzerServiceServicer):
|
|
31
|
+
"""
|
|
32
|
+
A wrapper around the gRPC service to expose native Python objects for analysis.
|
|
33
|
+
"""
|
|
34
|
+
def __init__(self, info: InfoResponse, timeout: int, custom_analysis_logic: AnalyzeLogicFunction):
|
|
35
|
+
self._info = info
|
|
36
|
+
self._timeout = timeout
|
|
37
|
+
self._custom_analysis_logic = custom_analysis_logic
|
|
38
|
+
self._settings: Dict[str, ares_data_schema_pb2.SchemaEntry] = {}
|
|
39
|
+
self._analysis_parameters: Dict[str, ares_data_schema_pb2.SchemaEntry] = {}
|
|
40
|
+
|
|
41
|
+
def GetInfo(self, request, context) -> connection_info_pb2.InfoResponse:
|
|
42
|
+
print("Info Requested!")
|
|
43
|
+
try:
|
|
44
|
+
response = connection_info_pb2.InfoResponse(
|
|
45
|
+
name=self._info.name,
|
|
46
|
+
version=self._info.version,
|
|
47
|
+
description=self._info.description)
|
|
48
|
+
|
|
49
|
+
return response
|
|
50
|
+
|
|
51
|
+
except Exception as e:
|
|
52
|
+
response = connection_info_pb2.InfoResponse(
|
|
53
|
+
name="ERROR",
|
|
54
|
+
version="ERROR",
|
|
55
|
+
description="Error fetching information"
|
|
56
|
+
)
|
|
57
|
+
print(f"Exception while trying to respond to ARES with information! {e}")
|
|
58
|
+
return response
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def Analyze(self, request: analyzer_service.AnalysisRequest, context) -> analysis_pb2.Analysis:
|
|
62
|
+
print("Received an analysis request!")
|
|
63
|
+
try:
|
|
64
|
+
python_request = AnalysisRequest(
|
|
65
|
+
inputs=ares_struct_utils.ares_struct_to_dict(request.inputs),
|
|
66
|
+
settings=ares_struct_utils.ares_struct_to_dict(request.settings),
|
|
67
|
+
metadata=RequestMetadata(request.metadata)
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
proto_analysis = analysis_pb2.Analysis()
|
|
71
|
+
python_response = self._custom_analysis_logic(python_request)
|
|
72
|
+
if isinstance(python_response, Awaitable):
|
|
73
|
+
python_response = python_response.__await__()
|
|
74
|
+
|
|
75
|
+
if not isinstance(python_response, Analysis):
|
|
76
|
+
print("Analysis response was an invalid type, ")
|
|
77
|
+
proto_analysis.analysis_outcome = ares_outcome_enum_pb2.FAILURE
|
|
78
|
+
proto_analysis.error_string = "The user's custom analysis logic returned an invalid type, analysis cannot be processed"
|
|
79
|
+
return proto_analysis
|
|
80
|
+
|
|
81
|
+
print("Sending Analysis Response.....")
|
|
82
|
+
return analysis_pb2.Analysis(
|
|
83
|
+
result=python_response.result,
|
|
84
|
+
analysis_outcome=ares_outcome_utils.python_ares_outcome_to_proto_ares_outcome(python_response.outcome),
|
|
85
|
+
error_string=python_response.error_string
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
except Exception as e:
|
|
89
|
+
context.set_code(grpc.StatusCode.INTERNAL)
|
|
90
|
+
context.set_details(f"Error in custom analysis logic: {e}")
|
|
91
|
+
return analysis_pb2.Analysis(analysis_outcome=ares_outcome_enum_pb2.FAILURE, error_string=str(e))
|
|
92
|
+
|
|
93
|
+
def GetState(self, request, context) -> connection_state_pb2.StateResponse:
|
|
94
|
+
try:
|
|
95
|
+
analyzer_state = connection_state_pb2.StateResponse(state=connection_state_pb2.State.ACTIVE)
|
|
96
|
+
return analyzer_state
|
|
97
|
+
|
|
98
|
+
except Exception as e:
|
|
99
|
+
print(f"{e}")
|
|
100
|
+
return connection_state_pb2.StateResponse(state=connection_state_pb2.State.ERROR, state_message=f"Exception while trying to respond to ARES with state! {e}")
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def GetAnalysisParameters(self, request, context):
|
|
104
|
+
print("Analysis Parameters Requested")
|
|
105
|
+
try:
|
|
106
|
+
analysisParamResponse = analyzer_service.AnalysisParametersResponse()
|
|
107
|
+
|
|
108
|
+
for key, value in self._analysis_parameters.items():
|
|
109
|
+
map_entry = analysisParamResponse.parameter_schema.fields[key]
|
|
110
|
+
map_entry.CopyFrom(value)
|
|
111
|
+
|
|
112
|
+
return analysisParamResponse
|
|
113
|
+
|
|
114
|
+
except Exception as e:
|
|
115
|
+
print(f"Exception while trying to respond to ARES with analysis parameters! {e}")
|
|
116
|
+
|
|
117
|
+
def GetAnalyzerCapabilities(self, request, context) -> analyzer_capabilities_pb2.AnalyzerCapabilities:
|
|
118
|
+
print("Capabilities Requested!")
|
|
119
|
+
capabilities = analyzer_capabilities_pb2.AnalyzerCapabilities(timeout_seconds=self._timeout)
|
|
120
|
+
try:
|
|
121
|
+
for(key, value) in self._settings.items():
|
|
122
|
+
settings_entry = capabilities.settings_schema.fields[key]
|
|
123
|
+
settings_entry.type = value.type
|
|
124
|
+
settings_entry.optional = value.optional
|
|
125
|
+
|
|
126
|
+
if len(value.string_choices.strings) != 0:
|
|
127
|
+
settings_entry.string_choices.strings.extend(value.string_choices.strings)
|
|
128
|
+
|
|
129
|
+
elif len(value.number_choices.numbers) != 0:
|
|
130
|
+
settings_entry.number_choices.numbers.extend(value.number_choices.numbers)
|
|
131
|
+
|
|
132
|
+
return capabilities
|
|
133
|
+
|
|
134
|
+
except Exception as e:
|
|
135
|
+
print(f"Exception while trying to respond to ARES capabilities request! {e}")
|
|
136
|
+
return capabilities
|
|
137
|
+
|
|
138
|
+
def GetConnectionStatus(self, request, context):
|
|
139
|
+
try:
|
|
140
|
+
return connection_status_pb2.ConnectionStatus(status=connection_status_pb2.AresStatus.CONNECTED)
|
|
141
|
+
|
|
142
|
+
except Exception as e:
|
|
143
|
+
print(f"Exception while trying to respond to ARES with connection status! {e}")
|
|
144
|
+
|
|
145
|
+
def ValidateInputs(self, request: analyzer_service.ParameterValidationRequest, context):
|
|
146
|
+
print("Validating Inputs")
|
|
147
|
+
response = analyzer_service.ParameterValidationResult(success=True)
|
|
148
|
+
provided_params: Mapping[str, ares_data_type_pb2.AresDataType] = request.input_schema.fields
|
|
149
|
+
|
|
150
|
+
for stored_key, stored_schema in self._analysis_parameters.items():
|
|
151
|
+
if stored_key in provided_params:
|
|
152
|
+
matching_schema = provided_params.get(stored_key)
|
|
153
|
+
|
|
154
|
+
if stored_schema.type != matching_schema:
|
|
155
|
+
message = f"Schema Mismatch! {stored_key} was provided with the value type {stored_schema.type}, but the value type {matching_schema} was expected!"
|
|
156
|
+
response.messages.append(message)
|
|
157
|
+
print(message)
|
|
158
|
+
else:
|
|
159
|
+
if not stored_schema.optional:
|
|
160
|
+
message = f"Schema Missing! {stored_key} is marked as a required piece of data for analysis, but no assignment was found in the provided schema!"
|
|
161
|
+
response.messages.append(message)
|
|
162
|
+
print(message)
|
|
163
|
+
|
|
164
|
+
if response.messages.count != 0:
|
|
165
|
+
response.success = False
|
|
166
|
+
|
|
167
|
+
return response
|
|
168
|
+
|
|
169
|
+
class AresAnalyzerService:
|
|
170
|
+
"""
|
|
171
|
+
Manages the gRPC server for the AresAnalyzerService.
|
|
172
|
+
"""
|
|
173
|
+
def __init__(self,
|
|
174
|
+
custom_analysis_logic: AnalyzeLogicFunction,
|
|
175
|
+
name: str,
|
|
176
|
+
version: str,
|
|
177
|
+
description: str = "",
|
|
178
|
+
timeout: int = 30,
|
|
179
|
+
use_localhost: bool = True,
|
|
180
|
+
port: int = 7083):
|
|
181
|
+
"""
|
|
182
|
+
Initializes the AresAnalyzerService.
|
|
183
|
+
|
|
184
|
+
Args:
|
|
185
|
+
custom_analysis_logic (`AnalyzeLogicFunction`): A callable function that will be executed when an Analysis request is received.
|
|
186
|
+
This function should accept a `PyAres.Analyzing.AnalysisRequest` object and return a
|
|
187
|
+
`PyAres.Analyzing.Analysis` object (or an awaitable that resolves to one).
|
|
188
|
+
name (str): The name of your analyzer.
|
|
189
|
+
version (str): The version of your analyzer.
|
|
190
|
+
description (str): A brief description of your analyzer.
|
|
191
|
+
use_localhost (bool): If true, binds to localhost. Otherwise, binds to [::].
|
|
192
|
+
port (int): The port that your analyzer service will serve on. Defaults to port 7083.
|
|
193
|
+
"""
|
|
194
|
+
self.info = InfoResponse(name=name, version=version, description=description)
|
|
195
|
+
self._capabilities = analyzer_capabilities_pb2.AnalyzerCapabilities(settings_schema={})
|
|
196
|
+
self._port = port
|
|
197
|
+
self._server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
|
|
198
|
+
self._service_wrapper = AresAnalyzerServiceWrapper(info=self.info, timeout=timeout, custom_analysis_logic=custom_analysis_logic)
|
|
199
|
+
analyzer_service_grpc.add_AresRemoteAnalyzerServiceServicer_to_server(self._service_wrapper, self._server)
|
|
200
|
+
|
|
201
|
+
if use_localhost:
|
|
202
|
+
self._server.add_insecure_port(f'localhost:{self._port}')
|
|
203
|
+
else:
|
|
204
|
+
self._server.add_insecure_port(f'[::]:{self._port}')
|
|
205
|
+
|
|
206
|
+
def add_setting(self, setting_name: str, setting_type: ares_data_models.AresDataType, optional: bool = True, constraints: Union[list[int], list[str], list[float]] = []):
|
|
207
|
+
"""
|
|
208
|
+
Adds an analyzer setting to be reported to ARES when capabilities are requested.
|
|
209
|
+
While most `PyAres.Models.AresDataType` options are supported, bool arrays and byte arrays
|
|
210
|
+
cannot be used as the type for your setting values.
|
|
211
|
+
|
|
212
|
+
Args:
|
|
213
|
+
setting_name (str): The name of the setting.
|
|
214
|
+
setting_type (AresDataType): The type of this settings value.
|
|
215
|
+
optional (bool): Whether the setting is optional.
|
|
216
|
+
constraints: An optional list of values to constrain the available setting choices. Can be integers, strings, or floats.
|
|
217
|
+
"""
|
|
218
|
+
self._service_wrapper._settings[setting_name] = ares_data_schema_utils.create_settings_schema_entry(setting_type, optional, constraints)
|
|
219
|
+
|
|
220
|
+
def add_analysis_parameter(self, parameter_name: str, parameter_type: ares_data_models.AresDataType, optional: bool = False):
|
|
221
|
+
"""
|
|
222
|
+
Adds an analysis parameter that will be reported to ARES. Analysis parameters are inputs your analyzer accepts from ARES, and will be mapped to command outputs
|
|
223
|
+
in experiment scripts.
|
|
224
|
+
|
|
225
|
+
Args:
|
|
226
|
+
parameter_name (str): The name of the parameter being created.
|
|
227
|
+
parameter_type (AresDataType): The type associated with the new parameter.
|
|
228
|
+
optional (bool): Defaults to false. Determines whether your analyzer requires this information.
|
|
229
|
+
"""
|
|
230
|
+
self._service_wrapper._analysis_parameters[parameter_name] = ares_data_schema_utils.create_settings_schema_entry(parameter_type, optional, [])
|
|
231
|
+
|
|
232
|
+
def set_timeout(self, new_timeout: int):
|
|
233
|
+
"""
|
|
234
|
+
Sets the time, in seconds, that ARES will wait to receive a response from this service.
|
|
235
|
+
|
|
236
|
+
Args:
|
|
237
|
+
new_timeout: The new timeout value in seconds.
|
|
238
|
+
"""
|
|
239
|
+
self._capabilities.timeout_seconds = new_timeout
|
|
240
|
+
|
|
241
|
+
def start(self):
|
|
242
|
+
"""
|
|
243
|
+
Starts the service on the specified port, and waits for termination.
|
|
244
|
+
"""
|
|
245
|
+
print(f"Starting Ares Analyzer Service on port {self._port}...")
|
|
246
|
+
self._server.start()
|
|
247
|
+
self._server.wait_for_termination()
|
|
248
|
+
|
|
249
|
+
def stop(self):
|
|
250
|
+
"""
|
|
251
|
+
Stops the service, terminating the connection.
|
|
252
|
+
"""
|
|
253
|
+
print("Stopping Ares Analyzer Service...")
|
|
254
|
+
self._server.stop(0).wait()
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from typing import Dict, Any
|
|
2
|
+
from ..Models import Outcome, RequestMetadata
|
|
3
|
+
|
|
4
|
+
class AnalysisRequest:
|
|
5
|
+
""" Represents an analysis request received from ARES. """
|
|
6
|
+
|
|
7
|
+
def __init__(self, inputs: Dict[str, Any], settings: Dict[str, Any], metadata: RequestMetadata):
|
|
8
|
+
self.inputs = inputs
|
|
9
|
+
self.settings = settings
|
|
10
|
+
self.request_metadata = metadata
|
|
11
|
+
|
|
12
|
+
class Analysis:
|
|
13
|
+
""" Represents the result of an analysis process. """
|
|
14
|
+
|
|
15
|
+
def __init__(self, result: float, outcome: Outcome = Outcome.SUCCESS, error_string: str = ""):
|
|
16
|
+
"""
|
|
17
|
+
Initializes an Analysis message
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
result: The value your analyzer returns as the result of the experiment being analyzed. Represented as a float.
|
|
21
|
+
success: A boolean value that represents whether analysis was done successfully.
|
|
22
|
+
error_string: An optional string argument for passing why analysis failed to ARES. Will default to an empty string if no value is provided.
|
|
23
|
+
"""
|
|
24
|
+
self.result = result
|
|
25
|
+
self.outcome = outcome
|
|
26
|
+
self.error_string = error_string
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class InfoResponse:
|
|
30
|
+
""" A response message that provides basic information about your analyzer. """
|
|
31
|
+
|
|
32
|
+
def __init__(self, name: str, version: str, description: str = ""):
|
|
33
|
+
"""
|
|
34
|
+
Initializes a new InfoResponse message.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
name: The name of your analyzer, to be displayed in ARES.
|
|
38
|
+
version: The specific version of your analyzer. This information is saved in experiment results that use your analyzer.
|
|
39
|
+
description: An optional (but recommended) string that gives a basic description of your analyzer.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
self.name = name
|
|
43
|
+
self.version = version
|
|
44
|
+
self.description = description
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from typing import Dict, Union
|
|
2
|
+
from ..Models import ares_data_models
|
|
3
|
+
|
|
4
|
+
class DeviceSchemaEntry:
|
|
5
|
+
""" A class that describes an input or output parameter for a device command """
|
|
6
|
+
|
|
7
|
+
def __init__(self, type: ares_data_models.AresDataType, description: str = "", unit: str = "", optional: bool = False, constraints: Union[list[int], list[float], list[str]] = []):
|
|
8
|
+
"""
|
|
9
|
+
Initializes a new DeviceSchemaEntry
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
type ('ares_data_models.AresDataType'): An AresDataType that describes the type associated with this schema entry
|
|
13
|
+
description (str): A description of the given schema entry
|
|
14
|
+
unit (str): The unit associated with this schema entry
|
|
15
|
+
optional (bool): A boolean value that determines whether or not this schema entry's inclusion is optional
|
|
16
|
+
contraints (Union[list[int], list[float], list[str]]): An optional list of contraints to limit the number of choices available for this schema entry
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
self.type = type
|
|
20
|
+
self.optional = optional
|
|
21
|
+
self.description = description
|
|
22
|
+
self.unit = unit
|
|
23
|
+
self.contraints = constraints
|
|
24
|
+
|
|
25
|
+
class DeviceCommandDescriptor:
|
|
26
|
+
""" A class that contains all the necessary information to describe a device command """
|
|
27
|
+
def __init__(self, name: str, description: str, input_schema: Dict[str, DeviceSchemaEntry], output_schema: Dict[str, DeviceSchemaEntry]):
|
|
28
|
+
"""
|
|
29
|
+
Initializes a new instance of the device command descriptor class.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
name (str): The name of this device command.
|
|
33
|
+
description (str): The description of this device command.
|
|
34
|
+
input_schema (list[ares_data_models.AresDataType]): A dictionary that defines the input parameters to the device command.
|
|
35
|
+
output_schema (list[ares_data_models.AresDataType]): A dictionary that defines the output parameters to the device command.
|
|
36
|
+
"""
|
|
37
|
+
self.name = name
|
|
38
|
+
self.description = description
|
|
39
|
+
self.input_schema = input_schema
|
|
40
|
+
self.output_schema = output_schema
|