flexCommunicator 0.1.0__py3-none-any.whl
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.
- flexCommunicator/__init__.py +0 -0
- flexCommunicator/clientLibraries/__init__.py +0 -0
- flexCommunicator/clientLibraries/flcpy/__init__.py +0 -0
- flexCommunicator/clientLibraries/flcpy/action/__init__.py +0 -0
- flexCommunicator/clientLibraries/flcpy/action/action.py +85 -0
- flexCommunicator/clientLibraries/flcpy/action/action_client.py +70 -0
- flexCommunicator/clientLibraries/flcpy/action/goal_handle.py +50 -0
- flexCommunicator/clientLibraries/flcpy/codec/ROS2Codec.py +227 -0
- flexCommunicator/clientLibraries/flcpy/codec/__init__.py +0 -0
- flexCommunicator/clientLibraries/flcpy/commands/__init__.py +0 -0
- flexCommunicator/clientLibraries/flcpy/commands/commandProcessor.py +113 -0
- flexCommunicator/clientLibraries/flcpy/commands/composer.py +25 -0
- flexCommunicator/clientLibraries/flcpy/communication/CommunicationManager.py +579 -0
- flexCommunicator/clientLibraries/flcpy/communication/__init__.py +0 -0
- flexCommunicator/clientLibraries/flcpy/contracts/__init__.py +0 -0
- flexCommunicator/clientLibraries/flcpy/contracts/contractVariable.py +93 -0
- flexCommunicator/clientLibraries/flcpy/flexCloud/__init__.py +0 -0
- flexCommunicator/clientLibraries/flcpy/flexCloud/flexCloudConfiguration.py +16 -0
- flexCommunicator/clientLibraries/flcpy/flexCloud/flexCloudManager.py +162 -0
- flexCommunicator/clientLibraries/flcpy/flexCloud/flexCloudOrchestrator.py +248 -0
- flexCommunicator/clientLibraries/flcpy/flexCloud/flexCloudVariable.py +130 -0
- flexCommunicator/clientLibraries/flcpy/flexNode.py +892 -0
- flexCommunicator/clientLibraries/flcpy/fmi/__init__.py +0 -0
- flexCommunicator/clientLibraries/flcpy/fmi/fmuNode.py +166 -0
- flexCommunicator/clientLibraries/flcpy/fmi/node.py +360 -0
- flexCommunicator/clientLibraries/flcpy/knowledge/KnowledgeManager.py +288 -0
- flexCommunicator/clientLibraries/flcpy/knowledge/__init__.py +0 -0
- flexCommunicator/clientLibraries/flcpy/logging/LoggingAndTracking.py +159 -0
- flexCommunicator/clientLibraries/flcpy/logging/__init__.py +0 -0
- flexCommunicator/clientLibraries/flcpy/messages/StandardizedMessages.py +64 -0
- flexCommunicator/clientLibraries/flcpy/messages/__init__.py +0 -0
- flexCommunicator/clientLibraries/flcpy/node.py +486 -0
- flexCommunicator/clientLibraries/flcpy/security/__init__.py +0 -0
- flexCommunicator/clientLibraries/flcpy/security/security.py +189 -0
- flexCommunicator/clientLibraries/flcpy/service/__init__.py +0 -0
- flexCommunicator/clientLibraries/flcpy/service/client.py +58 -0
- flexCommunicator/clientLibraries/flcpy/service/service.py +67 -0
- flexCommunicator/clientLibraries/flcpy/transport/PropertyBinding.py +108 -0
- flexCommunicator/clientLibraries/flcpy/transport/PropertyRegistry.py +142 -0
- flexCommunicator/clientLibraries/flcpy/transport/__init__.py +0 -0
- flexCommunicator/clientLibraries/flcpy/utils/Timer.py +22 -0
- flexCommunicator/clientLibraries/flcpy/utils/__init__.py +0 -0
- flexCommunicator/clientLibraries/flcpy/utils/auxiliary.py +261 -0
- flexCommunicator/clientLibraries/flcpy/utils/constants.py +276 -0
- flexCommunicator/clientLibraries/flcpy/utils/decorators.py +70 -0
- flexCommunicator/clientLibraries/flcpy/validityFrame/__init__.py +0 -0
- flexCommunicator/clientLibraries/flcpy/validityFrame/runtimeMonitor.py +101 -0
- flexCommunicator/clientLibraries/flcpy/validityFrame/validityFrameManager.py +958 -0
- flexcommunicator-0.1.0.dist-info/METADATA +568 -0
- flexcommunicator-0.1.0.dist-info/RECORD +53 -0
- flexcommunicator-0.1.0.dist-info/WHEEL +5 -0
- flexcommunicator-0.1.0.dist-info/licenses/LICENSE +201 -0
- flexcommunicator-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
#**************************************************************************
|
|
2
|
+
# * Copyright (C) 2025-present Bert Van Acker (B.MKR) <bva.bmkr@gmail.com>
|
|
3
|
+
# *
|
|
4
|
+
# * This file is part of the flexIA project.
|
|
5
|
+
# *
|
|
6
|
+
# * flexIA can not be copied and/or distributed without the express
|
|
7
|
+
# * permission of Bert Van Acker
|
|
8
|
+
# *************************************************************************
|
|
9
|
+
|
|
10
|
+
class GENERIC_STATUS:
|
|
11
|
+
UNKNOWN = "UNKNOWN"
|
|
12
|
+
INCORRECT_CMD = "INCORRECT_CMD"
|
|
13
|
+
|
|
14
|
+
class SECURITY_STORE:
|
|
15
|
+
SHARED_SECRET = "SHARED_SECRET"
|
|
16
|
+
FLEXCLOUD_USER = "FLEXCLOUD_USER"
|
|
17
|
+
FLEXCLOUD_PASSWORD = "FLEXCLOUD_PASSWORD"
|
|
18
|
+
FLEXCLOUD_LOGIN = "FLEXCLOUD_LOGIN"
|
|
19
|
+
FLEXCLOUD_ACTIVE_PROJECT = "FLEXCLOUD_ACTIVE_PROJECT"
|
|
20
|
+
FLEXCLOUD_ACTIVE_SHARED_KEY = "FLEXCLOUD_ACTIVE_SHARED_KEY"
|
|
21
|
+
FLEXCLOUD_CONNECTORID_SECRET = "FLEXCLOUD_CONNECTORID_SECRET"
|
|
22
|
+
|
|
23
|
+
class COMMAND_TYPE:
|
|
24
|
+
UNKNOWN = "UNKNOWN"
|
|
25
|
+
OTA_UPDATE = "OTA_UPDATE"
|
|
26
|
+
PING = "PING"
|
|
27
|
+
PUSH = "PUSH"
|
|
28
|
+
BUILD = "BUILD"
|
|
29
|
+
RUN = "RUN"
|
|
30
|
+
PONG = "PONG"
|
|
31
|
+
|
|
32
|
+
class REGISTRY_TYPE:
|
|
33
|
+
UNKNOWN = "UNKNOWN"
|
|
34
|
+
GITHUB = "github"
|
|
35
|
+
DOCKERHUB = "dockerhub"
|
|
36
|
+
|
|
37
|
+
class REGISTRY_WORKSPACE:
|
|
38
|
+
BASE = "apps/"
|
|
39
|
+
|
|
40
|
+
class APPLICATION_STATUS:
|
|
41
|
+
UNKNOWN = "UNKNOWN"
|
|
42
|
+
REGISTERED = "REGISTERED"
|
|
43
|
+
BUILD = "BUILD"
|
|
44
|
+
INITIALIZING = "INITIALIZING"
|
|
45
|
+
INITIALIZED = "INITIALIZED"
|
|
46
|
+
RUNNING = "RUNNING"
|
|
47
|
+
COMPLETED = "COMPLETED"
|
|
48
|
+
ERROR = "ERROR"
|
|
49
|
+
STOPPED = "STOPPED"
|
|
50
|
+
|
|
51
|
+
class TESTER_STATUS:
|
|
52
|
+
UNKNOWN = "UNKNOWN"
|
|
53
|
+
INITIALIZED = "INITIALIZED"
|
|
54
|
+
TESTING = "TESTING"
|
|
55
|
+
COMPLETED = "COMPLETED"
|
|
56
|
+
ERROR = "ERROR"
|
|
57
|
+
STOPPED = "STOPPED"
|
|
58
|
+
|
|
59
|
+
class PACKAGE_TYPE:
|
|
60
|
+
UNKNOWN = "UNKNOWN"
|
|
61
|
+
ROBOSAPIENS = "robosapiens"
|
|
62
|
+
FLEXIA = "flexia"
|
|
63
|
+
|
|
64
|
+
class WORKFLOW_TYPE:
|
|
65
|
+
UNKNOWN = "UNKNOWN"
|
|
66
|
+
DOCKER = "docker"
|
|
67
|
+
DOCKER_COMPOSE = "docker-compose"
|
|
68
|
+
CUSTOM = "custom"
|
|
69
|
+
NONE = "none"
|
|
70
|
+
|
|
71
|
+
class GITHUB:
|
|
72
|
+
DEFAULT_BRANCH = "master"
|
|
73
|
+
|
|
74
|
+
class FLEXCLOUD_VARIABLES:
|
|
75
|
+
APPLICATIONS = ":applications:"
|
|
76
|
+
VARIABLES = ":variables:"
|
|
77
|
+
STATUS = "status"
|
|
78
|
+
LOGS = "logs"
|
|
79
|
+
CONFIGURATION = ":configuration:"
|
|
80
|
+
REQUIREMENTS = ":requirements:"
|
|
81
|
+
REQUIREMENT_STATUS = ":status"
|
|
82
|
+
REQUIREMENT_DESCRIPTIONS = ":description"
|
|
83
|
+
REQUIREMENT_ERROR = ":error"
|
|
84
|
+
CONTRACTS = ":contract:"
|
|
85
|
+
ASSUMPTIONS = "assumptions:"
|
|
86
|
+
GUARANTEES = "guarantees:"
|
|
87
|
+
PROFILING = ":profiling:"
|
|
88
|
+
VALIDITY_FRAME = ":validity_frame"
|
|
89
|
+
RUNTIME_MONITORS = ":runtime_monitors:"
|
|
90
|
+
|
|
91
|
+
class TRANSPORT_PROTOCOLS:
|
|
92
|
+
PROTOCOL_MQTT = "mqtt"
|
|
93
|
+
PROTOCOL_RABBITMQ = "rabbitmq"
|
|
94
|
+
PROTOCOL_KAFKA = "kafka"
|
|
95
|
+
PROTOCOL_REDIS = "redis"
|
|
96
|
+
PROTOCOL_ZENOH = "zenoh"
|
|
97
|
+
PROTOCOL_WEBSOCKET = "websocket"
|
|
98
|
+
PROTOCOL_TCP = "tcp"
|
|
99
|
+
PROTOCOL_TCP_ALT = "tcp/ip"
|
|
100
|
+
PROTOCOL_OPC_UA = "opc_ua"
|
|
101
|
+
PROTOCOL_TWINCAT_ADS = "twincat_ads"
|
|
102
|
+
|
|
103
|
+
class CONFIG_KEYS:
|
|
104
|
+
KEY_EVENT_MANAGER_CONFIG = "Event_Manager_Config"
|
|
105
|
+
KEY_MESSAGE_MANAGER_CONFIG = "Message_Manager_Config"
|
|
106
|
+
KEY_LOGGER_CONFIG = "Logger_Config"
|
|
107
|
+
KEY_KNOWLEDGE_CONFIG = "Knowledge_Config"
|
|
108
|
+
KEY_APPLICATION_DESCRIPTOR = "application_Descriptor"
|
|
109
|
+
KEY_LOG_LEVEL = "log_level"
|
|
110
|
+
KEY_LOG_FORMAT = "format"
|
|
111
|
+
KEY_PROTOCOL = "protocol"
|
|
112
|
+
KEY_COMMUNICATION_MATRIX = "Communication_Matrix"
|
|
113
|
+
KEY_DATA_MANAGER_CONFIG = "Data_Manager_Config"
|
|
114
|
+
KEY_FLEXCLOUD_MANAGER_CONFIG = "flexCloud_Manager_Config"
|
|
115
|
+
KEY_COMMUNICATION_MANAGERS_CONFIG = "Communication_managers"
|
|
116
|
+
|
|
117
|
+
class FLEXCLOUD_MESSAGES:
|
|
118
|
+
MSG_INITIALIZING_KNOWLEDGE = "Initializing knowledge: {} knowledge"
|
|
119
|
+
MSG_INITIALIZING_EVENT_MANAGER = "Initializing Event Manager"
|
|
120
|
+
MSG_INITIALIZING_IO_MANAGER = "Initializing IO Manager"
|
|
121
|
+
MSG_USING_COMMUNICATION_MANAGER = "{} is using {} Communication Manager"
|
|
122
|
+
MSG_STARTING = "{} is starting..."
|
|
123
|
+
MSG_SHUTTING_DOWN = "{} is shutting down..."
|
|
124
|
+
MSG_REGISTER_EVENT_CALLBACK = "Registered callback for event: {}"
|
|
125
|
+
MSG_INITIALIZING_DATA_MANAGER = "Initializing Data Manager"
|
|
126
|
+
MSG_INITIALIZING_FLEXCLOUD_MANAGER = "Initializing flexCloud Manager"
|
|
127
|
+
MSG_INITIALIZING_APPLICATION_DESCRIPTOR = "Initializing flexCloud Manager"
|
|
128
|
+
MSG_INITIALIZING_PROPERTY_REGISTRY = "Initializing Property Registry"
|
|
129
|
+
MSG_UPDATE_PROPERTY_PROTOCOL_SUCCESS = "Transport protocol is successfully updated of property: "
|
|
130
|
+
|
|
131
|
+
class FLEXCLOUD_WARNINGS:
|
|
132
|
+
WARN_REGISTER_EVENT_CALLBACK_NOT_SET = "Event manager is not set for registering event callbacks."
|
|
133
|
+
WARN_NOT_IMPLEMENTED = "Called functions not implemented yet."
|
|
134
|
+
WARN_DATA_MANAGER_NOT_SET = "Data manager is not set for setting data."
|
|
135
|
+
WARN_KNOWLEDGE_MANAGER_NOT_SET = "knowledge manager is not set for storing data."
|
|
136
|
+
WARN_EVENT_MANAGER_NOT_SET = "Event manager is not set for Event publishing."
|
|
137
|
+
WARN_EMPTY_COMMUNICATION_MANAGERS = "No Communication managers defined, no inter-component data communication possible."
|
|
138
|
+
WARN_SINGLE_COMMUNICATION_MANAGER_DEPRICATED = "Only multi-transport communication managers are supported, please specify Communication_managers in config.yaml."
|
|
139
|
+
WARN_UNKNOWN_FLEXCLOUD_COMMAND = "Received unknown flexcloud command."
|
|
140
|
+
WARN_NO_MATCHING_TRANSPORT_PROTOCOL = "No matching transport protocol available for "
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
class FLEXCLOUD_ERRORS:
|
|
144
|
+
ERR_PROPERTY_REGISTRY_NOT_FOUND = "Given property is not defined in the communication matrix or transport protocol is not defined."
|
|
145
|
+
ERR_COMMUNICATION_MANAGER_NOT_FOUND = "No matching communication manager found, please verify the transport protocol."
|
|
146
|
+
ERR_REDIS_SUBSCRIPTION_CLOSED = "Redis listener thread exiting: {}"
|
|
147
|
+
ERR_INVALID_COMMAND_SIGNATURE = "Invalid command signature, no action executed."
|
|
148
|
+
ERR_UPDATE_PROPERTY_PROTOCOL_FAIL = "Failed to update transport protocol of property: "
|
|
149
|
+
class ENCODING:
|
|
150
|
+
ENCODING_UTF8 = "utf-8"
|
|
151
|
+
|
|
152
|
+
class DEFAULT_MESSAGES:
|
|
153
|
+
DEFAULT_EVENT_MESSAGE = {}
|
|
154
|
+
DEFAULT_DATA_MESSAGE = {}
|
|
155
|
+
|
|
156
|
+
class FLEXCLOUD_KEYS:
|
|
157
|
+
COMMAND = ":cmd"
|
|
158
|
+
RESPONSE = ":response"
|
|
159
|
+
|
|
160
|
+
class FLEXCLOUD_COMMANDS:
|
|
161
|
+
UNKNOWN = "UNKNOWN"
|
|
162
|
+
PING = "PING"
|
|
163
|
+
PONG = "PONG"
|
|
164
|
+
UPDATE_TRANSPORT = "UPDATE_TRANSPORT"
|
|
165
|
+
UPDATE_CONFIG = "UPDATE_CONFIG"
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
class CONTRACT_VARIABLE_TYPE:
|
|
169
|
+
ASSUMPTION = "ASSUMPTION"
|
|
170
|
+
GUARANTEE = "GUARANTEE"
|
|
171
|
+
|
|
172
|
+
class CONTRACT_CHECK_TYPE:
|
|
173
|
+
BOUND_CHECK = "BOUND_CHECK"
|
|
174
|
+
SET_MEMBER_CHECK = "SET_MEMBER_CHECK"
|
|
175
|
+
CUSTOM = "CUSTOM"
|
|
176
|
+
|
|
177
|
+
class CONTRACT_VARIABLE_OUTPUT:
|
|
178
|
+
VALID = "VALID"
|
|
179
|
+
INVALID = "INVALID"
|
|
180
|
+
UNKNOWN = "UNKNOWN"
|
|
181
|
+
|
|
182
|
+
class VF_RUNTIME_MONITOR_TYPE:
|
|
183
|
+
LOCAL = "LOCAL"
|
|
184
|
+
REMOTE = "REMOTE"
|
|
185
|
+
|
|
186
|
+
class RUNTIME_MONITOR_OUTPUT:
|
|
187
|
+
VALID = "VALID"
|
|
188
|
+
INVALID = "INVALID"
|
|
189
|
+
UNKNOWN = "UNKNOWN"
|
|
190
|
+
|
|
191
|
+
class RUNTIME_MONITOR_CHECK_TYPE:
|
|
192
|
+
BOUND_CHECK = "BOUND_CHECK"
|
|
193
|
+
SET_MEMBER_CHECK = "SET_MEMBER_CHECK"
|
|
194
|
+
CUSTOM = "CUSTOM"
|
|
195
|
+
REMOTE = "REMOTE"
|
|
196
|
+
|
|
197
|
+
class GOAL_STATUS:
|
|
198
|
+
ACCEPTED = "ACCEPTED "
|
|
199
|
+
EXECUTING = "EXECUTING "
|
|
200
|
+
CANCELING = "CANCELING "
|
|
201
|
+
SUCCEEDED = "SUCCEEDED"
|
|
202
|
+
ABORTED = "ABORTED"
|
|
203
|
+
CANCELED = "CANCELED"
|
|
204
|
+
|
|
205
|
+
class FMU_Node_State:
|
|
206
|
+
STARTUP="start-up"
|
|
207
|
+
IDLE="idle"
|
|
208
|
+
NODE_INPUT_UPDATE = "node_input_update"
|
|
209
|
+
NODE_OUTPUT_UPDATE = "node_output_update"
|
|
210
|
+
NODE_STEP = "node_step"
|
|
211
|
+
FMI_SETUP = "FMI_setup"
|
|
212
|
+
MQTT_SETUP = "MQTT_setup"
|
|
213
|
+
ERROR = "error"
|
|
214
|
+
|
|
215
|
+
class simConstants:
|
|
216
|
+
startTime_Default = 0.0
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
class FMI_communicationProtocol:
|
|
220
|
+
sim_start = "SIM/START"
|
|
221
|
+
sim_stop = "SIM/STOP"
|
|
222
|
+
sim_error = "SIM/ERROR"
|
|
223
|
+
sim_heartbeatRequest = "SIM/HEARTBEAT"
|
|
224
|
+
sim_startup = "SIM/STARTUP"
|
|
225
|
+
node_step = "STEP"
|
|
226
|
+
node_step_IPO = "STEP_IPO"
|
|
227
|
+
node_input = "INPUT"
|
|
228
|
+
node_output = "OUTPUT"
|
|
229
|
+
node_info = "INFO"
|
|
230
|
+
node_heartbeat = "HEARTBEAT"
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
class OrchestrationType:
|
|
234
|
+
FMI_local = "FMI_LOCAL"
|
|
235
|
+
DISTRIBUTED = "DISTRIBUTED"
|
|
236
|
+
DISTRIBUTED_FIXED_IO = "DISTRIBUTED_FIXED_IO"
|
|
237
|
+
|
|
238
|
+
class ExecutionPatterns:
|
|
239
|
+
TRIGGERED = "TRIGGERED"
|
|
240
|
+
IPO = "IPO"
|
|
241
|
+
IOP = "IOP"
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
class VerificationMethods:
|
|
245
|
+
STATICLOWERBOUND = "StaticLowerBound"
|
|
246
|
+
STATICUPPERBOUND = "StaticUpperBound"
|
|
247
|
+
STATICBOUND = "StaticBound"
|
|
248
|
+
|
|
249
|
+
class MonitorType:
|
|
250
|
+
RUNTIME = "runtime"
|
|
251
|
+
POSTPROCESSING = "postprocessing"
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
class RobotArmActions:
|
|
255
|
+
MOVEJ = "movej"
|
|
256
|
+
MOVEJ_KINEMATICS = "movej_kinematics"
|
|
257
|
+
COMMAND = "command"
|
|
258
|
+
GET_STATUS = "get_status"
|
|
259
|
+
|
|
260
|
+
class GRIPPERActions:
|
|
261
|
+
OPEN = "open"
|
|
262
|
+
CLOSE = "close"
|
|
263
|
+
MOVE= "move"
|
|
264
|
+
GET_STATUS = "get_status"
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
class CAMERAStatus:
|
|
268
|
+
OPERATIONAL = "OPERATIONAL"
|
|
269
|
+
ERROR = "ERROR"
|
|
270
|
+
NO_FRAME = "NO_FRAME"
|
|
271
|
+
MODEL_NOT_LOADED ="MODEL_NOT_LOADED"
|
|
272
|
+
INFERENCE_ERROR = "INFERENCE_ERROR"
|
|
273
|
+
|
|
274
|
+
class VALIDITY_FRAME_INTEGRATION:
|
|
275
|
+
ARCHITECTURE = ":SAIfetyArchitecture"
|
|
276
|
+
TRACEABILITYGRAPH = ":TraceabilityGraph"
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import functools
|
|
2
|
+
import time
|
|
3
|
+
from flexCommunicator.clientLibraries.flcpy.utils.constants import *
|
|
4
|
+
|
|
5
|
+
class flexRequirements:
|
|
6
|
+
"""
|
|
7
|
+
Method‐decorator for linking requirements to application functions
|
|
8
|
+
"""
|
|
9
|
+
def __init__(self, id: str, description: str, expectedExecutionTime=None):
|
|
10
|
+
self.call_count = 0
|
|
11
|
+
self.id = id
|
|
12
|
+
self.id_key = str(id)
|
|
13
|
+
self.description = description
|
|
14
|
+
self.expectedExecutionTime = expectedExecutionTime
|
|
15
|
+
|
|
16
|
+
def __call__(self, func):
|
|
17
|
+
@functools.wraps(func)
|
|
18
|
+
def wrapper(node, *args, **kwargs):
|
|
19
|
+
# here `self` is the flexNode instance
|
|
20
|
+
self.call_count += 1
|
|
21
|
+
if self.call_count == 1:
|
|
22
|
+
node.flexCloud_manager.write(key=node.requirements_key+ self.id_key+FLEXCLOUD_VARIABLES.REQUIREMENT_STATUS,value="PASS")
|
|
23
|
+
node.flexCloud_manager.write(key=node.requirements_key+ self.id_key+FLEXCLOUD_VARIABLES.REQUIREMENT_DESCRIPTIONS,value=self.description)
|
|
24
|
+
node.flexCloud_manager.write(key=node.requirements_key+ self.id_key+FLEXCLOUD_VARIABLES.REQUIREMENT_ERROR,value="-")
|
|
25
|
+
try:
|
|
26
|
+
if self.expectedExecutionTime is None:
|
|
27
|
+
# THE ACTUAL FUNCTION
|
|
28
|
+
return func(node, *args, **kwargs)
|
|
29
|
+
|
|
30
|
+
else:
|
|
31
|
+
# CHECK EXECUTION TIME
|
|
32
|
+
start_time = time.perf_counter()
|
|
33
|
+
value = func(node, *args, **kwargs)
|
|
34
|
+
end_time = time.perf_counter()
|
|
35
|
+
ET_time = end_time - start_time
|
|
36
|
+
if ET_time > self.expectedExecutionTime:
|
|
37
|
+
raise Exception(f"Expected execution time {self.expectedExecutionTime} secs, but got {ET_time:.4f} secs")
|
|
38
|
+
return value
|
|
39
|
+
|
|
40
|
+
except Exception as e:
|
|
41
|
+
node.flexCloud_manager.write(key=node.requirements_key+ self.id_key+FLEXCLOUD_VARIABLES.REQUIREMENT_STATUS,value="FAIL")
|
|
42
|
+
node.flexCloud_manager.write(key=node.requirements_key+ self.id_key+FLEXCLOUD_VARIABLES.REQUIREMENT_DESCRIPTIONS,value=self.description)
|
|
43
|
+
node.flexCloud_manager.write(key=node.requirements_key+ self.id_key+FLEXCLOUD_VARIABLES.REQUIREMENT_ERROR,value=str(e))
|
|
44
|
+
return -1
|
|
45
|
+
|
|
46
|
+
return wrapper
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class flexProfiler:
|
|
51
|
+
"""
|
|
52
|
+
Method‐decorator for performing a time measurement on a application function and publish (for profiling)
|
|
53
|
+
"""
|
|
54
|
+
def __init__(self):
|
|
55
|
+
x=1
|
|
56
|
+
|
|
57
|
+
def __call__(self, func):
|
|
58
|
+
@functools.wraps(func)
|
|
59
|
+
def wrapper_timer(node,*args, **kwargs):
|
|
60
|
+
start_time = time.perf_counter()
|
|
61
|
+
value = func(node,*args, **kwargs)
|
|
62
|
+
end_time = time.perf_counter()
|
|
63
|
+
run_time = end_time - start_time
|
|
64
|
+
node.flexCloud_manager.write_history(key=node.application_profiler_key + func.__name__, value=str(run_time))
|
|
65
|
+
print(f"Finished {func.__name__}() in {run_time:.4f} secs") # TODO: instead of printing, publish to flexCloud
|
|
66
|
+
return value
|
|
67
|
+
|
|
68
|
+
return wrapper_timer
|
|
69
|
+
|
|
70
|
+
|
|
File without changes
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#**************************************************************************
|
|
2
|
+
# * Copyright (C) 2025-present Bert Van Acker (B.MKR) <bva.bmkr@gmail.com>
|
|
3
|
+
# *
|
|
4
|
+
# * This file is part of the flexIA project.
|
|
5
|
+
# *
|
|
6
|
+
# * flexIA can not be copied and/or distributed without the express
|
|
7
|
+
# * permission of Bert Van Acker
|
|
8
|
+
# *************************************************************************
|
|
9
|
+
import threading
|
|
10
|
+
import json
|
|
11
|
+
import time
|
|
12
|
+
|
|
13
|
+
from flexCommunicator.clientLibraries.flcpy.utils.constants import *
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class runtimeMonitor(object):
|
|
17
|
+
def __init__(self, name, initial_value=0, type=VF_RUNTIME_MONITOR_TYPE.LOCAL, check=CONTRACT_CHECK_TYPE.BOUND_CHECK,bound = None,allowed_values=None,customFunction=None):
|
|
18
|
+
self._name = name
|
|
19
|
+
self._type = type # VF RUNTIME TYPE, LOCAL CHECKING OR REMOTE CHECKING
|
|
20
|
+
self._check = check
|
|
21
|
+
self._value = initial_value
|
|
22
|
+
self._requestedValue = initial_value
|
|
23
|
+
|
|
24
|
+
#flexCloud handler
|
|
25
|
+
self.flexCloud_manager = None
|
|
26
|
+
self.flexCloud_connectorID = None
|
|
27
|
+
self.flexCloud_applicationID = None
|
|
28
|
+
|
|
29
|
+
# Determine validity based on initial value
|
|
30
|
+
self._bound = bound
|
|
31
|
+
self._allowed_values = set(allowed_values) if allowed_values is not None else None
|
|
32
|
+
self._customFunction = customFunction
|
|
33
|
+
|
|
34
|
+
# Determine validity based on initial value
|
|
35
|
+
self._isValid = self._check_validity()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _sync_to_redis(self):
|
|
41
|
+
key = self.flexCloud_connectorID + FLEXCLOUD_VARIABLES.APPLICATIONS + self.flexCloud_applicationID + FLEXCLOUD_VARIABLES.VALIDITY_FRAME + FLEXCLOUD_VARIABLES.RUNTIME_MONITORS + self._name
|
|
42
|
+
self._write_knowledge(key=key + ":unchecked_value", value=self._requestedValue)
|
|
43
|
+
self._write_knowledge(key=key+":validity" , value=self._isValid)
|
|
44
|
+
|
|
45
|
+
def initialize(self):
|
|
46
|
+
""" Initialize the flexCloud variable"""
|
|
47
|
+
self._sync_to_redis()
|
|
48
|
+
|
|
49
|
+
def set(self, value):
|
|
50
|
+
self._requestedValue = value
|
|
51
|
+
self._isValid = self._check_validity()
|
|
52
|
+
if self._isValid == RUNTIME_MONITOR_OUTPUT.VALID:
|
|
53
|
+
self._value = value
|
|
54
|
+
self._sync_to_redis()
|
|
55
|
+
|
|
56
|
+
def get(self):
|
|
57
|
+
return self._value
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
#----------------------------- contract variable checks----------------
|
|
61
|
+
def _check_validity(self):
|
|
62
|
+
if self._type == VF_RUNTIME_MONITOR_TYPE.LOCAL:
|
|
63
|
+
if self._check == RUNTIME_MONITOR_CHECK_TYPE.BOUND_CHECK:
|
|
64
|
+
isValid = self._bound[0] <= self._requestedValue <= self._bound[1]
|
|
65
|
+
if isValid:
|
|
66
|
+
return RUNTIME_MONITOR_OUTPUT.VALID
|
|
67
|
+
else:
|
|
68
|
+
return RUNTIME_MONITOR_OUTPUT.INVALID
|
|
69
|
+
|
|
70
|
+
elif self._check == RUNTIME_MONITOR_CHECK_TYPE.SET_MEMBER_CHECK:
|
|
71
|
+
if self._allowed_values is None:
|
|
72
|
+
return RUNTIME_MONITOR_OUTPUT.INVALID
|
|
73
|
+
isValid = self._requestedValue in self._allowed_values
|
|
74
|
+
if isValid:
|
|
75
|
+
return RUNTIME_MONITOR_OUTPUT.VALID
|
|
76
|
+
else:
|
|
77
|
+
return RUNTIME_MONITOR_OUTPUT.INVALID
|
|
78
|
+
|
|
79
|
+
elif self._check == RUNTIME_MONITOR_CHECK_TYPE.CUSTOM:
|
|
80
|
+
isValid = self._customFunction(self._requestedValue)
|
|
81
|
+
return isValid
|
|
82
|
+
|
|
83
|
+
elif self._type == VF_RUNTIME_MONITOR_TYPE.REMOTE:
|
|
84
|
+
return RUNTIME_MONITOR_OUTPUT.UNKNOWN
|
|
85
|
+
|
|
86
|
+
# --------------------------- HELPER FUNCTIONS ------------------------
|
|
87
|
+
def _write_knowledge(self, key, value):
|
|
88
|
+
"""Write a value to the knowledge Manager."""
|
|
89
|
+
if isinstance(key, str):
|
|
90
|
+
if isinstance(value, str):
|
|
91
|
+
value = str(value)
|
|
92
|
+
return self.flexCloud_manager.write(key, value)
|
|
93
|
+
else:
|
|
94
|
+
# Convert the class instance to a dictionary
|
|
95
|
+
class_dict = {}
|
|
96
|
+
for key_attr, attr_value in key.__dict__.items():
|
|
97
|
+
public_key = key_attr.lstrip('_')
|
|
98
|
+
class_dict[public_key] = attr_value
|
|
99
|
+
value = json.dumps(class_dict) # Serialize the dictionary to a JSON string
|
|
100
|
+
return self.flexCloud_manager.write(key.name, value)
|
|
101
|
+
|