Skip to main content

A high-performance, dark-mode SCADA UI widget library for PyQt6.

Project description

SCADA UI Kit

CI PyPI version Python versions Wheel License Changelog

A robust, enterprise-grade industrial UI widget library for PyQt6, engineered for performance, deep customisation, and a smooth developer experience. The codebase is written to Fluent Python (2e) idioms: rich data-model methods, property-based APIs, deque-backed buffers, IntEnum state codes, Qt-signal observers, and fully typed public interfaces (PEP 561).

Features

  • ScadaRadialGauge - dark-mode radial gauge with a configurable alert threshold that turns the needle red above 80% of range. Assign to .value and the widget repaints itself.
  • ScadaStripChart - real-time scrolling telemetry chart backed by a fixed-length collections.deque for O(1) appends and automatic eviction of the oldest sample. Iterable and subscriptable like a normal sequence.
  • ScadaIndicator + ScadaIndicatorMatrix - multi-state LED indicators laid out in a grid. The matrix implements the full mapping protocol, so you can write matrix["COOLANT"] = IndicatorState.RUNNING, iterate with for name in matrix, and check membership with "COOLANT" in matrix.
  • ScadaToggle - heavy-duty actuator switch that emits toggled(bool) so you can wire control inputs straight to your indicator matrix or business logic.
  • IndicatorState enum - OFFLINE, RUNNING, WARNING, FAULT. It's an IntEnum, so raw integers still work for back-compat.
  • Typed - every public symbol ships with type hints and a PEP 561 py.typed marker, so mypy and pyright pick up the annotations out of the box.

Installation

From the project root:

pip install .

Or, for local development with live code reloads:

pip install -e .

PyQt6 is pulled in automatically as a dependency.

Quick Start

import sys
from PyQt6.QtWidgets import QApplication
from scada_ui_kit import ScadaRadialGauge

app = QApplication(sys.argv)
gauge = ScadaRadialGauge(title="REACTOR PRESSURE", unit="PSI", min_val=0, max_val=150)
gauge.value = 87        # property assignment - triggers the repaint automatically
gauge.show()
sys.exit(app.exec())

Mapping-style status updates

from scada_ui_kit import IndicatorState, ScadaIndicatorMatrix

matrix = ScadaIndicatorMatrix(columns=2)
for name in ("COOLANT", "CORE TEMP", "CONTAINMENT", "VENTILATION"):
    matrix.add_indicator(name)

matrix["COOLANT"] = IndicatorState.RUNNING
matrix["VENTILATION"] = IndicatorState.WARNING

assert "COOLANT" in matrix
for system in matrix:                         # __iter__ yields indicator names
    print(system, matrix[system].state)       # __getitem__ returns the widget

Toggle with observer wiring

from scada_ui_kit import IndicatorState, ScadaToggle

pump = ScadaToggle()
pump.toggled.connect(
    lambda on: matrix.__setitem__(
        "COOLANT",
        IndicatorState.RUNNING if on else IndicatorState.OFFLINE,
    )
)

Running the demos

The repository ships with five runnable scripts at the project root. Once the package is installed (pip install -e .):

python main_dashboard.py   # unified dashboard with all widgets and a live feed
python scada_gauge.py      # slider-driven gauge demo
python scada_chart.py      # sine-wave + noise strip chart
python scada_matrix.py     # indicator matrix showcase
python scada_toggle.py     # toggle wired to a live status label

Requirements

  • Python 3.10+
  • PyQt6 6.0+

Building distribution artifacts

The repo ships a small helper that produces an sdist and a wheel in ./dist/ and validates them with twine check before any upload.

pip install -e .[build]      # installs the `build` + `twine` tools locally
python build_package.py      # clean -> build -> twine check -> summary

Useful flags:

python build_package.py --clean-only   # just wipe dist/ and build/
python build_package.py --no-clean     # keep previous artifacts
python build_package.py --no-check     # skip the twine validation pass

A successful run prints something like:

[build] artifacts ready in ./dist/:
    scada_ui_kit-0.1.0-py3-none-any.whl                         12.3 KB
    scada_ui_kit-0.1.0.tar.gz                                   10.1 KB

The wheel is a single, self-contained file you can distribute to users - they install it with pip install scada_ui_kit-0.1.0-py3-none-any.whl.

Bumping the version

The package version lives in one place: __version__ in scada_ui_kit/__init__.py. pyproject.toml resolves it dynamically at build time via setuptools' attr directive, so drift is impossible by construction.

python bump_version.py patch        # 0.1.0 -> 0.1.1  (bug fix)
python bump_version.py minor        # 0.1.0 -> 0.2.0  (back-compatible feature)
python bump_version.py major        # 0.1.0 -> 1.0.0  (breaking change)
python bump_version.py 2.7.3        # explicit SemVer set
python bump_version.py patch -n     # dry-run: print the new version and exit

Git automation

python bump_version.py patch -c     # write + 'git add' + 'git commit'
python bump_version.py patch -c -t  # also create an annotated 'vX.Y.Z' tag

Safety checks that run before anything is written:

  • If --commit or --tag is requested, git rev-parse --is-inside-work-tree verifies we're actually in a repo.
  • If --tag is requested, git tag --list vX.Y.Z must be empty (no clobber).
  • The commit is scoped with git commit -- scada_ui_kit/__init__.py so any unrelated already-staged changes don't get swept into the release commit.

After a successful --commit -t, push with:

git push && git push origin vX.Y.Z

Typical release flow

python bump_version.py patch -c -t        # write, commit, tag
python build_package.py                   # sdist + wheel + twine check
python publish.py                         # TestPyPI (safe default)
python publish.py --production            # real PyPI, with y/N prompt
git push && git push origin vX.Y.Z        # share the release commit/tag

Publishing to PyPI / TestPyPI

Once the artifacts in dist/ are validated, publish.py uploads them with sensible safety defaults:

python publish.py                    # uploads to TestPyPI (safe default)
python publish.py --production       # uploads to real PyPI; asks for 'yes'
python publish.py --production -y    # non-interactive production upload (CI)

Authentication is delegated to twine, so any of the standard mechanisms work:

  • TWINE_USERNAME / TWINE_PASSWORD environment variables (recommended for CI; set TWINE_USERNAME=__token__ and TWINE_PASSWORD=<your PyPI API token>).
  • A ~/.pypirc file with [pypi] and [testpypi] sections.
  • The system keyring, if configured.

Safety features baked into the script:

  • twine check runs before any upload so malformed metadata is caught locally.
  • Production uploads require both --production and an explicit yes confirmation (or --yes for automation).
  • Non-interactive environments (no TTY) without --yes are refused outright for production, preventing accidents in cron jobs and CI triggers.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

scada_ui_kit-0.1.1.tar.gz (13.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

scada_ui_kit-0.1.1-py3-none-any.whl (10.8 kB view details)

Uploaded Python 3

File details

Details for the file scada_ui_kit-0.1.1.tar.gz.

File metadata

  • Download URL: scada_ui_kit-0.1.1.tar.gz
  • Upload date:
  • Size: 13.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for scada_ui_kit-0.1.1.tar.gz
Algorithm Hash digest
SHA256 515fcd2300653e5d28119663d2a7479572451e2b30e4a5923064d862545ae9ee
MD5 60ce1301ba4d481b5b5eb8f86a81635a
BLAKE2b-256 7ae13b8bda6f4d4c7dec037398ee8cffff6eb9a0bd88bbd2c57f242ff6eb5a69

See more details on using hashes here.

File details

Details for the file scada_ui_kit-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: scada_ui_kit-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 10.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for scada_ui_kit-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d755c3f91a4beebcb9daa7d49cd708f73a631f84f9877cc899600e7f75b5d674
MD5 808a5b0002a104b20f4d2e85dc52d7ec
BLAKE2b-256 1ece28f84e8f7adaaaf15a5fbf7347a7ffcc3016510319c8a6455d6fcdb218bd

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page