Blocking driver for Infratek 106A power analyzers. Single-shot (STOP) mode. Requires pyvisa + NI-VISA.
Early LEM D 4000 Devices are made by Infratek and will ID as 306A
pip install pyvisa
from infratek_106a import Infratek106A
with Infratek106A() as dev:
dev.configure(current_input="IN30", sync_source="CURR", aperture="250M", phase="L1")
dev.trigger()
print(dev.voltage_rms())
print(dev.current_rms("L2")) # switches phase automaticallyInfratek106A(resource="GPIB0::5::INSTR", timeout_ms=10000, warmup_count=1)warmup_count — number of discard triggers after any config change. The device returns garbage data for the first N measurements after changing acquisition settings (range, aperture, input, etc.). Increase if readings are unstable after config changes.
All parameters optional. Only sends commands for what you pass. Batches ACQ commands into a single STOP/restart cycle.
dev.configure(
current_input="IN30", # "IN5", "IN30", "SH"
sync_source="CURR", # "VOLT", "CURR"
aperture="500M", # "100M", "250M", "500M", "1", "2"
voltage_range="Auto", # "Auto", "300M", "1", "3", "10", "30", "100", "300", "1000"
current_range="Auto", # depends on input: IN30→"1".."100", IN5→"15M".."15", SH→"60M".."6"
phase="L1", # "L1", "L2", "L3"
warmup_count=3,
)dev.trigger() # blocking, waits for acquisition complete
# All read methods accept optional phase parameter
v = dev.voltage_rms()
v = dev.voltage_rms("L2")All accept optional phase parameter.
| Voltage | Current | Power | Energy |
|---|---|---|---|
voltage_rms() |
current_rms() |
power_active() |
energy_active() |
voltage_rms_ac() |
current_rms_ac() |
power_apparent() |
energy_apparent() |
voltage_rect() |
current_rect() |
power_reactive() |
|
voltage_mean() |
current_mean() |
power_factor() |
|
voltage_min() |
current_min() |
power_active_ac() |
|
voltage_max() |
current_max() |
power_apparent_ac() |
|
voltage_peak() |
current_peak() |
power_reactive_ac() |
|
voltage_crest() |
current_crest() |
power_factor_ac() |
|
voltage_form() |
current_form() |
||
voltage_thd() |
current_thd() |
||
current_int() |
|||
frequency() |
Other: energy_reset(), current_reset(), acquisition_quality(), error(), identify()
One trigger, read all phases:
dev.configure(current_input="IN30", sync_source="CURR", aperture="500M", phase="L1")
dev.trigger()
for ph in ("L1", "L2", "L3"):
v = dev.voltage_rms(ph)
i = dev.current_rms(ph)
p = dev.power_active(ph)
print(f"{ph}: {v:.2f} V {i:.4f} A {p:.2f} W")Harmonics 1–99. Returns list[float].
dev.trigger()
v_harmonics = dev.voltage_fft(1, 50, "L1")
i_harmonics = dev.current_fft(1, 50, "L1")
p_harmonics = dev.power_fft(1, 50, "L1")Plot:
import matplotlib.pyplot as plt
dev.trigger()
i_fft = dev.current_fft(1, 50, "L1")
v_fft = dev.voltage_fft(1, 50, "L1")
fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)
ax1.bar(range(1, 51), v_fft)
ax1.set_ylabel("Voltage (V)")
ax2.bar(range(1, 51), i_fft)
ax2.set_ylabel("Current (A)")
ax2.set_xlabel("Harmonic #")
plt.show()Channels 0–7. Returns list[float].
dev.trigger()
ainp = dev.analog_inputs(0, 7)
for ch, val in enumerate(ainp):
print(f"CH{ch}: {val:.6f}")Blocking driver — use a worker thread:
import threading
def worker():
dev.trigger()
v = dev.voltage_rms()
# update GUI from here
t = threading.Thread(target=worker)
t.start()