GUI application for J-V characterisation of solar cells. Controls source meter units (SMUs), solar simulators, filter wheels, and optional Arduino-based accessories.
For architecture and developer documentation see docs/ARCHITECTURE.md.
python -m iv_lab.main --settings config/system_settings_example.json --emulate# 1. Copy the example that matches your setup and edit it:
copy config\examples\oriel_iv.toml config\system_settings.toml
# 2. Run (auto-discovers config/system_settings.toml):
python -m iv_lab.mainThis is the simple recipe for a working install with a settings file the app always finds. It assumes you have a clone of this repository.
# From the repository folder:
pip install .
# Add the instrument-control libraries for real hardware (skip for emulation):
pip install ".[hardware]"This adds an iv-lab command that does exactly the same thing as
python -m iv_lab.main — use whichever you prefer.
The app needs one .toml file describing your hardware. Copy the example that
matches your bench (they live in config/examples/) and
edit it:
copy config\examples\sinus70_glovebox.toml config\system_settings.toml
notepad config\system_settings.tomlChange at least basePath, sdPath, the [lamp] brand/model, and the SMU
visa_address — see System settings for the details.
Remember the full path to this file — you will point the app at it in
step 4.
Login needs a users.txt. The simplest option is to use the generic one that
ships with the repo — copy it next to your settings file:
copy config\users_generic.txt config\users.txtYou can now log in with a blank username, or user / 123456. To add
named accounts, see User management.
Important
The app chooses its settings file based on where you launch it from. If
you run iv-lab with no --settings, it uses .\config\system_settings.toml
only when that folder exists in your current directory — otherwise it
silently falls back to a copy under %APPDATA%\iv_lab, which may be old or
describe different hardware. That mismatch is the usual cause of a wrong
"No … instrument found" error. The reliable habit is to always pass
--settings with the full path, so it never depends on which folder you
are in.
# Emulation (no instruments needed):
iv-lab --settings C:\Users\you\Documents\iv_lab\config\system_settings.toml --emulate
# Real hardware:
iv-lab --settings C:\Users\you\Documents\iv_lab\config\system_settings.tomlIf typing the path every time is tedious, set it once as an environment
variable — then iv-lab (from any folder) uses it automatically and you can
drop the --settings flag:
setx IV_LAB_SETTINGS "C:\Users\you\Documents\iv_lab\config\system_settings.toml"(Open a new terminal after setx for it to take effect.)
Calibration values you set in the app are written back into this settings file automatically.
iv-lab is a console program, so on Windows it opens a black terminal window
next to the GUI (handy for reading start-up messages while troubleshooting). To
launch without that window, use the windowed twin iv-lab-gui — it
takes exactly the same options:
iv-lab-gui --settings C:\Users\you\Documents\iv_lab\config\system_settings.tomlFor everyday use, make a desktop shortcut to iv-lab-gui.exe (it lives in
your Python Scripts folder — run python -c "import sysconfig; print(sysconfig.get_path('scripts'))"
to find it) and double-click it. iv-lab-gui has no console, so if the app ever
fails to start, re-run it once as iv-lab to see the message.
PDF reports look for EPFL_Logo.png in the folder you launch from, or wherever
--logo PATH points. Reports render fine without it.
How you update depends on how you installed (step 1):
If you cloned the repository — pull the latest code, then reinstall:
git pull
pip install --upgrade .Tip
Install with pip install -e . (the -e means editable) once, and you
never need to reinstall for code changes again — a plain git pull is enough,
because the installed package points straight at your source folder. Without
-e, pip copies the code into site-packages and freezes it, so edits
and version bumps won't take effect until you rerun pip install --upgrade .
(a common cause of the app still showing an old version number in its title
bar). Only rerun pip install -e . if the dependencies in pyproject.toml
change.
If you installed straight from GitHub (no clone) — re-run the install with
--upgrade:
pip install --upgrade "git+https://github.com/EPFL-LPI/iv_lab.git"Your settings and users files are separate from the code, so updating never touches them.
If you don't want to deal with git or downloading the whole repository, you
can install the app with a single command and let it create its own
configuration for you. This is the easiest path if you are not a programmer.
You need Python installed first (version 3.10 or newer). To check, open
PowerShell and type python --version. If it prints a version number
you're set; if not, install Python from python.org
and tick "Add Python to PATH" during setup.
Copy-paste this into PowerShell and press Enter:
pip install "git+https://github.com/EPFL-LPI/iv_lab.git"For real instruments (not needed if you only want to try emulation), also run:
pip install "iv_lab[hardware] @ git+https://github.com/EPFL-LPI/iv_lab.git"This adds an iv-lab command you can type from any folder.
Run:
iv-lab --initThis creates a personal configuration folder and puts two starter files in it:
system_settings.toml— describes your hardware. It starts in emulation mode, so the app runs immediately even with nothing connected.users.txt— the login list, pre-filled with the generic account.
The command prints the exact folder it used. On Windows it is:
C:\Users\<you>\AppData\Roaming\iv_lab
--init never overwrites files that already exist, so it is safe to run again.
iv-lab --emulateLog in with a blank username (or user / 123456). Because the config
lives in your personal folder, iv-lab finds it automatically — you do not
need to be in any particular directory or pass --settings.
Open the system_settings.toml that --init created (use the folder path it
printed) in Notepad and edit it:
notepad "$env:APPDATA\iv_lab\system_settings.toml"Change at least basePath, sdPath, the [lamp] brand/model, and the SMU
visa_address. The System settings section below explains
each field. If you'd like to start from a file that already matches a known
bench, open the config/examples/ folder on GitHub, copy
the contents of the closest .toml into your system_settings.toml, and adjust
from there.
Then run the app against real instruments (drop --emulate):
iv-labiv-lab is a console program, so on Windows a black terminal window opens next
to the app. To launch without it, use the windowed version iv-lab-gui
— it takes exactly the same options:
iv-lab-guiFor everyday use, make a desktop shortcut so you can just double-click:
-
Find your Python
Scriptsfolder — run this and copy the path it prints:python -c "import sysconfig; print(sysconfig.get_path('scripts'))"
-
Open that folder, right-click
iv-lab-gui.exe→ Show more options → Send to → Desktop (create shortcut).
Double-clicking that shortcut starts the app with no terminal window.
(iv-lab-gui has no console, so if the app ever fails to start, run iv-lab
once to read the error message.)
When a new version is released, upgrade with one command — your settings and login files are untouched:
pip install --upgrade "git+https://github.com/EPFL-LPI/iv_lab.git"Where the app looks for its settings file (all install methods)
When you run the app without --settings, it searches, in order:
- the
IV_LAB_SETTINGSenvironment variable (a full path to the file), .\config\system_settings.tomlin the folder you launched from,- the personal config folder (
%APPDATA%\iv_lab\system_settings.tomlon Windows,~/.config/iv_lab/system_settings.tomlelsewhere).
The GitHub install above relies on option 3. If you also keep a
config\system_settings.toml in some folder, option 2 will win whenever you
launch from that folder — which can load a different, possibly outdated file.
When in doubt, pass --settings with a full path to remove any ambiguity.
Machine-specific configuration lives in config/system_settings.toml (gitignored).
Annotated templates for every physical setup are in config/examples/:
| File | Hardware |
|---|---|
oriel_iv.toml |
Trinamic TMCM-1260 + Newport SOL3A + Keithley 2400 |
sinus70_1.toml |
Wavelabs Sinus70 + Keithley 2602 |
sinus70_glovebox.toml |
Wavelabs Sinus70 + Keithley 2400 (RS-232, glovebox) |
verasol_glovebox.toml |
Oriel VeraSol LSS-7120 (USB) + Keithley 2400 (RS-232, glovebox) |
ivlab_wavelabs.toml |
Wavelabs Sinus70 + Keithley 2602 (older IVLab station) |
ivlab_indoor.toml |
Manual lamp + Keithley 2602 (indoor) |
bcl.toml |
Trinamic TMCM-1260 + Newport SOL3A + Keithley 2602 (BCL) |
bcl_old_iv.toml |
Trinamic TMCM-3110 + Keithley 2602 + Arduino (BCL historical) |
gmf.toml |
Trinamic TMCM-1160 + Newport SOL3A + Keithley 2400 (macOS) |
dell.toml |
Manual lamp + Keithley 2401, no reference diode (laptop) |
fte.toml |
Manual lamp + Keithley 2401, RS-232 (field setup) |
old_iv.toml |
Manual lamp + Keithley 2400 + Arduino (original macOS station) |
Setting up a new machine:
- Copy the closest example to
config/system_settings.toml. - Edit the paths (
basePath,sdPath) and the VISA address of the SMU. - Run the app and use the Calibration panel to set
fullSunReferenceCurrent.
The app writes the calibrated value back intoconfig/system_settings.tomlautomatically.
Key fields to check:
[computer]
basePath = "C:\\Data" # where measurement files are saved
sdPath = "C:\\sd" # scrambled backup copy; set "" to disable
[SMU]
visa_address = "GPIB0::24::INSTR" # adjust to your instrument
visa_library = "C:\\Windows\\SysWOW64\\visa32.dll"
[lamp]
brand = "Trinamic" # or "Wavelabs", "VeraSol", "Oriel", "Manual", …
model = "TMCM-1260"TOML is used instead of JSON because it supports comments, making the example files self-documenting. The app also accepts
.jsonfiles if you have an existing JSON config.
User accounts are stored in config/users.txt (gitignored, machine-specific).
The committed file config/users_generic.txt provides a ready-to-use generic account and is the fallback when users.txt does not exist.
Leave the username blank (or enter user / 123456) to log in with the generic account. This works out of the box with users_generic.txt and is sufficient for day-to-day measurements.
users.txt stores a JSON dictionary {"username": "password"} in a legacy scrambled format — it cannot be edited as plain text. Use this one-liner to create or update the file:
python - <<'EOF'
from iv_lab.services.auth import write_users
write_users("config/users.txt", {
"user": "123456", # generic account — keep this
"alice": "12345", # SCIPER or chosen password
"bob": "67890",
})
EOFRun it from the repository root. The file is overwritten each time, so include all accounts you want to keep.
Calibration access is granted only to the generic user/123456 login and to the hardcoded usernames felix and legeyt. All other named accounts can run measurements but cannot access the calibration panel.
python -m iv_lab.main --settings path/to/my_settings.toml --users path/to/my_users.txtpip install -e .Optional hardware libraries (only needed when not using --emulate):
pyvisa+ a VISA back-end (NI-VISA or pyvisa-py) — SMU communication and the Oriel / VeraSol LSS-7120 simulatorspymeasure— Keithley 2400/2401/2450 driverspytrinamic— Trinamic filter wheel driver
The Wavelabs Sinus70 driver uses plain TCP sockets (Python standard library) and needs no extra package; the manual lamp needs none either.
python -m pytest