rccn-gen 1.2.0__py3-none-any.whl → 1.3.1__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.
rccn_gen/utils.py
CHANGED
@@ -6,6 +6,22 @@ from yamcs.pymdb import IntegerArgument, FloatArgument, BooleanArgument, Enumera
|
|
6
6
|
|
7
7
|
|
8
8
|
def to_upper_camel_case(s):
|
9
|
+
"""
|
10
|
+
Convert a string to UpperCamelCase (PascalCase).
|
11
|
+
|
12
|
+
Converts the first letter to uppercase and capitalizes each word
|
13
|
+
after spaces or underscores, removing all non-alphanumeric characters.
|
14
|
+
|
15
|
+
Parameters:
|
16
|
+
-----------
|
17
|
+
s : str
|
18
|
+
The input string to convert.
|
19
|
+
|
20
|
+
Returns:
|
21
|
+
--------
|
22
|
+
str
|
23
|
+
The converted string in UpperCamelCase.
|
24
|
+
"""
|
9
25
|
if s[0].islower():
|
10
26
|
s = s[0].upper() + s[1:]
|
11
27
|
if ' ' in s or '_' in s:
|
@@ -14,12 +30,48 @@ def to_upper_camel_case(s):
|
|
14
30
|
return s
|
15
31
|
|
16
32
|
def to_snake_case(s):
|
33
|
+
"""
|
34
|
+
Convert a string to snake_case.
|
35
|
+
|
36
|
+
Inserts underscores before uppercase letters, converts the string to lowercase,
|
37
|
+
replaces non-alphanumeric characters with underscores, and eliminates consecutive underscores.
|
38
|
+
|
39
|
+
Parameters:
|
40
|
+
-----------
|
41
|
+
s : str
|
42
|
+
The input string to convert.
|
43
|
+
|
44
|
+
Returns:
|
45
|
+
--------
|
46
|
+
str
|
47
|
+
The converted string in snake_case.
|
48
|
+
"""
|
17
49
|
s = re.sub(r'(?<!^)(?=[A-Z])', '_', s).lower()
|
18
50
|
s = re.sub(r'[^a-zA-Z0-9_]', '_', s)
|
19
51
|
s = re.sub(r'__', '_', s)
|
20
52
|
return s
|
21
53
|
|
22
54
|
def replace_with_indentation(text, keyword, replacement):
|
55
|
+
"""
|
56
|
+
Replace a keyword in text while preserving the original indentation.
|
57
|
+
|
58
|
+
This function finds the indentation level of the line containing the keyword
|
59
|
+
and applies the same indentation to each line of the replacement text.
|
60
|
+
|
61
|
+
Parameters:
|
62
|
+
-----------
|
63
|
+
text : str
|
64
|
+
The original text containing the keyword.
|
65
|
+
keyword : str
|
66
|
+
The keyword to replace.
|
67
|
+
replacement : str
|
68
|
+
The replacement text.
|
69
|
+
|
70
|
+
Returns:
|
71
|
+
--------
|
72
|
+
str
|
73
|
+
The text with the keyword replaced by properly indented replacement text.
|
74
|
+
"""
|
23
75
|
lines = text.split('\n')
|
24
76
|
indent = 0
|
25
77
|
for line in lines:
|
@@ -29,6 +81,26 @@ def replace_with_indentation(text, keyword, replacement):
|
|
29
81
|
return text.replace(keyword, replacement.replace('\n', ('\n'+(indent*' '))))
|
30
82
|
|
31
83
|
def insert_before_with_indentation(text, keyword, replacement):
|
84
|
+
"""
|
85
|
+
Insert text before a keyword while preserving the original indentation.
|
86
|
+
|
87
|
+
This function finds the indentation level of the line containing the keyword
|
88
|
+
and applies the same indentation to each line of the text to be inserted.
|
89
|
+
|
90
|
+
Parameters:
|
91
|
+
-----------
|
92
|
+
text : str
|
93
|
+
The original text containing the keyword.
|
94
|
+
keyword : str
|
95
|
+
The keyword before which to insert text.
|
96
|
+
replacement : str
|
97
|
+
The text to insert before the keyword.
|
98
|
+
|
99
|
+
Returns:
|
100
|
+
--------
|
101
|
+
str
|
102
|
+
The text with the replacement inserted before the keyword with proper indentation.
|
103
|
+
"""
|
32
104
|
lines = text.split('\n')
|
33
105
|
indent = 0
|
34
106
|
for line in lines:
|
@@ -37,34 +109,146 @@ def insert_before_with_indentation(text, keyword, replacement):
|
|
37
109
|
return text.replace(keyword, (replacement.replace('\n', ('\n'+(indent*' ')))+keyword))
|
38
110
|
|
39
111
|
def get_keywords(text):
|
112
|
+
"""
|
113
|
+
Extract all keywords from a text.
|
114
|
+
|
115
|
+
Keywords are identified as text enclosed between double angle brackets.
|
116
|
+
For example: <<KEYWORD>>
|
117
|
+
|
118
|
+
Parameters:
|
119
|
+
-----------
|
120
|
+
text : str
|
121
|
+
The text to search for keywords.
|
122
|
+
|
123
|
+
Returns:
|
124
|
+
--------
|
125
|
+
list
|
126
|
+
A list of all keywords found in the text.
|
127
|
+
"""
|
40
128
|
pattern = r'<<.*?>>'
|
41
129
|
return re.findall(pattern, text)
|
42
130
|
|
43
131
|
def get_var_keywords(text):
|
132
|
+
"""
|
133
|
+
Extract variable keywords from a text.
|
134
|
+
|
135
|
+
Variable keywords are identified as text starting with <<VAR_ and ending with >>.
|
136
|
+
For example: <<VAR_NAME>>
|
137
|
+
|
138
|
+
Parameters:
|
139
|
+
-----------
|
140
|
+
text : str
|
141
|
+
The text to search for variable keywords.
|
142
|
+
|
143
|
+
Returns:
|
144
|
+
--------
|
145
|
+
list
|
146
|
+
A list of all variable keywords found in the text.
|
147
|
+
"""
|
44
148
|
pattern = r'<<VAR_.*?>>'
|
45
149
|
return re.findall(pattern, text)
|
46
150
|
|
47
151
|
def get_service_module_keywords(text):
|
152
|
+
"""
|
153
|
+
Extract service module keywords from a text.
|
154
|
+
|
155
|
+
Service module keywords are identified as text starting with <<SERVICE_MODULE_ and ending with >>.
|
156
|
+
For example: <<SERVICE_MODULE_NAME>>
|
157
|
+
|
158
|
+
Parameters:
|
159
|
+
-----------
|
160
|
+
text : str
|
161
|
+
The text to search for service module keywords.
|
162
|
+
|
163
|
+
Returns:
|
164
|
+
--------
|
165
|
+
list
|
166
|
+
A list of all service module keywords found in the text.
|
167
|
+
"""
|
48
168
|
pattern = r'<<SERVICE_MODULE_.*?>>'
|
49
169
|
return re.findall(pattern, text)
|
50
170
|
|
51
171
|
def get_command_module_keywords(text):
|
172
|
+
"""
|
173
|
+
Extract command module keywords from a text.
|
174
|
+
|
175
|
+
Command module keywords are identified as text starting with <<COMMAND_MODULE_ and ending with >>.
|
176
|
+
For example: <<COMMAND_MODULE_NAME>>
|
177
|
+
|
178
|
+
Parameters:
|
179
|
+
-----------
|
180
|
+
text : str
|
181
|
+
The text to search for command module keywords.
|
182
|
+
|
183
|
+
Returns:
|
184
|
+
--------
|
185
|
+
list
|
186
|
+
A list of all command module keywords found in the text.
|
187
|
+
"""
|
52
188
|
pattern = r'<<COMMAND_MODULE_.*?>>'
|
53
189
|
return re.findall(pattern, text)
|
54
190
|
|
55
191
|
def delete_all_keywords(text):
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
192
|
+
"""
|
193
|
+
Remove all keywords from a text.
|
194
|
+
|
195
|
+
Finds all text enclosed in double angle brackets and removes them.
|
196
|
+
|
197
|
+
Parameters:
|
198
|
+
-----------
|
199
|
+
text : str
|
200
|
+
The text containing keywords to be removed.
|
201
|
+
|
202
|
+
Returns:
|
203
|
+
--------
|
204
|
+
str
|
205
|
+
The text with all keywords removed.
|
206
|
+
"""
|
207
|
+
keywords = get_keywords(text)
|
208
|
+
for keyword in keywords:
|
209
|
+
text = text.replace(keyword, '')
|
210
|
+
return text
|
60
211
|
|
61
212
|
def delete_all_command_module_keywords(text):
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
213
|
+
"""
|
214
|
+
Remove all command module keywords from a text.
|
215
|
+
|
216
|
+
Finds all text starting with <<COMMAND_MODULE_ and enclosed in double angle brackets,
|
217
|
+
then removes them.
|
218
|
+
|
219
|
+
Parameters:
|
220
|
+
-----------
|
221
|
+
text : str
|
222
|
+
The text containing command module keywords to be removed.
|
223
|
+
|
224
|
+
Returns:
|
225
|
+
--------
|
226
|
+
str
|
227
|
+
The text with all command module keywords removed.
|
228
|
+
"""
|
229
|
+
keywords = get_command_module_keywords(text)
|
230
|
+
for keyword in keywords:
|
231
|
+
text = text.replace(keyword, '')
|
232
|
+
return text
|
66
233
|
|
67
234
|
def arg_type_to_rust(arg, bit_number_str='32'):
|
235
|
+
"""
|
236
|
+
Convert a pymdb argument type to its corresponding Rust type.
|
237
|
+
|
238
|
+
Maps different argument types from pymdb to their equivalent Rust data types.
|
239
|
+
|
240
|
+
Parameters:
|
241
|
+
-----------
|
242
|
+
arg : object
|
243
|
+
A pymdb argument object (IntegerArgument, FloatArgument, etc.)
|
244
|
+
bit_number_str : str, optional
|
245
|
+
Bit width for numeric types. Default is '32'.
|
246
|
+
|
247
|
+
Returns:
|
248
|
+
--------
|
249
|
+
str
|
250
|
+
The corresponding Rust type name, or None if the type is not supported.
|
251
|
+
"""
|
68
252
|
if isinstance(arg, IntegerArgument):
|
69
253
|
if arg.signed:
|
70
254
|
return 'i'+bit_number_str
|
@@ -83,6 +267,26 @@ def arg_type_to_rust(arg, bit_number_str='32'):
|
|
83
267
|
return None
|
84
268
|
|
85
269
|
def arg_enum_rust_definition(arg):
|
270
|
+
"""
|
271
|
+
Generate Rust enum definition from an EnumeratedArgument.
|
272
|
+
|
273
|
+
Creates a Rust enum definition with all choices from the enumerated argument.
|
274
|
+
|
275
|
+
Parameters:
|
276
|
+
-----------
|
277
|
+
arg : EnumeratedArgument
|
278
|
+
The enumerated argument to convert to a Rust enum definition.
|
279
|
+
|
280
|
+
Returns:
|
281
|
+
--------
|
282
|
+
str
|
283
|
+
A string containing the complete Rust enum definition.
|
284
|
+
|
285
|
+
Raises:
|
286
|
+
-------
|
287
|
+
ValueError
|
288
|
+
If the provided argument is not an EnumeratedArgument.
|
289
|
+
"""
|
86
290
|
if not isinstance(arg, EnumeratedArgument):
|
87
291
|
raise ValueError('Provided Argument is not of type EnumeratedArgument.')
|
88
292
|
definition_text = 'pub enum '+arg.name+' {\n'
|
@@ -92,23 +296,74 @@ def arg_enum_rust_definition(arg):
|
|
92
296
|
return definition_text
|
93
297
|
|
94
298
|
def engineering_bit_number(raw_bit_number):
|
299
|
+
"""
|
300
|
+
Calculate an appropriate engineering bit width based on a raw bit width.
|
301
|
+
|
302
|
+
Rounds up the raw bit width to the next power of 2, with a minimum of 8 bits.
|
303
|
+
|
304
|
+
Parameters:
|
305
|
+
-----------
|
306
|
+
raw_bit_number : int
|
307
|
+
The raw bit width (1-128).
|
308
|
+
|
309
|
+
Returns:
|
310
|
+
--------
|
311
|
+
int
|
312
|
+
The calculated engineering bit width (a power of 2, minimum 8).
|
313
|
+
|
314
|
+
Raises:
|
315
|
+
-------
|
316
|
+
ValueError
|
317
|
+
If raw_bit_number is not between 1 and 128.
|
318
|
+
"""
|
95
319
|
if raw_bit_number < 1 or raw_bit_number > 128:
|
96
320
|
raise ValueError("raw_bit_number must be between 1 and 128")
|
97
321
|
power = 1
|
98
322
|
while 2**power < raw_bit_number:
|
99
323
|
power += 1
|
100
324
|
bit_number = 2**power
|
325
|
+
if bit_number < 8:
|
326
|
+
bit_number = 8
|
101
327
|
return (bit_number)
|
102
328
|
|
103
329
|
def get_data_type(parent_classes):
|
104
|
-
"""
|
105
|
-
|
330
|
+
"""
|
331
|
+
Extract the data type from a list of parent class names.
|
332
|
+
|
333
|
+
Searches through a list of class names to find one ending with 'DataType'.
|
334
|
+
|
335
|
+
Parameters:
|
336
|
+
-----------
|
337
|
+
parent_classes : list
|
338
|
+
A list of class names to search through.
|
339
|
+
|
340
|
+
Returns:
|
341
|
+
--------
|
342
|
+
str or None
|
343
|
+
The name of the class ending with 'DataType', or None if none is found.
|
344
|
+
"""
|
106
345
|
for class_name in parent_classes:
|
107
346
|
if class_name.endswith('DataType'):
|
108
347
|
return class_name
|
109
348
|
return None
|
110
349
|
|
111
350
|
def get_base_type(parent_classes):
|
351
|
+
"""
|
352
|
+
Determine the base type from a list of parent class names.
|
353
|
+
|
354
|
+
Checks if the parent classes include common base types like Argument, Member,
|
355
|
+
Parameter, or DataType.
|
356
|
+
|
357
|
+
Parameters:
|
358
|
+
-----------
|
359
|
+
parent_classes : list
|
360
|
+
A list of class names to search through.
|
361
|
+
|
362
|
+
Returns:
|
363
|
+
--------
|
364
|
+
str or None
|
365
|
+
The base type name if found, or None if none of the target base types are found.
|
366
|
+
"""
|
112
367
|
for base_type in ["Argument", "Member", "Parameter"]:
|
113
368
|
if base_type in parent_classes:
|
114
369
|
return base_type
|
@@ -117,6 +372,32 @@ def get_base_type(parent_classes):
|
|
117
372
|
return None
|
118
373
|
|
119
374
|
def rust_type_definition(pymdb_data_instance, parent_name="MyStruct"):
|
375
|
+
"""
|
376
|
+
Generate Rust type definition code from a pymdb data instance.
|
377
|
+
|
378
|
+
This is the main function for converting pymdb data types to Rust code.
|
379
|
+
It analyzes the pymdb instance, determines its data type, and generates
|
380
|
+
appropriate Rust code including struct fields and necessary type definitions.
|
381
|
+
|
382
|
+
Parameters:
|
383
|
+
-----------
|
384
|
+
pymdb_data_instance : object
|
385
|
+
A pymdb data instance (Parameter, Argument, Member, etc.).
|
386
|
+
parent_name : str, optional
|
387
|
+
The name of the parent struct, used for inferring unnamed elements. Default is "MyStruct".
|
388
|
+
|
389
|
+
Returns:
|
390
|
+
--------
|
391
|
+
list
|
392
|
+
A list with two elements:
|
393
|
+
- [0]: The struct field definition including attributes
|
394
|
+
- [1]: Any supporting type definitions needed (like enums)
|
395
|
+
|
396
|
+
Raises:
|
397
|
+
-------
|
398
|
+
ValueError
|
399
|
+
If the data type cannot be determined or is not supported.
|
400
|
+
"""
|
120
401
|
parent_classes = list(map(lambda type: type.__name__, type(pymdb_data_instance).mro()))
|
121
402
|
data_type = get_data_type(parent_classes)
|
122
403
|
base_type = get_base_type(parent_classes)
|
@@ -136,6 +417,8 @@ def rust_type_definition(pymdb_data_instance, parent_name="MyStruct"):
|
|
136
417
|
definition_text = ["",""]
|
137
418
|
if pymdb_data_instance.short_description is not None:
|
138
419
|
definition_text[0] += ("\n\t/// "+str(pymdb_data_instance.short_description)+"\n")
|
420
|
+
|
421
|
+
# Handle IntegerDataType
|
139
422
|
if data_type == 'IntegerDataType':
|
140
423
|
if pymdb_data_instance.encoding is None or pymdb_data_instance.encoding.bits is None:
|
141
424
|
raw_bit_number = 8
|
@@ -151,12 +434,15 @@ def rust_type_definition(pymdb_data_instance, parent_name="MyStruct"):
|
|
151
434
|
else:
|
152
435
|
definition_text[0] += ("\tpub "+sc_instance_name+": u"+eng_bit_number_str+",\n")
|
153
436
|
|
437
|
+
# Handle BooleanDataType
|
154
438
|
elif data_type == 'BooleanDataType':
|
155
439
|
definition_text[0] += ("\t#[bits(1)]\n\tpub "+sc_instance_name+": bool,\n")
|
156
440
|
|
441
|
+
# Handle StringDataType
|
157
442
|
elif data_type == 'StringDataType':
|
158
443
|
definition_text[0] += "\t#[null_terminated]\n\tpub "+sc_instance_name+": String,\n"
|
159
444
|
|
445
|
+
# Handle ArrayDataType
|
160
446
|
elif data_type == 'ArrayDataType':
|
161
447
|
definition_text = rust_type_definition(pymdb_data_instance.data_type, parent_name=pymdb_data_instance.name)
|
162
448
|
definition_text[0] = definition_text[0].replace(': ', ': Vec<').replace(',\n', '>,\n')
|
@@ -165,6 +451,7 @@ def rust_type_definition(pymdb_data_instance, parent_name="MyStruct"):
|
|
165
451
|
if pymdb_data_instance.long_description is not None:
|
166
452
|
definition_text[1] = "/// "+pymdb_data_instance.long_description+"\n" + definition_text[1]
|
167
453
|
|
454
|
+
# Handle EnumeratedDataType
|
168
455
|
elif data_type == 'EnumeratedDataType':
|
169
456
|
definition_text[0] += "\t#[bits("+str(pymdb_data_instance.encoding.bits)+")]\n"
|
170
457
|
definition_text[0] += "\tpub "+pymdb_data_instance.name+": "+pascalcase(pymdb_data_instance.name)+",\n"
|
@@ -175,6 +462,7 @@ def rust_type_definition(pymdb_data_instance, parent_name="MyStruct"):
|
|
175
462
|
if pymdb_data_instance.long_description is not None:
|
176
463
|
definition_text[1] = "/// "+pymdb_data_instance.long_description+"\n" + definition_text[1]
|
177
464
|
|
465
|
+
# Handle AggregateDataType
|
178
466
|
elif data_type == 'AggregateDataType':
|
179
467
|
struct_name = pascalcase(pymdb_data_instance.name)
|
180
468
|
definition_text[0] += "\tpub "+sc_instance_name+": "+struct_name+",\n"
|
@@ -190,6 +478,28 @@ def rust_type_definition(pymdb_data_instance, parent_name="MyStruct"):
|
|
190
478
|
definition_text[1] += insert
|
191
479
|
definition_text[1] += "}\n\n"
|
192
480
|
definition_text[1] += append
|
481
|
+
|
482
|
+
# Handle FloatDataType
|
483
|
+
elif data_type == 'FloatDataType':
|
484
|
+
if pymdb_data_instance.encoding is None or pymdb_data_instance.encoding.bits is None:
|
485
|
+
raw_bit_number = 32
|
486
|
+
print("RCCN-Warning: No encoding for "+base_type+" "+pymdb_data_instance.name+" found. Using 32 as default for raw bit number.")
|
487
|
+
else:
|
488
|
+
raw_bit_number = pymdb_data_instance.encoding.bits
|
489
|
+
raw_bit_number_str = str(raw_bit_number)
|
490
|
+
if raw_bit_number == 32:
|
491
|
+
eng_bit_number = 32
|
492
|
+
elif raw_bit_number == 64:
|
493
|
+
eng_bit_number = 64
|
494
|
+
else:
|
495
|
+
print("RCCN-Warning: Given raw bit number for "+base_type+" \'"+pymdb_data_instance.name+"\' is not equal to 32 or 64. A engineering bit number of 64 will be used.")
|
496
|
+
eng_bit_number = 64
|
497
|
+
eng_bit_number_str = str(eng_bit_number)
|
498
|
+
definition_text[0] += "\t#[bits("+raw_bit_number_str+")]\n"
|
499
|
+
definition_text[0] += ("\tpub "+sc_instance_name+": f"+eng_bit_number_str+",\n")
|
500
|
+
|
501
|
+
# Handle unsupported data types
|
193
502
|
else:
|
194
503
|
definition_text = ["\t// Please implement datatype "+data_type+" here.\n", ""]
|
504
|
+
|
195
505
|
return definition_text
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: rccn_gen
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.3.1
|
4
4
|
Summary: A python based generator for RACCOON OS source files in Rust from yamcs-pymdb config files.
|
5
5
|
Project-URL: Homepage, https://gitlab.com/rccn/pymdb_code_generation
|
6
6
|
Project-URL: Issues, https://gitlab.com/rccn/pymdb_code_generation/issues
|
@@ -29,10 +29,11 @@ To see whats new, see the [CHANGELOG](CHANGELOG.md).
|
|
29
29
|
## Using the Generator
|
30
30
|
The generator is based on [`pymdb`](https://github.com/yamcs/pymdb) and uses the same structure. Where `pymdb` gives the user freedom in defining systems, subsystems and their respective relations, the definitions for rust code generation is more restricted. For the rust generation, the user is bound to the following classes:
|
31
31
|
- `Application`,
|
32
|
-
- `Service`,
|
33
|
-
- `RCCNCommand
|
32
|
+
- `Service`,
|
33
|
+
- `RCCNCommand`, and
|
34
|
+
- `RCCNContainer`.
|
34
35
|
|
35
|
-
|
36
|
+
The Application and Service classes inherit from pymdb's Subsystem class and extend their functionality. The RCCNCommand extends the Command class and the RCCNContainer extends the Container class of pymdb. This means that an existing pymdb definition can be used to generate rust code by renaming the respective instances. No functionality for pymdb's XTCE generation will be lost.
|
36
37
|
|
37
38
|
A root system may be defined for the satellite.
|
38
39
|
```python
|
@@ -44,7 +45,7 @@ An application can be defined with the following statement.
|
|
44
45
|
```python
|
45
46
|
app = Application(system=root_system, name="ExampleApp", apid=42)
|
46
47
|
```
|
47
|
-
It has the obligatory arguments **system**, **name
|
48
|
+
It has the obligatory arguments **system**, **name** and **apid**. After all Applications, Services and RCCNCommands are defined, the rust code generator can be called on the application with `app.generate_rccn_code(export_directory='.')`.
|
48
49
|
|
49
50
|
### Service
|
50
51
|
|
@@ -81,7 +82,7 @@ my_command = RCCNCommand(
|
|
81
82
|
service.add_command(my_command)
|
82
83
|
```
|
83
84
|
|
84
|
-
The only obligatory
|
85
|
+
The only obligatory argument is **name**. If the subtype assignment is not given, a value will be chosen automatically. The connection to a service can also be achieved with base commands, where every base command must be unique to a service. For example:
|
85
86
|
|
86
87
|
```python
|
87
88
|
base_cmd = RCCNCommand(
|
@@ -98,6 +99,34 @@ my_command = RCCNCommand(
|
|
98
99
|
)
|
99
100
|
```
|
100
101
|
|
102
|
+
### RCCNContainer
|
103
|
+
A container to hold telemetry information can be created with:
|
104
|
+
```python
|
105
|
+
my_container = RCCNContainer(
|
106
|
+
system=service,
|
107
|
+
name='BatteryInformation',
|
108
|
+
short_description='This container holds information on battery voltage and current'
|
109
|
+
)
|
110
|
+
my_container.add_integer_parameter_entry(
|
111
|
+
name='BatteryNumber',
|
112
|
+
minimum=1,
|
113
|
+
maximum=4,
|
114
|
+
encoding=IntegerEncoding(bits=3),
|
115
|
+
short_description='Number of the battery'
|
116
|
+
)
|
117
|
+
my_container.add_float_parameter_entry(
|
118
|
+
name='Current',
|
119
|
+
units='Ampere',
|
120
|
+
encoding=FloatEncoding(bits=32),
|
121
|
+
short_description='Electric current of the battery.'
|
122
|
+
)
|
123
|
+
my_container.add_float_parameter_entry(
|
124
|
+
name='Voltage',
|
125
|
+
units='Volts',
|
126
|
+
encoding=FloatEncoding(bits=32),
|
127
|
+
short_description='Electric voltage of the battery.'
|
128
|
+
)
|
129
|
+
```
|
101
130
|
## Output
|
102
131
|
From the python configuration, the `main.rs`, `service.rs`, `command.rs`, `mod.rs`, `Cargo.toml` and `telemetry.rs` files are generated and are structured accordingly:
|
103
132
|
- rccn_usr_example_app/
|
@@ -1,7 +1,7 @@
|
|
1
1
|
rccn_gen/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
|
2
2
|
rccn_gen/__init__.py,sha256=rBnqIw3uQk-uBbRh9VnungoTRSr2V0Bqos32xFZ44Eo,168
|
3
|
-
rccn_gen/systems.py,sha256=
|
4
|
-
rccn_gen/utils.py,sha256=
|
3
|
+
rccn_gen/systems.py,sha256=NewVHJVITt3svMBkAigD23Wl3_-srjNBbiMsOqUstg4,83907
|
4
|
+
rccn_gen/utils.py,sha256=q5YSmyc3qADNYcycxQJBvrG6Df8CJelL4lhXF-dN_Ms,17016
|
5
5
|
rccn_gen/text_modules/cargo_toml/cargo.txt,sha256=AYjSo3WJE7lhOcJaiNgXP9Y-DXHDIFIt6p42rDTVNVE,427
|
6
6
|
rccn_gen/text_modules/command/command.txt,sha256=8Y-uJilhFLoinftIbn7uKfia9LLMZno2LkoDJ-4Y-9M,345
|
7
7
|
rccn_gen/text_modules/command/command_module_enum.txt,sha256=35sBlAV_CzQw95Uf2dNynrYOxVD2tT2XWfEvS4Zx_KY,121
|
@@ -14,6 +14,6 @@ rccn_gen/text_modules/mod/mod.txt,sha256=BF8LablBE4ddutdl5m0prvpvLdBRejueVOujkyr
|
|
14
14
|
rccn_gen/text_modules/service/command_module_match_cmd.txt,sha256=eVGo6ltuerG37rVxpXtL-JYuLyLW4c0i6NXb5g1_U-A,89
|
15
15
|
rccn_gen/text_modules/service/service.txt,sha256=qTxoOD5i7wH4yFiDn13rOJW9hIZyACA8W3m6UABe22U,695
|
16
16
|
rccn_gen/text_modules/telemetry/telemetry.txt,sha256=Re1d3BfpyXT_CEe7jJzLF3MARik0-J-K98K85iPOE40,193
|
17
|
-
rccn_gen-1.
|
18
|
-
rccn_gen-1.
|
19
|
-
rccn_gen-1.
|
17
|
+
rccn_gen-1.3.1.dist-info/METADATA,sha256=xYy5MKpPdYKRgTCLHeabF2vOG_laMSP1NidCw5FiAeM,9911
|
18
|
+
rccn_gen-1.3.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
19
|
+
rccn_gen-1.3.1.dist-info/RECORD,,
|
File without changes
|