rccn-gen 1.0.0__py3-none-any.whl → 1.0.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/systems.py
CHANGED
@@ -16,6 +16,7 @@ class Application(Subsystem):
|
|
16
16
|
system: System,
|
17
17
|
name: str,
|
18
18
|
apid: int,
|
19
|
+
vcid: int = 0,
|
19
20
|
export_file_path = '.',
|
20
21
|
snapshot_file_path = './.rccn_snapshots',
|
21
22
|
diff_file_path = './.rccn_diffs',
|
@@ -26,12 +27,13 @@ class Application(Subsystem):
|
|
26
27
|
super().__init__(system=system, name=name, *args, **kwargs)
|
27
28
|
|
28
29
|
self.apid = apid
|
30
|
+
self.vcid = vcid
|
29
31
|
system._subsystems_by_name[name] = self
|
30
32
|
self.export_file_path = export_file_path
|
31
33
|
self.snapshot_file_path = snapshot_file_path
|
32
34
|
self.snapshot_generated_file_path = os.path.join(snapshot_file_path, 'auto_generated')
|
33
35
|
self.diff_file_path = diff_file_path
|
34
|
-
self.text_modules_path = files('
|
36
|
+
self.text_modules_path = files('rccn_gen').joinpath('text_modules')
|
35
37
|
print(self.text_modules_path)
|
36
38
|
self.text_modules_main_path = os.path.join(self.text_modules_path, 'main')
|
37
39
|
print(self.text_modules_main_path)
|
@@ -98,6 +100,7 @@ class Application(Subsystem):
|
|
98
100
|
# Find and replace service variable keywords
|
99
101
|
var_translation = {
|
100
102
|
'<<VAR_APID>>':str(self.apid),
|
103
|
+
'<<VAR_VCID>>':str(self.vcid),
|
101
104
|
'<<VAR_APP_NAME_SCASE>>':to_snake_case(self.name),
|
102
105
|
}
|
103
106
|
var_keywords = get_var_keywords(text)
|
@@ -197,7 +200,7 @@ class Service(Subsystem):
|
|
197
200
|
self.init_kwargs = kwargs
|
198
201
|
self.name = name
|
199
202
|
self.service_id = service_id
|
200
|
-
self.text_modules_path = files('
|
203
|
+
self.text_modules_path = files('rccn_gen').joinpath('text_modules')
|
201
204
|
self.text_modules_service_path = os.path.join(self.text_modules_path, 'service')
|
202
205
|
self.text_modules_command_path = os.path.join(self.text_modules_path, 'command')
|
203
206
|
self.text_modules_telemetry_path = os.path.join(self.text_modules_path, 'telemetry')
|
@@ -272,7 +275,7 @@ class Service(Subsystem):
|
|
272
275
|
|
273
276
|
# Call keyword replacement for all associated commands (Later, there needs to be checking to account for user changes to the generated files)
|
274
277
|
if len(self.rccn_commands()) == 0:
|
275
|
-
print('Service '+self.name+' does not have any commands associated with it.')
|
278
|
+
print('RCCN-Gen: Service '+self.name+' does not have any commands associated with it.')
|
276
279
|
for command in self.rccn_commands():
|
277
280
|
text = command.find_and_replace_keywords(text, text_modules_path)
|
278
281
|
|
@@ -323,7 +326,7 @@ class Service(Subsystem):
|
|
323
326
|
self.generate_snapshot('command', 'command_user_snapshot')
|
324
327
|
# Generate command.rs file
|
325
328
|
if len(self.rccn_commands()) == 0:
|
326
|
-
print('Service '+self.name+' has no implemented commands. Generation of command.rs file will be skipped.')
|
329
|
+
print('RCCN-Gen: Service '+self.name+' has no implemented commands. Generation of command.rs file will be skipped.')
|
327
330
|
return
|
328
331
|
command_file_path = self.file_paths()['command_template']
|
329
332
|
with open(command_file_path, 'r') as file:
|
@@ -5,18 +5,17 @@ use rccn_usr::zenoh::key_expr::OwnedKeyExpr;
|
|
5
5
|
<<SERVICE_MODULE_MOD_SERVICE>>
|
6
6
|
|
7
7
|
const APID: u16 = <<VAR_APID>>;
|
8
|
+
const VCID: u8 = <<VAR_VCID>>;
|
8
9
|
|
9
10
|
fn main() -> Result<()> {
|
10
11
|
env_logger::init();
|
11
12
|
let mut app = PusApp::new(APID);
|
12
13
|
|
13
14
|
app
|
14
|
-
.add_tc_tm_channel(
|
15
|
-
OwnedKeyExpr::new("vc/bus_realtime/rx").unwrap(),
|
16
|
-
OwnedKeyExpr::new("vc/bus_realtime/tx").unwrap(),
|
17
|
-
)
|
15
|
+
.add_tc_tm_channel(VCID)
|
18
16
|
.unwrap();
|
19
17
|
|
18
|
+
|
20
19
|
<<SERVICE_MODULE_REGISTER_SERVICE>>
|
21
20
|
|
22
21
|
app.run();
|
rccn_gen/utils.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import re
|
2
|
+
import inflect
|
2
3
|
import os
|
3
4
|
from yamcs.pymdb import IntegerArgument, FloatArgument, BooleanArgument, EnumeratedArgument, StringArgument
|
4
5
|
|
@@ -106,18 +107,36 @@ def get_data_type(parent_classes):
|
|
106
107
|
return class_name
|
107
108
|
return None
|
108
109
|
|
109
|
-
def
|
110
|
-
|
110
|
+
def get_base_type(parent_classes):
|
111
|
+
for base_type in ["Argument", "Member", "Parameter"]:
|
112
|
+
if base_type in parent_classes:
|
113
|
+
return base_type
|
114
|
+
if "DataType" in parent_classes:
|
115
|
+
return "DataType"
|
116
|
+
return None
|
117
|
+
|
118
|
+
def rust_type_definition(pymdb_data_instance, parent_name="MyStruct"):
|
111
119
|
parent_classes = list(map(lambda type: type.__name__, type(pymdb_data_instance).mro()))
|
112
120
|
data_type = get_data_type(parent_classes)
|
113
|
-
base_type =
|
121
|
+
base_type = get_base_type(parent_classes)
|
122
|
+
if base_type is None:
|
123
|
+
base_type = pymdb_data_instance.__class__.__name__
|
114
124
|
if data_type is None:
|
115
|
-
raise ValueError("Data type not found in parent classes.")
|
125
|
+
raise ValueError("RCCN-Gen: Data type not found in parent classes.")
|
126
|
+
if not hasattr(pymdb_data_instance, 'name') or pymdb_data_instance.name is None:
|
127
|
+
p = inflect.engine()
|
128
|
+
singular_name = p.singular_noun(parent_name)
|
129
|
+
if singular_name is False:
|
130
|
+
pymdb_data_instance.name = parent_name
|
131
|
+
else:
|
132
|
+
pymdb_data_instance.name = singular_name
|
133
|
+
print("RCCN-Gen: Information: An unnamed "+base_type+" has been named \""+to_upper_camel_case(pymdb_data_instance.name)+"\" in the generated RCCN code.")
|
134
|
+
sc_instance_name = to_snake_case(pymdb_data_instance.name)
|
116
135
|
|
117
136
|
if data_type == 'IntegerDataType':
|
118
137
|
if pymdb_data_instance.encoding is None or pymdb_data_instance.encoding.bits is None:
|
119
138
|
raw_bit_number = 8
|
120
|
-
print("Warning: No encoding for "+base_type+" "+pymdb_data_instance.name+" found. Using 8 as default for raw bit number.")
|
139
|
+
print("RCCN-Gen: Warning: No encoding for "+base_type+" "+pymdb_data_instance.name+" found. Using 8 as default for raw bit number.")
|
121
140
|
else:
|
122
141
|
raw_bit_number = pymdb_data_instance.encoding.bits
|
123
142
|
raw_bit_number_str = str(raw_bit_number)
|
@@ -127,7 +146,7 @@ def rust_type_definition(pymdb_data_instance):
|
|
127
146
|
if pymdb_data_instance.signed:
|
128
147
|
definition_text[0] += ("\tpub "+sc_instance_name+": i"+eng_bit_number_str+",\n")
|
129
148
|
else:
|
130
|
-
definition_text += ("\tpub "+sc_instance_name+": u"+eng_bit_number_str+",\n")
|
149
|
+
definition_text[0] += ("\tpub "+sc_instance_name+": u"+eng_bit_number_str+",\n")
|
131
150
|
definition_text.append("")
|
132
151
|
|
133
152
|
elif data_type == 'BooleanDataType':
|
@@ -138,14 +157,8 @@ def rust_type_definition(pymdb_data_instance):
|
|
138
157
|
definition_text = ["\t#[null_terminated]\n\tpub "+sc_instance_name+": String,\n", ""]
|
139
158
|
|
140
159
|
elif data_type == 'ArrayDataType':
|
141
|
-
|
142
|
-
definition_text = [
|
143
|
-
definition_text.append("pub struct "+struct_name+" {\n")
|
144
|
-
for member in pymdb_data_instance.data_type.members:
|
145
|
-
definition_text[1] += rust_type_definition(member)[0]
|
146
|
-
definition_text[1] += "}\n"
|
147
|
-
for member in pymdb_data_instance.data_type.members:
|
148
|
-
definition_text[1] += rust_type_definition(member)[1]
|
160
|
+
definition_text = rust_type_definition(pymdb_data_instance.data_type, parent_name=pymdb_data_instance.name)
|
161
|
+
definition_text[0] = definition_text[0].replace(': ', ': Vec<').replace(',\n', '>,\n')
|
149
162
|
|
150
163
|
elif data_type == 'EnumeratedDataType':
|
151
164
|
definition_text = ["\tpub "+pymdb_data_instance.name+": "+to_upper_camel_case(pymdb_data_instance.name)+",\n"]
|
@@ -154,6 +167,16 @@ def rust_type_definition(pymdb_data_instance):
|
|
154
167
|
definition_text[1] += "\t"+str(choice[1])+" = "+str(choice[0])+",\n"
|
155
168
|
definition_text[1] += "}\n"
|
156
169
|
|
170
|
+
elif data_type == 'AggregateDataType':
|
171
|
+
struct_name = to_upper_camel_case(pymdb_data_instance.name)
|
172
|
+
definition_text = ["\tpub "+sc_instance_name+": "+struct_name+",\n"]
|
173
|
+
definition_text.append("pub struct "+struct_name+" {\n")
|
174
|
+
for member in pymdb_data_instance.members:
|
175
|
+
definition_text[1] += rust_type_definition(member, parent_name=pymdb_data_instance.name)[0]
|
176
|
+
definition_text[1] += "}\n"
|
177
|
+
for member in pymdb_data_instance.members:
|
178
|
+
definition_text[1] += rust_type_definition(member, parent_name=pymdb_data_instance.name)[1]
|
179
|
+
|
157
180
|
else:
|
158
181
|
definition_text = ["\t// Please implement datatype "+data_type+" here.\n", ""]
|
159
182
|
return definition_text
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: rccn_gen
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.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
|
@@ -16,7 +16,7 @@ Description-Content-Type: text/markdown
|
|
16
16
|
This generator is used to generate Rust files to deploy on the RACCOON OS satellite based on the pymdb config files used to generate the ground station XTCE files.
|
17
17
|
## Setup
|
18
18
|
- Pull the repo
|
19
|
-
- Set up a virtual python environment with
|
19
|
+
- Set up a virtual python environment with `python3` and activate:
|
20
20
|
```zsh
|
21
21
|
python -m venv .venv
|
22
22
|
source .venv/bin/activate
|
@@ -24,10 +24,12 @@ This generator is used to generate Rust files to deploy on the RACCOON OS satell
|
|
24
24
|
- Install pymdb with `pip install yamcs-pymdb`
|
25
25
|
|
26
26
|
## Using the Generator
|
27
|
-
The generator is based on 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
|
27
|
+
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:
|
28
28
|
- Application,
|
29
29
|
- Service, and
|
30
|
-
-
|
30
|
+
- `Application`,
|
31
|
+
- `Service`, and
|
32
|
+
- `RCCNCommand`.
|
31
33
|
|
32
34
|
All classes inherit from pymdb's Subsystem class and extend their functionality. 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.
|
33
35
|
|
@@ -117,7 +119,7 @@ The sequence from above is changed accordingly if no previous snapshot exists. I
|
|
117
119
|
Snapshots of the .rs files in the export directory are stored in `/user/`. These can be used to undo code regeneration if conflicts arise during the patching. Please note that by default, only the last 10 user snapshots are stored. You can change this property with the following command.
|
118
120
|
|
119
121
|
```python
|
120
|
-
app.keep_snapshots = 15 #
|
122
|
+
app.keep_snapshots = 15 # Whatever value you want
|
121
123
|
```
|
122
124
|
|
123
125
|
With the sequence from above, it becomes apperant that changes to the .rs file in the export directory always trump changes to the pymdb config. If for example, a main.rs file is generated for an application with and APID of 42, and this apid is changed in the main.rs file to 45, this change will persist after regenerating from the python config. Even if changes to the pymdb config where made after the changes to the main.rs file.
|
@@ -2,14 +2,14 @@ rccn_gen/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
|
|
2
2
|
rccn_gen/__init__.py,sha256=XVvKYcWw9K1P3J1BTbzbODY71Nc1FApCc0wf7ezd4Gc,193
|
3
3
|
rccn_gen/application.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
4
|
rccn_gen/service.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
|
-
rccn_gen/systems.py,sha256=
|
5
|
+
rccn_gen/systems.py,sha256=oLm0_jcxV0MZ3Bg7YsCraQ_zTj_yD_geoQpdJs_ATys,26898
|
6
6
|
rccn_gen/telemetry.py,sha256=huVcqGs95IXlpETWdlIyR9lK4ctZUsq7czgJwvTYtBk,3855
|
7
|
-
rccn_gen/utils.py,sha256=
|
7
|
+
rccn_gen/utils.py,sha256=tBzL6ZCSpjYnz4vtV7vzIAT6lcemCtIqxrmWMtzPEZU,7302
|
8
8
|
rccn_gen/text_modules/cargo_toml/cargo.txt,sha256=2e6xKomkml6-onfQ0QHNqvKnhGLYMUl8zYgbykmm83Y,292
|
9
9
|
rccn_gen/text_modules/command/command.txt,sha256=8Y-uJilhFLoinftIbn7uKfia9LLMZno2LkoDJ-4Y-9M,345
|
10
10
|
rccn_gen/text_modules/command/command_module_enum.txt,sha256=ApzRDQIs-BHJHtFA4ysfpYuWElGntXakkzZkgy57b74,94
|
11
11
|
rccn_gen/text_modules/command/command_module_struct.txt,sha256=FT7Ke0uOVxWYpGC_oj9zafr1ahrH-nf0nSxQje6kToY,22
|
12
|
-
rccn_gen/text_modules/main/main.txt,sha256=
|
12
|
+
rccn_gen/text_modules/main/main.txt,sha256=UQ0oHbzH7H3G4mxfeiTh5UeQ-X4C0Fw7IrCyZNH2clQ,426
|
13
13
|
rccn_gen/text_modules/main/service_module_import_service.txt,sha256=qPrU4fLs7Y65X5KJ868ut-izV5pHq7hU2nVRLxPnFCE,57
|
14
14
|
rccn_gen/text_modules/main/service_module_mod_service.txt,sha256=guvXFdV_-YezhTD_PWA-Z0tL8ReSZc0rh3RuWraJnQE,25
|
15
15
|
rccn_gen/text_modules/main/service_module_register_service.txt,sha256=4EIsgaxDLh51u0WjXfy7Xgo-6UFTdb4Nh2O4J7uFjS0,115
|
@@ -17,6 +17,6 @@ rccn_gen/text_modules/mod/mod.txt,sha256=BF8LablBE4ddutdl5m0prvpvLdBRejueVOujkyr
|
|
17
17
|
rccn_gen/text_modules/service/command_module_match_cmd.txt,sha256=eVGo6ltuerG37rVxpXtL-JYuLyLW4c0i6NXb5g1_U-A,89
|
18
18
|
rccn_gen/text_modules/service/service.txt,sha256=0KwwrfrjXuY4e3VNpCdTTzgW8bmYRQ21i-Lvhkz3hVA,691
|
19
19
|
rccn_gen/text_modules/telemetry/telemetry.txt,sha256=Re1d3BfpyXT_CEe7jJzLF3MARik0-J-K98K85iPOE40,193
|
20
|
-
rccn_gen-1.0.
|
21
|
-
rccn_gen-1.0.
|
22
|
-
rccn_gen-1.0.
|
20
|
+
rccn_gen-1.0.1.dist-info/METADATA,sha256=dm4UtqPyzUKNv_hnmprPaSmQtRrjE-lCuU-X_O9wnHc,8193
|
21
|
+
rccn_gen-1.0.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
22
|
+
rccn_gen-1.0.1.dist-info/RECORD,,
|
File without changes
|