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.
Files changed (53) hide show
  1. flexCommunicator/__init__.py +0 -0
  2. flexCommunicator/clientLibraries/__init__.py +0 -0
  3. flexCommunicator/clientLibraries/flcpy/__init__.py +0 -0
  4. flexCommunicator/clientLibraries/flcpy/action/__init__.py +0 -0
  5. flexCommunicator/clientLibraries/flcpy/action/action.py +85 -0
  6. flexCommunicator/clientLibraries/flcpy/action/action_client.py +70 -0
  7. flexCommunicator/clientLibraries/flcpy/action/goal_handle.py +50 -0
  8. flexCommunicator/clientLibraries/flcpy/codec/ROS2Codec.py +227 -0
  9. flexCommunicator/clientLibraries/flcpy/codec/__init__.py +0 -0
  10. flexCommunicator/clientLibraries/flcpy/commands/__init__.py +0 -0
  11. flexCommunicator/clientLibraries/flcpy/commands/commandProcessor.py +113 -0
  12. flexCommunicator/clientLibraries/flcpy/commands/composer.py +25 -0
  13. flexCommunicator/clientLibraries/flcpy/communication/CommunicationManager.py +579 -0
  14. flexCommunicator/clientLibraries/flcpy/communication/__init__.py +0 -0
  15. flexCommunicator/clientLibraries/flcpy/contracts/__init__.py +0 -0
  16. flexCommunicator/clientLibraries/flcpy/contracts/contractVariable.py +93 -0
  17. flexCommunicator/clientLibraries/flcpy/flexCloud/__init__.py +0 -0
  18. flexCommunicator/clientLibraries/flcpy/flexCloud/flexCloudConfiguration.py +16 -0
  19. flexCommunicator/clientLibraries/flcpy/flexCloud/flexCloudManager.py +162 -0
  20. flexCommunicator/clientLibraries/flcpy/flexCloud/flexCloudOrchestrator.py +248 -0
  21. flexCommunicator/clientLibraries/flcpy/flexCloud/flexCloudVariable.py +130 -0
  22. flexCommunicator/clientLibraries/flcpy/flexNode.py +892 -0
  23. flexCommunicator/clientLibraries/flcpy/fmi/__init__.py +0 -0
  24. flexCommunicator/clientLibraries/flcpy/fmi/fmuNode.py +166 -0
  25. flexCommunicator/clientLibraries/flcpy/fmi/node.py +360 -0
  26. flexCommunicator/clientLibraries/flcpy/knowledge/KnowledgeManager.py +288 -0
  27. flexCommunicator/clientLibraries/flcpy/knowledge/__init__.py +0 -0
  28. flexCommunicator/clientLibraries/flcpy/logging/LoggingAndTracking.py +159 -0
  29. flexCommunicator/clientLibraries/flcpy/logging/__init__.py +0 -0
  30. flexCommunicator/clientLibraries/flcpy/messages/StandardizedMessages.py +64 -0
  31. flexCommunicator/clientLibraries/flcpy/messages/__init__.py +0 -0
  32. flexCommunicator/clientLibraries/flcpy/node.py +486 -0
  33. flexCommunicator/clientLibraries/flcpy/security/__init__.py +0 -0
  34. flexCommunicator/clientLibraries/flcpy/security/security.py +189 -0
  35. flexCommunicator/clientLibraries/flcpy/service/__init__.py +0 -0
  36. flexCommunicator/clientLibraries/flcpy/service/client.py +58 -0
  37. flexCommunicator/clientLibraries/flcpy/service/service.py +67 -0
  38. flexCommunicator/clientLibraries/flcpy/transport/PropertyBinding.py +108 -0
  39. flexCommunicator/clientLibraries/flcpy/transport/PropertyRegistry.py +142 -0
  40. flexCommunicator/clientLibraries/flcpy/transport/__init__.py +0 -0
  41. flexCommunicator/clientLibraries/flcpy/utils/Timer.py +22 -0
  42. flexCommunicator/clientLibraries/flcpy/utils/__init__.py +0 -0
  43. flexCommunicator/clientLibraries/flcpy/utils/auxiliary.py +261 -0
  44. flexCommunicator/clientLibraries/flcpy/utils/constants.py +276 -0
  45. flexCommunicator/clientLibraries/flcpy/utils/decorators.py +70 -0
  46. flexCommunicator/clientLibraries/flcpy/validityFrame/__init__.py +0 -0
  47. flexCommunicator/clientLibraries/flcpy/validityFrame/runtimeMonitor.py +101 -0
  48. flexCommunicator/clientLibraries/flcpy/validityFrame/validityFrameManager.py +958 -0
  49. flexcommunicator-0.1.0.dist-info/METADATA +568 -0
  50. flexcommunicator-0.1.0.dist-info/RECORD +53 -0
  51. flexcommunicator-0.1.0.dist-info/WHEEL +5 -0
  52. flexcommunicator-0.1.0.dist-info/licenses/LICENSE +201 -0
  53. flexcommunicator-0.1.0.dist-info/top_level.txt +1 -0
File without changes
@@ -0,0 +1,166 @@
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
+ from flexCommunicator.clientLibraries.flcpy.fmi.node import *
10
+
11
+
12
+ class FMUNode(Node):
13
+ def __init__(self, name='tbd', description='tbd',stepsize=0.05, inports=None, outports=None, fmuPath=None, verbose=False):
14
+ super().__init__(name=name, description=description, inports=inports, outports=outports,stepSize=stepsize, verbose=verbose)
15
+ """Initialize a FMU node component.
16
+
17
+ Parameters
18
+ ----------
19
+ name : string
20
+ name of the node components
21
+
22
+ description : string
23
+ description of the node components
24
+
25
+ inports : list
26
+ inport list of the node components
27
+
28
+ outports : list
29
+ inport list of the node components
30
+
31
+ fmuPath : string
32
+ path to the FMU
33
+
34
+
35
+ verbose : bool
36
+ component verbose execution
37
+
38
+ See Also
39
+ --------
40
+ ..
41
+
42
+ Examples
43
+ --------
44
+ >> node = FMUNode(name="DUMMY_NODE_1", description='tbd', inports=[IN1_1], outports=[OUT1_1],fmuPath = "path/to/fmu", verbose=False)
45
+
46
+ """
47
+ self._inputList=[]
48
+ self._outputList = []
49
+ self._parameterList = []
50
+ # -- Functional mock-up unit (FMU) --
51
+ if fmuPath != None:
52
+ self._instantiateFMU(fmuPath)
53
+ x=1
54
+ # self._exposeFMUIO()
55
+ else:
56
+ self.model_description = None
57
+ self._fmu = None
58
+
59
+ @property
60
+ def FMU(self):
61
+ """The name property (read-only)."""
62
+ return self._fmu
63
+
64
+ # ------------------------------------------------------------------------------------------------------------------
65
+ # -------------------------------------------FMI INTEGRATION functions----------------------------------------------
66
+ # ------------------------------------------------------------------------------------------------------------------
67
+ def get_port_update(self,port):
68
+ try:
69
+ port.value = self._fmu.getReal([port.valueReference])[0]
70
+ return port
71
+ except:
72
+ return False
73
+
74
+
75
+
76
+ # ------------------------------------------------------------------------------------------------------------------
77
+ # --------------------------------------------FMU functions---------------------------------------------------------
78
+ # ------------------------------------------------------------------------------------------------------------------
79
+ def _instantiateFMU(self, path, startTime=0.0):
80
+ try:
81
+ from fmpy import read_model_description, extract
82
+ from fmpy.fmi2 import FMU2Slave
83
+ self.model_description = read_model_description(path)
84
+ # instantiate FMU
85
+ unzipdir = extract(path)
86
+ fmu = FMU2Slave(guid=self.model_description.guid, unzipDirectory=unzipdir,
87
+ modelIdentifier=self.model_description.coSimulation.modelIdentifier)
88
+ fmu.instantiate()
89
+ fmu.setupExperiment(startTime=startTime)
90
+ fmu.enterInitializationMode()
91
+ fmu.exitInitializationMode()
92
+ self._fmu = fmu
93
+ #determine the interface variables
94
+ for variable in self.model_description.modelVariables:
95
+ if variable.causality == 'input':
96
+ self._inputList.append([variable.name,variable.valueReference,variable.type,variable.start])
97
+ for input in self.inports:
98
+ if input.name == variable.name:
99
+ input.valueReference = variable.valueReference
100
+ elif variable.causality == 'output':
101
+ self._outputList.append([variable.name,variable.valueReference,variable.type,variable.start])
102
+ for output in self.outports:
103
+ if output.name == variable.name:
104
+ output.valueReference = variable.valueReference
105
+ elif variable.causality == 'parameter':
106
+ self._parameterList.append([variable.name,variable.valueReference,variable.type,variable.start])
107
+ #TODO: add the parameter components to be set!
108
+
109
+ except:
110
+ if self._verbose: print("FMU instantiation failed - No valid FMU found on path")
111
+ self._fmu = None
112
+
113
+ def getOutput(self, port):
114
+ if self._verbose:print("GetReal function - " + port.name)
115
+ port.value = self._fmu.getReal([port.valueReference])[0]
116
+
117
+ def setInput(self, port, value):
118
+ if self._verbose:print("SetReal function - " + port.name)
119
+ self._fmu.setReal([port.valueReference], [value])
120
+
121
+ def doStep(self, executionPattern=ExecutionPatterns.TRIGGERED):
122
+ if self._verbose:print("DoStep function - " + self.name)
123
+ self._fmu.doStep(currentCommunicationPoint=self._simTime, communicationStepSize=self._stepSize)
124
+ self._updateSimTime()
125
+
126
+
127
+ def info(self):
128
+ _info = self._compose_fmi_info()
129
+ return _info
130
+
131
+ def getInputs(self):
132
+ return self._inputList
133
+
134
+ def getOutputs(self):
135
+ return self._outputList
136
+
137
+ def getParameters(self):
138
+ return self._parameterList
139
+
140
+ def _compose_fmi_info(self):
141
+ # Collect general FMI info
142
+ _fmi_info = {
143
+ "model_Info": {
144
+ "FMI Version": self.model_description.fmiVersion,
145
+ "Model Name": self.model_description.coSimulation.modelIdentifier,
146
+ "Description": str(self.model_description.description),
147
+ "Continuous_States": str(self.model_description.numberOfContinuousStates),
148
+ "Event_Indicators": str(self.model_description.numberOfEventIndicators),
149
+ "Variables": str(len(self.model_description.modelVariables)),
150
+ "Generation Tool": self.model_description.generationTool,
151
+ "Generation Date": self.model_description.generationDateAndTime
152
+ },
153
+ "Variables": []
154
+ }
155
+
156
+ # Collect variables (only input/output)
157
+ for variable in self.model_description.modelVariables:
158
+ if variable.causality in ["output", "input"]:
159
+ _fmi_info["Variables"].append({
160
+ "Name": variable.name,
161
+ "Causality": variable.causality,
162
+ "StartValue": str(variable.start) if variable.start is not None else "-",
163
+ "Unit": variable.unit if variable.unit is not None else "-",
164
+ "Description": variable.description if variable.description is not None else "-"
165
+ })
166
+ return _fmi_info
@@ -0,0 +1,360 @@
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
+ from flexCommunicator.clientLibraries.flcpy.utils.constants import *
10
+ class Node(object):
11
+
12
+ def __init__(self, name='tbd',description='tbd',stepSize=0.05,inports=None,outports=None,doStepFunction = None,inputUpdateFunction = None,outputUpdateFunction = None,verbose=False):
13
+ """Initialize a generic node component.
14
+
15
+ Parameters
16
+ ----------
17
+ name : string
18
+ name of the node components
19
+
20
+ description : string
21
+ description of the node components
22
+
23
+ stepSize : double
24
+ stepsize of the node component
25
+
26
+ inports : list
27
+ inport list of the node components
28
+
29
+ outports : list
30
+ inport list of the node components
31
+
32
+ doStepFunction : function
33
+ doStepFuntion to overload standard function
34
+
35
+ inputUpdateFunction : function
36
+ inputUpdateFunction to overload standard function
37
+
38
+ outputUpdateFunction : function
39
+ outputUpdateFunction to overload standard function
40
+
41
+ verbose : bool
42
+ component verbose execution
43
+
44
+ See Also
45
+ --------
46
+ ..
47
+
48
+ Examples
49
+ --------
50
+ >> node = Node(name="DUMMY_NODE_1", description='tbd', inports=[IN1_1], outports=[OUT1_1], verbose=False)
51
+
52
+ """
53
+
54
+ self._name = name
55
+ self._description = description
56
+ if inports!=None:
57
+ self._inports=inports
58
+ else:
59
+ self._inports=[]
60
+ if outports != None:
61
+ self._outports = outports
62
+ else:
63
+ self._outports = []
64
+ self._verbose = verbose
65
+
66
+
67
+ #internal relations
68
+ self._internalRelations=[]
69
+
70
+ # -- function overloading --
71
+ if doStepFunction != None:
72
+ self._doStep = doStepFunction
73
+ if inputUpdateFunction != None:
74
+ self._inputUpdate = inputUpdateFunction
75
+ if outputUpdateFunction != None:
76
+ self._outputUpdate = outputUpdateFunction
77
+
78
+ # -- simulation node initialization
79
+ self._simTime = self._setSimTime(simConstants.startTime_Default)
80
+ self._stepSize = stepSize
81
+
82
+ @property
83
+ def name(self):
84
+ """The name property (read-only)."""
85
+ return self._name
86
+
87
+ @property
88
+ def description(self):
89
+ """The description property (read-only)."""
90
+ return self._description
91
+
92
+ @property
93
+ def inports(self):
94
+ """The inports list property (read)."""
95
+ return self._inports
96
+
97
+ @property
98
+ def outports(self):
99
+ """The outports list property (read)."""
100
+ return self._outports
101
+
102
+ @property
103
+ def internalRelations(self):
104
+ """The internal relations list property (read)."""
105
+ return self._internalRelations
106
+
107
+ @property
108
+ def simTime(self):
109
+ """The simtime property (read)."""
110
+ return self._simTime
111
+
112
+ def add_Port(self,port_for_adding):
113
+ """Add a single port `port_for_adding`
114
+
115
+ Parameters
116
+ ----------
117
+ relation_for_adding : Port
118
+ port node to be added
119
+
120
+
121
+ See Also
122
+ --------
123
+ ..
124
+
125
+ Examples
126
+ --------
127
+ >> todo:add example
128
+
129
+ """
130
+ if port_for_adding not in self._inports and port_for_adding not in self._outports:
131
+ if port_for_adding is None:
132
+ raise ValueError("Port cannot be added")
133
+ else:
134
+ if type(port_for_adding)=='Inport':
135
+ self._inports.append(port_for_adding)
136
+ elif type(port_for_adding)=='Outport':
137
+ self._outports.append(port_for_adding)
138
+ else:
139
+ raise ValueError("Port cannot be added")
140
+
141
+ def add_Relation(self,relation_for_adding):
142
+ """Add a single relation `relation_for_adding`
143
+
144
+ Parameters
145
+ ----------
146
+ relation_for_adding : Relation
147
+ Relation node to be added
148
+
149
+
150
+ See Also
151
+ --------
152
+ ..
153
+
154
+ Examples
155
+ --------
156
+ >> todo:add example
157
+
158
+ """
159
+ if relation_for_adding not in self._internalRelations:
160
+ if relation_for_adding is None:
161
+ raise ValueError("Internal relation cannot be added")
162
+ else:
163
+ self._internalRelations.append(relation_for_adding)
164
+
165
+
166
+ # ------------------------------------------------------------------------------------------------------------------
167
+ # ---------------------------------------LOCAL INTERFACE functions--------------------------------------------------
168
+ # ------------------------------------------------------------------------------------------------------------------
169
+ def inputUpdate(self):
170
+ if self._verbose:print("Input update for node: "+self.name)
171
+ # external function execution
172
+ self._inputUpdate()
173
+
174
+ def outputUpdate(self):
175
+ if self._verbose:print("Output update for node: "+self.name)
176
+ # external function execution
177
+ self._outputUpdate()
178
+
179
+
180
+
181
+ def doStep(self, executionPattern=ExecutionPatterns.TRIGGERED):
182
+ if executionPattern == ExecutionPatterns.TRIGGERED:
183
+ if self._verbose:print("doStep for node: "+self.name)
184
+ # external function execution
185
+ self._doStep()
186
+ elif executionPattern == ExecutionPatterns.IPO:
187
+ # (I)input
188
+ self.inputUpdate()
189
+ # (P)processing
190
+ if self._verbose:print("doStep for node: "+self.name)
191
+ # external function execution
192
+ self._doStep()
193
+ # (O)output
194
+ self.outputUpdate()
195
+ # update simulation time after execution
196
+ self._updateSimTime()
197
+
198
+ def _updateSimTime(self):
199
+ self._simTime += float(self._stepSize)
200
+
201
+ def _setSimTime(self, simTime):
202
+ self._simTime = simTime
203
+ return simTime
204
+
205
+ # ------------------------------------------------------------------------------------------------------------------
206
+ # -----------------------------------------EXECUTION functions------------------------------------------------------
207
+ # ------------------------------------------------------------------------------------------------------------------
208
+ def _inputUpdate(self):
209
+ if self._verbose: print("No user-defined function call provided for inputUpdate()")
210
+
211
+
212
+ def _outputUpdate(self):
213
+ if self._verbose: print("No user-defined function call provided for outputUpdate() - IN1 -> OUT1 for testing purposes")
214
+ # --- DUMMY BEHAVIOR FOR TESTING PURPOSE ---
215
+ self.outports[0].value = self.inports[0].value
216
+
217
+ def _doStep(self):
218
+ if self._verbose: print("No user-defined function call provided for doStep(), node behavior missing.")
219
+
220
+ class Port(object):
221
+
222
+ def __init__(self, name='tbd',description='tbd',initialValue = 1.0,valueReference=1,verbose=False):
223
+ """Initialize a port component.
224
+
225
+ Parameters
226
+ ----------
227
+ name : string
228
+ name of the port components
229
+
230
+ description : string
231
+ description of the port components
232
+
233
+ valueReference : int
234
+ valueReference of the port components (FMU-specific)
235
+
236
+ initialValue : string
237
+ initialValue of the port components
238
+
239
+
240
+ verbose : bool
241
+ component verbose execution
242
+
243
+ See Also
244
+ --------
245
+ ..
246
+
247
+ Examples
248
+ --------
249
+ >> port = Port(name="P1",description="description for P1",verbose=False)
250
+
251
+ """
252
+
253
+ self._name = name
254
+ self._description = description
255
+ self._value = initialValue
256
+ self._valueReference = valueReference
257
+ self._verbose = verbose
258
+
259
+
260
+
261
+ @property
262
+ def name(self):
263
+ """The name property (read-only)."""
264
+ return self._name
265
+
266
+ @property
267
+ def description(self):
268
+ """The description property (read-only)."""
269
+ return self._description
270
+
271
+ @property
272
+ def value(self):
273
+ """The value property (read)."""
274
+ return self._value
275
+
276
+ @value.setter
277
+ def value(self,value):
278
+ """The value property (write)."""
279
+ self._value = value
280
+
281
+ @property
282
+ def valueReference(self):
283
+ """The valueReference property (read)."""
284
+ return self._valueReference
285
+
286
+ @valueReference.setter
287
+ def valueReference(self, value):
288
+ """The valueReference property (write)."""
289
+ self._valueReference = value
290
+
291
+ class Inport(Port):
292
+
293
+ def __init__(self, name='tbd',description='tbd',reactive=False,verbose=False):
294
+ super().__init__(name=name, description=description, verbose=verbose)
295
+ """Initialize a port component.
296
+
297
+ Parameters
298
+ ----------
299
+ name : string
300
+ name of the port components
301
+
302
+ description : string
303
+ description of the port components
304
+
305
+ reactive : bool
306
+ reactive property of the inport
307
+
308
+ verbose : bool
309
+ component verbose execution
310
+
311
+ See Also
312
+ --------
313
+ ..
314
+
315
+ Examples
316
+ --------
317
+ >> port = Inport(name="P1",description="description for P1",reactive=False,verbose=False)
318
+
319
+ """
320
+
321
+ self._name = name
322
+ self._description = description
323
+ self._reactive=reactive
324
+ self._verbose = verbose
325
+
326
+ @property
327
+ def reactive(self):
328
+ """The reactive property (read-only)."""
329
+ return self._reactive
330
+
331
+ class Outport(Port):
332
+
333
+ def __init__(self, name='tbd', description='tbd', verbose=False):
334
+ super().__init__(name=name, description=description, verbose=verbose)
335
+ """Initialize a port component.
336
+
337
+ Parameters
338
+ ----------
339
+ name : string
340
+ name of the port components
341
+
342
+ description : string
343
+ description of the port components
344
+
345
+ verbose : bool
346
+ component verbose execution
347
+
348
+ See Also
349
+ --------
350
+ ..
351
+
352
+ Examples
353
+ --------
354
+ >> port = Outport(name="P1",description="description for P1",verbose=False)
355
+
356
+ """
357
+
358
+ self._name = name
359
+ self._description = description
360
+ self._verbose = verbose