rccn-gen 1.3.2__py3-none-any.whl → 1.3.4__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
@@ -19,6 +19,8 @@ from yamcs.pymdb.parameters import (
19
19
  StringParameter
20
20
  )
21
21
  from yamcs.pymdb.commands import Command, CommandLevel, CommandEntry, Argument, TransmissionConstraint
22
+ import logging
23
+ logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
22
24
 
23
25
  class Application(Subsystem):
24
26
  """
@@ -162,13 +164,16 @@ class Application(Subsystem):
162
164
  A dictionary mapping file types to their absolute paths.
163
165
  """
164
166
  paths = {
165
- 'main': os.path.join(self.export_directory, 'rccn_usr_'+snakecase(self.name), 'src', 'main.rs'),
166
- 'main_generated_snapshot': os.path.join(self.snapshot_directory, 'generated', 'rccn_usr_'+snakecase(self.name), 'src', 'main.rs'),
167
- 'main_user_snapshot': os.path.join(self.user_snapshot_path(), 'rccn_usr_'+snakecase(self.name), 'src', 'main.rs'),
168
- 'main_diff': os.path.join(self.diff_directory, 'rccn_usr_'+snakecase(self.name), 'src', 'main.diff'),
167
+ 'main': os.path.join(self.export_directory, snakecase(self.name), 'src', 'main.rs'),
168
+ 'main_generated_snapshot': os.path.join(self.snapshot_directory, 'generated', snakecase(self.name), 'src', 'main.rs'),
169
+ 'main_user_snapshot': os.path.join(self.user_snapshot_path(), snakecase(self.name), 'src', 'main.rs'),
170
+ 'main_diff': os.path.join(self.diff_directory, snakecase(self.name), 'src', 'main.diff'),
169
171
  'main_template': os.path.join(self.text_modules_main_path, 'main.txt'),
170
- 'cargo_toml': os.path.join(self.export_directory, 'rccn_usr_'+snakecase(self.name), 'Cargo.toml'),
172
+ 'cargo_toml': os.path.join(self.export_directory, snakecase(self.name), 'Cargo.toml'),
171
173
  'cargo_toml_template': os.path.join(self.text_modules_path, 'cargo_toml', 'cargo.txt'),
174
+ 'cargo_toml_generated_snapshot': os.path.join(self.snapshot_directory, 'generated', snakecase(self.name), 'cargo.toml'),
175
+ 'cargo_toml_user_snapshot': os.path.join(self.user_snapshot_path(), snakecase(self.name), 'cargo.toml'),
176
+ 'cargo_toml_diff': os.path.join(self.diff_directory, snakecase(self.name), 'cargo.diff'),
172
177
  }
173
178
  return paths
174
179
 
@@ -201,7 +206,7 @@ class Application(Subsystem):
201
206
  Creates the necessary directory structure for the application and its services
202
207
  in the export directory.
203
208
  """
204
- app_src_dir = os.path.join(self.export_directory, 'rccn_usr_'+snakecase(self.name), 'src')
209
+ app_src_dir = os.path.join(self.export_directory, snakecase(self.name), 'src')
205
210
  if not os.path.exists(app_src_dir):
206
211
  os.makedirs(app_src_dir)
207
212
  for service in self.services():
@@ -230,9 +235,11 @@ class Application(Subsystem):
230
235
  # Generate main.rs file
231
236
  with open(self.file_paths()['main_template'], 'r') as file:
232
237
  main_template_text = file.read()
238
+ logging.debug(f"[{__class__.__name__}] {self.file_paths()['main_template']} read")
233
239
  with open(self.file_paths()['main'], 'w') as file:
234
240
  new_main_text = self.find_and_replace_keywords(main_template_text)
235
241
  file.write("".join(new_main_text))
242
+ logging.info(f"[{__class__.__name__}] {self.file_paths()['main']} written")
236
243
  # Create snapshot of newly generated main.rs if instructed
237
244
  if self.snapshots:
238
245
  self.generate_snapshot('main', 'main_generated_snapshot')
@@ -321,7 +328,7 @@ class Application(Subsystem):
321
328
  if not os.path.exists(service.file_paths()['mod']):
322
329
  service.generate_mod_file()
323
330
  service.generate_telemetry_file()
324
- service.generate_rccn_command_file(os.path.join(self.export_directory, 'rccn_usr_'+snakecase(self.name), 'src'), os.path.join(self.text_modules_path, 'command'))
331
+ service.generate_rccn_command_file(os.path.join(self.export_directory, snakecase(self.name), 'src'), os.path.join(self.text_modules_path, 'command'))
325
332
  self.delete_old_snapshots()
326
333
 
327
334
  def generate_snapshot(self, current_file_reference, snapshot_file_reference):
@@ -407,12 +414,34 @@ class Application(Subsystem):
407
414
 
408
415
  def generate_cargo_toml_file(self):
409
416
  """
410
- Generate the Cargo.toml file for the application.
417
+ Generate the cargo.toml file for the application.
418
+
419
+ Performs several tasks:
420
+ 1. Creates diff file if both current and snapshot files exist
421
+ 2. Creates snapshot of current main with user changes if snapshots are enabled
422
+ 3. Generates new cargo.toml file from template
423
+ 4. Creates snapshot of newly generated main if snapshots are enabled
424
+ 5. Applies user changes from diff file if rebase_changes is enabled
411
425
  """
426
+ # Create cargo_toml.diff file
427
+ if os.path.exists(self.file_paths()['cargo_toml']) and os.path.exists(self.file_paths()['cargo_toml_generated_snapshot']):
428
+ os.maked(os.path.dirname(self.file_paths()['cargo_toml_diff']), exist_ok=True)
429
+ self.generate_diff_file('cargo_toml', 'cargo_toml_generated_snapshot', 'cargo_toml_diff')
430
+ # Create snapshot of cargo_toml with user changes if instructed
431
+ if self.snapshots and os.path.exists(self.file_paths()['cargo_toml']):
432
+ self.generate_snapshot('cargo_toml', 'cargo_toml_user_snapshot')
433
+ # Generate cargo_toml file
412
434
  with open(self.file_paths()['cargo_toml_template'], 'r') as file:
413
435
  cargo_toml_template_text = file.read()
414
436
  with open(self.file_paths()['cargo_toml'], 'w') as file:
415
- file.write(cargo_toml_template_text)
437
+ new_cargo_toml_text = self.find_and_replace_keywords(cargo_toml_template_text)
438
+ file.write("".join(new_cargo_toml_text))
439
+ # Create snapshot of newly generated cargo_toml if instructed
440
+ if self.snapshots:
441
+ self.generate_snapshot('cargo_toml', 'cargo_toml_generated_snapshot')
442
+ # Rebase cargo_toml.diff on cargo_toml if instructed
443
+ if self.rebase_changes and os.path.exists(self.file_paths()['cargo_toml_diff']):
444
+ os.system('patch '+self.file_paths()['cargo_toml']+' < '+self.file_paths()['cargo_toml_diff'])
416
445
 
417
446
 
418
447
  class Service(Subsystem):
@@ -532,22 +561,22 @@ class Service(Subsystem):
532
561
  source files, generated snapshots, user snapshots, diff files, and templates.
533
562
  """
534
563
  paths = {
535
- 'service': os.path.join(self.export_directory, 'rccn_usr_'+snakecase(self.system.name), 'src', snakecase(self.name), 'service.rs'),
536
- 'service_generated_snapshot': os.path.join(self.snapshot_directory, 'generated', 'rccn_usr_'+snakecase(self.system.name), 'src', snakecase(self.name), 'service.rs'),
537
- 'service_user_snapshot': os.path.join(self.snapshot_directory, 'user', datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S"), 'rccn_usr_'+snakecase(self.system.name), 'src', snakecase(self.name), 'service.rs'),
538
- 'service_diff': os.path.join(self.diff_directory, 'rccn_usr_'+snakecase(self.system.name), 'src', snakecase(self.name), 'service.diff'),
564
+ 'service': os.path.join(self.export_directory, snakecase(self.system.name), 'src', snakecase(self.name), 'service.rs'),
565
+ 'service_generated_snapshot': os.path.join(self.snapshot_directory, 'generated', snakecase(self.system.name), 'src', snakecase(self.name), 'service.rs'),
566
+ 'service_user_snapshot': os.path.join(self.snapshot_directory, 'user', datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S"), snakecase(self.system.name), 'src', snakecase(self.name), 'service.rs'),
567
+ 'service_diff': os.path.join(self.diff_directory, snakecase(self.system.name), 'src', snakecase(self.name), 'service.diff'),
539
568
  'service_template': os.path.join(self.text_modules_service_path, 'service.txt'),
540
- 'command': os.path.join(self.export_directory, 'rccn_usr_'+snakecase(self.system.name), 'src', snakecase(self.name), 'command.rs'),
541
- 'command_generated_snapshot': os.path.join(self.snapshot_directory, 'generated', 'rccn_usr_'+snakecase(self.system.name), 'src', snakecase(self.name), 'command.rs'),
542
- 'command_user_snapshot': os.path.join(self.snapshot_directory, 'user', datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S"), 'rccn_usr_'+snakecase(self.system.name), 'src', snakecase(self.name), 'command.rs'),
543
- 'command_diff': os.path.join(self.diff_directory, 'rccn_usr_'+snakecase(self.system.name), 'src', snakecase(self.name), 'command.diff'),
569
+ 'command': os.path.join(self.export_directory, snakecase(self.system.name), 'src', snakecase(self.name), 'command.rs'),
570
+ 'command_generated_snapshot': os.path.join(self.snapshot_directory, 'generated', snakecase(self.system.name), 'src', snakecase(self.name), 'command.rs'),
571
+ 'command_user_snapshot': os.path.join(self.snapshot_directory, 'user', datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S"), snakecase(self.system.name), 'src', snakecase(self.name), 'command.rs'),
572
+ 'command_diff': os.path.join(self.diff_directory, snakecase(self.system.name), 'src', snakecase(self.name), 'command.diff'),
544
573
  'command_template': os.path.join(self.text_modules_command_path, 'command.txt'),
545
- 'mod': os.path.join(self.export_directory, 'rccn_usr_'+snakecase(self.system.name), 'src', snakecase(self.name), 'mod.rs'),
574
+ 'mod': os.path.join(self.export_directory, snakecase(self.system.name), 'src', snakecase(self.name), 'mod.rs'),
546
575
  'mod_template': os.path.join(self.text_modules_path, 'mod', 'mod.txt'),
547
- 'telemetry': os.path.join(self.export_directory, 'rccn_usr_'+snakecase(self.system.name), 'src', snakecase(self.name), 'telemetry.rs'),
548
- 'telemetry_generated_snapshot': os.path.join(self.snapshot_directory, 'generated', 'rccn_usr_'+snakecase(self.system.name), 'src', snakecase(self.name), 'telemetry.rs'),
549
- 'telemetry_user_snapshot': os.path.join(self.snapshot_directory, 'user', datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S"), 'rccn_usr_'+snakecase(self.system.name), 'src', snakecase(self.name), 'command.rs'),
550
- 'telemetry_diff': os.path.join(self.diff_directory, 'rccn_usr_'+snakecase(self.system.name), 'src', snakecase(self.name), 'telemetry.diff'),
576
+ 'telemetry': os.path.join(self.export_directory, snakecase(self.system.name), 'src', snakecase(self.name), 'telemetry.rs'),
577
+ 'telemetry_generated_snapshot': os.path.join(self.snapshot_directory, 'generated', snakecase(self.system.name), 'src', snakecase(self.name), 'telemetry.rs'),
578
+ 'telemetry_user_snapshot': os.path.join(self.snapshot_directory, 'user', datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S"), snakecase(self.system.name), 'src', snakecase(self.name), 'command.rs'),
579
+ 'telemetry_diff': os.path.join(self.diff_directory, snakecase(self.system.name), 'src', snakecase(self.name), 'telemetry.diff'),
551
580
  'telemetry_template': os.path.join(self.text_modules_telemetry_path, 'telemetry.txt'),
552
581
  }
553
582
  return paths
@@ -605,6 +634,10 @@ class Service(Subsystem):
605
634
  for command in self.rccn_commands():
606
635
  text = command.find_and_replace_keywords(text, text_modules_path)
607
636
 
637
+ containers = self.rccn_container()
638
+ cnames = [c.name for c in containers]
639
+ telemetries = ", ".join(cnames)
640
+
608
641
  # Find and replace service variable keywords
609
642
  var_keywords = get_var_keywords(text)
610
643
  service_var_translation = {
@@ -612,6 +645,7 @@ class Service(Subsystem):
612
645
  '<<VAR_SERVICE_ID>>': lambda: str(self.service_id),
613
646
  '<<VAR_SERVICE_NAME_UCASE>>': lambda: pascalcase(self.name),
614
647
  '<<VAR_SERVICE_TELEMETRY>>': lambda: self.generate_rust_telemetry_definition(),
648
+ '<<VAR_IMPORTS_TELEMETRIES>>' : lambda: "use super::{command" + ("};" if len(containers) == 0 else ", telemetry};"),
615
649
  }
616
650
  for var_keyword in var_keywords:
617
651
  if var_keyword in service_var_translation.keys():
@@ -644,6 +678,7 @@ class Service(Subsystem):
644
678
  service_template_file_text = file.read()
645
679
  with open(self.file_paths()['service'], 'w') as file:
646
680
  file.write(self.find_and_replace_keywords(service_template_file_text, self.text_modules_service_path))
681
+ logging.info(f"[{__class__.__name__}] {self.file_paths()['service']} written")
647
682
  # Create snapshot of service.rs if instructed
648
683
  if self.snapshots:
649
684
  self.generate_snapshot('service', 'service_generated_snapshot')
@@ -678,7 +713,7 @@ class Service(Subsystem):
678
713
  self.generate_snapshot('command', 'command_user_snapshot')
679
714
  # Generate command.rs file
680
715
  if len(self.rccn_commands()) == 0:
681
- print('RCCN-Information: Service \''+self.name+'\' has no commands other than base command. Generation of command.rs file will be skipped.')
716
+ logging.debug(f'[{__class__.__name__}] RCCN-Information: Service \''+self.name+'\' has no commands other than base command. Generation of command.rs file will be skipped.')
682
717
  return
683
718
  command_file_path = self.file_paths()['command_template']
684
719
  with open(command_file_path, 'r') as file:
@@ -686,6 +721,7 @@ class Service(Subsystem):
686
721
  command_export_directory = os.path.join(export_file_dir, snakecase(self.name), 'command.rs')
687
722
  with open(command_export_directory, 'w') as file:
688
723
  file.write(self.find_and_replace_keywords(command_file_text, text_modules_path))
724
+ logging.info(f"[{__class__.__name__}] {command_export_directory} written")
689
725
  # Create snapshot of command.rs if instructed
690
726
  if self.snapshots:
691
727
  self.generate_snapshot('command', 'command_generated_snapshot')
@@ -762,6 +798,7 @@ class Service(Subsystem):
762
798
  telemetry_template_file_text = file.read()
763
799
  with open(self.file_paths()['telemetry'], 'w') as file:
764
800
  file.write(self.find_and_replace_keywords(telemetry_template_file_text, self.text_modules_telemetry_path))
801
+ logging.info(f"[{__class__.__name__}] {self.file_paths()['telemetry']} written")
765
802
  # Create snapshot of telemetry.rs if instructed
766
803
  if self.snapshots:
767
804
  self.generate_snapshot('telemetry', 'telemetry_generated_snapshot')
@@ -886,6 +923,7 @@ class RCCNCommand(Command):
886
923
  long_description: str | None = None,
887
924
  extra: Mapping[str, str] | None = None,
888
925
  abstract: bool = False,
926
+ specify_target_telemetry: str = None,
889
927
  base: Command | str | None = None,
890
928
  assignments: Mapping[str, Any] | None = None,
891
929
  arguments: Sequence[Argument] | None = None,
@@ -914,6 +952,8 @@ class RCCNCommand(Command):
914
952
  Arbitrary information about the command, keyed by name.
915
953
  abstract : bool, optional
916
954
  Whether this command is abstract. Default is False.
955
+ specify_target_telemetry : str, optional
956
+ Specify target telemetry that this command is supposed to request.
917
957
  base : Command | str, optional
918
958
  The base command or reference to a base command.
919
959
  assignments : Mapping[str, Any], optional
@@ -949,6 +989,7 @@ class RCCNCommand(Command):
949
989
  'constraint': constraint,
950
990
  **kwargs
951
991
  }
992
+ self.target_telemetry = specify_target_telemetry
952
993
  if 'system' in kwargs and isinstance(kwargs['system'], Service):
953
994
  self.add_to_service(kwargs['system'])
954
995
  elif base and (isinstance(base, Command) or isinstance(base, RCCNCommand)):
@@ -975,7 +1016,7 @@ class RCCNCommand(Command):
975
1016
  - The command's APID is automatically set to match the service's application APID
976
1017
  """
977
1018
  if self.init_kwargs['base'] is None and not any(command.name == 'base' for command in service.commands):
978
- print("RCCN-Information: Command \'"+self.init_kwargs['name']+"\' doesn\'t have a base argument and no base command was found in service \'"+service.name+"\'.\nStandard base command will be created with system = \'"+service.name+"\' and type = "+str(service.service_id)+".")
1019
+ logging.debug(f"[{__class__.__name__}] RCCN-Information: Command \'"+self.init_kwargs['name']+"\' doesn\'t have a base argument and no base command was found in service \'"+service.name+"\'.\nStandard base command will be created with system = \'"+service.name+"\' and type = "+str(service.service_id)+".")
979
1020
  self.init_kwargs['base'] = Command(
980
1021
  system=service,
981
1022
  name='base',
@@ -984,7 +1025,7 @@ class RCCNCommand(Command):
984
1025
  assignments={'type': service.service_id}
985
1026
  )
986
1027
  elif self.init_kwargs['base'] is None and any(command.name == 'base' for command in service.commands):
987
- print("RCCN-Information: Command \'"+self.init_kwargs['name']+"\' doesn\'t have a \'base\' argument. Existing base command for service \'"+service.name+"\' will be used.")
1028
+ logging.debug(f"[{__class__.__name__}] RCCN-Information: Command \'"+self.init_kwargs['name']+"\' doesn\'t have a \'base\' argument. Existing base command for service \'"+service.name+"\' will be used.")
988
1029
  self.init_kwargs['base'] = next(command for command in service.commands if command.name == 'base')
989
1030
  if 'system' in self.init_kwargs and isinstance(self.init_kwargs['system'], Service):
990
1031
  super().__init__(*self.init_args, **self.init_kwargs)
@@ -996,12 +1037,13 @@ class RCCNCommand(Command):
996
1037
  new_subtype = 1
997
1038
  while new_subtype in used_subtypes:
998
1039
  new_subtype = new_subtype + 1
999
- print('RCCN-Information: Command \''+self.name+'\' has no subtype specified. Subtype will be set to '+str(new_subtype)+'.')
1040
+ logging.debug(f'[{__class__.__name__}] RCCN-Information: Command \''+self.name+'\' has no subtype specified. Subtype will be set to '+str(new_subtype)+'.')
1000
1041
  self.assignments['subtype'] = new_subtype
1001
- self.struct_name = self.name + 'Args'
1042
+ if len(self.arguments) != 0:
1043
+ self.struct_name = self.name + 'Args'
1002
1044
 
1003
1045
 
1004
- def find_and_replace_keywords(self, text, text_modules_path):
1046
+ def find_and_replace_keywords(self, text, text_modules_path): # , service : Service):
1005
1047
  """
1006
1048
  Replace template keywords with actual command values.
1007
1049
 
@@ -1040,15 +1082,24 @@ class RCCNCommand(Command):
1040
1082
  replacement_text = (self.find_and_replace_keywords(module_text, text_modules_path) + '\n')
1041
1083
  text = insert_before_with_indentation(text, command_module_keyword, replacement_text)
1042
1084
 
1085
+ cmd_requests_tm = (self.target_telemetry is not None)
1086
+
1043
1087
  # Find and replace command variable keywords
1044
1088
  command_var_keywords = get_var_keywords(text)
1045
1089
  command_var_translation = {
1046
1090
  '<<VAR_COMMAND_NAME_UCASE>>': lambda: pascalcase(self.name),
1091
+ '<<VAR_ARGS>>' : lambda: "(args)" if len(self.arguments) != 0 else "",
1092
+ '<<VAR_HANDLER_FUNCTION>>' : lambda: "tc.handle_with_tm" if cmd_requests_tm else "tc.handle",
1047
1093
  '<<VAR_COMMAND_NAME>>': lambda: self.name,
1048
- '<<VAR_COMMAND_STRUCT_NAME>>': lambda: self.struct_name,
1094
+ '<<VAR_COMMAND_STRUCT_NAME>>': lambda: f"({self.struct_name})" if len(self.arguments) != 0 else '',
1049
1095
  '<<VAR_COMMAND_SUBTYPE>>': lambda: str(self.assignments['subtype']),
1050
1096
  '<<VAR_COMMAND_STRUCT>>': lambda: self.struct_definition(),
1051
- '<<VAR_SHORT_DESCRIPTION>>': lambda: "\n/// " + self.short_description if self.short_description is not None else "",
1097
+ '<<VAR_SHORT_DESCRIPTION>>': lambda: "// " + self.short_description if self.short_description is not None else "No short description provided",
1098
+ '<<VAR_INFO_TEXT>>' : lambda: "User functionality missing in" if not cmd_requests_tm else "Returning default telemetry from",
1099
+ '<<VAR_RETURN_TYPE>>' : lambda : "if false { return Err(()); }" if cmd_requests_tm else "return false;",
1100
+ '<<VAR_RETURN_TARGET_TM_TEMPLATE>>' : lambda : "" if not cmd_requests_tm else \
1101
+ f"\nlet mut tm = telemetry::{self.target_telemetry}::default();\n" \
1102
+ f"\nOk(tm)",
1052
1103
  }
1053
1104
  for command_var_keyword in command_var_keywords:
1054
1105
  if command_var_keyword in command_var_translation.keys():
@@ -1223,16 +1274,17 @@ class RCCNContainer(Container):
1223
1274
  if eq_expression.ref == self.base+'/subtype':
1224
1275
  condition_subtype = eq_expression.value
1225
1276
  if condition_type is not None and condition_type != self.type:
1226
- print('RCCN-Warning: Container '+self.name+' has a user-defined type of '+str(eq_expression.value)+', which does\'nt match the service ID. User-defined type will be used.')
1277
+ logging.debug(f'[{__class__.__name__}] RCCN-Warning: Container '+self.name+' has a user-defined type of '+str(eq_expression.value)+', which doesn\'t match the service ID. User-defined type will be used.')
1227
1278
  self.type = condition_type
1228
1279
  if condition_subtype is not None and self.subtype is not None and condition_subtype != self.subtype:
1229
- print('RCCN-Warning: Container '+self.name+' has an ambiguous user-defined subtype. \'subtype\' argument should match the \'condition\' argument.')
1280
+ logging.debug(f'[{__class__.__name__}] RCCN-Warning: Container '+self.name+' has an ambiguous user-defined subtype. \'subtype\' argument should match the \'condition\' argument.')
1230
1281
  elif condition_subtype is not None:
1231
1282
  self.subtype = condition_subtype
1232
1283
  elif self.subtype is not None and self.init_kwargs['condition'] is not None:
1233
1284
  self.init_kwargs['condition'] = AndExpression(
1234
1285
  EqExpression(self.base+'/type', self.type),
1235
- EqExpression(self.base+'/subtype', self.subtype)
1286
+ EqExpression(self.base+'/subtype', self.subtype),
1287
+ EqExpression('/PUS/ccsds/apid', service.system.apid)
1236
1288
  )
1237
1289
  else:
1238
1290
  used_subtypes = [container.subtype for container in service.rccn_container()]
@@ -1242,9 +1294,10 @@ class RCCNContainer(Container):
1242
1294
  self.subtype = new_subtype
1243
1295
  self.init_kwargs['condition'] = AndExpression(
1244
1296
  EqExpression(self.base+'/type', self.type),
1245
- EqExpression(self.base+'/subtype', self.subtype)
1297
+ EqExpression(self.base+'/subtype', self.subtype),
1298
+ EqExpression('/PUS/ccsds/apid', service.system.apid)
1246
1299
  )
1247
- print('RCCN-Information: Subtype for Container '+self.name+' is not specified through \'subtype\' or \'condition\' arguments. Subtype will be set to '+str(self.subtype)+'.')
1300
+ logging.debug(f'[{__class__.__name__}] RCCN-Information: Subtype for Container '+self.name+' is not specified through \'subtype\' or \'condition\' arguments. Subtype will be set to '+str(self.subtype)+'.')
1248
1301
 
1249
1302
  if 'system' in self.init_kwargs and isinstance(self.init_kwargs['system'], Service):
1250
1303
  super().__init__(**self.init_kwargs)
@@ -1269,7 +1322,7 @@ class RCCNContainer(Container):
1269
1322
  rccn_telemetry_text = ""
1270
1323
  if hasattr(self, 'short_description') and self.short_description is not None:
1271
1324
  rccn_telemetry_text += "/// "+str(self.short_description)+"\n"
1272
- rccn_telemetry_text += "#[derive(ServiceTelemetry, BitStruct, Debug)]\n"
1325
+ rccn_telemetry_text += "#[derive(ServiceTelemetry, BitStruct, Debug, Default)]\n"
1273
1326
  if hasattr(self, 'subtype') and self.subtype is not None:
1274
1327
  rccn_telemetry_text += "#[subtype("+str(self.subtype)+")]\n"
1275
1328
  rccn_telemetry_text += "pub struct " + self.name + " {\n"
@@ -1,7 +1,7 @@
1
1
  [package]
2
- name = "rccn_usr_example_app"
2
+ name = "<<VAR_APP_NAME_SCASE>>"
3
3
  version = "0.1.0"
4
- edition = "2021"
4
+ edition = "2024"
5
5
 
6
6
  [dependencies]
7
7
  anyhow = "1.0.91"
@@ -14,4 +14,7 @@ spacepackets = "0.12.0"
14
14
  tokio = "1.41.1"
15
15
  env_logger = { version = "0.11.7", default-features = false, features = ["color", "humantime"] }
16
16
  num-derive = "0.4"
17
- num-traits = "0.2"
17
+ num-traits = "0.2"
18
+ rccn_usr_bitstruct_derive = { version = "0.1.0", path = "../rccn_usr_bitstruct_derive" }
19
+ rccn_usr_pus_macros = { version = "0.1.0", path = "../rccn_usr_pus_macros" }
20
+ chrono = "0.4.40"
@@ -5,6 +5,7 @@ use rccn_usr_pus_macros::ServiceCommand;
5
5
 
6
6
  #[derive(ServiceCommand)]
7
7
  pub enum Command {
8
+
8
9
  <<COMMAND_MODULE_ENUM>>
9
10
  }
10
11
 
@@ -1,3 +1,3 @@
1
1
  <<VAR_SHORT_DESCRIPTION>>
2
2
  #[subservice(<<VAR_COMMAND_SUBTYPE>>)]
3
- <<VAR_COMMAND_NAME_UCASE>>(<<VAR_COMMAND_STRUCT_NAME>>),
3
+ <<VAR_COMMAND_NAME_UCASE>><<VAR_COMMAND_STRUCT_NAME>>,
@@ -1,3 +1,5 @@
1
- command::Command::<<VAR_COMMAND_NAME_UCASE>>(args) => tc.handle(|| {
2
-
1
+ command::Command::<<VAR_COMMAND_NAME_UCASE>><<VAR_ARGS>> => <<VAR_HANDLER_FUNCTION>>(|| {
2
+ <<VAR_SHORT_DESCRIPTION>>
3
+ println!("[ INFO ] <<VAR_INFO_TEXT>> <<VAR_COMMAND_NAME_UCASE>><<VAR_ARGS>>.");
4
+ <<VAR_RETURN_TYPE>><<VAR_RETURN_TARGET_TM_TEMPLATE>>
3
5
  }),
@@ -1,6 +1,6 @@
1
1
  use std::process::Command;
2
2
  use rccn_usr::service::{AcceptanceResult, AcceptedTc, PusService};
3
- use super::command;
3
+ <<VAR_IMPORTS_TELEMETRIES>>
4
4
  use anyhow::Result;
5
5
  use std::error::Error;
6
6
  use chrono::Local;
@@ -8,6 +8,7 @@ use std::fs;
8
8
 
9
9
 
10
10
  pub struct <<VAR_SERVICE_NAME_UCASE>> {
11
+ // tm_parameter
11
12
  }
12
13
 
13
14
 
@@ -1,14 +1,14 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rccn_gen
3
- Version: 1.3.2
3
+ Version: 1.3.4
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
7
- Author-email: Fabian Krech <f.krech@tu-berlin.de>
7
+ Author-email: Fabian Krech <f.krech@tu-berlin.de>, Alexander Balke <a.balke@tu-berlin.de>
8
8
  License-Expression: GPL-3.0
9
9
  Classifier: Operating System :: OS Independent
10
10
  Classifier: Programming Language :: Python :: 3
11
- Requires-Python: >=3.8
11
+ Requires-Python: >=3.12
12
12
  Requires-Dist: case-converter>=1.2.0
13
13
  Requires-Dist: inflect>=7.5.0
14
14
  Requires-Dist: yamcs-pymdb>=0.1.0
@@ -1,19 +1,19 @@
1
1
  rccn_gen/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
2
2
  rccn_gen/__init__.py,sha256=rBnqIw3uQk-uBbRh9VnungoTRSr2V0Bqos32xFZ44Eo,168
3
- rccn_gen/systems.py,sha256=vaagjFcQX3PmnylEdi0ThfS_JkBHlIuguUu6VLfn5DE,83907
3
+ rccn_gen/systems.py,sha256=Xqx2g3UzE-gQ5DwbNuLrx3ZfjNUq3h5F0Y-9m2y6zFU,87838
4
4
  rccn_gen/utils.py,sha256=q5YSmyc3qADNYcycxQJBvrG6Df8CJelL4lhXF-dN_Ms,17016
5
- rccn_gen/text_modules/cargo_toml/cargo.txt,sha256=AYjSo3WJE7lhOcJaiNgXP9Y-DXHDIFIt6p42rDTVNVE,427
6
- rccn_gen/text_modules/command/command.txt,sha256=8Y-uJilhFLoinftIbn7uKfia9LLMZno2LkoDJ-4Y-9M,345
7
- rccn_gen/text_modules/command/command_module_enum.txt,sha256=35sBlAV_CzQw95Uf2dNynrYOxVD2tT2XWfEvS4Zx_KY,121
5
+ rccn_gen/text_modules/cargo_toml/cargo.txt,sha256=9PMrwfTLsAaL3d7CZKm8g8c2cwye4vnLuk8rym5yddY,613
6
+ rccn_gen/text_modules/command/command.txt,sha256=EcHdAQHebEEsIjVodN2V8Nm9xMVocjDkWmi_3teG57o,350
7
+ rccn_gen/text_modules/command/command_module_enum.txt,sha256=u6mrsiYDMHqZlnED3PfM1PlYyWPlagQSn-79mUeUnnk,119
8
8
  rccn_gen/text_modules/command/command_module_struct.txt,sha256=FT7Ke0uOVxWYpGC_oj9zafr1ahrH-nf0nSxQje6kToY,22
9
9
  rccn_gen/text_modules/main/main.txt,sha256=t8lAYNCgxY8XHHGt8lVeZC103O1YLEY82UoTZ2U7S2I,446
10
10
  rccn_gen/text_modules/main/service_module_import_service.txt,sha256=BYPvt2VrTV4yjt7SSAPYKzvQOBIqeDQsMzgzTQ8XmZY,62
11
11
  rccn_gen/text_modules/main/service_module_mod_service.txt,sha256=guvXFdV_-YezhTD_PWA-Z0tL8ReSZc0rh3RuWraJnQE,25
12
12
  rccn_gen/text_modules/main/service_module_register_service.txt,sha256=4EIsgaxDLh51u0WjXfy7Xgo-6UFTdb4Nh2O4J7uFjS0,115
13
13
  rccn_gen/text_modules/mod/mod.txt,sha256=BF8LablBE4ddutdl5m0prvpvLdBRejueVOujkyrLe7I,52
14
- rccn_gen/text_modules/service/command_module_match_cmd.txt,sha256=eVGo6ltuerG37rVxpXtL-JYuLyLW4c0i6NXb5g1_U-A,89
15
- rccn_gen/text_modules/service/service.txt,sha256=qTxoOD5i7wH4yFiDn13rOJW9hIZyACA8W3m6UABe22U,695
14
+ rccn_gen/text_modules/service/command_module_match_cmd.txt,sha256=vXsVba96eIzzn1ZYy5p7oxn3QIDzuW6lkxx1T7IANbU,264
15
+ rccn_gen/text_modules/service/service.txt,sha256=kxjIhDO4_cMxVyz8jpvXzoLC5dnSGWkxPQIjnKVdHx0,719
16
16
  rccn_gen/text_modules/telemetry/telemetry.txt,sha256=Re1d3BfpyXT_CEe7jJzLF3MARik0-J-K98K85iPOE40,193
17
- rccn_gen-1.3.2.dist-info/METADATA,sha256=AZYmynW8QvCwT83y5LzL3d9ynFHX8LT9Dc9YVlN6Nns,9911
18
- rccn_gen-1.3.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
19
- rccn_gen-1.3.2.dist-info/RECORD,,
17
+ rccn_gen-1.3.4.dist-info/METADATA,sha256=Gh6s1Lpyn4IdGQuaVEHDEJ70Iu-w6ETM4jiBVL05sqU,9952
18
+ rccn_gen-1.3.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
19
+ rccn_gen-1.3.4.dist-info/RECORD,,