Skip to content

Building and deploying

Both control tools live in this repository. Their build and deploy paths are different and described separately below.

ADCL WinSoft

The Python application is packaged as a single-file Windows .exe via PyInstaller. Build is a Windows operation — the .exe is for Windows, the NI-DAQmx bindings only exist on Windows, and the build tooling has been validated only on the lab PC.

Dev install (after git pull)

From a Windows command prompt or PowerShell:

cd code\adcl_winsoft
deploy\install_dev.cmd

This xcopys the package source into C:\Users\kshit\.venvs\adcl_winsoft\Lib\site-packages\adcl_winsoft\. The reason we do not pip install -e . over the WSL UNC share is that the share is slow and the editable install is unreliable across the boundary. See the PyInstaller quirks note.

Dev run

deploy\run_dev.cmd

This activates the venv and runs python -m adcl_winsoft. Use this for any change-iterate-test loop; do not rebuild the .exe for every edit.

Building the .exe

deploy\build_exe.cmd

What this does:

  1. Stages source from the WSL repo to C:\Users\kshit\.adcl_winsoft_build\ via xcopy (much faster than reading via the WSL share).
  2. Activates the venv.
  3. Runs pyinstaller --noconfirm --clean adcl_winsoft.spec.
  4. Copies the resulting dist\ADCL WinSoft.exe into code\adcl_winsoft\release\ and to E:\Wind_tunnel\ADCLWinSoft\ on the lab PC.

Total build time on the lab PC is about 2 minutes. The resulting binary is ~65 MB, single-file, console=False.

What the spec file does

adcl_winsoft.spec is a hand-written PyInstaller spec, not an auto-generated one. The notable parts:

  • datas= carries the bundled Roboto fonts from src/adcl_winsoft/resources/fonts/.
  • copy_metadata() calls bundle package metadata for nidaqmx, nitypes, hightime, deprecation, pymodbus, argon2_cffi, PySide6, pyqtgraph. Without these, the .exe crashes at first import on importlib.metadata.version(...) calls. See PyInstaller quirks note.
  • hiddenimports= lists pymodbus submodules that PyInstaller's static analyzer does not catch.
  • excludes= removes large modules that are imported transitively but not used (tkinter, scipy submodules, etc.) to keep the binary small.

If you add a new third-party dependency to pyproject.toml, ask yourself:

  1. Does it call importlib.metadata.version(...) on itself or anything it imports? If yes, add it to copy_metadata().
  2. Does it have submodules that are imported via string lookup or importlib? If yes, add them to hiddenimports.
  3. Test the bundled .exe, not just the dev run. The dev run will not catch metadata bugs.

Admin password

tools/init_admin.py was the original CLI for setting the admin password. It is now legacy — first-run dialogs in __main__.py handle it interactively. The CLI is kept around because it is useful for unattended bring-up.

WindTunnelControl.ps1

The PowerShell tool needs no build step. Deployment is a copy.

Deploy after editing

From the WSL side (in the repository working copy):

cd code/wind_tunnel_control
powershell.exe -ExecutionPolicy RemoteSigned -File ./deploy.ps1

deploy.ps1 copies WindTunnelControl.ps1 and a .cmd launcher to E:\Wind_tunnel\AeroWare\. From there, the operator runs the launcher.

Why deploy alongside AeroWare

E:\Wind_tunnel\AeroWare\ is the directory the existing operators look in. Putting the new tool there avoids a "where is the tunnel software?" moment for anyone returning to the lab after a few months. It is not a technical requirement; the script will run from anywhere.

Versioning

Neither tool has a formal version-tagging discipline yet. The source in this repository is the truth; the deployed copies are derivatives. To know what version is on the lab PC, look at the file mtimes and compare to the git log of the source.

If we end up shipping ADCL WinSoft to anyone outside this lab, a semver tag inside pyproject.toml plus a CHANGELOG.md entry per release should be added.

Where the release binary lives

code/adcl_winsoft/release/ADCL WinSoft.exe is the most recent built binary, committed to the repository so a fresh clone of the repo on the lab PC can be deployed without rebuilding. The release directory has its own README.md describing what is there.