plesty.server.view.window

The console’s main window: menu bar, device table, detail pane.

Layout (designed for a bench, not docked):

┌ Bench  Device  View  Help ──────────────────────────────────────────┐
│ ┌ Devices ─────────────────────────────────────────────────────────┐ │
│ │ NAME    SOURCE                 STATE    PORT  PID    STARTED    │ │
│ │ pm100d  plesty-pm100d==0.2.1   running  5551  4242   10:21:03   │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ ┌ pm100d ──────────────────── [Log] [Jobs] [Reports] ──────────────┐ │
│ │ === plesty-server start … :: python -m plesty.pm100d …           │ │
│ │ [SERVER] Running at 127.0.0.1:5551                               │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ ~/.plesty/server · fleet.yaml · 2 devices · refreshed 10:21:05      │
└────────────────────────────────────────────────────────────────────┘

The window owns a Bench and a Worker; every menu action calls one presenter method on the worker and refreshes when it returns.

Attributes

COLUMNS

CHECK_COLUMN

NAME_COLUMN

REFRESH_MS

NOTICE_MS

Classes

MainWindow

The console window.

Functions

_card(→ PySide6.QtWidgets.QWidget)

A titled card with optional buttons: the console's layout primitive.

_button(→ PySide6.QtWidgets.QPushButton)

A card-header button wired to slot.

_short(→ str)

A path with the home directory abbreviated to ~.

_clock(→ str)

HH:MM:SS of an ISO timestamp (local time), or "".

_tone_brush(→ Any)

The palette colour for a state, looked up from the theme on the window.

Module Contents

plesty.server.view.window.COLUMNS = ('Fleet', 'Name', 'Source', 'State', 'Port', 'PID', 'Started')
plesty.server.view.window.CHECK_COLUMN = 0
plesty.server.view.window.NAME_COLUMN = 1
plesty.server.view.window.REFRESH_MS = 3000
plesty.server.view.window.NOTICE_MS = 20000
class plesty.server.view.window.MainWindow(bench: plesty.server.presenter.Bench, title: str = 'PLESTY bench', version: str = '')

Bases: PySide6.QtWidgets.QMainWindow

The console window.

Build the window around bench.

Parameters:
notice
bench
version = ''
worker
_views: list[plesty.server.presenter.DeviceView] = []
_starting: set[str]
_timer
_build_menu() None
Return type:

None

_add(menu: PySide6.QtWidgets.QMenu, text: str, slot: collections.abc.Callable[[], Any], shortcut: Any = None) PySide6.QtGui.QAction
Parameters:
  • menu (PySide6.QtWidgets.QMenu)

  • text (str)

  • slot (collections.abc.Callable[[], Any])

  • shortcut (Any)

Return type:

PySide6.QtGui.QAction

_build_body() None
Return type:

None

property selected: str | None

Name of the selected device, or None.

Return type:

str | None

select(name: str) None

Select the row of name (no-op when absent).

Parameters:

name (str)

Return type:

None

refresh() None

Re-read the devices on the worker and repaint when they arrive.

Return type:

None

_show_devices(views: list[plesty.server.presenter.DeviceView]) None
Parameters:

views (list[plesty.server.presenter.DeviceView])

Return type:

None

_selection_changed() None
Return type:

None

_update_buttons() None

Enable the device buttons for the selected row and its state.

Return type:

None

_refresh_detail() None
Return type:

None

_show_log(text: str) None
Parameters:

text (str)

Return type:

None

_show_jobs(jobs: list[plesty.server.model.Job]) None
Parameters:

jobs (list[plesty.server.model.Job])

Return type:

None

_show_reports(reports: list[Any]) None
Parameters:

reports (list[Any])

Return type:

None

_note(line: str) None

Show a progress line on its own row, and keep it.

Its own row, because a failure is standing information the operator has to act on and progress is not: neither may hide the other, which is also why this is not QStatusBar.showMessage — that hides every non-permanent widget, the standing failure included.

It clears itself after NOTICE_MS, because “installing …” an hour later is a lie about what the bench is doing. Nothing is lost — View ▸ Messages… has every line of the session.

Parameters:

line (str)

Return type:

None

clear_notice() None

Drop the progress line (the timer, and any action that finishes).

Return type:

None

property notice_text: str

The progress line currently shown (empty when none).

Return type:

str

show_messages() None

View → Messages…: every progress line this session, newest last.

Return type:

None

_show_message(text: str, tone: str) None
Parameters:
  • text (str)

  • tone (str)

Return type:

None

show_error(message: str) None

Report a failure in the window, where it costs the operator nothing to read.

Not a modal. What fails here fails asynchronously — an install takes minutes and the operator is often elsewhere — and a modal blocks the Qt event loop: the device table stops refreshing, an open job log stops tailing, and the console is frozen until somebody clicks it away. The message stays until it is dismissed or another replaces it.

Parameters:

message (str)

Return type:

None

clear_error() None

Hide the standing message (the Dismiss button, and any action that succeeds).

Return type:

None

property error_text: str

What the window is currently reporting as failed (empty when nothing).

Return type:

str

_call(action: collections.abc.Callable[[], Any], then: collections.abc.Callable[[Any], None] | None = None) None

Run a presenter call on the worker; refresh afterwards, report on error.

Parameters:
  • action (collections.abc.Callable[[], Any])

  • then (collections.abc.Callable[[Any], None] | None)

Return type:

None

_require() str | None
Return type:

str | None

_item_changed(item: PySide6.QtWidgets.QTableWidgetItem) None

A check box toggled: include/exclude the device from the working fleet.

Parameters:

item (PySide6.QtWidgets.QTableWidgetItem)

Return type:

None

_fleets_dir() pathlib.Path

Where the fleet file dialogs start: <home>/fleets/ (created on demand).

Return type:

pathlib.Path

new_fleet(path: str | None = None) None

File → New fleet…: an empty fleet file, made current (devices are added to it).

Parameters:

path (str | None)

Return type:

None

open_fleet(path: str | None = None) None

File → Open fleet…: replace the declarations with another fleet file.

Parameters:

path (str | None)

Return type:

None

save_fleet_as(path: str | None = None) None

File → Save working fleet as…: the checked devices to a new fleet file.

Parameters:

path (str | None)

Return type:

None

_fleet_changed() None
Return type:

None

edit_device_config() None

Edit → Device config…: declaration + .env of the highlighted device.

The catalogue is fetched on the worker first, so the module’s repository URL and latest tag are in the drop-downs when the operator switches a release declaration to a repository one.

Return type:

None

edit_fleet_file() None

Edit → Fleet file…: the YAML of the whole fleet.

Return type:

None

open_catalogue() None

Catalogue → Search & install…: fetch the hub catalogue, install a module.

Only the module: the fleet is not touched here. Declaring an instance of it is Edit ▸ Add device…, which offers what the bench holds.

Return type:

None

declare_device() None

Edit → Add device…: declare an instance of an installed module.

With nothing installed the user is sent to the catalogue instead.

Return type:

None

edit_device() None

Edit the declaration only (used by the context menu).

Return type:

None

remove_device() None

Edit → Remove from fleet (also the Remove button).

Return type:

None

start_device() None

Device → Start (one start at a time per device).

Return type:

None

stop_device() None

Device → Stop.

Return type:

None

restart_device() None

Device → Restart.

Return type:

None

install_device() None

Device → Install: starts the job and opens its dialog.

Return type:

None

update_device() None

Device → Update: starts the job and opens its dialog.

Return type:

None

uninstall_device() None

Device → Uninstall.

Return type:

None

field_test_device() None

Device → Field test…: configure, start the job, open its dialog.

Return type:

None

fleet_up() None

Device → Fleet up (the working fleet).

Return type:

None

fleet_down() None

Device → Fleet down (the working fleet).

Return type:

None

show_jobs() None

View → Jobs…: the Jobs tab of the detail pane.

Return type:

None

_open_job(job: plesty.server.model.Job) None
Parameters:

job (plesty.server.model.Job)

Return type:

None

_open_job_row(item: PySide6.QtWidgets.QTableWidgetItem) None
Parameters:

item (PySide6.QtWidgets.QTableWidgetItem)

Return type:

None

_context_menu(pos: Any) None
Parameters:

pos (Any)

Return type:

None

closeEvent(event: Any) None

Closing the console closes what it manages: servers and running jobs.

Asks first when something is running — an accidental close must not take a bench down — then stops everything synchronously so nothing is left unmanaged behind a window that is gone.

Parameters:

event (Any)

Return type:

None

plesty.server.view.window._card(title: str | PySide6.QtWidgets.QLabel, body: PySide6.QtWidgets.QWidget, buttons: list[PySide6.QtWidgets.QWidget] | None = None, own_row: bool = False) PySide6.QtWidgets.QWidget

A titled card with optional buttons: the console’s layout primitive.

Parameters:
  • title (str | PySide6.QtWidgets.QLabel) – Card title (a label is reused as-is).

  • body (PySide6.QtWidgets.QWidget) – The card’s content.

  • buttons (list[PySide6.QtWidgets.QWidget] | None) – Buttons shown on the title line (few) or, with own_row, on a bar of their own between the title and the body (many).

  • own_row (bool) – Put the buttons on their own row.

Return type:

PySide6.QtWidgets.QWidget

plesty.server.view.window._button(text: str, slot: collections.abc.Callable[[], Any], tooltip: str = '', primary: bool = False, danger: bool = False) PySide6.QtWidgets.QPushButton

A card-header button wired to slot.

Parameters:
  • text (str)

  • slot (collections.abc.Callable[[], Any])

  • tooltip (str)

  • primary (bool)

  • danger (bool)

Return type:

PySide6.QtWidgets.QPushButton

plesty.server.view.window._short(path: Any) str

A path with the home directory abbreviated to ~.

Parameters:

path (Any)

Return type:

str

plesty.server.view.window._clock(stamp: str | None) str

HH:MM:SS of an ISO timestamp (local time), or "".

Parameters:

stamp (str | None)

Return type:

str

plesty.server.view.window._tone_brush(widget: PySide6.QtWidgets.QWidget, state: str) Any

The palette colour for a state, looked up from the theme on the window.

Parameters:
  • widget (PySide6.QtWidgets.QWidget)

  • state (str)

Return type:

Any