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.
- chronaxis/__init__.py +72 -0
- chronaxis/__main__.py +12 -0
- chronaxis/analysis_cli.py +181 -0
- chronaxis/batch/__init__.py +14 -0
- chronaxis/batch/api.py +46 -0
- chronaxis/batch/cli.py +48 -0
- chronaxis/batch/config.py +37 -0
- chronaxis/batch/models.py +202 -0
- chronaxis/batch/process_transport.py +149 -0
- chronaxis/batch/process_tree.py +72 -0
- chronaxis/batch/publication.py +41 -0
- chronaxis/batch/runner.py +236 -0
- chronaxis/batch/templates.py +42 -0
- chronaxis/can_dependencies.py +42 -0
- chronaxis/cli.py +193 -0
- chronaxis/configuration/__init__.py +46 -0
- chronaxis/configuration/cli.py +41 -0
- chronaxis/configuration/diagnostics.py +107 -0
- chronaxis/configuration/explanation.py +233 -0
- chronaxis/configuration/file_tools.py +140 -0
- chronaxis/configuration/imports.py +144 -0
- chronaxis/configuration/initialization.py +36 -0
- chronaxis/configuration/json_parser.py +114 -0
- chronaxis/configuration/models.py +74 -0
- chronaxis/configuration/origins.py +90 -0
- chronaxis/configuration/overrides.py +55 -0
- chronaxis/configuration/resolution.py +150 -0
- chronaxis/configuration/template_catalog.py +68 -0
- chronaxis/configuration/templates/batch/analysis-annotated.yaml +18 -0
- chronaxis/configuration/templates/batch/analysis-minimal.yaml +18 -0
- chronaxis/configuration/templates/batch/annotated.yaml +6 -0
- chronaxis/configuration/templates/batch/minimal.yaml +6 -0
- chronaxis/configuration/templates/can-asc/annotated.yaml +18 -0
- chronaxis/configuration/templates/can-asc/minimal.yaml +18 -0
- chronaxis/configuration/templates/can-blf/annotated.yaml +18 -0
- chronaxis/configuration/templates/can-blf/minimal.yaml +18 -0
- chronaxis/configuration/templates/can-export/annotated.yaml +23 -0
- chronaxis/configuration/templates/can-export/minimal.yaml +23 -0
- chronaxis/configuration/templates/catalog.json +233 -0
- chronaxis/configuration/templates/charge-session/annotated.yaml +38 -0
- chronaxis/configuration/templates/charge-session/minimal.yaml +38 -0
- chronaxis/configuration/templates/command-response/annotated.yaml +32 -0
- chronaxis/configuration/templates/command-response/minimal.yaml +36 -0
- chronaxis/configuration/templates/fault-window/annotated.yaml +25 -0
- chronaxis/configuration/templates/fault-window/minimal.yaml +27 -0
- chronaxis/configuration/templates/ini-mapping/annotated.yaml +20 -0
- chronaxis/configuration/templates/ini-mapping/minimal.yaml +20 -0
- chronaxis/configuration/templates/raw-can-csv/annotated.yaml +34 -0
- chronaxis/configuration/templates/raw-can-csv/minimal.yaml +35 -0
- chronaxis/configuration/templates/shared/charge-session.asc +5 -0
- chronaxis/configuration/templates/shared/command-response.asc +8 -0
- chronaxis/configuration/templates/shared/fault-window.asc +5 -0
- chronaxis/configuration/templates/shared/power.asc +7 -0
- chronaxis/configuration/templates/shared/sample.asc +6 -0
- chronaxis/configuration/templates/shared/sample.blf +0 -0
- chronaxis/configuration/templates/shared/sample.csv +5 -0
- chronaxis/configuration/templates/shared/sample.dbc +11 -0
- chronaxis/configuration/templates/shared/signals.csv +6 -0
- chronaxis/configuration/templates/shared/source.ini +5 -0
- chronaxis/configuration/templates/shared/stability.asc +9 -0
- chronaxis/configuration/templates/shared/teaching.dbc +27 -0
- chronaxis/configuration/templates/shared/threshold.asc +7 -0
- chronaxis/configuration/templates/signal-csv/annotated.yaml +27 -0
- chronaxis/configuration/templates/signal-csv/minimal.yaml +27 -0
- chronaxis/configuration/templates/signal-export/annotated.yaml +27 -0
- chronaxis/configuration/templates/signal-export/minimal.yaml +29 -0
- chronaxis/configuration/templates/stability/annotated.yaml +35 -0
- chronaxis/configuration/templates/stability/minimal.yaml +35 -0
- chronaxis/configuration/templates/threshold/annotated.yaml +22 -0
- chronaxis/configuration/templates/threshold/minimal.yaml +22 -0
- chronaxis/configuration/yaml_parser.py +125 -0
- chronaxis/core/__init__.py +71 -0
- chronaxis/core/binding.py +449 -0
- chronaxis/core/calculation_series_join.py +106 -0
- chronaxis/core/calculations.py +435 -0
- chronaxis/core/calculations_memory_numpy.py +136 -0
- chronaxis/core/calculations_memory_reference.py +165 -0
- chronaxis/core/calculations_numpy.py +298 -0
- chronaxis/core/calculations_reference.py +294 -0
- chronaxis/core/condition_evidence.py +182 -0
- chronaxis/core/conditional_integral_result.py +43 -0
- chronaxis/core/conditional_integral_terms.py +146 -0
- chronaxis/core/conditional_integral_terms_numpy.py +148 -0
- chronaxis/core/conditional_integral_terms_reference.py +111 -0
- chronaxis/core/conditional_time_reduction.py +118 -0
- chronaxis/core/conditional_time_reduction_numpy.py +223 -0
- chronaxis/core/conditional_time_reduction_reference.py +213 -0
- chronaxis/core/declarations.py +192 -0
- chronaxis/core/decoded_binding.py +197 -0
- chronaxis/core/direct_message.py +387 -0
- chronaxis/core/export_interpolation.py +54 -0
- chronaxis/core/expression.py +642 -0
- chronaxis/core/expression_numpy.py +314 -0
- chronaxis/core/expression_reference.py +272 -0
- chronaxis/core/integral_result.py +53 -0
- chronaxis/core/integral_sum.py +77 -0
- chronaxis/core/integral_sum_numpy.py +224 -0
- chronaxis/core/integral_sum_reference.py +148 -0
- chronaxis/core/integral_terms.py +119 -0
- chronaxis/core/integral_terms_numpy.py +127 -0
- chronaxis/core/integral_terms_reference.py +91 -0
- chronaxis/core/mean_weights_numpy.py +29 -0
- chronaxis/core/mean_weights_reference.py +27 -0
- chronaxis/core/message_binding.py +305 -0
- chronaxis/core/models.py +485 -0
- chronaxis/core/normalize_numpy.py +396 -0
- chronaxis/core/numeric.py +472 -0
- chronaxis/core/numeric_numpy.py +440 -0
- chronaxis/core/record_intervals.py +115 -0
- chronaxis/core/sample_reduction.py +161 -0
- chronaxis/core/sample_reduction_numpy.py +160 -0
- chronaxis/core/sample_reduction_reference.py +154 -0
- chronaxis/core/selection.py +74 -0
- chronaxis/core/sequence.py +160 -0
- chronaxis/core/sequence_reference.py +248 -0
- chronaxis/core/stability.py +249 -0
- chronaxis/core/start_end.py +169 -0
- chronaxis/core/state.py +494 -0
- chronaxis/core/state_numpy.py +296 -0
- chronaxis/core/temporal.py +373 -0
- chronaxis/core/temporal_clock.py +25 -0
- chronaxis/core/temporal_memory_numpy.py +163 -0
- chronaxis/core/temporal_memory_reference.py +161 -0
- chronaxis/core/temporal_numpy.py +345 -0
- chronaxis/core/temporal_reference.py +304 -0
- chronaxis/core/time_reduction.py +190 -0
- chronaxis/core/time_reduction_numpy.py +205 -0
- chronaxis/core/time_reduction_reference.py +203 -0
- chronaxis/core/types.py +105 -0
- chronaxis/core/units.py +81 -0
- chronaxis/core/validation.py +94 -0
- chronaxis/core/window_delta.py +123 -0
- chronaxis/core/window_delta_numpy.py +78 -0
- chronaxis/core/window_delta_reference.py +69 -0
- chronaxis/core/windows.py +224 -0
- chronaxis/core/windows_numpy.py +78 -0
- chronaxis/core/windows_reference.py +61 -0
- chronaxis/execution/__init__.py +6 -0
- chronaxis/execution/batch_signal_groups.py +122 -0
- chronaxis/execution/bindings.py +296 -0
- chronaxis/execution/boundaries.py +568 -0
- chronaxis/execution/calculation_blocks.py +338 -0
- chronaxis/execution/calculation_values.py +55 -0
- chronaxis/execution/can_batch_reader.py +356 -0
- chronaxis/execution/can_reader.py +948 -0
- chronaxis/execution/can_reference_template.py +61 -0
- chronaxis/execution/condition_evidence.py +370 -0
- chronaxis/execution/conditional_integral_facts.py +310 -0
- chronaxis/execution/conditional_integral_reduction.py +216 -0
- chronaxis/execution/csv_observation.py +524 -0
- chronaxis/execution/csv_reader.py +662 -0
- chronaxis/execution/current_message_calculation.py +225 -0
- chronaxis/execution/driver_expression.py +274 -0
- chronaxis/execution/expressions.py +618 -0
- chronaxis/execution/frame_capture.py +245 -0
- chronaxis/execution/groups.py +236 -0
- chronaxis/execution/historical_conditional_blocks.py +264 -0
- chronaxis/execution/historical_conditional_integral.py +226 -0
- chronaxis/execution/historical_conditional_time_calculation.py +368 -0
- chronaxis/execution/historical_integral.py +219 -0
- chronaxis/execution/historical_observation.py +372 -0
- chronaxis/execution/historical_sample_calculation.py +338 -0
- chronaxis/execution/historical_selection_rows.py +300 -0
- chronaxis/execution/historical_time_calculation.py +341 -0
- chronaxis/execution/history.py +572 -0
- chronaxis/execution/history_records.py +225 -0
- chronaxis/execution/hold.py +448 -0
- chronaxis/execution/integral_facts.py +311 -0
- chronaxis/execution/integral_reduction.py +216 -0
- chronaxis/execution/legacy_frame_samples.py +94 -0
- chronaxis/execution/memory_reader.py +247 -0
- chronaxis/execution/message_bindings.py +293 -0
- chronaxis/execution/message_delivery.py +37 -0
- chronaxis/execution/observed_ingestion.py +551 -0
- chronaxis/execution/raw_signal_groups.py +192 -0
- chronaxis/execution/record_alarm_duration.py +114 -0
- chronaxis/execution/record_delta_condition.py +167 -0
- chronaxis/execution/record_diagnostics.py +87 -0
- chronaxis/execution/record_event_durations.py +143 -0
- chronaxis/execution/record_export_samples.py +94 -0
- chronaxis/execution/record_exports.py +155 -0
- chronaxis/execution/record_integral.py +196 -0
- chronaxis/execution/record_point_buffer.py +101 -0
- chronaxis/execution/record_rule_timeline.py +344 -0
- chronaxis/execution/record_sample.py +46 -0
- chronaxis/execution/record_sample_series.py +29 -0
- chronaxis/execution/record_scope_calculations.py +290 -0
- chronaxis/execution/record_selection.py +62 -0
- chronaxis/execution/record_sequences.py +199 -0
- chronaxis/execution/record_session_calculations.py +778 -0
- chronaxis/execution/record_signal_export.py +133 -0
- chronaxis/execution/record_source_cursor.py +295 -0
- chronaxis/execution/record_time_calculation.py +322 -0
- chronaxis/execution/record_time_indexes.py +143 -0
- chronaxis/execution/record_value_history.py +160 -0
- chronaxis/execution/record_windows.py +229 -0
- chronaxis/execution/required_expression.py +52 -0
- chronaxis/execution/retained_metadata.py +71 -0
- chronaxis/execution/run_session.py +402 -0
- chronaxis/execution/scanned_signal_proof.py +550 -0
- chronaxis/execution/signal_validity.py +40 -0
- chronaxis/execution/state.py +280 -0
- chronaxis/execution/temporal_buffer.py +508 -0
- chronaxis/execution/text_can_reader.py +359 -0
- chronaxis/execution/timeline.py +309 -0
- chronaxis/execution/timeline_multi.py +415 -0
- chronaxis/execution/window_delta_events.py +220 -0
- chronaxis/execution/window_replay.py +350 -0
- chronaxis/execution/windows.py +173 -0
- chronaxis/guide/README.md +70 -0
- chronaxis/guide/api/AnalysisError.md +14 -0
- chronaxis/guide/api/AnalysisPlan.md +96 -0
- chronaxis/guide/api/AnalysisResult.md +398 -0
- chronaxis/guide/api/AnalysisRunner.md +155 -0
- chronaxis/guide/api/BatchJob.md +19 -0
- chronaxis/guide/api/BatchJobResult.md +61 -0
- chronaxis/guide/api/BatchPlan.md +48 -0
- chronaxis/guide/api/BatchReport.md +108 -0
- chronaxis/guide/api/BatchRunner.md +84 -0
- chronaxis/guide/api/OutputManifest.md +23 -0
- chronaxis/guide/api/PlanFragment.md +47 -0
- chronaxis/guide/api/PlanValidationError.md +98 -0
- chronaxis/guide/api/PresetSpec.md +63 -0
- chronaxis/guide/api/ResultClosedError.md +14 -0
- chronaxis/guide/api/RunMetadata.md +100 -0
- chronaxis/guide/api/TimeConversion.md +29 -0
- chronaxis/guide/api/TimeOverflowError.md +17 -0
- chronaxis/guide/api/build_preset.md +36 -0
- chronaxis/guide/api/checked_add_ns.md +30 -0
- chronaxis/guide/api/convert_time.md +40 -0
- chronaxis/guide/api/explain_analysis_plan.md +38 -0
- chronaxis/guide/api/index.json +185 -0
- chronaxis/guide/api/load_analysis_plan.md +34 -0
- chronaxis/guide/api/load_batch_plan.md +36 -0
- chronaxis/guide/api/parse_datetime_ns.md +35 -0
- chronaxis/guide/api/parse_duration.md +30 -0
- chronaxis/guide/api/resolve_preset_roles.md +37 -0
- chronaxis/guide/api/run_batch.md +38 -0
- chronaxis/guide/api/shift_times_reference.md +33 -0
- chronaxis/guide/api/time_deltas_reference.md +37 -0
- chronaxis/guide/api/validate_analysis_plan.md +38 -0
- chronaxis/guide/en/README.md +74 -0
- chronaxis/guide/en/api/AnalysisError.md +14 -0
- chronaxis/guide/en/api/AnalysisPlan.md +93 -0
- chronaxis/guide/en/api/AnalysisResult.md +398 -0
- chronaxis/guide/en/api/AnalysisRunner.md +191 -0
- chronaxis/guide/en/api/BatchJob.md +17 -0
- chronaxis/guide/en/api/BatchJobResult.md +43 -0
- chronaxis/guide/en/api/BatchPlan.md +37 -0
- chronaxis/guide/en/api/BatchReport.md +52 -0
- chronaxis/guide/en/api/BatchRunner.md +51 -0
- chronaxis/guide/en/api/OutputManifest.md +23 -0
- chronaxis/guide/en/api/PlanFragment.md +33 -0
- chronaxis/guide/en/api/PlanValidationError.md +58 -0
- chronaxis/guide/en/api/PresetSpec.md +51 -0
- chronaxis/guide/en/api/ResultClosedError.md +14 -0
- chronaxis/guide/en/api/RunMetadata.md +100 -0
- chronaxis/guide/en/api/TimeConversion.md +23 -0
- chronaxis/guide/en/api/TimeOverflowError.md +14 -0
- chronaxis/guide/en/api/build_preset.md +23 -0
- chronaxis/guide/en/api/checked_add_ns.md +21 -0
- chronaxis/guide/en/api/convert_time.md +25 -0
- chronaxis/guide/en/api/explain_analysis_plan.md +30 -0
- chronaxis/guide/en/api/index.json +185 -0
- chronaxis/guide/en/api/load_analysis_plan.md +27 -0
- chronaxis/guide/en/api/load_batch_plan.md +28 -0
- chronaxis/guide/en/api/parse_datetime_ns.md +23 -0
- chronaxis/guide/en/api/parse_duration.md +20 -0
- chronaxis/guide/en/api/resolve_preset_roles.md +23 -0
- chronaxis/guide/en/api/run_batch.md +39 -0
- chronaxis/guide/en/api/shift_times_reference.md +21 -0
- chronaxis/guide/en/api/time_deltas_reference.md +22 -0
- chronaxis/guide/en/api/validate_analysis_plan.md +29 -0
- chronaxis/guide/en/fields/analysis/calculations-all-1.json +345 -0
- chronaxis/guide/en/fields/analysis/calculations-all-2.json +300 -0
- chronaxis/guide/en/fields/analysis/calculations-all-3.json +84 -0
- chronaxis/guide/en/fields/analysis/config_version-all-1.json +24 -0
- chronaxis/guide/en/fields/analysis/dataset-all-1.json +344 -0
- chronaxis/guide/en/fields/analysis/derived-all-1.json +147 -0
- chronaxis/guide/en/fields/analysis/diagnostics-all-1.json +69 -0
- chronaxis/guide/en/fields/analysis/execution-all-1.json +167 -0
- chronaxis/guide/en/fields/analysis/imports-all-1.json +39 -0
- chronaxis/guide/en/fields/analysis/intervals-all-1.json +173 -0
- chronaxis/guide/en/fields/analysis/message_calculations-all-1.json +345 -0
- chronaxis/guide/en/fields/analysis/message_calculations-all-2.json +270 -0
- chronaxis/guide/en/fields/analysis/metadata-all-1.json +24 -0
- chronaxis/guide/en/fields/analysis/outputs-all-1.json +332 -0
- chronaxis/guide/en/fields/analysis/outputs-all-2.json +319 -0
- chronaxis/guide/en/fields/analysis/outputs-all-3.json +321 -0
- chronaxis/guide/en/fields/analysis/outputs-all-4.json +236 -0
- chronaxis/guide/en/fields/analysis/outputs-all-5.json +246 -0
- chronaxis/guide/en/fields/analysis/outputs-all-6.json +214 -0
- chronaxis/guide/en/fields/analysis/overrides-all-1.json +104 -0
- chronaxis/guide/en/fields/analysis/presets-charge_session-1.json +398 -0
- chronaxis/guide/en/fields/analysis/presets-charge_session-2.json +114 -0
- chronaxis/guide/en/fields/analysis/presets-command_response-1.json +376 -0
- chronaxis/guide/en/fields/analysis/presets-fault_context-1.json +285 -0
- chronaxis/guide/en/fields/analysis/presets-threshold_excursion-1.json +317 -0
- chronaxis/guide/en/fields/analysis/rules-condition_duration-1.json +344 -0
- chronaxis/guide/en/fields/analysis/rules-condition_duration-2.json +27 -0
- chronaxis/guide/en/fields/analysis/rules-debounce-1.json +335 -0
- chronaxis/guide/en/fields/analysis/rules-falling_edge-1.json +317 -0
- chronaxis/guide/en/fields/analysis/rules-hysteresis-1.json +334 -0
- chronaxis/guide/en/fields/analysis/rules-hysteresis-2.json +27 -0
- chronaxis/guide/en/fields/analysis/rules-rising_edge-1.json +317 -0
- chronaxis/guide/en/fields/analysis/rules-start_end-1.json +333 -0
- chronaxis/guide/en/fields/analysis/rules-start_end-2.json +60 -0
- chronaxis/guide/en/fields/analysis/rules-start_only-1.json +334 -0
- chronaxis/guide/en/fields/analysis/rules-window_delta-1.json +338 -0
- chronaxis/guide/en/fields/analysis/rules-window_delta-2.json +96 -0
- chronaxis/guide/en/fields/analysis/sequences-all-1.json +378 -0
- chronaxis/guide/en/fields/analysis/sequences-all-2.json +70 -0
- chronaxis/guide/en/fields/analysis/signals-variant-1-1.json +349 -0
- chronaxis/guide/en/fields/analysis/signals-variant-1-2.json +297 -0
- chronaxis/guide/en/fields/analysis/signals-variant-1-3.json +323 -0
- chronaxis/guide/en/fields/analysis/signals-variant-1-4.json +192 -0
- chronaxis/guide/en/fields/analysis/signals-variant-2-1.json +327 -0
- chronaxis/guide/en/fields/analysis/signals-variant-2-2.json +312 -0
- chronaxis/guide/en/fields/analysis/signals-variant-2-3.json +294 -0
- chronaxis/guide/en/fields/analysis/signals-variant-2-4.json +253 -0
- chronaxis/guide/en/fields/analysis/signals-variant-2-5.json +44 -0
- chronaxis/guide/en/fields/analysis/sources-can_asc-1.json +318 -0
- chronaxis/guide/en/fields/analysis/sources-can_asc-2.json +310 -0
- chronaxis/guide/en/fields/analysis/sources-can_asc-3.json +311 -0
- chronaxis/guide/en/fields/analysis/sources-can_asc-4.json +69 -0
- chronaxis/guide/en/fields/analysis/sources-can_blf-1.json +317 -0
- chronaxis/guide/en/fields/analysis/sources-can_blf-2.json +310 -0
- chronaxis/guide/en/fields/analysis/sources-can_blf-3.json +317 -0
- chronaxis/guide/en/fields/analysis/sources-memory-1.json +332 -0
- chronaxis/guide/en/fields/analysis/sources-memory-2.json +125 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-1.json +330 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-10.json +233 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-11.json +225 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-12.json +228 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-13.json +226 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-14.json +230 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-15.json +227 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-16.json +230 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-17.json +238 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-18.json +239 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-19.json +233 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-2.json +310 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-20.json +242 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-21.json +230 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-22.json +228 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-23.json +230 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-24.json +223 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-25.json +290 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-26.json +131 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-3.json +297 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-4.json +226 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-5.json +230 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-6.json +227 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-7.json +230 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-8.json +238 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-9.json +239 -0
- chronaxis/guide/en/fields/analysis/sources-signal_csv-1.json +331 -0
- chronaxis/guide/en/fields/analysis/sources-signal_csv-2.json +307 -0
- chronaxis/guide/en/fields/analysis/sources-signal_csv-3.json +315 -0
- chronaxis/guide/en/fields/analysis/sources-variant-6-1.json +319 -0
- chronaxis/guide/en/fields/analysis/sources-variant-6-2.json +307 -0
- chronaxis/guide/en/fields/analysis/sources-variant-6-3.json +312 -0
- chronaxis/guide/en/fields/analysis/sources-variant-6-4.json +113 -0
- chronaxis/guide/en/fields/analysis/windows-all-1.json +361 -0
- chronaxis/guide/en/fields/analysis/windows-all-2.json +187 -0
- chronaxis/guide/en/fields/batch/backend-all-1.json +26 -0
- chronaxis/guide/en/fields/batch/batch_version-all-1.json +22 -0
- chronaxis/guide/en/fields/batch/fail_fast-all-1.json +22 -0
- chronaxis/guide/en/fields/batch/inputs-all-1.json +161 -0
- chronaxis/guide/en/fields/batch/jobs-all-1.json +58 -0
- chronaxis/guide/en/fields/batch/process_count-all-1.json +23 -0
- chronaxis/guide/en/fields/batch/source-all-1.json +22 -0
- chronaxis/guide/en/fields/batch/template-all-1.json +22 -0
- chronaxis/guide/en/fields/definitions/derived-all-1.json +121 -0
- chronaxis/guide/en/fields/definitions/signals-all-1.json +336 -0
- chronaxis/guide/en/fields/definitions/signals-all-2.json +307 -0
- chronaxis/guide/en/fields/definitions/signals-all-3.json +290 -0
- chronaxis/guide/en/fields/definitions/signals-all-4.json +347 -0
- chronaxis/guide/en/fields/definitions/signals-all-5.json +297 -0
- chronaxis/guide/en/fields/definitions/signals-all-6.json +259 -0
- chronaxis/guide/en/fields/definitions/signals-all-7.json +117 -0
- chronaxis/guide/en/fields/definitions/sources-all-1.json +332 -0
- chronaxis/guide/en/fields/definitions/sources-all-10.json +306 -0
- chronaxis/guide/en/fields/definitions/sources-all-11.json +294 -0
- chronaxis/guide/en/fields/definitions/sources-all-12.json +212 -0
- chronaxis/guide/en/fields/definitions/sources-all-13.json +217 -0
- chronaxis/guide/en/fields/definitions/sources-all-14.json +213 -0
- chronaxis/guide/en/fields/definitions/sources-all-15.json +214 -0
- chronaxis/guide/en/fields/definitions/sources-all-16.json +215 -0
- chronaxis/guide/en/fields/definitions/sources-all-17.json +213 -0
- chronaxis/guide/en/fields/definitions/sources-all-18.json +214 -0
- chronaxis/guide/en/fields/definitions/sources-all-19.json +213 -0
- chronaxis/guide/en/fields/definitions/sources-all-2.json +323 -0
- chronaxis/guide/en/fields/definitions/sources-all-20.json +217 -0
- chronaxis/guide/en/fields/definitions/sources-all-21.json +210 -0
- chronaxis/guide/en/fields/definitions/sources-all-22.json +214 -0
- chronaxis/guide/en/fields/definitions/sources-all-23.json +218 -0
- chronaxis/guide/en/fields/definitions/sources-all-24.json +209 -0
- chronaxis/guide/en/fields/definitions/sources-all-25.json +215 -0
- chronaxis/guide/en/fields/definitions/sources-all-26.json +218 -0
- chronaxis/guide/en/fields/definitions/sources-all-27.json +224 -0
- chronaxis/guide/en/fields/definitions/sources-all-28.json +215 -0
- chronaxis/guide/en/fields/definitions/sources-all-29.json +205 -0
- chronaxis/guide/en/fields/definitions/sources-all-3.json +303 -0
- chronaxis/guide/en/fields/definitions/sources-all-30.json +298 -0
- chronaxis/guide/en/fields/definitions/sources-all-31.json +315 -0
- chronaxis/guide/en/fields/definitions/sources-all-32.json +306 -0
- chronaxis/guide/en/fields/definitions/sources-all-33.json +209 -0
- chronaxis/guide/en/fields/definitions/sources-all-4.json +336 -0
- chronaxis/guide/en/fields/definitions/sources-all-5.json +299 -0
- chronaxis/guide/en/fields/definitions/sources-all-6.json +307 -0
- chronaxis/guide/en/fields/definitions/sources-all-7.json +320 -0
- chronaxis/guide/en/fields/definitions/sources-all-8.json +303 -0
- chronaxis/guide/en/fields/definitions/sources-all-9.json +315 -0
- chronaxis/guide/en/fields/index.json +3450 -0
- chronaxis/guide/en/fields/mapping/aliases-all-1.json +91 -0
- chronaxis/guide/en/fields/mapping/analysis-all-1.json +382 -0
- chronaxis/guide/en/fields/mapping/analysis-all-10.json +301 -0
- chronaxis/guide/en/fields/mapping/analysis-all-11.json +312 -0
- chronaxis/guide/en/fields/mapping/analysis-all-12.json +311 -0
- chronaxis/guide/en/fields/mapping/analysis-all-13.json +314 -0
- chronaxis/guide/en/fields/mapping/analysis-all-14.json +310 -0
- chronaxis/guide/en/fields/mapping/analysis-all-15.json +297 -0
- chronaxis/guide/en/fields/mapping/analysis-all-16.json +226 -0
- chronaxis/guide/en/fields/mapping/analysis-all-17.json +230 -0
- chronaxis/guide/en/fields/mapping/analysis-all-18.json +227 -0
- chronaxis/guide/en/fields/mapping/analysis-all-19.json +230 -0
- chronaxis/guide/en/fields/mapping/analysis-all-2.json +323 -0
- chronaxis/guide/en/fields/mapping/analysis-all-20.json +221 -0
- chronaxis/guide/en/fields/mapping/analysis-all-21.json +237 -0
- chronaxis/guide/en/fields/mapping/analysis-all-22.json +233 -0
- chronaxis/guide/en/fields/mapping/analysis-all-23.json +222 -0
- chronaxis/guide/en/fields/mapping/analysis-all-24.json +231 -0
- chronaxis/guide/en/fields/mapping/analysis-all-25.json +225 -0
- chronaxis/guide/en/fields/mapping/analysis-all-26.json +230 -0
- chronaxis/guide/en/fields/mapping/analysis-all-27.json +228 -0
- chronaxis/guide/en/fields/mapping/analysis-all-28.json +230 -0
- chronaxis/guide/en/fields/mapping/analysis-all-29.json +223 -0
- chronaxis/guide/en/fields/mapping/analysis-all-3.json +318 -0
- chronaxis/guide/en/fields/mapping/analysis-all-30.json +233 -0
- chronaxis/guide/en/fields/mapping/analysis-all-31.json +218 -0
- chronaxis/guide/en/fields/mapping/analysis-all-32.json +239 -0
- chronaxis/guide/en/fields/mapping/analysis-all-33.json +233 -0
- chronaxis/guide/en/fields/mapping/analysis-all-34.json +225 -0
- chronaxis/guide/en/fields/mapping/analysis-all-35.json +228 -0
- chronaxis/guide/en/fields/mapping/analysis-all-36.json +226 -0
- chronaxis/guide/en/fields/mapping/analysis-all-37.json +244 -0
- chronaxis/guide/en/fields/mapping/analysis-all-38.json +326 -0
- chronaxis/guide/en/fields/mapping/analysis-all-39.json +299 -0
- chronaxis/guide/en/fields/mapping/analysis-all-4.json +297 -0
- chronaxis/guide/en/fields/mapping/analysis-all-40.json +311 -0
- chronaxis/guide/en/fields/mapping/analysis-all-41.json +310 -0
- chronaxis/guide/en/fields/mapping/analysis-all-42.json +346 -0
- chronaxis/guide/en/fields/mapping/analysis-all-43.json +267 -0
- chronaxis/guide/en/fields/mapping/analysis-all-44.json +327 -0
- chronaxis/guide/en/fields/mapping/analysis-all-45.json +279 -0
- chronaxis/guide/en/fields/mapping/analysis-all-46.json +327 -0
- chronaxis/guide/en/fields/mapping/analysis-all-47.json +312 -0
- chronaxis/guide/en/fields/mapping/analysis-all-48.json +294 -0
- chronaxis/guide/en/fields/mapping/analysis-all-49.json +253 -0
- chronaxis/guide/en/fields/mapping/analysis-all-5.json +312 -0
- chronaxis/guide/en/fields/mapping/analysis-all-50.json +346 -0
- chronaxis/guide/en/fields/mapping/analysis-all-51.json +324 -0
- chronaxis/guide/en/fields/mapping/analysis-all-52.json +335 -0
- chronaxis/guide/en/fields/mapping/analysis-all-53.json +317 -0
- chronaxis/guide/en/fields/mapping/analysis-all-54.json +316 -0
- chronaxis/guide/en/fields/mapping/analysis-all-55.json +302 -0
- chronaxis/guide/en/fields/mapping/analysis-all-56.json +319 -0
- chronaxis/guide/en/fields/mapping/analysis-all-57.json +334 -0
- chronaxis/guide/en/fields/mapping/analysis-all-58.json +333 -0
- chronaxis/guide/en/fields/mapping/analysis-all-59.json +359 -0
- chronaxis/guide/en/fields/mapping/analysis-all-6.json +327 -0
- chronaxis/guide/en/fields/mapping/analysis-all-60.json +303 -0
- chronaxis/guide/en/fields/mapping/analysis-all-61.json +326 -0
- chronaxis/guide/en/fields/mapping/analysis-all-62.json +301 -0
- chronaxis/guide/en/fields/mapping/analysis-all-63.json +326 -0
- chronaxis/guide/en/fields/mapping/analysis-all-64.json +367 -0
- chronaxis/guide/en/fields/mapping/analysis-all-65.json +334 -0
- chronaxis/guide/en/fields/mapping/analysis-all-66.json +358 -0
- chronaxis/guide/en/fields/mapping/analysis-all-67.json +349 -0
- chronaxis/guide/en/fields/mapping/analysis-all-68.json +331 -0
- chronaxis/guide/en/fields/mapping/analysis-all-69.json +304 -0
- chronaxis/guide/en/fields/mapping/analysis-all-7.json +303 -0
- chronaxis/guide/en/fields/mapping/analysis-all-70.json +349 -0
- chronaxis/guide/en/fields/mapping/analysis-all-71.json +288 -0
- chronaxis/guide/en/fields/mapping/analysis-all-72.json +316 -0
- chronaxis/guide/en/fields/mapping/analysis-all-73.json +266 -0
- chronaxis/guide/en/fields/mapping/analysis-all-74.json +227 -0
- chronaxis/guide/en/fields/mapping/analysis-all-75.json +239 -0
- chronaxis/guide/en/fields/mapping/analysis-all-76.json +274 -0
- chronaxis/guide/en/fields/mapping/analysis-all-77.json +380 -0
- chronaxis/guide/en/fields/mapping/analysis-all-78.json +313 -0
- chronaxis/guide/en/fields/mapping/analysis-all-79.json +338 -0
- chronaxis/guide/en/fields/mapping/analysis-all-8.json +292 -0
- chronaxis/guide/en/fields/mapping/analysis-all-80.json +304 -0
- chronaxis/guide/en/fields/mapping/analysis-all-81.json +140 -0
- chronaxis/guide/en/fields/mapping/analysis-all-9.json +332 -0
- chronaxis/guide/en/fields/mapping/io_policy-all-1.json +19 -0
- chronaxis/guide/en/fields/mapping/mapping_version-all-1.json +19 -0
- chronaxis/guide/en/fields/mapping/path_base-all-1.json +19 -0
- chronaxis/guide/en/fields/mapping/sections-all-1.json +402 -0
- chronaxis/guide/en/fields/mapping/sections-all-2.json +232 -0
- chronaxis/guide/en/semantics.md +70 -0
- chronaxis/guide/en/tasks.json +290 -0
- chronaxis/guide/en/workflow.md +41 -0
- chronaxis/guide/examples/analysis-imports.yaml +22 -0
- chronaxis/guide/examples/analysis.yaml +23 -0
- chronaxis/guide/examples/batch-minimal.yaml +3 -0
- chronaxis/guide/examples/conditional-energy.yaml +36 -0
- chronaxis/guide/examples/data/activity.csv +6 -0
- chronaxis/guide/examples/data/can/activity.asc +11 -0
- chronaxis/guide/examples/data/can/calculation-minimal.asc +6 -0
- chronaxis/guide/examples/data/can/conditional-energy/part-1.asc +92 -0
- chronaxis/guide/examples/data/can/conditional-energy/part-2.asc +36 -0
- chronaxis/guide/examples/data/can/conditional-energy/signals.dbc +10 -0
- chronaxis/guide/examples/data/can/execution-comparison.asc +12 -0
- chronaxis/guide/examples/data/can/execution-report.asc +4 -0
- chronaxis/guide/examples/data/can/expression-extended.asc +11 -0
- chronaxis/guide/examples/data/can/interval-actual.asc +6 -0
- chronaxis/guide/examples/data/can/preset-charge-energy.asc +15 -0
- chronaxis/guide/examples/data/can/preset-charge-minimal.asc +11 -0
- chronaxis/guide/examples/data/can/preset-command-automatic.asc +11 -0
- chronaxis/guide/examples/data/can/preset-fault-context.asc +7 -0
- chronaxis/guide/examples/data/can/preset-threshold-delay.asc +7 -0
- chronaxis/guide/examples/data/can/preset-threshold-partial.asc +7 -0
- chronaxis/guide/examples/data/can/quality.asc +6 -0
- chronaxis/guide/examples/data/can/quickstart-parts/part1.asc +4 -0
- chronaxis/guide/examples/data/can/quickstart-parts/part2.asc +3 -0
- chronaxis/guide/examples/data/can/quickstart.asc +6 -0
- chronaxis/guide/examples/data/can/rule-condition_duration-extended.asc +35 -0
- chronaxis/guide/examples/data/can/rule-condition_duration-minimal.asc +19 -0
- chronaxis/guide/examples/data/can/rule-debounce-extended.asc +19 -0
- chronaxis/guide/examples/data/can/rule-falling_edge-extended.asc +35 -0
- chronaxis/guide/examples/data/can/rule-hysteresis-extended.asc +19 -0
- chronaxis/guide/examples/data/can/rule-start_end-extended.asc +35 -0
- chronaxis/guide/examples/data/can/rule-start_only-extended.asc +19 -0
- chronaxis/guide/examples/data/can/rule-window_delta-extended.asc +19 -0
- chronaxis/guide/examples/data/can/sequence-outcomes.asc +19 -0
- chronaxis/guide/examples/data/can/signal-types.asc +13 -0
- chronaxis/guide/examples/data/can/start-end.asc +30 -0
- chronaxis/guide/examples/data/can/teaching-base.asc +58 -0
- chronaxis/guide/examples/data/can/teaching.dbc +53 -0
- chronaxis/guide/examples/data/joint-current.csv +5 -0
- chronaxis/guide/examples/data/joint.asc +5 -0
- chronaxis/guide/examples/data/joint.dbc +7 -0
- chronaxis/guide/examples/data/message-clean.asc +6 -0
- chronaxis/guide/examples/data/message-direction.asc +7 -0
- chronaxis/guide/examples/data/message-direction.dbc +7 -0
- chronaxis/guide/examples/data/power.blf +0 -0
- chronaxis/guide/examples/data/power.dbc +6 -0
- chronaxis/guide/examples/data/quality.csv +5 -0
- chronaxis/guide/examples/data/raw-can-example.csv +5 -0
- chronaxis/guide/examples/data/signal-types.csv +5 -0
- chronaxis/guide/examples/data/signals.csv +6 -0
- chronaxis/guide/examples/data/timing.asc +6 -0
- chronaxis/guide/examples/data/timing.dbc +11 -0
- chronaxis/guide/examples/export-can-minimal.yaml +24 -0
- chronaxis/guide/examples/input-csv-minimal.yaml +23 -0
- chronaxis/guide/examples/preset-charge-energy.yaml +41 -0
- chronaxis/guide/examples/preset-charge-minimal.yaml +31 -0
- chronaxis/guide/examples/preset-fault-context.yaml +27 -0
- chronaxis/guide/examples/quality.yaml +19 -0
- chronaxis/guide/examples/sequence-outcomes.yaml +39 -0
- chronaxis/guide/examples/shared/definitions.yaml +14 -0
- chronaxis/guide/examples/signal-enum-minimal.yaml +19 -0
- chronaxis/guide/examples/signal-number-conversion.yaml +24 -0
- chronaxis/guide/examples/window-merged.yaml +28 -0
- chronaxis/guide/fields/analysis/calculations-all-1.json +360 -0
- chronaxis/guide/fields/analysis/calculations-all-2.json +299 -0
- chronaxis/guide/fields/analysis/calculations-all-3.json +70 -0
- chronaxis/guide/fields/analysis/config_version-all-1.json +24 -0
- chronaxis/guide/fields/analysis/dataset-all-1.json +344 -0
- chronaxis/guide/fields/analysis/derived-all-1.json +147 -0
- chronaxis/guide/fields/analysis/diagnostics-all-1.json +69 -0
- chronaxis/guide/fields/analysis/execution-all-1.json +167 -0
- chronaxis/guide/fields/analysis/imports-all-1.json +39 -0
- chronaxis/guide/fields/analysis/intervals-all-1.json +173 -0
- chronaxis/guide/fields/analysis/message_calculations-all-1.json +360 -0
- chronaxis/guide/fields/analysis/message_calculations-all-2.json +255 -0
- chronaxis/guide/fields/analysis/metadata-all-1.json +24 -0
- chronaxis/guide/fields/analysis/outputs-all-1.json +349 -0
- chronaxis/guide/fields/analysis/outputs-all-2.json +302 -0
- chronaxis/guide/fields/analysis/outputs-all-3.json +321 -0
- chronaxis/guide/fields/analysis/outputs-all-4.json +253 -0
- chronaxis/guide/fields/analysis/outputs-all-5.json +244 -0
- chronaxis/guide/fields/analysis/outputs-all-6.json +199 -0
- chronaxis/guide/fields/analysis/overrides-all-1.json +104 -0
- chronaxis/guide/fields/analysis/presets-charge_session-1.json +398 -0
- chronaxis/guide/fields/analysis/presets-charge_session-2.json +114 -0
- chronaxis/guide/fields/analysis/presets-command_response-1.json +376 -0
- chronaxis/guide/fields/analysis/presets-fault_context-1.json +285 -0
- chronaxis/guide/fields/analysis/presets-threshold_excursion-1.json +317 -0
- chronaxis/guide/fields/analysis/rules-condition_duration-1.json +344 -0
- chronaxis/guide/fields/analysis/rules-condition_duration-2.json +27 -0
- chronaxis/guide/fields/analysis/rules-debounce-1.json +335 -0
- chronaxis/guide/fields/analysis/rules-falling_edge-1.json +317 -0
- chronaxis/guide/fields/analysis/rules-hysteresis-1.json +334 -0
- chronaxis/guide/fields/analysis/rules-hysteresis-2.json +27 -0
- chronaxis/guide/fields/analysis/rules-rising_edge-1.json +317 -0
- chronaxis/guide/fields/analysis/rules-start_end-1.json +349 -0
- chronaxis/guide/fields/analysis/rules-start_end-2.json +44 -0
- chronaxis/guide/fields/analysis/rules-start_only-1.json +334 -0
- chronaxis/guide/fields/analysis/rules-window_delta-1.json +356 -0
- chronaxis/guide/fields/analysis/rules-window_delta-2.json +78 -0
- chronaxis/guide/fields/analysis/sequences-all-1.json +394 -0
- chronaxis/guide/fields/analysis/sequences-all-2.json +54 -0
- chronaxis/guide/fields/analysis/signals-variant-1-1.json +349 -0
- chronaxis/guide/fields/analysis/signals-variant-1-2.json +297 -0
- chronaxis/guide/fields/analysis/signals-variant-1-3.json +340 -0
- chronaxis/guide/fields/analysis/signals-variant-1-4.json +175 -0
- chronaxis/guide/fields/analysis/signals-variant-2-1.json +327 -0
- chronaxis/guide/fields/analysis/signals-variant-2-2.json +335 -0
- chronaxis/guide/fields/analysis/signals-variant-2-3.json +289 -0
- chronaxis/guide/fields/analysis/signals-variant-2-4.json +270 -0
- chronaxis/guide/fields/analysis/sources-can_asc-1.json +318 -0
- chronaxis/guide/fields/analysis/sources-can_asc-2.json +310 -0
- chronaxis/guide/fields/analysis/sources-can_asc-3.json +311 -0
- chronaxis/guide/fields/analysis/sources-can_asc-4.json +69 -0
- chronaxis/guide/fields/analysis/sources-can_blf-1.json +317 -0
- chronaxis/guide/fields/analysis/sources-can_blf-2.json +310 -0
- chronaxis/guide/fields/analysis/sources-can_blf-3.json +317 -0
- chronaxis/guide/fields/analysis/sources-memory-1.json +347 -0
- chronaxis/guide/fields/analysis/sources-memory-2.json +110 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-1.json +330 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-10.json +233 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-11.json +225 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-12.json +228 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-13.json +226 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-14.json +230 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-15.json +227 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-16.json +230 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-17.json +238 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-18.json +239 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-19.json +233 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-2.json +310 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-20.json +242 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-21.json +230 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-22.json +228 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-23.json +230 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-24.json +223 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-25.json +290 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-26.json +131 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-3.json +297 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-4.json +226 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-5.json +230 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-6.json +227 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-7.json +230 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-8.json +238 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-9.json +239 -0
- chronaxis/guide/fields/analysis/sources-signal_csv-1.json +331 -0
- chronaxis/guide/fields/analysis/sources-signal_csv-2.json +327 -0
- chronaxis/guide/fields/analysis/sources-signal_csv-3.json +295 -0
- chronaxis/guide/fields/analysis/sources-variant-6-1.json +319 -0
- chronaxis/guide/fields/analysis/sources-variant-6-2.json +327 -0
- chronaxis/guide/fields/analysis/sources-variant-6-3.json +314 -0
- chronaxis/guide/fields/analysis/sources-variant-6-4.json +91 -0
- chronaxis/guide/fields/analysis/windows-all-1.json +361 -0
- chronaxis/guide/fields/analysis/windows-all-2.json +187 -0
- chronaxis/guide/fields/batch/backend-all-1.json +26 -0
- chronaxis/guide/fields/batch/batch_version-all-1.json +22 -0
- chronaxis/guide/fields/batch/fail_fast-all-1.json +22 -0
- chronaxis/guide/fields/batch/inputs-all-1.json +161 -0
- chronaxis/guide/fields/batch/jobs-all-1.json +58 -0
- chronaxis/guide/fields/batch/process_count-all-1.json +23 -0
- chronaxis/guide/fields/batch/source-all-1.json +22 -0
- chronaxis/guide/fields/batch/template-all-1.json +22 -0
- chronaxis/guide/fields/definitions/derived-all-1.json +121 -0
- chronaxis/guide/fields/definitions/signals-all-1.json +336 -0
- chronaxis/guide/fields/definitions/signals-all-2.json +307 -0
- chronaxis/guide/fields/definitions/signals-all-3.json +305 -0
- chronaxis/guide/fields/definitions/signals-all-4.json +352 -0
- chronaxis/guide/fields/definitions/signals-all-5.json +311 -0
- chronaxis/guide/fields/definitions/signals-all-6.json +254 -0
- chronaxis/guide/fields/definitions/signals-all-7.json +88 -0
- chronaxis/guide/fields/definitions/sources-all-1.json +332 -0
- chronaxis/guide/fields/definitions/sources-all-10.json +307 -0
- chronaxis/guide/fields/definitions/sources-all-11.json +280 -0
- chronaxis/guide/fields/definitions/sources-all-12.json +209 -0
- chronaxis/guide/fields/definitions/sources-all-13.json +219 -0
- chronaxis/guide/fields/definitions/sources-all-14.json +213 -0
- chronaxis/guide/fields/definitions/sources-all-15.json +212 -0
- chronaxis/guide/fields/definitions/sources-all-16.json +232 -0
- chronaxis/guide/fields/definitions/sources-all-17.json +213 -0
- chronaxis/guide/fields/definitions/sources-all-18.json +212 -0
- chronaxis/guide/fields/definitions/sources-all-19.json +217 -0
- chronaxis/guide/fields/definitions/sources-all-2.json +336 -0
- chronaxis/guide/fields/definitions/sources-all-20.json +228 -0
- chronaxis/guide/fields/definitions/sources-all-21.json +212 -0
- chronaxis/guide/fields/definitions/sources-all-22.json +232 -0
- chronaxis/guide/fields/definitions/sources-all-23.json +213 -0
- chronaxis/guide/fields/definitions/sources-all-24.json +212 -0
- chronaxis/guide/fields/definitions/sources-all-25.json +217 -0
- chronaxis/guide/fields/definitions/sources-all-26.json +228 -0
- chronaxis/guide/fields/definitions/sources-all-27.json +212 -0
- chronaxis/guide/fields/definitions/sources-all-28.json +217 -0
- chronaxis/guide/fields/definitions/sources-all-29.json +227 -0
- chronaxis/guide/fields/definitions/sources-all-3.json +306 -0
- chronaxis/guide/fields/definitions/sources-all-30.json +333 -0
- chronaxis/guide/fields/definitions/sources-all-31.json +302 -0
- chronaxis/guide/fields/definitions/sources-all-32.json +319 -0
- chronaxis/guide/fields/definitions/sources-all-33.json +89 -0
- chronaxis/guide/fields/definitions/sources-all-4.json +336 -0
- chronaxis/guide/fields/definitions/sources-all-5.json +313 -0
- chronaxis/guide/fields/definitions/sources-all-6.json +292 -0
- chronaxis/guide/fields/definitions/sources-all-7.json +319 -0
- chronaxis/guide/fields/definitions/sources-all-8.json +315 -0
- chronaxis/guide/fields/definitions/sources-all-9.json +318 -0
- chronaxis/guide/fields/index.json +3432 -0
- chronaxis/guide/fields/mapping/aliases-all-1.json +91 -0
- chronaxis/guide/fields/mapping/analysis-all-1.json +382 -0
- chronaxis/guide/fields/mapping/analysis-all-10.json +307 -0
- chronaxis/guide/fields/mapping/analysis-all-11.json +311 -0
- chronaxis/guide/fields/mapping/analysis-all-12.json +329 -0
- chronaxis/guide/fields/mapping/analysis-all-13.json +294 -0
- chronaxis/guide/fields/mapping/analysis-all-14.json +311 -0
- chronaxis/guide/fields/mapping/analysis-all-15.json +280 -0
- chronaxis/guide/fields/mapping/analysis-all-16.json +227 -0
- chronaxis/guide/fields/mapping/analysis-all-17.json +230 -0
- chronaxis/guide/fields/mapping/analysis-all-18.json +221 -0
- chronaxis/guide/fields/mapping/analysis-all-19.json +237 -0
- chronaxis/guide/fields/mapping/analysis-all-2.json +342 -0
- chronaxis/guide/fields/mapping/analysis-all-20.json +233 -0
- chronaxis/guide/fields/mapping/analysis-all-21.json +244 -0
- chronaxis/guide/fields/mapping/analysis-all-22.json +228 -0
- chronaxis/guide/fields/mapping/analysis-all-23.json +226 -0
- chronaxis/guide/fields/mapping/analysis-all-24.json +230 -0
- chronaxis/guide/fields/mapping/analysis-all-25.json +227 -0
- chronaxis/guide/fields/mapping/analysis-all-26.json +230 -0
- chronaxis/guide/fields/mapping/analysis-all-27.json +221 -0
- chronaxis/guide/fields/mapping/analysis-all-28.json +237 -0
- chronaxis/guide/fields/mapping/analysis-all-29.json +233 -0
- chronaxis/guide/fields/mapping/analysis-all-3.json +322 -0
- chronaxis/guide/fields/mapping/analysis-all-30.json +244 -0
- chronaxis/guide/fields/mapping/analysis-all-31.json +228 -0
- chronaxis/guide/fields/mapping/analysis-all-32.json +226 -0
- chronaxis/guide/fields/mapping/analysis-all-33.json +230 -0
- chronaxis/guide/fields/mapping/analysis-all-34.json +227 -0
- chronaxis/guide/fields/mapping/analysis-all-35.json +230 -0
- chronaxis/guide/fields/mapping/analysis-all-36.json +221 -0
- chronaxis/guide/fields/mapping/analysis-all-37.json +291 -0
- chronaxis/guide/fields/mapping/analysis-all-38.json +315 -0
- chronaxis/guide/fields/mapping/analysis-all-39.json +304 -0
- chronaxis/guide/fields/mapping/analysis-all-4.json +312 -0
- chronaxis/guide/fields/mapping/analysis-all-40.json +307 -0
- chronaxis/guide/fields/mapping/analysis-all-41.json +292 -0
- chronaxis/guide/fields/mapping/analysis-all-42.json +333 -0
- chronaxis/guide/fields/mapping/analysis-all-43.json +296 -0
- chronaxis/guide/fields/mapping/analysis-all-44.json +322 -0
- chronaxis/guide/fields/mapping/analysis-all-45.json +298 -0
- chronaxis/guide/fields/mapping/analysis-all-46.json +347 -0
- chronaxis/guide/fields/mapping/analysis-all-47.json +302 -0
- chronaxis/guide/fields/mapping/analysis-all-48.json +263 -0
- chronaxis/guide/fields/mapping/analysis-all-49.json +301 -0
- chronaxis/guide/fields/mapping/analysis-all-5.json +313 -0
- chronaxis/guide/fields/mapping/analysis-all-50.json +336 -0
- chronaxis/guide/fields/mapping/analysis-all-51.json +335 -0
- chronaxis/guide/fields/mapping/analysis-all-52.json +335 -0
- chronaxis/guide/fields/mapping/analysis-all-53.json +334 -0
- chronaxis/guide/fields/mapping/analysis-all-54.json +339 -0
- chronaxis/guide/fields/mapping/analysis-all-55.json +335 -0
- chronaxis/guide/fields/mapping/analysis-all-56.json +336 -0
- chronaxis/guide/fields/mapping/analysis-all-57.json +335 -0
- chronaxis/guide/fields/mapping/analysis-all-58.json +333 -0
- chronaxis/guide/fields/mapping/analysis-all-59.json +325 -0
- chronaxis/guide/fields/mapping/analysis-all-6.json +323 -0
- chronaxis/guide/fields/mapping/analysis-all-60.json +334 -0
- chronaxis/guide/fields/mapping/analysis-all-61.json +311 -0
- chronaxis/guide/fields/mapping/analysis-all-62.json +289 -0
- chronaxis/guide/fields/mapping/analysis-all-63.json +383 -0
- chronaxis/guide/fields/mapping/analysis-all-64.json +357 -0
- chronaxis/guide/fields/mapping/analysis-all-65.json +375 -0
- chronaxis/guide/fields/mapping/analysis-all-66.json +351 -0
- chronaxis/guide/fields/mapping/analysis-all-67.json +346 -0
- chronaxis/guide/fields/mapping/analysis-all-68.json +317 -0
- chronaxis/guide/fields/mapping/analysis-all-69.json +313 -0
- chronaxis/guide/fields/mapping/analysis-all-7.json +306 -0
- chronaxis/guide/fields/mapping/analysis-all-70.json +326 -0
- chronaxis/guide/fields/mapping/analysis-all-71.json +316 -0
- chronaxis/guide/fields/mapping/analysis-all-72.json +264 -0
- chronaxis/guide/fields/mapping/analysis-all-73.json +228 -0
- chronaxis/guide/fields/mapping/analysis-all-74.json +241 -0
- chronaxis/guide/fields/mapping/analysis-all-75.json +273 -0
- chronaxis/guide/fields/mapping/analysis-all-76.json +382 -0
- chronaxis/guide/fields/mapping/analysis-all-77.json +328 -0
- chronaxis/guide/fields/mapping/analysis-all-78.json +338 -0
- chronaxis/guide/fields/mapping/analysis-all-79.json +304 -0
- chronaxis/guide/fields/mapping/analysis-all-8.json +309 -0
- chronaxis/guide/fields/mapping/analysis-all-80.json +140 -0
- chronaxis/guide/fields/mapping/analysis-all-9.json +329 -0
- chronaxis/guide/fields/mapping/io_policy-all-1.json +19 -0
- chronaxis/guide/fields/mapping/mapping_version-all-1.json +19 -0
- chronaxis/guide/fields/mapping/path_base-all-1.json +19 -0
- chronaxis/guide/fields/mapping/sections-all-1.json +402 -0
- chronaxis/guide/fields/mapping/sections-all-2.json +232 -0
- chronaxis/guide/lookup.py +90 -0
- chronaxis/guide/manifest.json +614 -0
- chronaxis/guide/run_analysis.py +34 -0
- chronaxis/guide/schemas/analysis.schema.json +8451 -0
- chronaxis/guide/schemas/batch-v1.schema.json +172 -0
- chronaxis/guide/schemas/definitions.schema.json +29 -0
- chronaxis/guide/schemas/legacy-import-v1.schema.json +143 -0
- chronaxis/guide/semantics.md +62 -0
- chronaxis/guide/tasks.json +290 -0
- chronaxis/guide/workflow.md +38 -0
- chronaxis/legacy/__init__.py +46 -0
- chronaxis/legacy/batch_read.py +412 -0
- chronaxis/legacy/batch_validation.py +134 -0
- chronaxis/legacy/batch_wire.py +264 -0
- chronaxis/legacy/batch_worker.py +417 -0
- chronaxis/legacy/binding.py +154 -0
- chronaxis/legacy/dbc_cycles.py +47 -0
- chronaxis/legacy/decode_policy.py +28 -0
- chronaxis/legacy/disjunction.py +79 -0
- chronaxis/legacy/export_worker.py +147 -0
- chronaxis/legacy/export_write.py +378 -0
- chronaxis/legacy/message_store.py +562 -0
- chronaxis/legacy/process_read.py +526 -0
- chronaxis/legacy/raw_store.py +341 -0
- chronaxis/legacy/records.py +709 -0
- chronaxis/legacy/required_records.py +122 -0
- chronaxis/legacy/sum.py +403 -0
- chronaxis/legacy/sum_numpy.py +43 -0
- chronaxis/legacy/updates.py +277 -0
- chronaxis/legacy/vendor/sclicer_functions_v1/can_processor.py +138 -0
- chronaxis/legacy/vendor/sclicer_functions_v1/file_processor.py +218 -0
- chronaxis/legacy/vendor/sclicer_functions_v1/utils.py +447 -0
- chronaxis/legacy/worker.py +352 -0
- chronaxis/migration/__init__.py +11 -0
- chronaxis/migration/api.py +270 -0
- chronaxis/migration/ini.py +110 -0
- chronaxis/migration/legacy_sum.py +304 -0
- chronaxis/migration/models.py +83 -0
- chronaxis/migration/publication.py +230 -0
- chronaxis/migration/sclicer.py +241 -0
- chronaxis/migration/slope.py +78 -0
- chronaxis/migration/start_end.py +48 -0
- chronaxis/planning/__init__.py +19 -0
- chronaxis/planning/channels.py +30 -0
- chronaxis/planning/checks.py +447 -0
- chronaxis/planning/config_groups.py +215 -0
- chronaxis/planning/dbc_defaults.py +88 -0
- chronaxis/planning/export_options.py +247 -0
- chronaxis/planning/input_defaults.py +62 -0
- chronaxis/planning/input_paths.py +124 -0
- chronaxis/planning/input_requirements.py +250 -0
- chronaxis/planning/inputs.py +306 -0
- chronaxis/planning/intervals.py +242 -0
- chronaxis/planning/legacy_execution.py +38 -0
- chronaxis/planning/message_calculations.py +171 -0
- chronaxis/planning/models.py +369 -0
- chronaxis/planning/nodes.py +355 -0
- chronaxis/planning/plan.py +294 -0
- chronaxis/planning/preset_models.py +211 -0
- chronaxis/planning/record_execution.py +76 -0
- chronaxis/planning/reports.py +523 -0
- chronaxis/planning/sequences.py +91 -0
- chronaxis/planning/signal_groups.py +61 -0
- chronaxis/planning/signal_validity.py +46 -0
- chronaxis/planning/text_inputs.py +110 -0
- chronaxis/presets.py +270 -0
- chronaxis/results/__init__.py +34 -0
- chronaxis/results/analysis_outcome.py +67 -0
- chronaxis/results/artifact_exports.py +212 -0
- chronaxis/results/binding_metadata.py +54 -0
- chronaxis/results/budget.py +138 -0
- chronaxis/results/can_metadata.py +247 -0
- chronaxis/results/codec.py +246 -0
- chronaxis/results/errors.py +25 -0
- chronaxis/results/export_files.py +216 -0
- chronaxis/results/frame_exports.py +299 -0
- chronaxis/results/frame_patch.py +186 -0
- chronaxis/results/frame_rebuild.py +458 -0
- chronaxis/results/frame_sort.py +223 -0
- chronaxis/results/input_diagnostics.py +51 -0
- chronaxis/results/manifest.py +343 -0
- chronaxis/results/merge_runs.py +207 -0
- chronaxis/results/owned_directory.py +32 -0
- chronaxis/results/raw_exports.py +689 -0
- chronaxis/results/readable.py +355 -0
- chronaxis/results/readable_format.py +94 -0
- chronaxis/results/result.py +734 -0
- chronaxis/results/rows.py +57 -0
- chronaxis/results/signal_exports.py +209 -0
- chronaxis/results/signal_grid.py +219 -0
- chronaxis/results/spool.py +421 -0
- chronaxis/results/summary.py +350 -0
- chronaxis/results/text_can_metadata.py +64 -0
- chronaxis/results/threshold_metadata.py +105 -0
- chronaxis/runner.py +121 -0
- chronaxis/sources/__init__.py +23 -0
- chronaxis/sources/asc.py +412 -0
- chronaxis/sources/blf.py +101 -0
- chronaxis/sources/can_spec.py +179 -0
- chronaxis/sources/can_updates.py +160 -0
- chronaxis/sources/csv_spec.py +133 -0
- chronaxis/sources/descriptions.py +65 -0
- chronaxis/sources/memory.py +299 -0
- chronaxis/sources/models.py +497 -0
- chronaxis/sources/packing.py +170 -0
- chronaxis/sources/protocol.py +221 -0
- chronaxis/sources/raw_can.py +62 -0
- chronaxis/sources/raw_csv.py +470 -0
- chronaxis/sources/raw_csv_layout.py +310 -0
- chronaxis/sources/signal_csv.py +608 -0
- chronaxis/sources/text_can_decode.py +421 -0
- chronaxis/sources/text_can_ref.py +48 -0
- chronaxis/sources/text_can_spec.py +61 -0
- chronaxis/timebase/__init__.py +19 -0
- chronaxis/timebase/conversion.py +364 -0
- chronaxis/timebase/numpy_ops.py +104 -0
- chronaxis/user_guide.py +81 -0
- chronaxis-0.1.0.dev0.dist-info/METADATA +172 -0
- chronaxis-0.1.0.dev0.dist-info/RECORD +917 -0
- chronaxis-0.1.0.dev0.dist-info/WHEEL +5 -0
- chronaxis-0.1.0.dev0.dist-info/entry_points.txt +2 -0
- chronaxis-0.1.0.dev0.dist-info/licenses/LICENSE +21 -0
- chronaxis-0.1.0.dev0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
"""在独立spawn进程按一条PULL许可推进一次冻结Sclicer公开函数链。
|
|
2
|
+
|
|
3
|
+
静态只导入标准库和records;INIT校验后才核三份原样vendor哈希、导入真实依赖,
|
|
4
|
+
原load_file一次并创建原iter_frames,不提前next。READY的单位来自同次db公开
|
|
5
|
+
messages/signals;每PULL只next一次、对同msg/db原parse_frame一次,返当前ITEM
|
|
6
|
+
后等待下一命令。STATUS/ACK不授予读取许可,STOP不取后继,正常EOF后退出。
|
|
7
|
+
|
|
8
|
+
本进程只发送最大65536字节的严格JSON bytes,不使用Connection.send/recv的pickle。
|
|
9
|
+
记录保原msg全部公开写出字段和全部原返回数值,不窥视generator frame、补decode、
|
|
10
|
+
增加筛选或缩放。finally只关本连接和原生成器,不声称旧reader底层FD已确定关闭;
|
|
11
|
+
父进程须等待本进程确实退出,OS才回收本进程旧FD。外部解释器/DBC/reader的RSS
|
|
12
|
+
不受父共享账目保证。失败发送有限原错误事实并以非零退出,不伪称原异常对象跨进程。
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
# spawn加载时不触及CAN库、原vendor或输入;这些依赖只在收到有效INIT后加载。
|
|
16
|
+
from hashlib import sha256
|
|
17
|
+
from importlib import metadata, util
|
|
18
|
+
import os
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
import platform
|
|
21
|
+
import sys
|
|
22
|
+
from .records import (LegacyCANRequest, LegacyDecodedFrame, LegacyRawFrame, MAX_WIRE_BYTES,
|
|
23
|
+
PROFILE_ID, decode_packet, decoded_to_dict, encode_packet, field_from_dict, field_to_dict)
|
|
24
|
+
|
|
25
|
+
# vendor文件复制自历史Sclicer项目;以下哈希用于核对原始文件字节。
|
|
26
|
+
VENDOR_SHA256 = {
|
|
27
|
+
'utils.py': 'cf3737ad5ab0a399dc7576585102339e0312b9babe690a1ba8decf543a71c2fd',
|
|
28
|
+
'file_processor.py': '5f37bd996ccd31eedd95bec5ed39289cd7f2fe3049110ebbe195db0cbefb1db6',
|
|
29
|
+
'can_processor.py': '3c96e67a1ec47ac181657b5bf5a9cabf7e35a1d5e2709577718c22d1293878e2',
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _send(connection, packet):
|
|
34
|
+
"""通过bytes接口发送一个有界JSON包,不调用pickle通道。
|
|
35
|
+
|
|
36
|
+
参数: connection为本子进程Connection;packet为协议dict。返回: None。
|
|
37
|
+
异常: 原wire类型/限额或管道错误;不重试导致重复ITEM。
|
|
38
|
+
"""
|
|
39
|
+
connection.send_bytes(encode_packet(packet))
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _receive(connection):
|
|
43
|
+
"""只接收一个不超过单包上限的bytes消息。
|
|
44
|
+
|
|
45
|
+
参数: connection为本子进程Connection。返回: 已校验dict。
|
|
46
|
+
异常: EOFError/OSError/协议错误传播,不把断管当正常来源EOF。
|
|
47
|
+
"""
|
|
48
|
+
return decode_packet(connection.recv_bytes(MAX_WIRE_BYTES))
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _exact(packet, names):
|
|
52
|
+
"""限制每种控制包的精确字段,不让多余许可或版本字段静默生效。
|
|
53
|
+
|
|
54
|
+
参数: packet为已解析dict;names为允许键容器。返回: None。
|
|
55
|
+
异常: ValueError为字段缺失或多余。
|
|
56
|
+
"""
|
|
57
|
+
if set(packet) != set(names):
|
|
58
|
+
raise ValueError('旧CAN控制包字段缺失或多余')
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _request(packet):
|
|
62
|
+
"""解析唯一INIT,只接受单个实际BLF和原DBC路径,不读取其内容摘要。
|
|
63
|
+
|
|
64
|
+
参数: packet为INIT dict。返回: LegacyCANRequest。
|
|
65
|
+
异常: 类型/形状/版本/路径错误;不调用旧reader或load_file。
|
|
66
|
+
"""
|
|
67
|
+
_exact(packet, ('op', 'version', 'path', 'dbc_path', 'fields'))
|
|
68
|
+
if packet['op'] != 'init' or type(packet['version']) is not int or packet['version'] != 1:
|
|
69
|
+
raise ValueError('旧CAN需要init/version1')
|
|
70
|
+
if type(packet['path']) is not str or type(packet['dbc_path']) is not str or type(packet['fields']) is not list:
|
|
71
|
+
raise TypeError('旧CAN INIT需要文本路径与fields数组')
|
|
72
|
+
request = LegacyCANRequest(Path(packet['path']), Path(packet['dbc_path']),
|
|
73
|
+
tuple(field_from_dict(value) for value in packet['fields']))
|
|
74
|
+
# 只做stat和扩展名边界;不额外读取原CAN或预扫消息,不暗换另一种profile。
|
|
75
|
+
if request.input_path.suffix.lower() != '.blf' or not request.input_path.is_file():
|
|
76
|
+
raise ValueError('首版旧CAN仅支持单个现有BLF文件')
|
|
77
|
+
if not request.dbc_path.is_file():
|
|
78
|
+
raise FileNotFoundError(request.dbc_path)
|
|
79
|
+
return request
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _load_vendor():
|
|
83
|
+
"""核原样三模块字节后在独立child安装其原名称,保绝对utils导入。
|
|
84
|
+
|
|
85
|
+
参数: 无。返回: (file_processor模块,can_processor模块,实际哈希dict)。
|
|
86
|
+
异常: 哈希、同名模块污染或原模块依赖导入错误;不猴补函数、reader或计数器。
|
|
87
|
+
"""
|
|
88
|
+
root = Path(__file__).resolve().parent / 'vendor' / 'sclicer_functions_v1'
|
|
89
|
+
actual = {}
|
|
90
|
+
for name, expected in VENDOR_SHA256.items():
|
|
91
|
+
actual[name] = sha256((root / name).read_bytes()).hexdigest()
|
|
92
|
+
if actual[name] != expected:
|
|
93
|
+
raise ValueError('旧CAN vendor哈希不匹配: ' + name)
|
|
94
|
+
# 原file_processor使用from utils导入;仅child内按原模块名加载,不碰父sys.modules。
|
|
95
|
+
modules = {}
|
|
96
|
+
sys.dont_write_bytecode = True
|
|
97
|
+
for name in ('utils', 'file_processor', 'can_processor'):
|
|
98
|
+
if name in sys.modules:
|
|
99
|
+
raise RuntimeError('隔离旧CAN进程存在同名模块: ' + name)
|
|
100
|
+
spec = util.spec_from_file_location(name, root / (name + '.py'))
|
|
101
|
+
if spec is None or spec.loader is None:
|
|
102
|
+
raise ImportError('无法加载原vendor模块: ' + name)
|
|
103
|
+
module = util.module_from_spec(spec)
|
|
104
|
+
sys.modules[name] = module
|
|
105
|
+
try:
|
|
106
|
+
spec.loader.exec_module(module)
|
|
107
|
+
except ModuleNotFoundError as error:
|
|
108
|
+
# 保持冻结模块原导入顺序,仅补充真实缺失依赖的可执行处理建议。
|
|
109
|
+
from ..can_dependencies import CANDependencyError
|
|
110
|
+
raise CANDependencyError(error.name or '未知模块') from error
|
|
111
|
+
modules[name] = module
|
|
112
|
+
return modules['file_processor'], modules['can_processor'], actual
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def _field_metadata(db, fields, *, cycle_fields=()):
|
|
116
|
+
"""只读同次db公开messages/signals核定位唯一,并返回原单位。
|
|
117
|
+
|
|
118
|
+
参数: db为唯一原load_file结果;fields为原LegacyCANField tuple;
|
|
119
|
+
cycle_fields仅指定需要周期的字段,须在fields中。默认不访问cycle_time。
|
|
120
|
+
返回: 按请求顺序的字段事实;周期请求的字段另含正cycle_ns。
|
|
121
|
+
仅DBC为FD而定位为经典CAN时增加固定兼容提示。
|
|
122
|
+
channel保声明,不冒称DBC已测通道;不把DBC声明写回原帧。
|
|
123
|
+
异常: ValueError为ID/消息/帧型/信号歧义或不符,TypeError为单位不受支持。
|
|
124
|
+
"""
|
|
125
|
+
if cycle_fields:
|
|
126
|
+
from .dbc_cycles import require_cycle_fields, cycle_time_ns
|
|
127
|
+
require_cycle_fields(cycle_fields)
|
|
128
|
+
if not set(cycle_fields).issubset(fields):
|
|
129
|
+
raise ValueError('周期字段须包含在本次DBC定位中')
|
|
130
|
+
from .binding import dbc_candidates
|
|
131
|
+
periods = {} if cycle_fields else None
|
|
132
|
+
result = []
|
|
133
|
+
for field in fields:
|
|
134
|
+
# 多定义允许由实际原帧决定;初始化所需的单位不能随候选改变。
|
|
135
|
+
candidates = dbc_candidates(db, field.frame_id, (field.signal,), field.is_extended, field.is_fd)
|
|
136
|
+
units = {signal.unit for message in candidates for signal in message.signals if signal.name == field.signal}
|
|
137
|
+
if len(units) != 1:
|
|
138
|
+
raise ValueError('候选DBC信号单位不同,请补充 is_extended 或 is_fd: ' + field.signal)
|
|
139
|
+
unit = next(iter(units))
|
|
140
|
+
compatible = field.is_fd is False and all(message.is_fd is True for message in candidates)
|
|
141
|
+
if unit is not None and type(unit) is not str:
|
|
142
|
+
raise TypeError('原DBC公开unit需要文本或None')
|
|
143
|
+
item = {'locator': field_to_dict(field), 'unit': unit}
|
|
144
|
+
if field.is_extended is None or field.is_fd is None:
|
|
145
|
+
# 父读取器据此跳过同ID但不含所需信号的帧,不伪造一次失效更新。
|
|
146
|
+
item['dbc_frames'] = [list(pair) for pair in dict.fromkeys(
|
|
147
|
+
(message.is_extended_frame, message.is_fd) for message in candidates)]
|
|
148
|
+
if compatible:
|
|
149
|
+
item['frame_format_compatibility'] = {'code': 'dbc_fd_classic_selector',
|
|
150
|
+
'dbc_is_fd': True, 'requested_is_fd': False}
|
|
151
|
+
if field in cycle_fields:
|
|
152
|
+
# 同一物理报文多个别名只取一次周期,后续记录不再访问DBC周期。
|
|
153
|
+
values = set()
|
|
154
|
+
for message in candidates:
|
|
155
|
+
# 多信号来自同一消息对象时只读一次周期,同ID不同定义不能相互覆盖。
|
|
156
|
+
identity = id(message)
|
|
157
|
+
if identity not in periods:
|
|
158
|
+
periods[identity] = cycle_time_ns(message.cycle_time)
|
|
159
|
+
values.add(periods[identity])
|
|
160
|
+
if len(values) != 1:
|
|
161
|
+
raise ValueError('候选DBC周期不同,请补充帧类型、period 或 valid_for: ' + field.signal)
|
|
162
|
+
item['cycle_ns'] = next(iter(values))
|
|
163
|
+
result.append(item)
|
|
164
|
+
return result
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def _frame(msg):
|
|
168
|
+
"""在一次原parse之后保存同次msg公开写出字段,不重建CAN消息。
|
|
169
|
+
|
|
170
|
+
参数: msg为本次原iter_frames刚yield的can.Message。返回: LegacyRawFrame。
|
|
171
|
+
异常: 新边界字段校验失败;data仅无损复制为bytes,不改timestamp/DLC/标志。
|
|
172
|
+
"""
|
|
173
|
+
if len(msg.data) > 64:
|
|
174
|
+
raise ValueError('原报文data超过64字节,不能先复制再拒绝')
|
|
175
|
+
return LegacyRawFrame(timestamp=msg.timestamp, arbitration_id=msg.arbitration_id,
|
|
176
|
+
is_extended_id=msg.is_extended_id, is_remote_frame=msg.is_remote_frame,
|
|
177
|
+
is_error_frame=msg.is_error_frame, channel=msg.channel, dlc=msg.dlc, data=bytes(msg.data),
|
|
178
|
+
is_fd=msg.is_fd, is_rx=msg.is_rx, bitrate_switch=msg.bitrate_switch,
|
|
179
|
+
error_state_indicator=msg.error_state_indicator)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def _argument_text(value, limit):
|
|
183
|
+
"""只摘要原生异常参数,不执行任意对象str或先展开完整巨型消息。
|
|
184
|
+
|
|
185
|
+
参数: value为一个原args值;limit为最大字符数。返回: 有限str,短原str保持内容。
|
|
186
|
+
异常: 无主动异常;未知对象仅标明类型,不调用其自定义字符串方法。
|
|
187
|
+
"""
|
|
188
|
+
if type(value) is str:
|
|
189
|
+
return value[:limit]
|
|
190
|
+
if value is None or type(value) in (bool, float):
|
|
191
|
+
return repr(value)[:limit]
|
|
192
|
+
if type(value) is int:
|
|
193
|
+
return str(value)[:limit] if value.bit_length() <= 128 else '<超过128位的整数参数>'
|
|
194
|
+
return '<参数类型:' + type(value).__name__[:64] + '>'
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def _error_packet(exc, phase, request_id):
|
|
198
|
+
"""保存有限原错误事实,不把远端异常对象或任意类传给父进程。
|
|
199
|
+
|
|
200
|
+
参数: exc为本child原错;phase为有限阶段文本;request_id为当前许可或None。
|
|
201
|
+
返回: 有限ERROR dict;message是至多4个args摘要,traceback仅至多8个栈地点,
|
|
202
|
+
均不是完整str(exc)或完整traceback,截断有明确note,短单str参数保持原文本。
|
|
203
|
+
异常: 标准库字段访问/编码错误传播;调用方仍须确定退出,不伪报正常EOF。
|
|
204
|
+
"""
|
|
205
|
+
# 不全量format_exception/str(exc),仅读有限原参数及栈地点,绝不访问locals/gi_frame。
|
|
206
|
+
arguments = exc.args if type(exc.args) is tuple else ()
|
|
207
|
+
message = ', '.join(_argument_text(value, 1024) for value in arguments[:4])
|
|
208
|
+
if not arguments:
|
|
209
|
+
message = '远端异常无可安全摘要的原生args'
|
|
210
|
+
places, current = [], exc.__traceback__
|
|
211
|
+
for _ in range(8):
|
|
212
|
+
if current is None:
|
|
213
|
+
break
|
|
214
|
+
code = current.tb_frame.f_code
|
|
215
|
+
places.append(code.co_filename[:256] + ':' + str(current.tb_lineno) + ' ' + code.co_name[:128])
|
|
216
|
+
current = current.tb_next
|
|
217
|
+
trace = '\n'.join(places)
|
|
218
|
+
original_notes = getattr(exc, '__notes__', ())
|
|
219
|
+
notes = [note[:256] if type(note) is str else '<非文本note>' for note in
|
|
220
|
+
(original_notes[:8] if type(original_notes) in (tuple, list) else ())]
|
|
221
|
+
notes.append('远端message仅原args有限摘要;traceback仅有限栈地点,非完整str/trace。')
|
|
222
|
+
limit = 4096
|
|
223
|
+
while True:
|
|
224
|
+
packet = {'op': 'error', 'request_id': request_id, 'phase': phase,
|
|
225
|
+
'error': {'module': type(exc).__module__[:128], 'type': type(exc).__name__[:128],
|
|
226
|
+
'message': message[:limit], 'traceback': trace[:limit],
|
|
227
|
+
'notes': [note[:min(limit, 256)] for note in notes] + ['远端诊断有界;可能截断。']}}
|
|
228
|
+
try:
|
|
229
|
+
encode_packet(packet)
|
|
230
|
+
return packet
|
|
231
|
+
except ValueError:
|
|
232
|
+
# 每轮减半,固定包头的诊断不受输入长度放大;最短仍明确失败类型。
|
|
233
|
+
if limit <= 64:
|
|
234
|
+
return {'op': 'error', 'request_id': request_id, 'phase': phase,
|
|
235
|
+
'error': {'module': type(exc).__module__[:32], 'type': type(exc).__name__[:32],
|
|
236
|
+
'message': '远端错误诊断超过wire上限', 'traceback': '', 'notes': ['诊断已截断。']}}
|
|
237
|
+
limit //= 2
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def _report_error(connection, exc, phase, request_id):
|
|
241
|
+
"""尽力发送原错误事实,断管不替代child原错或阻止退出。
|
|
242
|
+
|
|
243
|
+
参数: connection为本连接;exc/phase/request_id为原失败事实。返回: None。
|
|
244
|
+
异常: 不传播附加报告错误;原失败仍由worker最终非零退出表达。
|
|
245
|
+
"""
|
|
246
|
+
try:
|
|
247
|
+
_send(connection, _error_packet(exc, phase, request_id))
|
|
248
|
+
except BaseException as diagnostic:
|
|
249
|
+
exc.add_note('旧CAN远端错误报告附加失败: ' + type(diagnostic).__name__)
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def worker_main(connection):
|
|
253
|
+
"""作为spawn目标按INIT/PULL协议调用冻结旧公开链,等待许可时不预取。
|
|
254
|
+
|
|
255
|
+
参数: connection为父传来的独立duplex Connection。返回: 正常STOP或真实EOF时None。
|
|
256
|
+
异常: 原错误尽力发ERROR后以SystemExit(1)退出;连接/生成器附加关闭错误也非零。
|
|
257
|
+
副作用: 本child内一次load_file、一次iter_frames、每许可一次next/parse;不额外扫描。
|
|
258
|
+
"""
|
|
259
|
+
iterator, failure, request_id = None, None, None
|
|
260
|
+
phase = 'init'
|
|
261
|
+
pulls_received = frames_returned = parse_calls = 0
|
|
262
|
+
try:
|
|
263
|
+
request = _request(_receive(connection))
|
|
264
|
+
phase = 'vendor'
|
|
265
|
+
files, processor, vendor = _load_vendor()
|
|
266
|
+
phase = 'dbc'
|
|
267
|
+
# 通过原模块实际导入的cantools执行唯一原load_file,不加选项或第二次解析。
|
|
268
|
+
db = processor.cantools.database.load_file(str(request.dbc_path))
|
|
269
|
+
phase = 'metadata'
|
|
270
|
+
from .binding import FrameBindingResolver
|
|
271
|
+
from .batch_worker import _parse_selected
|
|
272
|
+
from collections import Counter
|
|
273
|
+
resolver = FrameBindingResolver(db, request.fields)
|
|
274
|
+
duplicate_ids = {frame_id for frame_id, count in Counter(message.frame_id for message in db.messages).items()
|
|
275
|
+
if count > 1}
|
|
276
|
+
phase = 'metadata'
|
|
277
|
+
fields = _field_metadata(db, request.fields)
|
|
278
|
+
iterator = files.iter_frames(str(request.input_path))
|
|
279
|
+
versions = {'python': platform.python_version(), 'python-can': metadata.version('python-can'),
|
|
280
|
+
'cantools': metadata.version('cantools'), 'natsort': metadata.version('natsort')}
|
|
281
|
+
_send(connection, {'op': 'ready', 'version': 1, 'profile': PROFILE_ID, 'worker_pid': os.getpid(),
|
|
282
|
+
'fields': fields, 'dependency_versions': versions, 'vendor_sha256': vendor})
|
|
283
|
+
# 只在收到下一条PULL时取原下一帧;STATUS/ACK/STOP均不授予此许可。
|
|
284
|
+
while True:
|
|
285
|
+
phase, request_id = 'control', None
|
|
286
|
+
packet = _receive(connection)
|
|
287
|
+
operation = packet.get('op')
|
|
288
|
+
if operation == 'stop':
|
|
289
|
+
_exact(packet, ('op',))
|
|
290
|
+
break
|
|
291
|
+
if operation == 'status':
|
|
292
|
+
_exact(packet, ('op',))
|
|
293
|
+
_send(connection, {'op': 'status', 'pulls_received': pulls_received,
|
|
294
|
+
'frames_returned': frames_returned, 'parse_calls': parse_calls})
|
|
295
|
+
continue
|
|
296
|
+
if operation == 'ack':
|
|
297
|
+
expected = ('op', 'request_id') if 'request_id' in packet else ('op',)
|
|
298
|
+
_exact(packet, expected)
|
|
299
|
+
if 'request_id' in packet and (frames_returned == 0 or type(packet['request_id']) is not int
|
|
300
|
+
or packet['request_id'] != frames_returned - 1):
|
|
301
|
+
raise ValueError('ACK只允许确认最近返回ITEM')
|
|
302
|
+
_send(connection, packet)
|
|
303
|
+
continue
|
|
304
|
+
if operation != 'pull':
|
|
305
|
+
raise ValueError('未知旧CAN控制操作')
|
|
306
|
+
_exact(packet, ('op', 'request_id'))
|
|
307
|
+
candidate_id = packet['request_id']
|
|
308
|
+
request_id = candidate_id if type(candidate_id) is int and candidate_id >= 0 else None
|
|
309
|
+
if request_id is None or request_id != frames_returned:
|
|
310
|
+
raise ValueError('PULL许可必须从0严格连续')
|
|
311
|
+
pulls_received += 1
|
|
312
|
+
phase = 'next'
|
|
313
|
+
try:
|
|
314
|
+
msg = next(iterator)
|
|
315
|
+
except StopIteration:
|
|
316
|
+
# EOF需要实际多一次许可,候选发出后仍须父确认本child退出,不能靠断管猜EOF。
|
|
317
|
+
_send(connection, {'op': 'eof', 'request_id': request_id, 'frame_count': frames_returned})
|
|
318
|
+
break
|
|
319
|
+
phase = 'parse'
|
|
320
|
+
parse_calls += 1
|
|
321
|
+
fields_for_frame = resolver.fields_for(msg)
|
|
322
|
+
message = resolver.message_for(msg, fields_for_frame)
|
|
323
|
+
values = _parse_selected(processor, db, msg, message, duplicate_ids)
|
|
324
|
+
phase = 'item'
|
|
325
|
+
record = LegacyDecodedFrame(frames_returned, _frame(msg), values)
|
|
326
|
+
_send(connection, {'op': 'item', 'request_id': request_id, 'record': decoded_to_dict(record)})
|
|
327
|
+
frames_returned += 1
|
|
328
|
+
# 释放本层当前wire/记录引用,不给下一帧任何许可;旧generator内部状态不读取。
|
|
329
|
+
msg = values = record = None
|
|
330
|
+
except BaseException as exc:
|
|
331
|
+
failure = exc
|
|
332
|
+
_report_error(connection, exc, phase, request_id)
|
|
333
|
+
finally:
|
|
334
|
+
# 旧生成器close不是底层FD关闭证明;进程退出才由OS回收旧未公开reader资源。
|
|
335
|
+
if iterator is not None:
|
|
336
|
+
try:
|
|
337
|
+
iterator.close()
|
|
338
|
+
except BaseException as cleanup:
|
|
339
|
+
if failure is None:
|
|
340
|
+
failure = cleanup
|
|
341
|
+
_report_error(connection, cleanup, 'generator_close', request_id)
|
|
342
|
+
else:
|
|
343
|
+
failure.add_note('旧生成器关闭附加失败: ' + type(cleanup).__name__)
|
|
344
|
+
try:
|
|
345
|
+
connection.close()
|
|
346
|
+
except BaseException as cleanup:
|
|
347
|
+
if failure is None:
|
|
348
|
+
failure = cleanup
|
|
349
|
+
else:
|
|
350
|
+
failure.add_note('旧CAN子连接关闭附加失败: ' + type(cleanup).__name__)
|
|
351
|
+
if failure is not None:
|
|
352
|
+
raise SystemExit(1)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""公开安全旧配置导入及冻结迁移报告,不启动来源扫描或旧配置对象。
|
|
2
|
+
|
|
3
|
+
输入为原INI bytes与显式mapping,或两个配置路径;输出完整静态AnalysisPlan
|
|
4
|
+
和逐字段报告。当前模式能力以各入口返回的report为准;导入成功不是数据验收。
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .api import import_legacy_ini, load_legacy_ini
|
|
8
|
+
from .models import LegacyFieldMapping, LegacyImportIssue, LegacyImportReport, LegacyImportResult
|
|
9
|
+
|
|
10
|
+
__all__ = ['import_legacy_ini', 'load_legacy_ini', 'LegacyImportResult', 'LegacyImportReport',
|
|
11
|
+
'LegacyImportIssue', 'LegacyFieldMapping']
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
"""提供纯字节旧INI导入与显式配置文件的加载入口,不读取分析数据。
|
|
2
|
+
|
|
3
|
+
共享流程检查原生JSON mapping、保存身份、复制analysis并固定词法绝对路径,
|
|
4
|
+
按模式转换后调用公开AnalysisPlan.from_dict/validate_analysis_plan。配置语义错误返回
|
|
5
|
+
整份失败报告;API类型、文件I/O、内存与取消错误保持原生异常,不伪装成成功。
|
|
6
|
+
支持Sclicer single/start_only、显式slope/start_end迁移和当前消息legacy_sum;不承诺旧完整缓存等价。
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import hashlib
|
|
10
|
+
import json
|
|
11
|
+
from dataclasses import replace
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
from ..configuration import load_configuration, ConfigurationError, field_path_text
|
|
15
|
+
from ..configuration.diagnostics import locate_error, field_path_parts
|
|
16
|
+
from ..planning import AnalysisPlan, PlanValidationError, validate_analysis_plan
|
|
17
|
+
from ..planning.checks import absolute_path, require_json_value
|
|
18
|
+
from .ini import ImportProblem, parse_ini, problem
|
|
19
|
+
from .models import LegacyImportIssue, LegacyImportReport, LegacyImportResult
|
|
20
|
+
from .sclicer import convert_sclicer
|
|
21
|
+
from .legacy_sum import convert_legacy_sum
|
|
22
|
+
|
|
23
|
+
MODES = ('legacy_sum', 'sclicer_single', 'sclicer_start_only', 'sclicer_slope', 'sclicer_start_end')
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _arguments(content, mapping, mode, base_dir, source_name, device_label):
|
|
27
|
+
"""先核公开API类型,不把编程错误包成迁移拒绝。
|
|
28
|
+
|
|
29
|
+
参数: 原公开入口参数。返回: None。异常: TypeError为原生类型错误;ValueError为未知mode。
|
|
30
|
+
"""
|
|
31
|
+
if type(content) is not bytes or type(mapping) is not dict:
|
|
32
|
+
raise TypeError('content需要bytes,mapping需要原生dict')
|
|
33
|
+
if type(mode) is not str or type(source_name) is not str or type(device_label) is not str:
|
|
34
|
+
raise TypeError('mode/source_name/device_label需要原生str')
|
|
35
|
+
if not isinstance(base_dir, (str, Path)):
|
|
36
|
+
raise TypeError('base_dir需要str或Path')
|
|
37
|
+
if mode not in MODES:
|
|
38
|
+
raise ValueError('未知导入mode:' + mode)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _report(content, mode, source_name, device_label, mapping_identity, fields, issues, plan):
|
|
42
|
+
"""封装整份结果;参数: 本次原事实;返回: LegacyImportResult;异常: 资源错误原样传播。"""
|
|
43
|
+
report = LegacyImportReport('success' if plan is not None else 'failed', mode, source_name,
|
|
44
|
+
hashlib.sha256(content).hexdigest(), mapping_identity, device_label,
|
|
45
|
+
tuple(fields), tuple(issues), None if plan is None else plan.identity)
|
|
46
|
+
return LegacyImportResult(plan, report, content)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _prepare_mapping(mapping, base):
|
|
50
|
+
"""检查完整mapping合同并复制为独立可修改分析配置。
|
|
51
|
+
|
|
52
|
+
参数: mapping原生对象;base词法绝对目录。返回: (独立mapping, identity)。
|
|
53
|
+
异常: ImportProblem/PlanValidationError为配置问题。目录输入会展开文件集合,缺省CAN声明会读取DBC。
|
|
54
|
+
"""
|
|
55
|
+
require_json_value(mapping, '$')
|
|
56
|
+
required = {'mapping_version', 'analysis'}
|
|
57
|
+
if not required <= set(mapping) or set(mapping) - required - {'aliases', 'sections', 'path_base', 'io_policy'}:
|
|
58
|
+
problem('invalid_mapping_shape', 'mapping', '$', 'mapping需要版本、analysis;aliases、sections、路径与IO策略可选')
|
|
59
|
+
if type(mapping['mapping_version']) is not int or mapping['mapping_version'] != 1:
|
|
60
|
+
problem('invalid_mapping_version', 'mapping', '$.mapping_version', '仅支持原生整数1')
|
|
61
|
+
if mapping.get('path_base', 'mapping_directory') != 'mapping_directory' or mapping.get('io_policy', 'explicit_mapping') != 'explicit_mapping':
|
|
62
|
+
problem('invalid_mapping_policy', 'mapping', '$', '路径与IO策略只支持mapping_directory及explicit_mapping')
|
|
63
|
+
# 身份识别原mapping;路径固定和新节点仅发生于后续独立副本。
|
|
64
|
+
encoded = json.dumps(mapping, ensure_ascii=False, allow_nan=False, sort_keys=True, separators=(',', ':'))
|
|
65
|
+
identity = hashlib.sha256(encoded.encode('utf-8')).hexdigest()
|
|
66
|
+
copied = json.loads(encoded)
|
|
67
|
+
copied.setdefault('aliases',{})
|
|
68
|
+
copied.setdefault('sections',{})
|
|
69
|
+
analysis, aliases, sections = copied['analysis'], copied['aliases'], copied['sections']
|
|
70
|
+
if type(analysis) is not dict or type(aliases) is not dict or type(sections) is not dict:
|
|
71
|
+
problem('invalid_mapping_shape', 'mapping', '$', 'analysis/aliases/sections必须为对象')
|
|
72
|
+
if 'imports' in analysis:
|
|
73
|
+
problem('unresolved_imports','mapping','$.analysis.imports',
|
|
74
|
+
'纯字典映射不读取公共定义;请用load_legacy_ini加载映射文件或先config resolve')
|
|
75
|
+
from ..planning.config_groups import normalize_configuration
|
|
76
|
+
analysis=copied['analysis']=normalize_configuration(analysis)
|
|
77
|
+
for key in ('rules', 'windows', 'message_calculations', 'presets'):
|
|
78
|
+
if key in analysis and (type(analysis[key]) is not list or analysis[key]):
|
|
79
|
+
problem('nonempty_generated_nodes', 'mapping', '$.analysis.' + key, '导入前该数组必须缺省或为空')
|
|
80
|
+
signals = analysis.get('signals')
|
|
81
|
+
if type(signals) is not list:
|
|
82
|
+
problem('missing_signal_mapping', 'mapping', '$.analysis.signals', '必须显式声明signals数组')
|
|
83
|
+
from ..planning.signal_groups import signal_entries
|
|
84
|
+
signals=analysis['signals']=[dict(item) for item,_ in signal_entries(signals)]
|
|
85
|
+
names = set()
|
|
86
|
+
for index, signal in enumerate(signals):
|
|
87
|
+
if type(signal) is not dict:
|
|
88
|
+
problem('invalid_signal_mapping', 'mapping', f'$.analysis.signals[{index}]', 'signal必须为对象')
|
|
89
|
+
# 有效期可按用户周期或运行时DBC周期确定,由公共计划执行同一套检查。
|
|
90
|
+
for key in ('name',):
|
|
91
|
+
if key not in signal:
|
|
92
|
+
problem('missing_signal_metadata', 'mapping', f'$.analysis.signals[{index}].{key}', '不得猜测信号声明:' + key)
|
|
93
|
+
if type(signal['name']) is str:
|
|
94
|
+
names.add(signal['name'])
|
|
95
|
+
# 原字段只有一个候选才自动对应;明确aliases始终优先,不从表达式名称猜测。
|
|
96
|
+
candidates={}
|
|
97
|
+
for signal in signals:
|
|
98
|
+
field=signal.get('field')
|
|
99
|
+
original=field.get('signal') if type(field) is dict else field
|
|
100
|
+
if type(original) is str:candidates.setdefault(original,[]).append(signal['name'])
|
|
101
|
+
for original,choices in candidates.items():
|
|
102
|
+
if len(choices)==1:aliases.setdefault(original,choices[0])
|
|
103
|
+
for old, new in aliases.items():
|
|
104
|
+
if type(new) is not str or new not in names or not old.strip():
|
|
105
|
+
problem('invalid_alias', 'mapping', '$.aliases.' + old, '原名称须明确映射至analysis.signals别名')
|
|
106
|
+
# 不同旧Name可由用户显式指向同一新信号;每个旧键仍只有一个明确目标。
|
|
107
|
+
# JSON/YAML重复旧键由加载器拒绝,未知目标在上面拒绝,不能借此猜测字段关系。
|
|
108
|
+
# 只固定公开来源路径,不递归猜测任意metadata中的路径文本。
|
|
109
|
+
sources = analysis.get('sources')
|
|
110
|
+
if type(sources) is not list:
|
|
111
|
+
problem('missing_source_mapping', 'mapping', '$.analysis.sources', '必须显式声明sources数组')
|
|
112
|
+
for index, source in enumerate(sources):
|
|
113
|
+
if type(source) is not dict:
|
|
114
|
+
problem('invalid_source_mapping', 'mapping', f'$.analysis.sources[{index}]', 'source必须为对象')
|
|
115
|
+
# 导入与普通入口使用同一来源默认规则,不要求再次填写格式/时间/名称。
|
|
116
|
+
from ..planning.input_defaults import source_defaults
|
|
117
|
+
from ..planning.input_paths import FILE_SUFFIXES, expand_source_files
|
|
118
|
+
# 既有单文件声明保持原字段形态;只有集合声明才输出展开后的paths。
|
|
119
|
+
single_path = (type(source.get('path')) is str and Path(source['path']).suffix.lower() in FILE_SUFFIXES
|
|
120
|
+
and not source['path'].endswith(('/', '\\')))
|
|
121
|
+
if source.get('source_type') != 'memory' and ('path' in source or 'paths' in source):
|
|
122
|
+
paths, shifts = expand_source_files(source,base,f'$.analysis.sources[{index}]')
|
|
123
|
+
source = dict(source, paths=[str(item) for item in paths])
|
|
124
|
+
source.pop('path',None)
|
|
125
|
+
if shifts is not None:
|
|
126
|
+
source['offsets'] = list(shifts)
|
|
127
|
+
source = source_defaults(source, index)
|
|
128
|
+
if single_path and 'paths' in source:
|
|
129
|
+
source['path'] = source.pop('paths')[0]
|
|
130
|
+
sources[index] = source
|
|
131
|
+
path = f'$.analysis.sources[{index}]'
|
|
132
|
+
if 'path' in source:
|
|
133
|
+
source['path'] = str(absolute_path(source['path'], base, path + '.path'))
|
|
134
|
+
if 'paths' in source:
|
|
135
|
+
if type(source['paths']) is not list:
|
|
136
|
+
problem('invalid_source_mapping', 'mapping', path + '.paths', 'paths必须为数组')
|
|
137
|
+
source['paths'] = [str(absolute_path(value, base, path + '.paths')) for value in source['paths']]
|
|
138
|
+
if 'dbc_by_channel' in source:
|
|
139
|
+
if type(source['dbc_by_channel']) is not dict:
|
|
140
|
+
problem('invalid_source_mapping', 'mapping', path + '.dbc_by_channel', 'dbc_by_channel必须为对象')
|
|
141
|
+
source['dbc_by_channel'] = {key: str(absolute_path(value, base, path + '.dbc_by_channel.' + key))
|
|
142
|
+
for key, value in source['dbc_by_channel'].items()}
|
|
143
|
+
# 仅缺省声明/定位才编译来源和信号;完整旧映射不新增DBC访问。
|
|
144
|
+
if any('dtype' not in item or 'unit' not in item or 'source' not in item
|
|
145
|
+
or type(item.get('field')) is dict and 'channel' not in item['field'] for item in signals):
|
|
146
|
+
from ..planning.inputs import parse_sources, parse_signals
|
|
147
|
+
source_models=parse_sources(sources,base)
|
|
148
|
+
typed=parse_signals(signals,source_models)
|
|
149
|
+
for raw,model in zip(signals,typed):
|
|
150
|
+
raw.setdefault('dtype',model.definition.dtype.value)
|
|
151
|
+
raw.setdefault('unit',model.definition.unit)
|
|
152
|
+
raw.setdefault('source',model.definition.source)
|
|
153
|
+
if model.definition.choices:raw.setdefault('choices',[list(pair) for pair in model.definition.choices])
|
|
154
|
+
if type(raw.get('field')) is dict:
|
|
155
|
+
source=next(s for s in source_models if s.name==model.definition.source)
|
|
156
|
+
raw['field'].setdefault('channel',source.config.channel + 1)
|
|
157
|
+
return copied, identity
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def import_legacy_ini(content: bytes, mapping: dict, *, mode, base_dir,
|
|
161
|
+
source_name='input.ini', device_label='pending') -> LegacyImportResult:
|
|
162
|
+
"""从原INI字节和显式mapping生成完整静态计划或整份拒绝报告。
|
|
163
|
+
|
|
164
|
+
参数: content为原bytes,mapping为JSON对象;mode选择合同模式;base_dir
|
|
165
|
+
为mapping目录;source_name/device_label只标识来源。返回: LegacyImportResult,
|
|
166
|
+
original_ini保同一bytes,失败plan为None。异常: API类型/未知mode、OSError、
|
|
167
|
+
MemoryError及取消保持原对象;配置语义与UTF-8错误进入report,不返回部分计划。
|
|
168
|
+
"""
|
|
169
|
+
_arguments(content, mapping, mode, base_dir, source_name, device_label)
|
|
170
|
+
fields, issues, identity = [], [], None
|
|
171
|
+
try:
|
|
172
|
+
try:
|
|
173
|
+
text = content.decode('utf-8-sig')
|
|
174
|
+
except UnicodeDecodeError as error:
|
|
175
|
+
problem('invalid_ini_encoding', 'ini', '$', str(error))
|
|
176
|
+
base = Path(base_dir).absolute()
|
|
177
|
+
try:
|
|
178
|
+
copied, identity = _prepare_mapping(mapping, base)
|
|
179
|
+
except PlanValidationError as error:
|
|
180
|
+
problem(error.code, 'mapping', error.path,
|
|
181
|
+
error.message+(';修正:'+error.hint if error.hint else ''))
|
|
182
|
+
parser, headers = parse_ini(text, fields, preserve_case=mode == 'legacy_sum')
|
|
183
|
+
if 'sections' not in mapping:
|
|
184
|
+
if mode in ('sclicer_single','sclicer_start_only','sclicer_start_end'):
|
|
185
|
+
for number,section in enumerate((s for s in parser.sections() if s.startswith('TRIGGER_')),1):
|
|
186
|
+
item=dict(name=f'trigger_{number}',window=f'window_{number}')
|
|
187
|
+
if mode=='sclicer_start_end':item.update(semantics='start_end_timeout-v1',emit_initial=False)
|
|
188
|
+
copied['sections'][section]=item
|
|
189
|
+
else:
|
|
190
|
+
problem('missing_section_parameters','mapping','$.sections','该模式仍需提供计算单位或slope参数,不能从段名猜测')
|
|
191
|
+
analysis = copied['analysis']
|
|
192
|
+
if mode == 'legacy_sum':
|
|
193
|
+
convert_legacy_sum(parser, headers, copied, analysis, fields, issues)
|
|
194
|
+
else:
|
|
195
|
+
convert_sclicer(parser, headers, copied, analysis, fields, issues, mode)
|
|
196
|
+
try:
|
|
197
|
+
from ..planning.config_groups import public_configuration
|
|
198
|
+
plan = AnalysisPlan.from_dict(public_configuration(analysis), base_dir=base)
|
|
199
|
+
validation = validate_analysis_plan(plan)
|
|
200
|
+
except PlanValidationError as error:
|
|
201
|
+
# 新条件错误仍回指原字段;其他计划配置错误明确归mapping,不制造INI行号。
|
|
202
|
+
original = next((item for item in fields if item.target == error.path), None)
|
|
203
|
+
problem(error.code, 'ini' if original else 'mapping', original.path if original else error.path,
|
|
204
|
+
error.message+(';修正:'+error.hint if error.hint else ''),
|
|
205
|
+
original.line if original else None, original.column if original else None)
|
|
206
|
+
if not validation.valid or not validation.execution_ready:
|
|
207
|
+
problem('plan_unavailable', 'plan', '$', '; '.join(validation.errors))
|
|
208
|
+
for warning in validation.warnings:
|
|
209
|
+
issues.append(LegacyImportIssue('static_unverified', 'plan', '$', warning, level='warning'))
|
|
210
|
+
return _report(content, mode, source_name, device_label, identity, fields, issues, plan)
|
|
211
|
+
except ImportProblem as error:
|
|
212
|
+
issues.append(error.issue)
|
|
213
|
+
return _report(content, mode, source_name, device_label, identity, fields, issues, None)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def load_legacy_ini(ini_path, mapping_path, *, mode, device_label='pending') -> LegacyImportResult:
|
|
218
|
+
"""只读INI、映射及显式一层公共定义,来源路径基准按实际声明文件确定。
|
|
219
|
+
|
|
220
|
+
参数: ini_path/mapping_path为str或Path;mode/device_label同字节API。
|
|
221
|
+
返回: LegacyImportResult,非法JSON/YAML给mapping定位。异常: API类型、未知mode、
|
|
222
|
+
文件读取OSError、MemoryError及取消原样传播;按声明展开目录及读取缺省信号所需DBC,不读取业务报文。
|
|
223
|
+
"""
|
|
224
|
+
if not isinstance(ini_path, (str, Path)) or not isinstance(mapping_path, (str, Path)):
|
|
225
|
+
raise TypeError('配置路径需要str或Path')
|
|
226
|
+
# API参数先校验,不能在明显编程错误下先触发文件读取。
|
|
227
|
+
_arguments(b'', {}, mode, mapping_path, str(ini_path), device_label)
|
|
228
|
+
ini, mapping_file = Path(ini_path), Path(mapping_path).absolute()
|
|
229
|
+
content = ini.read_bytes()
|
|
230
|
+
try:
|
|
231
|
+
document = load_configuration(mapping_file)
|
|
232
|
+
from ..configuration.imports import expand_document_imports
|
|
233
|
+
document = expand_document_imports(document)
|
|
234
|
+
mapping = document.data
|
|
235
|
+
except PlanValidationError as error:
|
|
236
|
+
location=error.location
|
|
237
|
+
issue=LegacyImportIssue(error.code,'mapping',error.path,str(error),
|
|
238
|
+
None if location is None else location.line,None if location is None else location.column)
|
|
239
|
+
return _report(content,mode,str(ini),device_label,None,(),(issue,),None)
|
|
240
|
+
except ConfigurationError as error:
|
|
241
|
+
# 文件IO沿用导入API的原生异常合同;语法错误则进入可发布的迁移报告。
|
|
242
|
+
if error.code=='load_error' and isinstance(error.__cause__,OSError):
|
|
243
|
+
raise error.__cause__
|
|
244
|
+
syntax_code='invalid_mapping_yaml' if mapping_file.suffix.lower() in ('.yaml','.yml') else 'invalid_mapping_json'
|
|
245
|
+
code={'duplicate_key':'duplicate_mapping_key','nonfinite_number':'invalid_mapping_number',
|
|
246
|
+
'invalid_number':'invalid_mapping_number','unsupported_format':'unsupported_mapping_format'}.get(error.code,syntax_code)
|
|
247
|
+
location=error.location
|
|
248
|
+
issue=LegacyImportIssue(code,'mapping',field_path_text(error.field_path),str(error),
|
|
249
|
+
None if location is None else location.line,None if location is None else location.column)
|
|
250
|
+
return _report(content,mode,str(ini),device_label,None,(),(issue,),None)
|
|
251
|
+
if type(mapping) is not dict:
|
|
252
|
+
return _report(content, mode, str(ini), device_label, None, (),
|
|
253
|
+
(LegacyImportIssue('invalid_mapping_shape', 'mapping', '$', 'mapping配置根必须为对象'),), None)
|
|
254
|
+
result=import_legacy_ini(content, mapping, mode=mode, base_dir=mapping_file.parent,
|
|
255
|
+
source_name=str(ini), device_label=device_label)
|
|
256
|
+
# 只补映射原文的错误位置。INI字段的行列已由迁移器确定,不能套映射位置。
|
|
257
|
+
issues=[]
|
|
258
|
+
for issue in result.report.issues:
|
|
259
|
+
parts=field_path_parts(issue.path)
|
|
260
|
+
if issue.origin!='mapping' or parts is None:
|
|
261
|
+
issues.append(issue)
|
|
262
|
+
continue
|
|
263
|
+
# 转换后计划路径从analysis内部开始,原mapping校验路径则已带前缀。
|
|
264
|
+
if parts and parts[0] not in mapping and ('analysis',*parts[:-1]) in document.locations:
|
|
265
|
+
parts=('analysis',*parts)
|
|
266
|
+
error=locate_error(PlanValidationError(field_path_text(parts),issue.message,issue.code),document)
|
|
267
|
+
location=error.location
|
|
268
|
+
issues.append(replace(issue,path=error.path,message=str(error),
|
|
269
|
+
line=None if location is None else location.line,column=None if location is None else location.column))
|
|
270
|
+
return replace(result,report=replace(result.report,issues=tuple(issues)))
|