Initial commit: First two meeasurements of sample 8, runs (almost) all stress and eth tests and measures power and ripple.
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.venv/
|
||||
157
measure.py
Normal file
@@ -0,0 +1,157 @@
|
||||
#!/usr/bin/env python3
|
||||
import pyvisa
|
||||
import yaml
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from datetime import datetime
|
||||
import os
|
||||
import argparse # For handling command-line arguments
|
||||
|
||||
|
||||
def detach_kernel_tmc(vid, pid):
|
||||
"""Detach kernel driver for USBTMC devices."""
|
||||
import usb.core, usb.util
|
||||
dev = usb.core.find(idVendor=vid, idProduct=pid)
|
||||
if not dev:
|
||||
return
|
||||
try:
|
||||
for cfg in dev:
|
||||
for intf in cfg:
|
||||
if intf.bInterfaceClass == 0xFE: # USBTMC
|
||||
if dev.is_kernel_driver_active(intf.bInterfaceNumber):
|
||||
dev.detach_kernel_driver(intf.bInterfaceNumber)
|
||||
try:
|
||||
dev.set_configuration()
|
||||
except Exception:
|
||||
pass
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def load_settings(file_path):
|
||||
"""Load settings from a YAML file."""
|
||||
with open(file_path, 'r') as file:
|
||||
return yaml.safe_load(file)
|
||||
|
||||
|
||||
def configure_oscilloscope(osc, settings):
|
||||
"""Configure the oscilloscope with the given settings."""
|
||||
osc.write(f":TIMebase:SCALe {settings['timebase_scale']}")
|
||||
for channel, config in settings['channels'].items():
|
||||
osc.write(f":CHANnel{channel}:OFFSet {config['offset']}")
|
||||
osc.write(f":CHANnel{channel}:SCALe {config['scale']}")
|
||||
osc.write(":SINGle") # Set to single trigger mode
|
||||
|
||||
|
||||
def fetch_waveform(osc, channel, timebase_scale):
|
||||
"""Fetch waveform data from a specific channel."""
|
||||
osc.write(f":WAVeform:SOURce CHANnel{channel}")
|
||||
osc.write(":WAVeform:FORMat ASCii")
|
||||
data = osc.query(":WAVeform:DATA?")
|
||||
|
||||
if data.startswith('#'):
|
||||
header_length = int(data[1]) # The second character indicates the header length
|
||||
data = data[2 + header_length:] # Skip the header
|
||||
|
||||
voltage = np.array([float(x) for x in data.split(',')])
|
||||
time = np.linspace(0, timebase_scale * 10, len(voltage)) # 10 divisions
|
||||
return time, voltage
|
||||
|
||||
|
||||
def save_waveform_plot(time, voltage, channel, output_dir):
|
||||
"""Save waveform as a JPG image."""
|
||||
plt.figure()
|
||||
plt.plot(time, voltage)
|
||||
plt.title(f"Channel {channel} Waveform")
|
||||
plt.xlabel("Time (s)")
|
||||
plt.ylabel("Voltage (V)")
|
||||
plt.grid()
|
||||
file_path = f"{output_dir}/channel{channel}_waveform.jpg"
|
||||
plt.savefig(file_path)
|
||||
plt.close()
|
||||
print(f"Waveform saved as {file_path}")
|
||||
|
||||
|
||||
def save_raw_timeseries(time, voltage, channel, output_dir):
|
||||
"""Save raw time series data as a CSV file."""
|
||||
file_path = f"{output_dir}/channel{channel}_timeseries.csv"
|
||||
data = np.column_stack((time, voltage))
|
||||
np.savetxt(file_path, data, delimiter=",", header="Time (s),Voltage (V)", comments="")
|
||||
print(f"Raw time series saved as {file_path}")
|
||||
|
||||
|
||||
def calculate_ripple(data):
|
||||
"""Calculate the ripple (peak-to-peak voltage)."""
|
||||
return float(np.ptp(data)) # Convert to plain float
|
||||
|
||||
|
||||
def calculate_average(data):
|
||||
"""Calculate the average voltage."""
|
||||
return float(np.mean(data)) # Convert to plain float
|
||||
|
||||
|
||||
def main():
|
||||
# Parse command-line arguments
|
||||
parser = argparse.ArgumentParser(description="Automated oscilloscope measurement script.")
|
||||
parser.add_argument("SampleNumber", type=int, help="The sample number for the test.")
|
||||
parser.add_argument("Supply", type=str, choices=["PoE", "PoELong", "external"], help="The supply type (PoE, PoELong, or external).")
|
||||
parser.add_argument("TestCase", type=str, choices=["baseline", "CPU", "EthPrim", "EthSec"], help="The test case (baseline, CPU, EthPrim, or EthSec).")
|
||||
args = parser.parse_args()
|
||||
|
||||
# Detach kernel driver if necessary
|
||||
VID, PID = 0x0957, 0x1798 # Keysight DSOX2014A
|
||||
detach_kernel_tmc(VID, PID)
|
||||
|
||||
# Load settings
|
||||
settings_file = "settings.yaml"
|
||||
settings = load_settings(settings_file)
|
||||
|
||||
# Ensure timebase_scale is a float
|
||||
timebase_scale = float(settings['timebase_scale'])
|
||||
|
||||
# Create a timestamped subfolder for results
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
output_dir = os.path.join(settings.get('output_directory', '.'), f"measurement_results_{timestamp}")
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
|
||||
# Connect to the oscilloscope
|
||||
rm = pyvisa.ResourceManager("@py") # Use pyvisa-py backend
|
||||
resource_string = f"USB0::0x{VID:04x}::0x{PID:04x}::MY59124583::INSTR"
|
||||
oscilloscope = rm.open_resource(resource_string)
|
||||
print("Connected to:", oscilloscope.query("*IDN?"))
|
||||
|
||||
# Configure the oscilloscope
|
||||
configure_oscilloscope(oscilloscope, settings)
|
||||
|
||||
# Trigger a measurement
|
||||
oscilloscope.write(":DIGitize")
|
||||
|
||||
# Fetch and process data for each channel
|
||||
results = {
|
||||
"SampleNumber": args.SampleNumber,
|
||||
"Supply": args.Supply,
|
||||
"TestCase": args.TestCase,
|
||||
"Channels": {}
|
||||
}
|
||||
for channel in settings['channels']:
|
||||
time, voltage = fetch_waveform(oscilloscope, channel, timebase_scale)
|
||||
save_waveform_plot(time, voltage, channel, output_dir)
|
||||
save_raw_timeseries(time, voltage, channel, output_dir)
|
||||
ripple = calculate_ripple(voltage)
|
||||
average = calculate_average(voltage)
|
||||
results["Channels"][channel] = {'ripple': ripple, 'average': average}
|
||||
print(f"Channel {channel}: Ripple = {ripple:.3f} V, Average = {average:.3f} V")
|
||||
|
||||
# Save results to a YAML file
|
||||
results_file = f"{output_dir}/results.yaml"
|
||||
with open(results_file, 'w') as file:
|
||||
yaml.dump(results, file)
|
||||
print(f"Results saved to {results_file}")
|
||||
|
||||
# Close the connection
|
||||
oscilloscope.close()
|
||||
print("Measurement complete.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
40000
output/measurement_results_20251111_143615/channel2_timeseries.csv
Normal file
BIN
output/measurement_results_20251111_143615/channel2_waveform.jpg
Normal file
|
After Width: | Height: | Size: 36 KiB |
40000
output/measurement_results_20251111_143615/channel3_timeseries.csv
Normal file
BIN
output/measurement_results_20251111_143615/channel3_waveform.jpg
Normal file
|
After Width: | Height: | Size: 37 KiB |
10
output/measurement_results_20251111_143615/results.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
Channels:
|
||||
2:
|
||||
average: 5.145188140703517
|
||||
ripple: 0.07235999999999976
|
||||
3:
|
||||
average: 3.2925820100502508
|
||||
ripple: 0.04823999999999984
|
||||
SampleNumber: 8
|
||||
Supply: external
|
||||
TestCase: baseline
|
||||
40000
output/measurement_results_20251111_143627/channel2_timeseries.csv
Normal file
BIN
output/measurement_results_20251111_143627/channel2_waveform.jpg
Normal file
|
After Width: | Height: | Size: 36 KiB |
40000
output/measurement_results_20251111_143627/channel3_timeseries.csv
Normal file
BIN
output/measurement_results_20251111_143627/channel3_waveform.jpg
Normal file
|
After Width: | Height: | Size: 37 KiB |
10
output/measurement_results_20251111_143627/results.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
Channels:
|
||||
2:
|
||||
average: 5.1029829145728645
|
||||
ripple: 0.06432000000000038
|
||||
3:
|
||||
average: 3.293092361809045
|
||||
ripple: 0.044219999999999704
|
||||
SampleNumber: 8
|
||||
Supply: external
|
||||
TestCase: CPU
|
||||
40000
output/measurement_results_20251111_143646/channel2_timeseries.csv
Normal file
BIN
output/measurement_results_20251111_143646/channel2_waveform.jpg
Normal file
|
After Width: | Height: | Size: 37 KiB |
40000
output/measurement_results_20251111_143646/channel3_timeseries.csv
Normal file
BIN
output/measurement_results_20251111_143646/channel3_waveform.jpg
Normal file
|
After Width: | Height: | Size: 37 KiB |
10
output/measurement_results_20251111_143646/results.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
Channels:
|
||||
2:
|
||||
average: 5.094936482412059
|
||||
ripple: 0.07235999999999976
|
||||
3:
|
||||
average: 3.2914342713567843
|
||||
ripple: 0.044219999999999704
|
||||
SampleNumber: 8
|
||||
Supply: external
|
||||
TestCase: EthPrim
|
||||
40000
output/measurement_results_20251111_144245/channel2_timeseries.csv
Normal file
BIN
output/measurement_results_20251111_144245/channel2_waveform.jpg
Normal file
|
After Width: | Height: | Size: 44 KiB |
40000
output/measurement_results_20251111_144245/channel3_timeseries.csv
Normal file
BIN
output/measurement_results_20251111_144245/channel3_waveform.jpg
Normal file
|
After Width: | Height: | Size: 39 KiB |
10
output/measurement_results_20251111_144245/results.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
Channels:
|
||||
2:
|
||||
average: 5.061786742668567
|
||||
ripple: 0.3859300000000001
|
||||
3:
|
||||
average: 3.2921956783919595
|
||||
ripple: 0.06834000000000007
|
||||
SampleNumber: 8
|
||||
Supply: PoE
|
||||
TestCase: baseline
|
||||
40000
output/measurement_results_20251111_144258/channel2_timeseries.csv
Normal file
BIN
output/measurement_results_20251111_144258/channel2_waveform.jpg
Normal file
|
After Width: | Height: | Size: 42 KiB |
40000
output/measurement_results_20251111_144258/channel3_timeseries.csv
Normal file
BIN
output/measurement_results_20251111_144258/channel3_waveform.jpg
Normal file
|
After Width: | Height: | Size: 42 KiB |
10
output/measurement_results_20251111_144258/results.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
Channels:
|
||||
2:
|
||||
average: 5.005816642916072
|
||||
ripple: 0.45828999999999986
|
||||
3:
|
||||
average: 3.291857286432161
|
||||
ripple: 0.07637999999999989
|
||||
SampleNumber: 8
|
||||
Supply: PoE
|
||||
TestCase: CPU
|
||||
40000
output/measurement_results_20251111_144317/channel2_timeseries.csv
Normal file
BIN
output/measurement_results_20251111_144317/channel2_waveform.jpg
Normal file
|
After Width: | Height: | Size: 44 KiB |
40000
output/measurement_results_20251111_144317/channel3_timeseries.csv
Normal file
BIN
output/measurement_results_20251111_144317/channel3_waveform.jpg
Normal file
|
After Width: | Height: | Size: 39 KiB |
10
output/measurement_results_20251111_144317/results.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
Channels:
|
||||
2:
|
||||
average: 5.063485833395835
|
||||
ripple: 0.3618100000000002
|
||||
3:
|
||||
average: 3.2923308542713565
|
||||
ripple: 0.06030000000000024
|
||||
SampleNumber: 8
|
||||
Supply: PoE
|
||||
TestCase: EthPrim
|
||||
40000
output/measurement_results_20251111_145855/channel2_timeseries.csv
Normal file
BIN
output/measurement_results_20251111_145855/channel2_waveform.jpg
Normal file
|
After Width: | Height: | Size: 39 KiB |
40000
output/measurement_results_20251111_145855/channel3_timeseries.csv
Normal file
BIN
output/measurement_results_20251111_145855/channel3_waveform.jpg
Normal file
|
After Width: | Height: | Size: 37 KiB |
10
output/measurement_results_20251111_145855/results.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
Channels:
|
||||
2:
|
||||
average: 5.156141507537689
|
||||
ripple: 0.05628000000000011
|
||||
3:
|
||||
average: 3.292163618090452
|
||||
ripple: 0.04823999999999984
|
||||
SampleNumber: 8
|
||||
Supply: external
|
||||
TestCase: baseline
|
||||
40000
output/measurement_results_20251111_145907/channel2_timeseries.csv
Normal file
BIN
output/measurement_results_20251111_145907/channel2_waveform.jpg
Normal file
|
After Width: | Height: | Size: 36 KiB |
40000
output/measurement_results_20251111_145907/channel3_timeseries.csv
Normal file
BIN
output/measurement_results_20251111_145907/channel3_waveform.jpg
Normal file
|
After Width: | Height: | Size: 38 KiB |
10
output/measurement_results_20251111_145907/results.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
Channels:
|
||||
2:
|
||||
average: 5.088713165829145
|
||||
ripple: 0.06431999999999949
|
||||
3:
|
||||
average: 3.291958492462311
|
||||
ripple: 0.05628000000000011
|
||||
SampleNumber: 8
|
||||
Supply: external
|
||||
TestCase: CPU
|
||||
40000
output/measurement_results_20251111_145927/channel2_timeseries.csv
Normal file
BIN
output/measurement_results_20251111_145927/channel2_waveform.jpg
Normal file
|
After Width: | Height: | Size: 38 KiB |
40000
output/measurement_results_20251111_145927/channel3_timeseries.csv
Normal file
BIN
output/measurement_results_20251111_145927/channel3_waveform.jpg
Normal file
|
After Width: | Height: | Size: 38 KiB |
10
output/measurement_results_20251111_145927/results.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
Channels:
|
||||
2:
|
||||
average: 5.081068944723618
|
||||
ripple: 0.06432000000000038
|
||||
3:
|
||||
average: 3.292249346733668
|
||||
ripple: 0.06432000000000038
|
||||
SampleNumber: 8
|
||||
Supply: external
|
||||
TestCase: EthPrim
|
||||
40000
output/measurement_results_20251111_150032/channel2_timeseries.csv
Normal file
BIN
output/measurement_results_20251111_150032/channel2_waveform.jpg
Normal file
|
After Width: | Height: | Size: 42 KiB |
40000
output/measurement_results_20251111_150032/channel3_timeseries.csv
Normal file
BIN
output/measurement_results_20251111_150032/channel3_waveform.jpg
Normal file
|
After Width: | Height: | Size: 40 KiB |
10
output/measurement_results_20251111_150032/results.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
Channels:
|
||||
2:
|
||||
average: 5.0519079399484985
|
||||
ripple: 0.32160999999999973
|
||||
3:
|
||||
average: 3.2914292462311554
|
||||
ripple: 0.06030000000000024
|
||||
SampleNumber: 8
|
||||
Supply: PoE
|
||||
TestCase: baseline
|
||||
40000
output/measurement_results_20251111_150044/channel2_timeseries.csv
Normal file
BIN
output/measurement_results_20251111_150044/channel2_waveform.jpg
Normal file
|
After Width: | Height: | Size: 45 KiB |
40000
output/measurement_results_20251111_150044/channel3_timeseries.csv
Normal file
BIN
output/measurement_results_20251111_150044/channel3_waveform.jpg
Normal file
|
After Width: | Height: | Size: 41 KiB |
10
output/measurement_results_20251111_150044/results.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
Channels:
|
||||
2:
|
||||
average: 5.007290644516113
|
||||
ripple: 0.3618100000000002
|
||||
3:
|
||||
average: 3.291560703517588
|
||||
ripple: 0.08040000000000003
|
||||
SampleNumber: 8
|
||||
Supply: PoE
|
||||
TestCase: CPU
|
||||
40000
output/measurement_results_20251111_150103/channel2_timeseries.csv
Normal file
BIN
output/measurement_results_20251111_150103/channel2_waveform.jpg
Normal file
|
After Width: | Height: | Size: 42 KiB |
40000
output/measurement_results_20251111_150103/channel3_timeseries.csv
Normal file
BIN
output/measurement_results_20251111_150103/channel3_waveform.jpg
Normal file
|
After Width: | Height: | Size: 39 KiB |
10
output/measurement_results_20251111_150103/results.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
Channels:
|
||||
2:
|
||||
average: 5.057190754268857
|
||||
ripple: 0.3215999999999992
|
||||
3:
|
||||
average: 3.2919710552763823
|
||||
ripple: 0.06432000000000038
|
||||
SampleNumber: 8
|
||||
Supply: PoE
|
||||
TestCase: EthPrim
|
||||
19
results/test_20251111_143614/iperf3_client.log
Normal file
@@ -0,0 +1,19 @@
|
||||
Connecting to host 10.11.0.91, port 5201
|
||||
[ 5] local 10.11.0.70 port 53466 connected to 10.11.0.91 port 5201
|
||||
[ ID] Interval Transfer Bitrate Retr Cwnd
|
||||
[ 5] 0.00-1.00 sec 11.8 MBytes 98.8 Mbits/sec 0 105 KBytes
|
||||
[ 5] 1.00-2.00 sec 11.2 MBytes 94.3 Mbits/sec 0 105 KBytes
|
||||
[ 5] 2.00-3.00 sec 11.2 MBytes 93.8 Mbits/sec 0 113 KBytes
|
||||
[ 5] 3.00-4.00 sec 11.2 MBytes 93.8 Mbits/sec 0 113 KBytes
|
||||
[ 5] 4.00-5.00 sec 11.3 MBytes 94.9 Mbits/sec 0 113 KBytes
|
||||
[ 5] 5.00-6.00 sec 11.3 MBytes 94.9 Mbits/sec 0 119 KBytes
|
||||
[ 5] 6.00-7.00 sec 11.0 MBytes 92.3 Mbits/sec 0 119 KBytes
|
||||
[ 5] 7.00-8.00 sec 11.3 MBytes 94.9 Mbits/sec 0 119 KBytes
|
||||
[ 5] 8.00-9.00 sec 11.3 MBytes 94.9 Mbits/sec 0 119 KBytes
|
||||
[ 5] 9.00-10.00 sec 11.2 MBytes 94.4 Mbits/sec 0 119 KBytes
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
[ ID] Interval Transfer Bitrate Retr
|
||||
[ 5] 0.00-10.00 sec 113 MBytes 94.7 Mbits/sec 0 sender
|
||||
[ 5] 0.00-10.04 sec 112 MBytes 93.8 Mbits/sec receiver
|
||||
|
||||
iperf Done.
|
||||
19
results/test_20251111_143614/iperf3_client_poe.log
Normal file
@@ -0,0 +1,19 @@
|
||||
Connecting to host 10.11.0.91, port 5201
|
||||
[ 5] local 10.11.0.70 port 42388 connected to 10.11.0.91 port 5201
|
||||
[ ID] Interval Transfer Bitrate Retr Cwnd
|
||||
[ 5] 0.00-1.00 sec 11.7 MBytes 98.4 Mbits/sec 0 116 KBytes
|
||||
[ 5] 1.00-2.00 sec 11.2 MBytes 93.8 Mbits/sec 0 116 KBytes
|
||||
[ 5] 2.00-3.00 sec 11.4 MBytes 95.9 Mbits/sec 0 116 KBytes
|
||||
[ 5] 3.00-4.00 sec 11.2 MBytes 93.8 Mbits/sec 0 116 KBytes
|
||||
[ 5] 4.00-5.00 sec 11.2 MBytes 93.8 Mbits/sec 0 120 KBytes
|
||||
[ 5] 5.00-6.00 sec 11.2 MBytes 93.8 Mbits/sec 0 120 KBytes
|
||||
[ 5] 6.00-7.00 sec 11.2 MBytes 93.8 Mbits/sec 0 120 KBytes
|
||||
[ 5] 7.00-8.00 sec 11.2 MBytes 93.8 Mbits/sec 0 120 KBytes
|
||||
[ 5] 8.00-9.00 sec 11.2 MBytes 93.8 Mbits/sec 0 120 KBytes
|
||||
[ 5] 9.00-10.00 sec 11.4 MBytes 95.9 Mbits/sec 0 120 KBytes
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
[ ID] Interval Transfer Bitrate Retr
|
||||
[ 5] 0.00-10.00 sec 113 MBytes 94.7 Mbits/sec 0 sender
|
||||
[ 5] 0.00-10.05 sec 112 MBytes 93.7 Mbits/sec receiver
|
||||
|
||||
iperf Done.
|
||||
24
results/test_20251111_143614/iperf3_server.log
Normal file
@@ -0,0 +1,24 @@
|
||||
-----------------------------------------------------------
|
||||
Server listening on 5201
|
||||
-----------------------------------------------------------
|
||||
Accepted connection from 10.11.0.70, port 42376
|
||||
[ 5] local 10.11.0.91 port 5201 connected to 10.11.0.70 port 42388
|
||||
[ ID] Interval Transfer Bitrate
|
||||
[ 5] 0.00-1.00 sec 10.7 MBytes 89.5 Mbits/sec
|
||||
[ 5] 1.00-2.00 sec 11.2 MBytes 94.2 Mbits/sec
|
||||
[ 5] 2.00-3.00 sec 11.2 MBytes 94.1 Mbits/sec
|
||||
[ 5] 3.00-4.00 sec 11.2 MBytes 94.1 Mbits/sec
|
||||
[ 5] 4.00-5.00 sec 11.2 MBytes 94.2 Mbits/sec
|
||||
[ 5] 5.00-6.00 sec 11.2 MBytes 94.1 Mbits/sec
|
||||
[ 5] 6.00-7.00 sec 11.2 MBytes 94.2 Mbits/sec
|
||||
[ 5] 7.00-8.00 sec 11.2 MBytes 94.1 Mbits/sec
|
||||
[ 5] 8.00-9.00 sec 11.2 MBytes 94.2 Mbits/sec
|
||||
[ 5] 9.00-10.00 sec 11.2 MBytes 94.1 Mbits/sec
|
||||
[ 5] 10.00-10.05 sec 625 KBytes 94.0 Mbits/sec
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
[ ID] Interval Transfer Bitrate
|
||||
[ 5] 0.00-10.05 sec 112 MBytes 93.7 Mbits/sec receiver
|
||||
iperf3: interrupt - the server has terminated
|
||||
-----------------------------------------------------------
|
||||
Server listening on 5201
|
||||
-----------------------------------------------------------
|
||||
1
results/test_20251111_143614/stress.log
Normal file
@@ -0,0 +1 @@
|
||||
stress: info: [1697] dispatching hogs: 2 cpu, 2 io, 2 vm, 0 hdd
|
||||
2
results/test_20251111_143614/stress_poe.log
Normal file
@@ -0,0 +1,2 @@
|
||||
stress: info: [1150] dispatching hogs: 2 cpu, 2 io, 2 vm, 0 hdd
|
||||
stress: info: [1150] successful run completed in 49s
|
||||
19
results/test_20251111_145855/iperf3_client.log
Normal file
@@ -0,0 +1,19 @@
|
||||
Connecting to host 10.11.0.91, port 5201
|
||||
[ 5] local 10.11.0.70 port 57980 connected to 10.11.0.91 port 5201
|
||||
[ ID] Interval Transfer Bitrate Retr Cwnd
|
||||
[ 5] 0.00-1.00 sec 11.7 MBytes 97.8 Mbits/sec 0 110 KBytes
|
||||
[ 5] 1.00-2.00 sec 11.2 MBytes 94.3 Mbits/sec 0 116 KBytes
|
||||
[ 5] 2.00-3.00 sec 11.2 MBytes 94.4 Mbits/sec 0 116 KBytes
|
||||
[ 5] 3.00-4.00 sec 11.4 MBytes 95.4 Mbits/sec 0 126 KBytes
|
||||
[ 5] 4.00-5.00 sec 11.3 MBytes 94.9 Mbits/sec 0 126 KBytes
|
||||
[ 5] 5.00-6.00 sec 11.2 MBytes 93.8 Mbits/sec 0 133 KBytes
|
||||
[ 5] 6.00-7.00 sec 11.2 MBytes 93.8 Mbits/sec 0 133 KBytes
|
||||
[ 5] 7.00-8.00 sec 11.2 MBytes 93.8 Mbits/sec 0 133 KBytes
|
||||
[ 5] 8.00-9.00 sec 11.2 MBytes 93.8 Mbits/sec 0 133 KBytes
|
||||
[ 5] 9.00-10.00 sec 11.2 MBytes 93.8 Mbits/sec 0 133 KBytes
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
[ ID] Interval Transfer Bitrate Retr
|
||||
[ 5] 0.00-10.00 sec 113 MBytes 94.6 Mbits/sec 0 sender
|
||||
[ 5] 0.00-10.05 sec 112 MBytes 93.7 Mbits/sec receiver
|
||||
|
||||
iperf Done.
|
||||
19
results/test_20251111_145855/iperf3_client_poe.log
Normal file
@@ -0,0 +1,19 @@
|
||||
Connecting to host 10.11.0.91, port 5201
|
||||
[ 5] local 10.11.0.70 port 44400 connected to 10.11.0.91 port 5201
|
||||
[ ID] Interval Transfer Bitrate Retr Cwnd
|
||||
[ 5] 0.00-1.00 sec 11.8 MBytes 98.9 Mbits/sec 0 113 KBytes
|
||||
[ 5] 1.00-2.00 sec 11.2 MBytes 93.8 Mbits/sec 0 113 KBytes
|
||||
[ 5] 2.00-3.00 sec 11.2 MBytes 93.8 Mbits/sec 0 113 KBytes
|
||||
[ 5] 3.00-4.00 sec 11.2 MBytes 93.8 Mbits/sec 0 113 KBytes
|
||||
[ 5] 4.00-5.00 sec 11.4 MBytes 95.9 Mbits/sec 0 113 KBytes
|
||||
[ 5] 5.00-6.00 sec 11.2 MBytes 93.8 Mbits/sec 0 117 KBytes
|
||||
[ 5] 6.00-7.00 sec 11.2 MBytes 93.8 Mbits/sec 0 117 KBytes
|
||||
[ 5] 7.00-8.00 sec 11.2 MBytes 93.8 Mbits/sec 0 117 KBytes
|
||||
[ 5] 8.00-9.00 sec 11.2 MBytes 93.8 Mbits/sec 0 117 KBytes
|
||||
[ 5] 9.00-10.00 sec 11.2 MBytes 93.8 Mbits/sec 0 117 KBytes
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
[ ID] Interval Transfer Bitrate Retr
|
||||
[ 5] 0.00-10.00 sec 113 MBytes 94.5 Mbits/sec 0 sender
|
||||
[ 5] 0.00-10.05 sec 112 MBytes 93.7 Mbits/sec receiver
|
||||
|
||||
iperf Done.
|
||||
24
results/test_20251111_145855/iperf3_server.log
Normal file
@@ -0,0 +1,24 @@
|
||||
-----------------------------------------------------------
|
||||
Server listening on 5201
|
||||
-----------------------------------------------------------
|
||||
Accepted connection from 10.11.0.70, port 44398
|
||||
[ 5] local 10.11.0.91 port 5201 connected to 10.11.0.70 port 44400
|
||||
[ ID] Interval Transfer Bitrate
|
||||
[ 5] 0.00-1.00 sec 10.7 MBytes 90.1 Mbits/sec
|
||||
[ 5] 1.00-2.00 sec 11.2 MBytes 94.2 Mbits/sec
|
||||
[ 5] 2.00-3.00 sec 11.2 MBytes 94.1 Mbits/sec
|
||||
[ 5] 3.00-4.00 sec 11.2 MBytes 94.2 Mbits/sec
|
||||
[ 5] 4.00-5.00 sec 11.2 MBytes 94.2 Mbits/sec
|
||||
[ 5] 5.00-6.00 sec 11.2 MBytes 94.1 Mbits/sec
|
||||
[ 5] 6.00-7.00 sec 11.2 MBytes 94.2 Mbits/sec
|
||||
[ 5] 7.00-8.00 sec 11.2 MBytes 94.1 Mbits/sec
|
||||
[ 5] 8.00-9.00 sec 11.2 MBytes 94.1 Mbits/sec
|
||||
[ 5] 9.00-10.00 sec 11.2 MBytes 94.2 Mbits/sec
|
||||
[ 5] 10.00-10.05 sec 574 KBytes 93.8 Mbits/sec
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
[ ID] Interval Transfer Bitrate
|
||||
[ 5] 0.00-10.05 sec 112 MBytes 93.7 Mbits/sec receiver
|
||||
iperf3: interrupt - the server has terminated
|
||||
-----------------------------------------------------------
|
||||
Server listening on 5201
|
||||
-----------------------------------------------------------
|
||||
1
results/test_20251111_145855/notes.txt
Normal file
@@ -0,0 +1 @@
|
||||
Now with caps between poe + - and gnd
|
||||
1
results/test_20251111_145855/stress.log
Normal file
@@ -0,0 +1 @@
|
||||
stress: info: [1278] dispatching hogs: 2 cpu, 2 io, 2 vm, 0 hdd
|
||||
2
results/test_20251111_145855/stress_poe.log
Normal file
@@ -0,0 +1,2 @@
|
||||
stress: info: [1196] dispatching hogs: 2 cpu, 2 io, 2 vm, 0 hdd
|
||||
stress: info: [1196] successful run completed in 65s
|
||||
188
run_tests.py
Normal file
@@ -0,0 +1,188 @@
|
||||
#!/usr/bin/env python3
|
||||
import subprocess
|
||||
import time
|
||||
import paramiko
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
def ssh_execute_command(host, username, command):
|
||||
"""Execute a command on a remote host via SSH and capture its output."""
|
||||
ssh = paramiko.SSHClient()
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
ssh.connect(hostname=host, username=username)
|
||||
stdin, stdout, stderr = ssh.exec_command(command)
|
||||
output = stdout.read().decode()
|
||||
error = stderr.read().decode()
|
||||
ssh.close()
|
||||
if error:
|
||||
raise RuntimeError(f"Error executing command '{command}': {error}")
|
||||
return output
|
||||
|
||||
|
||||
def ssh_execute_command_no_wait(host, username, command):
|
||||
"""Execute a command on a remote host via SSH without waiting for completion."""
|
||||
ssh = paramiko.SSHClient()
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
ssh.connect(hostname=host, username=username)
|
||||
ssh.exec_command(command)
|
||||
ssh.close()
|
||||
|
||||
|
||||
def fetch_file_from_dut(host, username, remote_path, local_path):
|
||||
"""Fetch a file from the DUT to the local machine."""
|
||||
ssh = paramiko.SSHClient()
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
ssh.connect(hostname=host, username=username)
|
||||
sftp = ssh.open_sftp()
|
||||
sftp.get(remote_path, local_path)
|
||||
sftp.close()
|
||||
ssh.close()
|
||||
|
||||
|
||||
def run_measurement(sample_number, supply, test_case, output_dir):
|
||||
"""Run the measure.py script."""
|
||||
subprocess.run(
|
||||
["python3", "measure.py", str(sample_number), supply, test_case],
|
||||
check=True
|
||||
)
|
||||
|
||||
|
||||
def run_iperf3_server(output_dir):
|
||||
"""Run iperf3 in server mode on the host and save its log."""
|
||||
print("Starting iperf3 server on the host...")
|
||||
log_file = os.path.join(output_dir, "iperf3_server.log")
|
||||
server_process = subprocess.Popen(
|
||||
["iperf3", "-s"],
|
||||
stdout=open(log_file, "w"),
|
||||
stderr=subprocess.STDOUT
|
||||
)
|
||||
time.sleep(2) # Allow the server to start
|
||||
return server_process
|
||||
|
||||
|
||||
def stop_iperf3_server(server_process):
|
||||
"""Stop the iperf3 server."""
|
||||
print("Stopping iperf3 server on the host...")
|
||||
server_process.terminate()
|
||||
server_process.wait()
|
||||
|
||||
|
||||
def start_background_command_and_measure(host, username, command, remote_log_file, local_log_file, sample_number, supply, test_case, output_dir):
|
||||
"""
|
||||
Start a background command on the DUT, perform the measurement while it's running,
|
||||
and fetch the log file after the command finishes.
|
||||
"""
|
||||
# Start the command in the background and redirect output to a log file on the DUT
|
||||
nohup_command = f"nohup {command} > {remote_log_file} 2>&1 &"
|
||||
ssh_execute_command_no_wait(host, username, nohup_command)
|
||||
print(f"Command '{command}' started on DUT. Log will be saved to {remote_log_file}")
|
||||
|
||||
# Wait briefly to ensure the command is running
|
||||
time.sleep(5)
|
||||
|
||||
# Perform the measurement while the command is running
|
||||
run_measurement(sample_number, supply, test_case, output_dir)
|
||||
|
||||
# Wait for the command to finish (optional: adjust this based on the command duration)
|
||||
time.sleep(5)
|
||||
|
||||
# Fetch the log file from the DUT
|
||||
fetch_file_from_dut(host, username, remote_log_file, local_log_file)
|
||||
print(f"Log file fetched from DUT: {local_log_file}")
|
||||
|
||||
|
||||
def main():
|
||||
sample_number = 8
|
||||
dut_ip = "10.11.0.45" # Replace with the actual DUT IP
|
||||
host_ip = "10.11.0.91" # Replace with the actual host IP
|
||||
username = "caster"
|
||||
|
||||
# Create a timestamped folder for logs and results
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
output_dir = os.path.join("results", f"test_{timestamp}")
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
|
||||
print("Measuring baseline...")
|
||||
run_measurement(sample_number, "external", "baseline", output_dir)
|
||||
|
||||
print("Running stress test...")
|
||||
# Run the stress test in the background and measure while it's running
|
||||
remote_stress_log = "/tmp/stress.log"
|
||||
local_stress_log = os.path.join(output_dir, "stress.log")
|
||||
start_background_command_and_measure(
|
||||
dut_ip,
|
||||
username,
|
||||
"stress -c 2 --io 2 --vm 2 --timeout 30",
|
||||
remote_stress_log,
|
||||
local_stress_log,
|
||||
sample_number,
|
||||
"external",
|
||||
"CPU",
|
||||
output_dir
|
||||
)
|
||||
|
||||
print("Running iperf3 test...")
|
||||
iperf3_server = run_iperf3_server(output_dir) # Start iperf3 server on the host
|
||||
try:
|
||||
remote_iperf3_client_log = "/tmp/iperf3_client.log"
|
||||
local_iperf3_client_log = os.path.join(output_dir, "iperf3_client.log")
|
||||
start_background_command_and_measure(
|
||||
dut_ip,
|
||||
username,
|
||||
f"iperf3 -c {host_ip}",
|
||||
remote_iperf3_client_log,
|
||||
local_iperf3_client_log,
|
||||
sample_number,
|
||||
"external",
|
||||
"EthPrim",
|
||||
output_dir
|
||||
)
|
||||
finally:
|
||||
stop_iperf3_server(iperf3_server) # Ensure the server is stopped
|
||||
|
||||
input("Switch power to PoE and press Enter to continue...")
|
||||
|
||||
print("Measuring baseline with PoE...")
|
||||
run_measurement(sample_number, "PoE", "baseline", output_dir)
|
||||
|
||||
print("Running stress test with PoE...")
|
||||
# Run the stress test in the background and measure while it's running
|
||||
remote_stress_log_poe = "/tmp/stress_poe.log"
|
||||
local_stress_log_poe = os.path.join(output_dir, "stress_poe.log")
|
||||
start_background_command_and_measure(
|
||||
dut_ip,
|
||||
username,
|
||||
"stress -c 2 --io 2 --vm 2 --timeout 15",
|
||||
remote_stress_log_poe,
|
||||
local_stress_log_poe,
|
||||
sample_number,
|
||||
"PoE",
|
||||
"CPU",
|
||||
output_dir
|
||||
)
|
||||
|
||||
print("Running iperf3 test with PoE...")
|
||||
iperf3_server = run_iperf3_server(output_dir) # Start iperf3 server on the host
|
||||
try:
|
||||
remote_iperf3_client_log_poe = "/tmp/iperf3_client_poe.log"
|
||||
local_iperf3_client_log_poe = os.path.join(output_dir, "iperf3_client_poe.log")
|
||||
start_background_command_and_measure(
|
||||
dut_ip,
|
||||
username,
|
||||
f"iperf3 -c {host_ip}",
|
||||
remote_iperf3_client_log_poe,
|
||||
local_iperf3_client_log_poe,
|
||||
sample_number,
|
||||
"PoE",
|
||||
"EthPrim",
|
||||
output_dir
|
||||
)
|
||||
finally:
|
||||
stop_iperf3_server(iperf3_server) # Ensure the server is stopped
|
||||
|
||||
print("All tests completed.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
9
settings.yaml
Normal file
@@ -0,0 +1,9 @@
|
||||
timebase_scale: 2e-6
|
||||
channels:
|
||||
2:
|
||||
offset: 5.0
|
||||
scale: 0.2
|
||||
3:
|
||||
offset: 3.3
|
||||
scale: 0.1
|
||||
output_directory: "./output"
|
||||
52
test.py
Normal file
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
# connect_dsx2014a_pyvisa.py
|
||||
import pyvisa
|
||||
import usb.core, usb.util
|
||||
|
||||
VID, PID = 0x0957, 0x1798 # Keysight DSOX2014A
|
||||
SERIAL = "MY59124583" # from your lsusb/PyUSB output
|
||||
|
||||
def detach_kernel_tmc(vid, pid):
|
||||
dev = usb.core.find(idVendor=vid, idProduct=pid)
|
||||
if not dev:
|
||||
return
|
||||
try:
|
||||
for cfg in dev:
|
||||
for intf in cfg:
|
||||
if intf.bInterfaceClass == 0xFE: # USBTMC
|
||||
if dev.is_kernel_driver_active(intf.bInterfaceNumber):
|
||||
dev.detach_kernel_driver(intf.bInterfaceNumber)
|
||||
try:
|
||||
dev.set_configuration()
|
||||
except Exception:
|
||||
pass
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def main():
|
||||
# If the kernel usbtmc module is bound, libusb can't talk. Detach it:
|
||||
detach_kernel_tmc(VID, PID)
|
||||
|
||||
rm = pyvisa.ResourceManager("@py") # pyvisa-py (libusb) backend
|
||||
candidates = [
|
||||
f"USB0::{VID}::{PID}::{SERIAL}::INSTR",
|
||||
f"USB::{VID}::{PID}::{SERIAL}::INSTR",
|
||||
f"USB0::0x{VID:04x}::0x{PID:04x}::{SERIAL}::INSTR",
|
||||
f"USB::0x{VID:04x}::0x{PID:04x}::{SERIAL}::INSTR",
|
||||
]
|
||||
|
||||
for addr in candidates:
|
||||
try:
|
||||
inst = rm.open_resource(addr)
|
||||
inst.timeout = 5000
|
||||
inst.read_termination = "\n"
|
||||
inst.write_termination = "\n"
|
||||
print("Connected:", addr, "->", inst.query("*IDN?").strip())
|
||||
inst.close()
|
||||
break
|
||||
except Exception as e:
|
||||
print(addr, "->", e)
|
||||
rm.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||