oscura 0.8.0__py3-none-any.whl → 0.11.0__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.
- oscura/__init__.py +19 -19
- oscura/__main__.py +4 -0
- oscura/analyzers/__init__.py +2 -0
- oscura/analyzers/digital/extraction.py +2 -3
- oscura/analyzers/digital/quality.py +1 -1
- oscura/analyzers/digital/timing.py +1 -1
- oscura/analyzers/ml/signal_classifier.py +6 -0
- oscura/analyzers/patterns/__init__.py +66 -0
- oscura/analyzers/power/basic.py +3 -3
- oscura/analyzers/power/soa.py +1 -1
- oscura/analyzers/power/switching.py +3 -3
- oscura/analyzers/signal_classification.py +529 -0
- oscura/analyzers/signal_integrity/sparams.py +3 -3
- oscura/analyzers/statistics/basic.py +10 -7
- oscura/analyzers/validation.py +1 -1
- oscura/analyzers/waveform/measurements.py +200 -156
- oscura/analyzers/waveform/measurements_with_uncertainty.py +91 -35
- oscura/analyzers/waveform/spectral.py +182 -84
- oscura/api/dsl/commands.py +15 -6
- oscura/api/server/templates/base.html +137 -146
- oscura/api/server/templates/export.html +84 -110
- oscura/api/server/templates/home.html +248 -267
- oscura/api/server/templates/protocols.html +44 -48
- oscura/api/server/templates/reports.html +27 -35
- oscura/api/server/templates/session_detail.html +68 -78
- oscura/api/server/templates/sessions.html +62 -72
- oscura/api/server/templates/waveforms.html +54 -64
- oscura/automotive/__init__.py +1 -1
- oscura/automotive/can/session.py +1 -1
- oscura/automotive/dbc/generator.py +638 -23
- oscura/automotive/dtc/data.json +17 -102
- oscura/automotive/flexray/fibex.py +9 -1
- oscura/automotive/uds/decoder.py +99 -6
- oscura/cli/analyze.py +8 -2
- oscura/cli/batch.py +36 -5
- oscura/cli/characterize.py +18 -4
- oscura/cli/export.py +47 -5
- oscura/cli/main.py +2 -0
- oscura/cli/onboarding/wizard.py +10 -6
- oscura/cli/pipeline.py +585 -0
- oscura/cli/visualize.py +6 -4
- oscura/convenience.py +400 -32
- oscura/core/measurement_result.py +286 -0
- oscura/core/progress.py +1 -1
- oscura/core/schemas/device_mapping.json +2 -8
- oscura/core/schemas/packet_format.json +4 -24
- oscura/core/schemas/protocol_definition.json +2 -12
- oscura/core/types.py +232 -239
- oscura/correlation/multi_protocol.py +1 -1
- oscura/export/legacy/__init__.py +11 -0
- oscura/export/legacy/wav.py +75 -0
- oscura/exporters/__init__.py +19 -0
- oscura/exporters/wireshark.py +809 -0
- oscura/hardware/acquisition/file.py +5 -19
- oscura/hardware/acquisition/saleae.py +10 -10
- oscura/hardware/acquisition/socketcan.py +4 -6
- oscura/hardware/acquisition/synthetic.py +1 -5
- oscura/hardware/acquisition/visa.py +6 -6
- oscura/hardware/security/side_channel_detector.py +5 -508
- oscura/inference/message_format.py +686 -1
- oscura/jupyter/display.py +2 -2
- oscura/jupyter/magic.py +3 -3
- oscura/loaders/__init__.py +17 -12
- oscura/loaders/binary.py +1 -1
- oscura/loaders/chipwhisperer.py +1 -2
- oscura/loaders/configurable.py +1 -1
- oscura/loaders/csv_loader.py +2 -2
- oscura/loaders/hdf5_loader.py +1 -1
- oscura/loaders/lazy.py +6 -1
- oscura/loaders/mmap_loader.py +0 -1
- oscura/loaders/numpy_loader.py +8 -7
- oscura/loaders/preprocessing.py +3 -5
- oscura/loaders/rigol.py +21 -7
- oscura/loaders/sigrok.py +2 -5
- oscura/loaders/tdms.py +3 -2
- oscura/loaders/tektronix.py +38 -32
- oscura/loaders/tss.py +20 -27
- oscura/loaders/validation.py +17 -10
- oscura/loaders/vcd.py +13 -8
- oscura/loaders/wav.py +1 -6
- oscura/pipeline/__init__.py +76 -0
- oscura/pipeline/handlers/__init__.py +165 -0
- oscura/pipeline/handlers/analyzers.py +1045 -0
- oscura/pipeline/handlers/decoders.py +899 -0
- oscura/pipeline/handlers/exporters.py +1103 -0
- oscura/pipeline/handlers/filters.py +891 -0
- oscura/pipeline/handlers/loaders.py +640 -0
- oscura/pipeline/handlers/transforms.py +768 -0
- oscura/reporting/formatting/measurements.py +55 -14
- oscura/reporting/templates/enhanced/protocol_re.html +504 -503
- oscura/sessions/legacy.py +49 -1
- oscura/side_channel/__init__.py +38 -57
- oscura/utils/builders/signal_builder.py +5 -5
- oscura/utils/comparison/compare.py +7 -9
- oscura/utils/comparison/golden.py +1 -1
- oscura/utils/filtering/convenience.py +2 -2
- oscura/utils/math/arithmetic.py +38 -62
- oscura/utils/math/interpolation.py +20 -20
- oscura/utils/pipeline/__init__.py +4 -17
- oscura/utils/progressive.py +1 -4
- oscura/utils/triggering/edge.py +1 -1
- oscura/utils/triggering/pattern.py +2 -2
- oscura/utils/triggering/pulse.py +2 -2
- oscura/utils/triggering/window.py +3 -3
- oscura/validation/hil_testing.py +11 -11
- oscura/visualization/__init__.py +46 -284
- oscura/visualization/batch.py +72 -433
- oscura/visualization/plot.py +542 -53
- oscura/visualization/styles.py +184 -318
- oscura/workflows/batch/advanced.py +1 -1
- oscura/workflows/batch/aggregate.py +12 -9
- oscura/workflows/complete_re.py +251 -23
- oscura/workflows/digital.py +27 -4
- oscura/workflows/multi_trace.py +136 -17
- oscura/workflows/waveform.py +11 -6
- oscura-0.11.0.dist-info/METADATA +460 -0
- {oscura-0.8.0.dist-info → oscura-0.11.0.dist-info}/RECORD +120 -145
- oscura/side_channel/dpa.py +0 -1025
- oscura/utils/optimization/__init__.py +0 -19
- oscura/utils/optimization/parallel.py +0 -443
- oscura/utils/optimization/search.py +0 -532
- oscura/utils/pipeline/base.py +0 -338
- oscura/utils/pipeline/composition.py +0 -248
- oscura/utils/pipeline/parallel.py +0 -449
- oscura/utils/pipeline/pipeline.py +0 -375
- oscura/utils/search/__init__.py +0 -16
- oscura/utils/search/anomaly.py +0 -424
- oscura/utils/search/context.py +0 -294
- oscura/utils/search/pattern.py +0 -288
- oscura/utils/storage/__init__.py +0 -61
- oscura/utils/storage/database.py +0 -1166
- oscura/visualization/accessibility.py +0 -526
- oscura/visualization/annotations.py +0 -371
- oscura/visualization/axis_scaling.py +0 -305
- oscura/visualization/colors.py +0 -451
- oscura/visualization/digital.py +0 -436
- oscura/visualization/eye.py +0 -571
- oscura/visualization/histogram.py +0 -281
- oscura/visualization/interactive.py +0 -1035
- oscura/visualization/jitter.py +0 -1042
- oscura/visualization/keyboard.py +0 -394
- oscura/visualization/layout.py +0 -400
- oscura/visualization/optimization.py +0 -1079
- oscura/visualization/palettes.py +0 -446
- oscura/visualization/power.py +0 -508
- oscura/visualization/power_extended.py +0 -955
- oscura/visualization/presets.py +0 -469
- oscura/visualization/protocols.py +0 -1246
- oscura/visualization/render.py +0 -223
- oscura/visualization/rendering.py +0 -444
- oscura/visualization/reverse_engineering.py +0 -838
- oscura/visualization/signal_integrity.py +0 -989
- oscura/visualization/specialized.py +0 -643
- oscura/visualization/spectral.py +0 -1226
- oscura/visualization/thumbnails.py +0 -340
- oscura/visualization/time_axis.py +0 -351
- oscura/visualization/waveform.py +0 -454
- oscura-0.8.0.dist-info/METADATA +0 -661
- {oscura-0.8.0.dist-info → oscura-0.11.0.dist-info}/WHEEL +0 -0
- {oscura-0.8.0.dist-info → oscura-0.11.0.dist-info}/entry_points.txt +0 -0
- {oscura-0.8.0.dist-info → oscura-0.11.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
"""Helper functions for creating MeasurementResult instances.
|
|
2
|
+
|
|
3
|
+
This module provides utilities to construct MeasurementResult TypedDict
|
|
4
|
+
instances with proper formatting and applicability tracking.
|
|
5
|
+
|
|
6
|
+
Example:
|
|
7
|
+
>>> from oscura.core.measurement_result import make_measurement, make_inapplicable
|
|
8
|
+
>>> # Applicable measurement
|
|
9
|
+
>>> freq = make_measurement(1000.0, "Hz")
|
|
10
|
+
>>> print(freq["display"])
|
|
11
|
+
1.000 kHz
|
|
12
|
+
|
|
13
|
+
>>> # Inapplicable measurement
|
|
14
|
+
>>> period = make_inapplicable("s", "Aperiodic signal")
|
|
15
|
+
>>> print(f"{period['display']} - {period['reason']}")
|
|
16
|
+
N/A - Aperiodic signal
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
import math
|
|
22
|
+
from typing import TYPE_CHECKING, Any
|
|
23
|
+
|
|
24
|
+
import numpy as np
|
|
25
|
+
|
|
26
|
+
if TYPE_CHECKING:
|
|
27
|
+
from oscura.core.types import MeasurementResult
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def format_si_prefix(value: float, unit: str, precision: int = 3) -> str:
|
|
31
|
+
"""Format value with appropriate SI prefix.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
value: Numeric value to format.
|
|
35
|
+
unit: Base unit (e.g., "Hz", "V", "s").
|
|
36
|
+
precision: Number of significant figures.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
Formatted string with SI prefix (e.g., "1.234 kHz", "5.67 mV").
|
|
40
|
+
|
|
41
|
+
Example:
|
|
42
|
+
>>> format_si_prefix(1000, "Hz")
|
|
43
|
+
'1.000 kHz'
|
|
44
|
+
>>> format_si_prefix(0.001, "V")
|
|
45
|
+
'1.000 mV'
|
|
46
|
+
>>> format_si_prefix(1e6, "Hz", precision=2)
|
|
47
|
+
'1.00 MHz'
|
|
48
|
+
"""
|
|
49
|
+
if value == 0 or not math.isfinite(value):
|
|
50
|
+
return f"{value:.{precision}g} {unit}"
|
|
51
|
+
|
|
52
|
+
# SI prefixes and their powers of 10
|
|
53
|
+
prefixes = [
|
|
54
|
+
(1e24, "Y"), # yotta
|
|
55
|
+
(1e21, "Z"), # zetta
|
|
56
|
+
(1e18, "E"), # exa
|
|
57
|
+
(1e15, "P"), # peta
|
|
58
|
+
(1e12, "T"), # tera
|
|
59
|
+
(1e9, "G"), # giga
|
|
60
|
+
(1e6, "M"), # mega
|
|
61
|
+
(1e3, "k"), # kilo
|
|
62
|
+
(1, ""), # no prefix
|
|
63
|
+
(1e-3, "m"), # milli
|
|
64
|
+
(1e-6, "µ"), # micro
|
|
65
|
+
(1e-9, "n"), # nano
|
|
66
|
+
(1e-12, "p"), # pico
|
|
67
|
+
(1e-15, "f"), # femto
|
|
68
|
+
(1e-18, "a"), # atto
|
|
69
|
+
(1e-21, "z"), # zepto
|
|
70
|
+
(1e-24, "y"), # yocto
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
abs_value = abs(value)
|
|
74
|
+
|
|
75
|
+
# Find appropriate prefix
|
|
76
|
+
for scale, prefix in prefixes:
|
|
77
|
+
if abs_value >= scale:
|
|
78
|
+
scaled = value / scale
|
|
79
|
+
return f"{scaled:.{precision}f} {prefix}{unit}"
|
|
80
|
+
|
|
81
|
+
# Fallback for very small values
|
|
82
|
+
return f"{value:.{precision}e} {unit}"
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def format_percentage(value: float, precision: int = 2) -> str:
|
|
86
|
+
"""Format percentage value.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
value: Percentage value (0-100).
|
|
90
|
+
precision: Decimal places.
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
Formatted percentage string.
|
|
94
|
+
|
|
95
|
+
Example:
|
|
96
|
+
>>> format_percentage(5.2)
|
|
97
|
+
'5.20%'
|
|
98
|
+
>>> format_percentage(0.123, precision=3)
|
|
99
|
+
'0.123%'
|
|
100
|
+
"""
|
|
101
|
+
return f"{value:.{precision}f}%"
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def format_ratio(value: float, precision: int = 3) -> str:
|
|
105
|
+
"""Format ratio value (0-1) as percentage.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
value: Ratio value (0.0 to 1.0).
|
|
109
|
+
precision: Decimal places.
|
|
110
|
+
|
|
111
|
+
Returns:
|
|
112
|
+
Formatted percentage string.
|
|
113
|
+
|
|
114
|
+
Example:
|
|
115
|
+
>>> format_ratio(0.052)
|
|
116
|
+
'5.200%'
|
|
117
|
+
>>> format_ratio(0.5)
|
|
118
|
+
'50.000%'
|
|
119
|
+
"""
|
|
120
|
+
return f"{value * 100:.{precision}f}%"
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def format_decibel(value: float, precision: int = 1) -> str:
|
|
124
|
+
"""Format decibel value.
|
|
125
|
+
|
|
126
|
+
Args:
|
|
127
|
+
value: Decibel value.
|
|
128
|
+
precision: Decimal places.
|
|
129
|
+
|
|
130
|
+
Returns:
|
|
131
|
+
Formatted dB string.
|
|
132
|
+
|
|
133
|
+
Example:
|
|
134
|
+
>>> format_decibel(42.5)
|
|
135
|
+
'42.5 dB'
|
|
136
|
+
>>> format_decibel(-3.01, precision=2)
|
|
137
|
+
'-3.01 dB'
|
|
138
|
+
"""
|
|
139
|
+
return f"{value:.{precision}f} dB"
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def make_measurement(
|
|
143
|
+
value: float, unit: str, *, precision: int = 3, raw_value: bool = False
|
|
144
|
+
) -> MeasurementResult:
|
|
145
|
+
"""Create an applicable MeasurementResult.
|
|
146
|
+
|
|
147
|
+
Args:
|
|
148
|
+
value: Measurement value.
|
|
149
|
+
unit: Unit string ("V", "Hz", "s", "dB", "%", "ratio", or "").
|
|
150
|
+
precision: Formatting precision (default: 3).
|
|
151
|
+
raw_value: If True, format as raw number (default: False).
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
MeasurementResult with applicable=True.
|
|
155
|
+
|
|
156
|
+
Example:
|
|
157
|
+
>>> result = make_measurement(1000, "Hz")
|
|
158
|
+
>>> result["value"]
|
|
159
|
+
1000.0
|
|
160
|
+
>>> result["display"]
|
|
161
|
+
'1.000 kHz'
|
|
162
|
+
>>> result["applicable"]
|
|
163
|
+
True
|
|
164
|
+
|
|
165
|
+
>>> # Percentage measurement
|
|
166
|
+
>>> thd = make_measurement(5.2, "%")
|
|
167
|
+
>>> thd["display"]
|
|
168
|
+
'5.200%'
|
|
169
|
+
|
|
170
|
+
>>> # Ratio measurement (auto-converts to percentage)
|
|
171
|
+
>>> duty = make_measurement(0.3, "ratio")
|
|
172
|
+
>>> duty["display"]
|
|
173
|
+
'30.000%'
|
|
174
|
+
"""
|
|
175
|
+
# Handle NaN/Inf values
|
|
176
|
+
if not math.isfinite(value):
|
|
177
|
+
return make_inapplicable(unit, f"Invalid value: {value}")
|
|
178
|
+
|
|
179
|
+
# Format display string based on unit type
|
|
180
|
+
if raw_value:
|
|
181
|
+
display = f"{value:.{precision}g}"
|
|
182
|
+
elif unit == "dB":
|
|
183
|
+
display = format_decibel(value, precision=precision)
|
|
184
|
+
elif unit == "%":
|
|
185
|
+
display = format_percentage(value, precision=precision)
|
|
186
|
+
elif unit == "ratio":
|
|
187
|
+
# Convert ratio (0-1) to percentage for display
|
|
188
|
+
display = format_ratio(value, precision=precision)
|
|
189
|
+
elif unit == "":
|
|
190
|
+
# Dimensionless - format as integer or float
|
|
191
|
+
if isinstance(value, (int, np.integer)) or value == int(value):
|
|
192
|
+
display = f"{int(value)}"
|
|
193
|
+
else:
|
|
194
|
+
display = f"{value:.{precision}g}"
|
|
195
|
+
else:
|
|
196
|
+
# SI units (V, Hz, s, A, W, etc.)
|
|
197
|
+
display = format_si_prefix(value, unit, precision=precision)
|
|
198
|
+
|
|
199
|
+
return {
|
|
200
|
+
"value": float(value),
|
|
201
|
+
"unit": unit,
|
|
202
|
+
"applicable": True,
|
|
203
|
+
"reason": None,
|
|
204
|
+
"display": display,
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def make_inapplicable(unit: str, reason: str) -> MeasurementResult:
|
|
209
|
+
"""Create an inapplicable MeasurementResult (replaces NaN).
|
|
210
|
+
|
|
211
|
+
Args:
|
|
212
|
+
unit: Unit string for metadata.
|
|
213
|
+
reason: Human-readable explanation (e.g., "Aperiodic signal").
|
|
214
|
+
|
|
215
|
+
Returns:
|
|
216
|
+
MeasurementResult with applicable=False, value=None.
|
|
217
|
+
|
|
218
|
+
Example:
|
|
219
|
+
>>> result = make_inapplicable("s", "Aperiodic signal (single impulse)")
|
|
220
|
+
>>> result["value"] is None
|
|
221
|
+
True
|
|
222
|
+
>>> result["applicable"]
|
|
223
|
+
False
|
|
224
|
+
>>> result["display"]
|
|
225
|
+
'N/A'
|
|
226
|
+
>>> result["reason"]
|
|
227
|
+
'Aperiodic signal (single impulse)'
|
|
228
|
+
"""
|
|
229
|
+
return {
|
|
230
|
+
"value": None,
|
|
231
|
+
"unit": unit,
|
|
232
|
+
"applicable": False,
|
|
233
|
+
"reason": reason,
|
|
234
|
+
"display": "N/A",
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def make_measurement_safe(
|
|
239
|
+
value: float | None, unit: str, inapplicable_reason: str | None = None, **kwargs: Any
|
|
240
|
+
) -> MeasurementResult:
|
|
241
|
+
"""Create MeasurementResult with automatic NaN/None handling.
|
|
242
|
+
|
|
243
|
+
Args:
|
|
244
|
+
value: Measurement value (can be NaN or None).
|
|
245
|
+
unit: Unit string.
|
|
246
|
+
inapplicable_reason: Reason if inapplicable (required if value is None/NaN).
|
|
247
|
+
**kwargs: Additional arguments passed to make_measurement().
|
|
248
|
+
|
|
249
|
+
Returns:
|
|
250
|
+
MeasurementResult (applicable if value is valid, inapplicable otherwise).
|
|
251
|
+
|
|
252
|
+
Example:
|
|
253
|
+
>>> # Valid value
|
|
254
|
+
>>> result = make_measurement_safe(1000, "Hz")
|
|
255
|
+
>>> result["applicable"]
|
|
256
|
+
True
|
|
257
|
+
|
|
258
|
+
>>> # NaN value
|
|
259
|
+
>>> result = make_measurement_safe(float('nan'), "s", "Aperiodic signal")
|
|
260
|
+
>>> result["applicable"]
|
|
261
|
+
False
|
|
262
|
+
>>> result["reason"]
|
|
263
|
+
'Aperiodic signal'
|
|
264
|
+
|
|
265
|
+
>>> # None value
|
|
266
|
+
>>> result = make_measurement_safe(None, "V", "DC signal")
|
|
267
|
+
>>> result["display"]
|
|
268
|
+
'N/A'
|
|
269
|
+
"""
|
|
270
|
+
# Check if value is invalid (None, NaN, Inf)
|
|
271
|
+
if value is None or not math.isfinite(value):
|
|
272
|
+
reason = inapplicable_reason or "Invalid or undefined value"
|
|
273
|
+
return make_inapplicable(unit, reason)
|
|
274
|
+
|
|
275
|
+
return make_measurement(value, unit, **kwargs)
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
__all__ = [
|
|
279
|
+
"format_decibel",
|
|
280
|
+
"format_percentage",
|
|
281
|
+
"format_ratio",
|
|
282
|
+
"format_si_prefix",
|
|
283
|
+
"make_inapplicable",
|
|
284
|
+
"make_measurement",
|
|
285
|
+
"make_measurement_safe",
|
|
286
|
+
]
|
oscura/core/progress.py
CHANGED
|
@@ -149,20 +149,14 @@
|
|
|
149
149
|
"type": "array",
|
|
150
150
|
"description": "Device IDs to include (whitelist)",
|
|
151
151
|
"items": {
|
|
152
|
-
"oneOf": [
|
|
153
|
-
{ "type": "integer" },
|
|
154
|
-
{ "type": "string", "pattern": "^0[xX][0-9A-Fa-f]+$" }
|
|
155
|
-
]
|
|
152
|
+
"oneOf": [{ "type": "integer" }, { "type": "string", "pattern": "^0[xX][0-9A-Fa-f]+$" }]
|
|
156
153
|
}
|
|
157
154
|
},
|
|
158
155
|
"exclude_devices": {
|
|
159
156
|
"type": "array",
|
|
160
157
|
"description": "Device IDs to exclude (blacklist)",
|
|
161
158
|
"items": {
|
|
162
|
-
"oneOf": [
|
|
163
|
-
{ "type": "integer" },
|
|
164
|
-
{ "type": "string", "pattern": "^0[xX][0-9A-Fa-f]+$" }
|
|
165
|
-
]
|
|
159
|
+
"oneOf": [{ "type": "integer" }, { "type": "string", "pattern": "^0[xX][0-9A-Fa-f]+$" }]
|
|
166
160
|
}
|
|
167
161
|
},
|
|
168
162
|
"include_categories": {
|
|
@@ -118,10 +118,7 @@
|
|
|
118
118
|
},
|
|
119
119
|
"value": {
|
|
120
120
|
"description": "Expected constant value for validation",
|
|
121
|
-
"oneOf": [
|
|
122
|
-
{ "type": "integer" },
|
|
123
|
-
{ "type": "array", "items": { "type": "integer" } }
|
|
124
|
-
]
|
|
121
|
+
"oneOf": [{ "type": "integer" }, { "type": "array", "items": { "type": "integer" } }]
|
|
125
122
|
},
|
|
126
123
|
"description": {
|
|
127
124
|
"type": "string",
|
|
@@ -188,18 +185,7 @@
|
|
|
188
185
|
},
|
|
189
186
|
"type": {
|
|
190
187
|
"type": "string",
|
|
191
|
-
"enum": [
|
|
192
|
-
"uint8",
|
|
193
|
-
"uint16",
|
|
194
|
-
"uint32",
|
|
195
|
-
"uint64",
|
|
196
|
-
"int8",
|
|
197
|
-
"int16",
|
|
198
|
-
"int32",
|
|
199
|
-
"int64",
|
|
200
|
-
"float32",
|
|
201
|
-
"float64"
|
|
202
|
-
],
|
|
188
|
+
"enum": ["uint8", "uint16", "uint32", "uint64", "int8", "int16", "int32", "int64", "float32", "float64"],
|
|
203
189
|
"description": "Sample data type"
|
|
204
190
|
},
|
|
205
191
|
"endian": {
|
|
@@ -303,10 +289,7 @@
|
|
|
303
289
|
},
|
|
304
290
|
"expected": {
|
|
305
291
|
"description": "Expected value",
|
|
306
|
-
"oneOf": [
|
|
307
|
-
{ "type": "integer" },
|
|
308
|
-
{ "type": "array", "items": { "type": "integer" } }
|
|
309
|
-
]
|
|
292
|
+
"oneOf": [{ "type": "integer" }, { "type": "array", "items": { "type": "integer" } }]
|
|
310
293
|
},
|
|
311
294
|
"on_failure": {
|
|
312
295
|
"type": "string",
|
|
@@ -379,10 +362,7 @@
|
|
|
379
362
|
},
|
|
380
363
|
"pattern": {
|
|
381
364
|
"description": "Idle pattern to detect",
|
|
382
|
-
"oneOf": [
|
|
383
|
-
{ "type": "string", "enum": ["auto", "zeros", "ones"] },
|
|
384
|
-
{ "type": "integer" }
|
|
385
|
-
]
|
|
365
|
+
"oneOf": [{ "type": "string", "enum": ["auto", "zeros", "ones"] }, { "type": "integer" }]
|
|
386
366
|
},
|
|
387
367
|
"min_duration": {
|
|
388
368
|
"type": "integer",
|
|
@@ -241,12 +241,7 @@
|
|
|
241
241
|
},
|
|
242
242
|
"value": {
|
|
243
243
|
"description": "Expected constant value for validation",
|
|
244
|
-
"oneOf": [
|
|
245
|
-
{ "type": "integer" },
|
|
246
|
-
{ "type": "number" },
|
|
247
|
-
{ "type": "string" },
|
|
248
|
-
{ "type": "array" }
|
|
249
|
-
]
|
|
244
|
+
"oneOf": [{ "type": "integer" }, { "type": "number" }, { "type": "string" }, { "type": "array" }]
|
|
250
245
|
},
|
|
251
246
|
"condition": {
|
|
252
247
|
"type": "string",
|
|
@@ -331,12 +326,7 @@
|
|
|
331
326
|
},
|
|
332
327
|
"expected": {
|
|
333
328
|
"description": "Expected value",
|
|
334
|
-
"oneOf": [
|
|
335
|
-
{ "type": "integer" },
|
|
336
|
-
{ "type": "number" },
|
|
337
|
-
{ "type": "string" },
|
|
338
|
-
{ "type": "array" }
|
|
339
|
-
]
|
|
329
|
+
"oneOf": [{ "type": "integer" }, { "type": "number" }, { "type": "string" }, { "type": "array" }]
|
|
340
330
|
},
|
|
341
331
|
"on_mismatch": {
|
|
342
332
|
"type": "string",
|