SCPI-Instrument-Control 1.0.1__tar.gz → 2.0.0__tar.gz
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.
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/CHANGELOG.md +59 -1
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/MANIFEST.in +3 -1
- {scpi_instrument_control-1.0.1/SCPI_Instrument_Control.egg-info → scpi_instrument_control-2.0.0}/PKG-INFO +59 -18
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/README.md +50 -13
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0/SCPI_Instrument_Control.egg-info}/PKG-INFO +59 -18
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/SCPI_Instrument_Control.egg-info/SOURCES.txt +29 -1
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/SCPI_Instrument_Control.egg-info/entry_points.txt +1 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/SCPI_Instrument_Control.egg-info/requires.txt +8 -2
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/SCPI_Instrument_Control.egg-info/top_level.txt +0 -1
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/examples/README.md +2 -2
- scpi_instrument_control-2.0.0/examples/data_logger_basic.py +147 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/examples/function_generator_basic.py +2 -2
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/pyproject.toml +15 -10
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/__init__.py +10 -1
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/automation.py +28 -12
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/channel.py +30 -18
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/connection/base.py +4 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/connection/mock.py +239 -46
- scpi_instrument_control-2.0.0/scpi_control/connection/socket.py +302 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/connection/visa_connection.py +7 -5
- scpi_instrument_control-2.0.0/scpi_control/daq_models.py +316 -0
- scpi_instrument_control-2.0.0/scpi_control/daq_scpi_commands.py +227 -0
- scpi_instrument_control-2.0.0/scpi_control/data_logger.py +762 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/function_generator.py +4 -4
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/app.py +4 -4
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/connection_manager.py +7 -7
- scpi_instrument_control-2.0.0/scpi_control/gui/daq_worker.py +205 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/main_window.py +131 -17
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/widgets/__init__.py +14 -1
- scpi_instrument_control-2.0.0/scpi_control/gui/widgets/daq_ai_panel.py +390 -0
- scpi_instrument_control-2.0.0/scpi_control/gui/widgets/daq_channel_config.py +317 -0
- scpi_instrument_control-2.0.0/scpi_control/gui/widgets/daq_data_view.py +371 -0
- scpi_instrument_control-2.0.0/scpi_control/gui/widgets/daq_scan_config.py +275 -0
- scpi_instrument_control-2.0.0/scpi_control/gui/widgets/data_logger_control.py +364 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/widgets/math_panel.py +2 -4
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/widgets/psu_control.py +2 -4
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/widgets/terminal_widget.py +10 -20
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/widgets/timebase_control.py +4 -8
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/widgets/vector_graphics_panel.py +2 -2
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/models.py +21 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/oscilloscope.py +51 -21
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/power_supply.py +5 -5
- scpi_instrument_control-2.0.0/scpi_control/report_generator/llm/__init__.py +20 -0
- scpi_instrument_control-2.0.0/scpi_control/report_generator/llm/daq_analyzer.py +316 -0
- scpi_instrument_control-2.0.0/scpi_control/report_generator/llm/daq_context_builder.py +340 -0
- scpi_instrument_control-2.0.0/scpi_control/report_generator/llm/daq_prompts.py +114 -0
- scpi_instrument_control-2.0.0/scpi_control/scpi_commands.py +339 -0
- scpi_instrument_control-2.0.0/scpi_control/server/__init__.py +0 -0
- scpi_instrument_control-2.0.0/scpi_control/server/__main__.py +19 -0
- scpi_instrument_control-2.0.0/scpi_control/server/api/__init__.py +0 -0
- scpi_instrument_control-2.0.0/scpi_control/server/api/discovery.py +35 -0
- scpi_instrument_control-2.0.0/scpi_control/server/api/scope.py +467 -0
- scpi_instrument_control-2.0.0/scpi_control/server/api/sessions.py +50 -0
- scpi_instrument_control-2.0.0/scpi_control/server/api/stream.py +103 -0
- scpi_instrument_control-2.0.0/scpi_control/server/app.py +91 -0
- scpi_instrument_control-2.0.0/scpi_control/server/compute.py +109 -0
- scpi_instrument_control-2.0.0/scpi_control/server/discovery.py +126 -0
- scpi_instrument_control-2.0.0/scpi_control/server/recorder.py +66 -0
- scpi_instrument_control-2.0.0/scpi_control/server/schemas.py +113 -0
- scpi_instrument_control-2.0.0/scpi_control/server/sessions.py +392 -0
- scpi_instrument_control-2.0.0/scpi_control/server/static/assets/index-0Vpguwg6.js +9 -0
- scpi_instrument_control-2.0.0/scpi_control/server/static/assets/index-CyUPLIHk.css +1 -0
- scpi_instrument_control-2.0.0/scpi_control/server/static/index.html +13 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/trigger.py +88 -44
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/vector_graphics.py +3 -2
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/waveform.py +27 -9
- scpi_instrument_control-1.0.1/scpi_control/connection/socket.py +0 -211
- scpi_instrument_control-1.0.1/scpi_control/report_generator/llm/__init__.py +0 -7
- scpi_instrument_control-1.0.1/scpi_control/scpi_commands.py +0 -206
- scpi_instrument_control-1.0.1/siglent/__init__.py +0 -35
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/LICENSE +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/SCPI_Instrument_Control.egg-info/dependency_links.txt +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/docs/SDS800XHD_Series_ProgrammingGuide_EN11G.pdf +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/docs/VISUAL_MEASUREMENTS.md +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/docs/images/01_main_window.png +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/docs/images/channel_controls.png +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/docs/images/cursors.png +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/docs/images/fft_analysis.png +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/docs/images/main_window.png +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/docs/images/measurements_panel.png +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/docs/images/visual_measurements.png +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/examples/advanced_analysis.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/examples/basic_usage.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/examples/batch_capture.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/examples/continuous_capture.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/examples/live_plot.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/examples/measurements.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/examples/probe_calibration_analysis.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/examples/psu_advanced_features.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/examples/psu_basic_control.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/examples/psu_gui_test.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/examples/psu_usb_connection.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/examples/report_generation_example.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/examples/simple_capture.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/examples/trigger_based_capture.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/examples/vector_graphics_xy_mode.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/examples/waveform_capture.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/resources/Test Equipment Wide.png +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/resources/Test Equipment.icns +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/resources/Test Equipment.ico +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/resources/Test Equipment.png +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/analysis.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/awg_models.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/awg_output.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/awg_scpi_commands.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/connection/__init__.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/exceptions.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/__init__.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/live_view_worker.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/utils/validators.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/vnc_window.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/waveform_capture_worker.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/widgets/channel_control.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/widgets/cursor_panel.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/widgets/error_dialog.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/widgets/fft_display.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/widgets/measurement_marker.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/widgets/measurement_markers/__init__.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/widgets/measurement_markers/frequency_marker.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/widgets/measurement_markers/timing_marker.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/widgets/measurement_markers/voltage_marker.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/widgets/measurement_panel.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/widgets/protocol_decode_panel.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/widgets/reference_panel.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/widgets/scope_web_view.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/widgets/trigger_control.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/widgets/visual_measurement_panel.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/widgets/waveform_display.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/gui/widgets/waveform_display_pg.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/math_channel.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/measurement.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/measurement_config.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/power_supply_output.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/protocol_decode.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/protocol_decoders/__init__.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/protocol_decoders/i2c_decoder.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/protocol_decoders/spi_decoder.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/protocol_decoders/uart_decoder.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/psu_data_logger.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/psu_models.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/psu_scpi_commands.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/py.typed +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/reference_waveform.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/__init__.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/app.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/generators/__init__.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/generators/base.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/generators/markdown_generator.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/generators/pdf_generator.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/llm/analyzer.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/llm/client.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/llm/context_builder.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/llm/prompts.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/main_window.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/models/__init__.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/models/app_settings.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/models/criteria.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/models/plot_style.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/models/report_data.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/models/report_options.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/models/template.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/models/test_types.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/utils/__init__.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/utils/image_handler.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/utils/waveform_analyzer.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/utils/waveform_loader.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/widgets/__init__.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/widgets/ai_analysis_panel.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/widgets/chat_sidebar.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/widgets/llm_settings_dialog.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/widgets/metadata_panel.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/widgets/pdf_preview_dialog.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/widgets/report_options_dialog.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/report_generator/widgets/template_manager_dialog.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/scpi_control/screen_capture.py +0 -0
- {scpi_instrument_control-1.0.1 → scpi_instrument_control-2.0.0}/setup.cfg +0 -0
|
@@ -7,15 +7,73 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.0.0] - 2026-07-15
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
### ⚠️ Breaking Changes
|
|
13
|
+
|
|
14
|
+
- **Removed the `siglent` compatibility shim.** `import siglent` now raises
|
|
15
|
+
`ModuleNotFoundError`; use `import scpi_control` (identical API). The shim
|
|
16
|
+
had emitted a `DeprecationWarning` since 1.0.0, which announced its removal
|
|
17
|
+
in v2.0.0. If you cannot migrate yet, pin `SCPI-Instrument-Control<2.0`.
|
|
18
|
+
- **Python 3.9+ required** (was 3.8+; Python 3.8 reached end of life in
|
|
19
|
+
October 2024). CI now tests Python 3.9 through 3.14.
|
|
12
20
|
|
|
13
21
|
### Added
|
|
14
22
|
|
|
23
|
+
- **Browser-based lab gateway** (`pip install "SCPI-Instrument-Control[web]"`,
|
|
24
|
+
then `scpi-web` or `python -m scpi_control.server`): a FastAPI server that
|
|
25
|
+
manages named multi-instrument sessions and serves a React UI to any
|
|
26
|
+
browser on the LAN. Mock-first — every feature works against the built-in
|
|
27
|
+
mock scope (`mock: true`).
|
|
28
|
+
- Live waveform streaming over WebSocket, with channel, timebase, trigger,
|
|
29
|
+
and acquisition (run/stop/single/auto) controls
|
|
30
|
+
- LAN instrument discovery and a dashboard-style home screen
|
|
31
|
+
- Measurements with live values and cross-tab-synchronized selection
|
|
32
|
+
- Software math channels (M1/M2) streamed as canvas traces
|
|
33
|
+
- SCPI terminal, instrument screenshot PNG, full-resolution waveform
|
|
34
|
+
export as CSV and JSON
|
|
35
|
+
- FFT spectrum view computed server-side from full-resolution data
|
|
36
|
+
(window selection, peak markers, THD readout)
|
|
37
|
+
- Software Butterworth filters (lowpass/highpass/bandpass) streamed as
|
|
38
|
+
F1/F2 traces
|
|
39
|
+
- Reference waveforms: save named snapshots, ghost overlay on the canvas,
|
|
40
|
+
live correlation and max-deviation statistics
|
|
41
|
+
- Measurement trend recording: server-side ring buffer at ~1 Hz, live
|
|
42
|
+
trend chart, CSV export; the measurement selection locks while recording
|
|
43
|
+
- Dual-dialect SCPI support: legacy (e.g. SDS1104X-E) and modern
|
|
44
|
+
(e.g. SDS800X HD) Siglent command sets behind one API, auto-detected from
|
|
45
|
+
`*IDN?` with a manual override
|
|
46
|
+
|
|
15
47
|
### Changed
|
|
16
48
|
|
|
49
|
+
- Connection layer hardened: thread-safe socket handling, exact-length
|
|
50
|
+
binary reads, default SCPI port 5025
|
|
51
|
+
- `wait_for_trigger` honors a user-configured NORMAL trigger mode instead of
|
|
52
|
+
forcing SINGLE
|
|
53
|
+
- Black formatting standardized on the 26.x stable style; dev extra now
|
|
54
|
+
requires `black>=26.5,<27` (installed on Python >= 3.10, where Black 26 is available)
|
|
55
|
+
- Removed the unused `uplot` frontend dependency (the UI draws on a
|
|
56
|
+
hand-rolled canvas)
|
|
57
|
+
|
|
17
58
|
### Fixed
|
|
18
59
|
|
|
60
|
+
- Mock-fidelity and hardware-behavior fixes from the 2026-07 code audit
|
|
61
|
+
(trigger vocabulary mapping, waveform preamble parsing, measurement
|
|
62
|
+
timeout handling, and related issues)
|
|
63
|
+
|
|
64
|
+
## [1.1.0] - 2026-01-12
|
|
65
|
+
|
|
66
|
+
### Added
|
|
67
|
+
|
|
68
|
+
- Data acquisition / data logger instrument support (`DataLogger`): Keysight
|
|
69
|
+
34970A/DAQ970A-style SCPI units — DMM function configuration (V/I/R/
|
|
70
|
+
temperature), scan lists, triggering, alarms, channel scaling, and timed
|
|
71
|
+
logging helpers (PR #39)
|
|
72
|
+
|
|
73
|
+
## [1.0.1] - 2026-01-07
|
|
74
|
+
|
|
75
|
+
Packaging and metadata fixes for the 1.0.0 rename release; no functional changes.
|
|
76
|
+
|
|
19
77
|
## [1.0.0] - 2026-01-06
|
|
20
78
|
|
|
21
79
|
### ⚠️ MAJOR RELEASE - Package Renamed
|
|
@@ -7,12 +7,14 @@ include pyproject.toml
|
|
|
7
7
|
# Include user-facing documentation
|
|
8
8
|
recursive-include docs/images *.png *.jpg
|
|
9
9
|
include docs/VISUAL_MEASUREMENTS.md
|
|
10
|
-
include docs/SCREENSHOT_GUIDE.md
|
|
11
10
|
include docs/SDS800XHD_Series_ProgrammingGuide_EN11G.pdf
|
|
12
11
|
|
|
13
12
|
# Include resources (logos, icons)
|
|
14
13
|
recursive-include resources *.png *.ico *.icns
|
|
15
14
|
|
|
15
|
+
# Include web gateway frontend build output (when present)
|
|
16
|
+
recursive-include scpi_control/server/static *
|
|
17
|
+
|
|
16
18
|
# Include examples
|
|
17
19
|
recursive-include examples *.py
|
|
18
20
|
recursive-include examples *.md
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: SCPI-Instrument-Control
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: Universal Python library for controlling SCPI-compatible test equipment via Ethernet/LAN. Supports oscilloscopes (Siglent SDS series, generic SCPI scopes), function generators/AWGs (Siglent SDG series, generic SCPI AWGs), and power supplies (Siglent SPD series, generic SCPI PSUs). Features include waveform capture, measurements, FFT analysis, PyQt6 GUI, automated report generation with AI analysis, and comprehensive SCPI command abstraction.
|
|
5
5
|
Author: Robin Mumm
|
|
6
6
|
Maintainer: little-did-I-know
|
|
@@ -17,11 +17,12 @@ Classifier: Intended Audience :: Developers
|
|
|
17
17
|
Classifier: Intended Audience :: Manufacturing
|
|
18
18
|
Classifier: Operating System :: OS Independent
|
|
19
19
|
Classifier: Programming Language :: Python :: 3
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.9
|
|
22
21
|
Classifier: Programming Language :: Python :: 3.10
|
|
23
22
|
Classifier: Programming Language :: Python :: 3.11
|
|
24
23
|
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
25
26
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
26
27
|
Classifier: Topic :: Scientific/Engineering
|
|
27
28
|
Classifier: Topic :: Scientific/Engineering :: Interface Engine/Protocol Translator
|
|
@@ -30,7 +31,7 @@ Classifier: Topic :: System :: Networking :: Monitoring
|
|
|
30
31
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
31
32
|
Classifier: Environment :: X11 Applications :: Qt
|
|
32
33
|
Classifier: Typing :: Typed
|
|
33
|
-
Requires-Python: >=3.
|
|
34
|
+
Requires-Python: >=3.9
|
|
34
35
|
Description-Content-Type: text/markdown
|
|
35
36
|
License-File: LICENSE
|
|
36
37
|
Requires-Dist: numpy>=1.24.0
|
|
@@ -40,17 +41,20 @@ Provides-Extra: dev
|
|
|
40
41
|
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
41
42
|
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
42
43
|
Requires-Dist: codecov>=2.1.0; extra == "dev"
|
|
43
|
-
Requires-Dist: black
|
|
44
|
+
Requires-Dist: black<27,>=26.5; python_version >= "3.10" and extra == "dev"
|
|
44
45
|
Requires-Dist: flake8>=6.0; extra == "dev"
|
|
45
46
|
Requires-Dist: build>=0.10.0; extra == "dev"
|
|
46
47
|
Requires-Dist: twine>=4.0.0; extra == "dev"
|
|
47
|
-
Requires-Dist: black[jupyter]>=23.0; extra == "dev"
|
|
48
48
|
Provides-Extra: hdf5
|
|
49
49
|
Requires-Dist: h5py>=3.8.0; extra == "hdf5"
|
|
50
50
|
Provides-Extra: gui
|
|
51
51
|
Requires-Dist: PyQt6>=6.6.0; extra == "gui"
|
|
52
52
|
Requires-Dist: PyQt6-WebEngine>=6.6.0; extra == "gui"
|
|
53
53
|
Requires-Dist: pyqtgraph>=0.13.0; extra == "gui"
|
|
54
|
+
Provides-Extra: web
|
|
55
|
+
Requires-Dist: fastapi>=0.115; extra == "web"
|
|
56
|
+
Requires-Dist: uvicorn[standard]>=0.30; extra == "web"
|
|
57
|
+
Requires-Dist: Pillow>=10.0; extra == "web"
|
|
54
58
|
Provides-Extra: fun
|
|
55
59
|
Requires-Dist: shapely>=2.0.0; extra == "fun"
|
|
56
60
|
Requires-Dist: Pillow>=10.0.0; extra == "fun"
|
|
@@ -312,7 +316,7 @@ pip install "SCPI-Instrument-Control[all]"
|
|
|
312
316
|
|
|
313
317
|
#### 2. Update Your Import Statements
|
|
314
318
|
|
|
315
|
-
**Old imports** (
|
|
319
|
+
**Old imports** (no longer work as of v2.0.0):
|
|
316
320
|
|
|
317
321
|
```python
|
|
318
322
|
from siglent import Oscilloscope, PowerSupply, FunctionGenerator
|
|
@@ -330,16 +334,11 @@ from scpi_control.waveform import Waveform
|
|
|
330
334
|
|
|
331
335
|
#### 3. Backward Compatibility
|
|
332
336
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
DeprecationWarning: The 'siglent' package name is deprecated and will be removed in v2.0.0.
|
|
339
|
-
Please update your imports to use 'scpi_control' instead.
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
**The compatibility layer will be removed in v2.0.0**, so please migrate your code when convenient.
|
|
337
|
+
The `siglent` compatibility shim was removed in **v2.0.0** (it had emitted a
|
|
338
|
+
`DeprecationWarning` since v1.0.0). `import siglent` now raises
|
|
339
|
+
`ModuleNotFoundError` — update your imports to `scpi_control` as shown above;
|
|
340
|
+
the API is otherwise identical. If you cannot migrate yet, pin
|
|
341
|
+
`SCPI-Instrument-Control<2.0`.
|
|
343
342
|
|
|
344
343
|
#### 4. Command-Line Tools
|
|
345
344
|
|
|
@@ -357,7 +356,7 @@ No changes needed to scripts or automation that invoke these commands.
|
|
|
357
356
|
| Old | New | Status |
|
|
358
357
|
|-----|-----|--------|
|
|
359
358
|
| PyPI package: `siglent` | PyPI package: `SCPI-Instrument-Control` | **Changed** |
|
|
360
|
-
| `import siglent` | `import scpi_control` | **
|
|
359
|
+
| `import siglent` | `import scpi_control` | **Required since v2.0.0** |
|
|
361
360
|
| `siglent-gui` command | `siglent-gui` command | **Unchanged** |
|
|
362
361
|
| `siglent-report-generator` command | `siglent-report-generator` command | **Unchanged** |
|
|
363
362
|
|
|
@@ -422,7 +421,7 @@ main()
|
|
|
422
421
|
|
|
423
422
|
### Core Library
|
|
424
423
|
|
|
425
|
-
- Python 3.
|
|
424
|
+
- Python 3.9+
|
|
426
425
|
- NumPy >= 1.24.0
|
|
427
426
|
- Matplotlib >= 3.7.0
|
|
428
427
|
- SciPy >= 1.10.0
|
|
@@ -681,6 +680,48 @@ See `examples/vector_graphics_xy_mode.py` for programmatic usage and animation e
|
|
|
681
680
|
- I2C, SPI, UART, CAN, LIN decoding
|
|
682
681
|
- Packet analysis and export
|
|
683
682
|
|
|
683
|
+
## Web Gateway (beta)
|
|
684
|
+
|
|
685
|
+
Control instruments from any browser on your LAN:
|
|
686
|
+
|
|
687
|
+
```bash
|
|
688
|
+
pip install scpi-instrument-control[web] # includes the browser gateway
|
|
689
|
+
scpi-web --host 0.0.0.0 --port 8765
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
Open `http://<gateway-pc>:8765`. Sessions can target real scopes by IP or a
|
|
693
|
+
built-in mock (`mock: true`) for hardware-free use. The API is documented at
|
|
694
|
+
`/docs` (OpenAPI). No authentication in this release — bind to `127.0.0.1`
|
|
695
|
+
(the default) unless your LAN is trusted.
|
|
696
|
+
|
|
697
|
+
- `GET /api/discover` scans the gateway's subnet (or `?cidr=…`) for SCPI
|
|
698
|
+
instruments on port 5025 and lists them with model and dialect — handy when
|
|
699
|
+
DHCP moves your instruments around.
|
|
700
|
+
- `GET .../scope/screenshot.png` — the instrument's display as a PNG
|
|
701
|
+
- `GET .../scope/waveform?channels=1,2&max_points=N` — waveform data as JSON
|
|
702
|
+
- `GET/PATCH .../scope/math/{1,2}` — software math channels (streamed as M1/M2 traces)
|
|
703
|
+
- `GET .../scope/measurements` — the current measurement selection
|
|
704
|
+
- `GET/PATCH .../scope/spectrum` — server-computed FFT spectrum (streamed as `spectrum` frames)
|
|
705
|
+
- `GET .../scope/filters` + `PATCH .../scope/filters/{1,2}` — software Butterworth filters (streamed as F1/F2 traces)
|
|
706
|
+
- `GET/POST/DELETE .../scope/references` + `GET/PUT .../scope/reference` — saved reference waveforms and the live overlay
|
|
707
|
+
- `POST .../scope/log/start` / `POST .../scope/log/stop` — record the selected measurements (~1 Hz) server-side
|
|
708
|
+
- `GET .../scope/log`, `GET .../scope/log/data?since=`, `GET .../scope/log.csv` — recording status, rows, and CSV export
|
|
709
|
+
|
|
710
|
+
### Browser UI
|
|
711
|
+
|
|
712
|
+
```bash
|
|
713
|
+
make webapp-install # once
|
|
714
|
+
make webapp-build # build the UI into the server
|
|
715
|
+
scpi-web --host 0.0.0.0 # serve API + UI on one port
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
Open `http://<gateway-pc>:8765`. For UI development, run `scpi-web` in one
|
|
719
|
+
terminal and `cd webapp/app && npm run dev` in another — Vite proxies `/api`
|
|
720
|
+
(HTTP and WebSocket) to the gateway with hot reload.
|
|
721
|
+
|
|
722
|
+
The home screen scans your LAN and lists instruments to connect to, resume, or
|
|
723
|
+
open a shared session on — plus manual IP and a hardware-free mock.
|
|
724
|
+
|
|
684
725
|
## API Documentation
|
|
685
726
|
|
|
686
727
|
### Oscilloscope
|
|
@@ -222,7 +222,7 @@ pip install "SCPI-Instrument-Control[all]"
|
|
|
222
222
|
|
|
223
223
|
#### 2. Update Your Import Statements
|
|
224
224
|
|
|
225
|
-
**Old imports** (
|
|
225
|
+
**Old imports** (no longer work as of v2.0.0):
|
|
226
226
|
|
|
227
227
|
```python
|
|
228
228
|
from siglent import Oscilloscope, PowerSupply, FunctionGenerator
|
|
@@ -240,16 +240,11 @@ from scpi_control.waveform import Waveform
|
|
|
240
240
|
|
|
241
241
|
#### 3. Backward Compatibility
|
|
242
242
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
DeprecationWarning: The 'siglent' package name is deprecated and will be removed in v2.0.0.
|
|
249
|
-
Please update your imports to use 'scpi_control' instead.
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
**The compatibility layer will be removed in v2.0.0**, so please migrate your code when convenient.
|
|
243
|
+
The `siglent` compatibility shim was removed in **v2.0.0** (it had emitted a
|
|
244
|
+
`DeprecationWarning` since v1.0.0). `import siglent` now raises
|
|
245
|
+
`ModuleNotFoundError` — update your imports to `scpi_control` as shown above;
|
|
246
|
+
the API is otherwise identical. If you cannot migrate yet, pin
|
|
247
|
+
`SCPI-Instrument-Control<2.0`.
|
|
253
248
|
|
|
254
249
|
#### 4. Command-Line Tools
|
|
255
250
|
|
|
@@ -267,7 +262,7 @@ No changes needed to scripts or automation that invoke these commands.
|
|
|
267
262
|
| Old | New | Status |
|
|
268
263
|
|-----|-----|--------|
|
|
269
264
|
| PyPI package: `siglent` | PyPI package: `SCPI-Instrument-Control` | **Changed** |
|
|
270
|
-
| `import siglent` | `import scpi_control` | **
|
|
265
|
+
| `import siglent` | `import scpi_control` | **Required since v2.0.0** |
|
|
271
266
|
| `siglent-gui` command | `siglent-gui` command | **Unchanged** |
|
|
272
267
|
| `siglent-report-generator` command | `siglent-report-generator` command | **Unchanged** |
|
|
273
268
|
|
|
@@ -332,7 +327,7 @@ main()
|
|
|
332
327
|
|
|
333
328
|
### Core Library
|
|
334
329
|
|
|
335
|
-
- Python 3.
|
|
330
|
+
- Python 3.9+
|
|
336
331
|
- NumPy >= 1.24.0
|
|
337
332
|
- Matplotlib >= 3.7.0
|
|
338
333
|
- SciPy >= 1.10.0
|
|
@@ -591,6 +586,48 @@ See `examples/vector_graphics_xy_mode.py` for programmatic usage and animation e
|
|
|
591
586
|
- I2C, SPI, UART, CAN, LIN decoding
|
|
592
587
|
- Packet analysis and export
|
|
593
588
|
|
|
589
|
+
## Web Gateway (beta)
|
|
590
|
+
|
|
591
|
+
Control instruments from any browser on your LAN:
|
|
592
|
+
|
|
593
|
+
```bash
|
|
594
|
+
pip install scpi-instrument-control[web] # includes the browser gateway
|
|
595
|
+
scpi-web --host 0.0.0.0 --port 8765
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
Open `http://<gateway-pc>:8765`. Sessions can target real scopes by IP or a
|
|
599
|
+
built-in mock (`mock: true`) for hardware-free use. The API is documented at
|
|
600
|
+
`/docs` (OpenAPI). No authentication in this release — bind to `127.0.0.1`
|
|
601
|
+
(the default) unless your LAN is trusted.
|
|
602
|
+
|
|
603
|
+
- `GET /api/discover` scans the gateway's subnet (or `?cidr=…`) for SCPI
|
|
604
|
+
instruments on port 5025 and lists them with model and dialect — handy when
|
|
605
|
+
DHCP moves your instruments around.
|
|
606
|
+
- `GET .../scope/screenshot.png` — the instrument's display as a PNG
|
|
607
|
+
- `GET .../scope/waveform?channels=1,2&max_points=N` — waveform data as JSON
|
|
608
|
+
- `GET/PATCH .../scope/math/{1,2}` — software math channels (streamed as M1/M2 traces)
|
|
609
|
+
- `GET .../scope/measurements` — the current measurement selection
|
|
610
|
+
- `GET/PATCH .../scope/spectrum` — server-computed FFT spectrum (streamed as `spectrum` frames)
|
|
611
|
+
- `GET .../scope/filters` + `PATCH .../scope/filters/{1,2}` — software Butterworth filters (streamed as F1/F2 traces)
|
|
612
|
+
- `GET/POST/DELETE .../scope/references` + `GET/PUT .../scope/reference` — saved reference waveforms and the live overlay
|
|
613
|
+
- `POST .../scope/log/start` / `POST .../scope/log/stop` — record the selected measurements (~1 Hz) server-side
|
|
614
|
+
- `GET .../scope/log`, `GET .../scope/log/data?since=`, `GET .../scope/log.csv` — recording status, rows, and CSV export
|
|
615
|
+
|
|
616
|
+
### Browser UI
|
|
617
|
+
|
|
618
|
+
```bash
|
|
619
|
+
make webapp-install # once
|
|
620
|
+
make webapp-build # build the UI into the server
|
|
621
|
+
scpi-web --host 0.0.0.0 # serve API + UI on one port
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
Open `http://<gateway-pc>:8765`. For UI development, run `scpi-web` in one
|
|
625
|
+
terminal and `cd webapp/app && npm run dev` in another — Vite proxies `/api`
|
|
626
|
+
(HTTP and WebSocket) to the gateway with hot reload.
|
|
627
|
+
|
|
628
|
+
The home screen scans your LAN and lists instruments to connect to, resume, or
|
|
629
|
+
open a shared session on — plus manual IP and a hardware-free mock.
|
|
630
|
+
|
|
594
631
|
## API Documentation
|
|
595
632
|
|
|
596
633
|
### Oscilloscope
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: SCPI-Instrument-Control
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: Universal Python library for controlling SCPI-compatible test equipment via Ethernet/LAN. Supports oscilloscopes (Siglent SDS series, generic SCPI scopes), function generators/AWGs (Siglent SDG series, generic SCPI AWGs), and power supplies (Siglent SPD series, generic SCPI PSUs). Features include waveform capture, measurements, FFT analysis, PyQt6 GUI, automated report generation with AI analysis, and comprehensive SCPI command abstraction.
|
|
5
5
|
Author: Robin Mumm
|
|
6
6
|
Maintainer: little-did-I-know
|
|
@@ -17,11 +17,12 @@ Classifier: Intended Audience :: Developers
|
|
|
17
17
|
Classifier: Intended Audience :: Manufacturing
|
|
18
18
|
Classifier: Operating System :: OS Independent
|
|
19
19
|
Classifier: Programming Language :: Python :: 3
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.9
|
|
22
21
|
Classifier: Programming Language :: Python :: 3.10
|
|
23
22
|
Classifier: Programming Language :: Python :: 3.11
|
|
24
23
|
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
25
26
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
26
27
|
Classifier: Topic :: Scientific/Engineering
|
|
27
28
|
Classifier: Topic :: Scientific/Engineering :: Interface Engine/Protocol Translator
|
|
@@ -30,7 +31,7 @@ Classifier: Topic :: System :: Networking :: Monitoring
|
|
|
30
31
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
31
32
|
Classifier: Environment :: X11 Applications :: Qt
|
|
32
33
|
Classifier: Typing :: Typed
|
|
33
|
-
Requires-Python: >=3.
|
|
34
|
+
Requires-Python: >=3.9
|
|
34
35
|
Description-Content-Type: text/markdown
|
|
35
36
|
License-File: LICENSE
|
|
36
37
|
Requires-Dist: numpy>=1.24.0
|
|
@@ -40,17 +41,20 @@ Provides-Extra: dev
|
|
|
40
41
|
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
41
42
|
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
42
43
|
Requires-Dist: codecov>=2.1.0; extra == "dev"
|
|
43
|
-
Requires-Dist: black
|
|
44
|
+
Requires-Dist: black<27,>=26.5; python_version >= "3.10" and extra == "dev"
|
|
44
45
|
Requires-Dist: flake8>=6.0; extra == "dev"
|
|
45
46
|
Requires-Dist: build>=0.10.0; extra == "dev"
|
|
46
47
|
Requires-Dist: twine>=4.0.0; extra == "dev"
|
|
47
|
-
Requires-Dist: black[jupyter]>=23.0; extra == "dev"
|
|
48
48
|
Provides-Extra: hdf5
|
|
49
49
|
Requires-Dist: h5py>=3.8.0; extra == "hdf5"
|
|
50
50
|
Provides-Extra: gui
|
|
51
51
|
Requires-Dist: PyQt6>=6.6.0; extra == "gui"
|
|
52
52
|
Requires-Dist: PyQt6-WebEngine>=6.6.0; extra == "gui"
|
|
53
53
|
Requires-Dist: pyqtgraph>=0.13.0; extra == "gui"
|
|
54
|
+
Provides-Extra: web
|
|
55
|
+
Requires-Dist: fastapi>=0.115; extra == "web"
|
|
56
|
+
Requires-Dist: uvicorn[standard]>=0.30; extra == "web"
|
|
57
|
+
Requires-Dist: Pillow>=10.0; extra == "web"
|
|
54
58
|
Provides-Extra: fun
|
|
55
59
|
Requires-Dist: shapely>=2.0.0; extra == "fun"
|
|
56
60
|
Requires-Dist: Pillow>=10.0.0; extra == "fun"
|
|
@@ -312,7 +316,7 @@ pip install "SCPI-Instrument-Control[all]"
|
|
|
312
316
|
|
|
313
317
|
#### 2. Update Your Import Statements
|
|
314
318
|
|
|
315
|
-
**Old imports** (
|
|
319
|
+
**Old imports** (no longer work as of v2.0.0):
|
|
316
320
|
|
|
317
321
|
```python
|
|
318
322
|
from siglent import Oscilloscope, PowerSupply, FunctionGenerator
|
|
@@ -330,16 +334,11 @@ from scpi_control.waveform import Waveform
|
|
|
330
334
|
|
|
331
335
|
#### 3. Backward Compatibility
|
|
332
336
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
DeprecationWarning: The 'siglent' package name is deprecated and will be removed in v2.0.0.
|
|
339
|
-
Please update your imports to use 'scpi_control' instead.
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
**The compatibility layer will be removed in v2.0.0**, so please migrate your code when convenient.
|
|
337
|
+
The `siglent` compatibility shim was removed in **v2.0.0** (it had emitted a
|
|
338
|
+
`DeprecationWarning` since v1.0.0). `import siglent` now raises
|
|
339
|
+
`ModuleNotFoundError` — update your imports to `scpi_control` as shown above;
|
|
340
|
+
the API is otherwise identical. If you cannot migrate yet, pin
|
|
341
|
+
`SCPI-Instrument-Control<2.0`.
|
|
343
342
|
|
|
344
343
|
#### 4. Command-Line Tools
|
|
345
344
|
|
|
@@ -357,7 +356,7 @@ No changes needed to scripts or automation that invoke these commands.
|
|
|
357
356
|
| Old | New | Status |
|
|
358
357
|
|-----|-----|--------|
|
|
359
358
|
| PyPI package: `siglent` | PyPI package: `SCPI-Instrument-Control` | **Changed** |
|
|
360
|
-
| `import siglent` | `import scpi_control` | **
|
|
359
|
+
| `import siglent` | `import scpi_control` | **Required since v2.0.0** |
|
|
361
360
|
| `siglent-gui` command | `siglent-gui` command | **Unchanged** |
|
|
362
361
|
| `siglent-report-generator` command | `siglent-report-generator` command | **Unchanged** |
|
|
363
362
|
|
|
@@ -422,7 +421,7 @@ main()
|
|
|
422
421
|
|
|
423
422
|
### Core Library
|
|
424
423
|
|
|
425
|
-
- Python 3.
|
|
424
|
+
- Python 3.9+
|
|
426
425
|
- NumPy >= 1.24.0
|
|
427
426
|
- Matplotlib >= 3.7.0
|
|
428
427
|
- SciPy >= 1.10.0
|
|
@@ -681,6 +680,48 @@ See `examples/vector_graphics_xy_mode.py` for programmatic usage and animation e
|
|
|
681
680
|
- I2C, SPI, UART, CAN, LIN decoding
|
|
682
681
|
- Packet analysis and export
|
|
683
682
|
|
|
683
|
+
## Web Gateway (beta)
|
|
684
|
+
|
|
685
|
+
Control instruments from any browser on your LAN:
|
|
686
|
+
|
|
687
|
+
```bash
|
|
688
|
+
pip install scpi-instrument-control[web] # includes the browser gateway
|
|
689
|
+
scpi-web --host 0.0.0.0 --port 8765
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
Open `http://<gateway-pc>:8765`. Sessions can target real scopes by IP or a
|
|
693
|
+
built-in mock (`mock: true`) for hardware-free use. The API is documented at
|
|
694
|
+
`/docs` (OpenAPI). No authentication in this release — bind to `127.0.0.1`
|
|
695
|
+
(the default) unless your LAN is trusted.
|
|
696
|
+
|
|
697
|
+
- `GET /api/discover` scans the gateway's subnet (or `?cidr=…`) for SCPI
|
|
698
|
+
instruments on port 5025 and lists them with model and dialect — handy when
|
|
699
|
+
DHCP moves your instruments around.
|
|
700
|
+
- `GET .../scope/screenshot.png` — the instrument's display as a PNG
|
|
701
|
+
- `GET .../scope/waveform?channels=1,2&max_points=N` — waveform data as JSON
|
|
702
|
+
- `GET/PATCH .../scope/math/{1,2}` — software math channels (streamed as M1/M2 traces)
|
|
703
|
+
- `GET .../scope/measurements` — the current measurement selection
|
|
704
|
+
- `GET/PATCH .../scope/spectrum` — server-computed FFT spectrum (streamed as `spectrum` frames)
|
|
705
|
+
- `GET .../scope/filters` + `PATCH .../scope/filters/{1,2}` — software Butterworth filters (streamed as F1/F2 traces)
|
|
706
|
+
- `GET/POST/DELETE .../scope/references` + `GET/PUT .../scope/reference` — saved reference waveforms and the live overlay
|
|
707
|
+
- `POST .../scope/log/start` / `POST .../scope/log/stop` — record the selected measurements (~1 Hz) server-side
|
|
708
|
+
- `GET .../scope/log`, `GET .../scope/log/data?since=`, `GET .../scope/log.csv` — recording status, rows, and CSV export
|
|
709
|
+
|
|
710
|
+
### Browser UI
|
|
711
|
+
|
|
712
|
+
```bash
|
|
713
|
+
make webapp-install # once
|
|
714
|
+
make webapp-build # build the UI into the server
|
|
715
|
+
scpi-web --host 0.0.0.0 # serve API + UI on one port
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
Open `http://<gateway-pc>:8765`. For UI development, run `scpi-web` in one
|
|
719
|
+
terminal and `cd webapp/app && npm run dev` in another — Vite proxies `/api`
|
|
720
|
+
(HTTP and WebSocket) to the gateway with hot reload.
|
|
721
|
+
|
|
722
|
+
The home screen scans your LAN and lists instruments to connect to, resume, or
|
|
723
|
+
open a shared session on — plus manual IP and a hardware-free mock.
|
|
724
|
+
|
|
684
725
|
## API Documentation
|
|
685
726
|
|
|
686
727
|
### Oscilloscope
|
|
@@ -23,6 +23,7 @@ examples/advanced_analysis.py
|
|
|
23
23
|
examples/basic_usage.py
|
|
24
24
|
examples/batch_capture.py
|
|
25
25
|
examples/continuous_capture.py
|
|
26
|
+
examples/data_logger_basic.py
|
|
26
27
|
examples/function_generator_basic.py
|
|
27
28
|
examples/live_plot.py
|
|
28
29
|
examples/measurements.py
|
|
@@ -47,6 +48,9 @@ scpi_control/awg_models.py
|
|
|
47
48
|
scpi_control/awg_output.py
|
|
48
49
|
scpi_control/awg_scpi_commands.py
|
|
49
50
|
scpi_control/channel.py
|
|
51
|
+
scpi_control/daq_models.py
|
|
52
|
+
scpi_control/daq_scpi_commands.py
|
|
53
|
+
scpi_control/data_logger.py
|
|
50
54
|
scpi_control/exceptions.py
|
|
51
55
|
scpi_control/function_generator.py
|
|
52
56
|
scpi_control/math_channel.py
|
|
@@ -75,6 +79,7 @@ scpi_control/connection/visa_connection.py
|
|
|
75
79
|
scpi_control/gui/__init__.py
|
|
76
80
|
scpi_control/gui/app.py
|
|
77
81
|
scpi_control/gui/connection_manager.py
|
|
82
|
+
scpi_control/gui/daq_worker.py
|
|
78
83
|
scpi_control/gui/live_view_worker.py
|
|
79
84
|
scpi_control/gui/main_window.py
|
|
80
85
|
scpi_control/gui/vnc_window.py
|
|
@@ -83,6 +88,11 @@ scpi_control/gui/utils/validators.py
|
|
|
83
88
|
scpi_control/gui/widgets/__init__.py
|
|
84
89
|
scpi_control/gui/widgets/channel_control.py
|
|
85
90
|
scpi_control/gui/widgets/cursor_panel.py
|
|
91
|
+
scpi_control/gui/widgets/daq_ai_panel.py
|
|
92
|
+
scpi_control/gui/widgets/daq_channel_config.py
|
|
93
|
+
scpi_control/gui/widgets/daq_data_view.py
|
|
94
|
+
scpi_control/gui/widgets/daq_scan_config.py
|
|
95
|
+
scpi_control/gui/widgets/data_logger_control.py
|
|
86
96
|
scpi_control/gui/widgets/error_dialog.py
|
|
87
97
|
scpi_control/gui/widgets/fft_display.py
|
|
88
98
|
scpi_control/gui/widgets/math_panel.py
|
|
@@ -118,6 +128,9 @@ scpi_control/report_generator/llm/__init__.py
|
|
|
118
128
|
scpi_control/report_generator/llm/analyzer.py
|
|
119
129
|
scpi_control/report_generator/llm/client.py
|
|
120
130
|
scpi_control/report_generator/llm/context_builder.py
|
|
131
|
+
scpi_control/report_generator/llm/daq_analyzer.py
|
|
132
|
+
scpi_control/report_generator/llm/daq_context_builder.py
|
|
133
|
+
scpi_control/report_generator/llm/daq_prompts.py
|
|
121
134
|
scpi_control/report_generator/llm/prompts.py
|
|
122
135
|
scpi_control/report_generator/models/__init__.py
|
|
123
136
|
scpi_control/report_generator/models/app_settings.py
|
|
@@ -139,4 +152,19 @@ scpi_control/report_generator/widgets/metadata_panel.py
|
|
|
139
152
|
scpi_control/report_generator/widgets/pdf_preview_dialog.py
|
|
140
153
|
scpi_control/report_generator/widgets/report_options_dialog.py
|
|
141
154
|
scpi_control/report_generator/widgets/template_manager_dialog.py
|
|
142
|
-
|
|
155
|
+
scpi_control/server/__init__.py
|
|
156
|
+
scpi_control/server/__main__.py
|
|
157
|
+
scpi_control/server/app.py
|
|
158
|
+
scpi_control/server/compute.py
|
|
159
|
+
scpi_control/server/discovery.py
|
|
160
|
+
scpi_control/server/recorder.py
|
|
161
|
+
scpi_control/server/schemas.py
|
|
162
|
+
scpi_control/server/sessions.py
|
|
163
|
+
scpi_control/server/api/__init__.py
|
|
164
|
+
scpi_control/server/api/discovery.py
|
|
165
|
+
scpi_control/server/api/scope.py
|
|
166
|
+
scpi_control/server/api/sessions.py
|
|
167
|
+
scpi_control/server/api/stream.py
|
|
168
|
+
scpi_control/server/static/index.html
|
|
169
|
+
scpi_control/server/static/assets/index-0Vpguwg6.js
|
|
170
|
+
scpi_control/server/static/assets/index-CyUPLIHk.css
|
|
@@ -21,11 +21,12 @@ pyinstaller>=6.0.0
|
|
|
21
21
|
pytest>=7.0
|
|
22
22
|
pytest-cov>=4.0.0
|
|
23
23
|
codecov>=2.1.0
|
|
24
|
-
black>=23.0
|
|
25
24
|
flake8>=6.0
|
|
26
25
|
build>=0.10.0
|
|
27
26
|
twine>=4.0.0
|
|
28
|
-
|
|
27
|
+
|
|
28
|
+
[dev:python_version >= "3.10"]
|
|
29
|
+
black<27,>=26.5
|
|
29
30
|
|
|
30
31
|
[docs]
|
|
31
32
|
mkdocs>=1.5.0
|
|
@@ -62,3 +63,8 @@ ollama>=0.6.0
|
|
|
62
63
|
[usb]
|
|
63
64
|
pyvisa>=1.14.0
|
|
64
65
|
pyvisa-py>=0.7.0
|
|
66
|
+
|
|
67
|
+
[web]
|
|
68
|
+
fastapi>=0.115
|
|
69
|
+
uvicorn[standard]>=0.30
|
|
70
|
+
Pillow>=10.0
|
|
@@ -232,7 +232,7 @@ collector.save_data(waveforms, 'output.mat', format='mat')
|
|
|
232
232
|
## Quick Start - Programmatic API
|
|
233
233
|
|
|
234
234
|
```python
|
|
235
|
-
from
|
|
235
|
+
from scpi_control.automation import DataCollector
|
|
236
236
|
|
|
237
237
|
# Simple capture
|
|
238
238
|
with DataCollector('192.168.1.100') as collector:
|
|
@@ -245,7 +245,7 @@ with DataCollector('192.168.1.100') as collector:
|
|
|
245
245
|
## Tips
|
|
246
246
|
|
|
247
247
|
- Make sure your oscilloscope is connected to the same network as your computer
|
|
248
|
-
- Ensure the SCPI port (
|
|
248
|
+
- Ensure the SCPI port (5025) is accessible
|
|
249
249
|
- Some commands may vary slightly between oscilloscope models - refer to your programming manual
|
|
250
250
|
- Enable at least one channel before capturing waveforms
|
|
251
251
|
- Use AUTO trigger mode for continuous acquisition
|