chronaxis 0.1.0.dev0__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 (917) hide show
  1. chronaxis/__init__.py +72 -0
  2. chronaxis/__main__.py +12 -0
  3. chronaxis/analysis_cli.py +181 -0
  4. chronaxis/batch/__init__.py +14 -0
  5. chronaxis/batch/api.py +46 -0
  6. chronaxis/batch/cli.py +48 -0
  7. chronaxis/batch/config.py +37 -0
  8. chronaxis/batch/models.py +202 -0
  9. chronaxis/batch/process_transport.py +149 -0
  10. chronaxis/batch/process_tree.py +72 -0
  11. chronaxis/batch/publication.py +41 -0
  12. chronaxis/batch/runner.py +236 -0
  13. chronaxis/batch/templates.py +42 -0
  14. chronaxis/can_dependencies.py +42 -0
  15. chronaxis/cli.py +193 -0
  16. chronaxis/configuration/__init__.py +46 -0
  17. chronaxis/configuration/cli.py +41 -0
  18. chronaxis/configuration/diagnostics.py +107 -0
  19. chronaxis/configuration/explanation.py +233 -0
  20. chronaxis/configuration/file_tools.py +140 -0
  21. chronaxis/configuration/imports.py +144 -0
  22. chronaxis/configuration/initialization.py +36 -0
  23. chronaxis/configuration/json_parser.py +114 -0
  24. chronaxis/configuration/models.py +74 -0
  25. chronaxis/configuration/origins.py +90 -0
  26. chronaxis/configuration/overrides.py +55 -0
  27. chronaxis/configuration/resolution.py +150 -0
  28. chronaxis/configuration/template_catalog.py +68 -0
  29. chronaxis/configuration/templates/batch/analysis-annotated.yaml +18 -0
  30. chronaxis/configuration/templates/batch/analysis-minimal.yaml +18 -0
  31. chronaxis/configuration/templates/batch/annotated.yaml +6 -0
  32. chronaxis/configuration/templates/batch/minimal.yaml +6 -0
  33. chronaxis/configuration/templates/can-asc/annotated.yaml +18 -0
  34. chronaxis/configuration/templates/can-asc/minimal.yaml +18 -0
  35. chronaxis/configuration/templates/can-blf/annotated.yaml +18 -0
  36. chronaxis/configuration/templates/can-blf/minimal.yaml +18 -0
  37. chronaxis/configuration/templates/can-export/annotated.yaml +23 -0
  38. chronaxis/configuration/templates/can-export/minimal.yaml +23 -0
  39. chronaxis/configuration/templates/catalog.json +233 -0
  40. chronaxis/configuration/templates/charge-session/annotated.yaml +38 -0
  41. chronaxis/configuration/templates/charge-session/minimal.yaml +38 -0
  42. chronaxis/configuration/templates/command-response/annotated.yaml +32 -0
  43. chronaxis/configuration/templates/command-response/minimal.yaml +36 -0
  44. chronaxis/configuration/templates/fault-window/annotated.yaml +25 -0
  45. chronaxis/configuration/templates/fault-window/minimal.yaml +27 -0
  46. chronaxis/configuration/templates/ini-mapping/annotated.yaml +20 -0
  47. chronaxis/configuration/templates/ini-mapping/minimal.yaml +20 -0
  48. chronaxis/configuration/templates/raw-can-csv/annotated.yaml +34 -0
  49. chronaxis/configuration/templates/raw-can-csv/minimal.yaml +35 -0
  50. chronaxis/configuration/templates/shared/charge-session.asc +5 -0
  51. chronaxis/configuration/templates/shared/command-response.asc +8 -0
  52. chronaxis/configuration/templates/shared/fault-window.asc +5 -0
  53. chronaxis/configuration/templates/shared/power.asc +7 -0
  54. chronaxis/configuration/templates/shared/sample.asc +6 -0
  55. chronaxis/configuration/templates/shared/sample.blf +0 -0
  56. chronaxis/configuration/templates/shared/sample.csv +5 -0
  57. chronaxis/configuration/templates/shared/sample.dbc +11 -0
  58. chronaxis/configuration/templates/shared/signals.csv +6 -0
  59. chronaxis/configuration/templates/shared/source.ini +5 -0
  60. chronaxis/configuration/templates/shared/stability.asc +9 -0
  61. chronaxis/configuration/templates/shared/teaching.dbc +27 -0
  62. chronaxis/configuration/templates/shared/threshold.asc +7 -0
  63. chronaxis/configuration/templates/signal-csv/annotated.yaml +27 -0
  64. chronaxis/configuration/templates/signal-csv/minimal.yaml +27 -0
  65. chronaxis/configuration/templates/signal-export/annotated.yaml +27 -0
  66. chronaxis/configuration/templates/signal-export/minimal.yaml +29 -0
  67. chronaxis/configuration/templates/stability/annotated.yaml +35 -0
  68. chronaxis/configuration/templates/stability/minimal.yaml +35 -0
  69. chronaxis/configuration/templates/threshold/annotated.yaml +22 -0
  70. chronaxis/configuration/templates/threshold/minimal.yaml +22 -0
  71. chronaxis/configuration/yaml_parser.py +125 -0
  72. chronaxis/core/__init__.py +71 -0
  73. chronaxis/core/binding.py +449 -0
  74. chronaxis/core/calculation_series_join.py +106 -0
  75. chronaxis/core/calculations.py +435 -0
  76. chronaxis/core/calculations_memory_numpy.py +136 -0
  77. chronaxis/core/calculations_memory_reference.py +165 -0
  78. chronaxis/core/calculations_numpy.py +298 -0
  79. chronaxis/core/calculations_reference.py +294 -0
  80. chronaxis/core/condition_evidence.py +182 -0
  81. chronaxis/core/conditional_integral_result.py +43 -0
  82. chronaxis/core/conditional_integral_terms.py +146 -0
  83. chronaxis/core/conditional_integral_terms_numpy.py +148 -0
  84. chronaxis/core/conditional_integral_terms_reference.py +111 -0
  85. chronaxis/core/conditional_time_reduction.py +118 -0
  86. chronaxis/core/conditional_time_reduction_numpy.py +223 -0
  87. chronaxis/core/conditional_time_reduction_reference.py +213 -0
  88. chronaxis/core/declarations.py +192 -0
  89. chronaxis/core/decoded_binding.py +197 -0
  90. chronaxis/core/direct_message.py +387 -0
  91. chronaxis/core/export_interpolation.py +54 -0
  92. chronaxis/core/expression.py +642 -0
  93. chronaxis/core/expression_numpy.py +314 -0
  94. chronaxis/core/expression_reference.py +272 -0
  95. chronaxis/core/integral_result.py +53 -0
  96. chronaxis/core/integral_sum.py +77 -0
  97. chronaxis/core/integral_sum_numpy.py +224 -0
  98. chronaxis/core/integral_sum_reference.py +148 -0
  99. chronaxis/core/integral_terms.py +119 -0
  100. chronaxis/core/integral_terms_numpy.py +127 -0
  101. chronaxis/core/integral_terms_reference.py +91 -0
  102. chronaxis/core/mean_weights_numpy.py +29 -0
  103. chronaxis/core/mean_weights_reference.py +27 -0
  104. chronaxis/core/message_binding.py +305 -0
  105. chronaxis/core/models.py +485 -0
  106. chronaxis/core/normalize_numpy.py +396 -0
  107. chronaxis/core/numeric.py +472 -0
  108. chronaxis/core/numeric_numpy.py +440 -0
  109. chronaxis/core/record_intervals.py +115 -0
  110. chronaxis/core/sample_reduction.py +161 -0
  111. chronaxis/core/sample_reduction_numpy.py +160 -0
  112. chronaxis/core/sample_reduction_reference.py +154 -0
  113. chronaxis/core/selection.py +74 -0
  114. chronaxis/core/sequence.py +160 -0
  115. chronaxis/core/sequence_reference.py +248 -0
  116. chronaxis/core/stability.py +249 -0
  117. chronaxis/core/start_end.py +169 -0
  118. chronaxis/core/state.py +494 -0
  119. chronaxis/core/state_numpy.py +296 -0
  120. chronaxis/core/temporal.py +373 -0
  121. chronaxis/core/temporal_clock.py +25 -0
  122. chronaxis/core/temporal_memory_numpy.py +163 -0
  123. chronaxis/core/temporal_memory_reference.py +161 -0
  124. chronaxis/core/temporal_numpy.py +345 -0
  125. chronaxis/core/temporal_reference.py +304 -0
  126. chronaxis/core/time_reduction.py +190 -0
  127. chronaxis/core/time_reduction_numpy.py +205 -0
  128. chronaxis/core/time_reduction_reference.py +203 -0
  129. chronaxis/core/types.py +105 -0
  130. chronaxis/core/units.py +81 -0
  131. chronaxis/core/validation.py +94 -0
  132. chronaxis/core/window_delta.py +123 -0
  133. chronaxis/core/window_delta_numpy.py +78 -0
  134. chronaxis/core/window_delta_reference.py +69 -0
  135. chronaxis/core/windows.py +224 -0
  136. chronaxis/core/windows_numpy.py +78 -0
  137. chronaxis/core/windows_reference.py +61 -0
  138. chronaxis/execution/__init__.py +6 -0
  139. chronaxis/execution/batch_signal_groups.py +122 -0
  140. chronaxis/execution/bindings.py +296 -0
  141. chronaxis/execution/boundaries.py +568 -0
  142. chronaxis/execution/calculation_blocks.py +338 -0
  143. chronaxis/execution/calculation_values.py +55 -0
  144. chronaxis/execution/can_batch_reader.py +356 -0
  145. chronaxis/execution/can_reader.py +948 -0
  146. chronaxis/execution/can_reference_template.py +61 -0
  147. chronaxis/execution/condition_evidence.py +370 -0
  148. chronaxis/execution/conditional_integral_facts.py +310 -0
  149. chronaxis/execution/conditional_integral_reduction.py +216 -0
  150. chronaxis/execution/csv_observation.py +524 -0
  151. chronaxis/execution/csv_reader.py +662 -0
  152. chronaxis/execution/current_message_calculation.py +225 -0
  153. chronaxis/execution/driver_expression.py +274 -0
  154. chronaxis/execution/expressions.py +618 -0
  155. chronaxis/execution/frame_capture.py +245 -0
  156. chronaxis/execution/groups.py +236 -0
  157. chronaxis/execution/historical_conditional_blocks.py +264 -0
  158. chronaxis/execution/historical_conditional_integral.py +226 -0
  159. chronaxis/execution/historical_conditional_time_calculation.py +368 -0
  160. chronaxis/execution/historical_integral.py +219 -0
  161. chronaxis/execution/historical_observation.py +372 -0
  162. chronaxis/execution/historical_sample_calculation.py +338 -0
  163. chronaxis/execution/historical_selection_rows.py +300 -0
  164. chronaxis/execution/historical_time_calculation.py +341 -0
  165. chronaxis/execution/history.py +572 -0
  166. chronaxis/execution/history_records.py +225 -0
  167. chronaxis/execution/hold.py +448 -0
  168. chronaxis/execution/integral_facts.py +311 -0
  169. chronaxis/execution/integral_reduction.py +216 -0
  170. chronaxis/execution/legacy_frame_samples.py +94 -0
  171. chronaxis/execution/memory_reader.py +247 -0
  172. chronaxis/execution/message_bindings.py +293 -0
  173. chronaxis/execution/message_delivery.py +37 -0
  174. chronaxis/execution/observed_ingestion.py +551 -0
  175. chronaxis/execution/raw_signal_groups.py +192 -0
  176. chronaxis/execution/record_alarm_duration.py +114 -0
  177. chronaxis/execution/record_delta_condition.py +167 -0
  178. chronaxis/execution/record_diagnostics.py +87 -0
  179. chronaxis/execution/record_event_durations.py +143 -0
  180. chronaxis/execution/record_export_samples.py +94 -0
  181. chronaxis/execution/record_exports.py +155 -0
  182. chronaxis/execution/record_integral.py +196 -0
  183. chronaxis/execution/record_point_buffer.py +101 -0
  184. chronaxis/execution/record_rule_timeline.py +344 -0
  185. chronaxis/execution/record_sample.py +46 -0
  186. chronaxis/execution/record_sample_series.py +29 -0
  187. chronaxis/execution/record_scope_calculations.py +290 -0
  188. chronaxis/execution/record_selection.py +62 -0
  189. chronaxis/execution/record_sequences.py +199 -0
  190. chronaxis/execution/record_session_calculations.py +778 -0
  191. chronaxis/execution/record_signal_export.py +133 -0
  192. chronaxis/execution/record_source_cursor.py +295 -0
  193. chronaxis/execution/record_time_calculation.py +322 -0
  194. chronaxis/execution/record_time_indexes.py +143 -0
  195. chronaxis/execution/record_value_history.py +160 -0
  196. chronaxis/execution/record_windows.py +229 -0
  197. chronaxis/execution/required_expression.py +52 -0
  198. chronaxis/execution/retained_metadata.py +71 -0
  199. chronaxis/execution/run_session.py +402 -0
  200. chronaxis/execution/scanned_signal_proof.py +550 -0
  201. chronaxis/execution/signal_validity.py +40 -0
  202. chronaxis/execution/state.py +280 -0
  203. chronaxis/execution/temporal_buffer.py +508 -0
  204. chronaxis/execution/text_can_reader.py +359 -0
  205. chronaxis/execution/timeline.py +309 -0
  206. chronaxis/execution/timeline_multi.py +415 -0
  207. chronaxis/execution/window_delta_events.py +220 -0
  208. chronaxis/execution/window_replay.py +350 -0
  209. chronaxis/execution/windows.py +173 -0
  210. chronaxis/guide/README.md +70 -0
  211. chronaxis/guide/api/AnalysisError.md +14 -0
  212. chronaxis/guide/api/AnalysisPlan.md +96 -0
  213. chronaxis/guide/api/AnalysisResult.md +398 -0
  214. chronaxis/guide/api/AnalysisRunner.md +155 -0
  215. chronaxis/guide/api/BatchJob.md +19 -0
  216. chronaxis/guide/api/BatchJobResult.md +61 -0
  217. chronaxis/guide/api/BatchPlan.md +48 -0
  218. chronaxis/guide/api/BatchReport.md +108 -0
  219. chronaxis/guide/api/BatchRunner.md +84 -0
  220. chronaxis/guide/api/OutputManifest.md +23 -0
  221. chronaxis/guide/api/PlanFragment.md +47 -0
  222. chronaxis/guide/api/PlanValidationError.md +98 -0
  223. chronaxis/guide/api/PresetSpec.md +63 -0
  224. chronaxis/guide/api/ResultClosedError.md +14 -0
  225. chronaxis/guide/api/RunMetadata.md +100 -0
  226. chronaxis/guide/api/TimeConversion.md +29 -0
  227. chronaxis/guide/api/TimeOverflowError.md +17 -0
  228. chronaxis/guide/api/build_preset.md +36 -0
  229. chronaxis/guide/api/checked_add_ns.md +30 -0
  230. chronaxis/guide/api/convert_time.md +40 -0
  231. chronaxis/guide/api/explain_analysis_plan.md +38 -0
  232. chronaxis/guide/api/index.json +185 -0
  233. chronaxis/guide/api/load_analysis_plan.md +34 -0
  234. chronaxis/guide/api/load_batch_plan.md +36 -0
  235. chronaxis/guide/api/parse_datetime_ns.md +35 -0
  236. chronaxis/guide/api/parse_duration.md +30 -0
  237. chronaxis/guide/api/resolve_preset_roles.md +37 -0
  238. chronaxis/guide/api/run_batch.md +38 -0
  239. chronaxis/guide/api/shift_times_reference.md +33 -0
  240. chronaxis/guide/api/time_deltas_reference.md +37 -0
  241. chronaxis/guide/api/validate_analysis_plan.md +38 -0
  242. chronaxis/guide/en/README.md +74 -0
  243. chronaxis/guide/en/api/AnalysisError.md +14 -0
  244. chronaxis/guide/en/api/AnalysisPlan.md +93 -0
  245. chronaxis/guide/en/api/AnalysisResult.md +398 -0
  246. chronaxis/guide/en/api/AnalysisRunner.md +191 -0
  247. chronaxis/guide/en/api/BatchJob.md +17 -0
  248. chronaxis/guide/en/api/BatchJobResult.md +43 -0
  249. chronaxis/guide/en/api/BatchPlan.md +37 -0
  250. chronaxis/guide/en/api/BatchReport.md +52 -0
  251. chronaxis/guide/en/api/BatchRunner.md +51 -0
  252. chronaxis/guide/en/api/OutputManifest.md +23 -0
  253. chronaxis/guide/en/api/PlanFragment.md +33 -0
  254. chronaxis/guide/en/api/PlanValidationError.md +58 -0
  255. chronaxis/guide/en/api/PresetSpec.md +51 -0
  256. chronaxis/guide/en/api/ResultClosedError.md +14 -0
  257. chronaxis/guide/en/api/RunMetadata.md +100 -0
  258. chronaxis/guide/en/api/TimeConversion.md +23 -0
  259. chronaxis/guide/en/api/TimeOverflowError.md +14 -0
  260. chronaxis/guide/en/api/build_preset.md +23 -0
  261. chronaxis/guide/en/api/checked_add_ns.md +21 -0
  262. chronaxis/guide/en/api/convert_time.md +25 -0
  263. chronaxis/guide/en/api/explain_analysis_plan.md +30 -0
  264. chronaxis/guide/en/api/index.json +185 -0
  265. chronaxis/guide/en/api/load_analysis_plan.md +27 -0
  266. chronaxis/guide/en/api/load_batch_plan.md +28 -0
  267. chronaxis/guide/en/api/parse_datetime_ns.md +23 -0
  268. chronaxis/guide/en/api/parse_duration.md +20 -0
  269. chronaxis/guide/en/api/resolve_preset_roles.md +23 -0
  270. chronaxis/guide/en/api/run_batch.md +39 -0
  271. chronaxis/guide/en/api/shift_times_reference.md +21 -0
  272. chronaxis/guide/en/api/time_deltas_reference.md +22 -0
  273. chronaxis/guide/en/api/validate_analysis_plan.md +29 -0
  274. chronaxis/guide/en/fields/analysis/calculations-all-1.json +345 -0
  275. chronaxis/guide/en/fields/analysis/calculations-all-2.json +300 -0
  276. chronaxis/guide/en/fields/analysis/calculations-all-3.json +84 -0
  277. chronaxis/guide/en/fields/analysis/config_version-all-1.json +24 -0
  278. chronaxis/guide/en/fields/analysis/dataset-all-1.json +344 -0
  279. chronaxis/guide/en/fields/analysis/derived-all-1.json +147 -0
  280. chronaxis/guide/en/fields/analysis/diagnostics-all-1.json +69 -0
  281. chronaxis/guide/en/fields/analysis/execution-all-1.json +167 -0
  282. chronaxis/guide/en/fields/analysis/imports-all-1.json +39 -0
  283. chronaxis/guide/en/fields/analysis/intervals-all-1.json +173 -0
  284. chronaxis/guide/en/fields/analysis/message_calculations-all-1.json +345 -0
  285. chronaxis/guide/en/fields/analysis/message_calculations-all-2.json +270 -0
  286. chronaxis/guide/en/fields/analysis/metadata-all-1.json +24 -0
  287. chronaxis/guide/en/fields/analysis/outputs-all-1.json +332 -0
  288. chronaxis/guide/en/fields/analysis/outputs-all-2.json +319 -0
  289. chronaxis/guide/en/fields/analysis/outputs-all-3.json +321 -0
  290. chronaxis/guide/en/fields/analysis/outputs-all-4.json +236 -0
  291. chronaxis/guide/en/fields/analysis/outputs-all-5.json +246 -0
  292. chronaxis/guide/en/fields/analysis/outputs-all-6.json +214 -0
  293. chronaxis/guide/en/fields/analysis/overrides-all-1.json +104 -0
  294. chronaxis/guide/en/fields/analysis/presets-charge_session-1.json +398 -0
  295. chronaxis/guide/en/fields/analysis/presets-charge_session-2.json +114 -0
  296. chronaxis/guide/en/fields/analysis/presets-command_response-1.json +376 -0
  297. chronaxis/guide/en/fields/analysis/presets-fault_context-1.json +285 -0
  298. chronaxis/guide/en/fields/analysis/presets-threshold_excursion-1.json +317 -0
  299. chronaxis/guide/en/fields/analysis/rules-condition_duration-1.json +344 -0
  300. chronaxis/guide/en/fields/analysis/rules-condition_duration-2.json +27 -0
  301. chronaxis/guide/en/fields/analysis/rules-debounce-1.json +335 -0
  302. chronaxis/guide/en/fields/analysis/rules-falling_edge-1.json +317 -0
  303. chronaxis/guide/en/fields/analysis/rules-hysteresis-1.json +334 -0
  304. chronaxis/guide/en/fields/analysis/rules-hysteresis-2.json +27 -0
  305. chronaxis/guide/en/fields/analysis/rules-rising_edge-1.json +317 -0
  306. chronaxis/guide/en/fields/analysis/rules-start_end-1.json +333 -0
  307. chronaxis/guide/en/fields/analysis/rules-start_end-2.json +60 -0
  308. chronaxis/guide/en/fields/analysis/rules-start_only-1.json +334 -0
  309. chronaxis/guide/en/fields/analysis/rules-window_delta-1.json +338 -0
  310. chronaxis/guide/en/fields/analysis/rules-window_delta-2.json +96 -0
  311. chronaxis/guide/en/fields/analysis/sequences-all-1.json +378 -0
  312. chronaxis/guide/en/fields/analysis/sequences-all-2.json +70 -0
  313. chronaxis/guide/en/fields/analysis/signals-variant-1-1.json +349 -0
  314. chronaxis/guide/en/fields/analysis/signals-variant-1-2.json +297 -0
  315. chronaxis/guide/en/fields/analysis/signals-variant-1-3.json +323 -0
  316. chronaxis/guide/en/fields/analysis/signals-variant-1-4.json +192 -0
  317. chronaxis/guide/en/fields/analysis/signals-variant-2-1.json +327 -0
  318. chronaxis/guide/en/fields/analysis/signals-variant-2-2.json +312 -0
  319. chronaxis/guide/en/fields/analysis/signals-variant-2-3.json +294 -0
  320. chronaxis/guide/en/fields/analysis/signals-variant-2-4.json +253 -0
  321. chronaxis/guide/en/fields/analysis/signals-variant-2-5.json +44 -0
  322. chronaxis/guide/en/fields/analysis/sources-can_asc-1.json +318 -0
  323. chronaxis/guide/en/fields/analysis/sources-can_asc-2.json +310 -0
  324. chronaxis/guide/en/fields/analysis/sources-can_asc-3.json +311 -0
  325. chronaxis/guide/en/fields/analysis/sources-can_asc-4.json +69 -0
  326. chronaxis/guide/en/fields/analysis/sources-can_blf-1.json +317 -0
  327. chronaxis/guide/en/fields/analysis/sources-can_blf-2.json +310 -0
  328. chronaxis/guide/en/fields/analysis/sources-can_blf-3.json +317 -0
  329. chronaxis/guide/en/fields/analysis/sources-memory-1.json +332 -0
  330. chronaxis/guide/en/fields/analysis/sources-memory-2.json +125 -0
  331. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-1.json +330 -0
  332. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-10.json +233 -0
  333. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-11.json +225 -0
  334. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-12.json +228 -0
  335. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-13.json +226 -0
  336. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-14.json +230 -0
  337. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-15.json +227 -0
  338. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-16.json +230 -0
  339. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-17.json +238 -0
  340. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-18.json +239 -0
  341. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-19.json +233 -0
  342. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-2.json +310 -0
  343. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-20.json +242 -0
  344. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-21.json +230 -0
  345. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-22.json +228 -0
  346. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-23.json +230 -0
  347. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-24.json +223 -0
  348. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-25.json +290 -0
  349. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-26.json +131 -0
  350. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-3.json +297 -0
  351. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-4.json +226 -0
  352. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-5.json +230 -0
  353. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-6.json +227 -0
  354. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-7.json +230 -0
  355. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-8.json +238 -0
  356. chronaxis/guide/en/fields/analysis/sources-raw_can_csv-9.json +239 -0
  357. chronaxis/guide/en/fields/analysis/sources-signal_csv-1.json +331 -0
  358. chronaxis/guide/en/fields/analysis/sources-signal_csv-2.json +307 -0
  359. chronaxis/guide/en/fields/analysis/sources-signal_csv-3.json +315 -0
  360. chronaxis/guide/en/fields/analysis/sources-variant-6-1.json +319 -0
  361. chronaxis/guide/en/fields/analysis/sources-variant-6-2.json +307 -0
  362. chronaxis/guide/en/fields/analysis/sources-variant-6-3.json +312 -0
  363. chronaxis/guide/en/fields/analysis/sources-variant-6-4.json +113 -0
  364. chronaxis/guide/en/fields/analysis/windows-all-1.json +361 -0
  365. chronaxis/guide/en/fields/analysis/windows-all-2.json +187 -0
  366. chronaxis/guide/en/fields/batch/backend-all-1.json +26 -0
  367. chronaxis/guide/en/fields/batch/batch_version-all-1.json +22 -0
  368. chronaxis/guide/en/fields/batch/fail_fast-all-1.json +22 -0
  369. chronaxis/guide/en/fields/batch/inputs-all-1.json +161 -0
  370. chronaxis/guide/en/fields/batch/jobs-all-1.json +58 -0
  371. chronaxis/guide/en/fields/batch/process_count-all-1.json +23 -0
  372. chronaxis/guide/en/fields/batch/source-all-1.json +22 -0
  373. chronaxis/guide/en/fields/batch/template-all-1.json +22 -0
  374. chronaxis/guide/en/fields/definitions/derived-all-1.json +121 -0
  375. chronaxis/guide/en/fields/definitions/signals-all-1.json +336 -0
  376. chronaxis/guide/en/fields/definitions/signals-all-2.json +307 -0
  377. chronaxis/guide/en/fields/definitions/signals-all-3.json +290 -0
  378. chronaxis/guide/en/fields/definitions/signals-all-4.json +347 -0
  379. chronaxis/guide/en/fields/definitions/signals-all-5.json +297 -0
  380. chronaxis/guide/en/fields/definitions/signals-all-6.json +259 -0
  381. chronaxis/guide/en/fields/definitions/signals-all-7.json +117 -0
  382. chronaxis/guide/en/fields/definitions/sources-all-1.json +332 -0
  383. chronaxis/guide/en/fields/definitions/sources-all-10.json +306 -0
  384. chronaxis/guide/en/fields/definitions/sources-all-11.json +294 -0
  385. chronaxis/guide/en/fields/definitions/sources-all-12.json +212 -0
  386. chronaxis/guide/en/fields/definitions/sources-all-13.json +217 -0
  387. chronaxis/guide/en/fields/definitions/sources-all-14.json +213 -0
  388. chronaxis/guide/en/fields/definitions/sources-all-15.json +214 -0
  389. chronaxis/guide/en/fields/definitions/sources-all-16.json +215 -0
  390. chronaxis/guide/en/fields/definitions/sources-all-17.json +213 -0
  391. chronaxis/guide/en/fields/definitions/sources-all-18.json +214 -0
  392. chronaxis/guide/en/fields/definitions/sources-all-19.json +213 -0
  393. chronaxis/guide/en/fields/definitions/sources-all-2.json +323 -0
  394. chronaxis/guide/en/fields/definitions/sources-all-20.json +217 -0
  395. chronaxis/guide/en/fields/definitions/sources-all-21.json +210 -0
  396. chronaxis/guide/en/fields/definitions/sources-all-22.json +214 -0
  397. chronaxis/guide/en/fields/definitions/sources-all-23.json +218 -0
  398. chronaxis/guide/en/fields/definitions/sources-all-24.json +209 -0
  399. chronaxis/guide/en/fields/definitions/sources-all-25.json +215 -0
  400. chronaxis/guide/en/fields/definitions/sources-all-26.json +218 -0
  401. chronaxis/guide/en/fields/definitions/sources-all-27.json +224 -0
  402. chronaxis/guide/en/fields/definitions/sources-all-28.json +215 -0
  403. chronaxis/guide/en/fields/definitions/sources-all-29.json +205 -0
  404. chronaxis/guide/en/fields/definitions/sources-all-3.json +303 -0
  405. chronaxis/guide/en/fields/definitions/sources-all-30.json +298 -0
  406. chronaxis/guide/en/fields/definitions/sources-all-31.json +315 -0
  407. chronaxis/guide/en/fields/definitions/sources-all-32.json +306 -0
  408. chronaxis/guide/en/fields/definitions/sources-all-33.json +209 -0
  409. chronaxis/guide/en/fields/definitions/sources-all-4.json +336 -0
  410. chronaxis/guide/en/fields/definitions/sources-all-5.json +299 -0
  411. chronaxis/guide/en/fields/definitions/sources-all-6.json +307 -0
  412. chronaxis/guide/en/fields/definitions/sources-all-7.json +320 -0
  413. chronaxis/guide/en/fields/definitions/sources-all-8.json +303 -0
  414. chronaxis/guide/en/fields/definitions/sources-all-9.json +315 -0
  415. chronaxis/guide/en/fields/index.json +3450 -0
  416. chronaxis/guide/en/fields/mapping/aliases-all-1.json +91 -0
  417. chronaxis/guide/en/fields/mapping/analysis-all-1.json +382 -0
  418. chronaxis/guide/en/fields/mapping/analysis-all-10.json +301 -0
  419. chronaxis/guide/en/fields/mapping/analysis-all-11.json +312 -0
  420. chronaxis/guide/en/fields/mapping/analysis-all-12.json +311 -0
  421. chronaxis/guide/en/fields/mapping/analysis-all-13.json +314 -0
  422. chronaxis/guide/en/fields/mapping/analysis-all-14.json +310 -0
  423. chronaxis/guide/en/fields/mapping/analysis-all-15.json +297 -0
  424. chronaxis/guide/en/fields/mapping/analysis-all-16.json +226 -0
  425. chronaxis/guide/en/fields/mapping/analysis-all-17.json +230 -0
  426. chronaxis/guide/en/fields/mapping/analysis-all-18.json +227 -0
  427. chronaxis/guide/en/fields/mapping/analysis-all-19.json +230 -0
  428. chronaxis/guide/en/fields/mapping/analysis-all-2.json +323 -0
  429. chronaxis/guide/en/fields/mapping/analysis-all-20.json +221 -0
  430. chronaxis/guide/en/fields/mapping/analysis-all-21.json +237 -0
  431. chronaxis/guide/en/fields/mapping/analysis-all-22.json +233 -0
  432. chronaxis/guide/en/fields/mapping/analysis-all-23.json +222 -0
  433. chronaxis/guide/en/fields/mapping/analysis-all-24.json +231 -0
  434. chronaxis/guide/en/fields/mapping/analysis-all-25.json +225 -0
  435. chronaxis/guide/en/fields/mapping/analysis-all-26.json +230 -0
  436. chronaxis/guide/en/fields/mapping/analysis-all-27.json +228 -0
  437. chronaxis/guide/en/fields/mapping/analysis-all-28.json +230 -0
  438. chronaxis/guide/en/fields/mapping/analysis-all-29.json +223 -0
  439. chronaxis/guide/en/fields/mapping/analysis-all-3.json +318 -0
  440. chronaxis/guide/en/fields/mapping/analysis-all-30.json +233 -0
  441. chronaxis/guide/en/fields/mapping/analysis-all-31.json +218 -0
  442. chronaxis/guide/en/fields/mapping/analysis-all-32.json +239 -0
  443. chronaxis/guide/en/fields/mapping/analysis-all-33.json +233 -0
  444. chronaxis/guide/en/fields/mapping/analysis-all-34.json +225 -0
  445. chronaxis/guide/en/fields/mapping/analysis-all-35.json +228 -0
  446. chronaxis/guide/en/fields/mapping/analysis-all-36.json +226 -0
  447. chronaxis/guide/en/fields/mapping/analysis-all-37.json +244 -0
  448. chronaxis/guide/en/fields/mapping/analysis-all-38.json +326 -0
  449. chronaxis/guide/en/fields/mapping/analysis-all-39.json +299 -0
  450. chronaxis/guide/en/fields/mapping/analysis-all-4.json +297 -0
  451. chronaxis/guide/en/fields/mapping/analysis-all-40.json +311 -0
  452. chronaxis/guide/en/fields/mapping/analysis-all-41.json +310 -0
  453. chronaxis/guide/en/fields/mapping/analysis-all-42.json +346 -0
  454. chronaxis/guide/en/fields/mapping/analysis-all-43.json +267 -0
  455. chronaxis/guide/en/fields/mapping/analysis-all-44.json +327 -0
  456. chronaxis/guide/en/fields/mapping/analysis-all-45.json +279 -0
  457. chronaxis/guide/en/fields/mapping/analysis-all-46.json +327 -0
  458. chronaxis/guide/en/fields/mapping/analysis-all-47.json +312 -0
  459. chronaxis/guide/en/fields/mapping/analysis-all-48.json +294 -0
  460. chronaxis/guide/en/fields/mapping/analysis-all-49.json +253 -0
  461. chronaxis/guide/en/fields/mapping/analysis-all-5.json +312 -0
  462. chronaxis/guide/en/fields/mapping/analysis-all-50.json +346 -0
  463. chronaxis/guide/en/fields/mapping/analysis-all-51.json +324 -0
  464. chronaxis/guide/en/fields/mapping/analysis-all-52.json +335 -0
  465. chronaxis/guide/en/fields/mapping/analysis-all-53.json +317 -0
  466. chronaxis/guide/en/fields/mapping/analysis-all-54.json +316 -0
  467. chronaxis/guide/en/fields/mapping/analysis-all-55.json +302 -0
  468. chronaxis/guide/en/fields/mapping/analysis-all-56.json +319 -0
  469. chronaxis/guide/en/fields/mapping/analysis-all-57.json +334 -0
  470. chronaxis/guide/en/fields/mapping/analysis-all-58.json +333 -0
  471. chronaxis/guide/en/fields/mapping/analysis-all-59.json +359 -0
  472. chronaxis/guide/en/fields/mapping/analysis-all-6.json +327 -0
  473. chronaxis/guide/en/fields/mapping/analysis-all-60.json +303 -0
  474. chronaxis/guide/en/fields/mapping/analysis-all-61.json +326 -0
  475. chronaxis/guide/en/fields/mapping/analysis-all-62.json +301 -0
  476. chronaxis/guide/en/fields/mapping/analysis-all-63.json +326 -0
  477. chronaxis/guide/en/fields/mapping/analysis-all-64.json +367 -0
  478. chronaxis/guide/en/fields/mapping/analysis-all-65.json +334 -0
  479. chronaxis/guide/en/fields/mapping/analysis-all-66.json +358 -0
  480. chronaxis/guide/en/fields/mapping/analysis-all-67.json +349 -0
  481. chronaxis/guide/en/fields/mapping/analysis-all-68.json +331 -0
  482. chronaxis/guide/en/fields/mapping/analysis-all-69.json +304 -0
  483. chronaxis/guide/en/fields/mapping/analysis-all-7.json +303 -0
  484. chronaxis/guide/en/fields/mapping/analysis-all-70.json +349 -0
  485. chronaxis/guide/en/fields/mapping/analysis-all-71.json +288 -0
  486. chronaxis/guide/en/fields/mapping/analysis-all-72.json +316 -0
  487. chronaxis/guide/en/fields/mapping/analysis-all-73.json +266 -0
  488. chronaxis/guide/en/fields/mapping/analysis-all-74.json +227 -0
  489. chronaxis/guide/en/fields/mapping/analysis-all-75.json +239 -0
  490. chronaxis/guide/en/fields/mapping/analysis-all-76.json +274 -0
  491. chronaxis/guide/en/fields/mapping/analysis-all-77.json +380 -0
  492. chronaxis/guide/en/fields/mapping/analysis-all-78.json +313 -0
  493. chronaxis/guide/en/fields/mapping/analysis-all-79.json +338 -0
  494. chronaxis/guide/en/fields/mapping/analysis-all-8.json +292 -0
  495. chronaxis/guide/en/fields/mapping/analysis-all-80.json +304 -0
  496. chronaxis/guide/en/fields/mapping/analysis-all-81.json +140 -0
  497. chronaxis/guide/en/fields/mapping/analysis-all-9.json +332 -0
  498. chronaxis/guide/en/fields/mapping/io_policy-all-1.json +19 -0
  499. chronaxis/guide/en/fields/mapping/mapping_version-all-1.json +19 -0
  500. chronaxis/guide/en/fields/mapping/path_base-all-1.json +19 -0
  501. chronaxis/guide/en/fields/mapping/sections-all-1.json +402 -0
  502. chronaxis/guide/en/fields/mapping/sections-all-2.json +232 -0
  503. chronaxis/guide/en/semantics.md +70 -0
  504. chronaxis/guide/en/tasks.json +290 -0
  505. chronaxis/guide/en/workflow.md +41 -0
  506. chronaxis/guide/examples/analysis-imports.yaml +22 -0
  507. chronaxis/guide/examples/analysis.yaml +23 -0
  508. chronaxis/guide/examples/batch-minimal.yaml +3 -0
  509. chronaxis/guide/examples/conditional-energy.yaml +36 -0
  510. chronaxis/guide/examples/data/activity.csv +6 -0
  511. chronaxis/guide/examples/data/can/activity.asc +11 -0
  512. chronaxis/guide/examples/data/can/calculation-minimal.asc +6 -0
  513. chronaxis/guide/examples/data/can/conditional-energy/part-1.asc +92 -0
  514. chronaxis/guide/examples/data/can/conditional-energy/part-2.asc +36 -0
  515. chronaxis/guide/examples/data/can/conditional-energy/signals.dbc +10 -0
  516. chronaxis/guide/examples/data/can/execution-comparison.asc +12 -0
  517. chronaxis/guide/examples/data/can/execution-report.asc +4 -0
  518. chronaxis/guide/examples/data/can/expression-extended.asc +11 -0
  519. chronaxis/guide/examples/data/can/interval-actual.asc +6 -0
  520. chronaxis/guide/examples/data/can/preset-charge-energy.asc +15 -0
  521. chronaxis/guide/examples/data/can/preset-charge-minimal.asc +11 -0
  522. chronaxis/guide/examples/data/can/preset-command-automatic.asc +11 -0
  523. chronaxis/guide/examples/data/can/preset-fault-context.asc +7 -0
  524. chronaxis/guide/examples/data/can/preset-threshold-delay.asc +7 -0
  525. chronaxis/guide/examples/data/can/preset-threshold-partial.asc +7 -0
  526. chronaxis/guide/examples/data/can/quality.asc +6 -0
  527. chronaxis/guide/examples/data/can/quickstart-parts/part1.asc +4 -0
  528. chronaxis/guide/examples/data/can/quickstart-parts/part2.asc +3 -0
  529. chronaxis/guide/examples/data/can/quickstart.asc +6 -0
  530. chronaxis/guide/examples/data/can/rule-condition_duration-extended.asc +35 -0
  531. chronaxis/guide/examples/data/can/rule-condition_duration-minimal.asc +19 -0
  532. chronaxis/guide/examples/data/can/rule-debounce-extended.asc +19 -0
  533. chronaxis/guide/examples/data/can/rule-falling_edge-extended.asc +35 -0
  534. chronaxis/guide/examples/data/can/rule-hysteresis-extended.asc +19 -0
  535. chronaxis/guide/examples/data/can/rule-start_end-extended.asc +35 -0
  536. chronaxis/guide/examples/data/can/rule-start_only-extended.asc +19 -0
  537. chronaxis/guide/examples/data/can/rule-window_delta-extended.asc +19 -0
  538. chronaxis/guide/examples/data/can/sequence-outcomes.asc +19 -0
  539. chronaxis/guide/examples/data/can/signal-types.asc +13 -0
  540. chronaxis/guide/examples/data/can/start-end.asc +30 -0
  541. chronaxis/guide/examples/data/can/teaching-base.asc +58 -0
  542. chronaxis/guide/examples/data/can/teaching.dbc +53 -0
  543. chronaxis/guide/examples/data/joint-current.csv +5 -0
  544. chronaxis/guide/examples/data/joint.asc +5 -0
  545. chronaxis/guide/examples/data/joint.dbc +7 -0
  546. chronaxis/guide/examples/data/message-clean.asc +6 -0
  547. chronaxis/guide/examples/data/message-direction.asc +7 -0
  548. chronaxis/guide/examples/data/message-direction.dbc +7 -0
  549. chronaxis/guide/examples/data/power.blf +0 -0
  550. chronaxis/guide/examples/data/power.dbc +6 -0
  551. chronaxis/guide/examples/data/quality.csv +5 -0
  552. chronaxis/guide/examples/data/raw-can-example.csv +5 -0
  553. chronaxis/guide/examples/data/signal-types.csv +5 -0
  554. chronaxis/guide/examples/data/signals.csv +6 -0
  555. chronaxis/guide/examples/data/timing.asc +6 -0
  556. chronaxis/guide/examples/data/timing.dbc +11 -0
  557. chronaxis/guide/examples/export-can-minimal.yaml +24 -0
  558. chronaxis/guide/examples/input-csv-minimal.yaml +23 -0
  559. chronaxis/guide/examples/preset-charge-energy.yaml +41 -0
  560. chronaxis/guide/examples/preset-charge-minimal.yaml +31 -0
  561. chronaxis/guide/examples/preset-fault-context.yaml +27 -0
  562. chronaxis/guide/examples/quality.yaml +19 -0
  563. chronaxis/guide/examples/sequence-outcomes.yaml +39 -0
  564. chronaxis/guide/examples/shared/definitions.yaml +14 -0
  565. chronaxis/guide/examples/signal-enum-minimal.yaml +19 -0
  566. chronaxis/guide/examples/signal-number-conversion.yaml +24 -0
  567. chronaxis/guide/examples/window-merged.yaml +28 -0
  568. chronaxis/guide/fields/analysis/calculations-all-1.json +360 -0
  569. chronaxis/guide/fields/analysis/calculations-all-2.json +299 -0
  570. chronaxis/guide/fields/analysis/calculations-all-3.json +70 -0
  571. chronaxis/guide/fields/analysis/config_version-all-1.json +24 -0
  572. chronaxis/guide/fields/analysis/dataset-all-1.json +344 -0
  573. chronaxis/guide/fields/analysis/derived-all-1.json +147 -0
  574. chronaxis/guide/fields/analysis/diagnostics-all-1.json +69 -0
  575. chronaxis/guide/fields/analysis/execution-all-1.json +167 -0
  576. chronaxis/guide/fields/analysis/imports-all-1.json +39 -0
  577. chronaxis/guide/fields/analysis/intervals-all-1.json +173 -0
  578. chronaxis/guide/fields/analysis/message_calculations-all-1.json +360 -0
  579. chronaxis/guide/fields/analysis/message_calculations-all-2.json +255 -0
  580. chronaxis/guide/fields/analysis/metadata-all-1.json +24 -0
  581. chronaxis/guide/fields/analysis/outputs-all-1.json +349 -0
  582. chronaxis/guide/fields/analysis/outputs-all-2.json +302 -0
  583. chronaxis/guide/fields/analysis/outputs-all-3.json +321 -0
  584. chronaxis/guide/fields/analysis/outputs-all-4.json +253 -0
  585. chronaxis/guide/fields/analysis/outputs-all-5.json +244 -0
  586. chronaxis/guide/fields/analysis/outputs-all-6.json +199 -0
  587. chronaxis/guide/fields/analysis/overrides-all-1.json +104 -0
  588. chronaxis/guide/fields/analysis/presets-charge_session-1.json +398 -0
  589. chronaxis/guide/fields/analysis/presets-charge_session-2.json +114 -0
  590. chronaxis/guide/fields/analysis/presets-command_response-1.json +376 -0
  591. chronaxis/guide/fields/analysis/presets-fault_context-1.json +285 -0
  592. chronaxis/guide/fields/analysis/presets-threshold_excursion-1.json +317 -0
  593. chronaxis/guide/fields/analysis/rules-condition_duration-1.json +344 -0
  594. chronaxis/guide/fields/analysis/rules-condition_duration-2.json +27 -0
  595. chronaxis/guide/fields/analysis/rules-debounce-1.json +335 -0
  596. chronaxis/guide/fields/analysis/rules-falling_edge-1.json +317 -0
  597. chronaxis/guide/fields/analysis/rules-hysteresis-1.json +334 -0
  598. chronaxis/guide/fields/analysis/rules-hysteresis-2.json +27 -0
  599. chronaxis/guide/fields/analysis/rules-rising_edge-1.json +317 -0
  600. chronaxis/guide/fields/analysis/rules-start_end-1.json +349 -0
  601. chronaxis/guide/fields/analysis/rules-start_end-2.json +44 -0
  602. chronaxis/guide/fields/analysis/rules-start_only-1.json +334 -0
  603. chronaxis/guide/fields/analysis/rules-window_delta-1.json +356 -0
  604. chronaxis/guide/fields/analysis/rules-window_delta-2.json +78 -0
  605. chronaxis/guide/fields/analysis/sequences-all-1.json +394 -0
  606. chronaxis/guide/fields/analysis/sequences-all-2.json +54 -0
  607. chronaxis/guide/fields/analysis/signals-variant-1-1.json +349 -0
  608. chronaxis/guide/fields/analysis/signals-variant-1-2.json +297 -0
  609. chronaxis/guide/fields/analysis/signals-variant-1-3.json +340 -0
  610. chronaxis/guide/fields/analysis/signals-variant-1-4.json +175 -0
  611. chronaxis/guide/fields/analysis/signals-variant-2-1.json +327 -0
  612. chronaxis/guide/fields/analysis/signals-variant-2-2.json +335 -0
  613. chronaxis/guide/fields/analysis/signals-variant-2-3.json +289 -0
  614. chronaxis/guide/fields/analysis/signals-variant-2-4.json +270 -0
  615. chronaxis/guide/fields/analysis/sources-can_asc-1.json +318 -0
  616. chronaxis/guide/fields/analysis/sources-can_asc-2.json +310 -0
  617. chronaxis/guide/fields/analysis/sources-can_asc-3.json +311 -0
  618. chronaxis/guide/fields/analysis/sources-can_asc-4.json +69 -0
  619. chronaxis/guide/fields/analysis/sources-can_blf-1.json +317 -0
  620. chronaxis/guide/fields/analysis/sources-can_blf-2.json +310 -0
  621. chronaxis/guide/fields/analysis/sources-can_blf-3.json +317 -0
  622. chronaxis/guide/fields/analysis/sources-memory-1.json +347 -0
  623. chronaxis/guide/fields/analysis/sources-memory-2.json +110 -0
  624. chronaxis/guide/fields/analysis/sources-raw_can_csv-1.json +330 -0
  625. chronaxis/guide/fields/analysis/sources-raw_can_csv-10.json +233 -0
  626. chronaxis/guide/fields/analysis/sources-raw_can_csv-11.json +225 -0
  627. chronaxis/guide/fields/analysis/sources-raw_can_csv-12.json +228 -0
  628. chronaxis/guide/fields/analysis/sources-raw_can_csv-13.json +226 -0
  629. chronaxis/guide/fields/analysis/sources-raw_can_csv-14.json +230 -0
  630. chronaxis/guide/fields/analysis/sources-raw_can_csv-15.json +227 -0
  631. chronaxis/guide/fields/analysis/sources-raw_can_csv-16.json +230 -0
  632. chronaxis/guide/fields/analysis/sources-raw_can_csv-17.json +238 -0
  633. chronaxis/guide/fields/analysis/sources-raw_can_csv-18.json +239 -0
  634. chronaxis/guide/fields/analysis/sources-raw_can_csv-19.json +233 -0
  635. chronaxis/guide/fields/analysis/sources-raw_can_csv-2.json +310 -0
  636. chronaxis/guide/fields/analysis/sources-raw_can_csv-20.json +242 -0
  637. chronaxis/guide/fields/analysis/sources-raw_can_csv-21.json +230 -0
  638. chronaxis/guide/fields/analysis/sources-raw_can_csv-22.json +228 -0
  639. chronaxis/guide/fields/analysis/sources-raw_can_csv-23.json +230 -0
  640. chronaxis/guide/fields/analysis/sources-raw_can_csv-24.json +223 -0
  641. chronaxis/guide/fields/analysis/sources-raw_can_csv-25.json +290 -0
  642. chronaxis/guide/fields/analysis/sources-raw_can_csv-26.json +131 -0
  643. chronaxis/guide/fields/analysis/sources-raw_can_csv-3.json +297 -0
  644. chronaxis/guide/fields/analysis/sources-raw_can_csv-4.json +226 -0
  645. chronaxis/guide/fields/analysis/sources-raw_can_csv-5.json +230 -0
  646. chronaxis/guide/fields/analysis/sources-raw_can_csv-6.json +227 -0
  647. chronaxis/guide/fields/analysis/sources-raw_can_csv-7.json +230 -0
  648. chronaxis/guide/fields/analysis/sources-raw_can_csv-8.json +238 -0
  649. chronaxis/guide/fields/analysis/sources-raw_can_csv-9.json +239 -0
  650. chronaxis/guide/fields/analysis/sources-signal_csv-1.json +331 -0
  651. chronaxis/guide/fields/analysis/sources-signal_csv-2.json +327 -0
  652. chronaxis/guide/fields/analysis/sources-signal_csv-3.json +295 -0
  653. chronaxis/guide/fields/analysis/sources-variant-6-1.json +319 -0
  654. chronaxis/guide/fields/analysis/sources-variant-6-2.json +327 -0
  655. chronaxis/guide/fields/analysis/sources-variant-6-3.json +314 -0
  656. chronaxis/guide/fields/analysis/sources-variant-6-4.json +91 -0
  657. chronaxis/guide/fields/analysis/windows-all-1.json +361 -0
  658. chronaxis/guide/fields/analysis/windows-all-2.json +187 -0
  659. chronaxis/guide/fields/batch/backend-all-1.json +26 -0
  660. chronaxis/guide/fields/batch/batch_version-all-1.json +22 -0
  661. chronaxis/guide/fields/batch/fail_fast-all-1.json +22 -0
  662. chronaxis/guide/fields/batch/inputs-all-1.json +161 -0
  663. chronaxis/guide/fields/batch/jobs-all-1.json +58 -0
  664. chronaxis/guide/fields/batch/process_count-all-1.json +23 -0
  665. chronaxis/guide/fields/batch/source-all-1.json +22 -0
  666. chronaxis/guide/fields/batch/template-all-1.json +22 -0
  667. chronaxis/guide/fields/definitions/derived-all-1.json +121 -0
  668. chronaxis/guide/fields/definitions/signals-all-1.json +336 -0
  669. chronaxis/guide/fields/definitions/signals-all-2.json +307 -0
  670. chronaxis/guide/fields/definitions/signals-all-3.json +305 -0
  671. chronaxis/guide/fields/definitions/signals-all-4.json +352 -0
  672. chronaxis/guide/fields/definitions/signals-all-5.json +311 -0
  673. chronaxis/guide/fields/definitions/signals-all-6.json +254 -0
  674. chronaxis/guide/fields/definitions/signals-all-7.json +88 -0
  675. chronaxis/guide/fields/definitions/sources-all-1.json +332 -0
  676. chronaxis/guide/fields/definitions/sources-all-10.json +307 -0
  677. chronaxis/guide/fields/definitions/sources-all-11.json +280 -0
  678. chronaxis/guide/fields/definitions/sources-all-12.json +209 -0
  679. chronaxis/guide/fields/definitions/sources-all-13.json +219 -0
  680. chronaxis/guide/fields/definitions/sources-all-14.json +213 -0
  681. chronaxis/guide/fields/definitions/sources-all-15.json +212 -0
  682. chronaxis/guide/fields/definitions/sources-all-16.json +232 -0
  683. chronaxis/guide/fields/definitions/sources-all-17.json +213 -0
  684. chronaxis/guide/fields/definitions/sources-all-18.json +212 -0
  685. chronaxis/guide/fields/definitions/sources-all-19.json +217 -0
  686. chronaxis/guide/fields/definitions/sources-all-2.json +336 -0
  687. chronaxis/guide/fields/definitions/sources-all-20.json +228 -0
  688. chronaxis/guide/fields/definitions/sources-all-21.json +212 -0
  689. chronaxis/guide/fields/definitions/sources-all-22.json +232 -0
  690. chronaxis/guide/fields/definitions/sources-all-23.json +213 -0
  691. chronaxis/guide/fields/definitions/sources-all-24.json +212 -0
  692. chronaxis/guide/fields/definitions/sources-all-25.json +217 -0
  693. chronaxis/guide/fields/definitions/sources-all-26.json +228 -0
  694. chronaxis/guide/fields/definitions/sources-all-27.json +212 -0
  695. chronaxis/guide/fields/definitions/sources-all-28.json +217 -0
  696. chronaxis/guide/fields/definitions/sources-all-29.json +227 -0
  697. chronaxis/guide/fields/definitions/sources-all-3.json +306 -0
  698. chronaxis/guide/fields/definitions/sources-all-30.json +333 -0
  699. chronaxis/guide/fields/definitions/sources-all-31.json +302 -0
  700. chronaxis/guide/fields/definitions/sources-all-32.json +319 -0
  701. chronaxis/guide/fields/definitions/sources-all-33.json +89 -0
  702. chronaxis/guide/fields/definitions/sources-all-4.json +336 -0
  703. chronaxis/guide/fields/definitions/sources-all-5.json +313 -0
  704. chronaxis/guide/fields/definitions/sources-all-6.json +292 -0
  705. chronaxis/guide/fields/definitions/sources-all-7.json +319 -0
  706. chronaxis/guide/fields/definitions/sources-all-8.json +315 -0
  707. chronaxis/guide/fields/definitions/sources-all-9.json +318 -0
  708. chronaxis/guide/fields/index.json +3432 -0
  709. chronaxis/guide/fields/mapping/aliases-all-1.json +91 -0
  710. chronaxis/guide/fields/mapping/analysis-all-1.json +382 -0
  711. chronaxis/guide/fields/mapping/analysis-all-10.json +307 -0
  712. chronaxis/guide/fields/mapping/analysis-all-11.json +311 -0
  713. chronaxis/guide/fields/mapping/analysis-all-12.json +329 -0
  714. chronaxis/guide/fields/mapping/analysis-all-13.json +294 -0
  715. chronaxis/guide/fields/mapping/analysis-all-14.json +311 -0
  716. chronaxis/guide/fields/mapping/analysis-all-15.json +280 -0
  717. chronaxis/guide/fields/mapping/analysis-all-16.json +227 -0
  718. chronaxis/guide/fields/mapping/analysis-all-17.json +230 -0
  719. chronaxis/guide/fields/mapping/analysis-all-18.json +221 -0
  720. chronaxis/guide/fields/mapping/analysis-all-19.json +237 -0
  721. chronaxis/guide/fields/mapping/analysis-all-2.json +342 -0
  722. chronaxis/guide/fields/mapping/analysis-all-20.json +233 -0
  723. chronaxis/guide/fields/mapping/analysis-all-21.json +244 -0
  724. chronaxis/guide/fields/mapping/analysis-all-22.json +228 -0
  725. chronaxis/guide/fields/mapping/analysis-all-23.json +226 -0
  726. chronaxis/guide/fields/mapping/analysis-all-24.json +230 -0
  727. chronaxis/guide/fields/mapping/analysis-all-25.json +227 -0
  728. chronaxis/guide/fields/mapping/analysis-all-26.json +230 -0
  729. chronaxis/guide/fields/mapping/analysis-all-27.json +221 -0
  730. chronaxis/guide/fields/mapping/analysis-all-28.json +237 -0
  731. chronaxis/guide/fields/mapping/analysis-all-29.json +233 -0
  732. chronaxis/guide/fields/mapping/analysis-all-3.json +322 -0
  733. chronaxis/guide/fields/mapping/analysis-all-30.json +244 -0
  734. chronaxis/guide/fields/mapping/analysis-all-31.json +228 -0
  735. chronaxis/guide/fields/mapping/analysis-all-32.json +226 -0
  736. chronaxis/guide/fields/mapping/analysis-all-33.json +230 -0
  737. chronaxis/guide/fields/mapping/analysis-all-34.json +227 -0
  738. chronaxis/guide/fields/mapping/analysis-all-35.json +230 -0
  739. chronaxis/guide/fields/mapping/analysis-all-36.json +221 -0
  740. chronaxis/guide/fields/mapping/analysis-all-37.json +291 -0
  741. chronaxis/guide/fields/mapping/analysis-all-38.json +315 -0
  742. chronaxis/guide/fields/mapping/analysis-all-39.json +304 -0
  743. chronaxis/guide/fields/mapping/analysis-all-4.json +312 -0
  744. chronaxis/guide/fields/mapping/analysis-all-40.json +307 -0
  745. chronaxis/guide/fields/mapping/analysis-all-41.json +292 -0
  746. chronaxis/guide/fields/mapping/analysis-all-42.json +333 -0
  747. chronaxis/guide/fields/mapping/analysis-all-43.json +296 -0
  748. chronaxis/guide/fields/mapping/analysis-all-44.json +322 -0
  749. chronaxis/guide/fields/mapping/analysis-all-45.json +298 -0
  750. chronaxis/guide/fields/mapping/analysis-all-46.json +347 -0
  751. chronaxis/guide/fields/mapping/analysis-all-47.json +302 -0
  752. chronaxis/guide/fields/mapping/analysis-all-48.json +263 -0
  753. chronaxis/guide/fields/mapping/analysis-all-49.json +301 -0
  754. chronaxis/guide/fields/mapping/analysis-all-5.json +313 -0
  755. chronaxis/guide/fields/mapping/analysis-all-50.json +336 -0
  756. chronaxis/guide/fields/mapping/analysis-all-51.json +335 -0
  757. chronaxis/guide/fields/mapping/analysis-all-52.json +335 -0
  758. chronaxis/guide/fields/mapping/analysis-all-53.json +334 -0
  759. chronaxis/guide/fields/mapping/analysis-all-54.json +339 -0
  760. chronaxis/guide/fields/mapping/analysis-all-55.json +335 -0
  761. chronaxis/guide/fields/mapping/analysis-all-56.json +336 -0
  762. chronaxis/guide/fields/mapping/analysis-all-57.json +335 -0
  763. chronaxis/guide/fields/mapping/analysis-all-58.json +333 -0
  764. chronaxis/guide/fields/mapping/analysis-all-59.json +325 -0
  765. chronaxis/guide/fields/mapping/analysis-all-6.json +323 -0
  766. chronaxis/guide/fields/mapping/analysis-all-60.json +334 -0
  767. chronaxis/guide/fields/mapping/analysis-all-61.json +311 -0
  768. chronaxis/guide/fields/mapping/analysis-all-62.json +289 -0
  769. chronaxis/guide/fields/mapping/analysis-all-63.json +383 -0
  770. chronaxis/guide/fields/mapping/analysis-all-64.json +357 -0
  771. chronaxis/guide/fields/mapping/analysis-all-65.json +375 -0
  772. chronaxis/guide/fields/mapping/analysis-all-66.json +351 -0
  773. chronaxis/guide/fields/mapping/analysis-all-67.json +346 -0
  774. chronaxis/guide/fields/mapping/analysis-all-68.json +317 -0
  775. chronaxis/guide/fields/mapping/analysis-all-69.json +313 -0
  776. chronaxis/guide/fields/mapping/analysis-all-7.json +306 -0
  777. chronaxis/guide/fields/mapping/analysis-all-70.json +326 -0
  778. chronaxis/guide/fields/mapping/analysis-all-71.json +316 -0
  779. chronaxis/guide/fields/mapping/analysis-all-72.json +264 -0
  780. chronaxis/guide/fields/mapping/analysis-all-73.json +228 -0
  781. chronaxis/guide/fields/mapping/analysis-all-74.json +241 -0
  782. chronaxis/guide/fields/mapping/analysis-all-75.json +273 -0
  783. chronaxis/guide/fields/mapping/analysis-all-76.json +382 -0
  784. chronaxis/guide/fields/mapping/analysis-all-77.json +328 -0
  785. chronaxis/guide/fields/mapping/analysis-all-78.json +338 -0
  786. chronaxis/guide/fields/mapping/analysis-all-79.json +304 -0
  787. chronaxis/guide/fields/mapping/analysis-all-8.json +309 -0
  788. chronaxis/guide/fields/mapping/analysis-all-80.json +140 -0
  789. chronaxis/guide/fields/mapping/analysis-all-9.json +329 -0
  790. chronaxis/guide/fields/mapping/io_policy-all-1.json +19 -0
  791. chronaxis/guide/fields/mapping/mapping_version-all-1.json +19 -0
  792. chronaxis/guide/fields/mapping/path_base-all-1.json +19 -0
  793. chronaxis/guide/fields/mapping/sections-all-1.json +402 -0
  794. chronaxis/guide/fields/mapping/sections-all-2.json +232 -0
  795. chronaxis/guide/lookup.py +90 -0
  796. chronaxis/guide/manifest.json +614 -0
  797. chronaxis/guide/run_analysis.py +34 -0
  798. chronaxis/guide/schemas/analysis.schema.json +8451 -0
  799. chronaxis/guide/schemas/batch-v1.schema.json +172 -0
  800. chronaxis/guide/schemas/definitions.schema.json +29 -0
  801. chronaxis/guide/schemas/legacy-import-v1.schema.json +143 -0
  802. chronaxis/guide/semantics.md +62 -0
  803. chronaxis/guide/tasks.json +290 -0
  804. chronaxis/guide/workflow.md +38 -0
  805. chronaxis/legacy/__init__.py +46 -0
  806. chronaxis/legacy/batch_read.py +412 -0
  807. chronaxis/legacy/batch_validation.py +134 -0
  808. chronaxis/legacy/batch_wire.py +264 -0
  809. chronaxis/legacy/batch_worker.py +417 -0
  810. chronaxis/legacy/binding.py +154 -0
  811. chronaxis/legacy/dbc_cycles.py +47 -0
  812. chronaxis/legacy/decode_policy.py +28 -0
  813. chronaxis/legacy/disjunction.py +79 -0
  814. chronaxis/legacy/export_worker.py +147 -0
  815. chronaxis/legacy/export_write.py +378 -0
  816. chronaxis/legacy/message_store.py +562 -0
  817. chronaxis/legacy/process_read.py +526 -0
  818. chronaxis/legacy/raw_store.py +341 -0
  819. chronaxis/legacy/records.py +709 -0
  820. chronaxis/legacy/required_records.py +122 -0
  821. chronaxis/legacy/sum.py +403 -0
  822. chronaxis/legacy/sum_numpy.py +43 -0
  823. chronaxis/legacy/updates.py +277 -0
  824. chronaxis/legacy/vendor/sclicer_functions_v1/can_processor.py +138 -0
  825. chronaxis/legacy/vendor/sclicer_functions_v1/file_processor.py +218 -0
  826. chronaxis/legacy/vendor/sclicer_functions_v1/utils.py +447 -0
  827. chronaxis/legacy/worker.py +352 -0
  828. chronaxis/migration/__init__.py +11 -0
  829. chronaxis/migration/api.py +270 -0
  830. chronaxis/migration/ini.py +110 -0
  831. chronaxis/migration/legacy_sum.py +304 -0
  832. chronaxis/migration/models.py +83 -0
  833. chronaxis/migration/publication.py +230 -0
  834. chronaxis/migration/sclicer.py +241 -0
  835. chronaxis/migration/slope.py +78 -0
  836. chronaxis/migration/start_end.py +48 -0
  837. chronaxis/planning/__init__.py +19 -0
  838. chronaxis/planning/channels.py +30 -0
  839. chronaxis/planning/checks.py +447 -0
  840. chronaxis/planning/config_groups.py +215 -0
  841. chronaxis/planning/dbc_defaults.py +88 -0
  842. chronaxis/planning/export_options.py +247 -0
  843. chronaxis/planning/input_defaults.py +62 -0
  844. chronaxis/planning/input_paths.py +124 -0
  845. chronaxis/planning/input_requirements.py +250 -0
  846. chronaxis/planning/inputs.py +306 -0
  847. chronaxis/planning/intervals.py +242 -0
  848. chronaxis/planning/legacy_execution.py +38 -0
  849. chronaxis/planning/message_calculations.py +171 -0
  850. chronaxis/planning/models.py +369 -0
  851. chronaxis/planning/nodes.py +355 -0
  852. chronaxis/planning/plan.py +294 -0
  853. chronaxis/planning/preset_models.py +211 -0
  854. chronaxis/planning/record_execution.py +76 -0
  855. chronaxis/planning/reports.py +523 -0
  856. chronaxis/planning/sequences.py +91 -0
  857. chronaxis/planning/signal_groups.py +61 -0
  858. chronaxis/planning/signal_validity.py +46 -0
  859. chronaxis/planning/text_inputs.py +110 -0
  860. chronaxis/presets.py +270 -0
  861. chronaxis/results/__init__.py +34 -0
  862. chronaxis/results/analysis_outcome.py +67 -0
  863. chronaxis/results/artifact_exports.py +212 -0
  864. chronaxis/results/binding_metadata.py +54 -0
  865. chronaxis/results/budget.py +138 -0
  866. chronaxis/results/can_metadata.py +247 -0
  867. chronaxis/results/codec.py +246 -0
  868. chronaxis/results/errors.py +25 -0
  869. chronaxis/results/export_files.py +216 -0
  870. chronaxis/results/frame_exports.py +299 -0
  871. chronaxis/results/frame_patch.py +186 -0
  872. chronaxis/results/frame_rebuild.py +458 -0
  873. chronaxis/results/frame_sort.py +223 -0
  874. chronaxis/results/input_diagnostics.py +51 -0
  875. chronaxis/results/manifest.py +343 -0
  876. chronaxis/results/merge_runs.py +207 -0
  877. chronaxis/results/owned_directory.py +32 -0
  878. chronaxis/results/raw_exports.py +689 -0
  879. chronaxis/results/readable.py +355 -0
  880. chronaxis/results/readable_format.py +94 -0
  881. chronaxis/results/result.py +734 -0
  882. chronaxis/results/rows.py +57 -0
  883. chronaxis/results/signal_exports.py +209 -0
  884. chronaxis/results/signal_grid.py +219 -0
  885. chronaxis/results/spool.py +421 -0
  886. chronaxis/results/summary.py +350 -0
  887. chronaxis/results/text_can_metadata.py +64 -0
  888. chronaxis/results/threshold_metadata.py +105 -0
  889. chronaxis/runner.py +121 -0
  890. chronaxis/sources/__init__.py +23 -0
  891. chronaxis/sources/asc.py +412 -0
  892. chronaxis/sources/blf.py +101 -0
  893. chronaxis/sources/can_spec.py +179 -0
  894. chronaxis/sources/can_updates.py +160 -0
  895. chronaxis/sources/csv_spec.py +133 -0
  896. chronaxis/sources/descriptions.py +65 -0
  897. chronaxis/sources/memory.py +299 -0
  898. chronaxis/sources/models.py +497 -0
  899. chronaxis/sources/packing.py +170 -0
  900. chronaxis/sources/protocol.py +221 -0
  901. chronaxis/sources/raw_can.py +62 -0
  902. chronaxis/sources/raw_csv.py +470 -0
  903. chronaxis/sources/raw_csv_layout.py +310 -0
  904. chronaxis/sources/signal_csv.py +608 -0
  905. chronaxis/sources/text_can_decode.py +421 -0
  906. chronaxis/sources/text_can_ref.py +48 -0
  907. chronaxis/sources/text_can_spec.py +61 -0
  908. chronaxis/timebase/__init__.py +19 -0
  909. chronaxis/timebase/conversion.py +364 -0
  910. chronaxis/timebase/numpy_ops.py +104 -0
  911. chronaxis/user_guide.py +81 -0
  912. chronaxis-0.1.0.dev0.dist-info/METADATA +172 -0
  913. chronaxis-0.1.0.dev0.dist-info/RECORD +917 -0
  914. chronaxis-0.1.0.dev0.dist-info/WHEEL +5 -0
  915. chronaxis-0.1.0.dev0.dist-info/entry_points.txt +2 -0
  916. chronaxis-0.1.0.dev0.dist-info/licenses/LICENSE +21 -0
  917. chronaxis-0.1.0.dev0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,709 @@
1
+ """冻结单BLF原公开函数链的报文、解码值、定位和有界IPC协议。
2
+
3
+ 输入为同次can.Message的公开写出字段、原parse_frame返回值与用户定位声明;
4
+ 输出是冻结dataclass及最大65536字节的JSON包。data以hex无损表达,非有限
5
+ 解码浮点使用明确标签;不执行eval、pickle或任意模型反序列化,不应用DBC缩放。
6
+ 本文件只依赖标准库,无来源/DBC读取或进程副作用。父进程承担wire/记录副本预算,
7
+ worker在INIT后才加载真实库;记录模型不声称原reader已关闭或旧进程RSS受控。
8
+ """
9
+
10
+ # 模型和wire不导入CAN库或数值核心,spawn加载本文件不会提前打开用户输入。
11
+ from collections.abc import Mapping
12
+ from dataclasses import dataclass
13
+ import json
14
+ from math import isfinite, isnan
15
+ from pathlib import Path
16
+ from re import fullmatch
17
+ from types import MappingProxyType
18
+
19
+ # profile和wire限额是本协议固定事实,不是旧CAN解析参数。
20
+ PROFILE_ID = 'sclicer-functions-v1'
21
+ MAX_WIRE_BYTES = 65536
22
+ _RAW_FIELDS = ('timestamp', 'arbitration_id', 'is_extended_id', 'is_remote_frame', 'is_error_frame',
23
+ 'channel', 'dlc', 'is_fd', 'is_rx', 'bitrate_switch', 'error_state_indicator')
24
+ _LOCATOR_FIELDS = ('channel', 'signal', 'frame_id', 'is_extended', 'is_fd')
25
+
26
+
27
+ def normalize_frame_id(value):
28
+ """将配置报文ID统一成整数;无前缀始终按十进制。
29
+
30
+ 参数: value为原生int或十进制、0x十六进制、0b二进制文本。
31
+ 返回: 0至0x1FFFFFFF的原生int。异常: TypeError为其他类型;ValueError为格式或范围非法。
32
+ 副作用: 无;不用于ASC等原始文件的专有进制解析。
33
+ """
34
+ # bool也是int子类,必须先按精确类型排除,不能把开关当报文ID。
35
+ if type(value) is str:
36
+ if fullmatch(r'[0-9]+', value):
37
+ value = int(value, 10)
38
+ elif fullmatch(r'0[xX][0-9a-fA-F]+', value):
39
+ value = int(value[2:], 16)
40
+ elif fullmatch(r'0[bB][01]+', value):
41
+ value = int(value[2:], 2)
42
+ else:
43
+ raise ValueError('frame_id需要十进制整数、0x十六进制或0b二进制')
44
+ elif type(value) is not int:
45
+ raise TypeError('frame_id需要整数或进制文本,不接受bool或浮点数')
46
+ # 范围只证明是合法CAN数值;小ID仍可能是扩展帧,不在这里猜类型。
47
+ if not 0 <= value <= 0x1FFFFFFF:
48
+ raise ValueError('frame_id超出CAN范围0至0x1FFFFFFF')
49
+ return value
50
+
51
+
52
+ # 只计算固定键名、标点、item文本、空values花括号和data_hex两端引号。
53
+ # 动态标量的位置故意留空,这不是待发送的JSON;字段顺序不影响字节总数。
54
+ # 下方独立编码器对照测试会捕捉原ITEM结构变动,不能另行放宽单条能力。
55
+ _ITEM_FIXED_BYTES = len(
56
+ b'{"op":"item","request_id":,"record":{"sequence":,"frame":{'
57
+ b'"timestamp":,"arbitration_id":,"is_extended_id":,"is_remote_frame":,'
58
+ b'"is_error_frame":,"channel":,"dlc":,"is_fd":,"is_rx":,'
59
+ b'"bitrate_switch":,"error_state_indicator":,"data_hex":""},"values":{}}}')
60
+
61
+
62
+ # 固定语法已包含values的{}与data_hex两引号。动态字段取确定上界:两个非负
63
+ # 64bit序号各20字符;有限binary64用32;29bit ID用9;DLC用2;64字节hex用128;
64
+ # 七个bool最多35。这里故意多算,只有完整上界不超过原限额时才能省掉精确计长。
65
+ _SMALL_ITEM_BASE_UPPER = _ITEM_FIXED_BYTES + 40 + 32 + 9 + 2 + 128 + 35
66
+
67
+
68
+ def _small_item_fits(values, sequence, channel):
69
+ """证明已核原字段的小ITEM符合原限额;不能证明时返回False,不拒绝输入。
70
+
71
+ 参数: values已确认为Mapping;sequence已核原生非负int;channel已核原帧类型。
72
+ 同次原帧的有限float时间、29bit ID、DLC/data不超过64及七个bool也须已核。
73
+ 返回: bool。True表示完整原生dict均已检查且整个ITEM的保守上界不超过65536。
74
+ 异常: 取消、分配失败或原生dict并发变化等运行时错误原样传播,不伪装成正常回退。
75
+ 边界: 只接受非空原生ASCII键及原生bool、有限float或绝对值不超过64bit的int。
76
+ 非有限诊断、Unicode、大整数和近限额记录都交回原精确路径;不复制或缓存值。
77
+ """
78
+ name = value = None
79
+ try:
80
+ # 自定义Mapping/dict子类不在此额外调用len/items,仍只按原路径观察一次。
81
+ if type(values) is not dict or sequence.bit_length() > 64:
82
+ return False
83
+ upper = _SMALL_ITEM_BASE_UPPER
84
+ if channel is None:
85
+ upper += 4
86
+ elif type(channel) is int:
87
+ if channel.bit_length() > 64:
88
+ return False
89
+ upper += 21 # 64bit绝对值最多20位十进制数字,再加可能的负号。
90
+ elif type(channel) is str:
91
+ upper += 6 * len(channel) + 2
92
+ if upper > MAX_WIRE_BYTES or not channel.isascii():
93
+ return False
94
+ else:
95
+ return False
96
+ # ASCII字符最坏为六字节转义;键引号与冒号共3;数值取32;多计一个逗号。
97
+ # 因而每个非空键至少占本证明的42字节。门禁失败只是需要精确检查。
98
+ if len(values) > (MAX_WIRE_BYTES - upper) // 42:
99
+ return False
100
+ for name, value in values.items():
101
+ if type(name) is not str or not name:
102
+ return False
103
+ upper += 6 * len(name) + 36
104
+ if upper > MAX_WIRE_BYTES or not name.isascii():
105
+ return False
106
+ value_type = type(value)
107
+ if value_type is float:
108
+ # 有限binary64的JSON表示至多24字符,此处用32覆盖全部符号/指数格式。
109
+ if not isfinite(value):
110
+ return False
111
+ elif value_type is int:
112
+ if value.bit_length() > 64:
113
+ return False
114
+ elif value_type is not bool:
115
+ return False
116
+ return True
117
+ finally:
118
+ values = sequence = channel = name = value = None
119
+
120
+
121
+ def _integer(value, name, minimum=0, maximum=None):
122
+ """检查原生整数边界,bool不能充当序号、通道或ID。
123
+
124
+ 参数: value为候选值;name定位字段;minimum/maximum为含端点范围,None无上界。
125
+ 返回: 原int。异常: TypeError为非int,ValueError为超范围;无转换或I/O。
126
+ """
127
+ if type(value) is not int:
128
+ raise TypeError(name + '需要原生int')
129
+ if value < minimum or maximum is not None and value > maximum:
130
+ raise ValueError(name + '超出允许范围')
131
+ return value
132
+
133
+
134
+ def _text(value, name):
135
+ """检查有限非空原文本,不将DBC名称改成表达式标识符。
136
+
137
+ 参数: value为候选文本;name定位字段。返回: 原str。
138
+ 异常: TypeError/ValueError为类型、空文本或超过单包字符上限;不改大小写/空格。
139
+ """
140
+ if type(value) is not str:
141
+ raise TypeError(name + '需要原生str')
142
+ if not value or len(value) > MAX_WIRE_BYTES:
143
+ raise ValueError(name + '为空或过长')
144
+ return value
145
+
146
+
147
+ def _shape(value, names, name):
148
+ """校验wire字典精确字段,拒绝额外对象标签或丢失字段。
149
+
150
+ 参数: value为候选dict;names为固定字段名容器;name定位对象。
151
+ 返回: 原dict。异常: TypeError/ValueError为容器或字段不符。
152
+ """
153
+ if type(value) is not dict:
154
+ raise TypeError(name + '需要dict')
155
+ if len(value) != len(names) or any(key not in names for key in value):
156
+ raise ValueError(name + '字段缺失或多余')
157
+ return value
158
+
159
+
160
+ @dataclass(frozen=True)
161
+ class LegacyRawFrame:
162
+ """保留同次原msg全部公开写出字段,不重构消息或推断DBC质量。"""
163
+
164
+ timestamp: float # 原浮点秒;有限性不代表上游精度可恢复。
165
+ arbitration_id: int # 原29位以内报文ID,不把channel拼进ID。
166
+ is_extended_id: bool # 原标准/扩展帧标志。
167
+ is_remote_frame: bool # 原远程帧标志,不按投影滤掉。
168
+ is_error_frame: bool # 原错误帧标志。
169
+ channel: int | str | None # 原公开通道值,不猜缺失通道。
170
+ dlc: int # 原公开DLC,不根据data长度重算。
171
+ data: bytes # 原payload的独立无损bytes副本。
172
+ is_fd: bool # 原CAN FD标志。
173
+ is_rx: bool | None # 原收发方向;CSV未提供时为None,不能据此导出Rx/Tx。
174
+ bitrate_switch: bool # 原FD速率切换标志。
175
+ error_state_indicator: bool # 原FD错误状态指示。
176
+
177
+ def __post_init__(self):
178
+ """校验公开字段类型,不补帧、缩放或改变原顺序。
179
+
180
+ 参数: 无。返回: None。异常: TypeError/ValueError为非法字段或超过CAN最大payload。
181
+ """
182
+ if type(self.timestamp) is not float or not isfinite(self.timestamp):
183
+ raise ValueError('原报文timestamp需要有限float秒')
184
+ _integer(self.arbitration_id, 'arbitration_id', maximum=0x1FFFFFFF)
185
+ _integer(self.dlc, 'dlc', maximum=64)
186
+ if type(self.data) is not bytes or len(self.data) > 64:
187
+ raise ValueError('原报文data需要不超过64字节的bytes')
188
+ if self.channel is not None and type(self.channel) not in (int, str):
189
+ raise TypeError('原报文channel需要int/str/None')
190
+ if type(self.channel) is str and len(self.channel) > MAX_WIRE_BYTES:
191
+ raise ValueError('原报文channel文本过长')
192
+ if self.is_rx is not None and type(self.is_rx) is not bool:
193
+ raise TypeError('is_rx需要bool或未知None')
194
+ for name in ('is_extended_id', 'is_remote_frame', 'is_error_frame', 'is_fd',
195
+ 'bitrate_switch', 'error_state_indicator'):
196
+ if type(getattr(self, name)) is not bool:
197
+ raise TypeError(name + '需要bool')
198
+
199
+
200
+ @dataclass(frozen=True)
201
+ class LegacyDecodedFrame:
202
+ """保存一次原yield和一次parse的结果,values独立只读且保留非有限诊断值。"""
203
+
204
+ sequence: int # 本次来源从0开始的原yield序号,不是物理文件行号。
205
+ frame: LegacyRawFrame # 同次原msg公开快照。
206
+ values: Mapping[str, int | float | bool] # 原返回字典,空dict不推断错误原因。
207
+
208
+ def __post_init__(self):
209
+ """冻结原数值映射,不把缺键或非有限浮点替换为零。
210
+
211
+ 参数: 无。返回: None。异常: TypeError/ValueError为序号、frame或数值类型错误。
212
+ """
213
+ _integer(self.sequence, 'sequence')
214
+ if type(self.frame) is not LegacyRawFrame or not isinstance(self.values, Mapping):
215
+ raise TypeError('解码记录需要LegacyRawFrame与数值Mapping')
216
+ # ITEM外壳也属于64KiB能力;先完整预检,再复制有界映射,避免大Mapping先复制后拒绝。
217
+ base = _wire_tree({'op': 'item', 'request_id': self.sequence,
218
+ 'record': {'sequence': self.sequence, 'frame': frame_to_dict(self.frame), 'values': {}}})
219
+ available = MAX_WIRE_BYTES - base + 2
220
+ _decoded_values_size(self.values, available)
221
+ values = {}
222
+ used = 2
223
+ for name, value in self.values.items():
224
+ # 第二遍仍逐项检查后才插入,Mapping在两遍间变化也不能扩大已复制前缀。
225
+ separator = 1 if values else 0
226
+ used += separator + _decoded_entry_size(name, value, available - used - separator)
227
+ values[name] = value
228
+ object.__setattr__(self, 'values', MappingProxyType(values))
229
+
230
+
231
+ @dataclass(frozen=True)
232
+ class StoredRawFrame:
233
+ """为首次读取保存原frame与分析坐标,供后续导出从新暂存回读。"""
234
+
235
+ sequence: int # 原yield顺序,含同刻不同消息。
236
+ time_ns: int # 明确映射后的int64纳秒,不改变原frame.timestamp。
237
+ frame: LegacyRawFrame # 原公开写出字段。
238
+
239
+ def __post_init__(self):
240
+ """检查原序号和新分析坐标,拒绝越界或替代模型。
241
+
242
+ 参数: 无。返回: None。异常: TypeError/ValueError为字段或int64范围不符。
243
+ """
244
+ _integer(self.sequence, 'sequence')
245
+ _integer(self.time_ns, 'time_ns', -(1 << 63), (1 << 63) - 1)
246
+ if type(self.frame) is not LegacyRawFrame:
247
+ raise TypeError('原始暂存需要LegacyRawFrame')
248
+
249
+
250
+ @dataclass(frozen=True)
251
+ class LegacyCANField:
252
+ """按通道、ID和信号定位;可选帧类型由运行时实际记录消除歧义。"""
253
+
254
+ channel: int # 用户明确通道;首版定位不接受缺失或自由文本。
255
+ signal: str # DBC原signal名称。
256
+ frame_id: int # 同次DBC核对的原报文ID。
257
+ is_extended: bool | None = None # None表示未限制帧类型,不等于标准帧。
258
+ is_fd: bool | None = None # None表示未限制经典CAN/FD。
259
+
260
+ def __post_init__(self):
261
+ """校验定位形状,实际唯一性由worker同次公开DBC元数据核实。
262
+
263
+ 参数: 无。返回: None。异常: TypeError/ValueError为声明字段非法。
264
+ """
265
+ _integer(self.channel, 'field.channel')
266
+ object.__setattr__(self, 'frame_id', normalize_frame_id(self.frame_id))
267
+ _text(self.signal, 'field.signal')
268
+ if any(value is not None and type(value) is not bool for value in (self.is_extended, self.is_fd)):
269
+ raise TypeError('字段is_extended/is_fd需要bool或省略')
270
+ if self.is_extended is False and self.frame_id > 0x7FF:
271
+ raise ValueError('标准帧frame_id不能超过0x7FF')
272
+
273
+ @property
274
+ def key(self):
275
+ """提供稳定原定位键,供新绑定层引用;不改signal名称。
276
+
277
+ 参数: 无。返回: 规范紧凑JSON str。异常: 原json编码错误;无I/O或DBC查询。
278
+ """
279
+ return encode_packet(field_to_dict(self)).decode('utf-8')
280
+
281
+
282
+ @dataclass(frozen=True)
283
+ class LegacyCANRequest:
284
+ """声明单BLF、单DBC和有限原定位;构造只校验模型,不访问文件。"""
285
+
286
+ input_path: Path # 原BLF路径,不在模型中resolve或新增扫描。
287
+ dbc_path: Path # 只供worker一次原load_file。
288
+ fields: tuple[LegacyCANField, ...] # 空tuple可原样读取全部帧,不省decode。
289
+
290
+ def __post_init__(self):
291
+ """拒绝替代路径/定位及重复完整定位,保留原tuple顺序。
292
+
293
+ 参数: 无。返回: None。异常: TypeError/ValueError为路径类型或重复定位错误。
294
+ """
295
+ if not isinstance(self.input_path, Path) or not isinstance(self.dbc_path, Path):
296
+ raise TypeError('原CAN请求路径需要Path')
297
+ if type(self.fields) is not tuple:
298
+ raise TypeError('原CAN请求fields需要LegacyCANField tuple')
299
+ if len(self.fields) > MAX_WIRE_BYTES // 2:
300
+ raise ValueError('原CAN定位数量超过wire能力')
301
+ if any(type(item) is not LegacyCANField for item in self.fields):
302
+ raise TypeError('原CAN请求fields需要LegacyCANField tuple')
303
+ # 路径和字段集先累计INIT字节,再创建重复键集合;不为任意大fields复制全部key。
304
+ for path in (self.input_path, self.dbc_path):
305
+ if sum(len(part) for part in path.parts) > MAX_WIRE_BYTES:
306
+ raise ValueError('原CAN路径超过wire能力')
307
+ used = _wire_tree({'op': 'init', 'version': 1, 'path': str(self.input_path),
308
+ 'dbc_path': str(self.dbc_path), 'fields': []})
309
+ for index, field in enumerate(self.fields):
310
+ separator = 1 if index else 0
311
+ used += separator + _wire_tree(field_to_dict(field), remaining=MAX_WIRE_BYTES - used - separator)
312
+ if len({item.key for item in self.fields}) != len(self.fields):
313
+ raise ValueError('原CAN请求完整定位重复')
314
+
315
+ @property
316
+ def profile(self):
317
+ """读取唯一受支持profile。参数: 无。返回: 固定str。异常: 无。
318
+ """
319
+ return PROFILE_ID
320
+
321
+
322
+ def frame_to_dict(frame):
323
+ """将原frame编码为固定JSON字段,data_hex不丢失任一字节。
324
+
325
+ 参数: frame为LegacyRawFrame。返回: 新dict。异常: TypeError为非法模型。
326
+ """
327
+ if type(frame) is not LegacyRawFrame:
328
+ raise TypeError('需要LegacyRawFrame')
329
+ return {**{name: getattr(frame, name) for name in _RAW_FIELDS}, 'data_hex': frame.data.hex()}
330
+
331
+
332
+ def frame_from_dict(value):
333
+ """只从固定字段重建原frame,不加载任意类或调用CAN构造器。
334
+
335
+ 参数: value为wire dict。返回: LegacyRawFrame。
336
+ 异常: TypeError/ValueError为形状、hex或原frame字段非法。
337
+ """
338
+ _shape(value, (*_RAW_FIELDS, 'data_hex'), 'raw frame')
339
+ text = value['data_hex']
340
+ if type(text) is not str or len(text) > 128 or len(text) % 2 or any(char not in '0123456789abcdefABCDEF' for char in text):
341
+ raise ValueError('data_hex需要不超过64字节的完整hex')
342
+ return LegacyRawFrame(**{name: value[name] for name in _RAW_FIELDS}, data=bytes.fromhex(text))
343
+
344
+
345
+ def _value_to_wire(value):
346
+ """给非有限原解码float明确标签,有限数字和bool保原类型。
347
+
348
+ 参数: value为原生int/float/bool。返回: JSON标量或diagnostic_float字典。
349
+ 异常: TypeError为未支持值;不按数值truthiness丢弃False或0。
350
+ """
351
+ if type(value) not in (int, float, bool):
352
+ raise TypeError('解码wire值仅支持数值或bool')
353
+ if type(value) is float and not isfinite(value):
354
+ return {'diagnostic_float': 'nan' if isnan(value) else 'inf' if value > 0 else '-inf'}
355
+ return value
356
+
357
+
358
+ def _value_from_wire(value):
359
+ """恢复固定非有限标签,拒绝裸NaN和任意标签对象。
360
+
361
+ 参数: value为JSON数值/bool或固定诊断dict。返回: 原生int/float/bool。
362
+ 异常: TypeError/ValueError为未知类型、标签或未标记非有限数值。
363
+ """
364
+ if type(value) is dict:
365
+ _shape(value, ('diagnostic_float',), 'decoded diagnostic')
366
+ if value['diagnostic_float'] not in ('nan', 'inf', '-inf'):
367
+ raise ValueError('未知非有限解码标签')
368
+ return float(value['diagnostic_float'])
369
+ if type(value) not in (int, float, bool) or type(value) is float and not isfinite(value):
370
+ raise TypeError('解码wire值非法或非有限标签缺失')
371
+ return value
372
+
373
+
374
+ def decoded_to_dict(record):
375
+ """编码一次原yield的完整解码记录,不投影或过滤返回键。
376
+
377
+ 参数: record为LegacyDecodedFrame。返回: 固定dict。
378
+ 异常: TypeError为非法模型;原值编码错误传播。
379
+ """
380
+ if type(record) is not LegacyDecodedFrame:
381
+ raise TypeError('需要LegacyDecodedFrame')
382
+ return {'sequence': record.sequence, 'frame': frame_to_dict(record.frame),
383
+ 'values': {name: _value_to_wire(value) for name, value in record.values.items()}}
384
+
385
+
386
+ def decoded_from_dict(value):
387
+ """重建单次原返回,空dict与非有限诊断均保持,不猜解码失败原因。
388
+
389
+ 参数: value为固定wire dict。返回: LegacyDecodedFrame。
390
+ 异常: TypeError/ValueError为形状或值非法。
391
+ """
392
+ _shape(value, ('sequence', 'frame', 'values'), 'decoded frame')
393
+ if type(value['values']) is not dict:
394
+ raise TypeError('decoded values需要dict')
395
+ # direct helper调用也不能绕过decode_packet,在新values字典复制前核原JSON树上限。
396
+ _wire_tree(value)
397
+ return LegacyDecodedFrame(value['sequence'], frame_from_dict(value['frame']),
398
+ {name: _value_from_wire(item) for name, item in value['values'].items()})
399
+
400
+
401
+ def _decoded_from_checked_dict(value):
402
+ """在同次严格JSON解包后重建原记录,原值只检查一次后冻结自有字典。
403
+
404
+ 参数: value为消息仓或批次解包中同次decode_packet刚返回的原生dict;
405
+ 两者之间不能调用外部代码、修改子树或把检查结果缓存到其他请求。
406
+ 返回: LegacyDecodedFrame,原字段、数值类型及非有限诊断按公共入口相同方式恢复。
407
+ 异常: 原形状、frame、数值、模型限额或分配/取消错误;调用方保持原错误包装。
408
+ 约束: 首次解包已检查UTF-8、重复键、深度和64KiB;本函数不是独立解析入口,
409
+ 不开放trusted参数。公共decoded_from_dict仍独立完整检查,不能改走本路径省略边界。
410
+ 本层新建的values只含原生不可变标量,未向外暴露;常见完整值可用保守上界
411
+ 证明ITEM不超限,不能证明时沿原精确路径。核完ITEM外壳/全部值
412
+ 后可直接冻结,不需要公开构造器为外部可变Mapping设置的第二遍检查和复制。
413
+ 副作用: 仅建立本条有界模型;不持有跨调用状态,不读写文件或改变预算。
414
+ 清理只断开本模块已结束异常frame的临时引用,保留原异常、诊断与traceback结构。
415
+ """
416
+ sequence = frame = values = record = current = None
417
+ try:
418
+ _shape(value, ('sequence', 'frame', 'values'), 'decoded frame')
419
+ if type(value['values']) is not dict:
420
+ raise TypeError('decoded values需要dict')
421
+ # 原构造表达式先取sequence,再构造frame及转换全部values;sequence的类型
422
+ # 检查在这三项求值之后,不能因合并步骤改变同时存在多个错误时的优先级。
423
+ sequence = value['sequence']
424
+ frame = frame_from_dict(value['frame'])
425
+ values = {name: _value_from_wire(item) for name, item in value['values'].items()}
426
+ _integer(sequence, 'sequence')
427
+ if type(frame) is not LegacyRawFrame:
428
+ raise TypeError('解码记录需要LegacyRawFrame与数值Mapping')
429
+ # 原decoded包在64KiB内,不等于加ITEM外壳后仍在限额内。此处frame及序号
430
+ # 已完成原检查,values也已在本层转换;只在完整保守上界成立时省精确计长。
431
+ # Unicode/非有限诊断/大整数/近限额沿原公式和错误先后,不凭wire成功放行。
432
+ if not _small_item_fits(values, sequence, frame.channel):
433
+ base = _wire_tree({'op': 'item', 'request_id': sequence,
434
+ 'record': {'sequence': sequence, 'frame': frame_to_dict(frame), 'values': {}}})
435
+ _decoded_values_size(values, MAX_WIRE_BYTES - base + 2)
436
+ # 字典只在本层创建和检查,无用户Mapping回调或借入可变别名;不调用公开
437
+ # 构造器重做第二遍。同一真实record持有冻结后的唯一dict,不借原parsed树。
438
+ record = object.__new__(LegacyDecodedFrame)
439
+ object.__setattr__(record, 'sequence', sequence)
440
+ object.__setattr__(record, 'frame', frame)
441
+ object.__setattr__(record, 'values', MappingProxyType(values))
442
+ return record
443
+ except BaseException as exc:
444
+ # 调用方可能保留原取消/错误;只清本模块已结束的辅助frame,不清用户或
445
+ # 标准库诊断,不沿cause/context扩展遍历。活跃的本函数由finally清其责任槽。
446
+ current = exc.__traceback__
447
+ while current is not None:
448
+ if current.tb_frame.f_globals.get('__name__') == __name__:
449
+ try:
450
+ current.tb_frame.clear()
451
+ except RuntimeError:
452
+ pass
453
+ current = current.tb_next
454
+ raise
455
+ finally:
456
+ value = sequence = frame = values = record = current = None
457
+
458
+
459
+ def _try_decoded_small_packet(payload):
460
+ """解析并证明常见完整decoded小包合法,不能证明时返回None交回原入口。
461
+
462
+ 参数: payload为本次已预付工作空间内的有界bytes,不借外部JSON树或验证标志。
463
+ 返回: 独立冻结的LegacyDecodedFrame;None只表示需走完整原路径,不表示输入非法。
464
+ 异常: 原JSON/模型错误、MemoryError或取消;外层只对普通错误重走原错误顺序。
465
+ 流程: 保留UTF-8、重复键、裸非有限常量检查及完整frame/sequence校验;只有
466
+ 原生ASCII键和有限数值/bool满足完整ITEM保守上界,才省去重复JSON树遍历。
467
+ 固定字段结构的深度与标量已由模型核定,ITEM上界也覆盖较小decoded包。
468
+ 复杂值、Unicode、近限额等均返回原路径;成功只创建一份frame及自有values。
469
+ 副作用: 无I/O、跨行缓存或新预算owner。回退前释放本次临时模型,原错误仅清理
470
+ 本模块已结束frame的借入引用;取消及内存错误不重试,不清用户诊断frame。
471
+ """
472
+ parsed = raw_values = values = sequence = frame = result = current = None
473
+ try:
474
+ if type(payload) is not bytes or not payload or len(payload) > MAX_WIRE_BYTES:
475
+ return None
476
+ parsed = json.loads(payload.decode('utf-8'), object_pairs_hook=_unique_object,
477
+ parse_constant=_reject_constant)
478
+ _shape(parsed, ('sequence', 'frame', 'values'), 'decoded frame')
479
+ raw_values = parsed['values']
480
+ if type(raw_values) is not dict:
481
+ return None
482
+ frame = frame_from_dict(parsed['frame'])
483
+ sequence = parsed['sequence']
484
+ _integer(sequence, 'sequence')
485
+ if not _small_item_fits(raw_values, sequence, frame.channel):
486
+ return None
487
+ # 正证明仅接受原生有限数值/bool;_value_from_wire对此域原样返回。
488
+ # parsed未暴露给调用方,复制一次可使最终冻结字典与解析树独立。
489
+ values = raw_values.copy()
490
+ result = object.__new__(LegacyDecodedFrame)
491
+ object.__setattr__(result, 'sequence', sequence)
492
+ object.__setattr__(result, 'frame', frame)
493
+ object.__setattr__(result, 'values', MappingProxyType(values))
494
+ return result
495
+ except BaseException as exc:
496
+ current = exc.__traceback__
497
+ while current is not None:
498
+ if current.tb_frame.f_globals.get('__name__') == __name__:
499
+ try:
500
+ current.tb_frame.clear()
501
+ except RuntimeError:
502
+ pass
503
+ current = current.tb_next
504
+ raise
505
+ finally:
506
+ payload = parsed = raw_values = values = sequence = frame = result = current = None
507
+
508
+
509
+ def _decoded_from_packet(payload):
510
+ """在同次专用decoded包解析中复用小包证明,保原完整入口的输出及错误顺序。
511
+
512
+ 参数: payload为完整decoded JSON bytes,仍受原64KiB及ITEM外壳限制。
513
+ 返回: LegacyDecodedFrame;完整字段、原值类型、量化前时间及非有限诊断不变。
514
+ 异常: 与decode_packet后接私有构建相同的原错误;MemoryError/取消原样传播。
515
+ 边界: 普通失败退出except并释放试算对象后,重新由原完整解析/构建决定报错;
516
+ 不提前把frame错误置于wire错误前。公共decode_packet及decoded_from_dict不变。
517
+ """
518
+ result = None
519
+ try:
520
+ try:
521
+ result = _try_decoded_small_packet(payload)
522
+ except (TypeError, ValueError, OverflowError, RecursionError):
523
+ pass
524
+ if result is not None:
525
+ return result
526
+ return _decoded_from_checked_dict(decode_packet(payload))
527
+ finally:
528
+ payload = result = None
529
+
530
+
531
+ def field_to_dict(field):
532
+ """按唯一定位合同输出原字段,不带样本或隐式别名。
533
+
534
+ 参数: field为LegacyCANField。返回: 固定dict。异常: TypeError为非法模型。
535
+ """
536
+ if type(field) is not LegacyCANField:
537
+ raise TypeError('需要LegacyCANField')
538
+ return {name: getattr(field, name) for name in _LOCATOR_FIELDS if getattr(field, name) is not None}
539
+
540
+
541
+ def field_from_dict(value):
542
+ """只构建固定定位模型,不接受多余元数据或对象标签。
543
+
544
+ 参数: value为固定dict。返回: LegacyCANField。异常: TypeError/ValueError为形状或字段非法。
545
+ """
546
+ # 省略与显式null区分;旧message不能静默忽略,避免误以为它仍约束匹配。
547
+ if type(value) is not dict:
548
+ raise TypeError('CAN field需要dict')
549
+ if 'message' in value:
550
+ raise ValueError('message参数已删除;请删除message,保留signal并用frame_id定位')
551
+ if set(value) - set(_LOCATOR_FIELDS) or not {'channel', 'signal', 'frame_id'} <= set(value):
552
+ raise ValueError('CAN field需要channel、frame_id、signal;仅可附加is_extended/is_fd')
553
+ if any(name in value and type(value[name]) is not bool for name in ('is_extended', 'is_fd')):
554
+ raise TypeError('is_extended/is_fd填写时必须为bool,不能为null')
555
+ return LegacyCANField(**value)
556
+
557
+
558
+ def _scalar_size(value, remaining):
559
+ """计算原生JSON标量字节,普通标量直接计数,复杂文本仍交原JSON编码器。
560
+
561
+ 参数: value为JSON标量;remaining为本包剩余字节。返回: 精确UTF-8编码长度。
562
+ 异常: TypeError/ValueError/UnicodeError为类型/数值/限额;标量暂态最多单包有限倍数。
563
+ """
564
+ if type(value) is str:
565
+ if len(value) + 2 > remaining:
566
+ raise ValueError('wire文本超过单包上限')
567
+ # 可打印ASCII中只需排除引号和反斜杠,其他字符一字节且不转义,另计两端引号。
568
+ # 控制字符、DEL、Unicode及转义文本保留原编码路径,不重写JSON转义/UTF-8规则。
569
+ if value.isascii() and value.isprintable() and '"' not in value and '\\' not in value:
570
+ size = len(value) + 2
571
+ else:
572
+ size = len(json.dumps(value, ensure_ascii=False, allow_nan=False, separators=(',', ':')).encode('utf-8'))
573
+ elif value is None:
574
+ size = 4 # JSON的null固定四个ASCII字节,不为尺寸检查重复构造编码器。
575
+ elif type(value) is bool:
576
+ size = 4 if value else 5 # JSON原样写true/false,不能按整数1/0的长度计算。
577
+ elif type(value) is int:
578
+ if value.bit_length() > MAX_WIRE_BYTES * 4:
579
+ raise ValueError('wire整数超过单包能力')
580
+ # 原生int的十进制表示与JSON一致,保符号及Python本身的超长整数转换限制。
581
+ size = len(str(value))
582
+ elif type(value) is float:
583
+ if not isfinite(value):
584
+ raise ValueError('wire非有限数值必须显式标签')
585
+ # 标准库JSON对有限原生float使用其repr,包含指数及-0.0;全为ASCII。
586
+ # 此处只计长度,最终输出仍由JSON编码器产生,非有限值继续由上方拒绝。
587
+ size = len(repr(value))
588
+ else:
589
+ raise TypeError('wire标量类型不受支持')
590
+ if size > remaining:
591
+ raise ValueError('wire包超过65536字节')
592
+ return size
593
+
594
+
595
+ def _decoded_entry_size(name, value, remaining):
596
+ """在插入新values字典前核单项完整wire成本,保0/False和非有限原值。
597
+
598
+ 参数: name为原信号str;value为原数值/bool;remaining为剩余值域字节。
599
+ 返回: 键、冒号和值的精确长度。异常: 原类型、非空名称或wire限额错误。
600
+ """
601
+ _text(name, 'decoded signal')
602
+ size = _scalar_size(name, remaining)
603
+ return size + 1 + _wire_tree(_value_to_wire(value), remaining=remaining - size - 1)
604
+
605
+
606
+ def _decoded_values_size(values, remaining):
607
+ """不复制Mapping先预检全部解码值,累计成本限制无界或动态items前缀。
608
+
609
+ 参数: values为原Mapping;remaining为含两花括号的wire可用字节。
610
+ 返回: 精确值字典长度。异常: 类型/限额错误,尚未创建values副本。
611
+ """
612
+ if len(values) > remaining // 4:
613
+ raise ValueError('解码信号数量超过64KiB wire能力')
614
+ used = 2
615
+ for index, (name, value) in enumerate(values.items()):
616
+ separator = 1 if index else 0
617
+ used += separator + _decoded_entry_size(name, value, remaining - used - separator)
618
+ return used
619
+
620
+
621
+ def _wire_tree(value, depth=0, remaining=MAX_WIRE_BYTES):
622
+ """在JSON复制前累计精确包大小,嵌套子树共享剩余额度而非各自重置上限。
623
+
624
+ 参数: value为JSON树;depth为递归层;remaining为整包尚余字节。
625
+ 返回: 紧凑UTF-8 JSON精确长度。异常: TypeError/ValueError为类型/深度/总量;无任意类构建。
626
+ """
627
+ if depth > 16 or remaining < 0:
628
+ raise ValueError('wire嵌套或累计大小超过上限')
629
+ if value is None or type(value) in (bool, int, float, str):
630
+ return _scalar_size(value, remaining)
631
+ if type(value) not in (dict, list):
632
+ raise TypeError('wire仅接JSON结构,不接任意对象')
633
+ if len(value) > remaining // 2:
634
+ raise ValueError('wire容器超过单包上限')
635
+ used = 2
636
+ if type(value) is dict:
637
+ for index, (name, item) in enumerate(value.items()):
638
+ if type(name) is not str:
639
+ raise TypeError('wire字典键需要str')
640
+ used += 1 if index else 0
641
+ # 键已确认为原生str,直接计数;仍先执行原递归入口的深度/剩余守卫。
642
+ # 守卫顺序及错误消息不变,不能因省去类型分流而放过第17层或负剩余额度。
643
+ key_remaining = remaining - used
644
+ if depth + 1 > 16 or key_remaining < 0:
645
+ raise ValueError('wire嵌套或累计大小超过上限')
646
+ used += _scalar_size(name, key_remaining)
647
+ used += 1
648
+ used += _wire_tree(item, depth + 1, remaining - used)
649
+ else:
650
+ for index, item in enumerate(value):
651
+ used += 1 if index else 0
652
+ used += _wire_tree(item, depth + 1, remaining - used)
653
+ if used > remaining:
654
+ raise ValueError('wire包超过65536字节')
655
+ return used
656
+
657
+
658
+ def encode_packet(value):
659
+ """编码最大65536字节的单个JSON对象包,不带换行或pickle。
660
+
661
+ 参数: value为dict根、有限JSON树。返回: UTF-8 bytes。
662
+ 异常: TypeError/ValueError为类型/非有限/深度/字节上限或JSON编码失败。
663
+ """
664
+ if type(value) is not dict:
665
+ raise TypeError('wire包根需要dict')
666
+ _wire_tree(value)
667
+ # 树预检已限制整包精确长度;一次编码避免逐JSON片段调用Python循环和UTF-8转换。
668
+ # 保留原排序、紧凑格式和严格UTF-8,并再次核对实际字节,不依赖尺寸预检独自守边界。
669
+ result = json.dumps(value, ensure_ascii=False, allow_nan=False, sort_keys=True,
670
+ separators=(',', ':')).encode('utf-8')
671
+ if len(result) > MAX_WIRE_BYTES:
672
+ raise ValueError('wire包超过65536字节')
673
+ return result
674
+
675
+
676
+ def _unique_object(pairs):
677
+ """拒绝重复JSON键,防止后值覆盖已核过的协议字段。
678
+
679
+ 参数: pairs为解析器键值对。返回: 新dict。异常: ValueError为重复字段。
680
+ """
681
+ result = {}
682
+ for name, value in pairs:
683
+ if name in result:
684
+ raise ValueError('wire存在重复JSON键')
685
+ result[name] = value
686
+ return result
687
+
688
+
689
+ def _reject_constant(value):
690
+ """拒绝NaN/Infinity非标准JSON常量。
691
+
692
+ 参数: value为解析器常量文本。返回: 无。异常: ValueError总是抛出。
693
+ """
694
+ raise ValueError('wire非法JSON数值: ' + value)
695
+
696
+
697
+ def decode_packet(payload):
698
+ """从有界JSON bytes校验包形状,不反序列化任意Python对象。
699
+
700
+ 参数: payload为不超过MAX_WIRE_BYTES的bytes。返回: 已校验dict。
701
+ 异常: TypeError/ValueError/UnicodeError为类型、大小、格式或结构非法。
702
+ """
703
+ if type(payload) is not bytes or not payload or len(payload) > MAX_WIRE_BYTES:
704
+ raise ValueError('wire包需要1至65536字节的bytes')
705
+ value = json.loads(payload.decode('utf-8'), object_pairs_hook=_unique_object, parse_constant=_reject_constant)
706
+ if type(value) is not dict:
707
+ raise TypeError('wire包根需要dict')
708
+ _wire_tree(value)
709
+ return value