powertrain-build 1.13.1__py3-none-any.whl → 1.13.3.dev3__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 (132) hide show
  1. powertrain_build/__init__.py +40 -40
  2. powertrain_build/__main__.py +6 -6
  3. powertrain_build/a2l.py +582 -582
  4. powertrain_build/a2l_merge.py +650 -650
  5. powertrain_build/a2l_templates.py +717 -717
  6. powertrain_build/build.py +985 -985
  7. powertrain_build/build_defs.py +309 -309
  8. powertrain_build/build_proj_config.py +690 -690
  9. powertrain_build/check_interface.py +575 -575
  10. powertrain_build/cli.py +141 -141
  11. powertrain_build/config.py +542 -542
  12. powertrain_build/core.py +395 -395
  13. powertrain_build/core_dummy.py +343 -343
  14. powertrain_build/create_conversion_table.py +73 -73
  15. powertrain_build/dids.py +916 -916
  16. powertrain_build/dummy.py +157 -157
  17. powertrain_build/dummy_spm.py +252 -252
  18. powertrain_build/environmentcheck.py +52 -52
  19. powertrain_build/ext_dbg.py +255 -255
  20. powertrain_build/ext_var.py +327 -327
  21. powertrain_build/feature_configs.py +301 -301
  22. powertrain_build/gen_allsysteminfo.py +227 -227
  23. powertrain_build/gen_label_split.py +449 -449
  24. powertrain_build/handcode_replacer.py +124 -124
  25. powertrain_build/html_report.py +133 -133
  26. powertrain_build/interface/__init__.py +4 -4
  27. powertrain_build/interface/application.py +511 -511
  28. powertrain_build/interface/base.py +500 -500
  29. powertrain_build/interface/csp_api.py +490 -490
  30. powertrain_build/interface/device_proxy.py +677 -677
  31. powertrain_build/interface/ems.py +67 -67
  32. powertrain_build/interface/export_global_vars.py +121 -121
  33. powertrain_build/interface/generate_adapters.py +132 -132
  34. powertrain_build/interface/generate_hi_interface.py +87 -87
  35. powertrain_build/interface/generate_service.py +69 -69
  36. powertrain_build/interface/generate_wrappers.py +147 -147
  37. powertrain_build/interface/generation_utils.py +142 -142
  38. powertrain_build/interface/hal.py +194 -194
  39. powertrain_build/interface/model_yaml_verification.py +348 -348
  40. powertrain_build/interface/service.py +296 -296
  41. powertrain_build/interface/simulink.py +249 -249
  42. powertrain_build/interface/update_call_sources.py +180 -180
  43. powertrain_build/interface/update_model_yaml.py +186 -186
  44. powertrain_build/interface/zone_controller.py +362 -362
  45. powertrain_build/lib/__init__.py +4 -4
  46. powertrain_build/lib/helper_functions.py +127 -127
  47. powertrain_build/lib/logger.py +55 -55
  48. powertrain_build/matlab_scripts/CodeGen/BuildAutomationPyBuild.m +78 -78
  49. powertrain_build/matlab_scripts/CodeGen/Generate_A2L.m +154 -154
  50. powertrain_build/matlab_scripts/CodeGen/generateTLUnit.m +239 -239
  51. powertrain_build/matlab_scripts/CodeGen/getAsilClassification.m +28 -28
  52. powertrain_build/matlab_scripts/CodeGen/modelConfiguredForTL.m +28 -28
  53. powertrain_build/matlab_scripts/CodeGen/moveDefOutports.m +88 -88
  54. powertrain_build/matlab_scripts/CodeGen/parseCalMeasData.m +410 -410
  55. powertrain_build/matlab_scripts/CodeGen/parseCoreIdentifiers.m +139 -139
  56. powertrain_build/matlab_scripts/CodeGen/parseDIDs.m +141 -141
  57. powertrain_build/matlab_scripts/CodeGen/parseInPorts.m +106 -106
  58. powertrain_build/matlab_scripts/CodeGen/parseIncludeConfigs.m +25 -25
  59. powertrain_build/matlab_scripts/CodeGen/parseModelInfo.m +38 -38
  60. powertrain_build/matlab_scripts/CodeGen/parseNVM.m +81 -81
  61. powertrain_build/matlab_scripts/CodeGen/parseOutPorts.m +120 -120
  62. powertrain_build/matlab_scripts/CodeGen/parsePreProcBlks.m +23 -23
  63. powertrain_build/matlab_scripts/CodeGen/struct2JSON.m +128 -128
  64. powertrain_build/matlab_scripts/CodeGen/updateCodeSwConfig.m +31 -31
  65. powertrain_build/matlab_scripts/Init_PyBuild.m +91 -91
  66. powertrain_build/matlab_scripts/__init__.py +2 -2
  67. powertrain_build/matlab_scripts/helperFunctions/Get_Full_Name.m +46 -46
  68. powertrain_build/matlab_scripts/helperFunctions/Get_SrcLines.m +12 -12
  69. powertrain_build/matlab_scripts/helperFunctions/Init_Models.m +78 -78
  70. powertrain_build/matlab_scripts/helperFunctions/Init_Projects.m +67 -67
  71. powertrain_build/matlab_scripts/helperFunctions/Read_Units.m +34 -34
  72. powertrain_build/matlab_scripts/helperFunctions/SetProjectTimeSamples.m +26 -26
  73. powertrain_build/matlab_scripts/helperFunctions/Strip_Suffix.m +16 -16
  74. powertrain_build/matlab_scripts/helperFunctions/followLink.m +118 -118
  75. powertrain_build/matlab_scripts/helperFunctions/getCodeSwitches.m +50 -50
  76. powertrain_build/matlab_scripts/helperFunctions/getConsumerBlocks.m +30 -30
  77. powertrain_build/matlab_scripts/helperFunctions/getDefBlock.m +39 -39
  78. powertrain_build/matlab_scripts/helperFunctions/getDefOutport.m +58 -58
  79. powertrain_build/matlab_scripts/helperFunctions/getDstBlocks.m +19 -19
  80. powertrain_build/matlab_scripts/helperFunctions/getDstLines.m +13 -13
  81. powertrain_build/matlab_scripts/helperFunctions/getInterfaceSignals.m +37 -37
  82. powertrain_build/matlab_scripts/helperFunctions/getName.m +37 -37
  83. powertrain_build/matlab_scripts/helperFunctions/getPath.m +6 -6
  84. powertrain_build/matlab_scripts/helperFunctions/getProperValue.m +21 -21
  85. powertrain_build/matlab_scripts/helperFunctions/getSrcBlocks.m +19 -19
  86. powertrain_build/matlab_scripts/helperFunctions/getSrcLines.m +13 -13
  87. powertrain_build/matlab_scripts/helperFunctions/loadLibraries.m +10 -10
  88. powertrain_build/matlab_scripts/helperFunctions/loadjson.m +6 -6
  89. powertrain_build/matlab_scripts/helperFunctions/modifyEnumStructField.m +21 -21
  90. powertrain_build/matlab_scripts/helperFunctions/removeConfigDuplicates.m +31 -31
  91. powertrain_build/matlab_scripts/helperFunctions/sortSystemByClass.m +26 -26
  92. powertrain_build/matlab_scripts/helperFunctions/tl_getfast.m +89 -89
  93. powertrain_build/matlab_scripts/helperFunctions/topLevelSystem.m +20 -20
  94. powertrain_build/matlab_scripts/helperFunctions/updateModels.m +131 -131
  95. powertrain_build/memory_section.py +224 -224
  96. powertrain_build/nvm_def.py +729 -729
  97. powertrain_build/problem_logger.py +86 -86
  98. powertrain_build/pt_matlab.py +430 -430
  99. powertrain_build/pt_win32.py +144 -144
  100. powertrain_build/replace_compu_tab_ref.py +105 -105
  101. powertrain_build/rte_dummy.py +254 -254
  102. powertrain_build/sched_funcs.py +209 -207
  103. powertrain_build/signal.py +7 -7
  104. powertrain_build/signal_if_html_rep.py +221 -221
  105. powertrain_build/signal_if_html_rep_all.py +302 -302
  106. powertrain_build/signal_incons_html_rep.py +180 -180
  107. powertrain_build/signal_incons_html_rep_all.py +366 -366
  108. powertrain_build/signal_incons_html_rep_base.py +168 -168
  109. powertrain_build/signal_inconsistency_check.py +641 -641
  110. powertrain_build/signal_interfaces.py +864 -864
  111. powertrain_build/templates/Index_SigCheck_All.html +22 -22
  112. powertrain_build/templates/Index_SigIf_All.html +19 -19
  113. powertrain_build/types.py +218 -218
  114. powertrain_build/unit_configs.py +419 -419
  115. powertrain_build/user_defined_types.py +660 -660
  116. powertrain_build/versioncheck.py +66 -66
  117. powertrain_build/wrapper.py +512 -512
  118. powertrain_build/xlrd_csv.py +87 -87
  119. powertrain_build/zone_controller/__init__.py +4 -4
  120. powertrain_build/zone_controller/calibration.py +176 -176
  121. powertrain_build/zone_controller/composition_yaml.py +880 -878
  122. {powertrain_build-1.13.1.dist-info → powertrain_build-1.13.3.dev3.dist-info}/METADATA +100 -100
  123. powertrain_build-1.13.3.dev3.dist-info/RECORD +130 -0
  124. {powertrain_build-1.13.1.dist-info → powertrain_build-1.13.3.dev3.dist-info}/WHEEL +1 -1
  125. {powertrain_build-1.13.1.dist-info → powertrain_build-1.13.3.dev3.dist-info}/licenses/LICENSE +202 -202
  126. powertrain_build-1.13.3.dev3.dist-info/pbr.json +1 -0
  127. powertrain_build-1.13.1.dist-info/RECORD +0 -130
  128. powertrain_build-1.13.1.dist-info/pbr.json +0 -1
  129. {powertrain_build-1.13.1.dist-info → powertrain_build-1.13.3.dev3.dist-info}/entry_points.txt +0 -0
  130. {powertrain_build-1.13.1.dist-info → powertrain_build-1.13.3.dev3.dist-info}/licenses/AUTHORS +0 -0
  131. {powertrain_build-1.13.1.dist-info → powertrain_build-1.13.3.dev3.dist-info}/licenses/NOTICE +0 -0
  132. {powertrain_build-1.13.1.dist-info → powertrain_build-1.13.3.dev3.dist-info}/top_level.txt +0 -0
@@ -1,296 +1,296 @@
1
- # Copyright 2024 Volvo Car Corporation
2
- # Licensed under Apache 2.0.
3
-
4
- """Module for handling the Service abstraction."""
5
-
6
-
7
- import re
8
-
9
- from powertrain_build.interface.base import filter_signals
10
- from powertrain_build.interface.csp_api import CspApi
11
- from powertrain_build.interface.application import get_internal_domain
12
- from powertrain_build.lib import logger
13
-
14
- LOGGER = logger.create_logger("service")
15
-
16
-
17
- def get_service(app, client_name, interface):
18
- """Get service implementation specification"""
19
- rasters = app.get_rasters()
20
- LOGGER.debug("Rasters: %s", rasters)
21
- translation_files = app.get_translation_files()
22
-
23
- sfw = ServiceFramework(app)
24
- sfw.filter = f"{client_name}_internal"
25
- sfw.name = f"{client_name}_{interface}"
26
- sfw.parse_definition(translation_files)
27
- internal = get_internal_domain(rasters)
28
- properties_from_json = [
29
- {"destination": "min", "source": "min", "default": "-"},
30
- {"destination": "max", "source": "max", "default": "-"},
31
- {"destination": "variable_type", "source": "type"},
32
- {"destination": "offset", "source": "offset", "default": "-"},
33
- {"destination": "factor", "source": "lsb", "default": 1},
34
- {"destination": "description", "source": "description"},
35
- {"destination": "unit", "source": "unit", "default": "-"},
36
- ]
37
- for raster in rasters:
38
- external_signals = filter_signals(raster.insignals, internal)
39
- sfw.add_signals(
40
- external_signals,
41
- "insignals",
42
- properties_from_json,
43
- )
44
- sfw.add_signals(raster.outsignals, "outsignals", properties_from_json)
45
- return sfw.to_model(interface)
46
-
47
-
48
- def get_service_list(app):
49
- """Get service list from app
50
-
51
- Args:
52
- app (Application): Pybuild project
53
-
54
- Returns:
55
- (str): a string containing the translated service list
56
- """
57
- translation_map = app.get_service_mapping()
58
- cmake = ''
59
- for proxy, service in translation_map.items():
60
- lib = re.sub('-', '_', service + '_lib' + proxy + '_service_proxy').upper()
61
- include = re.sub('-', '_', service + '_include_dir').upper()
62
- cmake += f"LIST(APPEND extra_libraries ${{{lib}}})\n"
63
- cmake += f"LIST(APPEND EXTRA_INCLUDE_DIRS ${{{include}}})\n"
64
- return cmake
65
-
66
-
67
- class ServiceFramework(CspApi):
68
- """Service Framework abstraction layer"""
69
-
70
- def __repr__(self):
71
- """String representation of SWFL"""
72
- return (
73
- f"<SWFL {self.name}"
74
- f" app_side insignals: {len(self.signal_names['app']['insignals'])}"
75
- f" app_side outsignals: {len(self.signal_names['app']['outsignals'])}>"
76
- )
77
-
78
- def get_map_file(self):
79
- """Get service translation map file
80
-
81
- Returns:
82
- (Path): service translation map file
83
- """
84
- return self.base_application.get_services_file()
85
-
86
- def get_map(self):
87
- """Get service translation map
88
-
89
- Returns:
90
- (dict): service translation map
91
- """
92
- return self.base_application.get_service_mapping()
93
-
94
- def check_endpoints(self):
95
- """Check and crash if signal endpoint contains both produces and consumes signals."""
96
- endpoints = {}
97
- for signal_name, signal_specs in self.translations.items():
98
- if signal_name in self.signal_names["app"]['insignals']:
99
- consumed = True
100
- elif signal_name in self.signal_names["app"]['outsignals']:
101
- consumed = False
102
- else:
103
- continue
104
- for signal_spec in signal_specs:
105
- endpoint = signal_spec[self.position.endpoint.value]
106
- api = signal_spec[self.position.api.value]
107
- key = (api, endpoint)
108
- if key not in endpoints:
109
- endpoints[key] = {
110
- "consumed": consumed,
111
- "signals": set()
112
- }
113
- endpoints[key]["signals"].add(signal_name)
114
- assert consumed == endpoints[key]["consumed"], \
115
- f"Signal endpoint {endpoint} for {api} contains both consumed and produced signals"
116
-
117
- def extract_endpoint_definitions(self, raw):
118
- """Extract endpoint definitions from yaml file.
119
-
120
- Args:
121
- raw (dict): Raw yaml file
122
- Returns:
123
- (dict): Endpoint definitions
124
- """
125
- self.parse_api_definitions(raw.get("service", {}))
126
-
127
- @staticmethod
128
- def extract_definition(definition):
129
- """Extract definition from yaml file.
130
- Returns the properties and methods for a service.
131
-
132
- Args:
133
- definition (dict): Definition from yaml file
134
- Returns:
135
- (dict): Specifications for a service
136
- """
137
- specifications = {}
138
- specifications['properties'] = definition.get('properties', [])
139
- specifications['methods'] = definition.get('methods', [])
140
- return specifications
141
-
142
- def to_model(self, client):
143
- """Method to generate dict to be saved as yaml
144
- Args:
145
- client (str): Name of the client in signal comm
146
- Returns:
147
- spec (dict): Signal model for using a service
148
- """
149
- properties, types = self.properties_service_model(client)
150
- descriptions = {
151
- 'internal': {
152
- 'brief': "Internal interface for associated application.",
153
- 'full': "This interface should only be used by the associated application."
154
- },
155
- 'external': {
156
- 'brief': "External interface.",
157
- 'full': "This interface should be used by modules wanting to interact with the associated application."
158
- },
159
- 'observer': {
160
- 'brief': "Read-only interface.",
161
- 'full': "This interface can be used by anyone wanting information from the associated application."
162
- },
163
- }
164
- model = {"name": self.name,
165
- "version": "${SERVICE_VERSION}",
166
- "description": descriptions[client],
167
- "properties": properties,
168
- "types": types}
169
- return model
170
-
171
- def properties_service_model(self, client):
172
- """Generate properties and types for a service
173
-
174
- Args:
175
- client (str): Name of the client in signal comm
176
-
177
- Returns:
178
- (list): List of properties
179
- (list): List of types
180
- """
181
- properties = {}
182
- types = {}
183
- accessors = {}
184
- if client == 'internal':
185
- accessors['insignals'] = 'r-'
186
- accessors['outsignals'] = '-w'
187
- elif client == 'external':
188
- accessors['insignals'] = '-w'
189
- accessors['outsignals'] = 'r-'
190
- else:
191
- accessors['insignals'] = 'r-'
192
- accessors['outsignals'] = 'r-'
193
-
194
- properties_in, types_in = self._properties_service_model(
195
- self.signal_names["app"]["insignals"],
196
- accessors['insignals'])
197
- properties_out, types_out = self._properties_service_model(
198
- self.signal_names["app"]["outsignals"],
199
- accessors['outsignals'])
200
-
201
- properties = properties_in + properties_out
202
- types = types_in + types_out
203
- return properties, types
204
-
205
- def _specifications(self, signal_names):
206
- """ Iterate over signal specifications for allowed services
207
-
208
- Args:
209
- signal_names (list): allowed signals
210
- Yields:
211
- specification (dict): Specification for a signal for an allowed service
212
- """
213
- for _, spec in self._generator(signal_names, unique_names=False):
214
- yield spec
215
-
216
- def _properties_service_model(self, signal_names, accessors):
217
- """ Placeholder
218
- """
219
- properties = []
220
- endpoint_members = {}
221
- endpoint_types = {}
222
- for signal_spec in self._specifications(signal_names):
223
- interface = signal_spec[self.position.api.value]
224
- if self.skip_interface(interface):
225
- continue
226
- endpoint = signal_spec[self.position.endpoint.value]
227
- primitive = signal_spec[self.position.property_name.value]
228
- if endpoint not in endpoint_members and primitive is not None:
229
- endpoint_members[endpoint] = []
230
- if primitive is not None:
231
- if endpoint not in endpoint_types:
232
- endpoint_types[endpoint] = {
233
- 'name': endpoint,
234
- 'kind': 'struct',
235
- 'description': {
236
- 'brief': endpoint,
237
- "full": "Generated from project without custom description"
238
- },
239
- 'members': []
240
- }
241
- endpoint_members[endpoint].append({
242
- 'name': primitive,
243
- 'type': primitive,
244
- })
245
- endpoint_types[endpoint]['members'].append({
246
- 'name': primitive,
247
- 'type': signal_spec[self.position.property_type.value],
248
- })
249
- else:
250
- primitive_type = signal_spec[self.position.property_type.value]
251
- primitive_desc = signal_spec[self.position.description.value]
252
- primitive_unit = signal_spec[self.position.unit.value]
253
- properties.append(
254
- {
255
- 'name': endpoint,
256
- 'type': primitive_type,
257
- 'unit': primitive_unit,
258
- 'accessors': accessors,
259
- 'description': {
260
- 'brief': endpoint,
261
- 'full': primitive_desc,
262
- }
263
- }
264
- )
265
- for endpoint_name in sorted(endpoint_members):
266
- properties.append(
267
- {
268
- 'name': endpoint_name,
269
- 'type': endpoint_name,
270
- 'unit': 'struct',
271
- 'accessors': accessors,
272
- 'description': {
273
- 'brief': endpoint_name,
274
- "full": "Generated from project without custom description"},
275
- }
276
- )
277
- return_types = []
278
- for endpoint_name, endpoint_type in endpoint_types.items():
279
- return_types.append(endpoint_type)
280
- return properties, return_types
281
-
282
- def skip_interface(self, interface):
283
- """ Filter services not in list.
284
-
285
- Args:
286
- service (str): interface
287
- Returns:
288
- skip (bool): Skip this interface
289
- """
290
- if self.filter is None:
291
- LOGGER.debug('No interface filter. Allowing everyone.')
292
- return False
293
- if interface in self.filter:
294
- LOGGER.debug('%s is in %s', interface, self.filter)
295
- return False
296
- return True
1
+ # Copyright 2024 Volvo Car Corporation
2
+ # Licensed under Apache 2.0.
3
+
4
+ """Module for handling the Service abstraction."""
5
+
6
+
7
+ import re
8
+
9
+ from powertrain_build.interface.base import filter_signals
10
+ from powertrain_build.interface.csp_api import CspApi
11
+ from powertrain_build.interface.application import get_internal_domain
12
+ from powertrain_build.lib import logger
13
+
14
+ LOGGER = logger.create_logger("service")
15
+
16
+
17
+ def get_service(app, client_name, interface):
18
+ """Get service implementation specification"""
19
+ rasters = app.get_rasters()
20
+ LOGGER.debug("Rasters: %s", rasters)
21
+ translation_files = app.get_translation_files()
22
+
23
+ sfw = ServiceFramework(app)
24
+ sfw.filter = f"{client_name}_internal"
25
+ sfw.name = f"{client_name}_{interface}"
26
+ sfw.parse_definition(translation_files)
27
+ internal = get_internal_domain(rasters)
28
+ properties_from_json = [
29
+ {"destination": "min", "source": "min", "default": "-"},
30
+ {"destination": "max", "source": "max", "default": "-"},
31
+ {"destination": "variable_type", "source": "type"},
32
+ {"destination": "offset", "source": "offset", "default": "-"},
33
+ {"destination": "factor", "source": "lsb", "default": 1},
34
+ {"destination": "description", "source": "description"},
35
+ {"destination": "unit", "source": "unit", "default": "-"},
36
+ ]
37
+ for raster in rasters:
38
+ external_signals = filter_signals(raster.insignals, internal)
39
+ sfw.add_signals(
40
+ external_signals,
41
+ "insignals",
42
+ properties_from_json,
43
+ )
44
+ sfw.add_signals(raster.outsignals, "outsignals", properties_from_json)
45
+ return sfw.to_model(interface)
46
+
47
+
48
+ def get_service_list(app):
49
+ """Get service list from app
50
+
51
+ Args:
52
+ app (Application): Pybuild project
53
+
54
+ Returns:
55
+ (str): a string containing the translated service list
56
+ """
57
+ translation_map = app.get_service_mapping()
58
+ cmake = ''
59
+ for proxy, service in translation_map.items():
60
+ lib = re.sub('-', '_', service + '_lib' + proxy + '_service_proxy').upper()
61
+ include = re.sub('-', '_', service + '_include_dir').upper()
62
+ cmake += f"LIST(APPEND extra_libraries ${{{lib}}})\n"
63
+ cmake += f"LIST(APPEND EXTRA_INCLUDE_DIRS ${{{include}}})\n"
64
+ return cmake
65
+
66
+
67
+ class ServiceFramework(CspApi):
68
+ """Service Framework abstraction layer"""
69
+
70
+ def __repr__(self):
71
+ """String representation of SWFL"""
72
+ return (
73
+ f"<SWFL {self.name}"
74
+ f" app_side insignals: {len(self.signal_names['app']['insignals'])}"
75
+ f" app_side outsignals: {len(self.signal_names['app']['outsignals'])}>"
76
+ )
77
+
78
+ def get_map_file(self):
79
+ """Get service translation map file
80
+
81
+ Returns:
82
+ (Path): service translation map file
83
+ """
84
+ return self.base_application.get_services_file()
85
+
86
+ def get_map(self):
87
+ """Get service translation map
88
+
89
+ Returns:
90
+ (dict): service translation map
91
+ """
92
+ return self.base_application.get_service_mapping()
93
+
94
+ def check_endpoints(self):
95
+ """Check and crash if signal endpoint contains both produces and consumes signals."""
96
+ endpoints = {}
97
+ for signal_name, signal_specs in self.translations.items():
98
+ if signal_name in self.signal_names["app"]['insignals']:
99
+ consumed = True
100
+ elif signal_name in self.signal_names["app"]['outsignals']:
101
+ consumed = False
102
+ else:
103
+ continue
104
+ for signal_spec in signal_specs:
105
+ endpoint = signal_spec[self.position.endpoint.value]
106
+ api = signal_spec[self.position.api.value]
107
+ key = (api, endpoint)
108
+ if key not in endpoints:
109
+ endpoints[key] = {
110
+ "consumed": consumed,
111
+ "signals": set()
112
+ }
113
+ endpoints[key]["signals"].add(signal_name)
114
+ assert consumed == endpoints[key]["consumed"], \
115
+ f"Signal endpoint {endpoint} for {api} contains both consumed and produced signals"
116
+
117
+ def extract_endpoint_definitions(self, raw):
118
+ """Extract endpoint definitions from yaml file.
119
+
120
+ Args:
121
+ raw (dict): Raw yaml file
122
+ Returns:
123
+ (dict): Endpoint definitions
124
+ """
125
+ self.parse_api_definitions(raw.get("service", {}))
126
+
127
+ @staticmethod
128
+ def extract_definition(definition):
129
+ """Extract definition from yaml file.
130
+ Returns the properties and methods for a service.
131
+
132
+ Args:
133
+ definition (dict): Definition from yaml file
134
+ Returns:
135
+ (dict): Specifications for a service
136
+ """
137
+ specifications = {}
138
+ specifications['properties'] = definition.get('properties', [])
139
+ specifications['methods'] = definition.get('methods', [])
140
+ return specifications
141
+
142
+ def to_model(self, client):
143
+ """Method to generate dict to be saved as yaml
144
+ Args:
145
+ client (str): Name of the client in signal comm
146
+ Returns:
147
+ spec (dict): Signal model for using a service
148
+ """
149
+ properties, types = self.properties_service_model(client)
150
+ descriptions = {
151
+ 'internal': {
152
+ 'brief': "Internal interface for associated application.",
153
+ 'full': "This interface should only be used by the associated application."
154
+ },
155
+ 'external': {
156
+ 'brief': "External interface.",
157
+ 'full': "This interface should be used by modules wanting to interact with the associated application."
158
+ },
159
+ 'observer': {
160
+ 'brief': "Read-only interface.",
161
+ 'full': "This interface can be used by anyone wanting information from the associated application."
162
+ },
163
+ }
164
+ model = {"name": self.name,
165
+ "version": "${SERVICE_VERSION}",
166
+ "description": descriptions[client],
167
+ "properties": properties,
168
+ "types": types}
169
+ return model
170
+
171
+ def properties_service_model(self, client):
172
+ """Generate properties and types for a service
173
+
174
+ Args:
175
+ client (str): Name of the client in signal comm
176
+
177
+ Returns:
178
+ (list): List of properties
179
+ (list): List of types
180
+ """
181
+ properties = {}
182
+ types = {}
183
+ accessors = {}
184
+ if client == 'internal':
185
+ accessors['insignals'] = 'r-'
186
+ accessors['outsignals'] = '-w'
187
+ elif client == 'external':
188
+ accessors['insignals'] = '-w'
189
+ accessors['outsignals'] = 'r-'
190
+ else:
191
+ accessors['insignals'] = 'r-'
192
+ accessors['outsignals'] = 'r-'
193
+
194
+ properties_in, types_in = self._properties_service_model(
195
+ self.signal_names["app"]["insignals"],
196
+ accessors['insignals'])
197
+ properties_out, types_out = self._properties_service_model(
198
+ self.signal_names["app"]["outsignals"],
199
+ accessors['outsignals'])
200
+
201
+ properties = properties_in + properties_out
202
+ types = types_in + types_out
203
+ return properties, types
204
+
205
+ def _specifications(self, signal_names):
206
+ """ Iterate over signal specifications for allowed services
207
+
208
+ Args:
209
+ signal_names (list): allowed signals
210
+ Yields:
211
+ specification (dict): Specification for a signal for an allowed service
212
+ """
213
+ for _, spec in self._generator(signal_names, unique_names=False):
214
+ yield spec
215
+
216
+ def _properties_service_model(self, signal_names, accessors):
217
+ """ Placeholder
218
+ """
219
+ properties = []
220
+ endpoint_members = {}
221
+ endpoint_types = {}
222
+ for signal_spec in self._specifications(signal_names):
223
+ interface = signal_spec[self.position.api.value]
224
+ if self.skip_interface(interface):
225
+ continue
226
+ endpoint = signal_spec[self.position.endpoint.value]
227
+ primitive = signal_spec[self.position.property_name.value]
228
+ if endpoint not in endpoint_members and primitive is not None:
229
+ endpoint_members[endpoint] = []
230
+ if primitive is not None:
231
+ if endpoint not in endpoint_types:
232
+ endpoint_types[endpoint] = {
233
+ 'name': endpoint,
234
+ 'kind': 'struct',
235
+ 'description': {
236
+ 'brief': endpoint,
237
+ "full": "Generated from project without custom description"
238
+ },
239
+ 'members': []
240
+ }
241
+ endpoint_members[endpoint].append({
242
+ 'name': primitive,
243
+ 'type': primitive,
244
+ })
245
+ endpoint_types[endpoint]['members'].append({
246
+ 'name': primitive,
247
+ 'type': signal_spec[self.position.property_type.value],
248
+ })
249
+ else:
250
+ primitive_type = signal_spec[self.position.property_type.value]
251
+ primitive_desc = signal_spec[self.position.description.value]
252
+ primitive_unit = signal_spec[self.position.unit.value]
253
+ properties.append(
254
+ {
255
+ 'name': endpoint,
256
+ 'type': primitive_type,
257
+ 'unit': primitive_unit,
258
+ 'accessors': accessors,
259
+ 'description': {
260
+ 'brief': endpoint,
261
+ 'full': primitive_desc,
262
+ }
263
+ }
264
+ )
265
+ for endpoint_name in sorted(endpoint_members):
266
+ properties.append(
267
+ {
268
+ 'name': endpoint_name,
269
+ 'type': endpoint_name,
270
+ 'unit': 'struct',
271
+ 'accessors': accessors,
272
+ 'description': {
273
+ 'brief': endpoint_name,
274
+ "full": "Generated from project without custom description"},
275
+ }
276
+ )
277
+ return_types = []
278
+ for endpoint_name, endpoint_type in endpoint_types.items():
279
+ return_types.append(endpoint_type)
280
+ return properties, return_types
281
+
282
+ def skip_interface(self, interface):
283
+ """ Filter services not in list.
284
+
285
+ Args:
286
+ service (str): interface
287
+ Returns:
288
+ skip (bool): Skip this interface
289
+ """
290
+ if self.filter is None:
291
+ LOGGER.debug('No interface filter. Allowing everyone.')
292
+ return False
293
+ if interface in self.filter:
294
+ LOGGER.debug('%s is in %s', interface, self.filter)
295
+ return False
296
+ return True